From 6ca41f6b9c04d0d7a401b5ac48fc4b1bc329f364 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Fromme?= Date: Mon, 23 Sep 2024 15:38:09 +0200 Subject: [PATCH] feat: validate application date range against existing dispositions --- src/Entity/Application.php | 2 + src/Validator/Constraints/Application.php | 16 +++++ .../Constraints/ApplicationValidator.php | 65 +++++++++++++++++++ templates/forms.html.twig | 2 +- templates/teamer/application/create.html.twig | 1 + 5 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 src/Validator/Constraints/Application.php create mode 100644 src/Validator/Constraints/ApplicationValidator.php diff --git a/src/Entity/Application.php b/src/Entity/Application.php index 8805c53..a43fbaf 100644 --- a/src/Entity/Application.php +++ b/src/Entity/Application.php @@ -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; diff --git a/src/Validator/Constraints/Application.php b/src/Validator/Constraints/Application.php new file mode 100644 index 0000000..6984c0c --- /dev/null +++ b/src/Validator/Constraints/Application.php @@ -0,0 +1,16 @@ +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() + ; + } + } +} \ No newline at end of file diff --git a/templates/forms.html.twig b/templates/forms.html.twig index a541919..7f54cd3 100644 --- a/templates/forms.html.twig +++ b/templates/forms.html.twig @@ -24,7 +24,7 @@ {%- block form_errors -%} {%- if errors|length > 0 -%} -