Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.14% covered (danger)
0.14%
1 / 707
14.29% covered (danger)
14.29%
1 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
FlyMsgUserDailyUsageService
0.14% covered (danger)
0.14%
1 / 707
14.29% covered (danger)
14.29%
1 / 7
2246.64
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 refresh
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 processUserSummaryUsage2
0.00% covered (danger)
0.00%
0 / 138
0.00% covered (danger)
0.00%
0 / 1
56
 processUserSummaryUsage
0.00% covered (danger)
0.00%
0 / 210
0.00% covered (danger)
0.00%
0 / 1
30
 processUserUsage
0.00% covered (danger)
0.00%
0 / 270
0.00% covered (danger)
0.00%
0 / 1
552
 parseMonth
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
2
 getHubspotUsage
0.00% covered (danger)
0.00%
0 / 72
0.00% covered (danger)
0.00%
0 / 1
90
1<?php
2
3namespace App\Services\UserInfo;
4
5use App\Http\Models\Admin\CompanyGroup;
6use App\Http\Models\FlyGrammarActions;
7use App\Http\Models\FlyMsgUserDailyUsage;
8use App\Http\Models\Auth\User;
9use App\Http\Models\UserInfo;
10use App\Http\Services\StatisticsService;
11use App\Traits\UsageTrait;
12use Illuminate\Support\Carbon;
13use App\Http\Models\FlyCutUsage;
14use App\Http\Models\HubspotProperties;
15use App\Http\Models\Shortcut;
16use MongoDB\BSON\UTCDateTime;
17
18class FlyMsgUserDailyUsageService
19{
20    use UsageTrait;
21
22    function __construct(
23        private StatisticsService $statisticsService
24    ) {}
25
26    public function refresh(FlyMsgUserDailyUsage $usage): void
27    {
28        $user = User::find($usage->user_id);
29
30        $this->processUserSummaryUsage($user);
31    }
32
33    public function processUserSummaryUsage2(User $user)
34    {
35        $userInfo = UserInfo::where('email', $user->email)->first();
36
37        $startDate = $user->created_at;
38
39        if ($startDate->lessThan(Carbon::parse('2022-01-01 00:00:00'))) {
40            $startDate = Carbon::parse('2022-01-01 00:00:00');
41        }
42
43        $endDate = now()->endOfDay();;
44
45        $sentence_rewrite_summarized = [];
46        $paragraph_rewrite_summarized = [];
47        $fly_engage_summarized = [];
48        $fly_post_summarized = [];
49        $fly_cut_summarized = [];
50        $time_saved_summarized = [];
51        $cost_savings_summarized = [];
52        $characters_typed_summarized = [];
53        while ($startDate->lessThanOrEqualTo($endDate)) {
54            $year = $startDate->year;
55            $month = $this->parseMonth($startDate->month);
56
57            $totalTimeSavedThisMonth = FlyMsgUserDailyUsage::where('user_id', $userInfo->user_id)->where('year', $year)->where('month', $startDate->month)->sum('time_saved');
58            $totalCostSavingsThisMonth = FlyMsgUserDailyUsage::where('user_id', $userInfo->user_id)->where('year', $year)->where('month', $startDate->month)->sum('cost_savings');
59            $totalCharactersTypedThisMonth = FlyMsgUserDailyUsage::where('user_id', $userInfo->user_id)->where('year', $year)->where('month', $startDate->month)->sum('characters_typed');
60
61            $userInfo->{"total_time_saved___{$month}_{$year}"} = $totalTimeSavedThisMonth;
62            $userInfo->{"total_cost_savings___{$month}_{$year}"} = $totalCostSavingsThisMonth;
63            $userInfo->{"of_characters_typed___{$month}_{$year}"} = $totalCharactersTypedThisMonth;
64
65            $formattedDate = $startDate->format('M Y');
66
67            if ($year >= 2023) {
68                $totalFlyPostUsedThisMonth = FlyMsgUserDailyUsage::where('user_id', $userInfo->user_id)->where('year', $year)->where('month', $startDate->month)->sum('flypost_count');
69                $totalFlyEngageUsedThisMonth = FlyMsgUserDailyUsage::where('user_id', $userInfo->user_id)->where('year', $year)->where('month', $startDate->month)->sum('flyengage_count');
70                $totalSentenceRewriteUsedThisMonth = FlyMsgUserDailyUsage::where('user_id', $userInfo->user_id)->where('year', $year)->where('month', $startDate->month)->sum('sentence_rewrite_count');
71                $totalParagraphRewriteUsedThisMonth = FlyMsgUserDailyUsage::where('user_id', $userInfo->user_id)->where('year', $year)->where('month', $startDate->month)->sum('paragraph_rewrite_count');
72                $totalFlyCutUsedThisMonth = FlyMsgUserDailyUsage::where('user_id', $userInfo->user_id)->where('year', $year)->where('month', $startDate->month)->sum('flycut_count');
73                $totalFlyGrammarActionsThisMonth = FlyMsgUserDailyUsage::where('user_id', $userInfo->user_id)->where('year', $year)->where('month', $startDate->month)->sum('fly_grammar_actions');
74
75                $sentence_rewrite_summarized[] = [
76                    'date' => $startDate->timestamp,
77                    'month' => $formattedDate,
78                    'total' => $totalSentenceRewriteUsedThisMonth
79                ];
80
81                $paragraph_rewrite_summarized[] = [
82                    'date' => $startDate->timestamp,
83                    'month' => $formattedDate,
84                    'total' => $totalParagraphRewriteUsedThisMonth
85                ];
86
87                $fly_engage_summarized[] = [
88                    'date' => $startDate->timestamp,
89                    'month' => $formattedDate,
90                    'total' => $totalFlyEngageUsedThisMonth
91                ];
92
93                $fly_post_summarized[] = [
94                    'date' => $startDate->timestamp,
95                    'month' => $formattedDate,
96                    'total' => $totalFlyPostUsedThisMonth
97                ];
98
99                $fly_cut_summarized[] = [
100                    'date' => $startDate->timestamp,
101                    'month' => $formattedDate,
102                    'total' => $totalFlyCutUsedThisMonth
103                ];
104
105                $fly_grammar_actions_summarized[] = [
106                    'date' => $startDate->timestamp,
107                    'month' => $formattedDate,
108                    'total' => $totalFlyGrammarActionsThisMonth
109                ];
110            }
111
112            $time_saved_summarized[] = [
113                'date' => $startDate->timestamp,
114                'month' => $formattedDate,
115                'total' => $totalTimeSavedThisMonth
116            ];
117
118            $cost_savings_summarized[] = [
119                'date' => $startDate->timestamp,
120                'month' => $formattedDate,
121                'total' => $totalCostSavingsThisMonth
122            ];
123
124            $characters_typed_summarized[] = [
125                'date' => $startDate->timestamp,
126                'month' => $formattedDate,
127                'total' => $totalCharactersTypedThisMonth
128            ];
129
130            $startDate->addMonth();
131            // if same month as endDate
132            if ($startDate->month == $endDate->month && $startDate->year == $endDate->year && $startDate->greaterThan($endDate)) {
133                $startDate = $endDate->copy();
134            }
135        }
136
137        $time_saved_summarized = collect($time_saved_summarized)->sortByDesc('date')->values();
138        $time_saved_summarized = $time_saved_summarized->map(function ($item) {
139            return $item['total'] . ' - ' . $item['month'];
140        });
141
142        $cost_savings_summarized = collect($cost_savings_summarized)->sortByDesc('date')->values();
143        $cost_savings_summarized = $cost_savings_summarized->map(function ($item) {
144            return $item['total'] . ' - ' . $item['month'];
145        });
146
147        $characters_typed_summarized = collect($characters_typed_summarized)->sortByDesc('date')->values();
148        $characters_typed_summarized = $characters_typed_summarized->map(function ($item) {
149            return $item['total'] . ' - ' . $item['month'];
150        });
151
152        $fly_cut_summarized = collect($fly_cut_summarized)->sortByDesc('date')->values();
153        $fly_cut_summarized = $fly_cut_summarized->map(function ($item) {
154            return $item['total'] . ' - ' . $item['month'];
155        });
156
157        $fly_engage_summarized = collect($fly_engage_summarized)->sortByDesc('date')->values();
158        $fly_engage_summarized = $fly_engage_summarized->map(function ($item) {
159            return $item['total'] . ' - ' . $item['month'];
160        });
161
162        $sentence_rewrite_summarized = collect($sentence_rewrite_summarized)->sortByDesc('date')->values();
163        $sentence_rewrite_summarized = $sentence_rewrite_summarized->map(function ($item) {
164            return $item['total'] . ' - ' . $item['month'];
165        });
166        $paragraph_rewrite_summarized = collect($paragraph_rewrite_summarized)->sortByDesc('date')->values();
167        $paragraph_rewrite_summarized = $paragraph_rewrite_summarized->map(function ($item) {
168            return $item['total'] . ' - ' . $item['month'];
169        });
170
171        $fly_post_summarized = collect($fly_post_summarized)->sortByDesc('date')->values();
172        $fly_post_summarized = $fly_post_summarized->map(function ($item) {
173            return $item['total'] . ' - ' . $item['month'];
174        });
175
176        $fly_grammar_actions_summarized = collect($fly_grammar_actions_summarized)->sortByDesc('date')->values();
177        $fly_grammar_actions_summarized = $fly_grammar_actions_summarized->map(function ($item) {
178            return $item['total'] . ' - ' . $item['month'];
179        });
180
181        $userInfo->total_time_saved_summarized_monthly_by_flymsg_by_user = $time_saved_summarized->implode('.   ');
182        $userInfo->total_cost_savings_summarized_monthly_by_flymsg_by_user = $cost_savings_summarized->implode('.   ');
183        $userInfo->total___of_characters_typed_monthly_by_flymsg_by_user = $characters_typed_summarized->implode('.   ');
184        $userInfo->total___of_times_flycut_is_used_summarized_monthly_by_user__count_ = $fly_cut_summarized->implode('.   ');
185        $userInfo->total___of_times_sentence_rewrite_is_used_summarized_monthly_by_user = $sentence_rewrite_summarized->implode('.   ');
186        $userInfo->total___of_times_paragraph_rewrite_is_used_summarized_monthly_by_user = $paragraph_rewrite_summarized->implode('.   ');
187        $userInfo->total___of_times_flyengage_is_used_summarized_monthly_by_user = $fly_engage_summarized->implode('.   ');
188        $userInfo->total___of_times_flyposts_is_used_summarized_monthly_by_user__count_ = $fly_post_summarized->implode('.   ');
189        $userInfo->total___of_times_flygrammar_is_used_summarized_monthly_by_user__count_ = $fly_grammar_actions_summarized->implode('.   ');
190
191        $userInfo->total___of_times_sentence_rewrite_used__count_ = FlyMsgUserDailyUsage::where('user_id', $userInfo->user_id)->sum('sentence_rewrite_count');
192        $userInfo->total___of_times_paragraph_rewrite_used__count_ = FlyMsgUserDailyUsage::where('user_id', $userInfo->user_id)->sum('paragraph_rewrite_count');
193        $userInfo->total___of_times_flyengage_used__count_ = FlyMsgUserDailyUsage::where('user_id', $userInfo->user_id)->sum('flyengage_count');
194        $userInfo->total___of_times_flyposts_used__count_ = FlyMsgUserDailyUsage::where('user_id', $userInfo->user_id)->sum('flypost_count');
195        $userInfo->total___of_times_flycut_used__count_ = FlyMsgUserDailyUsage::where('user_id', $userInfo->user_id)->sum('flycut_count');
196        $userInfo->total___of_times_flygrammar_used__count_ = FlyMsgUserDailyUsage::where('user_id', $userInfo->user_id)->sum('fly_grammar_actions');
197        $userInfo->total___of_times_flygrammar_accepted_used__count_ = FlyMsgUserDailyUsage::where('user_id', $userInfo->user_id)->sum('fly_grammar_accepted');
198        $userInfo->total___of_times_flygrammar_autocorrect_used__count_ = FlyMsgUserDailyUsage::where('user_id', $userInfo->user_id)->sum('fly_grammar_autocorrect');
199        $userInfo->total___of_times_flygrammar_autocomplete_used__count_ = FlyMsgUserDailyUsage::where('user_id', $userInfo->user_id)->sum('fly_grammar_autocomplete');
200
201        $userInfo->total_time_saved_by_flymsg_by_user = FlyMsgUserDailyUsage::where('user_id', $userInfo->user_id)->sum('time_saved');
202        $userInfo->total_cost_savings_by_flymsg_by_user = FlyMsgUserDailyUsage::where('user_id', $userInfo->user_id)->sum('cost_savings');
203        $userInfo->total___of_characters_typed_by_flymsg_by_user = FlyMsgUserDailyUsage::where('user_id', $userInfo->user_id)->sum('characters_typed');
204        $userInfo->number_of_flycuts_created_count = FlyMsgUserDailyUsage::where('user_id', $userInfo->user_id)->sum('flycuts_created');
205        $userInfo->number_of_flyplates_in_flycuts_count = FlyMsgUserDailyUsage::where('user_id', $userInfo->user_id)->sum('flyplates_added');
206
207        $userInfo->save();
208    }
209
210    public function processUserSummaryUsage(User $user)
211    {
212        $userInfo = UserInfo::where('email', $user->email)->first();
213        $startDate = $user->created_at->copy();
214
215        if ($startDate->lessThan(Carbon::parse('2022-01-01 00:00:00'))) {
216            $startDate = Carbon::parse('2022-01-01 00:00:00');
217        }
218
219        $endDate = now()->endOfDay();
220        $user_id = $userInfo->user_id;
221
222        // 1. Consulta agregada mensal com todos os campos relevantes
223        $monthly = FlyMsgUserDailyUsage::raw(function ($collection) use ($user_id, $startDate, $endDate) {
224            return $collection->aggregate([
225                [
226                    '$match' => [
227                        'user_id' => $user_id,
228                        'created_at' => [
229                            '$gte' => new UTCDateTime($startDate->startOfMonth()->timestamp * 1000),
230                            '$lte' => new UTCDateTime($endDate->endOfMonth()->timestamp * 1000),
231                        ],
232                    ],
233                ],
234                [
235                    '$group' => [
236                        '_id' => [
237                            'year'  => '$year',
238                            'month' => '$month',
239                        ],
240                        'total_time_saved'           => ['$sum' => '$time_saved'],
241                        'total_cost_savings'         => ['$sum' => '$cost_savings'],
242                        'total_characters_typed'     => ['$sum' => '$characters_typed'],
243                        'flyengage_count'            => ['$sum' => '$flyengage_count'],
244                        'sentence_rewrite_count'     => ['$sum' => '$sentence_rewrite_count'],
245                        'paragraph_rewrite_count'    => ['$sum' => '$paragraph_rewrite_count'],
246                        'flypost_count'              => ['$sum' => '$flypost_count'],
247                        'flycut_count'               => ['$sum' => '$flycut_count'],
248                        'fly_grammar_actions' => ['$sum' => '$fly_grammar_actions'],
249                        'fly_grammar_accepted' => ['$sum' => '$fly_grammar_accepted'],
250                        'fly_grammar_autocomplete' => ['$sum' => '$fly_grammar_autocomplete'],
251                    ],
252                ],
253                [
254                    '$sort' => ['_id.year' => 1, '_id.month' => 1],
255                ],
256            ]);
257        });
258
259        // 2. Consulta agregada total (não agrupado por mês)
260        $totals = FlyMsgUserDailyUsage::raw(function ($collection) use ($user_id) {
261            return $collection->aggregate([
262                ['$match' => ['user_id' => $user_id]],
263                ['$group' => [
264                    '_id' => null,
265                    'flyengage_count'        => ['$sum' => '$flyengage_count'],
266                    'sentence_rewrite_count' => ['$sum' => '$sentence_rewrite_count'],
267                    'paragraph_rewrite_count' => ['$sum' => '$paragraph_rewrite_count'],
268                    'flypost_count'          => ['$sum' => '$flypost_count'],
269                    'flycut_count'           => ['$sum' => '$flycut_count'],
270                    'total_time_saved'       => ['$sum' => '$time_saved'],
271                    'total_cost_savings'     => ['$sum' => '$cost_savings'],
272                    'total_characters_typed' => ['$sum' => '$characters_typed'],
273                    'number_of_flycuts_created_count' => ['$sum' => '$flycuts_created'],
274                    'number_of_flyplates_in_flycuts_count' => ['$sum' => '$flyplates_added'],
275                    'fly_grammar_actions' => ['$sum' => '$fly_grammar_actions'],
276                    'fly_grammar_accepted' => ['$sum' => '$fly_grammar_accepted'],
277                    'fly_grammar_autocorrect' => ['$sum' => '$fly_grammar_autocorrect'],
278                ]],
279            ]);
280        });
281        $totals = $totals[0] ?? [];
282
283        // 3. Processamento em memória
284        $sentence_rewrite_summarized   = [];
285        $paragraph_rewrite_summarized   = [];
286        $fly_engage_summarized   = [];
287        $fly_post_summarized     = [];
288        $fly_cut_summarized      = [];
289        $time_saved_summarized   = [];
290        $cost_savings_summarized = [];
291        $characters_typed_summarized = [];
292        $fly_grammar_actions_summarized = [];
293        $fly_grammar_accepted_summarized = [];
294        $fly_grammar_autocorrect_summarized = [];
295        $fly_grammar_autocomplete_summarized = [];
296
297        foreach ($monthly as $item) {
298            $year = $item['_id']['year'];
299            $monthNum = $item['_id']['month'];
300            $month = Carbon::createFromDate($year, $monthNum, 1);
301            $monthKey = strtolower($month->format('F')) . "_{$year}";
302            $formattedDate = $month->format('M Y');
303            $timestamp = $month->timestamp;
304
305            // Salva nos campos dinâmicos
306            $userInfo->{"total_time_saved___{$monthKey}"}       = $item['total_time_saved'];
307            $userInfo->{"total_cost_savings___{$monthKey}"}     = $item['total_cost_savings'];
308            $userInfo->{"of_characters_typed___{$monthKey}"}    = $item['total_characters_typed'];
309
310            $time_saved_summarized[] = [
311                'date' => $timestamp,
312                'month' => $formattedDate,
313                'total' => $item['total_time_saved']
314            ];
315            $cost_savings_summarized[] = [
316                'date' => $timestamp,
317                'month' => $formattedDate,
318                'total' => $item['total_cost_savings']
319            ];
320            $characters_typed_summarized[] = [
321                'date' => $timestamp,
322                'month' => $formattedDate,
323                'total' => $item['total_characters_typed']
324            ];
325
326            if ($year >= 2023) {
327                $fly_cut_summarized[] = [
328                    'date' => $timestamp,
329                    'month' => $formattedDate,
330                    'total' => $item['flycut_count']
331                ];
332                $fly_engage_summarized[] = [
333                    'date' => $timestamp,
334                    'month' => $formattedDate,
335                    'total' => $item['flyengage_count']
336                ];
337                $fly_post_summarized[] = [
338                    'date' => $timestamp,
339                    'month' => $formattedDate,
340                    'total' => $item['flypost_count']
341                ];
342            }
343            if ($year >= 2025) {
344                $sentence_rewrite_summarized[] = [
345                    'date' => $timestamp,
346                    'month' => $formattedDate,
347                    'total' => $item['sentence_rewrite_count']
348                ];
349                $paragraph_rewrite_summarized[] = [
350                    'date' => $timestamp,
351                    'month' => $formattedDate,
352                    'total' => $item['paragraph_rewrite_count']
353                ];
354                $fly_grammar_actions_summarized[] = [
355                    'date' => $timestamp,
356                    'month' => $formattedDate,
357                    'total' => $item['fly_grammar_actions']
358                ];
359                $fly_grammar_accepted_summarized[] = [
360                    'date' => $timestamp,
361                    'month' => $formattedDate,
362                    'total' => $item['fly_grammar_accepted']
363                ];
364                $fly_grammar_autocorrect_summarized[] = [
365                    'date' => $timestamp,
366                    'month' => $formattedDate,
367                    'total' => $item['fly_grammar_autocorrect']
368                ];
369                $fly_grammar_autocomplete_summarized[] = [
370                    'date' => $timestamp,
371                    'month' => $formattedDate,
372                    'total' => $item['fly_grammar_autocomplete']
373                ];
374            }
375        }
376
377        // Ordene e formate os arrays
378        $time_saved_summarized = collect($time_saved_summarized)->sortByDesc('date')->values()->map(function ($item) {
379            return $item['total'] . ' - ' . $item['month'];
380        });
381
382        $cost_savings_summarized = collect($cost_savings_summarized)->sortByDesc('date')->values()->map(function ($item) {
383            return $item['total'] . ' - ' . $item['month'];
384        });
385
386        $characters_typed_summarized = collect($characters_typed_summarized)->sortByDesc('date')->values()->map(function ($item) {
387            return $item['total'] . ' - ' . $item['month'];
388        });
389
390        $fly_cut_summarized = collect($fly_cut_summarized)->sortByDesc('date')->values()->map(function ($item) {
391            return $item['total'] . ' - ' . $item['month'];
392        });
393
394        $fly_engage_summarized = collect($fly_engage_summarized)->sortByDesc('date')->values()->map(function ($item) {
395            return $item['total'] . ' - ' . $item['month'];
396        });
397
398        $sentence_rewrite_summarized = collect($sentence_rewrite_summarized)->sortByDesc('date')->values()->map(function ($item) {
399            return $item['total'] . ' - ' . $item['month'];
400        });
401
402        $paragraph_rewrite_summarized = collect($paragraph_rewrite_summarized)->sortByDesc('date')->values()->map(function ($item) {
403            return $item['total'] . ' - ' . $item['month'];
404        });
405
406        $fly_post_summarized = collect($fly_post_summarized)->sortByDesc('date')->values()->map(function ($item) {
407            return $item['total'] . ' - ' . $item['month'];
408        });
409
410        $fly_grammar_actions_summarized = collect($fly_grammar_actions_summarized)->sortByDesc('date')->values()->map(function ($item) {
411            return $item['total'] . ' - ' . $item['month'];
412        });
413        $fly_grammar_accepted_summarized = collect($fly_grammar_accepted_summarized)->sortByDesc('date')->values()->map(function ($item) {
414            return $item['total'] . ' - ' . $item['month'];
415        });
416        $fly_grammar_autocorrect_summarized = collect($fly_grammar_autocorrect_summarized)->sortByDesc('date')->values()->map(function ($item) {
417            return $item['total'] . ' - ' . $item['month'];
418        });
419        $fly_grammar_autocomplete_summarized = collect($fly_grammar_autocomplete_summarized)->sortByDesc('date')->values()->map(function ($item) {
420            return $item['total'] . ' - ' . $item['month'];
421        });
422
423        // Monte os campos finais
424        $userInfo->total_time_saved_summarized_monthly_by_flymsg_by_user = $time_saved_summarized->implode('.   ');
425        $userInfo->total_cost_savings_summarized_monthly_by_flymsg_by_user = $cost_savings_summarized->implode('.   ');
426        $userInfo->total___of_characters_typed_monthly_by_flymsg_by_user = $characters_typed_summarized->implode('.   ');
427        $userInfo->total___of_times_flycut_is_used_summarized_monthly_by_user__count_ = $fly_cut_summarized->implode('.   ');
428        $userInfo->total___of_times_sentence_rewrite_is_used_summarized_monthly_by_user = $sentence_rewrite_summarized->implode('.   ');
429        $userInfo->total___of_times_paragraph_rewrite_is_used_summarized_monthly_by_user = $paragraph_rewrite_summarized->implode('.   ');
430        $userInfo->total___of_times_flyengage_is_used_summarized_monthly_by_user = $fly_engage_summarized->implode('.   ');
431        $userInfo->total___of_times_flyposts_is_used_summarized_monthly_by_user__count_ = $fly_post_summarized->implode('.   ');
432        $userInfo->total___of_times_flygrammar_is_used_summarized_monthly_by_user = $fly_grammar_actions_summarized->implode('.   ');
433        $userInfo->total___of_times_flygrammar_accepted_is_used_summarized_monthly_by_user = $fly_grammar_accepted_summarized->implode('.   ');
434        $userInfo->total___of_times_flygrammar_autocorrect_is_used_summarized_monthly_by_user = $fly_grammar_autocorrect_summarized->implode('.   ');
435        $userInfo->total___of_times_flygrammar_autocomplete_is_used_summarized_monthly_by_user = $fly_grammar_autocomplete_summarized->implode('.   ');
436
437        // Atualize os campos de totais absolutos
438        $userInfo->total___of_times_sentence_rewrite_used__count_ = $totals['sentence_rewrite_count'] ?? 0;
439        $userInfo->total___of_times_paragraph_rewrite_used__count_ = $totals['paragraph_rewrite_count'] ?? 0;
440        $userInfo->total___of_times_flyengage_used__count_ = $totals['flyengage_count'] ?? 0;
441        $userInfo->total___of_times_flyposts_used__count_ = $totals['flypost_count'] ?? 0;
442        $userInfo->total___of_times_flycut_used__count_ = $totals['flycut_count'] ?? 0;
443        $userInfo->total___of_times_flygrammar_is_used_count = $totals['fly_grammar_actions'] ?? 0;
444        $userInfo->total___of_times_flygrammar_accepted_is_used_count = $totals['fly_grammar_accepted'] ?? 0;
445        $userInfo->total___of_times_flygrammar_autocorrect_is_used_count = $totals['fly_grammar_autocorrect'] ?? 0;
446        $userInfo->total___of_times_flygrammar_autocomplete_is_used_count = $totals['fly_grammar_autocomplete'] ?? 0;
447        $userInfo->total_time_saved_by_flymsg_by_user = $totals['total_time_saved'] ?? 0;
448        $userInfo->total_cost_savings_by_flymsg_by_user = $totals['total_cost_savings'] ?? 0;
449        $userInfo->total___of_characters_typed_by_flymsg_by_user = $totals['total_characters_typed'] ?? 0;
450        $userInfo->number_of_flycuts_created_count = $totals['number_of_flycuts_created_count'] ?? 0;
451        $userInfo->number_of_flyplates_in_flycuts_count = $totals['number_of_flyplates_in_flycuts_count'] ?? 0;
452
453        $userInfo->save();
454    }
455
456    public function processUserUsage(User $user, bool $onlyUpdate = false): void
457    {
458        $startDate = $user->created_at->copy();
459
460        if ($startDate->lessThan(Carbon::parse('2022-01-01 00:00:00'))) {
461            $startDate = Carbon::parse('2022-01-01 00:00:00');
462        }
463
464        if ($onlyUpdate) {
465            $lastRegister = FlyMsgUserDailyUsage::where('user_id', $user->id)->orderBy('created_at', 'desc')->first();
466            if ($lastRegister) {
467                $startDate = $lastRegister->created_at->copy();
468            }
469        }
470
471        $endDate = now();
472
473        $user_id = $user->id;
474        $email_domain = strrchr($user->email, "@");
475        $user_status = $user->status ?? 'Active';
476        $hubspot_id = $user->hubspot_id;
477        $company_id = $user->company_id;
478
479        $group = CompanyGroup::find($user->company_group_id);
480        if (!empty($group?->parent_id)) {
481            $subgroup_id = $user->company_group_id;
482            $group_id = $group->parent_id;
483        } else {
484            $group_id = $user->company_group_id;
485            $subgroup_id = null;
486        }
487
488        $category = $company_id ? 'corporate' : 'individual';
489
490        // 1. Array associativo para todas as datas
491        $merged = [];
492
493        if ($startDate->lessThan(Carbon::parse('2023-02-01 00:00:00'))) {
494            // -------- HUBSPOT USAGE --------
495            $hubspotData = $this->getHubspotUsage($user_id); // igual ao anterior
496            foreach ($hubspotData as $month => $data) {
497                $formatted = ucwords(str_replace('_', ' ', $month)); // "April 2022"
498                $date = Carbon::createFromFormat('F Y', $formatted)->startOfMonth()->copy();
499                $daysInMonth = $date->daysInMonth;
500
501                for ($i = 1; $i <= $daysInMonth; $i++) {
502                    $dt = $date->copy()->day($i);
503                    $key = $dt->toDateString();
504                    if (!isset($merged[$key])) $merged[$key] = [];
505                    $merged[$key]['characters_typed'] = $data['characters_per_day'] ?? 0;
506                    $merged[$key]['cost_savings'] = $data['cost_per_day'] ?? 0;
507                    $merged[$key]['time_saved'] = $data['time_saved_per_day'] ?? 0;
508                    // Os outros campos virão depois
509                }
510            }
511        }
512
513        // -------- FLYCUT USAGE --------
514        $usages = FlyCutUsage::raw(function ($collection) use ($user_id, $startDate, $endDate) {
515            return $collection->aggregate([
516                ['$match' => [
517                    'user_id' => $user_id,
518                    'created_at' => [
519                        '$gte' => new UTCDateTime(strtotime($startDate->toDateString()) * 1000),
520                        '$lte' => new UTCDateTime(strtotime($endDate->toDateString()) * 1000),
521                    ],
522                ]],
523                ['$group' => [
524                    '_id' => [
525                        'year'  => ['$year' => '$created_at'],
526                        'month' => ['$month' => '$created_at'],
527                        'day'   => ['$dayOfMonth' => '$created_at'],
528                    ],
529                    'time_saved'        => ['$sum' => '$time_saved'],
530                    'cost_savings'      => ['$sum' => '$cost_saved'],
531                    'characters_typed'  => ['$sum' => '$characters_saved'],
532                    'sentence_rewrite_count'   => ['$sum' => ['$cond' => [['$eq' => ['$feature', 'sentence_rewrite']], 1, 0]]],
533                    'paragraph_rewrite_count'   => ['$sum' => ['$cond' => [['$eq' => ['$feature', 'paragraph_rewrite']], 1, 0]]],
534                    'flyengage_count'   => ['$sum' => ['$cond' => [['$eq' => ['$feature', 'flyengage']], 1, 0]]],
535                    'flypost_count'     => ['$sum' => ['$cond' => [['$eq' => ['$feature', 'flypost']], 1, 0]]],
536                    'flycut_count'      => ['$sum' => ['$cond' => [['$or' => [['$eq' => ['$feature', null]], ['$not' => ['$feature']]]], 1, 0]]],
537                ]],
538                ['$project' => [
539                    '_id' => 0,
540                    'year' => '$_id.year',
541                    'month' => '$_id.month',
542                    'day' => '$_id.day',
543                    'time_saved' => 1,
544                    'cost_savings' => 1,
545                    'characters_typed' => 1,
546                    'sentence_rewrite_count' => 1,
547                    'paragraph_rewrite_count' => 1,
548                    'flyengage_count' => 1,
549                    'flypost_count' => 1,
550                    'flycut_count' => 1,
551                ]]
552            ]);
553        });
554
555        foreach ($usages as $data) {
556            $dt = Carbon::createFromDate($data['year'], $data['month'], $data['day']);
557            $key = $dt->toDateString();
558            if (!isset($merged[$key])) $merged[$key] = [];
559            $merged[$key]['time_saved'] = $data['time_saved'] ?? 0;
560            $merged[$key]['cost_savings'] = $data['cost_savings'] ?? 0;
561            $merged[$key]['characters_typed'] = $data['characters_typed'] ?? 0;
562            $merged[$key]['sentence_rewrite_count'] = $data['sentence_rewrite_count'] ?? 0;
563            $merged[$key]['paragraph_rewrite_count'] = $data['paragraph_rewrite_count'] ?? 0;
564            $merged[$key]['flyengage_count'] = $data['flyengage_count'] ?? 0;
565            $merged[$key]['flypost_count'] = $data['flypost_count'] ?? 0;
566            $merged[$key]['flycut_count'] = $data['flycut_count'] ?? 0;
567        }
568
569        // -------- FLYCUT USAGE --------
570        $usages = FlyCutUsage::raw(function ($collection) use ($user_id, $startDate, $endDate) {
571            return $collection->aggregate([
572                ['$match' => [
573                    'user_id' => $user_id,
574                    'created_at' => [
575                        '$gte' => new UTCDateTime(strtotime($startDate->toDateString()) * 1000),
576                        '$lte' => new UTCDateTime(strtotime($endDate->toDateString()) * 1000),
577                    ],
578                ]],
579                ['$group' => [
580                    '_id' => [
581                        'year'  => ['$year' => '$created_at'],
582                        'month' => ['$month' => '$created_at'],
583                        'day'   => ['$dayOfMonth' => '$created_at'],
584                    ],
585                    'time_saved'        => ['$sum' => '$time_saved'],
586                    'cost_savings'      => ['$sum' => '$cost_saved'],
587                    'characters_typed'  => ['$sum' => '$characters_saved'],
588                    'sentence_rewrite_count'   => ['$sum' => ['$cond' => [['$eq' => ['$feature', 'sentence_rewrite']], 1, 0]]],
589                    'paragraph_rewrite_count'   => ['$sum' => ['$cond' => [['$eq' => ['$feature', 'paragraph_rewrite']], 1, 0]]],
590                    'flyengage_count'   => ['$sum' => ['$cond' => [['$eq' => ['$feature', 'flyengage']], 1, 0]]],
591                    'flypost_count'     => ['$sum' => ['$cond' => [['$eq' => ['$feature', 'flypost']], 1, 0]]],
592                    'flycut_count'      => ['$sum' => ['$cond' => [['$or' => [['$eq' => ['$feature', null]], ['$not' => ['$feature']]]], 1, 0]]],
593                ]],
594                ['$project' => [
595                    '_id' => 0,
596                    'year' => '$_id.year',
597                    'month' => '$_id.month',
598                    'day' => '$_id.day',
599                    'time_saved' => 1,
600                    'cost_savings' => 1,
601                    'characters_typed' => 1,
602                    'sentence_rewrite_count' => 1,
603                    'paragraph_rewrite_count' => 1,
604                    'flyengage_count' => 1,
605                    'flypost_count' => 1,
606                    'flycut_count' => 1,
607                ]]
608            ]);
609        });
610
611        foreach ($usages as $data) {
612            $dt = Carbon::createFromDate($data['year'], $data['month'], $data['day']);
613            $key = $dt->toDateString();
614            if (!isset($merged[$key])) $merged[$key] = [];
615            $merged[$key]['time_saved'] = $data['time_saved'] ?? 0;
616            $merged[$key]['cost_savings'] = $data['cost_savings'] ?? 0;
617            $merged[$key]['characters_typed'] = $data['characters_typed'] ?? 0;
618            $merged[$key]['sentence_rewrite_count'] = $data['sentence_rewrite_count'] ?? 0;
619            $merged[$key]['paragraph_rewrite_count'] = $data['paragraph_rewrite_count'] ?? 0;
620            $merged[$key]['flyengage_count'] = $data['flyengage_count'] ?? 0;
621            $merged[$key]['flypost_count'] = $data['flypost_count'] ?? 0;
622            $merged[$key]['flycut_count'] = $data['flycut_count'] ?? 0;
623        }
624
625        // -------- SHORTCUTS --------
626        $shortcuts = Shortcut::raw(function ($collection) use ($user_id, $startDate, $endDate) {
627            return $collection->aggregate([
628                ['$match' => [
629                    'user_id' => $user_id,
630                    'created_at' => [
631                        '$gte' => new UTCDateTime(strtotime($startDate->toDateString()) * 1000),
632                        '$lte' => new UTCDateTime(strtotime($endDate->toDateString()) * 1000),
633                    ],
634                ]],
635                ['$group' => [
636                    '_id' => [
637                        'year' => ['$year' => '$created_at'],
638                        'month' => ['$month' => '$created_at'],
639                        'day' => ['$dayOfMonth' => '$created_at'],
640                        'user_defined' => '$user_defined'
641                    ],
642                    'count' => ['$sum' => 1],
643                ]],
644                ['$project' => [
645                    '_id' => 0,
646                    'year' => '$_id.year',
647                    'month' => '$_id.month',
648                    'day' => '$_id.day',
649                    'user_defined' => '$_id.user_defined',
650                    'count' => 1,
651                ]]
652            ]);
653        });
654
655        foreach ($shortcuts as $data) {
656            $dt = Carbon::createFromDate($data['year'], $data['month'], $data['day']);
657            $key = $dt->toDateString();
658            if (!isset($merged[$key])) $merged[$key] = [];
659            $merged[$key]['flycuts_created']  = ($data['user_defined'] ?? false) ? $data['count'] : 0;
660            $merged[$key]['flyplates_added']  = (!($data['user_defined'] ?? false)) ? $data['count'] : 0;
661        }
662
663        // -------- FLYGRAMMAR USAGE --------
664        $actionsUsage = FlyGrammarActions::raw(function ($collection) use ($user_id, $startDate, $endDate) {
665            return $collection->aggregate([
666                ['$match' => [
667                    'user_id' => $user_id,
668                    'created_at' => [
669                        '$gte' => new UTCDateTime(strtotime($startDate->toDateString()) * 1000),
670                        '$lte' => new UTCDateTime(strtotime($endDate->toDateString()) * 1000),
671                    ],
672                ]],
673                ['$group' => [
674                    '_id' => [
675                        'year'  => ['$year' => '$created_at'],
676                        'month' => ['$month' => '$created_at'],
677                        'day'   => ['$dayOfMonth' => '$created_at'],
678                    ],
679                    'time_saved'        => ['$sum' => '$time_saved'],
680                    'cost_savings'      => ['$sum' => '$cost_saved'],
681                    'characters_typed'  => ['$sum' => '$characters_count'],
682                    'actions_count'     => ['$sum' => 1],
683                    'actions_accepted_count'     => ['$sum' => ['$cond' => [['$ne' => ['$action_type', 'autocorrect']], 1, 0]]],
684                    'actions_autocorrect_count'     => ['$sum' => ['$cond' => [['$eq' => ['$action_type', 'autocorrect']], 1, 0]]],
685                ]],
686                ['$project' => [
687                    '_id' => 0,
688                    'year' => '$_id.year',
689                    'month' => '$_id.month',
690                    'day' => '$_id.day',
691                    'time_saved' => 1,
692                    'cost_savings' => 1,
693                    'characters_typed' => 1,
694                    'actions_count' => 1,
695                    'actions_accepted_count' => 1,
696                    'actions_autocorrect_count' => 1,
697                ]]
698            ]);
699        });
700
701        foreach ($actionsUsage as $data) {
702            $dt = Carbon::createFromDate($data['year'], $data['month'], $data['day']);
703            $key = $dt->toDateString();
704            if (!isset($merged[$key])) $merged[$key] = [];
705            $merged[$key]['time_saved']        = ($merged[$key]['time_saved'] ?? 0) + ($data['time_saved'] ?? 0);
706            $merged[$key]['cost_savings']      = ($merged[$key]['cost_savings'] ?? 0) + ($data['cost_savings'] ?? 0);
707            $merged[$key]['characters_typed']  = ($merged[$key]['characters_typed'] ?? 0) + ($data['characters_typed'] ?? 0);
708            $merged[$key]['fly_grammar_actions']  = $data['actions_count'] ?? 0;
709            $merged[$key]['fly_grammar_accepted']  = $data['actions_accepted_count'] ?? 0;
710            $merged[$key]['fly_grammar_autocorrect']  = $data['actions_autocorrect_count'] ?? 0;
711            $merged[$key]['fly_grammar_autocomplete']  = $data['actions_autocomplete_count'] ?? 0;
712        }
713
714        // -------- ÃšNICO BULK OP --------
715        if (!empty($merged)) {
716            FlyMsgUserDailyUsage::raw(function ($collection) use ($merged, $user_id, $email_domain, $user_status, $hubspot_id, $company_id, $group_id, $subgroup_id, $category) {
717                $bulkOps = [];
718                foreach ($merged as $key => $fields) {
719                    $dt = Carbon::parse($key); // key Ã© 'Y-m-d'
720                    // Preenche campos padrão para evitar campo unset/undefined
721                    $toUpdate = [
722                        'user_id'       => $user_id,
723                        'year'          => $dt->year,
724                        'month'         => $dt->month,
725                        'day'           => $dt->day,
726                        'email_domain'  => $email_domain,
727                        'user_status'   => $user_status,
728                        'hubspot_id'    => $hubspot_id,
729                        'company_id'    => $company_id,
730                        'group_id'      => $group_id,
731                        'category'      => $category,
732                        'created_at'    => new UTCDateTime($dt->timestamp * 1000),
733                        'updated_at'    => new UTCDateTime($dt->timestamp * 1000),
734                    ];
735
736                    if (!empty($subgroup_id)) {
737                        $toUpdate['subgroup_id'] = $subgroup_id;
738                    }
739
740                    $row = array_merge([
741                        'time_saved'        => 0,
742                        'cost_savings'      => 0,
743                        'characters_typed'  => 0,
744                        'sentence_rewrite_count'   => 0,
745                        'paragraph_rewrite_count'   => 0,
746                        'flyengage_count'   => 0,
747                        'flypost_count'     => 0,
748                        'flycut_count'      => 0,
749                        'flycuts_created'   => 0,
750                        'flyplates_added'   => 0,
751                        'fly_grammar_actions'   => 0,
752                        'fly_grammar_accepted'   => 0,
753                        'fly_grammar_autocorrect'   => 0,
754                        'fly_grammar_autocomplete'   => 0,
755                    ], $fields, $toUpdate);
756                    $bulkOps[] = [
757                        'updateOne' => [
758                            [
759                                'user_id' => $row['user_id'],
760                                'year'    => $row['year'],
761                                'month'   => $row['month'],
762                                'day'     => $row['day'],
763                            ],
764                            ['$set' => $row],
765                            ['upsert' => true]
766                        ]
767                    ];
768                }
769                return $collection->bulkWrite($bulkOps);
770            });
771        }
772    }
773
774    private function parseMonth(int $month): string
775    {
776        return match ($month) {
777            1 => 'january',
778            2 => 'february',
779            3 => 'march',
780            4 => 'april',
781            5 => 'may',
782            6 => 'june',
783            7 => 'july',
784            8 => 'august',
785            9 => 'september',
786            10 => 'october',
787            11 => 'november',
788            default => 'december',
789        };
790    }
791
792    private function getHubspotUsage(string $user_id)
793    {
794        $allMonths = [
795            'october_2020',
796            'november_2020',
797            'december_2020',
798            'january_2021',
799            'february_2021',
800            'march_2021',
801            'april_2021',
802            'may_2021',
803            'june_2021',
804            'july_2021',
805            'august_2021',
806            'september_2021',
807            'october_2021',
808            'november_2021',
809            'december_2021',
810            'january_2022',
811            'february_2022',
812            'march_2022',
813            'april_2022',
814            'may_2022',
815            'june_2022',
816            'july_2022',
817            'august_2022',
818            'september_2022',
819            'october_2022',
820            'november_2022',
821            'december_2022',
822            'january_2023',
823        ];
824
825        $hubspotQuery = HubspotProperties::raw(function ($collection) use ($user_id, $allMonths) {
826            $fieldsProject = [
827                'flymsg_id' => 1
828            ];
829
830            foreach ($allMonths as $month) {
831                $fieldsProject['of_characters_typed___' . $month] = 1;
832                $fieldsProject['total_cost_savings___' . $month] = 1;
833                $fieldsProject['total_time_saved___' . $month] = 1;
834            }
835
836            return $collection->aggregate([
837                ['$match' => [
838                    'flymsg_id' => $user_id,
839                ]],
840                ['$project' => $fieldsProject]
841            ]);
842        });
843
844        $doc = $hubspotQuery[0] ?? null;
845
846        $monthlyData = [];
847
848        $user = User::find($user_id);
849
850        $wagePerHour = $user->setting?->wage_per_hour ?? FlyCutUsage::WAGE_PER_HOUR;
851        $userWordPerMinute = $user->setting?->words_per_minute ?? FlyCutUsage::WORDS_PER_MINUTE;
852        $characterPerHour = $userWordPerMinute * 300;
853
854        if ($doc) {
855            foreach ($allMonths as $month) {
856                $characters = isset($doc['of_characters_typed___' . $month]) ? (int)$doc['of_characters_typed___' . $month] : 0;
857                if ($characters <= 0) {
858                    continue;
859                }
860                // $time = isset($doc['total_time_saved___'.$month]) ? (int)$doc['total_time_saved___'.$month] : 0;
861                $time = round($characters / $characterPerHour, 8);
862                // $cost = isset($doc['total_cost_savings___'.$month]) ? (float)$doc['total_cost_savings___'.$month] : 0;
863                $cost = round($time * $wagePerHour, 8);;
864                $daysInMonth = cal_days_in_month(
865                    CAL_GREGORIAN,
866                    Carbon::createFromFormat('F Y', ucwords(str_replace('_', ' ', $month)))->startOfMonth()->format('m'),
867                    Carbon::createFromFormat('F Y', ucwords(str_replace('_', ' ', $month)))->startOfMonth()->format('Y')
868                );
869
870                $monthlyData[$month] = [
871                    'characters' => $characters,
872                    'characters_per_day' => (int)round($daysInMonth ? ($characters / $daysInMonth) : 0),
873                    'cost_savings' => $cost,
874                    'cost_per_day' => $daysInMonth ? ($cost / $daysInMonth) : 0,
875                    'time_saved' => $time,
876                    'time_saved_per_day' => $daysInMonth ? ($time / $daysInMonth) : 0,
877                ];
878            }
879        }
880
881        return $monthlyData;
882    }
883}