diff --git a/.changes/unreleased/Feature-20231114-143611.yaml b/.changes/unreleased/Feature-20231114-143611.yaml new file mode 100644 index 000000000..1da6fd5c8 --- /dev/null +++ b/.changes/unreleased/Feature-20231114-143611.yaml @@ -0,0 +1,5 @@ +kind: Feature +body: Create export for the average duration of social work actions +time: 2023-11-14T14:36:11.797238275+01:00 +custom: + Issue: "202" diff --git a/src/Bundle/ChillPersonBundle/Export/Export/AvgDurationAPWorkPersonAssociatedOnAccompanyingPeriod.php b/src/Bundle/ChillPersonBundle/Export/Export/AvgDurationAPWorkPersonAssociatedOnAccompanyingPeriod.php new file mode 100644 index 000000000..ad3f8f745 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Export/Export/AvgDurationAPWorkPersonAssociatedOnAccompanyingPeriod.php @@ -0,0 +1,131 @@ +filterStatsByCenters = $parameterBag->get('chill_main')['acl']['filter_stats_by_center']; + } + + public function buildForm(FormBuilderInterface $builder) {} + + public function getFormDefaultData(): array + { + return []; + } + + public function getAllowedFormattersTypes(): array + { + return [FormatterInterface::TYPE_TABULAR]; + } + + public function getDescription(): string + { + return 'export.export.avg_duration_acpw_associate_on_period.description'; + } + + public function getGroup(): string + { + return 'Exports of social work actions'; + } + + public function getLabels($key, array $values, $data) + { + if ('export_result' !== $key) { + throw new \LogicException("the key {$key} is not used by this export"); + } + + return static fn ($value) => '_header' === $value ? 'export.export.avg_duration_acpw_associate_on_period.header' : $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.avg_duration_acpw_associate_on_period.title'; + } + + public function getType(): string + { + return Declarations::SOCIAL_WORK_ACTION_TYPE; + } + + public function initiateQuery(array $requiredModifiers, array $acl, array $data = []) + { + $centers = array_map(static fn ($el) => $el['center'], $acl); + + $qb = $this->accompanyingPeriodWorkRepository->createQueryBuilder('acpw'); + + $qb + ->join('acpw.accompanyingPeriod', 'acp') + ->join('acp.participations', 'acppart') + ->join('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); + } + + $qb->select('AVG(DATE_DIFF(COALESCE(acpw.endDate, CURRENT_DATE()), acpw.startDate)) AS export_result'); + + AccompanyingCourseExportHelper::addClosingMotiveExclusionClause($qb); + + return $qb; + } + + public function requiredRole(): string + { + return AccompanyingPeriodVoter::STATS; + } + + public function supportsModifiers(): array + { + return [ + Declarations::SOCIAL_WORK_ACTION_TYPE, + Declarations::ACP_TYPE, + Declarations::PERSON_TYPE, + ]; + } +} diff --git a/src/Bundle/ChillPersonBundle/Export/Export/AvgDurationAPWorkPersonAssociatedOnWork.php b/src/Bundle/ChillPersonBundle/Export/Export/AvgDurationAPWorkPersonAssociatedOnWork.php new file mode 100644 index 000000000..8d34837ae --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Export/Export/AvgDurationAPWorkPersonAssociatedOnWork.php @@ -0,0 +1,130 @@ +filterStatsByCenters = $parameterBag->get('chill_main')['acl']['filter_stats_by_center']; + } + + public function buildForm(FormBuilderInterface $builder) {} + + public function getFormDefaultData(): array + { + return []; + } + + public function getAllowedFormattersTypes(): array + { + return [FormatterInterface::TYPE_TABULAR]; + } + + public function getDescription(): string + { + return 'export.export.avg_duration_acpw_associate_on_work.description'; + } + + public function getGroup(): string + { + return 'Exports of social work actions'; + } + + public function getLabels($key, array $values, $data) + { + if ('export_result' !== $key) { + throw new \LogicException("the key {$key} is not used by this export"); + } + + return static fn ($value) => '_header' === $value ? 'export.export.avg_duration_acpw_associate_on_work.header' : $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.avg_duration_acpw_associate_on_work.title'; + } + + public function getType(): string + { + return Declarations::SOCIAL_WORK_ACTION_TYPE; + } + + public function initiateQuery(array $requiredModifiers, array $acl, array $data = []) + { + $centers = array_map(static fn ($el) => $el['center'], $acl); + + $qb = $this->accompanyingPeriodWorkRepository->createQueryBuilder('acpw'); + + $qb + ->join('acpw.accompanyingPeriod', 'acp') + ->join('acpw.persons', '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); + } + + $qb->select('AVG(DATE_DIFF(COALESCE(acpw.endDate, CURRENT_DATE()), acpw.startDate)) AS export_result'); + + AccompanyingCourseExportHelper::addClosingMotiveExclusionClause($qb); + + return $qb; + } + + public function requiredRole(): string + { + return AccompanyingPeriodVoter::STATS; + } + + public function supportsModifiers(): array + { + return [ + Declarations::SOCIAL_WORK_ACTION_TYPE, + Declarations::ACP_TYPE, + Declarations::PERSON_TYPE, + ]; + } +} diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Export/AvgDurationAPWorkPersonAssociatedOnAccompanyingPeriodTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Export/AvgDurationAPWorkPersonAssociatedOnAccompanyingPeriodTest.php new file mode 100644 index 000000000..bd1bbdfd4 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Export/AvgDurationAPWorkPersonAssociatedOnAccompanyingPeriodTest.php @@ -0,0 +1,53 @@ +get(AccompanyingPeriodWorkRepository::class); + + yield new AvgDurationAPWorkPersonAssociatedOnAccompanyingPeriod($this->getParameters(true), $repository); + yield new AvgDurationAPWorkPersonAssociatedOnAccompanyingPeriod($this->getParameters(false), $repository); + } + + public function getFormData() + { + return []; + } + + public function getModifiersCombination() + { + return [ + [ + Declarations::SOCIAL_WORK_ACTION_TYPE, + Declarations::ACP_TYPE, + Declarations::PERSON_TYPE, + ]]; + } +} diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Export/AvgDurationAPWorkPersonAssociatedOnWorkTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Export/AvgDurationAPWorkPersonAssociatedOnWorkTest.php new file mode 100644 index 000000000..647026f8a --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Export/AvgDurationAPWorkPersonAssociatedOnWorkTest.php @@ -0,0 +1,53 @@ +get(AccompanyingPeriodWorkRepository::class); + + yield new AvgDurationAPWorkPersonAssociatedOnAccompanyingPeriod($this->getParameters(true), $repository); + yield new AvgDurationAPWorkPersonAssociatedOnAccompanyingPeriod($this->getParameters(false), $repository); + } + + public function getFormData() + { + return []; + } + + public function getModifiersCombination() + { + return [ + [ + Declarations::SOCIAL_WORK_ACTION_TYPE, + Declarations::ACP_TYPE, + Declarations::PERSON_TYPE, + ]]; + } +} diff --git a/src/Bundle/ChillPersonBundle/config/services/exports_social_actions.yaml b/src/Bundle/ChillPersonBundle/config/services/exports_social_actions.yaml index f813455d8..3e6f12fe1 100644 --- a/src/Bundle/ChillPersonBundle/config/services/exports_social_actions.yaml +++ b/src/Bundle/ChillPersonBundle/config/services/exports_social_actions.yaml @@ -22,6 +22,14 @@ services: tags: - { name: chill.export, alias: list_social_work_actions_associate_person_work } + Chill\PersonBundle\Export\Export\AvgDurationAPWorkPersonAssociatedOnAccompanyingPeriod: + tags: + - { name: chill.export, alias: avg_duration_social_work_actions_person_associated_on_period } + + Chill\PersonBundle\Export\Export\AvgDurationAPWorkPersonAssociatedOnWork: + tags: + - { name: chill.export, alias: avg_duration_social_work_actions_person_associated_on_work } + ## FILTERS chill.person.export.filter_social_work_type: class: Chill\PersonBundle\Export\Filter\SocialWorkFilters\SocialWorkTypeFilter diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index ceebe7d1b..71b428920 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -379,7 +379,10 @@ Create an average of accompanying courses duration of each person participation Closingdate to apply: Date de fin à prendre en compte lorsque le parcours n'est pas clotûré Exports of social work actions: Exports des actions d'accompagnement - +Count social work actions: Nombre d'actions +Count social work actions by various parameters: Compte le nombre d'actions d'accompagnement en fonction de différents filtres. +Average duration of social work actions: Durée moyenne des actions +Calculate the average duration of social work actions: Moyenne de la durée des actions. Exports of evaluations: Exports des évaluations Count evaluations: Nombre d'évaluations @@ -1008,6 +1011,16 @@ export: description: Compte le nombre d'actions d'accompagnement avec des filtres et regroupements possibles sur les usagers, les parcours et les actions. Les filtres et regroupements agissent sur les usagers concernés par l'action. header: Nombre d'actions + avg_duration_acpw_associate_on_period: + title: Durée moyenne des actions d'accompagnements, filtres et regroupement sur les usagers du parcours + header: Durée moyenne des actions d'accompagnements + description: Calcule la moyenne durée des actions d'accompagnements avec des filtres et regroupements possibles sur les usagers, les parcours et les actions. Les filtres et regroupements agissent sur les usagers concernés par le parcours de l'action. + + avg_duration_acpw_associate_on_work: + title: Durée moyenne des actions d'accompagnements, filtres et regroupement sur les usagers de l'action + header: Durée moyenne des actions d'accompagnements + description: Calcule la moyenne durée des actions d'accompagnements avec des filtres et regroupements possibles sur les usagers, les parcours et les actions. Les filtres et regroupements agissent sur les usagers concernés par l'action. + aggregator: person: by_household_composition: