diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/JobFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/JobFilter.php index 91c48b22b..7eaa1fc74 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/JobFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/JobFilter.php @@ -11,10 +11,15 @@ declare(strict_types=1); namespace Chill\PersonBundle\Export\Filter\SocialWorkFilters; +use Chill\MainBundle\Entity\User\UserJobHistory; use Chill\MainBundle\Entity\UserJob; use Chill\MainBundle\Export\FilterInterface; +use Chill\MainBundle\Form\Type\PickRollingDateType; +use Chill\MainBundle\Service\RollingDate\RollingDate; +use Chill\MainBundle\Service\RollingDate\RollingDateConverter; use Chill\MainBundle\Templating\TranslatableStringHelper; use Chill\PersonBundle\Export\Declarations; +use Doctrine\ORM\Query\Expr; use Doctrine\ORM\Query\Expr\Andx; use Doctrine\ORM\QueryBuilder; use Symfony\Bridge\Doctrine\Form\Type\EntityType; @@ -24,7 +29,13 @@ use function in_array; class JobFilter implements FilterInterface { - public function __construct(protected TranslatorInterface $translator, private readonly TranslatableStringHelper $translatableStringHelper) {} + private const PREFIX = 'acp_work_action_filter_user_job'; + + public function __construct( + private readonly RollingDateConverter $rollingDateConverter, + protected TranslatorInterface $translator, + private readonly TranslatableStringHelper $translatableStringHelper + ) {} public function addRole(): ?string { @@ -33,42 +44,59 @@ class JobFilter implements FilterInterface public function alterQuery(QueryBuilder $qb, $data) { - if (!in_array('acpwuser', $qb->getAllAliases(), true)) { - $qb->join('acpw.referrers', 'acpwuser'); - } + $p = self::PREFIX; - $where = $qb->getDQLPart('where'); - $clause = $qb->expr()->in('acpwuser.userJob', ':job'); - - if ($where instanceof Andx) { - $where->add($clause); - } else { - $where = $qb->expr()->andX($clause); - } - - $qb->add('where', $where); - $qb->setParameter('job', $data['job']); + $qb + ->leftJoin("acpw.referrers", "{$p}_user") + ->leftJoin( + UserJobHistory::class, + "{$p}_history", + Expr\Join::WITH, + $qb->expr()->eq("{$p}_history.user", "{$p}_user") + ) + ->andWhere( + $qb->expr()->andX( + $qb->expr()->lte("{$p}_history.startDate", ":{$p}_at"), + $qb->expr()->orX( + $qb->expr()->isNull("{$p}_history.endDate"), + $qb->expr()->gt("{$p}_history.endDate", ":{$p}_at") + ) + ) + ) + ->andWhere( + $qb->expr()->in("{$p}_history.job", ":{$p}_job") + ) + ->setParameters([ + ["{$p}_job", $data["job"]], + ["{$p}_at", $this->rollingDateConverter->convert($data['job_at'])] + ]); } - public function applyOn() + public function applyOn(): string { return Declarations::SOCIAL_WORK_ACTION_TYPE; } public function buildForm(FormBuilderInterface $builder) { - $builder->add('job', EntityType::class, [ - 'class' => UserJob::class, - 'choice_label' => fn (UserJob $j) => $this->translatableStringHelper->localize( - $j->getLabel() - ), - 'multiple' => true, - 'expanded' => true, - ]); + $builder + ->add('job', EntityType::class, [ + 'class' => UserJob::class, + 'choice_label' => fn (UserJob $j) => $this->translatableStringHelper->localize( + $j->getLabel() + ), + 'multiple' => true, + 'expanded' => true, + ]) + ->add('job_at', PickRollingDateType::class, [ + 'label' => 'export.filter.work.by_user_job.Calc date', + 'required' => true, + ]) + ; } public function getFormDefaultData(): array { - return []; + return ['job_at' => new RollingDate(RollingDate::T_TODAY)]; } public function describeAction($data, $format = 'string') @@ -81,13 +109,13 @@ class JobFilter implements FilterInterface ); } - return ['Filtered by treating agent job: only %jobs%', [ + return ['export.filter.work.by_user_job.Filtered by treating agent job: only %jobs%', [ '%jobs%' => implode(', ', $userjobs), ]]; } public function getTitle(): string { - return 'Filter by treating agent job'; + return 'export.filter.work.by_user_job.Filter by treating agent job'; } } diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Filter/SocialWorkFilters/JobFilterTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Filter/SocialWorkFilters/JobFilterTest.php index 890222b5b..f5836c18c 100644 --- a/src/Bundle/ChillPersonBundle/Tests/Export/Filter/SocialWorkFilters/JobFilterTest.php +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Filter/SocialWorkFilters/JobFilterTest.php @@ -12,6 +12,7 @@ declare(strict_types=1); namespace Chill\PersonBundle\Tests\Export\Filter\SocialWorkFilters; use Chill\MainBundle\Entity\UserJob; +use Chill\MainBundle\Service\RollingDate\RollingDate; use Chill\MainBundle\Test\Export\AbstractFilterTest; use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork; use Chill\PersonBundle\Export\Filter\SocialWorkFilters\JobFilter; @@ -49,7 +50,8 @@ final class JobFilterTest extends AbstractFilterTest return [ [ - 'job' => new ArrayCollection($jobs) + 'job' => new ArrayCollection($jobs), + 'job_at' => new RollingDate(RollingDate::T_FIXED_DATE, \DateTimeImmutable::createFromFormat('Y-m-d', '2020-01-01')) ] ]; } diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index 22b0c4096..9f4915f78 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -594,9 +594,6 @@ Filter by treating agent scope: Filtrer les actions par service de l'agent trait Filter by scope: Filtrer par service -Filter by treating agent job: Filtrer les actions par métier de l'agent traitant -"Filtered by treating agent job: only %jobs%": "Filtré par métier de l'agent traitant: uniquement %jobs%" - Filter by treating agent: Filtrer les actions par agent traitant Accepted agents: Agent traitant "Filtered by treating agent: only %agents%": "Filtré par agent traitant: uniquement %agents%" @@ -1159,6 +1156,10 @@ export: keep_null: Conserver les actions dont la date de fin n'est pas indiquée (actions en cours) keep_null_help: Si coché, les actions dont la date de fin est vide seront prises en compte. Si non coché, elles ne seront pas comptabilisée. Only where start date is between %startDate% and %endDate%: Seulement les actions dont la date de fin est entre le %startDate% et le %endDate% + by_user_job: + Filter by treating agent job: Filtrer les actions par métier de l'agent traitant + "Filtered by treating agent job: only %jobs%": "Filtré par métier de l'agent traitant: uniquement %jobs%" + Calc date: Date de calcul du métier de l'agent traitant list: person_with_acp: