forked from Somnia/SomniaRooms
Booking Creation - Finish initial implement.
- Check and update availability. - Set prices. - Generate booking refNumber.
This commit is contained in:
@@ -7,6 +7,8 @@ use App\Entity\BookingCustomer;
|
|||||||
use App\Entity\BookingRoom;
|
use App\Entity\BookingRoom;
|
||||||
use App\Repository\BookingRepository;
|
use App\Repository\BookingRepository;
|
||||||
use App\Repository\RoomCategoryRepository;
|
use App\Repository\RoomCategoryRepository;
|
||||||
|
use App\Repository\RoomAvailabilityRepository;
|
||||||
|
use App\Service\PricesService;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||||
@@ -41,13 +43,16 @@ class BookingController extends AbstractController
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[Route('/api/booking/create', name: 'app_booking_create')]
|
#[Route('/api/booking/create', name: 'app_booking_create')]
|
||||||
public function newBooking(Request $request, BookingRepository $repoBooking, EntityManagerInterface $entityManager, RoomCategoryRepository $repoCat): JsonResponse
|
public function newBooking(Request $request, BookingRepository $repoBooking, EntityManagerInterface $entityManager,
|
||||||
|
RoomCategoryRepository $repoCat, RoomAvailabilityRepository $repoAvailability,
|
||||||
|
PricesService $priceSrv): JsonResponse
|
||||||
{
|
{
|
||||||
$payload = $request->toArray();
|
$payload = $request->toArray();
|
||||||
if (\is_null($payload)) {
|
if (\is_null($payload)) {
|
||||||
throw new \Exception('Invalid Payload', 400);
|
throw new \Exception('Invalid Payload', 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$booking = new Booking();
|
$booking = new Booking();
|
||||||
try {
|
try {
|
||||||
$reqArrivalDate = $payload["arrivalDate"];
|
$reqArrivalDate = $payload["arrivalDate"];
|
||||||
@@ -65,11 +70,17 @@ class BookingController extends AbstractController
|
|||||||
$currentTime = new \DateTime();
|
$currentTime = new \DateTime();
|
||||||
|
|
||||||
// Create booking from request data.
|
// Create booking from request data.
|
||||||
//$booking = new Booking();
|
|
||||||
$booking->setBookingTime($currentTime);
|
$booking->setBookingTime($currentTime);
|
||||||
$booking->setArrivalDate($arrivalDate);
|
$booking->setArrivalDate($arrivalDate);
|
||||||
$booking->setDepartureDate($departureDate);
|
$booking->setDepartureDate($departureDate);
|
||||||
$booking->setRefNumber($currentTime->format("Y") . "001");
|
|
||||||
|
$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);
|
$entityManager->persist($booking);
|
||||||
|
|
||||||
@@ -89,6 +100,7 @@ class BookingController extends AbstractController
|
|||||||
throw new HttpException(400, "Se debe indicar al menos una habitación");
|
throw new HttpException(400, "Se debe indicar al menos una habitación");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create each room.
|
||||||
foreach ($reqRoomList as $roomItem) {
|
foreach ($reqRoomList as $roomItem) {
|
||||||
$room = new BookingRoom();
|
$room = new BookingRoom();
|
||||||
$room->setBooking($booking);
|
$room->setBooking($booking);
|
||||||
@@ -99,12 +111,39 @@ class BookingController extends AbstractController
|
|||||||
throw new HttpException(400, "La RoomCategory no es válida.");
|
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->setRoomCategory($roomCategory);
|
||||||
$room->setGuestNumber($roomItem["guestNumber"]);
|
$room->setGuestNumber($selectedGuestAmount);
|
||||||
$room->setAmount($roomItem["amount"]);
|
$room->setAmount($selectedAmount);
|
||||||
$room->setRoomPrice(5000);
|
|
||||||
|
//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: " . $roommCategory->getId() . " , guests: " . $selecctedGuestAmount);
|
||||||
|
}
|
||||||
|
|
||||||
$entityManager->persist($room);
|
$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->commit();
|
||||||
|
|||||||
@@ -57,4 +57,8 @@ class RoomAvailability
|
|||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function modNumAvailable(int $diffAmount):void {
|
||||||
|
$this->numAvailable -= $diffAmount;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
namespace App\Repository;
|
namespace App\Repository;
|
||||||
|
|
||||||
use App\Entity\RoomAvailability;
|
use App\Entity\RoomAvailability;
|
||||||
|
use App\Entity\RoomCategory;
|
||||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||||
use Doctrine\Persistence\ManagerRegistry;
|
use Doctrine\Persistence\ManagerRegistry;
|
||||||
|
|
||||||
@@ -34,7 +35,6 @@ class RoomAvailabilityRepository extends ServiceEntityRepository
|
|||||||
->getResult();
|
->getResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param \DateTimeInterface Period start (included in range).
|
* @param \DateTimeInterface Period start (included in range).
|
||||||
* @param \DateTimeInterface Period end (not included in range).
|
* @param \DateTimeInterface Period end (not included in range).
|
||||||
@@ -53,8 +53,30 @@ class RoomAvailabilityRepository extends ServiceEntityRepository
|
|||||||
->setParameter('startDate', $strStartDate)
|
->setParameter('startDate', $strStartDate)
|
||||||
->setParameter('endDate', $strEndDate)
|
->setParameter('endDate', $strEndDate)
|
||||||
->getQuery()
|
->getQuery()
|
||||||
->getArrayResult()
|
->getArrayResult();
|
||||||
;
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \DateTimeInterface Period start (included in range).
|
||||||
|
* @param \DateTimeInterface Period end (not included in range).
|
||||||
|
* @return int Returns number of available room of that category on selected period.
|
||||||
|
*/
|
||||||
|
public function getAvailabilityForCategoryInPeriod(RoomCategory $roomCategory, \DateTimeInterface $startDate, \DateTimeInterface $endDate): int|null
|
||||||
|
{
|
||||||
|
$strStartDate = $startDate->format('Y-m-d');
|
||||||
|
$strEndDate = $endDate->format('Y-m-d');
|
||||||
|
$roomCatId = $roomCategory->getId();
|
||||||
|
|
||||||
|
return $this->createQueryBuilder('ra')
|
||||||
|
->select('MIN(ra.numAvailable) as availability')
|
||||||
|
->andWhere('ra.day >= :startDate')
|
||||||
|
->andWhere('ra.day < :endDate')
|
||||||
|
->andWhere('ra.roomCategory = :roomCategory')
|
||||||
|
->setParameter('roomCategory', $roomCatId)
|
||||||
|
->setParameter('startDate', $strStartDate)
|
||||||
|
->setParameter('endDate', $strEndDate)
|
||||||
|
->getQuery()
|
||||||
|
->getSingleScalarResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getAvailabilityForPeriodDetails(\DateTimeInterface $startDate, \DateTimeInterface $endDate): array
|
public function getAvailabilityForPeriodDetails(\DateTimeInterface $startDate, \DateTimeInterface $endDate): array
|
||||||
@@ -68,7 +90,39 @@ class RoomAvailabilityRepository extends ServiceEntityRepository
|
|||||||
->setParameter('startDate', $strStartDate)
|
->setParameter('startDate', $strStartDate)
|
||||||
->setParameter('endDate', $strEndDate)
|
->setParameter('endDate', $strEndDate)
|
||||||
->getQuery()
|
->getQuery()
|
||||||
->getArrayResult()
|
->getArrayResult();
|
||||||
;
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates All Availability of selected roomCategory during period. It can operate in 2 modes, normal and diff mode.
|
||||||
|
* - Normal mode -> Sets value.
|
||||||
|
* - Diff mode -> apply value as sum ( currentAvailability += diff )
|
||||||
|
* NOTE: A Flush is needed after this operation.
|
||||||
|
*/
|
||||||
|
public function updateAvailabilityForRoomCategoryOnPeriod(RoomCategory $roomCategory, \DateTimeInterface $startDate, \DateTimeInterface $endDate, int $amount, bool $isDiff = false): void
|
||||||
|
{
|
||||||
|
$strStartDate = $startDate->format('Y-m-d');
|
||||||
|
$strEndDate = $endDate->format('Y-m-d');
|
||||||
|
$roomCatId = $roomCategory->getId();
|
||||||
|
|
||||||
|
$availabilityItemList = $this->createQueryBuilder('ra')
|
||||||
|
->andWhere('ra.day >= :startDate')
|
||||||
|
->andWhere('ra.day < :endDate')
|
||||||
|
->andWhere('ra.roomCategory = :roomCategory')
|
||||||
|
->setParameter('roomCategory', $roomCatId)
|
||||||
|
->setParameter('startDate', $strStartDate)
|
||||||
|
->setParameter('endDate', $strEndDate)
|
||||||
|
->getQuery()
|
||||||
|
->getResult();
|
||||||
|
|
||||||
|
$em = $this->getEntityManager();
|
||||||
|
|
||||||
|
foreach ($availabilityItemList as $item) {
|
||||||
|
if ($isDiff) {
|
||||||
|
$item->modNumAvailable($amount);
|
||||||
|
} else {
|
||||||
|
$item->setNumAvailable($amount);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user