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