Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
71.03% covered (warning)
71.03%
76 / 107
73.68% covered (warning)
73.68%
14 / 19
CRAP
0.00% covered (danger)
0.00%
0 / 1
AvailabilityList
71.03% covered (warning)
71.03%
76 / 107
73.68% covered (warning)
73.68%
14 / 19
128.56
0.00% covered (danger)
0.00%
0 / 1
 getMaxWorkstationCount
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 withCalculatedSlots
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 withType
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 withOutDoubles
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 hasMatchOf
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
3
 withDateTime
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 withDateTimeInRange
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
20
 getAvailableSecondsOnDateTime
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 isOpenedByDate
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
3
 isOpened
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
3
 hasAppointment
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
3
 getSlotList
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 getSlotListByType
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
20
 getConflicts
100.00% covered (success)
100.00%
17 / 17
100.00% covered (success)
100.00%
1 / 1
6
 hasOverlapWith
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
3
 getSummerizedSlotCount
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
6
 getCalculatedSlotCount
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
2
 withScope
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 withLessData
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2
3/**
4 * @copyright BerlinOnline Stadtportal GmbH & Co. KG
5 **/
6
7namespace BO\Zmsentities\Collection;
8
9use BO\Zmsentities\Availability;
10
11/**
12 * @SuppressWarnings(Complexity)
13 */
14class AvailabilityList extends Base
15{
16    const ENTITY_CLASS = '\BO\Zmsentities\Availability';
17
18    public function getMaxWorkstationCount()
19    {
20        $max = 0;
21        foreach ($this as $availability) {
22            if ($availability['workstationCount']['intern'] >  $max) {
23                $max = $availability['workstationCount']['intern'];
24            }
25        }
26        return $max;
27    }
28
29    public function withCalculatedSlots()
30    {
31        $list = clone $this;
32        foreach ($list as $key => $availability) {
33            $list[$key] = $availability->withCalculatedSlots();
34        }
35        return $list;
36    }
37
38    public function withType($type)
39    {
40        $collection = new static();
41        foreach ($this as $availability) {
42            if ($availability->type == $type) {
43                $collection[] = clone $availability;
44            }
45        }
46        return $collection;
47    }
48
49    public function withOutDoubles()
50    {
51        $collection = new static();
52        foreach ($this as $availability) {
53            if (false === $collection->hasMatchOf($availability)) {
54                $collection[] = clone $availability;
55            }
56        }
57        return $collection;
58    }
59
60    public function hasMatchOf(Availability $availability)
61    {
62        foreach ($this as $item) {
63            if ($item->isMatchOf($availability)) {
64                return $item;
65            }
66        }
67        return false;
68    }
69
70    public function withDateTime(\DateTimeInterface $dateTime)
71    {
72        $list = new self();
73        foreach ($this as $availability) {
74            if ($availability->isOpenedOnDate($dateTime)) {
75                $list->addEntity($availability);
76            }
77        }
78        return $list;
79    }
80
81    public function withDateTimeInRange(\DateTimeInterface $startDateTime, \DateTimeInterface $endDateTime)
82    {
83        $list = new self();
84        $currentDateTime = clone $startDateTime;
85        while ($currentDateTime <= $endDateTime) {
86            foreach ($this as $availability) {
87                if ($availability->isOpenedOnDate($currentDateTime)) {
88                    $list->addEntity($availability);
89                }
90            }
91            $currentDateTime = $currentDateTime->modify('+1 day');
92        }
93        return $list->withOutDoubles();
94    }
95
96    public function getAvailableSecondsOnDateTime(\DateTimeInterface $dateTime, $type = "intern")
97    {
98        $seconds = 0;
99        foreach ($this->withType('appointment')->withDateTime($dateTime) as $availability) {
100            $seconds += $availability->getAvailableSecondsPerDay($type);
101        }
102        return $seconds;
103    }
104
105    /*
106     * is opened on a day -> not specified by a time
107     */
108    public function isOpenedByDate(\DateTimeInterface $dateTime, $type = false)
109    {
110        foreach ($this as $availability) {
111            if ($availability->isOpenedOnDate($dateTime, $type)) {
112                return true;
113            }
114        }
115        return false;
116    }
117
118    /*
119     * is opened on a day with specified time
120     */
121    public function isOpened(\DateTimeInterface $dateTime, $type = "openinghours")
122    {
123        foreach ($this as $availability) {
124            if ($availability->isOpened($dateTime, $type)) {
125                return true;
126            }
127        }
128        return false;
129    }
130
131    public function hasAppointment(\BO\Zmsentities\Appointment $appointment)
132    {
133        foreach ($this as $availability) {
134            if ($availability->hasAppointment($appointment)) {
135                return true;
136            }
137        }
138        return false;
139    }
140
141    public function getSlotList()
142    {
143        $slotList = new SlotList();
144        foreach ($this as $availability) {
145            foreach ($availability->getSlotList() as $slot) {
146                $slotList->addEntity($slot);
147            }
148        }
149        return $slotList;
150    }
151
152    public function getSlotListByType($type)
153    {
154        $slotList = new SlotList();
155        foreach ($this as $availability) {
156            if ($availability->type == $type) {
157                foreach ($availability->getSlotList() as $slot) {
158                    $slotList->addEntity($slot);
159                }
160            }
161        }
162        return $slotList;
163    }
164
165    public function getConflicts($startDate, $endDate)
166    {
167        $processList = new ProcessList();
168        foreach ($this as $availability) {
169            $conflict = $availability->getConflict();
170            $currentDate = $startDate;
171            while ($currentDate <= $endDate) {
172                if ($availability->isOpenedOnDate($currentDate)) {
173                    if ($conflict) {
174                        $conflictOnDay = clone $conflict;
175                        // to avoid overwrite time settings from availability getConflict lets modify
176                        $appointmentTime = $conflictOnDay->getFirstAppointment()->getStartTime()->format('H:i');
177                        $newDate = clone $currentDate;
178                        $conflictOnDay->getFirstAppointment()->setDateTime($newDate->modify($appointmentTime));
179                        $processList->addEntity($conflictOnDay);
180                    }
181                    $overlapList = $this->hasOverlapWith($availability, $currentDate);
182                    if ($overlapList->count()) {
183                        $processList->addList($overlapList);
184                    }
185                }
186                $currentDate = $currentDate->modify('+1day');
187            }
188        }
189        return $processList;
190    }
191
192    public function hasOverlapWith(Availability $availability, \DateTimeInterface $currentDate)
193    {
194        $processList = new ProcessList();
195        foreach ($this as $availabilityCompare) {
196            if ($availabilityCompare->isOpenedOnDate($currentDate)) {
197                $overlaps = $availability->getTimeOverlaps($availabilityCompare, $currentDate);
198                $processList->addList($overlaps);
199            }
200        }
201        return $processList;
202    }
203
204    /**
205     * @return integer
206     */
207    public function getSummerizedSlotCount()
208    {
209        return array_reduce($this->getArrayCopy(), function ($carry, $item) {
210            $itemId = ($item->id) ? $item->id : $item->tempId;
211            $maxSlots = (int) $item->getSlotList()->getSummerizedSlot()->intern;
212            $carry[$itemId] = $maxSlots;
213            return $carry;
214        }, []);
215    }
216
217    /**
218     * @return integer
219     */
220    public function getCalculatedSlotCount(\BO\Zmsentities\Collection\ProcessList $processList)
221    {
222        return array_reduce($this->getArrayCopy(), function ($carry, $item) use ($processList) {
223            $itemId = $item->id;
224            $listWithAvailability = $processList->withAvailability($item);
225            $busySlots = $listWithAvailability->getAppointmentList()->getCalculatedSlotCount();
226            $carry[$itemId] = $busySlots;
227            return $carry;
228        }, []);
229    }
230
231
232    public function withScope(\BO\Zmsentities\Scope $scope)
233    {
234        $list = clone $this;
235        foreach ($list as $key => $availability) {
236            $list[$key] = $availability->withScope($scope);
237        }
238        return $list;
239    }
240
241    public function withLessData(array $keepArray = [])
242    {
243        $list = new self();
244        foreach ($this as $availability) {
245            $list->addEntity(clone $availability->withLessData($keepArray));
246        }
247        return $list;
248    }
249}