Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
92.31% covered (success)
92.31%
72 / 78
33.33% covered (danger)
33.33%
3 / 9
CRAP
0.00% covered (danger)
0.00%
0 / 1
ClientReport
92.31% covered (success)
92.31%
72 / 78
33.33% covered (danger)
33.33%
3 / 9
36.59
0.00% covered (danger)
0.00%
0 / 1
 readResponse
88.89% covered (warning)
88.89%
8 / 9
0.00% covered (danger)
0.00%
0 / 1
4.02
 writeReport
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
 writeReportHeader
100.00% covered (success)
100.00%
16 / 16
100.00% covered (success)
100.00%
1 / 1
7
 writeTotalsRow
94.44% covered (success)
94.44%
17 / 18
0.00% covered (danger)
0.00%
0 / 1
6.01
 writeReportData
100.00% covered (success)
100.00%
18 / 18
100.00% covered (success)
100.00%
1 / 1
6
 calculateNoAppointment
66.67% covered (warning)
66.67%
2 / 3
0.00% covered (danger)
0.00%
0 / 1
3.33
 calculateMissedNoAppointment
66.67% covered (warning)
66.67%
2 / 3
0.00% covered (danger)
0.00%
0 / 1
3.33
 calculateNoAppointmentForRow
66.67% covered (warning)
66.67%
2 / 3
0.00% covered (danger)
0.00%
0 / 1
3.33
 calculateMissedNoAppointmentForRow
66.67% covered (warning)
66.67%
2 / 3
0.00% covered (danger)
0.00%
0 / 1
3.33
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 as ReportEntity;
11use BO\Zmsstatistic\Helper\Download;
12use PhpOffice\PhpSpreadsheet\Spreadsheet;
13use Psr\Http\Message\RequestInterface;
14use Psr\Http\Message\ResponseInterface;
15
16class ClientReport extends Base
17{
18    /**
19     * @SuppressWarnings(Param)
20     * @return ResponseInterface
21     */
22    #[\Override]
23    public function readResponse(
24        RequestInterface $request,
25        ResponseInterface $response,
26        array $args
27    ): mixed {
28        $title = 'clientstatistic_' . $args['period'];
29        $download = (new Download($request))->setSpreadSheet($title);
30
31        $this->writeInfoHeader($args, $download->getSpreadSheet());
32        if ($args['reports']) {
33            foreach ($args['reports'] as $report) {
34                if ('month' == $report->period) {
35                    $this->writeReport($report, $download->getSpreadSheet(), 'yyyy', 'MMMM', 'yyyy');
36                } else {
37                    $this->writeReport($report, $download->getSpreadSheet());
38                }
39            }
40        }
41
42        return $download->writeDownload($response);
43    }
44
45    public function writeReport(
46        ReportEntity $report,
47        Spreadsheet $spreadsheet,
48        string $datePatternTotals = 'MMMM',
49        string $datePatternCol1 = 'ccc',
50        string $datePatternCol2 = 'dd.MM.yy'
51    ): Spreadsheet {
52        $sheet = $spreadsheet->getActiveSheet();
53        $this->writeReportHeader($report, $sheet);
54        $this->writeTotalsRow($report, $sheet, $datePatternTotals);
55        $this->writeReportData($report, $sheet, $datePatternCol1, $datePatternCol2);
56
57        return $spreadsheet;
58    }
59
60    public function writeReportHeader(ReportEntity $report, \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $sheet): void
61    {
62        $reportHeader = [];
63        if ('totals' == end($report->data)['date'] || 'month' == $report->period) {
64            $reportHeader[] = null;
65        }
66
67        $row = $report->data[0];
68        if (is_array($row)) {
69            foreach (array_keys($row) as $headline) {
70                if (!in_array($headline, static::$ignoreColumns)) {
71                    if (isset(static::$headlines[$headline])) {
72                        $reportHeader[] = static::$headlines[$headline];
73                    }
74                }
75            }
76        }
77
78        // Placeholders for the new columns
79        $end = array_splice($reportHeader, -1);  // get the last element
80        $reportHeader[] = static::$headlines['noappointment'];
81        $reportHeader[] = static::$headlines['missednoappointment'];
82        $reportHeader[] = static::$headlines['ticketprinter'];
83        $reportHeader[] = static::$headlines['ticketprintermissed'];
84
85        $reportHeader = array_merge($reportHeader, $end);  // append them back after adding new headers
86
87
88        $sheet->fromArray($reportHeader, null, 'A' . ($sheet->getHighestRow() + 2));
89    }
90
91    public function writeTotalsRow(
92        ReportEntity $report,
93        \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $sheet,
94        string $datePatternTotals
95    ): void {
96        if ('totals' == end($report->data)['date']) {
97            $totals = array_pop($report->data);
98            $dateString = $report->firstDay->year . '-' . $report->firstDay->month . '-' . $report->firstDay->day;
99            $dateCol1 = ('MMMM' == $datePatternTotals) ?
100                $this->getFormatedDates($this->setDateTime($dateString), $datePatternTotals) :
101                null;
102            $dateCol2 = $this->setDateTime($dateString)->format('Y');
103            $reportTotal = [$dateCol1, $dateCol2];
104
105            foreach ($totals as $key => $item) {
106                if (! in_array($key, static::$ignoreColumns) && 'date' != $key) {
107                    $reportTotal[] = (string)($item);
108                }
109            }
110
111            // Calculations for the new columns
112            $end = array_splice($reportTotal, -1);
113
114            $reportTotal[] = $this->calculateNoAppointment($totals);
115            $reportTotal[] = $this->calculateMissedNoAppointment($totals);
116            $reportTotal[] = (string)($totals['ticketprinter'] ?? 0);
117            $reportTotal[] = (string)($totals['ticketprintermissed'] ?? 0);
118
119            $reportTotal = array_merge($reportTotal, $end);
120
121            $sheet->fromArray($reportTotal, null, 'A' . ($sheet->getHighestRow() + 1));
122        }
123    }
124
125    public function writeReportData(
126        ReportEntity $report,
127        \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $sheet,
128        string $datePatternCol1,
129        string $datePatternCol2
130    ): void {
131        $reportData = [];
132
133        foreach ($report->data as $row => $entry) {
134            $processedRow = [];
135
136            foreach ($entry as $key => $item) {
137                if (!in_array($key, static::$ignoreColumns)) {
138                    if ('date' == $key) {
139                        $dateCol1 = $this->getFormatedDates($this->setDateTime($item), $datePatternCol1);
140                        $item = $this->getFormatedDates($this->setDateTime($item), $datePatternCol2);
141                        $processedRow[] = $dateCol1;
142                    }
143                    $processedRow[] = (is_numeric($item)) ? (string)($item) : $item;
144                }
145            }
146
147            // Calculations for the new columns
148            $end = array_splice($processedRow, -1);
149
150            $processedRow[] = $this->calculateNoAppointmentForRow($entry);
151            $processedRow[] = $this->calculateMissedNoAppointmentForRow($entry);
152            $processedRow[] = (string)($entry['ticketprinter'] ?? 0);
153            $processedRow[] = (string)($entry['ticketprintermissed'] ?? 0);
154
155            $processedRow = array_merge($processedRow, $end);
156
157            $reportData[$row] = $processedRow;
158        }
159
160        $sheet->fromArray($reportData, null, 'A' . ($sheet->getHighestRow() + 1));
161    }
162
163    private function calculateNoAppointment(array $totals): string
164    {
165        if (isset($totals['clientscount']) && isset($totals['withappointment'])) {
166            return (string) ($totals['clientscount'] - $totals['withappointment']);
167        }
168        return 'N/A';
169    }
170
171    private function calculateMissedNoAppointment(array $totals): string
172    {
173        if (isset($totals['missed']) && isset($totals['missedwithappointment'])) {
174            return (string) ($totals['missed'] - $totals['missedwithappointment']);
175        }
176        return 'N/A';
177    }
178
179    private function calculateNoAppointmentForRow(array $entry): string
180    {
181        if (isset($entry['clientscount']) && isset($entry['withappointment'])) {
182            return (string) ($entry['clientscount'] - $entry['withappointment']);
183        }
184        return 'N/A';
185    }
186
187    private function calculateMissedNoAppointmentForRow(array $entry): string
188    {
189        if (isset($entry['missed']) && isset($entry['missedwithappointment'])) {
190            return (string) ($entry['missed'] - $entry['missedwithappointment']);
191        }
192        return 'N/A';
193    }
194}