Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
64.62% covered (warning)
64.62%
84 / 130
48.98% covered (danger)
48.98%
24 / 49
CRAP
0.00% covered (danger)
0.00%
0 / 1
Scope
64.62% covered (warning)
64.62%
84 / 130
48.98% covered (danger)
48.98%
24 / 49
439.93
0.00% covered (danger)
0.00%
0 / 1
 getDefaults
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
1
 getSource
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getShortName
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getEmailFrom
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getEmailRequired
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getTelephoneActivated
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getTelephoneRequired
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getCustomTextfieldActivated
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getCustomTextfieldRequired
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getCustomTextfieldLabel
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getCustomTextfield2Activated
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getCustomTextfield2Required
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getCustomTextfield2Label
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getCaptchaActivatedRequired
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getInfoForAppointment
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getInfoForAllAppointments
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getProvider
66.67% covered (warning)
66.67%
6 / 9
0.00% covered (danger)
0.00%
0 / 1
5.93
 getProviderId
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getDayoffList
28.57% covered (danger)
28.57%
2 / 7
0.00% covered (danger)
0.00%
0 / 1
24.86
 getClosureList
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
56
 getRequestList
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getPreference
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
3
 getStatus
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getContactEmail
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getName
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getScopeInfo
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getScopeHint
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getDisplayNumberPrefix
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getAlternateRedirectUrl
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
 getAppointmentsPerMail
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
 getSlotsPerAppointment
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
 getWhitelistedMails
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
 getReservationDuration
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getWaitingTimeFromQueueList
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
 getCalculatedWorkstationCount
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
4
 getBookableStartDate
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 getBookableEndDate
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 updateStatusQueue
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
1 / 1
4
 incrementDisplayNumber
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
6
 hasEmailFrom
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 isEmailRequired
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
3
 isTelephoneRequired
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
 hasAccess
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
2
 withProviderSourceFrom
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 withLessData
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
5
 setStatusQueue
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 setStatusAvailability
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 isNewerThan
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 __toString
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3namespace BO\Zmsentities;
4
5use BO\Zmsentities\Collection\ClosureList;
6use BO\Zmsentities\Collection\DayoffList;
7
8/**
9 * @SuppressWarnings(Complexity)
10 */
11class Scope extends Schema\Entity implements Useraccount\AccessInterface
12{
13    public const string PRIMARY = 'id';
14
15    public static $schema = "scope.json";
16
17    /**
18     * @return (Contact|DayoffList|Provider|int|string)[]
19     *
20     */
21    #[\Override]
22    public function getDefaults()
23    {
24        return [
25            'id' => 0,
26            'source' => 'dldb',
27            'contact' => new Contact(),
28            'provider' => new Provider(),
29            'shortName' => '',
30            'dayoff' => new DayoffList()
31        ];
32    }
33
34    public function getSource()
35    {
36        return $this->toProperty()->source->get();
37    }
38
39    public function getShortName()
40    {
41        return $this->toProperty()->shortName->get();
42    }
43
44    public function getEmailFrom()
45    {
46        return $this->getPreference('client', 'emailFrom', null);
47    }
48
49    public function getEmailRequired()
50    {
51        return $this->getPreference('client', 'emailRequired', null);
52    }
53
54    public function getTelephoneActivated()
55    {
56        return $this->getPreference('client', 'telephoneActivated', null);
57    }
58
59    public function getTelephoneRequired()
60    {
61        return $this->getPreference('client', 'telephoneRequired', null);
62    }
63
64    public function getCustomTextfieldActivated()
65    {
66        return $this->getPreference('client', 'customTextfieldActivated', null);
67    }
68
69    public function getCustomTextfieldRequired()
70    {
71        return $this->getPreference('client', 'customTextfieldRequired', null);
72    }
73
74    public function getCustomTextfieldLabel()
75    {
76        return $this->getPreference('client', 'customTextfieldLabel', '');
77    }
78
79    public function getCustomTextfield2Activated()
80    {
81        return $this->getPreference('client', 'customTextfield2Activated', null);
82    }
83
84    public function getCustomTextfield2Required()
85    {
86        return $this->getPreference('client', 'customTextfield2Required', null);
87    }
88
89    public function getCustomTextfield2Label()
90    {
91        return $this->getPreference('client', 'customTextfield2Label', '');
92    }
93
94    public function getCaptchaActivatedRequired()
95    {
96        return $this->getPreference('client', 'captchaActivatedRequired', null);
97    }
98
99    public function getInfoForAppointment()
100    {
101        return $this->getPreference('appointment', 'infoForAppointment', null);
102    }
103
104    public function getInfoForAllAppointments()
105    {
106        return $this->getPreference('appointment', 'infoForAllAppointments', null);
107    }
108
109
110    public function getProvider(): Provider
111    {
112        if (!isset($this->provider)) {
113            throw new Exception\ScopeMissingProvider("Provider is missing", 500);
114        }
115        if (!$this->provider instanceof Provider) {
116            $this->provider = new Provider($this->toProperty()->provider->get());
117        }
118        if (!isset($this->provider['id']) || !$this->provider->id) {
119            $exception = new Exception\ScopeMissingProvider("No reference to a provider found for scope $this->id");
120            $exception->data['scope'] = $this->getArrayCopy();
121            throw $exception;
122        }
123        return $this->provider;
124    }
125
126    public function getProviderId()
127    {
128        return $this->getProvider()->id;
129    }
130
131    public function getDayoffList(): DayoffList
132    {
133        if (!isset($this->dayoff) || !$this->dayoff instanceof Collection\DayoffList) {
134            $this->dayoff = (!isset($this->dayoff) || !is_array($this->dayoff)) ? [] : $this->dayoff;
135            $this->dayoff = new Collection\DayoffList($this->dayoff);
136            foreach ($this->dayoff as $key => $dayoff) {
137                if (!$dayoff instanceof Dayoff) {
138                    $this->dayoff[$key] = new Dayoff($dayoff);
139                }
140            }
141        }
142        return $this->dayoff;
143    }
144
145    public function getClosureList(): ClosureList
146    {
147        if (!isset($this->closure) || !$this->closure instanceof Collection\ClosureList) {
148            $this->closure = (!isset($this->closure) || !is_array($this->closure)) ? [] : $this->closure;
149            $this->closure = new Collection\ClosureList($this->closure);
150            foreach ($this->closure as $key => $closure) {
151                if (!$closure instanceof Closure) {
152                    $this->closure[$key] = new Closure($closure);
153                }
154            }
155        }
156        return $this->closure;
157    }
158
159    public function getRequestList()
160    {
161        return $this->getProvider()->getRequestList();
162    }
163
164    /**
165     * @param false|null|string $isBool
166     *
167     */
168    public function getPreference(string $preferenceKey, string $index, string|false|null $isBool = false, $default = null)
169    {
170        $preference = $this->toProperty()->preferences->$preferenceKey->$index->get($default);
171        return ($isBool) ? ($preference ? 1 : 0) : $preference;
172    }
173
174    public function getStatus(string $statusKey, string $index)
175    {
176        return $this->toProperty()->status->$statusKey->$index->get();
177    }
178
179    public function getContactEmail()
180    {
181        return $this->toProperty()->contact->email->get();
182    }
183
184    public function getName()
185    {
186        return $this->toProperty()->contact->name->get();
187    }
188
189    public function getScopeInfo()
190    {
191        return $this->toProperty()->preferences->ticketprinter->buttonName->get();
192    }
193
194    public function getScopeHint()
195    {
196        return $this->toProperty()->hint->get();
197    }
198
199    public function getDisplayNumberPrefix()
200    {
201        return $this->toProperty()->preferences->queue->displayNumberPrefix->get();
202    }
203
204    public function getAlternateRedirectUrl()
205    {
206        $alternateUrl = $this->toProperty()->preferences->client->alternateAppointmentUrl->get();
207
208        return ($alternateUrl) ? $alternateUrl : null;
209    }
210
211    public function getAppointmentsPerMail()
212    {
213        $appointmentsPerMail = $this->toProperty()->preferences->client->appointmentsPerMail->get();
214
215        return ($appointmentsPerMail) ? $appointmentsPerMail : null;
216    }
217
218    public function getSlotsPerAppointment()
219    {
220        $slotsPerAppointment = $this->toProperty()->preferences->client->slotsPerAppointment->get();
221
222        return ($slotsPerAppointment) ? $slotsPerAppointment : null;
223    }
224
225    public function getWhitelistedMails()
226    {
227        $emails = $this->toProperty()->preferences->client->whitelistedMails->get();
228
229        return ($emails) ? $emails : '';
230    }
231
232    public function getReservationDuration()
233    {
234        return $this->toProperty()->preferences->appointment->reservationDuration->get();
235    }
236
237    public function getWaitingTimeFromQueueList(Collection\QueueList $queueList, \DateTimeInterface $dateTime)
238    {
239        return $queueList->getEstimatedWaitingTime(
240            $this->getPreference('queue', 'processingTimeAverage'),
241            $this->getCalculatedWorkstationCount(),
242            $dateTime
243        );
244    }
245
246    public function getCalculatedWorkstationCount()
247    {
248        $workstationCount = null;
249        if ($this->getStatus('queue', 'workstationCount') > 0) {
250            $workstationCount = $this->getStatus('queue', 'workstationCount');
251        } elseif (! $workstationCount && $this->getStatus('queue', 'ghostWorkstationCount') > 0) {
252            $workstationCount = $this->getStatus('queue', 'ghostWorkstationCount');
253        }
254        return $workstationCount;
255    }
256
257    /**
258    * Get last bookable start date of a scope
259    *
260    * @return \DateTimeImmutable $scopeEndDate
261    */
262    public function getBookableStartDate(\DateTimeInterface $now)
263    {
264        $now = Helper\DateTime::create($now);
265        $scopeStartDate = $this->toProperty()->preferences->appointment->startInDaysDefault->get();
266        return ($scopeStartDate) ? $now->modify('+' . $scopeStartDate . 'days') : $now;
267    }
268
269    /**
270    * Get last bookable end date of a scope
271    *
272    * @return \DateTimeImmutable $scopeEndDate
273    */
274    public function getBookableEndDate(\DateTimeInterface $now)
275    {
276        $now = Helper\DateTime::create($now);
277        $scopeEndDate = $this->toProperty()->preferences->appointment->endInDaysDefault->get();
278        return ($scopeEndDate) ? $now->modify('+' . $scopeEndDate . 'days') : $now;
279    }
280
281    public function updateStatusQueue(\DateTimeInterface $dateTime): static
282    {
283        $lastQueueUpdateDate = Helper\DateTime::create()
284            ->setTimestamp($this->getStatus('queue', 'lastGivenNumberTimestamp'));
285        if ($lastQueueUpdateDate->format('Y-m-d') == $dateTime->format('Y-m-d')) {
286            $this->setStatusQueue('lastGivenNumber', $this->getStatus('queue', 'lastGivenNumber') + 1);
287            $this->setStatusQueue('givenNumberCount', $this->getStatus('queue', 'givenNumberCount') + 1);
288        } else {
289            $this->setStatusQueue('lastGivenNumber', $this->getPreference('queue', 'firstNumber'));
290            $this->setStatusQueue('givenNumberCount', 1);
291        }
292        if ($this->getStatus('queue', 'lastGivenNumber') < $this->getPreference('queue', 'firstNumber')) {
293            $this->setStatusQueue('lastGivenNumber', $this->getPreference('queue', 'firstNumber'));
294        } elseif ($this->getStatus('queue', 'lastGivenNumber') > $this->getPreference('queue', 'lastNumber')) {
295            $this->setStatusQueue('lastGivenNumber', $this->getPreference('queue', 'firstNumber'));
296        }
297        $this->setStatusQueue('lastGivenNumberTimestamp', $dateTime->getTimestamp());
298        return $this;
299    }
300
301    public function incrementDisplayNumber(): static
302    {
303        if ($this->getStatus('queue', 'lastDisplayNumber') >= $this->getStatus('queue', 'maxDisplayNumber')) {
304            $this->setStatusQueue('lastDisplayNumber', 1);
305            return $this;
306        }
307
308        $this->setStatusQueue('lastDisplayNumber', $this->getStatus('queue', 'lastDisplayNumber') + 1);
309        return $this;
310    }
311
312    public function hasEmailFrom(): bool
313    {
314        $emailFrom = $this->getPreference('client', 'emailFrom');
315        return ($emailFrom) ? true : false;
316    }
317
318    public function isEmailRequired(): bool
319    {
320        $emailFrom = $this->getPreference('client', 'emailFrom');
321        $emailRequired = $this->getPreference('client', 'emailRequired');
322        return ($emailFrom && $emailRequired) ? true : false;
323    }
324
325    public function isTelephoneRequired(): bool
326    {
327        $telephoneRequired = $this->getPreference('client', 'telephoneRequired');
328        return $telephoneRequired ? true : false;
329    }
330
331    /**
332     * @return bool
333     */
334    #[\Override]
335    public function hasAccess(Useraccount $useraccount)
336    {
337        return $useraccount->isSuperUser() ||  $useraccount->hasScope($this->id);
338    }
339
340    /**
341     * Keep provider and source unchanged (non-superusers must not reassign scope location data).
342     */
343    public function withProviderSourceFrom(self $reference): self
344    {
345        $entity = clone $this;
346        $entity['source'] = $reference->getSource();
347        $entity->provider = new Provider($reference->getProvider()->getArrayCopy());
348        return $entity;
349    }
350
351    /**
352     * Reduce data of dereferenced entities to a required minimum
353     *
354     * @return static
355     */
356    #[\Override]
357    public function withLessData(array $keepArray = [])
358    {
359        $entity = clone $this;
360        if (! in_array('dayoff', $keepArray) && $entity->toProperty()->dayoff->isAvailable()) {
361            unset($entity['dayoff']);
362        }
363        if (! in_array('status', $keepArray)) {
364            unset($entity['status']);
365        }
366        if (! in_array('preferences', $keepArray)) {
367            unset($entity['preferences']);
368        }
369
370        return $entity;
371    }
372
373    public function setStatusQueue(string $key, int $value): static
374    {
375        $this->status['queue'][$key] = $value;
376        return $this;
377    }
378
379    public function setStatusAvailability($key, $value): static
380    {
381        $this->status['availability'][$key] = $value;
382        return $this;
383    }
384
385    /**
386     * Check if scope is newer than given time
387     *
388     * @return bool
389     */
390    public function isNewerThan(\DateTimeInterface $dateTime)
391    {
392        return ($dateTime->getTimestamp() < $this->lastChange);
393    }
394
395    public function __toString()
396    {
397        $string = 'scope#';
398        $string .= $this['id'];
399        $string .= ' ';
400        $string .= $this->getName();
401        return $string;
402    }
403}