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