Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
83.15% covered (warning)
83.15%
74 / 89
0.00% covered (danger)
0.00%
0 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
ReportRequestService
83.15% covered (warning)
83.15%
74 / 89
0.00% covered (danger)
0.00%
0 / 7
33.03
0.00% covered (danger)
0.00%
0 / 1
 getExchangeRequestData
85.71% covered (warning)
85.71%
6 / 7
0.00% covered (danger)
0.00%
0 / 1
4.05
 getExchangeRequestForDateRange
76.47% covered (warning)
76.47%
13 / 17
0.00% covered (danger)
0.00%
0 / 1
5.33
 getExchangeRequestForPeriod
81.82% covered (warning)
81.82%
9 / 11
0.00% covered (danger)
0.00%
0 / 1
2.02
 getRequestPeriod
60.00% covered (warning)
60.00%
3 / 5
0.00% covered (danger)
0.00%
0 / 1
2.26
 fetchAndCombineDataFromYears
92.00% covered (success)
92.00%
23 / 25
0.00% covered (danger)
0.00%
0 / 1
7.03
 createFilteredExchangeRequest
87.50% covered (warning)
87.50%
14 / 16
0.00% covered (danger)
0.00%
0 / 1
4.03
 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 ReportRequestService
16{
17    protected array $totals = ['requestscount'];
18
19    protected array $hashset = [
20        'requestscount'
21    ];
22
23    protected array $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 ($scopeId === '') {
34            return null;
35        }
36
37        if (ReportHelper::hasValues($dateRange)) {
38            return $this->getExchangeRequestForDateRange($scopeId, $dateRange);
39        }
40
41        return isset($args['period'])
42            ? $this->getExchangeRequestForPeriod($scopeId, $args['period'])
43            : null;
44    }
45
46    /**
47     * Get exchange request data for a specific date range
48     */
49    public function getExchangeRequestForDateRange(string $scopeId, array $dateRange): mixed
50    {
51        if (!isset($dateRange['from']) || !isset($dateRange['to'])) {
52            return null;
53        }
54        $fromDate = $dateRange['from'];
55        $toDate = $dateRange['to'];
56
57        try {
58            $reportHelper = new ReportHelper();
59            $years = $reportHelper->getYearsForDateRange($fromDate, $toDate);
60            $combinedData = $this->fetchAndCombineDataFromYears($reportHelper, $scopeId, $years, $fromDate, $toDate);
61
62            if (empty($combinedData['data'])) {
63                return null;
64            }
65
66            return $this->createFilteredExchangeRequest(
67                $combinedData['entity'],
68                $combinedData['data'],
69                $fromDate,
70                $toDate
71            );
72        } catch (Exception $exception) {
73            return null;
74        }
75    }
76
77    /**
78     * Get exchange request data for a specific period (legacy functionality)
79     */
80    public function getExchangeRequestForPeriod(string $scopeId, string $period): mixed
81    {
82        try {
83            $exchangeRequest = \App::http()
84                ->readGetResult('/warehouse/requestscope/' . $scopeId . '/' . $period . '/')
85                ->getEntity();
86            /** @var mixed $exchangeRequest */
87            return $exchangeRequest
88                ->toGrouped($this->groupfields, $this->hashset)
89                ->withRequestsSum()
90                ->withAverage('processingtime')
91                ->withWeightedAverageProcessingTime()
92                ->withUncapturedRequestRowSortedLast();
93        } catch (Exception $exception) {
94            return null;
95        }
96    }
97
98    /**
99     * Get request period data for the current scope
100     */
101    public function getRequestPeriod(string $scopeId): mixed
102    {
103        try {
104            return \App::http()
105                ->readGetResult('/warehouse/requestscope/' . $scopeId . '/')
106                ->getEntity();
107        } catch (Exception $exception) {
108            return null;
109        }
110    }
111
112    /**
113     * Fetch and combine data from multiple years
114     */
115    private function fetchAndCombineDataFromYears(ReportHelper $reportHelper, string $scopeId, array $years, string $fromDate, string $toDate): array
116    {
117        $combinedData = [];
118        $baseEntity = null;
119
120        foreach ($years as $year) {
121            $bounds = $reportHelper->getYearDateBounds($year, $fromDate, $toDate);
122            if ($bounds === null) {
123                continue;
124            }
125            try {
126                $exchangeRequest = \App::http()
127                    ->readGetResult(
128                        '/warehouse/requestscope/' . $scopeId . '/' . $year . '/',
129                        [
130                            'groupby' => 'day',
131                            'fromDate' => $bounds['from'],
132                            'toDate' => $bounds['to'],
133                        ]
134                    )
135                    ->getEntity();
136
137                // Use the first successfully fetched entity as the base
138                if ($baseEntity === null) {
139                    $baseEntity = $exchangeRequest;
140                }
141
142                // Combine data from all years
143                if (isset($exchangeRequest->data) && is_array($exchangeRequest->data)) {
144                    $combinedData = array_merge($combinedData, $exchangeRequest->data);
145                }
146            } catch (Exception $exception) {
147                // Continue with other years - don't fail completely if one year is missing
148            }
149        }
150
151        return [
152            'entity' => $baseEntity,
153            'data' => $combinedData
154        ];
155    }
156
157    /**
158     * Create filtered exchange request with updated properties
159     */
160    private function createFilteredExchangeRequest(
161        mixed $exchangeRequestBasic,
162        array $filteredData,
163        string $fromDate,
164        string $toDate
165    ): mixed {
166        $exchangeRequest = $exchangeRequestBasic;
167        $exchangeRequest->data = $filteredData;
168
169        if (!isset($exchangeRequest->period)) {
170            $exchangeRequest->period = 'day';
171        }
172
173        $exchangeRequest->firstDay = (new Day())->setDateTime(new DateTime($fromDate));
174        $exchangeRequest->lastDay = (new Day())->setDateTime(new DateTime($toDate));
175
176        if (!empty($filteredData)) {
177            $exchangeRequest = $exchangeRequest
178                ->toGrouped($this->groupfields, $this->hashset)
179                ->withRequestsSum()
180                ->withAverage('processingtime')
181                ->withWeightedAverageProcessingTime();
182
183            if (is_array($exchangeRequest->data)) {
184                $exchangeRequest = $exchangeRequest->withUncapturedRequestRowSortedLast();
185            }
186
187            return $exchangeRequest;
188        }
189
190        return $exchangeRequest->toHashed();
191    }
192
193    /**
194     * Prepare download arguments for request report
195     */
196    public function prepareDownloadArgs(
197        array $args,
198        mixed $exchangeRequest,
199        ?array $dateRange,
200        array $selectedScopes = []
201    ): array {
202        $args['category'] = 'requestscope';
203
204        if (ReportHelper::hasValues($dateRange)) {
205            $args['period'] = $dateRange['from'] . '_' . $dateRange['to'];
206        }
207
208        if (!empty($selectedScopes)) {
209            $args['selectedScopes'] = $selectedScopes;
210        }
211
212        if ($exchangeRequest && count($exchangeRequest->data)) {
213            $args['reports'][] = $exchangeRequest;
214        }
215
216        return $args;
217    }
218}