PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / 2.4
Booking for Appointments and Events Calendar – Amelia v2.4
2.4.5 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 / Application / Commands / Booking / Appointment / UpdateAppointmentTimeCommandHandler.php
ameliabooking / src / Application / Commands / Booking / Appointment Last commit date
AddAppointmentCommand.php 1 year ago AddAppointmentCommandHandler.php 2 months ago AddBookingCommand.php 1 year ago AddBookingCommandHandler.php 1 year ago ApproveBookingRemotelyCommand.php 1 year ago ApproveBookingRemotelyCommandHandler.php 2 months ago CancelBookingCommand.php 1 year ago CancelBookingCommandHandler.php 6 months ago CancelBookingRemotelyCommand.php 1 year ago CancelBookingRemotelyCommandHandler.php 5 months ago DeleteAppointmentCommand.php 1 year ago DeleteAppointmentCommandHandler.php 1 year ago DeleteBookingCommand.php 1 year ago DeleteBookingCommandHandler.php 10 months ago DeleteBookingRemotelyCommand.php 10 months ago DeleteBookingRemotelyCommandHandler.php 6 months ago GetAppointmentBookingsCommand.php 6 months ago GetAppointmentBookingsCommandHandler.php 2 months ago GetAppointmentCommand.php 7 years ago GetAppointmentCommandHandler.php 5 months ago GetAppointmentsCommand.php 1 year ago GetAppointmentsCommandHandler.php 5 months ago GetIcsCommand.php 6 months ago GetIcsCommandHandler.php 4 years ago GetTimeSlotsCommand.php 1 year ago GetTimeSlotsCommandHandler.php 2 months ago ReassignBookingCommand.php 1 year ago ReassignBookingCommandHandler.php 4 months ago RejectBookingRemotelyCommand.php 1 year ago RejectBookingRemotelyCommandHandler.php 5 months ago SuccessfulBookingCommand.php 1 year ago SuccessfulBookingCommandHandler.php 1 year ago UpdateAppointmentCommand.php 1 year ago UpdateAppointmentCommandHandler.php 3 months ago UpdateAppointmentNoteCommand.php 3 months ago UpdateAppointmentNoteCommandHandler.php 3 months ago UpdateAppointmentStatusCommand.php 1 year ago UpdateAppointmentStatusCommandHandler.php 2 months ago UpdateAppointmentTimeCommand.php 1 year ago UpdateAppointmentTimeCommandHandler.php 2 months ago UpdateBookingStatusCommand.php 1 year ago UpdateBookingStatusCommandHandler.php 6 months ago
UpdateAppointmentTimeCommandHandler.php
270 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\User\UserApplicationService;
13 use AmeliaBooking\Domain\Common\Exceptions\AuthorizationException;
14 use AmeliaBooking\Domain\Common\Exceptions\BookingCancellationException;
15 use AmeliaBooking\Domain\Common\Exceptions\InvalidArgumentException;
16 use AmeliaBooking\Domain\Entity\Bookable\Service\Service;
17 use AmeliaBooking\Domain\Entity\Booking\Appointment\Appointment;
18 use AmeliaBooking\Domain\Entity\Booking\Appointment\CustomerBooking;
19 use AmeliaBooking\Domain\Entity\Entities;
20 use AmeliaBooking\Domain\Entity\User\AbstractUser;
21 use AmeliaBooking\Domain\Entity\User\Provider;
22 use AmeliaBooking\Domain\Services\DateTime\DateTimeService;
23 use AmeliaBooking\Domain\Services\Reservation\ReservationServiceInterface;
24 use AmeliaBooking\Domain\Services\Settings\SettingsService;
25 use AmeliaBooking\Domain\ValueObjects\BooleanValueObject;
26 use AmeliaBooking\Domain\ValueObjects\DateTime\DateTimeValue;
27 use AmeliaBooking\Domain\ValueObjects\Number\Float\Price;
28 use AmeliaBooking\Infrastructure\Common\Exceptions\NotFoundException;
29 use AmeliaBooking\Infrastructure\Common\Exceptions\QueryExecutionException;
30 use AmeliaBooking\Infrastructure\Repository\Booking\Appointment\AppointmentRepository;
31 use AmeliaBooking\Infrastructure\Repository\Booking\Appointment\CustomerBookingRepository;
32 use AmeliaBooking\Infrastructure\Repository\User\UserRepository;
33 use AmeliaBooking\Infrastructure\WP\Translations\FrontendStrings;
34
35 /**
36 * Class UpdateAppointmentTimeCommandHandler
37 *
38 * @package AmeliaBooking\Application\Commands\Booking\Appointment
39 */
40 class UpdateAppointmentTimeCommandHandler extends CommandHandler
41 {
42 /**
43 * @var array
44 */
45 public $mandatoryFields = [
46 'bookingStart'
47 ];
48
49 /**
50 * @param UpdateAppointmentTimeCommand $command
51 *
52 * @return CommandResult
53 *
54 * @throws AccessDeniedException
55 * @throws InvalidArgumentException
56 * @throws QueryExecutionException
57 * @throws NotFoundException
58 */
59 public function handle(UpdateAppointmentTimeCommand $command)
60 {
61 $this->checkMandatoryFields($command);
62
63 $result = new CommandResult();
64
65 /** @var UserApplicationService $userAS */
66 $userAS = $this->container->get('application.user.service');
67 /** @var SettingsService $settingsDS */
68 $settingsDS = $this->container->get('domain.settings.service');
69 /** @var AppointmentRepository $appointmentRepo */
70 $appointmentRepo = $this->container->get('domain.booking.appointment.repository');
71 /** @var AppointmentApplicationService $appointmentAS */
72 $appointmentAS = $this->container->get('application.booking.appointment.service');
73 /** @var BookableApplicationService $bookableAS */
74 $bookableAS = $this->container->get('application.bookable.service');
75 /** @var BookingApplicationService $bookingAS */
76 $bookingAS = $this->container->get('application.booking.booking.service');
77 /** @var ReservationServiceInterface $reservationService */
78 $reservationService = $this->container->get('application.reservation.service')->get(Entities::APPOINTMENT);
79 /** @var PaymentApplicationService $paymentAS */
80 $paymentAS = $this->container->get('application.payment.service');
81
82 try {
83 /** @var AbstractUser $user */
84 $user = $command->getUserApplicationService()->authorization(
85 $command->getPage() === 'cabinet' ? $command->getToken() : null,
86 $command->getCabinetType()
87 );
88 } catch (AuthorizationException $e) {
89 $result->setResult(CommandResult::RESULT_ERROR);
90 $result->setData(
91 [
92 'reauthorize' => true
93 ]
94 );
95
96 return $result;
97 }
98
99 if ($userAS->isCustomer($user) && !$settingsDS->getSetting('roles', 'allowCustomerReschedule')) {
100 throw new AccessDeniedException('You are not allowed to update appointment');
101 }
102
103 /** @var Appointment $appointment */
104 $appointment = $appointmentRepo->getById((int)$command->getArg('id'));
105
106 $oldAppointment = clone $appointment;
107
108 $initialBookingStart = $appointment->getBookingStart()->getValue();
109 $initialBookingEnd = $appointment->getBookingEnd()->getValue();
110
111 /** @var Service $service */
112 $service = $bookableAS->getAppointmentService(
113 $appointment->getServiceId()->getValue(),
114 $appointment->getProviderId()->getValue()
115 );
116
117 /** @var CustomerBooking $booking */
118 foreach ($appointment->getBookings()->getItems() as $booking) {
119 if (
120 $userAS->isAmeliaUser($user) &&
121 $userAS->isCustomer($user) &&
122 $bookingAS->isBookingApprovedOrPending($booking->getStatus()->getValue()) &&
123 ($service->getMinCapacity()->getValue() !== 1 || $service->getMaxCapacity()->getValue() !== 1) &&
124 ($user->getId() && $booking->getCustomerId()->getValue() !== $user->getId()->getValue())
125 ) {
126 throw new AccessDeniedException('You are not allowed to update appointment');
127 }
128 }
129
130 if ($userAS->isCustomer($user)) {
131 $minimumRescheduleTimeInSeconds = $settingsDS
132 ->getEntitySettings($service->getSettings())
133 ->getGeneralSettings()
134 ->getMinimumTimeRequirementPriorToRescheduling();
135
136 try {
137 $reservationService->inspectMinimumCancellationTime(
138 $appointment->getBookingStart()->getValue(),
139 $minimumRescheduleTimeInSeconds
140 );
141 } catch (BookingCancellationException $e) {
142 $result->setResult(CommandResult::RESULT_ERROR);
143 $result->setMessage('You are not allowed to update booking');
144 $result->setData(
145 [
146 'rescheduleBookingUnavailable' => true
147 ]
148 );
149
150 return $result;
151 }
152 }
153
154 $bookingStart = $command->getField('bookingStart');
155
156 if ($command->getField('timeZone')) {
157 $bookingStart = DateTimeService::getDateTimeObjectInTimeZone(
158 $bookingStart,
159 $command->getField('timeZone')
160 )->setTimezone(DateTimeService::getTimeZone())->format('Y-m-d H:i:s');
161 }
162
163 $bookingStartInUtc = DateTimeService::getCustomDateTimeObject(
164 $bookingStart
165 )->setTimezone(new \DateTimeZone('UTC'))->format('Y-m-d H:i');
166
167 // Convert UTC slot to slot in TimeZone based on Settings
168 if ($command->getField('utcOffset') !== null && $settingsDS->getSetting('general', 'showClientTimeZone')) {
169 $bookingStart = DateTimeService::getCustomDateTimeFromUtc(
170 $bookingStart
171 );
172 }
173
174 $appointment->setBookingStart(
175 new DateTimeValue(
176 DateTimeService::getCustomDateTimeObject(
177 $bookingStart
178 )
179 )
180 );
181
182 $appointment->setBookingEnd(
183 new DateTimeValue(
184 DateTimeService::getCustomDateTimeObject($bookingStart)
185 ->modify('+' . $appointmentAS->getAppointmentLengthTime($appointment, $service) . ' second')
186 )
187 );
188
189 if (!$appointmentAS->canBeBooked($appointment, $userAS->isCustomer($user), null, null)) {
190 $result->setResult(CommandResult::RESULT_ERROR);
191 $result->setMessage(FrontendStrings::getCommonStrings()['time_slot_unavailable']);
192 $result->setData(
193 [
194 'timeSlotUnavailable' => true
195 ]
196 );
197
198 return $result;
199 }
200
201 do_action('amelia_before_booking_rescheduled', $oldAppointment->toArray(), null, $bookingStart);
202
203 $appointmentRepo->update((int)$command->getArg('id'), $appointment);
204
205 /** @var CustomerBooking $booking */
206 foreach ($appointment->getBookings()->getItems() as $booking) {
207 $paymentAS->updateBookingPaymentDate($booking, $bookingStartInUtc);
208
209 if ($appointmentAS->isPeriodCustomPricing($service)) {
210 /** @var UserRepository $userRepository */
211 $userRepository = $this->getContainer()->get('domain.users.repository');
212
213 /** @var CustomerBookingRepository $bookingRepository */
214 $bookingRepository = $this->container->get('domain.booking.customerBooking.repository');
215
216 /** @var Provider $provider */
217 $provider = $userRepository->getById($appointment->getProviderId()->getValue());
218
219 $price = $appointmentAS->getBookingPriceForService(
220 $service,
221 null,
222 $provider,
223 $appointment->getBookingStart()->getValue()->format('Y-m-d H:i:s')
224 );
225
226 $booking->setPrice(new Price($price));
227
228 $bookingRepository->updatePrice($booking->getId()->getValue(), $booking);
229 }
230 }
231
232 $appointment->setRescheduled(new BooleanValueObject(true));
233
234 $appointment->setInitialBookingStart(
235 new DateTimeValue($initialBookingStart)
236 );
237
238 $appointment->setInitialBookingEnd(
239 new DateTimeValue($initialBookingEnd)
240 );
241
242 $bookingAS->bookingRescheduled(
243 $appointment->getId()->getValue(),
244 Entities::APPOINTMENT,
245 null,
246 Entities::CUSTOMER
247 );
248
249 $bookingAS->bookingRescheduled(
250 $appointment->getId()->getValue(),
251 Entities::APPOINTMENT,
252 $appointment->getProviderId()->getValue(),
253 Entities::PROVIDER
254 );
255
256
257 do_action('amelia_after_booking_rescheduled', $oldAppointment->toArray(), null, $bookingStart);
258
259 $result->setResult(CommandResult::RESULT_SUCCESS);
260 $result->setMessage('Successfully updated appointment time');
261 $result->setData(
262 [
263 Entities::APPOINTMENT => $appointment->toArray(),
264 ]
265 );
266
267 return $result;
268 }
269 }
270