Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
83.72% covered (warning)
83.72%
72 / 86
25.00% covered (danger)
25.00%
2 / 8
CRAP
0.00% covered (danger)
0.00%
0 / 1
ReportWaitingService
83.72% covered (warning)
83.72%
72 / 86
25.00% covered (danger)
25.00%
2 / 8
35.15
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
66.67% covered (warning)
66.67%
10 / 15
0.00% covered (danger)
0.00%
0 / 1
7.33
 getExchangeWaitingForPeriod
84.62% covered (warning)
84.62%
11 / 13
0.00% covered (danger)
0.00%
0 / 1
2.01
 getWaitingPeriod
60.00% covered (warning)
60.00%
3 / 5
0.00% covered (danger)
0.00%
0 / 1
2.26
 fetchAndCombineDataFromYears
94.44% covered (success)
94.44%
17 / 18
0.00% covered (danger)
0.00%
0 / 1
6.01
 filterDataByDateRange
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
4
 createFilteredExchangeWaiting
88.24% covered (warning)
88.24%
15 / 17
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    ];
27
28    protected $groupfields = [
29        'date',
30        'hour'
31    ];
32
33    /**
34     * Get exchange waiting data based on date range or period
35     */
36    public function getExchangeWaitingData(string $scopeId, ?array $dateRange, array $args): mixed
37    {
38        if ($dateRange) {
39            return $this->getExchangeWaitingForDateRange($scopeId, $dateRange);
40        }
41
42        return isset($args['period'])
43            ? $this->getExchangeWaitingForPeriod($scopeId, $args['period'])
44            : null;
45    }
46
47    /**
48     * Get exchange waiting data for a specific date range
49     */
50    public function getExchangeWaitingForDateRange(string $scopeId, array $dateRange): mixed
51    {
52        if (!isset($dateRange['from']) || !isset($dateRange['to'])) {
53            return null;
54        }
55
56        $fromDate = $dateRange['from'];
57        $toDate = $dateRange['to'];
58
59        try {
60            $reportHelper = new ReportHelper();
61            $years = $reportHelper->getYearsForDateRange($fromDate, $toDate);
62            $combinedData = $this->fetchAndCombineDataFromYears($scopeId, $years);
63
64            if (empty($combinedData['data'])) {
65                return null;
66            }
67
68            $filteredData = $this->filterDataByDateRange($combinedData['data'], $fromDate, $toDate);
69
70            if (empty($filteredData)) {
71                return null;
72            }
73
74            return $this->createFilteredExchangeWaiting($combinedData['entity'], $filteredData, $fromDate, $toDate);
75        } catch (Exception $exception) {
76            return null;
77        }
78    }
79
80    /**
81     * Get exchange waiting data for a specific period (legacy functionality)
82     */
83    public function getExchangeWaitingForPeriod(string $scopeId, string $period): mixed
84    {
85        try {
86            $exchangeWaiting = \App::$http
87                ->readGetResult('/warehouse/waitingscope/' . $scopeId . '/' . $period . '/')
88                ->getEntity()
89                ->toGrouped($this->groupfields, $this->hashset)
90                ->withMaxByHour($this->hashset)
91                ->withMaxAndAverageFromWaitingTime();
92
93            // Apply extra ReportHelper processing
94            $exchangeWaiting = ReportHelper::withMaxAndAverage($exchangeWaiting, 'waitingtime');
95            $exchangeWaiting = ReportHelper::withMaxAndAverage($exchangeWaiting, 'waitingtime_termin');
96            $exchangeWaiting = ReportHelper::withMaxAndAverage($exchangeWaiting, 'waytime');
97            $exchangeWaiting = ReportHelper::withMaxAndAverage($exchangeWaiting, 'waytime_termin');
98
99            return $exchangeWaiting;
100        } catch (Exception $exception) {
101            return null;
102        }
103    }
104
105    /**
106     * Get waiting period data for the current scope
107     */
108    public function getWaitingPeriod(string $scopeId): mixed
109    {
110        try {
111            return \App::$http
112                ->readGetResult('/warehouse/waitingscope/' . $scopeId . '/')
113                ->getEntity();
114        } catch (Exception $exception) {
115            return null;
116        }
117    }
118
119    /**
120     * Fetch and combine data from multiple years
121     */
122    private function fetchAndCombineDataFromYears(string $scopeId, array $years): array
123    {
124        $combinedData = [];
125        $baseEntity = null;
126
127        foreach ($years as $year) {
128            try {
129                $exchangeWaiting = \App::$http
130                    ->readGetResult(
131                        '/warehouse/waitingscope/' . $scopeId . '/' . $year . '/',
132                        ['groupby' => 'day']
133                    )
134                    ->getEntity();
135
136                if ($baseEntity === null) {
137                    $baseEntity = $exchangeWaiting;
138                }
139
140                if (isset($exchangeWaiting->data) && is_array($exchangeWaiting->data)) {
141                    $combinedData = array_merge($combinedData, $exchangeWaiting->data);
142                }
143            } catch (Exception $exception) {
144                // continue with other years
145            }
146        }
147
148        return [
149            'entity' => $baseEntity,
150            'data' => $combinedData
151        ];
152    }
153
154    /**
155     * Filter data array by date range
156     */
157    private function filterDataByDateRange(array $data, string $fromDate, string $toDate): array
158    {
159        $filteredData = [];
160        foreach ($data as $row) {
161            if ($row[1] >= $fromDate && $row[1] <= $toDate) {
162                $filteredData[] = $row;
163            }
164        }
165        return $filteredData;
166    }
167
168    /**
169     * Create filtered exchange waiting with updated properties
170     */
171    private function createFilteredExchangeWaiting(
172        $exchangeWaitingFull,
173        array $filteredData,
174        string $fromDate,
175        string $toDate
176    ): mixed {
177        $exchangeWaiting = clone $exchangeWaitingFull;
178        $exchangeWaiting->data = $filteredData;
179
180        if (!isset($exchangeWaiting->period)) {
181            $exchangeWaiting->period = 'day';
182        }
183
184        $exchangeWaiting->firstDay = (new Day())->setDateTime(new DateTime($fromDate));
185        $exchangeWaiting->lastDay = (new Day())->setDateTime(new DateTime($toDate));
186
187        if (!empty($filteredData)) {
188            $exchangeWaiting = $exchangeWaiting
189                ->toGrouped($this->groupfields, $this->hashset)
190                ->withMaxByHour($this->hashset)
191                ->withMaxAndAverageFromWaitingTime();
192
193            $exchangeWaiting = ReportHelper::withMaxAndAverage($exchangeWaiting, 'waitingtime');
194            $exchangeWaiting = ReportHelper::withMaxAndAverage($exchangeWaiting, 'waitingtime_termin');
195            $exchangeWaiting = ReportHelper::withMaxAndAverage($exchangeWaiting, 'waytime');
196            $exchangeWaiting = ReportHelper::withMaxAndAverage($exchangeWaiting, 'waytime_termin');
197
198            return $exchangeWaiting;
199        }
200
201        return $exchangeWaiting->toHashed();
202    }
203
204    /**
205     * Prepare download arguments for waiting report
206     */
207    public function prepareDownloadArgs(
208        array $args,
209        mixed $exchangeWaiting,
210        ?array $dateRange,
211        array $selectedScopes = []
212    ): array {
213        $args['category'] = 'waitingscope';
214
215        if ($dateRange) {
216            $args['period'] = $dateRange['from'] . '_' . $dateRange['to'];
217        }
218
219        if (!empty($selectedScopes)) {
220            $args['selectedScopes'] = $selectedScopes;
221        }
222
223        if ($exchangeWaiting && count($exchangeWaiting->data)) {
224            $args['reports'][] = $exchangeWaiting;
225        }
226
227        return $args;
228    }
229}