<?php
namespace AF\PHDatabase\Repository;
use App\Controller\CalendarController;
use AF\PHDatabase\Entity\PriceListCommodity;
use App\Enum\PriceListPeopleEnum;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\ORM\Query\Expr\Join;
use Doctrine\Persistence\ManagerRegistry;
/**
* @method PriceListCommodity|null find($id, $lockMode = null, $lockVersion = null)
* @method PriceListCommodity|null findOneBy(array $criteria, array $orderBy = null)
* @method PriceListCommodity[] findAll()
* @method PriceListCommodity[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class PriceListCommodityRepository extends ServiceEntityRepository
{
// Po tym polu rozróżniamy, czy cennik jest dla osoby dorosłej czy dziecka
private $searchField = 'seatsNumber'; //peopleNumber
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, PriceListCommodity::class);
}
/**
* Zwraca kwoty z podanego standardu w wyznaczonym okresie czasu. Zawiera duplikaty (ten sam okres czasu).
* Kwoty są pobierane dla całego pokoju.
*
* Brak zdefiniowania daty końca oznacza, że pobiera wszystkie cenniki do końca.
*
* @param \DateTime $dateStart
* @param \DateTime|null $dateEnd
* @param int $roomStandard
* @return array
*/
public function getLowestPrice(\DateTime $dateStart, ?\DateTime $dateEnd, int $roomStandard): array
{
$parameters = [
'name' => 'www_%',
'peopleNumber' => PriceListPeopleEnum::ADULT, // Nie możemy używać cennika "Cały pokój", musimy mnożyć cenę za osobę dorosłą
'roomStandard' => $roomStandard,
'dateStart' => $dateStart->format('Y-m-d'),
];
$dateEndAvailable = false;
if ( $dateEnd !== null && $dateEnd->getTimestamp() > $dateStart->getTimestamp() ) {
$dateEndAvailable = true;
$parameters['dateEnd'] = $dateEnd->format('Y-m-d');
}
return $this->getEntityManager()
->createQuery('SELECT c, p FROM AF\PHDatabase\Entity\PriceListCommodity c
INNER JOIN c.priceList p WITH p.isAvailableForWebsite = true
WHERE p.name LIKE :name AND c.'.$this->searchField.' = :peopleNumber AND c.roomStandard = :roomStandard
AND (
(p.availableFrom >= :dateStart'.($dateEndAvailable ? ' AND p.availableUntil <= :dateEnd' : '').')
OR (p.availableFrom <= :dateStart AND p.availableUntil >= :dateStart)
'.($dateEndAvailable ? 'OR (p.availableFrom <= :dateEnd AND p.availableUntil >= :dateEnd)' : '').'
)
ORDER BY p.availableFrom, c.price')
->setParameters($parameters)
->getResult();
}
/**
* Zwraca wpis, który zawiera maksymalny dzień, do którego został wprowadzony cennik (obowiązuje do...)
*
* @param int $roomStandard
* @return int|mixed|string|null
* @throws \Doctrine\ORM\NonUniqueResultException
*/
public function getMaxDate(int $roomStandard)
{
return $this->getEntityManager()
->createQuery('SELECT c, p FROM AF\PHDatabase\Entity\PriceListCommodity c
INNER JOIN c.priceList p WITH p.isAvailableForWebsite = true
WHERE p.name LIKE :name AND c.'.$this->searchField.' = :peopleNumber AND c.roomStandard = :roomStandard
ORDER BY p.availableUntil DESC, c.price')
->setParameters([
'peopleNumber' => PriceListPeopleEnum::ADULT,
'roomStandard' => $roomStandard,
'name' => 'www_%'
])
->setMaxResults(1)
->getOneOrNullResult();
}
/**
* Zwraca cenniki do podanych standardów w określonym przedziale czasu
*
* @param string $dateStart
* @param string $dateEnd
* @param array $roomStandards
* @return array
*/
public function getPricesByStandards(string $dateStart, string $dateEnd, array $roomStandards): array
{
return $this->getEntityManager()
->createQuery('SELECT c, p FROM AF\PHDatabase\Entity\PriceListCommodity c
INNER JOIN c.priceList p WITH p.isAvailableForWebsite = true
WHERE c.roomStandard IN (:roomStandards) AND p.name LIKE :name
AND (
(p.availableFrom >= :dateStart AND p.availableUntil <= :dateEnd)
OR (p.availableFrom <= :dateStart AND p.availableUntil >= :dateStart)
OR (p.availableFrom <= :dateEnd AND p.availableUntil >= :dateEnd)
)
ORDER BY p.availableFrom, c.roomStandard, c.'.$this->searchField)
->setParameters([
'roomStandards' => $roomStandards,
'dateStart' => $dateStart,
'dateEnd' => $dateEnd,
'name' => 'www_%'
])
->getResult();
}
}