Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
86.14% covered (warning)
86.14%
87 / 101
0.00% covered (danger)
0.00%
0 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
ReportWaitingService
86.14% covered (warning)
86.14%
87 / 101
0.00% covered (danger)
0.00%
0 / 7
28.94
0.00% covered (danger)
0.00%
0 / 1
 getExchangeWaitingData
85.71% covered (warning)
85.71%
6 / 7
0.00% covered (danger)
0.00%
0 / 1
4.05
 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 ($scopeId === '') {
42            return null;
43        }
44
45        if ($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($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            $exchangeWaiting = \App::$http
93                ->readGetResult('/warehouse/waitingscope/' . $scopeId . '/' . $period . '/')
94                ->getEntity()
95                ->toGrouped($this->groupfields, $this->hashset);
96
97            $exchangeWaiting = ReportHelper::withTotalCustomers($exchangeWaiting);
98
99            $exchangeWaiting = $exchangeWaiting
100                ->withMaxByHour($this->hashset)
101                ->withMaxAndAverageFromWaitingTime();
102
103            // Apply extra ReportHelper processing
104            $exchangeWaiting = ReportHelper::withMaxAndAverage($exchangeWaiting, 'waitingtime');
105            $exchangeWaiting = ReportHelper::withMaxAndAverage($exchangeWaiting, 'waitingtime_termin');
106            $exchangeWaiting = ReportHelper::withMaxAndAverage($exchangeWaiting, 'waytime');
107            $exchangeWaiting = ReportHelper::withMaxAndAverage($exchangeWaiting, 'waytime_termin');
108
109            // per-date max/avg for total
110            $exchangeWaiting = ReportHelper::withMaxAndAverage($exchangeWaiting, 'waitingtime_total');
111            $exchangeWaiting = ReportHelper::withMaxAndAverage($exchangeWaiting, 'waytime_total');
112
113            // global max/avg for total
114            $exchangeWaiting = ReportHelper::withGlobalMaxAndAverage($exchangeWaiting, 'waitingtime_total');
115            $exchangeWaiting = ReportHelper::withGlobalMaxAndAverage($exchangeWaiting, 'waytime_total');
116
117            return $exchangeWaiting;
118        } catch (Exception $exception) {
119            return null;
120        }
121    }
122
123    /**
124     * Get waiting period data for the current scope
125     */
126    public function getWaitingPeriod(string $scopeId): mixed
127    {
128        try {
129            return \App::$http
130                ->readGetResult('/warehouse/waitingscope/' . $scopeId . '/')
131                ->getEntity();
132        } catch (Exception $exception) {
133            return null;
134        }
135    }
136
137    /**
138     * Fetch and combine data from multiple years
139     */
140    private function fetchAndCombineDataFromYears(string $scopeId, array $years, string $fromDate, string $toDate): array
141    {
142        $combinedData = [];
143        $baseEntity = null;
144
145        foreach ($years as $year) {
146            try {
147                $exchangeWaiting = \App::$http
148                    ->readGetResult(
149                        '/warehouse/waitingscope/' . $scopeId . '/' . $year . '/',
150                        [
151                            'groupby' => 'day',
152                            'fromDate' => $fromDate,
153                            'toDate' => $toDate
154                        ]
155                    )
156                    ->getEntity();
157
158                if (isset($exchangeWaiting->data) && is_array($exchangeWaiting->data)) {
159                    $combinedData = array_merge($combinedData, $exchangeWaiting->data);
160                }
161
162                if ($baseEntity === null) {
163                    unset($exchangeWaiting->data);
164                    $baseEntity = $exchangeWaiting;
165                }
166            } catch (Exception $exception) {
167                // continue with other years
168            }
169        }
170
171        return [
172            'entity' => $baseEntity,
173            'data' => $combinedData
174        ];
175    }
176
177    /**
178     * Create filtered exchange waiting with updated properties
179     */
180    private function createFilteredExchangeWaiting(
181        $exchangeWaitingBasic,
182        array $filteredData,
183        string $fromDate,
184        string $toDate
185    ): mixed {
186        $exchangeWaiting = $exchangeWaitingBasic;
187        $exchangeWaiting->data = $filteredData;
188
189        if (!isset($exchangeWaiting->period)) {
190            $exchangeWaiting->period = 'day';
191        }
192
193        $exchangeWaiting->firstDay = (new Day())->setDateTime(new DateTime($fromDate));
194        $exchangeWaiting->lastDay = (new Day())->setDateTime(new DateTime($toDate));
195
196        if (!empty($filteredData)) {
197            $exchangeWaiting = $exchangeWaiting
198                ->toGrouped($this->groupfields, $this->hashset);
199
200            $exchangeWaiting = ReportHelper::withTotalCustomers($exchangeWaiting);
201
202            $exchangeWaiting = $exchangeWaiting->withMaxByHour($this->hashset)
203                ->withMaxAndAverageFromWaitingTime();
204
205            $exchangeWaiting = ReportHelper::withMaxAndAverage($exchangeWaiting, 'waitingtime');
206            $exchangeWaiting = ReportHelper::withMaxAndAverage($exchangeWaiting, 'waitingtime_termin');
207            $exchangeWaiting = ReportHelper::withMaxAndAverage($exchangeWaiting, 'waytime');
208            $exchangeWaiting = ReportHelper::withMaxAndAverage($exchangeWaiting, 'waytime_termin');
209
210            $exchangeWaiting = ReportHelper::withMaxAndAverage($exchangeWaiting, 'waitingtime_total');
211            $exchangeWaiting = ReportHelper::withMaxAndAverage($exchangeWaiting, 'waytime_total');
212            $exchangeWaiting = ReportHelper::withGlobalMaxAndAverage($exchangeWaiting, 'waitingtime_total');
213            $exchangeWaiting = ReportHelper::withGlobalMaxAndAverage($exchangeWaiting, 'waytime_total');
214
215            return $exchangeWaiting;
216        }
217
218        return $exchangeWaiting->toHashed();
219    }
220
221    /**
222     * Prepare download arguments for waiting report
223     */
224    public function prepareDownloadArgs(
225        array $args,
226        mixed $exchangeWaiting,
227        ?array $dateRange,
228        array $selectedScopes = []
229    ): array {
230        $args['category'] = 'waitingscope';
231
232        if ($dateRange) {
233            $args['period'] = $dateRange['from'] . '_' . $dateRange['to'];
234        }
235
236        if (!empty($selectedScopes)) {
237            $args['selectedScopes'] = $selectedScopes;
238        }
239
240        if ($exchangeWaiting && count($exchangeWaiting->data)) {
241            $args['reports'][] = $exchangeWaiting;
242        }
243
244        return $args;
245    }
246}