diff --git a/CHANGELOG.md b/CHANGELOG.md index 61c429e57..a985c8493 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to * Load relationships without gender in french fixtures +* Add command to remove old draft accompanying periods ## Test releases diff --git a/src/Bundle/ChillPersonBundle/Command/RemoveOldDraftAccompanyingPeriodCommand.php b/src/Bundle/ChillPersonBundle/Command/RemoveOldDraftAccompanyingPeriodCommand.php new file mode 100644 index 000000000..5d503007f --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Command/RemoveOldDraftAccompanyingPeriodCommand.php @@ -0,0 +1,64 @@ +logger = $logger; + $this->remover = $remover; + } + + protected function configure(): void + { + $this + ->setDescription('Remove draft accompanying period which are still draft and unused') + ->addArgument('interval', InputArgument::OPTIONAL, 'The interval for unactive periods', 'P15D'); + } + + protected function execute(InputInterface $input, OutputInterface $output): int + { + $this->logger->info('[' . $this->getName() . '] started', [ + 'interval' => $input->getArgument('interval'), + ]); + + try { + $interval = new DateInterval($input->getArgument('interval')); + } catch (Exception $e) { + $this->logger->error('[' . $this->getName() . '] bad interval'); + + throw $e; + } + + $this->remover->remove($interval); + + $this->logger->info('[' . $this->getName() . '] end of command'); + + return 0; + } +} diff --git a/src/Bundle/ChillPersonBundle/Service/AccompanyingPeriod/OldDraftAccompanyingPeriodRemover.php b/src/Bundle/ChillPersonBundle/Service/AccompanyingPeriod/OldDraftAccompanyingPeriodRemover.php new file mode 100644 index 000000000..47a34e88c --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Service/AccompanyingPeriod/OldDraftAccompanyingPeriodRemover.php @@ -0,0 +1,103 @@ +em = $em; + $this->logger = $logger; + } + + public function remove(DateInterval $interval): void + { + $this->logger->debug('[' . __CLASS__ . '] start to remove old periods', [ + 'interval' => $interval->format('%d days'), + ]); + + $beforeDate = (new DateTimeImmutable('now'))->sub($interval); + + $results = $this->em->wrapInTransaction(static function (EntityManagerInterface $em) use ($beforeDate) { + $subDQL = 'SELECT p FROM ' . AccompanyingPeriod::class . ' p WHERE p.createdAt < :beforeDate AND p.step = :draft'; + $parameters = [ + 'beforeDate' => $beforeDate, + 'draft' => AccompanyingPeriod::STEP_DRAFT, + ]; + + $resources = $em->createQuery( + 'DELETE ' . AccompanyingPeriod\Resource::class . " r WHERE r.accompanyingPeriod IN ({$subDQL})" + ) + ->setParameters($parameters) + ->getSingleScalarResult(); + + $participations = $em->createQuery( + 'DELETE ' . AccompanyingPeriodParticipation::class . " part WHERE part.accompanyingPeriod IN ({$subDQL})" + ) + ->setParameters($parameters) + ->getSingleScalarResult(); + + $userHistory = $em->createQuery( + 'DELETE ' . AccompanyingPeriod\UserHistory::class . " h WHERE h.accompanyingPeriod IN ({$subDQL})" + ) + ->setParameters($parameters) + ->getSingleScalarResult(); + + $comments = $em->createQuery( + 'DELETE ' . AccompanyingPeriod\Comment::class . " c WHERE c.accompanyingPeriod IN ({$subDQL})" + ) + ->setParameters($parameters) + ->getSingleScalarResult(); + + $documents = $em->createQuery( + 'DELETE ' . AccompanyingCourseDocument::class . " d WHERE d.course IN ({$subDQL})" + ) + ->setParameters($parameters) + ->getSingleScalarResult(); + + $periods = $em + ->createQuery( + 'DELETE ' . AccompanyingPeriod::class . ' p WHERE p.createdAt < :beforeDate + AND p.step = :draft' + ) + ->setParameter(':beforeDate', $beforeDate, Types::DATETIME_IMMUTABLE) + ->setParameter(':draft', AccompanyingPeriod::STEP_DRAFT) + ->getSingleScalarResult(); + + return [ + 'comments' => $comments, + 'documents' => $documents, + 'participations' => $participations, + 'periods' => $periods, + 'resources' => $resources, + 'userHistory' => $userHistory, + ]; + }); + + $this->logger->info('[' . __CLASS__ . '] periods removed', array_merge($results, [ + 'interval' => $interval->format('%d days'), + ])); + } +} diff --git a/src/Bundle/ChillPersonBundle/Service/AccompanyingPeriod/OldDraftAccompanyingPeriodRemoverInterface.php b/src/Bundle/ChillPersonBundle/Service/AccompanyingPeriod/OldDraftAccompanyingPeriodRemoverInterface.php new file mode 100644 index 000000000..882fefe3b --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Service/AccompanyingPeriod/OldDraftAccompanyingPeriodRemoverInterface.php @@ -0,0 +1,19 @@ +addSql('ALTER TABLE "accompanying_periods_scopes" + DROP CONSTRAINT "fk_87c4eab032a7a428", + ADD CONSTRAINT "fk_87c4eab032a7a428" FOREIGN KEY (accompanying_period_id) REFERENCES chill_person_accompanying_period(id) + '); + } + + public function getDescription(): string + { + return 'apply CASCADE DELETE on entity related to accompanying periods'; + } + + public function up(Schema $schema): void + { + $this->addSql('ALTER TABLE "accompanying_periods_scopes" + DROP CONSTRAINT "fk_87c4eab032a7a428", + ADD CONSTRAINT "fk_87c4eab032a7a428" FOREIGN KEY (accompanying_period_id) REFERENCES chill_person_accompanying_period(id) ON DELETE CASCADE + '); + } +}