Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
82.95% covered (warning)
82.95%
73 / 88
0.00% covered (danger)
0.00%
0 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
ReportRequestService
82.95% covered (warning)
82.95%
73 / 88
0.00% covered (danger)
0.00%
0 / 7
33.17
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
80.00% covered (warning)
80.00%
8 / 10
0.00% covered (danger)
0.00%
0 / 1
2.03
 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 $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 ($scopeId === '') {
34            return null;
35        }
36
37        if ($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            return \App::$http
84                ->readGetResult('/warehouse/requestscope/' . $scopeId . '/' . $period . '/')
85                ->getEntity()
86                ->toGrouped($this->groupfields, $this->hashset)
87                ->withRequestsSum()
88                ->withAverage('processingtime')
89                ->withWeightedAverageProcessingTime()
90                ->withUncapturedRequestRowSortedLast();
91        } catch (Exception $exception) {
92            return null;
93        }
94    }
95
96    /**
97     * Get request period data for the current scope
98     */
99    public function getRequestPeriod(string $scopeId): mixed
100    {
101        try {
102            return \App::$http
103                ->readGetResult('/warehouse/requestscope/' . $scopeId . '/')
104                ->getEntity();
105        } catch (Exception $exception) {
106            return null;
107        }
108    }
109
110    /**
111     * Fetch and combine data from multiple years
112     */
113    private function fetchAndCombineDataFromYears(ReportHelper $reportHelper, string $scopeId, array $years, string $fromDate, string $toDate): array
114    {
115        $combinedData = [];
116        $baseEntity = null;
117
118        foreach ($years as $year) {
119            $bounds = $reportHelper->getYearDateBounds($year, $fromDate, $toDate);
120            if ($bounds === null) {
121                continue;
122            }
123            try {
124                $exchangeRequest = \App::$http
125                    ->readGetResult(
126                        '/warehouse/requestscope/' . $scopeId . '/' . $year . '/',
127                        [
128                            'groupby' => 'day',
129                            'fromDate' => $bounds['from'],
130                            'toDate' => $bounds['to'],
131                        ]
132                    )
133                    ->getEntity();
134
135                // Use the first successfully fetched entity as the base
136                if ($baseEntity === null) {
137                    $baseEntity = $exchangeRequest;
138                }
139
140                // Combine data from all years
141                if (isset($exchangeRequest->data) && is_array($exchangeRequest->data)) {
142                    $combinedData = array_merge($combinedData, $exchangeRequest->data);
143                }
144            } catch (Exception $exception) {
145                // Continue with other years - don't fail completely if one year is missing
146            }
147        }
148
149        return [
150            'entity' => $baseEntity,
151            'data' => $combinedData
152        ];
153    }
154
155    /**
156     * Create filtered exchange request with updated properties
157     */
158    private function createFilteredExchangeRequest(
159        $exchangeRequestBasic,
160        array $filteredData,
161        string $fromDate,
162        string $toDate
163    ): mixed {
164        $exchangeRequest = $exchangeRequestBasic;
165        $exchangeRequest->data = $filteredData;
166
167        if (!isset($exchangeRequest->period)) {
168            $exchangeRequest->period = 'day';
169        }
170
171        $exchangeRequest->firstDay = (new Day())->setDateTime(new DateTime($fromDate));
172        $exchangeRequest->lastDay = (new Day())->setDateTime(new DateTime($toDate));
173
174        if (!empty($filteredData)) {
175            $exchangeRequest = $exchangeRequest
176                ->toGrouped($this->groupfields, $this->hashset)
177                ->withRequestsSum()
178                ->withAverage('processingtime')
179                ->withWeightedAverageProcessingTime();
180
181            if (is_array($exchangeRequest->data)) {
182                $exchangeRequest = $exchangeRequest->withUncapturedRequestRowSortedLast();
183            }
184
185            return $exchangeRequest;
186        }
187
188        return $exchangeRequest->toHashed();
189    }
190
191    /**
192     * Prepare download arguments for request report
193     */
194    public function prepareDownloadArgs(
195        array $args,
196        mixed $exchangeRequest,
197        ?array $dateRange,
198        array $selectedScopes = []
199    ): array {
200        $args['category'] = 'requestscope';
201
202        if ($dateRange) {
203            $args['period'] = $dateRange['from'] . '_' . $dateRange['to'];
204        }
205
206        if (!empty($selectedScopes)) {
207            $args['selectedScopes'] = $selectedScopes;
208        }
209
210        if ($exchangeRequest && count($exchangeRequest->data)) {
211            $args['reports'][] = $exchangeRequest;
212        }
213
214        return $args;
215    }
216}