diff --git a/.changes/unreleased/Feature-20231109-170655.yaml b/.changes/unreleased/Feature-20231109-170655.yaml new file mode 100644 index 000000000..d4f793607 --- /dev/null +++ b/.changes/unreleased/Feature-20231109-170655.yaml @@ -0,0 +1,5 @@ +kind: Feature +body: 'Export: add an aggregator "group activities by presence"' +time: 2023-11-09T17:06:55.876380883+01:00 +custom: + Issue: "199" diff --git a/.changes/unreleased/Feature-20231109-173500.yaml b/.changes/unreleased/Feature-20231109-173500.yaml new file mode 100644 index 000000000..e356259b4 --- /dev/null +++ b/.changes/unreleased/Feature-20231109-173500.yaml @@ -0,0 +1,5 @@ +kind: Feature +body: 'Export: add a filter "filter activity by activity presence"' +time: 2023-11-09T17:35:00.158055832+01:00 +custom: + Issue: "199" diff --git a/.changes/unreleased/Feature-20231110-144056.yaml b/.changes/unreleased/Feature-20231110-144056.yaml new file mode 100644 index 000000000..f263d14c6 --- /dev/null +++ b/.changes/unreleased/Feature-20231110-144056.yaml @@ -0,0 +1,6 @@ +kind: Feature +body: 'Export: add an aggregator "group activities by person" (only for the activities + saved in a person context)' +time: 2023-11-10T14:40:56.93459414+01:00 +custom: + Issue: "199" diff --git a/.changes/unreleased/Feature-20231110-171720.yaml b/.changes/unreleased/Feature-20231110-171720.yaml new file mode 100644 index 000000000..69135e62c --- /dev/null +++ b/.changes/unreleased/Feature-20231110-171720.yaml @@ -0,0 +1,5 @@ +kind: Feature +body: 'Export: add a new aggregator "group peoples by postal code"' +time: 2023-11-10T17:17:20.236876015+01:00 +custom: + Issue: "199" diff --git a/.changes/unreleased/Feature-20231110-175928.yaml b/.changes/unreleased/Feature-20231110-175928.yaml new file mode 100644 index 000000000..a42e1210d --- /dev/null +++ b/.changes/unreleased/Feature-20231110-175928.yaml @@ -0,0 +1,7 @@ +kind: Feature +body: 'Export: split export about person on accompanying period work: one with the + people associated with the work, another one with the people associated with the + accompanying period' +time: 2023-11-10T17:59:28.388361356+01:00 +custom: + Issue: "200" diff --git a/.changes/unreleased/Fixed-20231113-120855.yaml b/.changes/unreleased/Fixed-20231113-120855.yaml new file mode 100644 index 000000000..6a2003d3d --- /dev/null +++ b/.changes/unreleased/Fixed-20231113-120855.yaml @@ -0,0 +1,5 @@ +kind: Fixed +body: 'Export: fix typo in filter "filter accompanying period work on end date"' +time: 2023-11-13T12:08:55.509927824+01:00 +custom: + Issue: "" diff --git a/.changes/unreleased/Fixed-20231113-152621.yaml b/.changes/unreleased/Fixed-20231113-152621.yaml new file mode 100644 index 000000000..e897fec30 --- /dev/null +++ b/.changes/unreleased/Fixed-20231113-152621.yaml @@ -0,0 +1,5 @@ +kind: Fixed +body: 'Export: Fix failure in export linked to household' +time: 2023-11-13T15:26:21.891117274+01:00 +custom: + Issue: "189" diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityPresenceAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityPresenceAggregator.php new file mode 100644 index 000000000..17e16357a --- /dev/null +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityPresenceAggregator.php @@ -0,0 +1,72 @@ +activityPresenceRepository->find($value)) { + return ''; + } + + return $this->translatableStringHelper->localize($presence->getName()); + }; + } + + public function getQueryKeys($data) + { + return ['activity_presence_aggregator_attendee']; + } + + public function getTitle(): string + { + return 'export.aggregator.activity.by_activity_presence.Group activity by presence'; + } + + public function addRole(): ?string + { + return null; + } + + public function alterQuery(QueryBuilder $qb, $data): void + { + $qb->addSelect('IDENTITY(activity.attendee) AS activity_presence_aggregator_attendee'); + $qb->addGroupBy('activity_presence_aggregator_attendee'); + } + + public function applyOn() + { + return Declarations::ACTIVITY; + } +} diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/PersonAggregators/PersonAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/PersonAggregators/PersonAggregator.php new file mode 100644 index 000000000..c7a3bd6b5 --- /dev/null +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/PersonAggregators/PersonAggregator.php @@ -0,0 +1,65 @@ +labelPersonHelper->getLabel($key, $values, 'export.aggregator.person.by_person.person'); + } + + public function getQueryKeys($data) + { + return ['activity_by_person_agg']; + } + + public function getTitle() + { + return 'export.aggregator.person.by_person.title'; + } + + public function addRole(): ?string + { + return null; + } + + public function alterQuery(QueryBuilder $qb, $data) + { + $qb + ->addSelect('IDENTITY(activity.person) AS activity_by_person_agg') + ->addGroupBy('activity_by_person_agg'); + } + + public function applyOn() + { + return Declarations::ACTIVITY_PERSON; + } +} diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ActivityPresenceFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ActivityPresenceFilter.php new file mode 100644 index 000000000..201b9f810 --- /dev/null +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ActivityPresenceFilter.php @@ -0,0 +1,82 @@ +add('presences', EntityType::class, [ + 'class' => ActivityPresence::class, + 'choice_label' => fn (ActivityPresence $presence) => $this->translatableStringHelper->localize($presence->getName()) + .($presence->isActive() ? '' : ' ('.$this->translator->trans('inactive').')'), + 'multiple' => true, + 'expanded' => true, + 'label' => 'export.filter.activity.by_presence.presences', + ]); + } + + public function getFormDefaultData(): array + { + return []; + } + + public function describeAction($data, $format = 'string') + { + $presences = array_map( + fn (ActivityPresence $presence) => $this->translatableStringHelper->localize($presence->getName()), + $data['presences'] instanceof Collection ? $data['presences']->toArray() : $data['presences'] + ); + + return [ + 'export.filter.activity.by_presence.Filtered by activity presence: only %presences%', + ['%presences%' => implode(', ', $presences)], + ]; + } + + public function addRole(): ?string + { + return null; + } + + public function alterQuery(QueryBuilder $qb, $data) + { + $qb + ->andWhere('activity.attendee IN (:activity_presence_filter_presences)') + ->setParameter('activity_presence_filter_presences', $data['presences']); + } + + public function applyOn() + { + return Declarations::ACTIVITY; + } +} diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ActivityPresenceAggregatorTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ActivityPresenceAggregatorTest.php new file mode 100644 index 000000000..ea2bafb0d --- /dev/null +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ActivityPresenceAggregatorTest.php @@ -0,0 +1,62 @@ +translatableStringHelper = self::$container->get(TranslatableStringHelperInterface::class); + $this->activityPresenceRepository = self::$container->get(ActivityPresenceRepositoryInterface::class); + } + + public function getAggregator() + { + return new ActivityPresenceAggregator($this->activityPresenceRepository, $this->translatableStringHelper); + } + + public function getFormData() + { + return [ + [], + ]; + } + + public function getQueryBuilders() + { + self::bootKernel(); + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('count(activity.id)') + ->from(Activity::class, 'activity'), + ]; + } +} diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/PersonAggregators/PersonAggregatorTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/PersonAggregators/PersonAggregatorTest.php new file mode 100644 index 000000000..388f13793 --- /dev/null +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/PersonAggregators/PersonAggregatorTest.php @@ -0,0 +1,57 @@ +labelPersonHelper = self::$container->get(LabelPersonHelper::class); + } + + public function getAggregator() + { + return new PersonAggregator($this->labelPersonHelper); + } + + public function getFormData() + { + return [[]]; + } + + public function getQueryBuilders() + { + self::bootKernel(); + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('count(activity.id)') + ->from(Activity::class, 'activity'), + ]; + } +} diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ActivityPresenceFilterTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ActivityPresenceFilterTest.php new file mode 100644 index 000000000..6fc3d10d8 --- /dev/null +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ActivityPresenceFilterTest.php @@ -0,0 +1,76 @@ +translator = self::$container->get(TranslatorInterface::class); + $this->translatableStringHelper = self::$container->get(TranslatableStringHelperInterface::class); + } + + public function getFilter() + { + return new ActivityPresenceFilter($this->translatableStringHelper, $this->translator); + } + + public function getFormData() + { + self::bootKernel(); + + $presences = self::$container->get(ActivityPresenceRepositoryInterface::class) + ->findAll(); + + return [ + [ + 'presences' => $presences, + ], + [ + 'presences' => new ArrayCollection($presences), + ], + ]; + } + + public function getQueryBuilders() + { + self::bootKernel(); + + $em = self::$container->get(EntityManagerInterface::class); + + yield $em->createQueryBuilder() + ->select('count(activity.id)') + ->from(Activity::class, 'activity'); + + self::ensureKernelShutdown(); + } +} diff --git a/src/Bundle/ChillActivityBundle/config/services/export.yaml b/src/Bundle/ChillActivityBundle/config/services/export.yaml index 29f7c2625..dcc6bec17 100644 --- a/src/Bundle/ChillActivityBundle/config/services/export.yaml +++ b/src/Bundle/ChillActivityBundle/config/services/export.yaml @@ -135,6 +135,11 @@ services: tags: - { name: chill.export_filter, alias: 'period_having_activity_betw_dates_filter' } + Chill\ActivityBundle\Export\Filter\ActivityPresenceFilter: + tags: + - { name: chill.export_filter, alias: 'activity_presence_filter' } + + ## Aggregators Chill\ActivityBundle\Export\Aggregator\PersonAggregators\ActivityReasonAggregator: tags: @@ -218,3 +223,11 @@ services: Chill\ActivityBundle\Export\Aggregator\ACPAggregators\ByActivityTypeAggregator: tags: - { name: chill.export_aggregator, alias: acp_by_activity_type_aggregator } + + Chill\ActivityBundle\Export\Aggregator\ActivityPresenceAggregator: + tags: + - { name: chill.export_aggregator, alias: activity_presence_agg } + + Chill\ActivityBundle\Export\Aggregator\PersonAggregators\PersonAggregator: + tags: + - { name: chill.export_aggregator, alias: activity_person_agg } diff --git a/src/Bundle/ChillActivityBundle/translations/messages.fr.yml b/src/Bundle/ChillActivityBundle/translations/messages.fr.yml index 759d222c1..52c5366a7 100644 --- a/src/Bundle/ChillActivityBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillActivityBundle/translations/messages.fr.yml @@ -389,8 +389,16 @@ export: Sent or received: Envoyé ou reçu is sent: envoyé is received: reçu + by_presence: + Filter activity by activity presence: Filtrer les échanges par présence de l'usager + presences: Présences + 'Filtered by activity presence: only %presences%': 'Filtré par présence de l''usager: seulement %presences%' aggregator: + person: + by_person: + title: Grouper les échanges par usager (dossier d'usager dans lequel l'échange est enregistré) + person: Usager acp: by_activity_type: title: Grouper les parcours par type d'échange @@ -421,6 +429,9 @@ export: by_persons: Group activity by persons: Grouper les échanges par usager participant Persons: Usagers participants + by_activity_presence: + Group activity by presence: Grouper les échanges par présence de l'usager + header: Présence de(s) usager(s) generic_doc: filter: diff --git a/src/Bundle/ChillMainBundle/Controller/ExportController.php b/src/Bundle/ChillMainBundle/Controller/ExportController.php index 190d5f1bf..d318fcc58 100644 --- a/src/Bundle/ChillMainBundle/Controller/ExportController.php +++ b/src/Bundle/ChillMainBundle/Controller/ExportController.php @@ -304,7 +304,7 @@ class ExportController extends AbstractController FormType::class, $defaultFormData, [ - 'method' => $isGenerate ? 'GET' : 'POST', + 'method' => $isGenerate ? Request::METHOD_GET : Request::METHOD_POST, 'csrf_protection' => !$isGenerate, ] ); @@ -352,7 +352,7 @@ class ExportController extends AbstractController $form = $this->createCreateFormExport($alias, 'export', $data, $savedExport); - if ('POST' === $request->getMethod()) { + if (Request::METHOD_POST === $request->getMethod()) { $form->handleRequest($request); if ($form->isValid()) { @@ -406,7 +406,7 @@ class ExportController extends AbstractController $form = $this->createCreateFormExport($alias, 'formatter', $data, $savedExport); - if ('POST' === $request->getMethod()) { + if (Request::METHOD_POST === $request->getMethod()) { $form->handleRequest($request); if ($form->isValid()) { @@ -536,7 +536,7 @@ class ExportController extends AbstractController $form = $this->createCreateFormExport($alias, 'centers', [], $savedExport); - if ('POST' === $request->getMethod()) { + if (Request::METHOD_POST === $request->getMethod()) { $form->handleRequest($request); if ($form->isValid()) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/HouseholdAggregators/ChildrenNumberAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/HouseholdAggregators/ChildrenNumberAggregator.php index b73b2e600..cea3de7dd 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/HouseholdAggregators/ChildrenNumberAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/HouseholdAggregators/ChildrenNumberAggregator.php @@ -19,11 +19,10 @@ use Chill\PersonBundle\Export\Declarations; use Doctrine\ORM\Query\Expr; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Contracts\Translation\TranslatorInterface; class ChildrenNumberAggregator implements AggregatorInterface { - public function __construct(private readonly TranslatorInterface $translator, private readonly RollingDateConverterInterface $rollingDateConverter) {} + public function __construct(private readonly RollingDateConverterInterface $rollingDateConverter) {} public function addRole(): ?string { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/PostalCodeAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/PostalCodeAggregator.php new file mode 100644 index 000000000..6f8978ad4 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/PostalCodeAggregator.php @@ -0,0 +1,99 @@ +add('calc_date', PickRollingDateType::class, [ + 'label' => 'export.aggregator.person.by_postal_code.at_date', + ]); + } + + public function getFormDefaultData(): array + { + return ['calc_date' => new RollingDate(RollingDate::T_TODAY)]; + } + + public function getLabels($key, array $values, mixed $data) + { + return function (null|int|string $value): string { + if ('_header' === $value) { + return 'export.aggregator.person.by_postal_code.header'; + } + + if (null === $value) { + return ''; + } + + return $value; + }; + } + + public function getQueryKeys($data) + { + return [self::PREFIX.'_postal_code_code', self::PREFIX.'_postal_code_label']; + } + + public function getTitle() + { + return 'export.aggregator.person.by_postal_code.title'; + } + + public function addRole(): ?string + { + return null; + } + + public function alterQuery(QueryBuilder $qb, $data) + { + $p = self::PREFIX; + + $qb + ->leftJoin( + 'person.householdAddresses', + "{$p}_household_addresses", + Join::WITH, + "{$p}_household_addresses.validFrom <= :{$p}_calc_date AND ({$p}_household_addresses.validTo IS NULL OR {$p}_household_addresses.validTo > :{$p}_calc_date)" + ) + ->setParameter("{$p}_calc_date", $this->rollingDateConverter->convert($data['calc_date'])) + ->leftJoin("{$p}_household_addresses.address", "{$p}_address") + ->leftJoin("{$p}_address.postcode", "{$p}_postal_code") + ->addSelect("{$p}_postal_code.code AS {$p}_postal_code_code") + ->addSelect("{$p}_postal_code.name AS {$p}_postal_code_label") + ->addGroupBy("{$p}_postal_code_code") + ->addGroupBy("{$p}_postal_code_label") + ; + } + + public function applyOn() + { + return Declarations::PERSON_TYPE; + } +} diff --git a/src/Bundle/ChillPersonBundle/Export/Export/CountAccompanyingPeriodWork.php b/src/Bundle/ChillPersonBundle/Export/Export/CountAccompanyingPeriodWorkAssociatePersonOnAccompanyingPeriod.php similarity index 90% rename from src/Bundle/ChillPersonBundle/Export/Export/CountAccompanyingPeriodWork.php rename to src/Bundle/ChillPersonBundle/Export/Export/CountAccompanyingPeriodWorkAssociatePersonOnAccompanyingPeriod.php index e274ac5cd..a73e4f037 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/CountAccompanyingPeriodWork.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/CountAccompanyingPeriodWorkAssociatePersonOnAccompanyingPeriod.php @@ -25,7 +25,7 @@ use Doctrine\ORM\QueryBuilder; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; use Symfony\Component\Form\FormBuilderInterface; -class CountAccompanyingPeriodWork implements ExportInterface, GroupedExportInterface +class CountAccompanyingPeriodWorkAssociatePersonOnAccompanyingPeriod implements ExportInterface, GroupedExportInterface { private readonly bool $filterStatsByCenters; @@ -53,7 +53,7 @@ class CountAccompanyingPeriodWork implements ExportInterface, GroupedExportInter public function getDescription(): string { - return 'Count social work actions by various parameters'; + return 'export.export.count_accompanying_period_work_associate_person.description'; } public function getGroup(): string @@ -68,7 +68,7 @@ class CountAccompanyingPeriodWork implements ExportInterface, GroupedExportInter } $labels = array_combine($values, $values); - $labels['_header'] = $this->getTitle(); + $labels['_header'] = 'export.export.count_accompanying_period_work_associate_person.header'; return static fn ($value) => $labels[$value]; } @@ -85,7 +85,7 @@ class CountAccompanyingPeriodWork implements ExportInterface, GroupedExportInter public function getTitle(): string { - return 'Count social work actions'; + return 'export.export.count_accompanying_period_work_associate_person.title'; } public function getType(): string diff --git a/src/Bundle/ChillPersonBundle/Export/Export/CountAccompanyingPeriodWorkAssociatePersonOnWork.php b/src/Bundle/ChillPersonBundle/Export/Export/CountAccompanyingPeriodWorkAssociatePersonOnWork.php new file mode 100644 index 000000000..4f43a78b0 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Export/Export/CountAccompanyingPeriodWorkAssociatePersonOnWork.php @@ -0,0 +1,139 @@ +filterStatsByCenters = $parameterBag->get('chill_main')['acl']['filter_stats_by_center']; + } + + public function buildForm(FormBuilderInterface $builder): void + { + // No form necessary? + } + + public function getFormDefaultData(): array + { + return []; + } + + public function getAllowedFormattersTypes(): array + { + return [FormatterInterface::TYPE_TABULAR]; + } + + public function getDescription(): string + { + return 'export.export.count_accompanying_period_work_associate_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"); + } + + $labels = array_combine($values, $values); + $labels['_header'] = 'export.export.count_accompanying_period_work_associate_work.header'; + + return static fn ($value) => $labels[$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.count_accompanying_period_work_associate_work.title'; + } + + public function getType(): string + { + return Declarations::SOCIAL_WORK_ACTION_TYPE; + } + + public function initiateQuery(array $requiredModifiers, array $acl, array $data = []): QueryBuilder + { + $centers = array_map(static fn ($el) => $el['center'], $acl); + + $qb = $this->em->createQueryBuilder(); + + $qb + ->from(AccompanyingPeriod\AccompanyingPeriodWork::class, 'acpw') + ->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('COUNT(DISTINCT acpw.id) 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/CountHousehold.php b/src/Bundle/ChillPersonBundle/Export/Export/CountHouseholdInPeriod.php similarity index 95% rename from src/Bundle/ChillPersonBundle/Export/Export/CountHousehold.php rename to src/Bundle/ChillPersonBundle/Export/Export/CountHouseholdInPeriod.php index 82a5c4aa4..8b56be371 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/CountHousehold.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/CountHouseholdInPeriod.php @@ -26,7 +26,7 @@ use Doctrine\ORM\Query; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; use Symfony\Component\Form\FormBuilderInterface; -class CountHousehold implements ExportInterface, GroupedExportInterface +class CountHouseholdInPeriod implements ExportInterface, GroupedExportInterface { private const TR_PREFIX = 'export.export.nb_household_with_course.'; private readonly bool $filterStatsByCenters; @@ -120,6 +120,7 @@ class CountHousehold implements ExportInterface, GroupedExportInterface ->join('person.accompanyingPeriodParticipations', 'acppart') ->join('acppart.accompanyingPeriod', 'acp') ->andWhere('acppart.startDate != acppart.endDate OR acppart.endDate IS NULL') + ->andWhere('hmember.startDate <= :count_household_at_date AND (hmember.endDate IS NULL OR hmember.endDate > :count_household_at_date)') ->setParameter('count_household_at_date', $this->rollingDateConverter->convert($data['calc_date'])); $qb @@ -135,7 +136,6 @@ class CountHousehold implements ExportInterface, GroupedExportInterface ' ) ) - ->andWhere('hmember.startDate <= :count_household_at_date AND (hmember.endDate IS NULL OR hmember.endDate > :count_household_at_date)') ->setParameter('authorized_centers', $centers); } diff --git a/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriodWork.php b/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriodWorkAssociatePersonOnAccompanyingPeriod.php similarity index 97% rename from src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriodWork.php rename to src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriodWorkAssociatePersonOnAccompanyingPeriod.php index 81c60bae6..49b21ef69 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriodWork.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriodWorkAssociatePersonOnAccompanyingPeriod.php @@ -47,7 +47,7 @@ use Doctrine\ORM\QueryBuilder; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; use Symfony\Component\Form\FormBuilderInterface; -class ListAccompanyingPeriodWork implements ListInterface, GroupedExportInterface +class ListAccompanyingPeriodWorkAssociatePersonOnAccompanyingPeriod implements ListInterface, GroupedExportInterface { private const FIELDS = [ 'id', @@ -121,7 +121,7 @@ class ListAccompanyingPeriodWork implements ListInterface, GroupedExportInterfac public function getDescription(): string { - return 'export.list.acpw.List description'; + return 'export.list.acpw_associate_period.List description'; } public function getGroup(): string @@ -190,12 +190,12 @@ class ListAccompanyingPeriodWork implements ListInterface, GroupedExportInterfac public function getResult($query, $data) { - return dump($query->getQuery()->getResult(AbstractQuery::HYDRATE_SCALAR)); + return $query->getQuery()->getResult(AbstractQuery::HYDRATE_SCALAR); } public function getTitle(): string { - return 'export.list.acpw.List of accompanying period works'; + return 'export.list.acpw_associate_period.List of accompanying period works'; } public function getType(): string diff --git a/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriodWorkAssociatePersonOnWork.php b/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriodWorkAssociatePersonOnWork.php new file mode 100644 index 000000000..4e68d5341 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriodWorkAssociatePersonOnWork.php @@ -0,0 +1,348 @@ +filterStatsByCenters = $parameterBag->get('chill_main')['acl']['filter_stats_by_center']; + } + + public function buildForm(FormBuilderInterface $builder) + { + $builder + ->add('calc_date', PickRollingDateType::class, [ + 'label' => 'export.list.acpw.Date of calculation for associated elements', + 'help' => 'export.list.acpw.help_description', + 'required' => true, + ]); + } + + public function getFormDefaultData(): array + { + return ['calc_date' => new RollingDate(RollingDate::T_TODAY)]; + } + + public function getAllowedFormattersTypes() + { + return [FormatterInterface::TYPE_LIST]; + } + + public function getDescription(): string + { + return 'export.list.acpw_associate_work.List description'; + } + + public function getGroup(): string + { + return 'Exports of social work actions'; + } + + public function getLabels($key, array $values, $data) + { + return match ($key) { + 'startDate', 'endDate', 'createdAt', 'updatedAt' => $this->dateTimeHelper->getLabel('export.list.acpw.'.$key), + 'socialAction' => function ($value) use ($key) { + if ('_header' === $value) { + return 'export.list.acpw.'.$key; + } + + if (null === $value) { + return ''; + } + + return $this->socialActionRender->renderString( + $this->socialActionRepository->find($value), + [] + ); + }, + 'socialIssue' => function ($value) use ($key) { + if ('_header' === $value) { + return 'export.list.acpw.'.$key; + } + + if (null === $value) { + return ''; + } + + return $this->socialIssueRender->renderString( + $this->socialIssueRepository->find($value), + [] + ); + }, + 'createdBy', 'updatedBy', 'acp_user' => $this->userHelper->getLabel($key, $values, 'export.list.acpw.'.$key), + 'referrers' => $this->userHelper->getLabel($key, $values, 'export.list.acpw.'.$key), + // 'acpwReferrers' => $this->userHelper->getLabelMulti($key, $values, 'export.list.acpw.' . $key), + 'personsName' => $this->personHelper->getLabelMulti($key, $values, 'export.list.acpw.'.$key), + 'handlingThierParty' => $this->thirdPartyHelper->getLabel($key, $values, 'export.list.acpw.'.$key), + 'thirdParties' => $this->thirdPartyHelper->getLabelMulti($key, $values, 'export.list.acpw.'.$key), + 'personsId', 'goalsId', 'goalResultsId', 'resultsId', 'evaluationsId' => $this->aggregateStringHelper->getLabelMulti($key, $values, 'export.list.acpw.'.$key), + 'goalsTitle', 'goalResultsTitle', 'resultsTitle', 'evaluationsTitle' => $this->translatableStringExportLabelHelper->getLabelMulti($key, $values, 'export.list.acpw.'.$key), + default => static function ($value) use ($key) { + if ('_header' === $value) { + return 'export.list.acpw.'.$key; + } + + if (null === $value) { + return ''; + } + + return $value; + }, + }; + } + + public function getQueryKeys($data) + { + return self::FIELDS; + } + + public function getResult($query, $data) + { + return $query->getQuery()->getResult(AbstractQuery::HYDRATE_SCALAR); + } + + public function getTitle(): string + { + return 'export.list.acpw_associate_work.List of accompanying period works'; + } + + 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->entityManager->createQueryBuilder(); + + $qb + ->from(AccompanyingPeriodWork::class, 'acpw') + ->distinct() + ->select('acpw.id AS id') + ->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); + } + + AccompanyingCourseExportHelper::addClosingMotiveExclusionClause($qb); + + $this->addSelectClauses($qb, $this->rollingDateConverter->convert($data['calc_date'])); + + 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, + ]; + } + + private function addSelectClauses(QueryBuilder $qb, \DateTimeImmutable $calcDate): void + { + // add regular fields + foreach ([ + 'startDate', + 'endDate', + 'note', + 'createdAt', + 'updatedAt', + ] as $field) { + $qb->addSelect(sprintf('acpw.%s AS %s', $field, $field)); + } + + // those with identity + foreach ([ + 'createdBy', + 'updatedBy', + 'handlingThierParty', + ] as $field) { + $qb->addSelect(sprintf('IDENTITY(acpw.%s) AS %s', $field, $field)); + } + + // join socialaction + $qb + ->join('acpw.socialAction', 'sa') + ->addSelect('sa.id AS socialActionId') + ->addSelect('sa.id AS socialAction') + ->addSelect('IDENTITY(sa.issue) AS socialIssue'); + + // join acp + $qb + ->addSelect('acp.id AS acp_id') + ->addSelect('IDENTITY(acp.user) AS acp_user'); + + // persons + $qb + ->addSelect('(SELECT AGGREGATE(person_acpw_member.id) FROM '.Person::class.' person_acpw_member ' + .'WHERE person_acpw_member MEMBER OF acpw.persons) AS personsId') + ->addSelect('(SELECT AGGREGATE(person1_acpw_member.id) FROM '.Person::class.' person1_acpw_member ' + .'WHERE person1_acpw_member MEMBER OF acpw.persons) AS personsName'); + + // referrers => at date XXXX + $qb + ->addSelect('(SELECT JSON_BUILD_OBJECT(\'uid\', IDENTITY(history.user), \'d\', history.startDate) FROM '.UserHistory::class.' history '. + 'WHERE history.accompanyingPeriod = acp AND history.startDate <= :calcDate AND (history.endDate IS NULL OR history.endDate > :calcDate)) AS referrers'); + + /* + // acpwReferrers at date XXX + $qb + ->addSelect('( + SELECT IDENTITY(acpw_ref_history.accompanyingPeriodWork) AS acpw_ref_history_id, + JSON_BUILD_OBJECT(\'uid\', IDENTITY(acpw_ref_history.user), \'d\', acpw_ref_history.startDate) + FROM ' . AccompanyingPeriodWorkReferrerHistory::class . ' acpw_ref_history ' . + 'WHERE acpw_ref_history.accompanyingPeriodWork = acpw AND acpw_ref_history.startDate <= :calcDate AND (acpw_ref_history.endDate IS NULL or acpw_ref_history.endDate > :calcDate) GROUP BY acpw_ref_history_id) AS acpwReferrers' + ); + */ + + // thirdparties + $qb + ->addSelect('(SELECT AGGREGATE(tp.id) FROM '.ThirdParty::class.' tp ' + .'WHERE tp MEMBER OF acpw.thirdParties) AS thirdParties'); + + // goals + $qb + ->addSelect('(SELECT AGGREGATE(IDENTITY(goal.goal)) FROM '.AccompanyingPeriodWorkGoal::class.' goal ' + .'WHERE goal MEMBER OF acpw.goals) AS goalsId') + ->addSelect('(SELECT AGGREGATE(g.title) FROM '.AccompanyingPeriodWorkGoal::class.' goal1 ' + .'LEFT JOIN '.Goal::class.' g WITH goal1.goal = g.id WHERE goal1 MEMBER OF acpw.goals) AS goalsTitle'); + + // goals results + $qb + ->addSelect('(SELECT AGGREGATE(wr.id) FROM '.Result::class.' wr ' + .'JOIN '.AccompanyingPeriodWorkGoal::class.' wg WITH wr MEMBER OF wg.results ' + .'WHERE wg MEMBER OF acpw.goals) AS goalResultsId') + ->addSelect('(SELECT AGGREGATE(wr1.title) FROM '.Result::class.' wr1 ' + .'JOIN '.AccompanyingPeriodWorkGoal::class.' wg1 WITH wr1 MEMBER OF wg1.results ' + .'WHERE wg1 MEMBER OF acpw.goals) AS goalResultsTitle'); + + // results + $qb + ->addSelect('(SELECT AGGREGATE(result.id) FROM '.Result::class.' result ' + .'WHERE result MEMBER OF acpw.results ) AS resultsId ') + ->addSelect('(SELECT AGGREGATE (result1.title) FROM '.Result::class.' result1 ' + .'WHERE result1 MEMBER OF acpw.results ) AS resultsTitle '); + + // evaluations + $qb + ->addSelect('(SELECT AGGREGATE(IDENTITY(we.evaluation)) FROM '.AccompanyingPeriodWorkEvaluation::class.' we ' + .'WHERE we MEMBER OF acpw.accompanyingPeriodWorkEvaluations ) AS evaluationsId ') + ->addSelect('(SELECT AGGREGATE(ev.title) FROM '.AccompanyingPeriodWorkEvaluation::class.' we1 ' + .'LEFT JOIN '.Evaluation::class.' ev WITH we1.evaluation = ev.id ' + .'WHERE we1 MEMBER OF acpw.accompanyingPeriodWorkEvaluations ) AS evaluationsTitle '); + + $qb->setParameter('calcDate', $calcDate); + } +} diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/AccompanyingPeriodWorkEndDateBetweenDateFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/AccompanyingPeriodWorkEndDateBetweenDateFilter.php index 373572e54..32bbbaf6e 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/AccompanyingPeriodWorkEndDateBetweenDateFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/AccompanyingPeriodWorkEndDateBetweenDateFilter.php @@ -54,7 +54,7 @@ final readonly class AccompanyingPeriodWorkEndDateBetweenDateFilter implements F public function describeAction($data, $format = 'string'): array { return [ - 'export.filter.work.end_between_dates.Only where end date is between %endDate% and %endDate%', + 'export.filter.work.end_between_dates.Only where start date is between %startDate% and %endDate%', [ '%startDate%' => null !== $data['start_date'] ? $this->rollingDateConverter->convert($data['start_date'])->format('d-m-Y') : '', '%endDate%' => null !== $data['end_date'] ? $this->rollingDateConverter->convert($data['end_date'])->format('d-m-Y') : '', diff --git a/src/Bundle/ChillPersonBundle/Security/Authorization/HouseholdVoter.php b/src/Bundle/ChillPersonBundle/Security/Authorization/HouseholdVoter.php index 798ed853a..415154457 100644 --- a/src/Bundle/ChillPersonBundle/Security/Authorization/HouseholdVoter.php +++ b/src/Bundle/ChillPersonBundle/Security/Authorization/HouseholdVoter.php @@ -78,7 +78,7 @@ class HouseholdVoter extends Voter implements ProvideRoleHierarchyInterface, Chi return match ($attribute) { self::SEE => $this->checkAssociatedMembersRole($subject, PersonVoter::SEE), self::EDIT => $this->checkAssociatedMembersRole($subject, PersonVoter::UPDATE), - self::STATS => $this->voteOnAttribute($attribute, $subject, $token), + self::STATS => $this->helper->voteOnAttribute($attribute, $subject, $token), default => throw new \UnexpectedValueException('attribute not supported'), }; } diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/PersonAggregators/PostalCodeAggregatorTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/PersonAggregators/PostalCodeAggregatorTest.php new file mode 100644 index 000000000..445f257b8 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/PersonAggregators/PostalCodeAggregatorTest.php @@ -0,0 +1,61 @@ +rollingDateConverter = self::$container->get(RollingDateConverterInterface::class); + } + + public function getAggregator() + { + return new PostalCodeAggregator($this->rollingDateConverter); + } + + public function getFormData() + { + return [ + ['calc_date' => new RollingDate(RollingDate::T_TODAY)], + ]; + } + + public function getQueryBuilders() + { + self::bootKernel(); + + $em = self::$container + ->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('count(person.id)') + ->from(Person::class, 'person'), + ]; + } +} diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Export/CountAccompanyingPeriodWorkTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Export/CountAccompanyingPeriodWorkAssociatePersonOnAccompanyingPeriodTest.php similarity index 69% rename from src/Bundle/ChillPersonBundle/Tests/Export/Export/CountAccompanyingPeriodWorkTest.php rename to src/Bundle/ChillPersonBundle/Tests/Export/Export/CountAccompanyingPeriodWorkAssociatePersonOnAccompanyingPeriodTest.php index 271f448d6..5caabf351 100644 --- a/src/Bundle/ChillPersonBundle/Tests/Export/Export/CountAccompanyingPeriodWorkTest.php +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Export/CountAccompanyingPeriodWorkAssociatePersonOnAccompanyingPeriodTest.php @@ -13,7 +13,7 @@ namespace Export\Export; use Chill\MainBundle\Test\Export\AbstractExportTest; use Chill\PersonBundle\Export\Declarations; -use Chill\PersonBundle\Export\Export\CountAccompanyingPeriodWork; +use Chill\PersonBundle\Export\Export\CountAccompanyingPeriodWorkAssociatePersonOnAccompanyingPeriod; use Doctrine\ORM\EntityManagerInterface; /** @@ -21,23 +21,19 @@ use Doctrine\ORM\EntityManagerInterface; * * @coversNothing */ -final class CountAccompanyingPeriodWorkTest extends AbstractExportTest +final class CountAccompanyingPeriodWorkAssociatePersonOnAccompanyingPeriodTest extends AbstractExportTest { - private CountAccompanyingPeriodWork $export; - protected function setUp(): void { self::bootKernel(); - - $this->export = self::$container->get(CountAccompanyingPeriodWork::class); } public function getExport() { $em = self::$container->get(EntityManagerInterface::class); - yield new CountAccompanyingPeriodWork($em, $this->getParameters(true)); - yield new CountAccompanyingPeriodWork($em, $this->getParameters(false)); + yield new CountAccompanyingPeriodWorkAssociatePersonOnAccompanyingPeriod($em, $this->getParameters(true)); + yield new CountAccompanyingPeriodWorkAssociatePersonOnAccompanyingPeriod($em, $this->getParameters(false)); } public function getFormData(): array diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Export/CountAccompanyingPeriodWorkAssociatePersonOnWorkTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Export/CountAccompanyingPeriodWorkAssociatePersonOnWorkTest.php new file mode 100644 index 000000000..6b6e7b7b4 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Export/CountAccompanyingPeriodWorkAssociatePersonOnWorkTest.php @@ -0,0 +1,48 @@ +get(EntityManagerInterface::class); + + yield new CountAccompanyingPeriodWorkAssociatePersonOnWork($em, $this->getParameters(true)); + yield new CountAccompanyingPeriodWorkAssociatePersonOnwork($em, $this->getParameters(false)); + } + + public function getFormData(): array + { + return [[]]; + } + + public function getModifiersCombination() + { + return [[Declarations::SOCIAL_WORK_ACTION_TYPE]]; + } +} diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Export/CountHouseholdInPeriodTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Export/CountHouseholdInPeriodTest.php new file mode 100644 index 000000000..b29c9a1f9 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Export/CountHouseholdInPeriodTest.php @@ -0,0 +1,58 @@ +get(EntityManagerInterface::class); + $rollingDate = self::$container->get(RollingDateConverterInterface::class); + + yield new CountHouseholdInPeriod($em, $rollingDate, $this->getParameters(true)); + yield new CountHouseholdInPeriod($em, $rollingDate, $this->getParameters(false)); + } + + public function getFormData() + { + return [ + ['calc_date' => new RollingDate(RollingDate::T_TODAY)], + ]; + } + + public function getModifiersCombination() + { + return [ + [ + Declarations::HOUSEHOLD_TYPE, + Declarations::ACP_TYPE, + Declarations::PERSON_TYPE, + ]]; + } +} diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Export/ListAccompanyingPeriodWorkAssociatePersonOnAccompanyingPeriodTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Export/ListAccompanyingPeriodWorkAssociatePersonOnAccompanyingPeriodTest.php new file mode 100644 index 000000000..aacd1bf55 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Export/ListAccompanyingPeriodWorkAssociatePersonOnAccompanyingPeriodTest.php @@ -0,0 +1,103 @@ +get(EntityManagerInterface::class); + $dateTimeHelper = self::$container->get(DateTimeHelper::class); + $userHelper = self::$container->get(UserHelper::class); + $personHelper = self::$container->get(LabelPersonHelper::class); + $thirdPartyHelper = self::$container->get(LabelThirdPartyHelper::class); + $translatableStringExportLabelHelper = self::$container->get(TranslatableStringExportLabelHelper::class); + $socialIssueRender = self::$container->get(SocialIssueRender::class); + $socialIssueRepository = self::$container->get(SocialIssueRepository::class); + $socialActionRender = self::$container->get(SocialActionRender::class); + $rollingDateConverter = self::$container->get(RollingDateConverterInterface::class); + $aggregateStringHelper = self::$container->get(AggregateStringHelper::class); + $socialActionRepository = self::$container->get(SocialActionRepository::class); + + yield new ListAccompanyingPeriodWorkAssociatePersonOnAccompanyingPeriod( + $entityManager, + $dateTimeHelper, + $userHelper, + $personHelper, + $thirdPartyHelper, + $translatableStringExportLabelHelper, + $socialIssueRender, + $socialIssueRepository, + $socialActionRender, + $rollingDateConverter, + $aggregateStringHelper, + $socialActionRepository, + $this->getParameters(true), + ); + + yield new ListAccompanyingPeriodWorkAssociatePersonOnAccompanyingPeriod( + $entityManager, + $dateTimeHelper, + $userHelper, + $personHelper, + $thirdPartyHelper, + $translatableStringExportLabelHelper, + $socialIssueRender, + $socialIssueRepository, + $socialActionRender, + $rollingDateConverter, + $aggregateStringHelper, + $socialActionRepository, + $this->getParameters(false), + ); + } + + public function getFormData() + { + return [ + ['calc_date' => new RollingDate(RollingDate::T_TODAY)], + ]; + } + + public function getModifiersCombination() + { + return [[Declarations::ACP_TYPE]]; + } +} diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Export/ListAccompanyingPeriodWorkTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Export/ListAccompanyingPeriodWorkAssociatePersonOnWorkTest.php similarity index 91% rename from src/Bundle/ChillPersonBundle/Tests/Export/Export/ListAccompanyingPeriodWorkTest.php rename to src/Bundle/ChillPersonBundle/Tests/Export/Export/ListAccompanyingPeriodWorkAssociatePersonOnWorkTest.php index ab8ca7c38..2f65ac85b 100644 --- a/src/Bundle/ChillPersonBundle/Tests/Export/Export/ListAccompanyingPeriodWorkTest.php +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Export/ListAccompanyingPeriodWorkAssociatePersonOnWorkTest.php @@ -19,7 +19,7 @@ use Chill\MainBundle\Service\RollingDate\RollingDate; use Chill\MainBundle\Service\RollingDate\RollingDateConverterInterface; use Chill\MainBundle\Test\Export\AbstractExportTest; use Chill\PersonBundle\Export\Declarations; -use Chill\PersonBundle\Export\Export\ListAccompanyingPeriodWork; +use Chill\PersonBundle\Export\Export\ListAccompanyingPeriodWorkAssociatePersonOnWork; use Chill\PersonBundle\Export\Helper\LabelPersonHelper; use Chill\PersonBundle\Repository\SocialWork\SocialActionRepository; use Chill\PersonBundle\Repository\SocialWork\SocialIssueRepository; @@ -33,7 +33,7 @@ use Doctrine\ORM\EntityManagerInterface; * * @coversNothing */ -class ListAccompanyingPeriodWorkTest extends AbstractExportTest +class ListAccompanyingPeriodWorkAssociatePersonOnWorkTest extends AbstractExportTest { protected function setUp(): void { @@ -56,7 +56,7 @@ class ListAccompanyingPeriodWorkTest extends AbstractExportTest $aggregateStringHelper = self::$container->get(AggregateStringHelper::class); $socialActionRepository = self::$container->get(SocialActionRepository::class); - yield new ListAccompanyingPeriodWork( + yield new ListAccompanyingPeriodWorkAssociatePersonOnWork( $entityManager, $dateTimeHelper, $userHelper, @@ -72,7 +72,7 @@ class ListAccompanyingPeriodWorkTest extends AbstractExportTest $this->getParameters(true), ); - yield new ListAccompanyingPeriodWork( + yield new ListAccompanyingPeriodWorkAssociatePersonOnWork( $entityManager, $dateTimeHelper, $userHelper, diff --git a/src/Bundle/ChillPersonBundle/config/services/exports_household.yaml b/src/Bundle/ChillPersonBundle/config/services/exports_household.yaml index 1a12c1bc8..15386c2cd 100644 --- a/src/Bundle/ChillPersonBundle/config/services/exports_household.yaml +++ b/src/Bundle/ChillPersonBundle/config/services/exports_household.yaml @@ -1,38 +1,30 @@ services: + _defaults: + autoconfigure: true + autowire: true ## Indicators - chill.person.export.count_household: - class: Chill\PersonBundle\Export\Export\CountHousehold - autowire: true - autoconfigure: true + Chill\PersonBundle\Export\Export\CountHouseholdInPeriod: tags: - { name: chill.export, alias: count_household } Chill\PersonBundle\Export\Export\ListHouseholdInPeriod: - autowire: true - autoconfigure: true tags: - { name: chill.export, alias: list_household_in_period } ## Filters chill.person.export.filter_household_composition: class: Chill\PersonBundle\Export\Filter\HouseholdFilters\CompositionFilter - autowire: true - autoconfigure: true tags: - { name: chill.export_filter, alias: household_composition_filter } ## Aggregators chill.person.export.aggregator_household_composition: class: Chill\PersonBundle\Export\Aggregator\HouseholdAggregators\CompositionAggregator - autowire: true - autoconfigure: true tags: - { name: chill.export_aggregator, alias: household_composition_aggregator } chill.person.export.aggregator_household_childrennumber: class: Chill\PersonBundle\Export\Aggregator\HouseholdAggregators\ChildrenNumberAggregator - autowire: true - autoconfigure: true tags: - { name: chill.export_aggregator, alias: household_childrennumber_aggregator } diff --git a/src/Bundle/ChillPersonBundle/config/services/exports_person.yaml b/src/Bundle/ChillPersonBundle/config/services/exports_person.yaml index 43f5556cf..d25a3b9e6 100644 --- a/src/Bundle/ChillPersonBundle/config/services/exports_person.yaml +++ b/src/Bundle/ChillPersonBundle/config/services/exports_person.yaml @@ -173,4 +173,6 @@ services: tags: - { name: chill.export_aggregator, alias: person_center_aggregator } - + Chill\PersonBundle\Export\Aggregator\PersonAggregators\PostalCodeAggregator: + tags: + - { name: chill.export_aggregator, alias: person_postal_code_aggregator } diff --git a/src/Bundle/ChillPersonBundle/config/services/exports_social_actions.yaml b/src/Bundle/ChillPersonBundle/config/services/exports_social_actions.yaml index 57be6bf40..f813455d8 100644 --- a/src/Bundle/ChillPersonBundle/config/services/exports_social_actions.yaml +++ b/src/Bundle/ChillPersonBundle/config/services/exports_social_actions.yaml @@ -4,14 +4,24 @@ services: autoconfigure: true ## Indicators - Chill\PersonBundle\Export\Export\CountAccompanyingPeriodWork: + Chill\PersonBundle\Export\Export\CountAccompanyingPeriodWorkAssociatePersonOnAccompanyingPeriod: tags: + # the name is not matching the class name: it is kept for backward compatibility - { name: chill.export, alias: count_social_work_actions } - Chill\PersonBundle\Export\Export\ListAccompanyingPeriodWork: + Chill\PersonBundle\Export\Export\CountAccompanyingPeriodWorkAssociatePersonOnWork: tags: + - { name: chill.export, alias: count_social_work_actions_associate_person_work } + + Chill\PersonBundle\Export\Export\ListAccompanyingPeriodWorkAssociatePersonOnAccompanyingPeriod: + tags: + # the name is not matching the class name: it is kept for backward compatibility - { name: chill.export, alias: list_social_work_actions } + Chill\PersonBundle\Export\Export\ListAccompanyingPeriodWorkAssociatePersonOnWork: + tags: + - { name: chill.export, alias: list_social_work_actions_associate_person_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 f2a90c31f..ceebe7d1b 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -379,8 +379,6 @@ 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. Exports of evaluations: Exports des évaluations @@ -1000,6 +998,16 @@ export: Count household with accompanying course by various parameters.: Compte le nombre de ménages impliqués dans un parcours selon différents filtres. Date of calculation of household members: Date à laquelle les membres du ménages sont comptabilisés + count_accompanying_period_work_associate_person: + title: Nombre d'actions, filtres et regroupements sur les usagers du parcours + 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 le parcours de l'action. + header: Nombre d'actions + + count_accompanying_period_work_associate_work: + title: Nombre d'actions, filtres et regroupements sur les usagers de l'action + 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 + aggregator: person: by_household_composition: @@ -1010,6 +1018,10 @@ export: title: Grouper les usagers par centre at_date: Date de calcul du centre center: Centre de l'usager + by_postal_code: + title: Grouper les usagers par code postal de l'adresse + at_date: Date de calcul de l'adresse + header: Code postal course: by_referrer: @@ -1268,6 +1280,14 @@ export: updatedBy: Modifié par timeSpent: Temps de rédaction (minutes) + acpw_associate_work: + List of accompanying period works: Liste des actions, filtres sur les usagers de l'action + List description: Compte le nombre d'actions d'accompagnement avec des filtres possibles sur les usagers, les parcours et les actions. Les filtres et regroupements agissent sur les usagers concernés par l'action. + + acpw_associate_period: + List of accompanying period works: Liste des actions, filtres sur les usagers du parcours + List description: Génère une liste des actions d'accompagnement, avec des filtres possibles sur les usagers, les parcours et les actions. Les filtres des usagers agissent sur les usagers concernés par le parcours de l'action. + acpw: List of accompanying period works: Liste des actions List description: Génère une liste des actions d'accompagnement, filtrée sur différents paramètres.