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