feat: validate application date range against existing dispositions

This commit is contained in:
Björn Fromme
2024-09-23 15:38:09 +02:00
parent 7d816d36ec
commit 6ca41f6b9c
5 changed files with 85 additions and 1 deletions
+2
View File
@@ -4,11 +4,13 @@ namespace App\Entity;
use App\Entity\Traits\TimestampableEntity;
use App\Repository\ApplicationRepository;
use App\Validator\Constraints as AppAssert;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Uid\Uuid;
#[ORM\Entity(repositoryClass: ApplicationRepository::class)]
#[AppAssert\Application]
class Application implements TimestampableEntityInterface
{
use TimestampableEntity;
+16
View File
@@ -0,0 +1,16 @@
<?php
namespace App\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
#[\Attribute]
class Application extends Constraint
{
public string $message = 'Diese Bewerbung überlappt sich mit einem deiner bestätigten Einsätze';
public function getTargets(): array|string
{
return static::CLASS_CONSTRAINT;
}
}
@@ -0,0 +1,65 @@
<?php
namespace App\Validator\Constraints;
use App\Repository\DispositionRepository;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
class ApplicationValidator extends ConstraintValidator
{
public function __construct(private readonly DispositionRepository $dispositionRepository)
{
}
public function validate(mixed $value, Constraint $constraint): void
{
/** @var \App\Entity\Application $application */
$application = $value;
$teamer = $application->getTeamer();
$assignment = $application->getAssignment();
$destination = $assignment->getDestination();
$applicationDateFrom = $destination->getDateFrom();
$applicationDateTo = $destination->getDateTo();
$qb = $this
->dispositionRepository
->createQueryBuilder('disposition')
;
$conflictingCount = $qb
->select($qb->expr()->count('disposition'))
->innerJoin('disposition.assignment', 'assignment')
->innerJoin('assignment.destination', 'destination')
->where($qb->expr()->andX(
$qb->expr()->eq('disposition.teamer', ':teamer'),
$qb->expr()->orX(
$qb->expr()->andX(
$qb->expr()->gt('destination.dateTo', ':application_date_from'),
$qb->expr()->lt('destination.dateTo', ':application_date_to'),
),
$qb->expr()->andX(
$qb->expr()->lt('destination.dateFrom', ':application_date_to'),
$qb->expr()->gt('destination.dateFrom', ':application_date_from'),
)
)
))
->setParameter('teamer', $teamer)
->setParameter('application_date_from', $applicationDateFrom)
->setParameter('application_date_to', $applicationDateTo)
->getQuery()
->getSingleScalarResult()
;
if (0 < $conflictingCount) {
$this
->context
->buildViolation($constraint->message)
->addViolation()
;
}
}
}