Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
95.59% covered (success)
95.59%
65 / 68
89.47% covered (warning)
89.47%
17 / 19
CRAP
0.00% covered (danger)
0.00%
0 / 1
Appointment
95.59% covered (success)
95.59%
65 / 68
89.47% covered (warning)
89.47%
17 / 19
33
0.00% covered (danger)
0.00%
0 / 1
 getDefaults
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 toDate
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 toTime
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 hasTime
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 setTime
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 setDateTime
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 addDate
100.00% covered (success)
100.00%
2 / 2
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
 getScope
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 addSlotCount
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
3
 getSlotCount
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getAvailability
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 toDateTime
80.00% covered (warning)
80.00%
4 / 5
0.00% covered (danger)
0.00%
0 / 1
2.03
 getStartTime
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getEndTime
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
4
 getEndTimeWithCustomSlotTime
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 setDateByString
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
2
 isMatching
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
3
 __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\Helper\Property;
6
7/**
8 * Schema-backed entity (ArrayObject::ARRAY_AS_PROPS); document dynamic keys for Psalm.
9 *
10 * @property int|string $date
11 */
12class Appointment extends Schema\Entity
13{
14    public const string PRIMARY = 'id';
15
16    public static $schema = "appointment.json";
17
18    /**
19     * @return (Availability|Scope|int)[]
20     *
21     */
22    #[\Override]
23    public function getDefaults()
24    {
25        return [
26            'date' => 0,
27            'scope' => new Scope(),
28            'availability' => new Availability(),
29            'slotCount' => 0,
30        ];
31    }
32
33    public function toDate(string $lang = 'de'): string|false
34    {
35        // Mittwoch 18. November 2015
36        return ($lang == 'en') ? date('l F d, Y', (int) $this->date) : Helper\DateTime::getFormatedDates(
37            $this->toDateTime(),
38            'EEEE dd. MMMM yyyy'
39        );
40    }
41
42    public function toTime(string $lang = 'de'): string
43    {
44        $suffix = ($lang == 'en') ? ' o\'clock' : ' Uhr';
45        return date('H:i', (int) $this->date) . $suffix;
46    }
47
48    public function hasTime(): bool
49    {
50        if ($this->date == 0) {
51            return false;
52        }
53        $time = $this->toDateTime();
54        return ('00:00' != $time->format('H:i'));
55    }
56
57    /**
58     * Modify time for appointment
59     */
60    public function setTime(mixed $timeString): static
61    {
62        $dateTime = $this->toDateTime();
63        $this->date = $dateTime->modify($timeString)->getTimestamp();
64        return $this;
65    }
66
67    public function setDateTime(\DateTimeInterface $dateTime): static
68    {
69        $this->date = $dateTime->getTimestamp();
70        return $this;
71    }
72
73    public function addDate(int $date): static
74    {
75        $this->date = $date;
76        return $this;
77    }
78
79    public function addScope(mixed $scopeId): static
80    {
81        $this->getScope()->id = $scopeId;
82        return $this;
83    }
84
85    public function getScope(): Scope
86    {
87        $this->scope = ($this->toProperty()->scope->isAvailable()) ? new Scope($this['scope']) : new Scope();
88        return $this->scope;
89    }
90
91    public function addSlotCount(int|null $slotCount = null): static
92    {
93        if ($slotCount !== null && $slotCount !== 0) {
94            $this->slotCount = $slotCount;
95        } else {
96            $this->slotCount += 1;
97        }
98
99        return $this;
100    }
101
102    public function getSlotCount(): mixed
103    {
104        return $this->slotCount;
105    }
106
107    public function getAvailability(): Availability
108    {
109        $data = array();
110        if (Property::__keyExists('availability', $this)) {
111            $data = $this['availability'];
112        }
113        return new Availability($data);
114    }
115
116    public function toDateTime(string $timezone = 'Europe/Berlin'): \DateTimeImmutable
117    {
118        $date = (new \DateTimeImmutable())->setTimestamp((int) $this->date);
119        //$date = \DateTimeImmutable::createFromFormat("U", $this->date);
120        if ($timezone === '') {
121            $timezone = 'Europe/Berlin';
122        }
123        $date = $date->setTimeZone(new \DateTimeZone($timezone));
124        return $date;
125    }
126
127    public function getStartTime(): \DateTimeImmutable
128    {
129        $time = $this->toDateTime();
130        return $time;
131    }
132
133    public function getEndTime(): mixed
134    {
135        $time = $this->getStartTime();
136        $availability = $this->getAvailability();
137        return ($availability->slotTimeInMinutes !== null
138            && $availability->slotTimeInMinutes !== ''
139            && (int) $availability->slotTimeInMinutes !== 0)
140          ? $time->modify('+' . ($availability->slotTimeInMinutes * $this->slotCount) . ' minutes')
141          : $time;
142    }
143
144    public function getEndTimeWithCustomSlotTime(mixed $slotTimeInMinutes): mixed
145    {
146        $time = $this->getStartTime();
147        return $time->modify('+' . ($slotTimeInMinutes * $this->slotCount) . ' minutes');
148    }
149
150    public function setDateByString(string $dateString, string $format = 'Y-m-d H:i'): static
151    {
152        $appointmentDateTime = \DateTimeImmutable::createFromFormat($format, $dateString);
153        if ($appointmentDateTime) {
154            $this->date = $appointmentDateTime->format('U');
155        } else {
156            throw new Exception\DateStringWrongFormat(
157                "String " . htmlspecialchars($dateString) . " not format " . htmlspecialchars($format)
158            );
159        }
160        return $this;
161    }
162
163    /**
164     * Does two appointments match, the matching appointment might have a lower slot count
165     */
166    public function isMatching(self $appointment): bool
167    {
168        if (
169            $appointment['scope']['id'] == $this['scope']['id']
170            && $appointment['date'] == $this['date']
171        ) {
172            return true;
173        }
174        return false;
175    }
176
177    public function __toString()
178    {
179        return "appointment#"
180            . $this->toDateTime()->format('c')
181            . " " . $this['slotCount'] . "slots"
182            . " scope" . $this['scope']['id']
183            ;
184    }
185}