From f8840d89bfcf996ee8060fe3443888766ecdec3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 23 Jan 2024 21:56:17 +0100 Subject: [PATCH 01/12] Add capability to store closing motive when closing accompanying period The commit introduces new functionality in the bundle that allows storing the closing motive when a course is closed. This is achieved by modifying the model and database schema to include a new `closingMotive` field in AccompanyingPeriodStepHistory entity. --- .../AccompanyingCourseController.php | 2 +- .../Entity/AccompanyingPeriod.php | 9 ++-- .../AccompanyingPeriodStepHistory.php | 19 +++++++ .../Tests/Entity/AccompanyingPeriodTest.php | 30 +++++++++++ .../migrations/Version20240123161457.php | 52 +++++++++++++++++++ 5 files changed, 108 insertions(+), 4 deletions(-) create mode 100644 src/Bundle/ChillPersonBundle/migrations/Version20240123161457.php diff --git a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php index a2ced7fee..6acca44e3 100644 --- a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php +++ b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php @@ -62,7 +62,7 @@ class AccompanyingCourseController extends \Symfony\Bundle\FrameworkBundle\Contr $workflow = $this->registry->get($accompanyingCourse); if ($workflow->can($accompanyingCourse, 'close')) { - $workflow->apply($accompanyingCourse, 'close'); + $workflow->apply($accompanyingCourse, 'close', ['closing_motive' => $form['closingMotive']->getData()]); $em->flush(); diff --git a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php index 9c88a4a69..4f9c480d0 100644 --- a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php +++ b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php @@ -1449,7 +1449,7 @@ class AccompanyingPeriod implements return $this; } - public function setStep(string $step): self + public function setStep(string $step, array $context = []): self { $previous = $this->step; @@ -1464,7 +1464,7 @@ class AccompanyingPeriod implements $history = new AccompanyingPeriodStepHistory(); $history->setStep($this->step)->setStartDate(new \DateTimeImmutable('now')); - $this->addStepHistory($history); + $this->addStepHistory($history, $context); } return $this; @@ -1507,11 +1507,14 @@ class AccompanyingPeriod implements return $this; } - private function addStepHistory(AccompanyingPeriodStepHistory $stepHistory): self + private function addStepHistory(AccompanyingPeriodStepHistory $stepHistory, array $context = []): self { if (!$this->stepHistories->contains($stepHistory)) { $this->stepHistories[] = $stepHistory; $stepHistory->setPeriod($this); + if (($context['closing_motive'] ?? null) instanceof ClosingMotive) { + $stepHistory->setClosingMotive($context['closing_motive']); + } $this->ensureStepContinuity(); } diff --git a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/AccompanyingPeriodStepHistory.php b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/AccompanyingPeriodStepHistory.php index 15b2f0d2e..fd4d573ce 100644 --- a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/AccompanyingPeriodStepHistory.php +++ b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/AccompanyingPeriodStepHistory.php @@ -59,6 +59,13 @@ class AccompanyingPeriodStepHistory implements TrackCreationInterface, TrackUpda */ private string $step; + /** + * @ORM\ManyToOne(targetEntity=ClosingMotive::class) + * + * @ORM\JoinColumn(nullable=true) + */ + private ?AccompanyingPeriod\ClosingMotive $closingMotive = null; + public function getEndDate(): ?\DateTimeImmutable { return $this->endDate; @@ -114,4 +121,16 @@ class AccompanyingPeriodStepHistory implements TrackCreationInterface, TrackUpda return $this; } + + public function getClosingMotive(): ?AccompanyingPeriod\ClosingMotive + { + return $this->closingMotive; + } + + public function setClosingMotive(?AccompanyingPeriod\ClosingMotive $closingMotive): self + { + $this->closingMotive = $closingMotive; + + return $this; + } } diff --git a/src/Bundle/ChillPersonBundle/Tests/Entity/AccompanyingPeriodTest.php b/src/Bundle/ChillPersonBundle/Tests/Entity/AccompanyingPeriodTest.php index 5fdb51c15..9e383b789 100644 --- a/src/Bundle/ChillPersonBundle/Tests/Entity/AccompanyingPeriodTest.php +++ b/src/Bundle/ChillPersonBundle/Tests/Entity/AccompanyingPeriodTest.php @@ -312,4 +312,34 @@ final class AccompanyingPeriodTest extends \PHPUnit\Framework\TestCase $this->assertNull($period->getRequestorPerson()); $this->assertNull($period->getRequestor()); } + + public function testSetStep(): void + { + $period = new AccompanyingPeriod(); + + $period->setStep(AccompanyingPeriod::STEP_CONFIRMED); + + self::assertEquals(AccompanyingPeriod::STEP_CONFIRMED, $period->getStep()); + self::assertCount(1, $period->getStepHistories()); + + $period->setStep(AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_SHORT); + + self::assertEquals(AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_SHORT, $period->getStep()); + self::assertCount(2, $period->getStepHistories()); + + $periodInactiveSteps = $period->getStepHistories()->filter(fn (AccompanyingPeriod\AccompanyingPeriodStepHistory $h) => AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_SHORT === $h->getStep()); + self::assertCount(1, $periodInactiveSteps); + + $period->setStep(AccompanyingPeriod::STEP_CLOSED, ['closing_motive' => $closingMotive = new AccompanyingPeriod\ClosingMotive()]); + + self::assertEquals(AccompanyingPeriod::STEP_CLOSED, $period->getStep()); + self::assertCount(3, $period->getStepHistories()); + + $periodClosedSteps = $period->getStepHistories()->filter(fn (AccompanyingPeriod\AccompanyingPeriodStepHistory $h) => AccompanyingPeriod::STEP_CLOSED === $h->getStep()); + self::assertCount(1, $periodClosedSteps); + + $periodClosedStep = $periodClosedSteps->first(); + + self::assertSame($closingMotive, $periodClosedStep->getClosingMotive()); + } } diff --git a/src/Bundle/ChillPersonBundle/migrations/Version20240123161457.php b/src/Bundle/ChillPersonBundle/migrations/Version20240123161457.php new file mode 100644 index 000000000..4c19e6c8f --- /dev/null +++ b/src/Bundle/ChillPersonBundle/migrations/Version20240123161457.php @@ -0,0 +1,52 @@ +addSql('ALTER TABLE chill_person_accompanying_period_step_history ADD closingMotive_id INT DEFAULT NULL'); + $this->addSql('ALTER TABLE chill_person_accompanying_period_step_history ADD CONSTRAINT FK_84D514AC504CB38D FOREIGN KEY (closingMotive_id) REFERENCES chill_person_accompanying_period_closingmotive (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE chill_person_accompanying_period_step_history ADD CONSTRAINT FK_84D514AC65FF1AEC FOREIGN KEY (updatedBy_id) REFERENCES users (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql(<<<'EOF' + WITH last_step AS ( + SELECT * FROM ( + SELECT *, rank() OVER (partition by period_id ORDER BY startdate DESC, id DESC) AS r FROM chill_person_accompanying_period_step_history cpapsh + ) as sq + WHERE r = 1 + ) + UPDATE chill_person_accompanying_period_step_history + SET closingMotive_id = chill_person_accompanying_period.closingmotive_id + FROM last_step, chill_person_accompanying_period + WHERE last_step.period_id = chill_person_accompanying_period_step_history.period_id AND chill_person_accompanying_period.id = chill_person_accompanying_period_step_history.period_id + AND last_step.step = 'CLOSED'; + EOF); + $this->addSql('CREATE INDEX IDX_84D514AC504CB38D ON chill_person_accompanying_period_step_history (closingMotive_id)'); + } + + public function down(Schema $schema): void + { + $this->addSql('ALTER TABLE chill_person_accompanying_period_step_history DROP CONSTRAINT FK_84D514AC504CB38D'); + $this->addSql('ALTER TABLE chill_person_accompanying_period_step_history DROP CONSTRAINT FK_84D514AC65FF1AEC'); + $this->addSql('DROP INDEX IDX_84D514AC504CB38D'); + $this->addSql('ALTER TABLE chill_person_accompanying_period_step_history DROP closingMotive_id'); + } +} From b6ea857389c14cb4d601cf3aba3e3d005911baab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Mon, 29 Jan 2024 09:55:02 +0100 Subject: [PATCH 02/12] Add AccompanyingCourseStepHistory counting capabilities The newly created CountAccompanyingCourseStepHistory class counts changes in AccompanyingPeriod status. Corresponding test file ensures the correct functionality. Supporting translations and necessary export declarations have been added to facilitate this change. --- exports_alias_conventions.md | 140 +++++++++--------- .../ChillPersonBundle/Export/Declarations.php | 2 + .../CountAccompanyingCourseStepHistory.php | 139 +++++++++++++++++ ...CountAccompanyingCourseStepHistoryTest.php | 48 ++++++ .../translations/messages.fr.yml | 3 + 5 files changed, 263 insertions(+), 69 deletions(-) create mode 100644 src/Bundle/ChillPersonBundle/Export/Export/CountAccompanyingCourseStepHistory.php create mode 100644 src/Bundle/ChillPersonBundle/Tests/Export/Export/CountAccompanyingCourseStepHistoryTest.php diff --git a/exports_alias_conventions.md b/exports_alias_conventions.md index eb0545702..d4d034314 100644 --- a/exports_alias_conventions.md +++ b/exports_alias_conventions.md @@ -5,72 +5,74 @@ Add condition with distinct alias on each export join clauses (Indicators + Filt These are alias conventions : -| Entity | Join | Attribute | Alias | -|:----------------------------------------|:----------------------------------------|:-------------------------------------------|:---------------------------------------| -| AccompanyingPeriod::class | | | acp | -| | AccompanyingPeriodWork::class | acp.works | acpw | -| | AccompanyingPeriodParticipation::class | acp.participations | acppart | -| | Location::class | acp.administrativeLocation | acploc | -| | ClosingMotive::class | acp.closingMotive | acpmotive | -| | UserJob::class | acp.job | acpjob | -| | Origin::class | acp.origin | acporigin | -| | Scope::class | acp.scopes | acpscope | -| | SocialIssue::class | acp.socialIssues | acpsocialissue | -| | User::class | acp.user | acpuser | -| | AccompanyingPeriopStepHistory::class | acp.stepHistories | acpstephistories | -| | AccompanyingPeriodInfo::class | not existing (using custom WITH clause) | acpinfo | -| AccompanyingPeriodWork::class | | | acpw | -| | AccompanyingPeriodWorkEvaluation::class | acpw.accompanyingPeriodWorkEvaluations | workeval | -| | SocialAction::class | acpw.socialAction | acpwsocialaction | -| | Goal::class | acpw.goals | goal | -| | Result::class | acpw.results | result | -| AccompanyingPeriodParticipation::class | | | acppart | -| | Person::class | acppart.person | partperson | -| AccompanyingPeriodWorkEvaluation::class | | | workeval | -| | Evaluation::class | workeval.evaluation | eval | -| AccompanyingPeriodInfo::class | | | acpinfo | -| | User::class | acpinfo.user | acpinfo_user | -| Goal::class | | | goal | -| | Result::class | goal.results | goalresult | -| Person::class | | | person | -| | Center::class | person.center | center | -| | HouseholdMember::class | partperson.householdParticipations | householdmember | -| | MaritalStatus::class | person.maritalStatus | personmarital | -| | VendeePerson::class | | vp | -| | VendeePersonMineur::class | | vpm | -| | CurrentPersonAddress::class | person.currentPersonAddress | currentPersonAddress (on a given date) | -| ResidentialAddress::class | | | resaddr | -| | ThirdParty::class | resaddr.hostThirdParty | tparty | -| ThirdParty::class | | | tparty | -| | ThirdPartyCategory::class | tparty.categories | tpartycat | -| HouseholdMember::class | | | householdmember | -| | Household::class | householdmember.household | household | -| | Person::class | householdmember.person | memberperson | -| | | memberperson.center | membercenter | -| Household::class | | | household | -| | HouseholdComposition::class | household.compositions | composition | -| Activity::class | | | activity | -| | Person::class | activity.person | actperson | -| | AccompanyingPeriod::class | activity.accompanyingPeriod | acp | -| | Person::class | activity\_person\_having\_activity.person | person\_person\_having\_activity | -| | ActivityReason::class | activity\_person\_having\_activity.reasons | reasons\_person\_having\_activity | -| | ActivityType::class | activity.activityType | acttype | -| | Location::class | activity.location | actloc | -| | SocialAction::class | activity.socialActions | actsocialaction | -| | SocialIssue::class | activity.socialIssues | actsocialssue | -| | ThirdParty::class | activity.thirdParties | acttparty | -| | User::class | activity.user | actuser | -| | User::class | activity.users | actusers | -| | ActivityReason::class | activity.reasons | actreasons | -| | Center::class | actperson.center | actcenter | -| | Person::class | activity.createdBy | actcreator | -| ActivityReason::class | | | actreasons | -| | ActivityReasonCategory::class | actreason.category | actreasoncat | -| Calendar::class | | | cal | -| | CancelReason::class | cal.cancelReason | calcancel | -| | Location::class | cal.location | calloc | -| | User::class | cal.user | caluser | -| VendeePerson::class | | | vp | -| | SituationProfessionelle::class | vp.situationProfessionelle | vpprof | -| | StatutLogement::class | vp.statutLogement | vplog | -| | TempsDeTravail::class | vp.tempsDeTravail | vptt | +| Entity | Join | Attribute | Alias | +|:----------------------------------------|:----------------------------------------|:-------------------------------------------|:-------------------------------------------| +| AccompanyingPeriodStepHistory::class | | | acpstephistory (contexte ACP_STEP_HISTORY) | +| | AccompanyingPeriod::class | acpstephistory.period | acp | +| AccompanyingPeriod::class | | | acp | +| | AccompanyingPeriodWork::class | acp.works | acpw | +| | AccompanyingPeriodParticipation::class | acp.participations | acppart | +| | Location::class | acp.administrativeLocation | acploc | +| | ClosingMotive::class | acp.closingMotive | acpmotive | +| | UserJob::class | acp.job | acpjob | +| | Origin::class | acp.origin | acporigin | +| | Scope::class | acp.scopes | acpscope | +| | SocialIssue::class | acp.socialIssues | acpsocialissue | +| | User::class | acp.user | acpuser | +| | AccompanyingPeriopStepHistory::class | acp.stepHistories | acpstephistories | +| | AccompanyingPeriodInfo::class | not existing (using custom WITH clause) | acpinfo | +| AccompanyingPeriodWork::class | | | acpw | +| | AccompanyingPeriodWorkEvaluation::class | acpw.accompanyingPeriodWorkEvaluations | workeval | +| | SocialAction::class | acpw.socialAction | acpwsocialaction | +| | Goal::class | acpw.goals | goal | +| | Result::class | acpw.results | result | +| AccompanyingPeriodParticipation::class | | | acppart | +| | Person::class | acppart.person | partperson | +| AccompanyingPeriodWorkEvaluation::class | | | workeval | +| | Evaluation::class | workeval.evaluation | eval | +| AccompanyingPeriodInfo::class | | | acpinfo | +| | User::class | acpinfo.user | acpinfo_user | +| Goal::class | | | goal | +| | Result::class | goal.results | goalresult | +| Person::class | | | person | +| | Center::class | person.center | center | +| | HouseholdMember::class | partperson.householdParticipations | householdmember | +| | MaritalStatus::class | person.maritalStatus | personmarital | +| | VendeePerson::class | | vp | +| | VendeePersonMineur::class | | vpm | +| | CurrentPersonAddress::class | person.currentPersonAddress | currentPersonAddress (on a given date) | +| ResidentialAddress::class | | | resaddr | +| | ThirdParty::class | resaddr.hostThirdParty | tparty | +| ThirdParty::class | | | tparty | +| | ThirdPartyCategory::class | tparty.categories | tpartycat | +| HouseholdMember::class | | | householdmember | +| | Household::class | householdmember.household | household | +| | Person::class | householdmember.person | memberperson | +| | | memberperson.center | membercenter | +| Household::class | | | household | +| | HouseholdComposition::class | household.compositions | composition | +| Activity::class | | | activity | +| | Person::class | activity.person | actperson | +| | AccompanyingPeriod::class | activity.accompanyingPeriod | acp | +| | Person::class | activity\_person\_having\_activity.person | person\_person\_having\_activity | +| | ActivityReason::class | activity\_person\_having\_activity.reasons | reasons\_person\_having\_activity | +| | ActivityType::class | activity.activityType | acttype | +| | Location::class | activity.location | actloc | +| | SocialAction::class | activity.socialActions | actsocialaction | +| | SocialIssue::class | activity.socialIssues | actsocialssue | +| | ThirdParty::class | activity.thirdParties | acttparty | +| | User::class | activity.user | actuser | +| | User::class | activity.users | actusers | +| | ActivityReason::class | activity.reasons | actreasons | +| | Center::class | actperson.center | actcenter | +| | Person::class | activity.createdBy | actcreator | +| ActivityReason::class | | | actreasons | +| | ActivityReasonCategory::class | actreason.category | actreasoncat | +| Calendar::class | | | cal | +| | CancelReason::class | cal.cancelReason | calcancel | +| | Location::class | cal.location | calloc | +| | User::class | cal.user | caluser | +| VendeePerson::class | | | vp | +| | SituationProfessionelle::class | vp.situationProfessionelle | vpprof | +| | StatutLogement::class | vp.statutLogement | vplog | +| | TempsDeTravail::class | vp.tempsDeTravail | vptt | diff --git a/src/Bundle/ChillPersonBundle/Export/Declarations.php b/src/Bundle/ChillPersonBundle/Export/Declarations.php index 4186861cb..83673234c 100644 --- a/src/Bundle/ChillPersonBundle/Export/Declarations.php +++ b/src/Bundle/ChillPersonBundle/Export/Declarations.php @@ -18,6 +18,8 @@ abstract class Declarations { final public const ACP_TYPE = 'accompanying_period'; + final public const ACP_STEP_HISTORY = 'accompanying_period_step_history'; + final public const EVAL_TYPE = 'evaluation'; final public const HOUSEHOLD_TYPE = 'household'; diff --git a/src/Bundle/ChillPersonBundle/Export/Export/CountAccompanyingCourseStepHistory.php b/src/Bundle/ChillPersonBundle/Export/Export/CountAccompanyingCourseStepHistory.php new file mode 100644 index 000000000..4f620fa34 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Export/Export/CountAccompanyingCourseStepHistory.php @@ -0,0 +1,139 @@ +repository = $em->getRepository(AccompanyingPeriod::class); + $this->filterStatsByCenters = $parameterBag->get('chill_main')['acl']['filter_stats_by_center']; + } + + public function buildForm(FormBuilderInterface $builder): void + { + // Nothing to add here + } + + public function getFormDefaultData(): array + { + return []; + } + + public function getAllowedFormattersTypes(): array + { + return [FormatterInterface::TYPE_TABULAR]; + } + + public function getDescription(): string + { + return 'export.export.acp_closing.description'; + } + + public function getGroup(): string + { + return 'Exports of accompanying courses'; + } + + public function getLabels($key, array $values, $data) + { + if ('export_result' !== $key) { + throw new \LogicException("the key {$key} is not used by this export"); + } + + return fn ($value) => '_header' === $value ? $this->getTitle() : $value; + } + + public function getQueryKeys($data): array + { + return ['export_result']; + } + + public function getResult($query, $data) + { + return $query->getQuery()->getResult(Query::HYDRATE_SCALAR); + } + + public function getTitle(): string + { + return 'export.export.acp_closing.title'; + } + + public function getType(): string + { + return Declarations::ACP_TYPE; + } + + public function initiateQuery(array $requiredModifiers, array $acl, array $data = []): QueryBuilder + { + $centers = array_map(static fn ($el) => $el['center'], $acl); + + $qb = $this->em->createQueryBuilder() + ->select('COUNT(DISTINCT acpstephistory.id) As export_result') + ->from(AccompanyingPeriod\AccompanyingPeriodStepHistory::class, 'acpstephistory') + ->join('acpstephistory.period', 'acp'); + + $qb + ->leftJoin('acp.participations', 'acppart') + ->leftJoin('acppart.person', 'person'); + + if ($this->filterStatsByCenters) { + $qb + ->andWhere( + $qb->expr()->exists( + 'SELECT 1 FROM '.PersonCenterHistory::class.' acl_count_person_history WHERE acl_count_person_history.person = person + AND acl_count_person_history.center IN (:authorized_centers) + ' + ) + ) + ->setParameter('authorized_centers', $centers); + } + + AccompanyingCourseExportHelper::addClosingMotiveExclusionClause($qb); + + return $qb; + } + + public function requiredRole(): string + { + return AccompanyingPeriodVoter::STATS; + } + + public function supportsModifiers(): array + { + return [ + Declarations::ACP_TYPE, + Declarations::PERSON_TYPE, + Declarations::ACP_STEP_HISTORY, + ]; + } +} diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Export/CountAccompanyingCourseStepHistoryTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Export/CountAccompanyingCourseStepHistoryTest.php new file mode 100644 index 000000000..19adee99f --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Export/CountAccompanyingCourseStepHistoryTest.php @@ -0,0 +1,48 @@ +get(EntityManagerInterface::class); + + yield new CountAccompanyingCourseStepHistory($em, $this->getParameters(true)); + yield new CountAccompanyingCourseStepHistory($em, $this->getParameters(false)); + } + + public function getFormData(): array + { + return [[]]; + } + + public function getModifiersCombination() + { + return [[Declarations::ACP_TYPE], [Declarations::ACP_TYPE, Declarations::ACP_STEP_HISTORY]]; + } +} diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index ec6036950..ce7f06ab1 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -985,6 +985,9 @@ export: YYYY-MM: par mois YYYY: par année export: + acp_closing: + title: Nombre de changements de statuts de parcours + description: Compte le nombre de changements de statuts de parcours. Cet export est indiqué pour obtenir le nombre de parcours ouverts ou fermés pendant une période de temps (un parcours pouvant être clôturé, puis ré-ouvert pendant la période de temps indiquée) acp_stats: avg_duration: Moyenne de la durée de participation de chaque usager concerné count_participations: Nombre de participations distinctes From 44ccfe92b61229804bd4268087aa180e8923dbb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Mon, 29 Jan 2024 11:13:38 +0100 Subject: [PATCH 03/12] Add ByDateFilter and its test for AccompanyingPeriodStepHistoryFilters A new filter called ByDateFilter has been added under AccompanyingPeriodStepHistoryFilters. This filter allows users to filter data based on a date range on the start date. Corresponding unit tests for ByDateFilter are included in this commit. Both English and French translations for the new filter are also added. --- .../ByDateFilter.php | 96 +++++++++++++++++++ .../ByDateFilterTest.php | 67 +++++++++++++ .../translations/messages+intl-icu.fr.yaml | 7 +- .../translations/messages.fr.yml | 7 ++ 4 files changed, 176 insertions(+), 1 deletion(-) create mode 100644 src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingPeriodStepHistoryFilters/ByDateFilter.php create mode 100644 src/Bundle/ChillPersonBundle/Tests/Export/Filter/AccompanyingPeriodStepHistoryFilters/ByDateFilterTest.php diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingPeriodStepHistoryFilters/ByDateFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingPeriodStepHistoryFilters/ByDateFilter.php new file mode 100644 index 000000000..8026f4573 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingPeriodStepHistoryFilters/ByDateFilter.php @@ -0,0 +1,96 @@ +add('start_date', PickRollingDateType::class, [ + 'label' => 'export.filter.step_history.by_date.start_date_label', + ]) + ->add('end_date', PickRollingDateType::class, [ + 'label' => 'export.filter.step_history.by_date.end_date_label', + ]); + } + + public function getFormDefaultData(): array + { + return [ + 'start_date' => new RollingDate(RollingDate::T_YEAR_CURRENT_START), + 'end_date' => new RollingDate(RollingDate::T_TODAY), + ]; + } + + public function describeAction($data, $format = 'string') + { + return [ + 'exports.filter.step_history.by_date.description', + [ + 'start_date' => $this->rollingDateConverter->convert($data['start_date']), + 'end_date' => $this->rollingDateConverter->convert($data['end_date']), + ], + ]; + } + + public function addRole(): ?string + { + return null; + } + + public function alterQuery(QueryBuilder $qb, $data) + { + $startDate = 'acp_step_history_by_date_start_filter'; + $endDate = 'acp_step_history_by_date_end_filter'; + + $qb + ->andWhere( + "acpstephistory.startDate >= :{$startDate} AND (acpstephistory.endDate < :{$endDate} OR acpstephistory.endDate IS NULL)" + ) + ->setParameter($startDate, $this->rollingDateConverter->convert($data['start_date'])) + ->setParameter($endDate, $this->rollingDateConverter->convert($data['end_date'])); + } + + public function applyOn() + { + return Declarations::ACP_STEP_HISTORY; + } +} diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Filter/AccompanyingPeriodStepHistoryFilters/ByDateFilterTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Filter/AccompanyingPeriodStepHistoryFilters/ByDateFilterTest.php new file mode 100644 index 000000000..978bf9488 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Filter/AccompanyingPeriodStepHistoryFilters/ByDateFilterTest.php @@ -0,0 +1,67 @@ +rollingDateConverter = self::$container->get(RollingDateConverterInterface::class); + } + + public function getFilter() + { + return new ByDateFilter($this->rollingDateConverter); + } + + public function getFormData() + { + return [ + [ + 'start_date' => new RollingDate(RollingDate::T_YEAR_CURRENT_START), + 'end_date' => new RollingDate(RollingDate::T_TODAY), + ], + ]; + } + + public function getQueryBuilders() + { + self::bootKernel(); + $em = self::$container->get(EntityManagerInterface::class); + + $qb = $em->createQueryBuilder() + ->select('COUNT(DISTINCT acpstephistory.id) As export_result') + ->from(AccompanyingPeriodStepHistory::class, 'acpstephistory') + ->join('acpstephistory.period', 'acp'); + + return [ + $qb, + ]; + } +} diff --git a/src/Bundle/ChillPersonBundle/translations/messages+intl-icu.fr.yaml b/src/Bundle/ChillPersonBundle/translations/messages+intl-icu.fr.yaml index af85b2217..52acb0d80 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages+intl-icu.fr.yaml +++ b/src/Bundle/ChillPersonBundle/translations/messages+intl-icu.fr.yaml @@ -140,7 +140,12 @@ exports: by_treating_agent: Filtered by treating agent at date: >- Les agents traitant au { agent_at, date, medium }, seulement {agents} - course: + + step_history: + by_date: + description: >- + Changements de statuts filtrés par date: après le { start_date, date, medium } (inclus), avant le { end_date, date, medium } + not_having_address_reference: describe: >- Uniquement les parcours qui ne sont pas localisés à une adresse de référence, à la date du {date_calc, date, medium} diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index ce7f06ab1..206664b63 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -1131,6 +1131,13 @@ export: by_geog_unit: Filtered by person's geographical unit (based on address) computed at %datecalc%, only %units%: Filtré par unité géographique (sur base de l'adresse), calculé le %datecalc%, seulement %units% + step_history: + by_closing_motive + by_date: + title: Filtrer les changements de statut du parcours par date + start_date_label: Changements après le + end_date_label: Changements avant le + person: by_composition: Filter by household composition: Filtrer les usagers par composition du ménage From 97d401b7f67289ec4dc2eefcffc577c6e60a8777 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Mon, 29 Jan 2024 11:37:59 +0100 Subject: [PATCH 04/12] Implement ByStepFilter for AccompanyingPeriodStepHistoryFilters and its tests A new feature has been added, the ByStepFilter, to the Chill project. The ByStepFilter provides a way to filter data in AccompanyingPeriodStepHistoryFilters based on certain steps. In addition, a new test suite has been introduced to ensure the correct functionality of this filter. The necessary translations for completing this feature have also been included. --- .../ByStepFilter.php | 87 +++++++++++++++++++ .../ByStepFilterTest.php | 66 ++++++++++++++ .../translations/messages.fr.yml | 7 +- 3 files changed, 159 insertions(+), 1 deletion(-) create mode 100644 src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingPeriodStepHistoryFilters/ByStepFilter.php create mode 100644 src/Bundle/ChillPersonBundle/Tests/Export/Filter/AccompanyingPeriodStepHistoryFilters/ByStepFilterTest.php diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingPeriodStepHistoryFilters/ByStepFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingPeriodStepHistoryFilters/ByStepFilter.php new file mode 100644 index 000000000..337b27e8a --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingPeriodStepHistoryFilters/ByStepFilter.php @@ -0,0 +1,87 @@ +add('steps', ChoiceType::class, [ + 'choices' => array_combine( + array_map(static fn (string $step): string => 'accompanying_period.'.$step, $steps), + $steps + ), + 'label' => 'export.filter.step_history.by_step.pick_steps', + 'multiple' => true, + 'expanded' => true, + ]); + } + + public function getFormDefaultData(): array + { + return [ + 'steps' => [], + ]; + } + + public function describeAction($data, $format = 'string') + { + return [ + 'export.filter.step_history.by_step.description', + [ + '%steps%' => implode(', ', array_map(fn (string $step) => $this->translator->trans('accompanying_period.'.$step), $data['steps'])), + ], + ]; + } + + public function addRole(): ?string + { + return null; + } + + public function alterQuery(QueryBuilder $qb, $data) + { + $qb + ->andWhere('acpstephistory.step IN (:acpstephistory_by_step_filter_steps)') + ->setParameter('acpstephistory_by_step_filter_steps', $data['steps']); + } + + public function applyOn() + { + return Declarations::ACP_STEP_HISTORY; + } +} diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Filter/AccompanyingPeriodStepHistoryFilters/ByStepFilterTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Filter/AccompanyingPeriodStepHistoryFilters/ByStepFilterTest.php new file mode 100644 index 000000000..a603bd219 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Filter/AccompanyingPeriodStepHistoryFilters/ByStepFilterTest.php @@ -0,0 +1,66 @@ + [AccompanyingPeriod::STEP_CONFIRMED, AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_LONG], + ], + [ + 'steps' => [AccompanyingPeriod::STEP_CLOSED], + ], + ]; + } + + public function getQueryBuilders() + { + self::bootKernel(); + $em = self::$container->get(EntityManagerInterface::class); + + $qb = $em->createQueryBuilder() + ->select('COUNT(DISTINCT acpstephistory.id) As export_result') + ->from(AccompanyingPeriodStepHistory::class, 'acpstephistory') + ->join('acpstephistory.period', 'acp'); + + return [ + $qb, + ]; + } +} diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index 206664b63..e865cab76 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -786,6 +786,8 @@ accompanying_period: DRAFT: Brouillon CONFIRMED: Confirmé CLOSED: Clotûré + CONFIRMED_INACTIVE_SHORT: Hors file active + CONFIRMED_INACTIVE_LONG: Pré-archivé emergency: Urgent occasional: ponctuel regular: régulier @@ -1132,7 +1134,10 @@ export: Filtered by person's geographical unit (based on address) computed at %datecalc%, only %units%: Filtré par unité géographique (sur base de l'adresse), calculé le %datecalc%, seulement %units% step_history: - by_closing_motive + by_step: + title: Filtrer les changements de statut du parcours par étape + pick_steps: Nouvelles étapes + description: "Filtré par étape: seulement %steps%" by_date: title: Filtrer les changements de statut du parcours par date start_date_label: Changements après le From 01785ed49416dad42597c9c46589794528dd7d7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Mon, 29 Jan 2024 12:13:23 +0100 Subject: [PATCH 05/12] Add ByStepAggregator to AccompanyingPeriodStepHistoryAggregators Added a new ByStepAggregator to the AccompanyingPeriodStepHistoryAggregators, allowing to group status changes in the course by step. The corresponding test suite ensures the correct operation of this new class. Updates in the translations file have also been made as part of this addition. --- .../ByStepAggregator.php | 86 +++++++++++++++++++ .../ByStepAggregatorTest.php | 58 +++++++++++++ .../translations/messages.fr.yml | 5 ++ 3 files changed, 149 insertions(+) create mode 100644 src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingPeriodStepHistoryAggregators/ByStepAggregator.php create mode 100644 src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingPeriodStepHistoryAggregators/ByStepAggregatorTest.php diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingPeriodStepHistoryAggregators/ByStepAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingPeriodStepHistoryAggregators/ByStepAggregator.php new file mode 100644 index 000000000..005d012f9 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingPeriodStepHistoryAggregators/ByStepAggregator.php @@ -0,0 +1,86 @@ +translator->trans('accompanying_period.'.$step); + }; + } + + public function getQueryKeys($data) + { + return [ + self::KEY, + ]; + } + + public function getTitle() + { + return 'export.aggregator.step_history.by_step.title'; + } + + public function addRole(): ?string + { + return null; + } + + public function alterQuery(QueryBuilder $qb, $data) + { + $qb + ->addSelect('acpstephistory.step AS '.self::KEY) + ->addGroupBy(self::KEY); + } + + public function applyOn() + { + return Declarations::ACP_STEP_HISTORY; + } +} diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingPeriodStepHistoryAggregators/ByStepAggregatorTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingPeriodStepHistoryAggregators/ByStepAggregatorTest.php new file mode 100644 index 000000000..f71b06351 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingPeriodStepHistoryAggregators/ByStepAggregatorTest.php @@ -0,0 +1,58 @@ +get(EntityManagerInterface::class); + + $qb = $em->createQueryBuilder() + ->select('COUNT(DISTINCT acpstephistory.id) As export_result') + ->from(AccompanyingPeriodStepHistory::class, 'acpstephistory') + ->join('acpstephistory.period', 'acp'); + + return [ + $qb, + ]; + } +} diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index e865cab76..8614a00db 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -1042,6 +1042,11 @@ export: at_date: Date de calcul de l'adresse header: Code postal + step_history: + by_step: + title: Grouper les changements de statut du parcours par étape + header: Nouveau statut du parcours + course: by-user: title: Grouper les parcours par usager participant From bf97b2a50cff31abd657102a19e4f4b66e9d0472 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Mon, 29 Jan 2024 12:31:57 +0100 Subject: [PATCH 06/12] Add ByDateAggregator to AccompanyingPeriodStepHistoryAggregators Implemented a new ByDateAggregator in the AccompanyingPeriodStepHistoryAggregators for grouping status changes by date. A corresponding test suite has been included to verify its function. Necessary translations have also been updated. --- .../ByDateAggregator.php | 90 +++++++++++++++++++ .../ByDateAggregatorTest.php | 61 +++++++++++++ .../translations/messages.fr.yml | 5 +- 3 files changed, 155 insertions(+), 1 deletion(-) create mode 100644 src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingPeriodStepHistoryAggregators/ByDateAggregator.php create mode 100644 src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingPeriodStepHistoryAggregators/ByDateAggregatorTest.php diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingPeriodStepHistoryAggregators/ByDateAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingPeriodStepHistoryAggregators/ByDateAggregator.php new file mode 100644 index 000000000..fbd80c7a5 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingPeriodStepHistoryAggregators/ByDateAggregator.php @@ -0,0 +1,90 @@ +add('frequency', ChoiceType::class, [ + 'choices' => array_combine( + array_map(fn (DateGroupingChoiceEnum $c) => 'export.enum.frequency.'.$c->value, DateGroupingChoiceEnum::cases()), + array_map(fn (DateGroupingChoiceEnum $c) => $c->value, DateGroupingChoiceEnum::cases()), + ), + 'label' => 'export.aggregator.course.by_opening_date.frequency', + 'multiple' => false, + 'expanded' => true, + ]); + } + + public function getFormDefaultData(): array + { + return ['frequency' => DateGroupingChoiceEnum::YEAR->value]; + } + + public function getLabels($key, array $values, mixed $data) + { + return function (?string $value): string { + if ('_header' === $value) { + return 'export.aggregator.step_history.by_date.header'; + } + + if (null === $value || '' === $value) { + return ''; + } + + return $value; + }; + } + + public function getQueryKeys($data) + { + return [self::KEY]; + } + + public function getTitle() + { + return 'export.aggregator.step_history.by_date.title'; + } + + public function addRole(): ?string + { + return null; + } + + public function alterQuery(QueryBuilder $qb, $data) + { + $p = self::KEY; + + $qb->addSelect(sprintf("TO_CHAR(acpstephistory.startDate, '%s') AS {$p}", $data['frequency'])); + $qb->addGroupBy($p); + $qb->addOrderBy($p, 'DESC'); + } + + public function applyOn() + { + return Declarations::ACP_STEP_HISTORY; + } +} diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingPeriodStepHistoryAggregators/ByDateAggregatorTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingPeriodStepHistoryAggregators/ByDateAggregatorTest.php new file mode 100644 index 000000000..74a30d1a6 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingPeriodStepHistoryAggregators/ByDateAggregatorTest.php @@ -0,0 +1,61 @@ + DateGroupingChoiceEnum::YEAR->value, + ], + [ + 'frequency' => DateGroupingChoiceEnum::WEEK->value, + ], + [ + 'frequency' => DateGroupingChoiceEnum::MONTH->value, + ], + ]; + } + + public function getQueryBuilders() + { + self::bootKernel(); + $em = self::$container->get(EntityManagerInterface::class); + + $qb = $em->createQueryBuilder() + ->select('COUNT(DISTINCT acpstephistory.id) As export_result') + ->from(AccompanyingPeriodStepHistory::class, 'acpstephistory') + ->join('acpstephistory.period', 'acp'); + + return [ + $qb, + ]; + } +} diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index 8614a00db..e751dd538 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -1046,7 +1046,10 @@ export: by_step: title: Grouper les changements de statut du parcours par étape header: Nouveau statut du parcours - + by_date: + title: Grouper les changement de statut du parcours par date + header: Date du changement de statut du parcours + date_grouping_label: Grouper par course: by-user: title: Grouper les parcours par usager participant From 568ee079b54f94edee44abe6c4ab22feaae108fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Mon, 29 Jan 2024 12:54:44 +0100 Subject: [PATCH 07/12] Add ByClosingMotiveAggregator on AccompanyingPeriodStepHistory exports and corresponding tests Added a new class ByClosingMotiveAggregator to the AccompanyingPeriodStepHistoryAggregators for grouping status changes by closing motive. This also includes a corresponding test class. Additionally, updated relevant translations in the messages.fr.yml file. --- .../ByClosingMotiveAggregator.php | 84 +++++++++++++++++++ .../ByClosingMotiveAggregatorTest.php | 68 +++++++++++++++ .../translations/messages.fr.yml | 6 +- 3 files changed, 157 insertions(+), 1 deletion(-) create mode 100644 src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingPeriodStepHistoryAggregators/ByClosingMotiveAggregator.php create mode 100644 src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingPeriodStepHistoryAggregators/ByClosingMotiveAggregatorTest.php diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingPeriodStepHistoryAggregators/ByClosingMotiveAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingPeriodStepHistoryAggregators/ByClosingMotiveAggregator.php new file mode 100644 index 000000000..f999a44db --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingPeriodStepHistoryAggregators/ByClosingMotiveAggregator.php @@ -0,0 +1,84 @@ +closingMotiveRepository->find((int) $value)) { + return ''; + } + + return $this->closingMotiveRender->renderString($closingMotive, []); + }; + } + + public function getQueryKeys($data) + { + return [ + self::KEY, + ]; + } + + public function getTitle() + { + return 'export.aggregator.step_history.by_closing_motive.title'; + } + + public function addRole(): ?string + { + return null; + } + + public function alterQuery(QueryBuilder $qb, $data) + { + $qb + ->addSelect('IDENTITY(acpstephistory.closingMotive) AS '.self::KEY) + ->addGroupBy(self::KEY); + } + + public function applyOn() + { + return Declarations::ACP_STEP_HISTORY; + } +} diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingPeriodStepHistoryAggregators/ByClosingMotiveAggregatorTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingPeriodStepHistoryAggregators/ByClosingMotiveAggregatorTest.php new file mode 100644 index 000000000..2ce63af34 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingPeriodStepHistoryAggregators/ByClosingMotiveAggregatorTest.php @@ -0,0 +1,68 @@ +closingMotiveRender = self::$container->get(ClosingMotiveRender::class); + $this->closingMotiveRepository = self::$container->get(ClosingMotiveRepositoryInterface::class); + } + + public function getAggregator() + { + return new ByClosingMotiveAggregator( + $this->closingMotiveRepository, + $this->closingMotiveRender + ); + } + + public function getFormData() + { + return [ + [], + ]; + } + + public function getQueryBuilders() + { + self::bootKernel(); + $em = self::$container->get(EntityManagerInterface::class); + + $qb = $em->createQueryBuilder() + ->select('COUNT(DISTINCT acpstephistory.id) As export_result') + ->from(AccompanyingPeriodStepHistory::class, 'acpstephistory') + ->join('acpstephistory.period', 'acp'); + + return [ + $qb, + ]; + } +} diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index e751dd538..4b3094add 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -1047,9 +1047,13 @@ export: title: Grouper les changements de statut du parcours par étape header: Nouveau statut du parcours by_date: - title: Grouper les changement de statut du parcours par date + title: Grouper les changements de statut du parcours par date header: Date du changement de statut du parcours date_grouping_label: Grouper par + by_closing_motive: + title: Grouper les changements de statut du parcours par motif de clôture + header: Motif de clôture + course: by-user: title: Grouper les parcours par usager participant From 5849d8d670b78ea51f645d656649d4c829792846 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Mon, 29 Jan 2024 13:29:42 +0100 Subject: [PATCH 08/12] fix typo --- src/Bundle/ChillPersonBundle/translations/messages.fr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index 4b3094add..ec6dae622 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -785,7 +785,7 @@ accompanying_period: dates_from_%opening_date%_to_%closing_date%: Ouvert du %opening_date% au %closing_date% DRAFT: Brouillon CONFIRMED: Confirmé - CLOSED: Clotûré + CLOSED: Clôturé CONFIRMED_INACTIVE_SHORT: Hors file active CONFIRMED_INACTIVE_LONG: Pré-archivé emergency: Urgent From 21bd6478adb3b60f07ec5d37f239fdf62bfb0ec4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Mon, 29 Jan 2024 13:30:37 +0100 Subject: [PATCH 09/12] Add DI configuration for the export of period step history data within the ChillPersonBundle This commit adds dependency injection configuration for the export of period step history data within the ChillPersonBundle. It specifically configures exports, filters, and aggregators, all related to the accompanying period step history. Additionally, it updates ChillPersonExtension to load this newly created configuration. --- .../ChillPersonExtension.php | 1 + ...orts_accompanying_period_step_history.yaml | 31 +++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 src/Bundle/ChillPersonBundle/config/services/exports_accompanying_period_step_history.yaml diff --git a/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php b/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php index 3d5c0bc64..ebbfedeb3 100644 --- a/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php +++ b/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php @@ -98,6 +98,7 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac $loader->load('services/exports_accompanying_course.yaml'); $loader->load('services/exports_social_actions.yaml'); $loader->load('services/exports_evaluation.yaml'); + $loader->load('services/exports_accompanying_period_step_history.yaml'); } $loader->load('services/exports_household.yaml'); diff --git a/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_period_step_history.yaml b/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_period_step_history.yaml new file mode 100644 index 000000000..09da707c9 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_period_step_history.yaml @@ -0,0 +1,31 @@ +services: + _defaults: + autowire: true + autoconfigure: true + + # exports + Chill\PersonBundle\Export\Export\CountAccompanyingCourseStepHistory: + tags: + - { name: chill.export, alias: count_acpstephistory } + + # filters + Chill\PersonBundle\Export\Filter\AccompanyingPeriodStepHistoryFilters\ByDateFilter: + tags: + - { name: chill.export_filter, alias: acpstephistory_filter_by_date } + + Chill\PersonBundle\Export\Filter\AccompanyingPeriodStepHistoryFilters\ByStepFilter: + tags: + - { name: chill.export_filter, alias: acpstephistory_filter_by_step } + + # aggregators + Chill\PersonBundle\Export\Aggregator\AccompanyingPeriodStepHistoryAggregators\ByClosingMotiveAggregator: + tags: + - { name: chill.export_aggregator, alias: acpstephistory_agg_by_closing_motive } + + Chill\PersonBundle\Export\Aggregator\AccompanyingPeriodStepHistoryAggregators\ByDateAggregator: + tags: + - { name: chill.export_aggregator, alias: acpstephistory_agg_by_date } + + Chill\PersonBundle\Export\Aggregator\AccompanyingPeriodStepHistoryAggregators\ByStepAggregator: + tags: + - { name: chill.export_aggregator, alias: acpstephistory_agg_by_step } From 86613a9be93b2238bf874cb0431cc8242f434248 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Mon, 29 Jan 2024 13:34:07 +0100 Subject: [PATCH 10/12] Add changie for the whole feature --- .changes/unreleased/Feature-20240129-133319.yaml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changes/unreleased/Feature-20240129-133319.yaml diff --git a/.changes/unreleased/Feature-20240129-133319.yaml b/.changes/unreleased/Feature-20240129-133319.yaml new file mode 100644 index 000000000..ff2b96ebf --- /dev/null +++ b/.changes/unreleased/Feature-20240129-133319.yaml @@ -0,0 +1,5 @@ +kind: Feature +body: 'Add capability to generate export about change of steps of accompanying period, and generate exports for this' +time: 2024-01-29T13:33:19.190365565+01:00 +custom: + Issue: "244" From 4bbad4fc61af62643f011e2df0807e62375dcb36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 7 Feb 2024 15:38:56 +0100 Subject: [PATCH 11/12] fix cs with php-cs-fixer 3.49 --- .../AccompanyingPeriod/AccompanyingPeriodStepHistory.php | 6 +++--- .../ByClosingMotiveAggregator.php | 2 +- .../ByStepAggregatorTest.php | 2 +- .../ByStepFilterTest.php | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/AccompanyingPeriodStepHistory.php b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/AccompanyingPeriodStepHistory.php index fd4d573ce..c25c11e69 100644 --- a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/AccompanyingPeriodStepHistory.php +++ b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/AccompanyingPeriodStepHistory.php @@ -64,7 +64,7 @@ class AccompanyingPeriodStepHistory implements TrackCreationInterface, TrackUpda * * @ORM\JoinColumn(nullable=true) */ - private ?AccompanyingPeriod\ClosingMotive $closingMotive = null; + private ?ClosingMotive $closingMotive = null; public function getEndDate(): ?\DateTimeImmutable { @@ -122,12 +122,12 @@ class AccompanyingPeriodStepHistory implements TrackCreationInterface, TrackUpda return $this; } - public function getClosingMotive(): ?AccompanyingPeriod\ClosingMotive + public function getClosingMotive(): ?ClosingMotive { return $this->closingMotive; } - public function setClosingMotive(?AccompanyingPeriod\ClosingMotive $closingMotive): self + public function setClosingMotive(?ClosingMotive $closingMotive): self { $this->closingMotive = $closingMotive; diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingPeriodStepHistoryAggregators/ByClosingMotiveAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingPeriodStepHistoryAggregators/ByClosingMotiveAggregator.php index f999a44db..b5776ebeb 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingPeriodStepHistoryAggregators/ByClosingMotiveAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingPeriodStepHistoryAggregators/ByClosingMotiveAggregator.php @@ -40,7 +40,7 @@ final readonly class ByClosingMotiveAggregator implements AggregatorInterface public function getLabels($key, array $values, mixed $data) { - return function (null|int|string $value): string { + return function (int|string|null $value): string { if ('_header' === $value) { return 'export.aggregator.step_history.by_closing_motive.header'; } diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingPeriodStepHistoryAggregators/ByStepAggregatorTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingPeriodStepHistoryAggregators/ByStepAggregatorTest.php index f71b06351..65752fea2 100644 --- a/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingPeriodStepHistoryAggregators/ByStepAggregatorTest.php +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingPeriodStepHistoryAggregators/ByStepAggregatorTest.php @@ -27,7 +27,7 @@ class ByStepAggregatorTest extends AbstractAggregatorTest public function getAggregator() { $translator = new class () implements TranslatorInterface { - public function trans(string $id, array $parameters = [], string $domain = null, string $locale = null) + public function trans(string $id, array $parameters = [], ?string $domain = null, ?string $locale = null) { return $id; } diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Filter/AccompanyingPeriodStepHistoryFilters/ByStepFilterTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Filter/AccompanyingPeriodStepHistoryFilters/ByStepFilterTest.php index a603bd219..2924be7e7 100644 --- a/src/Bundle/ChillPersonBundle/Tests/Export/Filter/AccompanyingPeriodStepHistoryFilters/ByStepFilterTest.php +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Filter/AccompanyingPeriodStepHistoryFilters/ByStepFilterTest.php @@ -28,7 +28,7 @@ class ByStepFilterTest extends AbstractFilterTest public function getFilter() { $translator = new class () implements TranslatorInterface { - public function trans(string $id, array $parameters = [], string $domain = null, string $locale = null) + public function trans(string $id, array $parameters = [], ?string $domain = null, ?string $locale = null) { return $id; } From f5f6eb78a2a8608109386cc1cd486758aac098f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 7 Feb 2024 16:00:55 +0100 Subject: [PATCH 12/12] fix incorrect merge of messages+intl-icu.fr.yaml --- .../translations/messages+intl-icu.fr.yaml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/translations/messages+intl-icu.fr.yaml b/src/Bundle/ChillPersonBundle/translations/messages+intl-icu.fr.yaml index 52acb0d80..28d3d1274 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages+intl-icu.fr.yaml +++ b/src/Bundle/ChillPersonBundle/translations/messages+intl-icu.fr.yaml @@ -136,6 +136,10 @@ exports: Filtered by person\'s geographical unit (based on address) computed at date, only units: "Filtré par zone géographique sur base de l'adresse, calculé à {datecalc, date, short}, seulement les zones suivantes: {units}" filter: + course: + not_having_address_reference: + describe: >- + Uniquement les parcours qui ne sont pas localisés à une adresse de référence, à la date du {date_calc, date, medium} work: by_treating_agent: Filtered by treating agent at date: >- @@ -146,9 +150,6 @@ exports: description: >- Changements de statuts filtrés par date: après le { start_date, date, medium } (inclus), avant le { end_date, date, medium } - not_having_address_reference: - describe: >- - Uniquement les parcours qui ne sont pas localisés à une adresse de référence, à la date du {date_calc, date, medium} 'total persons matching the search pattern': >- { total, plural,