From fcd5fba13e92a0c8db1c86cee0a061a75ddd2004 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Fri, 28 Jan 2022 14:42:18 +0100 Subject: [PATCH] add history for user in accompanying period (+ counter) --- .../Repository/NotificationRepository.php | 46 +++++----- .../Serializer/Model/Counter.php | 24 +++-- .../Entity/AccompanyingPeriod.php | 21 ++++- .../Entity/AccompanyingPeriod/UserHistory.php | 91 +++++++++++++++++++ ...mpanyingPeriodWorkEvaluationRepository.php | 1 + .../migrations/Version20220128133039.php | 44 +++++++++ 6 files changed, 196 insertions(+), 31 deletions(-) create mode 100644 src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/UserHistory.php create mode 100644 src/Bundle/ChillPersonBundle/migrations/Version20220128133039.php diff --git a/src/Bundle/ChillMainBundle/Repository/NotificationRepository.php b/src/Bundle/ChillMainBundle/Repository/NotificationRepository.php index 1479474fc..17cff837f 100644 --- a/src/Bundle/ChillMainBundle/Repository/NotificationRepository.php +++ b/src/Bundle/ChillMainBundle/Repository/NotificationRepository.php @@ -193,6 +193,29 @@ final class NotificationRepository implements ObjectRepository return $this->repository->findOneBy($criteria, $orderBy); } + /** + * @return array|Notification[] + */ + public function findUnreadByUser(User $user, int $limit = 20, int $offset = 0): array + { + $rsm = new Query\ResultSetMappingBuilder($this->em); + $rsm->addRootEntityFromClassMetadata(Notification::class, 'cmn'); + + $sql = 'SELECT ' . $rsm->generateSelectClause(['cmn' => 'cmn']) . ' ' . + 'FROM chill_main_notification cmn ' . + 'WHERE ' . + 'EXISTS (select 1 FROM chill_main_notification_addresses_unread cmnau WHERE cmnau.user_id = :userId and cmnau.notification_id = cmn.id) ' . + 'ORDER BY cmn.date DESC ' . + 'LIMIT :limit OFFSET :offset'; + + $nq = $this->em->createNativeQuery($sql, $rsm) + ->setParameter('userId', $user->getId()) + ->setParameter('limit', $limit) + ->setParameter('offset', $offset); + + return $nq->getResult(); + } + public function getClassName() { return Notification::class; @@ -219,29 +242,6 @@ final class NotificationRepository implements ObjectRepository return $qb->getQuery()->getResult(); } - /** - * @return array|Notification[] - */ - public function findUnreadByUser(User $user, int $limit = 20, int $offset = 0): array - { - $rsm = new Query\ResultSetMappingBuilder($this->em); - $rsm->addRootEntityFromClassMetadata(Notification::class, 'cmn'); - - $sql = 'SELECT ' . $rsm->generateSelectClause(['cmn' => 'cmn']) . ' ' . - 'FROM chill_main_notification cmn ' . - 'WHERE ' . - 'EXISTS (select 1 FROM chill_main_notification_addresses_unread cmnau WHERE cmnau.user_id = :userId and cmnau.notification_id = cmn.id) ' . - 'ORDER BY cmn.date DESC ' . - 'LIMIT :limit OFFSET :offset'; - - $nq = $this->em->createNativeQuery($sql, $rsm) - ->setParameter('userId', $user->getId()) - ->setParameter('limit', $limit) - ->setParameter('offset', $offset); - - return $nq->getResult(); - } - private function queryByAddressee(User $addressee, bool $countQuery = false): QueryBuilder { $qb = $this->repository->createQueryBuilder('n'); diff --git a/src/Bundle/ChillMainBundle/Serializer/Model/Counter.php b/src/Bundle/ChillMainBundle/Serializer/Model/Counter.php index e0b471e71..da1d348c7 100644 --- a/src/Bundle/ChillMainBundle/Serializer/Model/Counter.php +++ b/src/Bundle/ChillMainBundle/Serializer/Model/Counter.php @@ -1,8 +1,19 @@ counter; } - public function setCounter(?int $counter): Counter - { - $this->counter = $counter; - return $this; - } - public function jsonSerialize() { return ['count' => $this->counter]; } + public function setCounter(?int $counter): Counter + { + $this->counter = $counter; + return $this; + } } diff --git a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php index 728ef7322..c539c458d 100644 --- a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php +++ b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php @@ -26,6 +26,7 @@ use Chill\PersonBundle\Entity\AccompanyingPeriod\ClosingMotive; use Chill\PersonBundle\Entity\AccompanyingPeriod\Comment; use Chill\PersonBundle\Entity\AccompanyingPeriod\Origin; use Chill\PersonBundle\Entity\AccompanyingPeriod\Resource; +use Chill\PersonBundle\Entity\AccompanyingPeriod\UserHistory; use Chill\PersonBundle\Entity\SocialWork\SocialIssue; use Chill\PersonBundle\Validator\Constraints\AccompanyingPeriod\AccompanyingPeriodValidity; use Chill\PersonBundle\Validator\Constraints\AccompanyingPeriod\ParticipationOverlap; @@ -336,6 +337,13 @@ class AccompanyingPeriod implements */ private ?User $user = null; + /** + * @ORM\OneToMany(targetEntity=UserHistory::class, mappedBy="accompanyingPeriod") + * + * @var Collection|UserHistory[] + */ + private Collection $userHistories; + /** * Temporary field, which is filled when the user is changed. * @@ -368,6 +376,7 @@ class AccompanyingPeriod implements $this->comments = new ArrayCollection(); $this->works = new ArrayCollection(); $this->resources = new ArrayCollection(); + $this->userHistories = new ArrayCollection(); } /** @@ -1212,10 +1221,20 @@ class AccompanyingPeriod implements return $this; } - public function setUser(User $user): self + public function setUser(?User $user): self { if ($this->user !== $user) { $this->userPrevious = $this->user; + + if (null !== $user) { + $this->userHistories->add(new UserHistory($this, $user)); + } + + foreach ($this->userHistories as $history) { + if (null === $history->getEndDate()) { + $history->setEndDate(new DateTimeImmutable('now')); + } + } } $this->user = $user; diff --git a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/UserHistory.php b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/UserHistory.php new file mode 100644 index 000000000..738d12008 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/UserHistory.php @@ -0,0 +1,91 @@ +startDate = $startDate ?? new \DateTimeImmutable('now'); + $this->accompanyingPeriod = $accompanyingPeriod; + $this->user = $user; + } + + public function getAccompanyingPeriod(): AccompanyingPeriod + { + return $this->accompanyingPeriod; + } + + public function getEndDate(): ?DateTimeImmutable + { + return $this->endDate; + } + + public function getId(): ?int + { + return $this->id; + } + + public function getStartDate(): DateTimeImmutable + { + return $this->startDate; + } + + public function getUser(): User + { + return $this->user; + } + + public function setEndDate(?DateTimeImmutable $endDate): UserHistory + { + $this->endDate = $endDate; + + return $this; + } +} diff --git a/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/AccompanyingPeriodWorkEvaluationRepository.php b/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/AccompanyingPeriodWorkEvaluationRepository.php index f8a2e7f33..3178aa6e2 100644 --- a/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/AccompanyingPeriodWorkEvaluationRepository.php +++ b/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/AccompanyingPeriodWorkEvaluationRepository.php @@ -50,6 +50,7 @@ class AccompanyingPeriodWorkEvaluationRepository implements ObjectRepository /** * @param int $limit * @param int $offset + * * @return array|AccompanyingPeriodWorkEvaluation[] */ public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $offset = null): array diff --git a/src/Bundle/ChillPersonBundle/migrations/Version20220128133039.php b/src/Bundle/ChillPersonBundle/migrations/Version20220128133039.php new file mode 100644 index 000000000..0a4b8c933 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/migrations/Version20220128133039.php @@ -0,0 +1,44 @@ +addSql('DROP SEQUENCE chill_person_accompanying_period_user_history_id_seq CASCADE'); + $this->addSql('DROP TABLE chill_person_accompanying_period_user_history'); + } + + public function getDescription(): string + { + return 'Add table for tracking user history on accompanying period'; + } + + public function up(Schema $schema): void + { + $this->addSql('CREATE SEQUENCE chill_person_accompanying_period_user_history_id_seq INCREMENT BY 1 MINVALUE 1 START 1'); + $this->addSql('CREATE TABLE chill_person_accompanying_period_user_history (id INT NOT NULL, user_id INT, endDate TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL, startDate TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, accompanyingPeriod_id INT, PRIMARY KEY(id))'); + $this->addSql('CREATE INDEX IDX_6C258C49D7FA8EF0 ON chill_person_accompanying_period_user_history (accompanyingPeriod_id)'); + $this->addSql('CREATE INDEX IDX_6C258C49A76ED395 ON chill_person_accompanying_period_user_history (user_id)'); + $this->addSql('COMMENT ON COLUMN chill_person_accompanying_period_user_history.endDate IS \'(DC2Type:datetime_immutable)\''); + $this->addSql('COMMENT ON COLUMN chill_person_accompanying_period_user_history.startDate IS \'(DC2Type:datetime_immutable)\''); + $this->addSql('ALTER TABLE chill_person_accompanying_period_user_history ADD CONSTRAINT FK_6C258C49D7FA8EF0 FOREIGN KEY (accompanyingPeriod_id) REFERENCES chill_person_accompanying_period (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE chill_person_accompanying_period_user_history ADD CONSTRAINT FK_6C258C49A76ED395 FOREIGN KEY (user_id) REFERENCES users (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE chill_person_accompanying_period_user_history ADD CHECK (startdate <= enddate)'); + $this->addSql('INSERT INTO chill_person_accompanying_period_user_history (id, user_id, accompanyingperiod_id, startDate, endDate) ' . + 'SELECT nextval(\'chill_person_accompanying_period_user_history_id_seq\'), user_id, id, openingDate, null FROM chill_person_accompanying_period WHERE user_id IS NOT NULL'); + } +}