diff --git a/sources/AppBundle/AssembleeGenerale/Entity/Repository/AssembleeGeneraleRepository.php b/sources/AppBundle/AssembleeGenerale/Entity/Repository/AssembleeGeneraleRepository.php new file mode 100644 index 000000000..e02b4bdfe --- /dev/null +++ b/sources/AppBundle/AssembleeGenerale/Entity/Repository/AssembleeGeneraleRepository.php @@ -0,0 +1,57 @@ + + */ +class AssembleeGeneraleRepository extends EntityRepository +{ + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, AssembleeGenerale::class); + } + + public function getLatestDate(): ?\DateTimeImmutable + { + $ts = $this->getEntityManager()->getConnection()->fetchOne( + 'SELECT MAX(date) FROM afup_assemblee_generale', + ); + + return $ts ? new \DateTimeImmutable('@' . $ts) : null; + } + + public function hasPlanned(?\DateTimeInterface $currentDate = null): bool + { + $currentDate ??= new \DateTime(); + $latestDate = $this->getLatestDate(); + + return null !== $latestDate + && $latestDate->getTimestamp() > strtotime('-1 day', $currentDate->getTimestamp()); + } + + public function findOneByDate(\DateTimeInterface $date): ?AssembleeGenerale + { + return $this->createQueryBuilder('ag') + ->where('ag.date = :date') + ->setParameter('date', \DateTime::createFromFormat('U', $date->format('U')), UnixTimestampType::NAME) + ->setMaxResults(1) + ->getQuery() + ->getOneOrNullResult(); + } + + public function upsert(\DateTimeInterface $date, string $description): void + { + $assemblee = $this->findOneByDate($date) ?? new AssembleeGenerale(); + $assemblee->date = \DateTime::createFromFormat('U', $date->format('U')); + $assemblee->description = $description; + $this->save($assemblee); + } +} diff --git a/sources/AppBundle/AssembleeGenerale/Entity/Repository/PresenceRepository.php b/sources/AppBundle/AssembleeGenerale/Entity/Repository/PresenceRepository.php new file mode 100644 index 000000000..209c56c7a --- /dev/null +++ b/sources/AppBundle/AssembleeGenerale/Entity/Repository/PresenceRepository.php @@ -0,0 +1,33 @@ + + */ +class PresenceRepository extends EntityRepository +{ + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, Presence::class); + } + + /** + * @return Presence[] + */ + public function getByUser(User $user): array + { + return $this->createQueryBuilder('r') + ->where('r.utilisateur = :userId') + ->setParameter('userId', $user->getId()) + ->getQuery() + ->getResult(); + } +} diff --git a/sources/AppBundle/AssembleeGenerale/Entity/Repository/QuestionRepository.php b/sources/AppBundle/AssembleeGenerale/Entity/Repository/QuestionRepository.php new file mode 100644 index 000000000..c8a4d28cb --- /dev/null +++ b/sources/AppBundle/AssembleeGenerale/Entity/Repository/QuestionRepository.php @@ -0,0 +1,72 @@ + + */ +class QuestionRepository extends EntityRepository +{ + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, Question::class); + } + + public function loadNextOpenedQuestion(\DateTimeInterface $generalMeetingDate): ?Question + { + return $this->createQueryBuilder('q') + ->where('q.dateOuverture IS NOT NULL') + ->andWhere('q.dateCloture IS NULL') + ->andWhere('q.date = :date') + ->setParameter('date', \DateTime::createFromFormat('U', $generalMeetingDate->format('U')), UnixTimestampType::NAME) + ->orderBy('q.dateOuverture', 'ASC') + ->setMaxResults(1) + ->getQuery() + ->getOneOrNullResult(); + } + + /** + * @return Question[] + */ + public function loadClosedQuestions(\DateTimeInterface $generalMeetingDate): array + { + return $this->createQueryBuilder('q') + ->where('q.dateCloture IS NOT NULL') + ->andWhere('q.date = :date') + ->setParameter('date', \DateTime::createFromFormat('U', $generalMeetingDate->format('U')), UnixTimestampType::NAME) + ->orderBy('q.dateOuverture', 'ASC') + ->getQuery() + ->getResult(); + } + + /** + * @return Question[] + */ + public function loadByDate(\DateTimeInterface $generalMeetingDate): array + { + return $this->createQueryBuilder('q') + ->where('q.date = :date') + ->setParameter('date', \DateTime::createFromFormat('U', $generalMeetingDate->format('U')), UnixTimestampType::NAME) + ->getQuery() + ->getResult(); + } + + public function open(Question $question): void + { + $question->dateOuverture = new \DateTime(); + $this->save($question); + } + + public function close(Question $question): void + { + $question->dateCloture = new \DateTime(); + $this->save($question); + } +} diff --git a/sources/AppBundle/AssembleeGenerale/Entity/Repository/VoteRepository.php b/sources/AppBundle/AssembleeGenerale/Entity/Repository/VoteRepository.php new file mode 100644 index 000000000..c571fdcf8 --- /dev/null +++ b/sources/AppBundle/AssembleeGenerale/Entity/Repository/VoteRepository.php @@ -0,0 +1,71 @@ + + */ +class VoteRepository extends EntityRepository +{ + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, Vote::class); + } + + public function buildVote(int $questionId, int $userId, int $weight, string $value): Vote + { + $vote = new Vote(); + $vote->question = $this->getEntityManager()->getReference(Question::class, $questionId); + $vote->utilisateur = $this->getEntityManager()->getReference(Utilisateur::class, $userId); + $vote->poids = $weight; + $vote->valeur = $value; + $vote->creeLe = new \DateTime(); + return $vote; + } + + public function loadByQuestionIdAndUserId(int $questionId, int $userId): ?Vote + { + return $this->createQueryBuilder('v') + ->where('v.question = :question') + ->andWhere('v.utilisateur = :user') + ->setParameter('question', $questionId) + ->setParameter('user', $userId) + ->getQuery() + ->getOneOrNullResult(); + } + + /** + * @return array + */ + public function getResultsForQuestionId(int $questionId): array + { + $results = [ + VoteValeur::Oui->value => 0, + VoteValeur::Non->value => 0, + VoteValeur::Abstention->value => 0, + ]; + + $rows = $this->getEntityManager()->getConnection()->fetchAllAssociative( + 'SELECT `value`, SUM(weight) AS weight_sum + FROM afup_vote_assemblee_generale + WHERE afup_assemblee_generale_question_id = :question_id + GROUP BY `value`', + ['question_id' => $questionId], + ); + + foreach ($rows as $row) { + $results[$row['value']] = (int) $row['weight_sum']; + } + + return $results; + } +} diff --git a/sources/AppBundle/GeneralMeeting/GeneralMeetingQuestionFormType.php b/sources/AppBundle/AssembleeGenerale/Form/GeneralMeetingQuestionFormType.php similarity index 86% rename from sources/AppBundle/GeneralMeeting/GeneralMeetingQuestionFormType.php rename to sources/AppBundle/AssembleeGenerale/Form/GeneralMeetingQuestionFormType.php index 53385c55f..8836850fd 100644 --- a/sources/AppBundle/GeneralMeeting/GeneralMeetingQuestionFormType.php +++ b/sources/AppBundle/AssembleeGenerale/Form/GeneralMeetingQuestionFormType.php @@ -2,9 +2,9 @@ declare(strict_types=1); -namespace AppBundle\GeneralMeeting; +namespace AppBundle\AssembleeGenerale\Form; -use AppBundle\Association\Model\GeneralMeetingQuestion; +use AppBundle\AssembleeGenerale\Entity\Question; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\Extension\Core\Type\TextType; @@ -31,7 +31,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefaults([ - 'data_class' => GeneralMeetingQuestion::class, + 'data_class' => Question::class, ]); } } diff --git a/sources/AppBundle/GeneralMeeting/PrepareFormType.php b/sources/AppBundle/AssembleeGenerale/Form/PrepareFormType.php similarity index 96% rename from sources/AppBundle/GeneralMeeting/PrepareFormType.php rename to sources/AppBundle/AssembleeGenerale/Form/PrepareFormType.php index 41a9af47d..fb27cb9dc 100644 --- a/sources/AppBundle/GeneralMeeting/PrepareFormType.php +++ b/sources/AppBundle/AssembleeGenerale/Form/PrepareFormType.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace AppBundle\GeneralMeeting; +namespace AppBundle\AssembleeGenerale\Form; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\DateType; diff --git a/sources/AppBundle/GeneralMeeting/ReportListBuilder.php b/sources/AppBundle/AssembleeGenerale/ReportListBuilder.php similarity index 96% rename from sources/AppBundle/GeneralMeeting/ReportListBuilder.php rename to sources/AppBundle/AssembleeGenerale/ReportListBuilder.php index 9aed1ae3c..e9cb9a16a 100644 --- a/sources/AppBundle/GeneralMeeting/ReportListBuilder.php +++ b/sources/AppBundle/AssembleeGenerale/ReportListBuilder.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace AppBundle\GeneralMeeting; +namespace AppBundle\AssembleeGenerale; use Symfony\Component\DependencyInjection\Attribute\Autowire; use Symfony\Component\Finder\Finder; diff --git a/sources/AppBundle/Association/UserMembership/BadgesComputer.php b/sources/AppBundle/Association/UserMembership/BadgesComputer.php index b9ca13cee..73232a36b 100644 --- a/sources/AppBundle/Association/UserMembership/BadgesComputer.php +++ b/sources/AppBundle/Association/UserMembership/BadgesComputer.php @@ -4,8 +4,9 @@ namespace AppBundle\Association\UserMembership; +use AppBundle\AssembleeGenerale\Entity\Repository\PresenceRepository; +use AppBundle\AssembleeGenerale\Enum\PresenceEtat; use AppBundle\Association\Model\CompanyMember; -use AppBundle\Association\Model\Repository\GeneralMeetingResponseRepository; use AppBundle\Association\Model\User; use AppBundle\Event\Model\Repository\EventRepository; use AppBundle\Event\Model\Repository\UserBadgeRepository; @@ -18,7 +19,7 @@ public function __construct( private readonly SeniorityComputer $seniorityComputer, private readonly EventRepository $eventRepository, private readonly UserBadgeRepository $userBadgeRepository, - private readonly GeneralMeetingResponseRepository $generalMeetingResponseRepository, + private readonly PresenceRepository $reponseRepository, ) {} public function getBadges(User $user): array @@ -227,16 +228,16 @@ private function getSpeakerYears(User $user): array */ private function getGeneralMeetingYears(User $user): array { - $responses = $this->generalMeetingResponseRepository->getByUser($user); + $responses = $this->reponseRepository->getByUser($user); $currentTimestamp = new \DateTime()->format('U'); $dates = []; foreach ($responses as $response) { - if (false === $response->isPresent()) { + if ($response->presence !== PresenceEtat::Present) { continue; } - $date = $response->getDate(); + $date = $response->date; if ($date->format('U') > $currentTimestamp) { continue; diff --git a/sources/AppBundle/Command/GeneralMeetupNotificationCommand.php b/sources/AppBundle/Command/GeneralMeetupNotificationCommand.php index d85592252..3e9b4384d 100644 --- a/sources/AppBundle/Command/GeneralMeetupNotificationCommand.php +++ b/sources/AppBundle/Command/GeneralMeetupNotificationCommand.php @@ -4,6 +4,7 @@ namespace AppBundle\Command; +use AppBundle\AssembleeGenerale\Entity\Repository\AssembleeGeneraleRepository; use AppBundle\Association\Model\Repository\UserRepository; use AppBundle\GeneralMeeting\GeneralMeetingRepository; use AppBundle\Notifier\SlackNotifier; @@ -17,6 +18,7 @@ class GeneralMeetupNotificationCommand extends Command { public function __construct( private readonly UserRepository $userRepository, + private readonly AssembleeGeneraleRepository $assembleGeneraleRepository, private readonly GeneralMeetingRepository $generalMeetingRepository, private readonly MessageFactory $messageFactory, private readonly SlackNotifier $slackNotifier, @@ -32,7 +34,7 @@ protected function configure(): void protected function execute(InputInterface $input, OutputInterface $output): int { - if ($this->generalMeetingRepository->hasGeneralMeetingPlanned()) { + if ($this->assembleGeneraleRepository->hasPlanned()) { $this->slackNotifier->sendMessage($this->messageFactory->createMessageForGeneralMeeting( $this->generalMeetingRepository, $this->userRepository, diff --git a/sources/AppBundle/Controller/Admin/HomeAction.php b/sources/AppBundle/Controller/Admin/HomeAction.php index f19269e45..a4660d2ae 100644 --- a/sources/AppBundle/Controller/Admin/HomeAction.php +++ b/sources/AppBundle/Controller/Admin/HomeAction.php @@ -4,7 +4,7 @@ namespace AppBundle\Controller\Admin; -use AppBundle\Veille\Entity\Repository\NewsletterInscriptionRepository; +use AppBundle\AssembleeGenerale\Entity\Repository\AssembleeGeneraleRepository; use AppBundle\Association\UserMembership\StatisticsComputer; use AppBundle\Event\Model\Event; use AppBundle\Event\Model\Repository\EventRepository; @@ -12,6 +12,7 @@ use AppBundle\Event\Model\Repository\TicketEventTypeRepository; use AppBundle\GeneralMeeting\GeneralMeetingRepository; use AppBundle\Security\Authentication; +use AppBundle\Veille\Entity\Repository\NewsletterInscriptionRepository; use Psr\Clock\ClockInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; @@ -24,6 +25,7 @@ public function __construct( private readonly EventStatsRepository $eventStatsRepository, private readonly TicketEventTypeRepository $ticketEventTypeRepository, private readonly NewsletterInscriptionRepository $newsletterInscriptionRepository, + private readonly AssembleeGeneraleRepository $assembleGeneraleRepository, private readonly GeneralMeetingRepository $generalMeetingRepository, private readonly StatisticsComputer $statisticsComputer, private readonly ClockInterface $clock, @@ -119,8 +121,8 @@ public function __invoke(): Response 'url' => $this->generateUrl('admin_members_reporting'), ]; - $latestDate = $this->generalMeetingRepository->getLatestGeneralAssemblyDate(); - if ($this->generalMeetingRepository->hasGeneralMeetingPlanned()) { + $latestDate = $this->assembleGeneraleRepository->getLatestDate(); + if ($this->assembleGeneraleRepository->hasPlanned()) { $cards[] = [ 'title' => 'Assemblée générale', 'statistics' => [ diff --git a/sources/AppBundle/Controller/Admin/Members/GeneralMeeting/EditAction.php b/sources/AppBundle/Controller/Admin/Members/GeneralMeeting/EditAction.php index a1daf4548..b84c51bd9 100644 --- a/sources/AppBundle/Controller/Admin/Members/GeneralMeeting/EditAction.php +++ b/sources/AppBundle/Controller/Admin/Members/GeneralMeeting/EditAction.php @@ -4,8 +4,8 @@ namespace AppBundle\Controller\Admin\Members\GeneralMeeting; -use AppBundle\GeneralMeeting\GeneralMeetingRepository; -use AppBundle\GeneralMeeting\PrepareFormType; +use AppBundle\AssembleeGenerale\Entity\Repository\AssembleeGeneraleRepository; +use AppBundle\AssembleeGenerale\Form\PrepareFormType; use DateTime; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Request; @@ -13,26 +13,24 @@ class EditAction extends AbstractController { - public function __construct(private readonly GeneralMeetingRepository $generalMeetingRepository) {} + public function __construct(private readonly AssembleeGeneraleRepository $assembleGeneraleRepository) {} public function __invoke(Request $request): Response { $date = new DateTime('@' . $request->query->get('date')); - $generaleMeeting = $this->generalMeetingRepository->findOneByDate($date); - if (null === $generaleMeeting) { + $assemblee = $this->assembleGeneraleRepository->findOneByDate($date); + if (null === $assemblee) { throw $this->createNotFoundException(sprintf('General meeting with date "%d" not found', $date->getTimestamp())); } - $form = $this->createForm(PrepareFormType::class, $generaleMeeting, ['without_date' => true]); + $form = $this->createForm(PrepareFormType::class, ['description' => $assemblee->description], ['without_date' => true]); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { - $data = $form->getData(); - - $this->generalMeetingRepository->save($generaleMeeting['date'], $data['description']); + $this->assembleGeneraleRepository->upsert($assemblee->date, $form->getData()['description']); $this->addFlash('success', 'Description enregistrée'); return $this->redirectToRoute('admin_members_general_meeting_edit', [ - 'date' => $date->getTimestamp(), + 'date' => $assemblee->date->getTimestamp(), ]); } diff --git a/sources/AppBundle/Controller/Admin/Members/GeneralMeeting/ListAction.php b/sources/AppBundle/Controller/Admin/Members/GeneralMeeting/ListAction.php index c46050074..a054ad443 100644 --- a/sources/AppBundle/Controller/Admin/Members/GeneralMeeting/ListAction.php +++ b/sources/AppBundle/Controller/Admin/Members/GeneralMeeting/ListAction.php @@ -30,6 +30,7 @@ public function __invoke(Request $request): Response Assert::inArray($sort, self::VALID_SORTS); Assert::inArray($direction, self::VALID_DIRECTIONS); $dates = $this->generalMeetingRepository->getAllDates(); + $convocations = count($this->userRepository->getActiveMembers()); $nbAttendeesAndPowers = $nbAttendees = $quorum = $validAttendeeIds = null; if (null !== $latestDate) { diff --git a/sources/AppBundle/Controller/Admin/Members/GeneralMeeting/PrepareAction.php b/sources/AppBundle/Controller/Admin/Members/GeneralMeeting/PrepareAction.php index 8b299e3a6..4797e69e1 100644 --- a/sources/AppBundle/Controller/Admin/Members/GeneralMeeting/PrepareAction.php +++ b/sources/AppBundle/Controller/Admin/Members/GeneralMeeting/PrepareAction.php @@ -4,9 +4,9 @@ namespace AppBundle\Controller\Admin\Members\GeneralMeeting; +use AppBundle\AssembleeGenerale\Form\PrepareFormType; use AppBundle\AuditLog\Audit; use AppBundle\GeneralMeeting\GeneralMeetingRepository; -use AppBundle\GeneralMeeting\PrepareFormType; use DateTime; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\RedirectResponse; diff --git a/sources/AppBundle/Controller/Admin/Members/GeneralMeetingQuestion/AddAction.php b/sources/AppBundle/Controller/Admin/Members/GeneralMeetingQuestion/AddAction.php index 1c08a79bb..f7b88b46e 100644 --- a/sources/AppBundle/Controller/Admin/Members/GeneralMeetingQuestion/AddAction.php +++ b/sources/AppBundle/Controller/Admin/Members/GeneralMeetingQuestion/AddAction.php @@ -4,10 +4,10 @@ namespace AppBundle\Controller\Admin\Members\GeneralMeetingQuestion; -use AppBundle\Association\Model\GeneralMeetingQuestion; -use AppBundle\Association\Model\Repository\GeneralMeetingQuestionRepository; -use AppBundle\GeneralMeeting\GeneralMeetingQuestionFormType; -use AppBundle\GeneralMeeting\GeneralMeetingRepository; +use AppBundle\AssembleeGenerale\Entity\Question; +use AppBundle\AssembleeGenerale\Entity\Repository\AssembleeGeneraleRepository; +use AppBundle\AssembleeGenerale\Entity\Repository\QuestionRepository; +use AppBundle\AssembleeGenerale\Form\GeneralMeetingQuestionFormType; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -15,30 +15,30 @@ class AddAction extends AbstractController { public function __construct( - private readonly GeneralMeetingQuestionRepository $generalMeetingQuestionRepository, - private readonly GeneralMeetingRepository $generalMeetingRepository, + private readonly QuestionRepository $questionRepository, + private readonly AssembleeGeneraleRepository $assembleGeneraleRepository, ) {} public function __invoke(Request $request, $date): Response { $date = \DateTimeImmutable::createFromFormat('U', $date); - $generalMeeting = $this->generalMeetingRepository->findOneByDate($date); + $generalMeeting = $this->assembleGeneraleRepository->findOneByDate($date); if (!$generalMeeting) { throw $this->createNotFoundException(sprintf('L\'assemblée générale en date du %s n\'a pas été trouvée', $date->format('d/m/Y'))); } - $question = new GeneralMeetingQuestion(); - $question->setDate($generalMeeting['date']); - $question->setCreatedAt(new \DateTime()); + $question = new Question(); + $question->date = $generalMeeting->date; + $question->dateCreation = new \DateTime(); $form = $this->createForm(GeneralMeetingQuestionFormType::class, $question); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { - $this->generalMeetingQuestionRepository->save($question); + $this->questionRepository->save($question); $this->addFlash('notice', 'La question a été ajoutée'); return $this->redirectToRoute('admin_members_general_vote_list', [ - 'date' => $question->getDate()->format('U'), + 'date' => $question->date->format('U'), ]); } diff --git a/sources/AppBundle/Controller/Admin/Members/GeneralMeetingQuestion/DeleteAction.php b/sources/AppBundle/Controller/Admin/Members/GeneralMeetingQuestion/DeleteAction.php index ad018ab49..32969238b 100644 --- a/sources/AppBundle/Controller/Admin/Members/GeneralMeetingQuestion/DeleteAction.php +++ b/sources/AppBundle/Controller/Admin/Members/GeneralMeetingQuestion/DeleteAction.php @@ -4,36 +4,36 @@ namespace AppBundle\Controller\Admin\Members\GeneralMeetingQuestion; -use AppBundle\Association\Model\Repository\GeneralMeetingQuestionRepository; -use AppBundle\Association\Model\Repository\GeneralMeetingVoteRepository; +use AppBundle\AssembleeGenerale\Entity\Repository\QuestionRepository; +use AppBundle\AssembleeGenerale\Entity\Repository\VoteRepository; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\RedirectResponse; class DeleteAction extends AbstractController { public function __construct( - private readonly GeneralMeetingQuestionRepository $generalMeetingQuestionRepository, - private readonly GeneralMeetingVoteRepository $generalMeetingVoteRepository, + private readonly QuestionRepository $questionRepository, + private readonly VoteRepository $voteRepository, ) {} public function __invoke($id): RedirectResponse { - $question = $this->generalMeetingQuestionRepository->get($id); + $question = $this->questionRepository->find($id); if (null === $question) { throw $this->createNotFoundException(sprintf('Question %d not found', $id)); } - $results = $this->generalMeetingVoteRepository->getResultsForQuestionId($question->getId()); + $results = $this->voteRepository->getResultsForQuestionId($question->id); if (true === $question->hasVotes($results)) { throw $this->createAccessDeniedException('Seules les questions sans vote peuvent être supprimées'); } - $this->generalMeetingQuestionRepository->delete($question); + $this->questionRepository->delete($question); $this->addFlash('notice', 'La question a été supprimée'); return $this->redirectToRoute('admin_members_general_vote_list', [ - 'date' => $question->getDate()->format('U'), + 'date' => $question->date->format('U'), ]); } } diff --git a/sources/AppBundle/Controller/Admin/Members/GeneralMeetingQuestion/EditAction.php b/sources/AppBundle/Controller/Admin/Members/GeneralMeetingQuestion/EditAction.php index 0eacf1400..0f33e7ad8 100644 --- a/sources/AppBundle/Controller/Admin/Members/GeneralMeetingQuestion/EditAction.php +++ b/sources/AppBundle/Controller/Admin/Members/GeneralMeetingQuestion/EditAction.php @@ -4,18 +4,18 @@ namespace AppBundle\Controller\Admin\Members\GeneralMeetingQuestion; -use AppBundle\Association\Model\Repository\GeneralMeetingQuestionRepository; -use AppBundle\GeneralMeeting\GeneralMeetingQuestionFormType; +use AppBundle\AssembleeGenerale\Entity\Repository\QuestionRepository; +use AppBundle\AssembleeGenerale\Form\GeneralMeetingQuestionFormType; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Request; class EditAction extends AbstractController { - public function __construct(private readonly GeneralMeetingQuestionRepository $generalMeetingQuestionRepository) {} + public function __construct(private readonly QuestionRepository $questionRepository) {} public function __invoke(Request $request, $id) { - $question = $this->generalMeetingQuestionRepository->get($id); + $question = $this->questionRepository->find($id); if (null === $question) { throw $this->createNotFoundException(sprintf('Question %d not found', $id)); @@ -28,11 +28,11 @@ public function __invoke(Request $request, $id) $form = $this->createForm(GeneralMeetingQuestionFormType::class, $question); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { - $this->generalMeetingQuestionRepository->save($question); + $this->questionRepository->save($question); $this->addFlash('notice', 'La question a été modifiée'); return $this->redirectToRoute('admin_members_general_vote_list', [ - 'date' => $question->getDate()->format('U'), + 'date' => $question->date->format('U'), ]); } diff --git a/sources/AppBundle/Controller/Admin/Members/GeneralMeetingVote/CloseAction.php b/sources/AppBundle/Controller/Admin/Members/GeneralMeetingVote/CloseAction.php index cc3db9bf5..72d7bb137 100644 --- a/sources/AppBundle/Controller/Admin/Members/GeneralMeetingVote/CloseAction.php +++ b/sources/AppBundle/Controller/Admin/Members/GeneralMeetingVote/CloseAction.php @@ -4,20 +4,20 @@ namespace AppBundle\Controller\Admin\Members\GeneralMeetingVote; -use AppBundle\Association\Model\Repository\GeneralMeetingQuestionRepository; +use AppBundle\AssembleeGenerale\Entity\Repository\QuestionRepository; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; class CloseAction extends AbstractController { - public function __construct(private readonly GeneralMeetingQuestionRepository $generalMeetingQuestionRepository) {} + public function __construct(private readonly QuestionRepository $questionRepository) {} public function __invoke(Request $request): RedirectResponse { $questionId = $request->query->getInt('id'); - $question = $this->generalMeetingQuestionRepository->get($questionId); + $question = $this->questionRepository->find($questionId); if (null === $question) { throw $this->createNotFoundException(sprintf("Question %d not found", $questionId)); @@ -27,12 +27,12 @@ public function __invoke(Request $request): RedirectResponse throw $this->createAccessDeniedException("Only questions with status opened can be opened"); } - $this->generalMeetingQuestionRepository->close($question); + $this->questionRepository->close($question); $this->addFlash('notice', 'Le vote a été fermée'); return $this->redirectToRoute('admin_members_general_vote_list', [ - 'date' => $question->getDate()->format('U'), + 'date' => $question->date->format('U'), ]); } } diff --git a/sources/AppBundle/Controller/Admin/Members/GeneralMeetingVote/ListAction.php b/sources/AppBundle/Controller/Admin/Members/GeneralMeetingVote/ListAction.php index 434cb1ce1..f972d4508 100644 --- a/sources/AppBundle/Controller/Admin/Members/GeneralMeetingVote/ListAction.php +++ b/sources/AppBundle/Controller/Admin/Members/GeneralMeetingVote/ListAction.php @@ -4,8 +4,8 @@ namespace AppBundle\Controller\Admin\Members\GeneralMeetingVote; -use AppBundle\Association\Model\Repository\GeneralMeetingQuestionRepository; -use AppBundle\Association\Model\Repository\GeneralMeetingVoteRepository; +use AppBundle\AssembleeGenerale\Entity\Repository\QuestionRepository; +use AppBundle\AssembleeGenerale\Entity\Repository\VoteRepository; use AppBundle\GeneralMeeting\GeneralMeetingRepository; use DateTimeImmutable; use Symfony\Component\HttpFoundation\Request; @@ -16,8 +16,8 @@ class ListAction { public function __construct( private readonly GeneralMeetingRepository $generalMeetingRepository, - private readonly GeneralMeetingQuestionRepository $generalMeetingQuestionRepository, - private readonly GeneralMeetingVoteRepository $generalMeetingVoteRepository, + private readonly QuestionRepository $questionRepository, + private readonly VoteRepository $voteRepository, private readonly Environment $twig, ) {} @@ -32,10 +32,10 @@ public function __invoke(Request $request): Response } $rows = []; - foreach ($this->generalMeetingQuestionRepository->loadByDate($selectedDate) as $question) { + foreach ($this->questionRepository->loadByDate($selectedDate) as $question) { $rows[] = [ 'question' => $question, - 'results' => $this->generalMeetingVoteRepository->getResultsForQuestionId($question->getId()), + 'results' => $this->voteRepository->getResultsForQuestionId($question->id), ]; } diff --git a/sources/AppBundle/Controller/Admin/Members/GeneralMeetingVote/OpenAction.php b/sources/AppBundle/Controller/Admin/Members/GeneralMeetingVote/OpenAction.php index 5ef514af9..adbd02655 100644 --- a/sources/AppBundle/Controller/Admin/Members/GeneralMeetingVote/OpenAction.php +++ b/sources/AppBundle/Controller/Admin/Members/GeneralMeetingVote/OpenAction.php @@ -4,20 +4,20 @@ namespace AppBundle\Controller\Admin\Members\GeneralMeetingVote; -use AppBundle\Association\Model\Repository\GeneralMeetingQuestionRepository; +use AppBundle\AssembleeGenerale\Entity\Repository\QuestionRepository; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; class OpenAction extends AbstractController { - public function __construct(private readonly GeneralMeetingQuestionRepository $generalMeetingQuestionRepository) {} + public function __construct(private readonly QuestionRepository $questionRepository) {} public function __invoke(Request $request): RedirectResponse { $questionId = $request->query->getInt('id'); - $question = $this->generalMeetingQuestionRepository->get($questionId); + $question = $this->questionRepository->find($questionId); if (null === $question) { throw $this->createNotFoundException(sprintf("Question %d not found", $questionId)); @@ -27,12 +27,12 @@ public function __invoke(Request $request): RedirectResponse throw $this->createAccessDeniedException("Only questions with status waiting can be opened"); } - $this->generalMeetingQuestionRepository->open($question); + $this->questionRepository->open($question); $this->addFlash('notice', 'Le vote a été ouvert'); return $this->redirectToRoute('admin_members_general_vote_list', [ - 'date' => $question->getDate()->format('U'), + 'date' => $question->date->format('U'), ]); } } diff --git a/sources/AppBundle/Controller/Website/Member/IndexAction.php b/sources/AppBundle/Controller/Website/Member/IndexAction.php index fc71ec0bc..7842ce866 100644 --- a/sources/AppBundle/Controller/Website/Member/IndexAction.php +++ b/sources/AppBundle/Controller/Website/Member/IndexAction.php @@ -5,13 +5,14 @@ namespace AppBundle\Controller\Website\Member; use AppBundle\Antennes\AntenneRepository; -use AppBundle\Association\Model\Repository\GeneralMeetingQuestionRepository; -use AppBundle\Veille\Entity\Repository\NewsletterInscriptionRepository; +use AppBundle\AssembleeGenerale\Entity\Repository\AssembleeGeneraleRepository; +use AppBundle\AssembleeGenerale\Entity\Repository\QuestionRepository; use AppBundle\Association\UserMembership\BadgesComputer; use AppBundle\Association\UserMembership\UserService; use AppBundle\GeneralMeeting\GeneralMeetingRepository; use AppBundle\MembershipFee\Model\MembershipFee; use AppBundle\Security\Authentication; +use AppBundle\Veille\Entity\Repository\NewsletterInscriptionRepository; use AppBundle\Twig\ViewRenderer; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; @@ -22,9 +23,10 @@ final class IndexAction extends AbstractController public function __construct( private readonly ViewRenderer $view, + private readonly AssembleeGeneraleRepository $assembleGeneraleRepository, private readonly GeneralMeetingRepository $generalMeetingRepository, private readonly UserService $userService, - private readonly GeneralMeetingQuestionRepository $generalMeetingQuestionRepository, + private readonly QuestionRepository $questionRepository, private readonly BadgesComputer $badgesComputer, private readonly NewsletterInscriptionRepository $newsletterInscriptionRepository, private readonly Authentication $authentication, @@ -34,7 +36,6 @@ public function __construct( public function __invoke(): Response { $user = $this->authentication->getAfupUser(); - $generalMeetingFactory = $this->generalMeetingRepository; $userService = $this->userService; $cotisation = $userService->getLastSubscription($user); @@ -45,18 +46,15 @@ public function __invoke(): Response $daysBeforeMembershipExpiration = $user->getDaysBeforeMembershipExpiration(); - $generalMeetingRepository = $this->generalMeetingRepository; - $generalMeetingQuestionRepository = $this->generalMeetingQuestionRepository; - - $latestDate = $generalMeetingRepository->getLatestGeneralAssemblyDate(); - $hasGeneralMeetingPlanned = $generalMeetingFactory->hasGeneralMeetingPlanned(); + $latestDate = $this->assembleGeneraleRepository->getLatestDate(); + $hasGeneralMeetingPlanned = $this->assembleGeneraleRepository->hasPlanned(); $displayLinkToGeneralMeetingVote = false; if ($hasGeneralMeetingPlanned && null !== $latestDate && ($latestDate->format('Y-m-d') === new \DateTime('-1 day')->format('Y-m-d')) - && count($generalMeetingQuestionRepository->loadByDate($latestDate)) > 0 + && count($this->questionRepository->loadByDate($latestDate)) > 0 ) { $displayLinkToGeneralMeetingVote = true; } @@ -69,7 +67,7 @@ public function __invoke(): Response 'has_up_to_date_membership_fee' => $user->hasUpToDateMembershipFee(), 'office_label' => $user->getNearestOfficeLabel($this->antenneRepository), 'has_general_meeting_planned' => $hasGeneralMeetingPlanned, - 'has_user_rspved_to_next_general_meeting' => $generalMeetingFactory->hasUserRspvedToLastGeneralMeeting($user), + 'has_user_rspved_to_next_general_meeting' => $this->generalMeetingRepository->hasUserRspvedToLastGeneralMeeting($user), 'membershipfee_end_date' => $dateFinCotisation, 'display_link_to_general_meeting_vote' => $displayLinkToGeneralMeetingVote, ]); diff --git a/sources/AppBundle/Controller/Website/Membership/GeneralMeeting/DownloadReportAction.php b/sources/AppBundle/Controller/Website/Membership/GeneralMeeting/DownloadReportAction.php index 146a61b04..c0a5fe277 100644 --- a/sources/AppBundle/Controller/Website/Membership/GeneralMeeting/DownloadReportAction.php +++ b/sources/AppBundle/Controller/Website/Membership/GeneralMeeting/DownloadReportAction.php @@ -4,7 +4,7 @@ namespace AppBundle\Controller\Website\Membership\GeneralMeeting; -use AppBundle\GeneralMeeting\ReportListBuilder; +use AppBundle\AssembleeGenerale\ReportListBuilder; use AppBundle\Security\Authentication; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\BinaryFileResponse; diff --git a/sources/AppBundle/Controller/Website/Membership/GeneralMeeting/IndexAction.php b/sources/AppBundle/Controller/Website/Membership/GeneralMeeting/IndexAction.php index 4aeb30d92..eb1b0f7fd 100644 --- a/sources/AppBundle/Controller/Website/Membership/GeneralMeeting/IndexAction.php +++ b/sources/AppBundle/Controller/Website/Membership/GeneralMeeting/IndexAction.php @@ -6,14 +6,15 @@ use Symfony\Component\Validator\Constraints\Callback; use Afup\Site\Droits; +use AppBundle\AssembleeGenerale\Entity\Repository\AssembleeGeneraleRepository; +use AppBundle\AssembleeGenerale\Entity\Repository\QuestionRepository; +use AppBundle\AssembleeGenerale\Entity\Repository\VoteRepository; +use AppBundle\AssembleeGenerale\ReportListBuilder; use AppBundle\Association\Model\GeneralMeetingVote; -use AppBundle\Association\Model\Repository\GeneralMeetingQuestionRepository; -use AppBundle\Association\Model\Repository\GeneralMeetingVoteRepository; use AppBundle\Association\UserMembership\UserService; use AppBundle\AuditLog\Audit; use AppBundle\GeneralMeeting\Attendee; use AppBundle\GeneralMeeting\GeneralMeetingRepository; -use AppBundle\GeneralMeeting\ReportListBuilder; use AppBundle\Security\Authentication; use AppBundle\Twig\ViewRenderer; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; @@ -29,9 +30,10 @@ final class IndexAction extends AbstractController public function __construct( private readonly ViewRenderer $view, private readonly UserService $userService, + private readonly AssembleeGeneraleRepository $assembleGeneraleRepository, private readonly GeneralMeetingRepository $generalMeetingRepository, - private readonly GeneralMeetingQuestionRepository $generalMeetingQuestionRepository, - private readonly GeneralMeetingVoteRepository $generalMeetingVoteRepository, + private readonly QuestionRepository $questionRepository, + private readonly VoteRepository $voteRepository, private readonly ReportListBuilder $reportListBuilder, private readonly Droits $droits, private readonly Audit $audit, @@ -43,10 +45,9 @@ public function __invoke(Request $request): Response $userService = $this->userService; $user = $this->authentication->getAfupUser(); $title = 'Présence prochaine AG'; - $generalMeetingRepository = $this->generalMeetingRepository; - $latestDate = $generalMeetingRepository->getLatestAttendanceDate(); + $latestDate = $this->generalMeetingRepository->getLatestAttendanceDate(); Assert::notNull($latestDate); - $generalMeetingPlanned = $generalMeetingRepository->hasGeneralMeetingPlanned(); + $generalMeetingPlanned = $this->assembleGeneraleRepository->hasPlanned(); $cotisation = $userService->getLastSubscription($user); $needsMembersheepFeePayment = $latestDate->getTimestamp() > strtotime("+14 day", $cotisation->getEndDate()->getTimestamp()); @@ -58,8 +59,8 @@ public function __invoke(Request $request): Response ]); } - $attendee = $generalMeetingRepository->getAttendee($user->getUsername(), $latestDate); - $lastGeneralMeetingDescription = $generalMeetingRepository->obtenirDescription($latestDate); + $attendee = $this->generalMeetingRepository->getAttendee($user->getUsername(), $latestDate); + $lastGeneralMeetingDescription = $this->assembleGeneraleRepository->findOneByDate($latestDate)?->description; $data = [ 'presence' => 0, @@ -92,7 +93,7 @@ public function __invoke(Request $request): Response ], ]) ->add('id_personne_avec_pouvoir', ChoiceType::class, [ - 'choices' => array_flip($generalMeetingRepository->getPowerSelectionList($latestDate, $user->getUsername())), + 'choices' => array_flip($this->generalMeetingRepository->getPowerSelectionList($latestDate, $user->getUsername())), 'label' => 'Je donne mon pouvoir à', 'required' => false, ]) @@ -106,14 +107,14 @@ public function __invoke(Request $request): Response $data = $form->getData(); if ($attendee instanceof Attendee) { - $ok = $generalMeetingRepository->editAttendee( + $ok = $this->generalMeetingRepository->editAttendee( $user->getUsername(), $latestDate, $data['presence'], (int) $data['id_personne_avec_pouvoir'], ); } else { - $ok = $generalMeetingRepository->addAttendee( + $ok = $this->generalMeetingRepository->addAttendee( $user->getId(), $latestDate, $data['presence'], @@ -130,21 +131,18 @@ public function __invoke(Request $request): Response $this->addFlash('error', 'Une erreur est survenue lors de la modification de la présence et du pouvoir'); } - $attendeesWithPower = $generalMeetingRepository->getAttendees($latestDate, 'nom', 'asc', $user->getId()); + $attendeesWithPower = $this->generalMeetingRepository->getAttendees($latestDate, 'nom', 'asc', $user->getId()); - $generalMeetingQuestionRepository = $this->generalMeetingQuestionRepository; - $generalMeetingVoteRepository = $this->generalMeetingVoteRepository; - - $currentQuestion = $generalMeetingQuestionRepository->loadNextOpenedQuestion($latestDate); + $currentQuestion = $this->questionRepository->loadNextOpenedQuestion($latestDate); $voteForCurrentQuestion = null; if (null !== $currentQuestion) { - $voteForCurrentQuestion = $generalMeetingVoteRepository->loadByQuestionIdAndUserId($currentQuestion->getId(), $this->droits->obtenirIdentifiant()); + $voteForCurrentQuestion = $this->voteRepository->loadByQuestionIdAndUserId($currentQuestion->id, $this->droits->obtenirIdentifiant()); } $questionResults = []; - foreach ($generalMeetingQuestionRepository->loadClosedQuestions($latestDate) as $question) { - $results = $generalMeetingVoteRepository->getResultsForQuestionId($question->getId()); + foreach ($this->questionRepository->loadClosedQuestions($latestDate) as $question) { + $results = $this->voteRepository->getResultsForQuestionId($question->id); $questionResults[] = [ 'question' => $question, diff --git a/sources/AppBundle/Controller/Website/Membership/GeneralMeeting/VoteAction.php b/sources/AppBundle/Controller/Website/Membership/GeneralMeeting/VoteAction.php index 0f368d355..83f8622e9 100644 --- a/sources/AppBundle/Controller/Website/Membership/GeneralMeeting/VoteAction.php +++ b/sources/AppBundle/Controller/Website/Membership/GeneralMeeting/VoteAction.php @@ -5,9 +5,9 @@ namespace AppBundle\Controller\Website\Membership\GeneralMeeting; use Afup\Site\Droits; +use AppBundle\AssembleeGenerale\Entity\Repository\QuestionRepository; +use AppBundle\AssembleeGenerale\Entity\Repository\VoteRepository; use AppBundle\Association\Model\GeneralMeetingVote; -use AppBundle\Association\Model\Repository\GeneralMeetingQuestionRepository; -use AppBundle\Association\Model\Repository\GeneralMeetingVoteRepository; use AppBundle\GeneralMeeting\GeneralMeetingRepository; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\RedirectResponse; @@ -17,8 +17,8 @@ final class VoteAction extends AbstractController { public function __construct( private readonly GeneralMeetingRepository $generalMeetingRepository, - private readonly GeneralMeetingQuestionRepository $generalMeetingQuestionRepository, - private readonly GeneralMeetingVoteRepository $generalMeetingVoteRepository, + private readonly QuestionRepository $questionRepository, + private readonly VoteRepository $voteRepository, private readonly Droits $droits, ) {} @@ -32,7 +32,7 @@ public function __invoke(Request $request): RedirectResponse throw $this->createNotFoundException('Vote manquant'); } - $question = $this->generalMeetingQuestionRepository->get($questionId); + $question = $this->questionRepository->find($questionId); if (null === $question) { throw $this->createNotFoundException('QuestionId missing'); @@ -47,23 +47,16 @@ public function __invoke(Request $request): RedirectResponse $userId = $this->droits->obtenirIdentifiant(); - if (null !== $this->generalMeetingVoteRepository->loadByQuestionIdAndUserId($questionId, $userId)) { + if (null !== $this->voteRepository->loadByQuestionIdAndUserId($question->id, $userId)) { $this->addFlash('error', 'Vous avez déjà voté pour cette question'); return $redirection; } - $weight = 1 + count($this->generalMeetingRepository->getAttendees($question->getDate(), 'nom', 'asc', $userId)); + $weight = 1 + count($this->generalMeetingRepository->getAttendees($question->date, 'nom', 'asc', $userId)); - $generalMeetingVote = new GeneralMeetingVote(); - $generalMeetingVote - ->setQuestionId($question->getId()) - ->setUserId($this->droits->obtenirIdentifiant()) - ->setWeight($weight) - ->setValue($vote) - ->setCreatedAt(new \DateTime()) - ; + $generalMeetingVote = $this->voteRepository->buildVote($question->id, $userId, $weight, $vote); - $this->generalMeetingVoteRepository->save($generalMeetingVote); + $this->voteRepository->save($generalMeetingVote); $this->addFlash('notice', 'Votre vote a été pris en compte');