<?php
namespace App\Repository\Product;
use App\Entity\Booking\Booking;
use App\Entity\Booking\Cabin;
use App\Entity\Booking\ProspectRequest;
use App\Entity\Booking\Quote;
use App\Entity\Product\MarginCabin;
use App\Entity\Product\Product;
use App\Entity\Product\ProductVariant;
use App\Repository\ApplicationFilterRepository;
use DateTime;
use DateTimeInterface;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\ORM\NonUniqueResultException;
use Doctrine\ORM\QueryBuilder;
use Doctrine\Persistence\ManagerRegistry;
use Exception;
/**
* @method MarginCabin|null find($id, $lockMode = null, $lockVersion = null)
* @method MarginCabin|null findOneBy(array $criteria, array $orderBy = null)
* @method MarginCabin[] findAll()
* @method MarginCabin[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class MarginCabinRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, MarginCabin::class);
}
/**
* @throws NonUniqueResultException
* @throws Exception
*/
public function findByProductVariantAtDate(Object $object, ProductVariant $productVariant, DateTimeInterface $date, Cabin $cabin = null): ?MarginCabin
{
$qb = $this->createQueryBuilder('mc')
->join('mc.productVariant', 'pv')
->andWhere('pv.id = :productVariantId')
->setParameter('productVariantId', $productVariant->getId());
return $this->getFinalResult($qb, $object, $date, $cabin);
}
/**
* @throws NonUniqueResultException
* @throws Exception
*/
public function findByProductAtDate(Object $object, Product $product, DateTimeInterface $date, Cabin $cabin = null): ?MarginCabin
{
$qb = $this->createQueryBuilder('mc')
->join('mc.product', 'p')
->andWhere('p.id = :productId')
->setParameter('productId', $product->getId());
return $this->getFinalResult($qb, $object, $date, $cabin);
}
/**
* @throws NonUniqueResultException
*/
public function findDefaultByProduct(Object $object, Product $product, Cabin $cabin = null): ?MarginCabin
{
$qb = $this->createQueryBuilder('mc')
->join('mc.product', 'p')
->andWhere('p.id = :productId')
->andWhere('mc.isDefault = 1')
->andWhere('mc.isArchived = 0')
->setParameter('productId', $product->getId());
return $this->getFinalResult($qb, $object, null, $cabin);
}
/**
* @throws NonUniqueResultException
* @throws Exception
*/
private function getFinalResult(QueryBuilder $qb, Object $object, DateTimeInterface $date = null, Cabin $cabin = null): ?MarginCabin
{
if ((!$object instanceof Quote && !$object instanceof Booking && !$object instanceof ProspectRequest) || ($object instanceof ProspectRequest && $object->getCruiseHistory() === null)) {
throw new Exception('Invalid argument in "'.__METHOD__.'" method from '.get_class($this).' : object have to be a Quote or a Booking.');
}
$qb = $qb->innerJoin('mc.applicationFilter', 'af');
$qb = ApplicationFilterRepository::addApplicationFilterQueryBuilderForCruiseHistory($qb, $object->getCruiseHistory(), 'af', $date);
if ($cabin !== null) {
$qb = ApplicationFilterRepository::addApplicationFilterQueryBuilderForCabin($qb, $cabin);
}
if (!$object instanceof ProspectRequest) {
$qb = ApplicationFilterRepository::addApplicationFilterQueryBuilderForObject($qb, $object);
}
return $qb->orderBy('mc.id', 'DESC')
->setMaxResults(1)
->getQuery()
->getOneOrNullResult();
}
}