diff --git a/migrations/Version20251215135758.php b/migrations/Version20251215135758.php new file mode 100644 index 0000000..ec7d206 --- /dev/null +++ b/migrations/Version20251215135758.php @@ -0,0 +1,31 @@ +addSql('ALTER TABLE teamer ADD allow_overlapping_applications TINYINT(1) NOT NULL DEFAULT 0'); + } + + public function postUp(Schema $schema): void + { + $this->connection->executeStatement('UPDATE teamer SET allow_overlapping_applications = 0'); + } + + public function down(Schema $schema): void + { + $this->addSql('ALTER TABLE teamer DROP allow_overlapping_applications'); + } +} diff --git a/src/Controller/Admin/Teamer/SkillsController.php b/src/Controller/Admin/Teamer/SkillsController.php index c57bb94..1fbe788 100644 --- a/src/Controller/Admin/Teamer/SkillsController.php +++ b/src/Controller/Admin/Teamer/SkillsController.php @@ -7,6 +7,7 @@ use App\Repository\TrainingRepository; use Doctrine\ORM\EntityManagerInterface; use Psr\Log\LoggerInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; +use Symfony\Component\Form\Extension\Core\Type\CheckboxType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\FormInterface; use Symfony\Component\HttpFoundation\Request; @@ -64,6 +65,10 @@ class SkillsController extends AbstractController 'Bestandsteamer' => Teamer::STATUS_EXISTING, ], ]) + ->add('allowOverlappingApplications', CheckboxType::class, [ + 'label' => 'Überlappende Bewerbungen erlauben', + 'required' => false, + ]) ->getForm(); } } diff --git a/src/Entity/Teamer.php b/src/Entity/Teamer.php index e3fa4f2..f233d01 100644 --- a/src/Entity/Teamer.php +++ b/src/Entity/Teamer.php @@ -137,6 +137,9 @@ class Teamer implements TimestampableEntityInterface #[ORM\Column] private bool $viewed = false; + #[ORM\Column] + private bool $allowOverlappingApplications = false; + public function __construct() { $this->uuid = Uuid::v4(); @@ -797,4 +800,16 @@ class Teamer implements TimestampableEntityInterface return $this; } + + public function isAllowOverlappingApplications(): bool + { + return $this->allowOverlappingApplications; + } + + public function setAllowOverlappingApplications(bool $allowOverlappingApplications): static + { + $this->allowOverlappingApplications = $allowOverlappingApplications; + + return $this; + } } diff --git a/src/EventListener/InvalidateApplicationsListener.php b/src/EventListener/InvalidateApplicationsListener.php index a317191..47bb331 100644 --- a/src/EventListener/InvalidateApplicationsListener.php +++ b/src/EventListener/InvalidateApplicationsListener.php @@ -27,8 +27,13 @@ class InvalidateApplicationsListener } $disposition = $document->getDisposition(); - $assignment = $disposition->getAssignment(); $teamer = $disposition->getTeamer(); + + if (true === $teamer->isAllowOverlappingApplications()) { + return; + } + + $assignment = $disposition->getAssignment(); $period = $assignment->getEffectivePeriod(); // Find other applications by this teamer with overlapping date ranges diff --git a/src/Validator/Constraints/ApplicationValidator.php b/src/Validator/Constraints/ApplicationValidator.php index 6091d95..c359757 100644 --- a/src/Validator/Constraints/ApplicationValidator.php +++ b/src/Validator/Constraints/ApplicationValidator.php @@ -19,6 +19,10 @@ class ApplicationValidator extends ConstraintValidator $teamer = $application->getTeamer(); + if (true === $teamer->isAllowOverlappingApplications()) { + return; + } + $assignment = $application->getAssignment(); $destination = $assignment->getDestination(); diff --git a/templates/admin/teamer/skills.html.twig b/templates/admin/teamer/skills.html.twig index a6d68d0..6184939 100644 --- a/templates/admin/teamer/skills.html.twig +++ b/templates/admin/teamer/skills.html.twig @@ -17,12 +17,15 @@