Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.14% |
1 / 707 |
|
14.29% |
1 / 7 |
CRAP | |
0.00% |
0 / 1 |
FlyMsgUserDailyUsageService | |
0.14% |
1 / 707 |
|
14.29% |
1 / 7 |
2246.64 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
refresh | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
processUserSummaryUsage2 | |
0.00% |
0 / 138 |
|
0.00% |
0 / 1 |
56 | |||
processUserSummaryUsage | |
0.00% |
0 / 210 |
|
0.00% |
0 / 1 |
30 | |||
processUserUsage | |
0.00% |
0 / 270 |
|
0.00% |
0 / 1 |
552 | |||
parseMonth | |
0.00% |
0 / 14 |
|
0.00% |
0 / 1 |
2 | |||
getHubspotUsage | |
0.00% |
0 / 72 |
|
0.00% |
0 / 1 |
90 |
1 | <?php |
2 | |
3 | namespace App\Services\UserInfo; |
4 | |
5 | use App\Http\Models\Admin\CompanyGroup; |
6 | use App\Http\Models\FlyGrammarActions; |
7 | use App\Http\Models\FlyMsgUserDailyUsage; |
8 | use App\Http\Models\Auth\User; |
9 | use App\Http\Models\UserInfo; |
10 | use App\Http\Services\StatisticsService; |
11 | use App\Traits\UsageTrait; |
12 | use Illuminate\Support\Carbon; |
13 | use App\Http\Models\FlyCutUsage; |
14 | use App\Http\Models\HubspotProperties; |
15 | use App\Http\Models\Shortcut; |
16 | use MongoDB\BSON\UTCDateTime; |
17 | |
18 | class 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 | } |