From c1f578a81182d3bc9abcc5b8a272e1b77809f88e Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Fri, 29 Jul 2022 12:13:32 +0200 Subject: [PATCH 1/9] exports: add new referrer filter, with mechanism to use it in acp or acpw context --- .../ChillPersonBundle/Export/Declarations.php | 2 + .../Export/Export/CountAccompanyingCourse.php | 2 +- .../Export/Filter/ReferrerFilter.php | 161 ++++++++++++++++++ .../services/exports_accompanying_period.yaml | 7 + .../translations/messages.fr.yml | 4 + 5 files changed, 175 insertions(+), 1 deletion(-) create mode 100644 src/Bundle/ChillPersonBundle/Export/Filter/ReferrerFilter.php diff --git a/src/Bundle/ChillPersonBundle/Export/Declarations.php b/src/Bundle/ChillPersonBundle/Export/Declarations.php index bb892a69c..58a8eec24 100644 --- a/src/Bundle/ChillPersonBundle/Export/Declarations.php +++ b/src/Bundle/ChillPersonBundle/Export/Declarations.php @@ -21,4 +21,6 @@ abstract class Declarations public const PERSON_TYPE = 'person'; public const ACP_TYPE = 'accompanying_period'; + + public const ACP_SHARED = 'accompanying_period_shared'; } diff --git a/src/Bundle/ChillPersonBundle/Export/Export/CountAccompanyingCourse.php b/src/Bundle/ChillPersonBundle/Export/Export/CountAccompanyingCourse.php index b7b57d3cd..6d2c0c6f6 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/CountAccompanyingCourse.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/CountAccompanyingCourse.php @@ -105,7 +105,7 @@ class CountAccompanyingCourse implements ExportInterface, GroupedExportInterface public function supportsModifiers(): array { - return [Declarations::ACP_TYPE]; + return [Declarations::ACP_TYPE, Declarations::ACP_SHARED]; } public function getGroup(): string diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/ReferrerFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/ReferrerFilter.php new file mode 100644 index 000000000..22515d13e --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Export/Filter/ReferrerFilter.php @@ -0,0 +1,161 @@ +userRender = $userRender; + } + + /** + * @inheritDoc + */ + public function buildForm(FormBuilderInterface $builder) + { + $builder->add('accepted_referrers', EntityType::class, [ + 'class' => User::class, + 'choice_label' => function (User $u) { + return $this->userRender->renderString($u, []); + }, + 'multiple' => true, + 'expanded' => true + ]); + /* + $builder->add('referrers', EntityType::class, [ + 'class' => User::class, + 'choice_label' => function (User $u) { + return $this->userRender->renderString($u, []); + }, + 'multiple' => true, + 'expanded' => true + ]); + */ + + } + + /** + * @inheritDoc + */ + public function getTitle(): string + { + return 'Filtered by referrers'; + } + + /** + * @inheritDoc + */ + public function describeAction($data, $format = 'string') + { + $users = []; + + foreach ($data['accepted_referrers'] as $r) { + $users[] = $r; + } + + return [ + 'Filtered by referrer: only %referrers%', [ + '%referrers' => implode(", ou ", $users) + ]]; + /* + $referrers = []; + + foreach ($data['referrers'] as $r) { + $referrers[] = $this->userRender->renderString($r, []); + } + + return ['Filtered by referrers: only %referrers%', [ + '%referrers%' => implode(', ou ', $referrers) + ]]; + */ + } + + /** + * @inheritDoc + */ + public function addRole() + { + return null; + } + + /** + * @inheritDoc + */ + public function alterQuery(QueryBuilder $qb, $data) + { + + $where = $qb->getDQLPart('where'); + + $from_alias = $this->getEntityFromQB($qb); + + // Use querybuilder from alias to find which export context (indicator) + switch ($from_alias) { + case 'acp': + $clause = $qb->expr()->in('acp.user', ':referrers'); + break; + + case 'acpw': + $qb->join('acpw.referrers', 'r'); + $clause = $qb->expr()->in('r', ':referrers'); + break; + + default: + throw new \Exception("Referrer filter doesn't apply on that entity"); + } + + if ($where instanceof Andx) { + $where->add($clause); + } else { + $where = $qb->expr()->andX($clause); + } + + $qb->add('where', $where); + $qb->setParameter('referrers', $data['accepted_referrers']); + + /* + $qb->join('acpw.referrers', 'r'); + + $where = $qb->getDQLPart('where'); + $clause = $qb->expr()->in('r', ':referrers'); + + if ($where instanceof Andx) { + $where->add($clause); + } else { + $where = $qb->expr()->andX($clause); + } + + $qb->add('where', $where); + $qb->setParameter('referrers', $data['referrers']); + */ + } + + private function getEntityFromQB(QueryBuilder $qb): string + { + /** @var From $from */ + $from = $qb->getDQLPart('from'); + + return $from[0]->getAlias(); + } + + /** + * @inheritDoc + */ + public function applyOn() + { + return Declarations::ACP_SHARED; + } +} \ No newline at end of file diff --git a/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_period.yaml b/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_period.yaml index 72fa1ad80..4c4bca27d 100644 --- a/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_period.yaml +++ b/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_period.yaml @@ -95,4 +95,11 @@ services: tags: - { name: chill.export_filter, alias: accompanyingcourse_intensity_filter } + chill.person.export.filter_referrer: + class: Chill\PersonBundle\Export\Filter\ReferrerFilter + autowire: true + autoconfigure: true + tags: + - { name: chill.export_filter, alias: accompanyingcourse_referrer_filter } + ## Aggregators \ No newline at end of file diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index 4c5ca1dcf..a8d57227f 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -416,6 +416,10 @@ is occasional: le parcours est ponctuel is regular: le parcours est régulier "Filtered by intensity: only %intensity%": "Filtré par intensité: uniquement si %intensity%" +Filtered by referrers: Filtrer par référent +Accepted referrers: Référents +"Filtered by referrer: only %referrers%": "Filtré par référent: uniquement %referrers%" + From dd06a262a20f9a63f3abde180a705bcced4d5e04 Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Sun, 31 Jul 2022 19:22:39 +0200 Subject: [PATCH 2/9] remove commented unused --- .../Export/Filter/ReferrerFilter.php | 37 ------------------- 1 file changed, 37 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/ReferrerFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/ReferrerFilter.php index 22515d13e..a7727fda7 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/ReferrerFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/ReferrerFilter.php @@ -35,16 +35,6 @@ class ReferrerFilter implements FilterInterface 'multiple' => true, 'expanded' => true ]); - /* - $builder->add('referrers', EntityType::class, [ - 'class' => User::class, - 'choice_label' => function (User $u) { - return $this->userRender->renderString($u, []); - }, - 'multiple' => true, - 'expanded' => true - ]); - */ } @@ -71,17 +61,6 @@ class ReferrerFilter implements FilterInterface 'Filtered by referrer: only %referrers%', [ '%referrers' => implode(", ou ", $users) ]]; - /* - $referrers = []; - - foreach ($data['referrers'] as $r) { - $referrers[] = $this->userRender->renderString($r, []); - } - - return ['Filtered by referrers: only %referrers%', [ - '%referrers%' => implode(', ou ', $referrers) - ]]; - */ } /** @@ -125,22 +104,6 @@ class ReferrerFilter implements FilterInterface $qb->add('where', $where); $qb->setParameter('referrers', $data['accepted_referrers']); - - /* - $qb->join('acpw.referrers', 'r'); - - $where = $qb->getDQLPart('where'); - $clause = $qb->expr()->in('r', ':referrers'); - - if ($where instanceof Andx) { - $where->add($clause); - } else { - $where = $qb->expr()->andX($clause); - } - - $qb->add('where', $where); - $qb->setParameter('referrers', $data['referrers']); - */ } private function getEntityFromQB(QueryBuilder $qb): string From 7677b8aaa096fc869af01b970fe8fbd5c77b2e89 Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Fri, 29 Jul 2022 12:14:37 +0200 Subject: [PATCH 3/9] exports: add new OpenBetweenDates filter --- .../Export/Filter/OpenBetweenDatesFilter.php | 88 +++++++++++++++++++ .../services/exports_accompanying_period.yaml | 9 ++ .../translations/messages.fr.yml | 4 + 3 files changed, 101 insertions(+) create mode 100644 src/Bundle/ChillPersonBundle/Export/Filter/OpenBetweenDatesFilter.php diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/OpenBetweenDatesFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/OpenBetweenDatesFilter.php new file mode 100644 index 000000000..2515f4e75 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Export/Filter/OpenBetweenDatesFilter.php @@ -0,0 +1,88 @@ +add('date_from', ChillDateType::class, [ + 'data' => new DateTime(), + ]) + ->add('date_to', ChillDateType::class, [ + 'data' => new DateTime(), + ]) + ; + } + + /** + * @inheritDoc + */ + public function getTitle(): string + { + return 'Filtered by opened between dates'; + } + + /** + * @inheritDoc + */ + public function describeAction($data, $format = 'string') + { + return ['Filtered by opening dates: between %datefrom% and %dateto%', [ + '%datefrom%' => $data['date_from']->format('d-m-Y'), + '%dateto%' => $data['date_to']->format('d-m-Y'), + ]]; + } + + /** + * @inheritDoc + */ + public function addRole() + { + return null; + } + + /** + * @inheritDoc + */ + public function alterQuery(QueryBuilder $qb, $data) + { + $where = $qb->getDQLPart('where'); + + $clause = $qb->expr()->andX( + $qb->expr()->lt('acp.openingDate', ':datefrom'), + $qb->expr()->gt('acp.closingDate', ':dateto') + ); + + if ($where instanceof Andx) { + $where->add($clause); + } else { + $where = $qb->expr()->andX($clause); + } + + $qb->add('where', $where); + $qb->setParameter('datefrom', $data['date_from'], Types::DATE_MUTABLE); + $qb->setParameter('dateto', $data['date_to'], Types::DATE_MUTABLE); + } + + /** + * @inheritDoc + */ + public function applyOn(): string + { + return Declarations::ACP_TYPE; + } +} \ No newline at end of file diff --git a/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_period.yaml b/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_period.yaml index 4c4bca27d..1f98ffd39 100644 --- a/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_period.yaml +++ b/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_period.yaml @@ -102,4 +102,13 @@ services: tags: - { name: chill.export_filter, alias: accompanyingcourse_referrer_filter } + chill.person.export.filter_openbetweendates: + class: Chill\PersonBundle\Export\Filter\OpenBetweenDatesFilter + autowire: true + autoconfigure: true + tags: + - { name: chill.export_filter, alias: accompanyingcourse_openbetweendates_filter } + + + ## Aggregators \ No newline at end of file diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index a8d57227f..f3e4be1c4 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -420,6 +420,10 @@ Filtered by referrers: Filtrer par référent Accepted referrers: Référents "Filtered by referrer: only %referrers%": "Filtré par référent: uniquement %referrers%" +Filtered by opened between dates: Filtrer les parcours ouverts entre deux dates +Date from: Date de début +Date to: Date de fin +"Filtered by opening dates: between %datefrom% and %dateto%": "Filtrer les parcours ouverts entre deux dates: entre le %datefrom% et le %dateto%" From c401e34d63a93274adfab7fd69c5a83e456ae128 Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Mon, 1 Aug 2022 11:16:17 +0200 Subject: [PATCH 4/9] exports: add new ActiveOneDayBetweenDates filter --- .../Filter/ActiveOneDayBetweenDatesFilter.php | 93 +++++++++++++++++++ .../Export/Filter/OpenBetweenDatesFilter.php | 3 +- .../services/exports_accompanying_period.yaml | 9 +- .../translations/messages.fr.yml | 3 +- 4 files changed, 104 insertions(+), 4 deletions(-) create mode 100644 src/Bundle/ChillPersonBundle/Export/Filter/ActiveOneDayBetweenDatesFilter.php diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/ActiveOneDayBetweenDatesFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/ActiveOneDayBetweenDatesFilter.php new file mode 100644 index 000000000..6f6ef1197 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Export/Filter/ActiveOneDayBetweenDatesFilter.php @@ -0,0 +1,93 @@ +add('date_from', ChillDateType::class, [ + 'data' => new DateTime(), + ]) + ->add('date_to', ChillDateType::class, [ + 'data' => new DateTime(), + ]) + ; + } + + /** + * @inheritDoc + */ + public function getTitle(): string + { + return 'Filtered by active at least one day between dates'; + } + + /** + * @inheritDoc + */ + public function describeAction($data, $format = 'string') + { + return ['Filtered by actives courses: at least one day between %datefrom% and %dateto%', [ + '%datefrom%' => $data['date_from']->format('d-m-Y'), + '%dateto%' => $data['date_to']->format('d-m-Y'), + ]]; + } + + /** + * @inheritDoc + */ + public function addRole() + { + return null; + } + + /** + * @inheritDoc + */ + public function alterQuery(QueryBuilder $qb, $data) + { + $where = $qb->getDQLPart('where'); + + $clause = $qb->expr()->orX( + $qb->expr()->lt('(acp.openingDate + 1)', ':dateto'), + $qb->expr()->andX( + $qb->expr()->lt('acp.openingDate', ':datefrom'), + $qb->expr()->isNull('acp.closingDate') + ), + $qb->expr()->gt('(acp.closingDate - 1)', ':datefrom') + ); + + if ($where instanceof Andx) { + $where->add($clause); + } else { + $where = $qb->expr()->andX($clause); + } + + $qb->add('where', $where); + $qb->setParameter('datefrom', $data['date_from'], Types::DATE_MUTABLE); + $qb->setParameter('dateto', $data['date_to'], Types::DATE_MUTABLE); + } + + /** + * @inheritDoc + */ + public function applyOn(): string + { + return Declarations::ACP_TYPE; + } +} \ No newline at end of file diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/OpenBetweenDatesFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/OpenBetweenDatesFilter.php index 2515f4e75..ef829bdfa 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/OpenBetweenDatesFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/OpenBetweenDatesFilter.php @@ -2,6 +2,7 @@ namespace Chill\PersonBundle\Export\Filter; +use Chill\MainBundle\Export\FilterInterface; use Chill\MainBundle\Form\Type\ChillDateType; use Chill\PersonBundle\Export\Declarations; use Doctrine\DBAL\Types\Types; @@ -10,7 +11,7 @@ use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; use DateTime; -class OpenBetweenDatesFilter implements \Chill\MainBundle\Export\FilterInterface +class OpenBetweenDatesFilter implements FilterInterface { /** diff --git a/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_period.yaml b/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_period.yaml index 1f98ffd39..20131dc59 100644 --- a/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_period.yaml +++ b/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_period.yaml @@ -95,6 +95,13 @@ services: tags: - { name: chill.export_filter, alias: accompanyingcourse_intensity_filter } + chill.person.export.filter_activeonedaybetweendates: + class: Chill\PersonBundle\Export\Filter\ActiveOneDayBetweenDatesFilter + autowire: true + autoconfigure: true + tags: + - { name: chill.export_filter, alias: accompanyingcourse_activeonedaybetweendates_filter } + chill.person.export.filter_referrer: class: Chill\PersonBundle\Export\Filter\ReferrerFilter autowire: true @@ -109,6 +116,4 @@ services: tags: - { name: chill.export_filter, alias: accompanyingcourse_openbetweendates_filter } - - ## Aggregators \ No newline at end of file diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index f3e4be1c4..f047a6804 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -425,7 +425,8 @@ Date from: Date de début Date to: Date de fin "Filtered by opening dates: between %datefrom% and %dateto%": "Filtrer les parcours ouverts entre deux dates: entre le %datefrom% et le %dateto%" - +Filtered by active at least one day between dates: Filtrer les parcours actifs au moins un jour dans la période +"Filtered by actives courses: at least one day between %datefrom% and %dateto%": "Filtrer les parcours actifs: au moins un jour entre le %datefrom% et le %dateto%" ## aggregators Group people by nationality: Aggréger les personnes par nationalités From 758c56482b5e88b4c41f74615a5fe4145aa9c69a Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Mon, 1 Aug 2022 11:30:32 +0200 Subject: [PATCH 5/9] exports: add new ActiveOnDate filter --- .../Export/Filter/ActiveOnDateFilter.php | 87 +++++++++++++++++++ .../Filter/ActiveOneDayBetweenDatesFilter.php | 2 +- .../Export/Filter/OpenBetweenDatesFilter.php | 2 +- .../services/exports_accompanying_period.yaml | 7 ++ .../translations/messages.fr.yml | 4 + 5 files changed, 100 insertions(+), 2 deletions(-) create mode 100644 src/Bundle/ChillPersonBundle/Export/Filter/ActiveOnDateFilter.php diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/ActiveOnDateFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/ActiveOnDateFilter.php new file mode 100644 index 000000000..0d83bce13 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Export/Filter/ActiveOnDateFilter.php @@ -0,0 +1,87 @@ +add('on_date', ChillDateType::class, [ + 'data' => new DateTime(), + ]) + ; + } + + /** + * @inheritDoc + */ + public function getTitle(): string + { + return 'Filtered by active on date'; + } + + /** + * @inheritDoc + */ + public function describeAction($data, $format = 'string'): array + { + return ['Filtered by actives courses: active on %ondate%', [ + '%ondate%' => $data['on_date']->format('d-m-Y') + ]]; + } + + /** + * @inheritDoc + */ + public function addRole() + { + return null; + } + + /** + * @inheritDoc + */ + public function alterQuery(QueryBuilder $qb, $data) + { + $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; + } +} \ No newline at end of file diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/ActiveOneDayBetweenDatesFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/ActiveOneDayBetweenDatesFilter.php index 6f6ef1197..0054018d1 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/ActiveOneDayBetweenDatesFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/ActiveOneDayBetweenDatesFilter.php @@ -40,7 +40,7 @@ class ActiveOneDayBetweenDatesFilter implements FilterInterface /** * @inheritDoc */ - public function describeAction($data, $format = 'string') + public function describeAction($data, $format = 'string'): array { return ['Filtered by actives courses: at least one day between %datefrom% and %dateto%', [ '%datefrom%' => $data['date_from']->format('d-m-Y'), diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/OpenBetweenDatesFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/OpenBetweenDatesFilter.php index ef829bdfa..2c3514f92 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/OpenBetweenDatesFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/OpenBetweenDatesFilter.php @@ -40,7 +40,7 @@ class OpenBetweenDatesFilter implements FilterInterface /** * @inheritDoc */ - public function describeAction($data, $format = 'string') + public function describeAction($data, $format = 'string'): array { return ['Filtered by opening dates: between %datefrom% and %dateto%', [ '%datefrom%' => $data['date_from']->format('d-m-Y'), diff --git a/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_period.yaml b/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_period.yaml index 20131dc59..fb10e775f 100644 --- a/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_period.yaml +++ b/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_period.yaml @@ -95,6 +95,13 @@ services: tags: - { name: chill.export_filter, alias: accompanyingcourse_intensity_filter } + chill.person.export.filter_activeondate: + class: Chill\PersonBundle\Export\Filter\ActiveOnDateFilter + autowire: true + autoconfigure: true + tags: + - { name: chill.export_filter, alias: accompanyingcourse_activeondate_filter } + chill.person.export.filter_activeonedaybetweendates: class: Chill\PersonBundle\Export\Filter\ActiveOneDayBetweenDatesFilter autowire: true diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index f047a6804..0f65dcf6c 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -428,6 +428,10 @@ Date to: Date de fin Filtered by active at least one day between dates: Filtrer les parcours actifs au moins un jour dans la période "Filtered by actives courses: at least one day between %datefrom% and %dateto%": "Filtrer les parcours actifs: au moins un jour entre le %datefrom% et le %dateto%" +Filtered by active on date: Filtrer les parcours actifs à une date +On date: Actifs à cette date +"Filtered by actives courses: active on %ondate%": "Filtrer les parcours actifs: actifs le %ondate%" + ## aggregators Group people by nationality: Aggréger les personnes par nationalités Group by level: Grouper par niveau From b511517a0f51326d9ea1c81c25f0ef709536794c Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Mon, 1 Aug 2022 12:45:04 +0200 Subject: [PATCH 6/9] export new SocialActionFilter --- .../Export/Filter/SocialActionFilter.php | 101 ++++++++++++++++++ .../services/exports_accompanying_period.yaml | 7 ++ .../translations/messages.fr.yml | 19 ++-- 3 files changed, 120 insertions(+), 7 deletions(-) create mode 100644 src/Bundle/ChillPersonBundle/Export/Filter/SocialActionFilter.php diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/SocialActionFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/SocialActionFilter.php new file mode 100644 index 000000000..d421044a2 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Export/Filter/SocialActionFilter.php @@ -0,0 +1,101 @@ +translator = $translator; + $this->translatableStringHelper = $translatableStringHelper; + $this->actionRender = $actionRender; + } + + public function buildForm(FormBuilderInterface $builder) + { + $builder->add('accepted_socialactions', EntityType::class, [ + 'class' => SocialAction::class, + 'choice_label' => function (SocialAction $sa) { + return $this->actionRender->renderString($sa, []); + }, + 'multiple' => true, + 'expanded' => true, + ]); + } + + public function getTitle(): string + { + return 'Filter by socialaction'; + } + + public function describeAction($data, $format = 'string'): array + { + $socialactions = []; + + foreach ($data['accepted_socialactions'] as $sa) { + $socialactions[] = $this->actionRender->renderString($sa, []); + } + + return ['Filtered by socialactions: only %socialactions%', [ + '%socialactions%' => implode(", ou ", $socialactions) + ]]; + } + + public function addRole() + { + return null; + } + + public function alterQuery(QueryBuilder $qb, $data) + { + $qb->join('acp.works', 'acpw') + ->join('acpw.socialAction', 'sa') + ; + + $where = $qb->getDQLPart('where'); + $clause = $qb->expr()->in('sa.id', ':socialactions'); + + if ($where instanceof Andx) { + $where->add($clause); + } else { + $where = $qb->expr()->andX($clause); + } + + $qb->add('where', $where); + $qb->setParameter('socialactions', $data['accepted_socialactions']); + } + + public function applyOn(): string + { + return Declarations::ACP_TYPE; + } +} \ No newline at end of file diff --git a/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_period.yaml b/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_period.yaml index fb10e775f..0556f051c 100644 --- a/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_period.yaml +++ b/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_period.yaml @@ -60,6 +60,13 @@ services: tags: - { name: chill.export_filter, alias: accompanyingcourse_step_filter } + chill.person.export.filter_socialaction: + class: Chill\PersonBundle\Export\Filter\SocialActionFilter + autowire: true + autoconfigure: true + tags: + - { name: chill.export_filter, alias: accompanyingcourse_socialaction_filter } + chill.person.export.filter_origin: class: Chill\PersonBundle\Export\Filter\OriginFilter autowire: true diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index 0f65dcf6c..7f56b90fa 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -390,6 +390,10 @@ Filter by step: Filtrer par statut du parcours Accepted steps: Statuts "Filtered by steps: only %step%": "Filtré par statut du parcours: uniquement %step%" +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%" + Filter by origin: Filtrer par origine du parcours Accepted origins: Origines "Filtered by origins: only %origins%": "Filtré par origine du parcours: uniquement %origins%" @@ -416,6 +420,14 @@ is occasional: le parcours est ponctuel is regular: le parcours est régulier "Filtered by intensity: only %intensity%": "Filtré par intensité: uniquement si %intensity%" +Filtered by active on date: Filtrer les parcours actifs à une date +On date: Actifs à cette date +"Filtered by actives courses: active on %ondate%": "Filtrer les parcours actifs: actifs le %ondate%" + +Filtered by active at least one day between dates: Filtrer les parcours actifs au moins un jour dans la période +"Filtered by actives courses: at least one day between %datefrom% and %dateto%": "Filtrer les parcours actifs: au moins un jour entre le %datefrom% et le %dateto%" + + Filtered by referrers: Filtrer par référent Accepted referrers: Référents "Filtered by referrer: only %referrers%": "Filtré par référent: uniquement %referrers%" @@ -425,13 +437,6 @@ Date from: Date de début Date to: Date de fin "Filtered by opening dates: between %datefrom% and %dateto%": "Filtrer les parcours ouverts entre deux dates: entre le %datefrom% et le %dateto%" -Filtered by active at least one day between dates: Filtrer les parcours actifs au moins un jour dans la période -"Filtered by actives courses: at least one day between %datefrom% and %dateto%": "Filtrer les parcours actifs: au moins un jour entre le %datefrom% et le %dateto%" - -Filtered by active on date: Filtrer les parcours actifs à une date -On date: Actifs à cette date -"Filtered by actives courses: active on %ondate%": "Filtrer les parcours actifs: actifs le %ondate%" - ## aggregators Group people by nationality: Aggréger les personnes par nationalités Group by level: Grouper par niveau From bc2209319a256b4e30e7d2f77528af229ad33f91 Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Mon, 1 Aug 2022 14:32:11 +0200 Subject: [PATCH 7/9] export new EvaluationFilter --- .../Export/Filter/EvaluationFilter.php | 105 ++++++++++++++++++ .../services/exports_accompanying_period.yaml | 7 ++ .../translations/messages.fr.yml | 4 + 3 files changed, 116 insertions(+) create mode 100644 src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilter.php diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilter.php new file mode 100644 index 000000000..7dd2a683d --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilter.php @@ -0,0 +1,105 @@ +translatableStringHelper = $translatableStringHelper; + } + + /** + * @inheritDoc + */ + public function buildForm(FormBuilderInterface $builder) + { + $builder->add('accepted_evaluations', EntityType::class, [ + 'class' => Evaluation::class, + 'choice_label' => function (Evaluation $ev) { + return $this->translatableStringHelper->localize($ev->getTitle()); + }, + 'multiple' => true, + 'expanded' => true, + ]); + } + + /** + * @inheritDoc + */ + public function getTitle(): string + { + return 'Filter by evaluation'; + } + + /** + * @inheritDoc + */ + public function describeAction($data, $format = 'string'): array + { + $evaluations = []; + + foreach ($data['accepted_evaluations'] as $ev) { + $evaluations[] = $this->translatableStringHelper->localize($ev->getTitle()); + } + + return ['Filtered by evaluations: only %evals%', [ + '%evals%' => implode(", ou ", $evaluations) + ]]; + } + + /** + * @inheritDoc + */ + public function addRole() + { + return null; + } + + /** + * @inheritDoc + */ + public function alterQuery(QueryBuilder $qb, $data) + { + $qb + ->join('acp.works', 'acpw') + ->join('acpw.accompanyingPeriodWorkEvaluations', 'we') + ->join('we.evaluation', 'ev') + ; + + $where = $qb->getDQLPart('where'); + $clause = $qb->expr()->in('ev.id', ':evaluations'); + + if ($where instanceof Andx) { + $where->add($clause); + } else { + $where = $qb->expr()->andX($clause); + } + + $qb->add('where', $where); + $qb->setParameter('evaluations', $data['accepted_evaluations']); + } + + /** + * @inheritDoc + */ + public function applyOn(): string + { + return Declarations::ACP_TYPE; + } +} \ No newline at end of file diff --git a/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_period.yaml b/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_period.yaml index 0556f051c..9c3e27d58 100644 --- a/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_period.yaml +++ b/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_period.yaml @@ -67,6 +67,13 @@ services: tags: - { name: chill.export_filter, alias: accompanyingcourse_socialaction_filter } + chill.person.export.filter_evaluation: + class: Chill\PersonBundle\Export\Filter\EvaluationFilter + autowire: true + autoconfigure: true + tags: + - { name: chill.export_filter, alias: accompanyingcourse_evaluation_filter } + chill.person.export.filter_origin: class: Chill\PersonBundle\Export\Filter\OriginFilter autowire: true diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index 7f56b90fa..755797a12 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -394,6 +394,10 @@ 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%" +Filter by evaluation: Filtrer par évaluation +Accepted evaluations: Évaluations +"Filtered by evaluations: only %evals%": "Filtré par évaluation: uniquement %evals%" + Filter by origin: Filtrer par origine du parcours Accepted origins: Origines "Filtered by origins: only %origins%": "Filtré par origine du parcours: uniquement %origins%" From 4794e5e7b5c2f29657f53daafbb529fe309045ae Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Mon, 1 Aug 2022 15:45:31 +0200 Subject: [PATCH 8/9] export new ActivityTypeFilter --- .../Export/Filter/ActivityTypeFilter.php | 111 ++++++++++++++++++ .../services/exports_accompanying_period.yaml | 7 ++ .../translations/messages.fr.yml | 4 + 3 files changed, 122 insertions(+) create mode 100644 src/Bundle/ChillPersonBundle/Export/Filter/ActivityTypeFilter.php diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/ActivityTypeFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/ActivityTypeFilter.php new file mode 100644 index 000000000..f019394d4 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Export/Filter/ActivityTypeFilter.php @@ -0,0 +1,111 @@ +translatableStringHelper = $translatableStringHelper; + } + + /** + * @inheritDoc + */ + public function buildForm(FormBuilderInterface $builder) + { + $builder->add('accepted_activitytypes', EntityType::class, [ + 'class' => ActivityType::class, + 'choice_label' => function (ActivityType $aty) { + return $this->translatableStringHelper->localize($aty->getName()); + }, + 'multiple' => true, + 'expanded' => true + ]); + } + + /** + * @inheritDoc + */ + public function getTitle(): string + { + return 'Filter by activity type'; + } + + /** + * @inheritDoc + */ + public function describeAction($data, $format = 'string'): array + { + $types = []; + + foreach ($data['accepted_activitytypes'] as $aty) { + $types[] = $this->translatableStringHelper->localize($aty->getName()); + } + + return ['Filtered by activity types: only %activitytypes%', [ + '%activitytypes%' => implode(", ou ", $types) + ]]; + } + + /** + * @inheritDoc + */ + public function addRole() + { + return null; + } + + /** + * @inheritDoc + */ + public function alterQuery(QueryBuilder $qb, $data) + { + // One2many between activity and accompanyingperiod is not reversed ! + // we replace indicator 'from' clause by 'act', and put 'acp' in a join + + $qb->resetDQLPart('from'); + $qb->from('ChillActivityBundle:Activity', 'act'); + + $qb + ->join('act.accompanyingPeriod', 'acp') + ->join('act.activityType', 'aty') + ; + + $where = $qb->getDQLPart('where'); + $clause = $qb->expr()->in('aty.id', ':activitytypes'); + + if ($where instanceof Andx) { + $where->add($clause); + } else { + $where = $qb->expr()->andX($clause); + } + + $qb->add('where', $where); + $qb->setParameter('activitytypes', $data['accepted_activitytypes']); + + } + + /** + * @inheritDoc + */ + public function applyOn() + { + return Declarations::ACP_TYPE; + } +} \ No newline at end of file diff --git a/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_period.yaml b/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_period.yaml index 9c3e27d58..07f3db1ae 100644 --- a/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_period.yaml +++ b/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_period.yaml @@ -74,6 +74,13 @@ services: tags: - { name: chill.export_filter, alias: accompanyingcourse_evaluation_filter } + chill.person.export.filter_activitytype: + class: Chill\PersonBundle\Export\Filter\ActivityTypeFilter + autowire: true + autoconfigure: true + tags: + - { name: chill.export_filter, alias: accompanyingcourse_activitytype_filter } + chill.person.export.filter_origin: class: Chill\PersonBundle\Export\Filter\OriginFilter autowire: true diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index 755797a12..79f280360 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -398,6 +398,10 @@ Filter by evaluation: Filtrer par évaluation Accepted evaluations: Évaluations "Filtered by evaluations: only %evals%": "Filtré par évaluation: uniquement %evals%" +Filter by activity type: Filtrer par type d'activité +Accepted activitytypes: Types d'activités +"Filtered by activity types: only %activitytypes%": "Filtré par type d'activité: seulement %activitytypes%" + Filter by origin: Filtrer par origine du parcours Accepted origins: Origines "Filtered by origins: only %origins%": "Filtré par origine du parcours: uniquement %origins%" From 6e439adce251b87cd3e2a2cf60454c528b9c6d09 Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Mon, 1 Aug 2022 16:50:02 +0200 Subject: [PATCH 9/9] export new administrative location filter --- .../Filter/AdministrativeLocationFilter.php | 99 +++++++++++++++++++ .../services/exports_accompanying_period.yaml | 7 ++ .../translations/messages.fr.yml | 4 + 3 files changed, 110 insertions(+) create mode 100644 src/Bundle/ChillPersonBundle/Export/Filter/AdministrativeLocationFilter.php diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AdministrativeLocationFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AdministrativeLocationFilter.php new file mode 100644 index 000000000..b52a2abe1 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AdministrativeLocationFilter.php @@ -0,0 +1,99 @@ +translatableStringHelper = $translatableStringHelper; + } + + /** + * @inheritDoc + */ + public function buildForm(FormBuilderInterface $builder) + { + $builder->add('accepted_locations', EntityType::class, [ + 'class' => Location::class, + 'choice_label' => function (Location $l) { + return $l->getName() .' ('. $this->translatableStringHelper->localize($l->getLocationType()->getTitle()) . ')'; + }, + 'multiple' => true, + 'expanded' => true, + ]); + } + + /** + * @inheritDoc + */ + public function getTitle(): string + { + return 'Filter by administrative location'; + } + + /** + * @inheritDoc + */ + public function describeAction($data, $format = 'string'): array + { + $locations = []; + + foreach ($data['accepted_locations'] as $l) { + $locations[] = $l->getName(); + } + + return ['Filtered by administratives locations: only %locations%', [ + '%locations%' => implode(", ou ", $locations) + ]]; + } + + /** + * @inheritDoc + */ + public function addRole() + { + return null; + } + + /** + * @inheritDoc + */ + public function alterQuery(QueryBuilder $qb, $data) + { + $where = $qb->getDQLPart('where'); + $clause = $qb->expr()->in('acp.administrativeLocation', ':locations'); + + if ($where instanceof Andx) { + $where->add($clause); + } else { + $where = $qb->expr()->andX($clause); + } + + $qb->add('where', $where); + $qb->setParameter('locations', $data['accepted_locations']); + } + + /** + * @inheritDoc + */ + public function applyOn(): string + { + return Declarations::ACP_TYPE; + } +} \ No newline at end of file diff --git a/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_period.yaml b/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_period.yaml index 07f3db1ae..671309ae8 100644 --- a/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_period.yaml +++ b/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_period.yaml @@ -95,6 +95,13 @@ services: tags: - { name: chill.export_filter, alias: accompanyingcourse_closingmotive_filter } + chill.person.export.filter_administrative_location: + class: Chill\PersonBundle\Export\Filter\AdministrativeLocationFilter + autowire: true + autoconfigure: true + tags: + - { name: chill.export_filter, alias: accompanyingcourse_administrative_location_filter } + chill.person.export.filter_confidential: class: Chill\PersonBundle\Export\Filter\ConfidentialFilter autowire: true diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index 79f280360..a524228fc 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -410,6 +410,10 @@ Filter by closing motive: Filtrer par motif de fermeture Accepted closingmotives: Motifs de clôture "Filtered by closingmotive: only %closingmotives%": "Filtré par motif de clôture: uniquement %closingmotives%" +Filter by administrative location: Filtrer par localisation administrative +Accepted locations: Localisations administratives +"Filtered by administratives locations: only %locations%": "Filtré par localisation administrative: uniquement %locations%" + Filter by confidential: Filtrer par confidentialité Accepted confidentials: '' is confidential: le parcours est confidentiel