Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 489
0.00% covered (danger)
0.00%
0 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
UsersReportOverviewExport
0.00% covered (danger)
0.00%
0 / 489
0.00% covered (danger)
0.00%
0 / 5
42
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 array
0.00% covered (danger)
0.00%
0 / 81
0.00% covered (danger)
0.00%
0 / 1
6
 headings
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
2
 getCompanyOverview
0.00% covered (danger)
0.00%
0 / 315
0.00% covered (danger)
0.00%
0 / 1
2
 getFlyCutUsageByUser
0.00% covered (danger)
0.00%
0 / 77
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace App\Exports;
4
5use App\Helpers\CoachLevelHelper;
6use App\Http\Models\Admin\Company;
7use App\Http\Models\Auth\User;
8use App\Http\Models\HubspotProperties;
9use App\Traits\AccountCenter\Reporting\ChartTrait;
10use Carbon\Carbon;
11use Carbon\CarbonPeriod;
12use MongoDB\BSON\ObjectId;
13use MongoDB\BSON\UTCDateTime;
14use Vitorccs\LaravelCsv\Concerns\Exportable;
15use Vitorccs\LaravelCsv\Concerns\FromArray;
16use Vitorccs\LaravelCsv\Concerns\WithHeadings;
17
18class UsersReportOverviewExport implements FromArray, WithHeadings
19{
20    use ChartTrait;
21    use Exportable;
22
23    public $company_id;
24
25    public function __construct($company_id)
26    {
27        $this->company_id = $company_id;
28    }
29
30    public function array(): array
31    {
32        $flychartTotal = $this->getCompanyOverview($this->company_id, Carbon::now()->subMonths(12)->toDateString(), Carbon::now()->toDateString());
33
34        $users = User::select([
35            'id',
36            'first_name',
37            'last_name',
38            'company_group_id',
39            'company_id',
40            'deleted_at',
41            'avatar',
42        ])->where('company_id', '=', $this->company_id);
43
44        $users = $users->get();
45        $user_ids = $users->pluck('id')->toArray();
46
47        $period = CarbonPeriod::create(Carbon::now()->subMonths(12)->toDateString(), '1 month', Carbon::now()->toDateString());
48        $data = [];
49
50        $startDate = new UTCDateTime(Carbon::now()->subMonths(12)->startOfDay()->getTimestamp() * 1000);
51        $endDate = new UTCDateTime(Carbon::now()->endOfDay()->getTimestamp() * 1000);
52        $characterUsageTotal = $this->getFlyCutUsageByUser($user_ids, $startDate, $endDate);
53
54        foreach ($period as $date) {
55            $month_year = $date->format('M Y');
56            $year_month = $date->format('Y-m');
57
58            $purchased_licenses = $flychartTotal[0]->purchased_licenses;
59            $assigned_licenses = $flychartTotal[0]->total_active_licenses + $flychartTotal[0]->total_invited_licenses;
60            $activate_licenses = $flychartTotal[0]->total_active_licenses;
61            $extension_installed = 0;
62
63            $extensions_installed_query = HubspotProperties::raw(function ($collection) use ($user_ids, $date) {
64                return $collection->aggregate([
65                    [
66                        '$match' => [
67                            'flymsg_id' => ['$in' => $user_ids],
68                            '$or' => [
69                                [
70                                    'flymsg_chrome_extension_installed' => 'Yes',
71                                    'flymsg_chrome_extension_uninstalled' => 'No',
72                                ],
73                                [
74                                    'flymsg_edge_extension_installed' => 'Yes',
75                                    'flymsg_edge_extension_uninstalled' => 'No',
76                                ],
77                            ],
78                            'created_at' => [
79                                '$gte' => new UTCDateTime(strtotime($date->startOfMonth()->toDateString()) * 1000),
80                                '$lte' => new UTCDateTime(strtotime($date->endOfMonth()->toDateString()) * 1000),
81                            ],
82                        ],
83                    ],
84                    [
85                        '$sort' => [
86                            'created_at' => -1,
87                        ],
88                    ],
89                    [
90                        '$group' => [
91                            '_id' => '$flymsg_id',
92                            'most_recent' => ['$first' => '$$ROOT'],
93                        ],
94                    ],
95                ]);
96            });
97
98            $extension_installed = count($extensions_installed_query);
99
100            $flychart = collect($flychartTotal[0]->flycut_usage_aggregated)->firstWhere('month_year', $year_month);
101
102            $roi_spotlight = round($flychart->cost_saved_by_flymsg, 2);
103            $productivity_spotlight = round($flychart->time_saved_by_flymsg, 2);
104            $total_characters_typed = round($flychart->characters_typed_by_flymsg, 2);
105
106            $characterUsage = $characterUsageTotal->where('_id', $year_month)->first()?->users ?? [];
107
108            $coachLevels = CoachLevelHelper::categorizeCharacterUsage($characterUsage, count($user_ids));
109
110            $data[$month_year] = [
111                'Month' => $month_year,
112                'Purchased Licenses' => $purchased_licenses,
113                'Assigned Licenses' => $assigned_licenses,
114                'Activate Licenses' => $activate_licenses,
115                'Extension Installed' => $extension_installed,
116
117                'ROI Spotlight' => $roi_spotlight,
118                'Productivity Spotlight' => $productivity_spotlight,
119                'Total Characters Typed' => $total_characters_typed,
120
121                'Coach Level Beginner' => $coachLevels->beginner,
122                'Coach Level Intermediate' => $coachLevels->intermediate,
123                'Coach Level Proficient' => $coachLevels->proficient,
124                'Coach Level Advanced' => $coachLevels->advanced,
125                'Coach Level Expert' => $coachLevels->expert,
126            ];
127        }
128
129        return $data;
130    }
131
132    public function headings(): array
133    {
134        return [
135            'Months',
136            'Purchased Licenses',
137            'Assigned Licenses',
138            'Activate Licenses',
139            'Extension Installed',
140            'ROI Spotlight',
141            'Productivity Spotlight',
142            'Total Characters Typed',
143            'Coach Level Beginner',
144            'Coach Level Intermediate',
145            'Coach Level Proficient',
146            'Coach Level Advanced',
147            'Coach Level Expert',
148        ];
149    }
150
151    private function getCompanyOverview(string $companyId, string $startDate, string $endDate)
152    {
153        $companyId = new ObjectId($companyId);
154        $startDate = new UTCDateTime(strtotime($startDate) * 1000);
155        $endDate = new UTCDateTime(strtotime($endDate) * 1000);
156
157        $aggregation = [
158            [
159                '$match' => [
160                    '_id' => $companyId,
161                ],
162            ],
163            [
164                '$lookup' => [
165                    'from' => 'company_licenses',
166                    'let' => ['companyId' => ['$toString' => '$_id']],
167                    'pipeline' => [
168                        [
169                            '$match' => [
170                                '$expr' => ['$and' => [
171                                    ['$eq' => ['$company_id', '$$companyId']],
172                                ]],
173                            ],
174                        ],
175                        [
176                            '$project' => [
177                                'purchased_licenses' => [
178                                    '$add' => [
179                                        '$total_sales_pro_teams_license_count',
180                                        '$total_sales_pro_license_count',
181                                        '$total_growth_license_count',
182                                        '$total_starter_license_count',
183                                    ],
184                                ],
185                            ],
186                        ],
187                    ],
188                    'as' => 'licenses_data',
189                ],
190            ],
191            [
192                '$unwind' => [
193                    'path' => '$licenses_data',
194                    'preserveNullAndEmptyArrays' => true,
195                ],
196            ],
197            [
198                '$lookup' => [
199                    'from' => 'users',
200                    'let' => ['companyId' => ['$toString' => '$_id']],
201                    'pipeline' => [
202                        [
203                            '$match' => [
204                                '$expr' => ['$eq' => ['$company_id', '$$companyId']],
205                            ],
206                        ],
207                        [
208                            '$lookup' => [
209                                'from' => 'flycut_usage',
210                                'let' => ['userId' => ['$toString' => '$_id']],
211                                'pipeline' => [
212                                    [
213                                        '$match' => [
214                                            '$expr' => [
215                                                '$and' => [
216                                                    ['$eq' => ['$user_id', '$$userId']],
217                                                    ['$gte' => ['$created_at', $startDate]],
218                                                    ['$lte' => ['$created_at', $endDate]],
219                                                ],
220                                            ],
221                                        ],
222                                    ],
223                                    [
224                                        '$group' => [
225                                            '_id' => [
226                                                'month_year' => [
227                                                    '$dateToString' => [
228                                                        'format' => '%Y-%m',
229                                                        'date' => '$created_at',
230                                                    ],
231                                                ],
232                                            ],
233                                            'characters_typed_by_flymsg' => ['$sum' => '$characters_typed'],
234                                            'time_saved_by_flymsg' => ['$sum' => '$time_saved'],
235                                            'cost_saved_by_flymsg' => ['$sum' => '$cost_saved'],
236                                        ],
237                                    ],
238                                    [
239                                        '$sort' => ['_id.month_year' => 1],
240                                    ],
241                                ],
242                                'as' => 'monthly_usage_data',
243                            ],
244                        ],
245                        [
246                            '$unwind' => [
247                                'path' => '$monthly_usage_data',
248                                'preserveNullAndEmptyArrays' => false,
249                            ],
250                        ],
251                        [
252                            '$group' => [
253                                '_id' => '$monthly_usage_data._id.month_year',
254                                'characters_typed_by_flymsg' => ['$sum' => '$monthly_usage_data.characters_typed_by_flymsg'],
255                                'time_saved_by_flymsg' => ['$sum' => '$monthly_usage_data.time_saved_by_flymsg'],
256                                'cost_saved_by_flymsg' => ['$sum' => '$monthly_usage_data.cost_saved_by_flymsg'],
257                            ],
258                        ],
259                        [
260                            '$sort' => ['_id' => 1],
261                        ],
262                        [
263                            '$group' => [
264                                '_id' => null,
265                                'flycut_usage_aggregated' => [
266                                    '$push' => [
267                                        'month_year' => '$_id',
268                                        'characters_typed_by_flymsg' => '$characters_typed_by_flymsg',
269                                        'time_saved_by_flymsg' => '$time_saved_by_flymsg',
270                                        'cost_saved_by_flymsg' => '$cost_saved_by_flymsg',
271                                    ],
272                                ],
273                            ],
274                        ],
275                    ],
276                    'as' => 'flycut_data',
277                ],
278            ],
279            [
280                '$unwind' => [
281                    'path' => '$flycut_data',
282                    'preserveNullAndEmptyArrays' => true,
283                ],
284            ],
285            [
286                '$lookup' => [
287                    'from' => 'users',
288                    'let' => ['companyId' => ['$toString' => '$_id']],
289                    'pipeline' => [
290                        [
291                            '$match' => [
292                                '$expr' => ['$and' => [
293                                    ['$eq' => ['$company_id', '$$companyId']],
294                                ]],
295                            ],
296                        ],
297                        [
298                            '$lookup' => [
299                                'from' => 'subscriptions',
300                                'let' => ['userId' => ['$toString' => '$_id'], 'userStatus' => '$status'],
301                                'pipeline' => [
302                                    [
303                                        '$match' => [
304                                            '$expr' => [
305                                                '$and' => [
306                                                    ['$eq' => ['$user_id', '$$userId']],
307                                                    ['$eq' => ['$name', 'main']],
308                                                    ['$eq' => ['$stripe_status', 'active']],
309                                                    ['$eq' => ['$$userStatus', 'Active']],
310                                                ],
311                                            ],
312                                        ],
313                                    ],
314                                    [
315                                        '$sort' => ['created_at' => -1],
316                                    ],
317                                    [
318                                        '$limit' => 1,
319                                    ],
320                                ],
321                                'as' => 'active_users_subscriptions_data',
322                            ],
323                        ],
324                        [
325                            '$lookup' => [
326                                'from' => 'subscriptions',
327                                'let' => ['userId' => ['$toString' => '$_id'], 'userStatus' => '$status'],
328                                'pipeline' => [
329                                    [
330                                        '$match' => [
331                                            '$expr' => [
332                                                '$and' => [
333                                                    ['$eq' => ['$user_id', '$$userId']],
334                                                    ['$eq' => ['$name', 'main']],
335                                                    ['$eq' => ['$stripe_status', 'active']],
336                                                    ['$eq' => ['$$userStatus', 'Invited']],
337                                                ],
338                                            ],
339                                        ],
340                                    ],
341                                    [
342                                        '$sort' => ['created_at' => -1],
343                                    ],
344                                    [
345                                        '$limit' => 1,
346                                    ],
347                                ],
348                                'as' => 'invited_users_subscriptions_data',
349                            ],
350                        ],
351                        [
352                            '$addFields' => [
353                                'active_subscription_count' => ['$size' => '$active_users_subscriptions_data'],
354                                'invited_subscription_count' => ['$size' => '$invited_users_subscriptions_data'],
355                            ],
356                        ],
357                        [
358                            '$group' => [
359                                '_id' => null,
360                                'total_active_subscriptions' => ['$sum' => '$active_subscription_count'],
361                                'total_invited_subscriptions' => ['$sum' => '$invited_subscription_count'],
362                            ],
363                        ],
364                        [
365                            '$project' => [
366                                '_id' => 0,
367                                'total_active_subscriptions' => 1,
368                                'total_invited_subscriptions' => 1,
369                            ],
370                        ],
371                    ],
372                    'as' => 'sub_data',
373                ],
374            ],
375            [
376                '$unwind' => [
377                    'path' => '$sub_data',
378                    'preserveNullAndEmptyArrays' => true,
379                ],
380            ],
381            [
382                '$lookup' => [
383                    'from' => 'users',
384                    'let' => ['companyId' => ['$toString' => '$_id']],
385                    'pipeline' => [
386                        [
387                            '$match' => [
388                                '$expr' => ['$and' => [
389                                    ['$eq' => ['$company_id', '$$companyId']],
390                                ]],
391                            ],
392                        ],
393                        [
394                            '$lookup' => [
395                                'from' => 'hubspot_properties',
396                                'let' => ['userId' => ['$toString' => '$_id']],
397                                'pipeline' => [
398                                    [
399                                        '$match' => [
400                                            '$expr' => [
401                                                '$and' => [
402                                                    ['$eq' => ['$flymsg_id', '$$userId']],
403                                                    [
404                                                        '$or' => [
405                                                            [
406                                                                '$and' => [
407                                                                    ['$eq' => ['$flymsg_chrome_extension_installed', 'Yes']],
408                                                                    ['$eq' => ['$flymsg_chrome_extension_uninstalled', 'No']],
409                                                                ],
410                                                            ],
411                                                            [
412                                                                '$and' => [
413                                                                    ['$eq' => ['$flymsg_edge_extension_installed', 'Yes']],
414                                                                    ['$eq' => ['$flymsg_edge_extension_uninstalled', 'No']],
415                                                                ],
416                                                            ],
417                                                        ],
418                                                    ],
419                                                ],
420                                            ],
421                                        ],
422                                    ],
423                                    [
424                                        '$sort' => ['created_at' => -1],
425                                    ],
426                                    [
427                                        '$limit' => 1,
428                                    ],
429                                ],
430                                'as' => 'hubspot_data',
431                            ],
432                        ],
433                        [
434                            '$unwind' => [
435                                'path' => '$hubspot_data',
436                                'preserveNullAndEmptyArrays' => true,
437                            ],
438                        ],
439                        [
440                            '$group' => [
441                                '_id' => null,
442                                'total_extension_installed' => ['$sum' => ['$cond' => [['$ifNull' => ['$hubspot_data', false]], 1, 0]]],
443                            ],
444                        ],
445                    ],
446                    'as' => 'hp_data',
447                ],
448            ],
449            [
450                '$unwind' => [
451                    'path' => '$hp_data',
452                    'preserveNullAndEmptyArrays' => true,
453                ],
454            ],
455            [
456                '$project' => [
457                    'company_id' => '$_id',
458                    'purchased_licenses' => '$licenses_data.purchased_licenses',
459                    'total_active_licenses' => '$sub_data.total_active_subscriptions',
460                    'total_invited_licenses' => '$sub_data.total_invited_subscriptions',
461                    'total_extension_installed' => '$hp_data.total_extension_installed',
462                    'flycut_usage_aggregated' => '$flycut_data.flycut_usage_aggregated',
463                ],
464            ],
465        ];
466
467        return Company::withoutGlobalScopes()->raw(function ($collection) use ($aggregation) {
468            return $collection->aggregate($aggregation);
469        });
470    }
471
472    private function getFlyCutUsageByUser($userIds, $startDate, $endDate)
473    {
474        $aggregation = [
475            [
476                '$match' => [
477                    '_id' => ['$in' => array_map(function ($userId) {
478                        return new \MongoDB\BSON\ObjectId($userId);
479                    }, $userIds)],
480                ],
481            ],
482            [
483                '$lookup' => [
484                    'from' => 'flycut_usage',
485                    'let' => ['userId' => ['$toString' => '$_id']],
486                    'pipeline' => [
487                        [
488                            '$match' => [
489                                '$expr' => [
490                                    '$and' => [
491                                        ['$eq' => ['$user_id', '$$userId']],
492                                        ['$gte' => ['$created_at', $startDate]],
493                                        ['$lte' => ['$created_at', $endDate]],
494                                    ],
495                                ],
496                            ],
497                        ],
498                        [
499                            '$group' => [
500                                '_id' => [
501                                    'user_id' => '$user_id',
502                                    'month_year' => [
503                                        '$dateToString' => [
504                                            'format' => '%Y-%m',
505                                            'date' => '$created_at',
506                                        ],
507                                    ],
508                                ],
509                                'characters_typed' => ['$sum' => '$characters_typed'],
510                                'characters_saved' => ['$sum' => '$characters_saved'],
511                                'time_saved' => ['$sum' => '$time_saved'],
512                                'cost_saved' => ['$sum' => '$cost_saved'],
513                                'flycuts_used' => ['$sum' => 1],
514                            ],
515                        ],
516                        [
517                            '$sort' => ['_id.month_year' => 1],
518                        ],
519                    ],
520                    'as' => 'usage_data',
521                ],
522            ],
523            [
524                '$unwind' => [
525                    'path' => '$usage_data',
526                    'preserveNullAndEmptyArrays' => false,
527                ],
528            ],
529            [
530                '$group' => [
531                    '_id' => '$usage_data._id.month_year',
532                    'users' => [
533                        '$push' => [
534                            'user_id' => '$_id',
535                            'characters_typed' => '$usage_data.characters_typed',
536                            'characters_saved' => '$usage_data.characters_saved',
537                            'time_saved' => '$usage_data.time_saved',
538                            'cost_saved' => '$usage_data.cost_saved',
539                            'flycuts_used' => '$usage_data.flycuts_used',
540                        ],
541                    ],
542                ],
543            ],
544            [
545                '$sort' => ['_id' => 1],
546            ],
547        ];
548
549        return User::raw(function ($collection) use ($aggregation) {
550            return $collection->aggregate($aggregation);
551        });
552    }
553}