container->get('domain.booking.event.repository'); /** @var Event $event */ $event = $eventRepository->getById($eventData['eventId']); $booking = CustomerBookingFactory::create( array_merge($eventData['bookings'][0], ['status' => BookingStatus::APPROVED]) ); $booking->setStatus(new BookingStatus(BookingStatus::APPROVED)); $personsCount = 0; /** @var CustomerBooking $customerBooking */ foreach ($event->getBookings()->getItems() as $customerBooking) { if ($customerBooking->getStatus()->getValue() === BookingStatus::APPROVED) { $personsCount += $customerBooking->getPersons()->getValue(); } } if ($inspectAvailability && !$this->isBookable($event, null, DateTimeService::getNowDateTimeObject()) && $personsCount + $booking->getPersons()->getValue() > $event->getMaxCapacity()->getValue() ) { throw new BookingUnavailableException(''); } if ($save) { /** @var CustomerBookingRepository $bookingRepository */ $bookingRepository = $this->container->get('domain.booking.customerBooking.repository'); /** @var CustomerBookingExtraRepository $bookingExtraRepository */ $bookingExtraRepository = $this->container->get('domain.booking.customerBookingExtra.repository'); /** @var CustomerBookingEventPeriodRepository $bookingEventPeriodRepository */ $bookingEventPeriodRepository = $this->container->get('domain.booking.customerBookingEventPeriod.repository'); $booking->setPrice(new Price($event->getPrice()->getValue())); $booking->setToken(new Token()); $bookingId = $bookingRepository->add($booking); /** @var CustomerBookingExtra $bookingExtra */ foreach ($booking->getExtras()->getItems() as $bookingExtra) { $bookingExtra->setCustomerBookingId(new Id($bookingId)); $bookingExtraId = $bookingExtraRepository->add($bookingExtra); $bookingExtra->setId(new Id($bookingExtraId)); } $booking->setId(new Id($bookingId)); $this->addPayment( $bookingId, $eventData['payment'], $this->getPaymentAmount($booking, $event), $event->getPeriods()->getItem(0)->getPeriodStart()->getValue() ); /** @var EventPeriod $eventPeriod */ foreach ($event->getPeriods()->getItems() as $eventPeriod) { $bookingEventPeriod = CustomerBookingEventPeriodFactory::create([ 'eventPeriodId' => $eventPeriod->getId()->getValue(), 'customerBookingId' => $bookingId ]); $bookingEventPeriodRepository->add($bookingEventPeriod); } } return [ 'bookable' => $event, 'booking' => $booking, Entities::EVENT => $event, 'appointmentStatusChanged' => false, ]; } /** * @param int $bookingId * @param string $requestedStatus * @param string $token * * @return array * * @throws \Slim\Exception\ContainerValueNotFoundException * @throws AccessDeniedException * @throws InvalidArgumentException * @throws QueryExecutionException * @throws \Interop\Container\Exception\ContainerException * @throws BookingCancellationException * @throws NotFoundException */ public function updateStatus($bookingId, $requestedStatus, $token) { /** @var CustomerBookingRepository $bookingRepository */ $bookingRepository = $this->container->get('domain.booking.customerBooking.repository'); /** @var CustomerBooking $booking */ $booking = $bookingRepository->getById($bookingId); /** @var Event $reservation */ $event = $this->getReservationByBookingId($bookingId); $this->inspectToken($booking, $token); $this->inspectMinimumCancellationTime($event->getPeriods()->getItem(0)->getPeriodStart()->getValue()); $booking->setStatus(new BookingStatus($requestedStatus)); /** @var CustomerBookingRepository $bookingRepository */ $bookingRepository = $this->container->get('domain.booking.customerBooking.repository'); $bookingRepository->update($bookingId, $booking); return [ Entities::EVENT => $event->toArray(), 'appointmentStatusChanged' => false, Entities::BOOKING => $booking->toArray() ]; } /** * @param Event $reservation * @param CustomerBooking $booking * @param AbstractBookable $bookable * * @return array */ public function getBookingPeriods($reservation, $booking, $bookable) { $dates = []; /** @var EventPeriod $period */ foreach ($reservation->getPeriods()->getItems() as $period) { $dates[] = [ 'start' => DateTimeService::getCustomDateTimeInUtc( $period->getPeriodStart()->getValue()->format('Y-m-d H:i:s') ), 'end' => DateTimeService::getCustomDateTimeInUtc( $period->getPeriodEnd()->getValue()->format('Y-m-d H:i:s') ) ]; } return $dates; } /** * @param array $data * * @return AbstractBookable * * @throws \Slim\Exception\ContainerValueNotFoundException * @throws QueryExecutionException * @throws \Interop\Container\Exception\ContainerException * @throws InvalidArgumentException */ public function getBookable($data) { /** @var EventRepository $eventRepository */ $eventRepository = $this->container->get('domain.booking.event.repository'); return $eventRepository->getById($data['id']); } /** @noinspection MoreThanThreeArgumentsInspection */ /** * @param Event $bookable * @param CustomerBooking $booking * @param Event $reservation * @param string $paymentGateway * * @return array * * @throws InvalidArgumentException */ public function getInfo($bookable, $booking, $reservation, $paymentGateway) { $dateTimeValues = []; /** @var EventPeriod $period */ foreach ($bookable->getPeriods()->getItems() as $period) { $dateTimeValues[] = [ 'start' => $period->getPeriodStart()->getValue()->format('Y-m-d H:i'), 'end' => $period->getPeriodEnd()->getValue()->format('Y-m-d H:i') ]; } $info = [ 'type' => Entities::EVENT, 'eventId' => $bookable->getId()->getValue(), 'name' => $bookable->getName()->getValue(), 'couponId' => $booking->getCoupon() ? $booking->getCoupon()->getId()->getValue() : '', 'couponCode' => $booking->getCoupon() ? $booking->getCoupon()->getCode()->getValue() : '', 'dateTimeValues' => $dateTimeValues, 'bookings' => [ [ 'customerId' => $booking->getCustomer()->getId() ? $booking->getCustomer()->getId()->getValue() : null, 'customer' => [ 'email' => $booking->getCustomer()->getEmail()->getValue(), 'externalId' => $booking->getCustomer()->getExternalId() ? $booking->getCustomer()->getExternalId()->getValue() : null, 'firstName' => $booking->getCustomer()->getFirstName()->getValue(), 'id' => $booking->getCustomer()->getId() ? $booking->getCustomer()->getId()->getValue() : null, 'lastName' => $booking->getCustomer()->getLastName()->getValue(), 'phone' => $booking->getCustomer()->getPhone()->getValue() ], 'persons' => $booking->getPersons()->getValue(), 'extras' => [], 'utcOffset' => $booking->getUtcOffset() ? $booking->getUtcOffset()->getValue() : null, 'customFields' => $booking->getCustomFields() ? $booking->getCustomFields()->getValue() : null ] ], 'payment' => [ 'gateway' => $paymentGateway ] ]; foreach ($booking->getExtras()->keys() as $extraKey) { /** @var CustomerBookingExtra $bookingExtra */ $bookingExtra = $booking->getExtras()->getItem($extraKey); $info['bookings'][0]['extras'][] = [ 'extraId' => $bookingExtra->getExtraId()->getValue(), 'quantity' => $bookingExtra->getQuantity()->getValue() ]; } return $info; } /** * @param int $id * * @return Event * * @throws \Slim\Exception\ContainerValueNotFoundException * @throws QueryExecutionException * @throws \Interop\Container\Exception\ContainerException * @throws InvalidArgumentException */ public function getReservationById($id) { /** @var EventRepository $eventRepository */ $eventRepository = $this->container->get('domain.booking.event.repository'); return $eventRepository->getById($id); } /** * @param int $id * * @return Event * * @throws \Slim\Exception\ContainerValueNotFoundException * @throws QueryExecutionException * @throws \Interop\Container\Exception\ContainerException * @throws InvalidArgumentException */ public function getReservationByBookingId($id) { /** @var EventRepository $eventRepository */ $eventRepository = $this->container->get('domain.booking.event.repository'); /** @var Collection $events */ $events = $eventRepository->getByBookingIds([$id]); /** @var Event $event */ return $events->length() ? $events->getItem($events->keys()[0]) : null; } /** * @param Event $reservation * @param Event $bookable * @param \DateTime $dateTime * * @return boolean * * @throws InvalidArgumentException */ public function isBookable($reservation, $bookable, $dateTime) { $persons = 0; /** @var CustomerBooking $booking */ foreach ($reservation->getBookings()->getItems() as $booking) { if ($booking->getStatus()->getValue() === BookingStatus::APPROVED) { $persons += $booking->getPersons()->getValue(); } } $bookingCloses = $reservation->getBookingCloses() ? $reservation->getBookingCloses()->getValue() : $reservation->getPeriods()->getItem(0)->getPeriodStart()->getValue(); $bookingOpens = $reservation->getBookingOpens() ? $reservation->getBookingOpens()->getValue() : $reservation->getCreated()->getValue(); return $dateTime > $bookingOpens && $dateTime < $bookingCloses && $reservation->getMaxCapacity()->getValue() - $persons > 0 && in_array($reservation->getStatus()->getValue(), [BookingStatus::APPROVED, BookingStatus::PENDING], true); } }