PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / trunk
Booking for Appointments and Events Calendar – Amelia vtrunk
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 10 months ago
ScheduleService.php
249 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 LocationService */
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 (
114 ($hasVisibleLocations && !$availablePeriodLocations->length()) ||
115 ($hasVisibleLocations && $locationId && !$availablePeriodLocations->keyExists($locationId))
116 ) {
117 continue;
118 }
119
120 $hasService = $period->getPeriodServiceList()->length() === 0;
121
122 /** @var SpecialDayPeriodService $periodService */
123 foreach ($period->getPeriodServiceList()->getItems() as $periodService) {
124 if ($periodService->getServiceId()->getValue() === $serviceId) {
125 $hasService = true;
126 }
127 }
128
129 $start = $this->intervalService->getSeconds($period->getStartTime()->getValue()->format('H:i:s'));
130
131 $end = $this->intervalService->getSeconds($this->intervalService->getEndTimeString($period->getEndTime()->getValue()->format('H:i:s')));
132
133 if ($hasService) {
134 $specialDatesIntervals['free'][$start] = [
135 $start,
136 $end,
137 $locationId ? [$locationId] : $availablePeriodLocations->keys(),
138 ];
139 }
140 }
141
142 $intervals[] = [
143 'dates' => $specialDates,
144 'intervals' => $specialDatesIntervals
145 ];
146 }
147
148 return array_reverse($intervals);
149 }
150
151 /** @noinspection MoreThanThreeArgumentsInspection */
152 /**
153 * get week days intervals for provider.
154 *
155 * @param Provider $provider
156 * @param Collection $locations
157 * @param int $serviceId
158 * @param int|null $locationId
159 *
160 * @return array
161 * @throws InvalidArgumentException
162 */
163 public function getProviderWeekDaysIntervals($provider, $locations, $locationId, $serviceId)
164 {
165 $intervals = [];
166
167 $hasVisibleLocations = $this->locationService->hasVisibleLocations($locations);
168
169 /** @var Location $providerLocation */
170 $providerLocation = $provider->getLocationId() && $locations->length()
171 && $locations->keyExists($provider->getLocationId()->getValue()) ?
172 $locations->getItem($provider->getLocationId()->getValue()) : null;
173
174 $providerLocationId = $providerLocation ? $providerLocation->getId()->getValue() : null;
175
176 /** @var WeekDay $weekDay */
177 foreach ($provider->getWeekDayList()->getItems() as $weekDay) {
178 $dayIndex = $weekDay->getDayIndex()->getValue();
179
180 $intervals[$dayIndex]['busy'] = [];
181 $intervals[$dayIndex]['free'] = [];
182
183 /** @var TimeOut $timeOut */
184 foreach ($weekDay->getTimeOutList()->getItems() as $timeOut) {
185 $start = $this->intervalService->getSeconds($timeOut->getStartTime()->getValue()->format('H:i:s'));
186
187 $intervals[$dayIndex]['busy'][$start] = [
188 $start,
189 $this->intervalService->getSeconds($timeOut->getEndTime()->getValue()->format('H:i:s'))
190 ];
191 }
192
193 /** @var Period $period */
194 foreach ($weekDay->getPeriodList()->getItems() as $period) {
195 /** @var Collection $availablePeriodLocations */
196 $availablePeriodLocations = $this->providerService->getProviderPeriodLocations(
197 $period,
198 $providerLocation,
199 $locations,
200 $hasVisibleLocations
201 );
202
203 if (
204 ($hasVisibleLocations && !$availablePeriodLocations->length()) ||
205 ($hasVisibleLocations && $locationId && !$availablePeriodLocations->keyExists($locationId))
206 ) {
207 continue;
208 }
209
210 $hasService = $period->getPeriodServiceList()->length() === 0;
211
212 /** @var PeriodService $periodService */
213 foreach ($period->getPeriodServiceList()->getItems() as $periodService) {
214 if ($periodService->getServiceId()->getValue() === $serviceId) {
215 $hasService = true;
216 }
217 }
218
219 $start = $this->intervalService->getSeconds($period->getStartTime()->getValue()->format('H:i:s'));
220
221 $end = $this->intervalService->getSeconds($this->intervalService->getEndTimeString($period->getEndTime()->getValue()->format('H:i:s')));
222
223 if ($hasService) {
224 $intervals[$dayIndex]['free'][$start] = [
225 $start,
226 $end,
227 $locationId ? [$locationId] : $availablePeriodLocations->keys(),
228 ];
229 }
230 }
231
232 if ($weekDay->getPeriodList()->length() === 0) {
233 $start = $this->intervalService->getSeconds($weekDay->getStartTime()->getValue()->format('H:i:s'));
234
235 $end = $this->intervalService->getSeconds($this->intervalService->getEndTimeString($weekDay->getEndTime()->getValue()->format('H:i:s')));
236
237 $intervals[$dayIndex]['free'][$start] = [$start, $end, [$providerLocationId]];
238 }
239
240 $intervals[$dayIndex]['free'] = $this->intervalService->getAvailableIntervals(
241 $intervals[$dayIndex]['free'],
242 isset($intervals[$dayIndex]['busy']) ? $intervals[$dayIndex]['busy'] : []
243 );
244 }
245
246 return $intervals;
247 }
248 }
249