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