PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / 1.2.11
Booking for Appointments and Events Calendar – Amelia v1.2.11
2.4.4 2.4.3 2.4.2 2.4.1 2.4 trunk 1.2.1 1.2.10 1.2.11 1.2.12 1.2.13 1.2.14 1.2.15 1.2.16 1.2.17 1.2.18 1.2.19 1.2.2 1.2.20 1.2.21 1.2.22 1.2.23 1.2.24 1.2.25 1.2.26 1.2.27 1.2.28 1.2.29 1.2.3 1.2.30 1.2.31 1.2.32 1.2.33 1.2.34 1.2.35 1.2.36 1.2.37 1.2.38 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 2.0 2.0.1 2.0.2 2.1 2.1.1 2.1.2 2.1.3 2.2 2.2.1 2.3
ameliabooking / src / Domain / Services / Schedule / ScheduleService.php
ameliabooking / src / Domain / Services / Schedule Last commit date
ScheduleService.php 3 years ago
ScheduleService.php
246 lines
1 <?php
2
3 namespace AmeliaBooking\Domain\Services\Schedule;
4
5 use AmeliaBooking\Domain\Collection\Collection;
6 use AmeliaBooking\Domain\Common\Exceptions\InvalidArgumentException;
7 use AmeliaBooking\Domain\Entity\Location\Location;
8 use AmeliaBooking\Domain\Entity\Schedule\Period;
9 use AmeliaBooking\Domain\Entity\Schedule\PeriodService;
10 use AmeliaBooking\Domain\Entity\Schedule\SpecialDay;
11 use AmeliaBooking\Domain\Entity\Schedule\SpecialDayPeriod;
12 use AmeliaBooking\Domain\Entity\Schedule\SpecialDayPeriodService;
13 use AmeliaBooking\Domain\Entity\Schedule\TimeOut;
14 use AmeliaBooking\Domain\Entity\Schedule\WeekDay;
15 use AmeliaBooking\Domain\Entity\User\Provider;
16 use AmeliaBooking\Domain\Services\Interval\IntervalService;
17 use AmeliaBooking\Domain\Services\Location\LocationService;
18 use AmeliaBooking\Domain\Services\User\ProviderService;
19 use DateTime;
20 use DateInterval;
21 use DatePeriod;
22 use Exception;
23
24 /**
25 * Class ScheduleService
26 *
27 * @package AmeliaBooking\Domain\Services\Schedule
28 */
29 class ScheduleService
30 {
31 /** @var IntervalService */
32 private $intervalService;
33
34 /** @var ProviderService */
35 private $providerService;
36
37 /** @var ProviderService */
38 private $locationService;
39
40 /**
41 * ScheduleService constructor.
42 *
43 * @param IntervalService $intervalService
44 * @param ProviderService $providerService
45 * @param LocationService $locationService
46 */
47 public function __construct(
48 $intervalService,
49 $providerService,
50 $locationService
51 ) {
52 $this->intervalService = $intervalService;
53
54 $this->providerService = $providerService;
55
56 $this->locationService = $locationService;
57 }
58
59 /** @noinspection MoreThanThreeArgumentsInspection */
60 /**
61 * get special dates intervals for provider.
62 *
63 * @param Provider $provider
64 * @param Collection $locations
65 * @param int|null $locationId
66 * @param int $serviceId
67 *
68 * @return array
69 * @throws Exception
70 * @throws InvalidArgumentException
71 */
72 public function getProviderSpecialDayIntervals($provider, $locations, $locationId, $serviceId)
73 {
74 $intervals = [];
75
76 $hasVisibleLocations = $this->locationService->hasVisibleLocations($locations);
77
78 /** @var Location $providerLocation */
79 $providerLocation = $provider->getLocationId() &&
80 $locations->length() &&
81 $locations->keyExists($provider->getLocationId()->getValue()) ?
82 $locations->getItem($provider->getLocationId()->getValue()) : null;
83
84 /** @var SpecialDay $specialDay */
85 foreach ($provider->getSpecialDayList()->getItems() as $specialDay) {
86 $specialDates = [];
87
88 $endDateCopy = clone $specialDay->getEndDate()->getValue();
89
90 $specialDaysPeriod = new DatePeriod(
91 $specialDay->getStartDate()->getValue(),
92 new DateInterval('P1D'),
93 $endDateCopy->modify('+1 day')
94 );
95
96 /** @var DateTime $day */
97 foreach ($specialDaysPeriod as $day) {
98 $specialDates[$day->format('Y-m-d')] = true;
99 }
100
101 $specialDatesIntervals = [];
102
103 /** @var SpecialDayPeriod $period */
104 foreach ($specialDay->getPeriodList()->getItems() as $period) {
105 /** @var Collection $availablePeriodLocations */
106 $availablePeriodLocations = $this->providerService->getProviderPeriodLocations(
107 $period,
108 $providerLocation,
109 $locations,
110 $hasVisibleLocations
111 );
112
113 if (($hasVisibleLocations && !$availablePeriodLocations->length()) ||
114 ($hasVisibleLocations && $locationId && !$availablePeriodLocations->keyExists($locationId))
115 ) {
116 continue;
117 }
118
119 $hasService = $period->getPeriodServiceList()->length() === 0;
120
121 /** @var SpecialDayPeriodService $periodService */
122 foreach ($period->getPeriodServiceList()->getItems() as $periodService) {
123 if ($periodService->getServiceId()->getValue() === $serviceId) {
124 $hasService = true;
125 }
126 }
127
128 $start = $this->intervalService->getSeconds($period->getStartTime()->getValue()->format('H:i:s'));
129
130 $end = $this->intervalService->getSeconds($this->intervalService->getEndTimeString($period->getEndTime()->getValue()->format('H:i:s')));
131
132 if ($hasService) {
133 $specialDatesIntervals['free'][$start] = [
134 $start,
135 $end,
136 $locationId ? [$locationId] : $availablePeriodLocations->keys(),
137 ];
138 }
139 }
140
141 $intervals[] = [
142 'dates' => $specialDates,
143 'intervals' => $specialDatesIntervals
144 ];
145 }
146
147 return array_reverse($intervals);
148 }
149
150 /** @noinspection MoreThanThreeArgumentsInspection */
151 /**
152 * get week days intervals for provider.
153 *
154 * @param Provider $provider
155 * @param Collection $locations
156 * @param int $serviceId
157 * @param int|null $locationId
158 *
159 * @return array
160 * @throws InvalidArgumentException
161 */
162 public function getProviderWeekDaysIntervals($provider, $locations, $locationId, $serviceId)
163 {
164 $intervals = [];
165
166 $hasVisibleLocations = $this->locationService->hasVisibleLocations($locations);
167
168 /** @var Location $providerLocation */
169 $providerLocation = $provider->getLocationId() && $locations->length() ?
170 $locations->getItem($provider->getLocationId()->getValue()) : null;
171
172 $providerLocationId = $providerLocation ? $providerLocation->getId()->getValue() : null;
173
174 /** @var WeekDay $weekDay */
175 foreach ($provider->getWeekDayList()->getItems() as $weekDay) {
176 $dayIndex = $weekDay->getDayIndex()->getValue();
177
178 $intervals[$dayIndex]['busy'] = [];
179 $intervals[$dayIndex]['free'] = [];
180
181 /** @var TimeOut $timeOut */
182 foreach ($weekDay->getTimeOutList()->getItems() as $timeOut) {
183 $start = $this->intervalService->getSeconds($timeOut->getStartTime()->getValue()->format('H:i:s'));
184
185 $intervals[$dayIndex]['busy'][$start] = [
186 $start,
187 $this->intervalService->getSeconds($timeOut->getEndTime()->getValue()->format('H:i:s'))
188 ];
189 }
190
191 /** @var Period $period */
192 foreach ($weekDay->getPeriodList()->getItems() as $period) {
193 /** @var Collection $availablePeriodLocations */
194 $availablePeriodLocations = $this->providerService->getProviderPeriodLocations(
195 $period,
196 $providerLocation,
197 $locations,
198 $hasVisibleLocations
199 );
200
201 if (($hasVisibleLocations && !$availablePeriodLocations->length()) ||
202 ($hasVisibleLocations && $locationId && !$availablePeriodLocations->keyExists($locationId))
203 ) {
204 continue;
205 }
206
207 $hasService = $period->getPeriodServiceList()->length() === 0;
208
209 /** @var PeriodService $periodService */
210 foreach ($period->getPeriodServiceList()->getItems() as $periodService) {
211 if ($periodService->getServiceId()->getValue() === $serviceId) {
212 $hasService = true;
213 }
214 }
215
216 $start = $this->intervalService->getSeconds($period->getStartTime()->getValue()->format('H:i:s'));
217
218 $end = $this->intervalService->getSeconds($this->intervalService->getEndTimeString($period->getEndTime()->getValue()->format('H:i:s')));
219
220 if ($hasService) {
221 $intervals[$dayIndex]['free'][$start] = [
222 $start,
223 $end,
224 $locationId ? [$locationId] : $availablePeriodLocations->keys(),
225 ];
226 }
227 }
228
229 if ($weekDay->getPeriodList()->length() === 0) {
230 $start = $this->intervalService->getSeconds($weekDay->getStartTime()->getValue()->format('H:i:s'));
231
232 $end = $this->intervalService->getSeconds($this->intervalService->getEndTimeString($weekDay->getEndTime()->getValue()->format('H:i:s')));
233
234 $intervals[$dayIndex]['free'][$start] = [$start, $end, [$providerLocationId]];
235 }
236
237 $intervals[$dayIndex]['free'] = $this->intervalService->getAvailableIntervals(
238 $intervals[$dayIndex]['free'],
239 isset($intervals[$dayIndex]['busy']) ? $intervals[$dayIndex]['busy'] : []
240 );
241 }
242
243 return $intervals;
244 }
245 }
246