From 0d7f9afdfe1b6d19d6731f109f2c402fe4eb74a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Fromme?= Date: Fri, 3 Nov 2023 10:31:51 +0100 Subject: [PATCH] Feat: Add voter to prevent applications to fully equipped assignments --- src/Security/Voter/AssignmentVoter.php | 28 ++++++++++++++--- templates/teamer/index.html.twig | 43 +++++++++++++------------- 2 files changed, 44 insertions(+), 27 deletions(-) diff --git a/src/Security/Voter/AssignmentVoter.php b/src/Security/Voter/AssignmentVoter.php index 059323c..b28dae8 100644 --- a/src/Security/Voter/AssignmentVoter.php +++ b/src/Security/Voter/AssignmentVoter.php @@ -2,9 +2,11 @@ namespace App\Security\Voter; +use App\Entity\Application; use App\Entity\Assignment; +use App\Entity\Disposition; use App\Entity\User; -use App\Repository\ApplicationRepository; +use Doctrine\ORM\EntityManagerInterface; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Authorization\Voter\Voter; @@ -14,7 +16,7 @@ class AssignmentVoter extends Voter public const EDIT = 'EDIT'; public const APPLY = 'APPLY'; - public function __construct(private readonly ApplicationRepository $applicationRepository) + public function __construct(private readonly EntityManagerInterface $entityManager) {} protected function supports(string $attribute, mixed $subject): bool @@ -38,14 +40,30 @@ class AssignmentVoter extends Voter return true; } + /** @var Assignment $assignment */ + $assignment = $subject; + + // Only allow applications on empty slots + $availableSlots = (int) $assignment->getAvailableDispositions(); + if (0 < $availableSlots) { + $dispositions = $this + ->entityManager + ->getRepository(Disposition::class) + ->getCurrentByAssignment($assignment) + ; + + return count($dispositions) < $availableSlots; + } + // Only teamers without existing applications may apply to the assignment if (in_array('ROLE_TEAMER', $token->getRoleNames())) { /** @var User $user */ $user = $token->getUser(); $teamer = $user->getTeamer(); - /** @var Assignment $assignment */ - $assignment = $subject; - $application = $this->applicationRepository->findOneBy(['teamer' => $teamer, 'assignment' => $assignment]); + $application = $this + ->entityManager + ->getRepository(Application::class) + ->findOneBy(['teamer' => $teamer, 'assignment' => $assignment]); return null === $application; } diff --git a/templates/teamer/index.html.twig b/templates/teamer/index.html.twig index bd5aed0..c4aaecf 100644 --- a/templates/teamer/index.html.twig +++ b/templates/teamer/index.html.twig @@ -64,32 +64,31 @@ {% if assignment.applications|length %} {% set application = assignment.applications[0] %} {% if application.status == constant('App\\Entity\\Application::STATUS_REJECTED') %} - {% set icon = 'close' %} - {% set class = 'bg-gray-100 text-gray-800 hover:bg-gray-50' %} - {% set url = path('app_teamer_assignment', { 'uuid': assignment.uuid, 'r': return_url() }) %} - {% set label = 'Bewerbung abgelehnt' %} + + {{ icon('close', 'w-4 h-4 shrink-0') }} + Bewerbung abgelehnt + {% else %} - {% set icon = 'hourglass' %} - {% set class = 'bg-yellow-100 text-yellow-800 hover:bg-yellow-50' %} - {% set url = path('app_teamer_assignment', { 'uuid': assignment.uuid, 'r': return_url() }) %} - {% set label = 'in Bearbeitung' %} + + {{ icon('hourglass', 'w-4 h-4 shrink-0') }} + in Bearbeitung + {% endif %} {% elseif assignment.dispositions|length %} - {% set icon = 'check' %} - {% set class = 'bg-green-100 text-green-700 hover:bg-green-50' %} - {% set url = path('app_teamer_disposition_detail', { 'uuid': assignment.dispositions[0].uuid }) %} - {% set label = 'eingeteilt' %} - {% else %} - {% set icon = 'hand' %} - {% set class = '' %} - {% set url = path('app_teamer_assignment', { 'uuid': assignment.uuid, 'r': return_url() }) %} - {% set label = 'bewerben' %} + + {{ icon('check', 'w-4 h-4 shrink-0') }} + eingeteilt + + {% elseif is_granted('APPLY', assignment) %} + + {{ icon('hand', 'w-4 h-4 shrink-0') }} + bewerben + {% endif %} - - {{ icon(icon, 'w-4 h-4 shrink-0') }} - {{ label }} - {% set isBookmarked = teamer.bookmarks.contains(assignment) %}