Refactor filters and aggregators of "acpwusers" for using the acpw referrer history instead

This commit is contained in:
Julien Fastré 2023-10-16 13:06:25 +02:00
parent 51a4ffca2e
commit b65f76262a
Signed by: julienfastre
GPG Key ID: BDE2190974723FCB
10 changed files with 101 additions and 117 deletions

View File

@ -1,63 +0,0 @@
Entity,Join,Attribute,Alias
AccompanyingPeriod::class,,,acp
,AccompanyingPeriodWork::class,acp.works,acpw
,AccompanyingPeriodParticipation::class,acp.participations,acppart
,Location::class,acp.administrativeLocation,acploc
,ClosingMotive::class,acp.closingMotive,acpmotive
,UserJob::class,acp.job,acpjob
,Origin::class,acp.origin,acporigin
,Scope::class,acp.scopes,acpscope
,SocialIssue::class,acp.socialIssues,acpsocialissue
,User::class,acp.user,acpuser
AccompanyingPeriodWork::class,,,acpw
,AccompanyingPeriodWorkEvaluation::class,acpw.accompanyingPeriodWorkEvaluations,workeval
,User::class,acpw.referrers,acpwuser
,SocialAction::class,acpw.socialAction,acpwsocialaction
,Goal::class,acpw.goals,goal
,Result::class,acpw.results,result
AccompanyingPeriodParticipation::class,,,acppart
,Person::class,acppart.person,partperson
AccompanyingPeriodWorkEvaluation::class,,,workeval
,Evaluation::class,workeval.evaluation,eval
Goal::class,,,goal
,Result::class,goal.results,goalresult
Person::class,,,person
,Center::class,person.center,center
,HouseholdMember::class,partperson.householdParticipations,householdmember
,MaritalStatus::class,person.maritalStatus,personmarital
,VendeePerson::class,,vp
,VendeePersonMineur::class,,vpm
ResidentialAddress::class,,,resaddr
,ThirdParty::class,resaddr.hostThirdParty,tparty
ThirdParty::class,,,tparty
,ThirdPartyCategory::class,tparty.categories,tpartycat
HouseholdMember::class,,,householdmember
,Household::class,householdmember.household,household
,Person::class,householdmember.person,memberperson
,,memberperson.center,membercenter
Household::class,,,household
,HouseholdComposition::class,household.compositions,composition
Activity::class,,,activity
,Person::class,activity.person,actperson
,AccompanyingPeriod::class,activity.accompanyingPeriod,acp
,Person::class,activity_person_having_activity.person,person_person_having_activity
,ActivityReason::class,activity_person_having_activity.reasons,reasons_person_having_activity
,ActivityType::class,activity.activityType,acttype
,Location::class,activity.location,actloc
,SocialAction::class,activity.socialActions,actsocialaction
,SocialIssue::class,activity.socialIssues,actsocialssue
,ThirdParty::class,activity.thirdParties,acttparty
,User::class,activity.user,actuser
,User::class,activity.users,actusers
,ActivityReason::class,activity.reasons,actreasons
,Center::class,actperson.center,actcenter
ActivityReason::class,,,actreasons
,ActivityReasonCategory::class,actreason.category,actreasoncat
Calendar::class,,,cal
,CancelReason::class,cal.cancelReason,calcancel
,Location::class,cal.location,calloc
,User::class,cal.user,caluser
VendeePerson::class,,,vp
,SituationProfessionelle::class,vp.situationProfessionelle,vpprof
,StatutLogement::class,vp.statutLogement,vplog
,TempsDeTravail::class,vp.tempsDeTravail,vptt
1 Entity Join Attribute Alias
2 AccompanyingPeriod::class acp
3 AccompanyingPeriodWork::class acp.works acpw
4 AccompanyingPeriodParticipation::class acp.participations acppart
5 Location::class acp.administrativeLocation acploc
6 ClosingMotive::class acp.closingMotive acpmotive
7 UserJob::class acp.job acpjob
8 Origin::class acp.origin acporigin
9 Scope::class acp.scopes acpscope
10 SocialIssue::class acp.socialIssues acpsocialissue
11 User::class acp.user acpuser
12 AccompanyingPeriodWork::class acpw
13 AccompanyingPeriodWorkEvaluation::class acpw.accompanyingPeriodWorkEvaluations workeval
14 User::class acpw.referrers acpwuser
15 SocialAction::class acpw.socialAction acpwsocialaction
16 Goal::class acpw.goals goal
17 Result::class acpw.results result
18 AccompanyingPeriodParticipation::class acppart
19 Person::class acppart.person partperson
20 AccompanyingPeriodWorkEvaluation::class workeval
21 Evaluation::class workeval.evaluation eval
22 Goal::class goal
23 Result::class goal.results goalresult
24 Person::class person
25 Center::class person.center center
26 HouseholdMember::class partperson.householdParticipations householdmember
27 MaritalStatus::class person.maritalStatus personmarital
28 VendeePerson::class vp
29 VendeePersonMineur::class vpm
30 ResidentialAddress::class resaddr
31 ThirdParty::class resaddr.hostThirdParty tparty
32 ThirdParty::class tparty
33 ThirdPartyCategory::class tparty.categories tpartycat
34 HouseholdMember::class householdmember
35 Household::class householdmember.household household
36 Person::class householdmember.person memberperson
37 memberperson.center membercenter
38 Household::class household
39 HouseholdComposition::class household.compositions composition
40 Activity::class activity
41 Person::class activity.person actperson
42 AccompanyingPeriod::class activity.accompanyingPeriod acp
43 Person::class activity_person_having_activity.person person_person_having_activity
44 ActivityReason::class activity_person_having_activity.reasons reasons_person_having_activity
45 ActivityType::class activity.activityType acttype
46 Location::class activity.location actloc
47 SocialAction::class activity.socialActions actsocialaction
48 SocialIssue::class activity.socialIssues actsocialssue
49 ThirdParty::class activity.thirdParties acttparty
50 User::class activity.user actuser
51 User::class activity.users actusers
52 ActivityReason::class activity.reasons actreasons
53 Center::class actperson.center actcenter
54 ActivityReason::class actreasons
55 ActivityReasonCategory::class actreason.category actreasoncat
56 Calendar::class cal
57 CancelReason::class cal.cancelReason calcancel
58 Location::class cal.location calloc
59 User::class cal.user caluser
60 VendeePerson::class vp
61 SituationProfessionelle::class vp.situationProfessionelle vpprof
62 StatutLogement::class vp.statutLogement vplog
63 TempsDeTravail::class vp.tempsDeTravail vptt

View File

@ -21,7 +21,6 @@ These are alias conventions :
| | AccompanyingPeriodInfo::class | not existing (using custom WITH clause) | acpinfo |
| AccompanyingPeriodWork::class | | | acpw |
| | AccompanyingPeriodWorkEvaluation::class | acpw.accompanyingPeriodWorkEvaluations | workeval |
| | User::class | acpw.referrers | acpwuser |
| | SocialAction::class | acpw.socialAction | acpwsocialaction |
| | Goal::class | acpw.goals | goal |
| | Result::class | acpw.results | result |

View File

@ -22,6 +22,7 @@ use Chill\CalendarBundle\Entity\Calendar;
use Chill\CalendarBundle\Export\Filter\JobFilter;
use Chill\MainBundle\Entity\UserJob;
use Chill\MainBundle\Test\Export\AbstractFilterTest;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\EntityManagerInterface;
/**
@ -62,15 +63,11 @@ final class JobFilterTest extends AbstractFilterTest
->setMaxResults(1)
->getResult();
$data = [];
foreach ($array as $a) {
$data[] = [
'job' => $a,
];
}
return $data;
return [
[
'job' => new ArrayCollection($array)
]
];
}
public function getQueryBuilders(): array

View File

@ -22,6 +22,7 @@ use Chill\CalendarBundle\Entity\Calendar;
use Chill\CalendarBundle\Export\Filter\ScopeFilter;
use Chill\MainBundle\Entity\Scope;
use Chill\MainBundle\Test\Export\AbstractFilterTest;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\EntityManagerInterface;
/**
@ -62,15 +63,11 @@ final class ScopeFilterTest extends AbstractFilterTest
->setMaxResults(1)
->getResult();
$data = [];
foreach ($array as $a) {
$data[] = [
'scope' => $a,
];
}
return $data;
return [
[
'scope' => new ArrayCollection($array)
]
];
}
public function getQueryBuilders(): array

View File

@ -12,7 +12,10 @@ declare(strict_types=1);
namespace Chill\PersonBundle\Export\Aggregator\SocialWorkAggregators;
use Chill\MainBundle\Export\AggregatorInterface;
use Chill\MainBundle\Form\Type\PickRollingDateType;
use Chill\MainBundle\Repository\UserRepository;
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;
@ -21,7 +24,13 @@ use function in_array;
final readonly class ReferrerAggregator implements AggregatorInterface
{
public function __construct(private UserRepository $userRepository, private UserRender $userRender) {}
private const PREFIX = 'acpw_referrer_aggregator';
public function __construct(
private UserRepository $userRepository,
private UserRender $userRender,
private RollingDateConverterInterface $rollingDateConverter
) {}
public function addRole(): ?string
{
@ -30,11 +39,16 @@ final readonly class ReferrerAggregator implements AggregatorInterface
public function alterQuery(QueryBuilder $qb, $data)
{
if (!in_array('acpwuser', $qb->getAllAliases(), true)) {
$qb->leftJoin('acpw.referrers', 'acpwuser');
}
$p = self::PREFIX;
$qb->addSelect('acpwuser.id AS referrer_aggregator');
$qb
->leftJoin('acpw.referrersHistory', $p . "_acpwusers_history")
->andWhere("{$p}_acpwusers_history.startDate <= :{$p}_calc_date AND ({$p}_acpwusers_history.endDate IS NULL or {$p}_acpwusers_history.endDate > :{$p}_calc_date)");
$qb->setParameter("{$p}_calc_date", $this->rollingDateConverter->convert(
$data['referrer_at'] ?? new RollingDate(RollingDate::T_TODAY)
));
$qb->addSelect("IDENTITY({$p}_acpwusers_history.user) AS referrer_aggregator");
$qb->addGroupBy('referrer_aggregator');
}
@ -45,11 +59,16 @@ final readonly class ReferrerAggregator implements AggregatorInterface
public function buildForm(FormBuilderInterface $builder)
{
// no form
$builder->add('referrer_at', PickRollingDateType::class, [
'label' => 'export.aggregator.course_work.by_treating_agent.Calc date'
]);
}
public function getFormDefaultData(): array
{
return [];
return [
'referrer_at' => new RollingDate(RollingDate::T_TODAY),
];
}
public function getLabels($key, array $values, $data)
@ -76,6 +95,6 @@ final readonly class ReferrerAggregator implements AggregatorInterface
public function getTitle(): string
{
return 'Group by treating agent';
return 'export.aggregator.course_work.by_treating_agent.Group by treating agent';
}
}

View File

@ -12,7 +12,10 @@ declare(strict_types=1);
namespace Chill\PersonBundle\Export\Filter\SocialWorkFilters;
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\Query\Expr\Andx;
@ -20,8 +23,12 @@ use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface;
use function in_array;
class ReferrerFilter implements FilterInterface
final readonly class ReferrerFilter implements FilterInterface
{
private const PREFIX = 'acpw_referrer_filter';
public function __construct(private RollingDateConverterInterface $rollingDateConverter) {}
public function addRole(): ?string
{
return null;
@ -29,21 +36,19 @@ class ReferrerFilter 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', ':agents');
$qb
->leftJoin('acpw.referrersHistory', $p . "_acpwusers_history")
->andWhere("{$p}_acpwusers_history.startDate <= :{$p}_calc_date AND ({$p}_acpwusers_history.endDate IS NULL or {$p}_acpwusers_history.endDate > :{$p}_calc_date)")
->andWhere("{$p}_acpwusers_history.user IN (:{$p}_agents)");
if ($where instanceof Andx) {
$where->add($clause);
} else {
$where = $qb->expr()->andX($clause);
}
$qb->add('where', $where);
$qb->setParameter('agents', $data['accepted_agents']);
$qb
->setParameter("{$p}_agents", $data['accepted_agents'])
->setParameter("{$p}_calc_date", $this->rollingDateConverter->convert(
$data['agent_at'] ?? new RollingDate(RollingDate::T_TODAY)
))
;
}
public function applyOn(): string
@ -53,13 +58,23 @@ class ReferrerFilter implements FilterInterface
public function buildForm(FormBuilderInterface $builder)
{
$builder->add('accepted_agents', PickUserDynamicType::class, [
'multiple' => true,
]);
$builder
->add('accepted_agents', PickUserDynamicType::class, [
'multiple' => true,
'label' => 'export.filter.work.by_treating_agent.Accepted agents'
])
->add('agent_at', PickRollingDateType::class, [
'label' => 'export.filter.work.by_treating_agent.Calc date',
'help' => 'export.filter.work.by_treating_agent.calc_date_help',
])
;
}
public function getFormDefaultData(): array
{
return [];
return [
'accepted_agents' => [],
'agent_at' => new RollingDate(RollingDate::T_TODAY),
];
}
public function describeAction($data, $format = 'string'): array
@ -71,13 +86,14 @@ class ReferrerFilter implements FilterInterface
}
return [
'Filtered by treating agent: only %agents%', [
'%agents' => implode(', ', $users),
'exports.filter.work.by_treating_agent.Filtered by treating agent at date', [
'agents' => implode(', ', $users),
'agent_at' => $this->rollingDateConverter->convert($data['agent_at'] ?? new RollingDate(RollingDate::T_TODAY)),
], ];
}
public function getTitle(): string
{
return 'Filter by treating agent';
return 'export.filter.work.by_treating_agent.Filter by treating agent';
}
}

View File

@ -11,6 +11,7 @@ declare(strict_types=1);
namespace Chill\PersonBundle\Tests\Export\Aggregator\SocialWorkAggregators;
use Chill\MainBundle\Service\RollingDate\RollingDate;
use Chill\MainBundle\Test\Export\AbstractAggregatorTest;
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork;
use Chill\PersonBundle\Export\Aggregator\SocialWorkAggregators\ReferrerAggregator;
@ -39,7 +40,10 @@ final class ReferrerAggregatorTest extends AbstractAggregatorTest
public function getFormData(): array
{
return [
[],
[], // there are previous saved export which does not contains any data
[
'referrer_at' => new RollingDate(RollingDate::T_TODAY)
]
];
}

View File

@ -12,6 +12,7 @@ declare(strict_types=1);
namespace Chill\PersonBundle\Tests\Export\Filter\SocialWorkFilters;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Service\RollingDate\RollingDate;
use Chill\MainBundle\Test\Export\AbstractFilterTest;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Export\Filter\SocialWorkFilters\ReferrerFilter;
@ -47,8 +48,13 @@ final class ReferrerFilterTest extends AbstractFilterTest
$data = [];
foreach ($users as $u) {
$data[] = [
'accepted_agents' => $u, // some saved export does not have the parameter "agent_at"
];
$data[] = [
'accepted_agents' => $u,
'agent_at' => new RollingDate(RollingDate::T_TODAY)
];
}

View File

@ -135,7 +135,11 @@ exports:
by_person:
Filtered by person\'s geographical unit (based on address) computed at date, only units:
"Filtré par zone géographique sur base de l'adresse, calculé à {datecalc, date, short}, seulement les zones suivantes: {units}"
filter:
work:
by_treating_agent:
Filtered by treating agent at date: >-
Les agents traitant au { agent_at, date, medium }, seulement {agents}
'total persons matching the search pattern': >-
{ total, plural,
=0 {Aucun usager ne correspond aux termes de recherche}

View File

@ -588,10 +588,6 @@ Filter by current evaluations: Filtrer les évaluations en cours
## social actions filters/aggr
Filter by scope: Filtrer par service
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%"
Group by treating agent: Grouper les actions par agent traitant
Group social work actions by action type: Grouper les actions par type
Group social work actions by goal: Grouper les actions par objectif
@ -1040,6 +1036,9 @@ export:
Group course by scope: Grouper les parcours par service
course_work:
by_treating_agent:
Calc date: Référent à la date
Group by treating agent: Grouper les actions par agent traitant
by_current_action:
Current action ?: Action en cours ?
Group by current actions: Grouper les actions en cours
@ -1160,6 +1159,12 @@ export:
Filter by treating agent scope: Filtrer les actions par service de l'agent traitant
"Filtered by treating agent scope: only %scopes%": "Filtré par service de l'agent traitant: uniquement %scopes%"
Calc date: Date de calcul du service de l'agent traitant
by_treating_agent:
Filter by treating agent: Filtrer les actions par agent traitant
Accepted agents: Agent traitant
Calc date: Date à laquelle l'agent est en situation de désignation sur l'action
calc_date_help: Il s'agit de la date à laquelle l'agent est actif comme agent traitant de l'action, et non la date à la quelle l'agent est désigné comme agent traitant.
"Filtered by treating agent: only %agents%": "Filtré par agent traitant: uniquement %agents%"
list:
person_with_acp: