Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
88.78% covered (warning)
88.78%
87 / 98
70.00% covered (warning)
70.00%
7 / 10
CRAP
0.00% covered (danger)
0.00%
0 / 1
ReportHelper
88.78% covered (warning)
88.78%
87 / 98
70.00% covered (warning)
70.00%
7 / 10
59.28
0.00% covered (danger)
0.00%
0 / 1
 withMaxAndAverage
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
1 / 1
11
 withTotalCustomers
90.48% covered (success)
90.48%
19 / 21
0.00% covered (danger)
0.00%
0 / 1
7.04
 withGlobalMaxAndAverage
77.78% covered (warning)
77.78%
21 / 27
0.00% covered (danger)
0.00%
0 / 1
17.47
 formatTimeValue
62.50% covered (warning)
62.50%
5 / 8
0.00% covered (danger)
0.00%
0 / 1
3.47
 extractSelectedScopes
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
4
 getWorkstationScopeId
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 resolveScopeIdParam
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
3
 extractDateRange
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
5
 isValidDateFormat
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
3
 getYearsForDateRange
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3namespace BO\Zmsstatistic\Helper;
4
5use DateTime;
6
7class ReportHelper
8{
9    public static function withMaxAndAverage($entity, $targetKey)
10    {
11        foreach ($entity->data as $date => $dateItems) {
12            $maxima = 0;
13            $total = 0;
14            $count = 0;
15            foreach ($dateItems as $hourItems) {
16                if (is_array($hourItems)) { // Check if $hourItems is an array
17                    foreach ($hourItems as $key => $value) {
18                        if (is_numeric($value) && $targetKey == $key && 0 < $value) {
19                            $total += $value;
20                            $count += 1;
21                            $maxima = ($maxima > $value) ? $maxima : $value;
22                        }
23                    }
24                }
25            }
26            $entity->data[$date]['max_' . $targetKey] = $maxima;
27            $entity->data[$date]['average_' . $targetKey] = (! $total || ! $count) ? 0 : $total / $count;
28        }
29        return $entity;
30    }
31
32    public static function withTotalCustomers($entity)
33    {
34        foreach ($entity->data as $dateKey => $dateItems) {
35            if (!is_array($dateItems)) {
36                continue;
37            }
38
39            foreach ($dateItems as $hour => $hourItems) {
40                if (!is_array($hourItems)) {
41                    continue;
42                }
43
44                $countSpontan = (int) ($hourItems['waitingcount'] ?? 0);
45                $countTermin  = (int) ($hourItems['waitingcount_termin'] ?? 0);
46                $countTotal   = $countSpontan + $countTermin;
47
48                $waitSpontan = (float) ($hourItems['waitingtime'] ?? 0);
49                $waitTermin  = (float) ($hourItems['waitingtime_termin'] ?? 0);
50
51                $waySpontan  = (float) ($hourItems['waytime'] ?? 0);
52                $wayTermin   = (float) ($hourItems['waytime_termin'] ?? 0);
53
54                $entity->data[$dateKey][$hour]['waitingcount_total'] = $countTotal;
55
56                $entity->data[$dateKey][$hour]['waitingtime_total'] = ($countTotal > 0)
57                    ? (($waitSpontan * $countSpontan) + ($waitTermin * $countTermin)) / $countTotal
58                    : 0;
59
60                $entity->data[$dateKey][$hour]['waytime_total'] = ($countTotal > 0)
61                    ? (($waySpontan * $countSpontan) + ($wayTermin * $countTermin)) / $countTotal
62                    : 0;
63            }
64        }
65
66        return $entity;
67    }
68
69    public static function withGlobalMaxAndAverage($entity, string $targetKey)
70    {
71        $maxima = 0;
72        $total  = 0;
73        $count  = 0;
74
75        foreach ($entity->data as $dateItems) {
76            if (!is_array($dateItems)) {
77                continue;
78            }
79            foreach ($dateItems as $hourItems) {
80                if (!is_array($hourItems)) {
81                    continue;
82                }
83                $value = $hourItems[$targetKey] ?? null;
84                if (is_numeric($value) && $value > 0) {
85                    $value  = (float) $value;
86                    $maxima = ($maxima > $value) ? $maxima : $value;
87                    $total += $value;
88                    $count++;
89                }
90            }
91        }
92
93        $average = ($count > 0) ? ($total / $count) : 0;
94
95        if (is_object($entity->data)) {
96            if (!isset($entity->data->max) || !is_array($entity->data->max)) {
97                $entity->data->max = [];
98            }
99            $entity->data->max['max_' . $targetKey] = $maxima;
100            $entity->data->max['average_' . $targetKey] = $average;
101        } elseif (is_array($entity->data)) {
102            if (!isset($entity->data['max']) || !is_array($entity->data['max'])) {
103                $entity->data['max'] = [];
104            }
105            $entity->data['max']['max_' . $targetKey] = $maxima;
106            $entity->data['max']['average_' . $targetKey] = $average;
107        }
108
109        return $entity;
110    }
111
112    public static function formatTimeValue($value)
113    {
114        if (!is_numeric($value)) {
115            return $value;
116        }
117        $minutes = floor($value);
118        $seconds = round(($value - $minutes) * 60);
119        if ($seconds >= 60) {
120            $minutes += 1;
121            $seconds = 0;
122        }
123        return sprintf('%02d:%02d', $minutes, $seconds);
124    }
125
126    /**
127     * Extract selected scope IDs from request parameters
128     */
129    public function extractSelectedScopes(array $scopes): array
130    {
131        if (!empty($scopes)) {
132            $validScopes = array_filter($scopes, function ($scopeId) {
133                return is_numeric($scopeId) && $scopeId > 0;
134            });
135
136            if (!empty($validScopes)) {
137                return array_map('intval', $validScopes);
138            }
139        }
140
141        return [];
142    }
143
144    /**
145     * Workstation scope id when the user has selected a default location, otherwise null.
146     */
147    public function getWorkstationScopeId($workstation): ?int
148    {
149        $scopeId = (int) ($workstation->scope['id'] ?? 0);
150
151        return $scopeId > 0 ? $scopeId : null;
152    }
153
154    /**
155     * Scope id(s) for warehouse report queries from form selection or workstation default.
156     */
157    public function resolveScopeIdParam(array $selectedScopes, ?int $workstationScopeId): string
158    {
159        if (!empty($selectedScopes)) {
160            return implode(',', $selectedScopes);
161        }
162
163        return $workstationScopeId !== null ? (string) $workstationScopeId : '';
164    }
165
166    /**
167     * Extract and validate date range from request parameters
168     */
169    public function extractDateRange(?string $fromDate, ?string $toDate): ?array
170    {
171        if ($fromDate && $toDate && $this->isValidDateFormat($fromDate) && $this->isValidDateFormat($toDate)) {
172            return [
173                'from' => $fromDate,
174                'to' => $toDate
175            ];
176        }
177
178        return null;
179    }
180
181    /**
182     * Validate if the given string is a valid date format (YYYY-MM-DD)
183     */
184    public function isValidDateFormat(string $date): bool
185    {
186        if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $date)) {
187            return false;
188        }
189
190        $dateTime = DateTime::createFromFormat('Y-m-d', $date);
191        return $dateTime && $dateTime->format('Y-m-d') === $date;
192    }
193
194    /**
195     * Get all years that need to be fetched for a date range
196     */
197    public function getYearsForDateRange(string $fromDate, string $toDate): array
198    {
199        $fromYear = (int) substr($fromDate, 0, 4);
200        $toYear = (int) substr($toDate, 0, 4);
201
202        $years = [];
203        for ($year = $fromYear; $year <= $toYear; $year++) {
204            $years[] = $year;
205        }
206
207        return $years;
208    }
209}