Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 82
0.00% covered (danger)
0.00%
0 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
ReportingProductivitySpotlightRequest
0.00% covered (danger)
0.00%
0 / 82
0.00% covered (danger)
0.00%
0 / 2
182
0.00% covered (danger)
0.00%
0 / 1
 execute
0.00% covered (danger)
0.00%
0 / 67
0.00% covered (danger)
0.00%
0 / 1
110
 makeLineChartData
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
12
1<?php
2
3namespace App\Actions;
4
5use App\DTO\ReportingTopUsersRequestDTO;
6use App\Http\Models\Auth\User;
7use App\Http\Models\Chart;
8use Illuminate\Support\Carbon;
9use MongoDB\BSON\UTCDateTime;
10
11class ReportingProductivitySpotlightRequest
12{
13    /**
14     * Execute the action.
15     *
16     * @return array
17     */
18    public function execute(ReportingTopUsersRequestDTO $filter)
19    {
20        $start_date = ($filter->fromDate ? Carbon::parse($filter->fromDate) : Carbon::now()->subMonths(12))->startOfMonth();
21        $end_date = ($filter->toDate ? Carbon::parse($filter->toDate) : Carbon::now())->endOfMonth();
22
23        $users = User::select([
24            '_id',
25            'first_name',
26            'last_name',
27            'company_group_id',
28            'company_id',
29            'created_at',
30            'avatar',
31        ]);
32
33        $user_ids = explode(',', $filter->user_ids);
34        $user_ids = array_filter($user_ids, function ($value) {
35            return $value !== '';
36        });
37        if (count($user_ids) > 0) {
38            $users = $users->whereIn('_id', $user_ids);
39        }
40
41        $group_ids = explode(',', $filter->group_ids);
42        $group_ids = array_filter($group_ids, function ($value) {
43            return $value !== '';
44        });
45        if (count($group_ids) > 0) {
46            $users = $users->whereIn('company_group_id', $group_ids);
47        }
48
49        $subgroup_ids = explode(',', $filter->subgroup_ids);
50        $subgroup_ids = array_filter($subgroup_ids, function ($value) {
51            return $value !== '';
52        });
53        if (count($subgroup_ids) > 0) {
54            $users = $users->whereIn('company_group_id', $subgroup_ids);
55        }
56
57        $hasFilter = count($user_ids) || count($group_ids) || count($subgroup_ids);
58
59        $pipeline = [
60            [
61                '$match' => [
62                    'created_at' => [
63                        '$gte' => new UTCDateTime($start_date->getTimestamp() * 1000),
64                        '$lte' => new UTCDateTime($end_date->getTimestamp() * 1000),
65                    ],
66                ],
67            ],
68        ];
69
70        if ($hasFilter) {
71            $users = $users->get();
72
73            $ids = $users->pluck('id')->toArray();
74
75            $pipeline[] = [
76                '$match' => [
77                    'user_id' => ['$in' => $ids],
78                ],
79            ];
80        }
81
82        $pipeline[] = [
83            '$group' => [
84                '_id' => '$month_year',
85                'time_saved' => ['$sum' => '$time_saved'],
86            ],
87        ];
88
89        $pipeline[] = ['$sort' => ['_id.month_year' => 1]];
90
91        $flycut_usages = Chart::withoutGlobalScopes()->raw(function ($collection) use ($pipeline) {
92            return $collection->aggregate($pipeline);
93        });
94
95        $chart = $this->makeLineChartData($flycut_usages, $start_date, $end_date);
96        $total_time_saved = array_sum(array_column($chart, 'time_saved'));
97        $total_users = count($chart);
98        $average_time_saved = $total_users > 0 ? $total_time_saved / $total_users : 0;
99
100        return [
101            'chart' => $chart,
102            'total_time_saved' => number_format($total_time_saved, 2, '.', ','),
103            'average_time_saved' => round($average_time_saved, 2),
104        ];
105    }
106
107    private function makeLineChartData($flycut_usages, $start_date, $end_date)
108    {
109        $line_chart_data = [];
110        $period = new \DatePeriod(
111            new \DateTime($start_date->format('Y-m-01')),
112            new \DateInterval('P1M'),
113            new \DateTime($end_date->format('Y-m-01'))
114        );
115
116        foreach ($period as $date) {
117            $month_year = $date->format('M Y');
118            $test = $flycut_usages->firstWhere('_id', $month_year);
119            $time_saved = $test ? round($test->time_saved, 2) : 0;
120
121            $line_chart_data[$month_year] = [
122                'month_year' => $month_year,
123                'time_saved' => round($time_saved, 2),
124            ];
125        }
126
127        return array_values($line_chart_data);
128    }
129}