Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
61.45% |
51 / 83 |
|
12.50% |
1 / 8 |
CRAP | |
0.00% |
0 / 1 |
ReportRequestService | |
61.45% |
51 / 83 |
|
12.50% |
1 / 8 |
90.68 | |
0.00% |
0 / 1 |
getExchangeRequestData | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
3 | |||
getExchangeRequestForDateRange | |
66.67% |
10 / 15 |
|
0.00% |
0 / 1 |
7.33 | |||
getExchangeRequestForPeriod | |
75.00% |
6 / 8 |
|
0.00% |
0 / 1 |
2.06 | |||
getRequestPeriod | |
60.00% |
3 / 5 |
|
0.00% |
0 / 1 |
2.26 | |||
fetchAndCombineDataFromYears | |
94.44% |
17 / 18 |
|
0.00% |
0 / 1 |
6.01 | |||
filterDataByDateRange | |
80.00% |
4 / 5 |
|
0.00% |
0 / 1 |
4.13 | |||
createFilteredExchangeRequest | |
0.00% |
0 / 19 |
|
0.00% |
0 / 1 |
20 | |||
prepareDownloadArgs | |
75.00% |
6 / 8 |
|
0.00% |
0 / 1 |
5.39 |
1 | <?php |
2 | |
3 | /** |
4 | * @package Zmsstatistic |
5 | * @copyright BerlinOnline Stadtportal GmbH & Co. KG |
6 | **/ |
7 | |
8 | namespace BO\Zmsstatistic\Service; |
9 | |
10 | use BO\Zmsentities\Day; |
11 | use BO\Zmsstatistic\Helper\ReportHelper; |
12 | use DateTime; |
13 | use Exception; |
14 | |
15 | class ReportRequestService |
16 | { |
17 | protected $totals = ['requestscount']; |
18 | |
19 | protected $hashset = [ |
20 | 'requestscount' |
21 | ]; |
22 | |
23 | protected $groupfields = [ |
24 | 'name', |
25 | 'date' |
26 | ]; |
27 | |
28 | /** |
29 | * Get exchange request data based on date range or period |
30 | */ |
31 | public function getExchangeRequestData(string $scopeId, ?array $dateRange, array $args): mixed |
32 | { |
33 | if ($dateRange) { |
34 | return $this->getExchangeRequestForDateRange($scopeId, $dateRange); |
35 | } elseif (isset($args['period'])) { |
36 | return $this->getExchangeRequestForPeriod($scopeId, $args['period']); |
37 | } |
38 | |
39 | return null; |
40 | } |
41 | |
42 | /** |
43 | * Get exchange request data for a specific date range |
44 | */ |
45 | public function getExchangeRequestForDateRange(string $scopeId, array $dateRange): mixed |
46 | { |
47 | if (!isset($dateRange['from']) || !isset($dateRange['to'])) { |
48 | return null; |
49 | } |
50 | $fromDate = $dateRange['from']; |
51 | $toDate = $dateRange['to']; |
52 | |
53 | try { |
54 | $reportHelper = new ReportHelper(); |
55 | $years = $reportHelper->getYearsForDateRange($fromDate, $toDate); |
56 | $combinedData = $this->fetchAndCombineDataFromYears($scopeId, $years); |
57 | |
58 | if (empty($combinedData['data'])) { |
59 | return null; |
60 | } |
61 | |
62 | $filteredData = $this->filterDataByDateRange($combinedData['data'], $fromDate, $toDate); |
63 | |
64 | if (empty($filteredData)) { |
65 | return null; |
66 | } |
67 | |
68 | return $this->createFilteredExchangeRequest($combinedData['entity'], $filteredData, $fromDate, $toDate); |
69 | } catch (Exception $exception) { |
70 | return null; |
71 | } |
72 | } |
73 | |
74 | /** |
75 | * Get exchange request data for a specific period (legacy functionality) |
76 | */ |
77 | public function getExchangeRequestForPeriod(string $scopeId, string $period): mixed |
78 | { |
79 | try { |
80 | return \App::$http |
81 | ->readGetResult('/warehouse/requestscope/' . $scopeId . '/' . $period . '/') |
82 | ->getEntity() |
83 | ->toGrouped($this->groupfields, $this->hashset) |
84 | ->withRequestsSum() |
85 | ->withAverage('processingtime'); |
86 | } catch (Exception $exception) { |
87 | return null; |
88 | } |
89 | } |
90 | |
91 | /** |
92 | * Get request period data for the current scope |
93 | */ |
94 | public function getRequestPeriod(string $scopeId): mixed |
95 | { |
96 | try { |
97 | return \App::$http |
98 | ->readGetResult('/warehouse/requestscope/' . $scopeId . '/') |
99 | ->getEntity(); |
100 | } catch (Exception $exception) { |
101 | return null; |
102 | } |
103 | } |
104 | |
105 | /** |
106 | * Fetch and combine data from multiple years |
107 | */ |
108 | private function fetchAndCombineDataFromYears(string $scopeId, array $years): array |
109 | { |
110 | $combinedData = []; |
111 | $baseEntity = null; |
112 | |
113 | foreach ($years as $year) { |
114 | try { |
115 | $exchangeRequest = \App::$http |
116 | ->readGetResult( |
117 | '/warehouse/requestscope/' . $scopeId . '/' . $year . '/', |
118 | ['groupby' => 'day'] |
119 | ) |
120 | ->getEntity(); |
121 | |
122 | // Use the first successfully fetched entity as the base |
123 | if ($baseEntity === null) { |
124 | $baseEntity = $exchangeRequest; |
125 | } |
126 | |
127 | // Combine data from all years |
128 | if (isset($exchangeRequest->data) && is_array($exchangeRequest->data)) { |
129 | $combinedData = array_merge($combinedData, $exchangeRequest->data); |
130 | } |
131 | } catch (Exception $exception) { |
132 | // Continue with other years - don't fail completely if one year is missing |
133 | } |
134 | } |
135 | |
136 | return [ |
137 | 'entity' => $baseEntity, |
138 | 'data' => $combinedData |
139 | ]; |
140 | } |
141 | |
142 | /** |
143 | * Filter data array by date range |
144 | */ |
145 | private function filterDataByDateRange(array $data, string $fromDate, string $toDate): array |
146 | { |
147 | $filteredData = []; |
148 | foreach ($data as $row) { |
149 | if ($row[3] >= $fromDate && $row[3] <= $toDate) { |
150 | $filteredData[] = $row; |
151 | } |
152 | } |
153 | return $filteredData; |
154 | } |
155 | |
156 | /** |
157 | * Create filtered exchange request with updated properties |
158 | */ |
159 | private function createFilteredExchangeRequest( |
160 | $exchangeRequestFull, |
161 | array $filteredData, |
162 | string $fromDate, |
163 | string $toDate |
164 | ): mixed { |
165 | $exchangeRequest = clone $exchangeRequestFull; |
166 | $exchangeRequest->data = $filteredData; |
167 | |
168 | if (!isset($exchangeRequest->period)) { |
169 | $exchangeRequest->period = 'day'; |
170 | } |
171 | |
172 | $exchangeRequest->firstDay = (new Day())->setDateTime(new DateTime($fromDate)); |
173 | $exchangeRequest->lastDay = (new Day())->setDateTime(new DateTime($toDate)); |
174 | |
175 | if (!empty($filteredData)) { |
176 | $exchangeRequest = $exchangeRequest |
177 | ->toGrouped($this->groupfields, $this->hashset) |
178 | ->withRequestsSum() |
179 | ->withAverage('processingtime'); |
180 | |
181 | if (is_array($exchangeRequest->data)) { |
182 | $locale = \App::$supportedLanguages[\App::$locale]['locale'] ?? 'de_DE'; |
183 | $collator = new \Collator($locale); |
184 | uksort($exchangeRequest->data, static function ($itemA, $itemB) use ($collator) { |
185 | return $collator->compare($itemA, $itemB); |
186 | }); |
187 | } |
188 | |
189 | return $exchangeRequest; |
190 | } |
191 | |
192 | return $exchangeRequest->toHashed(); |
193 | } |
194 | |
195 | /** |
196 | * Prepare download arguments for request report |
197 | */ |
198 | public function prepareDownloadArgs( |
199 | array $args, |
200 | mixed $exchangeRequest, |
201 | ?array $dateRange, |
202 | array $selectedScopes = [] |
203 | ): array { |
204 | $args['category'] = 'requestscope'; |
205 | |
206 | if ($dateRange) { |
207 | $args['period'] = $dateRange['from'] . '_' . $dateRange['to']; |
208 | } |
209 | |
210 | if (!empty($selectedScopes)) { |
211 | $args['selectedScopes'] = $selectedScopes; |
212 | } |
213 | |
214 | if ($exchangeRequest && count($exchangeRequest->data)) { |
215 | $args['reports'][] = $exchangeRequest; |
216 | } |
217 | |
218 | return $args; |
219 | } |
220 | } |