From 89c231de41a1ad13a04663599bb20bd21539446c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Mon, 29 Apr 2024 13:03:22 +0200 Subject: [PATCH] Update geographical unit computation for closed periods in exports The geographical unit computation in the ChillPersonBundle now considers the closing date of an accompanying period when a person changes location. This provides more accurate statistics, especially in situations where the individual moved after the period closed. The changes also include refinements for the validFrom and validTo data within the AccompanyingCourseFilters and AccompanyingCourseAggregators. --- .changes/unreleased/Feature-20240429-130102.yaml | 7 +++++++ .../GeographicalUnitStatAggregator.php | 15 +++++++++------ .../GeographicalUnitStatFilter.php | 9 +++++---- 3 files changed, 21 insertions(+), 10 deletions(-) create mode 100644 .changes/unreleased/Feature-20240429-130102.yaml diff --git a/.changes/unreleased/Feature-20240429-130102.yaml b/.changes/unreleased/Feature-20240429-130102.yaml new file mode 100644 index 000000000..e07dcb40e --- /dev/null +++ b/.changes/unreleased/Feature-20240429-130102.yaml @@ -0,0 +1,7 @@ +kind: Feature +body: 'Take closing date into account when computing the geographical unit on accompanying + period. When a person moved after an accompanying period is closed, the date of + closing accompanying period is took into account if it is earlier than the date given by the user.' +time: 2024-04-29T13:01:02.463796452+02:00 +custom: + Issue: "276" diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/GeographicalUnitStatAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/GeographicalUnitStatAggregator.php index 2d6dbeae4..0a861d64c 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/GeographicalUnitStatAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/GeographicalUnitStatAggregator.php @@ -28,8 +28,11 @@ use Symfony\Component\Form\FormBuilderInterface; final readonly class GeographicalUnitStatAggregator implements AggregatorInterface { - public function __construct(private GeographicalUnitLayerRepositoryInterface $geographicalUnitLayerRepository, private TranslatableStringHelperInterface $translatableStringHelper, private RollingDateConverterInterface $rollingDateConverter) - { + public function __construct( + private GeographicalUnitLayerRepositoryInterface $geographicalUnitLayerRepository, + private TranslatableStringHelperInterface $translatableStringHelper, + private RollingDateConverterInterface $rollingDateConverter + ) { } public function addRole(): ?string @@ -43,10 +46,10 @@ final readonly class GeographicalUnitStatAggregator implements AggregatorInterfa $qb->andWhere( $qb->expr()->andX( - 'acp_geog_agg_location_history.startDate <= :acp_geog_aggregator_date', + 'acp_geog_agg_location_history.startDate <= LEAST(:acp_geog_aggregator_date, acp.closingDate)', $qb->expr()->orX( 'acp_geog_agg_location_history.endDate IS NULL', - 'acp_geog_agg_location_history.endDate > :acp_geog_aggregator_date' + 'acp_geog_agg_location_history.endDate > LEAST(:acp_geog_aggregator_date, acp.closingDate)' ) ) ); @@ -58,9 +61,9 @@ final readonly class GeographicalUnitStatAggregator implements AggregatorInterfa Join::WITH, $qb->expr()->andX( 'IDENTITY(acp_geog_agg_address_person_location.person) = IDENTITY(acp_geog_agg_location_history.personLocation)', - 'acp_geog_agg_address_person_location.validFrom <= :acp_geog_aggregator_date', + 'acp_geog_agg_address_person_location.validFrom <= LEAST(:acp_geog_aggregator_date, acp.closingDate)', $qb->expr()->orX( - 'acp_geog_agg_address_person_location.validTo > :acp_geog_aggregator_date', + 'acp_geog_agg_address_person_location.validTo > LEAST(:acp_geog_aggregator_date, acp.closingDate)', $qb->expr()->isNull('acp_geog_agg_address_person_location.validTo') ) ) diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/GeographicalUnitStatFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/GeographicalUnitStatFilter.php index 7d0980dad..d84745403 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/GeographicalUnitStatFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/GeographicalUnitStatFilter.php @@ -52,18 +52,19 @@ class GeographicalUnitStatFilter implements FilterInterface 'SELECT 1 FROM '.AccompanyingPeriod\AccompanyingPeriodLocationHistory::class.' acp_geog_filter_location_history + JOIN acp_geog_filter_location_history.period acp_geog_filter_location_history_period LEFT JOIN '.PersonHouseholdAddress::class.' acp_geog_filter_address_person_location WITH IDENTITY(acp_geog_filter_location_history.personLocation) = IDENTITY(acp_geog_filter_address_person_location.person) AND - (acp_geog_filter_address_person_location.validFrom < :acp_geog_filter_date AND ( - acp_geog_filter_address_person_location.validTo IS NULL OR acp_geog_filter_address_person_location.validTo > :acp_geog_filter_date + (acp_geog_filter_address_person_location.validFrom < LEAST(:acp_geog_filter_date, acp_geog_filter_location_history_period.closingDate) AND ( + acp_geog_filter_address_person_location.validTo IS NULL OR acp_geog_filter_address_person_location.validTo > LEAST(:acp_geog_filter_date, acp_geog_filter_location_history_period.closingDate) )) LEFT JOIN '.Address::class.' acp_geog_filter_address WITH COALESCE(IDENTITY(acp_geog_filter_address_person_location.address), IDENTITY(acp_geog_filter_location_history.addressLocation)) = acp_geog_filter_address.id LEFT JOIN acp_geog_filter_address.geographicalUnits acp_geog_filter_units WHERE - (acp_geog_filter_location_history.startDate <= :acp_geog_filter_date AND ( - acp_geog_filter_location_history.endDate IS NULL OR acp_geog_filter_location_history.endDate > :acp_geog_filter_date + (acp_geog_filter_location_history.startDate <= LEAST(:acp_geog_filter_date, acp_geog_filter_location_history_period.closingDate) AND ( + acp_geog_filter_location_history.endDate IS NULL OR acp_geog_filter_location_history.endDate > LEAST(:acp_geog_filter_date, acp_geog_filter_location_history_period.closingDate) )) AND acp_geog_filter_units IN (:acp_geog_filter_units) AND acp_geog_filter_location_history.period = acp.id