diff --git a/.changes/unreleased/Feature-20231018-133203.yaml b/.changes/unreleased/Feature-20231018-133203.yaml new file mode 100644 index 000000000..f839ebcf3 --- /dev/null +++ b/.changes/unreleased/Feature-20231018-133203.yaml @@ -0,0 +1,6 @@ +kind: Feature +body: '[export] add a filter and aggregator on accompanying period work: group/filter + by handling third party' +time: 2023-10-18T13:32:03.565201495+02:00 +custom: + Issue: "172" diff --git a/src/Bundle/ChillMainBundle/Resources/views/Export/new.html.twig b/src/Bundle/ChillMainBundle/Resources/views/Export/new.html.twig index 8ef4c3ad7..82b3e0c0c 100644 --- a/src/Bundle/ChillMainBundle/Resources/views/Export/new.html.twig +++ b/src/Bundle/ChillMainBundle/Resources/views/Export/new.html.twig @@ -1,5 +1,5 @@ {# - * Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS, + * Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS, / * * This program is free software: you can redistribute it and/or modify @@ -36,84 +36,84 @@ {% block content %}
- + {{ include('@ChillMain/Export/_breadcrumb.html.twig') }} - +

{{ export.title|trans }}

- +

{{ export.description|trans }}

- + {{ form_start(form) }} - + {% if form.children.export.children.filters is defined %} {% if form.children.export.children.filters is not empty%} - +

{{ 'Filters'| trans }}

- + {{ form_errors(form.children.export.children.filters) }} - +
{% for filter_form in form.children.export.children.filters %}
- + {{ form_widget(filter_form.enabled, { 'label': filter_form.vars.label, 'label_attr': { 'class': 'h6' }, 'attr': { 'data-display-target': filter_form.vars.id } }) }} - +
{{ form_widget(filter_form.form) }} {{ form_errors(filter_form) }}
- +
{% endfor %}
- + {% else %} {# render the children, to mark the widget as 'rendered' #} {{ form_widget(form.children.export.children.filters) }} {% endif %} {% endif %} - + {% if form.children.export.children.aggregators is defined %} {% if form.children.export.children.aggregators is not empty %} - +

{{ 'Aggregators'| trans }}

- +
{% for aggregator_form in form.children.export.children.aggregators %}
- + {{ form_widget(aggregator_form.enabled, { 'label': aggregator_form.vars.label, 'label_attr': { 'class': 'h6' }, 'attr': { 'data-display-target': aggregator_form.vars.id } }) }} - +
{{ form_widget(aggregator_form.form) }} {{ form_errors(aggregator_form) }}
- +
{% endfor %}
- + {% else %} {# render the children, to mark the widget as 'rendered' #} {{ form_widget(form.children.export.children.aggregators) }} {% endif %} {% endif %} - - + + {% if form.children.export.children.export.children|length > 0 %} - + @@ -123,12 +123,12 @@ {{ form_widget(form.children.export.children.export) }} - + {% else %} {# render the children, to mark the widget as 'rendered' #} {{ form_widget(form.children.export.children.export) }} {% endif %} - + {% if form.children.export.children.pick_formatter is defined %}

@@ -140,7 +140,7 @@ {{ form_row(form.children.export.children.pick_formatter.children.alias, { 'label' : 'Formatter' }) }}

{% endif %} - +

{{ form_widget(form.submit, { 'attr' : { 'class' : 'btn btn-create' }, 'label' : 'Go to formatter options' } ) }}

{{ form_end(form) }} diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/HandlingThirdPartyAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/HandlingThirdPartyAggregator.php new file mode 100644 index 000000000..f58246a25 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/HandlingThirdPartyAggregator.php @@ -0,0 +1,73 @@ +labelThirdPartyHelper->getLabel($key, $values, 'export.aggregator.course_work.by_handling_third_party.header'); + } + + public function getQueryKeys($data) + { + return [self::PREFIX.'_h3party']; + } + + public function getTitle() + { + return 'export.aggregator.course_work.by_handling_third_party.title'; + } + + public function addRole(): ?string + { + return null; + } + + public function alterQuery(QueryBuilder $qb, $data) + { + $p = self::PREFIX; + + $qb + ->addSelect("IDENTITY(acpw.handlingThierParty) AS {$p}_h3party") + ->addGroupBy("{$p}_h3party"); + } + + public function applyOn() + { + return Declarations::SOCIAL_WORK_ACTION_TYPE; + } +} diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HandlingThirdPartyFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HandlingThirdPartyFilter.php new file mode 100644 index 000000000..80bc7b04a --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HandlingThirdPartyFilter.php @@ -0,0 +1,78 @@ +add('handling_3parties', PickThirdpartyDynamicType::class, [ + 'label' => 'export.filter.work.by_handling3party.pick_3parties', + 'multiple' => true, + ]); + } + + public function getFormDefaultData(): array + { + return ['handling_3parties' => []]; + } + + public function describeAction($data, $format = 'string') + { + return [ + 'export.filter.work.by_handling3party.Only 3 parties %3parties%', + [ + '%3parties%' => implode( + ', ', + array_map(fn (ThirdParty $thirdParty) => $this->thirdPartyRender->renderString($thirdParty, []), $data['handling_3parties']) + ), + ], + ]; + } + + public function addRole(): ?string + { + return null; + } + + public function alterQuery(QueryBuilder $qb, $data) + { + $p = self::PREFIX; + + $qb->andWhere("acpw.handlingThierParty IN (:{$p}_3ps)"); + $qb->setParameter("{$p}_3ps", $data['handling_3parties']); + } + + public function applyOn() + { + return Declarations::SOCIAL_WORK_ACTION_TYPE; + } +} diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/SocialWorkAggregators/HandlingThirdPartyAggregatorTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/SocialWorkAggregators/HandlingThirdPartyAggregatorTest.php new file mode 100644 index 000000000..3677cedf2 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/SocialWorkAggregators/HandlingThirdPartyAggregatorTest.php @@ -0,0 +1,60 @@ +get(HandlingThirdPartyAggregator::class); + } + + public function getAggregator() + { + return self::$handlingThirdPartyAggregator; + } + + public function getFormData() + { + return [ + [], + ]; + } + + public function getQueryBuilders() + { + self::bootKernel(); + + $em = self::$container + ->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('count(acpw.id)') + ->from(AccompanyingPeriodWork::class, 'acpw'), + ]; + } +} diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Filter/SocialWorkFilters/HandlingThirdPartyFilterTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Filter/SocialWorkFilters/HandlingThirdPartyFilterTest.php new file mode 100644 index 000000000..e454a10fc --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Filter/SocialWorkFilters/HandlingThirdPartyFilterTest.php @@ -0,0 +1,71 @@ +thirdPartyRender = self::$container->get(ThirdPartyRender::class); + } + + public function getFilter() + { + return new HandlingThirdPartyFilter($this->thirdPartyRender); + } + + public function getFormData() + { + self::bootKernel(); + + $em = self::$container->get(EntityManagerInterface::class); + + $thirdParties = $em->createQuery('SELECT tp FROM '.ThirdParty::class.' tp') + ->setMaxResults(2) + ->getResult(); + + return [ + [ + 'handling_3parties' => $thirdParties, + ], + ]; + } + + public function getQueryBuilders() + { + self::bootKernel(); + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('acpw.id') + ->from(AccompanyingPeriodWork::class, 'acpw'), + ]; + } +} diff --git a/src/Bundle/ChillPersonBundle/config/services/exports_social_actions.yaml b/src/Bundle/ChillPersonBundle/config/services/exports_social_actions.yaml index c0e6abc4b..57be6bf40 100644 --- a/src/Bundle/ChillPersonBundle/config/services/exports_social_actions.yaml +++ b/src/Bundle/ChillPersonBundle/config/services/exports_social_actions.yaml @@ -1,116 +1,93 @@ services: + _defaults: + autowire: true + autoconfigure: true - ## Indicators - Chill\PersonBundle\Export\Export\CountAccompanyingPeriodWork: - autowire: true - autoconfigure: true - tags: - - { name: chill.export, alias: count_social_work_actions } + ## Indicators + Chill\PersonBundle\Export\Export\CountAccompanyingPeriodWork: + tags: + - { name: chill.export, alias: count_social_work_actions } - Chill\PersonBundle\Export\Export\ListAccompanyingPeriodWork: - autowire: true - autoconfigure: true - tags: - - { name: chill.export, alias: list_social_work_actions } + Chill\PersonBundle\Export\Export\ListAccompanyingPeriodWork: + tags: + - { name: chill.export, alias: list_social_work_actions } - ## FILTERS - chill.person.export.filter_social_work_type: - class: Chill\PersonBundle\Export\Filter\SocialWorkFilters\SocialWorkTypeFilter - autowire: true - autoconfigure: true - tags: - - { name: chill.export_filter, alias: social_work_type_filter } + ## FILTERS + chill.person.export.filter_social_work_type: + class: Chill\PersonBundle\Export\Filter\SocialWorkFilters\SocialWorkTypeFilter + tags: + - { name: chill.export_filter, alias: social_work_type_filter } - chill.person.export.filter_scope: - class: Chill\PersonBundle\Export\Filter\SocialWorkFilters\ScopeFilter - autowire: true - autoconfigure: true - tags: - - { name: chill.export_filter, alias: social_work_actions_scope_filter } + chill.person.export.filter_scope: + class: Chill\PersonBundle\Export\Filter\SocialWorkFilters\ScopeFilter + tags: + - { name: chill.export_filter, alias: social_work_actions_scope_filter } - chill.person.export.filter_job: - class: Chill\PersonBundle\Export\Filter\SocialWorkFilters\JobFilter - autowire: true - autoconfigure: true - tags: - - { name: chill.export_filter, alias: social_work_actions_job_filter } + chill.person.export.filter_job: + class: Chill\PersonBundle\Export\Filter\SocialWorkFilters\JobFilter + tags: + - { name: chill.export_filter, alias: social_work_actions_job_filter } - chill.person.export.filter_treatingagent: - class: Chill\PersonBundle\Export\Filter\SocialWorkFilters\ReferrerFilter - autowire: true - autoconfigure: true - tags: - - { name: chill.export_filter, alias: social_work_actions_treatingagent_filter } + chill.person.export.filter_treatingagent: + class: Chill\PersonBundle\Export\Filter\SocialWorkFilters\ReferrerFilter + tags: + - { name: chill.export_filter, alias: social_work_actions_treatingagent_filter } - Chill\PersonBundle\Export\Filter\SocialWorkFilters\CurrentActionFilter: - autowire: true - autoconfigure: true - tags: - - { name: chill.export_filter, alias: social_work_actions_current_filter } + Chill\PersonBundle\Export\Filter\SocialWorkFilters\CurrentActionFilter: + tags: + - { name: chill.export_filter, alias: social_work_actions_current_filter } - Chill\PersonBundle\Export\Filter\SocialWorkFilters\AccompanyingPeriodWorkStartDateBetweenDateFilter: - autowire: true - autoconfigure: true - tags: - - { name: chill.export_filter, alias: social_work_actions_start_btw_dates_filter } + Chill\PersonBundle\Export\Filter\SocialWorkFilters\AccompanyingPeriodWorkStartDateBetweenDateFilter: + tags: + - { name: chill.export_filter, alias: social_work_actions_start_btw_dates_filter } - Chill\PersonBundle\Export\Filter\SocialWorkFilters\AccompanyingPeriodWorkEndDateBetweenDateFilter: - autowire: true - autoconfigure: true - tags: - - { name: chill.export_filter, alias: social_work_actions_end_btw_dates_filter } + Chill\PersonBundle\Export\Filter\SocialWorkFilters\AccompanyingPeriodWorkEndDateBetweenDateFilter: + tags: + - { name: chill.export_filter, alias: social_work_actions_end_btw_dates_filter } - ## AGGREGATORS - chill.person.export.aggregator_action_type: - class: Chill\PersonBundle\Export\Aggregator\SocialWorkAggregators\ActionTypeAggregator - autowire: true - autoconfigure: true - tags: - - { name: chill.export_aggregator, alias: social_work_actions_action_type_aggregator } + ## AGGREGATORS + chill.person.export.aggregator_action_type: + class: Chill\PersonBundle\Export\Aggregator\SocialWorkAggregators\ActionTypeAggregator + tags: + - { name: chill.export_aggregator, alias: social_work_actions_action_type_aggregator } - chill.person.export.aggregator_treatingagent_scope: - class: Chill\PersonBundle\Export\Aggregator\SocialWorkAggregators\ScopeAggregator - autowire: true - autoconfigure: true - tags: - - { name: chill.export_aggregator, alias: social_work_actions_treatingagent_scope_aggregator } + chill.person.export.aggregator_treatingagent_scope: + class: Chill\PersonBundle\Export\Aggregator\SocialWorkAggregators\ScopeAggregator + tags: + - { name: chill.export_aggregator, alias: social_work_actions_treatingagent_scope_aggregator } - chill.person.export.aggregator_treatingagent_job: - class: Chill\PersonBundle\Export\Aggregator\SocialWorkAggregators\JobAggregator - autowire: true - autoconfigure: true - tags: - - { name: chill.export_aggregator, alias: social_work_actions_treatingagent_job_aggregator } + chill.person.export.aggregator_treatingagent_job: + class: Chill\PersonBundle\Export\Aggregator\SocialWorkAggregators\JobAggregator + tags: + - { name: chill.export_aggregator, alias: social_work_actions_treatingagent_job_aggregator } - Chill\PersonBundle\Export\Aggregator\SocialWorkAggregators\ReferrerAggregator: - autowire: true - autoconfigure: true - tags: - - { name: chill.export_aggregator, alias: social_work_actions_treatingagent_aggregator } + Chill\PersonBundle\Export\Aggregator\SocialWorkAggregators\ReferrerAggregator: + tags: + - { name: chill.export_aggregator, alias: social_work_actions_treatingagent_aggregator } - chill.person.export.aggregator_goal: - class: Chill\PersonBundle\Export\Aggregator\SocialWorkAggregators\GoalAggregator - autowire: true - autoconfigure: true - tags: - - { name: chill.export_aggregator, alias: social_work_actions_goal_aggregator } + chill.person.export.aggregator_goal: + class: Chill\PersonBundle\Export\Aggregator\SocialWorkAggregators\GoalAggregator + tags: + - { name: chill.export_aggregator, alias: social_work_actions_goal_aggregator } - chill.person.export.aggregator_result: - class: Chill\PersonBundle\Export\Aggregator\SocialWorkAggregators\ResultAggregator - autowire: true - autoconfigure: true - tags: - - { name: chill.export_aggregator, alias: social_work_actions_result_aggregator } + chill.person.export.aggregator_result: + class: Chill\PersonBundle\Export\Aggregator\SocialWorkAggregators\ResultAggregator + tags: + - { name: chill.export_aggregator, alias: social_work_actions_result_aggregator } - chill.person.export.aggregator_goalresult: - class: Chill\PersonBundle\Export\Aggregator\SocialWorkAggregators\GoalResultAggregator - autowire: true - autoconfigure: true - tags: - - { name: chill.export_aggregator, alias: social_work_actions_goal_result_aggregator } + chill.person.export.aggregator_goalresult: + class: Chill\PersonBundle\Export\Aggregator\SocialWorkAggregators\GoalResultAggregator + tags: + - { name: chill.export_aggregator, alias: social_work_actions_goal_result_aggregator } - Chill\PersonBundle\Export\Aggregator\SocialWorkAggregators\CurrentActionAggregator: - autowire: true - autoconfigure: true - tags: - - { name: chill.export_aggregator, alias: social_work_actions_current_aggregator } + Chill\PersonBundle\Export\Aggregator\SocialWorkAggregators\CurrentActionAggregator: + tags: + - { name: chill.export_aggregator, alias: social_work_actions_current_aggregator } + + Chill\PersonBundle\Export\Aggregator\SocialWorkAggregators\HandlingThirdPartyAggregator: + tags: + - { name: chill.export_aggregator, alias: accompanyingcourse_handling3party_aggregator } + + Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\HandlingThirdPartyFilter: + tags: + - { name: chill.export_filter, alias: 'acpw_handling3party_filter'} diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index 0c5a0fe57..4ab5d88a6 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -1066,6 +1066,9 @@ export: by_agent_job: Group by treating agent job: Grouper les actions par métier de l'agent traitant Calc date: Date de calcul du métier de l'agent traitant + by_handling_third_party: + title: Grouper les actions par tiers traitant + header: Tiers traitant eval: by_end_date: @@ -1181,6 +1184,10 @@ export: 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%" + by_handling3party: + title: Filtrer les actions par tiers traitant + Only 3 parties %3parties%: "Seulement les actions d'accompagnement qui ont pour tiers traitant: %3parties%" + pick_3parties: Tiers traitants des actions list: person_with_acp: diff --git a/src/Bundle/ChillThirdPartyBundle/Export/Helper/LabelThirdPartyHelper.php b/src/Bundle/ChillThirdPartyBundle/Export/Helper/LabelThirdPartyHelper.php index 9b4cbfa75..e92cdae93 100644 --- a/src/Bundle/ChillThirdPartyBundle/Export/Helper/LabelThirdPartyHelper.php +++ b/src/Bundle/ChillThirdPartyBundle/Export/Helper/LabelThirdPartyHelper.php @@ -25,7 +25,7 @@ class LabelThirdPartyHelper return $header; } - if (null === $value || null === $thirdParty = $this->thirdPartyRepository->find($value)) { + if ('' === $value || null === $value || null === $thirdParty = $this->thirdPartyRepository->find($value)) { return ''; }