Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
88.17% covered (warning)
88.17%
82 / 93
62.50% covered (warning)
62.50%
5 / 8
CRAP
0.00% covered (danger)
0.00%
0 / 1
ReportHelper
88.17% covered (warning)
88.17%
82 / 93
62.50% covered (warning)
62.50%
5 / 8
54.14
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
 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     * Extract and validate date range from request parameters
146     */
147    public function extractDateRange(?string $fromDate, ?string $toDate): ?array
148    {
149        if ($fromDate && $toDate && $this->isValidDateFormat($fromDate) && $this->isValidDateFormat($toDate)) {
150            return [
151                'from' => $fromDate,
152                'to' => $toDate
153            ];
154        }
155
156        return null;
157    }
158
159    /**
160     * Validate if the given string is a valid date format (YYYY-MM-DD)
161     */
162    public function isValidDateFormat(string $date): bool
163    {
164        if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $date)) {
165            return false;
166        }
167
168        $dateTime = DateTime::createFromFormat('Y-m-d', $date);
169        return $dateTime && $dateTime->format('Y-m-d') === $date;
170    }
171
172    /**
173     * Get all years that need to be fetched for a date range
174     */
175    public function getYearsForDateRange(string $fromDate, string $toDate): array
176    {
177        $fromYear = (int) substr($fromDate, 0, 4);
178        $toYear = (int) substr($toDate, 0, 4);
179
180        $years = [];
181        for ($year = $fromYear; $year <= $toYear; $year++) {
182            $years[] = $year;
183        }
184
185        return $years;
186    }
187}