PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / 2.4.4
Booking for Appointments and Events Calendar – Amelia v2.4.4
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 1 month 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 3 weeks ago GetAppointmentsCommand.php 1 year ago GetAppointmentsCommandHandler.php 3 weeks ago GetIcsCommand.php 6 months ago GetIcsCommandHandler.php 4 years ago GetTimeSlotsCommand.php 1 year ago GetTimeSlotsCommandHandler.php 1 month ago ReassignBookingCommand.php 1 year ago ReassignBookingCommandHandler.php 3 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 1 month ago UpdateBookingStatusCommand.php 1 year ago UpdateBookingStatusCommandHandler.php 5 months ago
UpdateAppointmentTimeCommandHandler.php
286 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 $isUserWithOnlyOneBooking = true;
118
119 /** @var CustomerBooking $booking */
120 foreach ($appointment->getBookings()->getItems() as $booking) {
121 if (
122 $userAS->isAmeliaUser($user) &&
123 $userAS->isCustomer($user) &&
124 $bookingAS->isBookingApprovedOrPending($booking->getStatus()->getValue()) &&
125 ($user->getId() && $booking->getCustomerId()->getValue() !== $user->getId()->getValue())
126 ) {
127 $isUserWithOnlyOneBooking = false;
128
129 break;
130 }
131 }
132
133 /** @var CustomerBooking $booking */
134 foreach ($appointment->getBookings()->getItems() as $booking) {
135 if (
136 $userAS->isAmeliaUser($user) &&
137 $userAS->isCustomer($user) &&
138 $bookingAS->isBookingApprovedOrPending($booking->getStatus()->getValue()) &&
139 ($service->getMinCapacity()->getValue() !== 1 || $service->getMaxCapacity()->getValue() !== 1 || !$isUserWithOnlyOneBooking) &&
140 ($user->getId() && $booking->getCustomerId()->getValue() !== $user->getId()->getValue())
141 ) {
142 throw new AccessDeniedException('You are not allowed to update appointment');
143 }
144 }
145
146 if ($userAS->isCustomer($user)) {
147 $minimumRescheduleTimeInSeconds = $settingsDS
148 ->getEntitySettings($service->getSettings())
149 ->getGeneralSettings()
150 ->getMinimumTimeRequirementPriorToRescheduling();
151
152 try {
153 $reservationService->inspectMinimumCancellationTime(
154 $appointment->getBookingStart()->getValue(),
155 $minimumRescheduleTimeInSeconds
156 );
157 } catch (BookingCancellationException $e) {
158 $result->setResult(CommandResult::RESULT_ERROR);
159 $result->setMessage('You are not allowed to update booking');
160 $result->setData(
161 [
162 'rescheduleBookingUnavailable' => true
163 ]
164 );
165
166 return $result;
167 }
168 }
169
170 $bookingStart = $command->getField('bookingStart');
171
172 if ($command->getField('timeZone')) {
173 $bookingStart = DateTimeService::getDateTimeObjectInTimeZone(
174 $bookingStart,
175 $command->getField('timeZone')
176 )->setTimezone(DateTimeService::getTimeZone())->format('Y-m-d H:i:s');
177 }
178
179 $bookingStartInUtc = DateTimeService::getCustomDateTimeObject(
180 $bookingStart
181 )->setTimezone(new \DateTimeZone('UTC'))->format('Y-m-d H:i');
182
183 // Convert UTC slot to slot in TimeZone based on Settings
184 if ($command->getField('utcOffset') !== null && $settingsDS->getSetting('general', 'showClientTimeZone')) {
185 $bookingStart = DateTimeService::getCustomDateTimeFromUtc(
186 $bookingStart
187 );
188 }
189
190 $appointment->setBookingStart(
191 new DateTimeValue(
192 DateTimeService::getCustomDateTimeObject(
193 $bookingStart
194 )
195 )
196 );
197
198 $appointment->setBookingEnd(
199 new DateTimeValue(
200 DateTimeService::getCustomDateTimeObject($bookingStart)
201 ->modify('+' . $appointmentAS->getAppointmentLengthTime($appointment, $service) . ' second')
202 )
203 );
204
205 if (!$appointmentAS->canBeBooked($appointment, $userAS->isCustomer($user), null, null)) {
206 $result->setResult(CommandResult::RESULT_ERROR);
207 $result->setMessage(FrontendStrings::getCommonStrings()['time_slot_unavailable']);
208 $result->setData(
209 [
210 'timeSlotUnavailable' => true
211 ]
212 );
213
214 return $result;
215 }
216
217 do_action('amelia_before_booking_rescheduled', $oldAppointment->toArray(), null, $bookingStart);
218
219 $appointmentRepo->update((int)$command->getArg('id'), $appointment);
220
221 /** @var CustomerBooking $booking */
222 foreach ($appointment->getBookings()->getItems() as $booking) {
223 $paymentAS->updateBookingPaymentDate($booking, $bookingStartInUtc);
224
225 if ($appointmentAS->isPeriodCustomPricing($service)) {
226 /** @var UserRepository $userRepository */
227 $userRepository = $this->getContainer()->get('domain.users.repository');
228
229 /** @var CustomerBookingRepository $bookingRepository */
230 $bookingRepository = $this->container->get('domain.booking.customerBooking.repository');
231
232 /** @var Provider $provider */
233 $provider = $userRepository->getById($appointment->getProviderId()->getValue());
234
235 $price = $appointmentAS->getBookingPriceForService(
236 $service,
237 null,
238 $provider,
239 $appointment->getBookingStart()->getValue()->format('Y-m-d H:i:s')
240 );
241
242 $booking->setPrice(new Price($price));
243
244 $bookingRepository->updatePrice($booking->getId()->getValue(), $booking);
245 }
246 }
247
248 $appointment->setRescheduled(new BooleanValueObject(true));
249
250 $appointment->setInitialBookingStart(
251 new DateTimeValue($initialBookingStart)
252 );
253
254 $appointment->setInitialBookingEnd(
255 new DateTimeValue($initialBookingEnd)
256 );
257
258 $bookingAS->bookingRescheduled(
259 $appointment->getId()->getValue(),
260 Entities::APPOINTMENT,
261 null,
262 Entities::CUSTOMER
263 );
264
265 $bookingAS->bookingRescheduled(
266 $appointment->getId()->getValue(),
267 Entities::APPOINTMENT,
268 $appointment->getProviderId()->getValue(),
269 Entities::PROVIDER
270 );
271
272
273 do_action('amelia_after_booking_rescheduled', $oldAppointment->toArray(), null, $bookingStart);
274
275 $result->setResult(CommandResult::RESULT_SUCCESS);
276 $result->setMessage('Successfully updated appointment time');
277 $result->setData(
278 [
279 Entities::APPOINTMENT => $appointment->toArray(),
280 ]
281 );
282
283 return $result;
284 }
285 }
286