toArray(); if (\is_null($payload)) { throw new \Exception('Invalid Payload', 400); } $refNumber = $payload["refNumber"]; $customerEmail = $payload["email"]; $bookingList = $repoBooking->findBy(["refNumber" => $refNumber]); if (\is_null($bookingList) || \count($bookingList) == 0) { throw new HttpException(404, 'Invalid Booking'); } $customerBooking = $bookingList[0]; if ($customerBooking->getBookingCustomer()->getEmail() != $customerEmail) { throw new HttpException(404, 'Invalid Booking'); } return $this->json($customerBooking); } /** * Create a new Booking. */ #[Route('/api/booking/create', name: 'app_booking_create', methods: ["POST"])] #[OA\Tag(name: "Booking")] #[OA\Response( response: 200, description: 'Returns booking details', content: new OA\JsonContent( type: 'object', ref: new Model(type: BookingCreateResponse::class) ) )] #[OA\RequestBody( content: new OA\JsonContent( type: 'object', ref: new Model(type: BookingCreateRequest::class), ) )] public function newBooking(Request $request, BookingRepository $repoBooking, EntityManagerInterface $entityManager, RoomCategoryRepository $repoCat, RoomAvailabilityRepository $repoAvailability, PricesService $priceSrv): JsonResponse { $payload = $request->toArray(); if (\is_null($payload)) { throw new HttpException('Invalid Payload', 400); } $booking = new Booking(); try { $reqArrivalDate = $payload["arrivalDate"]; $reqDepartureDate = $payload["departureDate"]; $arrivalDate = new \DateTime($reqArrivalDate); $departureDate = new \DateTime($reqDepartureDate); if ($arrivalDate >= $departureDate) { throw new HttpException(400, "Arrival cant be before departure"); } $entityManager->beginTransaction(); $currentTime = new \DateTime(); // Create booking from request data. $booking->setBookingTime($currentTime); $booking->setArrivalDate($arrivalDate); $booking->setDepartureDate($departureDate); $highest_id = $entityManager->createQueryBuilder() ->select('MAX(e.id)') ->from('App\Entity\Booking', 'e') ->getQuery() ->getSingleScalarResult(); $booking->setRefNumber($currentTime->format("Y") . $highest_id + 1); $entityManager->persist($booking); // Create booking customer. $reqCustomer = $payload["customerDetails"]; $bookingCustomer = new BookingCustomer(); $bookingCustomer->setName($reqCustomer["name"]); $bookingCustomer->setSurname($reqCustomer["surname"]); $bookingCustomer->setEmail($reqCustomer["email"]); $bookingCustomer->setPhoneNumber($reqCustomer["phoneNumber"]); $bookingCustomer->setBooking($booking); $entityManager->persist($bookingCustomer); $reqRoomList = $payload["rooms"]; if (\count($reqRoomList) == 0) { throw new HttpException(400, "Se debe indicar al menos una habitación"); } // Create each room. foreach ($reqRoomList as $roomItem) { $room = new BookingRoom(); $room->setBooking($booking); //Get Room category. $roomCategory = $repoCat->find($roomItem["roomCategory"]); if ($roomCategory == null) { throw new HttpException(400, "La RoomCategory no es válida."); } //Check room availability. $amountAvailable = $repoAvailability->getAvailabilityForCategoryInPeriod($roomCategory, $arrivalDate, $departureDate); $selectedAmount = $roomItem['amount']; $selectedGuestAmount = $roomItem["guestNumber"]; if($amountAvailable == null || $selectedAmount > $amountAvailable) { throw new HttpException(400, "No se pueden reservar más habitaciones de las disponibles."); } $room->setRoomCategory($roomCategory); $room->setGuestNumber($selectedGuestAmount); $room->setAmount($selectedAmount); //Get Price for period. $priceList = $priceSrv->getFinalPricesForSearch($roomCategory, $arrivalDate, $departureDate); $priceFound = false; foreach ($priceList as $key => $value) { if($key == $selectedGuestAmount) { $room->setRoomPrice($value); $priceFound = true; break; } } if(!$priceFound) { throw new HttpException( 500, "No se puedo obtener el precio para la categoría: " . $roomCategory->getId() . " , guests: " . $selectedGuestAmount ); } $entityManager->persist($room); //If booking is nice, let's update current availability. $repoAvailability->updateAvailabilityForRoomCategoryOnPeriod($roomCategory, $arrivalDate, $departureDate, $selectedAmount, true); //Update using "diff" mode. } $entityManager->commit(); $entityManager->flush(); } catch (\Throwable $th) { $entityManager->rollback(); throw $th; } $results = ["refNumber" => $booking->getRefNumber()]; return $this->json($results); } }