Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 232
0.00% covered (danger)
0.00%
0 / 9
CRAP
0.00% covered (danger)
0.00%
0 / 1
ChartTrait
0.00% covered (danger)
0.00%
0 / 232
0.00% covered (danger)
0.00%
0 / 9
132
0.00% covered (danger)
0.00%
0 / 1
 getTotalCharactersByUsersInPeriod
0.00% covered (danger)
0.00%
0 / 64
0.00% covered (danger)
0.00%
0 / 1
12
 getTotalCharactersAndShortcutsByUsersInPeriod
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
2
 matchUsersByIds
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
2
 lookupUsageData
0.00% covered (danger)
0.00%
0 / 47
0.00% covered (danger)
0.00%
0 / 1
2
 lookupShortcutData
0.00% covered (danger)
0.00%
0 / 25
0.00% covered (danger)
0.00%
0 / 1
2
 lookupHubspotData
0.00% covered (danger)
0.00%
0 / 23
0.00% covered (danger)
0.00%
0 / 1
2
 unwindData
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 groupUserData
0.00% covered (danger)
0.00%
0 / 40
0.00% covered (danger)
0.00%
0 / 1
2
 parseSubscriptionPlanName
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace App\Traits\AccountCenter\Reporting;
4
5use App\Http\Models\Auth\User;
6
7trait ChartTrait
8{
9    public function getTotalCharactersByUsersInPeriod(array $userIds, $startDate, $endDate)
10    {
11        $matchExpression = [
12            ['$eq' => ['$user_id', '$$userId']],
13        ];
14
15        if ($startDate) {
16            $matchExpression[] = ['$gte' => ['$created_at', $startDate]];
17        }
18
19        if ($endDate) {
20            $matchExpression[] = ['$lte' => ['$created_at', $endDate]];
21        }
22
23        $pipeline = [
24            [
25                '$match' => [
26                    '_id' => [
27                        '$in' => array_map(function ($userId) {
28                            return new \MongoDB\BSON\ObjectId($userId);
29                        }, $userIds),
30                    ],
31                ],
32            ],
33            [
34                '$lookup' => [
35                    'from' => 'fly_msg_user_daily_usage',
36                    'let' => ['userId' => ['$toString' => '$_id']],
37                    'pipeline' => [
38                        [
39                            '$match' => [
40                                '$expr' => [
41                                    '$and' => $matchExpression,
42                                ],
43                            ],
44                        ],
45                        [
46                            '$group' => [
47                                '_id' => null,
48                                'characters_typed' => ['$sum' => '$characters_typed'],
49                                'characters_saved' => ['$sum' => '$characters_typed'],
50                                'time_saved' => ['$sum' => '$time_saved'],
51                                'cost_saved' => ['$sum' => '$cost_savings'],
52                                'flycuts_used' => ['$sum' => '$flycut_count'],
53                            ],
54                        ],
55                    ],
56                    'as' => 'usage_data',
57                ],
58            ],
59            [
60                '$unwind' => [
61                    'path' => '$usage_data',
62                    'preserveNullAndEmptyArrays' => true,
63                ],
64            ],
65            [
66                '$project' => [
67                    'user_id' => 1,
68                    'name' => ['$concat' => ['$first_name', ' ', '$last_name']],
69                    'characters_typed' => ['$ifNull' => ['$usage_data.characters_typed', 0]],
70                    'characters_saved' => ['$ifNull' => ['$usage_data.characters_saved', 0]],
71                    'time_saved' => ['$ifNull' => ['$usage_data.time_saved', 0]],
72                    'cost_saved' => ['$ifNull' => ['$usage_data.cost_saved', 0]],
73                    'flycuts_used' => ['$ifNull' => ['$usage_data.flycuts_used', 0]],
74                ],
75            ],
76        ];
77
78        return User::withoutGlobalScopes()->raw(function ($collection) use ($pipeline) {
79            return $collection->aggregate($pipeline);
80        });
81    }
82
83    public function getTotalCharactersAndShortcutsByUsersInPeriod(array $userIds, $startDate, $endDate)
84    {
85        $pipeline = [
86            $this->matchUsersByIds($userIds),
87            $this->lookupUsageData($startDate, $endDate),
88            $this->lookupShortcutData(),
89            $this->lookupHubspotData(),
90            $this->unwindData('usage_data'),
91            $this->unwindData('shortcut_data'),
92            $this->unwindData('hubspot_data'),
93            $this->groupUserData(),
94        ];
95
96        return User::withoutGlobalScopes()->raw(function ($collection) use ($pipeline) {
97            return $collection->aggregate($pipeline);
98        });
99    }
100
101    private function matchUsersByIds(array $userIds)
102    {
103        return [
104            '$match' => [
105                '_id' => [
106                    '$in' => array_map(function ($userId) {
107                        return new \MongoDB\BSON\ObjectId($userId);
108                    }, $userIds),
109                ],
110            ],
111        ];
112    }
113
114    private function lookupUsageData($startDate, $endDate)
115    {
116        return [
117            '$lookup' => [
118                'from' => 'flycut_usage',
119                'let' => ['userId' => ['$toString' => '$_id']],
120                'pipeline' => [
121                    [
122                        '$match' => [
123                            '$expr' => [
124                                '$and' => [
125                                    ['$eq' => ['$user_id', '$$userId']],
126                                    ['$gte' => ['$created_at', $startDate]],
127                                    ['$lte' => ['$created_at', $endDate]],
128                                ],
129                            ],
130                        ],
131                    ],
132                    [
133                        '$group' => [
134                            '_id' => [
135                                'month_year' => ['$dateToString' => ['format' => '%Y-%m', 'date' => '$created_at']],
136                            ],
137                            'total_flyengage_used_count' => [
138                                '$sum' => ['$cond' => [['$eq' => ['$feature', 'flyengage']], 1, 0]],
139                            ],
140                            'total_sentence_rewrite_used_count' => [
141                                '$sum' => ['$cond' => [['$eq' => ['$feature', 'sentence_rewrite']], 1, 0]],
142                            ],
143                            'total_paragraph_rewrite_used_count' => [
144                                '$sum' => ['$cond' => [['$eq' => ['$feature', 'paragraph_rewrite']], 1, 0]],
145                            ],
146                            'total_flyposts_used_count' => [
147                                '$sum' => ['$cond' => [['$eq' => ['$feature', 'flypost']], 1, 0]],
148                            ],
149                            'total_characters_typed' => ['$sum' => '$characters_typed'],
150                            'total_time_saved' => ['$sum' => '$time_saved'],
151                            'total_cost_saved' => ['$sum' => '$cost_saved'],
152                        ],
153                    ],
154                    [
155                        '$sort' => [
156                            '_id.month_year' => 1,
157                        ],
158                    ],
159                ],
160                'as' => 'usage_data',
161            ],
162        ];
163    }
164
165    private function lookupShortcutData()
166    {
167        return [
168            '$lookup' => [
169                'from' => 'shortcuts',
170                'let' => ['userId' => ['$toString' => '$_id']],
171                'pipeline' => [
172                    [
173                        '$match' => [
174                            '$expr' => ['$eq' => ['$user_id', '$$userId']],
175                        ],
176                    ],
177                    [
178                        '$group' => [
179                            '_id' => null,
180                            'flycuts_created' => [
181                                '$sum' => ['$cond' => [['$eq' => ['$user_defined', true]], 1, 0]],
182                            ],
183                            'flyplates_added_to_flycuts' => [
184                                '$sum' => ['$cond' => [['$eq' => ['$user_defined', false]], 1, 0]],
185                            ],
186                        ],
187                    ],
188                ],
189                'as' => 'shortcut_data',
190            ],
191        ];
192    }
193
194    private function lookupHubspotData()
195    {
196        return [
197            '$lookup' => [
198                'from' => 'hubspot_properties',
199                'let' => ['flymsgId' => ['$toString' => '$_id']],
200                'pipeline' => [
201                    [
202                        '$match' => [
203                            '$expr' => ['$eq' => ['$flymsg_id', '$$flymsgId']],
204                        ],
205                    ],
206                    [
207                        '$project' => [
208                            'account_creation_date' => 1,
209                            'subscription_type' => 1,
210                            'flymsg_chrome_extension_installed' => 1,
211                            'flymsg_edge_extension_installed' => 1,
212                            'last_login' => 1,
213                        ],
214                    ],
215                ],
216                'as' => 'hubspot_data',
217            ],
218        ];
219    }
220
221    private function unwindData($field)
222    {
223        return ['$unwind' => ['path' => '$'.$field, 'preserveNullAndEmptyArrays' => true]];
224    }
225
226    private function groupUserData()
227    {
228        return [
229            '$group' => [
230                '_id' => '$_id',
231                'first_name' => ['$first' => '$first_name'],
232                'last_name' => ['$first' => '$last_name'],
233                'email' => ['$first' => '$email'],
234                'total_sentence_rewrite_used_count' => ['$first' => '$usage_data.total_sentence_rewrite_used_count'],
235                'total_paragraph_rewrite_used_count' => ['$first' => '$usage_data.total_paragraph_rewrite_used_count'],
236                'total_flyengage_used_count' => ['$first' => '$usage_data.total_flyengage_used_count'],
237                'total_flyposts_used_count' => ['$first' => '$usage_data.total_flyposts_used_count'],
238                'total_characters_typed_per_month' => [
239                    '$push' => [
240                        'month_year' => '$usage_data._id.month_year',
241                        'total' => '$usage_data.total_characters_typed',
242                    ],
243                ],
244                'total_time_saved_per_month' => [
245                    '$push' => [
246                        'month_year' => '$usage_data._id.month_year',
247                        'total' => '$usage_data.total_time_saved',
248                    ],
249                ],
250                'total_cost_saved_per_month' => [
251                    '$push' => [
252                        'month_year' => '$usage_data._id.month_year',
253                        'total' => '$usage_data.total_cost_saved',
254                    ],
255                ],
256                'total_characters_typed_overall' => ['$sum' => '$usage_data.total_characters_typed'],
257                'total_time_saved_overall' => ['$sum' => '$usage_data.total_time_saved'],
258                'total_cost_saved_overall' => ['$sum' => '$usage_data.total_cost_saved'],
259                'flycuts_created' => ['$first' => '$shortcut_data.flycuts_created'],
260                'flyplates_added_to_flycuts' => ['$first' => '$shortcut_data.flyplates_added_to_flycuts'],
261                'license_type' => ['$first' => '$hubspot_data.subscription_type'],
262                'account_creation_date' => ['$first' => '$hubspot_data.account_creation_date'],
263                'flymsg_chrome_extension_installed' => ['$first' => '$hubspot_data.flymsg_chrome_extension_installed'],
264                'flymsg_edge_extension_installed' => ['$first' => '$hubspot_data.flymsg_edge_extension_installed'],
265                'last_login' => ['$first' => '$hubspot_data.last_login'],
266            ],
267        ];
268    }
269
270    private function parseSubscriptionPlanName($identifier)
271    {
272        $result = match ($identifier) {
273            'starter', 'starter-yearly' => 'Starter',
274            'growth', 'growth-yearly', 'appsumo-growth-lifetime', 'dealfuel-growth-lifetime' => 'Growth',
275            'sales-pro-yearly', 'sales-pro-monthly' => 'Sales Pro',
276            'pro-plan-teams-smb' => 'Sales Pro Teams',
277            'pro-plan-teams-ent' => 'Sales Pro Teams - ENT',
278            'freemium' => 'Freemium',
279            default => 'Not Assigned',
280        };
281
282        return trim($result);
283    }
284}