[export] Add referrer on accompanying course filter between dates feature and relevant tests

Implemented a new filter to the software for social workers. This filter, ReferrerFilterBetweenDates, enables filtering of query results based on a range of dates and accepted referrers. Tests for this new functionality have also been added to ensure the feature works as expected.
This commit is contained in:
Julien Fastré 2024-01-23 14:20:27 +01:00
parent 3871299346
commit c707a34f16
Signed by: julienfastre
GPG Key ID: BDE2190974723FCB
5 changed files with 227 additions and 2 deletions

View File

@ -0,0 +1,123 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters;
use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Form\Type\PickRollingDateType;
use Chill\MainBundle\Form\Type\PickUserDynamicType;
use Chill\MainBundle\Service\RollingDate\RollingDate;
use Chill\MainBundle\Service\RollingDate\RollingDateConverterInterface;
use Chill\MainBundle\Templating\Entity\UserRender;
use Chill\PersonBundle\Export\Declarations;
use Doctrine\ORM\QueryBuilder;
use src\Bundle\ChillPersonBundle\Tests\Export\Filter\AccompanyingCourseFilters\ReferrerFilterBetweenDatesTest;
use Symfony\Component\Form\FormBuilderInterface;
/**
* Class ReferrerFilterBetweenDates.
*
* This class implements the FilterInterface and provides functionality to filter query results
* based on a range of dates and accepted referrers.
*
* @see ReferrerFilterBetweenDatesTest for tests
*/
class ReferrerFilterBetweenDates implements FilterInterface
{
private const A = 'acp_referrer_filter_uhistory';
private const P = 'acp_referrer_filter_date_start';
private const Q = 'acp_referrer_filter_date_end';
private const PU = 'acp_referrer_filter_users';
public function __construct(
private readonly RollingDateConverterInterface $rollingDateConverter,
private UserRender $userRender
) {
}
public function addRole(): ?string
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
{
$history = self::A;
$start = self::P;
$end = self::Q;
$users = self::PU;
$qb
->join('acp.userHistories', self::A)
->andWhere(
"OVERLAPSI({$history}.startDate, {$history}.endDate),(:{$start}, :{$end}) = TRUE"
)
->andWhere(
"{$history}.user IN (:{$users})",
)
->setParameter($users, $data['accepted_referrers'])
->setParameter($start, $this->rollingDateConverter->convert($data['start_date']))
->setParameter($end, $this->rollingDateConverter->convert($data['end_date']));
}
public function applyOn(): string
{
return Declarations::ACP_TYPE;
}
public function buildForm(FormBuilderInterface $builder)
{
$builder
->add('accepted_referrers', PickUserDynamicType::class, [
'multiple' => true,
])
->add('start_date', PickRollingDateType::class, [
'label' => 'export.filter.course.by_referrer_between_dates.start date',
'required' => true,
])
->add('end_date', PickRollingDateType::class, [
'label' => 'export.filter.course.by_referrer_between_dates.end date',
'required' => true,
]);
}
public function getFormDefaultData(): array
{
return [
'start_date' => new RollingDate(RollingDate::T_YEAR_CURRENT_START),
'end_date' => new RollingDate(RollingDate::T_TODAY),
'accepted_referrers' => [],
];
}
public function describeAction($data, $format = 'string'): array
{
$users = [];
foreach ($data['accepted_referrers'] as $r) {
$users[] = $this->userRender->renderString($r, []);
}
return [
'exports.filter.course.by_referrer_between_dates.description', [
'agents' => implode(', ', $users),
'start_date' => $this->rollingDateConverter->convert($data['start_date']),
'end_date' => $this->rollingDateConverter->convert($data['end_date']),
], ];
}
public function getTitle(): string
{
return 'export.filter.course.by_referrer_between_dates.title';
}
}

View File

@ -0,0 +1,89 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace src\Bundle\ChillPersonBundle\Tests\Export\Filter\AccompanyingCourseFilters;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Service\RollingDate\RollingDate;
use Chill\MainBundle\Service\RollingDate\RollingDateConverterInterface;
use Chill\MainBundle\Templating\Entity\UserRender;
use Chill\MainBundle\Test\Export\AbstractFilterTest;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\ReferrerFilterBetweenDates;
use Doctrine\ORM\EntityManagerInterface;
/**
* @internal
*
* @coversNothing
*/
class ReferrerFilterBetweenDatesTest extends AbstractFilterTest
{
private RollingDateConverterInterface $rollingDateConverter;
private UserRender $userRender;
protected function setUp(): void
{
parent::setUp();
self::bootKernel();
$this->rollingDateConverter = self::$container->get(RollingDateConverterInterface::class);
$this->userRender = self::$container->get(UserRender::class);
}
public function getFilter()
{
return new ReferrerFilterBetweenDates($this->rollingDateConverter, $this->userRender);
}
public function getFormData()
{
self:self::bootKernel();
$em = self::$container->get(EntityManagerInterface::class);
$users = $em->createQueryBuilder()
->from(User::class, 'u')
->select('u')
->getQuery()
->setMaxResults(1)
->getResult();
return [
[
'accepted_referrers' => $users[0],
'start_date' => new RollingDate(RollingDate::T_YEAR_PREVIOUS_START),
'end_date' => new RollingDate(RollingDate::T_TODAY),
],
];
}
public function getQueryBuilders()
{
self::bootKernel();
$em = self::$container->get(EntityManagerInterface::class);
yield $em->createQueryBuilder()
->from(AccompanyingPeriod::class, 'acp')
->select('acp.id');
$qb = $em->createQueryBuilder();
$qb
->from(AccompanyingPeriod\AccompanyingPeriodWork::class, 'acpw')
->join('acpw.accompanyingPeriod', 'acp')
->join('acp.participations', 'acppart')
->join('acppart.person', 'person')
;
$qb->select('COUNT(DISTINCT acpw.id) as export_result');
yield $qb;
}
}

View File

@ -96,11 +96,14 @@ services:
tags:
- { name: chill.export_filter, alias: accompanyingcourse_activeonedaybetweendates_filter }
chill.person.export.filter_referrer:
class: Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\ReferrerFilter
Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\ReferrerFilter:
tags:
- { name: chill.export_filter, alias: accompanyingcourse_referrer_filter }
Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\ReferrerFilterBetweenDates:
tags:
- { name: chill.export_filter, alias: accompanyingcourse_referrer_filter_between_dates }
chill.person.export.filter_openbetweendates:
class: Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\OpenBetweenDatesFilter
tags:

View File

@ -145,6 +145,12 @@ exports:
describe: >-
Uniquement les parcours qui ne sont pas localisés à une adresse de référence, à la date du {date_calc, date, medium}
Les agents traitants au { agent_at, date, medium }, seulement {agents}
by_referrer_between_dates:
description: >-
Filtré par référent du parcours, entre deux dates: depuis le {start_date, date, medium}, jusqu'au {end_date, date, medium}, seulement {agents}
'total persons matching the search pattern': >-
{ total, plural,
=0 {Aucun usager ne correspond aux termes de recherche}

View File

@ -1191,6 +1191,10 @@ export:
"Filtered by user main scope: only %scope%": "Filtré par service du référent: uniquement %scope%"
by_referrer:
Computation date for referrer: Date à laquelle le référent était actif
by_referrer_between_dates:
title: Filtrer les parcours par référent (entre deux dates)
start date: Le référent était actif après le
end date: Le référent était actif avant le
having_temporarily:
label: Qualité de la localisation
Having a temporarily location: Ayant une localisation temporaire