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 } ] """ diff --git a/src/Controller/Api/ProfileController.php b/src/Controller/Api/ProfileController.php index fbb09d7974..d10a98ec9b 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; @@ -233,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 = []; @@ -256,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); @@ -270,8 +280,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 +298,21 @@ public function saveMyNewCommittee(Committee $committee, UserInterface $adherent ], Response::HTTP_BAD_REQUEST); } + $currentCommittee = $adherent->getCommitteeV2Membership()?->getCommittee(); + + if ( + $currentCommittee + && $voterRepository->isInVoterListForCommitteeElection( + $adherent, + $currentCommittee, + 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() ;