Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
0.00% |
0 / 178 |
|
0.00% |
0 / 7 |
CRAP | |
0.00% |
0 / 1 |
| AccountCenterReporting | |
0.00% |
0 / 178 |
|
0.00% |
0 / 7 |
1806 | |
0.00% |
0 / 1 |
| getFilteredQuery | |
0.00% |
0 / 37 |
|
0.00% |
0 / 1 |
110 | |||
| getFilteredQueryPipeline | |
0.00% |
0 / 35 |
|
0.00% |
0 / 1 |
182 | |||
| filterUsersByCompanyDaily | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
30 | |||
| filterUsersByCompany | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
30 | |||
| buildLineChartData | |
0.00% |
0 / 34 |
|
0.00% |
0 / 1 |
12 | |||
| buildLineChartData2 | |
0.00% |
0 / 45 |
|
0.00% |
0 / 1 |
12 | |||
| buildLineChartDataForCounts | |
0.00% |
0 / 17 |
|
0.00% |
0 / 1 |
12 | |||
| 1 | <?php |
| 2 | |
| 3 | namespace App\Actions\AccountCenter\Reporting; |
| 4 | |
| 5 | use App\DTO\AccountCenter\Reporting\ReportingRequestDTO; |
| 6 | use App\Http\Models\Auth\Role; |
| 7 | use App\Http\Models\FlyMsgUserDailyUsage; |
| 8 | use Carbon\Carbon; |
| 9 | use Illuminate\Database\Eloquent\Builder; |
| 10 | use Illuminate\Database\Eloquent\Collection; |
| 11 | use MongoDB\BSON\UTCDateTime; |
| 12 | |
| 13 | class 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 | } |