diff --git a/phpstan-baseline.php b/phpstan-baseline.php index 0f31c6fc4..a9bbdcfeb 100644 --- a/phpstan-baseline.php +++ b/phpstan-baseline.php @@ -2920,23 +2920,17 @@ $ignoreErrors[] = [ 'message' => '#^Argument of an invalid type mixed supplied for foreach, only iterables are supported\\.$#', 'identifier' => 'foreach.nonIterable', - 'count' => 4, + 'count' => 3, 'path' => __DIR__ . '/sources/AppBundle/Association/UserMembership/BadgesComputer.php', ]; $ignoreErrors[] = [ 'message' => '#^Binary operation "\\." between \'Participation à l…\' and mixed results in an error\\.$#', 'identifier' => 'binaryOp.invalid', - 'count' => 2, - 'path' => __DIR__ . '/sources/AppBundle/Association/UserMembership/BadgesComputer.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Binary operation "\\." between \'Speaker de l\\\\\'année \' and mixed results in an error\\.$#', - 'identifier' => 'binaryOp.invalid', 'count' => 1, 'path' => __DIR__ . '/sources/AppBundle/Association/UserMembership/BadgesComputer.php', ]; $ignoreErrors[] = [ - 'message' => '#^Binary operation "\\." between \'ag\\-\' and mixed results in an error\\.$#', + 'message' => '#^Binary operation "\\." between \'Speaker de l\\\\\'année \' and mixed results in an error\\.$#', 'identifier' => 'binaryOp.invalid', 'count' => 1, 'path' => __DIR__ . '/sources/AppBundle/Association/UserMembership/BadgesComputer.php', @@ -2980,7 +2974,7 @@ $ignoreErrors[] = [ 'message' => '#^Cannot call method format\\(\\) on mixed\\.$#', 'identifier' => 'method.nonObject', - 'count' => 7, + 'count' => 3, 'path' => __DIR__ . '/sources/AppBundle/Association/UserMembership/BadgesComputer.php', ]; $ignoreErrors[] = [ @@ -2989,12 +2983,6 @@ 'count' => 2, 'path' => __DIR__ . '/sources/AppBundle/Association/UserMembership/BadgesComputer.php', ]; -$ignoreErrors[] = [ - 'message' => '#^Cannot call method getDate\\(\\) on mixed\\.$#', - 'identifier' => 'method.nonObject', - 'count' => 1, - 'path' => __DIR__ . '/sources/AppBundle/Association/UserMembership/BadgesComputer.php', -]; $ignoreErrors[] = [ 'message' => '#^Cannot call method getDateStart\\(\\) on mixed\\.$#', 'identifier' => 'method.nonObject', @@ -3031,12 +3019,6 @@ 'count' => 1, 'path' => __DIR__ . '/sources/AppBundle/Association/UserMembership/BadgesComputer.php', ]; -$ignoreErrors[] = [ - 'message' => '#^Cannot call method isPresent\\(\\) on mixed\\.$#', - 'identifier' => 'method.nonObject', - 'count' => 1, - 'path' => __DIR__ . '/sources/AppBundle/Association/UserMembership/BadgesComputer.php', -]; $ignoreErrors[] = [ 'message' => '#^Cannot cast mixed to string\\.$#', 'identifier' => 'cast.string', @@ -4951,24 +4933,6 @@ 'count' => 1, 'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Members/CompanyListAction.php', ]; -$ignoreErrors[] = [ - 'message' => '#^Cannot access offset \'description\' on mixed\\.$#', - 'identifier' => 'offsetAccess.nonOffsetAccessible', - 'count' => 1, - 'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Members/GeneralMeeting/EditAction.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Parameter \\#1 \\$date of method AppBundle\\\\GeneralMeeting\\\\GeneralMeetingRepository\\:\\:save\\(\\) expects DateTimeInterface, mixed given\\.$#', - 'identifier' => 'argument.type', - 'count' => 1, - 'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Members/GeneralMeeting/EditAction.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Parameter \\#2 \\$description of method AppBundle\\\\GeneralMeeting\\\\GeneralMeetingRepository\\:\\:save\\(\\) expects string, mixed given\\.$#', - 'identifier' => 'argument.type', - 'count' => 1, - 'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Members/GeneralMeeting/EditAction.php', -]; $ignoreErrors[] = [ 'message' => '#^Parameter \\#2 \\$datetime of static method DateTimeImmutable\\:\\:createFromFormat\\(\\) expects string, mixed given\\.$#', 'identifier' => 'argument.type', @@ -4987,18 +4951,6 @@ 'count' => 1, 'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Members/GeneralMeeting/ListingAction.php', ]; -$ignoreErrors[] = [ - 'message' => '#^Cannot access offset \'date\' on mixed\\.$#', - 'identifier' => 'offsetAccess.nonOffsetAccessible', - 'count' => 1, - 'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Members/GeneralMeeting/PrepareAction.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Cannot access offset \'description\' on mixed\\.$#', - 'identifier' => 'offsetAccess.nonOffsetAccessible', - 'count' => 1, - 'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Members/GeneralMeeting/PrepareAction.php', -]; $ignoreErrors[] = [ 'message' => '#^Parameter \\#1 \\$date of method AppBundle\\\\GeneralMeeting\\\\GeneralMeetingRepository\\:\\:prepare\\(\\) expects DateTimeInterface, mixed given\\.$#', 'identifier' => 'argument.type', @@ -5071,108 +5023,12 @@ 'count' => 2, 'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Members/GeneralMeeting/ReportsAction.php', ]; -$ignoreErrors[] = [ - 'message' => '#^Cannot call method format\\(\\) on DateTimeImmutable\\|false\\.$#', - 'identifier' => 'method.nonObject', - 'count' => 1, - 'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Members/GeneralMeetingQuestion/AddAction.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Cannot call method format\\(\\) on DateTimeInterface\\|null\\.$#', - 'identifier' => 'method.nonObject', - 'count' => 1, - 'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Members/GeneralMeetingQuestion/AddAction.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method AppBundle\\\\Controller\\\\Admin\\\\Members\\\\GeneralMeetingQuestion\\\\AddAction\\:\\:__invoke\\(\\) has parameter \\$date with no type specified\\.$#', - 'identifier' => 'missingType.parameter', - 'count' => 1, - 'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Members/GeneralMeetingQuestion/AddAction.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Parameter \\#1 \\$date of method AppBundle\\\\Association\\\\Model\\\\GeneralMeetingQuestion\\:\\:setDate\\(\\) expects DateTimeInterface, mixed given\\.$#', - 'identifier' => 'argument.type', - 'count' => 1, - 'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Members/GeneralMeetingQuestion/AddAction.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Parameter \\#1 \\$date of method AppBundle\\\\GeneralMeeting\\\\GeneralMeetingRepository\\:\\:findOneByDate\\(\\) expects DateTimeInterface, DateTimeImmutable\\|false given\\.$#', - 'identifier' => 'argument.type', - 'count' => 1, - 'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Members/GeneralMeetingQuestion/AddAction.php', -]; $ignoreErrors[] = [ 'message' => '#^Parameter \\#2 \\$datetime of static method DateTimeImmutable\\:\\:createFromFormat\\(\\) expects string, mixed given\\.$#', 'identifier' => 'argument.type', 'count' => 1, - 'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Members/GeneralMeetingQuestion/AddAction.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Cannot call method format\\(\\) on DateTimeInterface\\|null\\.$#', - 'identifier' => 'method.nonObject', - 'count' => 1, - 'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Members/GeneralMeetingQuestion/DeleteAction.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method AppBundle\\\\Controller\\\\Admin\\\\Members\\\\GeneralMeetingQuestion\\\\DeleteAction\\:\\:__invoke\\(\\) has parameter \\$id with no type specified\\.$#', - 'identifier' => 'missingType.parameter', - 'count' => 1, - 'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Members/GeneralMeetingQuestion/DeleteAction.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Parameter \\#2 \\.\\.\\.\\$values of function sprintf expects bool\\|float\\|int\\|string\\|null, mixed given\\.$#', - 'identifier' => 'argument.type', - 'count' => 1, - 'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Members/GeneralMeetingQuestion/DeleteAction.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Cannot call method format\\(\\) on DateTimeInterface\\|null\\.$#', - 'identifier' => 'method.nonObject', - 'count' => 1, - 'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Members/GeneralMeetingQuestion/EditAction.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method AppBundle\\\\Controller\\\\Admin\\\\Members\\\\GeneralMeetingQuestion\\\\EditAction\\:\\:__invoke\\(\\) has no return type specified\\.$#', - 'identifier' => 'missingType.return', - 'count' => 1, - 'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Members/GeneralMeetingQuestion/EditAction.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method AppBundle\\\\Controller\\\\Admin\\\\Members\\\\GeneralMeetingQuestion\\\\EditAction\\:\\:__invoke\\(\\) has parameter \\$id with no type specified\\.$#', - 'identifier' => 'missingType.parameter', - 'count' => 1, - 'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Members/GeneralMeetingQuestion/EditAction.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Parameter \\#2 \\.\\.\\.\\$values of function sprintf expects bool\\|float\\|int\\|string\\|null, mixed given\\.$#', - 'identifier' => 'argument.type', - 'count' => 1, - 'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Members/GeneralMeetingQuestion/EditAction.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Cannot call method format\\(\\) on DateTimeInterface\\|null\\.$#', - 'identifier' => 'method.nonObject', - 'count' => 1, - 'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Members/GeneralMeetingVote/CloseAction.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Parameter \\#1 \\$generalMeetingDate of method AppBundle\\\\Association\\\\Model\\\\Repository\\\\GeneralMeetingQuestionRepository\\:\\:loadByDate\\(\\) expects DateTimeInterface, DateTimeImmutable\\|null given\\.$#', - 'identifier' => 'argument.type', - 'count' => 1, 'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Members/GeneralMeetingVote/ListAction.php', ]; -$ignoreErrors[] = [ - 'message' => '#^Parameter \\#2 \\$datetime of static method DateTimeImmutable\\:\\:createFromFormat\\(\\) expects string, mixed given\\.$#', - 'identifier' => 'argument.type', - 'count' => 1, - 'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Members/GeneralMeetingVote/ListAction.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Cannot call method format\\(\\) on DateTimeInterface\\|null\\.$#', - 'identifier' => 'method.nonObject', - 'count' => 1, - 'path' => __DIR__ . '/sources/AppBundle/Controller/Admin/Members/GeneralMeetingVote/OpenAction.php', -]; $ignoreErrors[] = [ 'message' => '#^Parameter \\#1 \\$entity of method CCMBenchmark\\\\Ting\\\\Repository\\\\Repository\\\\:\\:delete\\(\\) expects AppBundle\\\\Event\\\\Model\\\\UserBadge, AppBundle\\\\Event\\\\Model\\\\UserBadge\\|null given\\.$#', 'identifier' => 'argument.type', @@ -6493,12 +6349,6 @@ 'count' => 1, 'path' => __DIR__ . '/sources/AppBundle/Controller/Website/Member/CompanyPublicProfileAction.php', ]; -$ignoreErrors[] = [ - 'message' => '#^Parameter \\#1 \\$value of function count expects array\\|Countable, iterable\\ given\\.$#', - 'identifier' => 'argument.type', - 'count' => 1, - 'path' => __DIR__ . '/sources/AppBundle/Controller/Website/Member/IndexAction.php', -]; $ignoreErrors[] = [ 'message' => '#^Binary operation "\\+" between int\\<0, max\\> and mixed results in an error\\.$#', 'identifier' => 'binaryOp.invalid', @@ -6655,12 +6505,6 @@ 'count' => 1, 'path' => __DIR__ . '/sources/AppBundle/Controller/Website/Membership/GeneralMeeting/IndexAction.php', ]; -$ignoreErrors[] = [ - 'message' => '#^Cannot call method getId\\(\\) on mixed\\.$#', - 'identifier' => 'method.nonObject', - 'count' => 1, - 'path' => __DIR__ . '/sources/AppBundle/Controller/Website/Membership/GeneralMeeting/IndexAction.php', -]; $ignoreErrors[] = [ 'message' => '#^Cannot call method getTimestamp\\(\\) on DateTime\\|null\\.$#', 'identifier' => 'method.nonObject', @@ -6685,18 +6529,6 @@ 'count' => 1, 'path' => __DIR__ . '/sources/AppBundle/Controller/Website/Membership/GeneralMeeting/IndexAction.php', ]; -$ignoreErrors[] = [ - 'message' => '#^Parameter \\#1 \\$date of method AppBundle\\\\GeneralMeeting\\\\GeneralMeetingRepository\\:\\:getAttendees\\(\\) expects DateTimeInterface, DateTimeInterface\\|null given\\.$#', - 'identifier' => 'argument.type', - 'count' => 1, - 'path' => __DIR__ . '/sources/AppBundle/Controller/Website/Membership/GeneralMeeting/VoteAction.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Parameter \\#1 \\$userId of method AppBundle\\\\Association\\\\Model\\\\GeneralMeetingVote\\:\\:setUserId\\(\\) expects int, int\\|null given\\.$#', - 'identifier' => 'argument.type', - 'count' => 1, - 'path' => __DIR__ . '/sources/AppBundle/Controller/Website/Membership/GeneralMeeting/VoteAction.php', -]; $ignoreErrors[] = [ 'message' => '#^Parameter \\#1 \\$content of class Symfony\\\\Component\\\\HttpFoundation\\\\Response constructor expects string\\|null, string\\|false given\\.$#', 'identifier' => 'argument.type', @@ -9697,12 +9529,6 @@ 'count' => 1, 'path' => __DIR__ . '/sources/AppBundle/GeneralMeeting/GeneralMeeting.php', ]; -$ignoreErrors[] = [ - 'message' => '#^Class AppBundle\\\\GeneralMeeting\\\\GeneralMeetingQuestionFormType extends generic class Symfony\\\\Component\\\\Form\\\\AbstractType but does not specify its types\\: TData$#', - 'identifier' => 'missingType.generics', - 'count' => 1, - 'path' => __DIR__ . '/sources/AppBundle/GeneralMeeting/GeneralMeetingQuestionFormType.php', -]; $ignoreErrors[] = [ 'message' => '#^Binary operation "\\." between \'@\' and mixed results in an error\\.$#', 'identifier' => 'binaryOp.invalid', @@ -9733,12 +9559,6 @@ 'count' => 1, 'path' => __DIR__ . '/sources/AppBundle/GeneralMeeting/GeneralMeetingRepository.php', ]; -$ignoreErrors[] = [ - 'message' => '#^Method AppBundle\\\\GeneralMeeting\\\\GeneralMeetingRepository\\:\\:getAttendees\\(\\) has parameter \\$direction with no type specified\\.$#', - 'identifier' => 'missingType.parameter', - 'count' => 1, - 'path' => __DIR__ . '/sources/AppBundle/GeneralMeeting/GeneralMeetingRepository.php', -]; $ignoreErrors[] = [ 'message' => '#^Method AppBundle\\\\GeneralMeeting\\\\GeneralMeetingRepository\\:\\:getPowerSelectionList\\(\\) should return array\\ but returns array\\\\.$#', 'identifier' => 'return.type', @@ -9775,12 +9595,6 @@ 'count' => 2, 'path' => __DIR__ . '/sources/AppBundle/GeneralMeeting/GeneralMeetingRepository.php', ]; -$ignoreErrors[] = [ - 'message' => '#^Parameter \\#2 \\$order of method Doctrine\\\\DBAL\\\\Query\\\\QueryBuilder\\:\\:orderBy\\(\\) expects string\\|null, mixed given\\.$#', - 'identifier' => 'argument.type', - 'count' => 1, - 'path' => __DIR__ . '/sources/AppBundle/GeneralMeeting/GeneralMeetingRepository.php', -]; $ignoreErrors[] = [ 'message' => '#^Parameter \\#3 \\$login of class AppBundle\\\\GeneralMeeting\\\\Attendee constructor expects string, mixed given\\.$#', 'identifier' => 'argument.type', @@ -9811,12 +9625,6 @@ 'count' => 1, 'path' => __DIR__ . '/sources/AppBundle/GeneralMeeting/GeneralMeetingRepository.php', ]; -$ignoreErrors[] = [ - 'message' => '#^Class AppBundle\\\\GeneralMeeting\\\\PrepareFormType extends generic class Symfony\\\\Component\\\\Form\\\\AbstractType but does not specify its types\\: TData$#', - 'identifier' => 'missingType.generics', - 'count' => 1, - 'path' => __DIR__ . '/sources/AppBundle/GeneralMeeting/PrepareFormType.php', -]; $ignoreErrors[] = [ 'message' => '#^Method AppBundle\\\\Github\\\\Exception\\\\UnableToFindGithubUserException\\:\\:__construct\\(\\) has parameter \\$username with no type specified\\.$#', 'identifier' => 'missingType.parameter', diff --git a/sources/AppBundle/AssembleeGenerale/Entity/AssembleeGenerale.php b/sources/AppBundle/AssembleeGenerale/Entity/AssembleeGenerale.php index 2fe053f0f..f416e0b4a 100644 --- a/sources/AppBundle/AssembleeGenerale/Entity/AssembleeGenerale.php +++ b/sources/AppBundle/AssembleeGenerale/Entity/AssembleeGenerale.php @@ -4,16 +4,24 @@ namespace AppBundle\AssembleeGenerale\Entity; -use AppBundle\Doctrine\Type\UnixTimestampType; use Doctrine\ORM\Mapping as ORM; #[ORM\Entity] #[ORM\Table(name: 'afup_assemblee_generale')] class AssembleeGenerale { + /** + * Identifiant = timestamp Unix (colonne `date`, int unsigned, clé de fait de la table). + * + * On le mappe en `int` et non en `\DateTime` (via UnixTimestampType) car Doctrine + * ne sait pas hasher un objet `DateTime` dans son identity map : + * UnitOfWork::getIdHashByIdentifier() fait un implode() qui exige une valeur scalaire. + * Un identifiant `\DateTime` provoque donc « Object of class DateTime could not be + * converted to string » à chaque flush où l'entité est managée. + */ #[ORM\Id] - #[ORM\Column(type: UnixTimestampType::NAME)] - public \DateTime $date; + #[ORM\Column] + public int $date; #[ORM\Column(type: 'text', nullable: true)] public ?string $description = null; diff --git a/sources/AppBundle/AssembleeGenerale/Entity/Question.php b/sources/AppBundle/AssembleeGenerale/Entity/Question.php index abaf63289..d66db1947 100644 --- a/sources/AppBundle/AssembleeGenerale/Entity/Question.php +++ b/sources/AppBundle/AssembleeGenerale/Entity/Question.php @@ -16,10 +16,10 @@ class Question #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column] - public ?int $id = null; + public int $id; - #[ORM\Column(type: UnixTimestampType::NAME, nullable: true)] - public ?\DateTime $date = null; + #[ORM\Column(type: UnixTimestampType::NAME)] + public \DateTime $date; #[ORM\Column(name: 'label', length: 255, nullable: true)] public ?string $texte = null; @@ -30,7 +30,6 @@ class Question $this->dateOuverture = $dateOuverture; if ($dateOuverture !== null) { $this->dateCreation ??= $dateOuverture; - $this->etat = QuestionEtat::Ouverte; } } } @@ -41,7 +40,6 @@ class Question $this->dateCloture = $dateCloture; if ($dateCloture !== null) { $this->dateCreation ??= $dateCloture; - $this->etat = QuestionEtat::Fermee; } } } @@ -49,7 +47,17 @@ class Question #[ORM\Column(name: 'created_at', type: 'datetime', nullable: true)] public ?\DateTime $dateCreation = null; - public QuestionEtat $etat = QuestionEtat::EnAttente; + /** + * État calculé à partir de dateOuverture/dateCloture (et non stocké) : il doit + * rester correct après hydratation Doctrine, qui ne déclenche pas les hooks `set`. + */ + public QuestionEtat $etat { + get => match (true) { + ($this->dateCloture ?? null) !== null => QuestionEtat::Fermee, + ($this->dateOuverture ?? null) !== null => QuestionEtat::Ouverte, + default => QuestionEtat::EnAttente, + }; + } /** * @param array $results @@ -58,4 +66,19 @@ public function hasVotes(array $results): bool { return 0 < $results[VoteValeur::Oui->value] + $results[VoteValeur::Non->value] + $results[VoteValeur::Abstention->value]; } + + public function hasStatusWaiting(): bool + { + return $this->etat === QuestionEtat::EnAttente; + } + + public function hasStatusOpened(): bool + { + return $this->etat === QuestionEtat::Ouverte; + } + + public function hasStatusClosed(): bool + { + return $this->etat === QuestionEtat::Fermee; + } } diff --git a/sources/AppBundle/AssembleeGenerale/Entity/Repository/AssembleeGeneraleRepository.php b/sources/AppBundle/AssembleeGenerale/Entity/Repository/AssembleeGeneraleRepository.php new file mode 100644 index 000000000..28236ea56 --- /dev/null +++ b/sources/AppBundle/AssembleeGenerale/Entity/Repository/AssembleeGeneraleRepository.php @@ -0,0 +1,59 @@ + + */ +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 is_numeric($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 + { + /** @var AssembleeGenerale|null $assemblee */ + $assemblee = $this->createQueryBuilder('ag') + ->where('ag.date = :date') + ->setParameter('date', $date->getTimestamp()) + ->setMaxResults(1) + ->getQuery() + ->getOneOrNullResult(); + + return $assemblee; + } + + public function upsert(\DateTimeInterface $date, string $description): void + { + $assemblee = $this->findOneByDate($date) ?? new AssembleeGenerale(); + $assemblee->date = $date->getTimestamp(); + $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..02565d470 --- /dev/null +++ b/sources/AppBundle/AssembleeGenerale/Entity/Repository/QuestionRepository.php @@ -0,0 +1,75 @@ + + */ +class QuestionRepository extends EntityRepository +{ + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, Question::class); + } + + public function loadNextOpenedQuestion(\DateTimeInterface $generalMeetingDate): ?Question + { + /** @var Question|null $question */ + $question = $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; + } + + /** + * @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..07d2b8754 --- /dev/null +++ b/sources/AppBundle/AssembleeGenerale/Entity/Repository/VoteRepository.php @@ -0,0 +1,83 @@ + + */ +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 + { + $question = $this->getEntityManager()->getReference(Question::class, $questionId); + $utilisateur = $this->getEntityManager()->getReference(Utilisateur::class, $userId); + \assert($question instanceof Question); + \assert($utilisateur instanceof Utilisateur); + + $vote = new Vote(); + $vote->question = $question; + $vote->utilisateur = $utilisateur; + $vote->poids = $weight; + $vote->valeur = VoteValeur::from($value); + $vote->creeLe = new \DateTime(); + return $vote; + } + + public function loadByQuestionIdAndUserId(int $questionId, int $userId): ?Vote + { + /** @var Vote|null $vote */ + $vote = $this->createQueryBuilder('v') + ->where('v.question = :question') + ->andWhere('v.utilisateur = :user') + ->setParameter('question', $questionId) + ->setParameter('user', $userId) + ->getQuery() + ->getOneOrNullResult(); + + return $vote; + } + + /** + * @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) { + $value = $row['value']; + $weightSum = $row['weight_sum']; + if (is_string($value) && is_numeric($weightSum)) { + $results[$value] = (int) $weightSum; + } + } + + return $results; + } +} diff --git a/sources/AppBundle/GeneralMeeting/GeneralMeetingQuestionFormType.php b/sources/AppBundle/AssembleeGenerale/Form/GeneralMeetingQuestionFormType.php similarity index 80% rename from sources/AppBundle/GeneralMeeting/GeneralMeetingQuestionFormType.php rename to sources/AppBundle/AssembleeGenerale/Form/GeneralMeetingQuestionFormType.php index 53385c55f..74d2de212 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; @@ -13,12 +13,15 @@ use Symfony\Component\Validator\Constraints\Length; use Symfony\Component\Validator\Constraints\NotBlank; +/** + * @extends AbstractType + */ class GeneralMeetingQuestionFormType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options): void { $builder - ->add('label', TextType::class, [ + ->add('texte', TextType::class, [ 'label' => 'Question', 'constraints' => [ new NotBlank(), @@ -31,7 +34,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 92% rename from sources/AppBundle/GeneralMeeting/PrepareFormType.php rename to sources/AppBundle/AssembleeGenerale/Form/PrepareFormType.php index 41a9af47d..f40e65ba5 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; @@ -11,6 +11,9 @@ use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; +/** + * @extends AbstractType> + */ class PrepareFormType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options): void 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..aa32c731f 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 @@ -223,20 +224,20 @@ private function getSpeakerYears(User $user): array } /** - * @return mixed[] + * @return \DateTime[] */ 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..6306aef43 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,31 +13,32 @@ 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']); + $description = is_string($data['description'] ?? null) ? $data['description'] : ''; + $this->assembleGeneraleRepository->upsert($date, $description); $this->addFlash('success', 'Description enregistrée'); return $this->redirectToRoute('admin_members_general_meeting_edit', [ - 'date' => $date->getTimestamp(), + 'date' => $assemblee->date, ]); } return $this->render('admin/members/general_meeting/edit.html.twig', [ 'form' => $form->createView(), + 'generalMeetingDate' => $date, ]); } } 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..d1cfd8106 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,34 @@ 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 + public function __invoke(Request $request, string $date): Response { - $date = \DateTimeImmutable::createFromFormat('U', $date); - $generalMeeting = $this->generalMeetingRepository->findOneByDate($date); + $generalMeetingDate = \DateTimeImmutable::createFromFormat('U', $date); + if (false === $generalMeetingDate) { + throw $this->createNotFoundException(sprintf('Date d\'assemblée générale invalide : %s', $date)); + } + + $generalMeeting = $this->assembleGeneraleRepository->findOneByDate($generalMeetingDate); 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'))); + throw $this->createNotFoundException(sprintf('L\'assemblée générale en date du %s n\'a pas été trouvée', $generalMeetingDate->format('d/m/Y'))); } - $question = new GeneralMeetingQuestion(); - $question->setDate($generalMeeting['date']); - $question->setCreatedAt(new \DateTime()); + $question = new Question(); + $question->date = \DateTime::createFromInterface($generalMeetingDate); + $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..eb090d558 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 + public function __invoke(int $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..a7f41e269 100644 --- a/sources/AppBundle/Controller/Admin/Members/GeneralMeetingQuestion/EditAction.php +++ b/sources/AppBundle/Controller/Admin/Members/GeneralMeetingQuestion/EditAction.php @@ -4,18 +4,19 @@ 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; +use Symfony\Component\HttpFoundation\Response; class EditAction extends AbstractController { - public function __construct(private readonly GeneralMeetingQuestionRepository $generalMeetingQuestionRepository) {} + public function __construct(private readonly QuestionRepository $questionRepository) {} - public function __invoke(Request $request, $id) + public function __invoke(Request $request, int $id): Response { - $question = $this->generalMeetingQuestionRepository->get($id); + $question = $this->questionRepository->find($id); if (null === $question) { throw $this->createNotFoundException(sprintf('Question %d not found', $id)); @@ -28,11 +29,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..71a7e9901 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,11 +32,13 @@ public function __invoke(Request $request): Response } $rows = []; - foreach ($this->generalMeetingQuestionRepository->loadByDate($selectedDate) as $question) { - $rows[] = [ - 'question' => $question, - 'results' => $this->generalMeetingVoteRepository->getResultsForQuestionId($question->getId()), - ]; + if (null !== $selectedDate) { + foreach ($this->questionRepository->loadByDate($selectedDate) as $question) { + $rows[] = [ + 'question' => $question, + 'results' => $this->voteRepository->getResultsForQuestionId($question->id), + ]; + } } return new Response($this->twig->render('admin/members/general_meeting_vote/list.html.twig', [ 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..027c19283 100644 --- a/sources/AppBundle/Controller/Website/Membership/GeneralMeeting/IndexAction.php +++ b/sources/AppBundle/Controller/Website/Membership/GeneralMeeting/IndexAction.php @@ -5,15 +5,15 @@ namespace AppBundle\Controller\Website\Membership\GeneralMeeting; 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,11 +29,11 @@ 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, private readonly Authentication $authentication, ) {} @@ -43,10 +43,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 +57,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 +91,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 +105,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 +129,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, $user->getId()); } $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..7cb1dc276 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'); @@ -46,24 +46,20 @@ public function __invoke(Request $request): RedirectResponse } $userId = $this->droits->obtenirIdentifiant(); + if (null === $userId) { + throw $this->createAccessDeniedException('Utilisateur non identifié'); + } - 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'); diff --git a/sources/AppBundle/GeneralMeeting/GeneralMeetingRepository.php b/sources/AppBundle/GeneralMeeting/GeneralMeetingRepository.php index 430014144..83d220173 100644 --- a/sources/AppBundle/GeneralMeeting/GeneralMeetingRepository.php +++ b/sources/AppBundle/GeneralMeeting/GeneralMeetingRepository.php @@ -145,6 +145,7 @@ public function obtenirDescription(DateTimeInterface $date) /** * @param string $order + * @param string $direction * @param int|null $idPersonneAvecPouvoir * * @return Attendee[] diff --git a/templates/admin/association/membership/generalmeeting.html.twig b/templates/admin/association/membership/generalmeeting.html.twig index a8de1edab..57eb7d9ed 100644 --- a/templates/admin/association/membership/generalmeeting.html.twig +++ b/templates/admin/association/membership/generalmeeting.html.twig @@ -16,7 +16,7 @@
- {{ question.label }} + {{ question.texte }}
{% if not vote_for_current_question %}
@@ -54,7 +54,7 @@ {% for question_result in question_results %} - {{ question_result.question.label }} + {{ question_result.question.texte }} Oui diff --git a/templates/admin/members/general_meeting/edit.html.twig b/templates/admin/members/general_meeting/edit.html.twig index d8cbc5c8c..7fba729eb 100644 --- a/templates/admin/members/general_meeting/edit.html.twig +++ b/templates/admin/members/general_meeting/edit.html.twig @@ -2,7 +2,7 @@ {% block content %}
-

Modifier l'assemblée générale du {{ form.vars.value.date|date('d/m/Y') }}

+

Modifier l'assemblée générale du {{ generalMeetingDate|date('d/m/Y') }}

{{ form_start(form) }} @@ -13,7 +13,7 @@ {{ form_errors(form.description) }}
- Retour {{ form_row(form.submit, {attr: {class: "ui primary button"}, label: "Enregistrer"}) }}
diff --git a/templates/admin/members/general_meeting_question/add.html.twig b/templates/admin/members/general_meeting_question/add.html.twig index f78d929be..766fe6664 100644 --- a/templates/admin/members/general_meeting_question/add.html.twig +++ b/templates/admin/members/general_meeting_question/add.html.twig @@ -11,9 +11,9 @@ {{ form_start(form) }}
- {{ form_label(form.label) }} - {{ form_widget(form.label, {attr: {class: 'inline fields'} }) }} - {{ form_errors(form.label) }} + {{ form_label(form.texte) }} + {{ form_widget(form.texte, {attr: {class: 'inline fields'} }) }} + {{ form_errors(form.texte) }}
- {{ form_label(form.label) }} - {{ form_widget(form.label, {attr: {class: 'inline fields'} }) }} - {{ form_errors(form.label) }} + {{ form_label(form.texte) }} + {{ form_widget(form.texte, {attr: {class: 'inline fields'} }) }} + {{ form_errors(form.texte) }}
+ data-confirmable-label="Êtes-vous sûr de vouloir ouvrir la question '{{ question.texte }}' ?"> + data-confirmable-label="Êtes-vous sûr de vouloir fermer la question '{{ question.texte }}' ?"> {% elseif question.hasStatusClosed %} @@ -90,7 +90,7 @@ data-position="left center" class="compact ui icon button confirmable" data-tooltip="Supprimer cette question" - data-confirmable-label="Êtes-vous sûr de vouloir supprimer la question '{{ question.label }}' ?"> + data-confirmable-label="Êtes-vous sûr de vouloir supprimer la question '{{ question.texte }}' ?"> {% endif %} diff --git a/tests/behat/features/Admin/Members/GeneralMeeting/GeneralMeetingQuestions.feature b/tests/behat/features/Admin/Members/GeneralMeeting/GeneralMeetingQuestions.feature index 836b67645..a415528ca 100644 --- a/tests/behat/features/Admin/Members/GeneralMeeting/GeneralMeetingQuestions.feature +++ b/tests/behat/features/Admin/Members/GeneralMeeting/GeneralMeetingQuestions.feature @@ -17,7 +17,7 @@ Feature: Administration - Partie Assemblée Générale Questions And I follow "afup-main-menu-item--assemblee_generale_votes" When I follow "Ajouter" Then the ".content h2" element should contain "Assemblée générale - questions" - And I fill in "general_meeting_question_form[label]" with "Une super question" + And I fill in "general_meeting_question_form[texte]" with "Une super question" And I press "Ajouter cette question" Then I should see "La question a été ajoutée" @@ -26,7 +26,7 @@ Feature: Administration - Partie Assemblée Générale Questions And I follow "afup-main-menu-item--assemblee_generale_votes" When I follow "question-1-edit" Then the ".content h2" element should contain "Modifier la question" - And I fill in "general_meeting_question_form[label]" with "Une super question modifié" + And I fill in "general_meeting_question_form[texte]" with "Une super question modifié" And I press "Modifier cette question" Then I should see "La question a été modifiée" And I should see "Une super question modifié"