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