PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / 1.2.20
Booking for Appointments and Events Calendar – Amelia v1.2.20
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 / Services / Reservation / EventReservationService.php
ameliabooking / src / Application / Services / Reservation Last commit date
AbstractReservationService.php 1 year ago AppointmentReservationService.php 1 year ago EventReservationService.php 1 year ago ReservationService.php 2 years ago
EventReservationService.php
1272 lines
1 <?php
2
3 namespace AmeliaBooking\Application\Services\Reservation;
4
5 use AmeliaBooking\Application\Commands\CommandResult;
6 use AmeliaBooking\Application\Services\Booking\EventApplicationService;
7 use AmeliaBooking\Application\Services\Coupon\CouponApplicationService;
8 use AmeliaBooking\Application\Services\Deposit\AbstractDepositApplicationService;
9 use AmeliaBooking\Application\Services\Helper\HelperService;
10 use AmeliaBooking\Application\Services\Tax\TaxApplicationService;
11 use AmeliaBooking\Domain\Collection\Collection;
12 use AmeliaBooking\Domain\Common\Exceptions\BookingCancellationException;
13 use AmeliaBooking\Domain\Common\Exceptions\BookingsLimitReachedException;
14 use AmeliaBooking\Domain\Common\Exceptions\BookingUnavailableException;
15 use AmeliaBooking\Domain\Common\Exceptions\CouponExpiredException;
16 use AmeliaBooking\Domain\Common\Exceptions\CouponInvalidException;
17 use AmeliaBooking\Domain\Common\Exceptions\CouponUnknownException;
18 use AmeliaBooking\Domain\Common\Exceptions\CustomerBookedException;
19 use AmeliaBooking\Domain\Common\Exceptions\InvalidArgumentException;
20 use AmeliaBooking\Domain\Entity\Bookable\AbstractBookable;
21 use AmeliaBooking\Domain\Entity\Booking\Appointment\CustomerBooking;
22 use AmeliaBooking\Domain\Entity\Booking\Appointment\CustomerBookingExtra;
23 use AmeliaBooking\Domain\Entity\Booking\Event\CustomerBookingEventPeriod;
24 use AmeliaBooking\Domain\Entity\Booking\Event\CustomerBookingEventTicket;
25 use AmeliaBooking\Domain\Entity\Booking\Event\Event;
26 use AmeliaBooking\Domain\Entity\Booking\Event\EventPeriod;
27 use AmeliaBooking\Domain\Entity\Booking\Event\EventTicket;
28 use AmeliaBooking\Domain\Entity\Booking\Reservation;
29 use AmeliaBooking\Domain\Entity\Coupon\Coupon;
30 use AmeliaBooking\Domain\Entity\Entities;
31 use AmeliaBooking\Domain\Entity\Location\Location;
32 use AmeliaBooking\Domain\Entity\Payment\Payment;
33 use AmeliaBooking\Domain\Entity\Tax\Tax;
34 use AmeliaBooking\Domain\Entity\User\AbstractUser;
35 use AmeliaBooking\Domain\Entity\User\Provider;
36 use AmeliaBooking\Domain\Factory\Booking\Appointment\CustomerBookingFactory;
37 use AmeliaBooking\Domain\Factory\Booking\Event\CustomerBookingEventPeriodFactory;
38 use AmeliaBooking\Domain\Factory\Booking\Event\CustomerBookingEventTicketFactory;
39 use AmeliaBooking\Domain\Services\DateTime\DateTimeService;
40 use AmeliaBooking\Domain\Services\Reservation\ReservationServiceInterface;
41 use AmeliaBooking\Domain\Services\Settings\SettingsService;
42 use AmeliaBooking\Domain\ValueObjects\BooleanValueObject;
43 use AmeliaBooking\Domain\ValueObjects\Number\Float\Price;
44 use AmeliaBooking\Domain\ValueObjects\Number\Integer\Id;
45 use AmeliaBooking\Domain\ValueObjects\Number\Integer\IntegerValue;
46 use AmeliaBooking\Domain\ValueObjects\String\AmountType;
47 use AmeliaBooking\Domain\ValueObjects\String\BookingStatus;
48 use AmeliaBooking\Domain\ValueObjects\String\PaymentType;
49 use AmeliaBooking\Domain\ValueObjects\String\Token;
50 use AmeliaBooking\Domain\ValueObjects\Json;
51 use AmeliaBooking\Infrastructure\Common\Exceptions\QueryExecutionException;
52 use AmeliaBooking\Infrastructure\Repository\Booking\Appointment\CustomerBookingExtraRepository;
53 use AmeliaBooking\Infrastructure\Repository\Booking\Appointment\CustomerBookingRepository;
54 use AmeliaBooking\Infrastructure\Repository\Booking\Event\CustomerBookingEventPeriodRepository;
55 use AmeliaBooking\Infrastructure\Repository\Booking\Event\CustomerBookingEventTicketRepository;
56 use AmeliaBooking\Infrastructure\Repository\Booking\Event\EventRepository;
57 use AmeliaBooking\Infrastructure\Repository\Location\LocationRepository;
58 use AmeliaBooking\Infrastructure\Repository\User\CustomerRepository;
59 use AmeliaBooking\Infrastructure\WP\Translations\FrontendStrings;
60 use DateTime;
61 use Exception;
62 use Slim\Exception\ContainerException;
63 use Slim\Exception\ContainerValueNotFoundException;
64
65 /**
66 * Class EventReservationService
67 *
68 * @package AmeliaBooking\Application\Services\Reservation
69 */
70 class EventReservationService extends AbstractReservationService
71 {
72 /**
73 * @return string
74 */
75 public function getType()
76 {
77 return Entities::EVENT;
78 }
79
80 /**
81 * @param array $eventData
82 * @param Reservation $reservation
83 * @param bool $save
84 *
85 * @return void
86 *
87 * @throws CouponExpiredException
88 * @throws CouponInvalidException
89 * @throws CouponUnknownException
90 * @throws BookingUnavailableException
91 * @throws ContainerValueNotFoundException
92 * @throws InvalidArgumentException
93 * @throws QueryExecutionException
94 * @throws Exception
95 */
96 public function book($eventData, $reservation, $save)
97 {
98 /** @var LocationRepository $locationRepository */
99 $locationRepository = $this->container->get('domain.locations.repository');
100
101 /** @var EventApplicationService $eventApplicationService */
102 $eventApplicationService = $this->container->get('application.booking.event.service');
103
104 /** @var CouponApplicationService $couponAS */
105 $couponAS = $this->container->get('application.coupon.service');
106
107 /** @var AbstractDepositApplicationService $depositAS */
108 $depositAS = $this->container->get('application.deposit.service');
109
110 $this->manageTaxes($eventData);
111
112 /** @var Coupon $coupon */
113 $coupon = !empty($eventData['couponCode']) ? $couponAS->processCoupon(
114 $eventData['couponCode'],
115 [$eventData['eventId']],
116 Entities::EVENT,
117 $eventData['bookings'][0]['customerId'],
118 $reservation->hasCouponValidation()->getValue()
119 ) : null;
120
121 if ($coupon) {
122 $eventData['bookings'][0]['coupon'] = $coupon->toArray();
123
124 $eventData['bookings'][0]['couponId'] = $coupon->getId()->getValue();
125 }
126
127 /** @var Event $event */
128 $event = $eventApplicationService->getEventById(
129 $eventData['eventId'],
130 [
131 'fetchEventsPeriods' => true,
132 'fetchEventsTickets' => true,
133 'fetchApprovedBookings' => true,
134 'fetchBookings' => true,
135 'fetchBookingsTickets' => true,
136 'fetchEventsProviders' => true,
137 ]
138 );
139
140 if ($event->getCustomPricing()->getValue()) {
141 $event->setCustomTickets($eventApplicationService->getTicketsPriceByDateRange($event->getCustomTickets()));
142 }
143
144 $bookingArray = array_merge($eventData['bookings'][0], empty($eventData['bookings'][0]['status']) ?
145 ['status' => BookingStatus::APPROVED] : ['status' => $eventData['bookings'][0]['status']]);
146
147 $bookingArray = apply_filters('amelia_before_event_booking_saved_filter', $bookingArray, $event ? $event->toArray() : null);
148
149 do_action('amelia_before_event_booking_saved', $bookingArray, $event ? $event->toArray() : null);
150
151 $booking = CustomerBookingFactory::create($bookingArray);
152
153 if ($event->getCustomPricing()->getValue()) {
154 $booking->setPersons(new IntegerValue(0));
155 }
156
157 $bookingStatus = empty($eventData['bookings'][0]['status']) ? BookingStatus::APPROVED : $eventData['bookings'][0]['status'];
158
159 if (!empty($eventData['payment']['gateway'])) {
160 $bookingStatus = in_array($eventData['payment']['gateway'], [PaymentType::MOLLIE, PaymentType::SQUARE]) ?
161 BookingStatus::PENDING : (empty($eventData['bookings'][0]['status']) ? BookingStatus::APPROVED : $eventData['bookings'][0]['status']);
162
163 if (!empty($eventData['payment']['orderStatus'])) {
164 $bookingStatus = $this->getWcStatus(
165 Entities::EVENT,
166 $eventData['payment']['orderStatus'],
167 'booking',
168 false
169 ) ?: $bookingStatus;
170 }
171 }
172
173 $booking->setStatus(new BookingStatus($bookingStatus));
174
175 $personsCount = 0;
176
177 /** @var CustomerBooking $customerBooking */
178 foreach ($event->getBookings()->getItems() as $customerBooking) {
179 if ($customerBooking->getStatus()->getValue() === BookingStatus::APPROVED) {
180 $personsCount += $customerBooking->getPersons()->getValue();
181 }
182 if ($customerBooking->getStatus()->getValue() !== BookingStatus::CANCELED &&
183 !$event->getBookMultipleTimes()->getValue() &&
184 $booking->getCustomerId() &&
185 $booking->getCustomerId()->getValue() === $customerBooking->getCustomerId()->getValue()
186 ) {
187 throw new CustomerBookedException(
188 FrontendStrings::getCommonStrings()['customer_already_booked_ev']
189 );
190 }
191 }
192
193 /** @var SettingsService $settingsDS */
194 $settingsDS = $this->container->get('domain.settings.service');
195
196 $limitPerCustomerEvents = $settingsDS->getSetting('roles', 'limitPerCustomerEvent');
197
198 if (!empty($limitPerCustomerEvents) &&
199 $limitPerCustomerEvents['enabled'] &&
200 empty($eventData['isBackendOrCabinet'])
201 ) {
202 /** @var EventRepository $eventRepository */
203 $eventRepository = $this->container->get('domain.booking.event.repository');
204
205 $count = $eventRepository->getRelevantBookingsCount(
206 $event,
207 $booking->toArray(),
208 $limitPerCustomerEvents
209 );
210
211 if ($count >= $limitPerCustomerEvents['numberOfApp']) {
212 throw new BookingsLimitReachedException(
213 FrontendStrings::getCommonStrings()['bookings_limit_reached']
214 );
215 }
216 }
217
218 /** @var AbstractUser $currentUser */
219 $currentUser = $this->container->get('logged.in.user');
220
221 $isCustomer = (!$currentUser || ($currentUser->getType() === AbstractUser::USER_ROLE_CUSTOMER));
222
223 $isProvider =
224 $reservation->getLoggedInUser() &&
225 $reservation->getLoggedInUser()->getType() === AbstractUser::USER_ROLE_PROVIDER;
226
227 if ($reservation->hasAvailabilityValidation()->getValue() &&
228 $isCustomer &&
229 !$isProvider &&
230 !$this->isBookable($event, $booking, DateTimeService::getNowDateTimeObject())
231 ) {
232 throw new BookingUnavailableException(
233 FrontendStrings::getCommonStrings()['time_slot_unavailable']
234 );
235 }
236
237
238 $booking->setAggregatedPrice(new BooleanValueObject($event->getAggregatedPrice() ? $event->getAggregatedPrice()->getValue() : true));
239
240 $paymentAmount = $this->getPaymentAmount($booking, $event)['price'];
241
242 $applyDeposit =
243 !empty($eventData['bookings'][0]['deposit']) && $eventData['payment']['gateway'] !== PaymentType::ON_SITE;
244
245 if ($applyDeposit) {
246 $personsCount = $booking->getPersons()->getValue();
247
248 if ($booking->getTicketsBooking() && $event->getCustomPricing()->getValue()) {
249 $personsCount = 0;
250
251 /** @var CustomerBookingEventTicket $bookingToEventTicket */
252 foreach ($booking->getTicketsBooking()->getItems() as $bookingToEventTicket) {
253 $personsCount += ($bookingToEventTicket->getPersons() ?
254 $bookingToEventTicket->getPersons()->getValue() : 0);
255 }
256 }
257
258 $paymentDeposit = $depositAS->calculateDepositAmount(
259 $paymentAmount,
260 $event,
261 $personsCount
262 );
263
264 $eventData['payment']['deposit'] = $paymentAmount !== $paymentDeposit;
265
266 $paymentAmount = $paymentDeposit;
267 }
268
269 if ($save) {
270 /** @var CustomerBookingRepository $bookingRepository */
271 $bookingRepository = $this->container->get('domain.booking.customerBooking.repository');
272
273 /** @var CustomerBookingExtraRepository $bookingExtraRepository */
274 $bookingExtraRepository = $this->container->get('domain.booking.customerBookingExtra.repository');
275
276 /** @var CustomerBookingEventPeriodRepository $bookingEventPeriodRepository */
277 $bookingEventPeriodRepository =
278 $this->container->get('domain.booking.customerBookingEventPeriod.repository');
279
280 /** @var CustomerBookingEventTicketRepository $bookingEventTicketRepository */
281 $bookingEventTicketRepository = $this->container->get('domain.booking.customerBookingEventTicket.repository');
282
283 $booking->setPrice(new Price($event->getPrice()->getValue()));
284 $booking->setToken(new Token());
285
286 if ($booking->getTicketsBooking() && $event->getCustomPricing()->getValue()) {
287 $ticketSumPrice = 0;
288
289 /** @var CustomerBookingEventTicket $bookingToEventTicket */
290 foreach ($booking->getTicketsBooking()->getItems() as $bookingToEventTicket) {
291 /** @var EventTicket $ticket */
292 $ticket = $event->getCustomTickets()->getItem(
293 $bookingToEventTicket->getEventTicketId()->getValue()
294 );
295
296 $ticketPrice = $ticket->getDateRangePrice() ?
297 $ticket->getDateRangePrice()->getValue() : $ticket->getPrice()->getValue();
298
299 $ticketSumPrice += $bookingToEventTicket->getPersons() ?
300 ($booking->getAggregatedPrice()->getValue() ? $bookingToEventTicket->getPersons()->getValue() : 1)
301 * $ticketPrice : 0;
302 }
303
304 $booking->setPrice(new Price($ticketSumPrice));
305 }
306
307 $booking->setActionsCompleted(new BooleanValueObject(!empty($eventData['payment']['isBackendBooking'])));
308
309 $bookingId = $bookingRepository->add($booking);
310
311 /** @var CustomerBookingExtra $bookingExtra */
312 foreach ($booking->getExtras()->getItems() as $bookingExtra) {
313 $bookingExtra->setCustomerBookingId(new Id($bookingId));
314 $bookingExtraId = $bookingExtraRepository->add($bookingExtra);
315 $bookingExtra->setId(new Id($bookingExtraId));
316 }
317
318 $booking->setId(new Id($bookingId));
319
320 /** @var Payment $payment */
321 $payment = $this->addPayment(
322 $booking->getId()->getValue(),
323 null,
324 $eventData['payment'],
325 $paymentAmount,
326 $event->getPeriods()->getItem(0)->getPeriodStart()->getValue(),
327 Entities::EVENT
328 );
329
330 /** @var Collection $payments */
331 $payments = new Collection();
332
333 $payments->addItem($payment);
334
335 $booking->setPayments($payments);
336
337 /** @var EventPeriod $eventPeriod */
338 foreach ($event->getPeriods()->getItems() as $eventPeriod) {
339 /** @var CustomerBookingEventPeriod $bookingEventPeriod */
340 $bookingEventPeriod = CustomerBookingEventPeriodFactory::create(
341 [
342 'eventPeriodId' => $eventPeriod->getId()->getValue(),
343 'customerBookingId' => $bookingId
344 ]
345 );
346
347 $bookingEventPeriodRepository->add($bookingEventPeriod);
348 }
349
350 /** @var CustomerBookingEventTicket $eventTicket */
351 foreach ($booking->getTicketsBooking()->getItems() as $eventTicket) {
352 if ($eventTicket->getPersons()) {
353 /** @var EventTicket $ticket */
354 $ticket = $event->getCustomTickets()->getItem($eventTicket->getEventTicketId()->getValue());
355
356 $ticketPrice = $ticket->getDateRangePrice() ?
357 $ticket->getDateRangePrice()->getValue() : $ticket->getPrice()->getValue();
358
359 /** @var CustomerBookingEventTicket $bookingEventTicket */
360 $bookingEventTicket = CustomerBookingEventTicketFactory::create(
361 [
362 'eventTicketId' => $eventTicket->getEventTicketId()->getValue(),
363 'customerBookingId' => $bookingId,
364 'persons' => $eventTicket->getPersons()->getValue(),
365 'price' => $ticketPrice,
366 ]
367 );
368
369 $bookingEventTicketRepository->add($bookingEventTicket);
370 }
371 }
372
373 $event->getBookings()->addItem($booking, $booking->getId()->getValue());
374
375 do_action('amelia_after_event_booking_saved', $booking ? $booking->toArray() : null, $event ? $event->toArray() : null);
376 }
377
378 if ($event->getLocationId()) {
379 /** @var Location $location */
380 $location = $locationRepository->getById($event->getLocationId()->getValue());
381
382 $event->setLocation($location);
383 }
384
385 $reservation->setApplyDeposit(new BooleanValueObject($applyDeposit));
386 if ($booking->getCustomer()) {
387 $reservation->setCustomer($booking->getCustomer());
388 }
389
390 /** @var Collection $bookings */
391 $bookings = new Collection();
392
393 $bookings->addItem($booking);
394
395 $event->setBookings($bookings);
396
397 $reservation->setBookable($event);
398 $reservation->setBooking($booking);
399 $reservation->setReservation($event);
400 $reservation->setRecurring(new Collection());
401 $reservation->setPackageReservations(new Collection());
402 $reservation->setIsStatusChanged(new BooleanValueObject(false));
403 }
404
405 /**
406 * @param CustomerBooking $booking
407 * @param string $requestedStatus
408 *
409 * @return array
410 *
411 * @throws ContainerException
412 * @throws ContainerValueNotFoundException
413 * @throws InvalidArgumentException
414 * @throws QueryExecutionException
415 * @throws BookingCancellationException
416 */
417 public function updateStatus($booking, $requestedStatus)
418 {
419 /** @var CustomerBookingRepository $bookingRepository */
420 $bookingRepository = $this->container->get('domain.booking.customerBooking.repository');
421 /** @var SettingsService $settingsDS */
422 $settingsDS = $this->container->get('domain.settings.service');
423
424 /** @var Event $reservation */
425 $event = $this->getReservationByBookingId($booking->getId()->getValue());
426
427 if ($requestedStatus === BookingStatus::CANCELED) {
428 $minimumCancelTimeInSeconds = $settingsDS
429 ->getEntitySettings($event->getSettings())
430 ->getGeneralSettings()
431 ->getMinimumTimeRequirementPriorToCanceling();
432
433 $this->inspectMinimumCancellationTime(
434 $event->getPeriods()->getItem(0)->getPeriodStart()->getValue(),
435 $minimumCancelTimeInSeconds
436 );
437 }
438
439 $booking->setStatus(new BookingStatus($requestedStatus));
440
441 $bookingRepository->update($booking->getId()->getValue(), $booking);
442
443 return [
444 Entities::EVENT => $event->toArray(),
445 'appointmentStatusChanged' => false,
446 Entities::BOOKING => $booking->toArray()
447 ];
448 }
449
450 /**
451 * @param Event $reservation
452 * @param CustomerBooking $booking
453 * @param AbstractBookable $bookable
454 *
455 * @return array
456 */
457 public function getBookingPeriods($reservation, $booking, $bookable)
458 {
459 $dates = [];
460
461 /** @var EventPeriod $period */
462 foreach ($reservation->getPeriods()->getItems() as $period) {
463 $dates[] = [
464 'start' => DateTimeService::getCustomDateTimeInUtc(
465 $period->getPeriodStart()->getValue()->format('Y-m-d H:i:s')
466 ),
467 'end' => DateTimeService::getCustomDateTimeInUtc(
468 $period->getPeriodEnd()->getValue()->format('Y-m-d H:i:s')
469 )
470 ];
471 }
472
473 return $dates;
474 }
475
476 /**
477 * @param array $data
478 *
479 * @return AbstractBookable
480 *
481 * @throws ContainerValueNotFoundException
482 * @throws QueryExecutionException
483 * @throws InvalidArgumentException
484 */
485 public function getBookableEntity($data)
486 {
487 /** @var EventRepository $eventRepository */
488 $eventRepository = $this->container->get('domain.booking.event.repository');
489
490 return $eventRepository->getById($data['eventId']);
491 }
492
493 /**
494 * @param Event $bookable
495 *
496 * @return boolean
497 */
498 public function isAggregatedPrice($bookable)
499 {
500 return $bookable->getAggregatedPrice()->getValue();
501 }
502
503 /**
504 * @param BooleanValueObject $bookableAggregatedPrice
505 * @param BooleanValueObject $extraAggregatedPrice
506 *
507 * @return boolean
508 */
509 public function isExtraAggregatedPrice($extraAggregatedPrice, $bookableAggregatedPrice)
510 {
511 return true;
512 }
513
514 /**
515 * @param Reservation $reservation
516 * @param string $paymentGateway
517 * @param array $requestData
518 *
519 * @return array
520 *
521 * @throws InvalidArgumentException
522 */
523 public function getWooCommerceData($reservation, $paymentGateway, $requestData)
524 {
525 /** @var Event $event */
526 $event = $reservation->getBookable();
527
528 /** @var AbstractUser $customer */
529 $customer = $reservation->getCustomer();
530
531 /** @var CustomerBooking $booking */
532 $booking = $reservation->getBooking();
533
534 $dateTimeValues = [];
535
536 /** @var EventPeriod $period */
537 foreach ($event->getPeriods()->getItems() as $period) {
538 $dateTimeValues[] = [
539 'start' => $period->getPeriodStart()->getValue()->format('Y-m-d H:i'),
540 'end' => $period->getPeriodEnd()->getValue()->format('Y-m-d H:i')
541 ];
542 }
543
544 $info = [
545 'type' => Entities::EVENT,
546 'eventId' => $event->getId()->getValue(),
547 'name' => $event->getName()->getValue(),
548 'couponId' => $booking->getCoupon() ? $booking->getCoupon()->getId()->getValue() : '',
549 'couponCode' => $booking->getCoupon() ? $booking->getCoupon()->getCode()->getValue() : '',
550 'dateTimeValues' => $dateTimeValues,
551 'bookings' => [
552 [
553 'customerId' => $customer->getId() ? $customer->getId()->getValue() : null,
554 'customer' => [
555 'email' => $customer->getEmail()->getValue(),
556 'externalId' => $customer->getExternalId() ? $customer->getExternalId()->getValue() : null,
557 'firstName' => $customer->getFirstName()->getValue(),
558 'id' => $customer->getId() ? $customer->getId()->getValue() : null,
559 'lastName' => $customer->getLastName()->getValue(),
560 'phone' => $customer->getPhone()->getValue(),
561 'countryPhoneIso' => $customer->getCountryPhoneIso() ?
562 $customer->getCountryPhoneIso()->getValue() : null
563 ],
564 'info' => $booking->getInfo()->getValue(),
565 'persons' => $booking->getPersons()->getValue(),
566 'extras' => [],
567 'utcOffset' => $booking->getUtcOffset() ? $booking->getUtcOffset()->getValue() : null,
568 'customFields' => $booking->getCustomFields() ?
569 json_decode($booking->getCustomFields()->getValue(), true) : null,
570 'deposit' => $reservation->getApplyDeposit()->getValue(),
571 'ticketsData' => $requestData['bookings'][0]['ticketsData'],
572 ]
573 ],
574 'payment' => [
575 'gateway' => $paymentGateway
576 ],
577 'locale' => $reservation->getLocale()->getValue(),
578 'timeZone' => $reservation->getTimeZone()->getValue(),
579 'recurring' => [],
580 'package' => [],
581 ];
582
583 foreach ($booking->getExtras()->keys() as $extraKey) {
584 /** @var CustomerBookingExtra $bookingExtra */
585 $bookingExtra = $booking->getExtras()->getItem($extraKey);
586
587 $info['bookings'][0]['extras'][] = [
588 'extraId' => $bookingExtra->getExtraId()->getValue(),
589 'quantity' => $bookingExtra->getQuantity()->getValue()
590 ];
591 }
592
593 return $info;
594 }
595
596
597 /**
598 * @param array $reservation
599 *
600 * @return array
601 *
602 * @throws InvalidArgumentException
603 */
604 public function getWooCommerceDataFromArray($reservation, $index)
605 {
606 /** @var array $event */
607 $event = $reservation['bookable'];
608
609 /** @var array $customer */
610 $customer = !empty($reservation['customer'])
611 ? $reservation['customer']
612 : (!empty($reservation['booking']['customer']) ? $reservation['booking']['customer'] : null);
613
614 /** @var array $booking */
615 $booking = $reservation['booking'];
616
617 if (!empty($booking['ticketsData'])) {
618 foreach ($booking['ticketsData'] as &$ticket) {
619 $customTicketIndex = array_search(
620 $ticket['eventTicketId'],
621 array_column($reservation['event']['customTickets'], 'id')
622 );
623 if ($customTicketIndex !== false) {
624 $ticket['name'] = $reservation['event']['customTickets'][$customTicketIndex]['name'];
625 }
626 }
627 }
628
629 $dateTimeValues = [];
630
631 $customerInfo = !empty($booking['info']) ? json_decode($booking['info'], true) : null;
632
633 /** @var EventPeriod $period */
634 foreach ($event['periods'] as $period) {
635 $dateTimeValues[] = [
636 'start' => $period['periodStart'],
637 'end' => $period['periodEnd']
638 ];
639 }
640
641 $info = [
642 'type' => Entities::EVENT,
643 'eventId' => $event['id'],
644 'name' => $event['name'],
645 'couponId' => $booking['coupon'] ? $booking['coupon']['id'] : '',
646 'couponCode' => $booking['coupon'] ? $booking['coupon']['code'] : '',
647 'dateTimeValues' => $dateTimeValues,
648 'bookings' => [
649 [
650 'customerId' => $customer['id'],
651 'customer' => [
652 'email' => $customer['email'],
653 'externalId' => $customer['externalId'],
654 'firstName' => $customer['firstName'],
655 'id' => $customer['id'],
656 'lastName' => $customer['lastName'],
657 'phone' => $customer['phone'],
658 'countryPhoneIso' => $customer['countryPhoneIso']
659 ],
660 'info' => $booking['info'],
661 'persons' => $booking['persons'],
662 'extras' => [],
663 'utcOffset' => $booking['utcOffset'],
664 'customFields' => $booking['customFields'] ?
665 json_decode($booking['customFields'], true) : null,
666 'deposit' => $booking['price'] > $booking['payments'][0]['amount'],
667 'ticketsData' => $booking['ticketsData'],
668 ]
669 ],
670 'payment' => [
671 'gateway' => $booking['payments'][0]['gateway']
672 ],
673 'locale' => $customerInfo ? $customerInfo['locale'] : null,
674 'timeZone' => $customerInfo ? $customerInfo['timeZone'] : null,
675 'recurring' => [],
676 'package' => [],
677 ];
678
679 foreach ($booking['extras'] as $extra) {
680 $info['bookings'][0]['extras'][] = [
681 'extraId' => $extra['id'],
682 'quantity' => $extra['quantity']
683 ];
684 }
685
686 return $info;
687 }
688
689 /**
690 * @param int $id
691 *
692 * @return Event
693 *
694 * @throws ContainerValueNotFoundException
695 * @throws QueryExecutionException
696 * @throws InvalidArgumentException
697 */
698 public function getReservationByBookingId($id)
699 {
700 /** @var EventRepository $eventRepository */
701 $eventRepository = $this->container->get('domain.booking.event.repository');
702
703 /** @var Event $event */
704 $event = $eventRepository->getByBookingId(
705 $id,
706 [
707 'fetchEventsTickets' => true,
708 'fetchEventsTags' => true,
709 'fetchEventsProviders' => true,
710 'fetchEventsImages' => true,
711 ]
712 );
713
714 /** @var Collection $eventsBookings */
715 $eventsBookings = $eventRepository->getBookingsByCriteria(
716 [
717 'ids' => [$event->getId()->getValue()],
718 'fetchBookings' => true,
719 'fetchBookingsTickets' => true,
720 'fetchBookingsUsers' => true,
721 'fetchBookingsPayments' => true,
722 ]
723 );
724
725 if ($eventsBookings->keyExists($event->getId()->getValue())) {
726 $event->setBookings($eventsBookings->getItem($event->getId()->getValue()));
727 }
728
729 return $event;
730 }
731
732 /**
733 * @param Event $reservation
734 * @param CustomerBooking $newBooking
735 * @param DateTime $dateTime
736 *
737 * @return boolean
738 *
739 * @throws InvalidArgumentException
740 */
741 public function isBookable($reservation, $newBooking, $dateTime)
742 {
743 if ($reservation->getCustomPricing() && $reservation->getCustomPricing()->getValue() && !$reservation->getMaxCustomCapacity()) {
744 $availableTicketsSpots = [];
745
746 /** @var EventTicket $ticket */
747 foreach ($reservation->getCustomTickets()->getItems() as $ticket) {
748 $availableTicketsSpots[$ticket->getId()->getValue()] = $ticket->getSpots()->getValue();
749 }
750
751 $reservedTicketsSpots = [];
752
753 /** @var CustomerBooking $booking */
754 foreach ($reservation->getBookings()->getItems() as $booking) {
755 if ($booking->getStatus()->getValue() === BookingStatus::APPROVED) {
756 /** @var CustomerBookingEventTicket $bookingTicket */
757 foreach ($booking->getTicketsBooking()->getItems() as $bookingTicket) {
758 $eventTicketId = $bookingTicket->getEventTicketId()->getValue();
759
760 if (!array_key_exists($eventTicketId, $reservedTicketsSpots)) {
761 $reservedTicketsSpots[$eventTicketId] = 0;
762 }
763
764 $reservedTicketsSpots[$eventTicketId] += $bookingTicket->getPersons()->getValue();
765 }
766 }
767 }
768
769 if ($newBooking) {
770 /** @var CustomerBookingEventTicket $newBookingTicket */
771 foreach ($newBooking->getTicketsBooking()->getItems() as $newBookingTicket) {
772 $eventTicketId = $newBookingTicket->getEventTicketId()->getValue();
773
774 if (empty($reservedTicketsSpots[$eventTicketId])) {
775 $reservedTicketsSpots[$eventTicketId] = 0;
776 }
777
778 $reservedTicketsSpots[$eventTicketId] +=
779 $newBookingTicket->getPersons() ? $newBookingTicket->getPersons()->getValue() : 0;
780 }
781 }
782
783 $hasTicketCapacity = [];
784
785 foreach ($availableTicketsSpots as $eventTicketId => $availablePersons) {
786 $hasTicketCapacity[$eventTicketId] = array_key_exists($eventTicketId, $reservedTicketsSpots) ?
787 ($newBooking ?
788 $reservedTicketsSpots[$eventTicketId] <= $availablePersons :
789 $reservedTicketsSpots[$eventTicketId] < $availablePersons
790 ) : true;
791 }
792
793 $hasCapacity = false;
794
795 foreach ($hasTicketCapacity as $ticketId => $ticketCapacity) {
796 if ($newBooking) {
797 $hasCapacity = true;
798
799 /** @var EventTicket $ticket */
800 $ticket = $reservation->getCustomTickets()->getItem($ticketId);
801
802 /** @var CustomerBookingEventTicket $ticketBooking */
803 foreach ($newBooking->getTicketsBooking()->getItems() as $ticketBooking) {
804 if ($ticketBooking->getEventTicketId()->getValue() === $ticketId &&
805 $ticketBooking->getPersons() &&
806 $ticketBooking->getPersons()->getValue() &&
807 (!$ticketCapacity || !$ticket->getEnabled()->getValue())
808 ) {
809 $hasCapacity = false;
810
811 break 2;
812 }
813 }
814 } else {
815 $hasCapacity = $hasCapacity || $ticketCapacity;
816 }
817 }
818 } else if ($reservation->getMaxCustomCapacity()) {
819 $availableTicketsSpots = $reservation->getMaxCustomCapacity()->getValue();
820 $reservedTicketsSpots = 0;
821 /** @var CustomerBooking $booking */
822 foreach ($reservation->getBookings()->getItems() as $booking) {
823 if ($booking->getStatus()->getValue() === BookingStatus::APPROVED) {
824 /** @var CustomerBookingEventTicket $bookingTicket */
825 foreach ($booking->getTicketsBooking()->getItems() as $bookingTicket) {
826 $reservedTicketsSpots += $bookingTicket->getPersons()->getValue();
827 }
828 }
829 }
830
831 if ($newBooking) {
832 /** @var CustomerBookingEventTicket $newBookingTicket */
833 foreach ($newBooking->getTicketsBooking()->getItems() as $newBookingTicket) {
834 $reservedTicketsSpots += $newBookingTicket->getPersons() ? $newBookingTicket->getPersons()->getValue() : 0;
835 }
836 }
837
838 $hasCapacity = ($newBooking ? $reservedTicketsSpots <= $availableTicketsSpots : $reservedTicketsSpots < $availableTicketsSpots);
839
840 } else {
841 $persons = 0;
842
843 /** @var CustomerBooking $booking */
844 foreach ($reservation->getBookings()->getItems() as $booking) {
845 if ($booking->getStatus()->getValue() === BookingStatus::APPROVED) {
846 $persons += $booking->getPersons()->getValue();
847 }
848 }
849 if ($newBooking) {
850 $hasCapacity = ($reservation->getMaxCapacity()->getValue() - $persons - $newBooking->getPersons()->getValue()) >= 0;
851 } else {
852 $hasCapacity = $reservation->getMaxCapacity()->getValue() - $persons > 0;
853 }
854 }
855
856 $bookingCloses = $reservation->getBookingCloses() ?
857 $reservation->getBookingCloses()->getValue() :
858 $reservation->getPeriods()->getItem(0)->getPeriodStart()->getValue();
859
860 $bookingOpens = $reservation->getBookingOpens() ?
861 $reservation->getBookingOpens()->getValue() :
862 $reservation->getCreated()->getValue();
863
864 $hasWaitingList = false;
865 $eventSettings = $reservation->getSettings() ? json_decode($reservation->getSettings()->getValue(), true) : null;
866
867 /** @var SettingsService $settingsDS */
868 $settingsDS = $this->container->get('domain.settings.service');
869 $waitingListSettings = $settingsDS->getSetting('appointments', 'waitingListEvents');
870
871 if (
872 $waitingListSettings['enabled'] && $eventSettings && !empty($eventSettings['waitingList']) &&
873 $eventSettings['waitingList']['enabled']
874 ) {
875 $waitingCustomers = 0;
876
877 foreach ($reservation->getBookings()->getItems() as $booking) {
878 if ($booking->getStatus()->getValue() === BookingStatus::WAITING) {
879 if ($reservation->getCustomPricing()->getValue()) {
880 foreach ($booking->getTicketsBooking()->getItems() as $item) {
881 $waitingCustomers += $item->getPersons()->getValue();
882 }
883 } else {
884 $waitingCustomers += $booking->getPersons()->getValue();
885 }
886 }
887 }
888
889 if ($newBooking && $reservation->getCustomPricing() && $reservation->getCustomPricing()->getValue()) {
890 foreach ($newBooking->getTicketsBooking()->getItems() as $item) {
891 if (!$reservation->getMaxCustomCapacity()) {
892 $ticketData = $reservation->getCustomTickets()->getItem($item->getId()->getValue());
893
894 $hasWaitingList = $ticketData->getWaitingListSpots() && $ticketData->getWaitingListSpots()->getValue() >=
895 ($item->getPersons() ? $item->getPersons()->getValue() : 0
896 + ($ticketData->getWaiting() ? $ticketData->getWaiting()->getValue() : 0));
897 }
898 }
899
900 if ($reservation->getMaxCustomCapacity()) {
901 $hasWaitingList = $eventSettings['waitingList']['maxCapacity'] > $waitingCustomers;
902 }
903
904 } else {
905 $hasWaitingList = $eventSettings['waitingList']['maxCapacity'] > $waitingCustomers;
906 }
907
908 $eventSettings['waitingList']['peopleWaiting'] = $waitingCustomers;
909
910 $reservation->setSettings(new Json(json_encode($eventSettings)));
911 }
912
913 return $dateTime > $bookingOpens &&
914 $dateTime < $bookingCloses &&
915 ($hasCapacity || $hasWaitingList) &&
916 in_array($reservation->getStatus()->getValue(), [BookingStatus::APPROVED, BookingStatus::PENDING], true);
917 }
918
919 /**
920 * @param CustomerBooking $booking
921 * @param Event $bookable
922 * @param string|null $reduction
923 *
924 * @return array
925 *
926 * @throws InvalidArgumentException
927 */
928 public function getPaymentAmount($booking, $bookable, $invoice = false)
929 {
930 /** @var TaxApplicationService $taxApplicationService */
931 $taxApplicationService = $this->container->get('application.tax.service');
932
933 /** @var Tax $eventTax */
934 $eventTax = $this->getTax($booking->getTax());
935
936 $persons = $booking->getPersons()->getValue();
937
938 $unitPrice = (float)$bookable->getPrice()->getValue();
939
940 $price = $unitPrice * ($this->isAggregatedPrice($bookable) ? $persons : 1);
941
942 $taxAmount = 0;
943
944 $ticketsTax = [];
945
946 if ($booking->getTicketsBooking() &&
947 $booking->getTicketsBooking()->length() &&
948 $bookable->getCustomPricing() &&
949 $bookable->getCustomPricing()->getValue()
950 ) {
951 /** @var EventApplicationService $eventApplicationService */
952 $eventApplicationService = $this->container->get('application.booking.event.service');
953
954 $bookable->setCustomTickets(
955 $eventApplicationService->getTicketsPriceByDateRange($bookable->getCustomTickets())
956 );
957
958 $ticketSumPrice = 0;
959
960 /** @var CustomerBookingEventTicket $bookingToEventTicket */
961 foreach ($booking->getTicketsBooking()->getItems() as $bookingToEventTicket) {
962 /** @var EventTicket $ticket */
963 $ticket = $bookable->getCustomTickets()->getItem($bookingToEventTicket->getEventTicketId()->getValue());
964
965 $ticketPrice = $ticket->getDateRangePrice() ?
966 $ticket->getDateRangePrice()->getValue() : $ticket->getPrice()->getValue();
967
968 $ticketPersons = $bookingToEventTicket->getPersons() ?
969 ($booking->getAggregatedPrice()->getValue() ? $bookingToEventTicket->getPersons()->getValue() : 1)
970 : 0;
971
972 $ticketSubtotal = $ticketPersons * $ticketPrice;
973
974 $ticketSumPrice += $ticketSubtotal;
975
976 if ($bookingToEventTicket->getId()) {
977 if ($eventTax && $eventTax->getExcluded()->getValue()) {
978 $ticketsTax[$bookingToEventTicket->getId()->getValue()] = $this->getTaxAmount($eventTax, $ticketSubtotal);
979 } else if ($eventTax && !$eventTax->getExcluded()->getValue()) {
980 $ticketsTax[$bookingToEventTicket->getId()->getValue()] = $this->getTaxAmount($eventTax, $taxApplicationService->getBasePrice($ticketSubtotal, $eventTax));
981 } else {
982 $ticketsTax[$bookingToEventTicket->getId()->getValue()] = 0;
983 }
984 }
985 }
986
987 $price = $ticketSumPrice;
988 }
989
990 if ($eventTax && !$eventTax->getExcluded()->getValue() && ($booking->getCoupon() || $invoice)) {
991 $price = $taxApplicationService->getBasePrice($price, $eventTax);
992 }
993
994 $subtraction = 0;
995
996 $reductionAmount = [
997 'deduction' => 0,
998 'discount' => 0,
999 ];
1000
1001 if ($booking->getCoupon()) {
1002 $reductionAmount['discount'] = $price / 100 * ($booking->getCoupon()->getDiscount()->getValue() ?: 0);
1003
1004 $reductionAmount['deduction'] = $booking->getCoupon()->getDeduction()->getValue();
1005
1006 $subtraction = $reductionAmount['discount'] + $reductionAmount['deduction'];
1007
1008 $price = max($price - $subtraction, 0);
1009 }
1010
1011 if ($eventTax && ($eventTax->getExcluded()->getValue() || $subtraction || $invoice)) {
1012 $taxAmount = $this->getTaxAmount($eventTax, $price);
1013 $price += $taxAmount;
1014 }
1015
1016 $price = (float)max(round($price, 2), 0);
1017
1018 return [
1019 'price' => apply_filters('amelia_modify_payment_amount', $price, $booking),
1020 'discount' => $reductionAmount['discount'],
1021 'deduction' => $reductionAmount['deduction'],
1022 'unit_price' => $unitPrice,
1023 'qty' => $persons,
1024 'subtotal' => $unitPrice * ($this->isAggregatedPrice($bookable) ? $persons : 1),
1025 'tax' => !empty($ticketsTax) ? null : $taxAmount,
1026 'tax_rate' => $eventTax ? $this->getTaxRate($eventTax) : '',
1027 'tax_type' => $eventTax ? $eventTax->getType()->getValue() : '',
1028 'tax_excluded' => $eventTax ? $eventTax->getExcluded()->getValue() : false,
1029 'tickets_tax' => $ticketsTax,
1030 'full_discount' => $this->getCouponDiscountAmount($booking->getCoupon(), $unitPrice) + ($booking->getCoupon() && $booking->getCoupon()->getDeduction() ? $booking->getCoupon()->getDeduction()->getValue() : 0)
1031 ];
1032 }
1033
1034 /**
1035 * @param Reservation $reservation
1036 *
1037 * @return float
1038 *
1039 * @throws InvalidArgumentException
1040 */
1041 public function getReservationPaymentAmount($reservation)
1042 {
1043 /** @var AbstractDepositApplicationService $depositAS */
1044 $depositAS = $this->container->get('application.deposit.service');
1045
1046 /** @var Event $bookable */
1047 $bookable = $reservation->getBookable();
1048
1049 $paymentAmount = $this->getPaymentAmount($reservation->getBooking(), $bookable)['price'];
1050
1051 if ($reservation->getApplyDeposit()->getValue()) {
1052 $personsCount = $reservation->getBooking()->getPersons()->getValue();
1053
1054 if ($reservation->getBooking()->getTicketsBooking() && $bookable->getCustomPricing()->getValue()) {
1055 $personsCount = 0;
1056
1057 /** @var CustomerBookingEventTicket $bookingToEventTicket */
1058 foreach ($reservation->getBooking()->getTicketsBooking()->getItems() as $bookingToEventTicket) {
1059 $personsCount += ($bookingToEventTicket->getPersons() ?
1060 $bookingToEventTicket->getPersons()->getValue() : 0);
1061 }
1062 }
1063
1064 $paymentAmount = $depositAS->calculateDepositAmount(
1065 $paymentAmount,
1066 $bookable,
1067 $personsCount
1068 );
1069 }
1070
1071 return $paymentAmount;
1072 }
1073
1074 /**
1075 * @param Reservation $reservation
1076 *
1077 * @return array
1078 *
1079 * @throws InvalidArgumentException
1080 */
1081 public function getProvidersPaymentAmount($reservation)
1082 {
1083 $amountData = [];
1084
1085 /** @var Payment $payment */
1086 $payment = $reservation->getBooking()->getPayments()->getItem(0);
1087
1088 /** @var Event $event */
1089 $event = $reservation->getBookable();
1090
1091 /** @var Provider $provider */
1092 foreach ($event->getProviders()->getItems() as $provider) {
1093 $amountData[$provider->getId()->getValue()][] = [
1094 'paymentId' => $payment->getId()->getValue(),
1095 'amount' => $this->getReservationPaymentAmount($reservation),
1096 ];
1097 }
1098
1099 return $amountData;
1100 }
1101
1102 /**
1103 * @param Payment $payment
1104 * @param boolean $fromLink
1105 *
1106 * @return CommandResult
1107 * @throws InvalidArgumentException
1108 * @throws Exception
1109 * @throws \Interop\Container\Exception\ContainerException
1110 */
1111 public function getReservationByPayment($payment, $fromLink = false)
1112 {
1113 $result = new CommandResult();
1114
1115 /** @var CustomerRepository $customerRepository */
1116 $customerRepository = $this->container->get('domain.users.customers.repository');
1117
1118 /** @var LocationRepository $locationRepository */
1119 $locationRepository = $this->container->get('domain.locations.repository');
1120
1121 /** @var ReservationServiceInterface $reservationService */
1122 $reservationService = $this->container->get('application.reservation.service')->get(Entities::EVENT);
1123
1124 /** @var Event $event */
1125 $event = $reservationService->getReservationByBookingId(
1126 $payment->getCustomerBookingId()->getValue()
1127 );
1128
1129 if ($event->getLocationId()) {
1130 /** @var Location $location */
1131 $location = $locationRepository->getById($event->getLocationId()->getValue());
1132
1133 $event->setLocation($location);
1134 }
1135
1136 /** @var CustomerBooking $booking */
1137 $booking = $event->getBookings()->getItem($payment->getCustomerBookingId()->getValue());
1138
1139 $booking->setChangedStatus(new BooleanValueObject(true));
1140
1141 $this->setToken($booking);
1142
1143 /** @var AbstractUser $customer */
1144 $customer = $customerRepository->getById($booking->getCustomerId()->getValue());
1145
1146 $result->setData(
1147 [
1148 'type' => Entities::EVENT,
1149 Entities::EVENT => $event->toArray(),
1150 Entities::BOOKING => $booking->toArray(),
1151 'appointmentStatusChanged' => false,
1152 'customer' => $customer->toArray(),
1153 'packageId' => 0,
1154 'recurring' => [],
1155 'utcTime' => $reservationService->getBookingPeriods(
1156 $event,
1157 $booking,
1158 $event
1159 ),
1160 'isRetry' => !$fromLink,
1161 'fromLink' => $fromLink,
1162 'paymentId' => $payment->getId()->getValue(),
1163 'packageCustomerId' => null,
1164 'payment' => [
1165 'id' => $payment->getId()->getValue(),
1166 'amount' => $payment->getAmount()->getValue(),
1167 'gateway' => $payment->getGateway()->getName()->getValue(),
1168 'gatewayTitle' => $payment->getGatewayTitle() ? $payment->getGatewayTitle()->getValue() : '',
1169 'invoiceNumber' => $payment->getInvoiceNumber() ? $payment->getInvoiceNumber()->getValue() : '',
1170 ],
1171 ]
1172 );
1173
1174 return $result;
1175 }
1176
1177 /**
1178 * @param int $bookingId
1179 *
1180 * @return CommandResult
1181 * @throws InvalidArgumentException
1182 * @throws Exception
1183 * @throws \Interop\Container\Exception\ContainerException
1184 */
1185 public function getBookingResultByBookingId($bookingId)
1186 {
1187 $result = new CommandResult();
1188
1189 /** @var CustomerRepository $customerRepository */
1190 $customerRepository = $this->container->get('domain.users.customers.repository');
1191
1192 /** @var LocationRepository $locationRepository */
1193 $locationRepository = $this->container->get('domain.locations.repository');
1194
1195 /** @var ReservationServiceInterface $reservationService */
1196 $reservationService = $this->container->get('application.reservation.service')->get(Entities::EVENT);
1197
1198 /** @var Event $event */
1199 $event = $reservationService->getReservationByBookingId(
1200 $bookingId
1201 );
1202
1203 if ($event->getLocationId()) {
1204 /** @var Location $location */
1205 $location = $locationRepository->getById($event->getLocationId()->getValue());
1206
1207 $event->setLocation($location);
1208 }
1209
1210 /** @var CustomerBooking $booking */
1211 $booking = $event->getBookings()->getItem($bookingId);
1212
1213 $booking->setChangedStatus(new BooleanValueObject(true));
1214
1215 $this->setToken($booking);
1216
1217 /** @var AbstractUser $customer */
1218 $customer = $customerRepository->getById($booking->getCustomerId()->getValue());
1219
1220 $result->setData(
1221 [
1222 'type' => Entities::EVENT,
1223 Entities::EVENT => $event->toArray(),
1224 Entities::BOOKING => $booking->toArray(),
1225 'appointmentStatusChanged' => false,
1226 'customer' => $customer->toArray(),
1227 'packageId' => 0,
1228 'recurring' => [],
1229 'utcTime' => $reservationService->getBookingPeriods(
1230 $event,
1231 $booking,
1232 $event
1233 ),
1234 'isRetry' => true,
1235 'paymentId' => null,
1236 'packageCustomerId' => null,
1237 'payment' => null,
1238 ]
1239 );
1240
1241 return $result;
1242 }
1243
1244 /**
1245 * @param array $data
1246 *
1247 * @return void
1248 * @throws QueryExecutionException
1249 */
1250 public function manageTaxes(&$data)
1251 {
1252 /** @var TaxApplicationService $taxAS */
1253 $taxAS = $this->container->get('application.tax.service');
1254
1255 /** @var SettingsService $settingsService */
1256 $settingsService = $this->container->get('domain.settings.service');
1257
1258 $taxesSettings = $settingsService->getSetting('payments', 'taxes');
1259
1260 if ($taxesSettings['enabled']) {
1261 /** @var Collection $taxes */
1262 $taxes = $taxAS->getAll();
1263
1264 $data['bookings'][0]['tax'] = $taxAS->getTaxData(
1265 $data['eventId'],
1266 Entities::EVENT,
1267 $taxes
1268 );
1269 }
1270 }
1271 }
1272