diff --git a/.changes/unreleased/Feature-20240617-152219.yaml b/.changes/unreleased/Feature-20240617-152219.yaml new file mode 100644 index 000000000..cb5b93e0f --- /dev/null +++ b/.changes/unreleased/Feature-20240617-152219.yaml @@ -0,0 +1,5 @@ +kind: Feature +body: '[export] the aggregator "Group by referrer" now accept a date range.' +time: 2024-06-17T15:22:19.030556768+02:00 +custom: + Issue: "282" diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ReferrerAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ReferrerAggregator.php index 78349dd56..925918e83 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ReferrerAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ReferrerAggregator.php @@ -12,6 +12,7 @@ declare(strict_types=1); namespace Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators; use Chill\MainBundle\Export\AggregatorInterface; +use Chill\MainBundle\Export\DataTransformerInterface; use Chill\MainBundle\Form\Type\PickRollingDateType; use Chill\MainBundle\Repository\UserRepository; use Chill\MainBundle\Service\RollingDate\RollingDate; @@ -21,14 +22,17 @@ use Chill\PersonBundle\Export\Declarations; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; -final readonly class ReferrerAggregator implements AggregatorInterface +final readonly class ReferrerAggregator implements AggregatorInterface, DataTransformerInterface { private const A = 'acp_ref_agg_uhistory'; private const P = 'acp_ref_agg_date'; - public function __construct(private UserRepository $userRepository, private UserRender $userRender, private RollingDateConverterInterface $rollingDateConverter) - { + public function __construct( + private UserRepository $userRepository, + private UserRender $userRender, + private RollingDateConverterInterface $rollingDateConverter + ) { } public function addRole(): ?string @@ -46,18 +50,16 @@ final readonly class ReferrerAggregator implements AggregatorInterface $qb->expr()->orX( $qb->expr()->isNull(self::A), $qb->expr()->andX( - $qb->expr()->lte(self::A.'.startDate', ':'.self::P), + $qb->expr()->lt(self::A.'.startDate', ':'.self::P.'_end_date'), $qb->expr()->orX( $qb->expr()->isNull(self::A.'.endDate'), - $qb->expr()->gt(self::A.'.endDate', ':'.self::P) + $qb->expr()->gte(self::A.'.endDate', ':'.self::P.'_start_date') ) ) ) ) - ->setParameter( - self::P, - $this->rollingDateConverter->convert($data['date_calc']) - ); + ->setParameter(':'.self::P.'_end_date', $this->rollingDateConverter->convert($data['end_date'])) + ->setParameter(':'.self::P.'_start_date', $this->rollingDateConverter->convert($data['end_date'])); } public function applyOn(): string @@ -68,15 +70,37 @@ final readonly class ReferrerAggregator implements AggregatorInterface public function buildForm(FormBuilderInterface $builder) { $builder - ->add('date_calc', PickRollingDateType::class, [ - 'label' => 'export.aggregator.course.by_referrer.Computation date for referrer', + ->add('start_date', PickRollingDateType::class, [ + 'label' => 'export.aggregator.course.by_referrer.Referrer after', + 'required' => true, + ]) + ->add('end_date', PickRollingDateType::class, [ + 'label' => 'export.aggregator.course.by_referrer.Until', 'required' => true, ]); } public function getFormDefaultData(): array { - return ['date_calc' => new RollingDate(RollingDate::T_TODAY)]; + return [ + 'start_date' => new RollingDate(RollingDate::T_YEAR_CURRENT_START), + 'end_date' => new RollingDate(RollingDate::T_TODAY), + ]; + } + + public function transformData(?array $before): array + { + $default = $this->getFormDefaultData(); + $data = []; + + if (null === $before) { + return $default; + } + + $data['start_date'] = $before['date_calc'] ?? $before['start_date'] ?? $default['start_date']; + $data['end_date'] = $before['date_calc'] ?? $before['end_date'] ?? $default['end_date']; + + return $data; } public function getLabels($key, array $values, $data) diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingCourseAggregators/ReferrerAggregatorTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingCourseAggregators/ReferrerAggregatorTest.php index 8951b61eb..fade92c04 100644 --- a/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingCourseAggregators/ReferrerAggregatorTest.php +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingCourseAggregators/ReferrerAggregatorTest.php @@ -33,7 +33,40 @@ final class ReferrerAggregatorTest extends AbstractAggregatorTest $this->aggregator = self::$container->get('chill.person.export.aggregator_referrer'); } - public function getAggregator() + /** + * @dataProvider provideBeforeData + */ + public function testDataTransformer(?array $before, array $expected): void + { + $actual = $this->getAggregator()->transformData($before); + + self::assertEqualsCanonicalizing(array_keys($expected), array_keys($actual)); + foreach (['start_date', 'end_date'] as $key) { + self::assertInstanceOf(RollingDate::class, $actual[$key]); + self::assertEquals($expected[$key]->getRoll(), $actual[$key]->getRoll(), "Check that the roll is the same for {$key}"); + } + } + + public function provideBeforeData(): iterable + { + yield [ + ['date_calc' => new RollingDate(RollingDate::T_TODAY)], + ['start_date' => new RollingDate(RollingDate::T_TODAY), 'end_date' => new RollingDate(RollingDate::T_TODAY)], + ]; + + yield [ + ['start_date' => new RollingDate(RollingDate::T_WEEK_CURRENT_START), 'end_date' => new RollingDate(RollingDate::T_TODAY)], + ['start_date' => new RollingDate(RollingDate::T_WEEK_CURRENT_START), 'end_date' => new RollingDate(RollingDate::T_TODAY)], + ]; + + yield [ + null, + // this is the default configuration + ['start_date' => new RollingDate(RollingDate::T_YEAR_CURRENT_START), 'end_date' => new RollingDate(RollingDate::T_TODAY)], + ]; + } + + public function getAggregator(): ReferrerAggregator { return $this->aggregator; } @@ -41,7 +74,10 @@ final class ReferrerAggregatorTest extends AbstractAggregatorTest public function getFormData(): array { return [ - ['date_calc' => new RollingDate(RollingDate::T_TODAY)], + [ + 'start_date' => new RollingDate(RollingDate::T_YEAR_CURRENT_START), + 'end_date' => new RollingDate(RollingDate::T_TODAY), + ], ]; } diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index bb40df9a9..fc95da2ea 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -1058,9 +1058,9 @@ export: by-user: title: Grouper les parcours par usager participant header: Usager participant - by_referrer: - Computation date for referrer: Date à laquelle le référent était actif + Referrer after: Référent après le + Until: Jusqu'au by_user_scope: Group course by referrer's scope: Grouper les parcours par service du référent Referrer's scope: Service du référent de parcours