Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
85.00% covered (warning)
85.00%
68 / 80
14.29% covered (danger)
14.29%
1 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
ReportClientService
85.00% covered (warning)
85.00%
68 / 80
14.29% covered (danger)
14.29%
1 / 7
29.46
0.00% covered (danger)
0.00%
0 / 1
 getExchangeClientData
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
4
 getExchangeClientForDateRange
76.47% covered (warning)
76.47%
13 / 17
0.00% covered (danger)
0.00%
0 / 1
5.33
 getExchangeClientForPeriod
71.43% covered (warning)
71.43%
5 / 7
0.00% covered (danger)
0.00%
0 / 1
2.09
 getClientPeriod
60.00% covered (warning)
60.00%
3 / 5
0.00% covered (danger)
0.00%
0 / 1
2.26
 fetchAndCombineDataFromYears
96.00% covered (success)
96.00%
24 / 25
0.00% covered (danger)
0.00%
0 / 1
6
 createFilteredExchangeClient
81.82% covered (warning)
81.82%
9 / 11
0.00% covered (danger)
0.00%
0 / 1
3.05
 prepareDownloadArgs
87.50% covered (warning)
87.50%
7 / 8
0.00% covered (danger)
0.00%
0 / 1
5.05
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 ReportClientService
16{
17    protected $totals = [
18        'clientscount',
19        'missed',
20        'withappointment',
21        'missedwithappointment',
22        'noappointment',
23        'missednoappointment',
24        'ticketprinter',
25        'ticketprintermissed',
26        'requestscount'
27    ];
28
29    /**
30     * Get exchange client data based on date range or period
31     */
32    public function getExchangeClientData(string $scopeId, ?array $dateRange, array $args): mixed
33    {
34        if ($scopeId === '') {
35            return null;
36        }
37
38        if ($dateRange) {
39            return $this->getExchangeClientForDateRange($scopeId, $dateRange);
40        }
41
42        return isset($args['period'])
43            ? $this->getExchangeClientForPeriod($scopeId, $args['period'])
44            : null;
45    }
46
47    /**
48     * Get exchange client data for a specific date range
49     */
50    public function getExchangeClientForDateRange(string $scopeId, array $dateRange): mixed
51    {
52        if (!isset($dateRange['from']) || !isset($dateRange['to'])) {
53            return null;
54        }
55        $fromDate = $dateRange['from'];
56        $toDate = $dateRange['to'];
57
58        try {
59            $reportHelper = new ReportHelper();
60            $years = $reportHelper->getYearsForDateRange($fromDate, $toDate);
61            $combinedData = $this->fetchAndCombineDataFromYears($scopeId, $years, $fromDate, $toDate);
62
63            if (empty($combinedData['data'])) {
64                return null;
65            }
66
67            return $this->createFilteredExchangeClient(
68                $combinedData['entity'],
69                $combinedData['data'],
70                $fromDate,
71                $toDate
72            );
73        } catch (Exception $exception) {
74            return null;
75        }
76    }
77
78    /**
79     * Get exchange client data for a specific period (legacy functionality)
80     */
81    public function getExchangeClientForPeriod(string $scopeId, string $period): mixed
82    {
83        try {
84            return \App::$http
85                ->readGetResult('/warehouse/clientscope/' . $scopeId . '/' . $period . '/')
86                ->getEntity()
87                ->withCalculatedTotals($this->totals, 'date')
88                ->toHashed();
89        } catch (Exception $exception) {
90            return null;
91        }
92    }
93
94    /**
95     * Get client period data for the current scope
96     */
97    public function getClientPeriod(string $scopeId): mixed
98    {
99        try {
100            return \App::$http
101                ->readGetResult('/warehouse/clientscope/' . $scopeId . '/')
102                ->getEntity();
103        } catch (Exception $exception) {
104            return null;
105        }
106    }
107
108    /**
109     * Fetch and combine data from multiple years
110     */
111    private function fetchAndCombineDataFromYears(string $scopeId, array $years, string $fromDate, string $toDate): array
112    {
113        $combinedData = [];
114        $baseEntity = null;
115
116        foreach ($years as $year) {
117            try {
118                $exchangeClient = \App::$http
119                    ->readGetResult(
120                        '/warehouse/clientscope/' . $scopeId . '/' . $year . '/',
121                        [
122                            'groupby' => 'day',
123                            'fromDate' => $fromDate,
124                            'toDate' => $toDate
125                        ]
126                    )
127                    ->getEntity();
128
129                // Use the first successfully fetched entity as the base
130                if ($baseEntity === null) {
131                    $baseEntity = $exchangeClient;
132                }
133
134                // Combine data from all years
135                if (isset($exchangeClient->data) && is_array($exchangeClient->data)) {
136                    $combinedData = array_merge($combinedData, $exchangeClient->data);
137                }
138            } catch (Exception $exception) {
139                // Continue with other years - don't fail completely if one year is missing
140            }
141        }
142
143        usort($combinedData, static function ($a, $b) {
144            return strcmp($a[1] ?? '', $b[1] ?? '');
145        });
146
147        return [
148            'entity' => $baseEntity,
149            'data' => $combinedData
150        ];
151    }
152
153    /**
154     * Create filtered exchange client with updated properties
155     */
156    private function createFilteredExchangeClient(
157        $exchangeClientBasic,
158        array $filteredData,
159        string $fromDate,
160        string $toDate
161    ): mixed {
162        $exchangeClient = $exchangeClientBasic;
163        $exchangeClient->data = $filteredData;
164
165        if (!isset($exchangeClient->period)) {
166            $exchangeClient->period = 'day';
167        }
168
169        $exchangeClient->firstDay = (new Day())->setDateTime(new DateTime($fromDate));
170        $exchangeClient->lastDay = (new Day())->setDateTime(new DateTime($toDate));
171
172        if (!empty($filteredData)) {
173            return $exchangeClient
174                ->withCalculatedTotals($this->totals, 'date')
175                ->toHashed();
176        }
177
178        return $exchangeClient->toHashed();
179    }
180
181    /**
182     * Prepare download arguments for client report
183     */
184    public function prepareDownloadArgs(
185        array $args,
186        mixed $exchangeClient,
187        ?array $dateRange,
188        array $selectedScopes = []
189    ): array {
190        $args['category'] = 'clientscope';
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 ($exchangeClient && count($exchangeClient->data)) {
201            $args['reports'][] = $exchangeClient;
202        }
203
204        return $args;
205    }
206}