API - Added mapping for API request objects.

This commit is contained in:
2024-10-01 20:43:25 +02:00
parent 986f422824
commit a495be6bb2
4 changed files with 78 additions and 105 deletions
+41 -56
View File
@@ -20,13 +20,14 @@ use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\Routing\Attribute\Route;
use OpenApi\Attributes as OA;
use Symfony\Component\HttpKernel\Attribute\MapRequestPayload;
class BookingController extends AbstractController
{
/**
* Get booking details
*/
#[Route('/api/booking/details', name: 'app_booking_details', methods: ["POST"])]
#[Route('/api/booking/details', name: 'app_booking_details', methods: ["POST"], format: "json")]
#[OA\Tag(name: "Booking")]
#[OA\Response(
response: 200,
@@ -42,23 +43,22 @@ class BookingController extends AbstractController
ref: new Model(type: BookingDetailsRequest::class),
)
)]
public function getBookingDetails(Request $request, BookingRepository $repoBooking): JsonResponse
{
$payload = $request->toArray();
if (\is_null($payload)) {
public function getBookingDetails(
BookingRepository $repoBooking,
#[MapRequestPayload()] BookingDetailsRequest $detailsRequest
): JsonResponse {
if (\is_null($detailsRequest)) {
throw new \Exception('Invalid Payload', 400);
}
$refNumber = $payload["refNumber"];
$customerEmail = $payload["email"];
$bookingList = $repoBooking->findBy(["refNumber" => $refNumber]);
$bookingList = $repoBooking->findBy(["refNumber" => $detailsRequest->refNumber]);
if (\is_null($bookingList) || \count($bookingList) == 0) {
throw new HttpException(404, 'Invalid Booking');
}
$customerBooking = $bookingList[0];
if ($customerBooking->getBookingCustomer()->getEmail() != $customerEmail) {
if ($customerBooking->getBookingCustomer()->getEmail() != $detailsRequest->email) {
throw new HttpException(404, 'Invalid Booking');
}
@@ -68,7 +68,7 @@ class BookingController extends AbstractController
/**
* Create a new Booking.
*/
#[Route('/api/booking/create', name: 'app_booking_create', methods: ["POST"])]
#[Route('/api/booking/create', name: 'app_booking_create', methods: ["POST"], format: "json")]
#[OA\Tag(name: "Booking")]
#[OA\Response(
response: 200,
@@ -84,25 +84,21 @@ class BookingController extends AbstractController
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)) {
public function newBooking(
Request $request,
EntityManagerInterface $entityManager,
RoomCategoryRepository $repoCat,
RoomAvailabilityRepository $repoAvailability,
PricesService $priceSrv,
#[MapRequestPayload()] BookingCreateRequest $createRequest
): JsonResponse {
if (\is_null($createRequest)) {
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) {
if ($createRequest->arrivalDate >= $createRequest->departureDate) {
throw new HttpException(400, "Arrival cant be before departure");
}
@@ -112,52 +108,42 @@ class BookingController extends AbstractController
// Create booking from request data.
$booking->setBookingTime($currentTime);
$booking->setArrivalDate($arrivalDate);
$booking->setDepartureDate($departureDate);
$booking->setArrivalDate($createRequest->arrivalDate);
$booking->setDepartureDate($createRequest->departureDate);
$booking->setBookingCustomer($createRequest->customerDetails);
//TODOME: Improve refNumber generation.
$highest_id = $entityManager->createQueryBuilder()
->select('MAX(e.id)')
->from('App\Entity\Booking', 'e')
->getQuery()
->getSingleScalarResult();
->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) {
if (\count($createRequest->rooms) == 0) {
throw new HttpException(400, "Se debe indicar al menos una habitación");
}
// Create each room.
foreach ($reqRoomList as $roomItem) {
foreach ($createRequest->rooms as $roomItem) {
$room = new BookingRoom();
$room->setBooking($booking);
//Get Room category.
$roomCategory = $repoCat->find($roomItem["roomCategory"]);
$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"];
$amountAvailable = $repoAvailability->getAvailabilityForCategoryInPeriod($roomCategory, $createRequest->arrivalDate, $createRequest->departureDate);
$selectedAmount = $roomItem->amount;
$selectedGuestAmount = $roomItem->guestNumber;
if($amountAvailable == null || $selectedAmount > $amountAvailable) {
if ($amountAvailable == null || $selectedAmount > $amountAvailable) {
throw new HttpException(400, "No se pueden reservar más habitaciones de las disponibles.");
}
@@ -166,17 +152,17 @@ class BookingController extends AbstractController
$room->setAmount($selectedAmount);
//Get Price for period.
$priceList = $priceSrv->getFinalPricesForSearch($roomCategory, $arrivalDate, $departureDate);
$priceList = $priceSrv->getFinalPricesForSearch($roomCategory, $createRequest->arrivalDate, $createRequest->departureDate);
$priceFound = false;
foreach ($priceList as $key => $value) {
if($key == $selectedGuestAmount) {
if ($key == $selectedGuestAmount) {
$room->setRoomPrice($value);
$priceFound = true;
break;
}
}
if(!$priceFound) {
if (!$priceFound) {
throw new HttpException(
500,
"No se puedo obtener el precio para la categoría: " . $roomCategory->getId() . " , guests: " . $selectedGuestAmount
@@ -186,12 +172,11 @@ class BookingController extends AbstractController
$entityManager->persist($room);
//If booking is nice, let's update current availability.
$repoAvailability->updateAvailabilityForRoomCategoryOnPeriod($roomCategory, $arrivalDate, $departureDate, $selectedAmount, true); //Update using "diff" mode.
$repoAvailability->updateAvailabilityForRoomCategoryOnPeriod($roomCategory, $createRequest->arrivalDate, $createRequest->departureDate, $selectedAmount, true); //Update using "diff" mode.
}
$entityManager->commit();
$entityManager->flush();
} catch (\Throwable $th) {
$entityManager->rollback();
throw $th;