PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / 1.2.20
Booking for Appointments and Events Calendar – Amelia v1.2.20
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 / Entity / EntityService.php
ameliabooking / src / Domain / Services / Entity Last commit date
EntityService.php 2 years ago
EntityService.php
274 lines
1 <?php
2
3 namespace AmeliaBooking\Domain\Services\Entity;
4
5 use AmeliaBooking\Domain\Collection\Collection;
6 use AmeliaBooking\Domain\Common\Exceptions\InvalidArgumentException;
7 use AmeliaBooking\Domain\Entity\Bookable\Service\Extra;
8 use AmeliaBooking\Domain\Entity\Bookable\Service\Service;
9 use AmeliaBooking\Domain\Entity\Booking\Appointment\Appointment;
10 use AmeliaBooking\Domain\Entity\Booking\SlotsEntities;
11 use AmeliaBooking\Domain\Entity\User\Provider;
12 use AmeliaBooking\Domain\Factory\Booking\SlotsEntitiesFactory;
13 use AmeliaBooking\Domain\Services\DateTime\DateTimeService;
14 use AmeliaBooking\Domain\Services\Resource\AbstractResourceService;
15 use AmeliaBooking\Domain\Services\User\ProviderService;
16 use AmeliaBooking\Domain\ValueObjects\DateTime\DateTimeValue;
17 use AmeliaBooking\Domain\ValueObjects\Duration;
18
19 /**
20 * Class EntityService
21 *
22 * @package AmeliaBooking\Domain\Services\Entity
23 */
24 class EntityService
25 {
26 /** @var ProviderService */
27 private $providerService;
28
29 /** @var AbstractResourceService */
30 private $resourceService;
31
32 /**
33 * EntityService constructor.
34 *
35 * @param ProviderService $providerService
36 * @param AbstractResourceService $resourceService
37 */
38 public function __construct(
39 ProviderService $providerService,
40 AbstractResourceService $resourceService
41 ) {
42 $this->providerService = $providerService;
43
44 $this->resourceService = $resourceService;
45 }
46
47 /**
48 * get filtered entities needed for slots calculation.
49 *
50 * @param array $settings
51 * @param array $props
52 * @param SlotsEntities $slotsEntities
53 *
54 * @return SlotsEntities
55 * @throws InvalidArgumentException
56 */
57 public function getFilteredSlotsEntities($settings, $props, $slotsEntities)
58 {
59 /** @var Collection $services */
60 $services = $slotsEntities->getServices() ?: new Collection();
61
62 /** @var Collection $providers */
63 $providers = $slotsEntities->getProviders() ?: new Collection();
64
65 /** @var Collection $locations */
66 $locations = $slotsEntities->getLocations() ?: new Collection();
67
68 /** @var Collection $filteredProviders */
69 $filteredProviders = new Collection();
70
71 /** @var Provider $provider */
72 foreach ($providers->getItems() as $provider) {
73 if ($provider->getServiceList()->keyExists($props['serviceId'])) {
74 if ($settings['allowAdminBookAtAnyTime']) {
75 $this->providerService->setProvidersAlwaysAvailable(
76 $providers
77 );
78 }
79
80 $this->providerService->setProviderServices(
81 $provider,
82 $services,
83 false
84 );
85
86 /** @var Service $service */
87 foreach ($provider->getServiceList()->getItems() as $service) {
88 $this->checkServiceTimes($service);
89 }
90
91 $filteredProviders->addItem($provider, $provider->getId()->getValue());
92 }
93 }
94
95 /** @var Service $service */
96 foreach ($services->getItems() as $service) {
97 $this->checkServiceTimes($service);
98 }
99
100 /** @var Collection $serviceResources */
101 $serviceResources = $slotsEntities->getResources() ? $this->resourceService->getServiceResources(
102 $slotsEntities->getResources(),
103 $props['serviceId']
104 ) : new Collection();
105
106 $this->resourceService->setNonSharedResources(
107 $serviceResources,
108 [
109 'service' => $services->keys(),
110 'location' => $locations->keys(),
111 ]
112 );
113
114 /** @var SlotsEntities $filteredSlotsEntities */
115 $filteredSlotsEntities = SlotsEntitiesFactory::create();
116
117 $filteredSlotsEntities->setServices($services);
118
119 $filteredSlotsEntities->setProviders($filteredProviders);
120
121 $filteredSlotsEntities->setLocations($locations);
122
123 $filteredSlotsEntities->setResources($serviceResources);
124
125 return $filteredSlotsEntities;
126 }
127
128 /**
129 * Add 0 as duration for service time before or time after if it is null
130 *
131 * @param Service $service
132 *
133 * @throws InvalidArgumentException
134 */
135 private function checkServiceTimes($service)
136 {
137 if (!$service->getTimeBefore()) {
138 $service->setTimeBefore(new Duration(0));
139 }
140
141 if (!$service->getTimeAfter()) {
142 $service->setTimeAfter(new Duration(0));
143 }
144 }
145
146 /**
147 * filter appointments required for slots calculation
148 *
149 * @param SlotsEntities $slotsEntities
150 * @param Collection $appointments
151 * @param array $props
152 *
153 * @return array
154 * @throws InvalidArgumentException
155 */
156 public function filterSlotsAppointments($slotsEntities, $appointments, $props)
157 {
158 /** @var Collection $services */
159 $services = $slotsEntities->getServices();
160
161 /** @var Collection $providers */
162 $providers = $slotsEntities->getProviders();
163
164 $providersIds = $providers->keys();
165
166 /** @var Appointment $appointment */
167 foreach ($appointments->getItems() as $index => $appointment) {
168 if (!in_array($appointment->getProviderId()->getValue(), $providersIds) ||
169 (
170 $props['excludeAppointmentId'] && $index === $props['excludeAppointmentId']
171 )
172 ) {
173 $appointments->deleteItem($index);
174 }
175 }
176
177 $continuousAppointments = [];
178 $continuousAppointmentsProviders = [];
179
180 $lastIndex = null;
181
182 /** @var Appointment $appointment */
183 foreach ($appointments->getItems() as $index => $appointment) {
184 /** @var Provider $provider */
185 $provider = $providers->getItem($appointment->getProviderId()->getValue());
186
187 /** @var Service $providerService */
188 $providerService = $provider->getServiceList()->keyExists($appointment->getServiceId()->getValue()) ?
189 $provider->getServiceList()->getItem($appointment->getServiceId()->getValue()) :
190 $services->getItem($appointment->getServiceId()->getValue());
191
192 $appointment->setService($providerService);
193
194 if ($lastIndex) {
195 /** @var Appointment $previousAppointment */
196 $previousAppointment = $appointments->getItem($lastIndex);
197
198 if ((
199 $previousAppointment->getLocationId() && $appointment->getLocationId() ?
200 $previousAppointment->getLocationId()->getValue() === $appointment->getLocationId()->getValue() : true
201 ) &&
202 $previousAppointment->getProviderId()->getValue() === $appointment->getProviderId()->getValue() &&
203 $previousAppointment->getServiceId()->getValue() === $appointment->getServiceId()->getValue() &&
204 $providerService->getMaxCapacity()->getValue() === 1 &&
205 $appointment->getBookingStart()->getValue()->format('H:i') !== '00:00' &&
206 $previousAppointment->getBookingEnd()->getValue()->format('Y-m-d H:i') ===
207 $appointment->getBookingStart()->getValue()->format('Y-m-d H:i')
208
209 ) {
210
211 $continuousAppointments[$appointment->getBookingStart()->getValue()->format('Y-m-d')]
212 [$appointment->getBookingStart()->getValue()->format('H:i')] = [];
213
214 if (empty($continuousAppointmentsProviders[$appointment->getBookingStart()->getValue()->format('Y-m-d')][$appointment->getProviderId()->getValue()])) {
215 $continuousAppointmentsProviders[$appointment->getBookingStart()->getValue()->format('Y-m-d')][$appointment->getProviderId()->getValue()] = 1;
216 } else {
217 $continuousAppointmentsProviders[$appointment->getBookingStart()->getValue()->format('Y-m-d')][$appointment->getProviderId()->getValue()]++;
218 }
219
220 $previousAppointment->setBookingEnd(
221 new DateTimeValue(
222 DateTimeService::getCustomDateTimeObject(
223 $appointment->getBookingEnd()->getValue()->format('Y-m-d H:i:s')
224 )
225 )
226 );
227
228 $appointments->deleteItem($index);
229 } else {
230 $lastIndex = $index;
231 }
232 } else {
233 $lastIndex = $index;
234 }
235 }
236
237 return [$continuousAppointments, $continuousAppointmentsProviders];
238 }
239
240 /**
241 * Return required time for the appointment in seconds by summing service duration, service time before and after
242 * and each passed extra.
243 *
244 * @param Service $service
245 * @param array $selectedExtras
246 *
247 * @return mixed
248 * @throws InvalidArgumentException
249 */
250 public function getAppointmentRequiredTime($service, $selectedExtras)
251 {
252 $requiredTime =
253 $service->getTimeBefore()->getValue() +
254 $service->getDuration()->getValue() +
255 $service->getTimeAfter()->getValue();
256
257 $extraIds = array_column($selectedExtras, 'id');
258
259 /** @var Extra $extra */
260 foreach ($service->getExtras()->getItems() as $extra) {
261 if (in_array($extra->getId()->getValue(), $extraIds, false)) {
262 if (!$extra->getDuration()) {
263 $extra->setDuration(new Duration(0));
264 }
265
266 $requiredTime += ($extra->getDuration()->getValue() *
267 array_column($selectedExtras, 'quantity', 'id')[$extra->getId()->getValue()]);
268 }
269 }
270
271 return $requiredTime;
272 }
273 }
274