diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ByHouseholdCompositionAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/ByHouseholdCompositionAggregator.php similarity index 75% rename from src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ByHouseholdCompositionAggregator.php rename to src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/ByHouseholdCompositionAggregator.php index f299762e6..7a1aaaa49 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ByHouseholdCompositionAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/ByHouseholdCompositionAggregator.php @@ -9,20 +9,18 @@ declare(strict_types=1); * the LICENSE file that was distributed with this source code. */ -namespace Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators; +namespace Chill\PersonBundle\Export\Aggregator\PersonAggregators; use Chill\MainBundle\Export\AggregatorInterface; use Chill\MainBundle\Form\Type\ChillDateType; use Chill\MainBundle\Templating\TranslatableStringHelperInterface; use Chill\PersonBundle\Entity\Household\HouseholdComposition; -use Chill\PersonBundle\Entity\Household\HouseholdMember; use Chill\PersonBundle\Export\Declarations; use Chill\PersonBundle\Repository\Household\HouseholdCompositionTypeRepositoryInterface; use DateTimeImmutable; use Doctrine\ORM\Query\Expr\Join; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; -use function in_array; class ByHouseholdCompositionAggregator implements AggregatorInterface { @@ -47,30 +45,20 @@ class ByHouseholdCompositionAggregator implements AggregatorInterface { $p = self::PREFIX; - if (!in_array('acppart', $qb->getAllAliases(), true)) { - $qb->leftJoin('acp.participations', 'acppart'); - } - $qb ->leftJoin( - HouseholdMember::class, - "{$p}_hm", - Join::WITH, - $qb->expr()->orX( - $qb->expr()->isNull("{$p}_hm"), - $qb->expr()->andX( - $qb->expr()->lte("{$p}_hm.startDate", ":{$p}_date"), - $qb->expr()->orX( - $qb->expr()->isNull("{$p}_hm.endDate"), - $qb->expr()->gt("{$p}_hm.endDate", ":{$p}_date") - ) - ) - ) + 'person.householdParticipations', + "{$p}_hm" ) ->leftJoin( HouseholdComposition::class, "{$p}_compo", Join::WITH, + $qb->expr()->eq("{$p}_hm.household", "{$p}_compo.household"), + ) + ->andWhere("{$p}_hm.startDate <= :{$p}_date AND ({$p}_hm.endDate IS NULL OR {$p}_hm.endDate > :{$p}_date)") + ->andWhere("{$p}_hm.shareHousehold = 'TRUE'") + ->andWhere( $qb->expr()->orX( $qb->expr()->isNull("{$p}_compo"), $qb->expr()->andX( @@ -89,13 +77,13 @@ class ByHouseholdCompositionAggregator implements AggregatorInterface public function applyOn() { - return Declarations::ACP_TYPE; + return Declarations::PERSON_TYPE; } public function buildForm(FormBuilderInterface $builder) { $builder->add('date_calc', ChillDateType::class, [ - 'label' => 'export.aggregator.course.by_household_composition.Calc date', + 'label' => 'export.aggregator.person.by_household_composition.Calc date', 'input_format' => 'datetime_immutable', 'data' => new DateTimeImmutable('now'), ]); @@ -105,7 +93,7 @@ class ByHouseholdCompositionAggregator implements AggregatorInterface { return function ($value) { if ('_header' === $value) { - return 'export.aggregator.course.by_household_composition.Household composition'; + return 'export.aggregator.person.by_household_composition.Household composition'; } if (null === $value) { @@ -127,6 +115,6 @@ class ByHouseholdCompositionAggregator implements AggregatorInterface public function getTitle() { - return 'export.aggregator.course.by_household_composition.Group course by household composition'; + return 'export.aggregator.person.by_household_composition.Group course by household composition'; } } diff --git a/src/Bundle/ChillPersonBundle/Export/Export/CountPerson.php b/src/Bundle/ChillPersonBundle/Export/Export/CountPerson.php index 98708149a..07a307563 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/CountPerson.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/CountPerson.php @@ -100,7 +100,7 @@ class CountPerson implements ExportInterface, GroupedExportInterface $qb = $this->personRepository->createQueryBuilder('person'); - $qb->select('COUNT(person.id) AS export_result') + $qb->select('COUNT(DISTINCT person.id) AS export_result') ->andWhere( $qb->expr()->exists( 'SELECT 1 FROM ' . PersonCenterHistory::class . ' pch WHERE pch.person = person.id AND pch.center IN (:authorized_centers)' diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ByHouseholdCompositionFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ByHouseholdCompositionFilter.php new file mode 100644 index 000000000..9b59549f1 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ByHouseholdCompositionFilter.php @@ -0,0 +1,110 @@ +householdCompositionTypeRepository = $householdCompositionTypeRepository; + $this->rollingDateConverter = $rollingDateConverter; + $this->translatableStringHelper = $translatableStringHelper; + } + + public function addRole(): ?string + { + return null; + } + + public function alterQuery(QueryBuilder $qb, $data) + { + $p = 'person_by_household_compo_filter'; + + $qb + ->andWhere( + $qb->expr()->exists( + 'SELECT 1 FROM ' . HouseholdMember::class . " {$p}_hm " . + 'JOIN ' . HouseholdComposition::class . " {$p}_compo WITH {$p}_hm.household = {$p}_compo.household " . + "WHERE {$p}_hm.person = person AND {$p}_hm.shareHousehold = 'TRUE' " . + "AND ({$p}_hm.startDate <= :{$p}_date AND ({$p}_hm.endDate IS NULL OR {$p}_hm.endDate > :{$p}_date)) " . + "AND ({$p}_compo.startDate <= :{$p}_date AND ({$p}_compo.endDate IS NULL OR {$p}_compo.endDate > :{$p}_date)) " . + "AND {$p}_compo.householdCompositionType IN (:{$p}_accepted)" + ) + ) + ->setParameter("{$p}_accepted", $data['compositions']) + ->setParameter("{$p}_date", $this->rollingDateConverter->convert($data['calc_date']), Types::DATE_IMMUTABLE); + } + + public function applyOn() + { + return Declarations::PERSON_TYPE; + } + + public function buildForm(FormBuilderInterface $builder) + { + $builder + ->add('compositions', EntityType::class, [ + 'class' => HouseholdCompositionType::class, + 'choices' => $this->householdCompositionTypeRepository->findAllActive(), + 'choice_label' => fn (HouseholdCompositionType $compositionType) => $this->translatableStringHelper->localize($compositionType->getLabel()), + 'label' => 'export.filter.person.by_composition.Accepted compositions', + 'multiple' => true, + 'expanded' => true, + ]) + ->add('calc_date', PickRollingDateType::class, [ + 'label' => 'export.filter.person.by_composition.Date calc', + 'data' => new RollingDate(RollingDate::T_TODAY), + ]); + } + + public function describeAction($data, $format = 'string') + { + $compos = array_map( + fn (HouseholdCompositionType $compositionType) => $this->translatableStringHelper->localize($compositionType->getLabel()), + $data['compositions']->toArray() + ); + + return ['export.filter.person.by_composition.Filtered by composition at %date%: only %compositions%', [ + '%compositions%' => implode(', ', $compos), + '%date%' => $this->rollingDateConverter->convert($data['calc_date'])->format('d-m-Y'), + ]]; + } + + public function getTitle() + { + return 'export.filter.person.by_composition.Filter by household composition'; + } +} diff --git a/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_course.yaml b/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_course.yaml index 71eecf4ff..6d0e160fd 100644 --- a/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_course.yaml +++ b/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_course.yaml @@ -214,10 +214,6 @@ services: tags: - { name: chill.export_aggregator, alias: accompanyingcourse_ref_scope_aggregator } - Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators\ByHouseholdCompositionAggregator: - tags: - - { name: chill.export_aggregator, alias: accompanyingcourse_by_household_compo_aggregator } - Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators\ByActionNumberAggregator: tags: - { name: chill.export_aggregator, alias: accompanyingcourse_by_action_number_aggregator } diff --git a/src/Bundle/ChillPersonBundle/config/services/exports_person.yaml b/src/Bundle/ChillPersonBundle/config/services/exports_person.yaml index b2b182c5b..05ae4b7b2 100644 --- a/src/Bundle/ChillPersonBundle/config/services/exports_person.yaml +++ b/src/Bundle/ChillPersonBundle/config/services/exports_person.yaml @@ -1,4 +1,7 @@ services: + _defaults: + autoconfigure: true + autowire: true ## Indicators chill.person.export.count_person: @@ -107,6 +110,10 @@ services: tags: - { name: chill.export_filter, alias: person_geog_filter } + Chill\PersonBundle\Export\Filter\PersonFilters\ByHouseholdCompositionFilter: + tags: + - { name: chill.export_filter, alias: person_by_household_composition_filter } + ## Aggregators chill.person.export.aggregator_nationality: class: Chill\PersonBundle\Export\Aggregator\PersonAggregators\NationalityAggregator @@ -156,3 +163,7 @@ services: tags: - { name: chill.export_aggregator, alias: person_geog_aggregator } + Chill\PersonBundle\Export\Aggregator\PersonAggregators\ByHouseholdCompositionAggregator: + tags: + - { name: chill.export_aggregator, alias: person_household_compo_aggregator } + diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index 022ac5654..41919fe4d 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -996,6 +996,11 @@ export: count_persons: Nombre d'usagers concernés distincts count_acps: Nombre de parcours distincts aggregator: + person: + by_household_composition: + Household composition: Composition du ménage + Group course by household composition: Grouper les personnes par composition familiale + Calc date: Date de calcul de la composition du ménage course: by_referrer: Computation date for referrer: Date à laquelle le référent était actif @@ -1008,10 +1013,6 @@ export: week: Durée du parcours en semaines month: Durée du parcours en mois Precision: Unité de la durée - by_household_composition: - Household composition: Composition du ménage - Group course by household composition: Grouper les parcours par composition familiale des ménages des usagers concernés - Calc date: Date de calcul de la composition du ménage by_number_of_action: Number of actions: Nombre d'actions by_creator_job: @@ -1038,6 +1039,12 @@ export: Max date: Date d'échéance filter: + person: + by_composition: + Filter by household composition: Filtrer les personnes par composition du ménage + Accepted compositions: Composition de ménages + Date calc: Date de calcul + 'Filtered by composition at %date%: only %compositions%': 'Filtré par composition du ménage, le %date%, seulement %compositions%' course: by_user_scope: Computation date for referrer: Date à laquelle le référent était actif