Lines 85.71% 90 / 105
Methods 0.00% 0 / 7
Classes 0.00% 0 / 1
Name Lines Methods CRAP
 getExchangeWaitingData 85.71% 6 / 7 0.00% 0 / 1 4.05
 getExchangeWaitingForDateRange 76.47% 13 / 17 0.00% 0 / 1 5.33
 getExchangeWaitingForPeriod 90.00% 18 / 20 0.00% 0 / 1 2.00
 getWaitingPeriod 60.00% 3 / 5 0.00% 0 / 1 2.26
 fetchAndCombineDataFromYears 92.30% 24 / 26 0.00% 0 / 1 7.02
 createFilteredExchangeWaiting 90.90% 20 / 22 0.00% 0 / 1 3.01
 prepareDownloadArgs 75.00% 6 / 8 0.00% 0 / 1 5.39
15class ReportWaitingService
16{
17    protected array $hashset = [
18        'waitingcount',
19        'waitingtime',
20        'waitingcalculated',
21        'waitingcount_termin',
22        'waitingtime_termin',
23        'waitingcalculated_termin',
24        'waytime',
25        'waytime_termin',
26        'waitingcount_total',
27        'waitingtime_total',
28        'waytime_total',
29    ];
30
31    protected array $groupfields = [
32        'date',
33        'hour'
34    ];
35
36    /**
37     * Get exchange waiting data based on date range or period
38     */
39    public function getExchangeWaitingData(string $scopeId, ?array $dateRange, array $args): mixed
40    {
41        if ($scopeId === '') {
42            return null;
43        }
44
45        if (ReportHelper::hasValues($dateRange)) {
46            return $this->getExchangeWaitingForDateRange($scopeId, $dateRange);
47        }
48
49        return isset($args['period'])
50            ? $this->getExchangeWaitingForPeriod($scopeId, $args['period'])
51            : null;
52    }
53
54    /**
55     * Get exchange waiting data for a specific date range
56     */
57    public function getExchangeWaitingForDateRange(string $scopeId, array $dateRange): mixed
58    {
59        if (!isset($dateRange['from']) || !isset($dateRange['to'])) {
60            return null;
61        }
62
63        $fromDate = $dateRange['from'];
64        $toDate = $dateRange['to'];
65
66        try {
67            $reportHelper = new ReportHelper();
68            $years = $reportHelper->getYearsForDateRange($fromDate, $toDate);
69            $combinedData = $this->fetchAndCombineDataFromYears($reportHelper, $scopeId, $years, $fromDate, $toDate);
70
71            if (empty($combinedData['data'])) {
72                return null;
73            }
74
75            return $this->createFilteredExchangeWaiting(
76                $combinedData['entity'],
77                $combinedData['data'],
78                $fromDate,
79                $toDate
80            );
81        } catch (Exception $exception) {
82            return null;
83        }
84    }
85
86    /**
87     * Get exchange waiting data for a specific period (legacy functionality)
88     */
89    public function getExchangeWaitingForPeriod(string $scopeId, string $period): mixed
90    {
91        try {
92            /** @var mixed $entity */
93            $entity = \App::http()
94                ->readGetResult('/warehouse/waitingscope/' . $scopeId . '/' . $period . '/')
95                ->getEntity();
96            $exchangeWaiting = $entity
97                ->toGrouped($this->groupfields, $this->hashset);
98
99            $exchangeWaiting = ReportHelper::withTotalCustomers($exchangeWaiting);
100
101            $exchangeWaiting = $exchangeWaiting
102                ->withMaxByHour($this->hashset)
103                ->withMaxAndAverageFromWaitingTime();
104
105            // Apply extra ReportHelper processing
106            $exchangeWaiting = ReportHelper::withMaxAndAverage($exchangeWaiting, 'waitingtime');
107            $exchangeWaiting = ReportHelper::withMaxAndAverage($exchangeWaiting, 'waitingtime_termin');
108            $exchangeWaiting = ReportHelper::withMaxAndAverage($exchangeWaiting, 'waytime');
109            $exchangeWaiting = ReportHelper::withMaxAndAverage($exchangeWaiting, 'waytime_termin');
110
111            // per-date max/avg for total
112            $exchangeWaiting = ReportHelper::withMaxAndAverage($exchangeWaiting, 'waitingtime_total');
113            $exchangeWaiting = ReportHelper::withMaxAndAverage($exchangeWaiting, 'waytime_total');
114
115            // global max/avg for total
116            $exchangeWaiting = ReportHelper::withGlobalMaxAndAverage($exchangeWaiting, 'waitingtime_total');
117            $exchangeWaiting = ReportHelper::withGlobalMaxAndAverage($exchangeWaiting, 'waytime_total');
118
119            return $exchangeWaiting;
120        } catch (Exception $exception) {
121            return null;
122        }
123    }
124
125    /**
126     * Get waiting period data for the current scope
127     */
128    public function getWaitingPeriod(string $scopeId): mixed
129    {
130        try {
131            return \App::http()
132                ->readGetResult('/warehouse/waitingscope/' . $scopeId . '/')
133                ->getEntity();
134        } catch (Exception $exception) {
135            return null;
136        }
137    }
138
139    /**
140     * Fetch and combine data from multiple years
141     */
142    private function fetchAndCombineDataFromYears(ReportHelper $reportHelper, string $scopeId, array $years, string $fromDate, string $toDate): array
143    {
144        $combinedData = [];
145        $baseEntity = null;
146
147        foreach ($years as $year) {
148            $bounds = $reportHelper->getYearDateBounds($year, $fromDate, $toDate);
149            if ($bounds === null) {
150                continue;
151            }
152            try {
153                $exchangeWaiting = \App::http()
154                    ->readGetResult(
155                        '/warehouse/waitingscope/' . $scopeId . '/' . $year . '/',
156                        [
157                            'groupby' => 'day',
158                            'fromDate' => $bounds['from'],
159                            'toDate' => $bounds['to'],
160                        ]
161                    )
162                    ->getEntity();
163
164                if (isset($exchangeWaiting->data) && is_array($exchangeWaiting->data)) {
165                    $combinedData = array_merge($combinedData, $exchangeWaiting->data);
166                }
167
168                if ($baseEntity === null) {
169                    unset($exchangeWaiting->data);
170                    $baseEntity = $exchangeWaiting;
171                }
172            } catch (Exception $exception) {
173                // continue with other years
174            }
175        }
176
177        return [
178            'entity' => $baseEntity,
179            'data' => $combinedData
180        ];
181    }
182
183    /**
184     * Create filtered exchange waiting with updated properties
185     */
186    private function createFilteredExchangeWaiting(
187        mixed $exchangeWaitingBasic,
188        array $filteredData,
189        string $fromDate,
190        string $toDate
191    ): mixed {
192        $exchangeWaiting = $exchangeWaitingBasic;
193        $exchangeWaiting->data = $filteredData;
194
195        if (!isset($exchangeWaiting->period)) {
196            $exchangeWaiting->period = 'day';
197        }
198
199        $exchangeWaiting->firstDay = (new Day())->setDateTime(new DateTime($fromDate));
200        $exchangeWaiting->lastDay = (new Day())->setDateTime(new DateTime($toDate));
201
202        if (!empty($filteredData)) {
203            $exchangeWaiting = $exchangeWaiting
204                ->toGrouped($this->groupfields, $this->hashset);
205
206            $exchangeWaiting = ReportHelper::withTotalCustomers($exchangeWaiting);
207
208            $exchangeWaiting = $exchangeWaiting->withMaxByHour($this->hashset)
209                ->withMaxAndAverageFromWaitingTime();
210
211            $exchangeWaiting = ReportHelper::withMaxAndAverage($exchangeWaiting, 'waitingtime');
212            $exchangeWaiting = ReportHelper::withMaxAndAverage($exchangeWaiting, 'waitingtime_termin');
213            $exchangeWaiting = ReportHelper::withMaxAndAverage($exchangeWaiting, 'waytime');
214            $exchangeWaiting = ReportHelper::withMaxAndAverage($exchangeWaiting, 'waytime_termin');
215
216            $exchangeWaiting = ReportHelper::withMaxAndAverage($exchangeWaiting, 'waitingtime_total');
217            $exchangeWaiting = ReportHelper::withMaxAndAverage($exchangeWaiting, 'waytime_total');
218            $exchangeWaiting = ReportHelper::withGlobalMaxAndAverage($exchangeWaiting, 'waitingtime_total');
219            $exchangeWaiting = ReportHelper::withGlobalMaxAndAverage($exchangeWaiting, 'waytime_total');
220
221            return $exchangeWaiting;
222        }
223
224        return $exchangeWaiting->toHashed();
225    }
226
227    /**
228     * Prepare download arguments for waiting report
229     */
230    public function prepareDownloadArgs(
231        array $args,
232        mixed $exchangeWaiting,
233        ?array $dateRange,
234        array $selectedScopes = []
235    ): array {
236        $args['category'] = 'waitingscope';
237
238        if (ReportHelper::hasValues($dateRange)) {
239            $args['period'] = $dateRange['from'] . '_' . $dateRange['to'];
240        }
241
242        if (!empty($selectedScopes)) {
243            $args['selectedScopes'] = $selectedScopes;
244        }
245
246        if ($exchangeWaiting && count($exchangeWaiting->data)) {
247            $args['reports'][] = $exchangeWaiting;
248        }
249
250        return $args;
251    }
252}