Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
42.47% |
31 / 73 |
|
50.00% |
1 / 2 |
CRAP | |
0.00% |
0 / 1 |
OverallCalendarRead | |
42.47% |
31 / 73 |
|
50.00% |
1 / 2 |
39.42 | |
0.00% |
0 / 1 |
buildCalendar | |
10.64% |
5 / 47 |
|
0.00% |
0 / 1 |
97.35 | |||
readResponse | |
100.00% |
26 / 26 |
|
100.00% |
1 / 1 |
1 |
1 | <?php |
2 | |
3 | namespace BO\Zmsapi; |
4 | |
5 | use BO\Slim\Render; |
6 | use BO\Mellon\Validator; |
7 | use BO\Zmsdb\OverallCalendar as CalendarQuery; |
8 | use DateTimeImmutable; |
9 | use DateTimeInterface; |
10 | |
11 | class OverallCalendarRead extends BaseController |
12 | { |
13 | private function buildCalendar(array $rows, int $defaultSeats = 1): array |
14 | { |
15 | $calendar = []; |
16 | $lastSlotInfo = []; |
17 | |
18 | foreach ($rows as $row) { |
19 | $dateKey = (new DateTimeImmutable($row['time']))->format('Y-m-d'); |
20 | $timeKey = (new DateTimeImmutable($row['time']))->format('H:i'); |
21 | $scopeKey = (int)$row['scope_id']; |
22 | $seatNo = (int)$row['seat']; |
23 | |
24 | $day =& $calendar[$dateKey]; |
25 | $scope =& $day['scopes'][$scopeKey]; |
26 | $time =& $scope['times'][$timeKey]['seats']; |
27 | |
28 | $day['date'] = (new DateTimeImmutable($dateKey))->getTimestamp(); |
29 | $scope['id'] = $scopeKey; |
30 | $scope['name'] = ''; |
31 | $scope['maxSeats'] = max($scope['maxSeats'] ?? 0, $seatNo, $defaultSeats); |
32 | $time[$seatNo]['init'] = true; |
33 | |
34 | if ($row['status'] === 'termin') { |
35 | if ($row['slots'] === null) { |
36 | $time[$seatNo] = ['status' => 'skip']; |
37 | } else { |
38 | $time[$seatNo] = [ |
39 | 'status' => 'termin', |
40 | 'processId' => (int)$row['process_id'], |
41 | 'slots' => (int)$row['slots'], |
42 | ]; |
43 | $lastSlotInfo["$scopeKey|$seatNo"] = [ |
44 | 'processId' => (int)$row['process_id'], |
45 | 'openSlots' => (int)$row['slots'] - 1, |
46 | ]; |
47 | } |
48 | } else { |
49 | $info = $lastSlotInfo["$scopeKey|$seatNo"] ?? null; |
50 | if ($info && $info['openSlots'] > 0) { |
51 | $time[$seatNo] = ['status' => 'skip']; |
52 | $lastSlotInfo["$scopeKey|$seatNo"]['openSlots']--; |
53 | } else { |
54 | $time[$seatNo] = ['status' => 'open']; |
55 | unset($lastSlotInfo["$scopeKey|$seatNo"]); |
56 | } |
57 | } |
58 | } |
59 | |
60 | foreach ($calendar as &$day) { |
61 | foreach ($day['scopes'] as &$scope) { |
62 | foreach ($scope['times'] as $timeKey => $slotInfo) { |
63 | for ($seatNumber = 1; $seatNumber <= $scope['maxSeats']; $seatNumber++) { |
64 | if (!isset($slotInfo['seats'][$seatNumber])) { |
65 | $slotInfo['seats'][$seatNumber] = ['status' => 'open']; |
66 | } |
67 | } |
68 | ksort($slotInfo['seats']); |
69 | |
70 | $scope['times'][$timeKey] = [ |
71 | 'name' => $timeKey, |
72 | 'seats' => array_values($slotInfo['seats']), |
73 | ]; |
74 | } |
75 | $scope['times'] = array_values($scope['times']); |
76 | } |
77 | $day['scopes'] = array_values($day['scopes']); |
78 | } |
79 | |
80 | return ['days' => array_values($calendar)]; |
81 | } |
82 | |
83 | public function readResponse( |
84 | \Psr\Http\Message\RequestInterface $request, |
85 | \Psr\Http\Message\ResponseInterface $response, |
86 | array $args |
87 | ) { |
88 | $scopeIdCsv = Validator::param('scopeIds') |
89 | ->isString()->isMatchOf('/^\d+(,\d+)*$/')->assertValid()->getValue(); |
90 | $scopeIds = array_map('intval', explode(',', $scopeIdCsv)); |
91 | |
92 | $dateFrom = Validator::param('dateFrom')->isDate('Y-m-d')->assertValid()->getValue(); |
93 | $dateUntil = Validator::param('dateUntil')->isDate('Y-m-d')->assertValid()->getValue(); |
94 | $updateAfter = Validator::param('updateAfter')->isDatetime()->setDefault(null)->getValue(); |
95 | |
96 | $flatRows = (new CalendarQuery())->readSlots( |
97 | $scopeIds, |
98 | $dateFrom, |
99 | $dateUntil, |
100 | $updateAfter |
101 | ); |
102 | |
103 | $structured = $this->buildCalendar($flatRows); |
104 | |
105 | $msg = Response\Message::create($request); |
106 | $msg->data = $structured; |
107 | $msg->meta->rows = count($flatRows); |
108 | |
109 | $response = Render::withLastModified( |
110 | $response, |
111 | (new DateTimeImmutable())->getTimestamp(), |
112 | '0' |
113 | ); |
114 | return Render::withJson( |
115 | $response, |
116 | $msg->setUpdatedMetaData(), |
117 | $msg->getStatuscode() |
118 | ); |
119 | } |
120 | } |