Add startDate and endDate on UserScopeFilter

This commit is contained in:
Julien Fastré 2024-06-17 14:10:41 +02:00
parent cbd9489810
commit fc8bc33ba9
Signed by: julienfastre
GPG Key ID: BDE2190974723FCB
5 changed files with 78 additions and 46 deletions

View File

@ -0,0 +1,6 @@
kind: Feature
body: '[export] add start date and end date on filters "filter course by referrer
job" and "filter course by referrer scope"'
time: 2024-06-17T14:25:05.041546007+02:00
custom:
Issue: "282"

View File

@ -14,22 +14,26 @@ namespace Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters;
use Chill\MainBundle\Entity\Scope; use Chill\MainBundle\Entity\Scope;
use Chill\MainBundle\Entity\User\UserScopeHistory; use Chill\MainBundle\Entity\User\UserScopeHistory;
use Chill\MainBundle\Export\FilterInterface; use Chill\MainBundle\Export\FilterInterface;
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\TranslatableStringHelper; use Chill\MainBundle\Templating\TranslatableStringHelper;
use Chill\PersonBundle\Entity\AccompanyingPeriod\UserHistory;
use Chill\PersonBundle\Export\Declarations; use Chill\PersonBundle\Export\Declarations;
use Doctrine\Common\Collections\Collection; use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Query\Expr\Join;
use Doctrine\ORM\QueryBuilder; use Doctrine\ORM\QueryBuilder;
use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormBuilderInterface;
class UserScopeFilter implements FilterInterface final readonly class UserScopeFilter implements FilterInterface
{ {
private const PREFIX = 'acp_filter_main_scope'; private const PREFIX = 'acp_filter_main_scope';
public function __construct( public function __construct(
private readonly ScopeRepositoryInterface $scopeRepository, private ScopeRepositoryInterface $scopeRepository,
private readonly TranslatableStringHelper $translatableStringHelper, private TranslatableStringHelper $translatableStringHelper,
private RollingDateConverterInterface $rollingDateConverter,
) { ) {
} }
@ -38,47 +42,35 @@ class UserScopeFilter implements FilterInterface
return null; return null;
} }
public function alterQuery(QueryBuilder $qb, $data) public function alterQuery(QueryBuilder $qb, $data): void
{ {
$p = self::PREFIX; $p = self::PREFIX;
$qb $qb->andWhere(
->join( $qb->expr()->exists(
'acp.userHistories', sprintf(
"{$p}_userHistory", <<<DQL
Join::WITH, SELECT 1
$qb->expr()->andX( FROM %s {$p}_userHistory
$qb->expr()->eq("{$p}_userHistory.accompanyingPeriod", 'acp.id'), JOIN %s {$p}_userScopeHistory
$qb->expr()->andX( WITH
$qb->expr()->gte('COALESCE(acp.closingDate, CURRENT_TIMESTAMP())', "{$p}_userHistory.startDate"), {$p}_userHistory.user = {$p}_userScopeHistory.user
$qb->expr()->orX( AND OVERLAPSI({$p}_userHistory.startDate, {$p}_userHistory.endDate),({$p}_userScopeHistory.startDate, {$p}_userScopeHistory.endDate) = TRUE
$qb->expr()->isNull("{$p}_userHistory.endDate"), WHERE {$p}_userHistory.accompanyingPeriod = acp
$qb->expr()->lt('COALESCE(acp.closingDate, CURRENT_TIMESTAMP())', "{$p}_userHistory.endDate") AND {$p}_userHistory.startDate <= :{$p}_endDate
) AND ({$p}_userHistory.endDate IS NULL OR {$p}_userHistory.endDate > :{$p}_startDate)
) AND {$p}_userScopeHistory.startDate <= :{$p}_endDate
) AND ({$p}_userScopeHistory.endDate IS NULL OR {$p}_userScopeHistory.endDate > :{$p}_startDate)
AND {$p}_userScopeHistory.scope IN (:{$p}_scopes)
DQL,
UserHistory::class,
UserScopeHistory::class,
),
) )
->join( )
UserScopeHistory::class, ->setParameter("{$p}_scopes", $data['scopes'])
"{$p}_scopeHistory", ->setParameter("{$p}_startDate", $this->rollingDateConverter->convert($data['start_date']))
Join::WITH, ->setParameter("{$p}_endDate", $this->rollingDateConverter->convert($data['end_date']));
$qb->expr()->andX(
$qb->expr()->eq("{$p}_scopeHistory.user", "{$p}_userHistory.user"),
$qb->expr()->andX(
$qb->expr()->lte("{$p}_scopeHistory.startDate", "{$p}_userHistory.startDate"),
$qb->expr()->orX(
$qb->expr()->isNull("{$p}_scopeHistory.endDate"),
$qb->expr()->gt("{$p}_scopeHistory.endDate", "{$p}_userHistory.startDate")
)
)
)
)
->andWhere($qb->expr()->in("{$p}_scopeHistory.scope", ":{$p}_scopes"))
->setParameter(
"{$p}_scopes",
$data['scopes'],
)
;
} }
public function applyOn(): string public function applyOn(): string
@ -95,20 +87,28 @@ class UserScopeFilter implements FilterInterface
'choice_label' => fn (Scope $s) => $this->translatableStringHelper->localize($s->getName()), 'choice_label' => fn (Scope $s) => $this->translatableStringHelper->localize($s->getName()),
'multiple' => true, 'multiple' => true,
'expanded' => true, 'expanded' => true,
])
->add('start_date', PickRollingDateType::class, [
'label' => 'export.filter.course.by_user_scope.Start from',
])
->add('end_date', PickRollingDateType::class, [
'label' => 'export.filter.course.by_user_scope.Until',
]); ]);
} }
public function describeAction($data, $format = 'string') public function describeAction($data, $format = 'string')
{ {
return [ return [
'export.filter.course.by_user_scope.Filtered by user main scope: only %scope%', [ 'exports.filter.course.by_user_scope.Filtered by user main scope: only scopes', [
'%scope%' => implode( 'scopes' => implode(
', ', ', ',
array_map( array_map(
fn (Scope $s) => $this->translatableStringHelper->localize($s->getName()), fn (Scope $s) => $this->translatableStringHelper->localize($s->getName()),
$data['scopes'] instanceof Collection ? $data['scopes']->toArray() : $data['scopes'] $data['scopes'] instanceof Collection ? $data['scopes']->toArray() : $data['scopes']
) )
), ),
'startDate' => $this->rollingDateConverter->convert($data['start_date']),
'endDate' => $this->rollingDateConverter->convert($data['end_date']),
], ],
]; ];
} }
@ -117,9 +117,30 @@ class UserScopeFilter implements FilterInterface
{ {
return [ return [
'scopes' => [], 'scopes' => [],
'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();
if (null === $before) {
return $default;
}
if (!array_key_exists('start_date', $before) || null === $before['start_date']) {
$before['start_date'] = $default['start_date'];
}
if (!array_key_exists('end_date', $before) || null === $before['end_date']) {
$before['end_date'] = $default['end_date'];
}
return $before;
}
public function getTitle(): string public function getTitle(): string
{ {
return 'export.filter.course.by_user_scope.Filter by user scope'; return 'export.filter.course.by_user_scope.Filter by user scope';

View File

@ -50,11 +50,13 @@ final class UserScopeFilterTest extends AbstractFilterTest
return [ return [
[ [
'date_calc' => new RollingDate(RollingDate::T_TODAY), 'start_date' => new RollingDate(RollingDate::T_YEAR_CURRENT_START),
'end_date' => new RollingDate(RollingDate::T_TODAY),
'scopes' => new ArrayCollection($scopes), 'scopes' => new ArrayCollection($scopes),
], ],
[ [
'date_calc' => new RollingDate(RollingDate::T_TODAY), 'start_date' => new RollingDate(RollingDate::T_YEAR_CURRENT_START),
'end_date' => new RollingDate(RollingDate::T_TODAY),
'scopes' => $scopes, 'scopes' => $scopes,
], ],
]; ];

View File

@ -145,6 +145,8 @@ exports:
Filtré par référent du parcours, entre deux dates: depuis le {start_date, date, medium}, jusqu'au {end_date, date, medium}, seulement {agents} Filtré par référent du parcours, entre deux dates: depuis le {start_date, date, medium}, jusqu'au {end_date, date, medium}, seulement {agents}
by_user_job: by_user_job:
"Filtered by user job: only job": "Filtré par métier du référent entre le {startDate, date, short} et le {endDate, date, short}: uniquement {job}" "Filtered by user job: only job": "Filtré par métier du référent entre le {startDate, date, short} et le {endDate, date, short}: uniquement {job}"
by_user_scope:
"Filtered by user main scope: only scopes": "Filtré par service du référent entre le {startDate, date, short} et le {endDate, date, short}: uniquement {scopes}"
work: work:
by_treating_agent: by_treating_agent:
Filtered by treating agent at date: >- Filtered by treating agent at date: >-

View File

@ -1215,7 +1215,8 @@ export:
'Filtered by steps: only %step% and between %date_from% and %date_to%': 'Filtré par statut: seulement %step%, entre %date_from% et %date_to%' 'Filtered by steps: only %step% and between %date_from% and %date_to%': 'Filtré par statut: seulement %step%, entre %date_from% et %date_to%'
by_user_scope: by_user_scope:
Filter by user scope: Filtrer les parcours par service du référent Filter by user scope: Filtrer les parcours par service du référent
"Filtered by user main scope: only %scope%": "Filtré par service du référent: uniquement %scope%" Start from: Référent et service depuis le
Until: Jusqu'au
by_referrer: by_referrer:
Computation date for referrer: Date à laquelle le référent était actif Computation date for referrer: Date à laquelle le référent était actif
by_referrer_between_dates: by_referrer_between_dates: