Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
86.30% covered (warning)
86.30%
126 / 146
93.75% covered (success)
93.75%
15 / 16
CRAP
0.00% covered (danger)
0.00%
0 / 1
Exchange
86.30% covered (warning)
86.30%
126 / 146
93.75% covered (success)
93.75%
15 / 16
97.87
0.00% covered (danger)
0.00%
0 / 1
 getDefaults
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
1
 setPeriod
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 addDictionaryEntry
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
1
 addDataSet
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
4
 withLessData
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
4
 getPositionByName
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
5
 withCalculatedTotals
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
1 / 1
7
 withMaxByHour
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
8
 withRequestsSum
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
6
 withAverage
0.00% covered (danger)
0.00%
0 / 20
0.00% covered (danger)
0.00%
0 / 1
132
 withMaxAndAverageFromWaitingTime
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
1 / 1
10
 getCalculatedTotals
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
4
 toHashed
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 getHashData
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
8
 toGrouped
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 getGroupedHashSet
100.00% covered (success)
100.00%
18 / 18
100.00% covered (success)
100.00%
1 / 1
9
1<?php
2
3namespace BO\Zmsentities;
4
5/**
6 * @SuppressWarnings(Complexity)
7 * @SuppressWarnings(PublicMethod)
8 *
9 */
10class Exchange extends Schema\Entity
11{
12    const PRIMARY = 'firstDay';
13
14    public static $schema = "exchange.json";
15
16    public function getDefaults()
17    {
18        return [
19            'firstDay' => new Day(),
20            'lastDay' => new Day(),
21            'period' => 'day',
22            'dictionary' => [ ],
23            'data' => [ ]
24        ];
25    }
26
27    public function setPeriod(\DateTimeInterface $firstDay, \DateTimeInterface $lastDay, $period = 'day')
28    {
29        $this->firstDay = (new Day())->setDateTime($firstDay);
30        $this->lastDay = (new Day())->setDateTime($lastDay);
31        $this->period = $period;
32        return $this;
33    }
34
35    public function addDictionaryEntry($variable, $type = 'string', $description = '', $reference = '')
36    {
37        $position = count($this['dictionary']);
38        $this['dictionary'][$position] = [
39            'position' => $position,
40            'variable' => $variable,
41            'type' => $type,
42            'description' => $description,
43            'reference' => $reference
44        ];
45        return $this;
46    }
47
48    public function addDataSet($values)
49    {
50        if (!is_array($values) && !$values instanceof \Traversable) {
51            throw new \Exception("Values have to be of type array");
52        }
53        if (count($this->dictionary) != count($values)) {
54            throw new \Exception("Mismatching dictionary settings for values (count mismatch)");
55        }
56        $this->data[] = $values;
57    }
58
59    public function withLessData()
60    {
61        $entity = clone $this;
62        if (isset($entity['firstDay'])) {
63            unset($entity['firstDay']);
64        }
65        if (isset($entity['lastDay'])) {
66            unset($entity['lastDay']);
67        }
68        if (isset($entity['period'])) {
69            unset($entity['period']);
70        }
71        return $entity;
72    }
73
74    public function getPositionByName($name)
75    {
76        if (isset($this->dictionary)) {
77            foreach ($this->dictionary as $entry) {
78                if (isset($entry['variable']) && $entry['variable'] == $name) {
79                    return $entry['position'];
80                }
81            }
82        }
83        return false;
84    }
85
86    public function withCalculatedTotals(array $keysToCalculate = ['count'], $dateName = 'name')
87    {
88        $entity = clone $this;
89        $namePosition = $this->getPositionByName($dateName);
90        if ($namePosition) {
91            $totals = array_fill(0, count($entity->data[0]), 0);
92            $totals[$namePosition] = 'totals';
93            foreach ($keysToCalculate as $name) {
94                $calculatePosition = $this->getPositionByName($name);
95                foreach ($this->data as $item) {
96                    foreach ($item as $position => $data) {
97                        if (is_numeric($data) && $calculatePosition == $position) {
98                            $totals[$position] += $data;
99                        }
100                    }
101                }
102            }
103            $entity->addDataSet($totals);
104        }
105        return $entity;
106    }
107
108    public function withMaxByHour(array $keysToCalculate = ['count'])
109    {
110        $entity = clone $this;
111        $maxima = [];
112        foreach ($entity->data as $dateItems) {
113            foreach ($dateItems as $hour => $hourItems) {
114                foreach ($hourItems as $key => $value) {
115                    if (is_numeric($value) && in_array($key, $keysToCalculate)) {
116                        $maxima[$hour][$key] = (
117                          isset($maxima[$hour][$key]) && $maxima[$hour][$key] > $value
118                        ) ? $maxima[$hour][$key] : $value;
119                    }
120                }
121            }
122            $entity->data['max'] = $maxima;
123        }
124        return $entity;
125    }
126
127    public function withRequestsSum($keysToCalculate = ['requestscount'])
128    {
129        $entity = clone $this;
130        $sum = [];
131        foreach ($entity->data as $name => $entry) {
132            $sum[$name] = 0;
133            foreach ($entry as $dateItem) {
134                foreach ($dateItem as $key => $value) {
135                    if (is_numeric($value) && in_array($key, $keysToCalculate)) {
136                        $sum[$name] += $value;
137                    }
138                }
139            }
140        }
141        $entity->data['sum'] = $sum;
142        return $entity;
143    }
144
145    public function withAverage($keyToCalculate)
146    {
147        $entity = clone $this;
148        $average = [];
149
150        foreach ($entity->data as $name => $entry) {
151            if (!is_array($entry) && !($entry instanceof \Traversable)) {
152                // Skip or handle non-iterable $entry appropriately.
153                continue;
154            }
155
156            $average[$name . '_sum'] = 0;
157            $average[$name . '_count'] = 0;
158
159            foreach ($entry as $dateItem) {
160                if (!is_array($dateItem) && !($dateItem instanceof \Traversable)) {
161                    // Skip or handle non-iterable $dateItem appropriately.
162                    continue;
163                }
164
165                foreach ($dateItem as $key => $value) {
166                    if (!is_numeric($value) || $key !== $keyToCalculate) {
167                        // Skip non-numeric values or when the key doesn't match.
168                        continue;
169                    }
170
171                    $average[$name . '_sum'] += $value;
172                    $average[$name . '_count']++;
173                }
174            }
175
176            $average[$name] = $average[$name . '_count'] > 0
177                ? round($average[$name . '_sum'] / $average[$name . '_count'], 2)
178                : null;
179        }
180
181        $entity->data['average_' . $keyToCalculate] = $average;
182        return $entity;
183    }
184
185
186    public function withMaxAndAverageFromWaitingTime()
187    {
188        $entity = clone $this;
189        foreach ($entity->data as $date => $dateItems) {
190            $maxima = 0;
191            $total = 0;
192            $count = 0;
193            foreach ($dateItems as $hourItems) {
194                foreach ($hourItems as $key => $value) {
195                    if (is_numeric($value) && 'waitingtime' == $key && 0 < $value) {
196                        $total += $value;
197                        $count += 1;
198                        $maxima = ($maxima > $value) ? $maxima : $value;
199                    }
200                }
201            }
202            $entity->data[$date]['max'] = $maxima;
203            $entity->data[$date]['average'] = (! $total || ! $count) ? 0 : floor($total / $count);
204        }
205        return $entity;
206    }
207
208    public function getCalculatedTotals()
209    {
210        foreach (array_reverse($this->data) as $item) {
211            foreach ($item as $data) {
212                if ($data == 'totals') {
213                    return $item;
214                }
215            }
216        }
217        return null;
218    }
219
220    public function toHashed(array $hashfields = [])
221    {
222        $entity = clone $this;
223        $entity->data = $this->getHashData($hashfields);
224        unset($entity->dictionary);
225        return $entity;
226    }
227
228    public function getHashData(array $hashfields = [], $first = false)
229    {
230        $hash = [];
231        foreach ($this->dictionary as $entry) {
232            foreach ($this->data as $key => $item) {
233                foreach ($item as $position => $data) {
234                    if ($entry['position'] == $position) {
235                        if (count($hashfields) && in_array($entry['variable'], $hashfields)) {
236                            $hash[$key][$entry['variable']] = $data;
237                        } else {
238                            $hash[$key][$entry['variable']] = $data;
239                        }
240                    }
241                }
242            }
243        }
244        return ($first) ? reset($hash) : $hash;
245    }
246
247    public function toGrouped(array $fields, array $hashfields)
248    {
249        $entity = clone $this;
250        $entity->data = $this->getGroupedHashSet($fields, $hashfields);
251        unset($entity->dictionary);
252        return $entity;
253    }
254
255    public function getGroupedHashSet(array $fields, array $hashfields)
256    {
257        $list = [];
258        if (count($fields)) {
259            $field = array_shift($fields);
260            $fieldposition = $this->getPositionByName($field);
261
262            $requestscountPosition = $this->getPositionByName('requestscount');
263
264
265            foreach ($this->data as $element) {
266                if (isset($element[$fieldposition])) {
267                    if (!isset($list[$element[$fieldposition]])) {
268                        $list[$element[$fieldposition]] = clone $this;
269                        $list[$element[$fieldposition]]->data = [];
270                    }
271                    if ($requestscountPosition !== false && isset($element[$requestscountPosition])) {
272                        $element[$requestscountPosition] = (int) $element[$requestscountPosition];
273                    }
274
275                    $list[$element[$fieldposition]]->data[] = $element;
276                }
277            }
278
279            foreach ($list as $key => $row) {
280                if ($row instanceof Exchange) {
281                    $list[$key] = $row->getGroupedHashSet($fields, $hashfields);
282                }
283            }
284        } else {
285            return $this->getHashData($hashfields, true);
286        }
287        return $list;
288    }
289}