Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
90.85% covered (success)
90.85%
258 / 284
77.05% covered (warning)
77.05%
47 / 61
CRAP
0.00% covered (danger)
0.00%
0 / 1
Process
90.85% covered (success)
90.85%
258 / 284
77.05% covered (warning)
77.05%
47 / 61
152.61
0.00% covered (danger)
0.00%
0 / 1
 getDefaults
100.00% covered (success)
100.00%
18 / 18
100.00% covered (success)
100.00%
1 / 1
1
 createFromScope
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
1
 getRequests
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
4
 getRequestIds
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getRequestCSV
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 addScope
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 addQueue
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
 addRequests
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
3
 updateRequests
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
3
 hasScopeAdmin
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 sendAdminMailOnConfirmation
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 sendAdminMailOnDeleted
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 sendAdminMailOnUpdated
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 shouldSendAdminMailOnClerkMail
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 withUpdatedData
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
3
 addAppointmentFromRequest
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
1 / 1
4
 addClientFromForm
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
5
 setStatus
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getStatus
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getReminderTimestamp
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 addReminderTimestamp
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 getAppointments
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
4
 getClients
83.33% covered (warning)
83.33%
5 / 6
0.00% covered (danger)
0.00%
0 / 1
4.07
 hasAppointment
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 isWithAppointment
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 hasProcessCredentials
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
4
 withReassignedCredentials
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 hasQueueNumber
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
3
 addAppointment
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getScopeId
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getCurrentScope
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getAmendment
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getShowUpTime
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
6
 getWaitingTime
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getProcessingTime
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getFinishTime
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 addAmendment
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
3
 getCustomTextfield
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 addCustomTextfield
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
3
 getAuthKey
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setRandomAuthKey
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setCallTime
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 getCallTimeString
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getCallTime
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 getFirstClient
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 getFirstAppointment
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
2
 setStatusBySettings
88.89% covered (warning)
88.89%
8 / 9
0.00% covered (danger)
0.00%
0 / 1
5.03
 setClientsCount
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 withoutPersonalData
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
2
 withLessData
100.00% covered (success)
100.00%
29 / 29
100.00% covered (success)
100.00%
1 / 1
21
 toCalendar
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
1
 toQueue
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
5
 hasArrivalTime
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 getArrivalTime
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
3
 getWaitedSeconds
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getWaitedMinutes
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getWaySeconds
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getWayMinutes
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 toDerefencedAmendment
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
1
 toDerefencedCustomTextfield
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
2
 __toString
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
1 / 1
4
1<?php
2
3namespace BO\Zmsentities;
4
5use BO\Zmsentities\Helper\Property;
6
7/**
8 * @SuppressWarnings(Complexity)
9 * @SuppressWarnings(Coupling)
10 * @SuppressWarnings(Public)
11 *
12 */
13class Process extends Schema\Entity
14{
15    const PRIMARY = 'id';
16    public const STATUS_FREE = 'free';
17    public const STATUS_RESERVED = 'reserved';
18    public const STATUS_CONFIRMED = 'confirmed';
19    public const STATUS_PRECONFIRMED = 'preconfirmed';
20    public const STATUS_QUEUED = 'queued';
21    public const STATUS_CALLED = 'called';
22    public const STATUS_PROCESSING = 'processing';
23    public const STATUS_PENDING = 'pending';
24    public const STATUS_PICKUP = 'pickup';
25    public const STATUS_FINISHED = 'finished';
26    public const STATUS_MISSED = 'missed';
27    public const STATUS_PARKED = 'parked';
28    public const STATUS_ARCHIVED = 'archived';
29    public const STATUS_DELETED = 'deleted';
30    public const STATUS_ANONYMIZED = 'anonymized';
31    public const STATUS_BLOCKED = 'blocked';
32    public const STATUS_CONFLICT = 'conflict';
33    public static $schema = "process.json";
34    public function getDefaults()
35    {
36        return [
37            'amendment' => '',
38            'customTextfield' => '',
39            'appointments' => new Collection\AppointmentList(),
40            'apiclient' => new Apiclient(),
41            'authKey' => '',
42            'clients' => new Collection\ClientList(),
43            'createIP' => '',
44            'createTimestamp' => time(),
45            'id' => 0,
46            'archiveId' => 0,
47            'queue' => new Queue(),
48            'reminderTimestamp' => 0,
49            'requests' => new Collection\RequestList(),
50            'scope' => new Scope(),
51            'status' => 'free',
52            'lastChange' => time()
53        ];
54    }
55
56    public static function createFromScope(Scope $scope, \DateTimeInterface $dateTime)
57    {
58        $appointment = new Appointment();
59        $appointment->addScope($scope->id);
60        $appointment->addSlotCount(0);
61        $appointment->addDate($dateTime->modify('00:00:00')->getTimestamp());
62        $process = new static();
63        $process->scope = $scope;
64        $process->setStatus('queued');
65        $process->addAppointment($appointment);
66        return $process;
67    }
68
69    /**
70     * @return Collection\RequestList
71     *
72     */
73    public function getRequests()
74    {
75        if (!$this->requests instanceof Collection\RequestList) {
76            $requestList = new Collection\RequestList();
77            foreach ($this->requests as $request) {
78                $request = ($request instanceof Request) ? $request : new Request($request);
79                $requestList->addEntity($request);
80            }
81            $this->requests = $requestList;
82        }
83        return $this->requests;
84    }
85
86    public function getRequestIds()
87    {
88        return $this->getRequests()->getIds();
89    }
90
91    public function getRequestCSV()
92    {
93        return $this->getRequests()->getIdsCsv();
94    }
95
96    public function addScope($scopeId)
97    {
98        $this->scope = new Scope(array('id' => $scopeId));
99        return $this;
100    }
101
102    public function addQueue($number, \DateTimeInterface $dateTime)
103    {
104        $this->queue = new Queue(array(
105            'number' => $number,
106            'arrivalTime' => $dateTime->getTimestamp()
107        ));
108        return $this;
109    }
110
111    public function addRequests($source, $requestCSV)
112    {
113        $requestList = $this->getRequests();
114        foreach (explode(',', $requestCSV) as $id) {
115            if (!$requestList->hasRequests($id)) {
116                $this->requests[] = new Request(array(
117                    'source' => $source,
118                    'id' => $id
119                ));
120            }
121        }
122        return $this;
123    }
124
125    public function updateRequests($source, $requestCSV = '')
126    {
127        $this->requests = new Collection\RequestList();
128        if ($requestCSV) {
129            foreach (explode(',', $requestCSV) as $id) {
130                $this->requests->addEntity(new Request(array(
131                            'source' => $source,
132                            'id' => $id
133                        )));
134            }
135        }
136        return $this;
137    }
138
139    public function hasScopeAdmin()
140    {
141        return ('' != $this->toProperty()->scope->contact->email->get());
142    }
143
144    public function sendAdminMailOnConfirmation()
145    {
146        return (bool) ((int) $this->toProperty()->scope->preferences->client->adminMailOnAppointment->get());
147    }
148
149    public function sendAdminMailOnDeleted()
150    {
151        return (bool) ((int) $this->toProperty()->scope->preferences->client->adminMailOnDeleted->get());
152    }
153
154    public function sendAdminMailOnUpdated()
155    {
156        return (bool) ((int) $this->toProperty()->scope->preferences->client->adminMailOnUpdated->get());
157    }
158
159    public function shouldSendAdminMailOnClerkMail()
160    {
161        return (bool) ((int) $this->toProperty()->scope->preferences->client->adminMailOnMailSent->get());
162    }
163
164    public function withUpdatedData($requestData, \DateTimeInterface $dateTime, $scope = null, $notice = '')
165    {
166        $this->scope = ($scope) ? $scope : $this->scope;
167        $this->addAppointmentFromRequest($requestData, $dateTime);
168        $requestCsv = isset($requestData['requests']) ? implode(',', $requestData['requests']) : 0;
169        $this->updateRequests($scope->getSource(), $requestCsv);
170        $this->addClientFromForm($requestData);
171        $this->addReminderTimestamp($requestData, $dateTime);
172        $this->addAmendment($requestData, $notice);
173        $this->addCustomTextfield($requestData, $notice);
174        return $this;
175    }
176
177    public function addAppointmentFromRequest($requestData, \DateTimeInterface $dateTime)
178    {
179        $this->appointments = null;
180        if (isset($requestData['selecteddate'])) {
181            $dateTime = new \DateTime($requestData['selecteddate']);
182        }
183        if (isset($requestData['selectedtime'])) {
184            $time = explode('-', $requestData['selectedtime']);
185            $dateTime->setTime($time[0], $time[1]);
186        }
187
188        $appointment = (new Appointment())
189            ->addDate($dateTime->getTimestamp())
190            ->addScope($this->scope['id']);
191        if (isset($requestData['slotCount'])) {
192            $appointment->addSlotCount($requestData['slotCount']);
193        }
194        $this->addAppointment($appointment);
195        return $this;
196    }
197
198    public function addClientFromForm($requestData)
199    {
200        $client = new Client();
201        foreach ($requestData as $key => $value) {
202            if (null !== $value && $client->offsetExists($key)) {
203                $client[$key] = (isset($value['value'])) ? $value['value'] : $value;
204            }
205        }
206        $this->clients = array();
207        $this->clients[] = $client;
208        return $this;
209    }
210
211    public function setStatus($status)
212    {
213        $this->status = $status;
214        return $this;
215    }
216
217    public function getStatus()
218    {
219        return $this->status;
220    }
221
222    public function getReminderTimestamp()
223    {
224        $timestamp = $this->toProperty()->reminderTimestamp->get();
225        return ($timestamp) ? $timestamp : 0;
226    }
227
228    public function addReminderTimestamp($input, \DateTimeInterface $dateTime)
229    {
230        $this->reminderTimestamp = (
231            Property::__keyExists('headsUpTime', $input) &&
232            $input['headsUpTime'] > 0
233        ) ? $dateTime->getTimestamp() - $input['headsUpTime'] : 0;
234        return $this;
235    }
236
237    /**
238     * @return \BO\Zmsentities\Collection\AppointmentList
239     *
240     */
241    public function getAppointments()
242    {
243        if (!$this['appointments'] instanceof Collection\AppointmentList) {
244            $this['appointments'] = new Collection\AppointmentList($this['appointments']);
245            foreach ($this['appointments'] as $index => $appointment) {
246                if (!$appointment instanceof Appointment) {
247                    $this['appointments'][$index] = new Appointment($appointment);
248                }
249            }
250        }
251        return $this['appointments'];
252    }
253
254    /**
255     * @return \BO\Zmsentities\Collection\ClientList
256     *
257     */
258    public function getClients()
259    {
260        if (!$this['clients'] instanceof Collection\ClientList) {
261            $this['clients'] = new Collection\ClientList($this['clients']);
262            foreach ($this['clients'] as $index => $client) {
263                if (!$client instanceof Client) {
264                    $this['clients'][$index] = new Client($client);
265                }
266            }
267        }
268        return $this['clients'];
269    }
270
271    public function hasAppointment($date, $scopeId)
272    {
273        return $this->getAppointments()->hasDateScope($date, $scopeId);
274    }
275
276    /**
277     * check if process is with appointment and not only queued
278     * return Boolean
279     */
280    public function isWithAppointment()
281    {
282        $appointment = $this->getFirstAppointment();
283        if ($appointment->hasTime()) {
284            return true;
285        }
286        return (1 == $this->toProperty()->queue->withAppointment->get());
287    }
288
289    public function hasProcessCredentials()
290    {
291        return (isset($this['id']) && isset($this['authKey']) && $this['id'] && $this['authKey']);
292    }
293
294    public function withReassignedCredentials($process)
295    {
296        $this->id = $process->getId();
297        $this->authKey = $process->getAuthKey();
298        return $this;
299    }
300
301    public function hasQueueNumber()
302    {
303        return (isset($this['queue']) && isset($this['queue']['number']) && $this['queue']['number']);
304    }
305
306    public function addAppointment(Appointment $newappointment)
307    {
308        $this->appointments[] = $newappointment;
309        return $this;
310    }
311
312    /**
313     * Reminder: A process might have multiple scopes. Each appointment can
314     * have his own scope. The scope in $this->scope is the current/next scope.
315     * This function returns the original scope ID and ignores internal scope
316     * which are used for processing like to pick up documents
317     *
318     */
319    public function getScopeId()
320    {
321        //TK 2020-09-28 changed because pickup and pending processes have assigned pickup scope
322        //as current scope - see zmsdb Query/Process EntityMapping
323        return $this->toProperty()->scope->id->get();
324    }
325
326    public function getCurrentScope(): Scope
327    {
328        return $this->getProperty('scope');
329    }
330
331    public function getAmendment()
332    {
333        return $this->toProperty()->amendment->get();
334    }
335
336    /*public function getShowUpTime()
337    {
338        return $this->toProperty()->showUpTime->get();
339    }*/
340
341    public function getShowUpTime($default = 'now', $timezone = null)
342    {
343        $showUpTime = $this->toProperty()->showUpTime->get();
344        $showDateTime = Helper\DateTime::create($default, $timezone);
345        if ($showUpTime) {
346            list($hours, $minutes, $seconds) = explode(':', $showUpTime);
347            $showDateTime = $showDateTime->setTime(intval($hours), intval($minutes), intval($seconds));
348        }
349        return $showDateTime;
350    }
351
352    public function getWaitingTime()
353    {
354        return $this->toProperty()->queue->waitingTime->get();
355    }
356
357    public function getProcessingTime()
358    {
359        return $this->toProperty()->processingTime->get();
360    }
361
362    public function getFinishTime()
363    {
364        return $this->toProperty()->finishTime->get();
365    }
366
367    public function addAmendment($input, $notice = '')
368    {
369        $this->amendment = $notice;
370        $this->amendment .= (isset($input['amendment']) && $input['amendment']) ? $input['amendment'] : '';
371        trim($this->amendment);
372        return $this;
373    }
374
375    public function getCustomTextfield()
376    {
377        return $this->toProperty()->customTextfield->get();
378    }
379
380    public function addCustomTextfield($input, $notice = '')
381    {
382        $this->customTextfield = $notice;
383        $this->customTextfield .= (
384            isset($input['customTextfield']) && $input['customTextfield']
385        ) ? $input['customTextfield'] : '';
386        trim($this->customTextfield);
387        return $this;
388    }
389
390    public function getAuthKey()
391    {
392        return $this->toProperty()->authKey->get();
393    }
394
395    public function setRandomAuthKey()
396    {
397        $this->authKey = substr(md5(rand()), 0, 4);
398    }
399
400    public function setCallTime($dateTime = null)
401    {
402        $this->queue['callTime'] = ($dateTime) ? $dateTime->getTimestamp() : 0;
403        return $this;
404    }
405
406    public function getCallTimeString()
407    {
408        return $this->getCallTime()->format('H:i:s');
409    }
410
411    public function getCallTime($default = 'now', $timezone = null)
412    {
413        $callTime = $this->toProperty()->queue->callTime->get();
414        $callDateTime = Helper\DateTime::create($default, $timezone);
415        if ($callTime) {
416            $callDateTime = $callDateTime->setTimestamp($callTime);
417        }
418        return $callDateTime;
419    }
420
421    public function getFirstClient()
422    {
423        $client = $this->getClients()->getFirst();
424        if (!$client) {
425            $client = new Client();
426            $this->clients->addEntity($client);
427        }
428        return $client;
429    }
430
431    public function getFirstAppointment(): Appointment
432    {
433        $appointment = $this->getAppointments()->getFirst();
434        if (!$appointment) {
435            $appointment = new Appointment();
436            $appointment->scope = $this->scope;
437            $this->appointments->addEntity($appointment);
438        }
439        return $appointment;
440    }
441
442    public function setStatusBySettings()
443    {
444        $scope = new Scope($this->scope);
445        if ('called' == $this->status && $this->queue['callCount'] > $scope->getPreference('queue', 'callCountMax')) {
446            $this->status = 'missed';
447        } elseif ('parked' == $this->status) {
448            $this->status = 'parked';
449        } elseif ('pickup' == $this->status) {
450            $this->status = 'queued';
451        } else {
452            $this->status = 'confirmed';
453        }
454        return $this;
455    }
456
457    public function setClientsCount($count)
458    {
459        $clientList = $this->getClients();
460        while ($clientList->count() < $count) {
461            $clientList->addEntity(new Client());
462        }
463        return $this;
464    }
465
466
467    public function withoutPersonalData()
468    {
469        $entity = clone $this;
470        if ($this->toProperty()->clients->isAvailable()) {
471            $client = $entity->getFirstClient();
472            unset($client['familyName']);
473            unset($client['email']);
474        }
475        return $entity;
476    }
477
478    /**
479     * Reduce data of dereferenced entities to a required minimum
480     *
481     */
482    public function withLessData(array $keepArray = [])
483    {
484        $entity = clone $this;
485        if (!in_array('availability', $keepArray)) {
486            foreach ($entity['appointments'] as $appointment) {
487                if ($appointment->toProperty()->scope->isAvailable()) {
488                    $scopeId = $appointment['scope']['id'];
489                    unset($appointment['scope']);
490                    $appointment['scope'] = ['id' => $entity->toProperty()->scope->id->get()];
491                    if ($scopeId != $entity->toProperty()->scope->id->get()) {
492                        $appointment['scope'] = ['id' => $scopeId];
493                    }
494                }
495                if ($appointment->toProperty()->availability->isAvailable()) {
496                    unset($appointment['availability']);
497                }
498            }
499        }
500
501        unset($entity['createTimestamp']);
502        unset($entity['createIP']);
503        if ($entity->toProperty()->scope->status->isAvailable()) {
504            unset($entity['scope']['status']);
505        }
506
507        if ($entity->status == 'free') {
508// delete keys
509            foreach (['authKey', 'queue', 'requests',] as $key) {
510                if (!in_array($key, $keepArray) && $entity->toProperty()->$key->isAvailable()) {
511                    unset($entity[$key]);
512                }
513            }
514            // delete if empty
515            foreach (['amendment', 'id', 'authKey', 'archiveId', 'reminderTimestamp',] as $key) {
516                if (!in_array($key, $keepArray) && $entity->toProperty()->$key->isAvailable() && !$entity[$key]) {
517                    unset($entity[$key]);
518                }
519            }
520            if (!in_array('provider', $keepArray) && $entity->toProperty()->scope->provider->data->isAvailable()) {
521                unset($entity['scope']['provider']['data']);
522            }
523        }
524
525        if (!in_array('dayoff', $keepArray) && $entity->toProperty()->scope->dayoff->isAvailable()) {
526            unset($entity['scope']['dayoff']);
527        }
528        if (!in_array('scope', $keepArray) && $entity->toProperty()->scope->preferences->isAvailable()) {
529            unset($entity['scope']['preferences']);
530        }
531        return $entity;
532    }
533
534    public function toCalendar()
535    {
536        $calendar = new Calendar();
537        $dateTime = $this->getFirstAppointment()->toDateTime();
538        $day = new Day();
539        $day->setDateTime($dateTime);
540        $calendar->firstDay = $day;
541        $calendar->lastDay = $day;
542        $calendar->requests = clone $this->getRequests();
543        $calendar->scopes = new Collection\ScopeList([$this->scope]);
544        return $calendar;
545    }
546
547    public function toQueue(\DateTimeInterface $dateTime)
548    {
549        $queue = new Queue($this->queue);
550        $queue->withAppointment = ($this->getFirstAppointment()->hasTime()) ? true : false;
551        $queue->waitingTime = ($queue->waitingTime) ? $queue->waitingTime : 0;
552        $queue->wayTime = ($queue->wayTime) ? $queue->wayTime : 0;
553        if ($queue->withAppointment) {
554            $queue->number = $this->id;
555        } else {
556            $queue->number = $this->toProperty()->queue->number->get();
557        }
558        $queue->arrivalTime = $this->getArrivalTime($dateTime)->getTimestamp();
559        return $queue->setProcess($this);
560    }
561
562    public function hasArrivalTime()
563    {
564        $arrivalTime = 0;
565        if ($this->isWithAppointment()) {
566            $arrivalTime = $this->getFirstAppointment()->date;
567        } else {
568            $arrivalTime = $this->toProperty()->queue->arrivalTime->get();
569        }
570        return ($arrivalTime) ? true : false;
571    }
572
573    public function getArrivalTime($default = 'now', $timezone = null)
574    {
575        $arrivalTime = 0;
576        if ($this->isWithAppointment()) {
577            $arrivalTime = $this->getFirstAppointment()->date;
578        } else {
579            $arrivalTime = $this->toProperty()->queue->arrivalTime->get();
580        }
581        $arrivalDateTime = Helper\DateTime::create($default, $timezone);
582        if ($arrivalTime) {
583            $arrivalDateTime = $arrivalDateTime->setTimestamp($arrivalTime);
584        }
585        return $arrivalDateTime;
586    }
587
588    /**
589     * Calculate real waiting time, only available after called
590     */
591    public function getWaitedSeconds($defaultTime = 'now')
592    {
593        return $this->getCallTime($defaultTime)->getTimestamp() - $this->getArrivalTime($defaultTime)->getTimestamp();
594    }
595
596    public function getWaitedMinutes($defaultTime = 'now')
597    {
598        return $this->getWaitedSeconds($defaultTime) / 60;
599    }
600
601    public function getWaySeconds($defaultTime = 'now')
602    {
603        return $this->getShowUpTime($defaultTime)->getTimestamp() - $this->getCallTime($defaultTime)->getTimestamp();
604    }
605
606    public function getWayMinutes($defaultTime = 'now')
607    {
608        return $this->getWaySeconds($defaultTime) / 60;
609    }
610
611    public function toDerefencedAmendment()
612    {
613        $lastChange = (new \DateTimeImmutable())->setTimestamp($this->createTimestamp)->format('c');
614        return var_export(array(
615                'BuergerID' => $this->id,
616                'StandortID' => $this->scope['id'],
617                'Anmerkung' => null,
618                'IPTimeStamp' => $this->createTimestamp,
619                'LastChange' => $lastChange,
620            ), 1);
621    }
622
623    public function toDerefencedCustomTextfield()
624    {
625        $lastChange = (new \DateTimeImmutable())->setTimestamp($this->createTimestamp)->format('c');
626        return var_export(array(
627                'BuergerID' => $this->id,
628                'StandortID' => $this->scope['id'],
629                'CustomTextfield' => null,
630                'IPTimeStamp' => $this->createTimestamp,
631                'LastChange' => $lastChange,
632            ), 1);
633    }
634
635    public function __toString()
636    {
637        $string = "process#";
638        $string .= $this->id ?: $this->archiveId;
639        $string .= ":" . $this->authKey;
640        $string .= " (" . $this->status . ")";
641        $string .= " " . $this->getFirstAppointment()->toDateTime()->format('c');
642        $string .= " " . ($this->isWithAppointment() ? "appoint" : "arrival:" . $this->getArrivalTime()->format('c'));
643        $string .= " " . $this->getFirstAppointment()->slotCount . "slots";
644        $string .= "*" . count($this->appointments);
645        foreach ($this->getRequests() as $request) {
646            $string .= " " . $request['source'] . "." . $request['id'];
647        }
648        $string .= " scope." . $this['scope']['id'];
649        $string .= " ~" . base_convert($this['lastChange'], 10, 35);
650        $string .= " client:" . $this['apiclient']['shortname'];
651        return $string;
652    }
653}