Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
95.12% covered (success)
95.12%
117 / 123
77.78% covered (warning)
77.78%
7 / 9
CRAP
0.00% covered (danger)
0.00%
0 / 1
Calendar
95.12% covered (success)
95.12%
117 / 123
77.78% covered (warning)
77.78%
7 / 9
36
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
4
 getDateTime
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 readMonthListByScopeList
100.00% covered (success)
100.00%
16 / 16
100.00% covered (success)
100.00%
1 / 1
3
 readAvailableSlotsFromDayAndScopeList
85.71% covered (warning)
85.71%
18 / 21
0.00% covered (danger)
0.00%
0 / 1
4.05
 readWeekDayListWithProcessList
91.67% covered (success)
91.67%
33 / 36
0.00% covered (danger)
0.00%
0 / 1
8.04
 getDateTimeFromWeekAndYear
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 toProcessListByHour
100.00% covered (success)
100.00%
16 / 16
100.00% covered (success)
100.00%
1 / 1
5
 toDayListByHour
100.00% covered (success)
100.00%
18 / 18
100.00% covered (success)
100.00%
1 / 1
7
 splitByDate
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
3
1<?php
2
3/**
4 *
5 * @package Zmsadmin
6 * @copyright BerlinOnline Stadtportal GmbH & Co. KG
7 *
8 */
9
10namespace BO\Zmsadmin\Helper;
11
12use BO\Zmsentities\Calendar as Entity;
13use BO\Zmsentities\Day;
14use BO\Zmsentities\Collection\DayList;
15use BO\Zmsentities\Collection\ProcessList;
16use BO\Zmsentities\Scope;
17
18class Calendar
19{
20    protected $calendar;
21
22    protected $dateTime;
23
24    public function __construct($selectedDate = null, $selectedWeek = null, $selectedYear = null)
25    {
26        if ($selectedWeek && $selectedYear) {
27            $this->dateTime = $this->getDateTimeFromWeekAndYear($selectedWeek, $selectedYear);
28        } else {
29            $this->dateTime = ($selectedDate) ? new \BO\Zmsentities\Helper\DateTime($selectedDate) : \App::$now;
30        }
31
32        $this->calendar = new Entity();
33        $this->calendar->firstDay = new Day();
34        $this->calendar->lastDay = new Day();
35    }
36
37    public function getDateTime()
38    {
39        return $this->dateTime;
40    }
41
42    public function readMonthListByScopeList(\BO\Zmsentities\Collection\ScopeList $scopeList, $slotType, $slotsRequired)
43    {
44        // TODO Berechne die Tage im Kalendar
45        $this->calendar->scopes = $scopeList;
46        $this->calendar->firstDay->setDateTime($this->dateTime->modify('first day of this month'));
47        $this->calendar->lastDay->setDateTime($this->dateTime->modify('last day of next month'));
48        try {
49            $calendar = \App::$http->readPostResult(
50                '/calendar/',
51                $this->calendar,
52                [
53                    'fillWithEmptyDays' => 1,
54                    'slotType' => $slotType,
55                    'slotsRequired' => $slotsRequired
56                ]
57            )->getEntity();
58        } catch (\BO\Zmsclient\Exception $exception) {
59            if ($exception->template != 'BO\Zmsapi\Exception\Calendar\AppointmentsMissed') {
60                throw $exception;
61            }
62        }
63        return $calendar->getMonthList();
64    }
65
66    public function readAvailableSlotsFromDayAndScopeList(
67        \BO\Zmsentities\Collection\ScopeList $scopeList,
68        $slotType = 'intern',
69        $slotsRequired = 0,
70        $forWeek = false
71    ) {
72        $this->calendar->scopes = $scopeList;
73
74        $this->calendar->firstDay->setDateTime($this->dateTime);
75        $this->calendar->lastDay->setDateTime($this->dateTime);
76
77        if ($forWeek) {
78            $startDate = clone $this->dateTime->modify('Monday this week');
79            $endDate = clone $this->dateTime->modify('Sunday this week');
80            $this->calendar->firstDay->setDateTime($startDate);
81            $this->calendar->lastDay->setDateTime($endDate);
82        }
83
84        try {
85            $slots = \App::$http->readPostResult(
86                '/process/status/free/',
87                $this->calendar,
88                [
89                    'slotType' => $slotType,
90                    'slotsRequired' => $slotsRequired,
91                    'gql' => GraphDefaults::getFreeProcessList()
92                ]
93            )->getCollection();
94        } catch (\BO\Zmsclient\Exception $exception) {
95            if ($exception->template != 'BO\Zmsapi\Exception\Process\FreeProcessListEmpty') {
96                throw $exception;
97            }
98        }
99        return $slots;
100    }
101
102    public function readWeekDayListWithProcessList(
103        ?\BO\Zmsentities\Cluster $cluster,
104        \BO\Zmsentities\Workstation $workstation
105    ) {
106        $showAllInCluster = $cluster && 1 == $workstation->queue['clusterEnabled'];
107        $scopeList = $workstation->getScopeList($cluster);
108        $scope = $scopeList->getFirst();
109
110        $dayList = new \BO\Zmsentities\Collection\DayList();
111
112        if ($showAllInCluster) {
113            $bookedProcessList = \App::$http
114                ->readGetResult('/cluster/' . $cluster->id . '/process/' . $this->dateTime->format('Y-m-d') . '/', ['showWeek' => 1])
115                ->getCollection();
116        } else {
117            $bookedProcessList = \App::$http
118                ->readGetResult('/scope/' . $scope->id . '/process/' . $this->dateTime->format('Y-m-d') . '/', ['showWeek' => 1])
119                ->getCollection();
120        }
121
122        /** @var ProcessList $bookedProcessList */
123        $processListByDate = $this->splitByDate($bookedProcessList);
124
125        $startDate = clone $this->dateTime->modify('Monday this week');
126        $endDate = clone $this->dateTime->modify('Sunday this week');
127        $currentDate = $startDate;
128
129        /** @var ProcessList $freeProcessList */
130        $freeProcessList = $this->readAvailableSlotsFromDayAndScopeList(
131            $scopeList,
132            'intern',
133            0,
134            true
135        );
136        $freeProcessListByDate = $freeProcessList ? $this->splitByDate($freeProcessList) : [];
137
138        while ($currentDate <= $endDate) {
139            $day = (new Day())->setDateTime($currentDate);
140            $day->status = Day::DETAIL;
141            $processList = new \BO\Zmsentities\Collection\ProcessList();
142
143            $this->dateTime = $currentDate;
144            if ($currentDate->format('Y-m-d') >= \App::$now->format('Y-m-d')) {
145                if (isset($freeProcessListByDate[$currentDate->format('Y-m-d')])) {
146                    $processList->addList($freeProcessListByDate[$currentDate->format('Y-m-d')]);
147                }
148
149                if (isset($processListByDate[$currentDate->format('Y-m-d')])) {
150                    $processList->addList($processListByDate[$currentDate->format('Y-m-d')]);
151                }
152            }
153
154            $day['processList'] = $this->toProcessListByHour($processList);
155            $dayList->addEntity($day);
156            $currentDate = $currentDate->modify('+1 day');
157        }
158
159        return $this->toDayListByHour($dayList);
160    }
161
162    protected function getDateTimeFromWeekAndYear($week, $year)
163    {
164        $dateTime = new \DateTimeImmutable();
165        return $dateTime->setISODate($year, $week);
166    }
167
168    public function toProcessListByHour(ProcessList $processList)
169    {
170        $list = array();
171        $oldList = $processList;
172        $oldList->sortByArrivalTime();
173        foreach ($oldList as $process) {
174            if (in_array($process->status, [ 'confirmed', 'free'])) {
175                $appointment = $process->getFirstAppointment();
176                $hour = (int)$appointment->toDateTime()->format('H');
177                if (!isset($list[$hour])) {
178                    $list[$hour] = array();
179                }
180                if (!isset($list[$hour][intval($appointment['date'])])) {
181                    $list[$hour][intval($appointment['date'])] = new ProcessList();
182                }
183                $list[$hour][intval($appointment['date'])]->addEntity($process);
184
185                unset($process);
186                ksort($list[$hour]);
187            }
188        }
189
190        ksort($list);
191        return $list;
192    }
193
194    public function toDayListByHour(DayList $dayList)
195    {
196        $list = array();
197        $hours = array();
198        $dayKeys = array();
199        foreach ($dayList as $day) {
200            $list['days'][] = $day;
201            $dayKey = $day->year . '-' . $day->month . '-' . $day->day;
202            $dayKeys[$dayKey] = $dayKey;
203            foreach ($day['processList'] as $hour => $processList) {
204                $list['hours'][$hour][$dayKey] = $processList;
205                $hours[$hour] = $hour;
206            }
207        }
208        foreach ($hours as $hour) {
209            foreach ($dayKeys as $dayKey) {
210                if (!isset($list['hours'][$hour][$dayKey])) {
211                    $list['hours'][$hour][$dayKey] = new ProcessList();
212                }
213            }
214            ksort($list['hours'][$hour]);
215        }
216
217        if (is_array($list['hours'])) {
218            ksort($list['hours']);
219        }
220
221        return $list;
222    }
223
224    private function splitByDate(ProcessList $processList)
225    {
226        $list = [];
227
228        foreach ($processList as $process) {
229            $dayKey = $process->getFirstAppointment()->toDateTime()->format("Y-m-d");
230            if (! isset($list[$dayKey])) {
231                $list[$dayKey] = new \BO\Zmsentities\Collection\ProcessList();
232                ;
233            }
234
235            $list[$dayKey]->addEntity($process);
236        }
237
238        return $list;
239    }
240}