PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / trunk
Booking for Appointments and Events Calendar – Amelia vtrunk
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 / GetAppointmentCommandHandler.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 2 weeks ago GetAppointmentsCommand.php 1 year ago GetAppointmentsCommandHandler.php 2 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 4 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
GetAppointmentCommandHandler.php
417 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\Booking\AppointmentApplicationService;
9 use AmeliaBooking\Application\Services\CustomField\AbstractCustomFieldApplicationService;
10 use AmeliaBooking\Application\Services\Payment\PaymentApplicationService;
11 use AmeliaBooking\Application\Services\Reservation\AppointmentReservationService;
12 use AmeliaBooking\Application\Services\User\CustomerApplicationService;
13 use AmeliaBooking\Application\Services\User\ProviderApplicationService;
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\InvalidArgumentException;
18 use AmeliaBooking\Domain\Entity\Booking\Appointment\Appointment;
19 use AmeliaBooking\Domain\Entity\Booking\Appointment\CustomerBooking;
20 use AmeliaBooking\Domain\Entity\Bookable\Service\PackageCustomer;
21 use AmeliaBooking\Domain\Entity\Bookable\Service\PackageCustomerService;
22 use AmeliaBooking\Domain\Entity\Entities;
23 use AmeliaBooking\Domain\Entity\Payment\Payment;
24 use AmeliaBooking\Domain\Entity\User\AbstractUser;
25 use AmeliaBooking\Domain\Services\Settings\SettingsService;
26 use AmeliaBooking\Infrastructure\Common\Exceptions\NotFoundException;
27 use AmeliaBooking\Infrastructure\Common\Exceptions\QueryExecutionException;
28 use AmeliaBooking\Infrastructure\Repository\Bookable\Service\ServiceRepository;
29 use AmeliaBooking\Infrastructure\Repository\Booking\Appointment\AppointmentRepository;
30 use AmeliaBooking\Infrastructure\Repository\Bookable\Service\PackageCustomerServiceRepository;
31 use AmeliaBooking\Infrastructure\Repository\CustomField\CustomFieldRepository;
32 use AmeliaBooking\Infrastructure\Repository\Payment\PaymentRepository;
33 use AmeliaBooking\Infrastructure\Services\LessonSpace\AbstractLessonSpaceService;
34 use AmeliaBooking\Infrastructure\WP\Integrations\IvyForms\IvyFormsService;
35 use DateTimeZone;
36 use Slim\Exception\ContainerValueNotFoundException;
37
38 /**
39 * Class GetAppointmentCommandHandler
40 *
41 * @package AmeliaBooking\Application\Commands\Booking\Appointment
42 */
43 class GetAppointmentCommandHandler extends CommandHandler
44 {
45 /**
46 * @param GetAppointmentCommand $command
47 *
48 * @return CommandResult
49 * @throws ContainerValueNotFoundException
50 * @throws AccessDeniedException
51 * @throws QueryExecutionException
52 * @throws InvalidArgumentException
53 * @throws NotFoundException
54 */
55 public function handle(GetAppointmentCommand $command)
56 {
57 $result = new CommandResult();
58
59 /** @var UserApplicationService $userAS */
60 $userAS = $this->container->get('application.user.service');
61
62 /** @var AbstractCustomFieldApplicationService $customFieldService */
63 $customFieldService = $this->container->get('application.customField.service');
64
65 /** @var AppointmentApplicationService $appointmentAS */
66 $appointmentAS = $this->container->get('application.booking.appointment.service');
67
68 /** @var PackageCustomerServiceRepository $packageCustomerServiceRepository */
69 $packageCustomerServiceRepository = $this->container->get('domain.bookable.packageCustomerService.repository');
70
71 try {
72 /** @var AbstractUser $user */
73 $user = $command->getUserApplicationService()->authorization(
74 $command->getPage() === 'cabinet' ? $command->getToken() : null,
75 $command->getCabinetType()
76 );
77 } catch (AuthorizationException $e) {
78 $result->setResult(CommandResult::RESULT_ERROR);
79 $result->setData(
80 [
81 'reauthorize' => true
82 ]
83 );
84
85 return $result;
86 }
87
88 /** @var AppointmentRepository $appointmentRepo */
89 $appointmentRepo = $this->container->get('domain.booking.appointment.repository');
90
91 /** @var ServiceRepository $serviceRepository */
92 $serviceRepository = $this->container->get('domain.bookable.service.repository');
93
94 /** @var CustomerApplicationService $customerAS */
95 $customerAS = $this->container->get('application.user.customer.service');
96
97 /** @var ProviderApplicationService $providerAS */
98 $providerAS = $this->container->get('application.user.provider.service');
99
100 /** @var CustomFieldRepository $customFieldRepository */
101 $customFieldRepository = $this->container->get('domain.customField.repository');
102
103 /** @var Appointment $appointment */
104 $appointment = $appointmentRepo->getById((int)$command->getField('id'));
105
106 // TODO: Redesign - check if could be removed, if every appointment call needs the same data returned
107 $getDrawerInfo = !empty($command->getField('params')['drawer']);
108
109 if ($userAS->isCustomer($user) && !$customerAS->hasCustomerBooking($appointment->getBookings(), $user)) {
110 throw new AccessDeniedException('You are not allowed to read appointment');
111 }
112
113 /** @var PaymentRepository $paymentRepository */
114 $paymentRepository = $this->container->get('domain.payment.repository');
115
116 $bookingIds = [];
117
118 $customerAS->removeBookingsForOtherCustomers($user, new Collection([$appointment]));
119
120 $timeZone = !empty($command->getField('params')['timeZone'])
121 ? $command->getField('params')['timeZone']
122 : ($user && $user->getType() === Entities::PROVIDER ? $providerAS->getTimeZone($user) : null);
123
124 if ($timeZone) {
125 $appointment->getBookingStart()->getValue()->setTimezone(new DateTimeZone($timeZone));
126
127 $appointment->getBookingEnd()->getValue()->setTimezone(new DateTimeZone($timeZone));
128 }
129
130 /** @var SettingsService $settingsDS */
131 $settingsDS = $this->container->get('domain.settings.service');
132
133 $badges = $settingsDS->isFeatureEnabled('employeeBadge')
134 ? $settingsDS->getSetting('roles', 'providerBadges')
135 : [];
136
137 $badge = !empty($badges['badges']) && $appointment->getProvider()->getBadgeId() ?
138 array_filter(
139 $badges['badges'],
140 function ($badge) use ($appointment) {
141 return $badge['id'] === $appointment->getProvider()->getBadgeId()->getValue();
142 }
143 )
144 : null;
145
146 $bookingsPrice = 0;
147 $paidPrice = 0;
148 $bookedSpots = 0;
149 $bookings = [];
150
151 /** @var PaymentApplicationService $paymentAS */
152 $paymentAS = $this->container->get('application.payment.service');
153
154 /** @var AppointmentReservationService $reservationService */
155 $reservationService = $this->container->get('application.reservation.service')->get(Entities::APPOINTMENT);
156
157 /** @var Collection $customFieldsCollection */
158 $customFieldsCollection = $customFieldRepository->getAll([], false);
159
160 /** @var CustomerBooking $booking */
161 foreach ($appointment->getBookings()->getItems() as $booking) {
162 /** @var Payment $payment */
163 foreach ($booking->getPayments()->getItems() as $payment) {
164 if ($payment->getParentId() && $payment->getParentId()->getValue()) {
165 try {
166 /** @var Payment $parentPayment */
167 $parentPayment = $paymentRepository->getById($payment->getParentId()->getValue());
168
169 $bookingIds[] = $parentPayment->getCustomerBookingId()->getValue();
170 } catch (\Exception $e) {
171 }
172 }
173
174 /** @var Collection $relatedPayments */
175 $relatedPayments = $paymentRepository->getByEntityId(
176 $payment->getParentId() ? $payment->getParentId()->getValue() : $payment->getId()->getValue(),
177 'parentId'
178 );
179
180 /** @var Payment $relatedPayment */
181 foreach ($relatedPayments->getItems() as $relatedPayment) {
182 $bookingIds[] = $relatedPayment->getCustomerBookingId()->getValue();
183 }
184 }
185 }
186
187 /** @var Collection $recurringAppointments */
188 $recurringAppointments = $bookingIds ? $appointmentRepo->getFiltered(
189 [
190 'bookingIds' => array_unique($bookingIds),
191 'customerId' => !empty($command->getField('params')['customerId']) ? $command->getField('params')['customerId'] : null
192 ]
193 ) : $appointmentRepo->getFiltered(
194 [
195 'parentId' => $appointment->getParentId() ?
196 $appointment->getParentId()->getValue() : $appointment->getId()->getValue()
197 ]
198 );
199
200 if ($recurringAppointments->keyExists($appointment->getId()->getValue())) {
201 $recurringAppointments->deleteItem($appointment->getId()->getValue());
202 }
203
204 $appointmentArray = $appointment->toArray();
205 if (!empty($appointmentArray['lessonSpace'])) {
206 /** @var SettingsService $settingsDS */
207 $settingsDS = $this->container->get('domain.settings.service');
208
209 $lessonSpaceApiKey = $settingsDS->getSetting('lessonSpace', 'apiKey');
210 $lessonSpaceEnabled = $settingsDS->getSetting('lessonSpace', 'enabled');
211 $lessonSpaceCompanyId = $settingsDS->getSetting('lessonSpace', 'companyId');
212 if ($lessonSpaceEnabled && $lessonSpaceApiKey && $lessonSpaceCompanyId) {
213 /** @var AbstractLessonSpaceService $lessonSpaceService */
214 $lessonSpaceService = $this->container->get('infrastructure.lesson.space.service');
215 $spaceId = explode("https://www.thelessonspace.com/space/", $appointmentArray['lessonSpace']);
216 if ($spaceId && count($spaceId) > 1) {
217 $appointmentArray['lessonSpaceDetails'] = $lessonSpaceService->getSpace($lessonSpaceApiKey, $lessonSpaceCompanyId, $spaceId[1]);
218 }
219 }
220 }
221
222 if (isset($appointmentArray['notifyParticipants'])) {
223 $appointmentArray['notifyParticipants'] = intval($appointmentArray['notifyParticipants']);
224 }
225 if (isset($appointmentArray['createPaymentLinks'])) {
226 $appointmentArray['createPaymentLinks'] = intval($appointmentArray['createPaymentLinks']);
227 }
228
229 $service = $serviceRepository->getByCriteria(
230 ['services' => [$appointment->getServiceId()->getValue()]]
231 )->getItem($appointment->getServiceId()->getValue());
232
233 if ($getDrawerInfo) {
234 $wcTax = 0;
235 $wcDiscount = 0;
236
237 /** @var CustomerBooking $booking */
238 foreach ($appointment->getBookings()->getItems() as $booking) {
239 $ivyEntryId = $booking->getIvyEntryId() ? $booking->getIvyEntryId()->getValue() : null;
240
241 if ($booking->getPackageCustomerService()) {
242 /** @var Collection $packageCustomerServices */
243 $packageCustomerServices = $packageCustomerServiceRepository->getByCriteria(
244 [
245 'ids' => [$booking->getPackageCustomerService()->getId()->getValue()],
246 ]
247 );
248
249 /** @var PackageCustomerService $packageCustomerService */
250 foreach ($packageCustomerServices->getItems() as $packageCustomerService) {
251 /** @var PackageCustomer $packageCustomer */
252 $packageCustomer = $packageCustomerService->getPackageCustomer();
253
254 $ivyEntryId = $packageCustomer && $packageCustomer->getIvyEntryId()
255 ? $packageCustomer->getIvyEntryId()->getValue()
256 : null;
257 }
258 }
259
260 $customFields = [];
261 $bookingPrice = $paymentAS->calculateAppointmentPrice($booking->toArray(), 'appointment');
262 $bookingsPrice += $bookingPrice;
263
264 $bookedSpots += $booking->getPersons()->getValue();
265
266 // Create bookable with extras to properly calculate payment amount
267 $bookableWithExtras = $paymentAS->createBookableWithExtras($booking->toArray(), 'appointment');
268 $bookingPaymentAmount = $reservationService->getPaymentAmount($booking, $bookableWithExtras, true);
269
270 $bookingPaidPrice = 0;
271 $paymentMethods = [];
272 $wcOrderUrls = [];
273 foreach ($booking->getPayments()->toArray() as $paymentItem) {
274 $paymentMethods[] = $paymentItem['gateway'];
275 if ($paymentItem['status'] === 'paid' || $paymentItem['status'] === 'partiallyPaid') {
276 $bookingPaidPrice += $paymentItem['amount'];
277 }
278
279 $paymentAS->addWcFields($paymentItem);
280
281 $wcTax += !empty($paymentItem['wcItemTaxValue']) ? $paymentItem['wcItemTaxValue'] : 0;
282
283 $wcDiscount += !empty($paymentItem['wcItemCouponValue']) ? $paymentItem['wcItemCouponValue'] : 0;
284
285 if (!empty($paymentItem['wcOrderId'])) {
286 $wcOrderUrls[$paymentItem['wcOrderId']] = $paymentItem['wcOrderUrl'];
287 }
288 }
289
290 $paidPrice += $bookingPaidPrice;
291
292 $customerBirthday = $booking->getCustomer() && $booking->getCustomer()->getBirthday() ?
293 $booking->getCustomer()->getBirthday()->getValue()->format('Y-m-d') :
294 null;
295
296 if ($booking->getCustomFields() && $booking->getCustomFields()->getValue()) {
297 $customFields = $customFieldService->reformatCustomField($booking, $customFields, $customFieldsCollection);
298 }
299
300 $total = $bookingPaymentAmount['subtotal']
301 + $bookingPaymentAmount['total_tax']
302 + $wcTax
303 - $bookingPaymentAmount['discount']
304 - $bookingPaymentAmount['deduction']
305 - $wcDiscount;
306
307 $bookings[] = [
308 'id' => $booking->getId()->getValue(),
309 'customer' => $booking->getCustomer() ? array_merge($booking->getCustomer()->toArray(), ['birthday' => $customerBirthday]) : null,
310 'status' => $booking->getStatus()->getValue(),
311 'isPackageBooking' => !!$booking->getPackageCustomerService(),
312 'payment' => [
313 'paymentMethods' => $paymentMethods,
314 'wcOrderUrls' => $wcOrderUrls,
315 'status' => $paymentAS->getFullStatus($booking->toArray(), 'appointment'),
316 'total' => $total,
317 'tax' => $bookingPaymentAmount['total_tax'],
318 'wcTax' => $wcTax,
319 'discount' => $bookingPaymentAmount['discount'] + $bookingPaymentAmount['deduction'],
320 'wcDiscount' => $wcDiscount,
321 'service' => $bookingPaymentAmount['bookable'],
322 'extras' => $bookingPaymentAmount['subtotal'] - $bookingPaymentAmount['bookable'],
323 'subtotal' => $bookingPaymentAmount['subtotal'],
324 'paid' => $bookingPaidPrice,
325 'due' => max($total - $bookingPaidPrice, 0),
326 'id' => $booking->getPayments()->length() > 0 ? $booking->getPayments()->toArray()[0]['id'] : null,
327 ],
328 'bookedSpots' => $booking->getPersons()->getValue(),
329 'customFields' => $customFields,
330 'extras' => $booking->getExtras() ? array_map(
331 function ($extra) use ($service) {
332 $serviceExtra = $service->getExtras()->getItem($extra['extraId']);
333 return array_merge(
334 $extra,
335 ['name' => $serviceExtra ? $serviceExtra->getName()->getValue() : null]
336 );
337 },
338 $booking->getExtras()->toArray()
339 ) : null,
340 'duration' => $booking->getDuration()
341 ? $booking->getDuration()->getValue()
342 : $service->getDuration()->getValue(),
343 'ivyEntryId' => $ivyEntryId,
344 'ivyEntryFields' => $ivyEntryId ? IvyFormsService::getEntryFields($ivyEntryId) : [],
345 ];
346 }
347
348 $serviceSettingsRaw = $service->getSettings() ? $service->getSettings()->getValue() : null;
349 $waitingListEnabled = false;
350 if (!empty($serviceSettingsRaw)) {
351 $serviceSettings = json_decode($serviceSettingsRaw, true);
352 if (isset($serviceSettings['waitingList']['enabled'])) {
353 $waitingListEnabled = (bool)$serviceSettings['waitingList']['enabled'];
354 }
355 }
356
357 $appointmentArray = [
358 'id' => $appointment->getId()->getValue(),
359 'employee' => $appointment->getProvider() ? [
360 'id' => $appointment->getProvider()->getId()->getValue(),
361 'firstName' => $appointment->getProvider()->getFirstName()->getValue(),
362 'lastName' => $appointment->getProvider()->getLastName() ? $appointment->getProvider()->getLastName()->getValue() : null,
363 'picture' => $appointment->getProvider()->getPicture() ? $appointment->getProvider()->getPicture()->getThumbPath() : null,
364 'badge' => !empty($badge) ? array_values($badge)[0] : null,
365 ] : null,
366 'location' => $appointment->getLocation() ? [
367 'id' => $appointment->getLocation()->getId()->getValue(),
368 'name' => $appointment->getLocation()->getName() ? $appointment->getLocation()->getName()->getValue() : null
369 ] : null,
370 'service' => $appointment->getService() ? [
371 'id' => $appointment->getService()->getId()->getValue(),
372 'name' => $appointment->getService()->getName()->getValue(),
373 'color' => $appointment->getService()->getColor() ? $appointment->getService()->getColor()->getValue() : null,
374 'pictureThumbPath' => $appointment->getService()->getPicture() ? $appointment->getService()->getPicture()->getThumbPath() : null,
375 'settings' => [
376 'waitingListEnabled' => $waitingListEnabled,
377 ],
378 ] : null,
379 'bookingStartDateTime' => $appointment->getBookingStart()->getValue()->format('Y-m-d H:i:s'),
380 'bookingEndDateTime' => $appointment->getBookingEnd()->getValue()->format('Y-m-d H:i:s'),
381 'recurringCount' => $recurringAppointments->length(),
382 'googleMeetLink' => $appointment->getGoogleMeetUrl(),
383 'zoomHostLink' => $appointment->getZoomMeeting() ? $appointment->getZoomMeeting()->getStartUrl()->getValue() : null,
384 'zoomJoinLink' => $appointment->getZoomMeeting() ? $appointment->getZoomMeeting()->getJoinUrl()->getValue() : null,
385 'lessonSpace' => $appointment->getLessonSpace() ? $appointment->getLessonSpace() : null,
386 'microsoftTeamsLink' => $appointment->getMicrosoftTeamsUrl() ? $appointment->getMicrosoftTeamsUrl() : null,
387 'note' => $appointment->getInternalNotes() ? $appointment->getInternalNotes()->getValue() : null,
388 'status' => $appointment->getStatus()->getValue(),
389 'bookings' => $bookings,
390 'price' => [
391 'total' => $bookingsPrice
392 ],
393 'paidPrice' => $paidPrice,
394 'bookedSpots' => $bookedSpots,
395 'cancelable' => $appointmentAS->isCancelable($appointment, $service, $user),
396 'reschedulable' => $appointmentAS->isReschedulable($appointment, $service, $user),
397 ];
398 }
399
400 $appointmentArray = apply_filters('amelia_get_appointment_filter', $appointmentArray);
401
402 do_action('amelia_get_appointment', $appointmentArray);
403
404
405 $result->setResult(CommandResult::RESULT_SUCCESS);
406 $result->setMessage('Successfully retrieved appointment');
407 $result->setData(
408 [
409 Entities::APPOINTMENT => $appointmentArray,
410 'recurring' => $recurringAppointments->toArray()
411 ]
412 );
413
414 return $result;
415 }
416 }
417