From af6bee249760b129c2fab4c34658e2f53cd7328e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 15 Nov 2023 12:14:55 +0100 Subject: [PATCH] Export: add an export which count persons on activity --- .../unreleased/Feature-20231115-121431.yaml | 5 + .../LinkedToACP/CountPersonsOnActivity.php | 138 ++++++++++++++++++ .../CountPersonsOnActivityTest.php | 54 +++++++ .../config/services/export.yaml | 4 + .../translations/messages.fr.yml | 5 + 5 files changed, 206 insertions(+) create mode 100644 .changes/unreleased/Feature-20231115-121431.yaml create mode 100644 src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/CountPersonsOnActivity.php create mode 100644 src/Bundle/ChillActivityBundle/Tests/Export/Export/LinkedToACP/CountPersonsOnActivityTest.php diff --git a/.changes/unreleased/Feature-20231115-121431.yaml b/.changes/unreleased/Feature-20231115-121431.yaml new file mode 100644 index 000000000..6f7e5a33f --- /dev/null +++ b/.changes/unreleased/Feature-20231115-121431.yaml @@ -0,0 +1,5 @@ +kind: Feature +body: 'Export: add an export which count persons on activity' +time: 2023-11-15T12:14:31.515840946+01:00 +custom: + Issue: "206" diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/CountPersonsOnActivity.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/CountPersonsOnActivity.php new file mode 100644 index 000000000..c49b9d4ad --- /dev/null +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/CountPersonsOnActivity.php @@ -0,0 +1,138 @@ +repository = $em->getRepository(Activity::class); + $this->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.count_person_on_activity.description'; + } + + public function getGroup(): string + { + return 'Exports of activities linked to an accompanying period'; + } + + public function getLabels($key, array $values, $data) + { + if ('export_count_activity' !== $key) { + throw new \LogicException("the key {$key} is not used by this export"); + } + + return static fn ($value) => '_header' === $value ? 'export.export.count_person_on_activity.header' : $value; + } + + public function getQueryKeys($data): array + { + return ['export_count_activity']; + } + + public function getResult($query, $data) + { + return $query->getQuery()->getResult(Query::HYDRATE_SCALAR); + } + + public function getTitle(): string + { + return 'export.export.count_person_on_activity.title'; + } + + public function getType(): string + { + return Declarations::ACTIVITY; + } + + public function initiateQuery(array $requiredModifiers, array $acl, array $data = []) + { + $centers = array_map(static fn ($el) => $el['center'], $acl); + + $qb = $this->repository + ->createQueryBuilder('activity') + ->join('activity.persons', 'person') + ->join('activity.accompanyingPeriod', 'acp'); + + if ($this->filterStatsByCenters) { + $qb + ->andWhere( + $qb->expr()->exists( + 'SELECT 1 FROM '.AccompanyingPeriodParticipation::class.' acl_count_part + JOIN '.PersonCenterHistory::class.' acl_count_person_history WITH IDENTITY(acl_count_person_history.person) = IDENTITY(acl_count_part.person) + WHERE acl_count_part.accompanyingPeriod = acp.id AND acl_count_person_history.center IN (:authorized_centers) + ' + ) + ) + ->setParameter('authorized_centers', $centers); + } + + AccompanyingCourseExportHelper::addClosingMotiveExclusionClause($qb); + + $qb->select('COUNT(DISTINCT person.id) as export_count_activity'); + + return $qb; + } + + public function requiredRole(): string + { + return ActivityStatsVoter::STATS; + } + + public function supportsModifiers(): array + { + return [ + Declarations::ACTIVITY, + Declarations::ACTIVITY_ACP, + PersonDeclarations::ACP_TYPE, + PersonDeclarations::PERSON_TYPE, + ]; + } +} diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Export/LinkedToACP/CountPersonsOnActivityTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Export/LinkedToACP/CountPersonsOnActivityTest.php new file mode 100644 index 000000000..25d6643fb --- /dev/null +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Export/LinkedToACP/CountPersonsOnActivityTest.php @@ -0,0 +1,54 @@ +get(EntityManagerInterface::class); + + yield new CountPersonsOnActivity($em, $this->getParameters(true)); + yield new CountPersonsOnActivity($em, $this->getParameters(false)); + } + + public function getFormData() + { + return [[]]; + } + + public function getModifiersCombination() + { + return [[ + Declarations::ACTIVITY, + Declarations::ACTIVITY_ACP, + PersonDeclarations::ACP_TYPE, + PersonDeclarations::PERSON_TYPE, + ]]; + } +} diff --git a/src/Bundle/ChillActivityBundle/config/services/export.yaml b/src/Bundle/ChillActivityBundle/config/services/export.yaml index dcc6bec17..52294be40 100644 --- a/src/Bundle/ChillActivityBundle/config/services/export.yaml +++ b/src/Bundle/ChillActivityBundle/config/services/export.yaml @@ -16,6 +16,10 @@ services: tags: - { name: chill.export, alias: 'list_activity_linked_to_person' } + Chill\ActivityBundle\Export\Export\LinkedToACP\CountPersonsOnActivity: + tags: + - { name: chill.export, alias: 'count_person_on_activity' } + chill.activity.export.count_activity_linked_to_acp: class: Chill\ActivityBundle\Export\Export\LinkedToACP\CountActivity tags: diff --git a/src/Bundle/ChillActivityBundle/translations/messages.fr.yml b/src/Bundle/ChillActivityBundle/translations/messages.fr.yml index 52c5366a7..036f75ce3 100644 --- a/src/Bundle/ChillActivityBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillActivityBundle/translations/messages.fr.yml @@ -332,6 +332,11 @@ docgen: myWorksOnly: Prendre en compte uniquement les actions d'accompagnement dont je suis référent export: + export: + count_person_on_activity: + title: Nombre d'usagers concernés par les échanges + description: Compte le nombre d'usagers concernés par les échanges. Si un usager est présent dans plusieurs échanges, il n'est comptabilisé qu'une seule fois. + header: Nombre d'usagers concernés par des échanges list: activity: users name: Nom des utilisateurs