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