exports: add new aggregators for acp

This commit is contained in:
Mathieu Jaumotte 2022-08-04 15:14:56 +02:00
parent f37e7cf393
commit fcd7ae3b8d
14 changed files with 811 additions and 24 deletions

View File

@ -188,6 +188,7 @@ Main location: Localisation principale
Main scope: Cercle
Main center: Centre
user job: Métier de l'utilisateur
Job: Métier
Choose a main center: Choisir un centre
Choose a main scope: Choisir un cercle
choose a job: Choisir un métier
@ -248,6 +249,7 @@ Country code: Code du pays
# circles / scopes
Choose the circle: Choisir le cercle
Scope: Service
Scopes: Services
#export

View File

@ -0,0 +1,104 @@
<?php
namespace Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators;
use Chill\MainBundle\Export\AggregatorInterface;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Chill\PersonBundle\Export\Declarations;
use Chill\PersonBundle\Repository\SocialWork\EvaluationRepository;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface;
final class EvaluationAggregator implements AggregatorInterface
{
private EvaluationRepository $evaluationRepository;
private TranslatableStringHelper $translatableStringHelper;
public function __construct(
EvaluationRepository $evaluationRepository,
TranslatableStringHelper $translatableStringHelper
) {
$this->evaluationRepository = $evaluationRepository;
$this->translatableStringHelper = $translatableStringHelper;
}
/**
* @inheritDoc
*/
public function getLabels($key, array $values, $data)
{
return function ($value): string {
if ('_header' === $value) {
return 'Evaluation';
}
$e = $this->evaluationRepository->find($value);
return $this->translatableStringHelper->localize(
$e->getTitle()
);
};
}
/**
* @inheritDoc
*/
public function getQueryKeys($data): array
{
return ['evaluation_aggregator'];
}
/**
* @inheritDoc
*/
public function buildForm(FormBuilderInterface $builder)
{
// no form
}
/**
* @inheritDoc
*/
public function getTitle(): string
{
return 'Group by evaluation';
}
/**
* @inheritDoc
*/
public function addRole()
{
return null;
}
/**
* @inheritDoc
*/
public function alterQuery(QueryBuilder $qb, $data)
{
$qb
->join('acp.works', 'acpw')
->join('acpw.accompanyingPeriodWorkEvaluations', 'we')
;
$qb->addSelect('IDENTITY(we.evaluation) AS evaluation_aggregator');
$groupby = $qb->getDQLPart('groupBy');
if (!empty($groupBy)) {
$qb->addGroupBy('evaluation_aggregator');
} else {
$qb->groupBy('evaluation_aggregator');
}
}
/**
* @inheritDoc
*/
public function applyOn(): string
{
return Declarations::ACP_TYPE;
}
}

View File

@ -0,0 +1,103 @@
<?php
namespace Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators;
use Chill\MainBundle\Export\AggregatorInterface;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Chill\PersonBundle\Entity\AccompanyingPeriod\Origin;
use Chill\PersonBundle\Export\Declarations;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface;
final class OriginAggregator implements AggregatorInterface
{
private EntityRepository $repository;
private TranslatableStringHelper $translatableStringHelper;
public function __construct(
EntityManagerInterface $em,
TranslatableStringHelper $translatableStringHelper
) {
$this->repository = $em->getRepository(Origin::class);
$this->translatableStringHelper = $translatableStringHelper;
}
/**
* @inheritDoc
*/
public function getLabels($key, array $values, $data)
{
return function ($value): string {
if ('_header' === $value) {
return 'Origin';
}
$o = $this->repository->find($value);
return $this->translatableStringHelper->localize(
$o->getLabel()
);
};
}
/**
* @inheritDoc
*/
public function getQueryKeys($data): array
{
return ['origin_aggregator'];
}
/**
* @inheritDoc
*/
public function buildForm(FormBuilderInterface $builder)
{
// no form
}
/**
* @inheritDoc
*/
public function getTitle(): string
{
return 'Group by origin';
}
/**
* @inheritDoc
*/
public function addRole()
{
return null;
}
/**
* @inheritDoc
*/
public function alterQuery(QueryBuilder $qb, $data)
{
$qb->join('acp.origin', 'o');
$qb->addSelect('o.id AS origin_aggregator');
$groupby = $qb->getDQLPart('groupBy');
if (!empty($groupBy)) {
$qb->addGroupBy('origin_aggregator');
} else {
$qb->groupBy('origin_aggregator');
}
}
/**
* @inheritDoc
*/
public function applyOn(): string
{
return Declarations::ACP_TYPE;
}
}

View File

@ -0,0 +1,99 @@
<?php
namespace Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators;
use Chill\MainBundle\Export\AggregatorInterface;
use Chill\PersonBundle\Export\Declarations;
use Chill\PersonBundle\Repository\SocialWork\SocialActionRepository;
use Chill\PersonBundle\Templating\Entity\SocialActionRender;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface;
final class SocialActionAggregator implements AggregatorInterface
{
private SocialActionRender $actionRender;
private SocialActionRepository $actionRepository;
public function __construct(
SocialActionRender $actionRender,
SocialActionRepository $actionRepository
) {
$this->actionRender = $actionRender;
$this->actionRepository = $actionRepository;
}
/**
* @inheritDoc
*/
public function getLabels($key, array $values, $data)
{
return function($value) {
if ('_header' === $value) {
return 'Social action';
}
$sa = $this->actionRepository->find($value);
return $this->actionRender->renderString($sa, []);
};
}
/**
* @inheritDoc
*/
public function getQueryKeys($data): array
{
return ['socialaction_aggregator'];
}
/**
* @inheritDoc
*/
public function buildForm(FormBuilderInterface $builder)
{
// no form
}
/**
* @inheritDoc
*/
public function getTitle(): string
{
return 'Group by social action';
}
/**
* @inheritDoc
*/
public function addRole()
{
return null;
}
/**
* @inheritDoc
*/
public function alterQuery(QueryBuilder $qb, $data)
{
$qb->join('acp.works', 'acpw');
$qb->addSelect('IDENTITY(acpw.socialAction) AS socialaction_aggregator'); // DISTINCT ??
$groupby = $qb->getDQLPart('groupBy');
if (!empty($groupBy)) {
$qb->addGroupBy('socialaction_aggregator');
} else {
$qb->groupBy('socialaction_aggregator');
}
}
/**
* @inheritDoc
*/
public function applyOn(): string
{
return Declarations::ACP_TYPE;
}
}

View File

@ -0,0 +1,100 @@
<?php
namespace Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators;
use Chill\MainBundle\Export\AggregatorInterface;
use Chill\PersonBundle\Export\Declarations;
use Chill\PersonBundle\Repository\SocialWork\SocialIssueRepository;
use Chill\PersonBundle\Templating\Entity\SocialIssueRender;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface;
final class SocialIssueAggregator implements AggregatorInterface
{
private SocialIssueRepository $issueRepository;
private SocialIssueRender $issueRender;
public function __construct(
SocialIssueRepository $issueRepository,
SocialIssueRender $issueRender
) {
$this->issueRepository = $issueRepository;
$this->issueRender = $issueRender;
}
/**
* @inheritDoc
*/
public function getLabels($key, array $values, $data)
{
return function ($value): string {
if ($value === '_header') {
return 'Social issues';
}
$i = $this->issueRepository->find($value);
return $this->issueRender->renderString($i, []);
};
}
/**
* @inheritDoc
*/
public function getQueryKeys($data): array
{
return ['socialissue_aggregator'];
}
/**
* @inheritDoc
*/
public function buildForm(FormBuilderInterface $builder)
{
// no form
}
/**
* @inheritDoc
*/
public function getTitle(): string
{
return 'Group by social issue';
}
/**
* @inheritDoc
*/
public function addRole()
{
return null;
}
/**
* @inheritDoc
*/
public function alterQuery(QueryBuilder $qb, $data)
{
$qb->join('acp.socialIssues', 'si');
$qb->addSelect('si.id as socialissue_aggregator');
$groupBy = $qb->getDQLPart('groupBy');
if (!empty($groupBy)) {
$qb->addGroupBy('socialissue_aggregator');
} else {
$qb->groupBy('socialissue_aggregator');
}
}
/**
* @inheritDoc
*/
public function applyOn(): string
{
return Declarations::ACP_TYPE;
}
}

View File

@ -0,0 +1,142 @@
<?php
namespace Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators;
use Chill\MainBundle\Export\AggregatorInterface;
//use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Form\Type\ChillDateType;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Export\Declarations;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Query\Expr\Andx;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
final class StepAggregator implements AggregatorInterface //, FilterInterface
{
private TranslatorInterface $translator;
public function __construct(
TranslatorInterface $translator
) {
$this->translator = $translator;
}
/**
* @inheritDoc
*/
public function getLabels($key, array $values, $data)
{
return function ($value): string {
switch ($value) {
case AccompanyingPeriod::STEP_DRAFT:
return $this->translator->trans('Draft');
case AccompanyingPeriod::STEP_CONFIRMED:
return $this->translator->trans('Confirmed');
case AccompanyingPeriod::STEP_CLOSED:
return $this->translator->trans('Closed');
case '_header':
return 'Step';
default:
throw new LogicException(sprintf('The value %s is not valid', $value));
}
};
}
/**
* @inheritDoc
*/
public function getQueryKeys($data): array
{
return ['step_aggregator'];
}
/**
* @inheritDoc
*/
public function buildForm(FormBuilderInterface $builder)
{
$builder->add('on_date', ChillDateType::class, [
'data' => new \DateTime(),
]);
}
/**
* @inheritDoc
*/
public function getTitle(): string
{
return 'Group by step';
}
/**
* @inheritDoc
*/
public function addRole()
{
return null;
}
/**
* @inheritDoc
*/
public function alterQuery(QueryBuilder $qb, $data)
{
$qb->addSelect('acp.step AS step_aggregator');
$groupBy = $qb->getDQLPart('groupBy');
if (!empty($groupBy)) {
$qb->addGroupBy('step_aggregator');
} else {
$qb->groupBy('step_aggregator');
}
// add date in where clause
$where = $qb->getDQLPart('where');
$clause = $qb->expr()->andX(
$qb->expr()->lte('acp.openingDate', ':ondate'),
$qb->expr()->orX(
$qb->expr()->gt('acp.closingDate', ':ondate'),
$qb->expr()->isNull('acp.closingDate')
)
);
if ($where instanceof Andx) {
$where->add($clause);
} else {
$where = $qb->expr()->andX($clause);
}
$qb->add('where', $where);
$qb->setParameter('ondate', $data['on_date'], Types::DATE_MUTABLE);
}
/**
* @inheritDoc
*/
public function applyOn(): string
{
return Declarations::ACP_TYPE;
}
/*
* TODO check if we need to add FilterInterface and DescribeAction Method to describe date filter ??
*
public function describeAction($data, $format = 'string')
{
return [
"Filtered by actives courses: active on %ondate%", [
'%ondate%' => $data['on_date']->format('d-m-Y')
]
];
}
*/
}

View File

@ -0,0 +1,101 @@
<?php
namespace Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators;
use Chill\MainBundle\Export\AggregatorInterface;
use Chill\MainBundle\Repository\UserJobRepository;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Chill\PersonBundle\Export\Declarations;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface;
final class UserJobAggregator implements AggregatorInterface
{
private UserJobRepository $jobRepository;
private TranslatableStringHelper $translatableStringHelper;
public function __construct(
UserJobRepository $jobRepository,
TranslatableStringHelper $translatableStringHelper
) {
$this->jobRepository = $jobRepository;
$this->translatableStringHelper = $translatableStringHelper;
}
/**
* @inheritDoc
*/
public function getLabels($key, array $values, $data)
{
return function($value): string {
if ($value === '_header') {
return 'Job';
}
$j = $this->jobRepository->find($value);
return $this->translatableStringHelper->localize(
$j->getLabel()
);
};
}
/**
* @inheritDoc
*/
public function getQueryKeys($data): array
{
return ['userjob_aggregator'];
}
/**
* @inheritDoc
*/
public function buildForm(FormBuilderInterface $builder)
{
// no form
}
/**
* @inheritDoc
*/
public function getTitle(): string
{
return 'Group by user job';
}
/**
* @inheritDoc
*/
public function addRole()
{
return null;
}
/**
* @inheritDoc
*/
public function alterQuery(QueryBuilder $qb, $data)
{
$qb->join('acp.job', 'j');
$qb->addSelect('IDENTITY(acp.job) AS userjob_aggregator');
$groupBy = $qb->getDQLPart('groupBy');
if (!empty($groupBy)) {
$qb->addGroupBy('userjob_aggregator');
} else {
$qb->groupBy('userjob_aggregator');
}
}
/**
* @inheritDoc
*/
public function applyOn(): string
{
return Declarations::ACP_TYPE;
}
}

View File

@ -0,0 +1,99 @@
<?php
namespace Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators;
use Chill\MainBundle\Export\AggregatorInterface;
use Chill\MainBundle\Repository\ScopeRepository;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Chill\PersonBundle\Export\Declarations;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface;
final class UserScopeAggregator implements AggregatorInterface
{
private ScopeRepository $scopeRepository;
private TranslatableStringHelper $translatableStringHelper;
public function __construct(
ScopeRepository $scopeRepository,
TranslatableStringHelper $translatableStringHelper
) {
$this->scopeRepository = $scopeRepository;
$this->translatableStringHelper = $translatableStringHelper;
}
/**
* @inheritDoc
*/
public function getLabels($key, array $values, $data)
{
return function ($value): string {
if ($value === '_header') {
return 'Scope';
}
$s = $this->scopeRepository->find($value);
return $this->translatableStringHelper->localize($s->getName());
};
}
/**
* @inheritDoc
*/
public function getQueryKeys($data): array
{
return ['userscope_aggregator'];
}
/**
* @inheritDoc
*/
public function buildForm(FormBuilderInterface $builder)
{
// no form
}
/**
* @inheritDoc
*/
public function getTitle(): string
{
return 'Group by user scope';
}
/**
* @inheritDoc
*/
public function addRole()
{
return null;
}
/**
* @inheritDoc
*/
public function alterQuery(QueryBuilder $qb, $data)
{
$qb->join('acp.scopes', 's');
$qb->addSelect('s.id as userscope_aggregator');
$groupBy = $qb->getDQLPart('groupBy');
if (!empty($groupBy)) {
$qb->addGroupBy('userscope_aggregator');
} else {
$qb->groupBy('userscope_aggregator');
}
}
/**
* @inheritDoc
*/
public function applyOn(): string
{
return Declarations::ACP_TYPE;
}
}

View File

@ -20,23 +20,17 @@ use Doctrine\ORM\Query\Expr\Andx;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Security\Core\Security;
use Symfony\Contracts\Translation\TranslatorInterface;
class CurrentUserJobFilter implements FilterInterface
{
protected TranslatorInterface $translator;
private Security $security;
private TranslatableStringHelper $translatableStringHelper;
public function __construct(
TranslatorInterface $translator,
TranslatableStringHelper $translatableStringHelper,
Security $security
) {
$this->translator = $translator;
$this->translatableStringHelper = $translatableStringHelper;
$this->security = $security;
}

View File

@ -22,15 +22,9 @@ use Doctrine\ORM\QueryBuilder;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Security\Core\Security;
use Symfony\Contracts\Translation\TranslatorInterface;
class CurrentUserScopeFilter implements FilterInterface
{
/**
* @var TranslatorInterface
*/
protected $translator;
private Security $security;
/**
@ -39,11 +33,9 @@ class CurrentUserScopeFilter implements FilterInterface
private TranslatableStringHelper $translatableStringHelper;
public function __construct(
TranslatorInterface $translator,
TranslatableStringHelper $translatableStringHelper,
Security $security
) {
$this->translator = $translator;
$this->translatableStringHelper = $translatableStringHelper;
$this->security = $security;
}

View File

@ -51,7 +51,7 @@ class GeographicalUnitStatFilter implements FilterInterface
*/
public function getTitle(): string
{
return 'Filter by geographic unit';
return 'Filter by geographical unit';
}
/**

View File

@ -11,15 +11,9 @@ use Doctrine\ORM\Query\Expr\Andx;
use Doctrine\ORM\QueryBuilder;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
class SocialActionFilter implements FilterInterface
{
/**
* @var TranslatorInterface
*/
protected $translator;
/**
* @var TranslatableStringHelper
*/
@ -31,11 +25,9 @@ class SocialActionFilter implements FilterInterface
private SocialActionRender $actionRender;
public function __construct(
TranslatorInterface $translator,
TranslatableStringHelper $translatableStringHelper,
SocialActionRender $actionRender
) {
$this->translator = $translator;
$this->translatableStringHelper = $translatableStringHelper;
$this->actionRender = $actionRender;
}

View File

@ -149,4 +149,52 @@ services:
tags:
- { name: chill.export_filter, alias: accompanyingcourse_openbetweendates_filter }
## Aggregators
## Aggregators
chill.person.export.aggregator_userscope:
class: Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators\UserScopeAggregator
autowire: true
autoconfigure: true
tags:
- { name: chill.export_aggregator, alias: accompanyingcourse_userscope_aggregator }
chill.person.export.aggregator_userjob:
class: Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators\UserJobAggregator
autowire: true
autoconfigure: true
tags:
- { name: chill.export_aggregator, alias: accompanyingcourse_userjob_aggregator }
chill.person.export.aggregator_socialissue:
class: Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators\SocialIssueAggregator
autowire: true
autoconfigure: true
tags:
- { name: chill.export_aggregator, alias: accompanyingcourse_socialissue_aggregator }
chill.person.export.aggregator_step:
class: Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators\StepAggregator
autowire: true
autoconfigure: true
tags:
- { name: chill.export_aggregator, alias: accompanyingcourse_step_aggregator }
chill.person.export.aggregator_socialaction:
class: Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators\SocialActionAggregator
autowire: true
autoconfigure: true
tags:
- { name: chill.export_aggregator, alias: accompanyingcourse_socialaction_aggregator }
chill.person.export.aggregator_evaluation:
class: Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators\EvaluationAggregator
autowire: true
autoconfigure: true
tags:
- { name: chill.export_aggregator, alias: accompanyingcourse_evaluation_aggregator }
chill.person.export.aggregator_origin:
class: Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators\OriginAggregator
autowire: true
autoconfigure: true
tags:
- { name: chill.export_aggregator, alias: accompanyingcourse_origin_aggregator }

View File

@ -203,6 +203,7 @@ This accompanying course is still a draft: Ce parcours est encore à l'état bro
Associated peoples: Usagers concernés
Resources: Interlocuteurs privilégiés
Any requestor to this accompanying course: Aucun demandeur pour ce parcours
Social action: Action d'accompagnement
Social actions: Actions d'accompagnement
Last social actions: Les dernières actions d'accompagnement
Social issue: Problématique sociale
@ -411,25 +412,34 @@ Having an accompanying period closed after this date: Ayant une période d'accom
Filter by user scope: Filtrer par service du référent
"Filtered by user main scope: only %scope%": "Filtré par service du référent: uniquement %scope%"
Group by user scope: Grouper par service du référent
Filter by user job: Filtrer par métier du référent
"Filtered by user job: only %job%": "Filtré par métier du référent: uniquement %job%"
Group by user job: Grouper par métier du référent
Filter by social issue: Filtrer par problématiques sociales
Accepted socialissues: Problématiques sociales
"Filtered by socialissues: only %socialissues%": "Filtré par problématique sociale: uniquement %socialissues%"
Group by social issue: Grouper par problématiques sociales
Filter by step: Filtrer par statut du parcours
Accepted steps: Statuts
Step: Statut
"Filtered by steps: only %step%": "Filtré par statut du parcours: uniquement %step%"
Group by step: Grouper par statut du parcours
Filter by geographical unit: Filtrer par zone géographique
Filter by socialaction: Filtrer par action d'accompagnement
Accepted socialactions: Actions d'accompagnement
"Filtered by socialactions: only %socialactions%": "Filtré par action d'accompagnement: uniquement %socialactions%"
Group by social action: Grouper par action d'accompagnement
Filter by evaluation: Filtrer par évaluation
Accepted evaluations: Évaluations
Evaluation: Évaluation
"Filtered by evaluations: only %evals%": "Filtré par évaluation: uniquement %evals%"
Group by evaluation: Grouper par évaluation
Filter by activity type: Filtrer par type d'activité
Accepted activitytypes: Types d'activités
@ -438,6 +448,7 @@ Accepted activitytypes: Types d'activités
Filter by origin: Filtrer par origine du parcours
Accepted origins: Origines
"Filtered by origins: only %origins%": "Filtré par origine du parcours: uniquement %origins%"
Group by origin: Grouper par origine du parcours
Filter by closing motive: Filtrer par motif de fermeture
Accepted closingmotives: Motifs de clôture