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