Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
83.95% covered (warning)
83.95%
68 / 81
14.29% covered (danger)
14.29%
1 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
ReportRequestService
83.95% covered (warning)
83.95%
68 / 81
14.29% covered (danger)
14.29%
1 / 7
30.01
0.00% covered (danger)
0.00%
0 / 1
 getExchangeRequestData
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 getExchangeRequestForDateRange
76.47% covered (warning)
76.47%
13 / 17
0.00% covered (danger)
0.00%
0 / 1
5.33
 getExchangeRequestForPeriod
77.78% covered (warning)
77.78%
7 / 9
0.00% covered (danger)
0.00%
0 / 1
2.04
 getRequestPeriod
60.00% covered (warning)
60.00%
3 / 5
0.00% covered (danger)
0.00%
0 / 1
2.26
 fetchAndCombineDataFromYears
95.45% covered (success)
95.45%
21 / 22
0.00% covered (danger)
0.00%
0 / 1
6
 createFilteredExchangeRequest
86.67% covered (warning)
86.67%
13 / 15
0.00% covered (danger)
0.00%
0 / 1
4.04
 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 $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        }
36
37        return isset($args['period'])
38            ? $this->getExchangeRequestForPeriod($scopeId, $args['period'])
39            : 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, $fromDate, $toDate);
57
58            if (empty($combinedData['data'])) {
59                return null;
60            }
61
62            return $this->createFilteredExchangeRequest(
63                $combinedData['entity'],
64                $combinedData['data'],
65                $fromDate,
66                $toDate
67            );
68        } catch (Exception $exception) {
69            return null;
70        }
71    }
72
73    /**
74     * Get exchange request data for a specific period (legacy functionality)
75     */
76    public function getExchangeRequestForPeriod(string $scopeId, string $period): mixed
77    {
78        try {
79            return \App::$http
80                ->readGetResult('/warehouse/requestscope/' . $scopeId . '/' . $period . '/')
81                ->getEntity()
82                ->toGrouped($this->groupfields, $this->hashset)
83                ->withRequestsSum()
84                ->withAverage('processingtime')
85                ->withUncapturedRequestRowSortedLast();
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, string $fromDate, string $toDate): 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                        [
119                            'groupby' => 'day',
120                            'fromDate' => $fromDate,
121                            'toDate' => $toDate
122                        ]
123                    )
124                    ->getEntity();
125
126                // Use the first successfully fetched entity as the base
127                if ($baseEntity === null) {
128                    $baseEntity = $exchangeRequest;
129                }
130
131                // Combine data from all years
132                if (isset($exchangeRequest->data) && is_array($exchangeRequest->data)) {
133                    $combinedData = array_merge($combinedData, $exchangeRequest->data);
134                }
135            } catch (Exception $exception) {
136                // Continue with other years - don't fail completely if one year is missing
137            }
138        }
139
140        return [
141            'entity' => $baseEntity,
142            'data' => $combinedData
143        ];
144    }
145
146    /**
147     * Create filtered exchange request with updated properties
148     */
149    private function createFilteredExchangeRequest(
150        $exchangeRequestBasic,
151        array $filteredData,
152        string $fromDate,
153        string $toDate
154    ): mixed {
155        $exchangeRequest = $exchangeRequestBasic;
156        $exchangeRequest->data = $filteredData;
157
158        if (!isset($exchangeRequest->period)) {
159            $exchangeRequest->period = 'day';
160        }
161
162        $exchangeRequest->firstDay = (new Day())->setDateTime(new DateTime($fromDate));
163        $exchangeRequest->lastDay = (new Day())->setDateTime(new DateTime($toDate));
164
165        if (!empty($filteredData)) {
166            $exchangeRequest = $exchangeRequest
167                ->toGrouped($this->groupfields, $this->hashset)
168                ->withRequestsSum()
169                ->withAverage('processingtime');
170
171            if (is_array($exchangeRequest->data)) {
172                $exchangeRequest = $exchangeRequest->withUncapturedRequestRowSortedLast();
173            }
174
175            return $exchangeRequest;
176        }
177
178        return $exchangeRequest->toHashed();
179    }
180
181    /**
182     * Prepare download arguments for request report
183     */
184    public function prepareDownloadArgs(
185        array $args,
186        mixed $exchangeRequest,
187        ?array $dateRange,
188        array $selectedScopes = []
189    ): array {
190        $args['category'] = 'requestscope';
191
192        if ($dateRange) {
193            $args['period'] = $dateRange['from'] . '_' . $dateRange['to'];
194        }
195
196        if (!empty($selectedScopes)) {
197            $args['selectedScopes'] = $selectedScopes;
198        }
199
200        if ($exchangeRequest && count($exchangeRequest->data)) {
201            $args['reports'][] = $exchangeRequest;
202        }
203
204        return $args;
205    }
206}