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