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