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