186 lines
6.9 KiB
PHP
186 lines
6.9 KiB
PHP
<?php
|
|
|
|
namespace App\Repository;
|
|
|
|
use App\Entity\RoomAvailability;
|
|
use App\Entity\RoomCategory;
|
|
use DateInterval;
|
|
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
|
use Doctrine\Persistence\ManagerRegistry;
|
|
|
|
/**
|
|
* @extends ServiceEntityRepository<RoomAvailability>
|
|
*
|
|
* @method RoomAvailability|null find($id, $lockMode = null, $lockVersion = null)
|
|
* @method RoomAvailability|null findOneBy(array $criteria, array $orderBy = null)
|
|
* @method RoomAvailability[] findAll()
|
|
* @method RoomAvailability[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
|
|
*/
|
|
class RoomAvailabilityRepository extends ServiceEntityRepository
|
|
{
|
|
public function __construct(ManagerRegistry $registry)
|
|
{
|
|
parent::__construct($registry, RoomAvailability::class);
|
|
}
|
|
|
|
/**
|
|
* @return RoomAvailability[] Returns an array of RoomAvailability objects
|
|
*/
|
|
public function findByRoomCategory($categoryId): array
|
|
{
|
|
return $this->createQueryBuilder('a')
|
|
->andWhere('a.roomCategory = :val')
|
|
->setParameter('val', $categoryId)
|
|
->orderBy('a.day', 'ASC')
|
|
->getQuery()
|
|
->getResult();
|
|
}
|
|
|
|
/**
|
|
* @param \DateTimeInterface Period start (included in range).
|
|
* @param \DateTimeInterface Period end (not included in range).
|
|
* @return RoomAvailability[] Returns an array of RoomAvailability objects
|
|
*/
|
|
public function getAvailabilityForPeriod(\DateTimeInterface $startDate, \DateTimeInterface $endDate): array
|
|
{
|
|
$strStartDate = $startDate->format('Y-m-d');
|
|
$strEndDate = $endDate->format('Y-m-d');
|
|
|
|
return $this->createQueryBuilder('ra')
|
|
->select('IDENTITY(ra.roomCategory) as roomCategory, MIN(ra.numAvailable) as availability')
|
|
->andWhere('ra.day >= :startDate')
|
|
->andWhere('ra.day < :endDate')
|
|
->groupBy('ra.roomCategory')
|
|
->setParameter('startDate', $strStartDate)
|
|
->setParameter('endDate', $strEndDate)
|
|
->getQuery()
|
|
->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
|
|
{
|
|
$strStartDate = $startDate->format('Y-m-d');
|
|
$strEndDate = $endDate->format('Y-m-d');
|
|
|
|
return $this->createQueryBuilder('ra')
|
|
->andWhere('ra.day >= :startDate')
|
|
->andWhere('ra.day < :endDate')
|
|
->setParameter('startDate', $strStartDate)
|
|
->setParameter('endDate', $strEndDate)
|
|
->getQuery()
|
|
->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);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* For a given RoomCategory, sets its availability for all days on a period with the given amount.
|
|
*/
|
|
public function bulkEditRoomAvailabilityForCategoryOnPeriod(RoomCategory $roomCategory, \DateTimeInterface $startDate, \DateTimeInterface $endDate, int $amount, bool $useTransactions = true): void
|
|
{
|
|
$strStartDate = $startDate->format('Y-m-d');
|
|
$strEndDate = $endDate->format('Y-m-d');
|
|
$roomCatId = $roomCategory->getId();
|
|
|
|
$entityManager = $this->getEntityManager();
|
|
if ($useTransactions) {
|
|
$entityManager->beginTransaction();
|
|
}
|
|
|
|
try {
|
|
|
|
//First, delete old data.
|
|
$this->createQueryBuilder('ra')
|
|
->delete()
|
|
->andWhere('ra.day >= :startDate')
|
|
->andWhere('ra.day <= :endDate')
|
|
->andWhere('ra.roomCategory = :roomCategory')
|
|
->setParameter('roomCategory', $roomCatId)
|
|
->setParameter('startDate', $strStartDate)
|
|
->setParameter('endDate', $strEndDate)
|
|
->getQuery()
|
|
->execute();
|
|
|
|
$entityManager->flush();
|
|
|
|
// Include end date.
|
|
$endDateIncluded = date_add($endDate, new DateInterval("P1D"));
|
|
//For each day, create item and persist it.
|
|
$daterange = new \DatePeriod($startDate, new \DateInterval('P1D'), $endDateIncluded);
|
|
foreach ($daterange as $date) {
|
|
$item = new RoomAvailability();
|
|
$item->setRoomCategory($roomCategory);
|
|
$item->setDay($date);
|
|
$item->setNumAvailable($amount);
|
|
|
|
$entityManager->persist($item);
|
|
}
|
|
|
|
$entityManager->flush();
|
|
|
|
if ($useTransactions) {
|
|
$entityManager->commit();
|
|
}
|
|
} catch (\Throwable $th) {
|
|
if ($useTransactions) {
|
|
$entityManager->rollback();
|
|
}
|
|
throw $th;
|
|
}
|
|
}
|
|
}
|