Add date range filter to referrer scope aggregator

A date range filter was added to the 'ReferrerScopeAggregator' class. This new feature allows users to filter courses by their referrer's scope based on a specified date range. In addition, relevant unit tests and translations were updated to support this new functionality.
This commit is contained in:
Julien Fastré 2024-06-17 16:21:28 +02:00
parent 6bd38f1a58
commit 791b3776c5
Signed by: julienfastre
GPG Key ID: BDE2190974723FCB
4 changed files with 84 additions and 6 deletions

View File

@ -0,0 +1,5 @@
kind: Feature
body: '[export] add date range on "group course by scope''s referrer"'
time: 2024-06-17T16:21:10.342069726+02:00
custom:
Issue: "282"

View File

@ -13,20 +13,25 @@ namespace Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators;
use Chill\MainBundle\Entity\User\UserScopeHistory; use Chill\MainBundle\Entity\User\UserScopeHistory;
use Chill\MainBundle\Export\AggregatorInterface; use Chill\MainBundle\Export\AggregatorInterface;
use Chill\MainBundle\Export\DataTransformerInterface;
use Chill\MainBundle\Form\Type\PickRollingDateType;
use Chill\MainBundle\Repository\ScopeRepositoryInterface; use Chill\MainBundle\Repository\ScopeRepositoryInterface;
use Chill\MainBundle\Service\RollingDate\RollingDate;
use Chill\MainBundle\Service\RollingDate\RollingDateConverterInterface;
use Chill\MainBundle\Templating\TranslatableStringHelperInterface; use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
use Chill\PersonBundle\Export\Declarations; use Chill\PersonBundle\Export\Declarations;
use Doctrine\ORM\Query\Expr\Join; use Doctrine\ORM\Query\Expr\Join;
use Doctrine\ORM\QueryBuilder; use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormBuilderInterface;
readonly class ReferrerScopeAggregator implements AggregatorInterface readonly class ReferrerScopeAggregator implements AggregatorInterface, DataTransformerInterface
{ {
private const PREFIX = 'acp_agg_referrer_scope'; private const PREFIX = 'acp_agg_referrer_scope';
public function __construct( public function __construct(
private ScopeRepositoryInterface $scopeRepository, private ScopeRepositoryInterface $scopeRepository,
private TranslatableStringHelperInterface $translatableStringHelper, private TranslatableStringHelperInterface $translatableStringHelper,
private RollingDateConverterInterface $rollingDateConverter,
) { ) {
} }
@ -47,11 +52,16 @@ readonly class ReferrerScopeAggregator implements AggregatorInterface
$qb->expr()->andX( $qb->expr()->andX(
$qb->expr()->eq("{$p}_userHistory.accompanyingPeriod", 'acp.id'), $qb->expr()->eq("{$p}_userHistory.accompanyingPeriod", 'acp.id'),
$qb->expr()->andX( $qb->expr()->andX(
// check that the user is referrer when the accompanying period is opened
$qb->expr()->gte('COALESCE(acp.closingDate, CURRENT_TIMESTAMP())', "{$p}_userHistory.startDate"), $qb->expr()->gte('COALESCE(acp.closingDate, CURRENT_TIMESTAMP())', "{$p}_userHistory.startDate"),
$qb->expr()->orX( $qb->expr()->orX(
$qb->expr()->isNull("{$p}_userHistory.endDate"), $qb->expr()->isNull("{$p}_userHistory.endDate"),
$qb->expr()->lt('COALESCE(acp.closingDate, CURRENT_TIMESTAMP())', "{$p}_userHistory.endDate") $qb->expr()->lt('COALESCE(acp.closingDate, CURRENT_TIMESTAMP())', "{$p}_userHistory.endDate")
) )
),
$qb->expr()->andX(
"{$p}_userHistory.startDate <= :{$p}_endDate",
"COALESCE({$p}_userHistory.endDate, CURRENT_TIMESTAMP()) > :{$p}_startDate"
) )
) )
) )
@ -67,9 +77,15 @@ readonly class ReferrerScopeAggregator implements AggregatorInterface
$qb->expr()->isNull("{$p}_scopeHistory.endDate"), $qb->expr()->isNull("{$p}_scopeHistory.endDate"),
$qb->expr()->gt("{$p}_scopeHistory.endDate", "{$p}_userHistory.startDate") $qb->expr()->gt("{$p}_scopeHistory.endDate", "{$p}_userHistory.startDate")
) )
),
$qb->expr()->andX(
"{$p}_scopeHistory.startDate <= :{$p}_endDate",
"COALESCE({$p}_scopeHistory.endDate, CURRENT_TIMESTAMP()) > :{$p}_startDate"
) )
) )
) )
->setParameter("{$p}_startDate", $this->rollingDateConverter->convert($data['start_date']))
->setParameter("{$p}_endDate", $this->rollingDateConverter->convert($data['end_date']))
->addSelect("IDENTITY({$p}_scopeHistory.scope) AS {$p}_select") ->addSelect("IDENTITY({$p}_scopeHistory.scope) AS {$p}_select")
->addGroupBy("{$p}_select"); ->addGroupBy("{$p}_select");
} }
@ -81,11 +97,34 @@ readonly class ReferrerScopeAggregator implements AggregatorInterface
public function buildForm(FormBuilderInterface $builder) public function buildForm(FormBuilderInterface $builder)
{ {
$builder
->add('start_date', PickRollingDateType::class, [
'label' => 'export.aggregator.course.by_referrer_scope.Referrer and scope after',
'required' => true,
])
->add('end_date', PickRollingDateType::class, [
'label' => 'export.aggregator.course.by_referrer_scope.Until',
'required' => true,
]);
} }
public function getFormDefaultData(): array public function getFormDefaultData(): array
{ {
return []; 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 = [];
$data['start_date'] = $before['start_date'] ?? new RollingDate(RollingDate::T_FIXED_DATE, new \DateTimeImmutable('1970-01-01'));
$data['end_date'] = $before['end_date'] ?? $default['end_date'];
return $data;
} }
public function getLabels($key, array $values, $data) public function getLabels($key, array $values, $data)

View File

@ -14,6 +14,7 @@ namespace Export\Aggregator\AccompanyingCourseAggregators;
use Chill\MainBundle\Entity\Scope; use Chill\MainBundle\Entity\Scope;
use Chill\MainBundle\Repository\ScopeRepositoryInterface; use Chill\MainBundle\Repository\ScopeRepositoryInterface;
use Chill\MainBundle\Service\RollingDate\RollingDate; use Chill\MainBundle\Service\RollingDate\RollingDate;
use Chill\MainBundle\Service\RollingDate\RollingDateConverter;
use Chill\MainBundle\Service\RollingDate\RollingDateConverterInterface; use Chill\MainBundle\Service\RollingDate\RollingDateConverterInterface;
use Chill\MainBundle\Templating\TranslatableStringHelperInterface; use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
use Chill\MainBundle\Test\Export\AbstractAggregatorTest; use Chill\MainBundle\Test\Export\AbstractAggregatorTest;
@ -48,16 +49,46 @@ final class ReferrerScopeAggregatorTest extends AbstractAggregatorTest
return new ReferrerScopeAggregator( return new ReferrerScopeAggregator(
$scopeRepository->reveal(), $scopeRepository->reveal(),
$translatableStringHelper->reveal(), $translatableStringHelper->reveal(),
$dateConverter->reveal() new RollingDateConverter(),
); );
} }
public function getFormData() public function getFormData()
{ {
return [ return [
[ ['start_date' => new RollingDate(RollingDate::T_WEEK_CURRENT_START), 'end_date' => new RollingDate(RollingDate::T_TODAY)],
'date_calc' => new RollingDate(RollingDate::T_TODAY), ];
], }
/**
* @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 [
null,
['start_date' => new RollingDate(RollingDate::T_FIXED_DATE, new \DateTimeImmutable('1970-01-01')), 'end_date' => new RollingDate(RollingDate::T_TODAY)],
];
yield [
[],
['start_date' => new RollingDate(RollingDate::T_FIXED_DATE, new \DateTimeImmutable('1970-01-01')), '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)],
]; ];
} }

View File

@ -1061,6 +1061,9 @@ export:
by_referrer: by_referrer:
Referrer after: Référent après le Referrer after: Référent après le
Until: Jusqu'au Until: Jusqu'au
by_referrer_scope:
Referrer and scope after: Référent et service après le
Until: Jusqu'au
by_user_scope: by_user_scope:
Group course by referrer's scope: Grouper les parcours par service du référent 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 Referrer's scope: Service du référent de parcours