Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
88.73% covered (warning)
88.73%
63 / 71
42.86% covered (danger)
42.86%
3 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
Base
88.73% covered (warning)
88.73%
63 / 71
42.86% covered (danger)
42.86%
3 / 7
30.20
0.00% covered (danger)
0.00%
0 / 1
 sanitizeDownloadFilenamePart
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 resolveDictionaryHeader
33.33% covered (danger)
33.33%
2 / 6
0.00% covered (danger)
0.00%
0 / 1
5.67
 writeRawReport
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
5
 writeFilteredExchangeReport
93.75% covered (success)
93.75%
15 / 16
0.00% covered (danger)
0.00%
0 / 1
6.01
 writeInfoHeader
92.31% covered (success)
92.31%
24 / 26
0.00% covered (danger)
0.00%
0 / 1
10.05
 setDateTime
75.00% covered (warning)
75.00%
3 / 4
0.00% covered (danger)
0.00%
0 / 1
3.14
 getFormatedDates
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3/**
4 * @package zmsstatistic
5 * @copyright BerlinOnline Stadtportal GmbH & Co. KG
6 **/
7
8namespace BO\Zmsstatistic\Download;
9
10use BO\Zmsentities\Exchange;
11use BO\Zmsstatistic\BaseController;
12use Exception;
13use PhpOffice\PhpSpreadsheet\Spreadsheet;
14
15class Base extends BaseController
16{
17    public static $ignoreColumns = [
18        'subjectid',
19        'scopeids',
20        'max',
21        'sum',
22        'ticketprinter',
23        'ticketprintermissed'
24    ];
25    public static $subjectTranslations = [
26        'waitingscope' => 'Wartesituation',
27        'waitingdepartment' => 'Wartesituation',
28        'waitingorganisation' => 'Wartesituation',
29        'clientscope' => 'Kundenstatistik',
30        'clientdepartment' => 'Kundenstatistik',
31        'clientorganisation' => 'Kundenstatistik',
32        'requestscope' => 'Dienstleistungsstatistik',
33        'requestdepartment' => 'Dienstleistungsstatistik',
34        'requestorganisation' => 'Dienstleistungsstatistik',
35        'raw-waitingscope' => 'Rohdaten Wartesituation',
36        'raw-waitingdepartment' => 'Rohdaten Wartesituation',
37        'raw-waitingorganisation' => 'Rohdaten Wartesituation',
38        'raw-clientscope' => 'Rohdaten Wartende',
39        'raw-clientdepartment' => 'Rohdaten Wartende',
40        'raw-clientorganisation' => 'Rohdaten Wartende',
41        'raw-requestscope' => 'Rohdaten Dienstleistungsstatistik',
42        'raw-requestdepartment' => 'Rohdaten Dienstleistungsstatistik',
43        'raw-requestorganisation' => 'Rohdaten Dienstleistungsstatistik',
44        'capacityscope' => 'Terminkapazität',
45        'raw-capacityscope' => 'Rohdaten Terminkapazität'
46    ];
47
48    public static $headlines = [
49        'subjectid' => 'ID',
50        'scopeids' => 'Standort IDs',
51        'date' => 'Datum',
52        'clientscount' => 'Kunden Erschienen',
53        'missed' => 'Kunden Nicht Erschienen',
54        'withappointment' => 'davon Terminkunden Erschienen',
55        'missedwithappointment' => 'davon Terminkunden Nicht Erschienen',
56        'noappointment' => 'davon Spontankunden Erschienen',
57        'missednoappointment' => 'davon Spontankunden Nicht Erschienen',
58        'ticketprinter' => 'Erschienen (E-Kiosk)',
59        'ticketprintermissed' => 'Nicht Erschienen (E-Kiosk)',
60        'requestscount' => 'Dienstleistungen',
61        'organisationname' => 'Organisation',
62        'departmentname' => 'Behörde',
63        'scopename' => 'Standort',
64        'bookedcount' => 'Gebuchte Kapazität (Zeitschlitze)',
65        'plannedcount' => 'Geplante Kapazität (Zeitschlitze)',
66        'bookedminutes' => 'Gebuchte Kapazität (Minuten)',
67        'plannedminutes' => 'Geplante Kapazität (Minuten)',
68    ];
69
70    protected function sanitizeDownloadFilenamePart(string $part): string
71    {
72        return str_replace(',', '_', $part);
73    }
74
75    protected function resolveDictionaryHeader(array $item): string
76    {
77        if (!empty($item['description'])) {
78            return (string) $item['description'];
79        }
80
81        $variable = $item['variable'] ?? '';
82        if (isset(static::$headlines[$variable])) {
83            return static::$headlines[$variable];
84        }
85
86        return (string) $variable;
87    }
88
89    protected function writeRawReport(Exchange $report, Spreadsheet $spreadsheet): Spreadsheet
90    {
91        $sheet = $spreadsheet->getActiveSheet();
92        $reportData = [];
93        foreach ($report->dictionary as $item) {
94            $reportData['header'][] = $this->resolveDictionaryHeader($item);
95        }
96        foreach ($report->data as $row => $entry) {
97            foreach ($entry as $item) {
98                $reportData[$row][] = is_numeric($item) ? (string) $item : $item;
99            }
100        }
101        $sheet->fromArray($reportData, null, 'A' . ($sheet->getHighestRow()));
102
103        return $spreadsheet;
104    }
105
106    protected function writeFilteredExchangeReport(
107        Exchange $report,
108        Spreadsheet $spreadsheet,
109        array $skipVariables = [],
110        int $rowGap = 0
111    ): Spreadsheet {
112        $sheet = $spreadsheet->getActiveSheet();
113        $columnIndexes = [];
114        $reportData = [];
115
116        foreach ($report->dictionary as $index => $item) {
117            $variable = $item['variable'] ?? '';
118            if (in_array($variable, $skipVariables, true)) {
119                continue;
120            }
121            $columnIndexes[] = $index;
122            $reportData['header'][] = $this->resolveDictionaryHeader($item);
123        }
124
125        foreach ($report->data as $row => $entry) {
126            foreach ($columnIndexes as $index) {
127                $value = $entry[$index] ?? '';
128                $reportData[$row][] = is_numeric($value) ? (string) $value : $value;
129            }
130        }
131
132        $startRow = $sheet->getHighestRow() + $rowGap;
133        $sheet->fromArray($reportData, null, 'A' . $startRow);
134
135        return $spreadsheet;
136    }
137
138    protected function writeInfoHeader(array $args, Spreadsheet $spreadsheet)
139    {
140        $sheet = $spreadsheet->getActiveSheet();
141        $infoData[] = static::$subjectTranslations[$args['category']];
142        if (isset($args['selectedScopes'])) {
143            try {
144                $scopesResult = \App::$http->readGetResult('/scope/')->getData();
145                $scopeMap = [];
146                foreach ($scopesResult as $scope) {
147                    $scopeMap[$scope->id] = $scope;
148                }
149                foreach ($args['selectedScopes'] as $scopeId) {
150                    if (isset($scopeMap[$scopeId])) {
151                        $infoData[] = $scopeMap[$scopeId]->provider->name . " " . $scopeMap[$scopeId]->shortName;
152                    }
153                }
154            } catch (Exception $exception) {
155                return null;
156            }
157        } else {
158            if (isset($args['organisation'])) {
159                $infoData[] = $args['organisation']['name'] ;
160            }
161            if (isset($args['department'])) {
162                $infoData[] = $args['department']['name'];
163            }
164            if (isset($args['scope'])) {
165                $infoData[] = $args['scope']['contact']['name'] . ' ' . $args['scope']['shortName'];
166            }
167        }
168
169        $infoData = array_chunk($infoData, 1);
170        $sheet->fromArray($infoData, null, 'A' . $sheet->getHighestRow());
171
172        if (isset($args['reports'][0]->firstDay)) {
173            $firstDay = $args['reports'][0]->firstDay->toDateTime()->format('d.m.Y');
174            $lastDay = $args['reports'][0]->lastDay->toDateTime()->format('d.m.Y');
175            $range = array('Zeitraum:', $firstDay, 'bis', $lastDay);
176            $sheet->fromArray($range, null, 'A' . ($sheet->getHighestRow() + 1));
177        }
178
179        return $spreadsheet;
180    }
181
182    protected function setDateTime($dateString)
183    {
184        $dateArr = explode('-', $dateString);
185        if (2 == count($dateArr)) {
186            $dateString = $dateString . '-01';
187        }
188        /* ignore because not in use now */
189        //@codeCoverageIgnoreStart
190        if (1 == count($dateArr)) {
191            $dateString = $dateString . '-01-01';
192        }
193        //@codeCoverageIgnoreEnd
194        return new \DateTime($dateString);
195    }
196
197    protected function getFormatedDates($date, $pattern = 'MMMM')
198    {
199        $dateFormatter = new \IntlDateFormatter(
200            'de-DE',
201            \IntlDateFormatter::MEDIUM,
202            \IntlDateFormatter::MEDIUM,
203            \App::TIMEZONE,
204            \IntlDateFormatter::GREGORIAN,
205            $pattern
206        );
207
208        return $dateFormatter->format($date->getTimestamp());
209    }
210}