PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / 1.2.20
Booking for Appointments and Events Calendar – Amelia v1.2.20
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 / Application / Commands / Booking / Appointment / ReassignBookingCommandHandler.php
ameliabooking / src / Application / Commands / Booking / Appointment Last commit date
AddAppointmentCommand.php 7 years ago AddAppointmentCommandHandler.php 1 year ago AddBookingCommand.php 7 years ago AddBookingCommandHandler.php 1 year ago ApproveBookingRemotelyCommand.php 2 years ago ApproveBookingRemotelyCommandHandler.php 1 year ago CancelBookingCommand.php 7 years ago CancelBookingCommandHandler.php 2 years ago CancelBookingRemotelyCommand.php 7 years ago CancelBookingRemotelyCommandHandler.php 2 years ago DeleteAppointmentCommand.php 7 years ago DeleteAppointmentCommandHandler.php 2 years ago DeleteBookingCommand.php 4 years ago DeleteBookingCommandHandler.php 2 years ago GetAppointmentCommand.php 7 years ago GetAppointmentCommandHandler.php 1 year ago GetAppointmentsCommand.php 7 years ago GetAppointmentsCommandHandler.php 1 year ago GetIcsCommand.php 5 years ago GetIcsCommandHandler.php 4 years ago GetPackageAppointmentsCommand.php 1 year ago GetPackageAppointmentsCommandHandler.php 1 year ago GetTimeSlotsCommand.php 7 years ago GetTimeSlotsCommandHandler.php 1 year ago ReassignBookingCommand.php 5 years ago ReassignBookingCommandHandler.php 1 year ago RejectBookingRemotelyCommand.php 2 years ago RejectBookingRemotelyCommandHandler.php 1 year ago SuccessfulBookingCommand.php 7 years ago SuccessfulBookingCommandHandler.php 1 year ago UpdateAppointmentCommand.php 7 years ago UpdateAppointmentCommandHandler.php 1 year ago UpdateAppointmentStatusCommand.php 7 years ago UpdateAppointmentStatusCommandHandler.php 1 year ago UpdateAppointmentTimeCommand.php 7 years ago UpdateAppointmentTimeCommandHandler.php 1 year ago UpdateBookingStatusCommand.php 1 year ago UpdateBookingStatusCommandHandler.php 1 year ago
ReassignBookingCommandHandler.php
658 lines
1 <?php
2
3 namespace AmeliaBooking\Application\Commands\Booking\Appointment;
4
5 use AmeliaBooking\Application\Commands\CommandHandler;
6 use AmeliaBooking\Application\Commands\CommandResult;
7 use AmeliaBooking\Application\Common\Exceptions\AccessDeniedException;
8 use AmeliaBooking\Application\Services\Bookable\BookableApplicationService;
9 use AmeliaBooking\Application\Services\Booking\AppointmentApplicationService;
10 use AmeliaBooking\Application\Services\Booking\BookingApplicationService;
11 use AmeliaBooking\Application\Services\Payment\PaymentApplicationService;
12 use AmeliaBooking\Application\Services\Reservation\AppointmentReservationService;
13 use AmeliaBooking\Application\Services\TimeSlot\TimeSlotService as ApplicationTimeSlotService;
14 use AmeliaBooking\Application\Services\User\UserApplicationService;
15 use AmeliaBooking\Domain\Collection\Collection;
16 use AmeliaBooking\Domain\Common\Exceptions\AuthorizationException;
17 use AmeliaBooking\Domain\Common\Exceptions\BookingCancellationException;
18 use AmeliaBooking\Domain\Common\Exceptions\InvalidArgumentException;
19 use AmeliaBooking\Domain\Entity\Bookable\Service\Service;
20 use AmeliaBooking\Domain\Entity\Booking\Appointment\Appointment;
21 use AmeliaBooking\Domain\Entity\Booking\Appointment\CustomerBooking;
22 use AmeliaBooking\Domain\Entity\Entities;
23 use AmeliaBooking\Domain\Entity\User\AbstractUser;
24 use AmeliaBooking\Domain\Entity\User\Customer;
25 use AmeliaBooking\Domain\Factory\Booking\Appointment\AppointmentFactory;
26 use AmeliaBooking\Domain\Services\DateTime\DateTimeService;
27 use AmeliaBooking\Domain\Services\Settings\SettingsService;
28 use AmeliaBooking\Domain\ValueObjects\BooleanValueObject;
29 use AmeliaBooking\Domain\ValueObjects\DateTime\DateTimeValue;
30 use AmeliaBooking\Domain\ValueObjects\Json;
31 use AmeliaBooking\Domain\ValueObjects\Number\Integer\Id;
32 use AmeliaBooking\Domain\ValueObjects\Number\Integer\IntegerValue;
33 use AmeliaBooking\Domain\ValueObjects\String\BookingStatus;
34 use AmeliaBooking\Domain\ValueObjects\String\Description;
35 use AmeliaBooking\Infrastructure\Common\Exceptions\NotFoundException;
36 use AmeliaBooking\Infrastructure\Common\Exceptions\QueryExecutionException;
37 use AmeliaBooking\Infrastructure\Repository\Booking\Appointment\AppointmentRepository;
38 use AmeliaBooking\Infrastructure\Repository\Booking\Appointment\CustomerBookingRepository;
39 use AmeliaBooking\Infrastructure\Repository\User\CustomerRepository;
40 use AmeliaBooking\Infrastructure\WP\Translations\FrontendStrings;
41 use Exception;
42 use Interop\Container\Exception\ContainerException;
43
44 /**
45 * Class ReassignBookingCommandHandler
46 *
47 * @package AmeliaBooking\Application\Commands\Booking\Appointment
48 */
49 class ReassignBookingCommandHandler extends CommandHandler
50 {
51 /**
52 * @var array
53 */
54 public $mandatoryFields = [
55 ];
56
57 /**
58 * @param ReassignBookingCommand $command
59 *
60 * @return CommandResult
61 *
62 * @throws AccessDeniedException
63 * @throws InvalidArgumentException
64 * @throws QueryExecutionException
65 * @throws NotFoundException
66 * @throws ContainerException
67 * @throws Exception
68 */
69 public function handle(ReassignBookingCommand $command)
70 {
71 $this->checkMandatoryFields($command);
72
73 $result = new CommandResult();
74
75 /** @var UserApplicationService $userAS */
76 $userAS = $this->container->get('application.user.service');
77 /** @var SettingsService $settingsDS */
78 $settingsDS = $this->container->get('domain.settings.service');
79 /** @var AppointmentRepository $appointmentRepository */
80 $appointmentRepository = $this->container->get('domain.booking.appointment.repository');
81 /** @var CustomerBookingRepository $bookingRepository */
82 $bookingRepository = $this->container->get('domain.booking.customerBooking.repository');
83 /** @var CustomerRepository $customerRepository */
84 $customerRepository = $this->container->get('domain.users.customers.repository');
85 /** @var AppointmentApplicationService $appointmentAS */
86 $appointmentAS = $this->container->get('application.booking.appointment.service');
87 /** @var BookableApplicationService $bookableAS */
88 $bookableAS = $this->container->get('application.bookable.service');
89 /** @var AppointmentReservationService $reservationService */
90 $reservationService = $this->container->get('application.reservation.service')->get(Entities::APPOINTMENT);
91 /** @var PaymentApplicationService $paymentAS */
92 $paymentAS = $this->container->get('application.payment.service');
93
94 try {
95 /** @var AbstractUser $user */
96 $user = $command->getUserApplicationService()->authorization(
97 $command->getPage() === 'cabinet' ? $command->getToken() : null,
98 $command->getCabinetType()
99 );
100 } catch (AuthorizationException $e) {
101 $result->setResult(CommandResult::RESULT_ERROR);
102 $result->setData(
103 [
104 'reauthorize' => true
105 ]
106 );
107
108 return $result;
109 }
110
111 if ($userAS->isCustomer($user) && !$settingsDS->getSetting('roles', 'allowCustomerReschedule')
112 ) {
113 throw new AccessDeniedException('You are not allowed to update booking');
114 }
115
116 /** @var Appointment $oldAppointment */
117 $oldAppointment = $reservationService->getReservationByBookingId((int)$command->getArg('id'));
118
119 $oldAppointment->setInitialBookingStart(
120 new DateTimeValue(clone $oldAppointment->getBookingStart()->getValue())
121 );
122
123 $oldAppointment->setInitialBookingEnd(
124 new DateTimeValue(clone $oldAppointment->getBookingEnd()->getValue())
125 );
126
127 /** @var CustomerBooking $booking */
128 $booking = $oldAppointment->getBookings()->getItem((int)$command->getArg('id'));
129
130 if ($command->getField('customFields')) {
131 $customFields = json_encode($command->getField('customFields'));
132
133 if (!$booking->getCustomFields() || $booking->getCustomFields()->getValue() !== $customFields) {
134 $booking->setUpdated(new BooleanValueObject(true));
135 }
136
137 $booking->setCustomFields(new Json($customFields));
138 }
139
140 /** @var CustomerBooking $oldAppointmentBooking */
141 foreach ($oldAppointment->getBookings()->getItems() as $oldAppointmentBooking) {
142 if ($userAS->isAmeliaUser($user) &&
143 $userAS->isCustomer($user) &&
144 ($booking->getId()->getValue() === $oldAppointmentBooking->getId()->getValue()) &&
145 ($user->getId() && $oldAppointmentBooking->getCustomerId()->getValue() !== $user->getId()->getValue())
146 ) {
147 throw new AccessDeniedException('You are not allowed to update booking');
148 }
149 }
150
151 /** @var Service $service */
152 $service = $bookableAS->getAppointmentService(
153 $oldAppointment->getServiceId()->getValue(),
154 $oldAppointment->getProviderId()->getValue()
155 );
156
157 $requiredServiceId = $command->getField('serviceId') ?: $oldAppointment->getServiceId()->getValue();
158
159 $requiredProviderId = $command->getField('providerId') ?: $oldAppointment->getProviderId()->getValue();
160
161 $requiredLocationId = $command->getField('locationId')
162 ?: (
163 $oldAppointment->getLocationId() ? $oldAppointment->getLocationId()->getValue() : null
164 );
165
166 $requiredBookingStatus = $command->getField('status') ?: $booking->getStatus()->getValue();
167
168 if ($userAS->isCustomer($user) &&
169 (
170 $requiredBookingStatus !== $booking->getStatus()->getValue() ||
171 $requiredServiceId !== $oldAppointment->getServiceId()->getValue() ||
172 $requiredProviderId !== $oldAppointment->getProviderId()->getValue() ||
173 $requiredLocationId !== (
174 $oldAppointment->getLocationId() ? $oldAppointment->getLocationId()->getValue() : null
175 )
176 )
177 ) {
178 throw new AccessDeniedException('You are not allowed to update booking');
179 }
180
181 $excludedAppointmentId = $oldAppointment->getBookings()->length() > 1 &&
182 (
183 $oldAppointment->getServiceId()->getValue() !== $requiredServiceId ||
184 $oldAppointment->getProviderId()->getValue() !== $requiredProviderId ||
185 (
186 $oldAppointment->getLocationId() &&
187 $oldAppointment->getLocationId()->getValue() !== $requiredLocationId
188 )
189 )
190 ? null
191 : $oldAppointment->getId()->getValue();
192
193 /** @var Service $requiredService */
194 $requiredService =
195 ($requiredServiceId !== $oldAppointment->getServiceId()->getValue()) ||
196 ($requiredProviderId !== $oldAppointment->getProviderId()->getValue())
197 ? $bookableAS->getAppointmentService($requiredServiceId, $requiredProviderId)
198 : $service;
199
200 $minimumRescheduleTimeInSeconds = $settingsDS
201 ->getEntitySettings($service->getSettings())
202 ->getGeneralSettings()
203 ->getMinimumTimeRequirementPriorToRescheduling();
204
205 if ($user && $user->getType() === AbstractUser::USER_ROLE_CUSTOMER) {
206 try {
207 $reservationService->inspectMinimumCancellationTime(
208 $oldAppointment->getBookingStart()->getValue(),
209 $minimumRescheduleTimeInSeconds
210 );
211 } catch (BookingCancellationException $e) {
212 $result->setResult(CommandResult::RESULT_ERROR);
213 $result->setMessage('You are not allowed to update booking');
214 $result->setData(
215 [
216 'rescheduleBookingUnavailable' => true
217 ]
218 );
219
220 return $result;
221 }
222 }
223
224 $bookingStart = $command->getField('bookingStart')
225 ? substr($command->getField('bookingStart'), 0, 16) . ':00'
226 : $oldAppointment->getBookingStart()->getValue()->format('Y-m-d H:i:s');
227
228 $bookingStartInUtc = DateTimeService::getCustomDateTimeObject(
229 $bookingStart
230 )->setTimezone(new \DateTimeZone('UTC'))->format('Y-m-d H:i');
231
232 if ($command->getField('timeZone') === 'UTC') {
233 $bookingStart = DateTimeService::getCustomDateTimeFromUtc(
234 $bookingStart
235 );
236 } elseif ($command->getField('timeZone')) {
237 $bookingStart = DateTimeService::getDateTimeObjectInTimeZone(
238 $bookingStart,
239 $command->getField('timeZone')
240 )->setTimezone(DateTimeService::getTimeZone())->format('Y-m-d H:i:s');
241 } elseif ($command->getField('utcOffset') !== null &&
242 $settingsDS->getSetting('general', 'showClientTimeZone')
243 ) {
244 $bookingStart = DateTimeService::getCustomDateTimeFromUtc(
245 $bookingStart
246 );
247 }
248
249 $bookingRescheduled = $bookingStart !== $oldAppointment->getBookingStart()->getValue()->format('Y-m-d H:i:s');
250
251 if (!$bookingRescheduled && (
252 (
253 $requiredBookingStatus &&
254 $booking->getStatus()->getValue() !== $requiredBookingStatus
255 ) ||
256 $oldAppointment->getProviderId()->getValue() !== $requiredProviderId
257 )
258 ) {
259 $booking->setUpdated(new BooleanValueObject(true));
260
261 $oldAppointment->getBookings()->getItem($booking->getId()->getValue())->setUpdated(
262 new BooleanValueObject(true)
263 );
264 }
265
266 /** @var ApplicationTimeSlotService $applicationTimeSlotService */
267 $applicationTimeSlotService = $this->container->get('application.timeSlot.service');
268
269 if (!$applicationTimeSlotService->isSlotFree(
270 $requiredService,
271 DateTimeService::getCustomDateTimeObject(
272 $bookingStart
273 ),
274 DateTimeService::getCustomDateTimeObject(
275 $bookingStart
276 ),
277 DateTimeService::getCustomDateTimeObject(
278 $bookingStart
279 ),
280 $requiredProviderId,
281 $requiredLocationId,
282 $booking->getExtras()->getItems(),
283 $excludedAppointmentId,
284 $booking->getPersons()->getValue(),
285 $user->getType() === AbstractUser::USER_ROLE_CUSTOMER
286 )) {
287 $result->setResult(CommandResult::RESULT_ERROR);
288 $result->setMessage(FrontendStrings::getCommonStrings()['time_slot_unavailable']);
289 $result->setData(
290 [
291 'timeSlotUnavailable' => true
292 ]
293 );
294
295 return $result;
296 }
297
298 /** @var AppointmentReservationService $reservationService */
299 $reservationService = $this->container->get('application.reservation.service')->get(Entities::APPOINTMENT);
300
301 if ($reservationService->checkLimitsPerCustomer(
302 $requiredService,
303 $oldAppointmentBooking->getCustomerId()->getValue(),
304 DateTimeService::getCustomDateTimeObject($bookingStart),
305 $oldAppointmentBooking->getId()->getValue()
306 )) {
307 $result->setResult(CommandResult::RESULT_ERROR);
308 $result->setMessage(FrontendStrings::getCommonStrings()['time_slot_unavailable']);
309 $result->setData(
310 [
311 'timeSlotUnavailable' => true
312 ]
313 );
314
315 return $result;
316 }
317
318 $setTimeZone = false;
319
320 if ($booking->getInfo() && $booking->getInfo()->getValue()) {
321 $info = json_decode($booking->getInfo()->getValue(), true);
322
323 if (empty($info['timeZone'])) {
324 $setTimeZone = true;
325 }
326 } else if (!$booking->getInfo() || $booking->getInfo()->getValue() === null) {
327 $setTimeZone = true;
328 }
329
330 if ($setTimeZone &&
331 (!$booking->getUtcOffset() || $booking->getInfo()->getValue() === null) &&
332 $userAS->isCustomer($user) &&
333 $command->getField('timeZone') &&
334 $command->getField('timeZone') !== 'UTC' &&
335 $command->getField('utcOffset') !== null &&
336 $settingsDS->getSetting('general', 'showClientTimeZone')
337 ) {
338 /** @var Customer $customer */
339 $customer = $customerRepository->getById($booking->getCustomerId()->getValue());
340
341 $booking->setInfo(
342 new Json(
343 json_encode(
344 [
345 'firstName' => $customer->getFirstName()->getValue(),
346 'lastName' => $customer->getLastName()->getValue(),
347 'phone' => null,
348 'locale' => null,
349 'timeZone' => $command->getField('timeZone'),
350 'urlParams' => null,
351 ]
352 )
353 )
354 );
355
356 $bookingRepository->updateFieldById(
357 $booking->getId()->getValue(),
358 $booking->getInfo()->getValue(),
359 'info'
360 );
361
362 $booking->setUtcOffset(new IntegerValue($command->getField('utcOffset')));
363
364 $bookingRepository->updateFieldById(
365 $booking->getId()->getValue(),
366 $booking->getUtcOffset()->getValue(),
367 'utcOffset'
368 );
369 }
370
371 /** @var Collection $existingAppointments */
372 $existingAppointments = $appointmentRepository->getFiltered(
373 [
374 'dates' => [$bookingStart, $bookingStart],
375 'services' => [$requiredServiceId],
376 'providers' => [$requiredProviderId],
377 ]
378 );
379
380 $userConnectionChanges = $appointmentAS->getUserConnectionChanges(
381 $requiredProviderId,
382 $oldAppointment->getProviderId()->getValue()
383 );
384
385 /** @var Appointment $newAppointment */
386 $newAppointment = null;
387
388 /** @var Appointment $existingAppointment */
389 $existingAppointment = $existingAppointments->length()
390 ? $existingAppointments->getItem($existingAppointments->keys()[0])
391 : null;
392
393 if ($existingAppointment &&
394 $existingAppointment->getId()->getValue() === $oldAppointment->getId()->getValue()
395 ) {
396 $existingAppointment = null;
397 }
398
399 $bookingStatus = $userAS->isCustomer($user)
400 ? $settingsDS
401 ->getEntitySettings($requiredService->getSettings())
402 ->getGeneralSettings()
403 ->getDefaultAppointmentStatus()
404 : $requiredBookingStatus;
405
406 $existingAppointmentStatusChanged = false;
407
408 $oldAppointmentStatus = $oldAppointment->getStatus()->getValue();
409
410 $appointmentRepository->beginTransaction();
411
412 do_action('amelia_before_booking_rescheduled', $oldAppointment->toArray(), $booking->toArray(), $bookingStart);
413
414 if ($existingAppointment === null &&
415 (
416 $oldAppointment->getBookings()->length() === 1 ||
417 (
418 !$bookingRescheduled &&
419 $requiredServiceId === $oldAppointment->getServiceId()->getValue() &&
420 $requiredProviderId === $oldAppointment->getProviderId()->getValue() &&
421 (
422 !$oldAppointment->getLocationId() ||
423 $oldAppointment->getLocationId()->getValue() === $requiredLocationId
424 )
425 )
426 )
427 ) {
428 $oldAppointment->setProviderId(new Id($requiredProviderId));
429 $oldAppointment->setServiceId(new Id($requiredServiceId));
430
431 if ($requiredLocationId) {
432 $oldAppointment->setLocationId(new Id($requiredLocationId));
433 }
434
435 /** @var BookingApplicationService $bookingAS */
436 $bookingAS = $this->container->get('application.booking.booking.service');
437
438 if ($bookingStart !== $oldAppointment->getBookingStart()->getValue()->format('Y-m-d H:i')) {
439 $bookingAS->bookingRescheduled(
440 $oldAppointment->getId()->getValue(),
441 Entities::APPOINTMENT,
442 $booking->getCustomerId()->getValue(),
443 Entities::CUSTOMER
444 );
445
446 $bookingAS->bookingRescheduled(
447 $oldAppointment->getId()->getValue(),
448 Entities::APPOINTMENT,
449 $oldAppointment->getProviderId()->getValue(),
450 Entities::PROVIDER
451 );
452 }
453
454 $oldAppointment->setBookingStart(
455 new DateTimeValue(
456 DateTimeService::getCustomDateTimeObject(
457 $bookingStart
458 )
459 )
460 );
461
462 $oldAppointment->setBookingEnd(
463 new DateTimeValue(
464 DateTimeService::getCustomDateTimeObject($bookingStart)
465 ->modify(
466 '+' . $appointmentAS->getAppointmentLengthTime($oldAppointment, $service) . ' second'
467 )
468 )
469 );
470
471 $oldAppointmentStatusChanged = $appointmentAS->manageAppointmentStatusByBooking(
472 $oldAppointment,
473 $requiredService,
474 $booking,
475 $bookingStatus,
476 $oldAppointment->getStatus()->getValue()
477 );
478
479 if ($command->getField('internalNotes')) {
480 $oldAppointment->setInternalNotes(new Description($command->getField('internalNotes')));
481 }
482
483 $paymentAS->updateBookingPaymentDate($booking, $bookingStartInUtc);
484
485 $appointmentRepository->update($oldAppointment->getId()->getValue(), $oldAppointment);
486
487 $oldAppointment->setRescheduled(new BooleanValueObject($bookingRescheduled));
488
489 $reservationService->updateWooCommerceOrder($booking, $oldAppointment);
490 } else {
491 $oldAppointment->getBookings()->deleteItem($booking->getId()->getValue());
492
493 if ($existingAppointment !== null) {
494 $booking->setAppointmentId($existingAppointment->getId());
495
496 $existingAppointment->getBookings()->addItem($booking, $booking->getId()->getValue());
497
498 $existingAppointmentStatusChanged = $appointmentAS->manageAppointmentStatusByBooking(
499 $existingAppointment,
500 $requiredService,
501 $booking,
502 $bookingStatus,
503 $oldAppointment->getStatus()->getValue()
504 );
505
506 $existingAppointment->setBookingEnd(
507 new DateTimeValue(
508 DateTimeService::getCustomDateTimeObject($bookingStart)
509 ->modify(
510 '+' . $appointmentAS->getAppointmentLengthTime($existingAppointment, $requiredService) . ' second'
511 )
512 )
513 );
514
515 $bookingRepository->updateFieldById(
516 $booking->getId()->getValue(),
517 $existingAppointment->getId()->getValue(),
518 'appointmentId'
519 );
520
521 $paymentAS->updateBookingPaymentDate($booking, $bookingStartInUtc);
522
523 $appointmentRepository->update($existingAppointment->getId()->getValue(), $existingAppointment);
524
525 $reservationService->updateWooCommerceOrder($booking, $existingAppointment);
526 } else if ($bookingRescheduled ||
527 $oldAppointment->getProviderId()->getValue() !== $requiredProviderId ||
528 $oldAppointment->getServiceId()->getValue() !== $requiredServiceId ||
529 (
530 $requiredLocationId &&
531 $oldAppointment->getLocationId() &&
532 $oldAppointment->getLocationId()->getValue() !== $requiredLocationId
533 )
534 ) {
535 $oldAppointment->setProviderId(new Id($requiredProviderId));
536 $oldAppointment->setServiceId(new Id($requiredServiceId));
537
538 if ($requiredLocationId) {
539 $oldAppointment->setLocationId(new Id($requiredLocationId));
540 }
541
542 $newAppointment = AppointmentFactory::create(
543 array_merge(
544 $oldAppointment->toArray(),
545 [
546 'id' => null,
547 'googleCalendarEventId' => null,
548 'outlookCalendarEventId' => null,
549 'zoomMeeting' => null,
550 'bookings' => [],
551 ]
552 )
553 );
554
555 $newAppointment->getBookings()->addItem($booking, $booking->getId()->getValue());
556
557 $newAppointment->setBookingStart(
558 new DateTimeValue(
559 DateTimeService::getCustomDateTimeObject(
560 $bookingStart
561 )
562 )
563 );
564
565 $newAppointment->setBookingEnd(
566 new DateTimeValue(
567 DateTimeService::getCustomDateTimeObject($bookingStart)
568 ->modify(
569 '+' . $appointmentAS->getAppointmentLengthTime($newAppointment, $requiredService) . ' second'
570 )
571 )
572 );
573
574 $newAppointment->setRescheduled(new BooleanValueObject($bookingRescheduled));
575
576 $appointmentAS->manageAppointmentStatusByBooking(
577 $newAppointment,
578 $requiredService,
579 $booking,
580 $bookingStatus,
581 $oldAppointment->getStatus()->getValue()
582 );
583
584 $newAppointmentId = $appointmentRepository->add($newAppointment);
585
586 $newAppointment->setId(new Id($newAppointmentId));
587
588 $booking->setAppointmentId(new Id($newAppointmentId));
589
590 $bookingRepository->updateFieldById(
591 $booking->getId()->getValue(),
592 $newAppointmentId,
593 'appointmentId'
594 );
595
596 $paymentAS->updateBookingPaymentDate($booking, $bookingStartInUtc);
597
598 $reservationService->updateWooCommerceOrder($booking, $newAppointment);
599 }
600
601 if ($oldAppointment->getBookings()->length() === 0) {
602 $appointmentRepository->delete($oldAppointment->getId()->getValue());
603
604 $oldAppointment->setStatus(new BookingStatus(BookingStatus::CANCELED));
605
606 $oldAppointmentStatusChanged = true;
607 } else {
608 $oldAppointmentStatusChanged = $appointmentAS->manageAppointmentStatusByBooking(
609 $oldAppointment,
610 $service,
611 null,
612 null,
613 null
614 );
615
616 $oldAppointment->setBookingEnd(
617 new DateTimeValue(
618 DateTimeService::getCustomDateTimeObject(
619 $oldAppointment->getBookingStart()->getValue()->format('Y-m-d H:i:s')
620 )->modify(
621 '+' . $appointmentAS->getAppointmentLengthTime($oldAppointment, $service) . ' second'
622 )
623 )
624 );
625
626 $appointmentRepository->update($oldAppointment->getId()->getValue(), $oldAppointment);
627 }
628 }
629
630 $bookingRepository->update($booking->getId()->getValue(), $booking);
631
632 $appointmentRepository->commit();
633
634 do_action('amelia_after_booking_rescheduled', $oldAppointment->toArray(), $booking->toArray(), $bookingStart);
635
636 $result->setResult(CommandResult::RESULT_SUCCESS);
637 $result->setMessage('Successfully updated appointment');
638 $result->setData(
639 [
640 Entities::BOOKING => $booking->toArray(),
641 'newAppointment' => $newAppointment ? $newAppointment->toArray() : null,
642 'oldAppointment' => $oldAppointment->toArray(),
643 'oldAppointmentStatusChanged' => $oldAppointmentStatusChanged,
644 'oldAppointmentStatus' => $oldAppointmentStatus,
645 'bookingRescheduled' => $bookingRescheduled,
646 'bookingEmployeeChanged' => $userConnectionChanges['appointmentEmployeeChanged'],
647 'bookingZoomUserChanged' => $userConnectionChanges['appointmentZoomUserChanged'],
648 'bookingZoomUsersLicenced' => $userConnectionChanges['appointmentZoomUsersLicenced'],
649 'existingAppointment' => $existingAppointment ? $existingAppointment->toArray() : null,
650 'existingAppointmentStatusChanged' => $existingAppointmentStatusChanged,
651 'createPaymentLinks' => $command->getField('createPaymentLinks'),
652 ]
653 );
654
655 return $result;
656 }
657 }
658