Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 178
0.00% covered (danger)
0.00%
0 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
AccountCenterReporting
0.00% covered (danger)
0.00%
0 / 178
0.00% covered (danger)
0.00%
0 / 7
1806
0.00% covered (danger)
0.00%
0 / 1
 getFilteredQuery
0.00% covered (danger)
0.00%
0 / 37
0.00% covered (danger)
0.00%
0 / 1
110
 getFilteredQueryPipeline
0.00% covered (danger)
0.00%
0 / 35
0.00% covered (danger)
0.00%
0 / 1
182
 filterUsersByCompanyDaily
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
30
 filterUsersByCompany
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
30
 buildLineChartData
0.00% covered (danger)
0.00%
0 / 34
0.00% covered (danger)
0.00%
0 / 1
12
 buildLineChartData2
0.00% covered (danger)
0.00%
0 / 45
0.00% covered (danger)
0.00%
0 / 1
12
 buildLineChartDataForCounts
0.00% covered (danger)
0.00%
0 / 17
0.00% covered (danger)
0.00%
0 / 1
12
1<?php
2
3namespace App\Actions\AccountCenter\Reporting;
4
5use App\DTO\AccountCenter\Reporting\ReportingRequestDTO;
6use App\Http\Models\Auth\Role;
7use App\Http\Models\FlyMsgUserDailyUsage;
8use Carbon\Carbon;
9use Illuminate\Database\Eloquent\Builder;
10use Illuminate\Database\Eloquent\Collection;
11use MongoDB\BSON\UTCDateTime;
12
13class AccountCenterReporting
14{
15    protected function getFilteredQuery(ReportingRequestDTO $filter)
16    {
17        $query = FlyMsgUserDailyUsage::query();
18
19        if (! empty($filter->fromDate)) {
20            $start_date = Carbon::parse($filter->fromDate)->startOfDay();
21
22            $query = $query->where('created_at', '>=', new UTCDateTime($start_date->getTimestamp() * 1000));
23        }
24
25        if (! empty($filter->toDate)) {
26            $end_date = Carbon::parse($filter->toDate)->endOfDay();
27
28            $query = $query->where('created_at', '<=', new UTCDateTime($end_date->getTimestamp() * 1000));
29        }
30
31        $user_ids = explode(',', $filter->userIds);
32        $user_ids = array_filter($user_ids, function ($value) {
33            return $value !== '';
34        });
35
36        if (count($user_ids) > 0) {
37            $query = $query->whereIn('user_id', $user_ids);
38        }
39
40        $hasNotAssignedGroup = in_array('-1', explode(',', $filter->groupIds));
41
42        if ($hasNotAssignedGroup) {
43            $query = $query->whereNull('group_id');
44        }
45
46        $group_ids = explode(',', $filter->groupIds);
47        $group_ids = array_filter($group_ids, function ($value) {
48            return $value !== '' && $value !== '-1';
49        });
50
51        if (count($group_ids) > 0) {
52            $query = $query->whereIn('group_id', $group_ids);
53        }
54
55        $subgroup_ids = explode(',', $filter->subgroupIds);
56        $subgroup_ids = array_filter($subgroup_ids, function ($value) {
57            return $value !== '';
58        });
59
60        if (count($subgroup_ids) > 0) {
61            $query = $query->whereIn('group_id', $subgroup_ids);
62        }
63
64        $company_ids = $filter->companyIds ?? [];
65        $company_ids = array_filter($company_ids, function ($value) {
66            return $value !== '';
67        });
68
69        if (count($company_ids) > 0) {
70            $query = $query->whereIn('company_id', $company_ids);
71        }
72
73        if ($filter->companyId) {
74            $query = $this->filterUsersByCompanyDaily($query, $filter->role, $group_ids, $filter->companyId, $filter->adminGroupIds);
75        }
76
77        return $query;
78    }
79
80    protected function getFilteredQueryPipeline(ReportingRequestDTO $filter)
81    {
82        $filters = [
83            'deleted_at' => ['$exists' => false],
84        ];
85
86        if (! empty($filter->fromDate)) {
87            $start_date = Carbon::parse($filter->fromDate)->startOfDay();
88            $filters['created_at']['$gte'] = new UTCDateTime($start_date->getTimestamp() * 1000);
89        }
90
91        if (! empty($filter->toDate)) {
92            $end_date = Carbon::parse($filter->toDate)->endOfDay();
93            $filters['created_at']['$lte'] = new UTCDateTime($end_date->getTimestamp() * 1000);
94        }
95
96        $user_ids = array_values(array_filter(explode(',', $filter->userIds)));
97        if (count($user_ids) > 0) {
98            $filters['user_id']['$in'] = $user_ids;
99        }
100
101        $hasNotAssignedGroup = in_array('-1', explode(',', $filter->groupIds));
102
103        if ($hasNotAssignedGroup) {
104            $filters['group_id'] = null;
105        }
106
107        $group_ids = array_values(array_filter(
108            explode(',', $filter->groupIds),
109            fn ($value) => $value !== '' && $value !== '-1'
110        ));
111        if (count($group_ids) > 0) {
112            $filters['group_id']['$in'] = $group_ids;
113        }
114
115        $subgroup_ids = array_values(array_filter(explode(',', $filter->subgroupIds)));
116        if (count($subgroup_ids) > 0) {
117            $filters['group_id']['$in'] = $subgroup_ids;
118        }
119
120        $company_ids = array_values(array_filter(explode(',', $filter->companyIds ?? '')));
121        if (count($company_ids) > 0) {
122            $filters['company_id']['$in'] = $company_ids;
123        }
124
125        if ($filter->companyId) {
126            if ($filter->role == Role::GLOBAL_ADMIN || $filter->role == Role::VENGRESO_ADMIN) {
127                $filters['company_id'] = $filter->companyId;
128            } elseif (empty($group_ids ?? [])) {
129                $filters['group_id']['$in'] = $filter->adminGroupIds ?? [];
130            }
131        }
132
133        return [
134            ['$match' => $filters],
135        ];
136    }
137
138    protected function filterUsersByCompanyDaily(Builder $query, string $role, array $groupIds, string $companyId, ?array $adminGroupIds, $global = false)
139    {
140        if ($role == Role::GLOBAL_ADMIN || $role == Role::VENGRESO_ADMIN || $global) {
141            return $query->where('company_id', '=', $companyId);
142        } elseif (empty($groupIds)) {
143            return $query->whereIn('group_id', $adminGroupIds ?? []);
144        }
145
146        return $query;
147    }
148
149    protected function filterUsersByCompany(Builder $query, string $role, array $groupIds, string $companyId, ?array $adminGroupIds, $global = false)
150    {
151        if ($role == Role::GLOBAL_ADMIN || $role == Role::VENGRESO_ADMIN || $global) {
152            return $query->where('company_id', '=', $companyId);
153        } elseif (empty($groupIds)) {
154            return $query->whereIn('company_group_id', $adminGroupIds ?? []);
155        }
156
157        return $query;
158    }
159
160    protected function buildLineChartData(Collection $flycutUsages, int $months)
161    {
162        // Initialize the line chart data array
163        $line_chart_data = [];
164        $current_date = Carbon::now()->setTimezone('UTC');
165        for ($i = 0; $i < $months; $i++) {
166            $month_year = $current_date->subMonth()->format('M Y');
167            $line_chart_data[$month_year] = [
168                'month_year' => $month_year,
169                'flycuts_used' => 0,
170                'characters_typed' => round(0, 2),
171                'time_saved' => round(0, 2),
172                'cost_saved' => round(0, 2),
173                'issues_fixed' => round(0, 2),
174            ];
175        }
176
177        // Aggregate the data by month
178        $aggregated_data = $flycutUsages->groupBy(function ($date) {
179            return Carbon::parse($date->created_at)->setTimezone('UTC')->format('M Y');
180        });
181
182        // Process the aggregated data
183        foreach ($aggregated_data as $month_year => $usages) {
184            $month = Carbon::parse($usages->first()->created_at)->setTimezone('UTC')->format('M Y');
185
186            $flycuts_used = $usages->count();
187            $characters_typed = $usages->sum('characters_typed');
188            $time_saved = $usages->sum('time_saved');
189            $cost_saved = $usages->sum('cost_saved');
190            $issues_fixed = $usages->sum('issues_fixed');
191
192            $line_chart_data[$month] = [
193                'month_year' => $month_year,
194                'flycuts_used' => $flycuts_used,
195                'characters_typed' => round($characters_typed, 2),
196                'time_saved' => round($time_saved, 2),
197                'cost_saved' => round($cost_saved, 2),
198                'issues_fixed' => round($issues_fixed, 2),
199            ];
200        }
201
202        // Convert month-year strings to DateTime objects and sort by date
203        uksort($line_chart_data, function ($a, $b) {
204            return strtotime($a) - strtotime($b);
205        });
206
207        return $line_chart_data;
208    }
209
210    protected function buildLineChartData2(Collection $flycutUsages, int $months)
211    {
212        // Initialize the line chart data array
213        $line_chart_data = [];
214        $current_date = Carbon::now()->setTimezone('UTC');
215        for ($i = 0; $i < $months; $i++) {
216            $month_year = $current_date->subMonth()->format('M Y');
217            $line_chart_data[$month_year] = [
218                'month_year' => $month_year,
219                'flycuts_used' => 0,
220                'characters_typed' => round(0, 2),
221                'time_saved' => round(0, 2),
222                'cost_saved' => round(0, 2),
223                'issues_fixed' => round(0, 2),
224                'issues_accepted' => round(0, 2),
225                'issues_autocorrect' => round(0, 2),
226                'paragraph_rewrite_count' => round(0, 2),
227            ];
228        }
229
230        // Aggregate the data by month
231        $aggregated_data = $flycutUsages->groupBy(function ($item) {
232            return $item->created_at->toDateTime()->format('M Y');
233        });
234
235        // Process the aggregated data
236        foreach ($aggregated_data as $month_year => $usages) {
237            $month = $usages->first()->created_at->toDateTime()->format('M Y');
238
239            $flycuts_used = $usages->count();
240            $characters_typed = $usages->sum('characters_typed');
241            $time_saved = $usages->sum('time_saved');
242            $cost_saved = $usages->sum('cost_savings');
243            $issues_fixed = $usages->sum('fly_grammar_actions');
244            $issues_accepted = $usages->sum('fly_grammar_accepted');
245            $issues_autocorrect = $usages->sum('fly_grammar_autocorrect');
246            $issues_autocomplete = $usages->sum('fly_grammar_autocomplete');
247            $paragraph_rewrite_count = $usages->sum('paragraph_rewrite_count');
248
249            $line_chart_data[$month] = [
250                'month_year' => $month_year,
251                'flycuts_used' => $flycuts_used,
252                'characters_typed' => round($characters_typed, 2),
253                'time_saved' => round($time_saved, 2),
254                'cost_saved' => round($cost_saved, 2),
255                'issues_fixed' => round($issues_fixed, 2),
256                'issues_accepted' => round($issues_accepted, 2),
257                'issues_autocorrect' => round($issues_autocorrect, 2),
258                'issues_autocomplete' => round($issues_autocomplete, 2),
259                'paragraph_rewrite_count' => round($paragraph_rewrite_count, 2),
260            ];
261        }
262
263        // Convert month-year strings to DateTime objects and sort by date
264        uksort($line_chart_data, function ($a, $b) {
265            return strtotime($a) - strtotime($b);
266        });
267
268        return $line_chart_data;
269    }
270
271    protected function buildLineChartDataForCounts(Collection $shortcut, int $months, string $property)
272    {
273        $line_chart_data = [];
274        $current_date = Carbon::now();
275        for ($i = 0; $i < $months; $i++) {
276            $month_year = $current_date->subMonth()->format('M Y');
277            $line_chart_data[$month_year] = ['count' => 0];
278        }
279
280        // Reset the current date to now
281        $current_date = Carbon::now();
282
283        // Aggregate the data by month
284        $aggregated_data = $shortcut->groupBy(function ($item) {
285            return Carbon::parse($item->created_at)->format('Y-m');
286        });
287
288        // Process the aggregated data and populate the line chart data array
289        foreach ($aggregated_data as $month_year => $usages) {
290            $month = Carbon::parse($usages->first()->created_at)->format('M Y');
291            $flycuts_used = $usages->sum($property);
292            $line_chart_data[$month] = ['count' => $flycuts_used];
293        }
294
295        // Ensure the data is sorted by date keys
296        uksort($line_chart_data, function ($a, $b) {
297            return strtotime($a) - strtotime($b);
298        });
299
300        return $line_chart_data;
301    }
302}