feat: groups price calculator admin crud, booking/offer flow and api

This commit is contained in:
Björn Fromme
2026-08-03 15:25:10 +02:00
parent eabed8295a
commit 9d2aa11fdb
258 changed files with 16231 additions and 582 deletions
@@ -0,0 +1,20 @@
<?php
declare(strict_types=1);
namespace App\Repository\Groups;
use App\Entity\Groups\AccommodationBooking;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
/**
* @extends ServiceEntityRepository<AccommodationBooking>
*/
class AccommodationBookingRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, AccommodationBooking::class);
}
}
@@ -0,0 +1,44 @@
<?php
declare(strict_types=1);
namespace App\Repository\Groups;
use App\Entity\Groups\AccommodationPrice;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
/**
* @extends ServiceEntityRepository<AccommodationPrice>
*/
class AccommodationPriceRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, AccommodationPrice::class);
}
/**
* Returns all AccommodationPrice records whose period overlaps with [dateFrom, dateTo]
* for the accommodation identified by the given hotel code.
*
* @return AccommodationPrice[]
*/
public function findByHotelCodeAndDateRange(
string $hotelCode,
\DateTimeImmutable $dateFrom,
\DateTimeImmutable $dateTo,
): array {
return $this->createQueryBuilder('ap')
->join('ap.accommodation', 'a')
->where('a.calendarCode = :hotelCode')
->andWhere('ap.dateFrom <= :dateTo')
->andWhere('ap.dateTo >= :dateFrom')
->setParameter('hotelCode', $hotelCode)
->setParameter('dateFrom', $dateFrom)
->setParameter('dateTo', $dateTo)
->orderBy('ap.dateFrom', 'ASC')
->getQuery()
->getResult();
}
}
@@ -0,0 +1,63 @@
<?php
namespace App\Repository\Groups;
use App\Entity\Groups\Accommodation;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
/**
* @extends ServiceEntityRepository<Accommodation>
*/
class AccommodationRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, Accommodation::class);
}
// /**
// * @return Accommodation[] Returns an array of Accommodation objects
// */
// public function findByExampleField($value): array
// {
// return $this->createQueryBuilder('a')
// ->andWhere('a.exampleField = :val')
// ->setParameter('val', $value)
// ->orderBy('a.id', 'ASC')
// ->setMaxResults(10)
// ->getQuery()
// ->getResult()
// ;
// }
// public function findOneBySomeField($value): ?Accommodation
// {
// return $this->createQueryBuilder('a')
// ->andWhere('a.exampleField = :val')
// ->setParameter('val', $value)
// ->getQuery()
// ->getOneOrNullResult()
// ;
// }
public function findOneByCmsCode(string $cmsCode): ?Accommodation
{
return $this->createQueryBuilder('a')
->andWhere('a.cmsCode = :cmsCode')
->setParameter('cmsCode', $cmsCode)
->getQuery()
->getOneOrNullResult()
;
}
public function findOneByCalendarCode(string $calendarCode): ?Accommodation
{
return $this->createQueryBuilder('a')
->andWhere('a.calendarCode = :calendarCode')
->setParameter('calendarCode', $calendarCode)
->getQuery()
->getOneOrNullResult()
;
}
}
@@ -0,0 +1,23 @@
<?php
declare(strict_types=1);
namespace App\Repository\Groups;
use App\Entity\Groups\AdditionalService;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
/**
* @extends ServiceEntityRepository<AdditionalService>
*/
class AdditionalServiceRepository extends ServiceEntityRepository
{
/** @use FindsByAccommodationAndDateRangeTrait<AdditionalService> */
use FindsByAccommodationAndDateRangeTrait;
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, AdditionalService::class);
}
}
@@ -0,0 +1,23 @@
<?php
declare(strict_types=1);
namespace App\Repository\Groups;
use App\Entity\Groups\BoardService;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
/**
* @extends ServiceEntityRepository<BoardService>
*/
class BoardServiceRepository extends ServiceEntityRepository
{
/** @use FindsByAccommodationAndDateRangeTrait<BoardService> */
use FindsByAccommodationAndDateRangeTrait;
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, BoardService::class);
}
}
@@ -0,0 +1,41 @@
<?php
declare(strict_types=1);
namespace App\Repository\Groups;
use App\Entity\Groups\Accommodation;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
/**
* @template T of object
*
* @phpstan-require-extends ServiceEntityRepository<T>
*/
trait FindsByAccommodationAndDateRangeTrait
{
/**
* Returns all records active during the given date range.
*
* Overlap condition: entity.dateFrom <= dateTo AND entity.dateTo >= dateFrom
*
* @return array<int, T>
*/
public function findByAccommodationAndDateRange(
Accommodation $accommodation,
\DateTimeImmutable $dateFrom,
\DateTimeImmutable $dateTo,
): array {
return $this->createQueryBuilder('s')
->where('s.accommodation = :accommodation')
->andWhere('s.dateFrom <= :dateTo')
->andWhere('s.dateTo >= :dateFrom')
->setParameter('accommodation', $accommodation)
->setParameter('dateFrom', $dateFrom)
->setParameter('dateTo', $dateTo)
->orderBy('s.dateFrom', 'ASC')
->addOrderBy('s.label', 'ASC')
->getQuery()
->getResult();
}
}