Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
68.20% covered (warning)
68.20%
148 / 217
60.61% covered (warning)
60.61%
20 / 33
CRAP
0.00% covered (danger)
0.00%
0 / 1
ProcessList
68.20% covered (warning)
68.20%
148 / 217
60.61% covered (warning)
60.61%
20 / 33
392.29
0.00% covered (danger)
0.00%
0 / 1
 toProcessListByTime
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
3
 withRequest
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 sortByScopeName
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
2
 sortByAppointmentDate
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 sortByArrivalTime
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 sortByEstimatedWaitingTime
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 sortByClientName
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
1
 sortPickupQueue
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
6
 sortByTimeKey
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 toProcessListByStatusList
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
12
 toConflictListByDay
95.00% covered (success)
95.00%
19 / 20
0.00% covered (danger)
0.00%
0 / 1
5
 getScopeList
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 getRequestList
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 getAppointmentList
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
4
 setTempAppointmentToProcess
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
5
 toQueueList
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
2
 withAvailability
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 withAvailabilityStrict
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
3
 withDepartmentNotificationEnabled
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
12
 withDepartmentHasMailFrom
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
12
 setConflictAmendment
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 withOutAvailability
76.92% covered (warning)
76.92%
10 / 13
0.00% covered (danger)
0.00%
0 / 1
5.31
 withUniqueScope
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
4
 withAccess
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
12
 withScopeId
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 withOutScopeId
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 withOutProcessId
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 withoutExpiredAppointmentDate
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
12
 withinExactDate
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
12
 withoutDublicatedConflicts
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
12
 testProcessListLength
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
4
 withoutProcessByStatus
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 withTimeRangeByAppointment
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
30
1<?php
2
3namespace BO\Zmsentities\Collection;
4
5use BO\Zmsentities\Helper\Sorter;
6use BO\Zmsentities\Helper\Property;
7use BO\Zmsentities\Helper\Messaging;
8use BO\Zmsentities\Process;
9
10/**
11 * @SuppressWarnings(Complexity)
12 * @SuppressWarnings(Public)
13 * @SuppressWarnings(Coupling)
14 *
15 */
16class ProcessList extends Base
17{
18    const ENTITY_CLASS = '\BO\Zmsentities\Process';
19
20    public function toProcessListByTime($format = null)
21    {
22        $list = new self();
23        foreach ($this as $process) {
24            $appointment = $process->getFirstAppointment();
25            $formattedDate = $appointment['date'];
26            if ($format) {
27                $formattedDate = $appointment->toDateTime()->format($format);
28            }
29            $list[$formattedDate][] = clone $process;
30        }
31        return $list;
32    }
33
34    public function withRequest($requestId)
35    {
36        $list = new self();
37        foreach ($this as $process) {
38            if ($process->requests->hasEntity($requestId)) {
39                $list->addEntity(clone $process);
40            }
41        }
42        return $list;
43    }
44
45    public function sortByScopeName()
46    {
47        $this->uasort(function ($a, $b) {
48            return strcmp(
49                Sorter::toSortableString(ucfirst($a->scope->contact['name'])),
50                Sorter::toSortableString(ucfirst($b->scope->contact['name']))
51            );
52        });
53        return $this;
54    }
55
56    public function sortByAppointmentDate()
57    {
58        $this->uasort(function ($a, $b) {
59            return ($a->getFirstAppointment()->date - $b->getFirstAppointment()->date);
60        });
61        return $this;
62    }
63
64    public function sortByArrivalTime()
65    {
66        $this->uasort(function ($a, $b) {
67            return ($a->queue['arrivalTime'] - $b->queue['arrivalTime']);
68        });
69        return $this;
70    }
71
72    public function sortByEstimatedWaitingTime()
73    {
74        $this->uasort(function ($a, $b) {
75            return ($a->queue['waitingTimeEstimate'] - $b->queue['waitingTimeEstimate']);
76        });
77        return $this;
78    }
79
80    public function sortByClientName()
81    {
82        $this->uasort(function ($a, $b) {
83            return strcmp(
84                Sorter::toSortableString($a->getFirstClient()['familyName']),
85                Sorter::toSortableString($b->getFirstClient()['familyName'])
86            );
87        });
88        return $this;
89    }
90
91    public function sortPickupQueue()
92    {
93        $this->uasort(function ($a, $b) {
94            if ($a->queue['arrivalTime'] == $b->queue['arrivalTime']) {
95                //error_log('equal arrival Time for :'. $a->id);
96                return strcmp(
97                    Sorter::toSortableString($a->getFirstClient()['familyName']),
98                    Sorter::toSortableString($b->getFirstClient()['familyName'])
99                );
100            }
101            return ($a->queue['arrivalTime'] - $b->queue['arrivalTime']);
102        });
103        return $this;
104    }
105
106    public function sortByTimeKey()
107    {
108        $this->uksort(function ($a, $b) {
109            return ($a - $b);
110        });
111        return $this;
112    }
113
114    public function toProcessListByStatusList(array $statusList)
115    {
116        $collection = new self();
117        foreach ($this as $process) {
118            if (in_array($process->getStatus(), $statusList)) {
119                $collection->addEntity($process);
120            }
121        }
122        return $collection;
123    }
124
125    public function toConflictListByDay()
126    {
127        $list = [];
128        $oldList = clone $this;
129        foreach ($oldList as $process) {
130            $appointmentList = [];
131            if (!isset($list[$process->getFirstAppointment()->getStartTime()->format('Y-m-d')])) {
132                $list[$process->getFirstAppointment()->getStartTime()->format('Y-m-d')] = [];
133            }
134            foreach ($process->getAppointments() as $appointment) {
135                $availabilityId = ($appointment->getAvailability()->getId()) ?
136                    $appointment->getAvailability()->getId() :
137                    $appointment->getAvailability()->tempId;
138                $appointmentList[] = [
139                    'startTime' => $appointment->getStartTime()->format('H:i'),
140                    'endTime' => $appointment->getEndTime()->format('H:i'),
141                    'availability' => $availabilityId
142                ];
143            }
144            $list[$process->getFirstAppointment()->getStartTime()->format('Y-m-d')][] = [
145                'message' => $process->amendment,
146                'appointments' => $appointmentList
147            ];
148        }
149        return $list;
150    }
151
152    public function getScopeList()
153    {
154        $list = new ScopeList();
155        foreach ($this as $process) {
156            if (Property::__keyExists('scope', $process)) {
157                $list[] = new \BO\Zmsentities\Scope($process['scope']);
158            }
159        }
160        return $list->withUniqueScopes();
161    }
162
163    public function getRequestList()
164    {
165        $list = new RequestList();
166        foreach ($this as $process) {
167            if (Property::__keyExists('requests', $process)) {
168                $list->addList($process->getRequests());
169            }
170        }
171        return $list->withUniqueRequests();
172    }
173
174    public function getAppointmentList()
175    {
176        $appointmentList = new AppointmentList();
177        foreach ($this as $process) {
178            if (Property::__keyExists('appointments', $process)) {
179                foreach ($process["appointments"] as $appointment) {
180                    $appointmentList->addEntity(new \BO\Zmsentities\Appointment($appointment));
181                }
182            }
183        }
184        return $appointmentList;
185    }
186
187    public function setTempAppointmentToProcess($dateTime, $scopeId)
188    {
189        $addedAppointment = false;
190        $appointment = (new \BO\Zmsentities\Appointment())->addDate($dateTime->getTimestamp())->addScope($scopeId);
191        foreach ($this as $process) {
192            if ($process->hasAppointment($dateTime->getTimestamp(), $scopeId) && !$addedAppointment) {
193                $entity = clone $process;
194                $this->addEntity($entity);
195                $addedAppointment = true;
196            }
197        }
198        if (!$addedAppointment) {
199            $entity = new \BO\Zmsentities\Process();
200            $entity->addAppointment($appointment);
201            $this->addEntity($entity);
202        }
203        return $this;
204    }
205
206    public function toQueueList($now)
207    {
208        $queueList = new QueueList();
209        foreach ($this as $process) {
210            $queue = $process->toQueue($now);
211            $queueList->addEntity($queue);
212        }
213        $queueList->setTransferedProcessList(true);
214        return $queueList;
215    }
216
217    public function withAvailability(\BO\Zmsentities\Availability $availability)
218    {
219        $processList = new static();
220        foreach ($this as $process) {
221            if ($availability->hasAppointment($process->getFirstAppointment())) {
222                $processList[] = clone $process;
223            }
224        }
225        return $processList;
226    }
227
228    public function withAvailabilityStrict(\BO\Zmsentities\Availability $availability)
229    {
230        $processList = new static();
231        $slotList = $availability->getSlotList();
232        foreach ($this as $process) {
233            if ($slotList->removeAppointment($process->getFirstAppointment())) {
234                $processList[] = clone $process;
235            }
236        }
237        return $processList;
238    }
239
240    public function withDepartmentNotificationEnabled()
241    {
242        $processList = new static();
243        foreach ($this as $process) {
244            if ($process->scope->hasNotificationReminderEnabled()) {
245                $entity = clone $process;
246                $processList->addEntity($entity);
247            }
248        }
249        return $processList;
250    }
251
252    public function withDepartmentHasMailFrom()
253    {
254        $processList = new static();
255        foreach ($this as $process) {
256            if ($process->scope->hasEmailFrom()) {
257                $entity = clone $process;
258                $processList->addEntity($entity);
259            }
260        }
261        return $processList;
262    }
263
264
265
266    public function setConflictAmendment()
267    {
268        foreach ($this as $process) {
269            $process->amendment = 'Die Slots für diesen Zeitraum wurden Ã¼berbucht';
270            if (! $process->getFirstAppointment()->availability->hasId()) {
271                $process->amendment = 'Der Vorgang (' . $process->getId() . ') befindet sich außerhalb der Ã–ffnungszeit!';
272            }
273        }
274        return $this;
275    }
276
277    public function withOutAvailability(\BO\Zmsentities\Collection\AvailabilityList $availabilityList)
278    {
279        $processList = new static();
280        foreach ($this->toProcessListByTime('Y-m-d') as $processListByDate) {
281            $dateTime = $processListByDate[0]->getFirstAppointment()->toDateTime();
282            $slotList = $availabilityList->withType('appointment')->withDateTime($dateTime)->getSlotList();
283            foreach ($processListByDate as $process) {
284                try {
285                    $slotList->withSlotsForAppointment($process->getFirstAppointment());
286                    if (!$slotList->removeAppointment($process->getFirstAppointment())) {
287                        $process->amendment = "";
288                        $processList[] = clone $process;
289                    }
290                } catch (\BO\Zmsentities\Exception\AppointmentNotFitInSlotList $exception) {
291                    $process->amendment = "";
292                    $processList[] = clone $process;
293                }
294            }
295        }
296        return $processList;
297    }
298
299    public function withUniqueScope($oncePerHour = false)
300    {
301        $processList = new static();
302        $scopeKeyList = [];
303        foreach ($this as $process) {
304            $scopeKey = $process->scope->id . '-';
305            if ($oncePerHour) {
306                $scopeKey .= $process->getFirstAppointment()->toDateTime()->format('H');
307            } else {
308                $scopeKey .= $process->getFirstAppointment()->toDateTime()->format('H:i');
309            }
310            if (!in_array($scopeKey, $scopeKeyList)) {
311                $processList[] = clone $process;
312                $scopeKeyList[] = $scopeKey;
313            }
314        }
315        return $processList;
316    }
317
318    public function withAccess(\BO\Zmsentities\Useraccount $useraccount)
319    {
320        $list = new static();
321        foreach ($this as $process) {
322            $process = clone $process;
323            if ($process->getCurrentScope()->hasAccess($useraccount)) {
324                $list[] = $process;
325            }
326        }
327        return $list;
328    }
329
330    public function withScopeId($scopeId)
331    {
332        $processList = new static();
333        foreach ($this as $process) {
334            if ($scopeId == $process->scope['id']) {
335                $processList[] = clone $process;
336            }
337        }
338        return $processList;
339    }
340
341    public function withOutScopeId($scopeId)
342    {
343        $processList = new static();
344        foreach ($this as $process) {
345            if ($scopeId != $process->scope['id']) {
346                $processList[] = clone $process;
347            }
348        }
349        return $processList;
350    }
351
352    public function withOutProcessId($processId)
353    {
354        $processList = new static();
355        foreach ($this as $process) {
356            if ($processId != $process->getId()) {
357                $processList[] = clone $process;
358            }
359        }
360        return $processList;
361    }
362
363    public function withoutExpiredAppointmentDate(\DateTimeInterface $now)
364    {
365        $conflictList = new self();
366        foreach ($this as $process) {
367            if ($process->getFirstAppointment()->date > $now->getTimestamp()) {
368                $conflictList->addEntity(clone $process);
369            }
370        }
371        return $conflictList;
372    }
373
374    public function withinExactDate(\DateTimeInterface $now)
375    {
376        $processList = new self();
377        foreach ($this as $process) {
378            if ($process->getFirstAppointment()->toDateTime()->format('Y-m-d') == $now->format('Y-m-d')) {
379                $processList->addEntity(clone $process);
380            }
381        }
382        return $processList;
383    }
384
385    public function withoutDublicatedConflicts()
386    {
387        $collection = new self();
388        foreach ($this as $conflict) {
389            if (! $collection->getAppointmentList()->hasAppointment($conflict->getFirstAppointment())) {
390                $collection->addEntity(clone $conflict);
391            }
392        }
393        return $collection;
394    }
395
396    public function testProcessListLength($processList, bool $isEmptyAllowed = false): ProcessList
397    {
398        $collection = ($processList instanceof Process) ?
399            (new self())->addEntity($processList) :
400            $processList;
401
402        if (0 === $collection->count() && ! $isEmptyAllowed) {
403            throw new \BO\Zmsentities\Exception\ProcessListEmpty();
404        }
405        return $collection;
406    }
407
408    public function withoutProcessByStatus($process, $status)
409    {
410        $collection = clone $this;
411        $collection = (1 <= $collection->count() && ! Messaging::isEmptyProcessListAllowed($status)) ?
412            $collection->withOutProcessId($process->getId()) :
413            $collection;
414        return $collection;
415    }
416
417    /*
418    * reduce process list to items with appointment time in range of given appointment
419    */
420    public function withTimeRangeByAppointment(\BO\Zmsentities\Appointment $appointment)
421    {
422        $processList = new self();
423        if ($this->count()) {
424            foreach ($this as $process) {
425                if (
426                    $appointment->getEndTime() > $process->getFirstAppointment()->getStartTime() &&
427                    $appointment->getStartTime() < $process->getFirstAppointment()->getEndTime()
428                ) {
429                    $processList->addEntity(clone $process);
430                }
431            }
432        }
433        return $processList;
434    }
435}