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