mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
Merge branch '163-re-associate-person-filters' into 'master'
[exports] fix the association between aggregators and filter and the export "count persons" Closes #138 and #163 See merge request Chill-Projet/chill-bundles!595
This commit is contained in:
commit
b35838f840
5
.changes/unreleased/Fixed-20230928-143246.yaml
Normal file
5
.changes/unreleased/Fixed-20230928-143246.yaml
Normal file
@ -0,0 +1,5 @@
|
||||
kind: Fixed
|
||||
body: Fix the filters and aggregators on exports "count peoples"
|
||||
time: 2023-09-28T14:32:46.696092741+02:00
|
||||
custom:
|
||||
Issue: "163"
|
@ -17,6 +17,9 @@ use Chill\ActivityBundle\Repository\ActivityReasonRepository;
|
||||
use Chill\MainBundle\Export\ExportElementValidatedInterface;
|
||||
use Chill\MainBundle\Export\FilterInterface;
|
||||
use Chill\MainBundle\Form\Type\Export\FilterType;
|
||||
use Chill\MainBundle\Form\Type\PickRollingDateType;
|
||||
use Chill\MainBundle\Service\RollingDate\RollingDate;
|
||||
use Chill\MainBundle\Service\RollingDate\RollingDateConverterInterface;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||
use Chill\PersonBundle\Export\Declarations;
|
||||
@ -46,7 +49,8 @@ class PersonHavingActivityBetweenDateFilter implements ExportElementValidatedInt
|
||||
public function __construct(
|
||||
TranslatableStringHelper $translatableStringHelper,
|
||||
ActivityReasonRepository $activityReasonRepository,
|
||||
TranslatorInterface $translator
|
||||
TranslatorInterface $translator,
|
||||
private readonly RollingDateConverterInterface $rollingDateConverter,
|
||||
) {
|
||||
$this->translatableStringHelper = $translatableStringHelper;
|
||||
$this->activityReasonRepository = $activityReasonRepository;
|
||||
@ -62,16 +66,19 @@ class PersonHavingActivityBetweenDateFilter implements ExportElementValidatedInt
|
||||
{
|
||||
// create a subquery for activity
|
||||
$sqb = $qb->getEntityManager()->createQueryBuilder();
|
||||
$sqb->select('person_person_having_activity.id')
|
||||
$sqb->select('1')
|
||||
->from(Activity::class, 'activity_person_having_activity')
|
||||
->join('activity_person_having_activity.person', 'person_person_having_activity');
|
||||
->leftJoin('activity_person_having_activity.person', 'person_person_having_activity');
|
||||
|
||||
// add clause between date
|
||||
$sqb->where('activity_person_having_activity.date BETWEEN '
|
||||
. ':person_having_activity_between_date_from'
|
||||
. ' AND '
|
||||
. ':person_having_activity_between_date_to');
|
||||
. ':person_having_activity_between_date_to'
|
||||
. ' AND '
|
||||
. '(person_person_having_activity.id = person.id OR person MEMBER OF activity_person_having_activity.persons)');
|
||||
|
||||
if (isset($data['reasons']) && [] !== $data['reasons']) {
|
||||
// add clause activity reason
|
||||
$sqb->join('activity_person_having_activity.reasons', 'reasons_person_having_activity');
|
||||
|
||||
@ -82,111 +89,70 @@ class PersonHavingActivityBetweenDateFilter implements ExportElementValidatedInt
|
||||
)
|
||||
);
|
||||
|
||||
$where = $qb->getDQLPart('where');
|
||||
$clause = $qb->expr()->in('person.id', $sqb->getDQL());
|
||||
|
||||
if ($where instanceof Expr\Andx) {
|
||||
$where->add($clause);
|
||||
} else {
|
||||
$where = $qb->expr()->andX($clause);
|
||||
$qb->setParameter('person_having_activity_reasons', $data['reasons']);
|
||||
}
|
||||
|
||||
$qb->add('where', $where);
|
||||
$qb->andWhere(
|
||||
$qb->expr()->exists($sqb->getDQL())
|
||||
);
|
||||
|
||||
$qb->setParameter(
|
||||
'person_having_activity_between_date_from',
|
||||
$data['date_from']
|
||||
$this->rollingDateConverter->convert($data['date_from_rolling'])
|
||||
);
|
||||
$qb->setParameter(
|
||||
'person_having_activity_between_date_to',
|
||||
$data['date_to']
|
||||
$this->rollingDateConverter->convert($data['date_to_rolling'])
|
||||
);
|
||||
$qb->setParameter('person_having_activity_reasons', $data['reasons']);
|
||||
}
|
||||
|
||||
public function applyOn(): string
|
||||
{
|
||||
return Declarations::PERSON_IMPLIED_IN;
|
||||
return Declarations::PERSON_TYPE;
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
$builder->add('date_from', DateType::class, [
|
||||
'label' => 'Implied in an activity after this date',
|
||||
'attr' => ['class' => 'datepicker'],
|
||||
'widget' => 'single_text',
|
||||
'format' => 'dd-MM-yyyy',
|
||||
$builder->add('date_from_rolling', PickRollingDateType::class, [
|
||||
'label' => 'export.filter.activity.person_between_dates.Implied in an activity after this date',
|
||||
]);
|
||||
|
||||
$builder->add('date_to', DateType::class, [
|
||||
'label' => 'Implied in an activity before this date',
|
||||
'attr' => ['class' => 'datepicker'],
|
||||
'widget' => 'single_text',
|
||||
'format' => 'dd-MM-yyyy',
|
||||
$builder->add('date_to_rolling', PickRollingDateType::class, [
|
||||
'label' => 'export.filter.activity.person_between_dates.Implied in an activity before this date',
|
||||
]);
|
||||
|
||||
if ([] !== $reasons = $this->activityReasonRepository->findAll()) {
|
||||
$builder->add('reasons', EntityType::class, [
|
||||
'class' => ActivityReason::class,
|
||||
'choices' => $reasons,
|
||||
'choice_label' => fn (ActivityReason $reason): ?string => $this->translatableStringHelper->localize($reason->getName()),
|
||||
'group_by' => fn (ActivityReason $reason): ?string => $this->translatableStringHelper->localize($reason->getCategory()->getName()),
|
||||
'multiple' => true,
|
||||
'expanded' => false,
|
||||
'label' => 'Activity reasons for those activities',
|
||||
'label' => 'export.filter.activity.person_between_dates.Activity reasons for those activities',
|
||||
'help' => 'export.filter.activity.person_between_dates.if no reasons',
|
||||
]);
|
||||
|
||||
$builder->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) {
|
||||
/** @var FormInterface $filterForm */
|
||||
$filterForm = $event->getForm()->getParent();
|
||||
$enabled = $filterForm->get(FilterType::ENABLED_FIELD)->getData();
|
||||
|
||||
if (true === $enabled) {
|
||||
// if the filter is enabled, add some validation
|
||||
$form = $event->getForm();
|
||||
$date_from = $form->get('date_from')->getData();
|
||||
$date_to = $form->get('date_to')->getData();
|
||||
|
||||
// check that fields are not empty
|
||||
if (null === $date_from) {
|
||||
$form->get('date_from')->addError(new FormError(
|
||||
$this->translator->trans('This field '
|
||||
. 'should not be empty')
|
||||
));
|
||||
}
|
||||
|
||||
if (null === $date_to) {
|
||||
$form->get('date_to')->addError(new FormError(
|
||||
$this->translator->trans('This field '
|
||||
. 'should not be empty')
|
||||
));
|
||||
}
|
||||
|
||||
// check that date_from is before date_to
|
||||
if (
|
||||
(null !== $date_from && null !== $date_to)
|
||||
&& $date_from >= $date_to
|
||||
) {
|
||||
$form->get('date_to')->addError(new FormError(
|
||||
$this->translator->trans('This date '
|
||||
. 'should be after the date given in "Implied in an '
|
||||
. 'activity after this date" field')
|
||||
));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
public function getFormDefaultData(): array
|
||||
{
|
||||
return ['date_from' => new DateTime(), 'date_to' => new DateTime(), 'reasons' => $this->activityReasonRepository->findAll()];
|
||||
return [
|
||||
'date_from_rolling' => new RollingDate(RollingDate::T_YEAR_PREVIOUS_START),
|
||||
'date_to_rolling' => new RollingDate(RollingDate::T_TODAY),
|
||||
'reasons' => [],
|
||||
];
|
||||
}
|
||||
|
||||
public function describeAction($data, $format = 'string')
|
||||
{
|
||||
return [
|
||||
'Filtered by person having an activity between %date_from% and '
|
||||
. '%date_to% with reasons %reasons_name%',
|
||||
[] === $data['reasons'] ?
|
||||
'export.filter.person_between_dates.describe_action_with_no_subject'
|
||||
: 'export.filter.person_between_dates.describe_action_with_subject',
|
||||
[
|
||||
'%date_from%' => $data['date_from']->format('d-m-Y'),
|
||||
'%date_to%' => $data['date_to']->format('d-m-Y'),
|
||||
'%reasons_name%' => implode(
|
||||
'date_from' => $this->rollingDateConverter->convert($data['date_from_rolling']),
|
||||
'date_to' => $this->rollingDateConverter->convert($data['date_to_rolling']),
|
||||
'reasons' => implode(
|
||||
', ',
|
||||
array_map(
|
||||
fn (ActivityReason $r): string => '"' . $this->translatableStringHelper->localize($r->getName()) . '"',
|
||||
@ -199,13 +165,15 @@ class PersonHavingActivityBetweenDateFilter implements ExportElementValidatedInt
|
||||
|
||||
public function getTitle()
|
||||
{
|
||||
return 'Filter by person having an activity in a period';
|
||||
return 'export.filter.activity.person_between_dates.title';
|
||||
}
|
||||
|
||||
public function validateForm($data, ExecutionContextInterface $context)
|
||||
{
|
||||
if (null === $data['reasons'] || count($data['reasons']) === 0) {
|
||||
$context->buildViolation('At least one reason must be chosen')
|
||||
if ($this->rollingDateConverter->convert($data['date_from_rolling'])
|
||||
>= $this->rollingDateConverter->convert($data['date_to_rolling'])) {
|
||||
$context->buildViolation('export.filter.activity.person_between_dates.date mismatch')
|
||||
->setTranslationDomain('messages')
|
||||
->addViolation();
|
||||
}
|
||||
}
|
||||
|
@ -3,3 +3,9 @@ export:
|
||||
activity:
|
||||
course_having_activity_between_date:
|
||||
Only course having an activity between from and to: Seulement les parcours ayant reçu au moins un échange entre le {from, date, short} et le {to, date, short}
|
||||
person_between_dates:
|
||||
describe_action_with_no_subject: >-
|
||||
Filtré par personne ayant eu un échange entre le {date_from, date} et le {date_to, date}
|
||||
describe_action_with_subject: >-
|
||||
Filtré par personne ayant eu un échange entre le {date_from, date} et le {date_to, date}, et un de ces sujets choisis: {reasons}
|
||||
|
||||
|
@ -255,11 +255,6 @@ Activities before this date: Échanges avant cette date
|
||||
"Filtered by date of activity: only between %date_from% and %date_to%": "Filtré par date de l'échange: uniquement entre %date_from% et %date_to%"
|
||||
This date should be after the date given in "Implied in an activity after this date" field: Cette date devrait être postérieure à la date donnée dans le champ "échanges après cette date"
|
||||
|
||||
Filtered by person having an activity in a period: Uniquement les usagers ayant eu un échange dans la période donnée
|
||||
Implied in an activity after this date: Impliqué dans un échange après cette date
|
||||
Implied in an activity before this date: Impliqué dans un échange avant cette date
|
||||
Filtered by person having an activity between %date_from% and %date_to% with reasons %reasons_name%: Filtré par usager associées à un échange entre %date_from% et %date_to% avec les sujets %reasons_name%
|
||||
Activity reasons for those activities: Sujets de ces échanges
|
||||
|
||||
Filter by activity type: Filtrer les échanges par type
|
||||
|
||||
@ -379,7 +374,13 @@ export:
|
||||
Receiving an activity before: Ayant reçu un échange avant le
|
||||
acp_by_activity_type:
|
||||
'acp_containing_at_least_one_%activitytypes%': 'Parcours filtrés: uniquement ceux qui contiennent au moins un échange d''un des types suivants: %activitytypes%'
|
||||
|
||||
person_between_dates:
|
||||
Implied in an activity after this date: Impliqué dans un échange après cette date
|
||||
Implied in an activity before this date: Impliqué dans un échange avant cette date
|
||||
Activity reasons for those activities: Sujets de ces échanges
|
||||
if no reasons: Si aucun sujet n'est coché, tous les sujets seront pris en compte
|
||||
title: Filtrer les personnes ayant été associés à un échange au cours de la période
|
||||
date mismatch: La date de fin de la période doit être supérieure à la date du début
|
||||
|
||||
aggregator:
|
||||
activity:
|
||||
|
@ -22,6 +22,9 @@ abstract class Declarations
|
||||
|
||||
public const HOUSEHOLD_TYPE = 'household';
|
||||
|
||||
/**
|
||||
* @deprecated consider using the PERSON_TYPE instead
|
||||
*/
|
||||
public const PERSON_IMPLIED_IN = 'person_implied_in';
|
||||
|
||||
public const PERSON_TYPE = 'person';
|
||||
|
@ -120,9 +120,7 @@ class CountPerson implements ExportInterface, GroupedExportInterface
|
||||
public function supportsModifiers()
|
||||
{
|
||||
return [
|
||||
'abcde',
|
||||
//Declarations::PERSON_TYPE,
|
||||
//Declarations::PERSON_IMPLIED_IN,
|
||||
Declarations::PERSON_TYPE,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -266,7 +266,7 @@ class ListPerson implements ExportElementValidatedInterface, ListInterface, Grou
|
||||
|
||||
public function supportsModifiers()
|
||||
{
|
||||
return [Declarations::PERSON_TYPE, Declarations::PERSON_IMPLIED_IN];
|
||||
return [Declarations::PERSON_TYPE];
|
||||
}
|
||||
|
||||
public function validateForm($data, ExecutionContextInterface $context)
|
||||
|
@ -205,7 +205,7 @@ class ListPersonHavingAccompanyingPeriod implements ExportElementValidatedInterf
|
||||
|
||||
public function supportsModifiers()
|
||||
{
|
||||
return [Declarations::PERSON_TYPE, Declarations::PERSON_IMPLIED_IN, Declarations::ACP_TYPE];
|
||||
return [Declarations::PERSON_TYPE, Declarations::ACP_TYPE];
|
||||
}
|
||||
|
||||
public function validateForm($data, ExecutionContextInterface $context)
|
||||
|
@ -149,6 +149,6 @@ final readonly class ListPersonWithAccompanyingPeriodDetails implements ListInte
|
||||
|
||||
public function supportsModifiers()
|
||||
{
|
||||
return [Declarations::PERSON_TYPE, Declarations::PERSON_IMPLIED_IN, Declarations::ACP_TYPE];
|
||||
return [Declarations::PERSON_TYPE, Declarations::ACP_TYPE];
|
||||
}
|
||||
}
|
||||
|
@ -463,7 +463,7 @@ class ReportList implements ExportElementValidatedInterface, ListInterface
|
||||
|
||||
public function supportsModifiers()
|
||||
{
|
||||
return [Declarations::PERSON_IMPLIED_IN, Declarations::PERSON_TYPE, 'report'];
|
||||
return [Declarations::PERSON_TYPE, 'report'];
|
||||
}
|
||||
|
||||
public function validateForm($data, ExecutionContextInterface $context)
|
||||
|
Loading…
x
Reference in New Issue
Block a user