diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/RequestorFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/RequestorFilter.php new file mode 100644 index 000000000..ca2173e5a --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Export/Filter/RequestorFilter.php @@ -0,0 +1,153 @@ + 'participation', + 'is other person' => 'other_person', + 'is thirdparty' => 'thirdparty', + 'no requestor' => 'no_requestor', + ]; + + private const DEFAULT_CHOICE = 'participation'; + + protected TranslatorInterface $translator; + + protected EntityManagerInterface $em; + + public function __construct( + TranslatorInterface $translator, + EntityManagerInterface $em + ) { + $this->translator = $translator; + $this->em = $em; + } + + /** + * @inheritDoc + */ + public function buildForm(FormBuilderInterface $builder) + { + $builder->add('accepted_choices', ChoiceType::class, [ + 'choices' => self::REQUESTOR_CHOICES, + 'multiple' => false, + 'expanded' => true, + 'empty_data' => self::DEFAULT_CHOICE, + 'data' => self::DEFAULT_CHOICE, + ]); + } + + /** + * @inheritDoc + */ + public function getTitle(): string + { + return 'Filter by requestor'; + } + + /** + * @inheritDoc + */ + public function describeAction($data, $format = 'string'): array + { + $choice = array_flip(self::REQUESTOR_CHOICES)[$data['accepted_choices']]; + + return ['Filtered by requestor: only %choice%', [ + '%choice%' => $this->translator->trans($choice) + ]]; + } + + /** + * @inheritDoc + */ + public function addRole() + { + return null; + } + + /** + * @inheritDoc + */ + public function alterQuery(QueryBuilder $qb, $data) + { + $where = $qb->getDQLPart('where'); + + switch ($data['accepted_choices']) { + case 'participation': + + $qb->join('acp.participations', 'part'); + + $clause = $qb->expr()->andX( + $qb->expr()->isNotNull('acp.requestorPerson'), + $qb->expr()->eq('acp.requestorPerson', 'part.person') + ); + break; + + case 'other_person': + + $expr = $this->em->getExpressionBuilder(); + + $qb->join('acp.participations','part'); + + $clause = $expr->andX( + $expr->isNotNull('acp.requestorPerson'), + $expr->notIn('acp.requestorPerson', + + // subquery + $this->em->createQueryBuilder() + ->select('identity(acp2.requestorPerson)') + ->from('ChillPersonBundle:AccompanyingPeriod', 'acp2') + ->join('acp2.participations', 'part2') + ->where($expr->eq('acp2.requestorPerson', 'part2.person')) + ->getDQL() + + ) + ); + break; + + case 'thirdparty': + + $clause = $qb->expr()->isNotNull('acp.requestorThirdParty'); + break; + + case 'no_requestor': + + $clause = $qb->expr()->andX( + $qb->expr()->isNull('acp.requestorPerson'), + $qb->expr()->isNull('acp.requestorThirdParty') + ); + break; + + default: + throw new \Exception('Uncaught choice exception'); + } + + if ($where instanceof Andx) { + $where->add($clause); + } else { + $where = $qb->expr()->andX($clause); + } + + $qb->add('where', $where); + } + + /** + * @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 62ad99b97..b715605af 100644 --- a/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_period.yaml +++ b/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_period.yaml @@ -102,6 +102,13 @@ services: tags: - { name: chill.export_filter, alias: accompanyingcourse_administrative_location_filter } + chill.person.export.filter_requestor: + class: Chill\PersonBundle\Export\Filter\RequestorFilter + autowire: true + autoconfigure: true + tags: + - { name: chill.export_filter, alias: accompanyingcourse_requestor_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 f613b09da..bdd70bee4 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -418,6 +418,14 @@ 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 requestor: Filtrer les parcours selon la présence du demandeur au sein des usagers concernés +Accepted choices: '' +is person concerned: Le demandeur est un usager concerné +is other person: Le demandeur est un autre usager +is thirdparty: Le demandeur est un tiers +no requestor: Il n'y a pas de demandeur +"Filtered by requestor: only %choice%": "Filtré par présence du demandeur au sein des usagers concernés: uniquement si %choice%" + Filter by confidential: Filtrer par confidentialité Accepted confidentials: '' is confidential: le parcours est confidentiel