From 648ec68cfb6358eba6a6328572f0cf8a396f7521 Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Thu, 1 Sep 2022 12:28:54 +0200 Subject: [PATCH 01/41] export SocialWorkTypeFilter: create dynamic Form Action-goal-result - initiate new Vue component - cleaning buildForm in Filter - add HiddenType with ModelTransformer - use ObjectToIdTransformer in HiddenType fields - setting mount() and teleport - list fetch url in api.js - html/bootstrap form structure - add Multiselect actionType - i18n import - add multiselect for goals and results - add and remove options in multiselect (wip) - fix basic vue add/remove element from data store - vue cleaning - add ids in value hiddenFields - adapt Filter in AlterQuery (wip) - improve code lisibility --- .../public/vuejs/FormActionGoalResult/App.vue | 295 ++++++++++++++++++ .../public/vuejs/FormActionGoalResult/api.js | 41 +++ .../vuejs/FormActionGoalResult/index.js | 13 + .../Resources/views/Export/new.html.twig | 3 + .../ChillMainBundle/chill.webpack.config.js | 1 + .../SocialWorkTypeFilter.php | 143 +++++---- 6 files changed, 442 insertions(+), 54 deletions(-) create mode 100644 src/Bundle/ChillMainBundle/Resources/public/vuejs/FormActionGoalResult/App.vue create mode 100644 src/Bundle/ChillMainBundle/Resources/public/vuejs/FormActionGoalResult/api.js create mode 100644 src/Bundle/ChillMainBundle/Resources/public/vuejs/FormActionGoalResult/index.js diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/FormActionGoalResult/App.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/FormActionGoalResult/App.vue new file mode 100644 index 000000000..39a7c023a --- /dev/null +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/FormActionGoalResult/App.vue @@ -0,0 +1,295 @@ + + + + + \ No newline at end of file diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/FormActionGoalResult/api.js b/src/Bundle/ChillMainBundle/Resources/public/vuejs/FormActionGoalResult/api.js new file mode 100644 index 000000000..afcece4f4 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/FormActionGoalResult/api.js @@ -0,0 +1,41 @@ +import { fetchResults } from 'ChillMainAssets/lib/api/apiMethods'; + +const getSocialActions = () => fetchResults( + '/api/1.0/person/social/social-action.json', { + item_per_page: 200 + } +); + +const getGoalByAction = (id) => { + let url = `/api/1.0/person/social-work/goal/by-social-action/${id}.json`; + return fetch(url) + .then(response => { + if (response.ok) { return response.json(); } + throw Error('Error with request resource response'); + }); +}; + +const getResultByAction = (id) => { + let url = `/api/1.0/person/social-work/result/by-social-action/${id}.json`; + return fetch(url) + .then(response => { + if (response.ok) { return response.json(); } + throw Error('Error with request resource response'); + }); +}; + +const getResultByGoal = (id) => { + let url = `/api/1.0/person/social-work/result/by-goal/${id}.json`; + return fetch(url) + .then(response => { + if (response.ok) { return response.json(); } + throw Error('Error with request resource response'); + }); +}; + +export { + getSocialActions, + getGoalByAction, + getResultByAction, + getResultByGoal, +} \ No newline at end of file diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/FormActionGoalResult/index.js b/src/Bundle/ChillMainBundle/Resources/public/vuejs/FormActionGoalResult/index.js new file mode 100644 index 000000000..d838fb0be --- /dev/null +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/FormActionGoalResult/index.js @@ -0,0 +1,13 @@ +import { createApp } from "vue"; +import { _createI18n } from 'ChillMainAssets/vuejs/_js/i18n'; +import App from './App.vue'; + +const i18n = _createI18n({}); + +const app = createApp({ + template: ``, +}) +.use(i18n) +.component('app', App) +.mount('#export_export') +; \ No newline at end of file diff --git a/src/Bundle/ChillMainBundle/Resources/views/Export/new.html.twig b/src/Bundle/ChillMainBundle/Resources/views/Export/new.html.twig index 8aac6c253..a8b5e8ea8 100644 --- a/src/Bundle/ChillMainBundle/Resources/views/Export/new.html.twig +++ b/src/Bundle/ChillMainBundle/Resources/views/Export/new.html.twig @@ -22,6 +22,9 @@ {% block js %} {{ encore_entry_script_tags('page_export') }} + {% if export_alias == 'count_social_work_actions' %} + {{ encore_entry_script_tags('vue_form_action_goal_result') }} + {% endif %} {% endblock js %} {% block content %} diff --git a/src/Bundle/ChillMainBundle/chill.webpack.config.js b/src/Bundle/ChillMainBundle/chill.webpack.config.js index 628f04ba5..c4c445d31 100644 --- a/src/Bundle/ChillMainBundle/chill.webpack.config.js +++ b/src/Bundle/ChillMainBundle/chill.webpack.config.js @@ -74,4 +74,5 @@ module.exports = function(encore, entries) // Vue entrypoints encore.addEntry('vue_address', __dirname + '/Resources/public/vuejs/Address/index.js'); encore.addEntry('vue_onthefly', __dirname + '/Resources/public/vuejs/OnTheFly/index.js'); + encore.addEntry('vue_form_action_goal_result', __dirname + '/Resources/public/vuejs/FormActionGoalResult/index.js'); }; diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/SocialWorkTypeFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/SocialWorkTypeFilter.php index 3e5889cb0..ac584ea40 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/SocialWorkTypeFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/SocialWorkTypeFilter.php @@ -1,27 +1,22 @@ socialActionRender = $socialActionRender; $this->translatableStringHelper = $translatableStringHelper; - $this->socialActionRepository = $socialActionRepository; + $this->em = $em; } public function buildForm(FormBuilderInterface $builder) { - $socialActions = $this->socialActionRepository->findAll(); - - $builder->add('actionType', ChoiceType::class, [ - 'choices' => $socialActions, - 'choice_label' => function (SocialAction $sa) { - return $this->socialActionRender->renderString($sa, []); - }, - 'multiple' => true, - 'expanded' => true - ]); - - /* - $refreshGoals = function (FormInterface $form, SocialAction $actionType = null) { - - $goals = null === $actionType ? [] : $actionType->getGoals(); - - $form->add('goal', ChoiceType::class, [ - 'placeholder' => '', - 'choices' => $goals, - 'choice_label' => function (Goal $g) { - return $this->translatableStringHelper->localize($g->getTitle()); + $builder + ->add('actionType', HiddenType::class) + ->get('actionType') + ->addModelTransformer(new CallbackTransformer( + static function (?iterable $actionsAsIterable): string { + if (null === $actionsAsIterable) { return ''; } + $actionIds = []; + foreach ($actionsAsIterable as $value) { + $actionIds[] = $value->getId(); + } + return implode(',', $actionIds); }, - ]); - }; + function (?string $actionsAsString): array { + if (null === $actionsAsString) { return []; } + return array_map( + fn (string $id): ?SocialAction + => $this->socialActionRepository->findOneBy(['id' => (int) $id]), + explode(',', $actionsAsString) + ); + } + )) + ; - $builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) use ($refreshGoals) { - $data = $event->getData(); - dump($data); + $builder + ->add('goal', HiddenType::class) + ->get('goal') + ->addModelTransformer(new CallbackTransformer( + static function (?iterable $goalsAsIterable): string { + if (null === $goalsAsIterable) { return ''; } + $goalIds = []; + foreach ($goalsAsIterable as $value) { + $goalIds[] = $value->getId(); + } + return implode(',', $goalIds); + }, + function (?string $goalsAsString): array { + if (null === $goalsAsString) { return []; } + return array_map( + fn (string $id): ?Goal + => $this->socialActionRepository->findOneBy(['id' => (int) $id]), + explode(',', $goalsAsString) + ); + } + )) + ; - $refreshGoals($event->getForm(), $data); - }); + $builder + ->add('result', HiddenType::class) + ->get('result') + ->addModelTransformer(new CallbackTransformer( + static function (?iterable $resultsAsIterable): string { + if (null === $resultsAsIterable) { return ''; } + $resultIds = []; + foreach ($resultsAsIterable as $value) { + $resultIds[] = $value->getId(); + } + return implode(',', $resultIds); + }, + function (?string $resultsAsString): array { + if (null === $resultsAsString) { return []; } + return array_map( + fn (string $id): ?Result + => $this->socialActionRepository->findOneBy(['id' => (int) $id]), + explode(',', $resultsAsString) + ); + } + )) + ; - $builder->get('actionType')->addEventListener( - FormEvents::POST_SUBMIT, - function (FormEvent $event) use ($refreshGoals) { - $actionType = $event->getForm()->getData(); - dump($actionType); - $refreshGoals($event->getForm()->getParent(), $actionType); - } - ); - */ } public function getTitle(): string @@ -122,7 +145,15 @@ class SocialWorkTypeFilter implements FilterInterface public function alterQuery(QueryBuilder $qb, $data) { $where = $qb->getDQLPart('where'); - $clause = $qb->expr()->in('r', ':referrers'); + $clause = $qb->expr()->eq('acpw.socialAction',':actionType'); + + /* + if (!empty($data['goal'])) { + $clause + $qb->expr()->in('acpw.goals', ':goals'); + } + $qb->expr()->in('acpw.results', ':results'); + */ if ($where instanceof Andx) { $where->add($clause); @@ -131,7 +162,11 @@ class SocialWorkTypeFilter implements FilterInterface } $qb->add('where', $where); - $qb->setParameter('referrers', $data['referrers']); + $qb->setParameters([ + 'actionType' => $data['actionType'], + 'goal' => $data['goal'], + 'result' => $data['result'], + ]); } public function applyOn(): string From f10ec3991dcd8267ddffa8dde7d345baebd23447 Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Thu, 8 Sep 2022 11:04:38 +0200 Subject: [PATCH 02/41] exports: put breadcrumb in an include, add a link to go back to the list --- .../Resources/views/Export/_breadcrumb.html.twig | 6 ++++++ .../Resources/views/Export/download.html.twig | 5 +---- .../ChillMainBundle/Resources/views/Export/new.html.twig | 5 +---- .../Resources/views/Export/new_centers_step.html.twig | 7 ++----- .../Resources/views/Export/new_formatter_step.html.twig | 5 +---- 5 files changed, 11 insertions(+), 17 deletions(-) create mode 100644 src/Bundle/ChillMainBundle/Resources/views/Export/_breadcrumb.html.twig diff --git a/src/Bundle/ChillMainBundle/Resources/views/Export/_breadcrumb.html.twig b/src/Bundle/ChillMainBundle/Resources/views/Export/_breadcrumb.html.twig new file mode 100644 index 000000000..1d4a6573c --- /dev/null +++ b/src/Bundle/ChillMainBundle/Resources/views/Export/_breadcrumb.html.twig @@ -0,0 +1,6 @@ +
+ + + + {{ export_group|trans }} +
diff --git a/src/Bundle/ChillMainBundle/Resources/views/Export/download.html.twig b/src/Bundle/ChillMainBundle/Resources/views/Export/download.html.twig index fa568d857..84eb85100 100644 --- a/src/Bundle/ChillMainBundle/Resources/views/Export/download.html.twig +++ b/src/Bundle/ChillMainBundle/Resources/views/Export/download.html.twig @@ -36,10 +36,7 @@ window.addEventListener("DOMContentLoaded", function(e) { {% block content %}
-
- - {{ export_group|trans }} -
+ {{ include('@ChillMain/Export/_breadcrumb.html.twig') }}

{{ export.title|trans }}

{{ "Download export"|trans }}

diff --git a/src/Bundle/ChillMainBundle/Resources/views/Export/new.html.twig b/src/Bundle/ChillMainBundle/Resources/views/Export/new.html.twig index 8aac6c253..7f7efae9a 100644 --- a/src/Bundle/ChillMainBundle/Resources/views/Export/new.html.twig +++ b/src/Bundle/ChillMainBundle/Resources/views/Export/new.html.twig @@ -27,10 +27,7 @@ {% block content %}
-
- - {{ export_group|trans }} -
+ {{ include('@ChillMain/Export/_breadcrumb.html.twig') }}

{{ export.title|trans }}

diff --git a/src/Bundle/ChillMainBundle/Resources/views/Export/new_centers_step.html.twig b/src/Bundle/ChillMainBundle/Resources/views/Export/new_centers_step.html.twig index 4a2d9ab9e..8874744c4 100644 --- a/src/Bundle/ChillMainBundle/Resources/views/Export/new_centers_step.html.twig +++ b/src/Bundle/ChillMainBundle/Resources/views/Export/new_centers_step.html.twig @@ -22,11 +22,8 @@ {% block content %}
- -
- - {{ export_group|trans }} -
+ + {{ include('@ChillMain/Export/_breadcrumb.html.twig') }}

{{ export.title|trans }}

diff --git a/src/Bundle/ChillMainBundle/Resources/views/Export/new_formatter_step.html.twig b/src/Bundle/ChillMainBundle/Resources/views/Export/new_formatter_step.html.twig index 443816611..1c3209455 100644 --- a/src/Bundle/ChillMainBundle/Resources/views/Export/new_formatter_step.html.twig +++ b/src/Bundle/ChillMainBundle/Resources/views/Export/new_formatter_step.html.twig @@ -23,10 +23,7 @@ {% block content %}
-
- - {{ export_group|trans }} -
+ {{ include('@ChillMain/Export/_breadcrumb.html.twig') }}

{{ export.title|trans }}

From a817b0bf4cf093b6fa26601ab580ad4ebc0697e1 Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Thu, 8 Sep 2022 11:31:23 +0200 Subject: [PATCH 03/41] exports: re-enable all modifiers stack with shared filters/aggrs --- .../Export/Export/LinkedToACP/AvgActivityDuration.php | 2 +- .../Export/Export/LinkedToACP/AvgActivityVisitDuration.php | 2 +- .../Export/Export/LinkedToACP/CountActivity.php | 2 +- .../Export/Export/LinkedToACP/SumActivityDuration.php | 2 +- .../Export/Export/LinkedToACP/SumActivityVisitDuration.php | 2 +- .../ChillPersonBundle/Export/Export/CountEvaluation.php | 4 ++-- src/Bundle/ChillPersonBundle/Export/Export/CountHousehold.php | 2 +- .../Export/Export/CountPersonWithAccompanyingCourse.php | 2 +- .../Export/Export/CountSocialWorkActions.php | 1 + src/Bundle/ChillPersonBundle/translations/messages.fr.yml | 4 ++-- 10 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityDuration.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityDuration.php index be20d2b9c..b2346b8fd 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityDuration.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityDuration.php @@ -101,7 +101,7 @@ class AvgActivityDuration implements ExportInterface, GroupedExportInterface return [ Declarations::ACTIVITY, Declarations::ACTIVITY_ACP, - //PersonDeclarations::ACP_TYPE, + PersonDeclarations::ACP_TYPE, ]; } } diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityVisitDuration.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityVisitDuration.php index 021c82d72..0195992fe 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityVisitDuration.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityVisitDuration.php @@ -101,7 +101,7 @@ class AvgActivityVisitDuration implements ExportInterface, GroupedExportInterfac return [ Declarations::ACTIVITY, Declarations::ACTIVITY_ACP, - //PersonDeclarations::ACP_TYPE, + PersonDeclarations::ACP_TYPE, ]; } } diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/CountActivity.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/CountActivity.php index 1f8b742dd..e4202c33a 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/CountActivity.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/CountActivity.php @@ -105,7 +105,7 @@ class CountActivity implements ExportInterface, GroupedExportInterface return [ Declarations::ACTIVITY, Declarations::ACTIVITY_ACP, - //PersonDeclarations::ACP_TYPE, + PersonDeclarations::ACP_TYPE, ]; } } diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityDuration.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityDuration.php index 4d9b43034..2e87623ef 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityDuration.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityDuration.php @@ -104,7 +104,7 @@ class SumActivityDuration implements ExportInterface, GroupedExportInterface return [ Declarations::ACTIVITY, Declarations::ACTIVITY_ACP, - //PersonDeclarations::ACP_TYPE, + PersonDeclarations::ACP_TYPE, ]; } } diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityVisitDuration.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityVisitDuration.php index 212b1384f..5bb6d542e 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityVisitDuration.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityVisitDuration.php @@ -104,7 +104,7 @@ class SumActivityVisitDuration implements ExportInterface, GroupedExportInterfac return [ Declarations::ACTIVITY, Declarations::ACTIVITY_ACP, - //PersonDeclarations::ACP_TYPE, + PersonDeclarations::ACP_TYPE, ]; } } diff --git a/src/Bundle/ChillPersonBundle/Export/Export/CountEvaluation.php b/src/Bundle/ChillPersonBundle/Export/Export/CountEvaluation.php index 5b2ab65eb..7178a54c8 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/CountEvaluation.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/CountEvaluation.php @@ -112,8 +112,8 @@ class CountEvaluation implements ExportInterface, GroupedExportInterface { return [ Declarations::EVAL_TYPE, - //Declarations::ACP_TYPE, - //Declarations::SOCIAL_WORK_ACTION_TYPE, + Declarations::SOCIAL_WORK_ACTION_TYPE, + Declarations::ACP_TYPE, ]; } } diff --git a/src/Bundle/ChillPersonBundle/Export/Export/CountHousehold.php b/src/Bundle/ChillPersonBundle/Export/Export/CountHousehold.php index f60f66310..18ddbaea1 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/CountHousehold.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/CountHousehold.php @@ -121,7 +121,7 @@ class CountHousehold implements ExportInterface, GroupedExportInterface { return [ Declarations::HOUSEHOLD_TYPE, - //Declarations::ACP_TYPE + Declarations::ACP_TYPE, ]; } } diff --git a/src/Bundle/ChillPersonBundle/Export/Export/CountPersonWithAccompanyingCourse.php b/src/Bundle/ChillPersonBundle/Export/Export/CountPersonWithAccompanyingCourse.php index 800023fc5..51d85c479 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/CountPersonWithAccompanyingCourse.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/CountPersonWithAccompanyingCourse.php @@ -111,8 +111,8 @@ class CountPersonWithAccompanyingCourse implements ExportInterface, GroupedExpor public function supportsModifiers(): array { return [ - Declarations::ACP_TYPE, Declarations::PERSON_TYPE, + Declarations::ACP_TYPE, ]; } } diff --git a/src/Bundle/ChillPersonBundle/Export/Export/CountSocialWorkActions.php b/src/Bundle/ChillPersonBundle/Export/Export/CountSocialWorkActions.php index 17de7e5ae..2ad6e9f1b 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/CountSocialWorkActions.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/CountSocialWorkActions.php @@ -110,6 +110,7 @@ class CountSocialWorkActions implements ExportInterface, GroupedExportInterface { return [ Declarations::SOCIAL_WORK_ACTION_TYPE, + Declarations::ACP_TYPE, ]; } } diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index e909f0ab7..70a0cda42 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -456,7 +456,7 @@ Filter by socialaction: Filtrer les parcours 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 les parcours par action d'accompagnement -Filter by type of action, objectives and results: "Filtrer par type d'action, objectif et résultat" +Filter by type of action, objectives and results: "Filtrer les actions par type, objectif et résultat" Filter by evaluation: Filtrer les parcours par évaluation Accepted evaluations: Évaluations @@ -576,7 +576,7 @@ Group by composition: Grouper les ménages par composition familiale Group by number of children: Grouper les ménages par nombre d'enfants ## persons aggregators -Group by duration: Grouper par durée du parcours +Group by duration: Grouper les parcours par durée Rounded month duration: Durée en mois (arrondie) current duration: en cours duration 0 month: 0 mois (<15 jours) From 5c2b2105b2c858e7fc6d759b3477a5e28a0c6623 Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Thu, 8 Sep 2022 11:47:41 +0200 Subject: [PATCH 04/41] exports: improve formatter twig template (when multiple order rows) --- .../views/Export/new_formatter_step.html.twig | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Resources/views/Export/new_formatter_step.html.twig b/src/Bundle/ChillMainBundle/Resources/views/Export/new_formatter_step.html.twig index 1c3209455..8ecaf6dd8 100644 --- a/src/Bundle/ChillMainBundle/Resources/views/Export/new_formatter_step.html.twig +++ b/src/Bundle/ChillMainBundle/Resources/views/Export/new_formatter_step.html.twig @@ -33,19 +33,21 @@

{{ 'Formatter'| trans }}

-
{% if form.children.formatter.children|length == 0 %}

{{ "No options availables. Your report is fully configured."|trans }}

{{ form_widget(form.children.formatter) }} {% else %} - {# we always have to render children, to mark as rendered #} - {% for input in form.children.formatter.children %} - {{ form_row(input) }} - {% endfor %} +
+ {# we always have to render children, to mark as rendered #} + {% for input in form.children.formatter.children %} +
+ {{ form_row(input) }} +
+ {% endfor %} +
{% endif %} -
From 712c7bc49208c2a1bc335285a25a0f3647605e64 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Thu, 8 Sep 2022 11:03:20 +0200 Subject: [PATCH 05/41] add actionRender in construct, it was missing --- .../Aggregator/SocialWorkAggregators/ActionTypeAggregator.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ActionTypeAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ActionTypeAggregator.php index b76db495d..fb64b3e01 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ActionTypeAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ActionTypeAggregator.php @@ -29,6 +29,7 @@ final class ActionTypeAggregator implements AggregatorInterface SocialActionRender $actionRender ) { $this->socialActionRepository = $socialActionRepository; + $this->actionRender = $actionRender; } public function addRole(): ?string From 5f2622d0d2fd7b10a4bb79ce1026f46f07b5f38c Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Thu, 8 Sep 2022 11:08:34 +0200 Subject: [PATCH 06/41] rename files for coherence with naming elsewhere --- .../Export/{CountAppointments.php => CountCalendars.php} | 3 +-- ...tAppointmentAvgDuration.php => StatCalendarAvgDuration.php} | 2 +- ...tAppointmentSumDuration.php => StatCalendarSumDuration.php} | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) rename src/Bundle/ChillCalendarBundle/Export/Export/{CountAppointments.php => CountCalendars.php} (95%) rename src/Bundle/ChillCalendarBundle/Export/Export/{StatAppointmentAvgDuration.php => StatCalendarAvgDuration.php} (96%) rename src/Bundle/ChillCalendarBundle/Export/Export/{StatAppointmentSumDuration.php => StatCalendarSumDuration.php} (96%) diff --git a/src/Bundle/ChillCalendarBundle/Export/Export/CountAppointments.php b/src/Bundle/ChillCalendarBundle/Export/Export/CountCalendars.php similarity index 95% rename from src/Bundle/ChillCalendarBundle/Export/Export/CountAppointments.php rename to src/Bundle/ChillCalendarBundle/Export/Export/CountCalendars.php index b9da17114..edf654a10 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Export/CountAppointments.php +++ b/src/Bundle/ChillCalendarBundle/Export/Export/CountCalendars.php @@ -22,9 +22,8 @@ use Doctrine\ORM\AbstractQuery; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Process\Exception\LogicException; -use Symfony\Component\Security\Core\Role\Role; -class CountAppointments implements ExportInterface, GroupedExportInterface +class CountCalendars implements ExportInterface, GroupedExportInterface { private CalendarRepository $calendarRepository; diff --git a/src/Bundle/ChillCalendarBundle/Export/Export/StatAppointmentAvgDuration.php b/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarAvgDuration.php similarity index 96% rename from src/Bundle/ChillCalendarBundle/Export/Export/StatAppointmentAvgDuration.php rename to src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarAvgDuration.php index 491cb38b9..51e94a288 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Export/StatAppointmentAvgDuration.php +++ b/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarAvgDuration.php @@ -22,7 +22,7 @@ use Doctrine\ORM\QueryBuilder; use LogicException; use Symfony\Component\Form\FormBuilderInterface; -class StatAppointmentAvgDuration implements ExportInterface, GroupedExportInterface +class StatCalendarAvgDuration implements ExportInterface, GroupedExportInterface { private CalendarRepository $calendarRepository; diff --git a/src/Bundle/ChillCalendarBundle/Export/Export/StatAppointmentSumDuration.php b/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarSumDuration.php similarity index 96% rename from src/Bundle/ChillCalendarBundle/Export/Export/StatAppointmentSumDuration.php rename to src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarSumDuration.php index 286c73be5..51591c670 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Export/StatAppointmentSumDuration.php +++ b/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarSumDuration.php @@ -22,7 +22,7 @@ use Doctrine\ORM\QueryBuilder; use LogicException; use Symfony\Component\Form\FormBuilderInterface; -class StatAppointmentSumDuration implements ExportInterface, GroupedExportInterface +class StatCalendarSumDuration implements ExportInterface, GroupedExportInterface { private CalendarRepository $calendarRepository; From ff5fab5f502efabd4547c870368641877b31d0bd Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Thu, 8 Sep 2022 11:08:34 +0200 Subject: [PATCH 07/41] rename files for coherence with naming elsewhere --- .../Resources/config/services/exports.yaml | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Bundle/ChillCalendarBundle/Resources/config/services/exports.yaml b/src/Bundle/ChillCalendarBundle/Resources/config/services/exports.yaml index 56580dba1..a7508f3b5 100644 --- a/src/Bundle/ChillCalendarBundle/Resources/config/services/exports.yaml +++ b/src/Bundle/ChillCalendarBundle/Resources/config/services/exports.yaml @@ -1,26 +1,26 @@ services: ## Indicators - chill.calendar.export.count_appointments: - class: Chill\CalendarBundle\Export\Export\CountAppointments + chill.calendar.export.count_calendars: + class: Chill\CalendarBundle\Export\Export\CountCalendars autowire: true autoconfigure: true tags: - - { name: chill.export, alias: count_appointments } + - { name: chill.export, alias: count_calendars } - chill.calendar.export.average_duration_appointments: - class: Chill\CalendarBundle\Export\Export\StatAppointmentAvgDuration + chill.calendar.export.average_duration_calendars: + class: Chill\CalendarBundle\Export\Export\StatCalendarAvgDuration autowire: true autoconfigure: true tags: - - { name: chill.export, alias: average_duration_appointments } + - { name: chill.export, alias: average_duration_calendars } - chill.calendar.export.sum_duration_appointments: - class: Chill\CalendarBundle\Export\Export\StatAppointmentSumDuration + chill.calendar.export.sum_duration_calendars: + class: Chill\CalendarBundle\Export\Export\StatCalendarSumDuration autowire: true autoconfigure: true tags: - - { name: chill.export, alias: sum_duration_appointments } + - { name: chill.export, alias: sum_duration_calendars } ## Filters @@ -101,4 +101,4 @@ services: autowire: true autoconfigure: true tags: - - { name: chill.export_aggregator, alias: month_aggregator } \ No newline at end of file + - { name: chill.export_aggregator, alias: month_aggregator } From ebfb030ba6e377c556b251a3a5c1d592fef18715 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Thu, 8 Sep 2022 11:20:27 +0200 Subject: [PATCH 08/41] add querybuilder method to repository --- .../Repository/CalendarRepository.php | 236 +++++++++++++++--- 1 file changed, 202 insertions(+), 34 deletions(-) diff --git a/src/Bundle/ChillCalendarBundle/Repository/CalendarRepository.php b/src/Bundle/ChillCalendarBundle/Repository/CalendarRepository.php index 55fba5f80..626a9f29f 100644 --- a/src/Bundle/ChillCalendarBundle/Repository/CalendarRepository.php +++ b/src/Bundle/ChillCalendarBundle/Repository/CalendarRepository.php @@ -12,52 +12,220 @@ declare(strict_types=1); namespace Chill\CalendarBundle\Repository; use Chill\CalendarBundle\Entity\Calendar; -use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; +use Chill\MainBundle\Entity\User; +use Chill\PersonBundle\Entity\AccompanyingPeriod; +use DateTimeImmutable; +use Doctrine\DBAL\Types\Types; +use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityRepository; -use Doctrine\Persistence\ManagerRegistry; +use Doctrine\ORM\Query\ResultSetMapping; +use Doctrine\ORM\QueryBuilder; +use Doctrine\Persistence\ObjectRepository; +use function count; -/** - * @method Calendar|null find($id, $lockMode = null, $lockVersion = null) - * @method Calendar|null findOneBy(array $criteria, array $orderBy = null) - * @method Calendar[] findAll() - * @method Calendar[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) - */ -class CalendarRepository extends ServiceEntityRepository +class CalendarRepository implements ObjectRepository { - // private EntityRepository $repository; + private EntityManagerInterface $em; - public function __construct(ManagerRegistry $registry) + private EntityRepository $repository; + + public function __construct(EntityManagerInterface $entityManager) { - parent::__construct($registry, Calendar::class); - // $this->repository = $entityManager->getRepository(AccompanyingPeriodWork::class); + $this->repository = $entityManager->getRepository(Calendar::class); + $this->em = $entityManager; } - // /** - // * @return Calendar[] Returns an array of Calendar objects - // */ - /* - public function findByExampleField($value) + public function countByAccompanyingPeriod(AccompanyingPeriod $period): int { - return $this->createQueryBuilder('c') - ->andWhere('c.exampleField = :val') - ->setParameter('val', $value) - ->orderBy('c.id', 'ASC') - ->setMaxResults(10) + return $this->repository->count(['accompanyingPeriod' => $period]); + } + + public function createQueryBuilder(string $alias, ?string $indexBy = null): QueryBuilder + { + return $this->repository->createQueryBuilder($alias, $indexBy); + } + + public function countByUser(User $user, DateTimeImmutable $from, DateTimeImmutable $to): int + { + return $this->buildQueryByUser($user, $from, $to) + ->select('COUNT(c)') ->getQuery() - ->getResult() - ; + ->getSingleScalarResult(); } - */ - /* - public function findOneBySomeField($value): ?Calendar + public function find($id): ?Calendar { - return $this->createQueryBuilder('c') - ->andWhere('c.exampleField = :val') - ->setParameter('val', $value) - ->getQuery() - ->getOneOrNullResult() - ; + return $this->repository->find($id); } + + /** + * @return array|Calendar[] */ + public function findAll(): array + { + return $this->repository->findAll(); + } + + /** + * @return array|Calendar[] + */ + public function findBy(array $criteria, ?array $orderBy = null, ?int $limit = null, ?int $offset = null): array + { + return $this->repository->findBy($criteria, $orderBy, $limit, $offset); + } + + /** + * @return array|Calendar[] + */ + public function findByAccompanyingPeriod(AccompanyingPeriod $period, ?array $orderBy = null, ?int $limit = null, ?int $offset = null): array + { + return $this->findBy( + [ + 'accompanyingPeriod' => $period, + ], + $orderBy, + $limit, + $orderBy + ); + } + + public function findByNotificationAvailable(DateTimeImmutable $startDate, DateTimeImmutable $endDate, ?int $limit = null, ?int $offset = null): array + { + $qb = $this->queryByNotificationAvailable($startDate, $endDate)->select('c'); + + if (null !== $limit) { + $qb->setMaxResults($limit); + } + + if (null !== $offset) { + $qb->setFirstResult($offset); + } + + return $qb->getQuery()->getResult(); + } + + /** + * @return array|Calendar[] + */ + public function findByUser(User $user, DateTimeImmutable $from, DateTimeImmutable $to, ?int $limit = null, ?int $offset = null): array + { + $qb = $this->buildQueryByUser($user, $from, $to)->select('c'); + + if (null !== $limit) { + $qb->setMaxResults($limit); + } + + if (null !== $offset) { + $qb->setFirstResult($offset); + } + + return $qb->getQuery()->getResult(); + } + + public function findOneBy(array $criteria): ?Calendar + { + return $this->repository->findOneBy($criteria); + } + + /** + * Given a list of remote ids, return an array where + * keys are the remoteIds, and value is a boolean, true if the + * id is present in database. + * + * @param array|list $remoteIds + * + * @return array + */ + public function findRemoteIdsPresent(array $remoteIds): array + { + if (0 === count($remoteIds)) { + return []; + } + + $remoteIdsStr = implode( + ', ', + array_fill(0, count($remoteIds), '((?))') + ); + + $sql = "SELECT + sq.remoteId as remoteid, + EXISTS (SELECT 1 FROM chill_calendar.calendar c WHERE c.remoteId = sq.remoteId) AS present + FROM + ( + VALUES {$remoteIdsStr} + ) AS sq(remoteId); + "; + + $rsm = new ResultSetMapping(); + $rsm + ->addScalarResult('remoteid', 'remoteId', Types::STRING) + ->addScalarResult('present', 'present', Types::BOOLEAN); + + $rows = $this->em + ->createNativeQuery( + $sql, + $rsm + ) + ->setParameters(array_values($remoteIds)) + ->getResult(); + + $results = []; + + foreach ($rows as $r) { + $results[$r['remoteId']] = $r['present']; + } + + return $results; + } + + public function getClassName() + { + return Calendar::class; + } + + private function buildQueryByUser(User $user, DateTimeImmutable $from, DateTimeImmutable $to): QueryBuilder + { + $qb = $this->repository->createQueryBuilder('c'); + + return $qb + ->where( + $qb->expr()->andX( + $qb->expr()->eq('c.mainUser', ':user'), + $qb->expr()->gte('c.startDate', ':startDate'), + $qb->expr()->lte('c.endDate', ':endDate'), + ) + ) + ->setParameters([ + 'user' => $user, + 'startDate' => $from, + 'endDate' => $to, + ]); + } + + private function queryByNotificationAvailable(DateTimeImmutable $startDate, DateTimeImmutable $endDate): QueryBuilder + { + $qb = $this->repository->createQueryBuilder('c'); + + $qb->where( + $qb->expr()->andX( + $qb->expr()->eq('c.sendSMS', ':true'), + $qb->expr()->gte('c.startDate', ':startDate'), + $qb->expr()->lt('c.startDate', ':endDate'), + $qb->expr()->orX( + $qb->expr()->eq('c.smsStatus', ':pending'), + $qb->expr()->eq('c.smsStatus', ':cancel_pending') + ) + ) + ); + + $qb->setParameters([ + 'true' => true, + 'startDate' => $startDate, + 'endDate' => $endDate, + 'pending' => Calendar::SMS_PENDING, + 'cancel_pending' => Calendar::SMS_CANCEL_PENDING, + ]); + + return $qb; + } } From 822b96f87fa2351bac329e0626ec88eed233fb17 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Thu, 8 Sep 2022 11:25:50 +0200 Subject: [PATCH 09/41] adjust property name to make it work with changes calendar bundle --- .../ChillCalendarBundle/Export/Aggregator/AgentAggregator.php | 2 +- .../ChillCalendarBundle/Export/Aggregator/JobAggregator.php | 2 +- .../ChillCalendarBundle/Export/Aggregator/ScopeAggregator.php | 2 +- src/Bundle/ChillCalendarBundle/Export/Filter/AgentFilter.php | 2 +- src/Bundle/ChillCalendarBundle/Export/Filter/JobFilter.php | 2 +- src/Bundle/ChillCalendarBundle/Export/Filter/ScopeFilter.php | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/AgentAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/AgentAggregator.php index 57ec33cdd..2974fb875 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/AgentAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/AgentAggregator.php @@ -41,7 +41,7 @@ final class AgentAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { if (!in_array('caluser', $qb->getAllAliases(), true)) { - $qb->join('cal.user', 'caluser'); + $qb->join('cal.mainUser', 'caluser'); } $qb->addSelect('caluser.id AS agent_aggregator'); diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/JobAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/JobAggregator.php index 17905cf35..46fc6e63d 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/JobAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/JobAggregator.php @@ -41,7 +41,7 @@ final class JobAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { if (!in_array('caluser', $qb->getAllAliases(), true)) { - $qb->join('cal.user', 'caluser'); + $qb->join('cal.mainUser', 'caluser'); } $qb->addSelect('IDENTITY(caluser.userJob) as job_aggregator'); diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/ScopeAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/ScopeAggregator.php index 7605c3d5d..351451ead 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/ScopeAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/ScopeAggregator.php @@ -41,7 +41,7 @@ final class ScopeAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { if (!in_array('caluser', $qb->getAllAliases(), true)) { - $qb->join('cal.user', 'caluser'); + $qb->join('cal.mainUser', 'caluser'); } $qb->addSelect('IDENTITY(caluser.mainScope) as scope_aggregator'); diff --git a/src/Bundle/ChillCalendarBundle/Export/Filter/AgentFilter.php b/src/Bundle/ChillCalendarBundle/Export/Filter/AgentFilter.php index 263b1e160..fe33c1210 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Filter/AgentFilter.php +++ b/src/Bundle/ChillCalendarBundle/Export/Filter/AgentFilter.php @@ -37,7 +37,7 @@ class AgentFilter implements FilterInterface public function alterQuery(QueryBuilder $qb, $data) { $where = $qb->getDQLPart('where'); - $clause = $qb->expr()->in('cal.user', ':agents'); + $clause = $qb->expr()->in('cal.mainUser', ':agents'); if ($where instanceof Andx) { $where->add($clause); diff --git a/src/Bundle/ChillCalendarBundle/Export/Filter/JobFilter.php b/src/Bundle/ChillCalendarBundle/Export/Filter/JobFilter.php index 03cd4857d..9248143c7 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Filter/JobFilter.php +++ b/src/Bundle/ChillCalendarBundle/Export/Filter/JobFilter.php @@ -43,7 +43,7 @@ class JobFilter implements FilterInterface public function alterQuery(QueryBuilder $qb, $data) { if (!in_array('caluser', $qb->getAllAliases(), true)) { - $qb->join('cal.user', 'caluser'); + $qb->join('cal.mainUser', 'caluser'); } $where = $qb->getDQLPart('where'); diff --git a/src/Bundle/ChillCalendarBundle/Export/Filter/ScopeFilter.php b/src/Bundle/ChillCalendarBundle/Export/Filter/ScopeFilter.php index cbd566e9e..10e9e699c 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Filter/ScopeFilter.php +++ b/src/Bundle/ChillCalendarBundle/Export/Filter/ScopeFilter.php @@ -43,7 +43,7 @@ class ScopeFilter implements FilterInterface public function alterQuery(QueryBuilder $qb, $data) { if (!in_array('caluser', $qb->getAllAliases(), true)) { - $qb->join('cal.user', 'caluser'); + $qb->join('cal.mainUser', 'caluser'); } $where = $qb->getDQLPart('where'); From 12c37ddb2c47b6ba3b394ecbf1eb400da402c94d Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Thu, 8 Sep 2022 11:59:44 +0200 Subject: [PATCH 10/41] adjust property name to make it work with changes calendar bundle --- .../Export/Aggregator/AgentAggregator.php | 2 +- .../Export/Aggregator/CancelReasonAggregator.php | 4 ++-- .../Export/Aggregator/JobAggregator.php | 2 +- .../Export/Aggregator/LocationAggregator.php | 2 +- .../Export/Aggregator/LocationTypeAggregator.php | 2 +- .../Export/Aggregator/MonthYearAggregator.php | 8 ++++---- .../Export/Aggregator/ScopeAggregator.php | 2 +- .../ChillCalendarBundle/Export/Export/CountCalendars.php | 7 ++++--- .../Export/Export/StatCalendarAvgDuration.php | 4 ++-- .../Export/Export/StatCalendarSumDuration.php | 4 ++-- .../ChillCalendarBundle/Export/Filter/AgentFilter.php | 2 +- .../Export/Filter/BetweenDatesFilter.php | 4 ++-- .../ChillCalendarBundle/Export/Filter/JobFilter.php | 2 +- .../ChillCalendarBundle/Export/Filter/ScopeFilter.php | 2 +- 14 files changed, 24 insertions(+), 23 deletions(-) diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/AgentAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/AgentAggregator.php index 2974fb875..3c2b54855 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/AgentAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/AgentAggregator.php @@ -85,6 +85,6 @@ final class AgentAggregator implements AggregatorInterface public function getTitle(): string { - return 'Group appointments by agent'; + return 'Group calendars by agent'; } } diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/CancelReasonAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/CancelReasonAggregator.php index a07f052bf..854710a79 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/CancelReasonAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/CancelReasonAggregator.php @@ -40,7 +40,7 @@ class CancelReasonAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { - // TODO: still needs to take into account appointments without a cancel reason somehow + // TODO: still needs to take into account calendars without a cancel reason somehow if (!in_array('calcancel', $qb->getAllAliases(), true)) { $qb->join('cal.cancelReason', 'calcancel'); } @@ -88,6 +88,6 @@ class CancelReasonAggregator implements AggregatorInterface public function getTitle(): string { - return 'Group appointments by cancel reason'; + return 'Group calendars by cancel reason'; } } diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/JobAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/JobAggregator.php index 46fc6e63d..51500f45f 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/JobAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/JobAggregator.php @@ -87,6 +87,6 @@ final class JobAggregator implements AggregatorInterface public function getTitle(): string { - return 'Group appointments by agent job'; + return 'Group calendars by agent job'; } } diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationAggregator.php index 236b1b74f..287dccec7 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationAggregator.php @@ -80,6 +80,6 @@ final class LocationAggregator implements AggregatorInterface public function getTitle(): string { - return 'Group appointments by location'; + return 'Group calendars by location'; } } diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationTypeAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationTypeAggregator.php index c8d02160f..5d7559b2d 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationTypeAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationTypeAggregator.php @@ -87,6 +87,6 @@ final class LocationTypeAggregator implements AggregatorInterface public function getTitle(): string { - return 'Group appointments by location type'; + return 'Group calendars by location type'; } } diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/MonthYearAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/MonthYearAggregator.php index 26329ad13..b4f01db12 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/MonthYearAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/MonthYearAggregator.php @@ -55,10 +55,10 @@ class MonthYearAggregator implements AggregatorInterface return 'by month and year'; } - $month = substr($value, 0, 2); - $year = substr($value, 3, 4); + $month = (int)substr($value, 0, 2); + $year = (int)substr($value, 3, 4); - return strftime('%B %G', mktime(0, 0, 0, $month, '1', $year)); + return strftime('%B %G', mktime(0, 0, 0, $month, 1, $year)); }; } @@ -69,6 +69,6 @@ class MonthYearAggregator implements AggregatorInterface public function getTitle(): string { - return 'Group appointments by month and year'; + return 'Group calendars by month and year'; } } diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/ScopeAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/ScopeAggregator.php index 351451ead..8d3685f96 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/ScopeAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/ScopeAggregator.php @@ -87,6 +87,6 @@ final class ScopeAggregator implements AggregatorInterface public function getTitle(): string { - return 'Group appointments by agent scope'; + return 'Group calendars by agent scope'; } } diff --git a/src/Bundle/ChillCalendarBundle/Export/Export/CountCalendars.php b/src/Bundle/ChillCalendarBundle/Export/Export/CountCalendars.php index edf654a10..9d78d0f26 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Export/CountCalendars.php +++ b/src/Bundle/ChillCalendarBundle/Export/Export/CountCalendars.php @@ -21,7 +21,8 @@ use Closure; use Doctrine\ORM\AbstractQuery; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\Process\Exception\LogicException; +use Symfony\Component\Validator\Exception\LogicException; + class CountCalendars implements ExportInterface, GroupedExportInterface { @@ -44,7 +45,7 @@ class CountCalendars implements ExportInterface, GroupedExportInterface public function getDescription(): string { - return 'Count appointments by various parameters.'; + return 'Count calendars by various parameters.'; } public function getGroup(): string @@ -78,7 +79,7 @@ class CountCalendars implements ExportInterface, GroupedExportInterface public function getTitle(): string { - return 'Count appointments'; + return 'Count calendars'; } public function getType(): string diff --git a/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarAvgDuration.php b/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarAvgDuration.php index 51e94a288..4649ef571 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarAvgDuration.php +++ b/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarAvgDuration.php @@ -44,7 +44,7 @@ class StatCalendarAvgDuration implements ExportInterface, GroupedExportInterface public function getDescription(): string { - return 'Get the average of appointment duration according to various filters'; + return 'Get the average of calendar duration according to various filters'; } public function getGroup(): string @@ -78,7 +78,7 @@ class StatCalendarAvgDuration implements ExportInterface, GroupedExportInterface public function getTitle(): string { - return 'Average appointment duration'; + return 'Average calendar duration'; } public function getType(): string diff --git a/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarSumDuration.php b/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarSumDuration.php index 51591c670..4e2ed6a63 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarSumDuration.php +++ b/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarSumDuration.php @@ -44,7 +44,7 @@ class StatCalendarSumDuration implements ExportInterface, GroupedExportInterface public function getDescription(): string { - return 'Get the sum of appointment durations according to various filters'; + return 'Get the sum of calendar durations according to various filters'; } public function getGroup(): string @@ -78,7 +78,7 @@ class StatCalendarSumDuration implements ExportInterface, GroupedExportInterface public function getTitle(): string { - return 'Sum of appointment durations'; + return 'Sum of calendar durations'; } public function getType(): string diff --git a/src/Bundle/ChillCalendarBundle/Export/Filter/AgentFilter.php b/src/Bundle/ChillCalendarBundle/Export/Filter/AgentFilter.php index fe33c1210..a0b77ece9 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Filter/AgentFilter.php +++ b/src/Bundle/ChillCalendarBundle/Export/Filter/AgentFilter.php @@ -82,6 +82,6 @@ class AgentFilter implements FilterInterface public function getTitle(): string { - return 'Filter appointments by agent'; + return 'Filter calendars by agent'; } } diff --git a/src/Bundle/ChillCalendarBundle/Export/Filter/BetweenDatesFilter.php b/src/Bundle/ChillCalendarBundle/Export/Filter/BetweenDatesFilter.php index c3aafc192..23e3ac4e6 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Filter/BetweenDatesFilter.php +++ b/src/Bundle/ChillCalendarBundle/Export/Filter/BetweenDatesFilter.php @@ -66,7 +66,7 @@ class BetweenDatesFilter implements FilterInterface public function describeAction($data, $format = 'string'): array { - return ['Filtered by appointments between %dateFrom% and %dateTo%', [ + return ['Filtered by calendars between %dateFrom% and %dateTo%', [ '%dateFrom%' => $data['date_from']->format('d-m-Y'), '%dateTo%' => $data['date_to']->format('d-m-Y'), ]]; @@ -74,6 +74,6 @@ class BetweenDatesFilter implements FilterInterface public function getTitle(): string { - return 'Filter appointments between certain dates'; + return 'Filter calendars between certain dates'; } } diff --git a/src/Bundle/ChillCalendarBundle/Export/Filter/JobFilter.php b/src/Bundle/ChillCalendarBundle/Export/Filter/JobFilter.php index 9248143c7..d5a70b3da 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Filter/JobFilter.php +++ b/src/Bundle/ChillCalendarBundle/Export/Filter/JobFilter.php @@ -95,6 +95,6 @@ class JobFilter implements FilterInterface public function getTitle(): string { - return 'Filter appointments by agent job'; + return 'Filter calendars by agent job'; } } diff --git a/src/Bundle/ChillCalendarBundle/Export/Filter/ScopeFilter.php b/src/Bundle/ChillCalendarBundle/Export/Filter/ScopeFilter.php index 10e9e699c..9f12cbf19 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Filter/ScopeFilter.php +++ b/src/Bundle/ChillCalendarBundle/Export/Filter/ScopeFilter.php @@ -95,6 +95,6 @@ class ScopeFilter implements FilterInterface public function getTitle() { - return 'Filter appointments by agent scope'; + return 'Filter calendars by agent scope'; } } From 967c8c62d469142b625379b859e6c53de190d124 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Thu, 8 Sep 2022 12:45:59 +0200 Subject: [PATCH 11/41] Revert "adjust property name to make it work with changes calendar bundle" This reverts commit 12c37ddb2c47b6ba3b394ecbf1eb400da402c94d. --- .../Export/Aggregator/AgentAggregator.php | 2 +- .../Export/Aggregator/CancelReasonAggregator.php | 4 ++-- .../Export/Aggregator/JobAggregator.php | 2 +- .../Export/Aggregator/LocationAggregator.php | 2 +- .../Export/Aggregator/LocationTypeAggregator.php | 2 +- .../Export/Aggregator/MonthYearAggregator.php | 8 ++++---- .../Export/Aggregator/ScopeAggregator.php | 2 +- .../ChillCalendarBundle/Export/Export/CountCalendars.php | 7 +++---- .../Export/Export/StatCalendarAvgDuration.php | 4 ++-- .../Export/Export/StatCalendarSumDuration.php | 4 ++-- .../ChillCalendarBundle/Export/Filter/AgentFilter.php | 2 +- .../Export/Filter/BetweenDatesFilter.php | 4 ++-- .../ChillCalendarBundle/Export/Filter/JobFilter.php | 2 +- .../ChillCalendarBundle/Export/Filter/ScopeFilter.php | 2 +- 14 files changed, 23 insertions(+), 24 deletions(-) diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/AgentAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/AgentAggregator.php index 3c2b54855..2974fb875 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/AgentAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/AgentAggregator.php @@ -85,6 +85,6 @@ final class AgentAggregator implements AggregatorInterface public function getTitle(): string { - return 'Group calendars by agent'; + return 'Group appointments by agent'; } } diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/CancelReasonAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/CancelReasonAggregator.php index 854710a79..a07f052bf 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/CancelReasonAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/CancelReasonAggregator.php @@ -40,7 +40,7 @@ class CancelReasonAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { - // TODO: still needs to take into account calendars without a cancel reason somehow + // TODO: still needs to take into account appointments without a cancel reason somehow if (!in_array('calcancel', $qb->getAllAliases(), true)) { $qb->join('cal.cancelReason', 'calcancel'); } @@ -88,6 +88,6 @@ class CancelReasonAggregator implements AggregatorInterface public function getTitle(): string { - return 'Group calendars by cancel reason'; + return 'Group appointments by cancel reason'; } } diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/JobAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/JobAggregator.php index 51500f45f..46fc6e63d 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/JobAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/JobAggregator.php @@ -87,6 +87,6 @@ final class JobAggregator implements AggregatorInterface public function getTitle(): string { - return 'Group calendars by agent job'; + return 'Group appointments by agent job'; } } diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationAggregator.php index 287dccec7..236b1b74f 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationAggregator.php @@ -80,6 +80,6 @@ final class LocationAggregator implements AggregatorInterface public function getTitle(): string { - return 'Group calendars by location'; + return 'Group appointments by location'; } } diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationTypeAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationTypeAggregator.php index 5d7559b2d..c8d02160f 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationTypeAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationTypeAggregator.php @@ -87,6 +87,6 @@ final class LocationTypeAggregator implements AggregatorInterface public function getTitle(): string { - return 'Group calendars by location type'; + return 'Group appointments by location type'; } } diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/MonthYearAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/MonthYearAggregator.php index b4f01db12..26329ad13 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/MonthYearAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/MonthYearAggregator.php @@ -55,10 +55,10 @@ class MonthYearAggregator implements AggregatorInterface return 'by month and year'; } - $month = (int)substr($value, 0, 2); - $year = (int)substr($value, 3, 4); + $month = substr($value, 0, 2); + $year = substr($value, 3, 4); - return strftime('%B %G', mktime(0, 0, 0, $month, 1, $year)); + return strftime('%B %G', mktime(0, 0, 0, $month, '1', $year)); }; } @@ -69,6 +69,6 @@ class MonthYearAggregator implements AggregatorInterface public function getTitle(): string { - return 'Group calendars by month and year'; + return 'Group appointments by month and year'; } } diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/ScopeAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/ScopeAggregator.php index 8d3685f96..351451ead 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/ScopeAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/ScopeAggregator.php @@ -87,6 +87,6 @@ final class ScopeAggregator implements AggregatorInterface public function getTitle(): string { - return 'Group calendars by agent scope'; + return 'Group appointments by agent scope'; } } diff --git a/src/Bundle/ChillCalendarBundle/Export/Export/CountCalendars.php b/src/Bundle/ChillCalendarBundle/Export/Export/CountCalendars.php index 9d78d0f26..edf654a10 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Export/CountCalendars.php +++ b/src/Bundle/ChillCalendarBundle/Export/Export/CountCalendars.php @@ -21,8 +21,7 @@ use Closure; use Doctrine\ORM\AbstractQuery; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\Validator\Exception\LogicException; - +use Symfony\Component\Process\Exception\LogicException; class CountCalendars implements ExportInterface, GroupedExportInterface { @@ -45,7 +44,7 @@ class CountCalendars implements ExportInterface, GroupedExportInterface public function getDescription(): string { - return 'Count calendars by various parameters.'; + return 'Count appointments by various parameters.'; } public function getGroup(): string @@ -79,7 +78,7 @@ class CountCalendars implements ExportInterface, GroupedExportInterface public function getTitle(): string { - return 'Count calendars'; + return 'Count appointments'; } public function getType(): string diff --git a/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarAvgDuration.php b/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarAvgDuration.php index 4649ef571..51e94a288 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarAvgDuration.php +++ b/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarAvgDuration.php @@ -44,7 +44,7 @@ class StatCalendarAvgDuration implements ExportInterface, GroupedExportInterface public function getDescription(): string { - return 'Get the average of calendar duration according to various filters'; + return 'Get the average of appointment duration according to various filters'; } public function getGroup(): string @@ -78,7 +78,7 @@ class StatCalendarAvgDuration implements ExportInterface, GroupedExportInterface public function getTitle(): string { - return 'Average calendar duration'; + return 'Average appointment duration'; } public function getType(): string diff --git a/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarSumDuration.php b/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarSumDuration.php index 4e2ed6a63..51591c670 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarSumDuration.php +++ b/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarSumDuration.php @@ -44,7 +44,7 @@ class StatCalendarSumDuration implements ExportInterface, GroupedExportInterface public function getDescription(): string { - return 'Get the sum of calendar durations according to various filters'; + return 'Get the sum of appointment durations according to various filters'; } public function getGroup(): string @@ -78,7 +78,7 @@ class StatCalendarSumDuration implements ExportInterface, GroupedExportInterface public function getTitle(): string { - return 'Sum of calendar durations'; + return 'Sum of appointment durations'; } public function getType(): string diff --git a/src/Bundle/ChillCalendarBundle/Export/Filter/AgentFilter.php b/src/Bundle/ChillCalendarBundle/Export/Filter/AgentFilter.php index a0b77ece9..fe33c1210 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Filter/AgentFilter.php +++ b/src/Bundle/ChillCalendarBundle/Export/Filter/AgentFilter.php @@ -82,6 +82,6 @@ class AgentFilter implements FilterInterface public function getTitle(): string { - return 'Filter calendars by agent'; + return 'Filter appointments by agent'; } } diff --git a/src/Bundle/ChillCalendarBundle/Export/Filter/BetweenDatesFilter.php b/src/Bundle/ChillCalendarBundle/Export/Filter/BetweenDatesFilter.php index 23e3ac4e6..c3aafc192 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Filter/BetweenDatesFilter.php +++ b/src/Bundle/ChillCalendarBundle/Export/Filter/BetweenDatesFilter.php @@ -66,7 +66,7 @@ class BetweenDatesFilter implements FilterInterface public function describeAction($data, $format = 'string'): array { - return ['Filtered by calendars between %dateFrom% and %dateTo%', [ + return ['Filtered by appointments between %dateFrom% and %dateTo%', [ '%dateFrom%' => $data['date_from']->format('d-m-Y'), '%dateTo%' => $data['date_to']->format('d-m-Y'), ]]; @@ -74,6 +74,6 @@ class BetweenDatesFilter implements FilterInterface public function getTitle(): string { - return 'Filter calendars between certain dates'; + return 'Filter appointments between certain dates'; } } diff --git a/src/Bundle/ChillCalendarBundle/Export/Filter/JobFilter.php b/src/Bundle/ChillCalendarBundle/Export/Filter/JobFilter.php index d5a70b3da..9248143c7 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Filter/JobFilter.php +++ b/src/Bundle/ChillCalendarBundle/Export/Filter/JobFilter.php @@ -95,6 +95,6 @@ class JobFilter implements FilterInterface public function getTitle(): string { - return 'Filter calendars by agent job'; + return 'Filter appointments by agent job'; } } diff --git a/src/Bundle/ChillCalendarBundle/Export/Filter/ScopeFilter.php b/src/Bundle/ChillCalendarBundle/Export/Filter/ScopeFilter.php index 9f12cbf19..10e9e699c 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Filter/ScopeFilter.php +++ b/src/Bundle/ChillCalendarBundle/Export/Filter/ScopeFilter.php @@ -95,6 +95,6 @@ class ScopeFilter implements FilterInterface public function getTitle() { - return 'Filter calendars by agent scope'; + return 'Filter appointments by agent scope'; } } From b0d77a16569626ad54d728553b121c3bb8d6b16c Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Thu, 8 Sep 2022 12:46:15 +0200 Subject: [PATCH 12/41] Revert "adjust property name to make it work with changes calendar bundle" This reverts commit 822b96f87fa2351bac329e0626ec88eed233fb17. --- .../ChillCalendarBundle/Export/Aggregator/AgentAggregator.php | 2 +- .../ChillCalendarBundle/Export/Aggregator/JobAggregator.php | 2 +- .../ChillCalendarBundle/Export/Aggregator/ScopeAggregator.php | 2 +- src/Bundle/ChillCalendarBundle/Export/Filter/AgentFilter.php | 2 +- src/Bundle/ChillCalendarBundle/Export/Filter/JobFilter.php | 2 +- src/Bundle/ChillCalendarBundle/Export/Filter/ScopeFilter.php | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/AgentAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/AgentAggregator.php index 2974fb875..57ec33cdd 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/AgentAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/AgentAggregator.php @@ -41,7 +41,7 @@ final class AgentAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { if (!in_array('caluser', $qb->getAllAliases(), true)) { - $qb->join('cal.mainUser', 'caluser'); + $qb->join('cal.user', 'caluser'); } $qb->addSelect('caluser.id AS agent_aggregator'); diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/JobAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/JobAggregator.php index 46fc6e63d..17905cf35 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/JobAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/JobAggregator.php @@ -41,7 +41,7 @@ final class JobAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { if (!in_array('caluser', $qb->getAllAliases(), true)) { - $qb->join('cal.mainUser', 'caluser'); + $qb->join('cal.user', 'caluser'); } $qb->addSelect('IDENTITY(caluser.userJob) as job_aggregator'); diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/ScopeAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/ScopeAggregator.php index 351451ead..7605c3d5d 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/ScopeAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/ScopeAggregator.php @@ -41,7 +41,7 @@ final class ScopeAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { if (!in_array('caluser', $qb->getAllAliases(), true)) { - $qb->join('cal.mainUser', 'caluser'); + $qb->join('cal.user', 'caluser'); } $qb->addSelect('IDENTITY(caluser.mainScope) as scope_aggregator'); diff --git a/src/Bundle/ChillCalendarBundle/Export/Filter/AgentFilter.php b/src/Bundle/ChillCalendarBundle/Export/Filter/AgentFilter.php index fe33c1210..263b1e160 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Filter/AgentFilter.php +++ b/src/Bundle/ChillCalendarBundle/Export/Filter/AgentFilter.php @@ -37,7 +37,7 @@ class AgentFilter implements FilterInterface public function alterQuery(QueryBuilder $qb, $data) { $where = $qb->getDQLPart('where'); - $clause = $qb->expr()->in('cal.mainUser', ':agents'); + $clause = $qb->expr()->in('cal.user', ':agents'); if ($where instanceof Andx) { $where->add($clause); diff --git a/src/Bundle/ChillCalendarBundle/Export/Filter/JobFilter.php b/src/Bundle/ChillCalendarBundle/Export/Filter/JobFilter.php index 9248143c7..03cd4857d 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Filter/JobFilter.php +++ b/src/Bundle/ChillCalendarBundle/Export/Filter/JobFilter.php @@ -43,7 +43,7 @@ class JobFilter implements FilterInterface public function alterQuery(QueryBuilder $qb, $data) { if (!in_array('caluser', $qb->getAllAliases(), true)) { - $qb->join('cal.mainUser', 'caluser'); + $qb->join('cal.user', 'caluser'); } $where = $qb->getDQLPart('where'); diff --git a/src/Bundle/ChillCalendarBundle/Export/Filter/ScopeFilter.php b/src/Bundle/ChillCalendarBundle/Export/Filter/ScopeFilter.php index 10e9e699c..cbd566e9e 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Filter/ScopeFilter.php +++ b/src/Bundle/ChillCalendarBundle/Export/Filter/ScopeFilter.php @@ -43,7 +43,7 @@ class ScopeFilter implements FilterInterface public function alterQuery(QueryBuilder $qb, $data) { if (!in_array('caluser', $qb->getAllAliases(), true)) { - $qb->join('cal.mainUser', 'caluser'); + $qb->join('cal.user', 'caluser'); } $where = $qb->getDQLPart('where'); From 8cf9bf4a5f82db693d49d508fd03c1013b98757b Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Thu, 8 Sep 2022 12:46:19 +0200 Subject: [PATCH 13/41] Revert "add querybuilder method to repository" This reverts commit ebfb030ba6e377c556b251a3a5c1d592fef18715. --- .../Repository/CalendarRepository.php | 238 +++--------------- 1 file changed, 35 insertions(+), 203 deletions(-) diff --git a/src/Bundle/ChillCalendarBundle/Repository/CalendarRepository.php b/src/Bundle/ChillCalendarBundle/Repository/CalendarRepository.php index 626a9f29f..55fba5f80 100644 --- a/src/Bundle/ChillCalendarBundle/Repository/CalendarRepository.php +++ b/src/Bundle/ChillCalendarBundle/Repository/CalendarRepository.php @@ -12,220 +12,52 @@ declare(strict_types=1); namespace Chill\CalendarBundle\Repository; use Chill\CalendarBundle\Entity\Calendar; -use Chill\MainBundle\Entity\User; -use Chill\PersonBundle\Entity\AccompanyingPeriod; -use DateTimeImmutable; -use Doctrine\DBAL\Types\Types; -use Doctrine\ORM\EntityManagerInterface; +use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\ORM\EntityRepository; -use Doctrine\ORM\Query\ResultSetMapping; -use Doctrine\ORM\QueryBuilder; -use Doctrine\Persistence\ObjectRepository; -use function count; +use Doctrine\Persistence\ManagerRegistry; -class CalendarRepository implements ObjectRepository +/** + * @method Calendar|null find($id, $lockMode = null, $lockVersion = null) + * @method Calendar|null findOneBy(array $criteria, array $orderBy = null) + * @method Calendar[] findAll() + * @method Calendar[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) + */ +class CalendarRepository extends ServiceEntityRepository { - private EntityManagerInterface $em; + // private EntityRepository $repository; - private EntityRepository $repository; - - public function __construct(EntityManagerInterface $entityManager) + public function __construct(ManagerRegistry $registry) { - $this->repository = $entityManager->getRepository(Calendar::class); - $this->em = $entityManager; + parent::__construct($registry, Calendar::class); + // $this->repository = $entityManager->getRepository(AccompanyingPeriodWork::class); } - public function countByAccompanyingPeriod(AccompanyingPeriod $period): int + // /** + // * @return Calendar[] Returns an array of Calendar objects + // */ + /* + public function findByExampleField($value) { - return $this->repository->count(['accompanyingPeriod' => $period]); - } - - public function createQueryBuilder(string $alias, ?string $indexBy = null): QueryBuilder - { - return $this->repository->createQueryBuilder($alias, $indexBy); - } - - public function countByUser(User $user, DateTimeImmutable $from, DateTimeImmutable $to): int - { - return $this->buildQueryByUser($user, $from, $to) - ->select('COUNT(c)') + return $this->createQueryBuilder('c') + ->andWhere('c.exampleField = :val') + ->setParameter('val', $value) + ->orderBy('c.id', 'ASC') + ->setMaxResults(10) ->getQuery() - ->getSingleScalarResult(); + ->getResult() + ; } - - public function find($id): ?Calendar - { - return $this->repository->find($id); - } - - /** - * @return array|Calendar[] */ - public function findAll(): array - { - return $this->repository->findAll(); - } - /** - * @return array|Calendar[] + /* + public function findOneBySomeField($value): ?Calendar + { + return $this->createQueryBuilder('c') + ->andWhere('c.exampleField = :val') + ->setParameter('val', $value) + ->getQuery() + ->getOneOrNullResult() + ; + } */ - public function findBy(array $criteria, ?array $orderBy = null, ?int $limit = null, ?int $offset = null): array - { - return $this->repository->findBy($criteria, $orderBy, $limit, $offset); - } - - /** - * @return array|Calendar[] - */ - public function findByAccompanyingPeriod(AccompanyingPeriod $period, ?array $orderBy = null, ?int $limit = null, ?int $offset = null): array - { - return $this->findBy( - [ - 'accompanyingPeriod' => $period, - ], - $orderBy, - $limit, - $orderBy - ); - } - - public function findByNotificationAvailable(DateTimeImmutable $startDate, DateTimeImmutable $endDate, ?int $limit = null, ?int $offset = null): array - { - $qb = $this->queryByNotificationAvailable($startDate, $endDate)->select('c'); - - if (null !== $limit) { - $qb->setMaxResults($limit); - } - - if (null !== $offset) { - $qb->setFirstResult($offset); - } - - return $qb->getQuery()->getResult(); - } - - /** - * @return array|Calendar[] - */ - public function findByUser(User $user, DateTimeImmutable $from, DateTimeImmutable $to, ?int $limit = null, ?int $offset = null): array - { - $qb = $this->buildQueryByUser($user, $from, $to)->select('c'); - - if (null !== $limit) { - $qb->setMaxResults($limit); - } - - if (null !== $offset) { - $qb->setFirstResult($offset); - } - - return $qb->getQuery()->getResult(); - } - - public function findOneBy(array $criteria): ?Calendar - { - return $this->repository->findOneBy($criteria); - } - - /** - * Given a list of remote ids, return an array where - * keys are the remoteIds, and value is a boolean, true if the - * id is present in database. - * - * @param array|list $remoteIds - * - * @return array - */ - public function findRemoteIdsPresent(array $remoteIds): array - { - if (0 === count($remoteIds)) { - return []; - } - - $remoteIdsStr = implode( - ', ', - array_fill(0, count($remoteIds), '((?))') - ); - - $sql = "SELECT - sq.remoteId as remoteid, - EXISTS (SELECT 1 FROM chill_calendar.calendar c WHERE c.remoteId = sq.remoteId) AS present - FROM - ( - VALUES {$remoteIdsStr} - ) AS sq(remoteId); - "; - - $rsm = new ResultSetMapping(); - $rsm - ->addScalarResult('remoteid', 'remoteId', Types::STRING) - ->addScalarResult('present', 'present', Types::BOOLEAN); - - $rows = $this->em - ->createNativeQuery( - $sql, - $rsm - ) - ->setParameters(array_values($remoteIds)) - ->getResult(); - - $results = []; - - foreach ($rows as $r) { - $results[$r['remoteId']] = $r['present']; - } - - return $results; - } - - public function getClassName() - { - return Calendar::class; - } - - private function buildQueryByUser(User $user, DateTimeImmutable $from, DateTimeImmutable $to): QueryBuilder - { - $qb = $this->repository->createQueryBuilder('c'); - - return $qb - ->where( - $qb->expr()->andX( - $qb->expr()->eq('c.mainUser', ':user'), - $qb->expr()->gte('c.startDate', ':startDate'), - $qb->expr()->lte('c.endDate', ':endDate'), - ) - ) - ->setParameters([ - 'user' => $user, - 'startDate' => $from, - 'endDate' => $to, - ]); - } - - private function queryByNotificationAvailable(DateTimeImmutable $startDate, DateTimeImmutable $endDate): QueryBuilder - { - $qb = $this->repository->createQueryBuilder('c'); - - $qb->where( - $qb->expr()->andX( - $qb->expr()->eq('c.sendSMS', ':true'), - $qb->expr()->gte('c.startDate', ':startDate'), - $qb->expr()->lt('c.startDate', ':endDate'), - $qb->expr()->orX( - $qb->expr()->eq('c.smsStatus', ':pending'), - $qb->expr()->eq('c.smsStatus', ':cancel_pending') - ) - ) - ); - - $qb->setParameters([ - 'true' => true, - 'startDate' => $startDate, - 'endDate' => $endDate, - 'pending' => Calendar::SMS_PENDING, - 'cancel_pending' => Calendar::SMS_CANCEL_PENDING, - ]); - - return $qb; - } } From 0a0a692eae24864d640efe489163c6398dc7d1e0 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Thu, 8 Sep 2022 12:46:23 +0200 Subject: [PATCH 14/41] Revert "rename files for coherence with naming elsewhere" This reverts commit ff5fab5f502efabd4547c870368641877b31d0bd. --- .../Resources/config/services/exports.yaml | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Bundle/ChillCalendarBundle/Resources/config/services/exports.yaml b/src/Bundle/ChillCalendarBundle/Resources/config/services/exports.yaml index a7508f3b5..56580dba1 100644 --- a/src/Bundle/ChillCalendarBundle/Resources/config/services/exports.yaml +++ b/src/Bundle/ChillCalendarBundle/Resources/config/services/exports.yaml @@ -1,26 +1,26 @@ services: ## Indicators - chill.calendar.export.count_calendars: - class: Chill\CalendarBundle\Export\Export\CountCalendars + chill.calendar.export.count_appointments: + class: Chill\CalendarBundle\Export\Export\CountAppointments autowire: true autoconfigure: true tags: - - { name: chill.export, alias: count_calendars } + - { name: chill.export, alias: count_appointments } - chill.calendar.export.average_duration_calendars: - class: Chill\CalendarBundle\Export\Export\StatCalendarAvgDuration + chill.calendar.export.average_duration_appointments: + class: Chill\CalendarBundle\Export\Export\StatAppointmentAvgDuration autowire: true autoconfigure: true tags: - - { name: chill.export, alias: average_duration_calendars } + - { name: chill.export, alias: average_duration_appointments } - chill.calendar.export.sum_duration_calendars: - class: Chill\CalendarBundle\Export\Export\StatCalendarSumDuration + chill.calendar.export.sum_duration_appointments: + class: Chill\CalendarBundle\Export\Export\StatAppointmentSumDuration autowire: true autoconfigure: true tags: - - { name: chill.export, alias: sum_duration_calendars } + - { name: chill.export, alias: sum_duration_appointments } ## Filters @@ -101,4 +101,4 @@ services: autowire: true autoconfigure: true tags: - - { name: chill.export_aggregator, alias: month_aggregator } + - { name: chill.export_aggregator, alias: month_aggregator } \ No newline at end of file From d81afb89f26eeeb99665bb8e1d06b91520c43433 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Thu, 8 Sep 2022 12:48:19 +0200 Subject: [PATCH 15/41] Revert "rename files for coherence with naming elsewhere" This reverts commit 5f2622d0d2fd7b10a4bb79ce1026f46f07b5f38c. --- .../Export/{CountCalendars.php => CountAppointments.php} | 3 ++- ...tCalendarAvgDuration.php => StatAppointmentAvgDuration.php} | 2 +- ...tCalendarSumDuration.php => StatAppointmentSumDuration.php} | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) rename src/Bundle/ChillCalendarBundle/Export/Export/{CountCalendars.php => CountAppointments.php} (95%) rename src/Bundle/ChillCalendarBundle/Export/Export/{StatCalendarAvgDuration.php => StatAppointmentAvgDuration.php} (96%) rename src/Bundle/ChillCalendarBundle/Export/Export/{StatCalendarSumDuration.php => StatAppointmentSumDuration.php} (96%) diff --git a/src/Bundle/ChillCalendarBundle/Export/Export/CountCalendars.php b/src/Bundle/ChillCalendarBundle/Export/Export/CountAppointments.php similarity index 95% rename from src/Bundle/ChillCalendarBundle/Export/Export/CountCalendars.php rename to src/Bundle/ChillCalendarBundle/Export/Export/CountAppointments.php index edf654a10..b9da17114 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Export/CountCalendars.php +++ b/src/Bundle/ChillCalendarBundle/Export/Export/CountAppointments.php @@ -22,8 +22,9 @@ use Doctrine\ORM\AbstractQuery; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Process\Exception\LogicException; +use Symfony\Component\Security\Core\Role\Role; -class CountCalendars implements ExportInterface, GroupedExportInterface +class CountAppointments implements ExportInterface, GroupedExportInterface { private CalendarRepository $calendarRepository; diff --git a/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarAvgDuration.php b/src/Bundle/ChillCalendarBundle/Export/Export/StatAppointmentAvgDuration.php similarity index 96% rename from src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarAvgDuration.php rename to src/Bundle/ChillCalendarBundle/Export/Export/StatAppointmentAvgDuration.php index 51e94a288..491cb38b9 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarAvgDuration.php +++ b/src/Bundle/ChillCalendarBundle/Export/Export/StatAppointmentAvgDuration.php @@ -22,7 +22,7 @@ use Doctrine\ORM\QueryBuilder; use LogicException; use Symfony\Component\Form\FormBuilderInterface; -class StatCalendarAvgDuration implements ExportInterface, GroupedExportInterface +class StatAppointmentAvgDuration implements ExportInterface, GroupedExportInterface { private CalendarRepository $calendarRepository; diff --git a/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarSumDuration.php b/src/Bundle/ChillCalendarBundle/Export/Export/StatAppointmentSumDuration.php similarity index 96% rename from src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarSumDuration.php rename to src/Bundle/ChillCalendarBundle/Export/Export/StatAppointmentSumDuration.php index 51591c670..286c73be5 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarSumDuration.php +++ b/src/Bundle/ChillCalendarBundle/Export/Export/StatAppointmentSumDuration.php @@ -22,7 +22,7 @@ use Doctrine\ORM\QueryBuilder; use LogicException; use Symfony\Component\Form\FormBuilderInterface; -class StatCalendarSumDuration implements ExportInterface, GroupedExportInterface +class StatAppointmentSumDuration implements ExportInterface, GroupedExportInterface { private CalendarRepository $calendarRepository; From 661e5458ee9a376f85610a5b6420f98ba3e09b65 Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Thu, 8 Sep 2022 14:17:17 +0200 Subject: [PATCH 16/41] bam --- src/Bundle/ChillPersonBundle/translations/messages.fr.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index 70a0cda42..98facddf9 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -552,6 +552,7 @@ Group by treating agent: Grouper les actions par agent traitant Group social work actions by action type: Grouper les actions par type Group social work actions by goal: Grouper les actions par objectif +Goal Type: Objectif Group social work actions by result: Grouper les actions par résultat ## evaluations filters/aggr From eafe68973ac13ad06c8a07e352cb3cd7f25217ae Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Thu, 8 Sep 2022 14:35:48 +0200 Subject: [PATCH 17/41] [bug] Temporary bypass Vue component --- .../ChillMainBundle/Resources/views/Export/new.html.twig | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Bundle/ChillMainBundle/Resources/views/Export/new.html.twig b/src/Bundle/ChillMainBundle/Resources/views/Export/new.html.twig index c6adb241d..8bab23d21 100644 --- a/src/Bundle/ChillMainBundle/Resources/views/Export/new.html.twig +++ b/src/Bundle/ChillMainBundle/Resources/views/Export/new.html.twig @@ -23,7 +23,13 @@ {% block js %} {{ encore_entry_script_tags('page_export') }} {% if export_alias == 'count_social_work_actions' %} + {# + TODO: [debug] comprendre pq l'activation du composant Vue bloque le passage de + http://localhost:8001/fr/exports/new/count_social_work_actions?step=export + vers http://localhost:8001/fr/exports/new/count_social_work_actions?step=formatter + {{ encore_entry_script_tags('vue_form_action_goal_result') }} + #} {% endif %} {% endblock js %} From ef7a388f384ea891f044d3517596b30c1e9747de Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Tue, 13 Sep 2022 12:37:25 +0200 Subject: [PATCH 18/41] exports: fix resetDQLPart('from') issue (632) https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/632 --- exports_alias_conventions.csv | 10 +++---- exports_alias_conventions.md | 10 +++---- .../HouseholdPositionAggregator.php | 30 ++++++++++--------- .../ActivityTypeFilter.php | 12 +++----- .../ResidentialAddressAtThirdpartyFilter.php | 12 ++++---- .../ResidentialAddressAtUserFilter.php | 13 ++++---- 6 files changed, 39 insertions(+), 48 deletions(-) diff --git a/exports_alias_conventions.csv b/exports_alias_conventions.csv index 1215479d8..a835c383a 100644 --- a/exports_alias_conventions.csv +++ b/exports_alias_conventions.csv @@ -23,17 +23,15 @@ Goal::class,,,goal ,Result::class,goal.results,goalresult Person::class,,,person ,Center::class,person.center,center -,HouseholdMember::class,partperson.householdParticipations,member +,HouseholdMember::class,partperson.householdParticipations,householdmember ,MaritalStatus::class,person.maritalStatus,personmarital ResidentialAddress::class,,,resaddr -,Person::class,resaddr.person,resaddrperson -,Center::class,resaddrperson.center,resaddrcenter ,ThirdParty::class,resaddr.hostThirdParty,tparty ThirdParty::class,,,tparty ,ThirdPartyCategory::class,tparty.categories,tpartycat -HouseholdMember::class,,,member -,Household::class,member.household,household -,Person::class,member.person,memberperson +HouseholdMember::class,,,householdmember +,Household::class,householdmember.household,household +,Person::class,householdmember.person,memberperson ,,memberperson.center,membercenter Household::class,,,household ,HouseholdComposition::class,household.compositions,composition diff --git a/exports_alias_conventions.md b/exports_alias_conventions.md index 85973eec1..404156bff 100644 --- a/exports_alias_conventions.md +++ b/exports_alias_conventions.md @@ -31,17 +31,15 @@ These are alias conventions : | | Result::class | goal.results | goalresult | | Person::class | | | person | | | Center::class | person.center | center | -| | HouseholdMember::class | partperson.householdParticipations | member | +| | HouseholdMember::class | partperson.householdParticipations | householdmember | | | MaritalStatus::class | person.maritalStatus | personmarital | | ResidentialAddress::class | | | resaddr | -| | Person::class | resaddr.person | resaddrperson | -| | Center::class | resaddrperson.center | resaddrcenter | | | ThirdParty::class | resaddr.hostThirdParty | tparty | | ThirdParty::class | | | tparty | | | ThirdPartyCategory::class | tparty.categories | tpartycat | -| HouseholdMember::class | | | member | -| | Household::class | member.household | household | -| | Person::class | member.person | memberperson | +| HouseholdMember::class | | | householdmember | +| | Household::class | householdmember.household | household | +| | Person::class | householdmember.person | memberperson | | | | memberperson.center | membercenter | | Household::class | | | household | | | HouseholdComposition::class | household.compositions | composition | diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/HouseholdPositionAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/HouseholdPositionAggregator.php index c0b52053d..89c0bb8f5 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/HouseholdPositionAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/HouseholdPositionAggregator.php @@ -16,8 +16,10 @@ use Chill\MainBundle\Export\ExportElementValidatedInterface; use Chill\MainBundle\Form\Type\ChillDateType; use Chill\MainBundle\Templating\TranslatableStringHelper; use Chill\PersonBundle\Entity\Household\HouseholdMember; +use Chill\PersonBundle\Export\Declarations; use Chill\PersonBundle\Repository\Household\PositionRepository; use DateTime; +use Doctrine\ORM\Query\Expr; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Validator\Context\ExecutionContextInterface; @@ -31,8 +33,11 @@ final class HouseholdPositionAggregator implements AggregatorInterface, ExportEl private TranslatorInterface $translator; - public function __construct(TranslatorInterface $translator, TranslatableStringHelper $translatableStringHelper, PositionRepository $positionRepository) - { + public function __construct( + TranslatorInterface $translator, + TranslatableStringHelper $translatableStringHelper, + PositionRepository $positionRepository + ) { $this->translator = $translator; $this->positionRepository = $positionRepository; $this->translatableStringHelper = $translatableStringHelper; @@ -45,28 +50,25 @@ final class HouseholdPositionAggregator implements AggregatorInterface, ExportEl public function alterQuery(QueryBuilder $qb, $data) { - $qb->resetDQLPart('from'); - $qb->from(HouseholdMember::class, 'member'); - - if (!in_array('memberperson', $qb->getAllAliases(), true)) { - $qb->join('member.person', 'memberperson'); + if (!in_array('householdmember', $qb->getAllAliases(), true)) { + $qb->join(HouseholdMember::class, 'householdmember', Expr\Join::WITH, 'householdmember.person = person'); } - if (!in_array('membercenter', $qb->getAllAliases(), true)) { - $qb->join('memberperson.center', 'membercenter'); + if (!in_array('center', $qb->getAllAliases(), true)) { + $qb->join('person.center', 'center'); } $qb->andWhere($qb->expr()->andX( - $qb->expr()->lte('member.startDate', ':date'), + $qb->expr()->lte('householdmember.startDate', ':date'), $qb->expr()->orX( - $qb->expr()->isNull('member.endDate'), - $qb->expr()->gte('member.endDate', ':date') + $qb->expr()->isNull('householdmember.endDate'), + $qb->expr()->gte('householdmember.endDate', ':date') ) )); $qb->setParameter('date', $data['date_position']); - $qb->addSelect('IDENTITY(member.position) AS household_position_aggregator'); + $qb->addSelect('IDENTITY(householdmember.position) AS household_position_aggregator'); $groupBy = $qb->getDQLPart('groupBy'); @@ -79,7 +81,7 @@ final class HouseholdPositionAggregator implements AggregatorInterface, ExportEl public function applyOn() { - return 'person'; + return Declarations::PERSON_TYPE; } public function buildForm(FormBuilderInterface $builder) diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ActivityTypeFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ActivityTypeFilter.php index f76a00c33..fab99df5f 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ActivityTypeFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ActivityTypeFilter.php @@ -11,10 +11,12 @@ declare(strict_types=1); namespace Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters; +use Chill\ActivityBundle\Entity\Activity; use Chill\ActivityBundle\Entity\ActivityType; use Chill\MainBundle\Export\FilterInterface; use Chill\MainBundle\Templating\TranslatableStringHelper; use Chill\PersonBundle\Export\Declarations; +use Doctrine\ORM\Query\Expr; use Doctrine\ORM\Query\Expr\Andx; use Doctrine\ORM\QueryBuilder; use Symfony\Bridge\Doctrine\Form\Type\EntityType; @@ -39,14 +41,8 @@ class ActivityTypeFilter implements FilterInterface 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', 'activity'); - - if (!in_array('actacp', $qb->getAllAliases(), true)) { - $qb->join('activity.accompanyingPeriod', 'actacp'); + if (!in_array('activity', $qb->getAllAliases(), true)) { + $qb->join(Activity::class, 'activity', Expr\Join::WITH, 'activity.accompanyingPeriod = acp'); } if (!in_array('acttype', $qb->getAllAliases(), true)) { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ResidentialAddressAtThirdpartyFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ResidentialAddressAtThirdpartyFilter.php index 73c551286..c38ce6a5b 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ResidentialAddressAtThirdpartyFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ResidentialAddressAtThirdpartyFilter.php @@ -14,6 +14,7 @@ namespace Chill\PersonBundle\Export\Filter\PersonFilters; use Chill\MainBundle\Export\FilterInterface; use Chill\MainBundle\Form\Type\ChillDateType; use Chill\MainBundle\Templating\TranslatableStringHelper; +use Chill\PersonBundle\Entity\Person\ResidentialAddress; use Chill\PersonBundle\Export\Declarations; use Chill\ThirdPartyBundle\Entity\ThirdPartyCategory; use DateTime; @@ -38,15 +39,12 @@ class ResidentialAddressAtThirdpartyFilter implements FilterInterface public function alterQuery(QueryBuilder $qb, $data) { - $qb->resetDQLPart('from'); - $qb->from('ChillPersonBundle:Person\ResidentialAddress', 'resaddr'); - - if (!in_array('resaddrperson', $qb->getAllAliases(), true)) { - $qb->join('resaddr.person', 'resaddrperson'); + if (!in_array('resaddr', $qb->getAllAliases(), true)) { + $qb->join(ResidentialAddress::class, 'resaddr', Expr\Join::WITH, 'resaddr.person = person'); } - if (!in_array('resaddrcenter', $qb->getAllAliases(), true)) { - $qb->join('resaddrperson.center', 'resaddrcenter'); + if (!in_array('center', $qb->getAllAliases(), true)) { + $qb->join('person.center', 'center'); } if (!in_array('tparty', $qb->getAllAliases(), true)) { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ResidentialAddressAtUserFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ResidentialAddressAtUserFilter.php index 5e78e574e..48275eb12 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ResidentialAddressAtUserFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ResidentialAddressAtUserFilter.php @@ -12,7 +12,9 @@ declare(strict_types=1); namespace Chill\PersonBundle\Export\Filter\PersonFilters; use Chill\MainBundle\Export\FilterInterface; +use Chill\PersonBundle\Entity\Person\ResidentialAddress; use Chill\PersonBundle\Export\Declarations; +use Doctrine\ORM\Query\Expr; use Doctrine\ORM\Query\Expr\Andx; use Doctrine\ORM\QueryBuilder; @@ -25,15 +27,12 @@ class ResidentialAddressAtUserFilter implements FilterInterface public function alterQuery(QueryBuilder $qb, $data) { - $qb->resetDQLPart('from'); - $qb->from('ChillPersonBundle:Person\ResidentialAddress', 'resaddr'); - - if (!in_array('resaddrperson', $qb->getAllAliases(), true)) { - $qb->join('resaddr.person', 'resaddrperson'); + if (!in_array('resaddr', $qb->getAllAliases(), true)) { + $qb->join(ResidentialAddress::class, 'resaddr', Expr\Join::WITH, 'resaddr.person = person'); } - if (!in_array('resaddrcenter', $qb->getAllAliases(), true)) { - $qb->join('resaddrperson.center', 'resaddrcenter'); + if (!in_array('center', $qb->getAllAliases(), true)) { + $qb->join('person.center', 'center'); } $where = $qb->getDQLPart('where'); From 42ea1f581319f33ffa27f0bb652096a96c4efb19 Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Tue, 13 Sep 2022 11:12:42 +0200 Subject: [PATCH 19/41] exports: better lisibility of exports index page --- .../ChillMainBundle/Resources/public/chill/chillmain.scss | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Bundle/ChillMainBundle/Resources/public/chill/chillmain.scss b/src/Bundle/ChillMainBundle/Resources/public/chill/chillmain.scss index f8bd42442..5c302bf83 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/chill/chillmain.scss +++ b/src/Bundle/ChillMainBundle/Resources/public/chill/chillmain.scss @@ -517,3 +517,9 @@ div.popover { div.v-toast { z-index: 10000!important; } + +div.grouped { + padding: 1em; + border: 1px solid black; + margin-bottom: 2em; +} \ No newline at end of file From d85be8a92eba9257500366c5eaa3531901602722 Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Tue, 13 Sep 2022 13:09:40 +0200 Subject: [PATCH 20/41] update exports_alias_conventions --- exports_alias_conventions.csv | 7 +- exports_alias_conventions.md | 131 +++++++++++++++++----------------- 2 files changed, 66 insertions(+), 72 deletions(-) diff --git a/exports_alias_conventions.csv b/exports_alias_conventions.csv index a835c383a..4b791463a 100644 --- a/exports_alias_conventions.csv +++ b/exports_alias_conventions.csv @@ -25,6 +25,8 @@ Person::class,,,person ,Center::class,person.center,center ,HouseholdMember::class,partperson.householdParticipations,householdmember ,MaritalStatus::class,person.maritalStatus,personmarital +,VendeePerson::class,,vp +,VendeePersonMineur::class,,vpm ResidentialAddress::class,,,resaddr ,ThirdParty::class,resaddr.hostThirdParty,tparty ThirdParty::class,,,tparty @@ -56,11 +58,6 @@ Calendar::class,,,cal ,Location::class,cal.location,calloc ,User::class,cal.user,caluser VendeePerson::class,,,vp -,Person::class,vp.person,vpperson -,Center::class,vpperson.center,vpcenter ,SituationProfessionelle::class,vp.situationProfessionelle,vpprof ,StatutLogement::class,vp.statutLogement,vplog ,TempsDeTravail::class,vp.tempsDeTravail,vptt -VendeePersonMineur::class,,,vpm -,Person::class,vpm.person,vpmperson -,Center::class,vpmperson.center,vpmcenter diff --git a/exports_alias_conventions.md b/exports_alias_conventions.md index 404156bff..f2dbb481e 100644 --- a/exports_alias_conventions.md +++ b/exports_alias_conventions.md @@ -5,70 +5,67 @@ Add condition with distinct alias on each export join clauses (Indicators + Filt These are alias conventions : -| Entity | Join | Attribute | Alias | -| :--- | :--- |:-------------------------------------------|:----------------------------------| -| AccompanyingPeriod::class | | | acp | -| | AccompanyingPeriodWork::class | acp.works | acpw | -| | AccompanyingPeriodParticipation::class | acp.participations | acppart | -| | Location::class | acp.administrativeLocation | acploc | -| | ClosingMotive::class | acp.closingMotive | acpmotive | -| | UserJob::class | acp.job | acpjob | -| | Origin::class | acp.origin | acporigin | -| | Scope::class | acp.scopes | acpscope | -| | SocialIssue::class | acp.socialIssues | acpsocialissue | -| | User::class | acp.user | acpuser | -| AccompanyingPeriodWork::class | | | acpw | -| | AccompanyingPeriodWorkEvaluation::class | acpw.accompanyingPeriodWorkEvaluations | workeval | -| | Goal::class | acpw.goals | goal | -| | User::class | acpw.referrers | acpwuser | -| | Result::class | acpw.results | acpwresult | -| | SocialAction::class | acpw.socialAction | acpwsocialaction | -| AccompanyingPeriodParticipation::class | | | acppart | -| | Person::class | acppart.person | partperson | -| AccompanyingPeriodWorkEvaluation::class | | | workeval | -| | Evaluation::class | workeval.evaluation | eval | -| Goal::class | | | goal | -| | Result::class | goal.results | goalresult | -| Person::class | | | person | -| | Center::class | person.center | center | -| | HouseholdMember::class | partperson.householdParticipations | householdmember | -| | MaritalStatus::class | person.maritalStatus | personmarital | -| ResidentialAddress::class | | | resaddr | -| | ThirdParty::class | resaddr.hostThirdParty | tparty | -| ThirdParty::class | | | tparty | -| | ThirdPartyCategory::class | tparty.categories | tpartycat | -| HouseholdMember::class | | | householdmember | -| | Household::class | householdmember.household | household | -| | Person::class | householdmember.person | memberperson | -| | | memberperson.center | membercenter | -| Household::class | | | household | -| | HouseholdComposition::class | household.compositions | composition | -| Activity::class | | | activity | -| | Person::class | activity.person | actperson | -| | AccompanyingPeriod::class | activity.accompanyingPeriod | actacp | -| | Person::class | activity\_person\_having\_activity.person | person\_person\_having\_activity | -| | ActivityReason::class | activity\_person\_having\_activity.reasons | reasons\_person\_having\_activity | -| | ActivityType::class | activity.activityType | acttype | -| | Location::class | activity.location | actloc | -| | SocialAction::class | activity.socialActions | actsocialaction | -| | SocialIssue::class | activity.socialIssues | actsocialssue | -| | ThirdParty::class | activity.thirdParties | acttparty | -| | User::class | activity.user | actuser | -| | User::class | activity.users | actusers | -| | ActivityReason::class | activity.reasons | actreasons | -| | Center::class | actperson.center | actcenter | -| ActivityReason::class | | | actreasons | -| | ActivityReasonCategory::class | actreason.category | actreasoncat | -| Calendar::class | | | cal | -| | CancelReason::class | cal.cancelReason | calcancel | -| | Location::class | cal.location | calloc | -| | User::class | cal.user | caluser | -| VendeePerson::class | | | vp | -| | Person::class | vp.person | vpperson | -| | Center::class | vpperson.center | vpcenter | -| | SituationProfessionelle::class | vp.situationProfessionelle | vpprof | -| | StatutLogement::class | vp.statutLogement | vplog | -| | TempsDeTravail::class | vp.tempsDeTravail | vptt | -| VendeePersonMineur::class | | | vpm | -| | Person::class | vpm.person | vpmperson | -| | Center::class | vpmperson.center | vpmcenter | +| Entity | Join | Attribute | Alias | +|:----------------------------------------|:----------------------------------------|:-------------------------------------------|:----------------------------------| +| AccompanyingPeriod::class | | | acp | +| | AccompanyingPeriodWork::class | acp.works | acpw | +| | AccompanyingPeriodParticipation::class | acp.participations | acppart | +| | Location::class | acp.administrativeLocation | acploc | +| | ClosingMotive::class | acp.closingMotive | acpmotive | +| | UserJob::class | acp.job | acpjob | +| | Origin::class | acp.origin | acporigin | +| | Scope::class | acp.scopes | acpscope | +| | SocialIssue::class | acp.socialIssues | acpsocialissue | +| | User::class | acp.user | acpuser | +| AccompanyingPeriodWork::class | | | acpw | +| | AccompanyingPeriodWorkEvaluation::class | acpw.accompanyingPeriodWorkEvaluations | workeval | +| | Goal::class | acpw.goals | goal | +| | User::class | acpw.referrers | acpwuser | +| | Result::class | acpw.results | acpwresult | +| | SocialAction::class | acpw.socialAction | acpwsocialaction | +| AccompanyingPeriodParticipation::class | | | acppart | +| | Person::class | acppart.person | partperson | +| AccompanyingPeriodWorkEvaluation::class | | | workeval | +| | Evaluation::class | workeval.evaluation | eval | +| Goal::class | | | goal | +| | Result::class | goal.results | goalresult | +| Person::class | | | person | +| | Center::class | person.center | center | +| | HouseholdMember::class | partperson.householdParticipations | householdmember | +| | MaritalStatus::class | person.maritalStatus | personmarital | +| | VendeePerson::class | | vp | +| | VendeePersonMineur::class | | vpm | +| ResidentialAddress::class | | | resaddr | +| | ThirdParty::class | resaddr.hostThirdParty | tparty | +| ThirdParty::class | | | tparty | +| | ThirdPartyCategory::class | tparty.categories | tpartycat | +| HouseholdMember::class | | | householdmember | +| | Household::class | householdmember.household | household | +| | Person::class | householdmember.person | memberperson | +| | | memberperson.center | membercenter | +| Household::class | | | household | +| | HouseholdComposition::class | household.compositions | composition | +| Activity::class | | | activity | +| | Person::class | activity.person | actperson | +| | AccompanyingPeriod::class | activity.accompanyingPeriod | actacp | +| | Person::class | activity\_person\_having\_activity.person | person\_person\_having\_activity | +| | ActivityReason::class | activity\_person\_having\_activity.reasons | reasons\_person\_having\_activity | +| | ActivityType::class | activity.activityType | acttype | +| | Location::class | activity.location | actloc | +| | SocialAction::class | activity.socialActions | actsocialaction | +| | SocialIssue::class | activity.socialIssues | actsocialssue | +| | ThirdParty::class | activity.thirdParties | acttparty | +| | User::class | activity.user | actuser | +| | User::class | activity.users | actusers | +| | ActivityReason::class | activity.reasons | actreasons | +| | Center::class | actperson.center | actcenter | +| ActivityReason::class | | | actreasons | +| | ActivityReasonCategory::class | actreason.category | actreasoncat | +| Calendar::class | | | cal | +| | CancelReason::class | cal.cancelReason | calcancel | +| | Location::class | cal.location | calloc | +| | User::class | cal.user | caluser | +| VendeePerson::class | | | vp | +| | SituationProfessionelle::class | vp.situationProfessionelle | vpprof | +| | StatutLogement::class | vp.statutLogement | vplog | +| | TempsDeTravail::class | vp.tempsDeTravail | vptt | From 18a6a5a7ebeefc5999d16f7a3edf9bf89ba8e9e8 Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Tue, 13 Sep 2022 13:27:24 +0200 Subject: [PATCH 21/41] exports: move acp ActivityType filter in ChillActivityBundle --- .../Export/Filter/ACPFilters}/ActivityTypeFilter.php | 2 +- src/Bundle/ChillActivityBundle/config/services/export.yaml | 5 +++++ .../config/services/exports_accompanying_course.yaml | 7 ------- 3 files changed, 6 insertions(+), 8 deletions(-) rename src/Bundle/{ChillPersonBundle/Export/Filter/AccompanyingCourseFilters => ChillActivityBundle/Export/Filter/ACPFilters}/ActivityTypeFilter.php (97%) diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ActivityTypeFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/ActivityTypeFilter.php similarity index 97% rename from src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ActivityTypeFilter.php rename to src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/ActivityTypeFilter.php index fab99df5f..7c0b202bd 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ActivityTypeFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/ActivityTypeFilter.php @@ -9,7 +9,7 @@ declare(strict_types=1); -namespace Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters; +namespace Chill\ActivityBundle\Export\Filter\ACPFilters; use Chill\ActivityBundle\Entity\Activity; use Chill\ActivityBundle\Entity\ActivityType; diff --git a/src/Bundle/ChillActivityBundle/config/services/export.yaml b/src/Bundle/ChillActivityBundle/config/services/export.yaml index c88046c5f..9abf33487 100644 --- a/src/Bundle/ChillActivityBundle/config/services/export.yaml +++ b/src/Bundle/ChillActivityBundle/config/services/export.yaml @@ -67,6 +67,11 @@ services: name: chill.export_filter alias: 'activity_person_having_ac_bw_date_filter' + chill.person.export.filter_activitytype: + class: Chill\ActivityBundle\Export\Filter\ACPFilters\ActivityTypeFilter + tags: + - { name: chill.export_filter, alias: accompanyingcourse_activitytype_filter } + chill.activity.export.locationtype_filter: class: Chill\ActivityBundle\Export\Filter\ACPFilters\LocationTypeFilter tags: diff --git a/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_course.yaml b/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_course.yaml index 73bd1cce3..f19db0649 100644 --- a/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_course.yaml +++ b/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_course.yaml @@ -65,13 +65,6 @@ services: tags: - { name: chill.export_filter, alias: accompanyingcourse_evaluation_filter } - chill.person.export.filter_activitytype: - class: Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\ActivityTypeFilter - autowire: true - autoconfigure: true - tags: - - { name: chill.export_filter, alias: accompanyingcourse_activitytype_filter } - chill.person.export.filter_origin: class: Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\OriginFilter autowire: true From 6c29638fed8ba23f37e77e6b1eb0614eef68e18c Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Tue, 13 Sep 2022 14:54:36 +0200 Subject: [PATCH 22/41] exports: fix export_result cell if null (issue 628) https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/628 --- .../ChillMainBundle/Export/Formatter/SpreadSheetFormatter.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Bundle/ChillMainBundle/Export/Formatter/SpreadSheetFormatter.php b/src/Bundle/ChillMainBundle/Export/Formatter/SpreadSheetFormatter.php index 86c304508..6d6a685b7 100644 --- a/src/Bundle/ChillMainBundle/Export/Formatter/SpreadSheetFormatter.php +++ b/src/Bundle/ChillMainBundle/Export/Formatter/SpreadSheetFormatter.php @@ -230,7 +230,8 @@ class SpreadSheetFormatter implements FormatterInterface $worksheet->fromArray( $sortedResults, null, - 'A' . $line + 'A' . $line, + true ); return $line + count($sortedResults) + 1; From 9b1e464011247b03958013d6ee16080df739e388 Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Wed, 14 Sep 2022 09:38:12 +0200 Subject: [PATCH 23/41] fix form error in App.vue (does not POST from step=export to step=formatter) --- .../Resources/public/vuejs/FormActionGoalResult/App.vue | 3 --- .../ChillMainBundle/Resources/views/Export/new.html.twig | 6 ------ 2 files changed, 9 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/FormActionGoalResult/App.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/FormActionGoalResult/App.vue index 39a7c023a..62ce45c23 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/FormActionGoalResult/App.vue +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/FormActionGoalResult/App.vue @@ -7,7 +7,6 @@
Date: Thu, 8 Sep 2022 15:00:37 +0200 Subject: [PATCH 24/41] exports: fix buildForm in SocialWorkType Filter --- .../SocialWorkTypeFilter.php | 82 ++++++------------- 1 file changed, 26 insertions(+), 56 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/SocialWorkTypeFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/SocialWorkTypeFilter.php index c2ffd74c6..7629a7b60 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/SocialWorkTypeFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/SocialWorkTypeFilter.php @@ -50,72 +50,42 @@ class SocialWorkTypeFilter implements FilterInterface $builder ->add('actionType', HiddenType::class) ->get('actionType') - ->addModelTransformer(new CallbackTransformer( - static function (?iterable $actionsAsIterable): string { - if (null === $actionsAsIterable) { return ''; } - $actionIds = []; - foreach ($actionsAsIterable as $value) { - $actionIds[] = $value->getId(); - } - return implode(',', $actionIds); - }, - function (?string $actionsAsString): array { - if (null === $actionsAsString) { return []; } - return array_map( - fn (string $id): ?SocialAction - => $this->socialActionRepository->findOneBy(['id' => (int) $id]), - explode(',', $actionsAsString) - ); - } - )) + ->addModelTransformer($this->iterableToIdTransformer(SocialAction::class)) ; - $builder ->add('goal', HiddenType::class) ->get('goal') - ->addModelTransformer(new CallbackTransformer( - static function (?iterable $goalsAsIterable): string { - if (null === $goalsAsIterable) { return ''; } - $goalIds = []; - foreach ($goalsAsIterable as $value) { - $goalIds[] = $value->getId(); - } - return implode(',', $goalIds); - }, - function (?string $goalsAsString): array { - if (null === $goalsAsString) { return []; } - return array_map( - fn (string $id): ?Goal - => $this->socialActionRepository->findOneBy(['id' => (int) $id]), - explode(',', $goalsAsString) - ); - } - )) + ->addModelTransformer($this->iterableToIdTransformer(Goal::class)) ; - $builder ->add('result', HiddenType::class) ->get('result') - ->addModelTransformer(new CallbackTransformer( - static function (?iterable $resultsAsIterable): string { - if (null === $resultsAsIterable) { return ''; } - $resultIds = []; - foreach ($resultsAsIterable as $value) { - $resultIds[] = $value->getId(); - } - return implode(',', $resultIds); - }, - function (?string $resultsAsString): array { - if (null === $resultsAsString) { return []; } - return array_map( - fn (string $id): ?Result - => $this->socialActionRepository->findOneBy(['id' => (int) $id]), - explode(',', $resultsAsString) - ); - } - )) + ->addModelTransformer($this->iterableToIdTransformer(Result::class)) ; + } + private function iterableToIdTransformer(string $entity): CallbackTransformer + { + return new CallbackTransformer( + static function (?iterable $asIterable): string { + if (null === $asIterable) { return ''; } + $ids = []; + foreach ($asIterable as $value) { + $ids[] = $value->getId(); + } + return implode(',', $ids); + }, + function (?string $asString) use ($entity): array { + if (null === $asString) { return []; } + return array_map( + fn (string $id) + => $this->em + ->getRepository($entity) + ->findOneBy(['id' => (int) $id]), + explode(',', $asString) + ); + } + ); } public function getTitle(): string From 478afc893bbc6bb9c18c3cbad595b10afa5d13ee Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Wed, 14 Sep 2022 12:08:57 +0200 Subject: [PATCH 25/41] exports: fix alterQuery and DescribeAction in SocialWorkTypeFilter --- .../SocialWorkTypeFilter.php | 90 ++++++++++++------- .../translations/messages.fr.yml | 4 +- 2 files changed, 63 insertions(+), 31 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/SocialWorkTypeFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/SocialWorkTypeFilter.php index 7629a7b60..0cf7f979d 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/SocialWorkTypeFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/SocialWorkTypeFilter.php @@ -50,17 +50,23 @@ class SocialWorkTypeFilter implements FilterInterface $builder ->add('actionType', HiddenType::class) ->get('actionType') - ->addModelTransformer($this->iterableToIdTransformer(SocialAction::class)) + ->addModelTransformer( + $this->iterableToIdTransformer(SocialAction::class) + ) ; $builder ->add('goal', HiddenType::class) ->get('goal') - ->addModelTransformer($this->iterableToIdTransformer(Goal::class)) + ->addModelTransformer( + $this->iterableToIdTransformer(Goal::class) + ) ; $builder ->add('result', HiddenType::class) ->get('result') - ->addModelTransformer($this->iterableToIdTransformer(Result::class)) + ->addModelTransformer( + $this->iterableToIdTransformer(Result::class) + ) ; } @@ -90,27 +96,35 @@ class SocialWorkTypeFilter implements FilterInterface public function getTitle(): string { - return 'Filter by type of action, objectives and results'; + return 'Filter by type of action, goals and results'; } public function describeAction($data, $format = 'string'): array { $actionTypes = []; - $objectives = []; + $goals = []; $results = []; foreach ($data['actionType'] as $at) { - $actionTypes[] = $at->getTitle(); - } - foreach ($data['objectives'] as $o) { - $objectives[] = $o->getTitle(); - } - foreach ($data['results'] as $r) { - $results[] = $r->getTitle(); + $actionTypes[] = $this->translatableStringHelper->localize( + $at->getTitle() + ); } - return ['Filtered by referrers: only %actionTypes%', [ - '%actionTypes%' => implode(', ou ', $actionTypes) + foreach ($data['goal'] as $g) { + $goals[] = $this->translatableStringHelper->localize( + $g->getTitle() + ); + } + + foreach ($data['result'] as $r) { + $results[] = $this->translatableStringHelper->localize( + $r->getTitle() + ); + } + + return ['Filtered actions by type, goals and results: %selected%', [ + '%selected%' => implode(', ', array_merge($actionTypes, $goals, $results)) ]]; } @@ -122,28 +136,44 @@ class SocialWorkTypeFilter implements FilterInterface public function alterQuery(QueryBuilder $qb, $data) { $where = $qb->getDQLPart('where'); - $clause = $qb->expr()->eq('acpw.socialAction',':actionType'); - /* - if (!empty($data['goal'])) { - $clause - $qb->expr()->in('acpw.goals', ':goals'); + if (count($data['actionType']) > 0) { + $clause = $qb->expr()->in('acpw.socialAction', ':actionType'); + + if ($where instanceof Andx) { + $where->add($clause); + } else { + $where = $qb->expr()->andX($clause); + } + + $qb->setParameter('actionType', $data['actionType']); } - $qb->expr()->in('acpw.results', ':results'); - */ - if ($where instanceof Andx) { - $where->add($clause); - } else { - $where = $qb->expr()->andX($clause); + if (count($data['goal']) > 0) { + if (!in_array('goal', $qb->getAllAliases(), true)) { + $qb->join('acpw.goals', 'goal'); + } + + $where->add( + $qb->expr()->in('goal.id', ':goals') + ); + + $qb->setParameter('goals', $data['goal']); + } + + if (count($data['result']) > 0) { + if (!in_array('result', $qb->getAllAliases(), true)) { + $qb->join('acpw.results', 'result'); + } + + $where->add( + $qb->expr()->in('result.id', ':results') + ); + + $qb->setParameter('results', $data['result']); } $qb->add('where', $where); - $qb->setParameters([ - 'actionType' => $data['actionType'], - 'goal' => $data['goal'], - 'result' => $data['result'], - ]); } public function applyOn(): string diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index 98facddf9..05e9a82a0 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -456,7 +456,9 @@ Filter by socialaction: Filtrer les parcours 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 les parcours par action d'accompagnement -Filter by type of action, objectives and results: "Filtrer les actions par type, objectif et résultat" + +Filter by type of action, goals and results: "Filtrer les actions par type, objectif et résultat" +'Filtered actions by type, goals and results: %selected%': "Actions filtrées par: %selected%" Filter by evaluation: Filtrer les parcours par évaluation Accepted evaluations: Évaluations From b2e83892a74922c310cc7256cdb762ed9ec776a5 Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Wed, 14 Sep 2022 12:30:17 +0200 Subject: [PATCH 26/41] update export alias conventions --- exports_alias_conventions.csv | 4 ++-- exports_alias_conventions.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/exports_alias_conventions.csv b/exports_alias_conventions.csv index 4b791463a..59b4c0fee 100644 --- a/exports_alias_conventions.csv +++ b/exports_alias_conventions.csv @@ -11,10 +11,10 @@ AccompanyingPeriod::class,,,acp ,User::class,acp.user,acpuser AccompanyingPeriodWork::class,,,acpw ,AccompanyingPeriodWorkEvaluation::class,acpw.accompanyingPeriodWorkEvaluations,workeval -,Goal::class,acpw.goals,goal ,User::class,acpw.referrers,acpwuser -,Result::class,acpw.results,acpwresult ,SocialAction::class,acpw.socialAction,acpwsocialaction +,Goal::class,acpw.goals,goal +,Result::class,acpw.results,result AccompanyingPeriodParticipation::class,,,acppart ,Person::class,acppart.person,partperson AccompanyingPeriodWorkEvaluation::class,,,workeval diff --git a/exports_alias_conventions.md b/exports_alias_conventions.md index f2dbb481e..f04c97ff2 100644 --- a/exports_alias_conventions.md +++ b/exports_alias_conventions.md @@ -19,10 +19,10 @@ These are alias conventions : | | User::class | acp.user | acpuser | | AccompanyingPeriodWork::class | | | acpw | | | AccompanyingPeriodWorkEvaluation::class | acpw.accompanyingPeriodWorkEvaluations | workeval | -| | Goal::class | acpw.goals | goal | | | User::class | acpw.referrers | acpwuser | -| | Result::class | acpw.results | acpwresult | | | SocialAction::class | acpw.socialAction | acpwsocialaction | +| | Goal::class | acpw.goals | goal | +| | Result::class | acpw.results | result | | AccompanyingPeriodParticipation::class | | | acppart | | | Person::class | acppart.person | partperson | | AccompanyingPeriodWorkEvaluation::class | | | workeval | From 424c9239b776d256a061f5ac612bffd39c5840c4 Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Wed, 14 Sep 2022 10:00:02 +0200 Subject: [PATCH 27/41] App.vue: improve logs to understand algo --- .../public/vuejs/FormActionGoalResult/App.vue | 77 ++++++++++++++----- 1 file changed, 57 insertions(+), 20 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/FormActionGoalResult/App.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/FormActionGoalResult/App.vue index 62ce45c23..93ee6c958 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/FormActionGoalResult/App.vue +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/FormActionGoalResult/App.vue @@ -54,6 +54,8 @@ new Promise((resolve, reject) => { - //console.log('fetch Goals', response); this.addElementInData('goals', response.results); resolve(); })).catch; getResultByAction(value.id).then(response => new Promise((resolve, reject) => { - //console.log('fetch Results', response); this.addElementInData('results', response.results); resolve(); })).catch; }, unselectAction(value) { - console.log('unselectAction', value); + console.log('----'); console.log('unselect action', value.id); getGoalByAction(value.id).then(response => new Promise((resolve, reject) => { - //console.log('fetch Goals', response); - this.goals.options = this.removeElementInData('goals', response.results); + [ this.goals.options, this.goals.value ] = this.removeElementInData('goals', response.results); resolve(); })).catch; getResultByAction(value.id).then(response => new Promise((resolve, reject) => { - //console.log('fetch Results', response); - this.results.options = this.removeElementInData('results', response.results); + [ this.results.options, this.results.value ] = this.removeElementInData('results', response.results); resolve(); })).catch; }, @@ -197,23 +198,33 @@ export default { * @param value */ selectGoal(value) { - console.log('selectGoal', value); + console.log('----'); console.log('select goal', value.id); getResultByGoal(value.id).then(response => new Promise((resolve, reject) => { - //console.log('fetch Results', response); this.addElementInData('results', response.results); resolve(); })).catch; }, unselectGoal(value) { - console.log('unselectGoal', value); + console.log('----'); console.log('unselect goal', value.id); getResultByGoal(value.id).then(response => new Promise((resolve, reject) => { - //console.log('fetch Results', response); - this.results.options = this.removeElementInData('results', response.results); + [ this.results.options, this.results.value ] = this.removeElementInData('results', response.results); resolve(); })).catch; }, + /** + * Select/unselect in Result Multiselect + * @param value + */ + selectResult(value) { + console.log('----'); console.log('select result', value.id); + }, + + unselectResult(value) { + console.log('----'); console.log('unselect result', value.id); + }, + /** * Add response elements in data target * @param target string -> 'actions', 'goals' or 'results' @@ -221,13 +232,17 @@ export default { */ addElementInData(target, response) { let data = this[target]; + let dump = []; response.forEach(elem => { let found = data.options.some(e => e.id === elem.id); if (!found) { - console.log('push elem in', target, elem.id); data.options.push(elem); + dump.push(elem.id); } }) + if (dump.length > 0) { + console.log('push ' + dump.length + ' elems in', target, dump); + } }, /** @@ -238,28 +253,48 @@ export default { */ removeElementInData(target, response) { let data = this[target]; + let dump = []; response.forEach(elem => { let found = data.options.some(e => e.id === elem.id); if (found) { - console.log('remove elem from', target, elem.id); data.options = data.options.filter(e => e.id !== elem.id); + dump.push(elem.id); /// remove too from selected and from hiddenField let selected = data.value.some(e => e.id === elem.id); if (selected) { + // remove from selected data.value = data.value.filter(e => e.id !== elem.id); + console.log('remove ' + elem.id + ' from selected ' + target); + // remove from hiddenField this.rebuildHiddenFieldValues(target); - // remove should be recursive; here it works but is not fine - if (target === 'goals') { // <==== TODO improve loop - this.unselectGoal(elem); - } + + // in any cases, remove should be recursive + this.unselectToNextField(target, elem); } /// } }) - return data.options; + if (dump.length > 0) { + console.log('remove ' + dump.length + ' elems from ' + target + ' options', dump); + } + return [ data.options, data.value ]; + }, + + /** + * When unselect Action, it could remove elements in goals multiselect. + * In that case, we have to unselect Goal to remove elements in results too. + * @param target + * @param elem + */ + unselectToNextField(target, elem) { + if (target === 'goals') { + console.log('!!!! target is goal: unselect goal', elem.id); + this.unselectGoal(elem); + console.log('!!!! done'); + } }, /** @@ -268,10 +303,12 @@ export default { */ rebuildHiddenFieldValues(target) { let data = this[target]; + console.log('rebuild hiddenFields ' + target + ' values :'); data.hiddenField.value = ''; // reset data.value.forEach(elem => { data.hiddenField.value = this.addIdToValue(data.hiddenField.value, elem.id); }) + console.log(data.hiddenField); }, addIdToValue(string, id) { From c7e88b39248358ac1b71107186d37859f7f83130 Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Wed, 14 Sep 2022 14:10:17 +0200 Subject: [PATCH 28/41] select action childrens when selecting parent --- .../public/vuejs/FormActionGoalResult/App.vue | 100 +++++++++++++----- 1 file changed, 76 insertions(+), 24 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/FormActionGoalResult/App.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/FormActionGoalResult/App.vue index 93ee6c958..60d2c7d49 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/FormActionGoalResult/App.vue +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/FormActionGoalResult/App.vue @@ -158,7 +158,6 @@ export default { this.results.hiddenField.value = ''; console.log(this.actions.hiddenField, this.goals.hiddenField, this.results.hiddenField); - // TODO choisir une action parente impliquera de retenir les actions "enfants". }, methods: { async getSocialActionsList() { @@ -171,14 +170,20 @@ export default { */ selectAction(value) { console.log('----'); console.log('select action', value.id); - getGoalByAction(value.id).then(response => new Promise((resolve, reject) => { - this.addElementInData('goals', response.results); - resolve(); - })).catch; - getResultByAction(value.id).then(response => new Promise((resolve, reject) => { - this.addElementInData('results', response.results); - resolve(); - })).catch; + let children = this.getChildrensFromParent(value); + this.addSelectedElement('actions', children); + + let parentAndChildren = [...[value], ...children]; + parentAndChildren.forEach(elem => { + getGoalByAction(elem.id).then(response => new Promise((resolve, reject) => { + this.addElementInData('goals', response.results); + resolve(); + })).catch; + getResultByAction(elem.id).then(response => new Promise((resolve, reject) => { + this.addElementInData('results', response.results); + resolve(); + })).catch; + }); }, unselectAction(value) { @@ -225,6 +230,21 @@ export default { console.log('----'); console.log('unselect result', value.id); }, + /** + * Choose parent action will involve retaining the "children" actions. + * @param value + * @return array + */ + getChildrensFromParent(value) { + if (null === value.parent) { + let excludeParent = this.actions.options.filter(o => o.parent !== null); + let children = excludeParent.filter(o => o.parent.id === value.id); + console.log("get childrens", children.map(e => e.id)); + return children; + } + return []; + }, + /** * Add response elements in data target * @param target string -> 'actions', 'goals' or 'results' @@ -260,21 +280,7 @@ export default { data.options = data.options.filter(e => e.id !== elem.id); dump.push(elem.id); - /// remove too from selected and from hiddenField - let selected = data.value.some(e => e.id === elem.id); - if (selected) { - - // remove from selected - data.value = data.value.filter(e => e.id !== elem.id); - console.log('remove ' + elem.id + ' from selected ' + target); - - // remove from hiddenField - this.rebuildHiddenFieldValues(target); - - // in any cases, remove should be recursive - this.unselectToNextField(target, elem); - } - /// + this.removeSelectedElement(target, elem); } }) if (dump.length > 0) { @@ -283,6 +289,52 @@ export default { return [ data.options, data.value ]; }, + /** + * + * @param target + * @param elements + */ + addSelectedElement(target, elements) { + let data = this[target]; + let dump = []; + elements.forEach(elem => { + let selected = data.value.some(e => e.id === elem.id); + if (!selected) { + + data.value.push(elem); + dump.push(elem.id); + + // add in hiddenField + this.rebuildHiddenFieldValues(target); + } + }); + if (dump.length > 0) { + console.log('add ' + dump.length + ' selected elems in', target, dump); + } + }, + + /** + * Remove element from selected and from hiddenField + * @param target + * @param elem + */ + removeSelectedElement(target, elem) { + let data = this[target]; + let selected = data.value.some(e => e.id === elem.id); + if (selected) { + + // remove from selected + data.value = data.value.filter(e => e.id !== elem.id); + console.log('remove ' + elem.id + ' from selected ' + target); + + // remove from hiddenField + this.rebuildHiddenFieldValues(target); + + // in any cases, remove should be recursive + this.unselectToNextField(target, elem); + } + }, + /** * When unselect Action, it could remove elements in goals multiselect. * In that case, we have to unselect Goal to remove elements in results too. From fceab958bb75fe815b87f5b87bb2834ddf757d5d Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Wed, 14 Sep 2022 13:31:05 +0200 Subject: [PATCH 29/41] comment logs --- .../public/vuejs/FormActionGoalResult/App.vue | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/FormActionGoalResult/App.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/FormActionGoalResult/App.vue index 60d2c7d49..d4d1be1b6 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/FormActionGoalResult/App.vue +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/FormActionGoalResult/App.vue @@ -157,7 +157,7 @@ export default { this.goals.hiddenField.value = ''; this.results.hiddenField.value = ''; - console.log(this.actions.hiddenField, this.goals.hiddenField, this.results.hiddenField); + //console.log(this.actions.hiddenField, this.goals.hiddenField, this.results.hiddenField); }, methods: { async getSocialActionsList() { @@ -169,7 +169,7 @@ export default { * @param value */ selectAction(value) { - console.log('----'); console.log('select action', value.id); + //console.log('----'); console.log('select action', value.id); let children = this.getChildrensFromParent(value); this.addSelectedElement('actions', children); @@ -187,7 +187,7 @@ export default { }, unselectAction(value) { - console.log('----'); console.log('unselect action', value.id); + //console.log('----'); console.log('unselect action', value.id); getGoalByAction(value.id).then(response => new Promise((resolve, reject) => { [ this.goals.options, this.goals.value ] = this.removeElementInData('goals', response.results); resolve(); @@ -203,7 +203,7 @@ export default { * @param value */ selectGoal(value) { - console.log('----'); console.log('select goal', value.id); + //console.log('----'); console.log('select goal', value.id); getResultByGoal(value.id).then(response => new Promise((resolve, reject) => { this.addElementInData('results', response.results); resolve(); @@ -211,7 +211,7 @@ export default { }, unselectGoal(value) { - console.log('----'); console.log('unselect goal', value.id); + //console.log('----'); console.log('unselect goal', value.id); getResultByGoal(value.id).then(response => new Promise((resolve, reject) => { [ this.results.options, this.results.value ] = this.removeElementInData('results', response.results); resolve(); @@ -223,11 +223,11 @@ export default { * @param value */ selectResult(value) { - console.log('----'); console.log('select result', value.id); + //console.log('----'); console.log('select result', value.id); }, unselectResult(value) { - console.log('----'); console.log('unselect result', value.id); + //console.log('----'); console.log('unselect result', value.id); }, /** @@ -239,7 +239,7 @@ export default { if (null === value.parent) { let excludeParent = this.actions.options.filter(o => o.parent !== null); let children = excludeParent.filter(o => o.parent.id === value.id); - console.log("get childrens", children.map(e => e.id)); + //console.log("get childrens", children.map(e => e.id)); return children; } return []; @@ -261,7 +261,7 @@ export default { } }) if (dump.length > 0) { - console.log('push ' + dump.length + ' elems in', target, dump); + //console.log('push ' + dump.length + ' elems in', target, dump); } }, @@ -284,7 +284,7 @@ export default { } }) if (dump.length > 0) { - console.log('remove ' + dump.length + ' elems from ' + target + ' options', dump); + //console.log('remove ' + dump.length + ' elems from ' + target + ' options', dump); } return [ data.options, data.value ]; }, @@ -309,7 +309,7 @@ export default { } }); if (dump.length > 0) { - console.log('add ' + dump.length + ' selected elems in', target, dump); + //console.log('add ' + dump.length + ' selected elems in', target, dump); } }, @@ -325,7 +325,7 @@ export default { // remove from selected data.value = data.value.filter(e => e.id !== elem.id); - console.log('remove ' + elem.id + ' from selected ' + target); + //console.log('remove ' + elem.id + ' from selected ' + target); // remove from hiddenField this.rebuildHiddenFieldValues(target); @@ -343,9 +343,9 @@ export default { */ unselectToNextField(target, elem) { if (target === 'goals') { - console.log('!!!! target is goal: unselect goal', elem.id); + //console.log('!!!! target is goal: unselect goal', elem.id); this.unselectGoal(elem); - console.log('!!!! done'); + //console.log('!!!! done'); } }, @@ -355,12 +355,12 @@ export default { */ rebuildHiddenFieldValues(target) { let data = this[target]; - console.log('rebuild hiddenFields ' + target + ' values :'); + //console.log('rebuild hiddenFields ' + target + ' values :'); data.hiddenField.value = ''; // reset data.value.forEach(elem => { data.hiddenField.value = this.addIdToValue(data.hiddenField.value, elem.id); }) - console.log(data.hiddenField); + //console.log(data.hiddenField); }, addIdToValue(string, id) { From fb60808dcad322515384018a85e69912b8b69411 Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Wed, 14 Sep 2022 17:28:03 +0200 Subject: [PATCH 30/41] export translations: improve title translations in filter/aggrs stack --- .../Export/LinkedToPerson/CountActivity.php | 2 +- .../PersonHavingActivityBetweenDateFilter.php | 2 +- .../PersonFilters/DeadOrAliveFilter.php | 2 +- .../ResidentialAddressAtThirdpartyFilter.php | 2 +- .../ResidentialAddressAtUserFilter.php | 4 +- .../translations/messages.fr.yml | 91 ++++++++++--------- 6 files changed, 55 insertions(+), 48 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/CountActivity.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/CountActivity.php index 398fb14bb..9f4d15ec7 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/CountActivity.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/CountActivity.php @@ -109,7 +109,7 @@ class CountActivity implements ExportInterface, GroupedExportInterface return [ Declarations::ACTIVITY, Declarations::ACTIVITY_PERSON, - //PersonDeclarations::PERSON_TYPE, + PersonDeclarations::PERSON_TYPE, ]; } } diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/PersonFilters/PersonHavingActivityBetweenDateFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/PersonFilters/PersonHavingActivityBetweenDateFilter.php index 8db312e35..871271aaa 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/PersonFilters/PersonHavingActivityBetweenDateFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/PersonFilters/PersonHavingActivityBetweenDateFilter.php @@ -197,7 +197,7 @@ class PersonHavingActivityBetweenDateFilter implements ExportElementValidatedInt public function getTitle() { - return 'Filtered by person having an activity in a period'; + return 'Filter by person having an activity in a period'; } public function validateForm($data, ExecutionContextInterface $context) diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/DeadOrAliveFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/DeadOrAliveFilter.php index 00d05117b..a161df44f 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/DeadOrAliveFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/DeadOrAliveFilter.php @@ -108,6 +108,6 @@ class DeadOrAliveFilter implements FilterInterface public function getTitle() { - return 'Filtered by person\'s that are alive or have deceased at a certain date'; + return "Filter by person's that are alive or have deceased at a certain date"; } } diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ResidentialAddressAtThirdpartyFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ResidentialAddressAtThirdpartyFilter.php index c38ce6a5b..c96fd680f 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ResidentialAddressAtThirdpartyFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ResidentialAddressAtThirdpartyFilter.php @@ -106,6 +106,6 @@ class ResidentialAddressAtThirdpartyFilter implements FilterInterface public function getTitle() { - return 'Filtered by person\'s who have a residential address located at a thirdparty of type'; + return "Filter by person's who have a residential address located at a thirdparty of type"; } } diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ResidentialAddressAtUserFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ResidentialAddressAtUserFilter.php index 48275eb12..482312143 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ResidentialAddressAtUserFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ResidentialAddressAtUserFilter.php @@ -59,11 +59,11 @@ class ResidentialAddressAtUserFilter implements FilterInterface public function describeAction($data, $format = 'string') { - return ['Filtered by person\'s who have a residential address located at another user']; + return ["Filtered by person's who have a residential address located at another user"]; } public function getTitle() { - return 'Filtered by person\'s who have a residential address located at another user'; + return "Filter by person's who have a residential address located at another user"; } } diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index 05e9a82a0..a81fb7e86 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -86,8 +86,8 @@ Civility: Civilité choose civility: -- All genders: tous les genres Any person selected: Aucune personne sélectionnée -Create a household and add an address: Ajouter une adresse pour un usager non suivi et seul dans un ménage -A new household will be created. The person will be member of this household.: Un nouveau ménage va être créé. L'usager sera membre de ce ménage. +Create a household and add an address: Ajouter une adresse pour une personne non suivie et seule dans un ménage +A new household will be created. The person will be member of this household.: Un nouveau ménage va être créé. La personne sera membre de ce ménage. Comment on the gender: Commentaire sur le genre # dédoublonnage @@ -127,8 +127,8 @@ address_country_code: Code pays 'Alreay existing person': 'Dossiers déjà encodés' 'Add the person': 'Ajouter la personne' -'Add the person and create an accompanying period': "Créer l'usager ET créer une période d'accompagnement" -'Add the person and create a household': "Créer l'usager ET créer un ménage" +'Add the person and create an accompanying period': "Créer la personne ET créer une période d'accompagnement" +'Add the person and create a household': "Créer la personne ET créer un ménage" Show person: Voir le dossier de la personne 'Confirm the creation': 'Confirmer la création' 'You will create this person': 'Vous allez créer le dossier suivant' @@ -200,7 +200,7 @@ Participants: Personnes impliquées Create an accompanying course: Créer un parcours Accompanying courses of users: Parcours des utilisateurs This accompanying course is still a draft: Ce parcours est encore à l'état brouillon. -Associated peoples: Usagers concernés +Associated peoples: Personnes concernées Resources: Interlocuteurs privilégiés Any requestor to this accompanying course: Aucun demandeur pour ce parcours Social action: Action d'accompagnement @@ -217,7 +217,7 @@ See this period: Voir cette période Requestor: Demandeur No requestor: Pas de demandeur No resources: "Pas d'interlocuteurs privilégiés" -Persons associated: Usagers concernés +Persons associated: Personnes concernés Referrer: Référent Referrers: Agents traitants Some peoples does not belong to any household currently. Add them to an household soon: Certaines personnes n'appartiennent à aucun ménage actuellement. Renseignez leur ménage dès que possible. @@ -244,7 +244,7 @@ List of resources: "Liste des ressources" There are no available resources: "Aucun ressource" no comment found: "Aucun commentaire" Select a type: "Choisissez un type" -Select a person: "Choisissez un usager" +Select a person: "Choisissez une personne" Select a thirdparty: "Choisissez un tiers" Contact person: "Personne de contact" Kind: "Type" @@ -276,11 +276,11 @@ Which kind of residential address would you create ?: Quel type d'adresse de ré The address of another person: L'adresse d'une autre personne The address of a third party: L'adresse d'un tiers A new address: Une nouvelle adresse -residential_address_person_explanation: L'adresse sera positionnée auprès d'un usager. Lorsque l'usager déménage, l'adresse de résidence suivra également cet usager +residential_address_person_explanation: L'adresse sera positionnée auprès d'une personne. Lorsque la personne déménage, l'adresse de résidence suivra également cette personne residential_address_third_party_explanation: L'adresse sera associée à celle d'un tiers. residential_address_new_address_explanation: Créer une nouvelle adresse. L'adresse sera fixe. New residential address: Nouvelle adresse de résidence -Host person: Choisir l'adresse d'un usager +Host person: Choisir l'adresse d'une personne Host third party: Choisir l'adresse d'un tiers The new residential address was created successfully: La nouvelle adresse de résidence a été créée Edit a residential address: Modifier l'addresse de résidence @@ -330,16 +330,16 @@ Accompanyied people: Personnes accompagnées ## exports Exports of persons: Exports des personnes -Count people by various parameters.: Compte le nombre d'usagers en fonction de différents filtres. -Count people: Nombre d'usagers +Count people by various parameters.: Compte le nombre de personnes en fonction de différents filtres. +Count people: Nombre de personnes List peoples: Liste des personnes Create a list of people according to various filters.: Crée une liste des personnes selon différents filtres. Fields to include in export: Champs à inclure dans l'export Address valid at this date: Addresse valide à cette date List duplicates: Liste des doublons Create a list of duplicate people: Créer la liste des personnes détectées comme doublons. -Count people participating in an accompanying course by various parameters.: Nombre d'usagers concernées par un parcours -Count people participating in an accompanying course: Nombre d'usagers concernés par un parcours +Count people participating in an accompanying course by various parameters.: Nombre de personnes concernées par un parcours +Count people participating in an accompanying course: Nombre de personnes concernés par un parcours Exports of accompanying courses: Exports des parcours d'accompagnement Count accompanying courses: Nombre de parcours @@ -362,72 +362,77 @@ Count households: Nombre de ménages Count household by various parameters.: Compte le nombre de ménages impliqués dans un parcours selon différents filtres. ## persons filters -Filter by person gender: Filtrer par genre de la personne +Filter by person gender: Filtrer les personnes par genre Accepted genders: Genres acceptés 'Filtering by genders: only %genders%': 'Filtré par genre: seulement %genders%' -Filter by person's nationality: Filtrer par nationalité +Filter by person's nationality: Filtrer les personnes par nationalité Nationalities: Nationalités Choose countries: Choisir les nationalités 'Filtered by nationality : %nationalities%': 'Filtré par nationalité : seulement %nationalities%' -Filter by person's birthdate: Filtrer par date de naissance de la personne +Filter by person's birthdate: Filtrer les personnes par date de naissance Born after this date: Nés après cette date Born before this date: Nés avant cette date This field should not be empty: Ce champ ne peut pas être vide This date should be after the date given in "born after" field: Cette date doit être après la date donnée du le champ "nés après le" "Filtered by person's birthdate: between %date_from% and %date_to%": "Filtré par date de naissance de la personne: uniquement nés entre le %date_from% et %date_to%" -Filter by person's deathdate: Filtrer par date de décès de la personne +Filter by person's deathdate: Filtrer les personnes par date de décès "Filtered by person's deathdate: between %date_from% and %date_to%": "Filtré par date de naissance de la personne: uniquement nés entre le %date_from% et %date_to%" Death after this date: Décédé après cette date Deathdate before: Décédé avant cette date - Alive: Vivant Deceased: Décédé Filter in relation to this date: Filtrer par rapport à cette date "Filtered by a state of %deadOrAlive% at this date %date_calc%": Filtré par personnes qui sont %deadOrAlive% à cette date %date_calc% -Filter by person's age: Filtrer par âge de la personne +Filter by person's age: Filtrer les personnes par age "Filtered by person's age: between %min_age% and %max_age%": "Filtré par âge de la personne entre %min_age% et %max_age%" Minimum age: Âge minimum Maximum age: Âge maximum The minimum age should be less than the maximum age.: L'âge minimum doit être plus bas que l'âge maximum. Date during which residential address was valid: Date de validité -Filtered by person\'s who have a residential address located at a thirdparty of type %thirparty_type%: Uniquement les usagers qui ont une addresse de résidence chez un tiers de catégorie %thirdparty_type% +Filtered by person\'s who have a residential address located at a thirdparty of type %thirparty_type%: Uniquement les personnes qui ont une addresse de résidence chez un tiers de catégorie %thirdparty_type% Family composition: Composition familiale Family composition at this time: Composition familiale à cette date. +Filter by person's marital status: Filtrer les personnes par état matrimonial Filtered by person's marital status: Filtré par état matrimonial -Filter by person's marital status: Filtrer par état matrimonial Marital status at this time: État matrimonial par rapport à cette date -Filter by entrusted child status: Filtrer les usagers qui sont "enfant confié" -Filtered by entrusted child status: Uniquement les usagers qui sont "enfant confié" +Filter by entrusted child status: Filtrer les personnes "enfant confié" +Filtered by entrusted child status: Uniquement les personnes qui sont "enfant confié" -Filter by nomadic status: Filtrer les usagers qui sont "gens de voyage" -Filtered by nomadic status: Uniquement les usagers qui sont "gens de voyage" +Filter by nomadic status: Filtrer les personnes "gens du voyage" +Filtered by nomadic status: Uniquement les personnes qui sont "gens du voyage" -Filtered by person's who have a residential address located at another user: Uniquement les usagers qui ont une addresse de résidence chez un autre usager +"Filter by person's who have a residential address located at another user": Filtrer les personnes qui ont une addresse de résidence chez une autre personne +"Filtered by person's who have a residential address located at another user": Uniquement les personnes qui ont une addresse de résidence chez une autre personne -Filtered by person's that are alive or have deceased at a certain date: Filtrer par usagers qui sont décédé ou vivant à une certaine date +Filter by person's that are alive or have deceased at a certain date: Filtrer les personnes qui sont décédées ou vivantes à une certaine date +Filtered by person's that are alive or have deceased at a certain date: Uniquement les personnes qui sont décédées ou vivantes à une certaine date -"Filter by accompanying period: active period": "Filtrer par période d'accompagnement: en file active" +"Filter by accompanying period: active period": "Filtrer les personnes par période d'accompagnement: en file active" Having an accompanying period opened after this date: Ayant une période d'accompagnement ouverte après cette date Having an accompanying period ending before this date, or still opened at this date: Ayant une période d'accompagnement fermée après cette date, ou toujours ouverte à cette date "Filtered by accompanying period: persons having an accompanying period opened after the %date_from% and closed before the %date_to% (or still opened at the %date_to%)": "Filtré par période d'accompagnement: personnes ayant une période d'accompagnement ouverte après le %date_from%, et cloturée le %date_to% (ou toujours ouverte le %date_to%)" -"Filter by accompanying period: starting between two dates": "Filtrer par période d'accompagnement: début de la période entre deux dates" +"Filter by accompanying period: starting between two dates": "Filtrer les personnes par période d'accompagnement: début de la période entre deux dates" "Having an accompanying period opened before this date": "Ayant une période d'accompagnement ouverte avant cette date" "Filtered by accompanying period: persons having an accompanying period opened between the %date_from% and %date_to%": "Filtrer par période d'accompagnement: ayant une période ouverte entre le %date_from% et le %date_to%" -"Filter by accompanying period: closed between two dates": "Filtrer par période d'accompagnement: période fermée entre deux dates" +"Filter by accompanying period: closed between two dates": "Filtrer les personnes par période d'accompagnement: période fermée entre deux dates" Having an accompanying period closed after this date: Ayant une période d'accompagnement fermée après cette date "Having an accompanying period closed before this date": "Ayant une période d'accompagnement fermée avant cette date" "Filtered by accompanying period: persons having an accompanying period closed between the %date_from% and %date_to%": "Filtrer par période d'accompagnement: ayant une période fermée entre le %date_from% et le %date_to%" +Filter by person having an activity in a period: Filtrer les personnes ayant eu une échange pendant la période donnée +Filtered by person having an activity between %date_from% and %date_to% with reasons %reasons_name%: Uniquement les personnes associées à une échange entre %date_from% et %date_to% avec les sujets %reasons_name% + + ## accompanying course filters/aggr Filter by user scope: Filtrer les parcours par service du référent "Filtered by user main scope: only %scope%": "Filtré par service du référent: uniquement %scope%" @@ -486,13 +491,13 @@ Administrative location: Localisation administrative "Filtered by administratives locations: only %locations%": "Filtré par localisation administrative: uniquement %locations%" Group by administrative location: Grouper les parcours par localisation administrative -Filter by requestor: Filtrer les parcours selon la présence du demandeur au sein des usagers concernés +Filter by requestor: Filtrer les parcours selon la présence du demandeur au sein des personnes concernées Accepted choices: '' -is person concerned: Le demandeur est un usager concerné -is other person: Le demandeur est un usager, mais n'est pas concerné +is person concerned: Le demandeur est une personne concernée +is other person: Le demandeur est une personne, mais n'est pas concernée is thirdparty: Le demandeur est un tiers no requestor: Le parcours ne comporte pas de demandeur -"Filtered by requestor: only %choice%": "Filtré par présence du demandeur au sein des usagers concernés: uniquement si %choice%" +"Filtered by requestor: only %choice%": "Filtré par présence du demandeur au sein des personnes concernées: uniquement si %choice%" Group by requestor: Grouper les parcours selon la nature du demandeur Filter by confidential: Filtrer les parcours par confidentialité @@ -592,13 +597,15 @@ Group by country: Grouper par pays Group people by gender: Grouper les personnes par genre Group people by their professional situation: Grouper les personnes par situation professionelle Group people by marital status: Grouper les personnes par état matrimonial -Aggregate by household position: Grouper par position dans le ménage + +Aggregate by household position: Grouper les personnes par position dans le ménage Household position in relation to this date: Position dans le ménage par rapport à cette date Household position: Position dans le ménage -Filtered by person's who have a residential address located at a thirdparty of type: Uniquement les usagers qui ont une addresse de résidence chez un tiers de catégorie "xxx" -"Filtered by person's who have a residential address located at a thirdparty of type %thirdparty_type% and valid on %date_calc%": "Uniquement les usagers qui ont une addresse de résidence chez un tiers de catégorie %thirdparty_type% et valide sur la date %date_calc%" -Aggregate by age: Grouper par âge +Filter by person's who have a residential address located at a thirdparty of type: Filtrer les personnes qui ont une addresse de résidence chez un tiers de catégorie "xxx" +"Filtered by person's who have a residential address located at a thirdparty of type %thirdparty_type% and valid on %date_calc%": "Uniquement les personnes qui ont une addresse de résidence chez un tiers de catégorie %thirdparty_type% et valide sur la date %date_calc%" + +Aggregate by age: Grouper les personnes par âge Calculate age in relation to this date: Calculer l'âge par rapport à cette date Group people by country of birth: Grouper les personnes par pays de naissance @@ -765,7 +772,7 @@ This course is located at a temporarily address. You should locate this course t Accompanying course location: Localisation du parcours This course is located by: Localisé auprès de This course has a temporarily location: Localisation temporaire -Choose a person to locate by: Localiser auprès d'un usager concerné +Choose a person to locate by: Localiser auprès d'une personne concernée Associate at least one member with an household, and set an address to this household: Associez au moins un membre du parcours à un ménage, et indiquez une adresse à ce ménage. Locate by: Localiser auprès de fix it: Compléter @@ -850,7 +857,7 @@ Person addresses: Adresses de résidence Household addresses: Adresses de domicile Insert an address: Insérer une adresse see social issues: Voir les problématiques sociales -see persons associated: Voir les usagers concernés +see persons associated: Voir les personnes concernées docgen: Accompanying Period basic: "Parcours d'accompagnement (basique)" @@ -871,10 +878,10 @@ docgen: period_notification: period_designated_subject: Vous êtes référent d'un parcours d'accompagnement You are designated to a new period: Vous avez été désigné référent d'un parcours d'accompagnement. - Persons are: Les usagers concernés sont les suivants + Persons are: Les personnes concernées sont les suivantes Social issues are: Les problématiques sociales renseignées sont les suivantes See it online: Visualisez le parcours en ligne - Person locating period has moved: L'usager qui localise un parcours a déménagé + Person locating period has moved: La personne qui localise un parcours a déménagé You are getting a notification for a period which does not exists any more: Cette notification ne correspond pas à une période d'accompagnement valide. You are getting a notification for a period you are not allowed to see: La notification fait référence à une période d'accompagnement à laquelle vous n'avez pas accès. From 5dcd157bd061a14469a6fff14bbc64a8c10082d5 Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Wed, 14 Sep 2022 18:12:29 +0200 Subject: [PATCH 31/41] export: move Vue component in ChillPersonBundle --- src/Bundle/ChillMainBundle/Resources/views/Export/new.html.twig | 2 +- src/Bundle/ChillMainBundle/chill.webpack.config.js | 1 - .../Resources/public/vuejs/ExportFormActionGoalResult}/App.vue | 0 .../Resources/public/vuejs/ExportFormActionGoalResult}/api.js | 0 .../Resources/public/vuejs/ExportFormActionGoalResult}/index.js | 0 src/Bundle/ChillPersonBundle/chill.webpack.config.js | 1 + 6 files changed, 2 insertions(+), 2 deletions(-) rename src/Bundle/{ChillMainBundle/Resources/public/vuejs/FormActionGoalResult => ChillPersonBundle/Resources/public/vuejs/ExportFormActionGoalResult}/App.vue (100%) rename src/Bundle/{ChillMainBundle/Resources/public/vuejs/FormActionGoalResult => ChillPersonBundle/Resources/public/vuejs/ExportFormActionGoalResult}/api.js (100%) rename src/Bundle/{ChillMainBundle/Resources/public/vuejs/FormActionGoalResult => ChillPersonBundle/Resources/public/vuejs/ExportFormActionGoalResult}/index.js (100%) diff --git a/src/Bundle/ChillMainBundle/Resources/views/Export/new.html.twig b/src/Bundle/ChillMainBundle/Resources/views/Export/new.html.twig index c6adb241d..ad49d9aa6 100644 --- a/src/Bundle/ChillMainBundle/Resources/views/Export/new.html.twig +++ b/src/Bundle/ChillMainBundle/Resources/views/Export/new.html.twig @@ -23,7 +23,7 @@ {% block js %} {{ encore_entry_script_tags('page_export') }} {% if export_alias == 'count_social_work_actions' %} - {{ encore_entry_script_tags('vue_form_action_goal_result') }} + {{ encore_entry_script_tags('vue_export_action_goal_result') }} {% endif %} {% endblock js %} diff --git a/src/Bundle/ChillMainBundle/chill.webpack.config.js b/src/Bundle/ChillMainBundle/chill.webpack.config.js index c4c445d31..628f04ba5 100644 --- a/src/Bundle/ChillMainBundle/chill.webpack.config.js +++ b/src/Bundle/ChillMainBundle/chill.webpack.config.js @@ -74,5 +74,4 @@ module.exports = function(encore, entries) // Vue entrypoints encore.addEntry('vue_address', __dirname + '/Resources/public/vuejs/Address/index.js'); encore.addEntry('vue_onthefly', __dirname + '/Resources/public/vuejs/OnTheFly/index.js'); - encore.addEntry('vue_form_action_goal_result', __dirname + '/Resources/public/vuejs/FormActionGoalResult/index.js'); }; diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/FormActionGoalResult/App.vue b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/ExportFormActionGoalResult/App.vue similarity index 100% rename from src/Bundle/ChillMainBundle/Resources/public/vuejs/FormActionGoalResult/App.vue rename to src/Bundle/ChillPersonBundle/Resources/public/vuejs/ExportFormActionGoalResult/App.vue diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/FormActionGoalResult/api.js b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/ExportFormActionGoalResult/api.js similarity index 100% rename from src/Bundle/ChillMainBundle/Resources/public/vuejs/FormActionGoalResult/api.js rename to src/Bundle/ChillPersonBundle/Resources/public/vuejs/ExportFormActionGoalResult/api.js diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/FormActionGoalResult/index.js b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/ExportFormActionGoalResult/index.js similarity index 100% rename from src/Bundle/ChillMainBundle/Resources/public/vuejs/FormActionGoalResult/index.js rename to src/Bundle/ChillPersonBundle/Resources/public/vuejs/ExportFormActionGoalResult/index.js diff --git a/src/Bundle/ChillPersonBundle/chill.webpack.config.js b/src/Bundle/ChillPersonBundle/chill.webpack.config.js index 85ee83c93..a445959e5 100644 --- a/src/Bundle/ChillPersonBundle/chill.webpack.config.js +++ b/src/Bundle/ChillPersonBundle/chill.webpack.config.js @@ -13,6 +13,7 @@ module.exports = function(encore, entries) encore.addEntry('vue_accourse_work_create', __dirname + '/Resources/public/vuejs/AccompanyingCourseWorkCreate/index.js'); encore.addEntry('vue_accourse_work_edit', __dirname + '/Resources/public/vuejs/AccompanyingCourseWorkEdit/index.js'); encore.addEntry('vue_visgraph', __dirname + '/Resources/public/vuejs/VisGraph/index.js'); + encore.addEntry('vue_export_action_goal_result', __dirname + '/Resources/public/vuejs/ExportFormActionGoalResult/index.js'); encore.addEntry('mod_set_referrer', __dirname + '/Resources/public/mod/AccompanyingPeriod/setReferrer.js'); From 91a5db4c14bea289d80edaea8656e612ee720e7f Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Thu, 15 Sep 2022 16:07:00 +0200 Subject: [PATCH 32/41] fix origin alias in qb --- .../AccompanyingCourseAggregators/OriginAggregator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/OriginAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/OriginAggregator.php index 4c784e08d..925160a2d 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/OriginAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/OriginAggregator.php @@ -45,7 +45,7 @@ final class OriginAggregator implements AggregatorInterface $qb->join('acp.origin', 'acporigin'); } - $qb->addSelect('o.id AS origin_aggregator'); + $qb->addSelect('acporigin.id AS origin_aggregator'); $groupby = $qb->getDQLPart('groupBy'); From 211a80e9beba3ee1f97a6c0b719edb696f230277 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 8 Sep 2022 13:46:24 +0200 Subject: [PATCH 33/41] deprecate chill prophecy train in favor of prophecy-phpunit bridge --- src/Bundle/ChillMainBundle/Test/ProphecyTrait.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Bundle/ChillMainBundle/Test/ProphecyTrait.php b/src/Bundle/ChillMainBundle/Test/ProphecyTrait.php index a25624719..ae274ca1d 100644 --- a/src/Bundle/ChillMainBundle/Test/ProphecyTrait.php +++ b/src/Bundle/ChillMainBundle/Test/ProphecyTrait.php @@ -18,6 +18,7 @@ namespace Chill\MainBundle\Test; * and use tearDownTrait after usage. * * @codeCoverageIgnore + * @deprecated use @class{Prophecy\PhpUnit\ProphecyTrait} instead */ trait ProphecyTrait { From e379d8adb5c94eb617cff0cd3fa6a2c19ef558bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 8 Sep 2022 13:47:35 +0200 Subject: [PATCH 34/41] [feature] use internal services to check for acl on exports --- .../Controller/ExportController.php | 5 +- .../ChillMainBundle/Export/ExportManager.php | 56 ++++++------------- .../Repository/CenterRepository.php | 12 ++++ .../Authorization/ChillExportVoter.php | 17 +++--- .../ChillMainBundle/config/services.yaml | 8 +-- 5 files changed, 42 insertions(+), 56 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Controller/ExportController.php b/src/Bundle/ChillMainBundle/Controller/ExportController.php index 1893a64b3..ffd73b777 100644 --- a/src/Bundle/ChillMainBundle/Controller/ExportController.php +++ b/src/Bundle/ChillMainBundle/Controller/ExportController.php @@ -23,6 +23,7 @@ use Symfony\Component\Form\Extension\Core\Type\FormType; use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\FormFactoryInterface; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Session\SessionInterface; use Symfony\Contracts\Translation\TranslatorInterface; @@ -142,10 +143,8 @@ class ExportController extends AbstractController /** * Render the list of available exports. - * - * @return \Symfony\Component\HttpFoundation\Response */ - public function indexAction(Request $request) + public function indexAction(): Response { $exportManager = $this->exportManager; diff --git a/src/Bundle/ChillMainBundle/Export/ExportManager.php b/src/Bundle/ChillMainBundle/Export/ExportManager.php index e2d099ba8..c1384a3b8 100644 --- a/src/Bundle/ChillMainBundle/Export/ExportManager.php +++ b/src/Bundle/ChillMainBundle/Export/ExportManager.php @@ -14,6 +14,7 @@ namespace Chill\MainBundle\Export; use Chill\MainBundle\Form\Type\Export\ExportType; use Chill\MainBundle\Form\Type\Export\PickCenterType; use Chill\MainBundle\Security\Authorization\AuthorizationHelper; +use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\QueryBuilder; use Generator; @@ -42,52 +43,38 @@ class ExportManager /** * The collected aggregators, injected by DI. * - * @var AggregatorInterface[] + * @var array|AggregatorInterface[] */ - private $aggregators = []; + private array $aggregators = []; - /** - * @var AuthorizationChecker - */ - private $authorizationChecker; + private AuthorizationCheckerInterface $authorizationChecker; - /** - * @var AuthorizationHelper - */ - private $authorizationHelper; + private AuthorizationHelperInterface $authorizationHelper; - /** - * @var EntityManagerInterface - */ - private $em; + private EntityManagerInterface $em; /** * Collected Exports, injected by DI. * - * @var ExportInterface[] + * @var array|ExportInterface[] */ - private $exports = []; + private array $exports = []; /** * The collected filters, injected by DI. * - * @var FilterInterface[] + * @var array|FilterInterface[] */ - private $filters = []; + private array $filters = []; /** * Collected Formatters, injected by DI. * - * @var FormatterInterface[] + * @var array|FormatterInterface[] */ - private $formatters = []; + private array $formatters = []; - /** - * a logger. - * - * @var LoggerInterface - */ - private $logger; + private LoggerInterface $logger; /** * @var \Symfony\Component\Security\Core\User\UserInterface @@ -98,7 +85,7 @@ class ExportManager LoggerInterface $logger, EntityManagerInterface $em, AuthorizationCheckerInterface $authorizationChecker, - AuthorizationHelper $authorizationHelper, + AuthorizationHelperInterface $authorizationHelper, TokenStorageInterface $tokenStorage ) { $this->logger = $logger; @@ -547,19 +534,16 @@ class ExportManager . 'an ExportInterface.'); } - if (null === $centers) { - $centers = $this->authorizationHelper->getReachableCenters( + if (null === $centers || [] === $centers) { + // we want to try if at least one center is reachable + return [] !== $this->authorizationHelper->getReachableCenters( $this->user, $role ); } - if (count($centers) === 0) { - return false; - } - foreach ($centers as $center) { - if ($this->authorizationChecker->isGranted($role, $center) === false) { + if (false === $this->authorizationChecker->isGranted($role, $center)) { //debugging $this->logger->debug('user has no access to element', [ 'method' => __METHOD__, @@ -568,10 +552,6 @@ class ExportManager 'role' => $role, ]); - ///// Bypasse les autorisations qui empêche d'afficher les nouveaux exports - return true; - ///// TODO supprimer le return true - return false; } } diff --git a/src/Bundle/ChillMainBundle/Repository/CenterRepository.php b/src/Bundle/ChillMainBundle/Repository/CenterRepository.php index 554f39880..e8f6f4fa3 100644 --- a/src/Bundle/ChillMainBundle/Repository/CenterRepository.php +++ b/src/Bundle/ChillMainBundle/Repository/CenterRepository.php @@ -30,6 +30,18 @@ final class CenterRepository implements ObjectRepository return $this->repository->find($id, $lockMode, $lockVersion); } + /** + * Return all active centers + * + * Note: this is a teaser: active will comes later on center entity + * + * @return Center[] + */ + public function findActive(): array + { + return $this->findAll(); + } + /** * @return Center[] */ diff --git a/src/Bundle/ChillMainBundle/Security/Authorization/ChillExportVoter.php b/src/Bundle/ChillMainBundle/Security/Authorization/ChillExportVoter.php index ec1a0479d..b98564adf 100644 --- a/src/Bundle/ChillMainBundle/Security/Authorization/ChillExportVoter.php +++ b/src/Bundle/ChillMainBundle/Security/Authorization/ChillExportVoter.php @@ -19,24 +19,23 @@ class ChillExportVoter extends Voter { public const EXPORT = 'chill_export'; - protected AuthorizationHelperInterface $authorizationHelper; + private VoterHelperInterface $helper; - public function __construct(AuthorizationHelperInterface $authorizationHelper) + public function __construct(VoterHelperFactoryInterface $voterHelperFactory) { - $this->authorizationHelper = $authorizationHelper; + $this->helper = $voterHelperFactory + ->generate(self::class) + ->addCheckFor(null, [self::EXPORT]) + ->build(); } protected function supports($attribute, $subject): bool { - return self::EXPORT === $attribute; + return $this->helper->supports($attribute, $subject); } protected function voteOnAttribute($attribute, $subject, TokenInterface $token): bool { - if (!$token->getUser() instanceof User) { - return false; - } - - return [] !== $this->authorizationHelper->getReachableCenters($token->getUser(), $attribute); + return $this->helper->voteOnAttribute($attribute, $subject, $token); } } diff --git a/src/Bundle/ChillMainBundle/config/services.yaml b/src/Bundle/ChillMainBundle/config/services.yaml index 6d55532a6..697fd62aa 100644 --- a/src/Bundle/ChillMainBundle/config/services.yaml +++ b/src/Bundle/ChillMainBundle/config/services.yaml @@ -88,12 +88,8 @@ services: - { name: validator.constraint_validator, alias: 'role_scope_scope_presence' } Chill\MainBundle\Export\ExportManager: - arguments: - - "@logger" - - "@doctrine.orm.entity_manager" - - "@security.authorization_checker" - - "@chill.main.security.authorization.helper" - - "@security.token_storage" + autoconfigure: true + autowire: true Chill\MainBundle\Security\Resolver\CenterResolverDispatcherInterface: '@Chill\MainBundle\Security\Resolver\CenterResolverDispatcher' From 38cb1fe35711c75a9a749eb58e7b37cee010ef93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Fri, 9 Sep 2022 10:54:21 +0200 Subject: [PATCH 35/41] [dev-feature] use an interface for describing CenterRepository (allow mocking in tests --- .../Repository/CenterRepository.php | 9 +-------- .../Repository/CenterRepositoryInterface.php | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 8 deletions(-) create mode 100644 src/Bundle/ChillMainBundle/Repository/CenterRepositoryInterface.php diff --git a/src/Bundle/ChillMainBundle/Repository/CenterRepository.php b/src/Bundle/ChillMainBundle/Repository/CenterRepository.php index e8f6f4fa3..d8e54d1c4 100644 --- a/src/Bundle/ChillMainBundle/Repository/CenterRepository.php +++ b/src/Bundle/ChillMainBundle/Repository/CenterRepository.php @@ -16,7 +16,7 @@ use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityRepository; use Doctrine\Persistence\ObjectRepository; -final class CenterRepository implements ObjectRepository +final class CenterRepository implements CenterRepositoryInterface { private EntityRepository $repository; @@ -30,13 +30,6 @@ final class CenterRepository implements ObjectRepository return $this->repository->find($id, $lockMode, $lockVersion); } - /** - * Return all active centers - * - * Note: this is a teaser: active will comes later on center entity - * - * @return Center[] - */ public function findActive(): array { return $this->findAll(); diff --git a/src/Bundle/ChillMainBundle/Repository/CenterRepositoryInterface.php b/src/Bundle/ChillMainBundle/Repository/CenterRepositoryInterface.php new file mode 100644 index 000000000..27ba64caf --- /dev/null +++ b/src/Bundle/ChillMainBundle/Repository/CenterRepositoryInterface.php @@ -0,0 +1,18 @@ + Date: Fri, 9 Sep 2022 18:36:13 +0200 Subject: [PATCH 36/41] [FIX] use AuthorizationHelperInterface instead of implementation in PickCenterType --- .../Form/Type/Export/PickCenterType.php | 36 ++++++------------- .../ChillMainBundle/config/services/form.yaml | 8 ++--- 2 files changed, 13 insertions(+), 31 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Form/Type/Export/PickCenterType.php b/src/Bundle/ChillMainBundle/Form/Type/Export/PickCenterType.php index c73402dd3..07776cb71 100644 --- a/src/Bundle/ChillMainBundle/Form/Type/Export/PickCenterType.php +++ b/src/Bundle/ChillMainBundle/Form/Type/Export/PickCenterType.php @@ -15,6 +15,7 @@ use Chill\MainBundle\Center\GroupingCenterInterface; use Chill\MainBundle\Entity\Center; use Chill\MainBundle\Export\ExportManager; use Chill\MainBundle\Security\Authorization\AuthorizationHelper; +use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface; use Doctrine\ORM\EntityRepository; use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\AbstractType; @@ -24,6 +25,7 @@ use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; +use Symfony\Component\Security\Core\User\UserInterface; use function array_intersect; use function array_key_exists; use function array_merge; @@ -38,30 +40,24 @@ class PickCenterType extends AbstractType { public const CENTERS_IDENTIFIERS = 'c'; - /** - * @var AuthorizationHelper - */ - protected $authorizationHelper; + protected AuthorizationHelperInterface $authorizationHelper; + + protected ExportManager $exportManager; /** - * @var ExportManager + * @var array|GroupingCenterInterface[] */ - protected $exportManager; - - /** - * @var GroupingCenterInterface[] - */ - protected $groupingCenters = []; + protected array $groupingCenters = []; /** * @var \Symfony\Component\Security\Core\User\UserInterface */ - protected $user; + protected UserInterface $user; public function __construct( TokenStorageInterface $tokenStorage, ExportManager $exportManager, - AuthorizationHelper $authorizationHelper + AuthorizationHelperInterface $authorizationHelper ) { $this->exportManager = $exportManager; $this->user = $tokenStorage->getToken()->getUser(); @@ -78,22 +74,12 @@ class PickCenterType extends AbstractType $export = $this->exportManager->getExport($options['export_alias']); $centers = $this->authorizationHelper->getReachableCenters( $this->user, - (string) $export->requiredRole() + $export->requiredRole() ); $builder->add(self::CENTERS_IDENTIFIERS, EntityType::class, [ 'class' => Center::class, - 'query_builder' => static function (EntityRepository $er) use ($centers) { - $qb = $er->createQueryBuilder('c'); - $ids = array_map( - static function (Center $el) { - return $el->getId(); - }, - $centers - ); - - return $qb->where($qb->expr()->in('c.id', $ids)); - }, + 'choices' => $centers, 'multiple' => true, 'expanded' => true, 'choice_label' => static function (Center $c) { diff --git a/src/Bundle/ChillMainBundle/config/services/form.yaml b/src/Bundle/ChillMainBundle/config/services/form.yaml index 407a1b6af..0a757a8db 100644 --- a/src/Bundle/ChillMainBundle/config/services/form.yaml +++ b/src/Bundle/ChillMainBundle/config/services/form.yaml @@ -81,12 +81,8 @@ services: chill.main.form.pick_centers_type: class: Chill\MainBundle\Form\Type\Export\PickCenterType - arguments: - - "@security.token_storage" - - '@Chill\MainBundle\Export\ExportManager' - - "@chill.main.security.authorization.helper" - tags: - - { name: form.type } + autowire: true + autoconfigure: true chill.main.form.formatter_type: class: Chill\MainBundle\Form\Type\Export\FormatterType From 78ea990189d8229150194c36dfbce55ee2708a1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Fri, 9 Sep 2022 18:36:46 +0200 Subject: [PATCH 37/41] allow voter to handle export about Accompanying periods on Center --- .../Security/Authorization/AccompanyingPeriodVoter.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php b/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php index 8da2036d7..b9c9fb219 100644 --- a/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php +++ b/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Chill\PersonBundle\Security\Authorization; +use Chill\MainBundle\Entity\Center; use Chill\MainBundle\Entity\User; use Chill\MainBundle\Security\Authorization\AbstractChillVoter; use Chill\MainBundle\Security\Authorization\VoterHelperFactoryInterface; @@ -119,6 +120,7 @@ class AccompanyingPeriodVoter extends AbstractChillVoter implements ProvideRoleH ->addCheckFor(null, [self::CREATE, self::REASSIGN_BULK]) ->addCheckFor(AccompanyingPeriod::class, [self::TOGGLE_CONFIDENTIAL, ...self::ALL]) ->addCheckFor(Person::class, [self::SEE, self::CREATE]) + ->addCheckFor(Center::class, [self::STATS]) ->build(); } From d716e0c2c276463c7042a11cbc2bbf2c516d1615 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Sun, 11 Sep 2022 22:44:09 +0200 Subject: [PATCH 38/41] add missing roles and adapt role voter for exports houshold and activity --- .../Authorization/ActivityStatsVoter.php | 40 ++++++------------- .../Security/Authorization/HouseholdVoter.php | 38 ++++++++++++++++-- .../translations/messages.fr.yml | 1 + 3 files changed, 47 insertions(+), 32 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Security/Authorization/ActivityStatsVoter.php b/src/Bundle/ChillActivityBundle/Security/Authorization/ActivityStatsVoter.php index 789e634e5..48448d5e3 100644 --- a/src/Bundle/ChillActivityBundle/Security/Authorization/ActivityStatsVoter.php +++ b/src/Bundle/ChillActivityBundle/Security/Authorization/ActivityStatsVoter.php @@ -13,10 +13,10 @@ namespace Chill\ActivityBundle\Security\Authorization; use Chill\MainBundle\Entity\Center; use Chill\MainBundle\Security\Authorization\AbstractChillVoter; -use Chill\MainBundle\Security\Authorization\AuthorizationHelper; +use Chill\MainBundle\Security\Authorization\VoterHelperFactoryInterface; +use Chill\MainBundle\Security\Authorization\VoterHelperInterface; use Chill\MainBundle\Security\ProvideRoleHierarchyInterface; - -use function in_array; +use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; class ActivityStatsVoter extends AbstractChillVoter implements ProvideRoleHierarchyInterface { @@ -24,14 +24,14 @@ class ActivityStatsVoter extends AbstractChillVoter implements ProvideRoleHierar public const STATS = 'CHILL_ACTIVITY_STATS'; - /** - * @var AuthorizationHelper - */ - protected $helper; + protected VoterHelperInterface $helper; - public function __construct(AuthorizationHelper $helper) + public function __construct(VoterHelperFactoryInterface $voterHelperFactory) { - $this->helper = $helper; + $this->helper = $voterHelperFactory + ->generate(self::class) + ->addCheckFor(Center::class, [self::STATS, self::LISTS]) + ->build(); } public function getRoles(): array @@ -49,30 +49,14 @@ class ActivityStatsVoter extends AbstractChillVoter implements ProvideRoleHierar return $this->getAttributes(); } - protected function getSupportedClasses() + protected function voteOnAttribute($attribute, $subject, TokenInterface $token) { - return [Center::class]; - } - - protected function isGranted($attribute, $object, $user = null) - { - if (!$user instanceof \Symfony\Component\Security\Core\User\UserInterface) { - return false; - } - - return $this->helper->userHasAccess($user, $object, $attribute); + return $this->helper->voteOnAttribute($attribute, $subject, $token); } protected function supports($attribute, $subject) { - if ( - $subject instanceof Center - && in_array($attribute, $this->getAttributes(), true) - ) { - return true; - } - - return false; + return $this->helper->supports($attribute, $subject); } private function getAttributes() diff --git a/src/Bundle/ChillPersonBundle/Security/Authorization/HouseholdVoter.php b/src/Bundle/ChillPersonBundle/Security/Authorization/HouseholdVoter.php index ca956db63..0288c9e61 100644 --- a/src/Bundle/ChillPersonBundle/Security/Authorization/HouseholdVoter.php +++ b/src/Bundle/ChillPersonBundle/Security/Authorization/HouseholdVoter.php @@ -11,6 +11,10 @@ declare(strict_types=1); namespace Chill\PersonBundle\Security\Authorization; +use Chill\MainBundle\Entity\Center; +use Chill\MainBundle\Security\Authorization\VoterHelperFactoryInterface; +use Chill\MainBundle\Security\Authorization\VoterHelperInterface; +use Chill\MainBundle\Security\ProvideRoleHierarchyInterface; use Chill\PersonBundle\Entity\Household\Household; use Chill\PersonBundle\Entity\Household\HouseholdMember; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; @@ -19,7 +23,7 @@ use Symfony\Component\Security\Core\Security; use UnexpectedValueException; use function in_array; -class HouseholdVoter extends Voter +class HouseholdVoter extends Voter implements ProvideRoleHierarchyInterface { public const EDIT = 'CHILL_PERSON_HOUSEHOLD_EDIT'; @@ -36,17 +40,40 @@ class HouseholdVoter extends Voter self::EDIT, self::SEE, ]; + private VoterHelperInterface $helper; + private Security $security; - public function __construct(Security $security) + public function __construct(Security $security, VoterHelperFactoryInterface $voterHelperFactory) { $this->security = $security; + $this->helper = $voterHelperFactory + ->generate(self::class) + ->addCheckFor(Center::class, [self::STATS]) + ->build(); + } + + public function getRolesWithHierarchy(): array + { + return [ 'Person' => $this->getRoles() ]; + } + + public function getRoles(): array + { + return [self::STATS]; + } + + public function getRolesWithoutScope(): array + { + return $this->getRoles(); } protected function supports($attribute, $subject) { - return $subject instanceof Household - && in_array($attribute, self::ALL, true); + return ($subject instanceof Household + && in_array($attribute, self::ALL, true)) + || $this->helper->supports($attribute, $subject) + ; } protected function voteOnAttribute($attribute, $subject, TokenInterface $token): bool @@ -58,6 +85,9 @@ class HouseholdVoter extends Voter case self::EDIT: return $this->checkAssociatedMembersRole($subject, PersonVoter::UPDATE); + case self::STATS: + return $this->voteOnAttribute($attribute, $subject, $token); + default: throw new UnexpectedValueException('attribute not supported'); } diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index a81fb7e86..dc53f4839 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -318,6 +318,7 @@ CHILL_PERSON_ACCOMPANYING_PERIOD_FULL: Voir les détails, créer, supprimer et m CHILL_PERSON_ACCOMPANYING_COURSE_REASSIGN_BULK: Réassigner les parcours en lot CHILL_PERSON_ACCOMPANYING_PERIOD_SEE_DETAILS: Voir les détails d'une période d'accompagnement CHILL_PERSON_ACCOMPANYING_PERIOD_STATS: Statistiques sur les parcours d'accompagnement +CHILL_PERSON_HOUSEHOLD_STATS: Statistiques sur les ménages #period Period closed!: Période clôturée! From d30ac75995e0191b7bbba5b05be96775283a92b7 Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Mon, 19 Sep 2022 11:22:41 +0200 Subject: [PATCH 39/41] exports: create workAction goalResult aggregator --- .../SocialWorkAggregators/GoalAggregator.php | 10 +- .../GoalResultAggregator.php | 94 +++++++++++++++++++ .../ResultAggregator.php | 12 ++- .../services/exports_social_actions.yaml | 7 ++ .../translations/messages.fr.yml | 5 +- 5 files changed, 118 insertions(+), 10 deletions(-) create mode 100644 src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/GoalResultAggregator.php diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/GoalAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/GoalAggregator.php index 4310dcac2..21c13cef9 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/GoalAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/GoalAggregator.php @@ -52,7 +52,7 @@ final class GoalAggregator implements AggregatorInterface } } - public function applyOn() + public function applyOn(): string { return Declarations::SOCIAL_WORK_ACTION_TYPE; } @@ -71,16 +71,18 @@ final class GoalAggregator implements AggregatorInterface $g = $this->goalRepository->find($value); - return $this->translatableStringHelper->localize($g->getTitle()); + return $this->translatableStringHelper->localize( + $g->getTitle() + ); }; } - public function getQueryKeys($data) + public function getQueryKeys($data): array { return ['goal_aggregator']; } - public function getTitle() + public function getTitle(): string { return 'Group social work actions by goal'; } diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/GoalResultAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/GoalResultAggregator.php new file mode 100644 index 000000000..86bfcd71a --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/GoalResultAggregator.php @@ -0,0 +1,94 @@ +resultRepository = $resultRepository; + $this->translatableStringHelper = $translatableStringHelper; + } + + + /** + * @inheritDoc + */ + public function getLabels($key, array $values, $data) + { + return function ($value): string { + if ('_header' === $value) { + return 'Goal and result Type'; + } + + //$g = $this->resultRepository->find($value); + + return + $value + //$this->translatableStringHelper->localize( + // $g->getTitle() + //) + ; + }; + } + + /** + * @inheritDoc + */ + public function getQueryKeys($data): array + { + return ['goal_result_aggregator']; + } + + /** + * @inheritDoc + */ + public function buildForm(FormBuilderInterface $builder) + { + // no form + } + + /** + * @inheritDoc + */ + public function getTitle(): string + { + return 'Group social work actions by goal and result'; + } + + /** + * @inheritDoc + */ + public function addRole(): ?string + { + return null; + } + + /** + * @inheritDoc + */ + public function alterQuery(QueryBuilder $qb, $data) + { + // TODO: Implement alterQuery() method. + } + + /** + * @inheritDoc + */ + public function applyOn(): string + { + return Declarations::SOCIAL_WORK_ACTION_TYPE; + } +} \ No newline at end of file diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ResultAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ResultAggregator.php index 47391ed69..2bbd8445c 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ResultAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ResultAggregator.php @@ -60,7 +60,7 @@ final class ResultAggregator implements AggregatorInterface } } - public function applyOn() + public function applyOn(): string { return Declarations::SOCIAL_WORK_ACTION_TYPE; } @@ -77,18 +77,20 @@ final class ResultAggregator implements AggregatorInterface return 'Result Type'; } - $g = $this->resultRepository->find($value); + $r = $this->resultRepository->find($value); - return $this->translatableStringHelper->localize($g->getTitle()); + return $this->translatableStringHelper->localize( + $r->getTitle() + ); }; } - public function getQueryKeys($data) + public function getQueryKeys($data): array { return ['result_aggregator']; } - public function getTitle() + public function getTitle(): string { return 'Group social work actions by result'; } diff --git a/src/Bundle/ChillPersonBundle/config/services/exports_social_actions.yaml b/src/Bundle/ChillPersonBundle/config/services/exports_social_actions.yaml index d5f7376db..450899659 100644 --- a/src/Bundle/ChillPersonBundle/config/services/exports_social_actions.yaml +++ b/src/Bundle/ChillPersonBundle/config/services/exports_social_actions.yaml @@ -79,3 +79,10 @@ services: autoconfigure: true 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 } diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index dc53f4839..ca48fbb7a 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -560,8 +560,11 @@ Group by treating agent: Grouper les actions par agent traitant Group social work actions by action type: Grouper les actions par type Group social work actions by goal: Grouper les actions par objectif -Goal Type: Objectif Group social work actions by result: Grouper les actions par résultat +Group social work actions by goal and result: Grouper les actions par objectif et résultat +Goal Type: Objectif +Result Type: Résultat +Goal and result Type: Objectif et résultat ## evaluations filters/aggr Filter by evaluation type: Filtrer les évaluations par type From 37d49e1123595ec9cabe155e7a7f9125c7c6d455 Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Mon, 19 Sep 2022 11:46:53 +0200 Subject: [PATCH 40/41] fix goal aggregator error --- .../Aggregator/SocialWorkAggregators/GoalAggregator.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/GoalAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/GoalAggregator.php index 21c13cef9..bc534c678 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/GoalAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/GoalAggregator.php @@ -41,7 +41,7 @@ final class GoalAggregator implements AggregatorInterface $qb->join('acpw.goals', 'goal'); } - $qb->addSelect('goal.id as goal_aggregator'); + $qb->addSelect('IDENTITY(goal.goal) as goal_aggregator'); $groupBy = $qb->getDQLPart('groupBy'); @@ -70,7 +70,7 @@ final class GoalAggregator implements AggregatorInterface } $g = $this->goalRepository->find($value); - + return $this->translatableStringHelper->localize( $g->getTitle() ); From 91af01336a1b21acdcf06e972cda9c4f6a3c2aa2 Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Mon, 19 Sep 2022 13:46:24 +0200 Subject: [PATCH 41/41] fix goalResult aggregator --- .../GoalResultAggregator.php | 78 +++++++++++++++---- .../ResultAggregator.php | 14 +--- 2 files changed, 64 insertions(+), 28 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/GoalResultAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/GoalResultAggregator.php index 86bfcd71a..aeced53d7 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/GoalResultAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/GoalResultAggregator.php @@ -5,20 +5,26 @@ namespace Chill\PersonBundle\Export\Aggregator\SocialWorkAggregators; use Chill\MainBundle\Export\AggregatorInterface; use Chill\MainBundle\Templating\TranslatableStringHelper; use Chill\PersonBundle\Export\Declarations; +use Chill\PersonBundle\Repository\SocialWork\GoalRepository; +use Chill\PersonBundle\Repository\SocialWork\ResultRepository; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; class GoalResultAggregator implements AggregatorInterface { - //private ResultRepository $resultRepository; + private ResultRepository $resultRepository; + + private GoalRepository $goalRepository; private TranslatableStringHelper $translatableStringHelper; public function __construct( - //ResultRepository $resultRepository, + ResultRepository $resultRepository, + GoalRepository $goalRepository, TranslatableStringHelper $translatableStringHelper ) { - //$this->resultRepository = $resultRepository; + $this->resultRepository = $resultRepository; + $this->goalRepository = $goalRepository; $this->translatableStringHelper = $translatableStringHelper; } @@ -28,19 +34,35 @@ class GoalResultAggregator implements AggregatorInterface */ public function getLabels($key, array $values, $data) { - return function ($value): string { - if ('_header' === $value) { - return 'Goal and result Type'; + return function ($value) use ($key): string { + switch ($key) { + case 'goal_aggregator': + + if ('_header' === $value) { + return 'Goal Type'; + } + + $g = $this->goalRepository->find($value); + + return $this->translatableStringHelper->localize( + $g->getTitle() + ); + + case 'result_aggregator': + + if ('_header' === $value) { + return 'Result Type'; + } + + $r = $this->resultRepository->find($value); + + return $this->translatableStringHelper->localize( + $r->getTitle() + ); + + default: + throw new \LogicException(); } - - //$g = $this->resultRepository->find($value); - - return - $value - //$this->translatableStringHelper->localize( - // $g->getTitle() - //) - ; }; } @@ -49,7 +71,10 @@ class GoalResultAggregator implements AggregatorInterface */ public function getQueryKeys($data): array { - return ['goal_result_aggregator']; + return [ + 'goal_aggregator', + 'result_aggregator' + ]; } /** @@ -81,7 +106,26 @@ class GoalResultAggregator implements AggregatorInterface */ public function alterQuery(QueryBuilder $qb, $data) { - // TODO: Implement alterQuery() method. + if (!in_array('goal', $qb->getAllAliases(), true)) { + $qb->join('acpw.goals', 'goal'); + } + + if (!in_array('goalresult', $qb->getAllAliases(), true)) { + $qb->join('goal.results', 'goalresult'); + } + + $qb->addSelect('IDENTITY(goal.goal) as goal_aggregator'); + $qb->addSelect('goalresult.id as result_aggregator'); + + $groupBy = $qb->getDQLPart('groupBy'); + + if (!empty($groupBy)) { + $qb->addGroupBy('goal_aggregator'); + } else { + $qb->groupBy('goal_aggregator'); + } + + $qb->addGroupBy('result_aggregator'); } /** diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ResultAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ResultAggregator.php index 2bbd8445c..8f7ac0624 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ResultAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ResultAggregator.php @@ -37,19 +37,11 @@ final class ResultAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { - if (!in_array('acpwresult', $qb->getAllAliases(), true)) { - $qb->join('acpw.results', 'acpwresult'); + if (!in_array('result', $qb->getAllAliases(), true)) { + $qb->join('acpw.results', 'result'); } - if (!in_array('goal', $qb->getAllAliases(), true)) { - $qb->join('acpw.goals', 'goal'); - } - - if (!in_array('goalresult', $qb->getAllAliases(), true)) { - $qb->join('goal.results', 'goalresult'); - } - - $qb->addSelect('acpwresult.id, IDENTITY(goal.results) as result_aggregator'); + $qb->addSelect('result.id as result_aggregator'); $groupBy = $qb->getDQLPart('groupBy');