From dff62f8f2dbe5db8017bbc038cd1cdfc611bc3f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Gardien?= Date: Tue, 5 Nov 2024 14:10:47 +0100 Subject: [PATCH 1/4] Adherent can not change repository if in recent election --- src/Controller/Api/ProfileController.php | 21 +++++++- .../VotingPlatform/VoterRepository.php | 49 +++++++++++++------ 2 files changed, 54 insertions(+), 16 deletions(-) diff --git a/src/Controller/Api/ProfileController.php b/src/Controller/Api/ProfileController.php index fbb09d7974..1682ea7738 100644 --- a/src/Controller/Api/ProfileController.php +++ b/src/Controller/Api/ProfileController.php @@ -24,6 +24,7 @@ use App\Repository\CommitteeRepository; use App\Repository\DonationRepository; use App\Repository\TaxReceiptRepository; +use App\Repository\VotingPlatform\VoterRepository; use App\Utils\HttpUtils; use Doctrine\ORM\EntityManagerInterface; use League\Flysystem\FilesystemOperator; @@ -270,8 +271,12 @@ public function myInstances(UserInterface $adherent, CommitteeRepository $commit #[Route(path: '/committees/{uuid}/join', methods: ['PUT'])] #[Security('is_granted("ROLE_OAUTH_SCOPE_WRITE:PROFILE") and user.isRenaissanceAdherent()')] - public function saveMyNewCommittee(Committee $committee, UserInterface $adherent, CommitteeMembershipManager $committeeMembershipManager): Response - { + public function saveMyNewCommittee( + Committee $committee, + UserInterface $adherent, + CommitteeMembershipManager $committeeMembershipManager, + VoterRepository $voterRepository, + ): Response { /** @var Adherent $adherent */ if ( !array_intersect( @@ -284,6 +289,18 @@ public function saveMyNewCommittee(Committee $committee, UserInterface $adherent ], Response::HTTP_BAD_REQUEST); } + if ( + $voterRepository->isInVoterListForCommitteeElection( + $adherent, + $committee, + new \DateTime('-3 months') + ) + ) { + return $this->json([ + 'message' => 'Vous avez participé à une élection interne il y a moins de 3 mois dans votre comité. Il ne vous est pas possible d\'en changer.', + ], Response::HTTP_BAD_REQUEST); + } + $committeeMembershipManager->followCommittee( $adherent, $committee, diff --git a/src/Repository/VotingPlatform/VoterRepository.php b/src/Repository/VotingPlatform/VoterRepository.php index 2b2f4b4115..12136628eb 100644 --- a/src/Repository/VotingPlatform/VoterRepository.php +++ b/src/Repository/VotingPlatform/VoterRepository.php @@ -3,6 +3,7 @@ namespace App\Repository\VotingPlatform; use App\Entity\Adherent; +use App\Entity\Committee; use App\Entity\VotingPlatform\Election; use App\Entity\VotingPlatform\ElectionRound; use App\Entity\VotingPlatform\Vote; @@ -171,20 +172,40 @@ public function findVotedForElection(Election $election): array ; } - public function isInVoterListForCommitteeElection(Adherent $adherent): bool - { - return 0 < (int) $this->createQueryBuilder('voter') - ->select('COUNT(1)') - ->innerJoin('voter.votersLists', 'list') - ->innerJoin('list.election', 'election') - ->innerJoin('election.designation', 'designation', Join::WITH, 'designation.type = :designation_type') - ->innerJoin('election.electionEntity', 'election_entity') - ->innerJoin('election_entity.committee', 'committee', Join::WITH, 'committee.version = 2') - ->where('voter.adherent = :adherent') - ->setParameters([ - 'adherent' => $adherent, - 'designation_type' => DesignationTypeEnum::COMMITTEE_SUPERVISOR, - ]) + public function isInVoterListForCommitteeElection( + Adherent $adherent, + ?Committee $committee = null, + ?\DateTimeInterface $after = null, + ): bool { + $qb = $this->createQueryBuilder('voter') + ->select('COUNT(1)') + ->innerJoin('voter.votersLists', 'list') + ->innerJoin('list.election', 'election') + ->innerJoin('election.designation', 'designation', Join::WITH, 'designation.type = :designation_type') + ->innerJoin('election.electionEntity', 'election_entity') + ->innerJoin('election_entity.committee', 'committee', Join::WITH, 'committee.version = 2') + ->where('voter.adherent = :adherent') + ->setParameters([ + 'adherent' => $adherent, + 'designation_type' => DesignationTypeEnum::COMMITTEE_SUPERVISOR, + ]) + ; + + if ($committee) { + $qb + ->andWhere('committee = :committee') + ->setParameter('committee', $committee) + ; + } + + if ($after) { + $qb + ->andWhere('designation.voteEndDate >= :after') + ->setParameter('after', $after) + ; + } + + return 0 < (int) $qb ->getQuery() ->getSingleScalarResult() ; From a17280059d8cd742379eb386f4975c874572c081 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Gardien?= Date: Tue, 5 Nov 2024 14:29:37 +0100 Subject: [PATCH 2/4] Check current committee --- src/Controller/Api/ProfileController.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Controller/Api/ProfileController.php b/src/Controller/Api/ProfileController.php index 1682ea7738..63a48d63e2 100644 --- a/src/Controller/Api/ProfileController.php +++ b/src/Controller/Api/ProfileController.php @@ -289,10 +289,13 @@ public function saveMyNewCommittee( ], Response::HTTP_BAD_REQUEST); } + $currentCommittee = $adherent->getCommitteeV2Membership()?->getCommittee(); + if ( - $voterRepository->isInVoterListForCommitteeElection( + $currentCommittee + && $voterRepository->isInVoterListForCommitteeElection( $adherent, - $committee, + $currentCommittee, new \DateTime('-3 months') ) ) { From 00444d88eafbfe7ef7f28f61714aadf201fb693a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Gardien?= Date: Tue, 5 Nov 2024 14:44:11 +0100 Subject: [PATCH 3/4] Display information to user --- src/Controller/Api/ProfileController.php | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/Controller/Api/ProfileController.php b/src/Controller/Api/ProfileController.php index 63a48d63e2..d10a98ec9b 100644 --- a/src/Controller/Api/ProfileController.php +++ b/src/Controller/Api/ProfileController.php @@ -234,7 +234,7 @@ public function showCommitteesOfMyZone(UserInterface $adherent, CommitteeReposit #[IsGranted('ROLE_OAUTH_SCOPE_READ:PROFILE')] #[Route(path: '/instances', methods: ['GET'])] - public function myInstances(UserInterface $adherent, CommitteeRepository $committeeRepository): Response + public function myInstances(UserInterface $adherent, CommitteeRepository $committeeRepository, VoterRepository $voterRepository): Response { $instance = []; @@ -257,13 +257,22 @@ public function myInstances(UserInterface $adherent, CommitteeRepository $commit ]; } - $myCommitteeMembership = $adherent->getCommitteeV2Membership(); + $currentCommittee = $adherent->getCommitteeV2Membership()?->getCommittee(); + + $recentElectionParticipation = $currentCommittee && $voterRepository->isInVoterListForCommitteeElection( + $adherent, + $currentCommittee, + new \DateTime('-3 months') + ); + $instance[] = [ 'type' => 'committee', - 'uuid' => $myCommitteeMembership?->getCommittee()->getUuid(), - 'name' => $myCommitteeMembership?->getCommittee()->getName(), - 'members_count' => $myCommitteeMembership?->getCommittee()->getMembersCount(), + 'uuid' => $currentCommittee?->getUuid(), + 'name' => $currentCommittee?->getName(), + 'members_count' => $currentCommittee?->getMembersCount(), 'assembly_committees_count' => \count($committeeRepository->findInAdherentZone($adherent)), + 'can_change_committee' => !$recentElectionParticipation, + 'message' => $recentElectionParticipation ? 'Vous avez participé à une élection interne il y a moins de 3 mois dans votre comité. Il ne vous est pas possible d\'en changer.' : null, ]; return $this->json($instance); From 4a4a1e0dd8deb50ceb60ec239ce7e962f964dcdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Gardien?= Date: Tue, 5 Nov 2024 15:55:16 +0100 Subject: [PATCH 4/4] Adjust tests --- features/api/profile.feature | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/features/api/profile.feature b/features/api/profile.feature index b76c644b9f..8019197c4c 100644 --- a/features/api/profile.feature +++ b/features/api/profile.feature @@ -1734,7 +1734,9 @@ Feature: "uuid": null, "name": null, "members_count": null, - "assembly_committees_count": 0 + "assembly_committees_count": 0, + "can_change_committee": true, + "message": null } ] """ @@ -1758,7 +1760,9 @@ Feature: "uuid": "@uuid@", "name": "Second Comité des 3 communes", "members_count": 3, - "assembly_committees_count": 2 + "assembly_committees_count": 2, + "can_change_committee": true, + "message": null } ] """