From ecb8ef0146fb4ea0b32731f10a03453d9c1ae24c Mon Sep 17 00:00:00 2001 From: Lucas Silva Date: Tue, 21 Mar 2023 14:34:38 +0100 Subject: [PATCH 001/321] add notification service for AccompanyingPeriodWork in show --- ...ompanyingPeriodWorkNotificationHandler.php | 46 +++++++++++++++++++ .../AccompanyingCourseWork/_item.html.twig | 7 +++ .../AccompanyingCourseWork/show.html.twig | 27 +++++++++-- .../showInNotification.html.twig | 28 +++++++++++ .../showInNotification.html.twig | 1 + .../config/services/notification.yaml | 3 ++ 6 files changed, 109 insertions(+), 3 deletions(-) create mode 100644 src/Bundle/ChillPersonBundle/Notification/AccompanyingPeriodWorkNotificationHandler.php create mode 100644 src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showInNotification.html.twig diff --git a/src/Bundle/ChillPersonBundle/Notification/AccompanyingPeriodWorkNotificationHandler.php b/src/Bundle/ChillPersonBundle/Notification/AccompanyingPeriodWorkNotificationHandler.php new file mode 100644 index 000000000..dbb30e983 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Notification/AccompanyingPeriodWorkNotificationHandler.php @@ -0,0 +1,46 @@ +accompanyingPeriodWorkRepository = $accompanyingPeriodWorkRepository; + } + + public function getTemplate(Notification $notification, array $options = []): string + { + return 'ChillPersonBundle:AccompanyingCourseWork:showInNotification.html.twig'; + } + + public function getTemplateData(Notification $notification, array $options = []): array + { + return [ + 'notification' => $notification, + 'work' => $this->accompanyingPeriodWorkRepository->find($notification->getRelatedEntityId()), + ]; + } + + public function supports(Notification $notification, array $options = []): bool + { + return $notification->getRelatedEntityClass() === AccompanyingPeriodWork::class; + } +} diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/_item.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/_item.html.twig index 001ac1661..728554aaf 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/_item.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/_item.html.twig @@ -129,6 +129,13 @@ {% if displayAction is defined and displayAction == true %} diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showInNotification.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showInNotification.html.twig new file mode 100644 index 000000000..70a1a0980 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showInNotification.html.twig @@ -0,0 +1,28 @@ +{% macro recordAction(work) %} +
  • + +
  • +{% endmacro %} +{% if work is not null %} +
    + {% if is_granted('CHILL_PERSON_ACCOMPANYING_PERIOD_SEE', work) %} + {% else %} + {% endif %} + {% include 'ChillPersonBundle:AccompanyingCourseWork:_item.html.twig' with { + 'itemBlocClass': 'bg-chill-llight-gray', + 'displayAction': true, + 'displayContent': 'short', + 'displayFontSmall': true, + 'w': work + } %} +
    + {{ 'This is the minimal period details'|trans ~ ': ' ~ work.id }}
    + {{ 'You are getting a notification for a period you are not allowed to see'|trans }} +
    +
    +{% else %} +
    + {{ 'You are getting a notification for a period which does not exists any more'|trans }} +
    +{% endif %} diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/showInNotification.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/showInNotification.html.twig index 630dcf100..d6d13cd17 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/showInNotification.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/showInNotification.html.twig @@ -6,6 +6,7 @@ {% endmacro %} {% if period is not null %} + {{ dump(period) }}
    {% if is_granted('CHILL_PERSON_ACCOMPANYING_PERIOD_SEE', period) %} {% include 'ChillPersonBundle:AccompanyingPeriod:_list_item.html.twig' with { diff --git a/src/Bundle/ChillPersonBundle/config/services/notification.yaml b/src/Bundle/ChillPersonBundle/config/services/notification.yaml index a7c9f4142..7fd64bfbf 100644 --- a/src/Bundle/ChillPersonBundle/config/services/notification.yaml +++ b/src/Bundle/ChillPersonBundle/config/services/notification.yaml @@ -2,3 +2,6 @@ services: Chill\PersonBundle\Notification\AccompanyingPeriodNotificationHandler: autowire: true autoconfigure: true + Chill\PersonBundle\Notification\AccompanyingPeriodWorkNotificationHandler: + autowire: true + autoconfigure: true From 457d71b4f3e0870555bd3ebc12b840d09a633ee6 Mon Sep 17 00:00:00 2001 From: Lucas Silva Date: Tue, 21 Mar 2023 16:03:22 +0100 Subject: [PATCH 002/321] add service + template pour documents --- ...eriodWorkEvaluationNotificationHandler.php | 46 +++++++++++++++++++ .../_objectifs_results_evaluations.html.twig | 6 ++- .../showEvaluationInNotification.html.twig | 24 ++++++++++ .../config/services/notification.yaml | 3 ++ 4 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 src/Bundle/ChillPersonBundle/Notification/AccompanyingPeriodWorkEvaluationNotificationHandler.php create mode 100644 src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showEvaluationInNotification.html.twig diff --git a/src/Bundle/ChillPersonBundle/Notification/AccompanyingPeriodWorkEvaluationNotificationHandler.php b/src/Bundle/ChillPersonBundle/Notification/AccompanyingPeriodWorkEvaluationNotificationHandler.php new file mode 100644 index 000000000..63e395a98 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Notification/AccompanyingPeriodWorkEvaluationNotificationHandler.php @@ -0,0 +1,46 @@ +accompanyingPeriodWorkEvaluationRepository = $accompanyingPeriodWorkEvaluationRepository; + } + + public function getTemplate(Notification $notification, array $options = []): string + { + return 'ChillPersonBundle:AccompanyingCourseWork:showEvaluationInNotification.html.twig'; + } + + public function getTemplateData(Notification $notification, array $options = []): array + { + return [ + 'notification' => $notification, + 'evaluation' => $this->accompanyingPeriodWorkEvaluationRepository->find($notification->getRelatedEntityId()), + ]; + } + + public function supports(Notification $notification, array $options = []): bool + { + return $notification->getRelatedEntityClass() === AccompanyingPeriodWorkEvaluation::class; + } +} diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/_objectifs_results_evaluations.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/_objectifs_results_evaluations.html.twig index 0dd0cc84a..3778f312b 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/_objectifs_results_evaluations.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/_objectifs_results_evaluations.html.twig @@ -129,13 +129,15 @@ {% import "@ChillDocStore/Macro/macro.html.twig" as m %} {% import "@ChillDocStore/Macro/macro_mimeicon.html.twig" as mm %} - {% if e.documents|length > 0 %} {% for d in e.documents %} + {% endfor %} @@ -143,7 +145,7 @@ {% else %} {{ 'No document found'|trans }} {% endif %} - + {% endif %} diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showEvaluationInNotification.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showEvaluationInNotification.html.twig new file mode 100644 index 000000000..d35cf44c3 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showEvaluationInNotification.html.twig @@ -0,0 +1,24 @@ +{% macro recordAction(evaluation) %} +
  • + +
  • +{% endmacro %} +{% if evaluation is not null %} +
    + {% if is_granted('CHILL_PERSON_ACCOMPANYING_PERIOD_SEE', evaluation) %} + {% else %} + {% endif %} + {% include 'ChillPersonBundle:AccompanyingCourseWork:_objectifs_results_evaluations.html.twig' with { + 'w': evaluation.accompanyingPeriodWork + } %} +
    + {{ 'This is the minimal period details'|trans ~ ': ' ~ evaluation.id }}
    + {{ 'You are getting a notification for a period you are not allowed to see'|trans }} +
    +
    +{% else %} +
    + {{ 'You are getting a notification for a period which does not exists any more'|trans }} +
    +{% endif %} diff --git a/src/Bundle/ChillPersonBundle/config/services/notification.yaml b/src/Bundle/ChillPersonBundle/config/services/notification.yaml index 7fd64bfbf..360873bee 100644 --- a/src/Bundle/ChillPersonBundle/config/services/notification.yaml +++ b/src/Bundle/ChillPersonBundle/config/services/notification.yaml @@ -5,3 +5,6 @@ services: Chill\PersonBundle\Notification\AccompanyingPeriodWorkNotificationHandler: autowire: true autoconfigure: true + Chill\PersonBundle\Notification\AccompanyingPeriodWorkEvaluationNotificationHandler: + autowire: true + autoconfigure: true From 1a759cabe4fc369ba6bd6eac99303d774b6816ee Mon Sep 17 00:00:00 2001 From: Lucas Silva Date: Wed, 22 Mar 2023 18:11:41 +0100 Subject: [PATCH 003/321] changing evaluation for document -> no render for twig --- ...kEvaluationDocumentNotificationHandler.php} | 18 +++++++++--------- .../_objectifs_results_evaluations.html.twig | 4 +++- ...EvaluationDocumentInNotification.html.twig} | 12 +++++++----- .../config/services/notification.yaml | 2 +- 4 files changed, 20 insertions(+), 16 deletions(-) rename src/Bundle/ChillPersonBundle/Notification/{AccompanyingPeriodWorkEvaluationNotificationHandler.php => AccompanyingPeriodWorkEvaluationDocumentNotificationHandler.php} (60%) rename src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/{showEvaluationInNotification.html.twig => showEvaluationDocumentInNotification.html.twig} (81%) diff --git a/src/Bundle/ChillPersonBundle/Notification/AccompanyingPeriodWorkEvaluationNotificationHandler.php b/src/Bundle/ChillPersonBundle/Notification/AccompanyingPeriodWorkEvaluationDocumentNotificationHandler.php similarity index 60% rename from src/Bundle/ChillPersonBundle/Notification/AccompanyingPeriodWorkEvaluationNotificationHandler.php rename to src/Bundle/ChillPersonBundle/Notification/AccompanyingPeriodWorkEvaluationDocumentNotificationHandler.php index 63e395a98..1f3ed0fb6 100644 --- a/src/Bundle/ChillPersonBundle/Notification/AccompanyingPeriodWorkEvaluationNotificationHandler.php +++ b/src/Bundle/ChillPersonBundle/Notification/AccompanyingPeriodWorkEvaluationDocumentNotificationHandler.php @@ -14,33 +14,33 @@ namespace Chill\PersonBundle\Notification; use Chill\MainBundle\Entity\Notification; use Chill\MainBundle\Notification\NotificationHandlerInterface; -use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluation; -use Chill\PersonBundle\Repository\AccompanyingPeriod\AccompanyingPeriodWorkEvaluationRepository; +use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluationDocument; +use Chill\PersonBundle\Repository\AccompanyingPeriod\AccompanyingPeriodWorkEvaluationDocumentRepository; -final class AccompanyingPeriodWorkEvaluationNotificationHandler implements NotificationHandlerInterface +final class AccompanyingPeriodWorkEvaluationDocumentNotificationHandler implements NotificationHandlerInterface { - private AccompanyingPeriodWorkEvaluationRepository $accompanyingPeriodWorkEvaluationRepository; + private AccompanyingPeriodWorkEvaluationDocumentRepository $accompanyingPeriodWorkEvaluationDocumentRepository; - public function __construct(AccompanyingPeriodWorkEvaluationRepository $accompanyingPeriodWorkEvaluationRepository) + public function __construct(AccompanyingPeriodWorkEvaluationDocumentRepository $accompanyingPeriodWorkEvaluationDocumentRepository) { - $this->accompanyingPeriodWorkEvaluationRepository = $accompanyingPeriodWorkEvaluationRepository; + $this->accompanyingPeriodWorkEvaluationDocumentRepository = $accompanyingPeriodWorkEvaluationDocumentRepository; } public function getTemplate(Notification $notification, array $options = []): string { - return 'ChillPersonBundle:AccompanyingCourseWork:showEvaluationInNotification.html.twig'; + return 'ChillPersonBundle:AccompanyingCourseWork:showEvaluationDocumentInNotification.html.twig'; } public function getTemplateData(Notification $notification, array $options = []): array { return [ 'notification' => $notification, - 'evaluation' => $this->accompanyingPeriodWorkEvaluationRepository->find($notification->getRelatedEntityId()), + 'document' => $this->accompanyingPeriodWorkEvaluationDocumentRepository->find($notification->getRelatedEntityId()), ]; } public function supports(Notification $notification, array $options = []): bool { - return $notification->getRelatedEntityClass() === AccompanyingPeriodWorkEvaluation::class; + return $notification->getRelatedEntityClass() === AccompanyingPeriodWorkEvaluationDocument::class; } } diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/_objectifs_results_evaluations.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/_objectifs_results_evaluations.html.twig index 3778f312b..029e347b1 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/_objectifs_results_evaluations.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/_objectifs_results_evaluations.html.twig @@ -130,13 +130,15 @@ {% import "@ChillDocStore/Macro/macro.html.twig" as m %} {% import "@ChillDocStore/Macro/macro_mimeicon.html.twig" as mm %} {% if e.documents|length > 0 %} +
    {{ d.title }} {{ mm.mimeIcon(d.storedObject.type) }} + + {{ d.storedObject|chill_document_button_group(d.title, is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_UPDATE', w), {'small': true}) }}
    {% for d in e.documents %} + {{ dump(d) }} diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showEvaluationInNotification.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showEvaluationDocumentInNotification.html.twig similarity index 81% rename from src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showEvaluationInNotification.html.twig rename to src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showEvaluationDocumentInNotification.html.twig index d35cf44c3..b9fd07a11 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showEvaluationInNotification.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showEvaluationDocumentInNotification.html.twig @@ -1,19 +1,21 @@ -{% macro recordAction(evaluation) %} +{% macro recordAction(document) %}
  • {% endmacro %} -{% if evaluation is not null %} +{% if document is not null %}
    - {% if is_granted('CHILL_PERSON_ACCOMPANYING_PERIOD_SEE', evaluation) %} + {% if is_granted('CHILL_PERSON_ACCOMPANYING_PERIOD_SEE', document) %} {% else %} {% endif %} + {{ dump(document) }} {% include 'ChillPersonBundle:AccompanyingCourseWork:_objectifs_results_evaluations.html.twig' with { - 'w': evaluation.accompanyingPeriodWork + + 'w': document.accompanyingPeriodWorkEvaluation.accompanyingPeriodWork } %}
    - {{ 'This is the minimal period details'|trans ~ ': ' ~ evaluation.id }}
    + {{ 'This is the minimal period details'|trans ~ ': ' ~ document.id }}
    {{ 'You are getting a notification for a period you are not allowed to see'|trans }}
    diff --git a/src/Bundle/ChillPersonBundle/config/services/notification.yaml b/src/Bundle/ChillPersonBundle/config/services/notification.yaml index 360873bee..f5d227429 100644 --- a/src/Bundle/ChillPersonBundle/config/services/notification.yaml +++ b/src/Bundle/ChillPersonBundle/config/services/notification.yaml @@ -5,6 +5,6 @@ services: Chill\PersonBundle\Notification\AccompanyingPeriodWorkNotificationHandler: autowire: true autoconfigure: true - Chill\PersonBundle\Notification\AccompanyingPeriodWorkEvaluationNotificationHandler: + Chill\PersonBundle\Notification\AccompanyingPeriodWorkEvaluationDocumentNotificationHandler: autowire: true autoconfigure: true From e850f67b0095aeac8601af69fe04074a1442134e Mon Sep 17 00:00:00 2001 From: Lucas Silva Date: Thu, 23 Mar 2023 14:59:32 +0100 Subject: [PATCH 004/321] rajout du voter, pour document et action dans la notif -> affiche les documents mais aussi le fais de partager dans notification create --- .../AccompanyingCourseWork/_item.html.twig | 2 +- .../_objectifs_results_evaluations.html.twig | 7 +++---- .../AccompanyingCourseWork/show.html.twig | 4 ++-- ...EvaluationDocumentInNotification.html.twig | 20 +++++++++---------- .../showInNotification.html.twig | 6 +++--- 5 files changed, 19 insertions(+), 20 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/_item.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/_item.html.twig index 728554aaf..76c61407d 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/_item.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/_item.html.twig @@ -131,7 +131,7 @@
    • - diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/_objectifs_results_evaluations.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/_objectifs_results_evaluations.html.twig index 029e347b1..4f5d36230 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/_objectifs_results_evaluations.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/_objectifs_results_evaluations.html.twig @@ -133,13 +133,12 @@
    {{ d.title }} {{ mm.mimeIcon(d.storedObject.type) }} - + {{ d.storedObject|chill_document_button_group(d.title, is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_UPDATE', w), {'small': true}) }}
    {% for d in e.documents %} - {{ dump(d) }} - + {% endfor %} diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/show.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/show.html.twig index 016ac10bb..bd83310b7 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/show.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/show.html.twig @@ -46,11 +46,11 @@
  • - +
  • {% else %} - + {% endif %} diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showEvaluationDocumentInNotification.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showEvaluationDocumentInNotification.html.twig index b9fd07a11..83ba7bf91 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showEvaluationDocumentInNotification.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showEvaluationDocumentInNotification.html.twig @@ -6,18 +6,18 @@ {% endmacro %} {% if document is not null %}
    - {% if is_granted('CHILL_PERSON_ACCOMPANYING_PERIOD_SEE', document) %} + {% if is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_EVALUATION_DOCUMENT_SHOW', document) %} + {% include 'ChillPersonBundle:AccompanyingCourseWork:_objectifs_results_evaluations.html.twig' with { + 'w': document.accompanyingPeriodWorkEvaluation.accompanyingPeriodWork, + 'd': document.storedObject, + 'displayContent': 'long', + } %} {% else %} +
    + {{ 'This is the minimal period details'|trans ~ ': ' ~ document.id }}
    + {{ 'You are getting a notification for a period you are not allowed to see'|trans }} +
    {% endif %} - {{ dump(document) }} - {% include 'ChillPersonBundle:AccompanyingCourseWork:_objectifs_results_evaluations.html.twig' with { - - 'w': document.accompanyingPeriodWorkEvaluation.accompanyingPeriodWork - } %} -
    - {{ 'This is the minimal period details'|trans ~ ': ' ~ document.id }}
    - {{ 'You are getting a notification for a period you are not allowed to see'|trans }} -
    {% else %}
    diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showInNotification.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showInNotification.html.twig index 70a1a0980..311692030 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showInNotification.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showInNotification.html.twig @@ -6,9 +6,7 @@ {% endmacro %} {% if work is not null %}
    - {% if is_granted('CHILL_PERSON_ACCOMPANYING_PERIOD_SEE', work) %} - {% else %} - {% endif %} + {% if is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_SEE', work) %} {% include 'ChillPersonBundle:AccompanyingCourseWork:_item.html.twig' with { 'itemBlocClass': 'bg-chill-llight-gray', 'displayAction': true, @@ -16,10 +14,12 @@ 'displayFontSmall': true, 'w': work } %} + {% else %}
    {{ 'This is the minimal period details'|trans ~ ': ' ~ work.id }}
    {{ 'You are getting a notification for a period you are not allowed to see'|trans }}
    + {% endif %}
    {% else %}
    From afb25276ee40e3f1adaa4871d5d19735853c2a18 Mon Sep 17 00:00:00 2001 From: Lucas Silva Date: Thu, 23 Mar 2023 15:32:30 +0100 Subject: [PATCH 005/321] enleve l'id en bas de page --- .../Resources/views/AccompanyingCourseWork/show.html.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/show.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/show.html.twig index bd83310b7..73b871260 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/show.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/show.html.twig @@ -55,7 +55,7 @@ {% endif %}
    - {{ work.id }} + {% if is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_UPDATE', work) %}
  • Date: Thu, 30 Mar 2023 00:07:38 +0200 Subject: [PATCH 006/321] UX: Better use of flex-table and tables in budget twig templates --- .../Resources/views/Budget/_budget.html.twig | 20 ++++++------------- .../views/Budget/_current_budget.html.twig | 15 +++----------- .../Resources/views/Budget/_macros.html.twig | 8 +++----- .../Resources/views/Person/index.html.twig | 10 ++++------ 4 files changed, 16 insertions(+), 37 deletions(-) diff --git a/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_budget.html.twig b/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_budget.html.twig index 6e248bf0c..e11a822cd 100644 --- a/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_budget.html.twig +++ b/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_budget.html.twig @@ -32,28 +32,21 @@ {% endif %} {% endfor %} -

    {{ 'Actual budget'|trans }}

    - {% if actualCharges|length > 0 or actualResources|length > 0 %} - {% include 'ChillBudgetBundle:Budget:_current_budget.html.twig' with { + {% include '@ChillBudget/Budget/_current_budget.html.twig' with { 'actualResources': actualResources, 'actualCharges': actualCharges, 'results': results, 'entity': entity } %} {% else %} -
    -
    -

    {{ "There isn't any element recorded"|trans }}

    -
    -
    +

    {{ "There isn't any element recorded"|trans }}

    {% endif %} {% if pastCharges|length > 0 or pastResources|length > 0 %} -

    {{ 'Past budget'|trans }}

    - - {% include 'ChillBudgetBundle:Budget:_past_budget.html.twig' with { +

    {{ 'Past budget'|trans }}

    a + {% include '@ChillBudget/Budget/_past_budget.html.twig' with { 'pastCharges': pastCharges, 'pastResources': pastResources, 'entity': entity @@ -61,9 +54,8 @@ {% endif %} {% if futureCharges|length > 0 or futureResources|length > 0 %} -

    {{ 'Future budget'|trans }}

    - - {% include 'ChillBudgetBundle:Budget:_future_budget.html.twig' with { +

    {{ 'Future budget'|trans }}

    + {% include '@ChillBudget/Budget/_future_budget.html.twig' with { 'futureResources': futureResources, 'futureCharges': futureCharges, 'entity': entity diff --git a/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_current_budget.html.twig b/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_current_budget.html.twig index b996da211..98e784cc5 100644 --- a/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_current_budget.html.twig +++ b/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_current_budget.html.twig @@ -1,30 +1,21 @@ -{% from 'ChillBudgetBundle:Budget:_macros.html.twig' import table_elements, table_results %} +{% from '@ChillBudget/Budget/_macros.html.twig' import table_elements, table_results %} {#

    {{ 'Actual budget'|trans }}

    #} -
    +

    {{ 'Actual resources'|trans }}

    - {% if actualResources|length > 0 %} -
    {{ table_elements(actualResources, 'resource') }} -
    {% else %} -
    {{ 'No resources registered'|trans }} -
    {% endif %}
    -
    +

    {{ 'Actual charges'|trans }}

    {% if actualCharges|length > 0 %} -
    {{ table_elements(actualCharges, 'charge') }} -
    {% else %} -
    {{ 'No charges registered'|trans }} -
    {% endif %}
    diff --git a/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_macros.html.twig b/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_macros.html.twig index e8d10578b..42090984a 100644 --- a/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_macros.html.twig +++ b/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_macros.html.twig @@ -1,5 +1,5 @@ {% macro table_elements(elements, family) %} -
  • {{ d.title }} {{ mm.mimeIcon(d.storedObject.type) }} - - + + {{ d.storedObject|chill_document_button_group(d.title, is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_UPDATE', w), {'small': true}) }}
    +
    @@ -28,7 +28,7 @@ {% if f.endDate is not null %} {{ f.startDate|format_date('short') ~ ' - ' ~ f.endDate|format_date('short') }} {% else %} - {{ f.startDate|format_date('short') ~ ' - ...' }} + {{ 'depuis le ' ~ f.startDate|format_date('short') }} {% endif %} - - - + - From 1abaf2acb024b12985825a96831b22a0fcf7045a Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Wed, 10 May 2023 10:28:36 +0200 Subject: [PATCH 040/321] DX: add help and description to use ImportSocialWorkMetadata command --- .../Command/ImportSocialWorkMetadata.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Bundle/ChillPersonBundle/Command/ImportSocialWorkMetadata.php b/src/Bundle/ChillPersonBundle/Command/ImportSocialWorkMetadata.php index 91615935c..8085732ba 100644 --- a/src/Bundle/ChillPersonBundle/Command/ImportSocialWorkMetadata.php +++ b/src/Bundle/ChillPersonBundle/Command/ImportSocialWorkMetadata.php @@ -42,10 +42,18 @@ final class ImportSocialWorkMetadata extends Command protected function configure() { + $description = 'Imports a structured table containing social issues, social actions, objectives, results and evaluations.'; + $help = 'File to csv format, no headers, semi-colon as delimiter, datas sorted by alphabetical order, column after column.'. PHP_EOL + . 'Columns are: social issues parent, social issues child, social actions parent, social actions child, goals, results, evaluations.'. PHP_EOL + . PHP_EOL + . 'See social_work_metadata.csv as example.'. PHP_EOL; + $this ->setName('chill:person:import-socialwork') ->addOption('filepath', 'f', InputOption::VALUE_REQUIRED, 'The file to import.') - ->addOption('language', 'l', InputOption::VALUE_OPTIONAL, 'The default language'); + ->addOption('language', 'l', InputOption::VALUE_OPTIONAL, 'The default language') + ->setDescription($description) + ->setHelp($help); } protected function execute(InputInterface $input, OutputInterface $output) From 8a684734e740d02975b46b98f82a285a7d6ab8df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 16 May 2023 23:24:33 +0200 Subject: [PATCH 041/321] Fixed: fix docgen normalization on household with "old" members When a household had old members, the indexes of each "current" members should be numerical and contiguous, to be transformed in a list. If this is not the case, the members are mapped to an associative array. This commit alter the generic DocGenObjectNormalizer to ensure that the ReadableCollection are normalized using the CollectionDocGenNormalizer as default, which do not preserve keys. --- .../Normalizer/CollectionDocGenNormalizer.php | 7 ++- .../Normalizer/DocGenObjectNormalizer.php | 9 ++++ .../CollectionDocGenNormalizerTest.php | 52 +++++++++++++++++++ .../Normalizer/HouseholdNormalizerTest.php | 52 ++++++++++++++++++- 4 files changed, 117 insertions(+), 3 deletions(-) create mode 100644 src/Bundle/ChillDocGeneratorBundle/tests/Serializer/Normalizer/CollectionDocGenNormalizerTest.php diff --git a/src/Bundle/ChillDocGeneratorBundle/Serializer/Normalizer/CollectionDocGenNormalizer.php b/src/Bundle/ChillDocGeneratorBundle/Serializer/Normalizer/CollectionDocGenNormalizer.php index 196018a03..b4e99bb98 100644 --- a/src/Bundle/ChillDocGeneratorBundle/Serializer/Normalizer/CollectionDocGenNormalizer.php +++ b/src/Bundle/ChillDocGeneratorBundle/Serializer/Normalizer/CollectionDocGenNormalizer.php @@ -13,6 +13,7 @@ namespace Chill\DocGeneratorBundle\Serializer\Normalizer; use ArrayObject; use Doctrine\Common\Collections\Collection; +use Doctrine\Common\Collections\ReadableCollection; use Symfony\Component\Serializer\Normalizer\ContextAwareNormalizerInterface; use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface; use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait; @@ -51,7 +52,9 @@ class CollectionDocGenNormalizer implements ContextAwareNormalizerInterface, Nor return false; } - return $data instanceof Collection - || (null === $data && Collection::class === ($context['docgen:expects'] ?? null)); + return $data instanceof ReadableCollection + || (null === $data && Collection::class === ($context['docgen:expects'] ?? null)) + || (null === $data && ReadableCollection::class === ($context['docgen:expects'] ?? null)) + ; } } diff --git a/src/Bundle/ChillDocGeneratorBundle/Serializer/Normalizer/DocGenObjectNormalizer.php b/src/Bundle/ChillDocGeneratorBundle/Serializer/Normalizer/DocGenObjectNormalizer.php index 3807ee9ee..bbf12b0fd 100644 --- a/src/Bundle/ChillDocGeneratorBundle/Serializer/Normalizer/DocGenObjectNormalizer.php +++ b/src/Bundle/ChillDocGeneratorBundle/Serializer/Normalizer/DocGenObjectNormalizer.php @@ -13,6 +13,7 @@ namespace Chill\DocGeneratorBundle\Serializer\Normalizer; use Chill\DocGeneratorBundle\Serializer\Helper\NormalizeNullValueHelper; use Chill\MainBundle\Templating\TranslatableStringHelperInterface; +use Doctrine\Common\Collections\ReadableCollection; use ReflectionClass; use RuntimeException; use Symfony\Component\PropertyAccess\PropertyAccess; @@ -271,6 +272,14 @@ class DocGenObjectNormalizer implements NormalizerAwareInterface, NormalizerInte if ($isTranslatable) { $data[$key] = $this->translatableStringHelper ->localize($value); + } elseif ($value instanceof ReadableCollection) { + // when normalizing collection, we should not preserve keys (to ensure that the result is a list) + // this is why we make call to the normalizer again to use the CollectionDocGenNormalizer + $data[$key] = + $this->normalizer->normalize($value, $format, array_merge( + $objectContext, + $attribute->getNormalizationContextForGroups($expectedGroups) + )); } elseif (is_iterable($value)) { $arr = []; diff --git a/src/Bundle/ChillDocGeneratorBundle/tests/Serializer/Normalizer/CollectionDocGenNormalizerTest.php b/src/Bundle/ChillDocGeneratorBundle/tests/Serializer/Normalizer/CollectionDocGenNormalizerTest.php new file mode 100644 index 000000000..7bfddadca --- /dev/null +++ b/src/Bundle/ChillDocGeneratorBundle/tests/Serializer/Normalizer/CollectionDocGenNormalizerTest.php @@ -0,0 +1,52 @@ +normalizer = self::$container->get(NormalizerInterface::class); + } + + public function testNormalizeFilteredArray(): void + { + $coll = new ArrayCollection([ + (object) ['v' => 'foo'], + (object) ['v' => 'bar'], + (object) ['v' => 'baz'], + ]); + + //filter to get non continuous indexes + $criteria = new Criteria(); + $criteria->where(Criteria::expr()->neq('v', 'bar')); + + $filtered = $coll->matching($criteria); + $normalized = $this->normalizer->normalize($filtered, 'docgen', []); + + self::assertIsArray($normalized); + self::assertArrayHasKey(0, $normalized); + self::assertArrayHasKey(1, $normalized); + } +} diff --git a/src/Bundle/ChillPersonBundle/Tests/Serializer/Normalizer/HouseholdNormalizerTest.php b/src/Bundle/ChillPersonBundle/Tests/Serializer/Normalizer/HouseholdNormalizerTest.php index acd4119a1..093b882ce 100644 --- a/src/Bundle/ChillPersonBundle/Tests/Serializer/Normalizer/HouseholdNormalizerTest.php +++ b/src/Bundle/ChillPersonBundle/Tests/Serializer/Normalizer/HouseholdNormalizerTest.php @@ -18,6 +18,7 @@ use Chill\PersonBundle\Entity\Person; use DateTimeImmutable; use Doctrine\ORM\EntityManagerInterface; use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; +use Symfony\Component\Serializer\Normalizer\AbstractNormalizer; use Symfony\Component\Serializer\Normalizer\NormalizerInterface; /** @@ -39,7 +40,7 @@ final class HouseholdNormalizerTest extends KernelTestCase $this->entityManager = self::$container->get(EntityManagerInterface::class); } - public function testNormalizationRecursive() + public function testNormalizationRecursive(): void { $person = new Person(); $person->setFirstName('ok')->setLastName('ok'); @@ -67,4 +68,53 @@ final class HouseholdNormalizerTest extends KernelTestCase $this->assertArrayHasKey('type', $normalized); $this->assertEquals('household', $normalized['type']); } + + /** + * When a household have old members (members which are not "current"), + * the indexes of the household must be reset to numerical and contiguous + * indexes. This ensure that it will be mapped as a list, not as an associative + * array. + */ + public function testHouseholdDocGenNormalizationWithOldMembers(): void + { + $previousPerson = new Person(); + $previousPerson->setFirstName('ok')->setLastName('ok'); + $this->entityManager->persist($previousPerson); + $member = new HouseholdMember(); + $household = new Household(); + $position = (new Position()) + ->setShareHousehold(true) + ->setAllowHolder(true); + + $member->setPerson($previousPerson) + ->setStartDate(new DateTimeImmutable('1 year ago')) + ->setEndDate(new DateTimeImmutable('1 month ago')) + ->setPosition($position); + + $household->addMember($member); + + $currentPerson1 = new Person(); + $currentPerson1->setFirstName('p1')->setLastName('p1'); + $this->entityManager->persist($currentPerson1); + $member = new HouseholdMember(); + $member->setPerson($currentPerson1) + ->setStartDate(new DateTimeImmutable('1 year ago')) + ->setPosition($position); + $household->addMember($member); + + $normalized = $this->normalizer->normalize( + $household, + 'docgen', + [ + AbstractNormalizer::GROUPS => ['docgen:read'], + 'docgen:expects' => Household::class, + 'docgen:person:with-household' => false, + 'docgen:person:with-relations' => false, + 'docgen:person:with-budget' => false, + ] + ); + + self::assertIsArray($normalized); + self::assertArrayHasKey(0, $normalized['currentMembers']); + } } From db9fef095ab4379b82a081011abcc90156aa42fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 17 May 2023 13:24:15 +0200 Subject: [PATCH 042/321] Fixed: force default values for cc users in workflow --- .../ChillMainBundle/Controller/WorkflowController.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Controller/WorkflowController.php b/src/Bundle/ChillMainBundle/Controller/WorkflowController.php index 36647612b..cfd28160c 100644 --- a/src/Bundle/ChillMainBundle/Controller/WorkflowController.php +++ b/src/Bundle/ChillMainBundle/Controller/WorkflowController.php @@ -359,9 +359,9 @@ class WorkflowController extends AbstractController } // TODO symfony 5: add those "future" on context ($workflow->apply($entityWorkflow, $transition, $context) - $entityWorkflow->futureCcUsers = $transitionForm['future_cc_users']->getData(); - $entityWorkflow->futureDestUsers = $transitionForm['future_dest_users']->getData(); - $entityWorkflow->futureDestEmails = $transitionForm['future_dest_emails']->getData(); + $entityWorkflow->futureCcUsers = $transitionForm['future_cc_users']->getData() ?? []; + $entityWorkflow->futureDestUsers = $transitionForm['future_dest_users']->getData() ?? []; + $entityWorkflow->futureDestEmails = $transitionForm['future_dest_emails']->getData() ?? []; $workflow->apply($entityWorkflow, $transition); From 8863e0a92efaadf6224c7d76341a12e94774025a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 17 May 2023 13:24:44 +0200 Subject: [PATCH 043/321] Fixed: force string on username --- src/Bundle/ChillMainBundle/Entity/User.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Entity/User.php b/src/Bundle/ChillMainBundle/Entity/User.php index a8ef88fbe..35b73786b 100644 --- a/src/Bundle/ChillMainBundle/Entity/User.php +++ b/src/Bundle/ChillMainBundle/Entity/User.php @@ -506,11 +506,11 @@ class User implements UserInterface * * @return User */ - public function setUsername($name) + public function setUsername(?string $name) { - $this->username = $name; + $this->username = (string) $name; - if (empty($this->getLabel())) { + if ("" === trim($this->getLabel())) { $this->setLabel($name); } From 66dc02735412e260dc1650214d3683d36e21042b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 17 May 2023 13:27:20 +0200 Subject: [PATCH 044/321] Fixed: fix first execution of accompanying period step change cronjob --- .../Lifecycle/AccompanyingPeriodStepChangeCronjob.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Bundle/ChillPersonBundle/AccompanyingPeriod/Lifecycle/AccompanyingPeriodStepChangeCronjob.php b/src/Bundle/ChillPersonBundle/AccompanyingPeriod/Lifecycle/AccompanyingPeriodStepChangeCronjob.php index bec31d45d..f637e70b9 100644 --- a/src/Bundle/ChillPersonBundle/AccompanyingPeriod/Lifecycle/AccompanyingPeriodStepChangeCronjob.php +++ b/src/Bundle/ChillPersonBundle/AccompanyingPeriod/Lifecycle/AccompanyingPeriodStepChangeCronjob.php @@ -27,7 +27,7 @@ readonly class AccompanyingPeriodStepChangeCronjob implements CronJobInterface { $now = $this->clock->now(); - if ($now->sub(new \DateInterval('P1D')) < $cronJobExecution->getLastStart()) { + if (null !== $cronJobExecution && $now->sub(new \DateInterval('P1D')) < $cronJobExecution->getLastStart()) { return false; } From fbd555e89aba7230b691931988c709809f6e2118 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 17 May 2023 16:05:53 +0200 Subject: [PATCH 045/321] Feature: add Household composition on household in docgen --- src/Bundle/ChillPersonBundle/Entity/Household/Household.php | 4 ++++ .../Entity/Household/HouseholdComposition.php | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/Bundle/ChillPersonBundle/Entity/Household/Household.php b/src/Bundle/ChillPersonBundle/Entity/Household/Household.php index 8a99c7eb4..74b8ed5f8 100644 --- a/src/Bundle/ChillPersonBundle/Entity/Household/Household.php +++ b/src/Bundle/ChillPersonBundle/Entity/Household/Household.php @@ -213,6 +213,10 @@ class Household return null; } + /** + * @Serializer\Groups({"docgen:read"}) + * @Serializer\SerializedName("current_composition") + */ public function getCurrentComposition(?DateTimeImmutable $at = null): ?HouseholdComposition { $at ??= new DateTimeImmutable('today'); diff --git a/src/Bundle/ChillPersonBundle/Entity/Household/HouseholdComposition.php b/src/Bundle/ChillPersonBundle/Entity/Household/HouseholdComposition.php index f11d1402b..65178c3ed 100644 --- a/src/Bundle/ChillPersonBundle/Entity/Household/HouseholdComposition.php +++ b/src/Bundle/ChillPersonBundle/Entity/Household/HouseholdComposition.php @@ -44,6 +44,7 @@ class HouseholdComposition implements TrackCreationInterface, TrackUpdateInterfa /** * @ORM\Column(type="date_immutable", nullable=true, options={"default": null}) * @Assert\GreaterThanOrEqual(propertyPath="startDate", groups={"Default", "household_composition"}) + * @Serializer\Groups({"docgen:read"}) */ private ?DateTimeImmutable $endDate = null; @@ -56,6 +57,7 @@ class HouseholdComposition implements TrackCreationInterface, TrackUpdateInterfa /** * @ORM\ManyToOne(targetEntity=HouseholdCompositionType::class) * @ORM\JoinColumn(nullable=false) + * @Serializer\Groups({"docgen:read"}) */ private ?HouseholdCompositionType $householdCompositionType = null; @@ -71,12 +73,14 @@ class HouseholdComposition implements TrackCreationInterface, TrackUpdateInterfa * @ORM\Column(type="integer", nullable=true, options={"default": null}) * @Assert\NotNull * @Assert\GreaterThanOrEqual(0, groups={"Default", "household_composition"}) + * @Serializer\Groups({"docgen:read"}) */ private ?int $numberOfChildren = null; /** * @ORM\Column(type="date_immutable", nullable=false) * @Assert\NotNull(groups={"Default", "household_composition"}) + * @Serializer\Groups({"docgen:read"}) */ private ?DateTimeImmutable $startDate = null; From 8a35c2e2eeb6f6bde0cb966b5264b264f0d982c4 Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Wed, 17 May 2023 16:28:51 +0200 Subject: [PATCH 046/321] Fix workflow regression with accompanying period work (introduced by commit 6b90a7d2a7 24/01/2023) --- .../views/Workflow/_accompanying_period_work.html.twig | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Bundle/ChillPersonBundle/Resources/views/Workflow/_accompanying_period_work.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/Workflow/_accompanying_period_work.html.twig index 49cd37180..9110bd212 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/Workflow/_accompanying_period_work.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/Workflow/_accompanying_period_work.html.twig @@ -3,6 +3,14 @@ {{ 'workflow.SocialAction deleted'|trans }} {% else %} +
    + {% include '@ChillPerson/AccompanyingCourseWork/_item.html.twig' with { + 'w': work, + 'displayAction': false, + 'displayContent': 'short', + 'itemBlocClass': 'bg-chill-llight-gray' + } %} +
    {% if display_action is defined and display_action == true %}
    diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/show.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/show.html.twig index 8d508539d..d32c1b700 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/show.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/show.html.twig @@ -35,6 +35,7 @@ {{ 'Back to the list'|trans }} +
  • {{ macro.workflowButton(work) }}
  • {% if accompanyingCourse.hasUser and accompanyingCourse.user is not same as(app.user) %} @@ -54,7 +55,6 @@ {% endif %}
  • -
  • {{ macro.workflowButton(work) }}
  • {% if is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_UPDATE', work) %}
  • Date: Tue, 23 May 2023 16:30:26 +0200 Subject: [PATCH 054/321] UX: [vue] Fix picto color in document actions dropdown --- .../public/vuejs/StoredObjectButton/ConvertButton.vue | 6 ++++++ .../public/vuejs/StoredObjectButton/DownloadButton.vue | 6 ++++++ .../public/vuejs/StoredObjectButton/WopiEditButton.vue | 3 +++ 3 files changed, 15 insertions(+) diff --git a/src/Bundle/ChillDocStoreBundle/Resources/public/vuejs/StoredObjectButton/ConvertButton.vue b/src/Bundle/ChillDocStoreBundle/Resources/public/vuejs/StoredObjectButton/ConvertButton.vue index aa99a223f..be482cf7e 100644 --- a/src/Bundle/ChillDocStoreBundle/Resources/public/vuejs/StoredObjectButton/ConvertButton.vue +++ b/src/Bundle/ChillDocStoreBundle/Resources/public/vuejs/StoredObjectButton/ConvertButton.vue @@ -44,3 +44,9 @@ async function download_and_open(event: Event): Promise { } + + diff --git a/src/Bundle/ChillDocStoreBundle/Resources/public/vuejs/StoredObjectButton/DownloadButton.vue b/src/Bundle/ChillDocStoreBundle/Resources/public/vuejs/StoredObjectButton/DownloadButton.vue index 98645873b..cbc314ff9 100644 --- a/src/Bundle/ChillDocStoreBundle/Resources/public/vuejs/StoredObjectButton/DownloadButton.vue +++ b/src/Bundle/ChillDocStoreBundle/Resources/public/vuejs/StoredObjectButton/DownloadButton.vue @@ -52,3 +52,9 @@ async function download_and_open(event: Event): Promise { } } + + diff --git a/src/Bundle/ChillDocStoreBundle/Resources/public/vuejs/StoredObjectButton/WopiEditButton.vue b/src/Bundle/ChillDocStoreBundle/Resources/public/vuejs/StoredObjectButton/WopiEditButton.vue index d68f60f86..ea244192e 100644 --- a/src/Bundle/ChillDocStoreBundle/Resources/public/vuejs/StoredObjectButton/WopiEditButton.vue +++ b/src/Bundle/ChillDocStoreBundle/Resources/public/vuejs/StoredObjectButton/WopiEditButton.vue @@ -40,5 +40,8 @@ async function beforeLeave(event: Event): Promise { From ef6a5e0b6bf320c155e3390769ecf50f4054128b Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Tue, 23 May 2023 16:32:08 +0200 Subject: [PATCH 055/321] UX: [vue] Change single button notification by dropdown button (edit workAction) --- .../vuejs/AccompanyingCourseWorkEdit/App.vue | 32 ++++++-- .../components/FormEvaluation.vue | 81 ++++++++++++------- 2 files changed, 77 insertions(+), 36 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/App.vue b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/App.vue index e6ee7de79..128148f8a 100644 --- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/App.vue +++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/App.vue @@ -296,13 +296,26 @@ @go-to-generate-workflow="goToGenerateWorkflow" >
  • +
  • + + @click="goToGenerateNotification(false)" + > +
  • +
  • -
  • -
  • - -
  • +
      +
    • + +
    • - - + + +
    • +
    • + + +
    • @@ -219,7 +232,10 @@ const i18n = { template_title: "Nom du template", browse: "Ajouter un document", replace: "Remplacer", - download: "Télécharger le fichier existant" + download: "Télécharger le fichier existant", + notification_notify_referrer: "Notifier le référent", + notification_notify_any: "Notifier d'autres utilisateurs", + notification_send: "Envoyer une notification", } } }; @@ -265,7 +281,8 @@ export default { }, computed: { ...mapState([ - 'isPosting' + 'isPosting', + 'work' ]), getTemplatesAvailables() { return this.$store.getters.getTemplatesAvailablesForEvaluation(this.evaluation.evaluation); @@ -395,10 +412,14 @@ export default { return this.$store.dispatch('submit', callback) .catch(e => { console.log(e); throw e; }); }, - goToGenerateDocumentNotification(document){ + goToGenerateDocumentNotification(document, tos){ const callback = (data) => { - let evaluation = data.accompanyingPeriodWorkEvaluations.find(e => e.key === this.evaluation.key); - window.location.assign(`/fr/notification/create?entityClass=Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluationDocument&entityId=${document.id}&returnPath=/fr/person/accompanying-period/work/${evaluation.id}/edit`) + let evaluation = data.accompanyingPeriodWorkEvaluations.find(e => e.key === this.evaluation.key); + if (tos === true) { + window.location.assign(`/fr/notification/create?entityClass=Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluationDocument&entityId=${document.id}&tos[0]=${this.$store.state.work.accompanyingPeriod.user.id}&returnPath=/fr/person/accompanying-period/work/${evaluation.id}/edit`) + } else { + window.location.assign(`/fr/notification/create?entityClass=Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluationDocument&entityId=${document.id}&returnPath=/fr/person/accompanying-period/work/${evaluation.id}/edit`) + } }; return this.$store.dispatch('submit', callback) .catch(e => {console.log(e); throw e}); From 53aa887da5c4168c1abe2f0ada16ee8fe009dc82 Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Tue, 23 May 2023 18:10:29 +0200 Subject: [PATCH 056/321] Fixed: [vue] add condition to use dropdown or single button --- .../vuejs/AccompanyingCourseWorkEdit/App.vue | 12 ++++++------ .../components/FormEvaluation.vue | 13 +++++++------ .../vuejs/AccompanyingCourseWorkEdit/store.js | 18 ++++++++++++++++++ 3 files changed, 31 insertions(+), 12 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/App.vue b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/App.vue index 128148f8a..072944192 100644 --- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/App.vue +++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/App.vue @@ -298,12 +298,7 @@
    • - - @@ -463,6 +458,7 @@ export default { 'isPosting', 'errors', 'templatesAvailablesForAction', + 'me', ]), ...mapGetters([ 'hasResultsForAction', @@ -520,6 +516,10 @@ export default { this.$store.commit('setPersonsPickedIds', v); } }, + AmIRefferer() { + return (!(this.work.accompanyingPeriod.user && this.me + && (this.work.accompanyingPeriod.user.id !== this.me.id))); + } }, methods: { toggleSelect() { diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/components/FormEvaluation.vue b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/components/FormEvaluation.vue index 1673c2f33..7d6678ec7 100644 --- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/components/FormEvaluation.vue +++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/components/FormEvaluation.vue @@ -116,12 +116,8 @@ >
    • - @@ -282,8 +278,13 @@ export default { computed: { ...mapState([ 'isPosting', - 'work' + 'work', + 'me', ]), + AmIRefferer() { + return (!(this.$store.state.work.accompanyingPeriod.user && this.$store.state.me + && (this.$store.state.work.accompanyingPeriod.user.id !== this.$store.state.me.id))); + }, getTemplatesAvailables() { return this.$store.getters.getTemplatesAvailablesForEvaluation(this.evaluation.evaluation); }, diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/store.js b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/store.js index 47e4b2d3f..9a46b741a 100644 --- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/store.js +++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/store.js @@ -35,6 +35,7 @@ const store = createStore({ referrers: window.accompanyingCourseWork.referrers, isPosting: false, errors: [], + me: null }, getters: { socialAction(state) { @@ -130,6 +131,9 @@ const store = createStore({ } }, mutations: { + setWhoAmiI(state, me) { + state.me = me; + }, setEvaluationsPicked(state, evaluations) { state.evaluationsPicked = evaluations.map((e, index) => { var k = Object.assign(e, { @@ -385,6 +389,19 @@ const store = createStore({ }, }, actions: { + getWhoAmI({ commit }) { + let url = `/api/1.0/main/whoami.json`; + window.fetch(url) + .then(response => { + if (response.ok) { + return response.json(); + } + throw { m: 'Error while retriving results for goal', s: response.status, b: response.body }; + }) + .then(data => { + commit('setWhoAmiI', data); + }); + }, updateThirdParty({ commit }, payload) { commit('updateThirdParty', payload); }, @@ -514,6 +531,7 @@ store.commit('setEvaluationsPicked', window.accompanyingCourseWork.accompanyingP store.dispatch('getReachablesResultsForAction'); store.dispatch('getReachablesGoalsForAction'); store.dispatch('getReachablesEvaluationsForAction'); +store.dispatch('getWhoAmI'); store.state.evaluationsPicked.forEach(evaluation => { store.dispatch('fetchTemplatesAvailablesForEvaluation', evaluation.evaluation) From 5351223d44af43d2a063eea6b408749128e0b263 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Tue, 23 May 2023 18:12:26 +0200 Subject: [PATCH 057/321] FIX [duplicates] reinstate gestion des doublons --- .../Actions/Remove/PersonMove.php | 69 ++++++++++++++----- .../Controller/PersonDuplicateController.php | 6 +- .../Menu/PersonMenuBuilder.php | 25 ++++--- .../views/PersonDuplicate/_sidepane.html.twig | 2 +- .../views/PersonDuplicate/confirm.html.twig | 8 +-- 5 files changed, 75 insertions(+), 35 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Actions/Remove/PersonMove.php b/src/Bundle/ChillPersonBundle/Actions/Remove/PersonMove.php index 13a62094d..8363134fd 100644 --- a/src/Bundle/ChillPersonBundle/Actions/Remove/PersonMove.php +++ b/src/Bundle/ChillPersonBundle/Actions/Remove/PersonMove.php @@ -13,7 +13,11 @@ namespace Chill\PersonBundle\Actions\Remove; use Chill\PersonBundle\Actions\ActionEvent; use Chill\PersonBundle\Entity\AccompanyingPeriod; +use Chill\PersonBundle\Entity\AccompanyingPeriodParticipation; +use Chill\PersonBundle\Entity\Household\HouseholdMember; +use Chill\PersonBundle\Entity\Household\PersonHouseholdAddress; use Chill\PersonBundle\Entity\Person; +use Chill\PersonBundle\Entity\Relationships\Relationship; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Mapping\ClassMetadata; use Symfony\Component\EventDispatcher\EventDispatcherInterface; @@ -42,9 +46,10 @@ class PersonMove protected $eventDispatcher; public function __construct( - EntityManagerInterface $em, + EntityManagerInterface $em, EventDispatcherInterface $eventDispatcher - ) { + ) + { $this->em = $em; $this->eventDispatcher = $eventDispatcher; } @@ -84,8 +89,11 @@ class PersonMove } foreach ($metadata->getAssociationMappings() as $field => $mapping) { - if (Person::class === $mapping['targetEntity']) { - if (in_array($metadata->getName(), $toDelete, true)) { + if (in_array($mapping['sourceEntity'], $this->getIgnoredEntities())) { + continue; + } + if (Person::class === $mapping['targetEntity'] and true === $mapping['isOwningSide']) { + if (in_array($mapping['sourceEntity'], $toDelete, true)) { $sql = $this->createDeleteSQL($metadata, $from, $field); $event = new ActionEvent( $from->getId(), @@ -117,10 +125,11 @@ class PersonMove $from->getId() ); + dump($sqls); return $sqls; } - protected function createDeleteSQL(ClassMetadata $metadata, Person $from, $field): string + private function createDeleteSQL(ClassMetadata $metadata, Person $from, $field): string { $mapping = $metadata->getAssociationMapping($field); @@ -137,26 +146,41 @@ class PersonMove ); } - protected function createMoveSQL(ClassMetadata $metadata, Person $from, Person $to, $field): string + private function createMoveSQL(ClassMetadata $metadata, Person $from, Person $to, $field): string { $mapping = $metadata->getAssociationMapping($field); // Set part of the query, aka in "UPDATE table SET " $sets = []; - - foreach ($mapping['joinColumns'] as $columns) { - $sets[] = sprintf('%s = %d', $columns['name'], $to->getId()); - } - $conditions = []; + dump($mapping); - foreach ($mapping['joinColumns'] as $columns) { - $conditions[] = sprintf('%s = %d', $columns['name'], $from->getId()); + if (array_key_exists('joinTable', $mapping)) { + $tableName = (null !== ($mapping['joinTable']['schema'] ?? null) ? $mapping['joinTable']['schema'] . '.' : '') + . $mapping['joinTable']['name']; + + foreach ($mapping['joinTable']['inverseJoinColumns'] as $columns) { + $sets[] = sprintf('%s = %d', $columns['name'], $to->getId()); + } + + foreach ($mapping['joinTable']['inverseJoinColumns'] as $columns) { + $conditions[] = sprintf('%s = %d', $columns['name'], $from->getId()); + } + } elseif (array_key_exists('joinColumns', $mapping)) { + $tableName = $this->getTableName($metadata); + foreach ($mapping['joinColumns'] as $columns) { + $sets[] = sprintf('%s = %d', $columns['name'], $to->getId()); + } + + + foreach ($mapping['joinColumns'] as $columns) { + $conditions[] = sprintf('%s = %d', $columns['name'], $from->getId()); + } } return sprintf( 'UPDATE %s SET %s WHERE %s', - $this->getTableName($metadata), + $tableName, implode(' ', $sets), implode(' AND ', $conditions) ); @@ -166,10 +190,23 @@ class PersonMove * return an array of classes where entities should be deleted * instead of moved. */ - protected function getDeleteEntities(): array + private function getDeleteEntities(): array { return [ - AccompanyingPeriod::class, + Person\PersonCenterHistory::class, + HouseholdMember::class, + AccompanyingPeriodParticipation::class, + AccompanyingPeriod\AccompanyingPeriodWork::class, + Relationship::class + ]; + } + + private function getIgnoredEntities(): array + { + return [ + Person\PersonCurrentAddress::class, + PersonHouseholdAddress::class, + Person\PersonCenterCurrent::class, ]; } diff --git a/src/Bundle/ChillPersonBundle/Controller/PersonDuplicateController.php b/src/Bundle/ChillPersonBundle/Controller/PersonDuplicateController.php index 928112d2e..ab353c83e 100644 --- a/src/Bundle/ChillPersonBundle/Controller/PersonDuplicateController.php +++ b/src/Bundle/ChillPersonBundle/Controller/PersonDuplicateController.php @@ -247,7 +247,7 @@ class PersonDuplicateController extends Controller ); $duplicatePersons = $this->similarPersonMatcher-> - matchPerson($person, $personNotDuplicateRepository, 0.5, SimilarPersonMatcher::SIMILAR_SEARCH_ORDER_BY_ALPHABETICAL); + matchPerson($person, 0.5, SimilarPersonMatcher::SIMILAR_SEARCH_ORDER_BY_ALPHABETICAL, false, $personNotDuplicateRepository); $notDuplicatePersons = $personNotDuplicateRepository->findNotDuplicatePerson($person); @@ -264,14 +264,14 @@ class PersonDuplicateController extends Controller $nb_activity = $em->getRepository(Activity::class)->findBy(['person' => $id]); $nb_document = $em->getRepository(PersonDocument::class)->findBy(['person' => $id]); - $nb_event = $em->getRepository(Participation::class)->findBy(['person' => $id]); +// $nb_event = $em->getRepository(Participation::class)->findBy(['person' => $id]); $nb_task = $em->getRepository(SingleTask::class)->countByParameters(['person' => $id]); $person = $em->getRepository(Person::class)->findOneBy(['id' => $id]); return [ 'nb_activity' => count($nb_activity), 'nb_document' => count($nb_document), - 'nb_event' => count($nb_event), +// 'nb_event' => count($nb_event), 'nb_task' => $nb_task, 'nb_addresses' => count($person->getAddresses()), ]; diff --git a/src/Bundle/ChillPersonBundle/Menu/PersonMenuBuilder.php b/src/Bundle/ChillPersonBundle/Menu/PersonMenuBuilder.php index 39ac557fb..b7934c2b2 100644 --- a/src/Bundle/ChillPersonBundle/Menu/PersonMenuBuilder.php +++ b/src/Bundle/ChillPersonBundle/Menu/PersonMenuBuilder.php @@ -15,6 +15,7 @@ use Chill\MainBundle\Routing\LocalMenuBuilderInterface; use Chill\PersonBundle\Entity\Person; use Chill\PersonBundle\Repository\ResidentialAddressRepository; use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter; +use Chill\PersonBundle\Security\Authorization\PersonVoter; use Knp\Menu\MenuItem; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; use Symfony\Component\Security\Core\Security; @@ -106,17 +107,19 @@ class PersonMenuBuilder implements LocalMenuBuilderInterface ->setExtras([ 'order' => 99999, ]); - /* - $menu->addChild($this->translator->trans('Person duplicate'), [ - 'route' => 'chill_person_duplicate_view', - 'routeParameters' => [ - 'person_id' => $parameters['person']->getId(), - ], - ]) - ->setExtras([ - 'order' => 99999, - ]); - */ + + if ($this->security->isGranted(PersonVoter::DUPLICATE, $parameters['person'])) { + $menu->addChild($this->translator->trans('Person duplicate'), [ + 'route' => 'chill_person_duplicate_view', + 'routeParameters' => [ + 'person_id' => $parameters['person']->getId(), + ], + ]) + ->setExtras([ + 'order' => 99999, + ]); + } + if ( 'visible' === $this->showAccompanyingPeriod && $this->security->isGranted(AccompanyingPeriodVoter::SEE, $parameters['person']) diff --git a/src/Bundle/ChillPersonBundle/Resources/views/PersonDuplicate/_sidepane.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/PersonDuplicate/_sidepane.html.twig index 660fff7a6..1e770062a 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/PersonDuplicate/_sidepane.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/PersonDuplicate/_sidepane.html.twig @@ -39,7 +39,7 @@
    • {{ person.counters.nb_activity }} {{ (person.counters.nb_activity > 1)? 'échanges' : 'échange' }}
    • {{ person.counters.nb_task }} {{ (person.counters.nb_task > 1)? 'tâches' : 'tâche' }}
    • {{ person.counters.nb_document }} {{ (person.counters.nb_document > 1)? 'documents' : 'document' }}
    • -
    • {{ person.counters.nb_event }} {{ (person.counters.nb_event > 1)? 'événements' : 'événement' }}
    • +{#
    • {{ person.counters.nb_event }} {{ (person.counters.nb_event > 1)? 'événements' : 'événement' }}
    • #}
    • {{ person.counters.nb_addresses }} {{ (person.counters.nb_addresses > 1)? 'adresses' : 'adresse' }}
    diff --git a/src/Bundle/ChillPersonBundle/Resources/views/PersonDuplicate/confirm.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/PersonDuplicate/confirm.html.twig index 304e78eb3..218b89f2a 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/PersonDuplicate/confirm.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/PersonDuplicate/confirm.html.twig @@ -25,7 +25,7 @@

    {{ 'Merge duplicate persons folders'|trans }}

    -
    +

    {{ 'Old person'|trans }}: {{ 'Old person explain'|trans }}

    @@ -43,7 +43,7 @@
    -
    +

    {{ 'New person'|trans }}: {{ 'New person explain'|trans }}

    @@ -63,10 +63,10 @@ {{ form_start(form) }} -
    +
    -
    +
    {{ form_widget(form.confirm) }}
    From 8b82e0c535c33616505ca5ed6e524864cfdc41c3 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Tue, 23 May 2023 18:19:31 +0200 Subject: [PATCH 058/321] FIX [rights] user shouldn't be allowed to see accompanyingperiods from within household --- .../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 ea32326a4..709624b54 100644 --- a/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php +++ b/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php @@ -18,6 +18,7 @@ use Chill\MainBundle\Security\Authorization\VoterHelperFactoryInterface; use Chill\MainBundle\Security\Authorization\VoterHelperInterface; use Chill\MainBundle\Security\ProvideRoleHierarchyInterface; use Chill\PersonBundle\Entity\AccompanyingPeriod; +use Chill\PersonBundle\Entity\Household\Household; use Chill\PersonBundle\Entity\Person; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Security; @@ -119,6 +120,7 @@ class AccompanyingPeriodVoter extends AbstractChillVoter implements ProvideRoleH ->generate(self::class) ->addCheckFor(null, [self::CREATE, self::REASSIGN_BULK]) ->addCheckFor(AccompanyingPeriod::class, [self::TOGGLE_CONFIDENTIAL, ...self::ALL]) + ->addCheckFor(Household::class, [self::SEE]) ->addCheckFor(Person::class, [self::SEE, self::CREATE]) ->addCheckFor(Center::class, [self::STATS]) ->build(); From 5109490aad0a0c12db9a8f4c3729de11a131f6bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 24 May 2023 13:09:04 +0200 Subject: [PATCH 059/321] Revert "FIX [duplicates] reinstate gestion des doublons" This reverts commit 5351223d44af43d2a063eea6b408749128e0b263. --- .../Actions/Remove/PersonMove.php | 69 +++++-------------- .../Controller/PersonDuplicateController.php | 6 +- .../Menu/PersonMenuBuilder.php | 25 +++---- .../views/PersonDuplicate/_sidepane.html.twig | 2 +- .../views/PersonDuplicate/confirm.html.twig | 8 +-- 5 files changed, 35 insertions(+), 75 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Actions/Remove/PersonMove.php b/src/Bundle/ChillPersonBundle/Actions/Remove/PersonMove.php index 8363134fd..13a62094d 100644 --- a/src/Bundle/ChillPersonBundle/Actions/Remove/PersonMove.php +++ b/src/Bundle/ChillPersonBundle/Actions/Remove/PersonMove.php @@ -13,11 +13,7 @@ namespace Chill\PersonBundle\Actions\Remove; use Chill\PersonBundle\Actions\ActionEvent; use Chill\PersonBundle\Entity\AccompanyingPeriod; -use Chill\PersonBundle\Entity\AccompanyingPeriodParticipation; -use Chill\PersonBundle\Entity\Household\HouseholdMember; -use Chill\PersonBundle\Entity\Household\PersonHouseholdAddress; use Chill\PersonBundle\Entity\Person; -use Chill\PersonBundle\Entity\Relationships\Relationship; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Mapping\ClassMetadata; use Symfony\Component\EventDispatcher\EventDispatcherInterface; @@ -46,10 +42,9 @@ class PersonMove protected $eventDispatcher; public function __construct( - EntityManagerInterface $em, + EntityManagerInterface $em, EventDispatcherInterface $eventDispatcher - ) - { + ) { $this->em = $em; $this->eventDispatcher = $eventDispatcher; } @@ -89,11 +84,8 @@ class PersonMove } foreach ($metadata->getAssociationMappings() as $field => $mapping) { - if (in_array($mapping['sourceEntity'], $this->getIgnoredEntities())) { - continue; - } - if (Person::class === $mapping['targetEntity'] and true === $mapping['isOwningSide']) { - if (in_array($mapping['sourceEntity'], $toDelete, true)) { + if (Person::class === $mapping['targetEntity']) { + if (in_array($metadata->getName(), $toDelete, true)) { $sql = $this->createDeleteSQL($metadata, $from, $field); $event = new ActionEvent( $from->getId(), @@ -125,11 +117,10 @@ class PersonMove $from->getId() ); - dump($sqls); return $sqls; } - private function createDeleteSQL(ClassMetadata $metadata, Person $from, $field): string + protected function createDeleteSQL(ClassMetadata $metadata, Person $from, $field): string { $mapping = $metadata->getAssociationMapping($field); @@ -146,41 +137,26 @@ class PersonMove ); } - private function createMoveSQL(ClassMetadata $metadata, Person $from, Person $to, $field): string + protected function createMoveSQL(ClassMetadata $metadata, Person $from, Person $to, $field): string { $mapping = $metadata->getAssociationMapping($field); // Set part of the query, aka in "UPDATE table SET " $sets = []; + + foreach ($mapping['joinColumns'] as $columns) { + $sets[] = sprintf('%s = %d', $columns['name'], $to->getId()); + } + $conditions = []; - dump($mapping); - if (array_key_exists('joinTable', $mapping)) { - $tableName = (null !== ($mapping['joinTable']['schema'] ?? null) ? $mapping['joinTable']['schema'] . '.' : '') - . $mapping['joinTable']['name']; - - foreach ($mapping['joinTable']['inverseJoinColumns'] as $columns) { - $sets[] = sprintf('%s = %d', $columns['name'], $to->getId()); - } - - foreach ($mapping['joinTable']['inverseJoinColumns'] as $columns) { - $conditions[] = sprintf('%s = %d', $columns['name'], $from->getId()); - } - } elseif (array_key_exists('joinColumns', $mapping)) { - $tableName = $this->getTableName($metadata); - foreach ($mapping['joinColumns'] as $columns) { - $sets[] = sprintf('%s = %d', $columns['name'], $to->getId()); - } - - - foreach ($mapping['joinColumns'] as $columns) { - $conditions[] = sprintf('%s = %d', $columns['name'], $from->getId()); - } + foreach ($mapping['joinColumns'] as $columns) { + $conditions[] = sprintf('%s = %d', $columns['name'], $from->getId()); } return sprintf( 'UPDATE %s SET %s WHERE %s', - $tableName, + $this->getTableName($metadata), implode(' ', $sets), implode(' AND ', $conditions) ); @@ -190,23 +166,10 @@ class PersonMove * return an array of classes where entities should be deleted * instead of moved. */ - private function getDeleteEntities(): array + protected function getDeleteEntities(): array { return [ - Person\PersonCenterHistory::class, - HouseholdMember::class, - AccompanyingPeriodParticipation::class, - AccompanyingPeriod\AccompanyingPeriodWork::class, - Relationship::class - ]; - } - - private function getIgnoredEntities(): array - { - return [ - Person\PersonCurrentAddress::class, - PersonHouseholdAddress::class, - Person\PersonCenterCurrent::class, + AccompanyingPeriod::class, ]; } diff --git a/src/Bundle/ChillPersonBundle/Controller/PersonDuplicateController.php b/src/Bundle/ChillPersonBundle/Controller/PersonDuplicateController.php index ab353c83e..928112d2e 100644 --- a/src/Bundle/ChillPersonBundle/Controller/PersonDuplicateController.php +++ b/src/Bundle/ChillPersonBundle/Controller/PersonDuplicateController.php @@ -247,7 +247,7 @@ class PersonDuplicateController extends Controller ); $duplicatePersons = $this->similarPersonMatcher-> - matchPerson($person, 0.5, SimilarPersonMatcher::SIMILAR_SEARCH_ORDER_BY_ALPHABETICAL, false, $personNotDuplicateRepository); + matchPerson($person, $personNotDuplicateRepository, 0.5, SimilarPersonMatcher::SIMILAR_SEARCH_ORDER_BY_ALPHABETICAL); $notDuplicatePersons = $personNotDuplicateRepository->findNotDuplicatePerson($person); @@ -264,14 +264,14 @@ class PersonDuplicateController extends Controller $nb_activity = $em->getRepository(Activity::class)->findBy(['person' => $id]); $nb_document = $em->getRepository(PersonDocument::class)->findBy(['person' => $id]); -// $nb_event = $em->getRepository(Participation::class)->findBy(['person' => $id]); + $nb_event = $em->getRepository(Participation::class)->findBy(['person' => $id]); $nb_task = $em->getRepository(SingleTask::class)->countByParameters(['person' => $id]); $person = $em->getRepository(Person::class)->findOneBy(['id' => $id]); return [ 'nb_activity' => count($nb_activity), 'nb_document' => count($nb_document), -// 'nb_event' => count($nb_event), + 'nb_event' => count($nb_event), 'nb_task' => $nb_task, 'nb_addresses' => count($person->getAddresses()), ]; diff --git a/src/Bundle/ChillPersonBundle/Menu/PersonMenuBuilder.php b/src/Bundle/ChillPersonBundle/Menu/PersonMenuBuilder.php index b7934c2b2..39ac557fb 100644 --- a/src/Bundle/ChillPersonBundle/Menu/PersonMenuBuilder.php +++ b/src/Bundle/ChillPersonBundle/Menu/PersonMenuBuilder.php @@ -15,7 +15,6 @@ use Chill\MainBundle\Routing\LocalMenuBuilderInterface; use Chill\PersonBundle\Entity\Person; use Chill\PersonBundle\Repository\ResidentialAddressRepository; use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter; -use Chill\PersonBundle\Security\Authorization\PersonVoter; use Knp\Menu\MenuItem; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; use Symfony\Component\Security\Core\Security; @@ -107,19 +106,17 @@ class PersonMenuBuilder implements LocalMenuBuilderInterface ->setExtras([ 'order' => 99999, ]); - - if ($this->security->isGranted(PersonVoter::DUPLICATE, $parameters['person'])) { - $menu->addChild($this->translator->trans('Person duplicate'), [ - 'route' => 'chill_person_duplicate_view', - 'routeParameters' => [ - 'person_id' => $parameters['person']->getId(), - ], - ]) - ->setExtras([ - 'order' => 99999, - ]); - } - + /* + $menu->addChild($this->translator->trans('Person duplicate'), [ + 'route' => 'chill_person_duplicate_view', + 'routeParameters' => [ + 'person_id' => $parameters['person']->getId(), + ], + ]) + ->setExtras([ + 'order' => 99999, + ]); + */ if ( 'visible' === $this->showAccompanyingPeriod && $this->security->isGranted(AccompanyingPeriodVoter::SEE, $parameters['person']) diff --git a/src/Bundle/ChillPersonBundle/Resources/views/PersonDuplicate/_sidepane.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/PersonDuplicate/_sidepane.html.twig index 1e770062a..660fff7a6 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/PersonDuplicate/_sidepane.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/PersonDuplicate/_sidepane.html.twig @@ -39,7 +39,7 @@
  • {{ person.counters.nb_activity }} {{ (person.counters.nb_activity > 1)? 'échanges' : 'échange' }}
  • {{ person.counters.nb_task }} {{ (person.counters.nb_task > 1)? 'tâches' : 'tâche' }}
  • {{ person.counters.nb_document }} {{ (person.counters.nb_document > 1)? 'documents' : 'document' }}
  • -{#
  • {{ person.counters.nb_event }} {{ (person.counters.nb_event > 1)? 'événements' : 'événement' }}
  • #} +
  • {{ person.counters.nb_event }} {{ (person.counters.nb_event > 1)? 'événements' : 'événement' }}
  • {{ person.counters.nb_addresses }} {{ (person.counters.nb_addresses > 1)? 'adresses' : 'adresse' }}
  • diff --git a/src/Bundle/ChillPersonBundle/Resources/views/PersonDuplicate/confirm.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/PersonDuplicate/confirm.html.twig index 218b89f2a..304e78eb3 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/PersonDuplicate/confirm.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/PersonDuplicate/confirm.html.twig @@ -25,7 +25,7 @@

    {{ 'Merge duplicate persons folders'|trans }}

    -
    +

    {{ 'Old person'|trans }}: {{ 'Old person explain'|trans }}

    @@ -43,7 +43,7 @@
    -
    +

    {{ 'New person'|trans }}: {{ 'New person explain'|trans }}

    @@ -63,10 +63,10 @@ {{ form_start(form) }} -
    +
    -
    +
    {{ form_widget(form.confirm) }}
    From 04359f27c6d1563b840980aae56be0ead9d271f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 24 May 2023 13:11:40 +0200 Subject: [PATCH 060/321] Revert "Revert "FIX [duplicates] reinstate gestion des doublons"" This reverts commit 5109490aad0a0c12db9a8f4c3729de11a131f6bd. --- .../Actions/Remove/PersonMove.php | 69 ++++++++++++++----- .../Controller/PersonDuplicateController.php | 6 +- .../Menu/PersonMenuBuilder.php | 25 ++++--- .../views/PersonDuplicate/_sidepane.html.twig | 2 +- .../views/PersonDuplicate/confirm.html.twig | 8 +-- 5 files changed, 75 insertions(+), 35 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Actions/Remove/PersonMove.php b/src/Bundle/ChillPersonBundle/Actions/Remove/PersonMove.php index 13a62094d..8363134fd 100644 --- a/src/Bundle/ChillPersonBundle/Actions/Remove/PersonMove.php +++ b/src/Bundle/ChillPersonBundle/Actions/Remove/PersonMove.php @@ -13,7 +13,11 @@ namespace Chill\PersonBundle\Actions\Remove; use Chill\PersonBundle\Actions\ActionEvent; use Chill\PersonBundle\Entity\AccompanyingPeriod; +use Chill\PersonBundle\Entity\AccompanyingPeriodParticipation; +use Chill\PersonBundle\Entity\Household\HouseholdMember; +use Chill\PersonBundle\Entity\Household\PersonHouseholdAddress; use Chill\PersonBundle\Entity\Person; +use Chill\PersonBundle\Entity\Relationships\Relationship; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Mapping\ClassMetadata; use Symfony\Component\EventDispatcher\EventDispatcherInterface; @@ -42,9 +46,10 @@ class PersonMove protected $eventDispatcher; public function __construct( - EntityManagerInterface $em, + EntityManagerInterface $em, EventDispatcherInterface $eventDispatcher - ) { + ) + { $this->em = $em; $this->eventDispatcher = $eventDispatcher; } @@ -84,8 +89,11 @@ class PersonMove } foreach ($metadata->getAssociationMappings() as $field => $mapping) { - if (Person::class === $mapping['targetEntity']) { - if (in_array($metadata->getName(), $toDelete, true)) { + if (in_array($mapping['sourceEntity'], $this->getIgnoredEntities())) { + continue; + } + if (Person::class === $mapping['targetEntity'] and true === $mapping['isOwningSide']) { + if (in_array($mapping['sourceEntity'], $toDelete, true)) { $sql = $this->createDeleteSQL($metadata, $from, $field); $event = new ActionEvent( $from->getId(), @@ -117,10 +125,11 @@ class PersonMove $from->getId() ); + dump($sqls); return $sqls; } - protected function createDeleteSQL(ClassMetadata $metadata, Person $from, $field): string + private function createDeleteSQL(ClassMetadata $metadata, Person $from, $field): string { $mapping = $metadata->getAssociationMapping($field); @@ -137,26 +146,41 @@ class PersonMove ); } - protected function createMoveSQL(ClassMetadata $metadata, Person $from, Person $to, $field): string + private function createMoveSQL(ClassMetadata $metadata, Person $from, Person $to, $field): string { $mapping = $metadata->getAssociationMapping($field); // Set part of the query, aka in "UPDATE table SET " $sets = []; - - foreach ($mapping['joinColumns'] as $columns) { - $sets[] = sprintf('%s = %d', $columns['name'], $to->getId()); - } - $conditions = []; + dump($mapping); - foreach ($mapping['joinColumns'] as $columns) { - $conditions[] = sprintf('%s = %d', $columns['name'], $from->getId()); + if (array_key_exists('joinTable', $mapping)) { + $tableName = (null !== ($mapping['joinTable']['schema'] ?? null) ? $mapping['joinTable']['schema'] . '.' : '') + . $mapping['joinTable']['name']; + + foreach ($mapping['joinTable']['inverseJoinColumns'] as $columns) { + $sets[] = sprintf('%s = %d', $columns['name'], $to->getId()); + } + + foreach ($mapping['joinTable']['inverseJoinColumns'] as $columns) { + $conditions[] = sprintf('%s = %d', $columns['name'], $from->getId()); + } + } elseif (array_key_exists('joinColumns', $mapping)) { + $tableName = $this->getTableName($metadata); + foreach ($mapping['joinColumns'] as $columns) { + $sets[] = sprintf('%s = %d', $columns['name'], $to->getId()); + } + + + foreach ($mapping['joinColumns'] as $columns) { + $conditions[] = sprintf('%s = %d', $columns['name'], $from->getId()); + } } return sprintf( 'UPDATE %s SET %s WHERE %s', - $this->getTableName($metadata), + $tableName, implode(' ', $sets), implode(' AND ', $conditions) ); @@ -166,10 +190,23 @@ class PersonMove * return an array of classes where entities should be deleted * instead of moved. */ - protected function getDeleteEntities(): array + private function getDeleteEntities(): array { return [ - AccompanyingPeriod::class, + Person\PersonCenterHistory::class, + HouseholdMember::class, + AccompanyingPeriodParticipation::class, + AccompanyingPeriod\AccompanyingPeriodWork::class, + Relationship::class + ]; + } + + private function getIgnoredEntities(): array + { + return [ + Person\PersonCurrentAddress::class, + PersonHouseholdAddress::class, + Person\PersonCenterCurrent::class, ]; } diff --git a/src/Bundle/ChillPersonBundle/Controller/PersonDuplicateController.php b/src/Bundle/ChillPersonBundle/Controller/PersonDuplicateController.php index 928112d2e..ab353c83e 100644 --- a/src/Bundle/ChillPersonBundle/Controller/PersonDuplicateController.php +++ b/src/Bundle/ChillPersonBundle/Controller/PersonDuplicateController.php @@ -247,7 +247,7 @@ class PersonDuplicateController extends Controller ); $duplicatePersons = $this->similarPersonMatcher-> - matchPerson($person, $personNotDuplicateRepository, 0.5, SimilarPersonMatcher::SIMILAR_SEARCH_ORDER_BY_ALPHABETICAL); + matchPerson($person, 0.5, SimilarPersonMatcher::SIMILAR_SEARCH_ORDER_BY_ALPHABETICAL, false, $personNotDuplicateRepository); $notDuplicatePersons = $personNotDuplicateRepository->findNotDuplicatePerson($person); @@ -264,14 +264,14 @@ class PersonDuplicateController extends Controller $nb_activity = $em->getRepository(Activity::class)->findBy(['person' => $id]); $nb_document = $em->getRepository(PersonDocument::class)->findBy(['person' => $id]); - $nb_event = $em->getRepository(Participation::class)->findBy(['person' => $id]); +// $nb_event = $em->getRepository(Participation::class)->findBy(['person' => $id]); $nb_task = $em->getRepository(SingleTask::class)->countByParameters(['person' => $id]); $person = $em->getRepository(Person::class)->findOneBy(['id' => $id]); return [ 'nb_activity' => count($nb_activity), 'nb_document' => count($nb_document), - 'nb_event' => count($nb_event), +// 'nb_event' => count($nb_event), 'nb_task' => $nb_task, 'nb_addresses' => count($person->getAddresses()), ]; diff --git a/src/Bundle/ChillPersonBundle/Menu/PersonMenuBuilder.php b/src/Bundle/ChillPersonBundle/Menu/PersonMenuBuilder.php index 39ac557fb..b7934c2b2 100644 --- a/src/Bundle/ChillPersonBundle/Menu/PersonMenuBuilder.php +++ b/src/Bundle/ChillPersonBundle/Menu/PersonMenuBuilder.php @@ -15,6 +15,7 @@ use Chill\MainBundle\Routing\LocalMenuBuilderInterface; use Chill\PersonBundle\Entity\Person; use Chill\PersonBundle\Repository\ResidentialAddressRepository; use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter; +use Chill\PersonBundle\Security\Authorization\PersonVoter; use Knp\Menu\MenuItem; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; use Symfony\Component\Security\Core\Security; @@ -106,17 +107,19 @@ class PersonMenuBuilder implements LocalMenuBuilderInterface ->setExtras([ 'order' => 99999, ]); - /* - $menu->addChild($this->translator->trans('Person duplicate'), [ - 'route' => 'chill_person_duplicate_view', - 'routeParameters' => [ - 'person_id' => $parameters['person']->getId(), - ], - ]) - ->setExtras([ - 'order' => 99999, - ]); - */ + + if ($this->security->isGranted(PersonVoter::DUPLICATE, $parameters['person'])) { + $menu->addChild($this->translator->trans('Person duplicate'), [ + 'route' => 'chill_person_duplicate_view', + 'routeParameters' => [ + 'person_id' => $parameters['person']->getId(), + ], + ]) + ->setExtras([ + 'order' => 99999, + ]); + } + if ( 'visible' === $this->showAccompanyingPeriod && $this->security->isGranted(AccompanyingPeriodVoter::SEE, $parameters['person']) diff --git a/src/Bundle/ChillPersonBundle/Resources/views/PersonDuplicate/_sidepane.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/PersonDuplicate/_sidepane.html.twig index 660fff7a6..1e770062a 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/PersonDuplicate/_sidepane.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/PersonDuplicate/_sidepane.html.twig @@ -39,7 +39,7 @@
  • {{ person.counters.nb_activity }} {{ (person.counters.nb_activity > 1)? 'échanges' : 'échange' }}
  • {{ person.counters.nb_task }} {{ (person.counters.nb_task > 1)? 'tâches' : 'tâche' }}
  • {{ person.counters.nb_document }} {{ (person.counters.nb_document > 1)? 'documents' : 'document' }}
  • -
  • {{ person.counters.nb_event }} {{ (person.counters.nb_event > 1)? 'événements' : 'événement' }}
  • +{#
  • {{ person.counters.nb_event }} {{ (person.counters.nb_event > 1)? 'événements' : 'événement' }}
  • #}
  • {{ person.counters.nb_addresses }} {{ (person.counters.nb_addresses > 1)? 'adresses' : 'adresse' }}
  • diff --git a/src/Bundle/ChillPersonBundle/Resources/views/PersonDuplicate/confirm.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/PersonDuplicate/confirm.html.twig index 304e78eb3..218b89f2a 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/PersonDuplicate/confirm.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/PersonDuplicate/confirm.html.twig @@ -25,7 +25,7 @@

    {{ 'Merge duplicate persons folders'|trans }}

    -
    +

    {{ 'Old person'|trans }}: {{ 'Old person explain'|trans }}

    @@ -43,7 +43,7 @@
    -
    +

    {{ 'New person'|trans }}: {{ 'New person explain'|trans }}

    @@ -63,10 +63,10 @@ {{ form_start(form) }} -
    +
    -
    +
    {{ form_widget(form.confirm) }}
    From d82a3e0ff6e57ebb1a763d5aa2c995bda6b78797 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 24 May 2023 12:06:07 +0200 Subject: [PATCH 061/321] Fixed: [download document] add a target when downloading document --- .../public/vuejs/StoredObjectButton/DownloadButton.vue | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Bundle/ChillDocStoreBundle/Resources/public/vuejs/StoredObjectButton/DownloadButton.vue b/src/Bundle/ChillDocStoreBundle/Resources/public/vuejs/StoredObjectButton/DownloadButton.vue index 98645873b..b22035bee 100644 --- a/src/Bundle/ChillDocStoreBundle/Resources/public/vuejs/StoredObjectButton/DownloadButton.vue +++ b/src/Bundle/ChillDocStoreBundle/Resources/public/vuejs/StoredObjectButton/DownloadButton.vue @@ -34,6 +34,7 @@ async function download_and_open(event: Event): Promise { const raw = await download_and_decrypt_doc(urlInfo, props.storedObject.keyInfos, new Uint8Array(props.storedObject.iv)); button.href = window.URL.createObjectURL(raw); + button.target = '_blank'; button.type = props.storedObject.type; button.download = props.filename || 'document'; @@ -45,10 +46,7 @@ async function download_and_open(event: Event): Promise { state.is_ready = true; - // for fixing https://gitlab.com/Chill-Projet/chill-bundles/-/issues/98 - window.setTimeout(() => { - button.click() - }, 750); + button.click(); } } From 20023dff671ea7457a5c56c0f94f4e3b7b70d55e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 24 May 2023 13:35:35 +0200 Subject: [PATCH 062/321] DX: fix cs --- .../ChillActivityBundle/Controller/ActivityController.php | 4 ++-- src/Bundle/ChillActivityBundle/Menu/PersonMenuBuilder.php | 4 ++-- src/Bundle/ChillThirdPartyBundle/Form/ThirdPartyType.php | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Controller/ActivityController.php b/src/Bundle/ChillActivityBundle/Controller/ActivityController.php index 97678af50..444c663fc 100644 --- a/src/Bundle/ChillActivityBundle/Controller/ActivityController.php +++ b/src/Bundle/ChillActivityBundle/Controller/ActivityController.php @@ -650,8 +650,8 @@ final class ActivityController extends AbstractController throw $this->createNotFoundException('Accompanying Period not found'); } - // TODO Add permission - // $this->denyAccessUnlessGranted('CHILL_PERSON_SEE', $person); + // TODO Add permission + // $this->denyAccessUnlessGranted('CHILL_PERSON_SEE', $person); } else { throw $this->createNotFoundException('Person or Accompanying Period not found'); } diff --git a/src/Bundle/ChillActivityBundle/Menu/PersonMenuBuilder.php b/src/Bundle/ChillActivityBundle/Menu/PersonMenuBuilder.php index 03a1b09ab..a3cebec38 100644 --- a/src/Bundle/ChillActivityBundle/Menu/PersonMenuBuilder.php +++ b/src/Bundle/ChillActivityBundle/Menu/PersonMenuBuilder.php @@ -26,12 +26,12 @@ final class PersonMenuBuilder implements LocalMenuBuilderInterface /** * @var AuthorizationCheckerInterface */ - protected $authorizationChecker; + private $authorizationChecker; /** * @var TranslatorInterface */ - protected $translator; + private $translator; public function __construct( AuthorizationCheckerInterface $authorizationChecker, diff --git a/src/Bundle/ChillThirdPartyBundle/Form/ThirdPartyType.php b/src/Bundle/ChillThirdPartyBundle/Form/ThirdPartyType.php index b1446a543..6c4984f33 100644 --- a/src/Bundle/ChillThirdPartyBundle/Form/ThirdPartyType.php +++ b/src/Bundle/ChillThirdPartyBundle/Form/ThirdPartyType.php @@ -117,7 +117,7 @@ class ThirdPartyType extends AbstractType 'label' => 'thirdparty.Contact data are confidential', ]); - // Institutional ThirdParty (parent) + // Institutional ThirdParty (parent) } else { $builder ->add('nameCompany', TextType::class, [ From a31c4063a19dfc27e3bb4f8502f05c06ed650b3e Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Wed, 24 May 2023 14:02:05 +0200 Subject: [PATCH 063/321] DX [cs-fixer] fixes --- .../Command/SynchronizeEntityInfoViewsCommand.php | 1 - .../Controller/PermissionsGroupController.php | 1 - .../ChillMainBundle/Controller/UserExportController.php | 1 - .../AccompanyingPeriodStepChangeMessageHandler.php | 1 - .../Lifecycle/AccompanyingPeriodStepChangeRequestor.php | 1 - .../Export/Export/ListHouseholdInPeriod.php | 1 - .../AccompanyingPeriod/AccompanyingPeriodInfoRepository.php | 1 - .../Lifecycle/AccompanyingPeriodStepChangeCronjobTest.php | 1 - .../Filter/SocialWorkFilters/SocialWorkTypeFilterTest.php | 6 +----- 9 files changed, 1 insertion(+), 13 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Command/SynchronizeEntityInfoViewsCommand.php b/src/Bundle/ChillMainBundle/Command/SynchronizeEntityInfoViewsCommand.php index c3dc8a87c..05fefe20f 100644 --- a/src/Bundle/ChillMainBundle/Command/SynchronizeEntityInfoViewsCommand.php +++ b/src/Bundle/ChillMainBundle/Command/SynchronizeEntityInfoViewsCommand.php @@ -36,5 +36,4 @@ class SynchronizeEntityInfoViewsCommand extends Command return 0; } - } diff --git a/src/Bundle/ChillMainBundle/Controller/PermissionsGroupController.php b/src/Bundle/ChillMainBundle/Controller/PermissionsGroupController.php index 488092931..97e80916c 100644 --- a/src/Bundle/ChillMainBundle/Controller/PermissionsGroupController.php +++ b/src/Bundle/ChillMainBundle/Controller/PermissionsGroupController.php @@ -163,7 +163,6 @@ final class PermissionsGroupController extends AbstractController */ public function deleteLinkRoleScopeAction(int $pgid, int $rsid): Response { - $permissionsGroup = $this->permissionsGroupRepository->find($pgid); $roleScope = $this->roleScopeRepository->find($rsid); diff --git a/src/Bundle/ChillMainBundle/Controller/UserExportController.php b/src/Bundle/ChillMainBundle/Controller/UserExportController.php index dc2674dbb..530ac19b7 100644 --- a/src/Bundle/ChillMainBundle/Controller/UserExportController.php +++ b/src/Bundle/ChillMainBundle/Controller/UserExportController.php @@ -141,5 +141,4 @@ final readonly class UserExportController ] ); } - } diff --git a/src/Bundle/ChillPersonBundle/AccompanyingPeriod/Lifecycle/AccompanyingPeriodStepChangeMessageHandler.php b/src/Bundle/ChillPersonBundle/AccompanyingPeriod/Lifecycle/AccompanyingPeriodStepChangeMessageHandler.php index 881b3999a..4a9873c6d 100644 --- a/src/Bundle/ChillPersonBundle/AccompanyingPeriod/Lifecycle/AccompanyingPeriodStepChangeMessageHandler.php +++ b/src/Bundle/ChillPersonBundle/AccompanyingPeriod/Lifecycle/AccompanyingPeriodStepChangeMessageHandler.php @@ -34,5 +34,4 @@ class AccompanyingPeriodStepChangeMessageHandler implements MessageHandlerInterf ($this->changer)($period, $message->getTransition()); } - } diff --git a/src/Bundle/ChillPersonBundle/AccompanyingPeriod/Lifecycle/AccompanyingPeriodStepChangeRequestor.php b/src/Bundle/ChillPersonBundle/AccompanyingPeriod/Lifecycle/AccompanyingPeriodStepChangeRequestor.php index 3d4979608..f1c3563fc 100644 --- a/src/Bundle/ChillPersonBundle/AccompanyingPeriod/Lifecycle/AccompanyingPeriodStepChangeRequestor.php +++ b/src/Bundle/ChillPersonBundle/AccompanyingPeriod/Lifecycle/AccompanyingPeriodStepChangeRequestor.php @@ -84,5 +84,4 @@ class AccompanyingPeriodStepChangeRequestor $this->messageBus->dispatch(new AccompanyingPeriodStepChangeRequestMessage($accompanyingPeriodId, 'mark_active')); } } - } diff --git a/src/Bundle/ChillPersonBundle/Export/Export/ListHouseholdInPeriod.php b/src/Bundle/ChillPersonBundle/Export/Export/ListHouseholdInPeriod.php index 24d929c00..8894d145d 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/ListHouseholdInPeriod.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/ListHouseholdInPeriod.php @@ -107,7 +107,6 @@ class ListHouseholdInPeriod implements ListInterface, GroupedExportInterface return $this->aggregateStringHelper->getLabelMulti($key, $values, 'export.list.household.' . $key); case 'compositionType': - //dump($values); return $this->translatableStringHelper->getLabel($key, $values, 'export.list.household.' . $key); default: diff --git a/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/AccompanyingPeriodInfoRepository.php b/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/AccompanyingPeriodInfoRepository.php index 57925b131..0296d00f1 100644 --- a/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/AccompanyingPeriodInfoRepository.php +++ b/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/AccompanyingPeriodInfoRepository.php @@ -89,5 +89,4 @@ readonly class AccompanyingPeriodInfoRepository implements AccompanyingPeriodInf { return AccompanyingPeriodInfo::class; } - } diff --git a/src/Bundle/ChillPersonBundle/Tests/AccompanyingPeriod/Lifecycle/AccompanyingPeriodStepChangeCronjobTest.php b/src/Bundle/ChillPersonBundle/Tests/AccompanyingPeriod/Lifecycle/AccompanyingPeriodStepChangeCronjobTest.php index 5c3c29179..5a5b50dbb 100644 --- a/src/Bundle/ChillPersonBundle/Tests/AccompanyingPeriod/Lifecycle/AccompanyingPeriodStepChangeCronjobTest.php +++ b/src/Bundle/ChillPersonBundle/Tests/AccompanyingPeriod/Lifecycle/AccompanyingPeriodStepChangeCronjobTest.php @@ -51,5 +51,4 @@ class AccompanyingPeriodStepChangeCronjobTest extends TestCase // can not run: not enough elapsed time yield ['2023-01-15T01:00:00+02:00', new \DateTimeImmutable('2023-01-15T00:30:00+02:00'), false]; } - } diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Filter/SocialWorkFilters/SocialWorkTypeFilterTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Filter/SocialWorkFilters/SocialWorkTypeFilterTest.php index f462bc47e..5287ab844 100644 --- a/src/Bundle/ChillPersonBundle/Tests/Export/Filter/SocialWorkFilters/SocialWorkTypeFilterTest.php +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Filter/SocialWorkFilters/SocialWorkTypeFilterTest.php @@ -78,17 +78,13 @@ final class SocialWorkTypeFilterTest extends AbstractFilterTest $goals = array_unique($goals); $results = array_unique($results); - $data = [ + return [ [ 'actionType' => implode(',', $actions), 'goal' => implode(',', $goals), 'result' => implode(',', $results), ], ]; - /// TODO ne fonctionne pas - var_dump($data); - - return $data; } public function getQueryBuilders(): array From f5448f9d95babf82d972d3ccc31eb0430cc4d9c7 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Wed, 24 May 2023 14:02:49 +0200 Subject: [PATCH 064/321] DX [phpstan] fixes --- .../ChillPersonBundle/Actions/Remove/PersonMove.php | 8 +++----- .../Controller/PersonDuplicateController.php | 4 ++-- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Actions/Remove/PersonMove.php b/src/Bundle/ChillPersonBundle/Actions/Remove/PersonMove.php index 8363134fd..4e2f7468e 100644 --- a/src/Bundle/ChillPersonBundle/Actions/Remove/PersonMove.php +++ b/src/Bundle/ChillPersonBundle/Actions/Remove/PersonMove.php @@ -48,8 +48,7 @@ class PersonMove public function __construct( EntityManagerInterface $em, EventDispatcherInterface $eventDispatcher - ) - { + ) { $this->em = $em; $this->eventDispatcher = $eventDispatcher; } @@ -89,7 +88,7 @@ class PersonMove } foreach ($metadata->getAssociationMappings() as $field => $mapping) { - if (in_array($mapping['sourceEntity'], $this->getIgnoredEntities())) { + if (in_array($mapping['sourceEntity'], $this->getIgnoredEntities(), true)) { continue; } if (Person::class === $mapping['targetEntity'] and true === $mapping['isOwningSide']) { @@ -125,7 +124,6 @@ class PersonMove $from->getId() ); - dump($sqls); return $sqls; } @@ -153,7 +151,7 @@ class PersonMove // Set part of the query, aka in "UPDATE table SET " $sets = []; $conditions = []; - dump($mapping); + $tableName = ''; if (array_key_exists('joinTable', $mapping)) { $tableName = (null !== ($mapping['joinTable']['schema'] ?? null) ? $mapping['joinTable']['schema'] . '.' : '') diff --git a/src/Bundle/ChillPersonBundle/Controller/PersonDuplicateController.php b/src/Bundle/ChillPersonBundle/Controller/PersonDuplicateController.php index ab353c83e..386e55039 100644 --- a/src/Bundle/ChillPersonBundle/Controller/PersonDuplicateController.php +++ b/src/Bundle/ChillPersonBundle/Controller/PersonDuplicateController.php @@ -247,7 +247,7 @@ class PersonDuplicateController extends Controller ); $duplicatePersons = $this->similarPersonMatcher-> - matchPerson($person, 0.5, SimilarPersonMatcher::SIMILAR_SEARCH_ORDER_BY_ALPHABETICAL, false, $personNotDuplicateRepository); + matchPerson($person, 0.5, SimilarPersonMatcher::SIMILAR_SEARCH_ORDER_BY_ALPHABETICAL, false); $notDuplicatePersons = $personNotDuplicateRepository->findNotDuplicatePerson($person); @@ -271,7 +271,7 @@ class PersonDuplicateController extends Controller return [ 'nb_activity' => count($nb_activity), 'nb_document' => count($nb_document), -// 'nb_event' => count($nb_event), + // 'nb_event' => count($nb_event), 'nb_task' => $nb_task, 'nb_addresses' => count($person->getAddresses()), ]; From 664bf743f933b50db3ded4ce281ff8c973ed8fb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 24 May 2023 15:08:59 +0200 Subject: [PATCH 065/321] Fix: force list of activities to be a list with incremental keys --- ...tActivitiesByAccompanyingPeriodContext.php | 34 ++++++++++++------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Service/DocGenerator/ListActivitiesByAccompanyingPeriodContext.php b/src/Bundle/ChillActivityBundle/Service/DocGenerator/ListActivitiesByAccompanyingPeriodContext.php index 3da451f2e..045d09beb 100644 --- a/src/Bundle/ChillActivityBundle/Service/DocGenerator/ListActivitiesByAccompanyingPeriodContext.php +++ b/src/Bundle/ChillActivityBundle/Service/DocGenerator/ListActivitiesByAccompanyingPeriodContext.php @@ -140,26 +140,36 @@ class ListActivitiesByAccompanyingPeriodContext implements return $normalized; } + /** + * @return list + */ private function filterActivitiesByUser(array $activities, User $user): array { - return array_filter( - $activities, - function ($activity) use ($user) { - $activityUsernames = array_map(static fn ($user) => $user['username'], $activity['users'] ?? []); - return in_array($user->getUsername(), $activityUsernames, true); - } + return array_values( + array_filter( + $activities, + function ($activity) use ($user) { + $activityUsernames = array_map(static fn ($user) => $user['username'], $activity['users'] ?? []); + return in_array($user->getUsername(), $activityUsernames, true); + } + ) ); } + /** + * @return list + */ private function filterWorksByUser(array $works, User $user): array { - return array_filter( - $works, - function ($work) use ($user) { - $workUsernames = array_map(static fn ($user) => $user['username'], $work['referrers'] ?? []); + return array_values( + array_filter( + $works, + function ($work) use ($user) { + $workUsernames = array_map(static fn ($user) => $user['username'], $work['referrers'] ?? []); - return in_array($user->getUsername(), $workUsernames, true); - } + return in_array($user->getUsername(), $workUsernames, true); + } + ) ); } From dad36927f31fd9e707e052ccba57366e5c01d29f Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Wed, 24 May 2023 15:34:39 +0200 Subject: [PATCH 066/321] FEATURE [export] uncheck all centers button --- .../views/Export/new_centers_step.html.twig | 17 +++++++++++++++++ .../translations/messages.fr.yml | 2 ++ 2 files changed, 19 insertions(+) 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 9e37dc2cd..40366669c 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 @@ -39,8 +39,13 @@ {{ 'This will eventually restrict your possibilities in filtering the data.'|trans }}

    {{ 'Center'|trans }}

    + {{ form_widget(form.centers.center) }} +
    + +
    + {% if form.centers.regroupment is defined %}

    {{ 'Pick aggregated centers'|trans }}

    {{ form_widget(form.centers.regroupment) }} @@ -53,3 +58,15 @@
    {% endblock content %} + +{% block js %} + + + +{% endblock js %} diff --git a/src/Bundle/ChillMainBundle/translations/messages.fr.yml b/src/Bundle/ChillMainBundle/translations/messages.fr.yml index 13c300fdd..fa28feef6 100644 --- a/src/Bundle/ChillMainBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillMainBundle/translations/messages.fr.yml @@ -285,6 +285,8 @@ The export will contains only data from the picked centers.: L'export ne contien This will eventually restrict your possibilities in filtering the data.: Les possibilités de filtrages seront adaptées aux droits de consultation pour les centres choisis. Go to export options: Vers la préparation de l'export Pick aggregated centers: Regroupement de centres +uncheck all: Désélectionner tout les centres +check all: Sélectionner tout les centres # export creation step 'export' : choose aggregators, filtering and formatter Formatter: Mise en forme Choose the formatter: Choisissez le format d'export voulu. From 6e618e688bf4b593702212559277a9aaed02bfcf Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Wed, 24 May 2023 15:50:25 +0200 Subject: [PATCH 067/321] DX [php-cs-fixer] --- .../ChillActivityBundle/Controller/ActivityController.php | 4 ++-- src/Bundle/ChillActivityBundle/Menu/PersonMenuBuilder.php | 4 ++-- .../Controller/PersonDuplicateController.php | 2 +- src/Bundle/ChillThirdPartyBundle/Form/ThirdPartyType.php | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Controller/ActivityController.php b/src/Bundle/ChillActivityBundle/Controller/ActivityController.php index 97678af50..444c663fc 100644 --- a/src/Bundle/ChillActivityBundle/Controller/ActivityController.php +++ b/src/Bundle/ChillActivityBundle/Controller/ActivityController.php @@ -650,8 +650,8 @@ final class ActivityController extends AbstractController throw $this->createNotFoundException('Accompanying Period not found'); } - // TODO Add permission - // $this->denyAccessUnlessGranted('CHILL_PERSON_SEE', $person); + // TODO Add permission + // $this->denyAccessUnlessGranted('CHILL_PERSON_SEE', $person); } else { throw $this->createNotFoundException('Person or Accompanying Period not found'); } diff --git a/src/Bundle/ChillActivityBundle/Menu/PersonMenuBuilder.php b/src/Bundle/ChillActivityBundle/Menu/PersonMenuBuilder.php index 03a1b09ab..a3cebec38 100644 --- a/src/Bundle/ChillActivityBundle/Menu/PersonMenuBuilder.php +++ b/src/Bundle/ChillActivityBundle/Menu/PersonMenuBuilder.php @@ -26,12 +26,12 @@ final class PersonMenuBuilder implements LocalMenuBuilderInterface /** * @var AuthorizationCheckerInterface */ - protected $authorizationChecker; + private $authorizationChecker; /** * @var TranslatorInterface */ - protected $translator; + private $translator; public function __construct( AuthorizationCheckerInterface $authorizationChecker, diff --git a/src/Bundle/ChillPersonBundle/Controller/PersonDuplicateController.php b/src/Bundle/ChillPersonBundle/Controller/PersonDuplicateController.php index 386e55039..7ade542e0 100644 --- a/src/Bundle/ChillPersonBundle/Controller/PersonDuplicateController.php +++ b/src/Bundle/ChillPersonBundle/Controller/PersonDuplicateController.php @@ -264,7 +264,7 @@ class PersonDuplicateController extends Controller $nb_activity = $em->getRepository(Activity::class)->findBy(['person' => $id]); $nb_document = $em->getRepository(PersonDocument::class)->findBy(['person' => $id]); -// $nb_event = $em->getRepository(Participation::class)->findBy(['person' => $id]); + // $nb_event = $em->getRepository(Participation::class)->findBy(['person' => $id]); $nb_task = $em->getRepository(SingleTask::class)->countByParameters(['person' => $id]); $person = $em->getRepository(Person::class)->findOneBy(['id' => $id]); diff --git a/src/Bundle/ChillThirdPartyBundle/Form/ThirdPartyType.php b/src/Bundle/ChillThirdPartyBundle/Form/ThirdPartyType.php index b1446a543..6c4984f33 100644 --- a/src/Bundle/ChillThirdPartyBundle/Form/ThirdPartyType.php +++ b/src/Bundle/ChillThirdPartyBundle/Form/ThirdPartyType.php @@ -117,7 +117,7 @@ class ThirdPartyType extends AbstractType 'label' => 'thirdparty.Contact data are confidential', ]); - // Institutional ThirdParty (parent) + // Institutional ThirdParty (parent) } else { $builder ->add('nameCompany', TextType::class, [ From 77997e2b6f9b6512e1dcb16c9baac9ff928fbd97 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Wed, 24 May 2023 16:24:58 +0200 Subject: [PATCH 068/321] FIX [review] fix review comments --- .../Resources/views/Export/new_centers_step.html.twig | 6 +++--- src/Bundle/ChillMainBundle/translations/messages.fr.yml | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) 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 40366669c..2e2dc0ec6 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 @@ -43,7 +43,7 @@ {{ form_widget(form.centers.center) }}
    - +
    {% if form.centers.regroupment is defined %} @@ -63,9 +63,9 @@ diff --git a/src/Bundle/ChillMainBundle/translations/messages.fr.yml b/src/Bundle/ChillMainBundle/translations/messages.fr.yml index fa28feef6..78de523c4 100644 --- a/src/Bundle/ChillMainBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillMainBundle/translations/messages.fr.yml @@ -285,8 +285,8 @@ The export will contains only data from the picked centers.: L'export ne contien This will eventually restrict your possibilities in filtering the data.: Les possibilités de filtrages seront adaptées aux droits de consultation pour les centres choisis. Go to export options: Vers la préparation de l'export Pick aggregated centers: Regroupement de centres -uncheck all: Désélectionner tout les centres -check all: Sélectionner tout les centres +uncheck all centers: Désélectionner tous les centres +check all centers: Sélectionner tous les centres # export creation step 'export' : choose aggregators, filtering and formatter Formatter: Mise en forme Choose the formatter: Choisissez le format d'export voulu. From afcd6e0605674312c7b9ce557bed4b9330947ea7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 23 May 2023 22:12:18 +0200 Subject: [PATCH 069/321] bootstrap generic doc manager and associated services --- ...ericDocForAccompanyingPeriodController.php | 48 +++++ .../GenericDoc/FetchQuery.php | 168 ++++++++++++++++++ .../GenericDoc/FetchQueryInterface.php | 45 +++++ .../GenericDoc/FetchQueryToSqlBuilder.php | 48 +++++ .../GenericDoc/GenericDocDTO.php | 22 +++ .../GenericDoc/Manager.php | 102 +++++++++++ ...ProviderForAccompanyingPeriodInterface.php | 33 ++++ .../GenericDoc/FetchQueryToSqlBuilderTest.php | 57 ++++++ .../Tests/GenericDoc/ManagerTest.php | 56 ++++++ .../ChillDocStoreBundle/config/services.yaml | 6 + 10 files changed, 585 insertions(+) create mode 100644 src/Bundle/ChillDocStoreBundle/Controller/GenericDocForAccompanyingPeriodController.php create mode 100644 src/Bundle/ChillDocStoreBundle/GenericDoc/FetchQuery.php create mode 100644 src/Bundle/ChillDocStoreBundle/GenericDoc/FetchQueryInterface.php create mode 100644 src/Bundle/ChillDocStoreBundle/GenericDoc/FetchQueryToSqlBuilder.php create mode 100644 src/Bundle/ChillDocStoreBundle/GenericDoc/GenericDocDTO.php create mode 100644 src/Bundle/ChillDocStoreBundle/GenericDoc/Manager.php create mode 100644 src/Bundle/ChillDocStoreBundle/GenericDoc/ProviderForAccompanyingPeriodInterface.php create mode 100644 src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/FetchQueryToSqlBuilderTest.php create mode 100644 src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/ManagerTest.php diff --git a/src/Bundle/ChillDocStoreBundle/Controller/GenericDocForAccompanyingPeriodController.php b/src/Bundle/ChillDocStoreBundle/Controller/GenericDocForAccompanyingPeriodController.php new file mode 100644 index 000000000..32a7cc1c9 --- /dev/null +++ b/src/Bundle/ChillDocStoreBundle/Controller/GenericDocForAccompanyingPeriodController.php @@ -0,0 +1,48 @@ +security->isGranted(AccompanyingCourseDocumentVoter::SEE, $accompanyingPeriod)) { + throw new AccessDeniedHttpException("not allowed to see the documents for accompanying period"); + } + + $nb = $this->manager->countDocForAccompanyingPeriod($accompanyingPeriod); + + return new Response($nb); + } + +} diff --git a/src/Bundle/ChillDocStoreBundle/GenericDoc/FetchQuery.php b/src/Bundle/ChillDocStoreBundle/GenericDoc/FetchQuery.php new file mode 100644 index 000000000..42e0fd335 --- /dev/null +++ b/src/Bundle/ChillDocStoreBundle/GenericDoc/FetchQuery.php @@ -0,0 +1,168 @@ + + */ + private array $joins = []; + + /** + * @var list + */ + private array $joinParams = []; + + /** + * @var list + */ + private array $wheres = []; + + /** + * @var list + */ + private array $whereParams = []; + + public function __construct( + private readonly string $selectKeyString, + private readonly string $selectIdentifierJsonB, + private readonly string $selectDate, + private string $from = '', + private array $selectIdentifierParams = [], + private array $selectDateParams = [], + ) { + } + + public function addJoinClause(string $sql, array $params = []): int + { + $this->joins[] = $sql; + $this->joinParams[] = $params; + + return count($this->joins) - 1; + } + + public function addWhereClause(string $sql, array $params = []): int + { + $this->wheres[] = $sql; + $this->whereParams[] = $params; + + return count($this->wheres) - 1; + } + + public function removeWhereClause(int $index): void + { + if (!array_key_exists($index, $this->wheres)) { + throw new \UnexpectedValueException("this index does not exists"); + } + + unset($this->wheres[$index], $this->whereParams[$index]); + + } + + public function removeJoinClause(int $index): void + { + if (!array_key_exists($index, $this->joins)) { + throw new \UnexpectedValueException("this index does not exists"); + } + + unset($this->joins[$index], $this->joinParams[$index]); + + } + + public function getSelectKeyString(): string + { + return $this->selectKeyString; + } + + public function getSelectIdentifierJsonB(): string + { + return $this->selectIdentifierJsonB; + } + + /** + * @inheritDoc + */ + public function getSelectIdentifierParams(): array + { + return $this->selectIdentifierParams; + } + + public function getSelectDate(): string + { + return $this->selectDate; + } + + /** + * @inheritDoc + */ + public function getSelectDateParams(): array + { + return $this->selectDateParams; + } + + public function getFromQuery(): string + { + return $this->from . " " . implode(' ', $this->joins); + } + + /** + * @inheritDoc + */ + public function getFromQueryParams(): array + { + $result = []; + + foreach ($this->joinParams as $params) { + $result = [...$result, ...$params]; + } + + return $result; + } + + public function getWhereQuery(): string + { + return implode(' AND ', $this->wheres); + } + + /** + * @inheritDoc + */ + public function getWhereQueryParams(): array + { + $result = []; + + foreach ($this->whereParams as $params) { + $result = [...$result, ...$params]; + } + + return $result; + } + + /** + * @param array $selectIdentifierParams + */ + public function setSelectIdentifierParams(array $selectIdentifierParams): void + { + $this->selectIdentifierParams = $selectIdentifierParams; + } + + /** + * @param array $selectDateParams + */ + public function setSelectDateParams(array $selectDateParams): void + { + $this->selectDateParams = $selectDateParams; + } +} diff --git a/src/Bundle/ChillDocStoreBundle/GenericDoc/FetchQueryInterface.php b/src/Bundle/ChillDocStoreBundle/GenericDoc/FetchQueryInterface.php new file mode 100644 index 000000000..c262d2a5d --- /dev/null +++ b/src/Bundle/ChillDocStoreBundle/GenericDoc/FetchQueryInterface.php @@ -0,0 +1,45 @@ + + */ + public function getSelectIdentifierParams(): array; + + public function getSelectDate(): string; + + /** + * @return list + */ + public function getSelectDateParams(): array; + + public function getFromQuery(): string; + + /** + * @return list + */ + public function getFromQueryParams(): array; + + public function getWhereQuery(): string; + + /** + * @return list + */ + public function getWhereQueryParams(): array; +} diff --git a/src/Bundle/ChillDocStoreBundle/GenericDoc/FetchQueryToSqlBuilder.php b/src/Bundle/ChillDocStoreBundle/GenericDoc/FetchQueryToSqlBuilder.php new file mode 100644 index 000000000..881435da7 --- /dev/null +++ b/src/Bundle/ChillDocStoreBundle/GenericDoc/FetchQueryToSqlBuilder.php @@ -0,0 +1,48 @@ +} + */ + public function toSql(FetchQueryInterface $query): array + { + $sql = strtr(self::SQL, [ + '{{ key }}' => $query->getSelectKeyString(), + '{{ identifiers }}' => $query->getSelectIdentifierJsonB(), + '{{ date }}' => $query->getSelectDate(), + '{{ from }}' => $query->getFromQuery(), + '{{ where }}' => $query->getWhereQuery(), + ]); + + $params = [ + ...$query->getSelectIdentifierParams(), + ...$query->getSelectDateParams(), + ...$query->getFromQueryParams(), + ...$query->getWhereQueryParams() + ]; + + return ['sql' => $sql, 'params' => $params]; + } +} diff --git a/src/Bundle/ChillDocStoreBundle/GenericDoc/GenericDocDTO.php b/src/Bundle/ChillDocStoreBundle/GenericDoc/GenericDocDTO.php new file mode 100644 index 000000000..6fb6139aa --- /dev/null +++ b/src/Bundle/ChillDocStoreBundle/GenericDoc/GenericDocDTO.php @@ -0,0 +1,22 @@ + + */ + private readonly iterable $providersForAccompanyingPeriod, + private readonly Connection $connection, + ) { + $this->builder = new FetchQueryToSqlBuilder(); + } + + /** + * @throws Exception + */ + public function countDocForAccompanyingPeriod( + AccompanyingPeriod $accompanyingPeriod, + ?\DateTimeImmutable $startDate = null, + ?\DateTimeImmutable $endDate = null, + ?string $content = null, + ?string $origin = null + ): int { + ['sql' => $sql, 'params' => $params] = $this->buildUnionQuery($accompanyingPeriod, $startDate, $endDate, $content, $origin); + $countSql = "SELECT count(*) AS c FROM {$sql} AS sq"; + $result = $this->connection->executeQuery($countSql, $params); + + $number = $result->fetchOne(); + + if (false === $number) { + throw new \UnexpectedValueException("number of documents failed to load"); + } + + return $number['c']; + } + + /** + * @throws Exception + */ + public function findDocForAccompanyingPeriod( + AccompanyingPeriod $accompanyingPeriod, + int $offset = 0, + int $limit = 20, + ?\DateTimeImmutable $startDate = null, + ?\DateTimeImmutable $endDate = null, + ?string $content = null, + ?string $origin = null + ): iterable { + ['sql' => $sql, 'params' => $params] = $this->buildUnionQuery($accompanyingPeriod, $startDate, $endDate, $content, $origin); + + $runSql = "{$sql} LIMIT ? OFFSET ?"; + $runParams = [...$params, ...[$limit, $offset]]; + + foreach($this->connection->iterateAssociative($runSql, $runParams) as $row) { + yield new GenericDocDTO($row['key'], $row['identifiers'], $row['date_doc']); + } + } + + /** + */ + private function buildUnionQuery( + AccompanyingPeriod|Person $linked, + ?\DateTimeImmutable $startDate = null, + ?\DateTimeImmutable $endDate = null, + ?string $content = null, + ?string $origin = null + ): array { + $sql = []; + $params = []; + + if ($linked instanceof AccompanyingPeriod) { + foreach ($this->providersForAccompanyingPeriod as $provider) { + ['sql' => $q, 'params' => $p ] = $this->builder + ->toSql($provider->buildFetchQueryForAccompanyingPeriod($linked, $startDate, $endDate, $content, $origin)); + $params = [...$params, ...$p]; + $sql[] = $q; + } + } + + return ['sql' => implode(' UNION ', $sql), 'params' => $params]; + } + +} diff --git a/src/Bundle/ChillDocStoreBundle/GenericDoc/ProviderForAccompanyingPeriodInterface.php b/src/Bundle/ChillDocStoreBundle/GenericDoc/ProviderForAccompanyingPeriodInterface.php new file mode 100644 index 000000000..07ca83694 --- /dev/null +++ b/src/Bundle/ChillDocStoreBundle/GenericDoc/ProviderForAccompanyingPeriodInterface.php @@ -0,0 +1,33 @@ +addJoinClause('LEFT JOIN other b ON a.id = b.foreign_id', ['foo']); + $index = $query->addJoinClause('LEFT JOIN other c ON a.id = c.foreign_id', ['bar']); + $query->addJoinClause('LEFT JOIN other d ON a.id = d.foreign_id', ['bar_baz']); + $query->removeJoinClause($index); + $query->addWhereClause('b.item = ?', ['baz']); + $index = $query->addWhereClause('b.cancel', [ 'foz']); + $query->removeWhereClause($index); + + ['sql' => $sql, 'params' => $params] = (new FetchQueryToSqlBuilder())->toSql($query); + + $filteredSql = + implode(" ", array_filter( + explode(" ", str_replace("\n", "", $sql)), + fn (string $tok) => $tok !== "" + )) + ; + + self::assertEquals( + "SELECT 'test' AS key, jsonb_build_object('id', a.column) AS identifiers, ". + "a.datecolumn AS doc_date FROM my_table a LEFT JOIN other b ON a.id = b.foreign_id LEFT JOIN other d ON a.id = d.foreign_id WHERE b.item = ?", + $filteredSql + ); + self::assertEquals(['foo', 'bar_baz', 'baz'], $params); + } + +} diff --git a/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/ManagerTest.php b/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/ManagerTest.php new file mode 100644 index 000000000..523e08c40 --- /dev/null +++ b/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/ManagerTest.php @@ -0,0 +1,56 @@ +em = self::$container->get(EntityManagerInterface::class); + + if (null !== $manager = self::$container->get(Manager::class)) { + $this->manager = $manager; + } else { + throw new \UnexpectedValueException("the manager was not found in the kernel"); + } + } + + public function testCountByAccompanyingPeriod(): void + { + $period = $this->em->createQuery('SELECT a FROM '.AccompanyingPeriod::class.' a') + ->setMaxResults(1) + ->getSingleResult(); + + if (null === $period) { + throw new \UnexpectedValueException("period not found"); + } + + $nb = $this->manager->countDocForAccompanyingPeriod($period); + + self::assertIsInt($nb); + } +} diff --git a/src/Bundle/ChillDocStoreBundle/config/services.yaml b/src/Bundle/ChillDocStoreBundle/config/services.yaml index 860495677..22161d2f6 100644 --- a/src/Bundle/ChillDocStoreBundle/config/services.yaml +++ b/src/Bundle/ChillDocStoreBundle/config/services.yaml @@ -45,3 +45,9 @@ services: autoconfigure: true resource: '../Service/' + Chill\DocStoreBundle\GenericDoc\Manager: + autowire: true + autoconfigure: true + arguments: + $providersForAccompanyingPeriod: !tagged_iterator chill_doc_store.generic_doc_accompanying_period_provider + From 8dbe2d6ec20e166f3259f41e08798842b4c184bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 24 May 2023 11:42:30 +0200 Subject: [PATCH 070/321] GenericDoc: add provider for AccompanyingCourseDocument, without filtering --- .../ChillDocStoreBundle.php | 7 ++ ...ericDocForAccompanyingPeriodController.php | 4 + .../GenericDoc/FetchQuery.php | 99 +++++++++++++++---- .../GenericDoc/FetchQueryInterface.php | 22 +++++ .../GenericDoc/FetchQueryToSqlBuilder.php | 19 +++- .../GenericDoc/Manager.php | 32 ++++-- ...ProviderForAccompanyingPeriodInterface.php | 2 +- .../AccompanyingCourseDocumentProvider.php | 84 ++++++++++++++++ .../GenericDoc/FetchQueryToSqlBuilderTest.php | 46 +++++++-- .../Tests/GenericDoc/ManagerTest.php | 63 ++++++++++-- ...AccompanyingCourseDocumentProviderTest.php | 78 +++++++++++++++ .../ChillDocStoreBundle/config/services.yaml | 4 + 12 files changed, 414 insertions(+), 46 deletions(-) create mode 100644 src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/AccompanyingCourseDocumentProvider.php create mode 100644 src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/Providers/AccompanyingCourseDocumentProviderTest.php diff --git a/src/Bundle/ChillDocStoreBundle/ChillDocStoreBundle.php b/src/Bundle/ChillDocStoreBundle/ChillDocStoreBundle.php index 81c71f45f..44bc7d70d 100644 --- a/src/Bundle/ChillDocStoreBundle/ChillDocStoreBundle.php +++ b/src/Bundle/ChillDocStoreBundle/ChillDocStoreBundle.php @@ -11,8 +11,15 @@ declare(strict_types=1); namespace Chill\DocStoreBundle; +use Chill\DocStoreBundle\GenericDoc\ProviderForAccompanyingPeriodInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\HttpKernel\Bundle\Bundle; class ChillDocStoreBundle extends Bundle { + public function build(ContainerBuilder $container) + { + $container->registerForAutoconfiguration(ProviderForAccompanyingPeriodInterface::class) + ->addTag('chill_doc_store.generic_doc_accompanying_period_provider'); + } } diff --git a/src/Bundle/ChillDocStoreBundle/Controller/GenericDocForAccompanyingPeriodController.php b/src/Bundle/ChillDocStoreBundle/Controller/GenericDocForAccompanyingPeriodController.php index 32a7cc1c9..0a9175087 100644 --- a/src/Bundle/ChillDocStoreBundle/Controller/GenericDocForAccompanyingPeriodController.php +++ b/src/Bundle/ChillDocStoreBundle/Controller/GenericDocForAccompanyingPeriodController.php @@ -42,6 +42,10 @@ final readonly class GenericDocForAccompanyingPeriodController $nb = $this->manager->countDocForAccompanyingPeriod($accompanyingPeriod); + foreach ($this->manager->findDocForAccompanyingPeriod($accompanyingPeriod) as $dto) { + dump($dto); + } + return new Response($nb); } diff --git a/src/Bundle/ChillDocStoreBundle/GenericDoc/FetchQuery.php b/src/Bundle/ChillDocStoreBundle/GenericDoc/FetchQuery.php index 42e0fd335..30e07a841 100644 --- a/src/Bundle/ChillDocStoreBundle/GenericDoc/FetchQuery.php +++ b/src/Bundle/ChillDocStoreBundle/GenericDoc/FetchQuery.php @@ -11,7 +11,7 @@ declare(strict_types=1); namespace Chill\DocStoreBundle\GenericDoc; -use Nelmio\Alice\Throwable\Exception\FixtureBuilder\Denormalizer\UnexpectedValueException; +use Doctrine\DBAL\Types\Types; class FetchQuery implements FetchQueryInterface { @@ -21,42 +21,56 @@ class FetchQuery implements FetchQueryInterface private array $joins = []; /** - * @var list + * @var list> */ private array $joinParams = []; /** - * @var list + * @var array> + */ + private array $joinTypes = []; + + /** + * @var array */ private array $wheres = []; /** - * @var list + * @var array> */ private array $whereParams = []; + /** + * @var array> + */ + private array $whereTypes = []; + public function __construct( private readonly string $selectKeyString, private readonly string $selectIdentifierJsonB, private readonly string $selectDate, private string $from = '', private array $selectIdentifierParams = [], + private array $selectIdentifierTypes = [], private array $selectDateParams = [], + private array $selectDateTypes = [], ) { } - public function addJoinClause(string $sql, array $params = []): int + public function addJoinClause(string $sql, array $params = [], array $types = []): int { $this->joins[] = $sql; $this->joinParams[] = $params; + $this->joinTypes[] = $types; return count($this->joins) - 1; } - public function addWhereClause(string $sql, array $params = []): int + public function addWhereClause(string $sql, array $params = [], array $types = []): int { $this->wheres[] = $sql; $this->whereParams[] = $params; + $this->whereTypes[] = $types; return count($this->wheres) - 1; } @@ -67,7 +81,7 @@ class FetchQuery implements FetchQueryInterface throw new \UnexpectedValueException("this index does not exists"); } - unset($this->wheres[$index], $this->whereParams[$index]); + unset($this->wheres[$index], $this->whereParams[$index], $this->whereTypes[$index]); } @@ -77,7 +91,7 @@ class FetchQuery implements FetchQueryInterface throw new \UnexpectedValueException("this index does not exists"); } - unset($this->joins[$index], $this->joinParams[$index]); + unset($this->joins[$index], $this->joinParams[$index], $this->joinTypes[$index]); } @@ -99,11 +113,21 @@ class FetchQuery implements FetchQueryInterface return $this->selectIdentifierParams; } + public function getSelectIdentifiersTypes(): array + { + return $this->selectIdentifierTypes; + } + public function getSelectDate(): string { return $this->selectDate; } + public function getSelectDateTypes(): array + { + return $this->selectDateTypes; + } + /** * @inheritDoc */ @@ -131,6 +155,17 @@ class FetchQuery implements FetchQueryInterface return $result; } + public function getFromQueryTypes(): array + { + $result = []; + + foreach ($this->joinTypes as $types) { + $result = [...$result, ...$types]; + } + + return $result; + } + public function getWhereQuery(): string { return implode(' AND ', $this->wheres); @@ -150,19 +185,49 @@ class FetchQuery implements FetchQueryInterface return $result; } - /** - * @param array $selectIdentifierParams - */ - public function setSelectIdentifierParams(array $selectIdentifierParams): void + public function getWhereQueryTypes(): array { - $this->selectIdentifierParams = $selectIdentifierParams; + $result = []; + + foreach ($this->whereTypes as $types) { + $result = [...$result, ...$types]; + } + + return $result; } - /** - * @param array $selectDateParams - */ - public function setSelectDateParams(array $selectDateParams): void + public function setSelectIdentifierParams(array $selectIdentifierParams): self + { + $this->selectIdentifierParams = $selectIdentifierParams; + + return $this; + } + + public function setSelectDateParams(array $selectDateParams): self { $this->selectDateParams = $selectDateParams; + + return $this; + } + + public function setFrom(string $from): self + { + $this->from = $from; + + return $this; + } + + public function setSelectIdentifierTypes(array $selectIdentifierTypes): self + { + $this->selectIdentifierTypes = $selectIdentifierTypes; + + return $this; + } + + public function setSelectDateTypes(array $selectDateTypes): self + { + $this->selectDateTypes = $selectDateTypes; + + return $this; } } diff --git a/src/Bundle/ChillDocStoreBundle/GenericDoc/FetchQueryInterface.php b/src/Bundle/ChillDocStoreBundle/GenericDoc/FetchQueryInterface.php index c262d2a5d..e46795457 100644 --- a/src/Bundle/ChillDocStoreBundle/GenericDoc/FetchQueryInterface.php +++ b/src/Bundle/ChillDocStoreBundle/GenericDoc/FetchQueryInterface.php @@ -11,6 +11,8 @@ declare(strict_types=1); namespace Chill\DocStoreBundle\GenericDoc; +use Doctrine\DBAL\Types\Types; + interface FetchQueryInterface { public function getSelectKeyString(): string; @@ -22,6 +24,11 @@ interface FetchQueryInterface */ public function getSelectIdentifierParams(): array; + /** + * @return list + */ + public function getSelectIdentifiersTypes(): array; + public function getSelectDate(): string; /** @@ -29,6 +36,11 @@ interface FetchQueryInterface */ public function getSelectDateParams(): array; + /** + * @return list + */ + public function getSelectDateTypes(): array; + public function getFromQuery(): string; /** @@ -36,10 +48,20 @@ interface FetchQueryInterface */ public function getFromQueryParams(): array; + /** + * @return list + */ + public function getFromQueryTypes(): array; + public function getWhereQuery(): string; /** * @return list */ public function getWhereQueryParams(): array; + + /** + * @return list + */ + public function getWhereQueryTypes(): array; } diff --git a/src/Bundle/ChillDocStoreBundle/GenericDoc/FetchQueryToSqlBuilder.php b/src/Bundle/ChillDocStoreBundle/GenericDoc/FetchQueryToSqlBuilder.php index 881435da7..2c0c59cff 100644 --- a/src/Bundle/ChillDocStoreBundle/GenericDoc/FetchQueryToSqlBuilder.php +++ b/src/Bundle/ChillDocStoreBundle/GenericDoc/FetchQueryToSqlBuilder.php @@ -11,20 +11,22 @@ declare(strict_types=1); namespace Chill\DocStoreBundle\GenericDoc; +use Doctrine\DBAL\Types\Types; + final readonly class FetchQueryToSqlBuilder { private const SQL = <<<'SQL' SELECT '{{ key }}' AS key, {{ identifiers }} AS identifiers, - {{ date }} AS doc_date + {{ date }}::date AS doc_date FROM {{ from }} - WHERE {{ where }} + {{ where }} SQL; /** * @param FetchQueryInterface $query - * @return array{sql: string, params: list} + * @return array{sql: string, params: list, types: list} */ public function toSql(FetchQueryInterface $query): array { @@ -33,7 +35,7 @@ final readonly class FetchQueryToSqlBuilder '{{ identifiers }}' => $query->getSelectIdentifierJsonB(), '{{ date }}' => $query->getSelectDate(), '{{ from }}' => $query->getFromQuery(), - '{{ where }}' => $query->getWhereQuery(), + '{{ where }}' => '' === ($w = $query->getWhereQuery()) ? '' : 'WHERE ' . $w, ]); $params = [ @@ -43,6 +45,13 @@ final readonly class FetchQueryToSqlBuilder ...$query->getWhereQueryParams() ]; - return ['sql' => $sql, 'params' => $params]; + $types = [ + ...$query->getSelectIdentifiersTypes(), + ...$query->getSelectDateTypes(), + ...$query->getFromQueryTypes(), + ...$query->getWhereQueryTypes(), + ]; + + return ['sql' => $sql, 'params' => $params, 'types' => $types]; } } diff --git a/src/Bundle/ChillDocStoreBundle/GenericDoc/Manager.php b/src/Bundle/ChillDocStoreBundle/GenericDoc/Manager.php index bbc46c367..d67ff6d0d 100644 --- a/src/Bundle/ChillDocStoreBundle/GenericDoc/Manager.php +++ b/src/Bundle/ChillDocStoreBundle/GenericDoc/Manager.php @@ -15,6 +15,7 @@ use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\Person; use Doctrine\DBAL\Connection; use Doctrine\DBAL\Exception; +use Doctrine\DBAL\Types\Types; class Manager { @@ -41,7 +42,12 @@ class Manager ?string $origin = null ): int { ['sql' => $sql, 'params' => $params] = $this->buildUnionQuery($accompanyingPeriod, $startDate, $endDate, $content, $origin); - $countSql = "SELECT count(*) AS c FROM {$sql} AS sq"; + + if ($sql === '') { + return 0; + } + + $countSql = "SELECT count(*) AS c FROM ({$sql}) AS sq"; $result = $this->connection->executeQuery($countSql, $params); $number = $result->fetchOne(); @@ -50,7 +56,7 @@ class Manager throw new \UnexpectedValueException("number of documents failed to load"); } - return $number['c']; + return $number; } /** @@ -65,13 +71,18 @@ class Manager ?string $content = null, ?string $origin = null ): iterable { - ['sql' => $sql, 'params' => $params] = $this->buildUnionQuery($accompanyingPeriod, $startDate, $endDate, $content, $origin); + ['sql' => $sql, 'params' => $params, 'types' => $types] = $this->buildUnionQuery($accompanyingPeriod, $startDate, $endDate, $content, $origin); $runSql = "{$sql} LIMIT ? OFFSET ?"; $runParams = [...$params, ...[$limit, $offset]]; + $runTypes = [...$types, ...[Types::INTEGER, Types::INTEGER]]; - foreach($this->connection->iterateAssociative($runSql, $runParams) as $row) { - yield new GenericDocDTO($row['key'], $row['identifiers'], $row['date_doc']); + foreach($this->connection->iterateAssociative($runSql, $runParams, $runTypes) as $row) { + yield new GenericDocDTO( + $row['key'], + json_decode($row['identifiers'], true, JSON_THROW_ON_ERROR), + new \DateTimeImmutable($row['doc_date']) + ); } } @@ -86,17 +97,24 @@ class Manager ): array { $sql = []; $params = []; + $types = []; if ($linked instanceof AccompanyingPeriod) { foreach ($this->providersForAccompanyingPeriod as $provider) { - ['sql' => $q, 'params' => $p ] = $this->builder + if (!$provider->isAllowedForAccompanyingPeriod($linked)) { + continue; + } + + ['sql' => $q, 'params' => $p, 'types' => $t ] = $this->builder ->toSql($provider->buildFetchQueryForAccompanyingPeriod($linked, $startDate, $endDate, $content, $origin)); $params = [...$params, ...$p]; + $types = [...$types, ...$t]; + $sql[] = $q; } } - return ['sql' => implode(' UNION ', $sql), 'params' => $params]; + return ['sql' => implode(' UNION ', $sql), 'params' => $params, 'types' => $types]; } } diff --git a/src/Bundle/ChillDocStoreBundle/GenericDoc/ProviderForAccompanyingPeriodInterface.php b/src/Bundle/ChillDocStoreBundle/GenericDoc/ProviderForAccompanyingPeriodInterface.php index 07ca83694..935fe48a9 100644 --- a/src/Bundle/ChillDocStoreBundle/GenericDoc/ProviderForAccompanyingPeriodInterface.php +++ b/src/Bundle/ChillDocStoreBundle/GenericDoc/ProviderForAccompanyingPeriodInterface.php @@ -28,6 +28,6 @@ interface ProviderForAccompanyingPeriodInterface * * @return bool */ - public function isAllowed(): bool; + public function isAllowedForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod): bool; } diff --git a/src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/AccompanyingCourseDocumentProvider.php b/src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/AccompanyingCourseDocumentProvider.php new file mode 100644 index 000000000..8f6a9fdad --- /dev/null +++ b/src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/AccompanyingCourseDocumentProvider.php @@ -0,0 +1,84 @@ +entityManager->getClassMetadata(AccompanyingCourseDocument::class); + + $query = new FetchQuery( + 'accompanying_course_document', + sprintf('jsonb_build_object(\'id\', %s)', $classMetadata->getIdentifierColumnNames()[0]), + sprintf($classMetadata->getColumnName('date')), + $classMetadata->getSchemaName() . '.' . $classMetadata->getTableName() + ); + + $query->addWhereClause( + sprintf('%s = ?', $classMetadata->getSingleAssociationJoinColumnName('course')), + [$accompanyingPeriod->getId()], + [Types::INTEGER] + ); + + if (null !== $startDate) { + $query->addWhereClause( + sprintf('? >= %s', $classMetadata->getColumnName('date')), + [$startDate], + [Types::DATE_IMMUTABLE] + ); + } + + if (null !== $endDate) { + $query->addWhereClause( + sprintf('? < %s', $classMetadata->getColumnName('date')), + [$endDate], + [Types::DATE_IMMUTABLE] + ); + } + + if (null !== $content) { + $query->addWhereClause( + sprintf( + '(%s ilike ? OR %s ilike ?)', + $classMetadata->getColumnName('title'), + $classMetadata->getColumnName('description') + ), + [$content, $content], + [Types::STRING, Types::STRING] + ); + } + + return $query; + } + + public function isAllowedForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod): bool + { + return $this->security->isGranted(AccompanyingCourseDocumentVoter::SEE, $accompanyingPeriod); + } +} diff --git a/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/FetchQueryToSqlBuilderTest.php b/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/FetchQueryToSqlBuilderTest.php index c6db09513..02be9460f 100644 --- a/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/FetchQueryToSqlBuilderTest.php +++ b/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/FetchQueryToSqlBuilderTest.php @@ -13,6 +13,7 @@ namespace Chill\DocStoreBundle\Tests\GenericDoc; use Chill\DocStoreBundle\GenericDoc\FetchQueryToSqlBuilder; use Chill\DocStoreBundle\GenericDoc\FetchQuery; +use Doctrine\DBAL\Types\Types; use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; /** @@ -29,15 +30,15 @@ class FetchQueryToSqlBuilderTest extends KernelTestCase 'a.datecolumn', 'my_table a' ); - $query->addJoinClause('LEFT JOIN other b ON a.id = b.foreign_id', ['foo']); - $index = $query->addJoinClause('LEFT JOIN other c ON a.id = c.foreign_id', ['bar']); - $query->addJoinClause('LEFT JOIN other d ON a.id = d.foreign_id', ['bar_baz']); + $query->addJoinClause('LEFT JOIN other b ON a.id = b.foreign_id', ['foo'], [Types::STRING]); + $index = $query->addJoinClause('LEFT JOIN other c ON a.id = c.foreign_id', ['bar'], [Types::STRING]); + $query->addJoinClause('LEFT JOIN other d ON a.id = d.foreign_id', ['bar_baz'], [Types::STRING]); $query->removeJoinClause($index); - $query->addWhereClause('b.item = ?', ['baz']); - $index = $query->addWhereClause('b.cancel', [ 'foz']); + $query->addWhereClause('b.item = ?', ['baz'], [Types::STRING]); + $index = $query->addWhereClause('b.cancel', [ 'foz'], [Types::STRING]); $query->removeWhereClause($index); - ['sql' => $sql, 'params' => $params] = (new FetchQueryToSqlBuilder())->toSql($query); + ['sql' => $sql, 'params' => $params, 'types' => $types] = (new FetchQueryToSqlBuilder())->toSql($query); $filteredSql = implode(" ", array_filter( @@ -48,10 +49,41 @@ class FetchQueryToSqlBuilderTest extends KernelTestCase self::assertEquals( "SELECT 'test' AS key, jsonb_build_object('id', a.column) AS identifiers, ". - "a.datecolumn AS doc_date FROM my_table a LEFT JOIN other b ON a.id = b.foreign_id LEFT JOIN other d ON a.id = d.foreign_id WHERE b.item = ?", + "a.datecolumn::date AS doc_date FROM my_table a LEFT JOIN other b ON a.id = b.foreign_id LEFT JOIN other d ON a.id = d.foreign_id WHERE b.item = ?", $filteredSql ); self::assertEquals(['foo', 'bar_baz', 'baz'], $params); + self::assertEquals([Types::STRING, Types::STRING, Types::STRING], $types); + + + + } + + public function testToSqlWithoutWhere(): void + { + $query = new FetchQuery( + 'test', + 'jsonb_build_object(\'id\', a.column)', + 'a.datecolumn', + 'my_table a' + ); + + ['sql' => $sql, 'params' => $params, 'types' => $types] = (new FetchQueryToSqlBuilder())->toSql($query); + + $filteredSql = + implode(" ", array_filter( + explode(" ", str_replace("\n", "", $sql)), + fn (string $tok) => $tok !== "" + )) + ; + + self::assertEquals( + "SELECT 'test' AS key, jsonb_build_object('id', a.column) AS identifiers, ". + "a.datecolumn::date AS doc_date FROM my_table a", + $filteredSql + ); + self::assertEquals([], $params); + self::assertEquals([], $types); } } diff --git a/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/ManagerTest.php b/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/ManagerTest.php index 523e08c40..59cc24bf2 100644 --- a/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/ManagerTest.php +++ b/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/ManagerTest.php @@ -11,9 +11,15 @@ declare(strict_types=1); namespace Chill\DocStoreBundle\Tests\GenericDoc; +use Chill\DocStoreBundle\GenericDoc\FetchQuery; +use Chill\DocStoreBundle\GenericDoc\FetchQueryInterface; +use Chill\DocStoreBundle\GenericDoc\GenericDocDTO; use Chill\DocStoreBundle\GenericDoc\Manager; +use Chill\DocStoreBundle\GenericDoc\ProviderForAccompanyingPeriodInterface; use Chill\PersonBundle\Entity\AccompanyingPeriod; +use Doctrine\DBAL\Connection; use Doctrine\ORM\EntityManagerInterface; +use Prophecy\PhpUnit\ProphecyTrait; use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; /** @@ -22,21 +28,17 @@ use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; */ class ManagerTest extends KernelTestCase { - private Manager $manager; - + use ProphecyTrait; private EntityManagerInterface $em; + private Connection $connection; + protected function setUp(): void { self::bootKernel(); $this->em = self::$container->get(EntityManagerInterface::class); - - if (null !== $manager = self::$container->get(Manager::class)) { - $this->manager = $manager; - } else { - throw new \UnexpectedValueException("the manager was not found in the kernel"); - } + $this->connection = self::$container->get(Connection::class); } public function testCountByAccompanyingPeriod(): void @@ -49,8 +51,51 @@ class ManagerTest extends KernelTestCase throw new \UnexpectedValueException("period not found"); } - $nb = $this->manager->countDocForAccompanyingPeriod($period); + $manager = new Manager( + [new SimpleProvider()], + $this->connection, + ); + + $nb = $manager->countDocForAccompanyingPeriod($period); self::assertIsInt($nb); } + + public function testFindDocByAccompanyingPeriod(): void + { + $period = $this->em->createQuery('SELECT a FROM '.AccompanyingPeriod::class.' a') + ->setMaxResults(1) + ->getSingleResult(); + + if (null === $period) { + throw new \UnexpectedValueException("period not found"); + } + + $manager = new Manager( + [new SimpleProvider()], + $this->connection, + ); + + foreach ($manager->findDocForAccompanyingPeriod($period) as $doc) { + self::assertInstanceOf(GenericDocDTO::class, $doc); + } + } +} + +final readonly class SimpleProvider implements ProviderForAccompanyingPeriodInterface +{ + public function buildFetchQueryForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod, ?\DateTimeImmutable $startDate = null, ?\DateTimeImmutable $endDate = null, ?string $content = null, ?string $origin = null): FetchQueryInterface + { + return new FetchQuery( + 'accompanying_course_document', + sprintf('jsonb_build_object(\'id\', %s)', 'id'), + 'd', + '(VALUES (1, \'2023-05-01\'::date), (2, \'2023-05-01\'::date)) AS sq (id, d)', + ); + } + + public function isAllowedForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod): bool + { + return true; + } } diff --git a/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/Providers/AccompanyingCourseDocumentProviderTest.php b/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/Providers/AccompanyingCourseDocumentProviderTest.php new file mode 100644 index 000000000..b88f8e36f --- /dev/null +++ b/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/Providers/AccompanyingCourseDocumentProviderTest.php @@ -0,0 +1,78 @@ +entityManager = self::$container->get(EntityManagerInterface::class); + } + + /** + * @dataProvider provideSearchArguments + */ + public function testWithoutAnyArgument(?\DateTimeImmutable $startDate, ?\DateTimeImmutable $endDate, ?string $content = null): void + { + $period = $this->entityManager->createQuery('SELECT a FROM '.AccompanyingPeriod::class.' a') + ->setMaxResults(1) + ->getSingleResult(); + + if (null === $period) { + throw new \UnexpectedValueException("period not found"); + } + + $security = $this->prophesize(Security::class); + $security->isGranted(AccompanyingCourseDocumentVoter::SEE, $period) + ->willReturn(true); + + $provider = new AccompanyingCourseDocumentProvider( + $security->reveal(), + $this->entityManager + ); + + $query = $provider->buildFetchQueryForAccompanyingPeriod($period, $startDate, $endDate, $content); + + ['sql' => $sql, 'params' => $params, 'types' => $types] = (new FetchQueryToSqlBuilder())->toSql($query); + + $this->entityManager->getConnection()->executeQuery($sql, $params, $types); + + self::assertTrue(true, "test that no errors occurs"); + } + + public function provideSearchArguments(): iterable + { + yield [null, null, null]; + yield [new \DateTimeImmutable('1 month ago'), null, null]; + yield [new \DateTimeImmutable('1 month ago'), new \DateTimeImmutable('now'), null]; + yield [null, null, 'test']; + } +} diff --git a/src/Bundle/ChillDocStoreBundle/config/services.yaml b/src/Bundle/ChillDocStoreBundle/config/services.yaml index 22161d2f6..16b0365d4 100644 --- a/src/Bundle/ChillDocStoreBundle/config/services.yaml +++ b/src/Bundle/ChillDocStoreBundle/config/services.yaml @@ -51,3 +51,7 @@ services: arguments: $providersForAccompanyingPeriod: !tagged_iterator chill_doc_store.generic_doc_accompanying_period_provider + Chill\DocStoreBundle\GenericDoc\Providers\: + autowire: true + autoconfigure: true + resource: '../GenericDoc/Providers/' From fec2dd0f74e852f48fd2bb4102eafc2147468a11 Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Wed, 24 May 2023 19:51:52 +0200 Subject: [PATCH 071/321] enable debug --- .../public/vuejs/_components/Entity/PersonRenderBox.vue | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/_components/Entity/PersonRenderBox.vue b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/_components/Entity/PersonRenderBox.vue index 740eb0039..1833222e8 100644 --- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/_components/Entity/PersonRenderBox.vue +++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/_components/Entity/PersonRenderBox.vue @@ -207,7 +207,7 @@ diff --git a/src/Bundle/ChillDocStoreBundle/Resources/public/vuejs/StoredObjectButton/helpers.ts b/src/Bundle/ChillDocStoreBundle/Resources/public/vuejs/StoredObjectButton/helpers.ts index 5b61a108d..c0b0fa940 100644 --- a/src/Bundle/ChillDocStoreBundle/Resources/public/vuejs/StoredObjectButton/helpers.ts +++ b/src/Bundle/ChillDocStoreBundle/Resources/public/vuejs/StoredObjectButton/helpers.ts @@ -149,16 +149,21 @@ async function download_and_decrypt_doc(urlGenerator: string, keyData: JsonWebKe } if (iv.length === 0) { + console.log('returning document immediatly'); return rawResponse.blob(); } + console.log('start decrypting doc'); + const rawBuffer = await rawResponse.arrayBuffer(); try { const key = await window.crypto.subtle .importKey('jwk', keyData, { name: algo }, false, ['decrypt']); + console.log('key created'); const decrypted = await window.crypto.subtle .decrypt({ name: algo, iv: iv }, key, rawBuffer); + console.log('doc decrypted'); return Promise.resolve(new Blob([decrypted])); } catch (e) { From 60aeb57c45d6d2e923fad9288d1a76c2730d7847 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Thu, 25 May 2023 12:43:09 +0200 Subject: [PATCH 085/321] FIX [filiation] change validator to allow delete and patch of relationship --- .../Relationship/RelationshipNoDuplicateValidator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Bundle/ChillPersonBundle/Validator/Constraints/Relationship/RelationshipNoDuplicateValidator.php b/src/Bundle/ChillPersonBundle/Validator/Constraints/Relationship/RelationshipNoDuplicateValidator.php index 10e651b56..cb1e5395e 100644 --- a/src/Bundle/ChillPersonBundle/Validator/Constraints/Relationship/RelationshipNoDuplicateValidator.php +++ b/src/Bundle/ChillPersonBundle/Validator/Constraints/Relationship/RelationshipNoDuplicateValidator.php @@ -46,7 +46,7 @@ class RelationshipNoDuplicateValidator extends ConstraintValidator ]); foreach ($relationships as $r) { - if ( + if ( spl_object_hash($r) !== spl_object_hash($value) and $r->getFromPerson() === $fromPerson || $r->getFromPerson() === $toPerson || $r->getToPerson() === $fromPerson From 72f5b0b275b7fd4528fabe70eb516729c165c156 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Thu, 25 May 2023 12:52:23 +0200 Subject: [PATCH 086/321] DX [cs-fix] --- .../Relationship/RelationshipNoDuplicateValidator.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Validator/Constraints/Relationship/RelationshipNoDuplicateValidator.php b/src/Bundle/ChillPersonBundle/Validator/Constraints/Relationship/RelationshipNoDuplicateValidator.php index cb1e5395e..b44a966cc 100644 --- a/src/Bundle/ChillPersonBundle/Validator/Constraints/Relationship/RelationshipNoDuplicateValidator.php +++ b/src/Bundle/ChillPersonBundle/Validator/Constraints/Relationship/RelationshipNoDuplicateValidator.php @@ -46,8 +46,8 @@ class RelationshipNoDuplicateValidator extends ConstraintValidator ]); foreach ($relationships as $r) { - if ( spl_object_hash($r) !== spl_object_hash($value) and - $r->getFromPerson() === $fromPerson + if (spl_object_hash($r) !== spl_object_hash($value) + and $r->getFromPerson() === $fromPerson || $r->getFromPerson() === $toPerson || $r->getToPerson() === $fromPerson || $r->getToPerson() === $toPerson From 1b0569c9744ede4a7b430888ab87a5880afaf516 Mon Sep 17 00:00:00 2001 From: nobohan Date: Thu, 25 May 2023 13:58:46 +0200 Subject: [PATCH 087/321] Feature: add thirdParty choice in docgen context - use array_values --- .../AccompanyingPeriodContext.php | 14 ++++++----- ...ccompanyingPeriodWorkEvaluationContext.php | 16 +++++++------ .../Service/DocGenerator/PersonContext.php | 24 +++++++++++-------- 3 files changed, 31 insertions(+), 23 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Service/DocGenerator/AccompanyingPeriodContext.php b/src/Bundle/ChillPersonBundle/Service/DocGenerator/AccompanyingPeriodContext.php index d0ea59090..66be9aceb 100644 --- a/src/Bundle/ChillPersonBundle/Service/DocGenerator/AccompanyingPeriodContext.php +++ b/src/Bundle/ChillPersonBundle/Service/DocGenerator/AccompanyingPeriodContext.php @@ -214,13 +214,15 @@ class AccompanyingPeriodContext implements } $thirdParties = array_merge( - array_filter([$entity->getRequestorThirdParty()]), + array_filter(array_values([$entity->getRequestorThirdParty()])), array_filter( - array_map( - fn (Resource $r): ?ThirdParty => $r->getThirdParty(), - $entity->getResources()->filter( - static fn (Resource $r): bool => null !== $r->getThirdParty() - )->toArray() + array_values( + array_map( + fn (Resource $r): ?ThirdParty => $r->getThirdParty(), + $entity->getResources()->filter( + static fn (Resource $r): bool => null !== $r->getThirdParty() + )->toArray() + ) ) ) ); diff --git a/src/Bundle/ChillPersonBundle/Service/DocGenerator/AccompanyingPeriodWorkEvaluationContext.php b/src/Bundle/ChillPersonBundle/Service/DocGenerator/AccompanyingPeriodWorkEvaluationContext.php index d7fff210b..62e13789f 100644 --- a/src/Bundle/ChillPersonBundle/Service/DocGenerator/AccompanyingPeriodWorkEvaluationContext.php +++ b/src/Bundle/ChillPersonBundle/Service/DocGenerator/AccompanyingPeriodWorkEvaluationContext.php @@ -117,14 +117,16 @@ class AccompanyingPeriodWorkEvaluationContext implements $this->accompanyingPeriodWorkContext->buildPublicForm($builder, $template, $entity->getAccompanyingPeriodWork()); $thirdParties = array_merge( - array_filter($entity->getAccompanyingPeriodWork()->getThirdParties()->toArray()), - array_filter([$entity->getAccompanyingPeriodWork()->getHandlingThierParty()]), + array_filter(array_values($entity->getAccompanyingPeriodWork()->getThirdParties()->toArray())), + array_filter(array_values([$entity->getAccompanyingPeriodWork()->getHandlingThierParty()])), array_filter( - array_map( - fn (Resource $r): ?ThirdParty => $r->getThirdParty(), - $entity->getAccompanyingPeriodWork()->getAccompanyingPeriod()->getResources()->filter( - static fn (Resource $r): bool => null !== $r->getThirdParty() - )->toArray() + array_values( + array_map( + fn (Resource $r): ?ThirdParty => $r->getThirdParty(), + $entity->getAccompanyingPeriodWork()->getAccompanyingPeriod()->getResources()->filter( + static fn (Resource $r): bool => null !== $r->getThirdParty() + )->toArray() + ) ) ) ); diff --git a/src/Bundle/ChillPersonBundle/Service/DocGenerator/PersonContext.php b/src/Bundle/ChillPersonBundle/Service/DocGenerator/PersonContext.php index 583ac189c..4d49bcfba 100644 --- a/src/Bundle/ChillPersonBundle/Service/DocGenerator/PersonContext.php +++ b/src/Bundle/ChillPersonBundle/Service/DocGenerator/PersonContext.php @@ -178,19 +178,23 @@ final class PersonContext implements PersonContextInterface $thirdParties = array_merge( array_filter( - array_map( - fn (ResidentialAddress $r): ?ThirdParty => $r->getHostThirdParty(), - $this - ->residentialAddressRepository - ->findCurrentResidentialAddressByPerson($entity) + array_values( + array_map( + fn (ResidentialAddress $r): ?ThirdParty => $r->getHostThirdParty(), + $this + ->residentialAddressRepository + ->findCurrentResidentialAddressByPerson($entity) + ) ) ), array_filter( - array_map( - fn (PersonResource $r): ?ThirdParty => $r->getThirdParty(), - $entity->getResources()->filter( - static fn (PersonResource $r): bool => null !== $r->getThirdParty() - )->toArray() + array_values( + array_map( + fn (PersonResource $r): ?ThirdParty => $r->getThirdParty(), + $entity->getResources()->filter( + static fn (PersonResource $r): bool => null !== $r->getThirdParty() + )->toArray() + ) ) ) ); From 6c3fa5cb98b2889e40f1d777f2edc4769ef39be1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 25 May 2023 15:22:52 +0200 Subject: [PATCH 088/321] Fixed: [UI] in designation and redispatch list, the period's statuses were'nt shown correctly --- .../views/AccompanyingPeriod/_list_item.html.twig | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/_list_item.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/_list_item.html.twig index 6c7fbf7c0..47b8c8a15 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/_list_item.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/_list_item.html.twig @@ -16,11 +16,13 @@
    {% if period.step == 'DRAFT' %} - {{- 'Draft'|trans|upper -}} - {% elseif period.step == 'CONFIRMED' %} - {{- 'Confirmed'|trans|upper -}} - {% else %} - {{- 'Closed'|trans|upper -}} + {{ 'course.draft'|trans }} + {% elseif period.step == 'CLOSED' %} + {{ 'course.closed'|trans }} + {% elseif period.step == 'CONFIRMED_INACTIVE_SHORT' %} + {{ 'course.inactive_short'|trans }} + {% elseif period.step == 'CONFIRMED_INACTIVE_LONG' %} + {{ 'course.inactive_long'|trans }} {% endif %}
    From b679dbe26ccf27a097dce62ae2590a6bfe5b1f64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 25 May 2023 15:24:14 +0200 Subject: [PATCH 089/321] Fixed: Do not send a confirmation message when period is mark_active back --- .../AccompanyingPeriod/Events/UserRefEventSubscriber.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Bundle/ChillPersonBundle/AccompanyingPeriod/Events/UserRefEventSubscriber.php b/src/Bundle/ChillPersonBundle/AccompanyingPeriod/Events/UserRefEventSubscriber.php index 8d7249928..50e7dcabb 100644 --- a/src/Bundle/ChillPersonBundle/AccompanyingPeriod/Events/UserRefEventSubscriber.php +++ b/src/Bundle/ChillPersonBundle/AccompanyingPeriod/Events/UserRefEventSubscriber.php @@ -51,7 +51,10 @@ class UserRefEventSubscriber implements EventSubscriberInterface public function onStateEntered(EnteredEvent $enteredEvent): void { - if ($enteredEvent->getMarking()->has(AccompanyingPeriod::STEP_CONFIRMED)) { + if ( + $enteredEvent->getMarking()->has(AccompanyingPeriod::STEP_CONFIRMED) + and $enteredEvent->getTransition()->getName() === 'confirm' + ) { $this->onPeriodConfirmed($enteredEvent->getSubject()); } } From ff03299f80c2e2a24843a52dc23bd25789ddf2d0 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Thu, 25 May 2023 17:06:10 +0200 Subject: [PATCH 090/321] FEATURE [workflow][doc] scroll immediately to document in workflow and let background flash --- .../vuejs/AccompanyingCourseWorkEdit/App.vue | 21 ++++++++++++++++--- .../components/AddEvaluation.vue | 7 +++++-- .../components/FormEvaluation.vue | 20 +++++++++++++++--- .../Workflow/_evaluation_document.html.twig | 2 +- 4 files changed, 41 insertions(+), 9 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/App.vue b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/App.vue index 755e4455c..adbcf1097 100644 --- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/App.vue +++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/App.vue @@ -122,7 +122,8 @@ + v-bind:evaluation="e" + v-bind:docId="this.docId"> @@ -389,6 +390,7 @@ export default { i18n, data() { return { + docId: null, isExpanded: false, editor: ClassicEditor, showAddObjective: false, @@ -428,7 +430,14 @@ export default { }, }; }, - computed: { + beforeMount() { + const urlParams = new URLSearchParams(window.location.search); + this.docId = urlParams.get('doc_id'); + }, + mounted() { + this.scrollToElement(this.docId); + }, + computed: { ...mapState([ 'work', 'resultsForAction', @@ -559,7 +568,7 @@ export default { }); }, saveFormOnTheFly(payload) { - console.log('saveFormOnTheFly: type', payload.type, ', data', payload.data); + // console.log('saveFormOnTheFly: type', payload.type, ', data', payload.data); let body = { type: payload.type }; body.name = payload.data.text; @@ -581,6 +590,12 @@ export default { this.$toast.open({message: 'An error occurred'}); } }) + }, + scrollToElement(docId) { + const documentEl = document.getElementById(`document_${docId}`); + if (documentEl) { + documentEl.scrollIntoView({behavior: 'smooth'}); + } } } }; diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/components/AddEvaluation.vue b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/components/AddEvaluation.vue index 411c386a8..215c5d6cc 100644 --- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/components/AddEvaluation.vue +++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/components/AddEvaluation.vue @@ -11,7 +11,7 @@
    - +
    • @@ -85,7 +85,7 @@ export default { Modal, ListWorkflowModal, }, - props: ['evaluation'], + props: ['evaluation', 'docId'], i18n, data() { return { @@ -95,6 +95,9 @@ export default { } }; }, +/* mounted() { + console.log('docId is here', this.docId) + },*/ computed: { pickedEvaluations() { return this.$store.state.evaluationsPicked; diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/components/FormEvaluation.vue b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/components/FormEvaluation.vue index 7dcb595a3..ff7597dec 100644 --- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/components/FormEvaluation.vue +++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/components/FormEvaluation.vue @@ -80,7 +80,7 @@
      -
      +
      @@ -92,7 +92,7 @@ :data-key="i" @input="onInputDocumentTitle"/>
      -
      +
      @@ -221,7 +221,7 @@ const i18n = { export default { name: "FormEvaluation", - props: ['evaluation'], + props: ['evaluation', 'docId'], components: { ckeditor: CKEditor.component, PickTemplate, @@ -402,4 +402,18 @@ export default { ul.document-upload { justify-content: flex-start; } + + .bg-blink{ + color: #050000; + padding: 10px; + display: inline-block; + border-radius: 5px; + animation: blinkingBackground 2.2s infinite; + animation-iteration-count: 3; + } + @keyframes blinkingBackground{ + 0% { background-color: #fa8888;} + 50% { background-color: #ffffff;} + 100% { background-color: #fa8888;} + } diff --git a/src/Bundle/ChillPersonBundle/Resources/views/Workflow/_evaluation_document.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/Workflow/_evaluation_document.html.twig index 691a903ab..112d4089d 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/Workflow/_evaluation_document.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/Workflow/_evaluation_document.html.twig @@ -123,7 +123,7 @@
      • {{ doc.storedObject|chill_document_button_group(doc.title, is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_UPDATE', evaluation.accompanyingPeriodWork)) }}
      • - + {{ 'Show'|trans }}
      • From 08874d734ed08b6135fe91da1ad42e00e3e82f18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Fri, 26 May 2023 21:58:52 +0200 Subject: [PATCH 091/321] [generic doc] add doc provider and renderer for evaluation document --- .../GenericDoc/Manager.php | 2 +- ...AccompanyingCourseDocumentProviderTest.php | 5 +- .../GenericDoc/evaluation_document.html.twig | 75 +++++++++++++ ...PeriodWorkEvaluationGenericDocProvider.php | 105 ++++++++++++++++++ ...PeriodWorkEvaluationGenericDocRenderer.php | 42 +++++++ ...odWorkEvaluationGenericDocProviderTest.php | 79 +++++++++++++ 6 files changed, 305 insertions(+), 3 deletions(-) create mode 100644 src/Bundle/ChillPersonBundle/Resources/views/GenericDoc/evaluation_document.html.twig create mode 100644 src/Bundle/ChillPersonBundle/Service/GenericDoc/Providers/AccompanyingPeriodWorkEvaluationGenericDocProvider.php create mode 100644 src/Bundle/ChillPersonBundle/Service/GenericDoc/Renderer/AccompanyingPeriodWorkEvaluationGenericDocRenderer.php create mode 100644 src/Bundle/ChillPersonBundle/Tests/Service/GenericDoc/Providers/AccompanyingPeriodWorkEvaluationGenericDocProviderTest.php diff --git a/src/Bundle/ChillDocStoreBundle/GenericDoc/Manager.php b/src/Bundle/ChillDocStoreBundle/GenericDoc/Manager.php index 21189f55e..1a0287a71 100644 --- a/src/Bundle/ChillDocStoreBundle/GenericDoc/Manager.php +++ b/src/Bundle/ChillDocStoreBundle/GenericDoc/Manager.php @@ -73,7 +73,7 @@ class Manager ): iterable { ['sql' => $sql, 'params' => $params, 'types' => $types] = $this->buildUnionQuery($accompanyingPeriod, $startDate, $endDate, $content, $origin); - $runSql = "{$sql} LIMIT ? OFFSET ?"; + $runSql = "{$sql} ORDER BY doc_date DESC LIMIT ? OFFSET ?"; $runParams = [...$params, ...[$limit, $offset]]; $runTypes = [...$types, ...[Types::INTEGER, Types::INTEGER]]; diff --git a/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/Providers/AccompanyingCourseDocumentProviderTest.php b/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/Providers/AccompanyingCourseDocumentProviderTest.php index ee9978735..8c6bd524d 100644 --- a/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/Providers/AccompanyingCourseDocumentProviderTest.php +++ b/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/Providers/AccompanyingCourseDocumentProviderTest.php @@ -63,9 +63,10 @@ class AccompanyingCourseDocumentProviderTest extends KernelTestCase ['sql' => $sql, 'params' => $params, 'types' => $types] = (new FetchQueryToSqlBuilder())->toSql($query); - $this->entityManager->getConnection()->executeQuery($sql, $params, $types); + $nb = $this->entityManager->getConnection()->executeQuery('SELECT COUNT(*) FROM ('.$sql.') AS sq', $params, $types) + ->fetchOne(); - self::assertTrue(true, "test that no errors occurs"); + self::assertIsInt($nb); } public function provideSearchArguments(): iterable diff --git a/src/Bundle/ChillPersonBundle/Resources/views/GenericDoc/evaluation_document.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/GenericDoc/evaluation_document.html.twig new file mode 100644 index 000000000..255139bb4 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Resources/views/GenericDoc/evaluation_document.html.twig @@ -0,0 +1,75 @@ +{% import "@ChillDocStore/Macro/macro.html.twig" as m %} +{% import "@ChillDocStore/Macro/macro_mimeicon.html.twig" as mm %} +{% import '@ChillPerson/Macro/updatedBy.html.twig' as mmm %} + +{% set w = document.accompanyingPeriodWorkEvaluation.accompanyingPeriodWork %} + +
        +
        +
        + {% if document.storedObject.isPending %} +
        {{ 'docgen.Doc generation is pending'|trans }}
        + {% elseif document.storedObject.isFailure %} +
        {{ 'docgen.Doc generation failed'|trans }}
        + {% endif %} +
        + {{ document.title }} +
        + {% if document.storedObject.type is not empty %} +
        + {{ mm.mimeIcon(document.storedObject.type) }} +
        + {% endif %} + {% if document.storedObject.hasTemplate %} +
        +

        {{ document.storedObject.template.name|localize_translatable_string }}

        +
        + {% endif %} +
        + +
        +
        +
        + {{ document.storedObject.createdAt|format_date('short') }} +
        +
        +
        +
        + +
        +
        +

        + + {{ w.socialAction|chill_entity_render_string }} > {{ document.accompanyingPeriodWorkEvaluation.evaluation.title|localize_translatable_string }} + +

        +
        +
        + +
        +
        + {{ mmm.createdBy(document) }} +
        +
          +
        • + {{ chill_entity_workflow_list('Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluationDocument', document.id) }} +
        • + {% if is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_EVALUATION_DOCUMENT_SHOW', document) %} +
        • + {{ document.storedObject|chill_document_button_group(document.title, is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_UPDATE', document.accompanyingPeriodWorkEvaluation.accompanyingPeriodWork)) }} +
        • + {% endif %} + {% if is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_SEE', w)%} +
        • + +
        • + {% endif %} + {% if is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_UPDATE', w) %} +
        • + +
        • + {% endif %} +
        + +
        +
        diff --git a/src/Bundle/ChillPersonBundle/Service/GenericDoc/Providers/AccompanyingPeriodWorkEvaluationGenericDocProvider.php b/src/Bundle/ChillPersonBundle/Service/GenericDoc/Providers/AccompanyingPeriodWorkEvaluationGenericDocProvider.php new file mode 100644 index 000000000..834375bfc --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Service/GenericDoc/Providers/AccompanyingPeriodWorkEvaluationGenericDocProvider.php @@ -0,0 +1,105 @@ +entityManager->getClassMetadata(AccompanyingPeriod\AccompanyingPeriodWorkEvaluationDocument::class); + $storedObjectMetadata = $this->entityManager->getClassMetadata(StoredObject::class); + $evaluationMetadata = $this->entityManager->getClassMetadata(AccompanyingPeriod\AccompanyingPeriodWorkEvaluation::class); + $accompanyingPeriodWorkMetadata = $this->entityManager->getClassMetadata(AccompanyingPeriod\AccompanyingPeriodWork::class); + + $query = new FetchQuery( + self::KEY, + sprintf("jsonb_build_object('id', apwed.%s)", $classMetadata->getColumnName('id')), + sprintf('apwed.'.$storedObjectMetadata->getColumnName('createdAt')), + $classMetadata->getTableName().' AS apwed' + ); + $query->addJoinClause(sprintf( + 'JOIN %s doc_store ON doc_store.%s = apwed.%s', + $storedObjectMetadata->getSchemaName().'.'.$storedObjectMetadata->getTableName(), + $storedObjectMetadata->getColumnName('id'), + $classMetadata->getSingleAssociationJoinColumnName('storedObject') + )); + $query->addJoinClause(sprintf( + 'JOIN %s evaluation ON apwed.%s = evaluation.%s', + $evaluationMetadata->getTableName(), + $classMetadata->getAssociationMapping('accompanyingPeriodWorkEvaluation')['joinColumns'][0]['name'], + $evaluationMetadata->getColumnName('id') + )); + $query->addJoinClause(sprintf( + 'JOIN %s action ON evaluation.%s = action.%s', + $accompanyingPeriodWorkMetadata->getTableName(), + $evaluationMetadata->getAssociationMapping('accompanyingPeriodWork')['joinColumns'][0]['name'], + $accompanyingPeriodWorkMetadata->getColumnName('id') + )); + + $query->addWhereClause( + sprintf('action.%s = ?', $accompanyingPeriodWorkMetadata->getAssociationMapping('accompanyingPeriod')['joinColumns'][0]['name']), + [$accompanyingPeriod->getId()], + [Types::INTEGER] + ); + + if (null !== $startDate) { + $query->addWhereClause( + sprintf('doc_store.%s <= ?', $storedObjectMetadata->getColumnName('createdAt')), + [$startDate], + [Types::DATE_IMMUTABLE] + ); + } + + if (null !== $endDate) { + $query->addWhereClause( + sprintf('doc_store.%s > ?', $storedObjectMetadata->getColumnName('createdAt')), + [$endDate], + [Types::DATE_IMMUTABLE] + ); + } + + if (null !== $content) { + $query->addWhereClause( + sprintf('apwed.%s ilike ?', $classMetadata->getColumnName('title')), + ['%' . $content . '%'], + [Types::STRING] + ); + } + + return $query; + } + + public function isAllowedForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod): bool + { + return $this->security->isGranted(AccompanyingPeriodWorkVoter::SEE, $accompanyingPeriod); + } + + +} diff --git a/src/Bundle/ChillPersonBundle/Service/GenericDoc/Renderer/AccompanyingPeriodWorkEvaluationGenericDocRenderer.php b/src/Bundle/ChillPersonBundle/Service/GenericDoc/Renderer/AccompanyingPeriodWorkEvaluationGenericDocRenderer.php new file mode 100644 index 000000000..5da8297fb --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Service/GenericDoc/Renderer/AccompanyingPeriodWorkEvaluationGenericDocRenderer.php @@ -0,0 +1,42 @@ +key === AccompanyingPeriodWorkEvaluationGenericDocProvider::KEY; + } + + public function getTemplate(GenericDocDTO $genericDocDTO, $options = []): string + { + return '@ChillPerson/GenericDoc/evaluation_document.html.twig'; + } + + public function getTemplateData(GenericDocDTO $genericDocDTO, $options = []): array + { + return [ + 'document' => $this->accompanyingPeriodWorkEvaluationDocumentRepository->find($genericDocDTO->identifiers['id']) + ]; + } +} diff --git a/src/Bundle/ChillPersonBundle/Tests/Service/GenericDoc/Providers/AccompanyingPeriodWorkEvaluationGenericDocProviderTest.php b/src/Bundle/ChillPersonBundle/Tests/Service/GenericDoc/Providers/AccompanyingPeriodWorkEvaluationGenericDocProviderTest.php new file mode 100644 index 000000000..c9ed96581 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Service/GenericDoc/Providers/AccompanyingPeriodWorkEvaluationGenericDocProviderTest.php @@ -0,0 +1,79 @@ +entityManager = self::$container->get(EntityManagerInterface::class); + } + + /** + * @dataProvider provideSearchArguments + */ + public function testBuildFetchQueryForAccompanyingPeriod( + ?\DateTimeImmutable $startDate = null, + ?\DateTimeImmutable $endDate = null, + ?string $content = null + ): void { + $period = $this->entityManager->createQuery("SELECT a FROM " . AccompanyingPeriod::class . ' a') + ->setMaxResults(1) + ->getSingleResult(); + + if (null === $period) { + throw new \RuntimeException('no accompanying period in databasee'); + } + + $security = $this->prophesize(Security::class); + + $provider = new AccompanyingPeriodWorkEvaluationGenericDocProvider( + $security->reveal(), + $this->entityManager + ); + + $query = $provider->buildFetchQueryForAccompanyingPeriod($period, $startDate, $endDate, $content); + ['sql' => $sql, 'params' => $params, 'types' => $types] = (new FetchQueryToSqlBuilder())->toSql($query); + + $nb = $this->entityManager->getConnection()->executeQuery( + 'SELECT COUNT(*) FROM ('.$sql.') AS sq', + $params, + $types + )->fetchOne(); + + self::assertIsInt($nb, "Test that there are no errors"); + } + + public function provideSearchArguments(): iterable + { + yield [null, null, null]; + yield [new \DateTimeImmutable('1 month ago'), null, null]; + yield [new \DateTimeImmutable('1 month ago'), new \DateTimeImmutable('now'), null]; + yield [null, null, 'test']; + } +} From a3d3588b75d37d7573ffe9626aa94ac7a6b57f54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Fri, 26 May 2023 22:01:02 +0200 Subject: [PATCH 092/321] DX: fix json_decode signature --- src/Bundle/ChillDocStoreBundle/GenericDoc/Manager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Bundle/ChillDocStoreBundle/GenericDoc/Manager.php b/src/Bundle/ChillDocStoreBundle/GenericDoc/Manager.php index 1a0287a71..498693206 100644 --- a/src/Bundle/ChillDocStoreBundle/GenericDoc/Manager.php +++ b/src/Bundle/ChillDocStoreBundle/GenericDoc/Manager.php @@ -80,7 +80,7 @@ class Manager foreach($this->connection->iterateAssociative($runSql, $runParams, $runTypes) as $row) { yield new GenericDocDTO( $row['key'], - json_decode($row['identifiers'], true, JSON_THROW_ON_ERROR), + json_decode($row['identifiers'], true, 512, JSON_THROW_ON_ERROR), new \DateTimeImmutable($row['doc_date']), $accompanyingPeriod, ); From eb107f5a1506b60afeb28d535f0688b833ad6264 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 30 May 2023 12:46:05 +0200 Subject: [PATCH 093/321] add filter for generic doc + fix issues in filter --- ...ericDocForAccompanyingPeriodController.php | 38 +++++++++++-- .../GenericDoc/GenericDocDTO.php | 8 +-- .../GenericDoc/Manager.php | 53 ++++++++++++++----- ...anyingProviderCourseDocumentGenericDoc.php | 6 +-- .../accompanying_period_list.html.twig | 2 + .../Tests/GenericDoc/ManagerTest.php | 7 ++- .../translations/messages.fr.yml | 6 +++ .../Templating/Listing/FilterOrderHelper.php | 5 ++ ...PeriodWorkEvaluationGenericDocProvider.php | 4 +- .../translations/messages.fr.yml | 5 ++ 10 files changed, 109 insertions(+), 25 deletions(-) diff --git a/src/Bundle/ChillDocStoreBundle/Controller/GenericDocForAccompanyingPeriodController.php b/src/Bundle/ChillDocStoreBundle/Controller/GenericDocForAccompanyingPeriodController.php index 7403e2ebc..70c41db50 100644 --- a/src/Bundle/ChillDocStoreBundle/Controller/GenericDocForAccompanyingPeriodController.php +++ b/src/Bundle/ChillDocStoreBundle/Controller/GenericDocForAccompanyingPeriodController.php @@ -14,6 +14,7 @@ namespace Chill\DocStoreBundle\Controller; use Chill\DocStoreBundle\GenericDoc\Manager; use Chill\DocStoreBundle\Security\Authorization\AccompanyingCourseDocumentVoter; use Chill\MainBundle\Pagination\PaginatorFactory; +use Chill\MainBundle\Templating\Listing\FilterOrderHelperFactory; use Chill\PersonBundle\Entity\AccompanyingPeriod; use Symfony\Bundle\TwigBundle\TwigEngine; use Symfony\Component\HttpFoundation\Response; @@ -25,9 +26,10 @@ use Symfony\Component\Templating\EngineInterface; final readonly class GenericDocForAccompanyingPeriodController { public function __construct( - private Security $security, + private FilterOrderHelperFactory $filterOrderHelperFactory, private Manager $manager, private PaginatorFactory $paginator, + private Security $security, private EngineInterface $twig, ) { } @@ -45,12 +47,41 @@ final readonly class GenericDocForAccompanyingPeriodController throw new AccessDeniedHttpException("not allowed to see the documents for accompanying period"); } - $nb = $this->manager->countDocForAccompanyingPeriod($accompanyingPeriod); + $filterBuilder = $this->filterOrderHelperFactory + ->create(self::class) + ->addSearchBox() + ->addDateRange('dateRange', 'generic_doc.filter.date-range'); + + if ([] !== $places = $this->manager->placesForAccompanyingPeriod($accompanyingPeriod)) { + $filterBuilder->addCheckbox('places', $places, [], array_map( + static fn (string $k) => 'generic_doc.filter.keys.' . $k, + $places + )); + } + + $filter = $filterBuilder + ->build(); + + ['to' => $endDate, 'from' => $startDate ] = $filter->getDateRangeData('dateRange'); + $content = $filter->getQueryString(); + + $nb = $this->manager->countDocForAccompanyingPeriod( + $accompanyingPeriod, + $startDate, + $endDate, + $content, + $filter->hasCheckBox('places') ? array_values($filter->getCheckboxData('places')) : [] + ); $paginator = $this->paginator->create($nb); + $documents = $this->manager->findDocForAccompanyingPeriod( $accompanyingPeriod, $paginator->getCurrentPageFirstItemNumber(), - $paginator->getItemsPerPage() + $paginator->getItemsPerPage(), + $startDate, + $endDate, + $content, + $filter->hasCheckBox('places') ? array_values($filter->getCheckboxData('places')) : [] ); return new Response($this->twig->render( @@ -59,6 +90,7 @@ final readonly class GenericDocForAccompanyingPeriodController 'accompanyingCourse' => $accompanyingPeriod, 'pagination' => $paginator, 'documents' => iterator_to_array($documents), + 'filter' => $filter, ] )); } diff --git a/src/Bundle/ChillDocStoreBundle/GenericDoc/GenericDocDTO.php b/src/Bundle/ChillDocStoreBundle/GenericDoc/GenericDocDTO.php index e47814685..25a96750c 100644 --- a/src/Bundle/ChillDocStoreBundle/GenericDoc/GenericDocDTO.php +++ b/src/Bundle/ChillDocStoreBundle/GenericDoc/GenericDocDTO.php @@ -14,12 +14,12 @@ namespace Chill\DocStoreBundle\GenericDoc; use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\Person; -class GenericDocDTO +final readonly class GenericDocDTO { public function __construct( - public readonly string $key, - public readonly array $identifiers, - public readonly \DateTimeImmutable $docDate, + public string $key, + public array $identifiers, + public \DateTimeImmutable $docDate, public AccompanyingPeriod|Person $linked, ) { } diff --git a/src/Bundle/ChillDocStoreBundle/GenericDoc/Manager.php b/src/Bundle/ChillDocStoreBundle/GenericDoc/Manager.php index 498693206..dad432e3e 100644 --- a/src/Bundle/ChillDocStoreBundle/GenericDoc/Manager.php +++ b/src/Bundle/ChillDocStoreBundle/GenericDoc/Manager.php @@ -32,6 +32,7 @@ class Manager } /** + * @param list $places * @throws Exception */ public function countDocForAccompanyingPeriod( @@ -39,16 +40,16 @@ class Manager ?\DateTimeImmutable $startDate = null, ?\DateTimeImmutable $endDate = null, ?string $content = null, - ?string $origin = null + array $places = [] ): int { - ['sql' => $sql, 'params' => $params] = $this->buildUnionQuery($accompanyingPeriod, $startDate, $endDate, $content, $origin); + ['sql' => $sql, 'params' => $params, 'types' => $types] = $this->buildUnionQuery($accompanyingPeriod, $startDate, $endDate, $content, $places); if ($sql === '') { return 0; } $countSql = "SELECT count(*) AS c FROM ({$sql}) AS sq"; - $result = $this->connection->executeQuery($countSql, $params); + $result = $this->connection->executeQuery($countSql, $params, $types); $number = $result->fetchOne(); @@ -60,6 +61,7 @@ class Manager } /** + * @param list $places places to search. When empty, search in all places * @throws Exception */ public function findDocForAccompanyingPeriod( @@ -69,15 +71,19 @@ class Manager ?\DateTimeImmutable $startDate = null, ?\DateTimeImmutable $endDate = null, ?string $content = null, - ?string $origin = null + array $places = [] ): iterable { - ['sql' => $sql, 'params' => $params, 'types' => $types] = $this->buildUnionQuery($accompanyingPeriod, $startDate, $endDate, $content, $origin); + ['sql' => $sql, 'params' => $params, 'types' => $types] = $this->buildUnionQuery($accompanyingPeriod, $startDate, $endDate, $content, $places); + + if ($sql === '') { + return []; + } $runSql = "{$sql} ORDER BY doc_date DESC LIMIT ? OFFSET ?"; $runParams = [...$params, ...[$limit, $offset]]; $runTypes = [...$types, ...[Types::INTEGER, Types::INTEGER]]; - foreach($this->connection->iterateAssociative($runSql, $runParams, $runTypes) as $row) { + foreach ($this->connection->iterateAssociative($runSql, $runParams, $runTypes) as $row) { yield new GenericDocDTO( $row['key'], json_decode($row['identifiers'], true, 512, JSON_THROW_ON_ERROR), @@ -87,14 +93,34 @@ class Manager } } + public function placesForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod): array + { + ['sql' => $sql, 'params' => $params, 'types' => $types] = $this->buildUnionQuery($accompanyingPeriod); + + if ($sql === '') { + return []; + } + + $runSql = "SELECT DISTINCT key FROM ({$sql}) AS sq"; + + $keys = []; + + foreach ($this->connection->iterateAssociative($runSql, $params, $types) as $k) { + $keys[] = $k['key']; + } + + return $keys; + } + /** + * @param list $places places to search. When empty, search in all places */ private function buildUnionQuery( AccompanyingPeriod|Person $linked, ?\DateTimeImmutable $startDate = null, ?\DateTimeImmutable $endDate = null, ?string $content = null, - ?string $origin = null + array $places = [], ): array { $sql = []; $params = []; @@ -105,17 +131,20 @@ class Manager if (!$provider->isAllowedForAccompanyingPeriod($linked)) { continue; } + $query = $provider->buildFetchQueryForAccompanyingPeriod($linked, $startDate, $endDate, $content); - ['sql' => $q, 'params' => $p, 'types' => $t ] = $this->builder - ->toSql($provider->buildFetchQueryForAccompanyingPeriod($linked, $startDate, $endDate, $content, $origin)); - $params = [...$params, ...$p]; - $types = [...$types, ...$t]; + if ([] !== $places and !in_array($query->getSelectKeyString(), $places, true)) { + continue; + } + + ['sql' => $q, 'params' => $p, 'types' => $t ] = $this->builder->toSql($query); $sql[] = $q; + $params = [...$params, ...$p]; + $types = [...$types, ...$t]; } } return ['sql' => implode(' UNION ', $sql), 'params' => $params, 'types' => $types]; } - } diff --git a/src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/AccompanyingProviderCourseDocumentGenericDoc.php b/src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/AccompanyingProviderCourseDocumentGenericDoc.php index fc0eb3b5f..970ce646d 100644 --- a/src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/AccompanyingProviderCourseDocumentGenericDoc.php +++ b/src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/AccompanyingProviderCourseDocumentGenericDoc.php @@ -50,7 +50,7 @@ final readonly class AccompanyingProviderCourseDocumentGenericDoc implements Gen if (null !== $startDate) { $query->addWhereClause( - sprintf('? >= %s', $classMetadata->getColumnName('date')), + sprintf('? <= %s', $classMetadata->getColumnName('date')), [$startDate], [Types::DATE_IMMUTABLE] ); @@ -58,7 +58,7 @@ final readonly class AccompanyingProviderCourseDocumentGenericDoc implements Gen if (null !== $endDate) { $query->addWhereClause( - sprintf('? < %s', $classMetadata->getColumnName('date')), + sprintf('? >= %s', $classMetadata->getColumnName('date')), [$endDate], [Types::DATE_IMMUTABLE] ); @@ -71,7 +71,7 @@ final readonly class AccompanyingProviderCourseDocumentGenericDoc implements Gen $classMetadata->getColumnName('title'), $classMetadata->getColumnName('description') ), - [$content, $content], + ['%' . $content . '%', '%' . $content . '%'], [Types::STRING, Types::STRING] ); } diff --git a/src/Bundle/ChillDocStoreBundle/Resources/views/GenericDoc/accompanying_period_list.html.twig b/src/Bundle/ChillDocStoreBundle/Resources/views/GenericDoc/accompanying_period_list.html.twig index b2967d2f0..f76e4b984 100644 --- a/src/Bundle/ChillDocStoreBundle/Resources/views/GenericDoc/accompanying_period_list.html.twig +++ b/src/Bundle/ChillDocStoreBundle/Resources/views/GenericDoc/accompanying_period_list.html.twig @@ -22,6 +22,8 @@

        {{ 'Documents' }}

        + {{ filter|chill_render_filter_order_helper }} + {% if documents|length == 0 %}

        {{ 'No documents'|trans }}

        {% else %} diff --git a/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/ManagerTest.php b/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/ManagerTest.php index 2bda8e2ae..597aea84a 100644 --- a/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/ManagerTest.php +++ b/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/ManagerTest.php @@ -18,6 +18,7 @@ use Chill\DocStoreBundle\GenericDoc\Manager; use Chill\DocStoreBundle\GenericDoc\GenericDocForAccompanyingPeriodProviderInterface; use Chill\PersonBundle\Entity\AccompanyingPeriod; use Doctrine\DBAL\Connection; +use Doctrine\DBAL\Types\Types; use Doctrine\ORM\EntityManagerInterface; use Prophecy\PhpUnit\ProphecyTrait; use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; @@ -86,12 +87,16 @@ final readonly class SimpleGenericDocProvider implements GenericDocForAccompanyi { public function buildFetchQueryForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod, ?\DateTimeImmutable $startDate = null, ?\DateTimeImmutable $endDate = null, ?string $content = null, ?string $origin = null): FetchQueryInterface { - return new FetchQuery( + $query = new FetchQuery( 'accompanying_course_document', sprintf('jsonb_build_object(\'id\', %s)', 'id'), 'd', '(VALUES (1, \'2023-05-01\'::date), (2, \'2023-05-01\'::date)) AS sq (id, d)', ); + + $query->addWhereClause('d > ?', [new \DateTimeImmutable('2023-01-01')], [Types::DATE_IMMUTABLE]); + + return $query; } public function isAllowedForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod): bool diff --git a/src/Bundle/ChillDocStoreBundle/translations/messages.fr.yml b/src/Bundle/ChillDocStoreBundle/translations/messages.fr.yml index 1d06c58e4..1dde57eee 100644 --- a/src/Bundle/ChillDocStoreBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillDocStoreBundle/translations/messages.fr.yml @@ -22,6 +22,12 @@ Any description: Aucune description document: Any title: Aucun titre +generic_doc: + filter: + keys: + accompanying_course_document: Document du parcours + date-range: Date du document + # delete Delete document ?: Supprimer le document ? Are you sure you want to remove this document ?: Êtes-vous sûr·e de vouloir supprimer ce document ? diff --git a/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelper.php b/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelper.php index 367cc0861..94aa3c50b 100644 --- a/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelper.php +++ b/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelper.php @@ -91,6 +91,11 @@ class FilterOrderHelper return $this->checkboxes; } + public function hasCheckBox(string $name): bool + { + return array_key_exists($name, $this->checkboxes); + } + /** * @return array<'to': DateTimeImmutable, 'from': DateTimeImmutable> */ diff --git a/src/Bundle/ChillPersonBundle/Service/GenericDoc/Providers/AccompanyingPeriodWorkEvaluationGenericDocProvider.php b/src/Bundle/ChillPersonBundle/Service/GenericDoc/Providers/AccompanyingPeriodWorkEvaluationGenericDocProvider.php index 834375bfc..883836547 100644 --- a/src/Bundle/ChillPersonBundle/Service/GenericDoc/Providers/AccompanyingPeriodWorkEvaluationGenericDocProvider.php +++ b/src/Bundle/ChillPersonBundle/Service/GenericDoc/Providers/AccompanyingPeriodWorkEvaluationGenericDocProvider.php @@ -71,7 +71,7 @@ final readonly class AccompanyingPeriodWorkEvaluationGenericDocProvider implemen if (null !== $startDate) { $query->addWhereClause( - sprintf('doc_store.%s <= ?', $storedObjectMetadata->getColumnName('createdAt')), + sprintf('doc_store.%s >= ?', $storedObjectMetadata->getColumnName('createdAt')), [$startDate], [Types::DATE_IMMUTABLE] ); @@ -79,7 +79,7 @@ final readonly class AccompanyingPeriodWorkEvaluationGenericDocProvider implemen if (null !== $endDate) { $query->addWhereClause( - sprintf('doc_store.%s > ?', $storedObjectMetadata->getColumnName('createdAt')), + sprintf('doc_store.%s < ?', $storedObjectMetadata->getColumnName('createdAt')), [$endDate], [Types::DATE_IMMUTABLE] ); diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index 341136f65..a344ac50d 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -1231,3 +1231,8 @@ social_action: social_issue: and children: et dérivés + +generic_doc: + filter: + keys: + accompanying_period_work_evaluation_document: Document des actions d'accompagnement From 90a5a735aafebb58ba16d8ea17e2383fe0d2f13f Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Tue, 30 May 2023 14:38:16 +0200 Subject: [PATCH 094/321] FIX [route] adjust to using new route name in redirect --- .../Controller/DocumentAccompanyingCourseController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Bundle/ChillDocStoreBundle/Controller/DocumentAccompanyingCourseController.php b/src/Bundle/ChillDocStoreBundle/Controller/DocumentAccompanyingCourseController.php index 8762050aa..384eeb510 100644 --- a/src/Bundle/ChillDocStoreBundle/Controller/DocumentAccompanyingCourseController.php +++ b/src/Bundle/ChillDocStoreBundle/Controller/DocumentAccompanyingCourseController.php @@ -160,7 +160,7 @@ class DocumentAccompanyingCourseController extends AbstractController $this->addFlash('success', $this->translator->trans('The document is successfully registered')); - return $this->redirectToRoute('accompanying_course_document_index', ['course' => $course->getId()]); + return $this->redirectToRoute('chill_docstore_generic-doc_by-period_index', ['id' => $course->getId()]); } if ($form->isSubmitted() && !$form->isValid()) { From 101cca8662e0aef2444cfd189975cec118fd98da Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Tue, 30 May 2023 16:56:20 +0200 Subject: [PATCH 095/321] FEATURE [genericDoc] generic doc interface implemented for rendez-vous --- .../GenericDoc/calendar_document.html.twig | 72 +++++++++++++ ...anyingPeriodCalendarGenericDocProvider.php | 101 ++++++++++++++++++ ...anyingPeriodCalendarGenericDocRenderer.php | 44 ++++++++ .../translations/messages.fr.yml | 2 + .../translations/messages.fr.yml | 1 + 5 files changed, 220 insertions(+) create mode 100644 src/Bundle/ChillCalendarBundle/Resources/views/GenericDoc/calendar_document.html.twig create mode 100644 src/Bundle/ChillCalendarBundle/Service/GenericDoc/Providers/AccompanyingPeriodCalendarGenericDocProvider.php create mode 100644 src/Bundle/ChillCalendarBundle/Service/GenericDoc/Renderers/AccompanyingPeriodCalendarGenericDocRenderer.php diff --git a/src/Bundle/ChillCalendarBundle/Resources/views/GenericDoc/calendar_document.html.twig b/src/Bundle/ChillCalendarBundle/Resources/views/GenericDoc/calendar_document.html.twig new file mode 100644 index 000000000..712b362f5 --- /dev/null +++ b/src/Bundle/ChillCalendarBundle/Resources/views/GenericDoc/calendar_document.html.twig @@ -0,0 +1,72 @@ +{% import "@ChillDocStore/Macro/macro.html.twig" as m %} +{% import "@ChillDocStore/Macro/macro_mimeicon.html.twig" as mm %} +{% import '@ChillPerson/Macro/updatedBy.html.twig' as mmm %} + +{% set c = document.calendar %} + +
        +
        +
        + {% if document.storedObject.isPending %} +
        {{ 'docgen.Doc generation is pending'|trans }}
        + {% elseif document.storedObject.isFailure %} +
        {{ 'docgen.Doc generation failed'|trans }}
        + {% endif %} +
        + {{ document.storedObject.title }} +
        +
        + {{ 'chill_calendar.Document'|trans }} +
        + {% if document.storedObject.hasTemplate %} +
        +

        {{ document.storedObject.template.name|localize_translatable_string }}

        +
        + {% endif %} +
        + +
        +
        +
        + {{ document.storedObject.createdAt|format_date('short') }} +
        +
        +
        +
        + +
        +
        +

        + {% if c.endDate.diff(c.startDate).days >= 1 %} + {{ c.startDate|format_datetime('short', 'short') }} + - {{ c.endDate|format_datetime('short', 'short') }} + {% else %} + {{ c.startDate|format_datetime('short', 'short') }} + - {{ c.endDate|format_datetime('none', 'short') }} + {% endif %} +

        +
        +
        + +
        +
        + {{ mmm.createdBy(document) }} +
        +
          +
        • + {{ chill_entity_workflow_list('Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluationDocument', document.id) }} +
        • + {% if is_granted('CHILL_CALENDAR_DOC_SEE', document) %} +
        • + {{ document.storedObject|chill_document_button_group(document.storedObject.title, is_granted('CHILL_CALENDAR_CALENDAR_EDIT', c)) }} +
        • + {% endif %} + {% if is_granted('CHILL_CALENDAR_CALENDAR_EDIT', c) %} +
        • + +
        • + {% endif %} +
        + +
        +
        diff --git a/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Providers/AccompanyingPeriodCalendarGenericDocProvider.php b/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Providers/AccompanyingPeriodCalendarGenericDocProvider.php new file mode 100644 index 000000000..ff2cdbcf5 --- /dev/null +++ b/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Providers/AccompanyingPeriodCalendarGenericDocProvider.php @@ -0,0 +1,101 @@ +security = $security; + $this->em = $entityManager; + } + + public function buildFetchQueryForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod, ?\DateTimeImmutable $startDate = null, ?\DateTimeImmutable $endDate = null, ?string $content = null, ?string $origin = null): FetchQueryInterface + { + $classMetadata = $this->em->getClassMetadata(CalendarDoc::class); + $storedObjectMetadata = $this->em->getClassMetadata(StoredObject::class); + $calendarMetadata = $this->em->getClassMetadata(Calendar::class); + + $query = new FetchQuery( + self::KEY, + sprintf("jsonb_build_object('id', cd.%s)", $classMetadata->getColumnName('id')), + 'cd.'.$storedObjectMetadata->getColumnName('createdAt'), + $classMetadata->getSchemaName().'.'.$classMetadata->getTableName().' AS cd' + ); + $query->addJoinClause( + 'JOIN chill_doc.stored_object doc_store ON doc_store.id = cd.storedobject_id' + ); + + $query->addJoinClause( + 'JOIN chill_calendar.calendar calendar ON calendar.id = cd.calendar_id' + ); + + $query->addWhereClause( + 'calendar.accompanyingperiod_id = ?', + [$accompanyingPeriod->getId()], + [Types::INTEGER] + ); + + if (null !== $startDate) { + $query->addWhereClause( + sprintf('doc_store.%s >= ?', $storedObjectMetadata->getColumnName('createdAt')), + [$startDate], + [Types::DATE_IMMUTABLE] + ); + } + + if (null !== $endDate) { + $query->addWhereClause( + sprintf('doc_store.%s < ?', $storedObjectMetadata->getColumnName('createdAt')), + [$endDate], + [Types::DATE_IMMUTABLE] + ); + } + + if (null !== $content) { + $query->addWhereClause( + 'doc_store.title ilike ?', + ['%' . $content . '%'], + [Types::STRING] + ); + } + + return $query; + } + + public function isAllowedForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod): bool + { + return $this->security->isGranted(CalendarVoter::SEE, $accompanyingPeriod); + } + + +} diff --git a/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Renderers/AccompanyingPeriodCalendarGenericDocRenderer.php b/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Renderers/AccompanyingPeriodCalendarGenericDocRenderer.php new file mode 100644 index 000000000..0f680797c --- /dev/null +++ b/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Renderers/AccompanyingPeriodCalendarGenericDocRenderer.php @@ -0,0 +1,44 @@ +repository = $calendarDocRepository; + } + + public function supports(GenericDocDTO $genericDocDTO, $options = []): bool + { + return $genericDocDTO->key === AccompanyingPeriodCalendarGenericDocProvider::KEY; + } + + public function getTemplate(GenericDocDTO $genericDocDTO, $options = []): string + { + return '@ChillCalendar/GenericDoc/calendar_document.html.twig'; + } + + public function getTemplateData(GenericDocDTO $genericDocDTO, $options = []): array + { + return [ + 'document' => $this->repository->find($genericDocDTO->identifiers['id']) + ]; + } +} diff --git a/src/Bundle/ChillCalendarBundle/translations/messages.fr.yml b/src/Bundle/ChillCalendarBundle/translations/messages.fr.yml index eb02be280..5e1fc971a 100644 --- a/src/Bundle/ChillCalendarBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillCalendarBundle/translations/messages.fr.yml @@ -43,6 +43,7 @@ crud: title_edit: Modifier le motif d'annulation chill_calendar: + Document: Document d'un rendez-vous form: The main user is mandatory. He will organize the appointment.: L'utilisateur principal est obligatoire. Il est l'organisateur de l'événement. Create for referrer: Créer pour le référent @@ -65,6 +66,7 @@ chill_calendar: Document outdated: La date et l'heure du rendez-vous ont été modifiés après la création du document + remote_ms_graph: freebusy_statuses: busy: Occupé diff --git a/src/Bundle/ChillDocStoreBundle/translations/messages.fr.yml b/src/Bundle/ChillDocStoreBundle/translations/messages.fr.yml index 1dde57eee..4fa41f180 100644 --- a/src/Bundle/ChillDocStoreBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillDocStoreBundle/translations/messages.fr.yml @@ -26,6 +26,7 @@ generic_doc: filter: keys: accompanying_course_document: Document du parcours + accompanying_period_calendar_document: Document des rendez-vous date-range: Date du document # delete From d09e5d33db2b3d2001208d1097b0915412b9137f Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Tue, 30 May 2023 16:59:16 +0200 Subject: [PATCH 096/321] WIP [genericDoc][activity] implementing generic doc for activities --- ...anyingPeriodActivityGenericDocProvider.php | 110 ++++++++++++++++++ ...anyingPeriodActivityGenericDocRenderer.php | 45 +++++++ 2 files changed, 155 insertions(+) create mode 100644 src/Bundle/ChillActivityBundle/Service/GenericDoc/Providers/AccompanyingPeriodActivityGenericDocProvider.php create mode 100644 src/Bundle/ChillActivityBundle/Service/GenericDoc/Renderers/AccompanyingPeriodActivityGenericDocRenderer.php diff --git a/src/Bundle/ChillActivityBundle/Service/GenericDoc/Providers/AccompanyingPeriodActivityGenericDocProvider.php b/src/Bundle/ChillActivityBundle/Service/GenericDoc/Providers/AccompanyingPeriodActivityGenericDocProvider.php new file mode 100644 index 000000000..fc7484edf --- /dev/null +++ b/src/Bundle/ChillActivityBundle/Service/GenericDoc/Providers/AccompanyingPeriodActivityGenericDocProvider.php @@ -0,0 +1,110 @@ +em = $entityManager; + $this->security = $security; + } + + /** + * @param AccompanyingPeriod $accompanyingPeriod + * @param DateTimeImmutable|null $startDate + * @param DateTimeImmutable|null $endDate + * @param string|null $content + * @param string|null $origin + * @return FetchQueryInterface + * @throws MappingException + */ + public function buildFetchQueryForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod, ?DateTimeImmutable $startDate = null, ?DateTimeImmutable $endDate = null, ?string $content = null, ?string $origin = null): FetchQueryInterface + { + $storedObjectMetadata = $this->em->getClassMetadata(StoredObject::class); +// $activityMetadata = $this->em->getClassMetadata(Activity::class); + + $query = new FetchQuery( + self::KEY, + "jsonb_build_object('id', doc_obj.id)", + 'doc_obj.'.$storedObjectMetadata->getColumnName('createdAt'), + $storedObjectMetadata->getSchemaName().'.'.$storedObjectMetadata->getTableName().' AS doc_obj' + ); + + $query->addJoinClause( + 'JOIN public.activity_storedobject activity_doc ON activity_doc.storedobject_id = doc_obj.id' + ); + + $query->addJoinClause( + 'JOIN public.activity activity ON activity.id = activity_doc.activity_id' + ); + + $query->addWhereClause( + 'activity.accompanyingperiod_id = ?', + [$accompanyingPeriod->getId()], + [Types::INTEGER] + ); + + if (null !== $startDate) { + $query->addWhereClause( + sprintf('doc_obj.%s >= ?', $storedObjectMetadata->getColumnName('createdAt')), + [$startDate], + [Types::DATE_IMMUTABLE] + ); + } + + if (null !== $endDate) { + $query->addWhereClause( + sprintf('doc_obj.%s < ?', $storedObjectMetadata->getColumnName('createdAt')), + [$endDate], + [Types::DATE_IMMUTABLE] + ); + } + + if (null !== $content) { + $query->addWhereClause( + 'doc_obj.title ilike ?', + ['%' . $content . '%'], + [Types::STRING] + ); + } + + return $query; + } + + /** + * @param AccompanyingPeriod $accompanyingPeriod + * @return bool + */ + public function isAllowedForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod): bool + { + return $this->security->isGranted(ActivityVoter::SEE, $accompanyingPeriod); + } +} diff --git a/src/Bundle/ChillActivityBundle/Service/GenericDoc/Renderers/AccompanyingPeriodActivityGenericDocRenderer.php b/src/Bundle/ChillActivityBundle/Service/GenericDoc/Renderers/AccompanyingPeriodActivityGenericDocRenderer.php new file mode 100644 index 000000000..eddcc6828 --- /dev/null +++ b/src/Bundle/ChillActivityBundle/Service/GenericDoc/Renderers/AccompanyingPeriodActivityGenericDocRenderer.php @@ -0,0 +1,45 @@ +repository = $storedObjectRepository; + } + + public function supports(GenericDocDTO $genericDocDTO, $options = []): bool + { + return $genericDocDTO->key === AccompanyingPeriodActivityGenericDocProvider::KEY; + } + + public function getTemplate(GenericDocDTO $genericDocDTO, $options = []): string + { + return '@ChillCalendar/GenericDoc/activity_document.html.twig'; + } + + public function getTemplateData(GenericDocDTO $genericDocDTO, $options = []): array + { + return [ + 'document' => $this->repository->find($genericDocDTO->identifiers['id']) + ]; + } +} + From bd074ebade229eaf747dd9be8f914e0f09f883a9 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Tue, 30 May 2023 17:50:32 +0200 Subject: [PATCH 097/321] FEATURE [genericDoc][calendar] use metadatas --- ...anyingPeriodCalendarGenericDocProvider.php | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Providers/AccompanyingPeriodCalendarGenericDocProvider.php b/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Providers/AccompanyingPeriodCalendarGenericDocProvider.php index ff2cdbcf5..e653cfc25 100644 --- a/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Providers/AccompanyingPeriodCalendarGenericDocProvider.php +++ b/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Providers/AccompanyingPeriodCalendarGenericDocProvider.php @@ -21,6 +21,7 @@ use Chill\DocStoreBundle\GenericDoc\GenericDocForAccompanyingPeriodProviderInter use Chill\PersonBundle\Entity\AccompanyingPeriod; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\EntityManagerInterface; +use Doctrine\ORM\Mapping\MappingException; use Symfony\Component\Security\Core\Security; final class AccompanyingPeriodCalendarGenericDocProvider implements GenericDocForAccompanyingPeriodProviderInterface @@ -39,6 +40,9 @@ final class AccompanyingPeriodCalendarGenericDocProvider implements GenericDocFo $this->em = $entityManager; } + /** + * @throws MappingException + */ public function buildFetchQueryForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod, ?\DateTimeImmutable $startDate = null, ?\DateTimeImmutable $endDate = null, ?string $content = null, ?string $origin = null): FetchQueryInterface { $classMetadata = $this->em->getClassMetadata(CalendarDoc::class); @@ -52,15 +56,23 @@ final class AccompanyingPeriodCalendarGenericDocProvider implements GenericDocFo $classMetadata->getSchemaName().'.'.$classMetadata->getTableName().' AS cd' ); $query->addJoinClause( - 'JOIN chill_doc.stored_object doc_store ON doc_store.id = cd.storedobject_id' - ); + sprintf('JOIN %s doc_store ON doc_store.%s = cd.%s', + $storedObjectMetadata->getSchemaName().'.'.$storedObjectMetadata->getTableName(), + $storedObjectMetadata->getColumnName('id'), + $classMetadata->getSingleAssociationJoinColumnName('storedObject') + )); $query->addJoinClause( - 'JOIN chill_calendar.calendar calendar ON calendar.id = cd.calendar_id' + sprintf('JOIN %s calendar ON calendar.%s = cd.%s', + $calendarMetadata->getSchemaName().'.'.$calendarMetadata->getTableName(), + $calendarMetadata->getColumnName('id'), + $classMetadata->getSingleAssociationJoinColumnName('calendar') + ) ); $query->addWhereClause( - 'calendar.accompanyingperiod_id = ?', + sprintf('calendar.%s = ?', + $calendarMetadata->getAssociationMapping('accompanyingPeriod')['joinColumns'][0]['name']), [$accompanyingPeriod->getId()], [Types::INTEGER] ); @@ -83,7 +95,7 @@ final class AccompanyingPeriodCalendarGenericDocProvider implements GenericDocFo if (null !== $content) { $query->addWhereClause( - 'doc_store.title ilike ?', + sprintf('doc_store.%s ilike ?', $storedObjectMetadata->getColumnName('title')), ['%' . $content . '%'], [Types::STRING] ); From c245ffe559196e37eb38dd5aeb41f83fa13212a7 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Tue, 30 May 2023 18:14:32 +0200 Subject: [PATCH 098/321] WIP [genericDoc][activity] add repository method to get activity linked to storedObject --- .../Repository/ActivityRepository.php | 12 ++++ .../GenericDoc/activity_document.html.twig | 72 +++++++++++++++++++ ...anyingPeriodActivityGenericDocProvider.php | 3 +- ...anyingPeriodActivityGenericDocRenderer.php | 13 ++-- 4 files changed, 94 insertions(+), 6 deletions(-) create mode 100644 src/Bundle/ChillActivityBundle/Resources/views/GenericDoc/activity_document.html.twig diff --git a/src/Bundle/ChillActivityBundle/Repository/ActivityRepository.php b/src/Bundle/ChillActivityBundle/Repository/ActivityRepository.php index 5a6e16cd5..02658b03d 100644 --- a/src/Bundle/ChillActivityBundle/Repository/ActivityRepository.php +++ b/src/Bundle/ChillActivityBundle/Repository/ActivityRepository.php @@ -15,6 +15,7 @@ use Chill\ActivityBundle\Entity\Activity; use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\Person; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; +use Doctrine\ORM\Query\Expr; use Doctrine\Persistence\ManagerRegistry; /** @@ -97,4 +98,15 @@ class ActivityRepository extends ServiceEntityRepository return $qb->getQuery()->getResult(); } + + public function findOneByDocument(int $documentId): Activity + { + $qb = $this->createQueryBuilder('a'); + $qb->select('a'); + + $qb->innerJoin('a.documents', 'd', Expr\Join::WITH, 'd.storedobject_id = :documentId'); + $qb->setParameter('documentId', $documentId); + + return $qb->getQuery()->getResult(); + } } diff --git a/src/Bundle/ChillActivityBundle/Resources/views/GenericDoc/activity_document.html.twig b/src/Bundle/ChillActivityBundle/Resources/views/GenericDoc/activity_document.html.twig new file mode 100644 index 000000000..aeaea0872 --- /dev/null +++ b/src/Bundle/ChillActivityBundle/Resources/views/GenericDoc/activity_document.html.twig @@ -0,0 +1,72 @@ +{% import "@ChillDocStore/Macro/macro.html.twig" as m %} +{% import "@ChillDocStore/Macro/macro_mimeicon.html.twig" as mm %} +{% import '@ChillPerson/Macro/updatedBy.html.twig' as mmm %} + +{% set a = document.calendar %} + +
        +
        +
        + {% if document.storedObject.isPending %} +
        {{ 'docgen.Doc generation is pending'|trans }}
        + {% elseif document.storedObject.isFailure %} +
        {{ 'docgen.Doc generation failed'|trans }}
        + {% endif %} +
        + {{ document.storedObject.title }} +
        +
        + {{ 'chill_calendar.Document'|trans }} +
        + {% if document.storedObject.hasTemplate %} +
        +

        {{ document.storedObject.template.name|localize_translatable_string }}

        +
        + {% endif %} +
        + +
        +
        +
        + {{ document.storedObject.createdAt|format_date('short') }} +
        +
        +
        +
        + +
        +
        +

        + {% if c.endDate.diff(c.startDate).days >= 1 %} + {{ c.startDate|format_datetime('short', 'short') }} + - {{ c.endDate|format_datetime('short', 'short') }} + {% else %} + {{ c.startDate|format_datetime('short', 'short') }} + - {{ c.endDate|format_datetime('none', 'short') }} + {% endif %} +

        +
        +
        + +
        +
        + {{ mmm.createdBy(document) }} +
        +
          +
        • + {{ chill_entity_workflow_list('Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluationDocument', document.id) }} +
        • + {% if is_granted('CHILL_CALENDAR_DOC_SEE', document) %} +
        • + {{ document.storedObject|chill_document_button_group(document.storedObject.title, is_granted('CHILL_CALENDAR_CALENDAR_EDIT', c)) }} +
        • + {% endif %} + {% if is_granted('CHILL_CALENDAR_CALENDAR_EDIT', c) %} +
        • + +
        • + {% endif %} +
        + +
        +
        diff --git a/src/Bundle/ChillActivityBundle/Service/GenericDoc/Providers/AccompanyingPeriodActivityGenericDocProvider.php b/src/Bundle/ChillActivityBundle/Service/GenericDoc/Providers/AccompanyingPeriodActivityGenericDocProvider.php index fc7484edf..bf7a022f1 100644 --- a/src/Bundle/ChillActivityBundle/Service/GenericDoc/Providers/AccompanyingPeriodActivityGenericDocProvider.php +++ b/src/Bundle/ChillActivityBundle/Service/GenericDoc/Providers/AccompanyingPeriodActivityGenericDocProvider.php @@ -27,7 +27,7 @@ final class AccompanyingPeriodActivityGenericDocProvider implements GenericDocFo { public const KEY = 'accompanying_period_activity_document'; - private EntityManagerInterface $em; + private EntityManagerInterface $em; private Security $security; @@ -49,7 +49,6 @@ final class AccompanyingPeriodActivityGenericDocProvider implements GenericDocFo public function buildFetchQueryForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod, ?DateTimeImmutable $startDate = null, ?DateTimeImmutable $endDate = null, ?string $content = null, ?string $origin = null): FetchQueryInterface { $storedObjectMetadata = $this->em->getClassMetadata(StoredObject::class); -// $activityMetadata = $this->em->getClassMetadata(Activity::class); $query = new FetchQuery( self::KEY, diff --git a/src/Bundle/ChillActivityBundle/Service/GenericDoc/Renderers/AccompanyingPeriodActivityGenericDocRenderer.php b/src/Bundle/ChillActivityBundle/Service/GenericDoc/Renderers/AccompanyingPeriodActivityGenericDocRenderer.php index eddcc6828..f243fb941 100644 --- a/src/Bundle/ChillActivityBundle/Service/GenericDoc/Renderers/AccompanyingPeriodActivityGenericDocRenderer.php +++ b/src/Bundle/ChillActivityBundle/Service/GenericDoc/Renderers/AccompanyingPeriodActivityGenericDocRenderer.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Chill\ActivityBundle\Service\GenericDoc\Renderers; +use Chill\ActivityBundle\Repository\ActivityRepository; use Chill\ActivityBundle\Service\GenericDoc\Providers\AccompanyingPeriodActivityGenericDocProvider; use Chill\DocStoreBundle\GenericDoc\GenericDocDTO; use Chill\DocStoreBundle\GenericDoc\Twig\GenericDocRendererInterface; @@ -18,11 +19,14 @@ use Chill\DocStoreBundle\Repository\StoredObjectRepository; final class AccompanyingPeriodActivityGenericDocRenderer implements GenericDocRendererInterface { - private StoredObjectRepository $repository; + private StoredObjectRepository $objectRepository; - public function __construct(StoredObjectRepository $storedObjectRepository) + private ActivityRepository $activityRepository; + + public function __construct(StoredObjectRepository $storedObjectRepository, ActivityRepository $activityRepository) { - $this->repository = $storedObjectRepository; + $this->objectRepository = $storedObjectRepository; + $this->activityRepository = $activityRepository; } public function supports(GenericDocDTO $genericDocDTO, $options = []): bool @@ -38,7 +42,8 @@ final class AccompanyingPeriodActivityGenericDocRenderer implements GenericDocRe public function getTemplateData(GenericDocDTO $genericDocDTO, $options = []): array { return [ - 'document' => $this->repository->find($genericDocDTO->identifiers['id']) + 'activity' => $this->activityRepository->findOneByDocument($genericDocDTO->identifiers['id']), + 'document' => $this->objectRepository->find($genericDocDTO->identifiers['id']) ]; } } From 40af1e64ac5dc612833b95752e86244cf616a84a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 30 May 2023 20:48:35 +0200 Subject: [PATCH 099/321] [generic doc] listing generic doc for person --- .../ChillDocStoreBundle.php | 3 + .../Controller/GenericDocForPerson.php | 95 +++++++++++++ ...ForAccompanyingPeriodProviderInterface.php | 2 - .../GenericDocForPersonProviderInterface.php | 31 ++++ .../GenericDoc/Manager.php | 108 +++++++++++--- .../PersonDocumentGenericDocProvider.php | 51 +++++++ ...anyingCourseDocumentGenericDocRenderer.php | 20 ++- .../PersonDocumentACLAwareRepository.php | 134 ++++++++++++++++-- ...sonDocumentACLAwareRepositoryInterface.php | 14 ++ .../Repository/PersonDocumentRepository.php | 49 +++++++ .../views/GenericDoc/person_list.html.twig | 74 ++++++++++ .../Tests/GenericDoc/ManagerTest.php | 119 +++++++++++++++- .../PersonDocumentGenericDocProviderTest.php | 84 +++++++++++ .../PersonDocumentACLAwareRepositoryTest.php | 99 +++++++++++++ .../ChillDocStoreBundle/config/services.yaml | 1 + 15 files changed, 842 insertions(+), 42 deletions(-) create mode 100644 src/Bundle/ChillDocStoreBundle/Controller/GenericDocForPerson.php create mode 100644 src/Bundle/ChillDocStoreBundle/GenericDoc/GenericDocForPersonProviderInterface.php create mode 100644 src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/PersonDocumentGenericDocProvider.php create mode 100644 src/Bundle/ChillDocStoreBundle/Repository/PersonDocumentRepository.php create mode 100644 src/Bundle/ChillDocStoreBundle/Resources/views/GenericDoc/person_list.html.twig create mode 100644 src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/Providers/PersonDocumentGenericDocProviderTest.php create mode 100644 src/Bundle/ChillDocStoreBundle/Tests/Repository/PersonDocumentACLAwareRepositoryTest.php diff --git a/src/Bundle/ChillDocStoreBundle/ChillDocStoreBundle.php b/src/Bundle/ChillDocStoreBundle/ChillDocStoreBundle.php index bc659d146..8dcbe72c3 100644 --- a/src/Bundle/ChillDocStoreBundle/ChillDocStoreBundle.php +++ b/src/Bundle/ChillDocStoreBundle/ChillDocStoreBundle.php @@ -12,6 +12,7 @@ declare(strict_types=1); namespace Chill\DocStoreBundle; use Chill\DocStoreBundle\GenericDoc\GenericDocForAccompanyingPeriodProviderInterface; +use Chill\DocStoreBundle\GenericDoc\GenericDocForPersonProviderInterface; use Chill\DocStoreBundle\GenericDoc\Twig\GenericDocRendererInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\HttpKernel\Bundle\Bundle; @@ -22,6 +23,8 @@ class ChillDocStoreBundle extends Bundle { $container->registerForAutoconfiguration(GenericDocForAccompanyingPeriodProviderInterface::class) ->addTag('chill_doc_store.generic_doc_accompanying_period_provider'); + $container->registerForAutoconfiguration(GenericDocForPersonProviderInterface::class) + ->addTag('chill_doc_store.generic_doc_person_provider'); $container->registerForAutoconfiguration(GenericDocRendererInterface::class) ->addTag('chill_doc_store.generic_doc_renderer'); } diff --git a/src/Bundle/ChillDocStoreBundle/Controller/GenericDocForPerson.php b/src/Bundle/ChillDocStoreBundle/Controller/GenericDocForPerson.php new file mode 100644 index 000000000..3484e0904 --- /dev/null +++ b/src/Bundle/ChillDocStoreBundle/Controller/GenericDocForPerson.php @@ -0,0 +1,95 @@ +security->isGranted(PersonDocumentVoter::SEE, $person)) { + throw new AccessDeniedHttpException("not allowed to see the documents for person"); + } + + $filterBuilder = $this->filterOrderHelperFactory + ->create(self::class) + ->addSearchBox() + ->addDateRange('dateRange', 'generic_doc.filter.date-range'); + + if ([] !== $places = $this->manager->placesForPerson($person)) { + $filterBuilder->addCheckbox('places', $places, [], array_map( + static fn (string $k) => 'generic_doc.filter.keys.' . $k, + $places + )); + } + + $filter = $filterBuilder + ->build(); + + ['to' => $endDate, 'from' => $startDate ] = $filter->getDateRangeData('dateRange'); + $content = $filter->getQueryString(); + + $nb = $this->manager->countDocForPerson( + $person, + $startDate, + $endDate, + $content, + $filter->hasCheckBox('places') ? array_values($filter->getCheckboxData('places')) : [] + ); + $paginator = $this->paginator->create($nb); + + $documents = $this->manager->findDocForPerson( + $person, + $paginator->getCurrentPageFirstItemNumber(), + $paginator->getItemsPerPage(), + $startDate, + $endDate, + $content, + $filter->hasCheckBox('places') ? array_values($filter->getCheckboxData('places')) : [] + ); + + return new Response($this->twig->render( + '@ChillDocStore/GenericDoc/person_list.html.twig', + [ + 'person' => $person, + 'pagination' => $paginator, + 'documents' => iterator_to_array($documents), + 'filter' => $filter, + ] + )); + } + +} diff --git a/src/Bundle/ChillDocStoreBundle/GenericDoc/GenericDocForAccompanyingPeriodProviderInterface.php b/src/Bundle/ChillDocStoreBundle/GenericDoc/GenericDocForAccompanyingPeriodProviderInterface.php index 4702e74c7..0d3cb1c32 100644 --- a/src/Bundle/ChillDocStoreBundle/GenericDoc/GenericDocForAccompanyingPeriodProviderInterface.php +++ b/src/Bundle/ChillDocStoreBundle/GenericDoc/GenericDocForAccompanyingPeriodProviderInterface.php @@ -25,8 +25,6 @@ interface GenericDocForAccompanyingPeriodProviderInterface /** * Return true if the user is allowed to see some documents for this provider. - * - * @return bool */ public function isAllowedForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod): bool; diff --git a/src/Bundle/ChillDocStoreBundle/GenericDoc/GenericDocForPersonProviderInterface.php b/src/Bundle/ChillDocStoreBundle/GenericDoc/GenericDocForPersonProviderInterface.php new file mode 100644 index 000000000..027afe834 --- /dev/null +++ b/src/Bundle/ChillDocStoreBundle/GenericDoc/GenericDocForPersonProviderInterface.php @@ -0,0 +1,31 @@ + */ - private readonly iterable $providersForAccompanyingPeriod, - private readonly Connection $connection, + private iterable $providersForAccompanyingPeriod, + + /** + * @var iterable + */ + private iterable $providersForPerson, + private Connection $connection, ) { $this->builder = new FetchQueryToSqlBuilder(); } @@ -44,6 +49,11 @@ class Manager ): int { ['sql' => $sql, 'params' => $params, 'types' => $types] = $this->buildUnionQuery($accompanyingPeriod, $startDate, $endDate, $content, $places); + return $this->countDoc($sql, $params, $types); + } + + private function countDoc(string $sql, array $params, array $types): int + { if ($sql === '') { return 0; } @@ -60,8 +70,21 @@ class Manager return $number; } + public function countDocForPerson( + Person $person, + ?\DateTimeImmutable $startDate = null, + ?\DateTimeImmutable $endDate = null, + ?string $content = null, + array $places = [] + ): int { + ['sql' => $sql, 'params' => $params, 'types' => $types] = $this->buildUnionQuery($person, $startDate, $endDate, $content, $places); + + return $this->countDoc($sql, $params, $types); + } + /** * @param list $places places to search. When empty, search in all places + * @return iterable * @throws Exception */ public function findDocForAccompanyingPeriod( @@ -75,6 +98,15 @@ class Manager ): iterable { ['sql' => $sql, 'params' => $params, 'types' => $types] = $this->buildUnionQuery($accompanyingPeriod, $startDate, $endDate, $content, $places); + return $this->findDocs($accompanyingPeriod, $sql, $params, $types, $offset, $limit); + } + + /** + * @throws \JsonException + * @throws Exception + */ + private function findDocs(AccompanyingPeriod|Person $linked, string $sql, array $params, array $types, int $offset, int $limit): iterable + { if ($sql === '') { return []; } @@ -88,20 +120,50 @@ class Manager $row['key'], json_decode($row['identifiers'], true, 512, JSON_THROW_ON_ERROR), new \DateTimeImmutable($row['doc_date']), - $accompanyingPeriod, + $linked, ); } } + /** + * @param list $places places to search. When empty, search in all places + * @return iterable + */ + public function findDocForPerson( + Person $person, + int $offset = 0, + int $limit = 20, + ?\DateTimeImmutable $startDate = null, + ?\DateTimeImmutable $endDate = null, + ?string $content = null, + array $places = [] + ): iterable { + ['sql' => $sql, 'params' => $params, 'types' => $types] = $this->buildUnionQuery($person, $startDate, $endDate, $content, $places); + + return $this->findDocs($person, $sql, $params, $types, $offset, $limit); + } + + public function placesForPerson(Person $person): array + { + ['sql' => $sql, 'params' => $params, 'types' => $types] = $this->buildUnionQuery($person); + + return $this->places($sql, $params, $types); + } + public function placesForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod): array { ['sql' => $sql, 'params' => $params, 'types' => $types] = $this->buildUnionQuery($accompanyingPeriod); + return $this->places($sql, $params, $types); + } + + private function places(string $sql, array $params, array $types): array + { if ($sql === '') { return []; } - $runSql = "SELECT DISTINCT key FROM ({$sql}) AS sq"; + $runSql = "SELECT DISTINCT key FROM ({$sql}) AS sq ORDER BY key"; $keys = []; @@ -122,28 +184,38 @@ class Manager ?string $content = null, array $places = [], ): array { - $sql = []; - $params = []; - $types = []; + $queries = []; if ($linked instanceof AccompanyingPeriod) { foreach ($this->providersForAccompanyingPeriod as $provider) { if (!$provider->isAllowedForAccompanyingPeriod($linked)) { continue; } - $query = $provider->buildFetchQueryForAccompanyingPeriod($linked, $startDate, $endDate, $content); - - if ([] !== $places and !in_array($query->getSelectKeyString(), $places, true)) { + $queries[] = $provider->buildFetchQueryForAccompanyingPeriod($linked, $startDate, $endDate, $content); + } + } else { + foreach ($this->providersForPerson as $provider) { + if (!$provider->isAllowedForPerson($linked)) { continue; } - - ['sql' => $q, 'params' => $p, 'types' => $t ] = $this->builder->toSql($query); - - $sql[] = $q; - $params = [...$params, ...$p]; - $types = [...$types, ...$t]; + $queries[] = $provider->buildFetchQueryForPerson($linked, $startDate, $endDate, $content); } } + $sql = []; + $params = []; + $types = []; + + foreach ($queries as $query) { + if ([] !== $places and !in_array($query->getSelectKeyString(), $places, true)) { + continue; + } + + ['sql' => $q, 'params' => $p, 'types' => $t ] = $this->builder->toSql($query); + + $sql[] = $q; + $params = [...$params, ...$p]; + $types = [...$types, ...$t]; + } return ['sql' => implode(' UNION ', $sql), 'params' => $params, 'types' => $types]; } diff --git a/src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/PersonDocumentGenericDocProvider.php b/src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/PersonDocumentGenericDocProvider.php new file mode 100644 index 000000000..08a0df960 --- /dev/null +++ b/src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/PersonDocumentGenericDocProvider.php @@ -0,0 +1,51 @@ +personDocumentACLAwareRepository->buildFetchQueryForPerson( + $person, + $startDate, + $endDate, + $content + ); + } + + public function isAllowedForPerson(Person $person): bool + { + return $this->security->isGranted(PersonDocumentVoter::SEE, $person); + } +} diff --git a/src/Bundle/ChillDocStoreBundle/GenericDoc/Renderer/AccompanyingCourseDocumentGenericDocRenderer.php b/src/Bundle/ChillDocStoreBundle/GenericDoc/Renderer/AccompanyingCourseDocumentGenericDocRenderer.php index 4e27f6335..a533b577a 100644 --- a/src/Bundle/ChillDocStoreBundle/GenericDoc/Renderer/AccompanyingCourseDocumentGenericDocRenderer.php +++ b/src/Bundle/ChillDocStoreBundle/GenericDoc/Renderer/AccompanyingCourseDocumentGenericDocRenderer.php @@ -12,20 +12,25 @@ declare(strict_types=1); namespace Chill\DocStoreBundle\GenericDoc\Renderer; use Chill\DocStoreBundle\GenericDoc\GenericDocDTO; +use Chill\DocStoreBundle\GenericDoc\Providers\PersonDocumentGenericDocProvider; use Chill\DocStoreBundle\GenericDoc\Twig\GenericDocRendererInterface; use Chill\DocStoreBundle\GenericDoc\Providers\AccompanyingProviderCourseDocumentGenericDoc; use Chill\DocStoreBundle\Repository\AccompanyingCourseDocumentRepository; +use Chill\DocStoreBundle\Repository\PersonDocumentRepository; +use Chill\PersonBundle\Entity\AccompanyingPeriod; final readonly class AccompanyingCourseDocumentGenericDocRenderer implements GenericDocRendererInterface { public function __construct( private AccompanyingCourseDocumentRepository $accompanyingCourseDocumentRepository, + private PersonDocumentRepository $personDocumentRepository, ) { } public function supports(GenericDocDTO $genericDocDTO, $options = []): bool { - return $genericDocDTO->key === AccompanyingProviderCourseDocumentGenericDoc::KEY; + return $genericDocDTO->key === AccompanyingProviderCourseDocumentGenericDoc::KEY + || $genericDocDTO->key === PersonDocumentGenericDocProvider::KEY; } public function getTemplate(GenericDocDTO $genericDocDTO, $options = []): string @@ -35,9 +40,18 @@ final readonly class AccompanyingCourseDocumentGenericDocRenderer implements Gen public function getTemplateData(GenericDocDTO $genericDocDTO, $options = []): array { + if ($genericDocDTO->linked instanceof AccompanyingPeriod) { + return [ + 'document' => $this->accompanyingCourseDocumentRepository->find($genericDocDTO->identifiers['id']), + 'accompanyingCourse' => $genericDocDTO->linked, + 'options' => $options, + ]; + } + + // this is a person return [ - 'document' => $this->accompanyingCourseDocumentRepository->find($genericDocDTO->identifiers['id']), - 'accompanyingCourse' => $genericDocDTO->linked, + 'document' => $this->personDocumentRepository->find($genericDocDTO->identifiers['id']), + 'person' => $genericDocDTO->linked, 'options' => $options, ]; } diff --git a/src/Bundle/ChillDocStoreBundle/Repository/PersonDocumentACLAwareRepository.php b/src/Bundle/ChillDocStoreBundle/Repository/PersonDocumentACLAwareRepository.php index 23dcc4e0b..5d85541aa 100644 --- a/src/Bundle/ChillDocStoreBundle/Repository/PersonDocumentACLAwareRepository.php +++ b/src/Bundle/ChillDocStoreBundle/Repository/PersonDocumentACLAwareRepository.php @@ -12,30 +12,36 @@ declare(strict_types=1); namespace Chill\DocStoreBundle\Repository; use Chill\DocStoreBundle\Entity\PersonDocument; +use Chill\DocStoreBundle\GenericDoc\FetchQuery; +use Chill\DocStoreBundle\GenericDoc\FetchQueryInterface; +use Chill\DocStoreBundle\GenericDoc\Providers\PersonDocumentGenericDocProvider; use Chill\DocStoreBundle\Security\Authorization\PersonDocumentVoter; +use Chill\MainBundle\Entity\Scope; +use Chill\MainBundle\Security\Authorization\AuthorizationHelperForCurrentUserInterface; use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface; use Chill\MainBundle\Security\Resolver\CenterResolverDispatcher; +use Chill\MainBundle\Security\Resolver\CenterResolverDispatcherInterface; +use Chill\MainBundle\Security\Resolver\CenterResolverManagerInterface; use Chill\PersonBundle\Entity\Person; +use DateTimeImmutable; +use Doctrine\DBAL\Types\Types; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Security\Core\Security; class PersonDocumentACLAwareRepository implements PersonDocumentACLAwareRepositoryInterface { - private AuthorizationHelperInterface $authorizationHelper; + private AuthorizationHelperForCurrentUserInterface $authorizationHelperForCurrentUser; - private CenterResolverDispatcher $centerResolverDispatcher; + private CenterResolverManagerInterface $centerResolverManager; private EntityManagerInterface $em; - private Security $security; - - public function __construct(EntityManagerInterface $em, AuthorizationHelperInterface $authorizationHelper, CenterResolverDispatcher $centerResolverDispatcher, Security $security) + public function __construct(EntityManagerInterface $em, CenterResolverManagerInterface $centerResolverManager, AuthorizationHelperForCurrentUserInterface $authorizationHelperForCurrentUser) { $this->em = $em; - $this->authorizationHelper = $authorizationHelper; - $this->centerResolverDispatcher = $centerResolverDispatcher; - $this->security = $security; + $this->centerResolverManager = $centerResolverManager; + $this->authorizationHelperForCurrentUser = $authorizationHelperForCurrentUser; } public function buildQueryByPerson(Person $person): QueryBuilder @@ -49,6 +55,62 @@ class PersonDocumentACLAwareRepository implements PersonDocumentACLAwareReposito return $qb; } + + public function buildFetchQueryForPerson(Person $person, ?DateTimeImmutable $startDate = null, ?DateTimeImmutable $endDate = null, ?string $content = null): FetchQueryInterface + { + $query = $this->buildBaseFetchQueryForPerson($person, $startDate, $endDate, $content); + + return $this->addFetchQueryByPersonACL($query, $person); + } + + public function buildBaseFetchQueryForPerson(Person $person, ?DateTimeImmutable $startDate = null, ?DateTimeImmutable $endDate = null, ?string $content = null): FetchQuery + { + $personDocMetadata = $this->em->getClassMetadata(PersonDocument::class); + + $query = new FetchQuery( + PersonDocumentGenericDocProvider::KEY, + sprintf('jsonb_build_object(\'id\', person_document.%s)', $personDocMetadata->getSingleIdentifierColumnName()), + sprintf('person_document.%s', $personDocMetadata->getColumnName('date')), + sprintf('%s AS person_document', $personDocMetadata->getSchemaName().'.'.$personDocMetadata->getTableName()) + ); + + $query->addWhereClause( + sprintf('person_document.%s = ?', $personDocMetadata->getSingleAssociationJoinColumnName('person')), + [$person->getId()], + [Types::INTEGER] + ); + + if (null !== $startDate) { + $query->addWhereClause( + sprintf('? <= %s', $personDocMetadata->getColumnName('date')), + [$startDate], + [Types::DATE_IMMUTABLE] + ); + } + + if (null !== $endDate) { + $query->addWhereClause( + sprintf('? >= %s', $personDocMetadata->getColumnName('date')), + [$endDate], + [Types::DATE_IMMUTABLE] + ); + } + + if (null !== $content and '' !== $content) { + $query->addWhereClause( + sprintf( + '(%s ilike ? OR %s ilike ?)', + $personDocMetadata->getColumnName('title'), + $personDocMetadata->getColumnName('description') + ), + ['%' . $content . '%', '%' . $content . '%'], + [Types::STRING, Types::STRING] + ); + } + + return $query; + } + public function countByPerson(Person $person): int { $qb = $this->buildQueryByPerson($person)->select('COUNT(d)'); @@ -75,16 +137,58 @@ class PersonDocumentACLAwareRepository implements PersonDocumentACLAwareReposito private function addACL(QueryBuilder $qb, Person $person): void { - $center = $this->centerResolverDispatcher->resolveCenter($person); + $reachableScopes = []; - $reachableScopes = $this->authorizationHelper - ->getReachableScopes( - $this->security->getUser(), - PersonDocumentVoter::SEE, - $center - ); + foreach ($this->centerResolverManager->resolveCenters($person) as $center) { + $reachableScopes = [ + ...$reachableScopes, + ...$this->authorizationHelperForCurrentUser + ->getReachableScopes( + PersonDocumentVoter::SEE, + $center + ) + ]; + } + + if ([] === $reachableScopes) { + $qb->andWhere("'FALSE' = 'TRUE'"); + + return; + } $qb->andWhere($qb->expr()->in('d.scope', ':scopes')) ->setParameter('scopes', $reachableScopes); } + + private function addFetchQueryByPersonACL(FetchQuery $fetchQuery, Person $person): FetchQuery + { + $personDocMetadata = $this->em->getClassMetadata(PersonDocument::class); + + $reachableScopes = []; + + foreach ($this->centerResolverManager->resolveCenters($person) as $center) { + $reachableScopes = [ + ...$reachableScopes, + ...$this->authorizationHelperForCurrentUser->getReachableScopes(PersonDocumentVoter::SEE, $center) + ]; + } + + if ([] === $reachableScopes) { + $fetchQuery->addWhereClause('FALSE = TRUE'); + + return $fetchQuery; + } + + $fetchQuery->addWhereClause( + sprintf( + 'person_document.%s IN (%s)', + $personDocMetadata->getSingleAssociationJoinColumnName('scope'), + implode(', ', array_fill(0, count($reachableScopes), '?')) + ), + array_map(static fn (Scope $s) => $s->getId(), $reachableScopes), + array_fill(0, count($reachableScopes), Types::INTEGER) + ); + + return $fetchQuery; + } } diff --git a/src/Bundle/ChillDocStoreBundle/Repository/PersonDocumentACLAwareRepositoryInterface.php b/src/Bundle/ChillDocStoreBundle/Repository/PersonDocumentACLAwareRepositoryInterface.php index 6c4bd2e9a..0b5e26792 100644 --- a/src/Bundle/ChillDocStoreBundle/Repository/PersonDocumentACLAwareRepositoryInterface.php +++ b/src/Bundle/ChillDocStoreBundle/Repository/PersonDocumentACLAwareRepositoryInterface.php @@ -11,11 +11,25 @@ declare(strict_types=1); namespace Chill\DocStoreBundle\Repository; +use Chill\DocStoreBundle\GenericDoc\FetchQueryInterface; use Chill\PersonBundle\Entity\Person; interface PersonDocumentACLAwareRepositoryInterface { + /** + * @deprecated use fetch query for listing and counting person documents + */ public function countByPerson(Person $person): int; + /** + * @deprecated use fetch query for listing and counting person documents + */ public function findByPerson(Person $person, array $orderBy = [], int $limit = 20, int $offset = 0): array; + + public function buildFetchQueryForPerson( + Person $person, + ?\DateTimeImmutable $startDate = null, + ?\DateTimeImmutable $endDate = null, + ?string $content = null + ): FetchQueryInterface; } diff --git a/src/Bundle/ChillDocStoreBundle/Repository/PersonDocumentRepository.php b/src/Bundle/ChillDocStoreBundle/Repository/PersonDocumentRepository.php new file mode 100644 index 000000000..62a3bbcec --- /dev/null +++ b/src/Bundle/ChillDocStoreBundle/Repository/PersonDocumentRepository.php @@ -0,0 +1,49 @@ + + */ +readonly class PersonDocumentRepository implements ObjectRepository +{ + private EntityRepository $repository; + + public function __construct( + private EntityManagerInterface $entityManager + ) + { + $this->repository = $this->entityManager->getRepository($this->getClassName()); + } + + public function find($id): ?PersonDocument + { + return $this->repository->find($id); + } + + public function findAll() + { + return $this->repository->findAll(); + } + + public function findBy(array $criteria, ?array $orderBy = null, ?int $limit = null, ?int $offset = null) + { + return $this->repository->findBy($criteria, $orderBy, $limit, $offset); + } + + public function findOneBy(array $criteria): ?PersonDocument + { + return $this->repository->findOneBy($criteria); + } + + public function getClassName(): string + { + return PersonDocument::class; + } +} diff --git a/src/Bundle/ChillDocStoreBundle/Resources/views/GenericDoc/person_list.html.twig b/src/Bundle/ChillDocStoreBundle/Resources/views/GenericDoc/person_list.html.twig new file mode 100644 index 000000000..a4aa4fbbc --- /dev/null +++ b/src/Bundle/ChillDocStoreBundle/Resources/views/GenericDoc/person_list.html.twig @@ -0,0 +1,74 @@ +{# + * Copyright (C) 2018, Champs Libres Cooperative SCRLFS, + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . +#} + +{% extends "@ChillPerson/Person/layout.html.twig" %} + +{% set activeRouteKey = '' %} + +{% import "@ChillDocStore/Macro/macro.html.twig" as m %} + +{% block title %} + {{ 'Documents for %name%'|trans({ '%name%': person|chill_entity_render_string } ) }} +{% endblock %} + +{% block js %} + {{ parent() }} + {{ encore_entry_script_tags('mod_docgen_picktemplate') }} + {{ encore_entry_script_tags('mod_entity_workflow_pick') }} + {{ encore_entry_script_tags('mod_document_action_buttons_group') }} +{% endblock %} + +{% block css %} + {{ parent() }} + {{ encore_entry_link_tags('mod_docgen_picktemplate') }} + {{ encore_entry_link_tags('mod_entity_workflow_pick') }} + {{ encore_entry_link_tags('mod_document_action_buttons_group') }} +{% endblock %} + +{% block content %} + +
        +

        {{ 'Documents for %name%'|trans({ '%name%': person|chill_entity_render_string } ) }}

        + + {{ filter|chill_render_filter_order_helper }} + + {% if documents|length == 0 %} +

        {{ 'No documents'|trans }}

        + {% else %} +
        + {% for document in documents %} + {{ document|chill_generic_doc_render }} + {% endfor %} +
        + {% endif %} + + {{ chill_pagination(pagination) }} + +
        + + {% if is_granted('CHILL_PERSON_DOCUMENT_CREATE', person) %} + + {% endif %} + +
        +{% endblock %} diff --git a/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/ManagerTest.php b/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/ManagerTest.php index 597aea84a..f59779374 100644 --- a/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/ManagerTest.php +++ b/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/ManagerTest.php @@ -14,9 +14,12 @@ namespace Chill\DocStoreBundle\Tests\GenericDoc; use Chill\DocStoreBundle\GenericDoc\FetchQuery; use Chill\DocStoreBundle\GenericDoc\FetchQueryInterface; use Chill\DocStoreBundle\GenericDoc\GenericDocDTO; +use Chill\DocStoreBundle\GenericDoc\GenericDocForPersonProviderInterface; use Chill\DocStoreBundle\GenericDoc\Manager; use Chill\DocStoreBundle\GenericDoc\GenericDocForAccompanyingPeriodProviderInterface; use Chill\PersonBundle\Entity\AccompanyingPeriod; +use Chill\PersonBundle\Entity\Person; +use DateTimeImmutable; use Doctrine\DBAL\Connection; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\EntityManagerInterface; @@ -53,7 +56,8 @@ class ManagerTest extends KernelTestCase } $manager = new Manager( - [new SimpleGenericDocProvider()], + [new SimpleGenericDocAccompanyingPeriodProvider()], + [new SimpleGenericDocPersonProvider()], $this->connection, ); @@ -62,6 +66,27 @@ class ManagerTest extends KernelTestCase self::assertIsInt($nb); } + public function testCountByPerson(): void + { + $person = $this->em->createQuery('SELECT a FROM '.Person::class.' a') + ->setMaxResults(1) + ->getSingleResult(); + + if (null === $person) { + throw new \UnexpectedValueException("person found"); + } + + $manager = new Manager( + [new SimpleGenericDocAccompanyingPeriodProvider()], + [new SimpleGenericDocPersonProvider()], + $this->connection, + ); + + $nb = $manager->countDocForPerson($person); + + self::assertIsInt($nb); + } + public function testFindDocByAccompanyingPeriod(): void { $period = $this->em->createQuery('SELECT a FROM '.AccompanyingPeriod::class.' a') @@ -73,7 +98,8 @@ class ManagerTest extends KernelTestCase } $manager = new Manager( - [new SimpleGenericDocProvider()], + [new SimpleGenericDocAccompanyingPeriodProvider()], + [new SimpleGenericDocPersonProvider()], $this->connection, ); @@ -81,14 +107,77 @@ class ManagerTest extends KernelTestCase self::assertInstanceOf(GenericDocDTO::class, $doc); } } + + public function testFindDocByPerson(): void + { + $person = $this->em->createQuery('SELECT a FROM '.Person::class.' a') + ->setMaxResults(1) + ->getSingleResult(); + + if (null === $person) { + throw new \UnexpectedValueException("person not found"); + } + + $manager = new Manager( + [new SimpleGenericDocAccompanyingPeriodProvider()], + [new SimpleGenericDocPersonProvider()], + $this->connection, + ); + + foreach ($manager->findDocForPerson($person) as $doc) { + self::assertInstanceOf(GenericDocDTO::class, $doc); + } + } + + public function testPlacesForPerson(): void + { + $person = $this->em->createQuery('SELECT a FROM '.Person::class.' a') + ->setMaxResults(1) + ->getSingleResult(); + + if (null === $person) { + throw new \UnexpectedValueException("person not found"); + } + + $manager = new Manager( + [new SimpleGenericDocAccompanyingPeriodProvider()], + [new SimpleGenericDocPersonProvider()], + $this->connection, + ); + + $places = $manager->placesForPerson($person); + + self::assertEquals(['dummy_person_doc'], $places); + } + + public function testPlacesForAccompanyingPeriod(): void + { + $period = $this->em->createQuery('SELECT a FROM '.AccompanyingPeriod::class.' a') + ->setMaxResults(1) + ->getSingleResult(); + + if (null === $period) { + throw new \UnexpectedValueException("period not found"); + } + + $manager = new Manager( + [new SimpleGenericDocAccompanyingPeriodProvider()], + [new SimpleGenericDocPersonProvider()], + $this->connection, + ); + + $places = $manager->placesForAccompanyingPeriod($period); + + self::assertEquals(['accompanying_course_document_dummy'], $places); + } } -final readonly class SimpleGenericDocProvider implements GenericDocForAccompanyingPeriodProviderInterface +final readonly class SimpleGenericDocAccompanyingPeriodProvider implements GenericDocForAccompanyingPeriodProviderInterface { public function buildFetchQueryForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod, ?\DateTimeImmutable $startDate = null, ?\DateTimeImmutable $endDate = null, ?string $content = null, ?string $origin = null): FetchQueryInterface { $query = new FetchQuery( - 'accompanying_course_document', + 'accompanying_course_document_dummy', sprintf('jsonb_build_object(\'id\', %s)', 'id'), 'd', '(VALUES (1, \'2023-05-01\'::date), (2, \'2023-05-01\'::date)) AS sq (id, d)', @@ -104,3 +193,25 @@ final readonly class SimpleGenericDocProvider implements GenericDocForAccompanyi return true; } } + +final readonly class SimpleGenericDocPersonProvider implements GenericDocForPersonProviderInterface +{ + public function buildFetchQueryForPerson(Person $person, ?DateTimeImmutable $startDate = null, ?DateTimeImmutable $endDate = null, ?string $content = null, ?string $origin = null): FetchQueryInterface + { + $query = new FetchQuery( + 'dummy_person_doc', + sprintf('jsonb_build_object(\'id\', %s)', 'id'), + 'd', + '(VALUES (1, \'2023-05-01\'::date), (2, \'2023-05-01\'::date)) AS sq (id, d)', + ); + + $query->addWhereClause('d > ?', [new \DateTimeImmutable('2023-01-01')], [Types::DATE_IMMUTABLE]); + + return $query; + } + + public function isAllowedForPerson(Person $person): bool + { + return true; + } +} diff --git a/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/Providers/PersonDocumentGenericDocProviderTest.php b/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/Providers/PersonDocumentGenericDocProviderTest.php new file mode 100644 index 000000000..577357820 --- /dev/null +++ b/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/Providers/PersonDocumentGenericDocProviderTest.php @@ -0,0 +1,84 @@ +entityManager = self::$container->get(EntityManagerInterface::class); + $this->personDocumentACLAwareRepository = self::$container->get(PersonDocumentACLAwareRepositoryInterface::class); + } + + /** + * @dataProvider provideDataBuildFetchQueryForPerson + * @throws \Doctrine\DBAL\Exception + * @throws \Doctrine\ORM\NoResultException + * @throws \Doctrine\ORM\NonUniqueResultException + */ + public function testBuildFetchQueryForPerson(?DateTimeImmutable $startDate, ?DateTimeImmutable $endDate, ?string $content): void + { + $security = $this->prophesize(Security::class); + $person = $this->entityManager->createQuery('SELECT a FROM '.Person::class.' a') + ->setMaxResults(1) + ->getSingleResult(); + + if (null === $person) { + throw new \UnexpectedValueException("person found"); + } + + $provider = new PersonDocumentGenericDocProvider( + $security->reveal(), + $this->personDocumentACLAwareRepository + ); + + $query = $provider->buildFetchQueryForPerson($person, $startDate, $endDate, $content); + + ['sql' => $sql, 'params' => $params, 'types' => $types] = (new FetchQueryToSqlBuilder())->toSql($query); + + $nb = $this->entityManager->getConnection() + ->fetchOne("SELECT COUNT(*) AS nb FROM (${sql}) AS sq", $params, $types); + + self::assertIsInt($nb, "Test that the query is syntactically correct"); + } + + public function provideDataBuildFetchQueryForPerson(): iterable + { + yield [null, null, null]; + yield [new DateTimeImmutable('1 year ago'), null, null]; + yield [null, new DateTimeImmutable('1 year ago'), null]; + yield [new DateTimeImmutable('2 years ago'), new DateTimeImmutable('1 year ago'), null]; + yield [null, null, 'test']; + yield [new DateTimeImmutable('2 years ago'), new DateTimeImmutable('1 year ago'), 'test']; + } +} diff --git a/src/Bundle/ChillDocStoreBundle/Tests/Repository/PersonDocumentACLAwareRepositoryTest.php b/src/Bundle/ChillDocStoreBundle/Tests/Repository/PersonDocumentACLAwareRepositoryTest.php new file mode 100644 index 000000000..98fca5622 --- /dev/null +++ b/src/Bundle/ChillDocStoreBundle/Tests/Repository/PersonDocumentACLAwareRepositoryTest.php @@ -0,0 +1,99 @@ +entityManager = self::$container->get(EntityManagerInterface::class); + $this->scopeRepository = self::$container->get(ScopeRepositoryInterface::class); + } + + /** + * @dataProvider provideDataBuildFetchQueryForPerson + * @throws \Doctrine\DBAL\Exception + * @throws \Doctrine\ORM\NoResultException + * @throws \Doctrine\ORM\NonUniqueResultException + */ + public function testBuildFetchQueryForPerson(?DateTimeImmutable $startDate = null, ?DateTimeImmutable $endDate = null, ?string $content = null): void + { + $centerManager = $this->prophesize(CenterResolverManagerInterface::class); + $centerManager->resolveCenters(Argument::type(Person::class)) + ->willReturn([new Center()]); + + $scopes = $this->scopeRepository->findAll(); + $authorizationHelper = $this->prophesize(AuthorizationHelperForCurrentUserInterface::class); + $authorizationHelper->getReachableScopes(PersonDocumentVoter::SEE, Argument::any())->willReturn($scopes); + + $repository = new PersonDocumentACLAwareRepository( + $this->entityManager, + $centerManager->reveal(), + $authorizationHelper->reveal() + ); + + $person = $this->entityManager->createQuery("SELECT p FROM " . Person::class . " p") + ->setMaxResults(1) + ->getSingleResult(); + + if (null === $person) { + throw new \RuntimeException("person not exists in database"); + } + + $query = $repository->buildFetchQueryForPerson($person, $startDate, $endDate, $content); + ['sql' => $sql, 'params' => $params, 'types' => $types] = (new FetchQueryToSqlBuilder())->toSql($query); + + $nb = $this->entityManager->getConnection() + ->fetchOne("SELECT COUNT(*) FROM ({$sql}) AS sq", $params, $types); + + self::assertIsInt($nb, "test that the query could be executed"); + } + + public function provideDataBuildFetchQueryForPerson(): iterable + { + yield [null, null, null]; + yield [new DateTimeImmutable('1 year ago'), null, null]; + yield [null, new DateTimeImmutable('1 year ago'), null]; + yield [new DateTimeImmutable('2 years ago'), new DateTimeImmutable('1 year ago'), null]; + yield [null, null, 'test']; + yield [new DateTimeImmutable('2 years ago'), new DateTimeImmutable('1 year ago'), 'test']; + } + +} diff --git a/src/Bundle/ChillDocStoreBundle/config/services.yaml b/src/Bundle/ChillDocStoreBundle/config/services.yaml index f242acc1c..04fc3ace3 100644 --- a/src/Bundle/ChillDocStoreBundle/config/services.yaml +++ b/src/Bundle/ChillDocStoreBundle/config/services.yaml @@ -50,6 +50,7 @@ services: autoconfigure: true arguments: $providersForAccompanyingPeriod: !tagged_iterator chill_doc_store.generic_doc_accompanying_period_provider + $providersForPerson: !tagged_iterator chill_doc_store.generic_doc_person_provider Chill\DocStoreBundle\GenericDoc\Twig\GenericDocExtension: autoconfigure: true From e9fdabf93166f01f2a157f7d89f0ec4cd2792565 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 30 May 2023 21:24:22 +0200 Subject: [PATCH 100/321] Remove old list for person document --- .../Controller/DocumentPersonController.php | 51 +------------ .../ChillDocStoreBundle/Menu/MenuBuilder.php | 4 +- .../views/PersonDocument/delete.html.twig | 4 +- .../views/PersonDocument/edit.html.twig | 2 +- .../views/PersonDocument/index.html.twig | 72 ------------------- .../views/PersonDocument/new.html.twig | 2 +- .../views/PersonDocument/show.html.twig | 2 +- 7 files changed, 9 insertions(+), 128 deletions(-) delete mode 100644 src/Bundle/ChillDocStoreBundle/Resources/views/PersonDocument/index.html.twig diff --git a/src/Bundle/ChillDocStoreBundle/Controller/DocumentPersonController.php b/src/Bundle/ChillDocStoreBundle/Controller/DocumentPersonController.php index 6fcb6a8e5..20e8e9b03 100644 --- a/src/Bundle/ChillDocStoreBundle/Controller/DocumentPersonController.php +++ b/src/Bundle/ChillDocStoreBundle/Controller/DocumentPersonController.php @@ -45,10 +45,6 @@ class DocumentPersonController extends AbstractController protected TranslatorInterface $translator; - private PaginatorFactory $paginatorFactory; - - private PersonDocumentACLAwareRepositoryInterface $personDocumentACLAwareRepository; - /** * DocumentPersonController constructor. */ @@ -56,14 +52,10 @@ class DocumentPersonController extends AbstractController TranslatorInterface $translator, EventDispatcherInterface $eventDispatcher, AuthorizationHelper $authorizationHelper, - PaginatorFactory $paginatorFactory, - PersonDocumentACLAwareRepositoryInterface $personDocumentACLAwareRepository ) { $this->translator = $translator; $this->eventDispatcher = $eventDispatcher; $this->authorizationHelper = $authorizationHelper; - $this->paginatorFactory = $paginatorFactory; - $this->personDocumentACLAwareRepository = $personDocumentACLAwareRepository; } /** @@ -88,7 +80,7 @@ class DocumentPersonController extends AbstractController return $this->redirect($request->query->get('returnPath')); } - return $this->redirectToRoute('person_document_index', ['person' => $person->getId()]); + return $this->redirectToRoute('chill_docstore_generic-doc_by-person_index', ['id' => $person->getId()]); } return $this->render( @@ -160,45 +152,6 @@ class DocumentPersonController extends AbstractController ); } - /** - * @Route("/", name="person_document_index", methods="GET") - */ - public function index(Person $person): Response - { - $em = $this->getDoctrine()->getManager(); - - if (null === $person) { - throw $this->createNotFoundException('Person not found'); - } - - $this->denyAccessUnlessGranted(PersonVoter::SEE, $person); - - $total = $this->personDocumentACLAwareRepository->countByPerson($person); - $pagination = $this->paginatorFactory->create($total); - - $documents = $this->personDocumentACLAwareRepository->findByPerson( - $person, - ['date' => 'DESC', 'id' => 'DESC'], - $pagination->getItemsPerPage(), - $pagination->getCurrentPageFirstItemNumber() - ); - - $event = new PrivacyEvent($person, [ - 'element_class' => PersonDocument::class, - 'action' => 'index', - ]); - $this->eventDispatcher->dispatch(PrivacyEvent::PERSON_PRIVACY_EVENT, $event); - - return $this->render( - 'ChillDocStoreBundle:PersonDocument:index.html.twig', - [ - 'documents' => $documents, - 'person' => $person, - 'pagination' => $pagination, - ] - ); - } - /** * @Route("/new", name="person_document_new", methods="GET|POST") */ @@ -233,7 +186,7 @@ class DocumentPersonController extends AbstractController $this->addFlash('success', $this->translator->trans('The document is successfully registered')); - return $this->redirectToRoute('person_document_index', ['person' => $person->getId()]); + return $this->redirectToRoute('chill_docstore_generic-doc_by-person_index', ['id' => $person->getId()]); } if ($form->isSubmitted() && !$form->isValid()) { diff --git a/src/Bundle/ChillDocStoreBundle/Menu/MenuBuilder.php b/src/Bundle/ChillDocStoreBundle/Menu/MenuBuilder.php index 95b23904a..4288dc821 100644 --- a/src/Bundle/ChillDocStoreBundle/Menu/MenuBuilder.php +++ b/src/Bundle/ChillDocStoreBundle/Menu/MenuBuilder.php @@ -80,9 +80,9 @@ final class MenuBuilder implements LocalMenuBuilderInterface if ($this->security->isGranted(PersonDocumentVoter::SEE, $person)) { $menu->addChild($this->translator->trans('Documents'), [ - 'route' => 'person_document_index', + 'route' => 'chill_docstore_generic-doc_by-person_index', 'routeParameters' => [ - 'person' => $person->getId(), + 'id' => $person->getId(), ], ]) ->setExtras([ diff --git a/src/Bundle/ChillDocStoreBundle/Resources/views/PersonDocument/delete.html.twig b/src/Bundle/ChillDocStoreBundle/Resources/views/PersonDocument/delete.html.twig index bfdd87dc3..41c229faa 100644 --- a/src/Bundle/ChillDocStoreBundle/Resources/views/PersonDocument/delete.html.twig +++ b/src/Bundle/ChillDocStoreBundle/Resources/views/PersonDocument/delete.html.twig @@ -36,8 +36,8 @@ 'title' : 'Delete document ?'|trans, 'display_content' : block('docdescription'), 'confirm_question' : 'Are you sure you want to remove this document ?'|trans, - 'cancel_route' : 'person_document_index', - 'cancel_parameters' : {'person' : person.id, 'id': document.id}, + 'cancel_route' : 'chill_docstore_generic-doc_by-person_index', + 'cancel_parameters' : {'id' : person.id}, 'form' : delete_form } ) }} {% endblock %} diff --git a/src/Bundle/ChillDocStoreBundle/Resources/views/PersonDocument/edit.html.twig b/src/Bundle/ChillDocStoreBundle/Resources/views/PersonDocument/edit.html.twig index 416a35e35..17ce9d774 100644 --- a/src/Bundle/ChillDocStoreBundle/Resources/views/PersonDocument/edit.html.twig +++ b/src/Bundle/ChillDocStoreBundle/Resources/views/PersonDocument/edit.html.twig @@ -38,7 +38,7 @@
        • - + {{ 'Back to the list' | trans }}
        • diff --git a/src/Bundle/ChillDocStoreBundle/Resources/views/PersonDocument/index.html.twig b/src/Bundle/ChillDocStoreBundle/Resources/views/PersonDocument/index.html.twig deleted file mode 100644 index 8d201605e..000000000 --- a/src/Bundle/ChillDocStoreBundle/Resources/views/PersonDocument/index.html.twig +++ /dev/null @@ -1,72 +0,0 @@ -{# - * Copyright (C) 2018, Champs Libres Cooperative SCRLFS, - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . -#} - -{% extends "@ChillPerson/Person/layout.html.twig" %} - -{% set activeRouteKey = '' %} - -{% import "@ChillDocStore/Macro/macro.html.twig" as m %} - -{% block title %} - {{ 'Documents for %name%'|trans({ '%name%': person|chill_entity_render_string } ) }} -{% endblock %} - -{% block js %} - {{ parent() }} - {{ encore_entry_script_tags('mod_docgen_picktemplate') }} - {{ encore_entry_script_tags('mod_entity_workflow_pick') }} - {{ encore_entry_script_tags('mod_document_action_buttons_group') }} -{% endblock %} - -{% block css %} - {{ parent() }} - {{ encore_entry_link_tags('mod_docgen_picktemplate') }} - {{ encore_entry_link_tags('mod_entity_workflow_pick') }} - {{ encore_entry_link_tags('mod_document_action_buttons_group') }} -{% endblock %} - -{% block content %} - -
          -

          {{ 'Documents for %name%'|trans({ '%name%': person|chill_entity_render_string } ) }}

          - - {% if documents|length == 0 %} -

          {{ 'No documents'|trans }}

          - {% else %} -
          - {% for document in documents %} - {% include 'ChillDocStoreBundle:List:list_item.html.twig' %} - {% endfor %} -
          - {% endif %} - - {{ chill_pagination(pagination) }} - -
          - - {% if is_granted('CHILL_PERSON_DOCUMENT_CREATE', person) %} - - {% endif %} - -
          -{% endblock %} diff --git a/src/Bundle/ChillDocStoreBundle/Resources/views/PersonDocument/new.html.twig b/src/Bundle/ChillDocStoreBundle/Resources/views/PersonDocument/new.html.twig index 3187714a6..faf8895e7 100644 --- a/src/Bundle/ChillDocStoreBundle/Resources/views/PersonDocument/new.html.twig +++ b/src/Bundle/ChillDocStoreBundle/Resources/views/PersonDocument/new.html.twig @@ -42,7 +42,7 @@
          • - + {{ 'Back to the list' | trans }}
          • diff --git a/src/Bundle/ChillDocStoreBundle/Resources/views/PersonDocument/show.html.twig b/src/Bundle/ChillDocStoreBundle/Resources/views/PersonDocument/show.html.twig index c276e067e..1c0aa5e64 100644 --- a/src/Bundle/ChillDocStoreBundle/Resources/views/PersonDocument/show.html.twig +++ b/src/Bundle/ChillDocStoreBundle/Resources/views/PersonDocument/show.html.twig @@ -63,7 +63,7 @@
            • - + {{ 'Back to the list' | trans }}
            • From 40ddd1f1ee3787656dc944785e493c56be5d6718 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 30 May 2023 21:25:33 +0200 Subject: [PATCH 101/321] Add license --- .../Repository/PersonDocumentRepository.php | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/Bundle/ChillDocStoreBundle/Repository/PersonDocumentRepository.php b/src/Bundle/ChillDocStoreBundle/Repository/PersonDocumentRepository.php index 62a3bbcec..40afdc220 100644 --- a/src/Bundle/ChillDocStoreBundle/Repository/PersonDocumentRepository.php +++ b/src/Bundle/ChillDocStoreBundle/Repository/PersonDocumentRepository.php @@ -1,5 +1,14 @@ repository = $this->entityManager->getRepository($this->getClassName()); } From da36c59616379c77119d7fe9ff2e56275e003b68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 30 May 2023 21:52:36 +0200 Subject: [PATCH 102/321] refactor: rename class providing AccompanyingCourseDocument Generic doc --- ...php => AccompanyingCourseDocumentGenericDocProvider.php} | 2 +- .../AccompanyingCourseDocumentGenericDocRenderer.php | 4 ++-- ...=> AccompanyingCourseDocumentGenericDocProviderTest.php} | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) rename src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/{AccompanyingProviderCourseDocumentGenericDoc.php => AccompanyingCourseDocumentGenericDocProvider.php} (95%) rename src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/Providers/{AccompanyingCourseDocumentProviderTest.php => AccompanyingCourseDocumentGenericDocProviderTest.php} (90%) diff --git a/src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/AccompanyingProviderCourseDocumentGenericDoc.php b/src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/AccompanyingCourseDocumentGenericDocProvider.php similarity index 95% rename from src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/AccompanyingProviderCourseDocumentGenericDoc.php rename to src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/AccompanyingCourseDocumentGenericDocProvider.php index 970ce646d..439f6a511 100644 --- a/src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/AccompanyingProviderCourseDocumentGenericDoc.php +++ b/src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/AccompanyingCourseDocumentGenericDocProvider.php @@ -21,7 +21,7 @@ use Doctrine\DBAL\Types\Types; use Doctrine\ORM\EntityManagerInterface; use Symfony\Component\Security\Core\Security; -final readonly class AccompanyingProviderCourseDocumentGenericDoc implements GenericDocForAccompanyingPeriodProviderInterface +final readonly class AccompanyingCourseDocumentGenericDocProvider implements GenericDocForAccompanyingPeriodProviderInterface { public const KEY = 'accompanying_course_document'; diff --git a/src/Bundle/ChillDocStoreBundle/GenericDoc/Renderer/AccompanyingCourseDocumentGenericDocRenderer.php b/src/Bundle/ChillDocStoreBundle/GenericDoc/Renderer/AccompanyingCourseDocumentGenericDocRenderer.php index a533b577a..ffa158aca 100644 --- a/src/Bundle/ChillDocStoreBundle/GenericDoc/Renderer/AccompanyingCourseDocumentGenericDocRenderer.php +++ b/src/Bundle/ChillDocStoreBundle/GenericDoc/Renderer/AccompanyingCourseDocumentGenericDocRenderer.php @@ -14,7 +14,7 @@ namespace Chill\DocStoreBundle\GenericDoc\Renderer; use Chill\DocStoreBundle\GenericDoc\GenericDocDTO; use Chill\DocStoreBundle\GenericDoc\Providers\PersonDocumentGenericDocProvider; use Chill\DocStoreBundle\GenericDoc\Twig\GenericDocRendererInterface; -use Chill\DocStoreBundle\GenericDoc\Providers\AccompanyingProviderCourseDocumentGenericDoc; +use Chill\DocStoreBundle\GenericDoc\Providers\AccompanyingCourseDocumentGenericDocProvider; use Chill\DocStoreBundle\Repository\AccompanyingCourseDocumentRepository; use Chill\DocStoreBundle\Repository\PersonDocumentRepository; use Chill\PersonBundle\Entity\AccompanyingPeriod; @@ -29,7 +29,7 @@ final readonly class AccompanyingCourseDocumentGenericDocRenderer implements Gen public function supports(GenericDocDTO $genericDocDTO, $options = []): bool { - return $genericDocDTO->key === AccompanyingProviderCourseDocumentGenericDoc::KEY + return $genericDocDTO->key === AccompanyingCourseDocumentGenericDocProvider::KEY || $genericDocDTO->key === PersonDocumentGenericDocProvider::KEY; } diff --git a/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/Providers/AccompanyingCourseDocumentProviderTest.php b/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/Providers/AccompanyingCourseDocumentGenericDocProviderTest.php similarity index 90% rename from src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/Providers/AccompanyingCourseDocumentProviderTest.php rename to src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/Providers/AccompanyingCourseDocumentGenericDocProviderTest.php index 8c6bd524d..79ced9258 100644 --- a/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/Providers/AccompanyingCourseDocumentProviderTest.php +++ b/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/Providers/AccompanyingCourseDocumentGenericDocProviderTest.php @@ -12,7 +12,7 @@ declare(strict_types=1); namespace Chill\DocStoreBundle\Tests\GenericDoc\Providers; use Chill\DocStoreBundle\GenericDoc\FetchQueryToSqlBuilder; -use Chill\DocStoreBundle\GenericDoc\Providers\AccompanyingProviderCourseDocumentGenericDoc; +use Chill\DocStoreBundle\GenericDoc\Providers\AccompanyingCourseDocumentGenericDocProvider; use Chill\DocStoreBundle\Security\Authorization\AccompanyingCourseDocumentVoter; use Chill\PersonBundle\Entity\AccompanyingPeriod; use Doctrine\DBAL\Types\Types; @@ -25,7 +25,7 @@ use Symfony\Component\Security\Core\Security; * @internal * @coversNothing */ -class AccompanyingCourseDocumentProviderTest extends KernelTestCase +class AccompanyingCourseDocumentGenericDocProviderTest extends KernelTestCase { use ProphecyTrait; private EntityManagerInterface $entityManager; @@ -54,7 +54,7 @@ class AccompanyingCourseDocumentProviderTest extends KernelTestCase $security->isGranted(AccompanyingCourseDocumentVoter::SEE, $period) ->willReturn(true); - $provider = new AccompanyingProviderCourseDocumentGenericDoc( + $provider = new AccompanyingCourseDocumentGenericDocProvider( $security->reveal(), $this->entityManager ); From 2b57807565a335e6d81a761bd11d490cc9fa7de0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 30 May 2023 22:14:13 +0200 Subject: [PATCH 103/321] show generic doc accompanying course document in person generic doc list --- ...anyingCourseDocumentGenericDocProvider.php | 75 +++++++++++++++++-- ...anyingCourseDocumentGenericDocRenderer.php | 10 +-- 2 files changed, 73 insertions(+), 12 deletions(-) diff --git a/src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/AccompanyingCourseDocumentGenericDocProvider.php b/src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/AccompanyingCourseDocumentGenericDocProvider.php index 439f6a511..054e6a6d8 100644 --- a/src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/AccompanyingCourseDocumentGenericDocProvider.php +++ b/src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/AccompanyingCourseDocumentGenericDocProvider.php @@ -15,13 +15,17 @@ use Chill\DocStoreBundle\Entity\AccompanyingCourseDocument; use Chill\DocStoreBundle\GenericDoc\FetchQuery; use Chill\DocStoreBundle\GenericDoc\FetchQueryInterface; use Chill\DocStoreBundle\GenericDoc\GenericDocForAccompanyingPeriodProviderInterface; +use Chill\DocStoreBundle\GenericDoc\GenericDocForPersonProviderInterface; use Chill\DocStoreBundle\Security\Authorization\AccompanyingCourseDocumentVoter; use Chill\PersonBundle\Entity\AccompanyingPeriod; +use Chill\PersonBundle\Entity\Person; +use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter; +use DateTimeImmutable; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\EntityManagerInterface; use Symfony\Component\Security\Core\Security; -final readonly class AccompanyingCourseDocumentGenericDocProvider implements GenericDocForAccompanyingPeriodProviderInterface +final readonly class AccompanyingCourseDocumentGenericDocProvider implements GenericDocForAccompanyingPeriodProviderInterface, GenericDocForPersonProviderInterface { public const KEY = 'accompanying_course_document'; @@ -38,7 +42,7 @@ final readonly class AccompanyingCourseDocumentGenericDocProvider implements Gen $query = new FetchQuery( self::KEY, sprintf('jsonb_build_object(\'id\', %s)', $classMetadata->getIdentifierColumnNames()[0]), - sprintf($classMetadata->getColumnName('date')), + $classMetadata->getColumnName('date'), $classMetadata->getSchemaName() . '.' . $classMetadata->getTableName() ); @@ -48,6 +52,67 @@ final readonly class AccompanyingCourseDocumentGenericDocProvider implements Gen [Types::INTEGER] ); + return $this->addWhereClause($query, $startDate, $endDate, $content); + } + + public function isAllowedForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod): bool + { + return $this->security->isGranted(AccompanyingCourseDocumentVoter::SEE, $accompanyingPeriod); + } + + public function buildFetchQueryForPerson(Person $person, ?DateTimeImmutable $startDate = null, ?DateTimeImmutable $endDate = null, ?string $content = null, ?string $origin = null): FetchQueryInterface + { + $classMetadata = $this->entityManager->getClassMetadata(AccompanyingCourseDocument::class); + + $query = new FetchQuery( + self::KEY, + sprintf('jsonb_build_object(\'id\', %s)', $classMetadata->getIdentifierColumnNames()[0]), + $classMetadata->getColumnName('date'), + $classMetadata->getSchemaName() . '.' . $classMetadata->getTableName() . ' AS acc_course_document' + ); + + $atLeastOne = false; + $or = []; + $orParams = []; + $orTypes = []; + + foreach ($person->getAccompanyingPeriodParticipations() as $participation) { + if (!$this->security->isGranted(AccompanyingCourseDocumentVoter::SEE, $participation->getAccompanyingPeriod())) { + continue; + } + + $atLeastOne = true; + + $or[] = sprintf( + "(acc_course_document.%s = ? AND acc_course_document.%s BETWEEN ? AND COALESCE(?, 'infinity'::date))", + $classMetadata->getSingleAssociationJoinColumnName('course'), + $classMetadata->getColumnName('date') + ); + $orParams = [...$orParams, $participation->getAccompanyingPeriod()->getId(), $participation->getStartDate(), $participation->getEndDate()]; + $orTypes = [...$orTypes, Types::INTEGER, Types::DATE_MUTABLE, Types::DATE_MUTABLE]; + } + + if (!$atLeastOne) { + // there aren't any period allowed to be seen. Add an unreachable condition + $query->addWhereClause('TRUE = FALSE'); + + return $query; + } + + $query->addWhereClause(implode(' OR ', $or), $orParams, $orTypes); + + return $this->addWhereClause($query, $startDate, $endDate, $content); + } + + public function isAllowedForPerson(Person $person): bool + { + return $this->security->isGranted(AccompanyingPeriodVoter::SEE, $person); + } + + private function addWhereClause(FetchQuery $query, ?\DateTimeImmutable $startDate = null, ?\DateTimeImmutable $endDate = null, ?string $content = null): FetchQuery + { + $classMetadata = $this->entityManager->getClassMetadata(AccompanyingCourseDocument::class); + if (null !== $startDate) { $query->addWhereClause( sprintf('? <= %s', $classMetadata->getColumnName('date')), @@ -64,7 +129,7 @@ final readonly class AccompanyingCourseDocumentGenericDocProvider implements Gen ); } - if (null !== $content) { + if (null !== $content and '' !== $content) { $query->addWhereClause( sprintf( '(%s ilike ? OR %s ilike ?)', @@ -79,8 +144,4 @@ final readonly class AccompanyingCourseDocumentGenericDocProvider implements Gen return $query; } - public function isAllowedForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod): bool - { - return $this->security->isGranted(AccompanyingCourseDocumentVoter::SEE, $accompanyingPeriod); - } } diff --git a/src/Bundle/ChillDocStoreBundle/GenericDoc/Renderer/AccompanyingCourseDocumentGenericDocRenderer.php b/src/Bundle/ChillDocStoreBundle/GenericDoc/Renderer/AccompanyingCourseDocumentGenericDocRenderer.php index ffa158aca..052153be8 100644 --- a/src/Bundle/ChillDocStoreBundle/GenericDoc/Renderer/AccompanyingCourseDocumentGenericDocRenderer.php +++ b/src/Bundle/ChillDocStoreBundle/GenericDoc/Renderer/AccompanyingCourseDocumentGenericDocRenderer.php @@ -40,18 +40,18 @@ final readonly class AccompanyingCourseDocumentGenericDocRenderer implements Gen public function getTemplateData(GenericDocDTO $genericDocDTO, $options = []): array { - if ($genericDocDTO->linked instanceof AccompanyingPeriod) { + if (AccompanyingCourseDocumentGenericDocProvider::KEY === $genericDocDTO->key) { return [ - 'document' => $this->accompanyingCourseDocumentRepository->find($genericDocDTO->identifiers['id']), - 'accompanyingCourse' => $genericDocDTO->linked, + 'document' => $doc = $this->accompanyingCourseDocumentRepository->find($genericDocDTO->identifiers['id']), + 'accompanyingCourse' => $doc->getCourse(), 'options' => $options, ]; } // this is a person return [ - 'document' => $this->personDocumentRepository->find($genericDocDTO->identifiers['id']), - 'person' => $genericDocDTO->linked, + 'document' => $doc = $this->personDocumentRepository->find($genericDocDTO->identifiers['id']), + 'person' => $doc->getPerson(), 'options' => $options, ]; } From ed556d9ee8dd52bd6d076fee7e26b9818b2f3f0e Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Wed, 31 May 2023 09:47:48 +0200 Subject: [PATCH 104/321] FIX [review] process review and make minor visual changes --- .../public/vuejs/AccompanyingCourseWorkEdit/App.vue | 12 ++++++------ .../components/AddEvaluation.vue | 7 ++----- .../components/FormEvaluation.vue | 12 +++++++----- 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/App.vue b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/App.vue index adbcf1097..1c9c2fd6d 100644 --- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/App.vue +++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/App.vue @@ -123,7 +123,7 @@ v-for="e in pickedEvaluations" v-bind:key="e.key" v-bind:evaluation="e" - v-bind:docId="this.docId"> + v-bind:docAnchorId="this.docAnchorId"> @@ -390,7 +390,7 @@ export default { i18n, data() { return { - docId: null, + docAnchorId: null, isExpanded: false, editor: ClassicEditor, showAddObjective: false, @@ -432,10 +432,10 @@ export default { }, beforeMount() { const urlParams = new URLSearchParams(window.location.search); - this.docId = urlParams.get('doc_id'); + this.docAnchorId = urlParams.get('doc_id'); }, mounted() { - this.scrollToElement(this.docId); + this.scrollToElement(this.docAnchorId); }, computed: { ...mapState([ @@ -591,8 +591,8 @@ export default { } }) }, - scrollToElement(docId) { - const documentEl = document.getElementById(`document_${docId}`); + scrollToElement(docAnchorId) { + const documentEl = document.getElementById(`document_${docAnchorId}`); if (documentEl) { documentEl.scrollIntoView({behavior: 'smooth'}); } diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/components/AddEvaluation.vue b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/components/AddEvaluation.vue index 215c5d6cc..baa3fa798 100644 --- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/components/AddEvaluation.vue +++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/components/AddEvaluation.vue @@ -11,7 +11,7 @@
        - +
        • @@ -85,7 +85,7 @@ export default { Modal, ListWorkflowModal, }, - props: ['evaluation', 'docId'], + props: ['evaluation', 'docAnchorId'], i18n, data() { return { @@ -95,9 +95,6 @@ export default { } }; }, -/* mounted() { - console.log('docId is here', this.docId) - },*/ computed: { pickedEvaluations() { return this.$store.state.evaluationsPicked; diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/components/FormEvaluation.vue b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/components/FormEvaluation.vue index ff7597dec..10bac43b3 100644 --- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/components/FormEvaluation.vue +++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/components/FormEvaluation.vue @@ -80,12 +80,13 @@
          -
          +
          From cb718a80dece206e020c4cac7e86aa2e0b735172 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 31 May 2023 12:23:34 +0200 Subject: [PATCH 105/321] Add accompanying period work evaluation documents to the list of documents for person --- ...anyingCourseDocumentGenericDocProvider.php | 2 +- ...PeriodWorkEvaluationGenericDocProvider.php | 136 +++++++++++++----- 2 files changed, 99 insertions(+), 39 deletions(-) diff --git a/src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/AccompanyingCourseDocumentGenericDocProvider.php b/src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/AccompanyingCourseDocumentGenericDocProvider.php index 054e6a6d8..fd36f7976 100644 --- a/src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/AccompanyingCourseDocumentGenericDocProvider.php +++ b/src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/AccompanyingCourseDocumentGenericDocProvider.php @@ -99,7 +99,7 @@ final readonly class AccompanyingCourseDocumentGenericDocProvider implements Gen return $query; } - $query->addWhereClause(implode(' OR ', $or), $orParams, $orTypes); + $query->addWhereClause('(' . implode(' OR ', $or) . ')', $orParams, $orTypes); return $this->addWhereClause($query, $startDate, $endDate, $content); } diff --git a/src/Bundle/ChillPersonBundle/Service/GenericDoc/Providers/AccompanyingPeriodWorkEvaluationGenericDocProvider.php b/src/Bundle/ChillPersonBundle/Service/GenericDoc/Providers/AccompanyingPeriodWorkEvaluationGenericDocProvider.php index 883836547..f8b99a048 100644 --- a/src/Bundle/ChillPersonBundle/Service/GenericDoc/Providers/AccompanyingPeriodWorkEvaluationGenericDocProvider.php +++ b/src/Bundle/ChillPersonBundle/Service/GenericDoc/Providers/AccompanyingPeriodWorkEvaluationGenericDocProvider.php @@ -15,13 +15,16 @@ use Chill\DocStoreBundle\Entity\StoredObject; use Chill\DocStoreBundle\GenericDoc\FetchQuery; use Chill\DocStoreBundle\GenericDoc\FetchQueryInterface; use Chill\DocStoreBundle\GenericDoc\GenericDocForAccompanyingPeriodProviderInterface; +use Chill\DocStoreBundle\GenericDoc\GenericDocForPersonProviderInterface; use Chill\PersonBundle\Entity\AccompanyingPeriod; +use Chill\PersonBundle\Entity\Person; use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodWorkVoter; +use DateTimeImmutable; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\EntityManagerInterface; use Symfony\Component\Security\Core\Security; -final readonly class AccompanyingPeriodWorkEvaluationGenericDocProvider implements GenericDocForAccompanyingPeriodProviderInterface +final readonly class AccompanyingPeriodWorkEvaluationGenericDocProvider implements GenericDocForAccompanyingPeriodProviderInterface, GenericDocForPersonProviderInterface { public const KEY = 'accompanying_period_work_evaluation_document'; @@ -32,6 +35,100 @@ final readonly class AccompanyingPeriodWorkEvaluationGenericDocProvider implemen } public function buildFetchQueryForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod, ?\DateTimeImmutable $startDate = null, ?\DateTimeImmutable $endDate = null, ?string $content = null, ?string $origin = null): FetchQueryInterface + { + $accompanyingPeriodWorkMetadata = $this->entityManager->getClassMetadata(AccompanyingPeriod\AccompanyingPeriodWork::class); + $query = $this->buildBaseQuery(); + + $query->addWhereClause( + sprintf('action.%s = ?', $accompanyingPeriodWorkMetadata->getAssociationMapping('accompanyingPeriod')['joinColumns'][0]['name']), + [$accompanyingPeriod->getId()], + [Types::INTEGER] + ); + + return $this->addWhereClausesToQuery($query, $startDate, $endDate, $content); + } + + public function isAllowedForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod): bool + { + return $this->security->isGranted(AccompanyingPeriodWorkVoter::SEE, $accompanyingPeriod); + } + + private function addWhereClausesToQuery(FetchQuery $query, ?\DateTimeImmutable $startDate = null, ?\DateTimeImmutable $endDate = null, ?string $content = null): FetchQuery + { + $classMetadata = $this->entityManager->getClassMetadata(AccompanyingPeriod\AccompanyingPeriodWorkEvaluationDocument::class); + $storedObjectMetadata = $this->entityManager->getClassMetadata(StoredObject::class); + + if (null !== $startDate) { + $query->addWhereClause( + sprintf('doc_store.%s >= ?', $storedObjectMetadata->getColumnName('createdAt')), + [$startDate], + [Types::DATE_IMMUTABLE] + ); + } + + if (null !== $endDate) { + $query->addWhereClause( + sprintf('doc_store.%s < ?', $storedObjectMetadata->getColumnName('createdAt')), + [$endDate], + [Types::DATE_IMMUTABLE] + ); + } + + if (null !== $content) { + $query->addWhereClause( + sprintf('apwed.%s ilike ?', $classMetadata->getColumnName('title')), + ['%' . $content . '%'], + [Types::STRING] + ); + } + + return $query; + } + + public function buildFetchQueryForPerson(Person $person, ?DateTimeImmutable $startDate = null, ?DateTimeImmutable $endDate = null, ?string $content = null, ?string $origin = null): FetchQueryInterface + { + $storedObjectMetadata = $this->entityManager->getClassMetadata(StoredObject::class); + $accompanyingPeriodWorkMetadata = $this->entityManager->getClassMetadata(AccompanyingPeriod\AccompanyingPeriodWork::class); + $query = $this->buildBaseQuery(); + + // we loop over each accompanying period participation, to check of the user is allowed to see them + $or = []; + $orParams = []; + $orTypes = []; + foreach ($person->getAccompanyingPeriodParticipations() as $participation) { + if (!$this->security->isGranted(AccompanyingPeriodWorkVoter::SEE, $participation->getAccompanyingPeriod())) { + continue; + } + + $or[] = sprintf( + '(action.%s = ? AND apwed.%s BETWEEN ?::date AND COALESCE(?::date, \'infinity\'::date))', + $accompanyingPeriodWorkMetadata->getSingleAssociationJoinColumnName('accompanyingPeriod'), + $storedObjectMetadata->getColumnName('createdAt') + ); + $orParams = [...$orParams, $participation->getAccompanyingPeriod()->getId(), + DateTimeImmutable::createFromInterface($participation->getStartDate()), + null === $participation->getEndDate() ? null : DateTimeImmutable::createFromInterface($participation->getEndDate())]; + $orTypes = [...$orTypes, Types::INTEGER, Types::DATE_IMMUTABLE, Types::DATE_IMMUTABLE]; + } + + if ([] === $or) { + $query->addWhereClause('TRUE = FALSE'); + + return $query; + } + + $query->addWhereClause(sprintf('(%s)', implode(' OR ', $or)), $orParams, $orTypes); + + return $this->addWhereClausesToQuery($query, $startDate, $endDate, $content); + } + + public function isAllowedForPerson(Person $person): bool + { + // this will be filtered during query + return true; + } + + private function buildBaseQuery(): FetchQuery { $classMetadata = $this->entityManager->getClassMetadata(AccompanyingPeriod\AccompanyingPeriodWorkEvaluationDocument::class); $storedObjectMetadata = $this->entityManager->getClassMetadata(StoredObject::class); @@ -63,43 +160,6 @@ final readonly class AccompanyingPeriodWorkEvaluationGenericDocProvider implemen $accompanyingPeriodWorkMetadata->getColumnName('id') )); - $query->addWhereClause( - sprintf('action.%s = ?', $accompanyingPeriodWorkMetadata->getAssociationMapping('accompanyingPeriod')['joinColumns'][0]['name']), - [$accompanyingPeriod->getId()], - [Types::INTEGER] - ); - - if (null !== $startDate) { - $query->addWhereClause( - sprintf('doc_store.%s >= ?', $storedObjectMetadata->getColumnName('createdAt')), - [$startDate], - [Types::DATE_IMMUTABLE] - ); - } - - if (null !== $endDate) { - $query->addWhereClause( - sprintf('doc_store.%s < ?', $storedObjectMetadata->getColumnName('createdAt')), - [$endDate], - [Types::DATE_IMMUTABLE] - ); - } - - if (null !== $content) { - $query->addWhereClause( - sprintf('apwed.%s ilike ?', $classMetadata->getColumnName('title')), - ['%' . $content . '%'], - [Types::STRING] - ); - } - return $query; } - - public function isAllowedForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod): bool - { - return $this->security->isGranted(AccompanyingPeriodWorkVoter::SEE, $accompanyingPeriod); - } - - } From 4489098addd0d202a84d999d43c37d4494a421bf Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Wed, 31 May 2023 14:20:54 +0200 Subject: [PATCH 106/321] FIX [calculator] type cast result to a float --- src/Bundle/ChillBudgetBundle/Calculator/CalculatorResult.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Bundle/ChillBudgetBundle/Calculator/CalculatorResult.php b/src/Bundle/ChillBudgetBundle/Calculator/CalculatorResult.php index 380e641a6..2a67486f0 100644 --- a/src/Bundle/ChillBudgetBundle/Calculator/CalculatorResult.php +++ b/src/Bundle/ChillBudgetBundle/Calculator/CalculatorResult.php @@ -21,7 +21,7 @@ class CalculatorResult public $label; - public $result; + public float $result; public $type; } From 20489813f068c6147976ee1e6ed50b1b5dc2c66c Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Tue, 30 May 2023 14:38:16 +0200 Subject: [PATCH 107/321] FIX [route] adjust to using new route name in redirect --- .../Controller/DocumentAccompanyingCourseController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Bundle/ChillDocStoreBundle/Controller/DocumentAccompanyingCourseController.php b/src/Bundle/ChillDocStoreBundle/Controller/DocumentAccompanyingCourseController.php index 8762050aa..384eeb510 100644 --- a/src/Bundle/ChillDocStoreBundle/Controller/DocumentAccompanyingCourseController.php +++ b/src/Bundle/ChillDocStoreBundle/Controller/DocumentAccompanyingCourseController.php @@ -160,7 +160,7 @@ class DocumentAccompanyingCourseController extends AbstractController $this->addFlash('success', $this->translator->trans('The document is successfully registered')); - return $this->redirectToRoute('accompanying_course_document_index', ['course' => $course->getId()]); + return $this->redirectToRoute('chill_docstore_generic-doc_by-period_index', ['id' => $course->getId()]); } if ($form->isSubmitted() && !$form->isValid()) { From 47a3e30ec532e6cf27ba00e049a2e90c6ea7bd9b Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Tue, 30 May 2023 16:56:20 +0200 Subject: [PATCH 108/321] FEATURE [genericDoc] generic doc interface implemented for rendez-vous --- .../GenericDoc/calendar_document.html.twig | 72 +++++++++++++ ...anyingPeriodCalendarGenericDocProvider.php | 101 ++++++++++++++++++ ...anyingPeriodCalendarGenericDocRenderer.php | 44 ++++++++ .../translations/messages.fr.yml | 2 + .../translations/messages.fr.yml | 1 + 5 files changed, 220 insertions(+) create mode 100644 src/Bundle/ChillCalendarBundle/Resources/views/GenericDoc/calendar_document.html.twig create mode 100644 src/Bundle/ChillCalendarBundle/Service/GenericDoc/Providers/AccompanyingPeriodCalendarGenericDocProvider.php create mode 100644 src/Bundle/ChillCalendarBundle/Service/GenericDoc/Renderers/AccompanyingPeriodCalendarGenericDocRenderer.php diff --git a/src/Bundle/ChillCalendarBundle/Resources/views/GenericDoc/calendar_document.html.twig b/src/Bundle/ChillCalendarBundle/Resources/views/GenericDoc/calendar_document.html.twig new file mode 100644 index 000000000..712b362f5 --- /dev/null +++ b/src/Bundle/ChillCalendarBundle/Resources/views/GenericDoc/calendar_document.html.twig @@ -0,0 +1,72 @@ +{% import "@ChillDocStore/Macro/macro.html.twig" as m %} +{% import "@ChillDocStore/Macro/macro_mimeicon.html.twig" as mm %} +{% import '@ChillPerson/Macro/updatedBy.html.twig' as mmm %} + +{% set c = document.calendar %} + +
          +
          +
          + {% if document.storedObject.isPending %} +
          {{ 'docgen.Doc generation is pending'|trans }}
          + {% elseif document.storedObject.isFailure %} +
          {{ 'docgen.Doc generation failed'|trans }}
          + {% endif %} +
          + {{ document.storedObject.title }} +
          +
          + {{ 'chill_calendar.Document'|trans }} +
          + {% if document.storedObject.hasTemplate %} +
          +

          {{ document.storedObject.template.name|localize_translatable_string }}

          +
          + {% endif %} +
          + +
          +
          +
          + {{ document.storedObject.createdAt|format_date('short') }} +
          +
          +
          +
          + +
          +
          +

          + {% if c.endDate.diff(c.startDate).days >= 1 %} + {{ c.startDate|format_datetime('short', 'short') }} + - {{ c.endDate|format_datetime('short', 'short') }} + {% else %} + {{ c.startDate|format_datetime('short', 'short') }} + - {{ c.endDate|format_datetime('none', 'short') }} + {% endif %} +

          +
          +
          + +
          +
          + {{ mmm.createdBy(document) }} +
          +
            +
          • + {{ chill_entity_workflow_list('Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluationDocument', document.id) }} +
          • + {% if is_granted('CHILL_CALENDAR_DOC_SEE', document) %} +
          • + {{ document.storedObject|chill_document_button_group(document.storedObject.title, is_granted('CHILL_CALENDAR_CALENDAR_EDIT', c)) }} +
          • + {% endif %} + {% if is_granted('CHILL_CALENDAR_CALENDAR_EDIT', c) %} +
          • + +
          • + {% endif %} +
          + +
          +
          diff --git a/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Providers/AccompanyingPeriodCalendarGenericDocProvider.php b/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Providers/AccompanyingPeriodCalendarGenericDocProvider.php new file mode 100644 index 000000000..ff2cdbcf5 --- /dev/null +++ b/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Providers/AccompanyingPeriodCalendarGenericDocProvider.php @@ -0,0 +1,101 @@ +security = $security; + $this->em = $entityManager; + } + + public function buildFetchQueryForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod, ?\DateTimeImmutable $startDate = null, ?\DateTimeImmutable $endDate = null, ?string $content = null, ?string $origin = null): FetchQueryInterface + { + $classMetadata = $this->em->getClassMetadata(CalendarDoc::class); + $storedObjectMetadata = $this->em->getClassMetadata(StoredObject::class); + $calendarMetadata = $this->em->getClassMetadata(Calendar::class); + + $query = new FetchQuery( + self::KEY, + sprintf("jsonb_build_object('id', cd.%s)", $classMetadata->getColumnName('id')), + 'cd.'.$storedObjectMetadata->getColumnName('createdAt'), + $classMetadata->getSchemaName().'.'.$classMetadata->getTableName().' AS cd' + ); + $query->addJoinClause( + 'JOIN chill_doc.stored_object doc_store ON doc_store.id = cd.storedobject_id' + ); + + $query->addJoinClause( + 'JOIN chill_calendar.calendar calendar ON calendar.id = cd.calendar_id' + ); + + $query->addWhereClause( + 'calendar.accompanyingperiod_id = ?', + [$accompanyingPeriod->getId()], + [Types::INTEGER] + ); + + if (null !== $startDate) { + $query->addWhereClause( + sprintf('doc_store.%s >= ?', $storedObjectMetadata->getColumnName('createdAt')), + [$startDate], + [Types::DATE_IMMUTABLE] + ); + } + + if (null !== $endDate) { + $query->addWhereClause( + sprintf('doc_store.%s < ?', $storedObjectMetadata->getColumnName('createdAt')), + [$endDate], + [Types::DATE_IMMUTABLE] + ); + } + + if (null !== $content) { + $query->addWhereClause( + 'doc_store.title ilike ?', + ['%' . $content . '%'], + [Types::STRING] + ); + } + + return $query; + } + + public function isAllowedForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod): bool + { + return $this->security->isGranted(CalendarVoter::SEE, $accompanyingPeriod); + } + + +} diff --git a/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Renderers/AccompanyingPeriodCalendarGenericDocRenderer.php b/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Renderers/AccompanyingPeriodCalendarGenericDocRenderer.php new file mode 100644 index 000000000..0f680797c --- /dev/null +++ b/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Renderers/AccompanyingPeriodCalendarGenericDocRenderer.php @@ -0,0 +1,44 @@ +repository = $calendarDocRepository; + } + + public function supports(GenericDocDTO $genericDocDTO, $options = []): bool + { + return $genericDocDTO->key === AccompanyingPeriodCalendarGenericDocProvider::KEY; + } + + public function getTemplate(GenericDocDTO $genericDocDTO, $options = []): string + { + return '@ChillCalendar/GenericDoc/calendar_document.html.twig'; + } + + public function getTemplateData(GenericDocDTO $genericDocDTO, $options = []): array + { + return [ + 'document' => $this->repository->find($genericDocDTO->identifiers['id']) + ]; + } +} diff --git a/src/Bundle/ChillCalendarBundle/translations/messages.fr.yml b/src/Bundle/ChillCalendarBundle/translations/messages.fr.yml index eb02be280..5e1fc971a 100644 --- a/src/Bundle/ChillCalendarBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillCalendarBundle/translations/messages.fr.yml @@ -43,6 +43,7 @@ crud: title_edit: Modifier le motif d'annulation chill_calendar: + Document: Document d'un rendez-vous form: The main user is mandatory. He will organize the appointment.: L'utilisateur principal est obligatoire. Il est l'organisateur de l'événement. Create for referrer: Créer pour le référent @@ -65,6 +66,7 @@ chill_calendar: Document outdated: La date et l'heure du rendez-vous ont été modifiés après la création du document + remote_ms_graph: freebusy_statuses: busy: Occupé diff --git a/src/Bundle/ChillDocStoreBundle/translations/messages.fr.yml b/src/Bundle/ChillDocStoreBundle/translations/messages.fr.yml index 1dde57eee..4fa41f180 100644 --- a/src/Bundle/ChillDocStoreBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillDocStoreBundle/translations/messages.fr.yml @@ -26,6 +26,7 @@ generic_doc: filter: keys: accompanying_course_document: Document du parcours + accompanying_period_calendar_document: Document des rendez-vous date-range: Date du document # delete From 9eb9a9a214d9801fa5fa87ae10449b1068a16576 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Tue, 30 May 2023 16:59:16 +0200 Subject: [PATCH 109/321] WIP [genericDoc][activity] implementing generic doc for activities --- ...anyingPeriodActivityGenericDocProvider.php | 110 ++++++++++++++++++ ...anyingPeriodActivityGenericDocRenderer.php | 45 +++++++ 2 files changed, 155 insertions(+) create mode 100644 src/Bundle/ChillActivityBundle/Service/GenericDoc/Providers/AccompanyingPeriodActivityGenericDocProvider.php create mode 100644 src/Bundle/ChillActivityBundle/Service/GenericDoc/Renderers/AccompanyingPeriodActivityGenericDocRenderer.php diff --git a/src/Bundle/ChillActivityBundle/Service/GenericDoc/Providers/AccompanyingPeriodActivityGenericDocProvider.php b/src/Bundle/ChillActivityBundle/Service/GenericDoc/Providers/AccompanyingPeriodActivityGenericDocProvider.php new file mode 100644 index 000000000..fc7484edf --- /dev/null +++ b/src/Bundle/ChillActivityBundle/Service/GenericDoc/Providers/AccompanyingPeriodActivityGenericDocProvider.php @@ -0,0 +1,110 @@ +em = $entityManager; + $this->security = $security; + } + + /** + * @param AccompanyingPeriod $accompanyingPeriod + * @param DateTimeImmutable|null $startDate + * @param DateTimeImmutable|null $endDate + * @param string|null $content + * @param string|null $origin + * @return FetchQueryInterface + * @throws MappingException + */ + public function buildFetchQueryForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod, ?DateTimeImmutable $startDate = null, ?DateTimeImmutable $endDate = null, ?string $content = null, ?string $origin = null): FetchQueryInterface + { + $storedObjectMetadata = $this->em->getClassMetadata(StoredObject::class); +// $activityMetadata = $this->em->getClassMetadata(Activity::class); + + $query = new FetchQuery( + self::KEY, + "jsonb_build_object('id', doc_obj.id)", + 'doc_obj.'.$storedObjectMetadata->getColumnName('createdAt'), + $storedObjectMetadata->getSchemaName().'.'.$storedObjectMetadata->getTableName().' AS doc_obj' + ); + + $query->addJoinClause( + 'JOIN public.activity_storedobject activity_doc ON activity_doc.storedobject_id = doc_obj.id' + ); + + $query->addJoinClause( + 'JOIN public.activity activity ON activity.id = activity_doc.activity_id' + ); + + $query->addWhereClause( + 'activity.accompanyingperiod_id = ?', + [$accompanyingPeriod->getId()], + [Types::INTEGER] + ); + + if (null !== $startDate) { + $query->addWhereClause( + sprintf('doc_obj.%s >= ?', $storedObjectMetadata->getColumnName('createdAt')), + [$startDate], + [Types::DATE_IMMUTABLE] + ); + } + + if (null !== $endDate) { + $query->addWhereClause( + sprintf('doc_obj.%s < ?', $storedObjectMetadata->getColumnName('createdAt')), + [$endDate], + [Types::DATE_IMMUTABLE] + ); + } + + if (null !== $content) { + $query->addWhereClause( + 'doc_obj.title ilike ?', + ['%' . $content . '%'], + [Types::STRING] + ); + } + + return $query; + } + + /** + * @param AccompanyingPeriod $accompanyingPeriod + * @return bool + */ + public function isAllowedForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod): bool + { + return $this->security->isGranted(ActivityVoter::SEE, $accompanyingPeriod); + } +} diff --git a/src/Bundle/ChillActivityBundle/Service/GenericDoc/Renderers/AccompanyingPeriodActivityGenericDocRenderer.php b/src/Bundle/ChillActivityBundle/Service/GenericDoc/Renderers/AccompanyingPeriodActivityGenericDocRenderer.php new file mode 100644 index 000000000..eddcc6828 --- /dev/null +++ b/src/Bundle/ChillActivityBundle/Service/GenericDoc/Renderers/AccompanyingPeriodActivityGenericDocRenderer.php @@ -0,0 +1,45 @@ +repository = $storedObjectRepository; + } + + public function supports(GenericDocDTO $genericDocDTO, $options = []): bool + { + return $genericDocDTO->key === AccompanyingPeriodActivityGenericDocProvider::KEY; + } + + public function getTemplate(GenericDocDTO $genericDocDTO, $options = []): string + { + return '@ChillCalendar/GenericDoc/activity_document.html.twig'; + } + + public function getTemplateData(GenericDocDTO $genericDocDTO, $options = []): array + { + return [ + 'document' => $this->repository->find($genericDocDTO->identifiers['id']) + ]; + } +} + From 4155af6686cd173c8689b5d9bff52b3996963644 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Tue, 30 May 2023 17:50:32 +0200 Subject: [PATCH 110/321] FEATURE [genericDoc][calendar] use metadatas --- ...anyingPeriodCalendarGenericDocProvider.php | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Providers/AccompanyingPeriodCalendarGenericDocProvider.php b/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Providers/AccompanyingPeriodCalendarGenericDocProvider.php index ff2cdbcf5..e653cfc25 100644 --- a/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Providers/AccompanyingPeriodCalendarGenericDocProvider.php +++ b/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Providers/AccompanyingPeriodCalendarGenericDocProvider.php @@ -21,6 +21,7 @@ use Chill\DocStoreBundle\GenericDoc\GenericDocForAccompanyingPeriodProviderInter use Chill\PersonBundle\Entity\AccompanyingPeriod; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\EntityManagerInterface; +use Doctrine\ORM\Mapping\MappingException; use Symfony\Component\Security\Core\Security; final class AccompanyingPeriodCalendarGenericDocProvider implements GenericDocForAccompanyingPeriodProviderInterface @@ -39,6 +40,9 @@ final class AccompanyingPeriodCalendarGenericDocProvider implements GenericDocFo $this->em = $entityManager; } + /** + * @throws MappingException + */ public function buildFetchQueryForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod, ?\DateTimeImmutable $startDate = null, ?\DateTimeImmutable $endDate = null, ?string $content = null, ?string $origin = null): FetchQueryInterface { $classMetadata = $this->em->getClassMetadata(CalendarDoc::class); @@ -52,15 +56,23 @@ final class AccompanyingPeriodCalendarGenericDocProvider implements GenericDocFo $classMetadata->getSchemaName().'.'.$classMetadata->getTableName().' AS cd' ); $query->addJoinClause( - 'JOIN chill_doc.stored_object doc_store ON doc_store.id = cd.storedobject_id' - ); + sprintf('JOIN %s doc_store ON doc_store.%s = cd.%s', + $storedObjectMetadata->getSchemaName().'.'.$storedObjectMetadata->getTableName(), + $storedObjectMetadata->getColumnName('id'), + $classMetadata->getSingleAssociationJoinColumnName('storedObject') + )); $query->addJoinClause( - 'JOIN chill_calendar.calendar calendar ON calendar.id = cd.calendar_id' + sprintf('JOIN %s calendar ON calendar.%s = cd.%s', + $calendarMetadata->getSchemaName().'.'.$calendarMetadata->getTableName(), + $calendarMetadata->getColumnName('id'), + $classMetadata->getSingleAssociationJoinColumnName('calendar') + ) ); $query->addWhereClause( - 'calendar.accompanyingperiod_id = ?', + sprintf('calendar.%s = ?', + $calendarMetadata->getAssociationMapping('accompanyingPeriod')['joinColumns'][0]['name']), [$accompanyingPeriod->getId()], [Types::INTEGER] ); @@ -83,7 +95,7 @@ final class AccompanyingPeriodCalendarGenericDocProvider implements GenericDocFo if (null !== $content) { $query->addWhereClause( - 'doc_store.title ilike ?', + sprintf('doc_store.%s ilike ?', $storedObjectMetadata->getColumnName('title')), ['%' . $content . '%'], [Types::STRING] ); From c07e26785e5b73e810b50bb41be02d2ad424e01c Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Tue, 30 May 2023 18:14:32 +0200 Subject: [PATCH 111/321] WIP [genericDoc][activity] add repository method to get activity linked to storedObject --- .../Repository/ActivityRepository.php | 12 ++++ .../GenericDoc/activity_document.html.twig | 72 +++++++++++++++++++ ...anyingPeriodActivityGenericDocProvider.php | 3 +- ...anyingPeriodActivityGenericDocRenderer.php | 13 ++-- 4 files changed, 94 insertions(+), 6 deletions(-) create mode 100644 src/Bundle/ChillActivityBundle/Resources/views/GenericDoc/activity_document.html.twig diff --git a/src/Bundle/ChillActivityBundle/Repository/ActivityRepository.php b/src/Bundle/ChillActivityBundle/Repository/ActivityRepository.php index 5a6e16cd5..02658b03d 100644 --- a/src/Bundle/ChillActivityBundle/Repository/ActivityRepository.php +++ b/src/Bundle/ChillActivityBundle/Repository/ActivityRepository.php @@ -15,6 +15,7 @@ use Chill\ActivityBundle\Entity\Activity; use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\Person; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; +use Doctrine\ORM\Query\Expr; use Doctrine\Persistence\ManagerRegistry; /** @@ -97,4 +98,15 @@ class ActivityRepository extends ServiceEntityRepository return $qb->getQuery()->getResult(); } + + public function findOneByDocument(int $documentId): Activity + { + $qb = $this->createQueryBuilder('a'); + $qb->select('a'); + + $qb->innerJoin('a.documents', 'd', Expr\Join::WITH, 'd.storedobject_id = :documentId'); + $qb->setParameter('documentId', $documentId); + + return $qb->getQuery()->getResult(); + } } diff --git a/src/Bundle/ChillActivityBundle/Resources/views/GenericDoc/activity_document.html.twig b/src/Bundle/ChillActivityBundle/Resources/views/GenericDoc/activity_document.html.twig new file mode 100644 index 000000000..aeaea0872 --- /dev/null +++ b/src/Bundle/ChillActivityBundle/Resources/views/GenericDoc/activity_document.html.twig @@ -0,0 +1,72 @@ +{% import "@ChillDocStore/Macro/macro.html.twig" as m %} +{% import "@ChillDocStore/Macro/macro_mimeicon.html.twig" as mm %} +{% import '@ChillPerson/Macro/updatedBy.html.twig' as mmm %} + +{% set a = document.calendar %} + +
          +
          +
          + {% if document.storedObject.isPending %} +
          {{ 'docgen.Doc generation is pending'|trans }}
          + {% elseif document.storedObject.isFailure %} +
          {{ 'docgen.Doc generation failed'|trans }}
          + {% endif %} +
          + {{ document.storedObject.title }} +
          +
          + {{ 'chill_calendar.Document'|trans }} +
          + {% if document.storedObject.hasTemplate %} +
          +

          {{ document.storedObject.template.name|localize_translatable_string }}

          +
          + {% endif %} +
          + +
          +
          +
          + {{ document.storedObject.createdAt|format_date('short') }} +
          +
          +
          +
          + +
          +
          +

          + {% if c.endDate.diff(c.startDate).days >= 1 %} + {{ c.startDate|format_datetime('short', 'short') }} + - {{ c.endDate|format_datetime('short', 'short') }} + {% else %} + {{ c.startDate|format_datetime('short', 'short') }} + - {{ c.endDate|format_datetime('none', 'short') }} + {% endif %} +

          +
          +
          + +
          +
          + {{ mmm.createdBy(document) }} +
          +
            +
          • + {{ chill_entity_workflow_list('Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluationDocument', document.id) }} +
          • + {% if is_granted('CHILL_CALENDAR_DOC_SEE', document) %} +
          • + {{ document.storedObject|chill_document_button_group(document.storedObject.title, is_granted('CHILL_CALENDAR_CALENDAR_EDIT', c)) }} +
          • + {% endif %} + {% if is_granted('CHILL_CALENDAR_CALENDAR_EDIT', c) %} +
          • + +
          • + {% endif %} +
          + +
          +
          diff --git a/src/Bundle/ChillActivityBundle/Service/GenericDoc/Providers/AccompanyingPeriodActivityGenericDocProvider.php b/src/Bundle/ChillActivityBundle/Service/GenericDoc/Providers/AccompanyingPeriodActivityGenericDocProvider.php index fc7484edf..bf7a022f1 100644 --- a/src/Bundle/ChillActivityBundle/Service/GenericDoc/Providers/AccompanyingPeriodActivityGenericDocProvider.php +++ b/src/Bundle/ChillActivityBundle/Service/GenericDoc/Providers/AccompanyingPeriodActivityGenericDocProvider.php @@ -27,7 +27,7 @@ final class AccompanyingPeriodActivityGenericDocProvider implements GenericDocFo { public const KEY = 'accompanying_period_activity_document'; - private EntityManagerInterface $em; + private EntityManagerInterface $em; private Security $security; @@ -49,7 +49,6 @@ final class AccompanyingPeriodActivityGenericDocProvider implements GenericDocFo public function buildFetchQueryForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod, ?DateTimeImmutable $startDate = null, ?DateTimeImmutable $endDate = null, ?string $content = null, ?string $origin = null): FetchQueryInterface { $storedObjectMetadata = $this->em->getClassMetadata(StoredObject::class); -// $activityMetadata = $this->em->getClassMetadata(Activity::class); $query = new FetchQuery( self::KEY, diff --git a/src/Bundle/ChillActivityBundle/Service/GenericDoc/Renderers/AccompanyingPeriodActivityGenericDocRenderer.php b/src/Bundle/ChillActivityBundle/Service/GenericDoc/Renderers/AccompanyingPeriodActivityGenericDocRenderer.php index eddcc6828..f243fb941 100644 --- a/src/Bundle/ChillActivityBundle/Service/GenericDoc/Renderers/AccompanyingPeriodActivityGenericDocRenderer.php +++ b/src/Bundle/ChillActivityBundle/Service/GenericDoc/Renderers/AccompanyingPeriodActivityGenericDocRenderer.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Chill\ActivityBundle\Service\GenericDoc\Renderers; +use Chill\ActivityBundle\Repository\ActivityRepository; use Chill\ActivityBundle\Service\GenericDoc\Providers\AccompanyingPeriodActivityGenericDocProvider; use Chill\DocStoreBundle\GenericDoc\GenericDocDTO; use Chill\DocStoreBundle\GenericDoc\Twig\GenericDocRendererInterface; @@ -18,11 +19,14 @@ use Chill\DocStoreBundle\Repository\StoredObjectRepository; final class AccompanyingPeriodActivityGenericDocRenderer implements GenericDocRendererInterface { - private StoredObjectRepository $repository; + private StoredObjectRepository $objectRepository; - public function __construct(StoredObjectRepository $storedObjectRepository) + private ActivityRepository $activityRepository; + + public function __construct(StoredObjectRepository $storedObjectRepository, ActivityRepository $activityRepository) { - $this->repository = $storedObjectRepository; + $this->objectRepository = $storedObjectRepository; + $this->activityRepository = $activityRepository; } public function supports(GenericDocDTO $genericDocDTO, $options = []): bool @@ -38,7 +42,8 @@ final class AccompanyingPeriodActivityGenericDocRenderer implements GenericDocRe public function getTemplateData(GenericDocDTO $genericDocDTO, $options = []): array { return [ - 'document' => $this->repository->find($genericDocDTO->identifiers['id']) + 'activity' => $this->activityRepository->findOneByDocument($genericDocDTO->identifiers['id']), + 'document' => $this->objectRepository->find($genericDocDTO->identifiers['id']) ]; } } From ba55fa349baa108487af2b5eef9737196aa6c022 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Wed, 31 May 2023 16:53:38 +0200 Subject: [PATCH 112/321] FEATURE [genericDoc][activity] finalize implementation --- .../Repository/ActivityRepository.php | 11 ---- .../GenericDoc/activity_document.html.twig | 63 ++++++++++--------- ...anyingPeriodActivityGenericDocProvider.php | 23 ++----- ...anyingPeriodActivityGenericDocRenderer.php | 4 +- .../ChillActivityBundle/config/services.yaml | 3 + 5 files changed, 45 insertions(+), 59 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Repository/ActivityRepository.php b/src/Bundle/ChillActivityBundle/Repository/ActivityRepository.php index 02658b03d..a3bfb5942 100644 --- a/src/Bundle/ChillActivityBundle/Repository/ActivityRepository.php +++ b/src/Bundle/ChillActivityBundle/Repository/ActivityRepository.php @@ -98,15 +98,4 @@ class ActivityRepository extends ServiceEntityRepository return $qb->getQuery()->getResult(); } - - public function findOneByDocument(int $documentId): Activity - { - $qb = $this->createQueryBuilder('a'); - $qb->select('a'); - - $qb->innerJoin('a.documents', 'd', Expr\Join::WITH, 'd.storedobject_id = :documentId'); - $qb->setParameter('documentId', $documentId); - - return $qb->getQuery()->getResult(); - } } diff --git a/src/Bundle/ChillActivityBundle/Resources/views/GenericDoc/activity_document.html.twig b/src/Bundle/ChillActivityBundle/Resources/views/GenericDoc/activity_document.html.twig index aeaea0872..11aeeeca1 100644 --- a/src/Bundle/ChillActivityBundle/Resources/views/GenericDoc/activity_document.html.twig +++ b/src/Bundle/ChillActivityBundle/Resources/views/GenericDoc/activity_document.html.twig @@ -2,25 +2,30 @@ {% import "@ChillDocStore/Macro/macro_mimeicon.html.twig" as mm %} {% import '@ChillPerson/Macro/updatedBy.html.twig' as mmm %} -{% set a = document.calendar %} +{% set person_id = null %} +{% if activity.person %} + {% set person_id = activity.person.id %} +{% endif %} -
          +{% set accompanying_course_id = null %} +{% if activity.accompanyingPeriod %} + {% set accompanying_course_id = activity.accompanyingPeriod.id %} +{% endif %} + +
          - {% if document.storedObject.isPending %} -
          {{ 'docgen.Doc generation is pending'|trans }}
          - {% elseif document.storedObject.isFailure %} + {% if document.isPending %} +
          {{ 'docgen.Doc generation is pending'|trans }}
          + {% elseif document.isFailure %}
          {{ 'docgen.Doc generation failed'|trans }}
          {% endif %}
          - {{ document.storedObject.title }} + {{ document.title }}
          -
          - {{ 'chill_calendar.Document'|trans }} -
          - {% if document.storedObject.hasTemplate %} + {% if document.hasTemplate %}
          -

          {{ document.storedObject.template.name|localize_translatable_string }}

          +

          {{ document.template.name|localize_translatable_string }}

          {% endif %}
          @@ -28,7 +33,7 @@
          - {{ document.storedObject.createdAt|format_date('short') }} + {{ document.createdAt|format_date('short') }}
          @@ -36,15 +41,15 @@
          -

          - {% if c.endDate.diff(c.startDate).days >= 1 %} - {{ c.startDate|format_datetime('short', 'short') }} - - {{ c.endDate|format_datetime('short', 'short') }} - {% else %} - {{ c.startDate|format_datetime('short', 'short') }} - - {{ c.endDate|format_datetime('none', 'short') }} - {% endif %} -

          +

          + + + {{ activity.type.name | localize_translatable_string }} + {% if activity.emergency %} + {{ 'Emergency'|trans|upper }} + {% endif %} + +

          @@ -53,17 +58,19 @@ {{ mmm.createdBy(document) }}
            -
          • - {{ chill_entity_workflow_list('Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluationDocument', document.id) }} -
          • - {% if is_granted('CHILL_CALENDAR_DOC_SEE', document) %} + {% if is_granted('CHILL_ACTIVITY_SEE_DETAILS', activity) %}
          • - {{ document.storedObject|chill_document_button_group(document.storedObject.title, is_granted('CHILL_CALENDAR_CALENDAR_EDIT', c)) }} + {{ document|chill_document_button_group(document.title, is_granted('CHILL_ACTIVITY_UPDATE', activity), {small: false}) }}
          • {% endif %} - {% if is_granted('CHILL_CALENDAR_CALENDAR_EDIT', c) %} + {% if is_granted('CHILL_ACTIVITY_SEE', activity)%}
          • - + +
          • + {% endif %} + {% if is_granted('CHILL_ACTIVITY_UPDATE', activity) %} +
          • +
          • {% endif %}
          diff --git a/src/Bundle/ChillActivityBundle/Service/GenericDoc/Providers/AccompanyingPeriodActivityGenericDocProvider.php b/src/Bundle/ChillActivityBundle/Service/GenericDoc/Providers/AccompanyingPeriodActivityGenericDocProvider.php index bf7a022f1..8c787fd3a 100644 --- a/src/Bundle/ChillActivityBundle/Service/GenericDoc/Providers/AccompanyingPeriodActivityGenericDocProvider.php +++ b/src/Bundle/ChillActivityBundle/Service/GenericDoc/Providers/AccompanyingPeriodActivityGenericDocProvider.php @@ -27,32 +27,19 @@ final class AccompanyingPeriodActivityGenericDocProvider implements GenericDocFo { public const KEY = 'accompanying_period_activity_document'; - private EntityManagerInterface $em; - - private Security $security; - - public function __construct(Security $security, EntityManagerInterface $entityManager) - { - $this->em = $entityManager; - $this->security = $security; + public function __construct( + private EntityManagerInterface $em, + private Security $security + ){ } - /** - * @param AccompanyingPeriod $accompanyingPeriod - * @param DateTimeImmutable|null $startDate - * @param DateTimeImmutable|null $endDate - * @param string|null $content - * @param string|null $origin - * @return FetchQueryInterface - * @throws MappingException - */ public function buildFetchQueryForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod, ?DateTimeImmutable $startDate = null, ?DateTimeImmutable $endDate = null, ?string $content = null, ?string $origin = null): FetchQueryInterface { $storedObjectMetadata = $this->em->getClassMetadata(StoredObject::class); $query = new FetchQuery( self::KEY, - "jsonb_build_object('id', doc_obj.id)", + "jsonb_build_object('id', doc_obj.id, 'activity_id', activity.id)", 'doc_obj.'.$storedObjectMetadata->getColumnName('createdAt'), $storedObjectMetadata->getSchemaName().'.'.$storedObjectMetadata->getTableName().' AS doc_obj' ); diff --git a/src/Bundle/ChillActivityBundle/Service/GenericDoc/Renderers/AccompanyingPeriodActivityGenericDocRenderer.php b/src/Bundle/ChillActivityBundle/Service/GenericDoc/Renderers/AccompanyingPeriodActivityGenericDocRenderer.php index f243fb941..f3b70dac2 100644 --- a/src/Bundle/ChillActivityBundle/Service/GenericDoc/Renderers/AccompanyingPeriodActivityGenericDocRenderer.php +++ b/src/Bundle/ChillActivityBundle/Service/GenericDoc/Renderers/AccompanyingPeriodActivityGenericDocRenderer.php @@ -36,13 +36,13 @@ final class AccompanyingPeriodActivityGenericDocRenderer implements GenericDocRe public function getTemplate(GenericDocDTO $genericDocDTO, $options = []): string { - return '@ChillCalendar/GenericDoc/activity_document.html.twig'; + return '@ChillActivity/GenericDoc/activity_document.html.twig'; } public function getTemplateData(GenericDocDTO $genericDocDTO, $options = []): array { return [ - 'activity' => $this->activityRepository->findOneByDocument($genericDocDTO->identifiers['id']), + 'activity' => $this->activityRepository->find($genericDocDTO->identifiers['activity_id']), 'document' => $this->objectRepository->find($genericDocDTO->identifiers['id']) ]; } diff --git a/src/Bundle/ChillActivityBundle/config/services.yaml b/src/Bundle/ChillActivityBundle/config/services.yaml index d55f86d4f..18be76ec9 100644 --- a/src/Bundle/ChillActivityBundle/config/services.yaml +++ b/src/Bundle/ChillActivityBundle/config/services.yaml @@ -38,3 +38,6 @@ services: Chill\ActivityBundle\Service\EntityInfo\: resource: '../Service/EntityInfo/' + + Chill\ActivityBundle\Service\GenericDoc\: + resource: '../Service/GenericDoc/' From ef04a0405645fc5a38396e8f88486928a40be697 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Wed, 31 May 2023 16:54:21 +0200 Subject: [PATCH 113/321] FEATURE [genericDoc][calendar] minor changes to template and provider --- .../views/GenericDoc/calendar_document.html.twig | 3 --- .../AccompanyingPeriodCalendarGenericDocProvider.php | 10 ++-------- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/src/Bundle/ChillCalendarBundle/Resources/views/GenericDoc/calendar_document.html.twig b/src/Bundle/ChillCalendarBundle/Resources/views/GenericDoc/calendar_document.html.twig index 712b362f5..4cd369366 100644 --- a/src/Bundle/ChillCalendarBundle/Resources/views/GenericDoc/calendar_document.html.twig +++ b/src/Bundle/ChillCalendarBundle/Resources/views/GenericDoc/calendar_document.html.twig @@ -53,9 +53,6 @@ {{ mmm.createdBy(document) }}
            -
          • - {{ chill_entity_workflow_list('Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluationDocument', document.id) }} -
          • {% if is_granted('CHILL_CALENDAR_DOC_SEE', document) %}
          • {{ document.storedObject|chill_document_button_group(document.storedObject.title, is_granted('CHILL_CALENDAR_CALENDAR_EDIT', c)) }} diff --git a/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Providers/AccompanyingPeriodCalendarGenericDocProvider.php b/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Providers/AccompanyingPeriodCalendarGenericDocProvider.php index e653cfc25..7efc1589d 100644 --- a/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Providers/AccompanyingPeriodCalendarGenericDocProvider.php +++ b/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Providers/AccompanyingPeriodCalendarGenericDocProvider.php @@ -28,16 +28,10 @@ final class AccompanyingPeriodCalendarGenericDocProvider implements GenericDocFo { public const KEY = 'accompanying_period_calendar_document'; - private EntityManagerInterface $em; - - private Security $security; - public function __construct( - Security $security, - EntityManagerInterface $entityManager + private Security $security, + private EntityManagerInterface $em ) { - $this->security = $security; - $this->em = $entityManager; } /** From 9a3fcf081ecb5d3d7449878c7562d4528df167b6 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Wed, 31 May 2023 17:10:38 +0200 Subject: [PATCH 114/321] FEATURE [personCalendar][genericDoc] implement genericDoc for calendar objects linked to a person --- .../PersonCalendarGenericDocProvider.php | 112 ++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 src/Bundle/ChillCalendarBundle/Service/GenericDoc/Providers/PersonCalendarGenericDocProvider.php diff --git a/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Providers/PersonCalendarGenericDocProvider.php b/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Providers/PersonCalendarGenericDocProvider.php new file mode 100644 index 000000000..12235f10a --- /dev/null +++ b/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Providers/PersonCalendarGenericDocProvider.php @@ -0,0 +1,112 @@ +em->getClassMetadata(CalendarDoc::class); + $storedObjectMetadata = $this->em->getClassMetadata(StoredObject::class); + $calendarMetadata = $this->em->getClassMetadata(Calendar::class); + + $query = new FetchQuery( + self::KEY, + sprintf("jsonb_build_object('id', cd.%s)", $classMetadata->getColumnName('id')), + 'cd.'.$storedObjectMetadata->getColumnName('createdAt'), + $classMetadata->getSchemaName().'.'.$classMetadata->getTableName().' AS cd' + ); + $query->addJoinClause( + sprintf('JOIN %s doc_store ON doc_store.%s = cd.%s', + $storedObjectMetadata->getSchemaName().'.'.$storedObjectMetadata->getTableName(), + $storedObjectMetadata->getColumnName('id'), + $classMetadata->getSingleAssociationJoinColumnName('storedObject') + )); + + $query->addJoinClause( + sprintf('JOIN %s calendar ON calendar.%s = cd.%s', + $calendarMetadata->getSchemaName().'.'.$calendarMetadata->getTableName(), + $calendarMetadata->getColumnName('id'), + $classMetadata->getSingleAssociationJoinColumnName('calendar') + ) + ); + + $query->addWhereClause( + sprintf('calendar.%s = ?', + $calendarMetadata->getAssociationMapping('person')['joinColumns'][0]['name']), + [$person->getId()], + [Types::INTEGER] + ); + + if (null !== $startDate) { + $query->addWhereClause( + sprintf('doc_store.%s >= ?', $storedObjectMetadata->getColumnName('createdAt')), + [$startDate], + [Types::DATE_IMMUTABLE] + ); + } + + if (null !== $endDate) { + $query->addWhereClause( + sprintf('doc_store.%s < ?', $storedObjectMetadata->getColumnName('createdAt')), + [$endDate], + [Types::DATE_IMMUTABLE] + ); + } + + if (null !== $content) { + $query->addWhereClause( + sprintf('doc_store.%s ilike ?', $storedObjectMetadata->getColumnName('title')), + ['%' . $content . '%'], + [Types::STRING] + ); + } + + dump($query); + + return $query; + } + + /** + * @param Person $person + * @return bool + */ + public function isAllowedForPerson(Person $person): bool + { + return $this->security->isGranted(CalendarVoter::SEE, $person); + } +} From 80dfa092db2c1e51f6fa33a1f843d785edc7e0d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 31 May 2023 23:29:34 +0200 Subject: [PATCH 115/321] fixes: add tests for generation and fix some situation --- .../Service/DocGenerator/ActivityContext.php | 4 +- .../AccompanyingPeriodContext.php | 26 +- ...ccompanyingPeriodWorkEvaluationContext.php | 8 +- .../Service/DocGenerator/PersonContext.php | 23 +- .../DocGenerator/PersonContextInterface.php | 3 +- .../AccompanyingPeriodContextTest.php | 291 ++++++++++++++++++ .../DocGenerator/PersonContextTest.php | 183 ++++++++++- .../Repository/ThirdPartyRepository.php | 2 +- 8 files changed, 503 insertions(+), 37 deletions(-) create mode 100644 src/Bundle/ChillPersonBundle/Tests/Service/DocGenerator/AccompanyingPeriodContextTest.php diff --git a/src/Bundle/ChillActivityBundle/Service/DocGenerator/ActivityContext.php b/src/Bundle/ChillActivityBundle/Service/DocGenerator/ActivityContext.php index 91827267c..a20ca365b 100644 --- a/src/Bundle/ChillActivityBundle/Service/DocGenerator/ActivityContext.php +++ b/src/Bundle/ChillActivityBundle/Service/DocGenerator/ActivityContext.php @@ -206,10 +206,10 @@ class ActivityContext implements $normalized = []; foreach (['mainPerson', 'person1', 'person2'] as $k) { - $normalized[$k] = null === $data[$k] ? null : $data[$k]->getId(); + $normalized[$k] = ($data[$k] ?? null)?->getId(); } - $normalized['thirdParty'] = null === $data['thirdParty'] ? null : $data['thirdParty']->getId(); + $normalized['thirdParty'] = ($data['thirdParty'] ?? null)?->getId(); return $normalized; } diff --git a/src/Bundle/ChillPersonBundle/Service/DocGenerator/AccompanyingPeriodContext.php b/src/Bundle/ChillPersonBundle/Service/DocGenerator/AccompanyingPeriodContext.php index 66be9aceb..0db54a47a 100644 --- a/src/Bundle/ChillPersonBundle/Service/DocGenerator/AccompanyingPeriodContext.php +++ b/src/Bundle/ChillPersonBundle/Service/DocGenerator/AccompanyingPeriodContext.php @@ -44,6 +44,7 @@ use Symfony\Contracts\Translation\TranslatorInterface; use function array_key_exists; /** + * @see AccompanyingPeriodContextTest * @template-implements DocGeneratorContextWithPublicFormInterface */ class AccompanyingPeriodContext implements @@ -116,12 +117,11 @@ class AccompanyingPeriodContext implements 'person2' => $data['person2'] ?? false, 'person2Label' => $data['person2Label'] ?? $this->translator->trans('docgen.person 2'), 'thirdParty' => $data['thirdParty'] ?? false, - 'thirdPartyLabel' => $data['thirdPartyLabel'] ?? $this->translator->trans('thirdParty'), + 'thirdPartyLabel' => $data['thirdPartyLabel'] ?? $this->translator->trans('Third party'), ]; if (array_key_exists('category', $data)) { - $r['category'] = array_key_exists('category', $data) ? - $this->documentCategoryRepository->find($data['category']) : null; + $r['category'] = $this->documentCategoryRepository->find($data['category']); } return $r; @@ -214,17 +214,15 @@ class AccompanyingPeriodContext implements } $thirdParties = array_merge( - array_filter(array_values([$entity->getRequestorThirdParty()])), - array_filter( - array_values( - array_map( - fn (Resource $r): ?ThirdParty => $r->getThirdParty(), - $entity->getResources()->filter( - static fn (Resource $r): bool => null !== $r->getThirdParty() - )->toArray() - ) + array_values(array_filter([$entity->getRequestorThirdParty()])), + array_values(array_filter( + array_map( + fn (Resource $r): ?ThirdParty => $r->getThirdParty(), + $entity->getResources()->filter( + static fn (Resource $r): bool => null !== $r->getThirdParty() + )->toArray() ) - ) + )) ); if ($options['thirdParty'] ?? false) { @@ -320,7 +318,7 @@ class AccompanyingPeriodContext implements $normalized[$k] = null !== ($data[$k] ?? null) ? $data[$k]->getId() : null; } - $normalized['thirdParty'] = null === $data['thirdParty'] ? null : $data['thirdParty']->getId(); + $normalized['thirdParty'] = ($data['thirdParty'] ?? null)?->getId(); return $normalized; } diff --git a/src/Bundle/ChillPersonBundle/Service/DocGenerator/AccompanyingPeriodWorkEvaluationContext.php b/src/Bundle/ChillPersonBundle/Service/DocGenerator/AccompanyingPeriodWorkEvaluationContext.php index 62e13789f..ee746a034 100644 --- a/src/Bundle/ChillPersonBundle/Service/DocGenerator/AccompanyingPeriodWorkEvaluationContext.php +++ b/src/Bundle/ChillPersonBundle/Service/DocGenerator/AccompanyingPeriodWorkEvaluationContext.php @@ -117,10 +117,10 @@ class AccompanyingPeriodWorkEvaluationContext implements $this->accompanyingPeriodWorkContext->buildPublicForm($builder, $template, $entity->getAccompanyingPeriodWork()); $thirdParties = array_merge( - array_filter(array_values($entity->getAccompanyingPeriodWork()->getThirdParties()->toArray())), - array_filter(array_values([$entity->getAccompanyingPeriodWork()->getHandlingThierParty()])), - array_filter( - array_values( + array_values(array_filter($entity->getAccompanyingPeriodWork()->getThirdParties()->toArray())), + array_values(array_filter([$entity->getAccompanyingPeriodWork()->getHandlingThierParty()])), + array_values( + array_filter( array_map( fn (Resource $r): ?ThirdParty => $r->getThirdParty(), $entity->getAccompanyingPeriodWork()->getAccompanyingPeriod()->getResources()->filter( diff --git a/src/Bundle/ChillPersonBundle/Service/DocGenerator/PersonContext.php b/src/Bundle/ChillPersonBundle/Service/DocGenerator/PersonContext.php index 4d49bcfba..1ced31121 100644 --- a/src/Bundle/ChillPersonBundle/Service/DocGenerator/PersonContext.php +++ b/src/Bundle/ChillPersonBundle/Service/DocGenerator/PersonContext.php @@ -38,6 +38,7 @@ use DateTime; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityRepository; use LogicException; +use Service\DocGenerator\PersonContextTest; use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; use Symfony\Component\Form\Extension\Core\Type\CheckboxType; @@ -50,6 +51,9 @@ use Symfony\Contracts\Translation\TranslatorInterface; use function array_key_exists; use function count; +/** + * @see PersonContextTest + */ final class PersonContext implements PersonContextInterface { private AuthorizationHelperInterface $authorizationHelper; @@ -130,12 +134,11 @@ final class PersonContext implements PersonContextInterface 'mainPerson' => $data['mainPerson'] ?? false, 'mainPersonLabel' => $data['mainPersonLabel'] ?? $this->translator->trans('docgen.Main person'), 'thirdParty' => $data['thirdParty'] ?? false, - 'thirdPartyLabel' => $data['thirdPartyLabel'] ?? $this->translator->trans('thirdParty'), + 'thirdPartyLabel' => $data['thirdPartyLabel'] ?? $this->translator->trans('Third party'), ]; if (array_key_exists('category', $data)) { - $r['category'] = array_key_exists('category', $data) ? - $this->documentCategoryRepository->find($data['category']) : null; + $r['category'] = $this->documentCategoryRepository->find($data['category']); } return $r; @@ -177,8 +180,8 @@ final class PersonContext implements PersonContextInterface ]); $thirdParties = array_merge( - array_filter( - array_values( + array_values( + array_filter( array_map( fn (ResidentialAddress $r): ?ThirdParty => $r->getHostThirdParty(), $this @@ -187,8 +190,8 @@ final class PersonContext implements PersonContextInterface ) ) ), - array_filter( - array_values( + array_values( + array_filter( array_map( fn (PersonResource $r): ?ThirdParty => $r->getThirdParty(), $entity->getResources()->filter( @@ -223,10 +226,6 @@ final class PersonContext implements PersonContextInterface public function getData(DocGeneratorTemplate $template, $entity, array $contextGenerationData = []): array { - if (!$entity instanceof Person) { - throw new UnexpectedTypeException($entity, Person::class); - } - $data = []; $data = array_merge($data, $this->baseContextData->getData($contextGenerationData['creator'] ?? null)); $data['person'] = $this->normalizer->normalize($entity, 'docgen', [ @@ -297,7 +296,7 @@ final class PersonContext implements PersonContextInterface return [ 'title' => $data['title'] ?? '', 'scope_id' => $scope instanceof Scope ? $scope->getId() : null, - 'thirdParty' => null === $data['thirdParty'] ? null : $data['thirdParty']->getId(), + 'thirdParty' => ($data['thirdParty'] ?? null)?->getId(), ]; } diff --git a/src/Bundle/ChillPersonBundle/Service/DocGenerator/PersonContextInterface.php b/src/Bundle/ChillPersonBundle/Service/DocGenerator/PersonContextInterface.php index 6de8c1c50..53e241292 100644 --- a/src/Bundle/ChillPersonBundle/Service/DocGenerator/PersonContextInterface.php +++ b/src/Bundle/ChillPersonBundle/Service/DocGenerator/PersonContextInterface.php @@ -19,7 +19,8 @@ use Chill\PersonBundle\Entity\Person; use Symfony\Component\Form\FormBuilderInterface; /** - * @template-extends DocGeneratorContextWithPublicFormInterface + * @template-extends DocGeneratorContextWithPublicFormInterface + * @template-extends DocGeneratorContextWithAdminFormInterface */ interface PersonContextInterface extends DocGeneratorContextWithAdminFormInterface, DocGeneratorContextWithPublicFormInterface { diff --git a/src/Bundle/ChillPersonBundle/Tests/Service/DocGenerator/AccompanyingPeriodContextTest.php b/src/Bundle/ChillPersonBundle/Tests/Service/DocGenerator/AccompanyingPeriodContextTest.php new file mode 100644 index 000000000..f9f888999 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Service/DocGenerator/AccompanyingPeriodContextTest.php @@ -0,0 +1,291 @@ +baseContextData = self::$container->get(BaseContextData::class); + $this->documentCategoryRepository = self::$container->get(DocumentCategoryRepository::class); + $this->em = self::$container->get(EntityManagerInterface::class); + $this->normalizer = self::$container->get(NormalizerInterface::class); + $this->personRender = self::$container->get(PersonRenderInterface::class); + $this->personRepository = self::$container->get(PersonRepository::class); + $this->translatableStringHelper = self::$container->get(TranslatableStringHelperInterface::class); + $this->translator = self::$container->get(TranslatorInterface::class); + $this->thirdPartyRender = self::$container->get(ThirdPartyRender::class); + $this->thirdPartyRepository = self::$container->get(ThirdPartyRepository::class); + } + + private function buildContext(): AccompanyingPeriodContext + { + return new AccompanyingPeriodContext( + $this->documentCategoryRepository, + $this->normalizer, + $this->translatableStringHelper, + $this->em, + $this->personRender, + $this->personRepository, + $this->translator, + $this->baseContextData, + $this->thirdPartyRender, + $this->thirdPartyRepository, + ); + } + + /** + * This test run the methods executed when a document is generated: + * + * - normalized data from the form in a way that they are stored in message queue; + * - denormalize the data from the message queue, + * - and get the data, as they will be transmitted to the GeneratorDriver + * + * @param array $options the options, as they are stored in the DocGeneratorTemplate (the admin form data) + * @param AccompanyingPeriod $entity The entity from which the data will be extracted + * @param array $data The data, from the public form + * @param array $expectedNormalized, how the normalized data are expected (allow to check that this data will be compliant with the storage in messenger queue) + * @param callable $assertionsOnData some test that will be executed on the normalized data + * @dataProvider provideNormalizedData + */ + public function testContextGenerationDataNormalizeDenormalizeGetData( + array $options, + AccompanyingPeriod $entity, + array $data, + array $expectedNormalized, + callable $assertionsOnData + ): void { + $context = $this->buildContext(); + $template = new DocGeneratorTemplate(); + $template->setName(["fr" =>"test"])->setContext(AccompanyingPeriodContext::class) + ->setDescription("description")->setActive(true) + ->setOptions($options); + + $normalized = $context->contextGenerationDataNormalize($template, $entity, $data); + + self::assertEquals($expectedNormalized, $normalized); + + $denormalized = $context->contextGenerationDataDenormalize($template, $entity, $normalized); + + $data = $context->getData($template, $entity, $denormalized); + + call_user_func($assertionsOnData, $data); + } + + public function provideNormalizedData(): iterable + { + self::bootKernel(); + $em = self::$container->get(EntityManagerInterface::class); + + $thirdParty = $em->createQuery("SELECT t FROM " . ThirdParty::class . " t") + ->setMaxResults(1) + ->getSingleResult(); + + if (null === $thirdParty) { + throw new \RuntimeException("No thirdparty in database"); + } + + $period = $em->createQuery("SELECT a FROM " . AccompanyingPeriod::class . " a WHERE a.step = 'CONFIRMED'") + ->setMaxResults(1) + ->getSingleResult(); + + if (null === $period) { + throw new \RuntimeException("No confirmed period in database"); + } + + $person = $em->createQuery("SELECT p FROM " . Person::class . " p") + ->setMaxResults(1) + ->getSingleResult(); + + if (null === $person) { + throw new \RuntimeException("No confirmed period in database"); + } + + yield [ + // test with only thirdParty + [ + 'mainPerson' => false, + 'mainPersonLabel' => 'person', + 'person1' => false, + 'person1Label' => 'person2', + 'person2' => false, + 'person2Label' => 'person2', + 'thirdParty' => true, + 'thirdPartyLabel' => '3party' + ], + $period, + [ + 'thirdParty' => $thirdParty + ], + [ + 'thirdParty' => $thirdParty->getId(), + 'mainPerson' => null, + 'person1' => null, + 'person2' => null, + ], + function (array $data) use ($thirdParty, $period) { + self::assertArrayHasKey('thirdParty', $data); + self::assertEquals($thirdParty->getId(), $data['thirdParty']['id']); + + self::assertArrayHasKey('course', $data); + self::assertEquals($period->getId(), $data['course']['id']); + }, + ]; + + yield [ + // test with only mainPerson + [ + 'mainPerson' => true, + 'mainPersonLabel' => 'person', + 'person1' => false, + 'person1Label' => 'person2', + 'person2' => false, + 'person2Label' => 'person2', + 'thirdParty' => false, + 'thirdPartyLabel' => '3party' + ], + $period, + [ + 'mainPerson' => $person, + ], + [ + 'thirdParty' => null, + 'mainPerson' => $person->getId(), + 'person1' => null, + 'person2' => null, + ], + function (array $data) use ($person, $period) { + self::assertArrayHasKey('mainPerson', $data); + self::assertEquals($person->getId(), $data['mainPerson']['id']); + + self::assertArrayHasKey('course', $data); + self::assertEquals($period->getId(), $data['course']['id']); + }, + ]; + + yield [ + // test with every options activated + [ + 'mainPerson' => true, + 'mainPersonLabel' => 'person', + 'person1' => true, + 'person1Label' => 'person2', + 'person2' => true, + 'person2Label' => 'person2', + 'thirdParty' => true, + 'thirdPartyLabel' => '3party' + ], + $period, + [ + 'mainPerson' => $person, + 'person1' => $person, + 'person2' => $person, + 'thirdParty' => $thirdParty, + ], + [ + 'thirdParty' => $thirdParty->getId(), + 'mainPerson' => $person->getId(), + 'person1' => $person->getId(), + 'person2' => $person->getId(), + ], + function (array $data) use ($person, $thirdParty, $period) { + self::assertArrayHasKey('mainPerson', $data); + self::assertEquals($person->getId(), $data['mainPerson']['id']); + + self::assertArrayHasKey('person1', $data); + self::assertEquals($person->getId(), $data['person1']['id']); + + self::assertArrayHasKey('person2', $data); + self::assertEquals($person->getId(), $data['person2']['id']); + + self::assertArrayHasKey('thirdParty', $data); + self::assertEquals($thirdParty->getId(), $data['thirdParty']['id']); + + self::assertArrayHasKey('course', $data); + self::assertEquals($period->getId(), $data['course']['id']); + }, + ]; + + yield [ + // test with any option activated + [ + 'mainPerson' => false, + 'mainPersonLabel' => 'person', + 'person1' => false, + 'person1Label' => 'person2', + 'person2' => false, + 'person2Label' => 'person2', + 'thirdParty' => false, + 'thirdPartyLabel' => '3party' + ], + $period, + [ + 'mainPerson' => null, + 'person1' => null, + 'person2' => null, + 'thirdParty' => null, + ], + [ + 'thirdParty' => null, + 'mainPerson' => null, + 'person1' => null, + 'person2' => null, + ], + function (array $data) use ($period) { + self::assertArrayHasKey('course', $data); + self::assertEquals($period->getId(), $data['course']['id']); + }, + ]; + } +} diff --git a/src/Bundle/ChillPersonBundle/Tests/Service/DocGenerator/PersonContextTest.php b/src/Bundle/ChillPersonBundle/Tests/Service/DocGenerator/PersonContextTest.php index d0138dc30..71fce8c92 100644 --- a/src/Bundle/ChillPersonBundle/Tests/Service/DocGenerator/PersonContextTest.php +++ b/src/Bundle/ChillPersonBundle/Tests/Service/DocGenerator/PersonContextTest.php @@ -18,20 +18,30 @@ use Chill\DocStoreBundle\Entity\PersonDocument; use Chill\DocStoreBundle\Entity\StoredObject; use Chill\DocStoreBundle\Repository\DocumentCategoryRepository; use Chill\DocStoreBundle\Security\Authorization\PersonDocumentVoter; +use Chill\MainBundle\Entity\Address; use Chill\MainBundle\Entity\Center; +use Chill\MainBundle\Entity\PostalCode; use Chill\MainBundle\Entity\Scope; use Chill\MainBundle\Entity\User; use Chill\MainBundle\Form\Type\ScopePickerType; +use Chill\MainBundle\Repository\ScopeRepositoryInterface; use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface; use Chill\MainBundle\Security\Resolver\CenterResolverManagerInterface; use Chill\MainBundle\Templating\TranslatableStringHelperInterface; +use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\Person; +use Chill\PersonBundle\Repository\ResidentialAddressRepository; +use Chill\PersonBundle\Service\DocGenerator\AccompanyingPeriodContext; use Chill\PersonBundle\Service\DocGenerator\PersonContext; +use Chill\ThirdPartyBundle\Entity\ThirdParty; +use Chill\ThirdPartyBundle\Repository\ThirdPartyRepository; +use Chill\ThirdPartyBundle\Templating\Entity\ThirdPartyRender; use Doctrine\ORM\EntityManagerInterface; use PHPUnit\Framework\TestCase; use Prophecy\Argument; use Prophecy\Exception\Prediction\FailedPredictionException; use Prophecy\PhpUnit\ProphecyTrait; +use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; use Symfony\Component\Form\Extension\Core\Type\TextType; @@ -46,10 +56,142 @@ use function count; * @internal * @coversNothing */ -final class PersonContextTest extends TestCase +final class PersonContextTest extends KernelTestCase { use ProphecyTrait; + /** + * This test run the methods executed when a document is generated: + * + * - normalized data from the form in a way that they are stored in message queue; + * - denormalize the data from the message queue, + * - and get the data, as they will be transmitted to the GeneratorDriver + * + * @param array $options the options, as they are stored in the DocGeneratorTemplate (the admin form data) + * @param Person $entity The entity from which the data will be extracted + * @param array $data The data, from the public form + * @param array $expectedNormalized, how the normalized data are expected (allow to check that this data will be compliant with the storage in messenger queue) + * @param callable $assertionsOnData some test that will be executed on the normalized data + * @dataProvider provideNormalizedData + */ + public function testContextGenerationDataNormalizeDenormalizeGetData( + array $options, + Person $entity, + array $data, + array $expectedNormalized, + callable $assertionsOnData + ): void { + // we boot kernel only for this test + self::bootKernel(); + + // we create a PersonContext with the minimal dependency injection needed (relying on + // prophecy for other dependencies) + $context = $this->buildPersonContext( + null, + self::$container->get(BaseContextData::class), + self::$container->get(CenterResolverManagerInterface::class), + self::$container->get(DocumentCategoryRepository::class), + self::$container->get(EntityManagerInterface::class), + self::$container->get(NormalizerInterface::class), + (new ParameterBag(['chill_main' => ['acl' => ['form_show_scopes' => false]]])), + null, + self::$container->get(Security::class), + null, + null, + null, + self::$container->get(ThirdPartyRepository::class) + ); + $template = new DocGeneratorTemplate(); + $template->setName(["fr" =>"test"])->setContext(AccompanyingPeriodContext::class) + ->setDescription("description")->setActive(true) + ->setOptions($options); + + $normalized = $context->contextGenerationDataNormalize($template, $entity, $data); + + self::assertEquals($expectedNormalized, $normalized); + + $denormalized = $context->contextGenerationDataDenormalize($template, $entity, $normalized); + + $data = $context->getData($template, $entity, $denormalized); + + call_user_func($assertionsOnData, $data); + } + + public function provideNormalizedData(): iterable + { + self::bootKernel(); + $em = self::$container->get(EntityManagerInterface::class); + + $thirdParty = $em->createQuery("SELECT t FROM " . ThirdParty::class . " t") + ->setMaxResults(1) + ->getSingleResult(); + + if (null === $thirdParty) { + throw new \RuntimeException("No thirdparty in database"); + } + + $person = $em->createQuery("SELECT p FROM " . Person::class . " p") + ->setMaxResults(1) + ->getSingleResult(); + + if (null === $person) { + throw new \RuntimeException("No confirmed period in database"); + } + + $category = self::$container->get(DocumentCategoryRepository::class) + ->findAll()[0]; + + if (null === $category) { + throw new \RuntimeException("no document category in database"); + } + + yield [ + [ + 'thirdParty' => true, + 'thirdPartyLabel' => '3party', + 'category' => $category, + ], + $person, + [ + 'title' => 'test', + 'thirdParty' => $thirdParty, + ], + [ + 'thirdParty' => $thirdParty->getId(), + 'title' => 'test', + 'scope_id' => null, + ], + function ($data) use ($person, $thirdParty) { + self::assertArrayHasKey('person', $data); + self::assertEquals($person->getId(), $data['person']['id']); + + self::assertArrayHasKey('thirdParty', $data); + self::assertEquals($thirdParty->getId(), $data['thirdParty']['id']); + } + ]; + + yield [ + [ + 'thirdParty' => false, + 'thirdPartyLabel' => '3party', + 'category' => $category, + ], + $person, + [ + 'title' => 'test', + ], + [ + 'title' => 'test', + 'scope_id' => null, + 'thirdParty' => null, + ], + function ($data) use ($person, $thirdParty) { + self::assertArrayHasKey('person', $data); + self::assertEquals($person->getId(), $data['person']['id']); + } + ]; + } + /** * Test that the build person context works in the case when 'form_show_scope' is false. */ @@ -208,9 +350,13 @@ final class PersonContextTest extends TestCase ?EntityManagerInterface $em = null, ?NormalizerInterface $normalizer = null, ?ParameterBagInterface $parameterBag = null, + ?ScopeRepositoryInterface $scopeRepository = null, ?Security $security = null, ?TranslatorInterface $translator = null, - ?TranslatableStringHelperInterface $translatableStringHelper = null + ?TranslatableStringHelperInterface $translatableStringHelper = null, + ?ThirdPartyRender $thirdPartyRender = null, + ?ThirdPartyRepository $thirdPartyRepository = null, + ?ResidentialAddressRepository $residentialAddressRepository = null ): PersonContext { if (null === $authorizationHelper) { $authorizationHelper = $this->prophesize(AuthorizationHelperInterface::class)->reveal(); @@ -250,6 +396,11 @@ final class PersonContextTest extends TestCase $parameterBag = new ParameterBag(['chill_main' => ['acl' => ['form_show_scopes' => true]]]); } + if (null === $scopeRepository) { + $scopeRepository = $this->prophesize(ScopeRepositoryInterface::class); + $scopeRepository = $scopeRepository->reveal(); + } + if (null === $security) { $security = $this->prophesize(Security::class); $security->getUser()->willReturn(new User()); @@ -267,6 +418,28 @@ final class PersonContextTest extends TestCase $translatableStringHelper = $translatableStringHelper->reveal(); } + if (null === $thirdPartyRender) { + $thirdPartyRender = $this->prophesize(ThirdPartyRender::class); + $thirdPartyRender = $thirdPartyRender->reveal(); + } + + if (null === $thirdPartyRepository) { + $thirdPartyRepository = $this->prophesize(ThirdPartyRepository::class); + $thirdPartyRepository = $thirdPartyRepository->reveal(); + } + + if (null === $residentialAddressRepository) { + $residentialAddressRepository = $this->prophesize(ResidentialAddressRepository::class); + $residentialAddressRepository->findCurrentResidentialAddressByPerson(Argument::type(Person::class), Argument::any()) + ->willReturn([ + (new Person\ResidentialAddress()) + ->setAddress((new Address()) + ->setStreet('test street') + ->setPostcode(new PostalCode())) + ]); + $residentialAddressRepository = $residentialAddressRepository->reveal(); + } + return new PersonContext( $authorizationHelper, $baseContextData, @@ -275,9 +448,13 @@ final class PersonContextTest extends TestCase $em, $normalizer, $parameterBag, + $scopeRepository, $security, $translator, - $translatableStringHelper + $translatableStringHelper, + $thirdPartyRender, + $thirdPartyRepository, + $residentialAddressRepository ); } } diff --git a/src/Bundle/ChillThirdPartyBundle/Repository/ThirdPartyRepository.php b/src/Bundle/ChillThirdPartyBundle/Repository/ThirdPartyRepository.php index 76e15ef17..f9893b9d9 100644 --- a/src/Bundle/ChillThirdPartyBundle/Repository/ThirdPartyRepository.php +++ b/src/Bundle/ChillThirdPartyBundle/Repository/ThirdPartyRepository.php @@ -21,7 +21,7 @@ use DomainException; use function array_key_exists; -final class ThirdPartyRepository implements ObjectRepository +class ThirdPartyRepository implements ObjectRepository { private EntityRepository $repository; From 9c109d2efdbe78d99d813b3a35abf9c532cf8fa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 31 May 2023 23:47:02 +0200 Subject: [PATCH 116/321] DX: use array spred instead of array_merge --- .../AccompanyingPeriodContext.php | 19 ++++------ ...ccompanyingPeriodWorkEvaluationContext.php | 20 ++++------ .../Service/DocGenerator/PersonContext.php | 37 +++++++++---------- 3 files changed, 33 insertions(+), 43 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Service/DocGenerator/AccompanyingPeriodContext.php b/src/Bundle/ChillPersonBundle/Service/DocGenerator/AccompanyingPeriodContext.php index 0db54a47a..4f6235930 100644 --- a/src/Bundle/ChillPersonBundle/Service/DocGenerator/AccompanyingPeriodContext.php +++ b/src/Bundle/ChillPersonBundle/Service/DocGenerator/AccompanyingPeriodContext.php @@ -213,17 +213,14 @@ class AccompanyingPeriodContext implements } } - $thirdParties = array_merge( - array_values(array_filter([$entity->getRequestorThirdParty()])), - array_values(array_filter( - array_map( - fn (Resource $r): ?ThirdParty => $r->getThirdParty(), - $entity->getResources()->filter( - static fn (Resource $r): bool => null !== $r->getThirdParty() - )->toArray() - ) - )) - ); + $thirdParties = [...array_values(array_filter([$entity->getRequestorThirdParty()])), ...array_values(array_filter( + array_map( + fn (Resource $r): ?ThirdParty => $r->getThirdParty(), + $entity->getResources()->filter( + static fn (Resource $r): bool => null !== $r->getThirdParty() + )->toArray() + ) + ))]; if ($options['thirdParty'] ?? false) { $builder->add('thirdParty', EntityType::class, [ diff --git a/src/Bundle/ChillPersonBundle/Service/DocGenerator/AccompanyingPeriodWorkEvaluationContext.php b/src/Bundle/ChillPersonBundle/Service/DocGenerator/AccompanyingPeriodWorkEvaluationContext.php index ee746a034..f58788120 100644 --- a/src/Bundle/ChillPersonBundle/Service/DocGenerator/AccompanyingPeriodWorkEvaluationContext.php +++ b/src/Bundle/ChillPersonBundle/Service/DocGenerator/AccompanyingPeriodWorkEvaluationContext.php @@ -116,20 +116,16 @@ class AccompanyingPeriodWorkEvaluationContext implements { $this->accompanyingPeriodWorkContext->buildPublicForm($builder, $template, $entity->getAccompanyingPeriodWork()); - $thirdParties = array_merge( - array_values(array_filter($entity->getAccompanyingPeriodWork()->getThirdParties()->toArray())), - array_values(array_filter([$entity->getAccompanyingPeriodWork()->getHandlingThierParty()])), - array_values( - array_filter( - array_map( - fn (Resource $r): ?ThirdParty => $r->getThirdParty(), - $entity->getAccompanyingPeriodWork()->getAccompanyingPeriod()->getResources()->filter( - static fn (Resource $r): bool => null !== $r->getThirdParty() - )->toArray() - ) + $thirdParties = [...array_values(array_filter($entity->getAccompanyingPeriodWork()->getThirdParties()->toArray())), ...array_values(array_filter([$entity->getAccompanyingPeriodWork()->getHandlingThierParty()])), ...array_values( + array_filter( + array_map( + fn (Resource $r): ?ThirdParty => $r->getThirdParty(), + $entity->getAccompanyingPeriodWork()->getAccompanyingPeriod()->getResources()->filter( + static fn (Resource $r): bool => null !== $r->getThirdParty() + )->toArray() ) ) - ); + )]; $options = $template->getOptions(); if ($options['thirdParty'] ?? false) { diff --git a/src/Bundle/ChillPersonBundle/Service/DocGenerator/PersonContext.php b/src/Bundle/ChillPersonBundle/Service/DocGenerator/PersonContext.php index 1ced31121..9d7f1cdd5 100644 --- a/src/Bundle/ChillPersonBundle/Service/DocGenerator/PersonContext.php +++ b/src/Bundle/ChillPersonBundle/Service/DocGenerator/PersonContext.php @@ -179,28 +179,25 @@ final class PersonContext implements PersonContextInterface 'data' => $this->translatableStringHelper->localize($template->getName()), ]); - $thirdParties = array_merge( - array_values( - array_filter( - array_map( - fn (ResidentialAddress $r): ?ThirdParty => $r->getHostThirdParty(), - $this - ->residentialAddressRepository - ->findCurrentResidentialAddressByPerson($entity) - ) - ) - ), - array_values( - array_filter( - array_map( - fn (PersonResource $r): ?ThirdParty => $r->getThirdParty(), - $entity->getResources()->filter( - static fn (PersonResource $r): bool => null !== $r->getThirdParty() - )->toArray() - ) + $thirdParties = [...array_values( + array_filter( + array_map( + fn (ResidentialAddress $r): ?ThirdParty => $r->getHostThirdParty(), + $this + ->residentialAddressRepository + ->findCurrentResidentialAddressByPerson($entity) ) ) - ); + ), ...array_values( + array_filter( + array_map( + fn (PersonResource $r): ?ThirdParty => $r->getThirdParty(), + $entity->getResources()->filter( + static fn (PersonResource $r): bool => null !== $r->getThirdParty() + )->toArray() + ) + ) + )]; if ($options['thirdParty'] ?? false) { $builder->add('thirdParty', EntityType::class, [ From 07ff425bfcdc26dc512cadd999e7bcf8fc2d5893 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 1 Jun 2023 09:39:40 +0200 Subject: [PATCH 117/321] initialize .changie and backup previous changelog --- .changes/header.tpl.md | 6 + .changes/unreleased/.gitkeep | 0 .changes/v2.0.0.md | 677 +++++++++++++++++++++++++++++++++++ .changie.yaml | 31 ++ CHANGELOG.md | 18 +- 5 files changed, 723 insertions(+), 9 deletions(-) create mode 100644 .changes/header.tpl.md create mode 100644 .changes/unreleased/.gitkeep create mode 100644 .changes/v2.0.0.md create mode 100644 .changie.yaml diff --git a/.changes/header.tpl.md b/.changes/header.tpl.md new file mode 100644 index 000000000..df8faa7b2 --- /dev/null +++ b/.changes/header.tpl.md @@ -0,0 +1,6 @@ +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), +and is generated by [Changie](https://github.com/miniscruff/changie). diff --git a/.changes/unreleased/.gitkeep b/.changes/unreleased/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/.changes/v2.0.0.md b/.changes/v2.0.0.md new file mode 100644 index 000000000..8d70ecba6 --- /dev/null +++ b/.changes/v2.0.0.md @@ -0,0 +1,677 @@ +## 2.0.0 + +* this is a release to relaunch our proceess of release with semantic versioning + +## Test releases + +### 2.0.0-beta3 + +* [person][export] Fixed: rename the alias for `accompanying_period` to `acp` in filter associated with person +* [activity][export] Feature: improve label for aliases in "Filter by activity type" +* [activity][export] DX/Feature: use of an `ActivityTypeRepositoryInterface` instead of the old-style EntityRepository +* [person][export] Fixed: some inconsistency with date filter on accompanying courses +* [person][export] Fixed: use left join for related entities in accompanying course aggregators +* [workflow] Feature: allow user to copy and send manually the access link for the workflow +* [workflow] Feature: show the email addresses that received an access link for the workflow +### 2.0.0-beta2 + +* [workflow]: Fixed: the notification is sent when the user is added to the first step. +* [budget] Feature: allow to desactivate some charges and resources, adding an `active` key in the configuration +* [person] Feature: on Evaluation, allow to configure an URL from the admin + +### 2022-06 + +* [workflow]: added pagination to workflow list page +* [homepage_widget]: null error on tasks widget fixed +* [person-thirdparty]: fix quick-add of names that consist of multiple parts (eg. De Vlieger) within onthefly modal person/thirdparty +* [search]: Order of birthdate fields changed in advanced search to avoid confusion. +* [workflow]: Constraint added to workflow (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/675) +* [social_action]: only show active objectives (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/625) +* [household]: Reposition and cut button for enfant hors menage have been deleted (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/620) +* [admin]: Add crud for composition type in admin (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/611) +* [social_action]: only show active objectives (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/625) + +## Test releases + +### 2022-05-30 + +* fix creating a new AccompanyingPeriodWorkEvaluationDocument when replacing the document (the workflow was lost) + +### 2022-05-27 + +* [storedobject] add title field on StoredObject entity + use it in activity documents (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/604) +* [main] add a "read more..." on comment embeddable when overflown (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/604) +* [person] add closing motive to closed acc course (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/603) +* [person] household filiation: fetch person info when unfolding person (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/586) +* [admin] repair edit of social action in the admin (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/601) +* [admin]: add select2 to Goal form type entity fields (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/702) +* [main] allow hide permissions group list menu (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/577) +* [main] allow hide change user password menu (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/577) +* [main] filter user jobs by active jobs (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/577) +* [main] add civility to User (entity, migration and form type) (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/577) +* [admin] refactorisation of the admin section: reorganisation of the menu, translations, form types, new entities (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/592) +* [admin] add admin section for languages and countries (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/596) +* [activity] activity admin: translations + remove label field for comment on admin activity type (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/587) +* [main] admin user_job: improvements (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/588) +* [address] can add extra address info even if noAddress (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/576) + + +### 2022-05-06 + +* [person] add civility when creating a person (with the on-the-fly component or in the php form) (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/557) +* [person] add address when creating a person (with the on-the-fly component or in the php form) (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/557) +* [person] add household creation API point (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/557) + +### 2021-04-29 + +* [person] prevent circular references in PersonDocGenNormalizer (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/527) +* [person] add maritalStatusComment to PersonDocGenNormalizer (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/582) +* Load relationships without gender in french fixtures +* Add command to remove old draft accompanying periods +* [parcours]: If users assings him/herself as referrer and job is not null. Update parcours job (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/578) + +### 2021-04-28 + +* [address] fix bug when editing address: update location and addressreferenceId + better update of the map in edition (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/593) +* [main] avoid address reference search on undefined post code (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/561) +* [person] prevent duplicate relationship in filiation/household graph (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/560) +* [Documents] Validate storedObject and allow for null data (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/565) +* [parcours]: Comments can be unpinned + edit/delete for all users that are allowed to edit parcours (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/566) + +### 2021-04-26 + +* [Datepickers] datepickers fixed when using keyboard to enter date (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/545) +* [social_action] Display 'agents traitants' in parcours resumé and social action list (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/568) +* [Person_search] Closed parcours shown within an accordeon that can be opened/closed (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/574) + +### 2021-04-24 + +* [notification email on course designation] allow raw string in email content generation +* [Accompanying period work] list evaluations associated to a work by startDate, and then by id, from the most recent to older +* [Documents] Change wording 'créer' to 'enregistrer' (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/634) +* [Parcours]: The number of 'mes parcours' displayed (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/572) +* [Hompage_widget]: Renaming of tabs and removal of social actions tab (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/570) +* [activity]: Ignore thirdparties when creating a social action via an activity (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/573) +* [parcours]: change wording of warning message and button when user is not associated to a household yet (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/590#note_918370943) +* [Accompanying period work evaluations] list documents associated to a work by creation date, and then by id, from the most recent to older +* [Course comment] add validationConstraint NotNull and NotBlank on comment content, to avoid sql error +* [Notifications] delay the sending of notificaiton to kernel.terminate +* [Notifications / Period user change] fix the sending of notification when user changes +* [Activity form] invert 'incoming' and 'receiving' in Activity form +* [Activity form] keep the same order for 'attendee' field in new and edit form +* [list with period] use "sameas" test operator to introduce requestor in list +* [notification email on course designation] allow raw string in email content generation +* [Accompanying period work] list evaluations associated to a work by startDate, and then by id, from the most recent to older +* [evaluation_document] changing date to datetime in order to display the time at which document was created (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/569) + + +### 2021-04-13 + +* [person] household address: add a form for editing the validFrom date (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/541) +* [person] householdmemberseditor: fix composition type bug in select form (vuejs) (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/543) +* [docgen] add more persons choices in docgen for course: amongst requestor (if person), resources of course (if person), and PersonResource (if person); +* [docgen] add a new context with a list of activities in course +* [docgen] add a comment in budget lines +* [notifications] allow to send a notification to an email address. The address receive an access link +* [adresses] add constraints in database to avoid errors later: postcode not null, and validfrom <= validto +* [accompanying work editor] add a label on document title input + +### 2021-04-07 + +* notification list: move action buttons outside of the toggle +* fix detecting of non-read notification +* filter users which are disabled in search user api +* order query for location and add pagination in list +* allow every person which has part for a workflow to see the workflow page +* able to see the workflow if the evaluation document has been deleted +* hardcode the list of supported mime types for edition with collabora +* list of accompanying course: allow to see the pinned comment in list_item + +### 2021-04-06 + +* [main] notification toggle read: correct js syntax for compilation in production (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/548) +* [parcours] Display of interlocuteurs changed to flex-table in parcours edit page to prevent cut-off of information (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/535) +* [activity] espace entre les boutons pour supprimer les documents + + +### continuous release in February and March + +* Creation of PickCivilityType, and implementation in PersonType and ThirdpartyType +* [person] Accompanying course evaluation documents: disable the WOPI edit link if mimetype not supported and if no keyInfos +(https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/585) +* [activity] display error messages above the form in creating a new location (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/481) +* [activity] show required field in activity edit/new by an asterix in the vuejs fields (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/494) +* [ACL] fix allow to see the course, event if the scope'course does not contains the scope's user +* [search] enforce limit of results for fetching rsults by search api https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/576 +* [activity] Fix delete button for document (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/554) +* [activity] Add return path the document generation (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/553) +* [person] add person ressource to person docgen normaliser (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/517) +* [person] AccompanyingCourseWorkEdit: fix deleting evaluation documents (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/546) +* [person] AccompanyingCourseWorkEdit: download existing documents (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/512) +* [person] AccompanyingCourseWorkEdit: replace document by a new one (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/511) +* [person] AccompanyingPeriodWork: add referrers to work, add doctrine event listener to add logged user to referrers collection and display a referrers list in work list (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/502) +* [person] AccompanyingPeriodWorkEvaluation: fix circular reference when serialising (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/495) +* [person] order accompanying period by opening date in search persons, person and household period lists (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/493) +* [parcours] autosave of the pinned comment for draft accompanying course (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/477) +* [main] filter user job in undispatch acc period to assign (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/472) +* [main] filter user job in undispatch acc period to assign (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/472) +* [person] Add url in accompanying period work evaluations entity and form (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/476) +* [person] Add document generation in admin and in person/{id}/document (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/464) +* [activity] do not override location if already exist (when validating new activity) (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/470) +* [parcours] Toggle emergency/intensity only by referrer (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/442) +* [docstore] Add an API entrypoint for StoredObject (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/466) +* [person] Add the possibility of uploading existing documents to AccPeriodWorkEvaluationDocument (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/466) +* [person] Add title to AccPeriodWorkEvaluationDocument (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/466) +* [person] Order social issues by the field "ordering" (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/388) +* [Person/Household list] when listing other simultaneous members of an household, exclude the members on person, not on members (avoid to show two membersship with the same person) +* [draft periods] add a delete button (if acl granted) on each draft period listed on draft period page (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/463) +* [Person] Display suffixText in RenderPerson, PersonText.vue, RenderPersonBox.vue (was made for displaying "enfant confie") (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/441) +* [budget]: budget enabled for persons and households (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/469) +* [person] residential address: show residential address or info in PersonRenderBox, refactor Residential Address (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/439) +* [thirdparty] Add a contact to a thirdparty from within onTheFly (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/345) +* [documents] Improve flex-table item-col placement when long buttons and long metadata +* [thirdparty] Fix display of multiple contact badges so they wrap onto next line (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/482) +* [confidential] Fix position of toggle button so it does not cover text nor fall outside of box (no issue) +* [parcours] Fix edit of both thirdparty and contact name (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/474) +* [template] do not list inactive templates (for doc generator) +* [household] bugfix if position of member is null, renderbox no longer throws an error (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/480) +* [parcours] location cannot be removed if linked to a user (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/478) +* [person] email added to twig personRenderbox (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/490) +* [activity] Only youngest descendant is kept for social issues and actions (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/471) +* [person] Add link to current household in person banner (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/484) +* [address] person badge in address history changed to open OnTheFly with all person info (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/489) +* [person] Change 'personne' with 'usager' and '&' with 'ET' (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/499) +* [thirdparty] Add parameter condition to display centers or not (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/500) +* [phonenumber] Remove placeholder in phonenumber field (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/496) +* [person_resource] separate create page created to avoid confusion (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/504) +* [contact] add contact button color changed plus the pipe at the side removed (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/506) +* [thirdparty] For contacts show current civility/profession in edit form + fix saving of edited information (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/491) +* [household] create-edit household composition placed in separate page to avoid confusion (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/505) +* [blur] Improved positioning of toggle icon (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/486) +* [thirdparty] add firstname field to thirdparty 'child' or 'contact' types (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/508) +* [household] create-edit household composition placed in separate page to avoid confusion (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/505) +* [blur] Improved positioning of toggle icon (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/486) +* [parcours] List of parcours for a specific user so they can be reassigned in case of absence (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/509) +* [thirdparty] Thirdparty view page, english text translated (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/534) +* [social_action] Translation changed in evaluation section (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/512) +* [filiation] Possible to add person (or create onthefly) to add to filiation graph + add relation (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/519) +* [household] Within parcours listing page of household add create button (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/560) +* [person_resource] bugfix when adding thirdparty or freetext resource + prevent personOwner themselves to be added. (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/526) +* [aside_activity] style correction + sticky-form create button (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/529) +* [budget] order within the menu adjusted (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/592) +* [onthefly] fix create person. Bug was noticed in filiation (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/591) +* [parcours] Create document buttons made sticky (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/532) +* [person] Trailing guillemet removed (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/530) +* [notification] Display of social action within workflow notification set to display block (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/537) +* [onthefly] trim trailing whitespace in email of person and thirdparty (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/542) + +* [action] Only youngest descendant is kept for social issues and actions (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/471) +## Test releases + +### test release 2022-02-21 + +* [notifications] Word 'un' changed to number '1' for notifications in user menu (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/483) +* [documents] 'gabarit' changed to 'modèle' (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/405) +* [person_resources] Menu name and order changed (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/460) +* workflow: fix sending notifications +* [thirdparty] Extend the thirdparty search to thirdparty children (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/448) +* [person]: AddPersons: allow creation of person or thirdparty only (no users) (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/422) +* [person]: AddPersons: allow creation of person or thirdparty depending on allowed types (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/422) +* [person]: AddPersons: add suggestion of name when creating new person or thirdparty (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/422) +* [main] Address: fix small bug: when modifying an address without street (isNoAddress), also check errors if street is an empty string as back-end change null value to empty string for street (and streetNumber) +* [main] Address: stronger client-side validation of addresses (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/449) +* [person] accompanying course: filter suggested entities by open participations (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/415) +[activity] can click through the cross icon for removing person in concerned group (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/476) +[activity] correct associated persons by considering only open participations (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/476) +* [person_resources]: Renderboxes used to display person/thirdparty info (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/465) +* [Household]: Add end date in HouseholdMember form for 'enfant hors menage' (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/434) +* [homepage_widget]: If no sender then display as 'notification automatique' (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/435) +* [parcours]: Order social activities and only display most recent three in parcours resumé (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/481) +* [3party]: 3party: redirect to parent when contact (child) is opened in view page +* [parcours / addresses]: launch an event when a person change address (either through changing household or because the household is associated to a new address). If the person is localising a course, the course location go back to a temporarily address. +* [thirdparty]: address/phonenumber/email/fonction displayed in thirdpartyrenderbox (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/401) +* [thirdparty_contact]: in search results the 'qualité' is displayed (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/465) +* [bug]: fix confidential toggle of address in thirdpartyrenderbox (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/460) + + + +### test release 2022-02-14 + +* AddPersons: remove ul-li html tags from AddPersons (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/419) +* [doc-generator] do not set required fields for mainPerson, person1, person2 (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement#456) +* [doc-generation] add age and obele in the mainPerson, person1 and person2 list + add obele in person renderString if addAge (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/370) +* [person] accompanying course work: fix on-the-fly update of thirdParty +* fix normalisation of accompanying course requestor api (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/378) +* [person] add a returnPath when clicking on some Person or ThirdParty badge (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/427) +* [person] accompanying course work: fix on-the-fly update of thirdParty +* [on-the-fly] close modal only after validation +* [person] correct thirdparty PATCH url + add email and altnames in AddPerson and serializer (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/433) +* change order for accompanying course work list +* [parcours]: Mes parcours brouillon added to user menu (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/440) +* [Documents]: List view adapted to display more information (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/414) +* [person]: style fix in parcours listing per person. (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/432) +* [parcours]: Only the referrer can toggle the intensity of the parcours (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/442) +* [household]: display address of current household (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/415) +* ajoute un ordre dans les localisation (api) +* [pick entity]: fix translations in modal (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/419) +* [homepage_widget]: fix translation on emergency badge (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/440) +* [person]: create person and household added to button dropdown (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/454) +* display full address in address.text in normalization. Adapt AddressRenderBox +* [address]: Correction residential address 'depuis le' (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/459) +* [Documents]: List view adapted to display more information (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/414) +* [Thirdparty_contact]: address blurred if confidential in view page (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/450) +* [thirdparty] Add a contact to a thirdparty from within onTheFly (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/345) + + +### test release 2021-02-01 + +* renommer "dossier numéro" en "parcours numéro" dans les résultats de recherche +* renomme date de début en date d'ouverture dans le formulaire parcours +* [homepage widget] improve content tables, improve counter pluralization with style on number +* [notification lists] add comments counter information +* [workflows] fix popover header with previous transition +* [parcours]: validation + message for closing parcours adjusted. +* [household]: household composition double edit button replaced by a delete action (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/426) +[fast_actions] improve fast-actions buttons override mechanism, fix https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/413 +[homepage widget] add vue homepage_widget with asynchone loading, give a global view resume of the user concerned actions, notifications, etc. +* [person]: Comment on marital status is possible even if marital status is not defined (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/421) +* [parcours]: In the list of person results the requestor is not displayed if defined as anonymous (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/424) +* [bugfix]: modal closes and newly created person/thirdparty is selected when multiple persons/thirdparties are created through the modal (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/429) +* [person_resource]: Onthefly button added to view person/thirdparty and badge differentiation for a contact-thirdparty (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/428) +* [workflow][notification] improve how notifications and workflows are 'attached' to entities: contextual list, counter, buttons and vue modal +* [AddAddress] disable multiselect search, and rely only on most pertinent Cities and Street computed backend +* [fast_actions] improve fast-actions buttons override mechanism, fix https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/413 +* [homepage widget] add vue homepage_widget with asynchone loading, give a global view resume of the user concerned actions, notifications, etc. +* [thirdparty] Add a contact to a thirdparty from within onTheFly (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/345) +* [homepage widget] add vue homepage_widget with asynchone loading, give a global view resume of the user concerned actions, notifications, etc. + + +### test release 2021-01-31 + +* [person] accompanying course: optimisation: do not fetch some resources for the banner (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/409) +* [person] accompanying course: close modal when edit participation (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/420) +* [person] accompanying course: treat validation error when editing on-the-fly entities (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/420) +* [activity] show activity attendee (présence) in the activity list (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/412) +* [activity] admin: change validation rule for social action visible field (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/413) +* [parcours]: component added to change the opening date of a parcours (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/411) +* [search]: listing of parcours display changed (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/410) +* [user]: page with accompanying periods to which is user is referent (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/408) +* [person] age added to renderstring + renderbox/ vue component created to display person text (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/389) +* [household member editor] allow to push to existing household + + +### test release 2021-01-28 + +* [person] improve filiations vis graph: disable physics, use chill colors for persons-households-course, increase label of relations, remove labels on household arrows and other improvements (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/286, https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/362) +* [activity] Order activity by date and by id (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/364) +* [main] increase length of 4 Address fields (change to TEXT, no size limits) (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/277) +* [main] Add confidential option for address, in edit and view (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/165) +* [person] name suggestions within create person form when person is created departing from a search input (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/377) +* [person] Add residential address entity, form and list for each person +* [aside_activity]: dynamicUserPickerType used (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/399) +* dispatching list + + +### test release 2021-01-26 + +* [parcours] comments truncated if too long + link added (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/406) +* [person]: possibility to add person resources (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/382) +* [person ressources]: module added + + +### test release 2022-01-24 + +* [person] name suggestions within create person form when person is created departing from a search input (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/377) +* [notification: formulaire création] descend la box avec la description dans le bas du formulaire +* [notification for activity]: fix link to activity +* [notification] add "URGENT" before accompanying course with emergency = true +* [notification] add a "read more" button on system notification +* [notification] add `[Chill]` in the subject of each notification, automatically +* [notification] add a counter for notification in activity list and accompanying period list, and search results +* [parcours] bugfix if deathdate is not defined (eg. for a thirdparty) parcours is still displayed. Gave error before. +* [workflow] add breadcrumb to show steps +* [popover] add popover html popup mechanism (used by workflow breadcrumb) +* [templates] improve updatedBy macro in item metadatas +* [parcours]: bug fix when comment is pinned all other comments remain in the collection (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/385) +* [workflow] + * add My workflow section with my opened subscriptions + * apply workflow on documents, accompanyingCourseWork and Evaluations +* [wopi-link] a new vue component allow to open wopi link in a fullscreen chill-themed modal + +### test release 2022-01-19 +* vuejs: add dead information on all on-the-fly person render boxes, in vis graph and other templates (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/271) +* [thirdparty] fix bug in 3rd party view: types was replaced by thirdPartyTypes +* [main] location form type: fix unmapped address field (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/246) +* [activity] fix wrong import of js assets for adding and viewing documents in activity (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/83 & https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/176) +* [person]: space added between deathdate and age in twig renderbox (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/380) +* [forms] dynamic picker types for user/person/thirdparty types created (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/386) + +### test release 2022-01-17 + +* [main] Add editableByUser field to locationType entity, adapt the admin template and add this condition in the location-type endpoint (see https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/297) +* [main] Add mainLocation field to User entity and add it in user form type +* rewrite page which allow to select activity +* [main] Add mainLocation field to User entity and add it in user form type +* [course list in person context] show full username/label for ref +* [accompanying period work] remove the possibility to generate document from an accompanying period work +* vuejs: add validation on required fields for AddPerson, Address and Location components +* vuejs: treat 422 validation errors in locations and AddPerson components +* [person]: space added between deathdate and age in twig renderbox (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/380) + +## Test releases +* vuejs: add validation on required fields for AddPerson, Address and Location components +* vuejs: treat 422 validation errors in locations and AddPerson components +* [person]: space added between deathdate and age in twig renderbox (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/380) + +### test release 2022-01-12 + +* fix thirdparty normalizer on telephone field: https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/322 + +### test release 2022-01-11 + +* vuejs: translate in French all multiselect widgets +* [address] define address lines according postal standards for France and Belgium (default) and change AddressRender, chill_entity_render_box and AddressRenderBox.vue +* [household] change translations (champs-libres/departement-de-la-vendee/accent-suivi-developpement#109) +* [household] add address i18n in household component (champs-libres/departement-de-la-vendee/accent-suivi-developpement#158) +* [household] add on the fly i18n in household component +* [household] redirect to the household page when a household is created from a person (champs-libres/departement-de-la-vendee/accent-suivi-developpement#175) +* [household] household member editor: display alert if some members have already an household (champs-libres/departement-de-la-vendee/accent-suivi-developpement#172) +* [household] household member editor: do not add in new members if the member is included in the members of household (champs-libres/departement-de-la-vendee/accent-suivi-developpement#123) +* [household] household member editor: remove markNoAddress button (champs-libres/departement-de-la-vendee/accent-suivi-developpement#109) +* [person]: ordering fields in add person (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/61) +* [person]: Add email and alt names in add person (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/61) +* [accompanyingCourse] Add a delete action and delete buttons to delete a accompanying course when step = DRAFT (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/64) +* [accompanyingCourse] Add a administrative location in the accompanying course, set the user current location as default, allow to select a location in a select field and do not allow to confirm the accompanying course if location is empty. +* [accompanyingCourse] Add the administrative location in the available variables for document generation +* AddAddress: optimize loading: wait for the user finish typing; +* UserPicker: fix bug with deprecated role +* docgen: add base context + tests +* docgen: add age for person +* [household menu] fix filiation order https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/265 +* [AddAddress]: optimize loading: wait for the user finish typing; +* [UserPicker]: fix bug with deprecated role +* [docgen]: add base context + tests +* [docgen]: add age for person +* [task]: fix dropdown menu style + fix bug in singleTaskController (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/338) +* Household: fix bug when moving person on the same day (see https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/281) +* Household: show date validFrom and validTo when moving +* address reference: add index for refid +* [accompanyingCourse_work] fix styles conflicts + fix bug with remove goal (remove goals one at a time) +* [accompanyingCourse] improve masonry on resume page, add origin +* [notification] new notification interface, can be associated to AccompanyingCourse/Period, Activities. + * List notifications, show, and comment in User section + * Notify button and contextual notification box on associated objects pages +* [accompanyingCourse] add a comment for each resource associated. A modal allow to save comment. Comment is displayed in on-the-fly show modal of the accompanyingCourse context (edit page + resume page). + +### test release 2021-12-14 + +* [asideactivity] creation of aside activity category fixed (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/262) +* [vendee/person] fix typo "situation professionelle" => "situation professionnelle" +* [main] add availableForUsers condition from locationType in the location API endpoint (champs-libres/departement-de-la-vendee/accent-suivi-developpement#248) +* [main] add the current location of the user as API point + add it in the activity location list (champs-libres/departement-de-la-vendee/accent-suivi-developpement#247) +* [activity] improve show/new/edit templates, fix SEE and SEE_DETAILS acl +* [badges] create specific badge for TMS, and make person/thirdparty badges clickable with on-the-fly modal in : + * concerned groups items (activity, calendar) + * accompanyingCourseWork lists + * accompanyingCourse lists +* [acompanyingCourse] add initial comment on Resume page +* [person] create button full width (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/330) + +### test release 2021-12-11 + +* [main] add order field to civility +* [main] change address format in case the country is France, in Address render box and address normalizer +* [person] add validator for accompanying period with a test on social issues (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/76) +* [activity] fix visibility for location +* [origin] fix origin: use correctly the translatable strings + * /!\ everyone must update the origin table. As there is only one row, execute `update chill_person_accompanying_period_origin set label = jsonb_build_object('fr', 'appel téléphonique');` +* [person] redirect bug fixed. +* [action] add an unrelated issue within action creation. +* [origin] fix origin: use correctly the translatable strings + * /!\ everyone must update the origin table. As there is only one row, execute `update chill_person_accompanying_period_origin set label = jsonb_build_object('fr', 'appel téléphonique');` +* [main] change order of civilities in civility fixtures (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/191) +* [person] set min attr in the minimum of children field (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/191) +* [person] add marital status date in person view (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/191) +* [person] show number of children + allow set number of children to null (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/191) +* [person] show acceptSMS option (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/191) +* [person] add death information in person render box in twig and vue render boxes (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/191) +* [asideactivity] creation of aside activity category fixed (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/262) +* [vendee/person] fix typo "situation professionelle" => "situation professionnelle" +* [accompanyingcourse_work] Changes in layout/behavior of edit form (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/321) +* [badge-entity] design coherency between pills badge-person and 3 kinds of badge-thirdparty +* [AddPersons] suggestions row are clickable, not only checkbox + +### test release 2021-12-06 + +* [main] address: use search API end points for getting postal code and reference address (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/316) +* [main] address: in edit mode, select the encoded values in multiselect for address reference and city (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/316) +* [person search] fix bug when using birthdate after and birthdate before +* [person search] increase pertinence when lastname begins with search pattern +* [activity/actions] Améliore la cohérence du design entre + * la page résumé d'un parcours (liste d'actions récentes et liste d'activités récentes) + * la page liste des actions + * la page liste des activités (contexte personne / contexte parcours) +* [household] field to edit wheter person is titulaire of household or not removed (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/322) +* [activity] create work if a work with same social action is not associated to the activity +* [visgraph] improve and fix bugs on vis-network relationship graph +* [bugfix] posting of birth- and deathdate through api fixed. +* [suggestions] improve suggestions lists + +### Test release 2021-11-19 - bis + +* [household] do not allow to create two addresses on the same date +* [activity] handle case when there is no social action associated to social issue +* [activity] layout for issues / actions +* [activity][bugfix] in edit mode, the form will now load the social action list + + +### Test release 2021-11-29 + +* [person] suggest entities (person | thirdparty) when creating/editing the accompanying course (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/119) +* [activity] add custom validation on the Activity class, based on what is required from the ActivityType (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/188) +* [main] translate multiselect messages when selecting/creating address +* [main] set the coordinates of the city when creating a new address OR choosing "pas d'adresse complète" +* Use the user.label in accompanying course banner, instead of username; +* fix: show validation message when closing accompanying course; +* [thirdparty] link from modal to thirdparty detail page fixed (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/228) +* [assets] new asset to style suggestions lists (with add/remove item link) (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/258) +* [accompanyingCourseWorkEdit] improves hyphenation and line breaks for long badges +* [acompanyingCourse] improve Resume page + * complete all needed informations, + * actions and activities are clickables, + * better placement with js masonry blocks on top of content area, + * https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/101 + * https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/295 +* [activity/calendar] on show page, concerned groups of persons table adapt itself to isVisibles options +* [activity] remove the "plus" button in activity list +* [activity] check ACL on activity list in person context +* [list for accompanying course in person] filter list using ACL +* [validation] toasts are displayed for errors when modifying accompanying course (generalization required). +* [period] only the user can enable confidentiality +* add an endpoint for checking permissions. See https://gitlab.com/Chill-Projet/chill-bundles/-/merge_requests/232 +* [activity] for a new activity: suggest and create on-the-fly locations based on the accompanying course location + location of the suggested parties +* [calendar] for a new rdv: suggest and create on-the-fly locations based on the accompanying course location + location of the suggested parties +* [period] Validation added when period is confidential and confirmed -> user cannot be null. + + +## Test releases + +### Test release 2021-11-22 + +* [activity] delete admin_user_show in twig template because this route is not defined and should be defined +* [activity] suggest requestor, user and ressources for adding persons|user|3rdparty +* [calendar] suggest persons, professionals and invites for adding persons|3rdparty|user +* [activity] take into account the restrictions on person|thirdparties|users visibilities defined in ActivityType +* [main] Add currentLocation to the User entity + add a page for selecting this location + add in the user menu (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/133) +* [activity] add user current location as default location for a new activity (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/133) +* [task] Select2 field in task form to allow search for a user (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/167) +* remove "search by phone configuration option": search by phone is now executed by default +* remplacer le classement par ordre alphabétique par un classement par ordre de pertinence, qui tient compte: + * de la présence d'une string avec le nom de la ville; + * de la similarité; + * du fait que la recherche commence par une partie du mot recherché +* ajouter la recherche par numéro de téléphone directement dans la barre de recherche et dans le formulaire recherche avancée; +* ajouter la recherche par date de naissance directement dans la barre de recherche; +* ajouter la recherche par ville dans la recherche avancée +* ajouter un lien vers le ménage dans les résultats de recherche +* ajouter l'id du parcours dans les résultats de recherche +* ajouter le demandeur dans les résultats de recherche +* ajout d'un bouton "recherche avancée" sur la page d'accueil +* [person] create an accompanying course: add client-side validation if no origin (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/210) +* [person] fix bounds for computing current person address: the new address appears immediatly +* [docgen] create a normalizer and serializer for normalization on doc format +* [person normalization] the key center is now "centers" and is an array. Empty array if no center +* [accompanyingCourse] Ability to close accompanying course (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/296) +* [task] Select2 field in task form to allow search for a user (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/167) +* [list result] show all courses, except ones with period closed +* [accompanyingCourse] improve banner with small carousel to display slide social-issues or slide associated persons (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/69) + +### Test release 2021-11-15 + +* [main] fix adding multiple AddresseDeRelais (combine PickAddressType with ChillCollection) +* [person]: do not suggest the current household of the person (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/51) +* [person]: display other phone numbers in view + add message in case no others phone numbers (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/184) +* unnecessary whitespace removed from person banner after person-id + double parentheses removed (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/290) +* [person]: delete accompanying period work, including related objects (cascade) (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/36) +* [address]: Display of incomplete address adjusted. +* [household]: improve relationship graph + * add form to create/edit/delete relationship link, + * improve graph refresh mechanism + * add feature to export canvas as image (png) +* [person suggest] In widget "add person", improve the pertinence of persons when one of the names starts with the pattern; +* [person] do not ask for center any more on person creation +* [3party] do not ask for center any more on 3party creation + +## Test releases + +### Test release 2021-11-08 + +* [person]: Display the name of a user when searching after a User (TMS) +* [person]: Add civility to the person +* [person]: Various improvements on the edit person form +* [person]: Set available_languages and available_countries as parameters for use in the edit person form +* [activity] Bugfix: documents can now be added to an activity. +* [tasks] improve tasks with filter order +* [tasks] refactor singleControllerTasks: limit the number of conditions from the context +* [validations] validation of accompanying period added: no duplicate participations or resources (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/60). +* [renderbox] If gender of person is not defined, no icon is displayed instead of neuter-icon (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/129). +* [confidential information] module added to blur confidential information (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/248). +* refactor `AuthorizationHelper` and `UserACLAwareRepository` to fix constructor, and separate logic for parent role helper into `ParentRoleHelper` +* [main]: filter location and locationType in backend: exclude NULL names, only active and availableToUsers +* [activity]: perform client-side validation & show/hide fields in the "new location" modal +* [person]: normalize person with CenterResolverDispatcher and handle case where center is null or multiple in PersonRenderBox +* [docstore] voter for PersonDocument and AccompanyingCourseDocument on the 2.0 way (using VoterHelperFactory) +* [docstore] add authorization check inside controller and menu +* [activity]: fix inheritance for role `ACTIVITY FULL` and add missing acl in menu +* [person] show current address in search results +* [person] show alt names in search results +* [admin]: links to activity admin section added again. +* [household]: endDate field deleted from household edit form. +* [household]: View accompanying periods of current and old household members. +* [tasks]: different layout for task list / my tasks, and fix link to tasks in alert or in warning +* [admin]: links to activity admin section added again. +* [household]: household addresses ordered by ValidFrom date and by id to show the last created address on top. +* [socialWorkAction]: display of social issue and parent issues + banner context added. +* [DBAL dependencies] Upgrade to DBAL 3.1 + +### Test release 2021-10-27 + +* [person]: delete double actions buttons on search person page +* [person]: accompanying course work: remove creation date display the list of work + handle case when end date is null +* [main]: Add new pages with a menu for managing location and location type in the admin +* [main]: Add some fixtures for location type +* [calendar]: Pass the location when transforming a calendar item (rdv) into an activity +* [calendar]: Add a user menu for "my calendar" + +### Test release 2021-10-18 + +* [3party]: french translation of contact and company +* [3party]: show parent in list +* [3party]: change color for badge "child" +* [3party]: fix address creation +* [household members editor] finalisation of editor +* [AccompanyingCourse banner]: replace translation referrer (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/70) +* [Location]: add location system in activity and RV (calendar). User can choose in location list or create a new location. +* [household]: add relationship page with dynamic data visualisation graph + +## Test releases + +### Test release 2021-10-11 + +* Address: zoom on postal code geometry + fix origin of manually entered postal code + +* in the Address vue component, order the postal code and street address by alphabetic and numeric order + +* add 3 new fields to PostalCode and adapt postal code command and fixtures + +* [Aside activity] Fixes for aside activity + + * categories with child + * fast creation buttons + * add ordering for types + +* [AccompanyingCourse Resume page] dashboard for AccompanyingCourseWork and for Activities; +* Improve badges behaviour with small screens; + +* [ThirdParty]: + + * third party list + * create a kind contact/institution when create a new thirdparty, and set contact embedded as kind=child; + * filter thirdparties in list + +* [FilterOrder]: add development kit for generating filter and ordering in list +* [Capitalization of names] person names are capitalized on creation, on prePersist event +* [On-The-Fly] modale works for showing, editing and creating person or thirdparty ; +* [AccompanyingCourse Resume page] associated persons list, can see household when hover, and with show on-the-fly modale when clicking person ; + +### test release 2021-10-04 + +* [Household editor][UI] Update how household suggestion and addresses are picked; + + See https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/80 +* [AddAddress] Handle address suggestion; +* [CenterType][Create a person] when overriding the ACL rules, allow to show a PickCenterType + when no centers are reachable by the default ACL. +* [Household] Show comment event if no address are associated with the household; +* [Person results] Add requestor into search results: + + * a badge "requestor" is shown into search results; + * periods where the person is only requestor (without participating) are also shown; + + Issues: + + * https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/13 + * https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/199 +* [Person form] "accept sms" not required: + + https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/37 + https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/221 + +* [Household editor] suggest only temporarily addresses; + See https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/82 +* On-The-Fly modale works for showing, editing and creating person and thirdparty ; +* AccompanyingCourse Resume page: list associated persons by household, see household when hover, and show on-the-fly modale when clicking on person ; +* [AddAddress] Handle address suggestion; +* [AddAddress][Entity address]: add a link between address and address reference; +* [Household editor] suggest household by comparing the temporary addresses from courses; + + See https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/81 +* On-The-Fly modale works for showing, editing and creating person and thirdparty + + +## Test released + + + +## Stable releases + +No stable releases for v2+ + diff --git a/.changie.yaml b/.changie.yaml new file mode 100644 index 000000000..e77a5ecf3 --- /dev/null +++ b/.changie.yaml @@ -0,0 +1,31 @@ +changesDir: .changes +unreleasedDir: unreleased +headerPath: header.tpl.md +changelogPath: CHANGELOG.md +versionExt: md +versionFormat: '## {{.Version}} - {{.Time.Format "2006-01-02"}}' +kindFormat: '### {{.Kind}}' +changeFormat: >- + '* {{- if not (eq .Custom.Issue "") }}([#{{ .Custom.Issue }}](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/{{ .Custom.Issue }})){{- end }} {{.Body}}' +custom: + - key: Issue + label: Issue number (on chill-bundles repository) (optional) + optional: true + type: int + minInt: 1 +kinds: + - label: Feature + auto: minor + - label: Deprecated + auto: minor + - label: Fixed + auto: patch + - label: Security + auto: patch + - label: DX + auto: patch +newlines: + afterChangelogHeader: 1 + beforeChangelogVersion: 1 + endOfVersion: 1 +envPrefix: CHANGIE_ diff --git a/CHANGELOG.md b/CHANGELOG.md index b2f951479..5475b20b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,16 +1,19 @@ # Changelog - All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to +adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), +and is generated by [Changie](https://github.com/miniscruff/changie). -* [Semantic Versioning](https://semver.org/spec/v2.0.0.html) for stable releases; -* date versioning for test releases -## Unreleased +## 2.0.0 + +* this is a release to relaunch our proceess of release with semantic versioning + +## Test releases + +### 2.0.0-beta3 - * [person][export] Fixed: rename the alias for `accompanying_period` to `acp` in filter associated with person * [activity][export] Feature: improve label for aliases in "Filter by activity type" * [activity][export] DX/Feature: use of an `ActivityTypeRepositoryInterface` instead of the old-style EntityRepository @@ -18,9 +21,6 @@ and this project adheres to * [person][export] Fixed: use left join for related entities in accompanying course aggregators * [workflow] Feature: allow user to copy and send manually the access link for the workflow * [workflow] Feature: show the email addresses that received an access link for the workflow - -## Test releases - ### 2.0.0-beta2 * [workflow]: Fixed: the notification is sent when the user is added to the first step. From 1b9fea04ce209046b43ac6e59209c7c05a28eb8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 1 Jun 2023 10:26:35 +0200 Subject: [PATCH 118/321] [changies] fixes and allow multiline messages --- .changie.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.changie.yaml b/.changie.yaml index e77a5ecf3..83fd9770a 100644 --- a/.changie.yaml +++ b/.changie.yaml @@ -6,13 +6,16 @@ versionExt: md versionFormat: '## {{.Version}} - {{.Time.Format "2006-01-02"}}' kindFormat: '### {{.Kind}}' changeFormat: >- - '* {{- if not (eq .Custom.Issue "") }}([#{{ .Custom.Issue }}](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/{{ .Custom.Issue }})){{- end }} {{.Body}}' + * {{ if not (eq .Custom.Issue "") }}([#{{ .Custom.Issue }}](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/{{ .Custom.Issue }})) {{- end }}{{.Body}} custom: - key: Issue label: Issue number (on chill-bundles repository) (optional) optional: true type: int minInt: 1 +body: + # allow multiline messages + block: true kinds: - label: Feature auto: minor From 5196d26a3ea7ccac135fdda0f4f5fc93a2d70bf3 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Thu, 1 Jun 2023 10:44:14 +0200 Subject: [PATCH 119/321] FEATURE [translations] add translations --- src/Bundle/ChillCalendarBundle/translations/messages.fr.yml | 6 ++++++ src/Bundle/ChillDocStoreBundle/translations/messages.fr.yml | 1 - src/Bundle/ChillPersonBundle/translations/messages.fr.yml | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Bundle/ChillCalendarBundle/translations/messages.fr.yml b/src/Bundle/ChillCalendarBundle/translations/messages.fr.yml index 5e1fc971a..99aae1082 100644 --- a/src/Bundle/ChillCalendarBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillCalendarBundle/translations/messages.fr.yml @@ -147,3 +147,9 @@ CHILL_CALENDAR_CALENDAR_EDIT: Modifier les rendez-vous CHILL_CALENDAR_CALENDAR_DELETE: Supprimer les rendez-vous CHILL_CALENDAR_CALENDAR_SEE: Voir les rendez-vous + +generic_doc: + filter: + keys: + accompanying_period_calendar_document: Document des rendez-vous + person_calendar_document: Document des rendez-vous de la personne diff --git a/src/Bundle/ChillDocStoreBundle/translations/messages.fr.yml b/src/Bundle/ChillDocStoreBundle/translations/messages.fr.yml index 4fa41f180..1dde57eee 100644 --- a/src/Bundle/ChillDocStoreBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillDocStoreBundle/translations/messages.fr.yml @@ -26,7 +26,6 @@ generic_doc: filter: keys: accompanying_course_document: Document du parcours - accompanying_period_calendar_document: Document des rendez-vous date-range: Date du document # delete diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index a344ac50d..9b30e3a0b 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -1236,3 +1236,4 @@ generic_doc: filter: keys: accompanying_period_work_evaluation_document: Document des actions d'accompagnement + person_document: Documents de la personne From 59e1e02b92b3bc66a0dfb607c9455284138541f3 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Thu, 1 Jun 2023 10:45:55 +0200 Subject: [PATCH 120/321] FEATURE [calendar][docs] try to implement showing calendar docs from parcours context in person context --- .../PersonCalendarGenericDocProvider.php | 76 ++++++++++++++----- ...anyingPeriodCalendarGenericDocRenderer.php | 3 +- 2 files changed, 58 insertions(+), 21 deletions(-) diff --git a/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Providers/PersonCalendarGenericDocProvider.php b/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Providers/PersonCalendarGenericDocProvider.php index 12235f10a..bed04414c 100644 --- a/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Providers/PersonCalendarGenericDocProvider.php +++ b/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Providers/PersonCalendarGenericDocProvider.php @@ -19,6 +19,7 @@ use Chill\DocStoreBundle\GenericDoc\FetchQuery; use Chill\DocStoreBundle\GenericDoc\FetchQueryInterface; use Chill\DocStoreBundle\GenericDoc\GenericDocForPersonProviderInterface; use Chill\PersonBundle\Entity\Person; +use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodWorkVoter; use DateTimeImmutable; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\EntityManagerInterface; @@ -35,6 +36,38 @@ final class PersonCalendarGenericDocProvider implements GenericDocForPersonProvi ) { } + + private function addWhereClausesToQuery(FetchQuery $query, ?\DateTimeImmutable $startDate = null, ?\DateTimeImmutable $endDate = null, ?string $content = null): FetchQuery + { + $storedObjectMetadata = $this->em->getClassMetadata(StoredObject::class); + + if (null !== $startDate) { + $query->addWhereClause( + sprintf('doc_store.%s >= ?', $storedObjectMetadata->getColumnName('createdAt')), + [$startDate], + [Types::DATE_IMMUTABLE] + ); + } + + if (null !== $endDate) { + $query->addWhereClause( + sprintf('doc_store.%s < ?', $storedObjectMetadata->getColumnName('createdAt')), + [$endDate], + [Types::DATE_IMMUTABLE] + ); + } + + if (null !== $content) { + $query->addWhereClause( + sprintf('doc_store.%s ilike ?', $storedObjectMetadata->getColumnName('title')), + ['%' . $content . '%'], + [Types::STRING] + ); + } + + return $query; + } + /** * @throws MappingException */ @@ -72,33 +105,36 @@ final class PersonCalendarGenericDocProvider implements GenericDocForPersonProvi [Types::INTEGER] ); - if (null !== $startDate) { - $query->addWhereClause( - sprintf('doc_store.%s >= ?', $storedObjectMetadata->getColumnName('createdAt')), - [$startDate], - [Types::DATE_IMMUTABLE] + // get the documents associated with accompanying periods in which person participates + $or = []; + $orParams = []; + $orTypes = []; + foreach ($person->getAccompanyingPeriodParticipations() as $participation) { + if (!$this->security->isGranted(CalendarVoter::SEE, $participation->getAccompanyingPeriod())) { + continue; + } + + $or[] = sprintf( + '(calendar.%s = ? AND cd.%s BETWEEN ?::date AND COALESCE(?::date, \'infinity\'::date))', + $calendarMetadata->getSingleAssociationJoinColumnName('accompanyingPeriod'), + $storedObjectMetadata->getColumnName('createdAt') ); + $orParams = [...$orParams, $participation->getAccompanyingPeriod()->getId(), + DateTimeImmutable::createFromInterface($participation->getStartDate()), + null === $participation->getEndDate() ? null : DateTimeImmutable::createFromInterface($participation->getEndDate())]; + $orTypes = [...$orTypes, Types::INTEGER, Types::DATE_IMMUTABLE, Types::DATE_IMMUTABLE]; } - if (null !== $endDate) { - $query->addWhereClause( - sprintf('doc_store.%s < ?', $storedObjectMetadata->getColumnName('createdAt')), - [$endDate], - [Types::DATE_IMMUTABLE] - ); + if ([] === $or) { + $query->addWhereClause('TRUE = FALSE'); + + return $query; } - if (null !== $content) { - $query->addWhereClause( - sprintf('doc_store.%s ilike ?', $storedObjectMetadata->getColumnName('title')), - ['%' . $content . '%'], - [Types::STRING] - ); - } +// $query->addWhereClause(sprintf('(%s)', implode(' OR ', $or)), $orParams, $orTypes); - dump($query); + return $this->addWhereClausesToQuery($query, $startDate, $endDate, $content); - return $query; } /** diff --git a/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Renderers/AccompanyingPeriodCalendarGenericDocRenderer.php b/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Renderers/AccompanyingPeriodCalendarGenericDocRenderer.php index 0f680797c..d9636d99d 100644 --- a/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Renderers/AccompanyingPeriodCalendarGenericDocRenderer.php +++ b/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Renderers/AccompanyingPeriodCalendarGenericDocRenderer.php @@ -13,6 +13,7 @@ namespace Chill\CalendarBundle\Service\GenericDoc\Renderers; use Chill\CalendarBundle\Repository\CalendarDocRepository; use Chill\CalendarBundle\Service\GenericDoc\Providers\AccompanyingPeriodCalendarGenericDocProvider; +use Chill\CalendarBundle\Service\GenericDoc\Providers\PersonCalendarGenericDocProvider; use Chill\DocStoreBundle\GenericDoc\GenericDocDTO; use Chill\DocStoreBundle\GenericDoc\Twig\GenericDocRendererInterface; @@ -27,7 +28,7 @@ final class AccompanyingPeriodCalendarGenericDocRenderer implements GenericDocRe public function supports(GenericDocDTO $genericDocDTO, $options = []): bool { - return $genericDocDTO->key === AccompanyingPeriodCalendarGenericDocProvider::KEY; + return $genericDocDTO->key === AccompanyingPeriodCalendarGenericDocProvider::KEY || $genericDocDTO->key === PersonCalendarGenericDocProvider::KEY; } public function getTemplate(GenericDocDTO $genericDocDTO, $options = []): string From 5dc1cbce487fc0ea1ef96365271c89e11c383a60 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Thu, 1 Jun 2023 11:01:29 +0200 Subject: [PATCH 121/321] FEATURE [activity][docs] generic doc for activity documents in person context --- ...rsonActivityDocumentACLAwareRepository.php | 197 ++++++++++++++++++ .../PersonActivityGenericDocProvider.php | 57 +++++ 2 files changed, 254 insertions(+) create mode 100644 src/Bundle/ChillActivityBundle/Repository/PersonActivityDocumentACLAwareRepository.php create mode 100644 src/Bundle/ChillActivityBundle/Service/GenericDoc/Providers/PersonActivityGenericDocProvider.php diff --git a/src/Bundle/ChillActivityBundle/Repository/PersonActivityDocumentACLAwareRepository.php b/src/Bundle/ChillActivityBundle/Repository/PersonActivityDocumentACLAwareRepository.php new file mode 100644 index 000000000..862deb1ab --- /dev/null +++ b/src/Bundle/ChillActivityBundle/Repository/PersonActivityDocumentACLAwareRepository.php @@ -0,0 +1,197 @@ +em = $em; + $this->centerResolverManager = $centerResolverManager; + $this->authorizationHelperForCurrentUser = $authorizationHelperForCurrentUser; + } + + public function buildQueryByPerson(Person $person): QueryBuilder + { + $qb = $this->em->getRepository(PersonDocument::class)->createQueryBuilder('d'); + + $qb + ->where($qb->expr()->eq('d.person', ':person')) + ->setParameter('person', $person); + + return $qb; + } + + + public function buildFetchQueryForPerson(Person $person, ?DateTimeImmutable $startDate = null, ?DateTimeImmutable $endDate = null, ?string $content = null): FetchQueryInterface + { + $query = $this->buildBaseFetchQueryForPerson($person, $startDate, $endDate, $content); + + return $this->addFetchQueryByPersonACL($query, $person); + } + + public function buildBaseFetchQueryForPerson(Person $person, ?DateTimeImmutable $startDate = null, ?DateTimeImmutable $endDate = null, ?string $content = null): FetchQuery + { + $storedObjectMetadata = $this->em->getClassMetadata(StoredObject::class); + + $query = new FetchQuery( + PersonDocumentGenericDocProvider::KEY, + sprintf('jsonb_build_object(\'id\', stored_obj.%s)', $storedObjectMetadata->getSingleIdentifierColumnName()), + sprintf('stored_obj.%s', $storedObjectMetadata->getColumnName('createdAt')), + sprintf('%s AS stored_obj', $storedObjectMetadata->getSchemaName().'.'.$storedObjectMetadata->getTableName()) + ); + + $query->addJoinClause( + 'JOIN public.activity_storedobject activity_doc ON activity_doc.storedobject_id = stored_obj.id' + ); + + $query->addJoinClause( + 'JOIN public.activity activity ON activity.id = activity_doc.activity_id' + ); + + $query->addWhereClause( + 'activity.person_id = ?', + [$person->getId()], + [Types::INTEGER] + ); + + if (null !== $startDate) { + $query->addWhereClause( + sprintf('stored_obj.%s >= ?', $storedObjectMetadata->getColumnName('createdAt')), + [$startDate], + [Types::DATE_IMMUTABLE] + ); + } + + if (null !== $endDate) { + $query->addWhereClause( + sprintf('stored_obj.%s < ?', $storedObjectMetadata->getColumnName('createdAt')), + [$endDate], + [Types::DATE_IMMUTABLE] + ); + } + + if (null !== $content) { + $query->addWhereClause( + 'stored_obj.title ilike ?', + ['%' . $content . '%'], + [Types::STRING] + ); + } + + return $query; + } + + public function countByPerson(Person $person): int + { + $qb = $this->buildQueryByPerson($person)->select('COUNT(d)'); + + $this->addACL($qb, $person); + + return $qb->getQuery()->getSingleScalarResult(); + } + + public function findByPerson(Person $person, array $orderBy = [], int $limit = 20, int $offset = 0): array + { + $qb = $this->buildQueryByPerson($person)->select('d'); + + $this->addACL($qb, $person); + + foreach ($orderBy as $field => $order) { + $qb->addOrderBy('d.' . $field, $order); + } + + $qb->setFirstResult($offset)->setMaxResults($limit); + + return $qb->getQuery()->getResult(); + } + + private function addACL(QueryBuilder $qb, Person $person): void + { + $reachableScopes = []; + + foreach ($this->centerResolverManager->resolveCenters($person) as $center) { + $reachableScopes = [ + ...$reachableScopes, + ...$this->authorizationHelperForCurrentUser + ->getReachableScopes( + PersonDocumentVoter::SEE, + $center + ) + ]; + } + + if ([] === $reachableScopes) { + $qb->andWhere("'FALSE' = 'TRUE'"); + + return; + } + + $qb->andWhere($qb->expr()->in('d.scope', ':scopes')) + ->setParameter('scopes', $reachableScopes); + } + + private function addFetchQueryByPersonACL(FetchQuery $fetchQuery, Person $person): FetchQuery + { + $personDocMetadata = $this->em->getClassMetadata(PersonDocument::class); + + $reachableScopes = []; + + foreach ($this->centerResolverManager->resolveCenters($person) as $center) { + $reachableScopes = [ + ...$reachableScopes, + ...$this->authorizationHelperForCurrentUser->getReachableScopes(PersonDocumentVoter::SEE, $center) + ]; + } + + if ([] === $reachableScopes) { + $fetchQuery->addWhereClause('FALSE = TRUE'); + + return $fetchQuery; + } + + $fetchQuery->addWhereClause( + sprintf( + 'person_document.%s IN (%s)', + $personDocMetadata->getSingleAssociationJoinColumnName('scope'), + implode(', ', array_fill(0, count($reachableScopes), '?')) + ), + array_map(static fn (Scope $s) => $s->getId(), $reachableScopes), + array_fill(0, count($reachableScopes), Types::INTEGER) + ); + + return $fetchQuery; + } +} diff --git a/src/Bundle/ChillActivityBundle/Service/GenericDoc/Providers/PersonActivityGenericDocProvider.php b/src/Bundle/ChillActivityBundle/Service/GenericDoc/Providers/PersonActivityGenericDocProvider.php new file mode 100644 index 000000000..d00a23e79 --- /dev/null +++ b/src/Bundle/ChillActivityBundle/Service/GenericDoc/Providers/PersonActivityGenericDocProvider.php @@ -0,0 +1,57 @@ +security = $security; + $this->personActivityDocumentACLAwareRepository = $personActivityDocumentACLAwareRepository; + } + + public function buildFetchQueryForPerson(Person $person, ?DateTimeImmutable $startDate = null, ?DateTimeImmutable $endDate = null, ?string $content = null, ?string $origin = null): FetchQueryInterface + { + return $this->personActivityDocumentACLAwareRepository->buildFetchQueryForPerson( + $person, + $startDate, + $endDate, + $content + ); + } + + /** + * @param Person $person + * @return bool + */ + public function isAllowedForPerson(Person $person): bool + { + return $this->security->isGranted(ActivityVoter::SEE, $person); + } +} From 7eb4fb4e563d618b562786e9d36c1c6aa820ea58 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Thu, 1 Jun 2023 13:09:51 +0200 Subject: [PATCH 122/321] FEATURE [calendar][docs] fix query to display rendez-vous documents from person and parcours contexts --- .../Providers/PersonCalendarGenericDocProvider.php | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Providers/PersonCalendarGenericDocProvider.php b/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Providers/PersonCalendarGenericDocProvider.php index bed04414c..640f0d197 100644 --- a/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Providers/PersonCalendarGenericDocProvider.php +++ b/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Providers/PersonCalendarGenericDocProvider.php @@ -98,13 +98,6 @@ final class PersonCalendarGenericDocProvider implements GenericDocForPersonProvi ) ); - $query->addWhereClause( - sprintf('calendar.%s = ?', - $calendarMetadata->getAssociationMapping('person')['joinColumns'][0]['name']), - [$person->getId()], - [Types::INTEGER] - ); - // get the documents associated with accompanying periods in which person participates $or = []; $orParams = []; From 2aeb72811a68f51dfc2c1ff300c34c7aa28a62ae Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Thu, 1 Jun 2023 13:31:35 +0200 Subject: [PATCH 123/321] [activity][docs] attempt to implement generic doc for activity documents in person context --- ...rsonActivityDocumentACLAwareRepository.php | 64 +++++++++++++------ ...anyingPeriodActivityGenericDocProvider.php | 4 +- ...anyingPeriodActivityGenericDocRenderer.php | 3 +- 3 files changed, 51 insertions(+), 20 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Repository/PersonActivityDocumentACLAwareRepository.php b/src/Bundle/ChillActivityBundle/Repository/PersonActivityDocumentACLAwareRepository.php index 862deb1ab..84bb08fb4 100644 --- a/src/Bundle/ChillActivityBundle/Repository/PersonActivityDocumentACLAwareRepository.php +++ b/src/Bundle/ChillActivityBundle/Repository/PersonActivityDocumentACLAwareRepository.php @@ -11,6 +11,8 @@ declare(strict_types=1); namespace Chill\ActivityBundle\Repository; +use Chill\ActivityBundle\Entity\Activity; +use Chill\ActivityBundle\Security\Authorization\ActivityVoter; use Chill\DocStoreBundle\Entity\PersonDocument; use Chill\DocStoreBundle\Entity\StoredObject; use Chill\DocStoreBundle\GenericDoc\FetchQuery; @@ -22,25 +24,22 @@ use Chill\MainBundle\Entity\Scope; use Chill\MainBundle\Security\Authorization\AuthorizationHelperForCurrentUserInterface; use Chill\MainBundle\Security\Resolver\CenterResolverManagerInterface; use Chill\PersonBundle\Entity\Person; +use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodWorkVoter; use DateTimeImmutable; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\QueryBuilder; use Symfony\Component\HttpKernel\HttpCache\Store; +use Symfony\Component\Security\Core\Security; class PersonActivityDocumentACLAwareRepository implements PersonDocumentACLAwareRepositoryInterface { - private AuthorizationHelperForCurrentUserInterface $authorizationHelperForCurrentUser; - - private CenterResolverManagerInterface $centerResolverManager; - - private EntityManagerInterface $em; - - public function __construct(EntityManagerInterface $em, CenterResolverManagerInterface $centerResolverManager, AuthorizationHelperForCurrentUserInterface $authorizationHelperForCurrentUser) + public function __construct( + private EntityManagerInterface $em, + private CenterResolverManagerInterface $centerResolverManager, + private AuthorizationHelperForCurrentUserInterface $authorizationHelperForCurrentUser, + private Security $security) { - $this->em = $em; - $this->centerResolverManager = $centerResolverManager; - $this->authorizationHelperForCurrentUser = $authorizationHelperForCurrentUser; } public function buildQueryByPerson(Person $person): QueryBuilder @@ -65,10 +64,11 @@ class PersonActivityDocumentACLAwareRepository implements PersonDocumentACLAware public function buildBaseFetchQueryForPerson(Person $person, ?DateTimeImmutable $startDate = null, ?DateTimeImmutable $endDate = null, ?string $content = null): FetchQuery { $storedObjectMetadata = $this->em->getClassMetadata(StoredObject::class); + $activityMetadata = $this->em->getClassMetadata(Activity::class); $query = new FetchQuery( PersonDocumentGenericDocProvider::KEY, - sprintf('jsonb_build_object(\'id\', stored_obj.%s)', $storedObjectMetadata->getSingleIdentifierColumnName()), + sprintf('jsonb_build_object(\'id\', stored_obj.%s, \'activity_id\', activity.%s)', $storedObjectMetadata->getSingleIdentifierColumnName(), $activityMetadata->getSingleIdentifierColumnName()), sprintf('stored_obj.%s', $storedObjectMetadata->getColumnName('createdAt')), sprintf('%s AS stored_obj', $storedObjectMetadata->getSchemaName().'.'.$storedObjectMetadata->getTableName()) ); @@ -81,11 +81,39 @@ class PersonActivityDocumentACLAwareRepository implements PersonDocumentACLAware 'JOIN public.activity activity ON activity.id = activity_doc.activity_id' ); - $query->addWhereClause( + // add documents of activities from parcours context + $or = []; + $orParams = []; + $orTypes = []; + foreach ($person->getAccompanyingPeriodParticipations() as $participation) { + if (!$this->security->isGranted(ActivityVoter::SEE, $participation->getAccompanyingPeriod())) { + continue; + } + + $or[] = sprintf( + '(activity.%s = ? AND stored_obj.%s BETWEEN ?::date AND COALESCE(?::date, \'infinity\'::date))', + $activityMetadata->getSingleAssociationJoinColumnName('accompanyingPeriod'), + $storedObjectMetadata->getColumnName('createdAt') + ); + $orParams = [...$orParams, $participation->getAccompanyingPeriod()->getId(), + DateTimeImmutable::createFromInterface($participation->getStartDate()), + null === $participation->getEndDate() ? null : DateTimeImmutable::createFromInterface($participation->getEndDate())]; + $orTypes = [...$orTypes, Types::INTEGER, Types::DATE_IMMUTABLE, Types::DATE_IMMUTABLE]; + } + + if ([] === $or) { + $query->addWhereClause('TRUE = FALSE'); + + return $query; + } + + $query->addWhereClause(sprintf('(%s)', implode(' OR ', $or)), $orParams, $orTypes); + +/* $query->addWhereClause( 'activity.person_id = ?', [$person->getId()], [Types::INTEGER] - ); + );*/ if (null !== $startDate) { $query->addWhereClause( @@ -147,7 +175,7 @@ class PersonActivityDocumentACLAwareRepository implements PersonDocumentACLAware ...$reachableScopes, ...$this->authorizationHelperForCurrentUser ->getReachableScopes( - PersonDocumentVoter::SEE, + ActivityVoter::SEE, $center ) ]; @@ -165,14 +193,14 @@ class PersonActivityDocumentACLAwareRepository implements PersonDocumentACLAware private function addFetchQueryByPersonACL(FetchQuery $fetchQuery, Person $person): FetchQuery { - $personDocMetadata = $this->em->getClassMetadata(PersonDocument::class); + $activityMetadata = $this->em->getClassMetadata(Activity::class); $reachableScopes = []; foreach ($this->centerResolverManager->resolveCenters($person) as $center) { $reachableScopes = [ ...$reachableScopes, - ...$this->authorizationHelperForCurrentUser->getReachableScopes(PersonDocumentVoter::SEE, $center) + ...$this->authorizationHelperForCurrentUser->getReachableScopes(ActivityVoter::SEE, $center) ]; } @@ -184,8 +212,8 @@ class PersonActivityDocumentACLAwareRepository implements PersonDocumentACLAware $fetchQuery->addWhereClause( sprintf( - 'person_document.%s IN (%s)', - $personDocMetadata->getSingleAssociationJoinColumnName('scope'), + 'activity.%s IN (%s)', + $activityMetadata->getSingleAssociationJoinColumnName('scope'), implode(', ', array_fill(0, count($reachableScopes), '?')) ), array_map(static fn (Scope $s) => $s->getId(), $reachableScopes), diff --git a/src/Bundle/ChillActivityBundle/Service/GenericDoc/Providers/AccompanyingPeriodActivityGenericDocProvider.php b/src/Bundle/ChillActivityBundle/Service/GenericDoc/Providers/AccompanyingPeriodActivityGenericDocProvider.php index 8c787fd3a..284182cfb 100644 --- a/src/Bundle/ChillActivityBundle/Service/GenericDoc/Providers/AccompanyingPeriodActivityGenericDocProvider.php +++ b/src/Bundle/ChillActivityBundle/Service/GenericDoc/Providers/AccompanyingPeriodActivityGenericDocProvider.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Chill\ActivityBundle\Service\GenericDoc\Providers; +use Chill\ActivityBundle\Entity\Activity; use Chill\ActivityBundle\Security\Authorization\ActivityVoter; use Chill\DocStoreBundle\Entity\StoredObject; use Chill\DocStoreBundle\GenericDoc\FetchQuery; @@ -36,10 +37,11 @@ final class AccompanyingPeriodActivityGenericDocProvider implements GenericDocFo public function buildFetchQueryForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod, ?DateTimeImmutable $startDate = null, ?DateTimeImmutable $endDate = null, ?string $content = null, ?string $origin = null): FetchQueryInterface { $storedObjectMetadata = $this->em->getClassMetadata(StoredObject::class); + $activityMetadata = $this->em->getClassMetadata(Activity::class); $query = new FetchQuery( self::KEY, - "jsonb_build_object('id', doc_obj.id, 'activity_id', activity.id)", + sprintf("jsonb_build_object('id', doc_obj.%s, 'activity_id', activity.%s)", $storedObjectMetadata->getSingleIdentifierColumnName(), $activityMetadata->getSingleIdentifierColumnName()), 'doc_obj.'.$storedObjectMetadata->getColumnName('createdAt'), $storedObjectMetadata->getSchemaName().'.'.$storedObjectMetadata->getTableName().' AS doc_obj' ); diff --git a/src/Bundle/ChillActivityBundle/Service/GenericDoc/Renderers/AccompanyingPeriodActivityGenericDocRenderer.php b/src/Bundle/ChillActivityBundle/Service/GenericDoc/Renderers/AccompanyingPeriodActivityGenericDocRenderer.php index f3b70dac2..9f9a4bec8 100644 --- a/src/Bundle/ChillActivityBundle/Service/GenericDoc/Renderers/AccompanyingPeriodActivityGenericDocRenderer.php +++ b/src/Bundle/ChillActivityBundle/Service/GenericDoc/Renderers/AccompanyingPeriodActivityGenericDocRenderer.php @@ -13,6 +13,7 @@ namespace Chill\ActivityBundle\Service\GenericDoc\Renderers; use Chill\ActivityBundle\Repository\ActivityRepository; use Chill\ActivityBundle\Service\GenericDoc\Providers\AccompanyingPeriodActivityGenericDocProvider; +use Chill\ActivityBundle\Service\GenericDoc\Providers\PersonActivityGenericDocProvider; use Chill\DocStoreBundle\GenericDoc\GenericDocDTO; use Chill\DocStoreBundle\GenericDoc\Twig\GenericDocRendererInterface; use Chill\DocStoreBundle\Repository\StoredObjectRepository; @@ -31,7 +32,7 @@ final class AccompanyingPeriodActivityGenericDocRenderer implements GenericDocRe public function supports(GenericDocDTO $genericDocDTO, $options = []): bool { - return $genericDocDTO->key === AccompanyingPeriodActivityGenericDocProvider::KEY; + return $genericDocDTO->key === AccompanyingPeriodActivityGenericDocProvider::KEY || $genericDocDTO->key === PersonActivityGenericDocProvider::KEY; } public function getTemplate(GenericDocDTO $genericDocDTO, $options = []): string From d1e1b1c4cee1f3be8d045977e4c6c838a0bf0188 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 1 Jun 2023 14:02:48 +0200 Subject: [PATCH 124/321] [export form] decouple data from PickCenter form --- .../Controller/ExportController.php | 27 +++++++++----- .../Export/ExportFormHelper.php | 37 +++++++++++++++++++ .../DataMapper/ExportPickCenterDataMapper.php | 11 ++++-- .../Form/Type/Export/PickCenterType.php | 15 +++----- .../config/services/export.yaml | 2 + 5 files changed, 68 insertions(+), 24 deletions(-) create mode 100644 src/Bundle/ChillMainBundle/Export/ExportFormHelper.php diff --git a/src/Bundle/ChillMainBundle/Controller/ExportController.php b/src/Bundle/ChillMainBundle/Controller/ExportController.php index 6c4ea0269..a327b536a 100644 --- a/src/Bundle/ChillMainBundle/Controller/ExportController.php +++ b/src/Bundle/ChillMainBundle/Controller/ExportController.php @@ -13,6 +13,7 @@ namespace Chill\MainBundle\Controller; use Chill\MainBundle\Entity\SavedExport; use Chill\MainBundle\Entity\User; +use Chill\MainBundle\Export\ExportFormHelper; use Chill\MainBundle\Export\ExportManager; use Chill\MainBundle\Form\SavedExportType; use Chill\MainBundle\Form\Type\Export\ExportType; @@ -86,7 +87,8 @@ class ExportController extends AbstractController LoggerInterface $logger, SessionInterface $session, TranslatorInterface $translator, - EntityManagerInterface $entityManager + EntityManagerInterface $entityManager, + private readonly ExportFormHelper $exportFormHelper, ) { $this->entityManager = $entityManager; $this->redis = $chillRedis; @@ -293,10 +295,15 @@ class ExportController extends AbstractController $isGenerate = strpos($step, 'generate_') === 0; $builder = $this->formFactory - ->createNamedBuilder(null, FormType::class, [], [ - 'method' => $isGenerate ? 'GET' : 'POST', - 'csrf_protection' => $isGenerate ? false : true, - ]); + ->createNamedBuilder( + null, + FormType::class, + $this->exportFormHelper->getDefaultData($step, $exportManager->getExport($alias)), + [ + 'method' => $isGenerate ? 'GET' : 'POST', + 'csrf_protection' => $isGenerate ? false : true, + ] + ); // TODO: add a condition to be able to select a regroupment of centers? @@ -341,7 +348,7 @@ class ExportController extends AbstractController * * @return \Symfony\Component\HttpFoundation\Response */ - protected function exportFormStep(Request $request, $export, $alias) + private function exportFormStep(Request $request, $export, $alias) { $exportManager = $this->exportManager; @@ -405,7 +412,7 @@ class ExportController extends AbstractController * * @return \Symfony\Component\HttpFoundation\Response */ - protected function formatterFormStep(Request $request, $export, $alias) + private function formatterFormStep(Request $request, $export, $alias) { // check we have data from the previous step (export step) $data = $this->session->get('export_step', null); @@ -462,7 +469,7 @@ class ExportController extends AbstractController * * @return \Symfony\Component\HttpFoundation\RedirectResponse */ - protected function forwardToGenerate(Request $request, $export, $alias) + private function forwardToGenerate(Request $request, $export, $alias) { $dataCenters = $this->session->get('centers_step_raw', null); $dataFormatter = $this->session->get('formatter_step_raw', null); @@ -494,7 +501,7 @@ class ExportController extends AbstractController return $this->redirectToRoute('chill_main_export_download', ['key' => $key, 'alias' => $alias]); } - protected function rebuildData($key) + private function rebuildData($key) { $rawData = $this->rebuildRawData($key); @@ -527,7 +534,7 @@ class ExportController extends AbstractController * * @return Response */ - protected function selectCentersStep(Request $request, $export, $alias) + private function selectCentersStep(Request $request, $export, $alias) { /** @var \Chill\MainBundle\Export\ExportManager $exportManager */ $exportManager = $this->exportManager; diff --git a/src/Bundle/ChillMainBundle/Export/ExportFormHelper.php b/src/Bundle/ChillMainBundle/Export/ExportFormHelper.php new file mode 100644 index 000000000..1105217c8 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Export/ExportFormHelper.php @@ -0,0 +1,37 @@ + $steps + */ + public function getDefaultData(string $step, ExportInterface $export): array + { + $data = []; + + if ($step === 'centers') { + $data['centers'] = $this->authorizationHelper->getReachableCenters($export->requiredRole()); + } + + return $data; + } +} diff --git a/src/Bundle/ChillMainBundle/Form/DataMapper/ExportPickCenterDataMapper.php b/src/Bundle/ChillMainBundle/Form/DataMapper/ExportPickCenterDataMapper.php index 01303bfbb..c88f1dfe3 100644 --- a/src/Bundle/ChillMainBundle/Form/DataMapper/ExportPickCenterDataMapper.php +++ b/src/Bundle/ChillMainBundle/Form/DataMapper/ExportPickCenterDataMapper.php @@ -22,7 +22,10 @@ use function count; class ExportPickCenterDataMapper implements DataMapperInterface { - protected RegroupmentRepository $regroupmentRepository; + public function __construct( + private RegroupmentRepository $regroupmentRepository, + ) { + } public function mapDataToForms($data, $forms): void { @@ -37,15 +40,15 @@ class ExportPickCenterDataMapper implements DataMapperInterface foreach ($this->regroupmentRepository->findAll() as $regroupment) { /** @phpstan-ignore-next-line */ - [$contained, $notContained] = $regroupment->getCenters()->partition(static fn (Center $center): bool => false); + [$contained, $notContained] = $regroupment->getCenters()->partition(static fn (int $id, Center $center): bool => false); if (0 === count($notContained)) { $pickedRegroupment[] = $regroupment; } } - $form['regroupment']->setData($pickedRegroupment); - $form['centers']->setData($data); + $form['regroupment']->setData([]); + $form['center']->setData($data); } public function mapFormsToData($forms, &$data): void diff --git a/src/Bundle/ChillMainBundle/Form/Type/Export/PickCenterType.php b/src/Bundle/ChillMainBundle/Form/Type/Export/PickCenterType.php index c89907cf3..b2d903909 100644 --- a/src/Bundle/ChillMainBundle/Form/Type/Export/PickCenterType.php +++ b/src/Bundle/ChillMainBundle/Form/Type/Export/PickCenterType.php @@ -16,6 +16,7 @@ use Chill\MainBundle\Entity\Regroupment; use Chill\MainBundle\Export\ExportManager; use Chill\MainBundle\Form\DataMapper\ExportPickCenterDataMapper; use Chill\MainBundle\Repository\RegroupmentRepository; +use Chill\MainBundle\Security\Authorization\AuthorizationHelperForCurrentUserInterface; use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface; use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\AbstractType; @@ -33,22 +34,18 @@ final class PickCenterType extends AbstractType { public const CENTERS_IDENTIFIERS = 'c'; - private AuthorizationHelperInterface $authorizationHelper; + private AuthorizationHelperForCurrentUserInterface $authorizationHelper; private ExportManager $exportManager; private RegroupmentRepository $regroupmentRepository; - private UserInterface $user; - public function __construct( - TokenStorageInterface $tokenStorage, ExportManager $exportManager, RegroupmentRepository $regroupmentRepository, - AuthorizationHelperInterface $authorizationHelper + AuthorizationHelperForCurrentUserInterface $authorizationHelper ) { $this->exportManager = $exportManager; - $this->user = $tokenStorage->getToken()->getUser(); $this->authorizationHelper = $authorizationHelper; $this->regroupmentRepository = $regroupmentRepository; } @@ -57,18 +54,16 @@ final class PickCenterType extends AbstractType { $export = $this->exportManager->getExport($options['export_alias']); $centers = $this->authorizationHelper->getReachableCenters( - $this->user, $export->requiredRole() ); $builder->add('center', EntityType::class, [ 'class' => Center::class, - 'label' => 'center', 'choices' => $centers, + 'label' => 'center', 'multiple' => true, 'expanded' => true, 'choice_label' => static fn (Center $c) => $c->getName(), - 'data' => $centers, ]); if (count($this->regroupmentRepository->findAllActive()) > 0) { @@ -82,7 +77,7 @@ final class PickCenterType extends AbstractType ]); } - $builder->setDataMapper(new ExportPickCenterDataMapper()); + $builder->setDataMapper(new ExportPickCenterDataMapper($this->regroupmentRepository)); } public function configureOptions(OptionsResolver $resolver) diff --git a/src/Bundle/ChillMainBundle/config/services/export.yaml b/src/Bundle/ChillMainBundle/config/services/export.yaml index ea7328839..b0dbf934d 100644 --- a/src/Bundle/ChillMainBundle/config/services/export.yaml +++ b/src/Bundle/ChillMainBundle/config/services/export.yaml @@ -6,6 +6,8 @@ services: Chill\MainBundle\Export\Helper\: resource: '../../Export/Helper' + Chill\MainBundle\Export\ExportFormHelper: ~ + chill.main.export_element_validator: class: Chill\MainBundle\Validator\Constraints\Export\ExportElementConstraintValidator tags: From fb0afc7e0aa78b44894bde5814aefd5264c85769 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Fri, 2 Jun 2023 15:32:38 +0200 Subject: [PATCH 125/321] [WIP] get default data from saved exports for center and export steps --- .../Controller/ExportController.php | 100 ++++++++------- .../Export/ExportFormHelper.php | 116 ++++++++++++++++-- .../ChillMainBundle/Export/ExportManager.php | 75 +++++------ .../Form/Type/Export/AggregatorType.php | 1 - .../Form/Type/Export/FilterType.php | 1 - .../Form/Type/Export/PickFormatterType.php | 2 - .../MaritalStatusAggregator.php | 6 + .../Export/Export/CountPerson.php | 11 +- .../Export/Filter/PersonFilters/AgeFilter.php | 10 ++ 9 files changed, 225 insertions(+), 97 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Controller/ExportController.php b/src/Bundle/ChillMainBundle/Controller/ExportController.php index a327b536a..41237b21e 100644 --- a/src/Bundle/ChillMainBundle/Controller/ExportController.php +++ b/src/Bundle/ChillMainBundle/Controller/ExportController.php @@ -13,13 +13,16 @@ namespace Chill\MainBundle\Controller; use Chill\MainBundle\Entity\SavedExport; use Chill\MainBundle\Entity\User; +use Chill\MainBundle\Export\DirectExportInterface; use Chill\MainBundle\Export\ExportFormHelper; +use Chill\MainBundle\Export\ExportInterface; use Chill\MainBundle\Export\ExportManager; use Chill\MainBundle\Form\SavedExportType; use Chill\MainBundle\Form\Type\Export\ExportType; use Chill\MainBundle\Form\Type\Export\FormatterType; use Chill\MainBundle\Form\Type\Export\PickCenterType; use Chill\MainBundle\Redis\ChillRedis; +use Chill\MainBundle\Repository\SavedExportRepositoryInterface; use Chill\MainBundle\Security\Authorization\SavedExportVoter; use Doctrine\ORM\EntityManagerInterface; use LogicException; @@ -37,6 +40,7 @@ use Symfony\Component\HttpFoundation\Session\SessionInterface; use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; use Symfony\Component\Routing\Annotation\Route; +use Symfony\Component\Security\Core\Security; use Symfony\Contracts\Translation\TranslatorInterface; use function count; use function serialize; @@ -89,6 +93,8 @@ class ExportController extends AbstractController TranslatorInterface $translator, EntityManagerInterface $entityManager, private readonly ExportFormHelper $exportFormHelper, + private readonly SavedExportRepositoryInterface $savedExportRepository, + private readonly Security $security, ) { $this->entityManager = $entityManager; $this->redis = $chillRedis; @@ -103,12 +109,11 @@ class ExportController extends AbstractController { /** @var \Chill\MainBundle\Export\ExportManager $exportManager */ $exportManager = $this->exportManager; - $export = $exportManager->getExport($alias); - $key = $request->query->get('key', null); + $savedExport = $this->getSavedExportFromRequest($request); - [$dataCenters, $dataExport, $dataFormatter] = $this->rebuildData($key); + [$dataCenters, $dataExport, $dataFormatter] = $this->rebuildData($key, $savedExport); $formatterAlias = $exportManager->getFormatterAlias($dataExport['export']); @@ -146,8 +151,9 @@ class ExportController extends AbstractController /** @var \Chill\MainBundle\Export\ExportManager $exportManager */ $exportManager = $this->exportManager; $key = $request->query->get('key', null); + $savedExport = $this->getSavedExportFromRequest($request); - [$dataCenters, $dataExport, $dataFormatter] = $this->rebuildData($key); + [$dataCenters, $dataExport, $dataFormatter] = $this->rebuildData($key, $savedExport); return $exportManager->generate( $alias, @@ -206,12 +212,8 @@ class ExportController extends AbstractController * 3. 'generate': gather data from session from the previous steps, and * make a redirection to the "generate" action with data in query (HTTP GET) * - * @param string $request - * @param Request $alias - * - * @return \Symfony\Component\HttpFoundation\Response */ - public function newAction(Request $request, $alias) + public function newAction(Request $request, string $alias): Response { // first check for ACL $exportManager = $this->exportManager; @@ -221,20 +223,22 @@ class ExportController extends AbstractController throw $this->createAccessDeniedException('The user does not have access to this export'); } + $savedExport = $this->getSavedExportFromRequest($request); + $step = $request->query->getAlpha('step', 'centers'); switch ($step) { case 'centers': - return $this->selectCentersStep($request, $export, $alias); + return $this->selectCentersStep($request, $export, $alias, $savedExport); case 'export': - return $this->exportFormStep($request, $export, $alias); + return $this->exportFormStep($request, $export, $alias, $savedExport); case 'formatter': - return $this->formatterFormStep($request, $export, $alias); + return $this->formatterFormStep($request, $export, $alias, $savedExport); case 'generate': - return $this->forwardToGenerate($request, $export, $alias); + return $this->forwardToGenerate($request, $export, $alias, $savedExport); default: throw $this->createNotFoundException("The given step '{$step}' is invalid"); @@ -284,29 +288,35 @@ class ExportController extends AbstractController /** * create a form to show on different steps. * - * @param string $alias * @param array $data the data from previous step. Required for steps 'formatter' and 'generate_formatter' - * @param mixed $step */ - protected function createCreateFormExport($alias, $step, $data = []): FormInterface + protected function createCreateFormExport(string $alias, string $step, array $data, ?SavedExport $savedExport): FormInterface { /** @var \Chill\MainBundle\Export\ExportManager $exportManager */ $exportManager = $this->exportManager; $isGenerate = strpos($step, 'generate_') === 0; + $options = match ($step) { + 'export', 'generate_export' => ['picked_centers' => $exportManager->getPickedCenters($data['centers'])], + default => [], + }; + + $defaultFormData = match ($savedExport) { + null => $this->exportFormHelper->getDefaultData($step, $exportManager->getExport($alias), $options), + default => $this->exportFormHelper->savedExportDataToFormData($savedExport, $step, $options), + }; + $builder = $this->formFactory ->createNamedBuilder( null, FormType::class, - $this->exportFormHelper->getDefaultData($step, $exportManager->getExport($alias)), + $defaultFormData, [ 'method' => $isGenerate ? 'GET' : 'POST', - 'csrf_protection' => $isGenerate ? false : true, + 'csrf_protection' => !$isGenerate, ] ); - // TODO: add a condition to be able to select a regroupment of centers? - if ('centers' === $step || 'generate_centers' === $step) { $builder->add('centers', PickCenterType::class, [ 'export_alias' => $alias, @@ -342,13 +352,8 @@ class ExportController extends AbstractController * * When the method is POST, the form is stored if valid, and a redirection * is done to next step. - * - * @param string $alias - * @param \Chill\MainBundle\Export\DirectExportInterface|\Chill\MainBundle\Export\ExportInterface $export - * - * @return \Symfony\Component\HttpFoundation\Response */ - private function exportFormStep(Request $request, $export, $alias) + private function exportFormStep(Request $request, DirectExportInterface|ExportInterface $export, string $alias, ?SavedExport $savedExport = null): Response { $exportManager = $this->exportManager; @@ -364,7 +369,7 @@ class ExportController extends AbstractController $export = $exportManager->getExport($alias); - $form = $this->createCreateFormExport($alias, 'export', $data); + $form = $this->createCreateFormExport($alias, 'export', $data, $savedExport); if ($request->getMethod() === 'POST') { $form->handleRequest($request); @@ -386,6 +391,7 @@ class ExportController extends AbstractController $this->generateUrl('chill_main_export_new', [ 'step' => $this->getNextStep('export', $export), 'alias' => $alias, + 'from_saved' => $request->get('from_saved', '') ]) ); } @@ -406,13 +412,8 @@ class ExportController extends AbstractController * * If the form is posted and valid, store the data in session and * redirect to the next step. - * - * @param \Chill\MainBundle\Export\DirectExportInterface|\Chill\MainBundle\Export\ExportInterface $export - * @param string $alias - * - * @return \Symfony\Component\HttpFoundation\Response */ - private function formatterFormStep(Request $request, $export, $alias) + private function formatterFormStep(Request $request, DirectExportInterface|ExportInterface $export, string $alias, ?SavedExport $savedExport = null): Response { // check we have data from the previous step (export step) $data = $this->session->get('export_step', null); @@ -424,7 +425,7 @@ class ExportController extends AbstractController ]); } - $form = $this->createCreateFormExport($alias, 'formatter', $data); + $form = $this->createCreateFormExport($alias, 'formatter', $data, $savedExport); if ($request->getMethod() === 'POST') { $form->handleRequest($request); @@ -443,6 +444,7 @@ class ExportController extends AbstractController [ 'alias' => $alias, 'step' => $this->getNextStep('formatter', $export), + 'from_saved' => $request->get('from_saved', ''), ] )); } @@ -469,7 +471,7 @@ class ExportController extends AbstractController * * @return \Symfony\Component\HttpFoundation\RedirectResponse */ - private function forwardToGenerate(Request $request, $export, $alias) + private function forwardToGenerate(Request $request, $export, $alias, ?SavedExport $savedExport) { $dataCenters = $this->session->get('centers_step_raw', null); $dataFormatter = $this->session->get('formatter_step_raw', null); @@ -501,17 +503,17 @@ class ExportController extends AbstractController return $this->redirectToRoute('chill_main_export_download', ['key' => $key, 'alias' => $alias]); } - private function rebuildData($key) + private function rebuildData($key, ?SavedExport $savedExport) { $rawData = $this->rebuildRawData($key); $alias = $rawData['alias']; - $formCenters = $this->createCreateFormExport($alias, 'generate_centers'); + $formCenters = $this->createCreateFormExport($alias, 'generate_centers', [], $savedExport); $formCenters->submit($rawData['centers']); $dataCenters = $formCenters->getData(); - $formExport = $this->createCreateFormExport($alias, 'generate_export', $dataCenters); + $formExport = $this->createCreateFormExport($alias, 'generate_export', $dataCenters, $savedExport); $formExport->submit($rawData['export']); $dataExport = $formExport->getData(); @@ -519,7 +521,8 @@ class ExportController extends AbstractController $formFormatter = $this->createCreateFormExport( $alias, 'generate_formatter', - $dataExport + $dataExport, + $savedExport ); $formFormatter->submit($rawData['formatter']); $dataFormatter = $formFormatter->getData(); @@ -534,12 +537,12 @@ class ExportController extends AbstractController * * @return Response */ - private function selectCentersStep(Request $request, $export, $alias) + private function selectCentersStep(Request $request, $export, $alias, ?SavedExport $savedExport = null) { /** @var \Chill\MainBundle\Export\ExportManager $exportManager */ $exportManager = $this->exportManager; - $form = $this->createCreateFormExport($alias, 'centers'); + $form = $this->createCreateFormExport($alias, 'centers', [], $savedExport); if ($request->getMethod() === 'POST') { $form->handleRequest($request); @@ -571,6 +574,7 @@ class ExportController extends AbstractController return $this->redirectToRoute('chill_main_export_new', [ 'step' => $this->getNextStep('centers', $export), 'alias' => $alias, + 'from_saved' => $request->get('from_saved', ''), ]); } } @@ -677,4 +681,18 @@ class ExportController extends AbstractController return $rawData; } + + private function getSavedExportFromRequest(Request $request): ?SavedExport + { + $savedExport = match ($savedExportId = $request->query->get('from_saved', '')) { + '' => null, + default => $this->savedExportRepository->find($savedExportId), + }; + + if (null !== $savedExport && !$this->security->isGranted(SavedExportVoter::EDIT, $savedExport)) { + throw new AccessDeniedHttpException("saved export edition not allowed"); + } + + return $savedExport; + } } diff --git a/src/Bundle/ChillMainBundle/Export/ExportFormHelper.php b/src/Bundle/ChillMainBundle/Export/ExportFormHelper.php index 1105217c8..6f00c91da 100644 --- a/src/Bundle/ChillMainBundle/Export/ExportFormHelper.php +++ b/src/Bundle/ChillMainBundle/Export/ExportFormHelper.php @@ -11,27 +11,127 @@ declare(strict_types=1); namespace Chill\MainBundle\Export; +use Chill\MainBundle\Entity\SavedExport; +use Chill\MainBundle\Form\Type\Export\ExportType; +use Chill\MainBundle\Form\Type\Export\FilterType; +use Chill\MainBundle\Form\Type\Export\PickCenterType; use Chill\MainBundle\Security\Authorization\AuthorizationHelperForCurrentUserInterface; +use Symfony\Component\Form\Extension\Core\Type\FormType; +use Symfony\Component\Form\FormFactoryInterface; final readonly class ExportFormHelper { public function __construct( - private ExportManager $exportManager, private AuthorizationHelperForCurrentUserInterface $authorizationHelper, + private ExportManager $exportManager, + private FormFactoryInterface $formFactory, ) { } - /** - * @param list<"centers"> $steps - */ - public function getDefaultData(string $step, ExportInterface $export): array + public function getDefaultData(string $step, ExportInterface|DirectExportInterface $export, array $options = []): array { - $data = []; + return match ($step) { + 'centers', 'generate_centers' => ['centers' => $this->authorizationHelper->getReachableCenters($export->requiredRole())], + 'export', 'generate_export' => ['export' => $this->getDefaultDataStepExport($export, $options)], + 'formatter', 'generate_formatter' => [], + default => throw new \LogicException("step not allowed : " . $step), + }; + } - if ($step === 'centers') { - $data['centers'] = $this->authorizationHelper->getReachableCenters($export->requiredRole()); + private function getDefaultDataStepExport(ExportInterface|DirectExportInterface $export, array $options): array + { + $data = [ + ExportType::EXPORT_KEY => $export->getFormDefaultData(), + ExportType::FILTER_KEY => [], + ExportType::AGGREGATOR_KEY => [], + ExportType::PICK_FORMATTER_KEY => [], + ]; + + $filters = $this->exportManager->getFiltersApplyingOn($export, $options['picked_centers']); + foreach ($filters as $alias => $filter) { + $data[ExportType::FILTER_KEY][$alias] = [ + FilterType::ENABLED_FIELD => false, + 'form' => $filter->getFormDefaultData() + ]; } + $aggregators = $this->exportManager + ->getAggregatorsApplyingOn($export, $options['picked_centers']); + foreach ($aggregators as $alias => $aggregator) { + $data[ExportType::AGGREGATOR_KEY][$alias] = [ + 'enabled' => false, + 'form' => $aggregator->getFormDefaultData(), + ]; + } + + $allowedFormatters = $this->exportManager + ->getFormattersByTypes($export->getAllowedFormattersTypes()); + $choices = []; + foreach (array_keys(iterator_to_array($allowedFormatters)) as $alias) { + $choices[] = $alias; + } + + $data[ExportType::PICK_FORMATTER_KEY]['alias'] = match (count($choices)) { + 1 => $choices[0], + default => null, + }; + return $data; } + + public function savedExportDataToFormData( + SavedExport $savedExport, + string $step, + array $formOptions = [], + ): array { + return match ($step) { + 'centers', 'generate_centers' => $this->savedExportDataToFormDataStepCenter($savedExport), + 'export', 'generate_export' => $this->savedExportDataToFormDataStepExport($savedExport, $formOptions), + 'formatter', 'generate_formatter' => [], + default => throw new \LogicException("this step is not allowed: " . $step), + }; + } + + private function savedExportDataToFormDataStepCenter( + SavedExport $savedExport, + ): array { + $builder = $this->formFactory + ->createBuilder( + FormType::class, + [], + [ + 'csrf_protection' => false, + ] + ); + + $builder->add('centers', PickCenterType::class, [ + 'export_alias' => $savedExport->getExportAlias(), + ]); + $form = $builder->getForm(); + $form->submit($savedExport->getOptions()['centers']); + + return $form->getData(); + } + + private function savedExportDataToFormDataStepExport( + SavedExport $savedExport, + array $formOptions + ): array { + $builder = $this->formFactory + ->createBuilder( + FormType::class, + [], + [ + 'csrf_protection' => false, + ] + ); + + $builder->add('export', ExportType::class, [ + 'export_alias' => $savedExport->getExportAlias(), ...$formOptions + ]); + $form = $builder->getForm(); + $form->submit($savedExport->getOptions()['export']); + + return $form->getData(); + } } diff --git a/src/Bundle/ChillMainBundle/Export/ExportManager.php b/src/Bundle/ChillMainBundle/Export/ExportManager.php index f39926083..7ad880642 100644 --- a/src/Bundle/ChillMainBundle/Export/ExportManager.php +++ b/src/Bundle/ChillMainBundle/Export/ExportManager.php @@ -12,7 +12,6 @@ declare(strict_types=1); namespace Chill\MainBundle\Export; use Chill\MainBundle\Form\Type\Export\ExportType; -use Chill\MainBundle\Form\Type\Export\PickCenterType; use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface; use Doctrine\ORM\QueryBuilder; use Generator; @@ -131,9 +130,9 @@ class ExportManager * * @internal This class check the interface implemented by export, and, if ´ListInterface´ is used, return an empty array * - * @return AggregatorInterface[] a \Generator that contains aggretagors. The key is the filter's alias + * @return null|iterable a \Generator that contains aggretagors. The key is the filter's alias */ - public function &getAggregatorsApplyingOn(ExportInterface $export, ?array $centers = null) + public function &getAggregatorsApplyingOn(ExportInterface $export, ?array $centers = null): ?iterable { if ($export instanceof ListInterface) { return; @@ -149,7 +148,7 @@ class ExportManager } } - public function addExportElementsProvider(ExportElementsProviderInterface $provider, $prefix) + public function addExportElementsProvider(ExportElementsProviderInterface $provider, string $prefix): void { foreach ($provider->getExportElements() as $suffix => $element) { $alias = $prefix . '_' . $suffix; @@ -173,23 +172,16 @@ class ExportManager * add a formatter. * * @internal used by DI - * - * @param string $alias */ - public function addFormatter(FormatterInterface $formatter, $alias) + public function addFormatter(FormatterInterface $formatter, string $alias) { $this->formatters[$alias] = $formatter; } /** * Generate a response which contains the requested data. - * - * @param string $exportAlias - * @param mixed[] $data - * - * @return Response */ - public function generate($exportAlias, array $pickedCentersData, array $data, array $formatterData) + public function generate(string $exportAlias, array $pickedCentersData, array $data, array $formatterData): Response { $export = $this->getExport($exportAlias); $centers = $this->getPickedCenters($pickedCentersData); @@ -288,7 +280,11 @@ class ExportManager return $this->aggregators[$alias]; } - public function getAggregators(array $aliases) + /** + * @param array $aliases + * @return iterable + */ + public function getAggregators(array $aliases): iterable { foreach ($aliases as $alias) { yield $alias => $this->getAggregator($alias); @@ -296,9 +292,11 @@ class ExportManager } /** - * @return string[] the existing type for known exports + * Get the types for known exports + * + * @return list the existing type for known exports */ - public function getExistingExportsTypes() + public function getExistingExportsTypes(): array { $existingTypes = []; @@ -317,10 +315,8 @@ class ExportManager * @param string $alias * * @throws RuntimeException - * - * @return ExportInterface */ - public function getExport($alias) + public function getExport($alias): ExportInterface|DirectExportInterface { if (!array_key_exists($alias, $this->exports)) { throw new RuntimeException("The export with alias {$alias} is not known."); @@ -334,9 +330,9 @@ class ExportManager * * @param bool $whereUserIsGranted if true (default), restrict to user which are granted the right to execute the export * - * @return ExportInterface[] an array where export's alias are keys + * @return iterable an array where export's alias are keys */ - public function getExports($whereUserIsGranted = true) + public function getExports($whereUserIsGranted = true): iterable { foreach ($this->exports as $alias => $export) { if ($whereUserIsGranted) { @@ -354,9 +350,9 @@ class ExportManager * * @param bool $whereUserIsGranted * - * @return array where keys are the groups's name and value is an array of exports + * @return array> where keys are the groups's name and value is an array of exports */ - public function getExportsGrouped($whereUserIsGranted = true): array + public function getExportsGrouped(bool $whereUserIsGranted = true): array { $groups = ['_' => []]; @@ -375,10 +371,8 @@ class ExportManager * @param string $alias * * @throws RuntimeException if the filter is not known - * - * @return FilterInterface */ - public function getFilter($alias) + public function getFilter(string $alias): FilterInterface { if (!array_key_exists($alias, $this->filters)) { throw new RuntimeException("The filter with alias {$alias} is not known."); @@ -390,16 +384,17 @@ class ExportManager /** * get all filters. * - * @param Generator $aliases + * @param array $aliases + * @return iterable $aliases */ - public function getFilters(array $aliases) + public function getFilters(array $aliases): iterable { foreach ($aliases as $alias) { yield $alias => $this->getFilter($alias); } } - public function getFormatter($alias) + public function getFormatter(string $alias): FormatterInterface { if (!array_key_exists($alias, $this->formatters)) { throw new RuntimeException("The formatter with alias {$alias} is not known."); @@ -414,7 +409,7 @@ class ExportManager * @param array $data the data from the export form * @string the formatter alias|null */ - public function getFormatterAlias(array $data) + public function getFormatterAlias(array $data): ?string { if (array_key_exists(ExportType::PICK_FORMATTER_KEY, $data)) { return $data[ExportType::PICK_FORMATTER_KEY]['alias']; @@ -426,9 +421,9 @@ class ExportManager /** * Get all formatters which supports one of the given types. * - * @return Generator + * @return iterable */ - public function getFormattersByTypes(array $types) + public function getFormattersByTypes(array $types): iterable { foreach ($this->formatters as $alias => $formatter) { if (in_array($formatter->getType(), $types, true)) { @@ -445,7 +440,7 @@ class ExportManager * * @return \Chill\MainBundle\Entity\Center[] the picked center */ - public function getPickedCenters(array $data) + public function getPickedCenters(array $data): array { return $data; } @@ -455,9 +450,9 @@ class ExportManager * * @param array $data the data from the export form * - * @return string[] + * @return list */ - public function getUsedAggregatorsAliases(array $data) + public function getUsedAggregatorsAliases(array $data): array { $aggregators = $this->retrieveUsedAggregators($data[ExportType::AGGREGATOR_KEY]); @@ -471,9 +466,8 @@ class ExportManager * @param \Chill\MainBundle\Export\ExportElementInterface $element * @param DirectExportInterface|ExportInterface $export * - * @return bool */ - public function isGrantedForElement(ExportElementInterface $element, ?ExportElementInterface $export = null, ?array $centers = null) + public function isGrantedForElement(ExportElementInterface $element, ?ExportElementInterface $export = null, ?array $centers = null): bool { if ($element instanceof ExportInterface || $element instanceof DirectExportInterface) { $role = $element->requiredRole(); @@ -548,13 +542,12 @@ class ExportManager * Check for acl. If an user is not authorized to see an aggregator, throw an * UnauthorizedException. * - * @param type $data * @throw UnauthorizedHttpException if the user is not authorized */ private function handleAggregators( ExportInterface $export, QueryBuilder $qb, - $data, + array $data, array $center ) { $aggregators = $this->retrieveUsedAggregators($data); @@ -600,9 +593,9 @@ class ExportManager /** * @param mixed $data * - * @return AggregatorInterface[] + * @return iterable */ - private function retrieveUsedAggregators($data) + private function retrieveUsedAggregators($data): iterable { if (null === $data) { return []; diff --git a/src/Bundle/ChillMainBundle/Form/Type/Export/AggregatorType.php b/src/Bundle/ChillMainBundle/Form/Type/Export/AggregatorType.php index eff303573..1ea01d5f8 100644 --- a/src/Bundle/ChillMainBundle/Form/Type/Export/AggregatorType.php +++ b/src/Bundle/ChillMainBundle/Form/Type/Export/AggregatorType.php @@ -32,7 +32,6 @@ class AggregatorType extends AbstractType ->add('enabled', CheckboxType::class, [ 'value' => true, 'required' => false, - 'data' => false, ]); $filterFormBuilder = $builder->create('form', FormType::class, [ diff --git a/src/Bundle/ChillMainBundle/Form/Type/Export/FilterType.php b/src/Bundle/ChillMainBundle/Form/Type/Export/FilterType.php index 153f8946b..7994881d5 100644 --- a/src/Bundle/ChillMainBundle/Form/Type/Export/FilterType.php +++ b/src/Bundle/ChillMainBundle/Form/Type/Export/FilterType.php @@ -33,7 +33,6 @@ class FilterType extends AbstractType $builder ->add(self::ENABLED_FIELD, CheckboxType::class, [ 'value' => true, - 'data' => false, 'required' => false, ]); diff --git a/src/Bundle/ChillMainBundle/Form/Type/Export/PickFormatterType.php b/src/Bundle/ChillMainBundle/Form/Type/Export/PickFormatterType.php index ce442231e..b3253ec42 100644 --- a/src/Bundle/ChillMainBundle/Form/Type/Export/PickFormatterType.php +++ b/src/Bundle/ChillMainBundle/Form/Type/Export/PickFormatterType.php @@ -47,8 +47,6 @@ class PickFormatterType extends AbstractType 'multiple' => false, 'placeholder' => 'Choose a format', ]); - - //$builder->get('type')->addModelTransformer($transformer); } public function configureOptions(OptionsResolver $resolver) diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/MaritalStatusAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/MaritalStatusAggregator.php index 08bde4bda..c311aadf3 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/MaritalStatusAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/MaritalStatusAggregator.php @@ -48,6 +48,7 @@ final class MaritalStatusAggregator implements AggregatorInterface public function applyOn() { + return 'abcde'; return Declarations::PERSON_TYPE; } @@ -56,6 +57,11 @@ final class MaritalStatusAggregator implements AggregatorInterface // no form } + public function getFormDefaultData(): array + { + return []; + } + public function getLabels($key, array $values, $data) { return function ($value): string { diff --git a/src/Bundle/ChillPersonBundle/Export/Export/CountPerson.php b/src/Bundle/ChillPersonBundle/Export/Export/CountPerson.php index 60429ae55..c1800395c 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/CountPerson.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/CountPerson.php @@ -38,6 +38,11 @@ class CountPerson implements ExportInterface, GroupedExportInterface // No form necessary } + public function getFormDefaultData(): array + { + return []; + } + public function getAllowedFormattersTypes() { return [FormatterInterface::TYPE_TABULAR]; @@ -115,9 +120,9 @@ class CountPerson implements ExportInterface, GroupedExportInterface public function supportsModifiers() { return [ - Declarations::PERSON_TYPE, - Declarations::PERSON_IMPLIED_IN, - //Declarations::ACP_TYPE + 'abcde', + //Declarations::PERSON_TYPE, + //Declarations::PERSON_IMPLIED_IN, ]; } } diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/AgeFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/AgeFilter.php index c05f97ca8..66db7e95b 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/AgeFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/AgeFilter.php @@ -73,6 +73,7 @@ class AgeFilter implements ExportElementValidatedInterface, FilterInterface public function applyOn() { + return 'abcde'; return Declarations::PERSON_TYPE; } @@ -92,6 +93,15 @@ class AgeFilter implements ExportElementValidatedInterface, FilterInterface ]); } + public function getFormDefaultData(): array + { + return [ + 'min_age' => 0, + 'max_age' => 120, + 'date_calc' => new RollingDate(RollingDate::T_TODAY), + ]; + } + public function describeAction($data, $format = 'string') { return ['Filtered by person\'s age: ' From cb0a6bbd21403a8de3be1af05cac7fe1094f9bf0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Sun, 4 Jun 2023 01:10:50 +0200 Subject: [PATCH 126/321] Regenerate data from saved export on formatter test [ci-skip] --- .../Controller/ExportController.php | 31 ++++++++-------- .../Export/ExportFormHelper.php | 35 +++++++++++++++++-- .../Export/Formatter/SpreadSheetFormatter.php | 20 ++++++++--- .../NationalityAggregator.php | 8 +++++ 4 files changed, 71 insertions(+), 23 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Controller/ExportController.php b/src/Bundle/ChillMainBundle/Controller/ExportController.php index 41237b21e..2ad6377a6 100644 --- a/src/Bundle/ChillMainBundle/Controller/ExportController.php +++ b/src/Bundle/ChillMainBundle/Controller/ExportController.php @@ -297,8 +297,18 @@ class ExportController extends AbstractController $isGenerate = strpos($step, 'generate_') === 0; $options = match ($step) { - 'export', 'generate_export' => ['picked_centers' => $exportManager->getPickedCenters($data['centers'])], - default => [], + 'export', 'generate_export' => [ + 'export_alias' => $alias, + 'picked_centers' => $exportManager->getPickedCenters($data['centers']) + ], + 'formatter', 'generate_formatter' => [ + 'export_alias' => $alias, + 'formatter_alias' => $exportManager->getFormatterAlias($data['export']), + 'aggregator_aliases' => $exportManager->getUsedAggregatorsAliases($data['export']), + ], + default => [ + 'export_alias' => $alias, + ], }; $defaultFormData = match ($savedExport) { @@ -318,26 +328,15 @@ class ExportController extends AbstractController ); if ('centers' === $step || 'generate_centers' === $step) { - $builder->add('centers', PickCenterType::class, [ - 'export_alias' => $alias, - ]); + $builder->add('centers', PickCenterType::class, $options); } if ('export' === $step || 'generate_export' === $step) { - $builder->add('export', ExportType::class, [ - 'export_alias' => $alias, - 'picked_centers' => $exportManager->getPickedCenters($data['centers']), - ]); + $builder->add('export', ExportType::class, $options); } if ('formatter' === $step || 'generate_formatter' === $step) { - $builder->add('formatter', FormatterType::class, [ - 'formatter_alias' => $exportManager - ->getFormatterAlias($data['export']), - 'export_alias' => $alias, - 'aggregator_aliases' => $exportManager - ->getUsedAggregatorsAliases($data['export']), - ]); + $builder->add('formatter', FormatterType::class, $options); } $builder->add('submit', SubmitType::class, [ diff --git a/src/Bundle/ChillMainBundle/Export/ExportFormHelper.php b/src/Bundle/ChillMainBundle/Export/ExportFormHelper.php index 6f00c91da..3deb2acbc 100644 --- a/src/Bundle/ChillMainBundle/Export/ExportFormHelper.php +++ b/src/Bundle/ChillMainBundle/Export/ExportFormHelper.php @@ -14,6 +14,7 @@ namespace Chill\MainBundle\Export; use Chill\MainBundle\Entity\SavedExport; use Chill\MainBundle\Form\Type\Export\ExportType; use Chill\MainBundle\Form\Type\Export\FilterType; +use Chill\MainBundle\Form\Type\Export\FormatterType; use Chill\MainBundle\Form\Type\Export\PickCenterType; use Chill\MainBundle\Security\Authorization\AuthorizationHelperForCurrentUserInterface; use Symfony\Component\Form\Extension\Core\Type\FormType; @@ -33,11 +34,18 @@ final readonly class ExportFormHelper return match ($step) { 'centers', 'generate_centers' => ['centers' => $this->authorizationHelper->getReachableCenters($export->requiredRole())], 'export', 'generate_export' => ['export' => $this->getDefaultDataStepExport($export, $options)], - 'formatter', 'generate_formatter' => [], + 'formatter', 'generate_formatter' => ['formatter' => $this->getDefaultDataStepFormatter($options)], default => throw new \LogicException("step not allowed : " . $step), }; } + private function getDefaultDataStepFormatter(array $options): array + { + $formatter = $this->exportManager->getFormatter($options['formatter_alias']); + + return $formatter->getFormDefaultData($options['aggregator_aliases']); + } + private function getDefaultDataStepExport(ExportInterface|DirectExportInterface $export, array $options): array { $data = [ @@ -87,7 +95,7 @@ final readonly class ExportFormHelper return match ($step) { 'centers', 'generate_centers' => $this->savedExportDataToFormDataStepCenter($savedExport), 'export', 'generate_export' => $this->savedExportDataToFormDataStepExport($savedExport, $formOptions), - 'formatter', 'generate_formatter' => [], + 'formatter', 'generate_formatter' => $this->savedExportDataToFormDataStepFormatter($savedExport, $formOptions), default => throw new \LogicException("this step is not allowed: " . $step), }; } @@ -134,4 +142,27 @@ final readonly class ExportFormHelper return $form->getData(); } + + private function savedExportDataToFormDataStepFormatter( + SavedExport $savedExport, + array $formOptions + ): array { + dump(__METHOD__); + $builder = $this->formFactory + ->createBuilder( + FormType::class, + [], + [ + 'csrf_protection' => false, + ] + ); + + $builder->add('formatter', FormatterType::class, [ + 'export_alias' => $savedExport->getExportAlias(), ...$formOptions + ]); + $form = $builder->getForm(); + $form->submit($savedExport->getOptions()['formatter']); + + return $form->getData(); + } } diff --git a/src/Bundle/ChillMainBundle/Export/Formatter/SpreadSheetFormatter.php b/src/Bundle/ChillMainBundle/Export/Formatter/SpreadSheetFormatter.php index dc09c55a1..6a4b38e84 100644 --- a/src/Bundle/ChillMainBundle/Export/Formatter/SpreadSheetFormatter.php +++ b/src/Bundle/ChillMainBundle/Export/Formatter/SpreadSheetFormatter.php @@ -173,7 +173,19 @@ class SpreadSheetFormatter implements FormatterInterface } } - public function getName() + public function getFormDefaultData(array $aggregatorAliases): array + { + $data = ['format' => 'xlsx']; + + $aggregators = iterator_to_array($this->exportManager->getAggregators($aggregatorAliases)); + foreach (array_keys($aggregators) as $index => $alias) { + $data[$alias] = ['order' => $index + 1]; + } + + return $data; + } + + public function getName(): string { return 'SpreadSheet (xlsx, ods)'; } @@ -185,7 +197,7 @@ class SpreadSheetFormatter implements FormatterInterface array $exportData, array $filtersData, array $aggregatorsData - ) { + ): Response { // store all data when the process is initiated $this->result = $result; $this->formatterData = $formatterData; @@ -574,10 +586,8 @@ class SpreadSheetFormatter implements FormatterInterface * * This form allow to choose the aggregator position (row or column) and * the ordering - * - * @param string $nbAggregators */ - private function appendAggregatorForm(FormBuilderInterface $builder, $nbAggregators) + private function appendAggregatorForm(FormBuilderInterface $builder, int $nbAggregators): void { $builder->add('order', ChoiceType::class, [ 'choices' => array_combine( diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/NationalityAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/NationalityAggregator.php index d7c4097af..b1bd7a085 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/NationalityAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/NationalityAggregator.php @@ -88,6 +88,7 @@ final class NationalityAggregator implements AggregatorInterface, ExportElementV public function applyOn() { + return 'abcde'; return 'person'; } @@ -103,6 +104,13 @@ final class NationalityAggregator implements AggregatorInterface, ExportElementV ]); } + public function getFormDefaultData(): array + { + return [ + 'group_by_level' => 'country', + ]; + } + public function getLabels($key, array $values, $data) { $labels = []; From 02afcb30d488f66e1cfe30eb0e90e5e5b730c667 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Sun, 4 Jun 2023 01:11:38 +0200 Subject: [PATCH 127/321] [export][rector] first rector rule to add new method to filters --- .php-cs-fixer.dist.php | 1 + composer.json | 5 +- phpstan.neon.dist | 1 + phpunit.rector.xml | 29 +++ ...aultDataOnExportFilterAggregatorRector.php | 170 ++++++++++++++++++ ...DataOnExportFilterAggregatorRectorTest.php | 40 +++++ ...le-reuse-data-on-form-default-data.php.inc | 107 +++++++++++ .../Fixture/filter-no-data-on-builder.php.inc | 105 +++++++++++ ...er-reuse-data-on-form-default-data.php.inc | 96 ++++++++++ ...th-no-method-get-form-default-data.php.inc | 87 +++++++++ ...sting-get-form-default-data-method.php.inc | 46 +++++ .../config/config.php | 14 ++ 12 files changed, 700 insertions(+), 1 deletion(-) create mode 100644 phpunit.rector.xml create mode 100644 utils/rector/src/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector.php create mode 100644 utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRectorTest.php create mode 100644 utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/Fixture/filter-multiple-reuse-data-on-form-default-data.php.inc create mode 100644 utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/Fixture/filter-no-data-on-builder.php.inc create mode 100644 utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/Fixture/filter-reuse-data-on-form-default-data.php.inc create mode 100644 utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/Fixture/filter-with-no-method-get-form-default-data.php.inc create mode 100644 utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/Fixture/skip-filter-existing-get-form-default-data-method.php.inc create mode 100644 utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/config/config.php diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index 4b5bf98ee..31d64e600 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -13,6 +13,7 @@ $finder = PhpCsFixer\Finder::create(); $finder ->in(__DIR__.'/src') + ->in(__DIR__.'/utils') ->append([__FILE__]) ->exclude(['docs/', 'tests/app']) ->notPath('tests/app') diff --git a/composer.json b/composer.json index f6d3eb27a..d3567bca0 100644 --- a/composer.json +++ b/composer.json @@ -67,6 +67,7 @@ "fakerphp/faker": "^1.13", "jangregor/phpstan-prophecy": "^1.0", "nelmio/alice": "^3.8", + "nikic/php-parser": "^4.15", "phpspec/prophecy-phpunit": "^2.0", "phpstan/extension-installer": "^1.2", "phpstan/phpstan": "^1.9", @@ -110,7 +111,9 @@ "psr-4": { "App\\": "tests/app/src/", "Chill\\DocGeneratorBundle\\Tests\\": "src/Bundle/ChillDocGeneratorBundle/tests", - "Chill\\WopiBundle\\Tests\\": "src/Bundle/ChillDocGeneratorBundle/tests" + "Chill\\WopiBundle\\Tests\\": "src/Bundle/ChillDocGeneratorBundle/tests", + "Utils\\Rector\\": "utils/rector/src", + "Utils\\Rector\\Tests\\": "utils/rector/tests" } }, "config": { diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 56b7c2228..62dbe0468 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -2,6 +2,7 @@ parameters: level: 5 paths: - src/ + - utils/ tmpDir: .cache/ reportUnmatchedIgnoredErrors: false excludePaths: diff --git a/phpunit.rector.xml b/phpunit.rector.xml new file mode 100644 index 000000000..f8d9d3a11 --- /dev/null +++ b/phpunit.rector.xml @@ -0,0 +1,29 @@ + + + + + utils/rector/tests + + + + + + utils/rector/src + + + diff --git a/utils/rector/src/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector.php b/utils/rector/src/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector.php new file mode 100644 index 000000000..c41ecfa91 --- /dev/null +++ b/utils/rector/src/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector.php @@ -0,0 +1,170 @@ +classAnalyzer->hasImplements($node, FilterInterface::class)) { + return null; + } + + $buildFormStmtIndex = null; + $hasGetFormDefaultDataMethod = false; + foreach ($node->stmts as $k => $stmt) { + if (!$stmt instanceof Node\Stmt\ClassMethod) { + continue; + } + + if ('buildForm' === $stmt->name->name) { + $buildFormStmtIndex = $k; + } + + if ('getFormDefaultData' === $stmt->name->name) { + $hasGetFormDefaultDataMethod = true; + } + } + + if ($hasGetFormDefaultDataMethod || null === $buildFormStmtIndex) { + return null; + } + + $stmtBefore = array_slice($node->stmts, 0, $buildFormStmtIndex, false); + $stmtAfter = array_slice($node->stmts, $buildFormStmtIndex + 1); + + // lines to satisfay phpstan parser + if (!$node->stmts[$buildFormStmtIndex] instanceof Node\Stmt\ClassMethod) { + throw new \LogicException(); + } + + ['build_form_method' => $buildFormMethod, 'empty_to_replace' => $emptyToReplace] + = $this->filterBuildFormMethod($node->stmts[$buildFormStmtIndex]); + + $node->stmts = [ + ...$stmtBefore, + $buildFormMethod, + $this->makeGetFormDefaultData($node->stmts[$buildFormStmtIndex], $emptyToReplace), + ...$stmtAfter, + ]; + + return $node; + } + + private function makeGetFormDefaultData(Node\Stmt\ClassMethod $buildFormMethod, array $emptyToReplace): Node\Stmt\ClassMethod + { + $method = new Node\Stmt\ClassMethod('getFormDefaultData'); + $method->flags = Node\Stmt\Class_::MODIFIER_PUBLIC; + $method->returnType = new Node\Identifier('array'); + + $data = new Node\Expr\Array_([]); + + foreach ($emptyToReplace as $key => $value) { + $item = new Node\Expr\ArrayItem($value, new Node\Scalar\String_($key)); + $data->items[] = $item; + } + + $method->stmts[] = new Node\Stmt\Return_($data); + + return $method; + } + + /** + * @param Node\Stmt\ClassMethod $buildFormMethod + * @return array{"build_form_method": Node\Stmt\ClassMethod, "empty_to_replace": array} + */ + private function filterBuildFormMethod(Node\Stmt\ClassMethod $buildFormMethod): array + { + $builderName = $buildFormMethod->params[0]->var->name; + + $newStmts = []; + $emptyDataToReplace = []; + + foreach ($buildFormMethod->stmts as $stmt) { + if ($stmt instanceof Node\Stmt\Expression + // it must be a method call + && $stmt->expr instanceof Node\Expr\MethodCall + // the method call must be "add" + && $stmt->expr->name instanceof Node\Identifier + && $stmt->expr->name->name === 'add' + // and the method call must apply on the builder (compare with builderName) + && $stmt->expr->var instanceof Node\Expr\Variable + && $stmt->expr->var->name === $builderName + // it must have a first argument, a string + // TODO what happens if a value, or a const ? + && ($stmt->expr->args[0] ?? null) instanceof Node\Arg + && $stmt->expr->args[0]->value instanceof Node\Scalar\String_ + // and a third argument, an array + && ($stmt->expr->args[2] ?? null) instanceof Node\Arg + && $stmt->expr->args[2]->value instanceof Node\Expr\Array_ + ) { + + // we parse on the 3rd argument, to find if there is an 'empty_data' key + $emptyDataIndex = null; + foreach ($stmt->expr->args[2]->value->items as $arrayItemIndex => $item) { + /* @phpstan-ignore-next-line */ + if ($item->key->value === 'data') { + $k = $stmt->expr->args[0]->value->value; + $emptyDataToReplace[$k] = $item->value; + $emptyDataIndex = $arrayItemIndex; + } + } + + if (null !== $emptyDataIndex) { + $stmt->expr->args[2]->value->items = array_values( + array_filter( + $stmt->expr->args[2]->value->items, + /* @phpstan-ignore-next-line */ + fn (Node\Expr\ArrayItem $item) => $item->key->value !== 'data' + ) + ); + } + + $newStmts[] = $stmt; + } else { + $newStmts[] = $stmt; + } + } + + $buildFormMethod->stmts = $newStmts; + + return ['build_form_method' => $buildFormMethod, "empty_to_replace" => $emptyDataToReplace]; + } +} diff --git a/utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRectorTest.php b/utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRectorTest.php new file mode 100644 index 000000000..800d2876f --- /dev/null +++ b/utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRectorTest.php @@ -0,0 +1,40 @@ +doTestFile($file); + } + + public function provideData(): \Iterator + { + return self::yieldFilesFromDirectory(__DIR__.'/Fixture'); + } + + public function provideConfigFilePath(): string + { + return __DIR__.'/config/config.php'; + } +} diff --git a/utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/Fixture/filter-multiple-reuse-data-on-form-default-data.php.inc b/utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/Fixture/filter-multiple-reuse-data-on-form-default-data.php.inc new file mode 100644 index 000000000..5429d3c82 --- /dev/null +++ b/utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/Fixture/filter-multiple-reuse-data-on-form-default-data.php.inc @@ -0,0 +1,107 @@ +add('foo', PickRollingDateType::class, [ + 'label' => 'Test thing', + 'data' => new RollingDate(RollingDate::T_TODAY) + ]); + + $builder->add('baz', TextType::class, [ + 'label' => 'OrNiCar', + 'data' => 'Castor' + ]); + } + + public function getTitle() + { + // TODO: Implement getTitle() method. + } + + public function addRole(): ?string + { + // TODO: Implement addRole() method. + } + + public function alterQuery(QueryBuilder $qb, $data) + { + // TODO: Implement alterQuery() method. + } + + public function applyOn() + { + // TODO: Implement applyOn() method. + } +} +?> +----- +add('foo', PickRollingDateType::class, [ + 'label' => 'Test thing' + ]); + + $builder->add('baz', TextType::class, [ + 'label' => 'OrNiCar' + ]); + } + public function getFormDefaultData(): array + { + return ['foo' => new RollingDate(RollingDate::T_TODAY), 'baz' => 'Castor']; + } + + public function getTitle() + { + // TODO: Implement getTitle() method. + } + + public function addRole(): ?string + { + // TODO: Implement addRole() method. + } + + public function alterQuery(QueryBuilder $qb, $data) + { + // TODO: Implement alterQuery() method. + } + + public function applyOn() + { + // TODO: Implement applyOn() method. + } +} +?> diff --git a/utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/Fixture/filter-no-data-on-builder.php.inc b/utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/Fixture/filter-no-data-on-builder.php.inc new file mode 100644 index 000000000..285c16b50 --- /dev/null +++ b/utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/Fixture/filter-no-data-on-builder.php.inc @@ -0,0 +1,105 @@ +add('foo', PickRollingDateType::class, [ + 'label' => 'Test thing', + ]); + + $builder->add('baz', TextType::class, [ + 'label' => 'OrNiCar', + ]); + } + + public function getTitle() + { + // TODO: Implement getTitle() method. + } + + public function addRole(): ?string + { + // TODO: Implement addRole() method. + } + + public function alterQuery(QueryBuilder $qb, $data) + { + // TODO: Implement alterQuery() method. + } + + public function applyOn() + { + // TODO: Implement applyOn() method. + } +} +?> +----- +add('foo', PickRollingDateType::class, [ + 'label' => 'Test thing', + ]); + + $builder->add('baz', TextType::class, [ + 'label' => 'OrNiCar', + ]); + } + public function getFormDefaultData(): array + { + return []; + } + + public function getTitle() + { + // TODO: Implement getTitle() method. + } + + public function addRole(): ?string + { + // TODO: Implement addRole() method. + } + + public function alterQuery(QueryBuilder $qb, $data) + { + // TODO: Implement alterQuery() method. + } + + public function applyOn() + { + // TODO: Implement applyOn() method. + } +} +?> diff --git a/utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/Fixture/filter-reuse-data-on-form-default-data.php.inc b/utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/Fixture/filter-reuse-data-on-form-default-data.php.inc new file mode 100644 index 000000000..b2e78e49c --- /dev/null +++ b/utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/Fixture/filter-reuse-data-on-form-default-data.php.inc @@ -0,0 +1,96 @@ +add('test', PickRollingDateType::class, [ + 'label' => 'Test thing', + 'data' => new RollingDate(RollingDate::T_TODAY) + ]); + } + + public function getTitle() + { + // TODO: Implement getTitle() method. + } + + public function addRole(): ?string + { + // TODO: Implement addRole() method. + } + + public function alterQuery(QueryBuilder $qb, $data) + { + // TODO: Implement alterQuery() method. + } + + public function applyOn() + { + // TODO: Implement applyOn() method. + } +} +?> +----- +add('test', PickRollingDateType::class, [ + 'label' => 'Test thing' + ]); + } + public function getFormDefaultData(): array + { + return ['test' => new RollingDate(RollingDate::T_TODAY)]; + } + + public function getTitle() + { + // TODO: Implement getTitle() method. + } + + public function addRole(): ?string + { + // TODO: Implement addRole() method. + } + + public function alterQuery(QueryBuilder $qb, $data) + { + // TODO: Implement alterQuery() method. + } + + public function applyOn() + { + // TODO: Implement applyOn() method. + } +} +?> diff --git a/utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/Fixture/filter-with-no-method-get-form-default-data.php.inc b/utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/Fixture/filter-with-no-method-get-form-default-data.php.inc new file mode 100644 index 000000000..687bd9d0c --- /dev/null +++ b/utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/Fixture/filter-with-no-method-get-form-default-data.php.inc @@ -0,0 +1,87 @@ + +----- + diff --git a/utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/Fixture/skip-filter-existing-get-form-default-data-method.php.inc b/utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/Fixture/skip-filter-existing-get-form-default-data-method.php.inc new file mode 100644 index 000000000..2fefc908d --- /dev/null +++ b/utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/Fixture/skip-filter-existing-get-form-default-data-method.php.inc @@ -0,0 +1,46 @@ +rule(\Utils\Rector\Rector\ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector::class); +}; From c8bab1218f04e58f3eb20c19ef9a4e61e9f6c88c Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Mon, 5 Jun 2023 10:01:35 +0200 Subject: [PATCH 128/321] FIX [filiation][validator] adjust validation condition --- .../Relationship/RelationshipNoDuplicateValidator.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Validator/Constraints/Relationship/RelationshipNoDuplicateValidator.php b/src/Bundle/ChillPersonBundle/Validator/Constraints/Relationship/RelationshipNoDuplicateValidator.php index b44a966cc..5b1038287 100644 --- a/src/Bundle/ChillPersonBundle/Validator/Constraints/Relationship/RelationshipNoDuplicateValidator.php +++ b/src/Bundle/ChillPersonBundle/Validator/Constraints/Relationship/RelationshipNoDuplicateValidator.php @@ -47,10 +47,12 @@ class RelationshipNoDuplicateValidator extends ConstraintValidator foreach ($relationships as $r) { if (spl_object_hash($r) !== spl_object_hash($value) - and $r->getFromPerson() === $fromPerson - || $r->getFromPerson() === $toPerson - || $r->getToPerson() === $fromPerson - || $r->getToPerson() === $toPerson + and + ( + ($r->getFromPerson() === $fromPerson and $r->getToPerson() === $toPerson) + || + ($r->getFromPerson() === $toPerson and $r->getToPerson() === $fromPerson) + ) ) { $this->context->buildViolation($constraint->message) ->addViolation(); From d5ee158caa43639f853b13d2d68368c9b90cf731 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Mon, 5 Jun 2023 16:41:55 +0200 Subject: [PATCH 129/321] [export][rector] rector rules to add get form default data on export, aggregator, direct export --- ...aultDataOnExportFilterAggregatorRector.php | 10 +- ...th-no-method-get-form-default-data.php.inc | 133 ++++++++++++++++++ ...th-no-method-get-form-default-data.php.inc | 77 ++++++++++ ...th-no-method-get-form-default-data.php.inc | 95 +++++++++++++ 4 files changed, 314 insertions(+), 1 deletion(-) create mode 100644 utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/Fixture/aggregator-with-no-method-get-form-default-data.php.inc create mode 100644 utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/Fixture/direct-export-with-no-method-get-form-default-data.php.inc create mode 100644 utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/Fixture/export-with-no-method-get-form-default-data.php.inc diff --git a/utils/rector/src/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector.php b/utils/rector/src/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector.php index c41ecfa91..5fe993180 100644 --- a/utils/rector/src/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector.php +++ b/utils/rector/src/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector.php @@ -11,6 +11,9 @@ declare(strict_types=1); namespace Utils\Rector\Rector; +use Chill\MainBundle\Export\AggregatorInterface; +use Chill\MainBundle\Export\DirectExportInterface; +use Chill\MainBundle\Export\ExportInterface; use Chill\MainBundle\Export\FilterInterface; use PhpParser\Node; use Rector\Core\Rector\AbstractRector; @@ -43,7 +46,12 @@ class ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector extends Abstra return null; } - if (!$this->classAnalyzer->hasImplements($node, FilterInterface::class)) { + if ( + !$this->classAnalyzer->hasImplements($node, FilterInterface::class) + && !$this->classAnalyzer->hasImplements($node, AggregatorInterface::class) + && !$this->classAnalyzer->hasImplements($node, ExportInterface::class) + && !$this->classAnalyzer->hasImplements($node, DirectExportInterface::class) + ) { return null; } diff --git a/utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/Fixture/aggregator-with-no-method-get-form-default-data.php.inc b/utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/Fixture/aggregator-with-no-method-get-form-default-data.php.inc new file mode 100644 index 000000000..aa373e629 --- /dev/null +++ b/utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/Fixture/aggregator-with-no-method-get-form-default-data.php.inc @@ -0,0 +1,133 @@ + +----- + diff --git a/utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/Fixture/direct-export-with-no-method-get-form-default-data.php.inc b/utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/Fixture/direct-export-with-no-method-get-form-default-data.php.inc new file mode 100644 index 000000000..d60f62dcb --- /dev/null +++ b/utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/Fixture/direct-export-with-no-method-get-form-default-data.php.inc @@ -0,0 +1,77 @@ + +----- + diff --git a/utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/Fixture/export-with-no-method-get-form-default-data.php.inc b/utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/Fixture/export-with-no-method-get-form-default-data.php.inc new file mode 100644 index 000000000..ba5a6d4ec --- /dev/null +++ b/utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/Fixture/export-with-no-method-get-form-default-data.php.inc @@ -0,0 +1,95 @@ + +----- + From ea77adc64043d1bc1581662e4aff8738139ab640 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Mon, 5 Jun 2023 16:47:45 +0200 Subject: [PATCH 130/321] [edit export] add required method on export's interface The method "getFormDefaultData" is applyied on every interface which will use it: - ExportInterface - AggregatorInterface - DirectExportInterface - FilterInterface The method buildForm is moved to those interfaces. [ci-skip] --- .../ChillMainBundle/Export/AggregatorInterface.php | 11 +++++++++++ .../ChillMainBundle/Export/DirectExportInterface.php | 11 +++++++++++ .../Export/ExportElementInterface.php | 4 ---- .../ChillMainBundle/Export/ExportInterface.php | 11 +++++++++++ .../ChillMainBundle/Export/FilterInterface.php | 12 ++++++++++++ .../ChillMainBundle/Export/FormatterInterface.php | 5 +++++ 6 files changed, 50 insertions(+), 4 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Export/AggregatorInterface.php b/src/Bundle/ChillMainBundle/Export/AggregatorInterface.php index 850d29838..8d805f612 100644 --- a/src/Bundle/ChillMainBundle/Export/AggregatorInterface.php +++ b/src/Bundle/ChillMainBundle/Export/AggregatorInterface.php @@ -12,6 +12,7 @@ declare(strict_types=1); namespace Chill\MainBundle\Export; use Closure; +use Symfony\Component\Form\FormBuilderInterface; /** * Interface for Aggregators. @@ -21,6 +22,16 @@ use Closure; */ interface AggregatorInterface extends ModifierInterface { + /** + * Add a form to collect data from the user. + */ + public function buildForm(FormBuilderInterface $builder); + + /** + * Get the default data, that can be use as "data" for the form + */ + public function getFormDefaultData(): array; + /** * get a callable which will be able to transform the results into * viewable and understable string. diff --git a/src/Bundle/ChillMainBundle/Export/DirectExportInterface.php b/src/Bundle/ChillMainBundle/Export/DirectExportInterface.php index 9703a42de..5bad5bb42 100644 --- a/src/Bundle/ChillMainBundle/Export/DirectExportInterface.php +++ b/src/Bundle/ChillMainBundle/Export/DirectExportInterface.php @@ -11,10 +11,21 @@ declare(strict_types=1); namespace Chill\MainBundle\Export; +use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\HttpFoundation\Response; interface DirectExportInterface extends ExportElementInterface { + /** + * Add a form to collect data from the user. + */ + public function buildForm(FormBuilderInterface $builder); + + /** + * Get the default data, that can be use as "data" for the form + */ + public function getFormDefaultData(): array; + /** * Generate the export. */ diff --git a/src/Bundle/ChillMainBundle/Export/ExportElementInterface.php b/src/Bundle/ChillMainBundle/Export/ExportElementInterface.php index 3b0402f42..b0441c829 100644 --- a/src/Bundle/ChillMainBundle/Export/ExportElementInterface.php +++ b/src/Bundle/ChillMainBundle/Export/ExportElementInterface.php @@ -19,10 +19,6 @@ use Symfony\Component\Form\FormBuilderInterface; */ interface ExportElementInterface { - /** - * Add a form to collect data from the user. - */ - public function buildForm(FormBuilderInterface $builder); /** * get a title, which will be used in UI (and translated). diff --git a/src/Bundle/ChillMainBundle/Export/ExportInterface.php b/src/Bundle/ChillMainBundle/Export/ExportInterface.php index d4e456ca6..f357a9fdb 100644 --- a/src/Bundle/ChillMainBundle/Export/ExportInterface.php +++ b/src/Bundle/ChillMainBundle/Export/ExportInterface.php @@ -13,6 +13,7 @@ namespace Chill\MainBundle\Export; use Doctrine\ORM\NativeQuery; use Doctrine\ORM\QueryBuilder; +use Symfony\Component\Form\FormBuilderInterface; /** * Interface for Export. @@ -28,6 +29,16 @@ use Doctrine\ORM\QueryBuilder; */ interface ExportInterface extends ExportElementInterface { + /** + * Add a form to collect data from the user. + */ + public function buildForm(FormBuilderInterface $builder); + + /** + * Get the default data, that can be use as "data" for the form + */ + public function getFormDefaultData(): array; + /** * Return which formatter type is allowed for this report. * diff --git a/src/Bundle/ChillMainBundle/Export/FilterInterface.php b/src/Bundle/ChillMainBundle/Export/FilterInterface.php index 5e398c30d..7db850108 100644 --- a/src/Bundle/ChillMainBundle/Export/FilterInterface.php +++ b/src/Bundle/ChillMainBundle/Export/FilterInterface.php @@ -11,6 +11,8 @@ declare(strict_types=1); namespace Chill\MainBundle\Export; +use Symfony\Component\Form\FormBuilderInterface; + /** * Interface for filters. * @@ -23,6 +25,16 @@ interface FilterInterface extends ModifierInterface { public const STRING_FORMAT = 'string'; + /** + * Add a form to collect data from the user. + */ + public function buildForm(FormBuilderInterface $builder); + + /** + * Get the default data, that can be use as "data" for the form + */ + public function getFormDefaultData(): array; + /** * Describe the filtering action. * diff --git a/src/Bundle/ChillMainBundle/Export/FormatterInterface.php b/src/Bundle/ChillMainBundle/Export/FormatterInterface.php index 1f9df225a..e939c47f2 100644 --- a/src/Bundle/ChillMainBundle/Export/FormatterInterface.php +++ b/src/Bundle/ChillMainBundle/Export/FormatterInterface.php @@ -34,6 +34,11 @@ interface FormatterInterface array $aggregatorAliases ); + /** + * get the default data for the form build by buildForm + */ + public function getFormDefaultData(array $aggregatorAliases): array; + public function getName(); /** From 3adf3625dc3cff44513eb08ab0b42804c0f4dfd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Mon, 5 Jun 2023 17:21:21 +0200 Subject: [PATCH 131/321] apply rector rules for exports --- docs/source/_static/code/exports/BirthdateFilter.php | 6 ++++-- docs/source/_static/code/exports/CountPerson.php | 4 ++++ rector.php | 3 +++ .../ACPAggregators/ByActivityNumberAggregator.php | 4 ++++ .../Aggregator/ACPAggregators/ByCreatorAggregator.php | 4 ++++ .../ACPAggregators/BySocialActionAggregator.php | 4 ++++ .../Aggregator/ACPAggregators/BySocialIssueAggregator.php | 4 ++++ .../Aggregator/ACPAggregators/ByThirdpartyAggregator.php | 4 ++++ .../Aggregator/ACPAggregators/CreatorScopeAggregator.php | 4 ++++ .../Export/Aggregator/ACPAggregators/DateAggregator.php | 5 ++++- .../Aggregator/ACPAggregators/LocationTypeAggregator.php | 4 ++++ .../Export/Aggregator/ActivityTypeAggregator.php | 4 ++++ .../Export/Aggregator/ActivityUserAggregator.php | 4 ++++ .../Export/Aggregator/ActivityUsersAggregator.php | 4 ++++ .../Export/Aggregator/ActivityUsersJobAggregator.php | 4 ++++ .../Export/Aggregator/ActivityUsersScopeAggregator.php | 4 ++++ .../PersonAggregators/ActivityReasonAggregator.php | 4 ++++ .../Export/Aggregator/SentReceivedAggregator.php | 4 ++++ .../Export/Export/LinkedToACP/AvgActivityDuration.php | 4 ++++ .../Export/LinkedToACP/AvgActivityVisitDuration.php | 4 ++++ .../Export/Export/LinkedToACP/CountActivity.php | 4 ++++ .../Export/Export/LinkedToACP/SumActivityDuration.php | 4 ++++ .../Export/LinkedToACP/SumActivityVisitDuration.php | 4 ++++ .../Export/Export/LinkedToPerson/CountActivity.php | 4 ++++ .../Export/Export/LinkedToPerson/StatActivityDuration.php | 4 ++++ .../Export/Filter/ACPFilters/ActivityTypeFilter.php | 4 ++++ .../Export/Filter/ACPFilters/ByCreatorFilter.php | 4 ++++ .../Export/Filter/ACPFilters/BySocialActionFilter.php | 4 ++++ .../Export/Filter/ACPFilters/BySocialIssueFilter.php | 4 ++++ .../Export/Filter/ACPFilters/EmergencyFilter.php | 5 ++++- .../Export/Filter/ACPFilters/HasNoActivityFilter.php | 4 ++++ .../Export/Filter/ACPFilters/LocationFilter.php | 4 ++++ .../Export/Filter/ACPFilters/LocationTypeFilter.php | 4 ++++ .../Export/Filter/ACPFilters/SentReceivedFilter.php | 5 ++++- .../Export/Filter/ACPFilters/UserFilter.php | 4 ++++ .../Export/Filter/ACPFilters/UserScopeFilter.php | 4 ++++ .../Export/Filter/ActivityDateFilter.php | 4 ++++ .../Export/Filter/ActivityTypeFilter.php | 4 ++++ .../Export/Filter/ActivityUsersFilter.php | 4 ++++ .../Export/Filter/PersonFilters/ActivityReasonFilter.php | 4 ++++ .../PersonHavingActivityBetweenDateFilter.php | 7 ++++--- .../ChillActivityBundle/Export/Filter/UsersJobFilter.php | 4 ++++ .../Export/Filter/UsersScopeFilter.php | 4 ++++ .../src/Export/Aggregator/ByActivityTypeAggregator.php | 4 ++++ .../src/Export/Aggregator/ByUserJobAggregator.php | 4 ++++ .../src/Export/Aggregator/ByUserScopeAggregator.php | 4 ++++ .../src/Export/Export/AvgAsideActivityDuration.php | 4 ++++ .../src/Export/Export/CountAsideActivity.php | 4 ++++ .../src/Export/Export/SumAsideActivityDuration.php | 4 ++++ .../src/Export/Filter/ByActivityTypeFilter.php | 4 ++++ .../src/Export/Filter/ByDateFilter.php | 4 ++++ .../src/Export/Filter/ByUserFilter.php | 4 ++++ .../src/Export/Filter/ByUserJobFilter.php | 4 ++++ .../src/Export/Filter/ByUserScopeFilter.php | 4 ++++ .../Export/Aggregator/AgentAggregator.php | 4 ++++ .../Export/Aggregator/CancelReasonAggregator.php | 4 ++++ .../Export/Aggregator/JobAggregator.php | 4 ++++ .../Export/Aggregator/LocationAggregator.php | 4 ++++ .../Export/Aggregator/LocationTypeAggregator.php | 4 ++++ .../Export/Aggregator/MonthYearAggregator.php | 4 ++++ .../Export/Aggregator/ScopeAggregator.php | 4 ++++ .../Export/Aggregator/UrgencyAggregator.php | 4 ++++ .../ChillCalendarBundle/Export/Export/CountCalendars.php | 4 ++++ .../Export/Export/StatCalendarAvgDuration.php | 4 ++++ .../Export/Export/StatCalendarSumDuration.php | 4 ++++ .../ChillCalendarBundle/Export/Filter/AgentFilter.php | 4 ++++ .../Export/Filter/BetweenDatesFilter.php | 4 ++++ .../Export/Filter/CalendarRangeFilter.php | 5 ++++- .../ChillCalendarBundle/Export/Filter/JobFilter.php | 4 ++++ .../ChillCalendarBundle/Export/Filter/ScopeFilter.php | 4 ++++ .../AdministrativeLocationAggregator.php | 4 ++++ .../ByActionNumberAggregator.php | 4 ++++ .../ClosingMotiveAggregator.php | 4 ++++ .../ConfidentialAggregator.php | 4 ++++ .../CreatorJobAggregator.php | 4 ++++ .../AccompanyingCourseAggregators/DurationAggregator.php | 4 ++++ .../AccompanyingCourseAggregators/EmergencyAggregator.php | 4 ++++ .../EvaluationAggregator.php | 4 ++++ .../GeographicalUnitStatAggregator.php | 4 ++++ .../AccompanyingCourseAggregators/IntensityAggregator.php | 4 ++++ .../AccompanyingCourseAggregators/OriginAggregator.php | 4 ++++ .../AccompanyingCourseAggregators/ReferrerAggregator.php | 5 ++++- .../ReferrerScopeAggregator.php | 5 ++++- .../AccompanyingCourseAggregators/RequestorAggregator.php | 4 ++++ .../AccompanyingCourseAggregators/ScopeAggregator.php | 4 ++++ .../SocialActionAggregator.php | 4 ++++ .../SocialIssueAggregator.php | 4 ++++ .../AccompanyingCourseAggregators/StepAggregator.php | 8 +++++--- .../AccompanyingCourseAggregators/UserJobAggregator.php | 4 ++++ .../EvaluationAggregators/ByEndDateAggregator.php | 5 ++++- .../EvaluationAggregators/ByMaxDateAggregator.php | 5 ++++- .../EvaluationAggregators/ByStartDateAggregator.php | 5 ++++- .../EvaluationAggregators/EvaluationTypeAggregator.php | 4 ++++ .../EvaluationAggregators/HavingEndDateAggregator.php | 4 ++++ .../HouseholdAggregators/ChildrenNumberAggregator.php | 8 +++++--- .../HouseholdAggregators/CompositionAggregator.php | 8 +++++--- .../Export/Aggregator/PersonAggregators/AgeAggregator.php | 5 ++++- .../ByHouseholdCompositionAggregator.php | 5 ++++- .../PersonAggregators/CountryOfBirthAggregator.php | 4 ++++ .../Aggregator/PersonAggregators/GenderAggregator.php | 4 ++++ .../PersonAggregators/GeographicalUnitAggregator.php | 4 ++++ .../PersonAggregators/HouseholdPositionAggregator.php | 5 ++++- .../SocialWorkAggregators/ActionTypeAggregator.php | 4 ++++ .../SocialWorkAggregators/CurrentActionAggregator.php | 4 ++++ .../Aggregator/SocialWorkAggregators/GoalAggregator.php | 4 ++++ .../SocialWorkAggregators/GoalResultAggregator.php | 4 ++++ .../Aggregator/SocialWorkAggregators/JobAggregator.php | 4 ++++ .../SocialWorkAggregators/ReferrerAggregator.php | 4 ++++ .../Aggregator/SocialWorkAggregators/ResultAggregator.php | 4 ++++ .../Aggregator/SocialWorkAggregators/ScopeAggregator.php | 4 ++++ .../Export/Export/CountAccompanyingCourse.php | 4 ++++ .../Export/Export/CountAccompanyingPeriodWork.php | 4 ++++ .../ChillPersonBundle/Export/Export/CountEvaluation.php | 4 ++++ .../ChillPersonBundle/Export/Export/CountHousehold.php | 5 ++++- .../Export/Export/CountPersonWithAccompanyingCourse.php | 4 ++++ .../Export/Export/ListPersonDuplicate.php | 5 ++++- .../Export/Export/StatAccompanyingCourseDuration.php | 5 ++++- .../AccompanyingCourseFilters/ActiveOnDateFilter.php | 8 +++++--- .../ActiveOneDayBetweenDatesFilter.php | 4 ++++ .../AdministrativeLocationFilter.php | 4 ++++ .../AccompanyingCourseFilters/ClosingMotiveFilter.php | 4 ++++ .../AccompanyingCourseFilters/ConfidentialFilter.php | 5 ++++- .../Filter/AccompanyingCourseFilters/CreatorFilter.php | 4 ++++ .../Filter/AccompanyingCourseFilters/CreatorJobFilter.php | 4 ++++ .../Filter/AccompanyingCourseFilters/EmergencyFilter.php | 5 ++++- .../Filter/AccompanyingCourseFilters/EvaluationFilter.php | 4 ++++ .../GeographicalUnitStatFilter.php | 4 ++++ .../AccompanyingCourseFilters/HasNoActionFilter.php | 4 ++++ .../AccompanyingCourseFilters/HasNoReferrerFilter.php | 5 ++++- .../HasTemporaryLocationFilter.php | 4 ++++ .../HavingAnAccompanyingPeriodInfoWithinDatesFilter.php | 4 ++++ .../Filter/AccompanyingCourseFilters/IntensityFilter.php | 5 ++++- .../AccompanyingCourseFilters/OpenBetweenDatesFilter.php | 4 ++++ .../Filter/AccompanyingCourseFilters/OriginFilter.php | 4 ++++ .../Filter/AccompanyingCourseFilters/ReferrerFilter.php | 4 ++++ .../Filter/AccompanyingCourseFilters/RequestorFilter.php | 5 ++++- .../AccompanyingCourseFilters/SocialActionFilter.php | 4 ++++ .../AccompanyingCourseFilters/SocialIssueFilter.php | 4 ++++ .../Filter/AccompanyingCourseFilters/StepFilter.php | 4 ++++ .../Filter/AccompanyingCourseFilters/UserJobFilter.php | 4 ++++ .../Filter/AccompanyingCourseFilters/UserScopeFilter.php | 4 ++++ .../UserWorkingOnCourseFilter.php | 4 ++++ .../Export/Filter/EvaluationFilters/ByEndDateFilter.php | 4 ++++ .../Export/Filter/EvaluationFilters/ByStartDateFilter.php | 4 ++++ .../Filter/EvaluationFilters/CurrentEvaluationsFilter.php | 4 ++++ .../Filter/EvaluationFilters/EvaluationTypeFilter.php | 4 ++++ .../Export/Filter/EvaluationFilters/MaxDateFilter.php | 4 ++++ .../Export/Filter/HouseholdFilters/CompositionFilter.php | 4 ++++ .../Filter/PersonFilters/AddressRefStatusFilter.php | 4 ++++ .../Export/Filter/PersonFilters/BirthdateFilter.php | 6 ++++-- .../Filter/PersonFilters/ByHouseholdCompositionFilter.php | 4 ++++ .../Export/Filter/PersonFilters/DeadOrAliveFilter.php | 5 ++++- .../Export/Filter/PersonFilters/DeathdateFilter.php | 6 ++++-- .../Export/Filter/PersonFilters/GenderFilter.php | 4 ++++ .../Filter/PersonFilters/GeographicalUnitFilter.php | 4 ++++ .../Export/Filter/PersonFilters/MaritalStatusFilter.php | 4 ++++ .../Export/Filter/PersonFilters/NationalityFilter.php | 4 ++++ .../ResidentialAddressAtThirdpartyFilter.php | 5 ++++- .../PersonFilters/ResidentialAddressAtUserFilter.php | 5 ++++- .../Filter/PersonFilters/WithoutHouseholdComposition.php | 5 ++++- .../AccompanyingPeriodWorkEndDateBetweenDateFilter.php | 4 ++++ .../AccompanyingPeriodWorkStartDateBetweenDateFilter.php | 4 ++++ .../Filter/SocialWorkFilters/CurrentActionFilter.php | 4 ++++ .../Export/Filter/SocialWorkFilters/JobFilter.php | 4 ++++ .../Export/Filter/SocialWorkFilters/ReferrerFilter.php | 4 ++++ .../Export/Filter/SocialWorkFilters/ScopeFilter.php | 4 ++++ .../Filter/SocialWorkFilters/SocialWorkTypeFilter.php | 4 ++++ .../ChillReportBundle/Export/Filter/ReportDateFilter.php | 6 ++++-- 168 files changed, 675 insertions(+), 47 deletions(-) diff --git a/docs/source/_static/code/exports/BirthdateFilter.php b/docs/source/_static/code/exports/BirthdateFilter.php index 64c1d53a9..e25d8b42f 100644 --- a/docs/source/_static/code/exports/BirthdateFilter.php +++ b/docs/source/_static/code/exports/BirthdateFilter.php @@ -62,7 +62,6 @@ class BirthdateFilter implements ExportElementValidatedInterface, FilterInterfac { $builder->add('date_from', DateType::class, [ 'label' => 'Born after this date', - 'data' => new DateTime(), 'attr' => ['class' => 'datepicker'], 'widget' => 'single_text', 'format' => 'dd-MM-yyyy', @@ -70,12 +69,15 @@ class BirthdateFilter implements ExportElementValidatedInterface, FilterInterfac $builder->add('date_to', DateType::class, [ 'label' => 'Born before this date', - 'data' => new DateTime(), 'attr' => ['class' => 'datepicker'], 'widget' => 'single_text', 'format' => 'dd-MM-yyyy', ]); } + public function getFormDefaultData(): array + { + return ['date_from' => new DateTime(), 'date_to' => new DateTime()]; + } // here, we create a simple string which will describe the action of // the filter in the Response diff --git a/docs/source/_static/code/exports/CountPerson.php b/docs/source/_static/code/exports/CountPerson.php index afe19c73b..be800e52c 100644 --- a/docs/source/_static/code/exports/CountPerson.php +++ b/docs/source/_static/code/exports/CountPerson.php @@ -36,6 +36,10 @@ class CountPerson implements ExportInterface { // this export does not add any form } + public function getFormDefaultData(): array + { + return []; + } public function getAllowedFormattersTypes() { diff --git a/rector.php b/rector.php index ec9a0c684..b65dc2a59 100644 --- a/rector.php +++ b/rector.php @@ -24,6 +24,9 @@ return static function (RectorConfig $rectorConfig): void { LevelSetList::UP_TO_PHP_74 ]); + // chill rules + $rectorConfig->rule(\Utils\Rector\Rector\ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector::class); + // skip some path... $rectorConfig->skip([ // make rector stuck for some files diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByActivityNumberAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByActivityNumberAggregator.php index 5c6656009..c23db738e 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByActivityNumberAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByActivityNumberAggregator.php @@ -40,6 +40,10 @@ class ByActivityNumberAggregator implements AggregatorInterface { // No form needed } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByCreatorAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByCreatorAggregator.php index 69149737b..917459de3 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByCreatorAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByCreatorAggregator.php @@ -52,6 +52,10 @@ class ByCreatorAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/BySocialActionAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/BySocialActionAggregator.php index 89732412d..1a75357ae 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/BySocialActionAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/BySocialActionAggregator.php @@ -57,6 +57,10 @@ class BySocialActionAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/BySocialIssueAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/BySocialIssueAggregator.php index 158e87664..9100a8c8f 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/BySocialIssueAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/BySocialIssueAggregator.php @@ -57,6 +57,10 @@ class BySocialIssueAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByThirdpartyAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByThirdpartyAggregator.php index c3ca6d59c..ac05b153c 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByThirdpartyAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByThirdpartyAggregator.php @@ -57,6 +57,10 @@ class ByThirdpartyAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/CreatorScopeAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/CreatorScopeAggregator.php index 2c7ec1483..a4b5258e2 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/CreatorScopeAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/CreatorScopeAggregator.php @@ -57,6 +57,10 @@ class CreatorScopeAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/DateAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/DateAggregator.php index b4b23dc0b..ea2fa5ee4 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/DateAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/DateAggregator.php @@ -84,9 +84,12 @@ class DateAggregator implements AggregatorInterface 'multiple' => false, 'expanded' => true, 'empty_data' => self::DEFAULT_CHOICE, - 'data' => self::DEFAULT_CHOICE, ]); } + public function getFormDefaultData(): array + { + return ['frequency' => self::DEFAULT_CHOICE]; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/LocationTypeAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/LocationTypeAggregator.php index ec4ce6315..c72609e2c 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/LocationTypeAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/LocationTypeAggregator.php @@ -57,6 +57,10 @@ class LocationTypeAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityTypeAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityTypeAggregator.php index 7cd16718e..a74428b4a 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityTypeAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityTypeAggregator.php @@ -60,6 +60,10 @@ class ActivityTypeAggregator implements AggregatorInterface { // no form required for this aggregator } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data): Closure { diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUserAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUserAggregator.php index 9bde692c6..2fab2af83 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUserAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUserAggregator.php @@ -58,6 +58,10 @@ class ActivityUserAggregator implements AggregatorInterface { // nothing to add } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, $values, $data): Closure { diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersAggregator.php index 139f2743e..e1e9f161d 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersAggregator.php @@ -56,6 +56,10 @@ class ActivityUsersAggregator implements AggregatorInterface { // nothing to add on the form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersJobAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersJobAggregator.php index 5741a0e58..721078989 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersJobAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersJobAggregator.php @@ -55,6 +55,10 @@ class ActivityUsersJobAggregator implements \Chill\MainBundle\Export\AggregatorI { // nothing to add in the form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersScopeAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersScopeAggregator.php index 15da300be..d7932e9e8 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersScopeAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersScopeAggregator.php @@ -55,6 +55,10 @@ class ActivityUsersScopeAggregator implements \Chill\MainBundle\Export\Aggregato { // nothing to add in the form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/PersonAggregators/ActivityReasonAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/PersonAggregators/ActivityReasonAggregator.php index eaccf95cb..2537f2cf6 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/PersonAggregators/ActivityReasonAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/PersonAggregators/ActivityReasonAggregator.php @@ -110,6 +110,10 @@ class ActivityReasonAggregator implements AggregatorInterface, ExportElementVali ] ); } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/SentReceivedAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/SentReceivedAggregator.php index 5f772e156..ae1dae375 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/SentReceivedAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/SentReceivedAggregator.php @@ -47,6 +47,10 @@ class SentReceivedAggregator implements AggregatorInterface { // No form needed } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data): callable { diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityDuration.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityDuration.php index 34771d077..6930784d3 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityDuration.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityDuration.php @@ -39,6 +39,10 @@ class AvgActivityDuration implements ExportInterface, GroupedExportInterface public function buildForm(FormBuilderInterface $builder) { } + public function getFormDefaultData(): array + { + return []; + } public function getAllowedFormattersTypes(): array { diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityVisitDuration.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityVisitDuration.php index df21362cd..f1e926c64 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityVisitDuration.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityVisitDuration.php @@ -40,6 +40,10 @@ class AvgActivityVisitDuration implements ExportInterface, GroupedExportInterfac { // TODO: Implement buildForm() method. } + public function getFormDefaultData(): array + { + return []; + } public function getAllowedFormattersTypes(): array { diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/CountActivity.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/CountActivity.php index 6b7b1562d..d473a925a 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/CountActivity.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/CountActivity.php @@ -39,6 +39,10 @@ class CountActivity implements ExportInterface, GroupedExportInterface public function buildForm(FormBuilderInterface $builder) { } + public function getFormDefaultData(): array + { + return []; + } public function getAllowedFormattersTypes(): array { diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityDuration.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityDuration.php index e916cab54..8adb3b77f 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityDuration.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityDuration.php @@ -40,6 +40,10 @@ class SumActivityDuration implements ExportInterface, GroupedExportInterface { // TODO: Implement buildForm() method. } + public function getFormDefaultData(): array + { + return []; + } public function getAllowedFormattersTypes(): array { diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityVisitDuration.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityVisitDuration.php index 18a47289c..cc424e68b 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityVisitDuration.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityVisitDuration.php @@ -40,6 +40,10 @@ class SumActivityVisitDuration implements ExportInterface, GroupedExportInterfac { // TODO: Implement buildForm() method. } + public function getFormDefaultData(): array + { + return []; + } public function getAllowedFormattersTypes(): array { diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/CountActivity.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/CountActivity.php index 4246df173..6360251b3 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/CountActivity.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/CountActivity.php @@ -35,6 +35,10 @@ class CountActivity implements ExportInterface, GroupedExportInterface public function buildForm(FormBuilderInterface $builder) { } + public function getFormDefaultData(): array + { + return []; + } public function getAllowedFormattersTypes() { diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/StatActivityDuration.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/StatActivityDuration.php index 050034954..e68d47cd3 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/StatActivityDuration.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/StatActivityDuration.php @@ -53,6 +53,10 @@ class StatActivityDuration implements ExportInterface, GroupedExportInterface public function buildForm(FormBuilderInterface $builder) { } + public function getFormDefaultData(): array + { + return []; + } public function getAllowedFormattersTypes() { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/ActivityTypeFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/ActivityTypeFilter.php index c6616a4c6..4ffc3b38c 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/ActivityTypeFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/ActivityTypeFilter.php @@ -68,6 +68,10 @@ class ActivityTypeFilter implements FilterInterface 'expanded' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/ByCreatorFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/ByCreatorFilter.php index 322393f32..add9c7c3d 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/ByCreatorFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/ByCreatorFilter.php @@ -52,6 +52,10 @@ class ByCreatorFilter implements FilterInterface 'multiple' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/BySocialActionFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/BySocialActionFilter.php index d0c1b0fc7..08f6bbbc3 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/BySocialActionFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/BySocialActionFilter.php @@ -60,6 +60,10 @@ class BySocialActionFilter implements FilterInterface 'multiple' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/BySocialIssueFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/BySocialIssueFilter.php index bbb882a65..bd6e2ef4a 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/BySocialIssueFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/BySocialIssueFilter.php @@ -60,6 +60,10 @@ class BySocialIssueFilter implements FilterInterface 'multiple' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/EmergencyFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/EmergencyFilter.php index b79c2ca10..807ba3903 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/EmergencyFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/EmergencyFilter.php @@ -68,9 +68,12 @@ class EmergencyFilter implements FilterInterface 'multiple' => false, 'expanded' => true, 'empty_data' => self::DEFAULT_CHOICE, - 'data' => self::DEFAULT_CHOICE, ]); } + public function getFormDefaultData(): array + { + return ['accepted_emergency' => self::DEFAULT_CHOICE]; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/HasNoActivityFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/HasNoActivityFilter.php index 570f42ae0..b5dab4009 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/HasNoActivityFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/HasNoActivityFilter.php @@ -44,6 +44,10 @@ class HasNoActivityFilter implements FilterInterface { //no form needed } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/LocationFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/LocationFilter.php index 3d69d1633..312f3a6a0 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/LocationFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/LocationFilter.php @@ -46,6 +46,10 @@ class LocationFilter implements FilterInterface 'label' => 'pick location', ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/LocationTypeFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/LocationTypeFilter.php index 5fe928b6c..1c3415460 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/LocationTypeFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/LocationTypeFilter.php @@ -65,6 +65,10 @@ class LocationTypeFilter implements FilterInterface //'label' => false, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/SentReceivedFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/SentReceivedFilter.php index 8daa7a781..0f2a1c7e4 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/SentReceivedFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/SentReceivedFilter.php @@ -69,9 +69,12 @@ class SentReceivedFilter implements FilterInterface 'multiple' => false, 'expanded' => true, 'empty_data' => self::DEFAULT_CHOICE, - 'data' => self::DEFAULT_CHOICE, ]); } + public function getFormDefaultData(): array + { + return ['accepted_sentreceived' => self::DEFAULT_CHOICE]; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/UserFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/UserFilter.php index 6350f3ace..9ae988579 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/UserFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/UserFilter.php @@ -61,6 +61,10 @@ class UserFilter implements FilterInterface 'label' => 'Creators', ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/UserScopeFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/UserScopeFilter.php index 4319c100a..adb1e94f1 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/UserScopeFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/UserScopeFilter.php @@ -71,6 +71,10 @@ class UserScopeFilter implements FilterInterface 'expanded' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ActivityDateFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ActivityDateFilter.php index f2216c929..d1e69fe28 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ActivityDateFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ActivityDateFilter.php @@ -127,6 +127,10 @@ class ActivityDateFilter implements FilterInterface } }); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ActivityTypeFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ActivityTypeFilter.php index b9d39c3ce..8dfcb543c 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ActivityTypeFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ActivityTypeFilter.php @@ -78,6 +78,10 @@ class ActivityTypeFilter implements ExportElementValidatedInterface, FilterInter ], ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ActivityUsersFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ActivityUsersFilter.php index 2f6cd8462..a63ca2629 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ActivityUsersFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ActivityUsersFilter.php @@ -56,6 +56,10 @@ class ActivityUsersFilter implements FilterInterface 'label' => 'Users', ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/PersonFilters/ActivityReasonFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/PersonFilters/ActivityReasonFilter.php index c55d579e4..31cfde6b6 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/PersonFilters/ActivityReasonFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/PersonFilters/ActivityReasonFilter.php @@ -82,6 +82,10 @@ class ActivityReasonFilter implements ExportElementValidatedInterface, FilterInt 'expanded' => false, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/PersonFilters/PersonHavingActivityBetweenDateFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/PersonFilters/PersonHavingActivityBetweenDateFilter.php index e3c85fe9c..490b5fd0c 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/PersonFilters/PersonHavingActivityBetweenDateFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/PersonFilters/PersonHavingActivityBetweenDateFilter.php @@ -112,7 +112,6 @@ class PersonHavingActivityBetweenDateFilter implements ExportElementValidatedInt { $builder->add('date_from', DateType::class, [ 'label' => 'Implied in an activity after this date', - 'data' => new DateTime(), 'attr' => ['class' => 'datepicker'], 'widget' => 'single_text', 'format' => 'dd-MM-yyyy', @@ -120,7 +119,6 @@ class PersonHavingActivityBetweenDateFilter implements ExportElementValidatedInt $builder->add('date_to', DateType::class, [ 'label' => 'Implied in an activity before this date', - 'data' => new DateTime(), 'attr' => ['class' => 'datepicker'], 'widget' => 'single_text', 'format' => 'dd-MM-yyyy', @@ -130,7 +128,6 @@ class PersonHavingActivityBetweenDateFilter implements ExportElementValidatedInt 'class' => ActivityReason::class, 'choice_label' => fn (ActivityReason $reason): ?string => $this->translatableStringHelper->localize($reason->getName()), 'group_by' => fn (ActivityReason $reason): ?string => $this->translatableStringHelper->localize($reason->getCategory()->getName()), - 'data' => $this->activityReasonRepository->findAll(), 'multiple' => true, 'expanded' => false, 'label' => 'Activity reasons for those activities', @@ -176,6 +173,10 @@ class PersonHavingActivityBetweenDateFilter implements ExportElementValidatedInt } }); } + public function getFormDefaultData(): array + { + return ['date_from' => new DateTime(), 'date_to' => new DateTime(), 'reasons' => $this->activityReasonRepository->findAll()]; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/UsersJobFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/UsersJobFilter.php index b52ef441c..e85b2d247 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/UsersJobFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/UsersJobFilter.php @@ -60,6 +60,10 @@ class UsersJobFilter implements FilterInterface 'expanded' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/UsersScopeFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/UsersScopeFilter.php index 61b12264e..07ff509ce 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/UsersScopeFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/UsersScopeFilter.php @@ -67,6 +67,10 @@ class UsersScopeFilter implements FilterInterface 'expanded' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByActivityTypeAggregator.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByActivityTypeAggregator.php index 32418e3c3..8ae43534d 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByActivityTypeAggregator.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByActivityTypeAggregator.php @@ -50,6 +50,10 @@ class ByActivityTypeAggregator implements AggregatorInterface { // No form needed } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByUserJobAggregator.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByUserJobAggregator.php index d2fe7c2f2..f09a704e2 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByUserJobAggregator.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByUserJobAggregator.php @@ -57,6 +57,10 @@ class ByUserJobAggregator implements AggregatorInterface { // nothing to add in the form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByUserScopeAggregator.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByUserScopeAggregator.php index 6c06ee756..3dd465db2 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByUserScopeAggregator.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByUserScopeAggregator.php @@ -57,6 +57,10 @@ class ByUserScopeAggregator implements AggregatorInterface { // nothing to add in the form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Export/AvgAsideActivityDuration.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Export/AvgAsideActivityDuration.php index f3db629cb..2b28062f6 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Export/AvgAsideActivityDuration.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Export/AvgAsideActivityDuration.php @@ -34,6 +34,10 @@ class AvgAsideActivityDuration implements ExportInterface, GroupedExportInterfac public function buildForm(FormBuilderInterface $builder) { } + public function getFormDefaultData(): array + { + return []; + } public function getAllowedFormattersTypes(): array { diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Export/CountAsideActivity.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Export/CountAsideActivity.php index 9204fad4b..91210f764 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Export/CountAsideActivity.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Export/CountAsideActivity.php @@ -34,6 +34,10 @@ class CountAsideActivity implements ExportInterface, GroupedExportInterface public function buildForm(FormBuilderInterface $builder) { } + public function getFormDefaultData(): array + { + return []; + } public function getAllowedFormattersTypes(): array { diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Export/SumAsideActivityDuration.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Export/SumAsideActivityDuration.php index af17a2591..741f129f1 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Export/SumAsideActivityDuration.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Export/SumAsideActivityDuration.php @@ -34,6 +34,10 @@ class SumAsideActivityDuration implements ExportInterface, GroupedExportInterfac public function buildForm(FormBuilderInterface $builder) { } + public function getFormDefaultData(): array + { + return []; + } public function getAllowedFormattersTypes(): array { diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByActivityTypeFilter.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByActivityTypeFilter.php index 3ad8e0e93..3d389f5b3 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByActivityTypeFilter.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByActivityTypeFilter.php @@ -76,6 +76,10 @@ class ByActivityTypeFilter implements FilterInterface }, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByDateFilter.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByDateFilter.php index 7a1b6f4dc..5019c3597 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByDateFilter.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByDateFilter.php @@ -119,6 +119,10 @@ class ByDateFilter implements FilterInterface } }); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserFilter.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserFilter.php index 795c813cd..2858d3417 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserFilter.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserFilter.php @@ -53,6 +53,10 @@ class ByUserFilter implements FilterInterface 'label' => 'Creators', ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserJobFilter.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserJobFilter.php index 86194b123..55f477768 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserJobFilter.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserJobFilter.php @@ -60,6 +60,10 @@ class ByUserJobFilter implements FilterInterface 'expanded' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserScopeFilter.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserScopeFilter.php index 4342e11eb..8fa51866d 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserScopeFilter.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserScopeFilter.php @@ -67,6 +67,10 @@ class ByUserScopeFilter implements FilterInterface 'expanded' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/AgentAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/AgentAggregator.php index e1de9f399..1b1b170b8 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/AgentAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/AgentAggregator.php @@ -58,6 +58,10 @@ final class AgentAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data): Closure { diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/CancelReasonAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/CancelReasonAggregator.php index 611cb6d79..a9967c470 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/CancelReasonAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/CancelReasonAggregator.php @@ -59,6 +59,10 @@ class CancelReasonAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data): Closure { diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/JobAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/JobAggregator.php index 23292a5b0..51291b49e 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/JobAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/JobAggregator.php @@ -58,6 +58,10 @@ final class JobAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data): Closure { diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationAggregator.php index 940000f47..952d0c5d5 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationAggregator.php @@ -52,6 +52,10 @@ final class LocationAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data): Closure { diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationTypeAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationTypeAggregator.php index 6574e3934..a9b369af0 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationTypeAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationTypeAggregator.php @@ -58,6 +58,10 @@ final class LocationTypeAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data): Closure { diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/MonthYearAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/MonthYearAggregator.php index 7b2a5e898..b3c2aaf19 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/MonthYearAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/MonthYearAggregator.php @@ -40,6 +40,10 @@ class MonthYearAggregator implements AggregatorInterface { // No form needed } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data): Closure { diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/ScopeAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/ScopeAggregator.php index 3aff3e0d8..01874b0e2 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/ScopeAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/ScopeAggregator.php @@ -58,6 +58,10 @@ final class ScopeAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data): Closure { diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/UrgencyAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/UrgencyAggregator.php index ad5910461..66ab8b42e 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/UrgencyAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/UrgencyAggregator.php @@ -56,6 +56,10 @@ class UrgencyAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data): Closure { diff --git a/src/Bundle/ChillCalendarBundle/Export/Export/CountCalendars.php b/src/Bundle/ChillCalendarBundle/Export/Export/CountCalendars.php index 9d3f00f99..e0391948e 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Export/CountCalendars.php +++ b/src/Bundle/ChillCalendarBundle/Export/Export/CountCalendars.php @@ -36,6 +36,10 @@ class CountCalendars implements ExportInterface, GroupedExportInterface { // No form necessary } + public function getFormDefaultData(): array + { + return []; + } public function getAllowedFormattersTypes(): array { diff --git a/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarAvgDuration.php b/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarAvgDuration.php index 14dd42d6b..dcbfb695b 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarAvgDuration.php +++ b/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarAvgDuration.php @@ -36,6 +36,10 @@ class StatCalendarAvgDuration implements ExportInterface, GroupedExportInterface { // no form needed } + public function getFormDefaultData(): array + { + return []; + } public function getAllowedFormattersTypes(): array { diff --git a/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarSumDuration.php b/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarSumDuration.php index 1d31bfa26..7f509a896 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarSumDuration.php +++ b/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarSumDuration.php @@ -36,6 +36,10 @@ class StatCalendarSumDuration implements ExportInterface, GroupedExportInterface { // no form needed } + public function getFormDefaultData(): array + { + return []; + } public function getAllowedFormattersTypes(): array { diff --git a/src/Bundle/ChillCalendarBundle/Export/Filter/AgentFilter.php b/src/Bundle/ChillCalendarBundle/Export/Filter/AgentFilter.php index b58cee594..0cef89c20 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Filter/AgentFilter.php +++ b/src/Bundle/ChillCalendarBundle/Export/Filter/AgentFilter.php @@ -63,6 +63,10 @@ class AgentFilter implements FilterInterface 'expanded' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillCalendarBundle/Export/Filter/BetweenDatesFilter.php b/src/Bundle/ChillCalendarBundle/Export/Filter/BetweenDatesFilter.php index 59019ac03..71dc95e60 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Filter/BetweenDatesFilter.php +++ b/src/Bundle/ChillCalendarBundle/Export/Filter/BetweenDatesFilter.php @@ -67,6 +67,10 @@ class BetweenDatesFilter implements FilterInterface 'data' => new RollingDate(RollingDate::T_TODAY), ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillCalendarBundle/Export/Filter/CalendarRangeFilter.php b/src/Bundle/ChillCalendarBundle/Export/Filter/CalendarRangeFilter.php index d6c38e163..5ffb7c01f 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Filter/CalendarRangeFilter.php +++ b/src/Bundle/ChillCalendarBundle/Export/Filter/CalendarRangeFilter.php @@ -69,9 +69,12 @@ class CalendarRangeFilter implements FilterInterface 'multiple' => false, 'expanded' => true, 'empty_data' => self::DEFAULT_CHOICE, - 'data' => self::DEFAULT_CHOICE, ]); } + public function getFormDefaultData(): array + { + return ['hasCalendarRange' => self::DEFAULT_CHOICE]; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillCalendarBundle/Export/Filter/JobFilter.php b/src/Bundle/ChillCalendarBundle/Export/Filter/JobFilter.php index 69fb24447..d02bb8e9d 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Filter/JobFilter.php +++ b/src/Bundle/ChillCalendarBundle/Export/Filter/JobFilter.php @@ -76,6 +76,10 @@ class JobFilter implements FilterInterface 'expanded' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillCalendarBundle/Export/Filter/ScopeFilter.php b/src/Bundle/ChillCalendarBundle/Export/Filter/ScopeFilter.php index 08d9ae023..d8a40da72 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Filter/ScopeFilter.php +++ b/src/Bundle/ChillCalendarBundle/Export/Filter/ScopeFilter.php @@ -76,6 +76,10 @@ class ScopeFilter implements FilterInterface 'expanded' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/AdministrativeLocationAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/AdministrativeLocationAggregator.php index 96deac574..56fdc07d7 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/AdministrativeLocationAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/AdministrativeLocationAggregator.php @@ -57,6 +57,10 @@ class AdministrativeLocationAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ByActionNumberAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ByActionNumberAggregator.php index 2dffccbbb..104b934ca 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ByActionNumberAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ByActionNumberAggregator.php @@ -39,6 +39,10 @@ class ByActionNumberAggregator implements AggregatorInterface { // No form needed } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ClosingMotiveAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ClosingMotiveAggregator.php index 342958361..73cfdc7b9 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ClosingMotiveAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ClosingMotiveAggregator.php @@ -52,6 +52,10 @@ class ClosingMotiveAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ConfidentialAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ConfidentialAggregator.php index e9b9e28fa..4ad18030e 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ConfidentialAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ConfidentialAggregator.php @@ -48,6 +48,10 @@ class ConfidentialAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/CreatorJobAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/CreatorJobAggregator.php index c336a8887..5a060bcd7 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/CreatorJobAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/CreatorJobAggregator.php @@ -57,6 +57,10 @@ class CreatorJobAggregator implements AggregatorInterface { // No form needed } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/DurationAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/DurationAggregator.php index 0dc66e81e..581c7d6e5 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/DurationAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/DurationAggregator.php @@ -84,6 +84,10 @@ final class DurationAggregator implements AggregatorInterface 'expanded' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/EmergencyAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/EmergencyAggregator.php index 02f9f5cd9..4429c7b62 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/EmergencyAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/EmergencyAggregator.php @@ -48,6 +48,10 @@ class EmergencyAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/EvaluationAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/EvaluationAggregator.php index b6436efc0..119fa50b7 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/EvaluationAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/EvaluationAggregator.php @@ -61,6 +61,10 @@ final class EvaluationAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/GeographicalUnitStatAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/GeographicalUnitStatAggregator.php index d001cbef7..22b21d352 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/GeographicalUnitStatAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/GeographicalUnitStatAggregator.php @@ -133,6 +133,10 @@ final class GeographicalUnitStatAggregator implements AggregatorInterface 'expanded' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/IntensityAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/IntensityAggregator.php index a3618f40f..ac55d7734 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/IntensityAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/IntensityAggregator.php @@ -48,6 +48,10 @@ class IntensityAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/OriginAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/OriginAggregator.php index 37d0c7b20..1d01920d5 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/OriginAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/OriginAggregator.php @@ -59,6 +59,10 @@ final class OriginAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ReferrerAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ReferrerAggregator.php index a09097fd2..7b826600a 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ReferrerAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ReferrerAggregator.php @@ -81,11 +81,14 @@ final class ReferrerAggregator implements AggregatorInterface { $builder ->add('date_calc', PickRollingDateType::class, [ - 'data' => new RollingDate(RollingDate::T_TODAY), 'label' => 'export.aggregator.course.by_referrer.Computation date for referrer', 'required' => true, ]); } + public function getFormDefaultData(): array + { + return ['date_calc' => new RollingDate(RollingDate::T_TODAY)]; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ReferrerScopeAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ReferrerScopeAggregator.php index ccbd21da1..adfd9b489 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ReferrerScopeAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ReferrerScopeAggregator.php @@ -88,11 +88,14 @@ class ReferrerScopeAggregator implements AggregatorInterface public function buildForm(FormBuilderInterface $builder) { $builder->add('date_calc', PickRollingDateType::class, [ - 'data' => new RollingDate(RollingDate::T_TODAY), 'label' => 'export.aggregator.course.by_user_scope.Computation date for referrer', 'required' => true, ]); } + public function getFormDefaultData(): array + { + return ['date_calc' => new RollingDate(RollingDate::T_TODAY)]; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/RequestorAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/RequestorAggregator.php index 7b5cf0edd..3baf9bd33 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/RequestorAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/RequestorAggregator.php @@ -69,6 +69,10 @@ final class RequestorAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ScopeAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ScopeAggregator.php index 8f34661bb..253727c89 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ScopeAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ScopeAggregator.php @@ -57,6 +57,10 @@ final class ScopeAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/SocialActionAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/SocialActionAggregator.php index 3bdd6549e..b82b47ad0 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/SocialActionAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/SocialActionAggregator.php @@ -58,6 +58,10 @@ final class SocialActionAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/SocialIssueAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/SocialIssueAggregator.php index 12fa5a454..29fcba4a2 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/SocialIssueAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/SocialIssueAggregator.php @@ -58,6 +58,10 @@ final class SocialIssueAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/StepAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/StepAggregator.php index 85cfc3190..7632f72f0 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/StepAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/StepAggregator.php @@ -76,9 +76,11 @@ final class StepAggregator implements AggregatorInterface public function buildForm(FormBuilderInterface $builder) { - $builder->add('on_date', PickRollingDateType::class, [ - 'data' => new RollingDate(RollingDate::T_TODAY), - ]); + $builder->add('on_date', PickRollingDateType::class, []); + } + public function getFormDefaultData(): array + { + return ['on_date' => new RollingDate(RollingDate::T_TODAY)]; } public function getLabels($key, array $values, $data) diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/UserJobAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/UserJobAggregator.php index a8acdcf12..13d1e3f83 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/UserJobAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/UserJobAggregator.php @@ -57,6 +57,10 @@ final class UserJobAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/ByEndDateAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/ByEndDateAggregator.php index 2f4275c49..cb66fa600 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/ByEndDateAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/ByEndDateAggregator.php @@ -75,9 +75,12 @@ class ByEndDateAggregator implements AggregatorInterface 'multiple' => false, 'expanded' => true, 'empty_data' => self::DEFAULT_CHOICE, - 'data' => self::DEFAULT_CHOICE, ]); } + public function getFormDefaultData(): array + { + return ['frequency' => self::DEFAULT_CHOICE]; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/ByMaxDateAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/ByMaxDateAggregator.php index 9283fd9dc..af6dfc465 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/ByMaxDateAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/ByMaxDateAggregator.php @@ -75,9 +75,12 @@ class ByMaxDateAggregator implements AggregatorInterface 'multiple' => false, 'expanded' => true, 'empty_data' => self::DEFAULT_CHOICE, - 'data' => self::DEFAULT_CHOICE, ]); } + public function getFormDefaultData(): array + { + return ['frequency' => self::DEFAULT_CHOICE]; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/ByStartDateAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/ByStartDateAggregator.php index cd183b25e..87a6a672b 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/ByStartDateAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/ByStartDateAggregator.php @@ -75,9 +75,12 @@ class ByStartDateAggregator implements AggregatorInterface 'multiple' => false, 'expanded' => true, 'empty_data' => self::DEFAULT_CHOICE, - 'data' => self::DEFAULT_CHOICE, ]); } + public function getFormDefaultData(): array + { + return ['frequency' => self::DEFAULT_CHOICE]; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/EvaluationTypeAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/EvaluationTypeAggregator.php index 0c13611cb..a48ed763d 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/EvaluationTypeAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/EvaluationTypeAggregator.php @@ -52,6 +52,10 @@ class EvaluationTypeAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/HavingEndDateAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/HavingEndDateAggregator.php index e33bb326f..e710949fd 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/HavingEndDateAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/HavingEndDateAggregator.php @@ -48,6 +48,10 @@ class HavingEndDateAggregator implements AggregatorInterface { // No form needed } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/HouseholdAggregators/ChildrenNumberAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/HouseholdAggregators/ChildrenNumberAggregator.php index 0c9bc623f..1c5b3dc2c 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/HouseholdAggregators/ChildrenNumberAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/HouseholdAggregators/ChildrenNumberAggregator.php @@ -72,9 +72,11 @@ class ChildrenNumberAggregator implements AggregatorInterface public function buildForm(FormBuilderInterface $builder) { - $builder->add('on_date', PickRollingDateType::class, [ - 'data' => new RollingDate(RollingDate::T_TODAY), - ]); + $builder->add('on_date', PickRollingDateType::class, []); + } + public function getFormDefaultData(): array + { + return ['on_date' => new RollingDate(RollingDate::T_TODAY)]; } public function getLabels($key, array $values, $data) diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/HouseholdAggregators/CompositionAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/HouseholdAggregators/CompositionAggregator.php index 52bcd88e5..62fc20173 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/HouseholdAggregators/CompositionAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/HouseholdAggregators/CompositionAggregator.php @@ -77,9 +77,11 @@ class CompositionAggregator implements AggregatorInterface public function buildForm(FormBuilderInterface $builder) { - $builder->add('on_date', PickRollingDateType::class, [ - 'data' => new RollingDate(RollingDate::T_TODAY), - ]); + $builder->add('on_date', PickRollingDateType::class, []); + } + public function getFormDefaultData(): array + { + return ['on_date' => new RollingDate(RollingDate::T_TODAY)]; } public function getLabels($key, array $values, $data) diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/AgeAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/AgeAggregator.php index 365a73704..2a63e475a 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/AgeAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/AgeAggregator.php @@ -50,12 +50,15 @@ final class AgeAggregator implements AggregatorInterface, ExportElementValidated { $builder->add('date_age_calculation', DateType::class, [ 'label' => 'Calculate age in relation to this date', - 'data' => new DateTime(), 'attr' => ['class' => 'datepicker'], 'widget' => 'single_text', 'format' => 'dd-MM-yyyy', ]); } + public function getFormDefaultData(): array + { + return ['date_age_calculation' => new DateTime()]; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/ByHouseholdCompositionAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/ByHouseholdCompositionAggregator.php index 80f0faa17..16b62c2b5 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/ByHouseholdCompositionAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/ByHouseholdCompositionAggregator.php @@ -94,9 +94,12 @@ class ByHouseholdCompositionAggregator implements AggregatorInterface { $builder->add('date_calc', PickRollingDateType::class, [ 'label' => 'export.aggregator.person.by_household_composition.Calc date', - 'data' => new RollingDate(RollingDate::T_TODAY), ]); } + public function getFormDefaultData(): array + { + return ['date_calc' => new RollingDate(RollingDate::T_TODAY)]; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/CountryOfBirthAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/CountryOfBirthAggregator.php index 3d785b586..90882245e 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/CountryOfBirthAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/CountryOfBirthAggregator.php @@ -108,6 +108,10 @@ final class CountryOfBirthAggregator implements AggregatorInterface, ExportEleme 'multiple' => false, ]); } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/GenderAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/GenderAggregator.php index f76420047..dbe3d19d3 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/GenderAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/GenderAggregator.php @@ -48,6 +48,10 @@ final class GenderAggregator implements AggregatorInterface public function buildForm(FormBuilderInterface $builder) { } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/GeographicalUnitAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/GeographicalUnitAggregator.php index 5d73c1fdd..6c6ed340f 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/GeographicalUnitAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/GeographicalUnitAggregator.php @@ -105,6 +105,10 @@ class GeographicalUnitAggregator implements AggregatorInterface 'expanded' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public static function getDefaultAlias(): string { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/HouseholdPositionAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/HouseholdPositionAggregator.php index 107634803..63d84d4da 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/HouseholdPositionAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/HouseholdPositionAggregator.php @@ -90,9 +90,12 @@ final class HouseholdPositionAggregator implements AggregatorInterface, ExportEl { $builder->add('date_position', PickRollingDateType::class, [ 'label' => 'Household position in relation to this date', - 'data' => new RollingDate(RollingDate::T_TODAY), ]); } + public function getFormDefaultData(): array + { + return ['date_position' => new RollingDate(RollingDate::T_TODAY)]; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ActionTypeAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ActionTypeAggregator.php index c1fccb968..66c87d94f 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ActionTypeAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ActionTypeAggregator.php @@ -75,6 +75,10 @@ final class ActionTypeAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/CurrentActionAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/CurrentActionAggregator.php index 58fcb2874..539c9f286 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/CurrentActionAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/CurrentActionAggregator.php @@ -51,6 +51,10 @@ class CurrentActionAggregator implements AggregatorInterface { // No form needed } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/GoalAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/GoalAggregator.php index 8cc6a25da..4c0e8b393 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/GoalAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/GoalAggregator.php @@ -55,6 +55,10 @@ final class GoalAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/GoalResultAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/GoalResultAggregator.php index 17b263d7e..c99ee85ea 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/GoalResultAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/GoalResultAggregator.php @@ -68,6 +68,10 @@ class GoalResultAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/JobAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/JobAggregator.php index cbf07091f..8271c90e3 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/JobAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/JobAggregator.php @@ -57,6 +57,10 @@ final class JobAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ReferrerAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ReferrerAggregator.php index 0fe53b707..047504224 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ReferrerAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ReferrerAggregator.php @@ -57,6 +57,10 @@ final class ReferrerAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ResultAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ResultAggregator.php index 2e46673da..3cce7b283 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ResultAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ResultAggregator.php @@ -55,6 +55,10 @@ final class ResultAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ScopeAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ScopeAggregator.php index 243263b83..0828b5d0d 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ScopeAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ScopeAggregator.php @@ -57,6 +57,10 @@ final class ScopeAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Export/CountAccompanyingCourse.php b/src/Bundle/ChillPersonBundle/Export/Export/CountAccompanyingCourse.php index 978f88a10..75583dfa0 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/CountAccompanyingCourse.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/CountAccompanyingCourse.php @@ -39,6 +39,10 @@ class CountAccompanyingCourse implements ExportInterface, GroupedExportInterface { // Nothing to add here } + public function getFormDefaultData(): array + { + return []; + } public function getAllowedFormattersTypes(): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Export/CountAccompanyingPeriodWork.php b/src/Bundle/ChillPersonBundle/Export/Export/CountAccompanyingPeriodWork.php index 122ee14d9..8a035bdcd 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/CountAccompanyingPeriodWork.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/CountAccompanyingPeriodWork.php @@ -38,6 +38,10 @@ class CountAccompanyingPeriodWork implements ExportInterface, GroupedExportInter { // No form necessary? } + public function getFormDefaultData(): array + { + return []; + } public function getAllowedFormattersTypes(): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Export/CountEvaluation.php b/src/Bundle/ChillPersonBundle/Export/Export/CountEvaluation.php index 1613b63d3..3de433e2e 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/CountEvaluation.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/CountEvaluation.php @@ -37,6 +37,10 @@ class CountEvaluation implements ExportInterface, GroupedExportInterface { // TODO: Implement buildForm() method. } + public function getFormDefaultData(): array + { + return []; + } public function getAllowedFormattersTypes(): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Export/CountHousehold.php b/src/Bundle/ChillPersonBundle/Export/Export/CountHousehold.php index 0b693b9d8..05e32fde6 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/CountHousehold.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/CountHousehold.php @@ -46,11 +46,14 @@ class CountHousehold implements ExportInterface, GroupedExportInterface { $builder ->add('calc_date', PickRollingDateType::class, [ - 'data' => new RollingDate(RollingDate::T_TODAY), 'label' => self::TR_PREFIX . 'Date of calculation of household members', 'required' => false, ]); } + public function getFormDefaultData(): array + { + return ['calc_date' => new RollingDate(RollingDate::T_TODAY)]; + } public function getAllowedFormattersTypes(): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Export/CountPersonWithAccompanyingCourse.php b/src/Bundle/ChillPersonBundle/Export/Export/CountPersonWithAccompanyingCourse.php index e52cc83b1..ae7238d4e 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/CountPersonWithAccompanyingCourse.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/CountPersonWithAccompanyingCourse.php @@ -39,6 +39,10 @@ class CountPersonWithAccompanyingCourse implements ExportInterface, GroupedExpor { // TODO: Implement buildForm() method. } + public function getFormDefaultData(): array + { + return []; + } public function getAllowedFormattersTypes(): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Export/ListPersonDuplicate.php b/src/Bundle/ChillPersonBundle/Export/Export/ListPersonDuplicate.php index e40ffccce..e7c105604 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/ListPersonDuplicate.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/ListPersonDuplicate.php @@ -74,9 +74,12 @@ class ListPersonDuplicate implements DirectExportInterface, ExportElementValidat { $builder->add('precision', NumberType::class, [ 'label' => 'Precision', - 'data' => self::PRECISION_DEFAULT_VALUE, ]); } + public function getFormDefaultData(): array + { + return ['precision' => self::PRECISION_DEFAULT_VALUE]; + } public function generate(array $acl, array $data = []): Response { diff --git a/src/Bundle/ChillPersonBundle/Export/Export/StatAccompanyingCourseDuration.php b/src/Bundle/ChillPersonBundle/Export/Export/StatAccompanyingCourseDuration.php index 31ca41cbb..66b47131d 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/StatAccompanyingCourseDuration.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/StatAccompanyingCourseDuration.php @@ -41,9 +41,12 @@ class StatAccompanyingCourseDuration implements ExportInterface, GroupedExportIn { $builder->add('closingdate', ChillDateType::class, [ 'label' => 'Closingdate to apply', - 'data' => new DateTime('now'), ]); } + public function getFormDefaultData(): array + { + return ['closingdate' => new DateTime('now')]; + } public function getAllowedFormattersTypes(): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ActiveOnDateFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ActiveOnDateFilter.php index 3fa8d711f..fcb4d67fb 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ActiveOnDateFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ActiveOnDateFilter.php @@ -67,9 +67,11 @@ class ActiveOnDateFilter implements FilterInterface public function buildForm(FormBuilderInterface $builder) { $builder - ->add('on_date', PickRollingDateType::class, [ - 'data' => new RollingDate(RollingDate::T_TODAY), - ]); + ->add('on_date', PickRollingDateType::class, []); + } + public function getFormDefaultData(): array + { + return ['on_date' => new RollingDate(RollingDate::T_TODAY)]; } public function describeAction($data, $format = 'string'): array diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ActiveOneDayBetweenDatesFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ActiveOneDayBetweenDatesFilter.php index f713e8a97..f693a6d04 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ActiveOneDayBetweenDatesFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ActiveOneDayBetweenDatesFilter.php @@ -63,6 +63,10 @@ class ActiveOneDayBetweenDatesFilter implements FilterInterface 'data' => new RollingDate(RollingDate::T_TODAY), ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/AdministrativeLocationFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/AdministrativeLocationFilter.php index c74e309b2..aa1abb36e 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/AdministrativeLocationFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/AdministrativeLocationFilter.php @@ -53,6 +53,10 @@ class AdministrativeLocationFilter implements FilterInterface 'multiple' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ClosingMotiveFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ClosingMotiveFilter.php index e57370f30..153b2ecbd 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ClosingMotiveFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ClosingMotiveFilter.php @@ -64,6 +64,10 @@ class ClosingMotiveFilter implements FilterInterface 'expanded' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ConfidentialFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ConfidentialFilter.php index 8fcd874fe..b9db9f439 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ConfidentialFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ConfidentialFilter.php @@ -67,9 +67,12 @@ class ConfidentialFilter implements FilterInterface 'multiple' => false, 'expanded' => true, 'empty_data' => self::DEFAULT_CHOICE, - 'data' => self::DEFAULT_CHOICE, ]); } + public function getFormDefaultData(): array + { + return ['accepted_confidentials' => self::DEFAULT_CHOICE]; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/CreatorFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/CreatorFilter.php index b13947e60..8a8a24013 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/CreatorFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/CreatorFilter.php @@ -50,6 +50,10 @@ class CreatorFilter implements FilterInterface 'label' => false, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/CreatorJobFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/CreatorJobFilter.php index f585cfafb..5faeb850f 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/CreatorJobFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/CreatorJobFilter.php @@ -69,6 +69,10 @@ class CreatorJobFilter implements FilterInterface 'label' => 'Job', ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/EmergencyFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/EmergencyFilter.php index afdb717f0..6fc60f6e9 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/EmergencyFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/EmergencyFilter.php @@ -67,9 +67,12 @@ class EmergencyFilter implements FilterInterface 'multiple' => false, 'expanded' => true, 'empty_data' => self::DEFAULT_CHOICE, - 'data' => self::DEFAULT_CHOICE, ]); } + public function getFormDefaultData(): array + { + return ['accepted_emergency' => self::DEFAULT_CHOICE]; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/EvaluationFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/EvaluationFilter.php index ab7f4257e..a6fb3583d 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/EvaluationFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/EvaluationFilter.php @@ -75,6 +75,10 @@ class EvaluationFilter implements FilterInterface 'attr' => ['class' => 'select2'], ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/GeographicalUnitStatFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/GeographicalUnitStatFilter.php index d35565c80..b4ffed280 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/GeographicalUnitStatFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/GeographicalUnitStatFilter.php @@ -114,6 +114,10 @@ class GeographicalUnitStatFilter implements FilterInterface 'multiple' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HasNoActionFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HasNoActionFilter.php index 54c28d027..4820116c0 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HasNoActionFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HasNoActionFilter.php @@ -38,6 +38,10 @@ class HasNoActionFilter implements FilterInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HasNoReferrerFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HasNoReferrerFilter.php index 4c682a56a..6d01ea7c2 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HasNoReferrerFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HasNoReferrerFilter.php @@ -65,9 +65,12 @@ class HasNoReferrerFilter implements FilterInterface $builder ->add('calc_date', PickRollingDateType::class, [ 'label' => 'Has no referrer on this date', - 'data' => new RollingDate(RollingDate::T_TODAY), ]); } + public function getFormDefaultData(): array + { + return ['calc_date' => new RollingDate(RollingDate::T_TODAY)]; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HasTemporaryLocationFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HasTemporaryLocationFilter.php index 615ace4c6..f9b2f2bd6 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HasTemporaryLocationFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HasTemporaryLocationFilter.php @@ -95,6 +95,10 @@ class HasTemporaryLocationFilter implements FilterInterface 'data' => new RollingDate(RollingDate::T_TODAY), ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HavingAnAccompanyingPeriodInfoWithinDatesFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HavingAnAccompanyingPeriodInfoWithinDatesFilter.php index 7069a1d80..cdc771b19 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HavingAnAccompanyingPeriodInfoWithinDatesFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HavingAnAccompanyingPeriodInfoWithinDatesFilter.php @@ -46,6 +46,10 @@ final readonly class HavingAnAccompanyingPeriodInfoWithinDatesFilter implements ]) ; } + public function getFormDefaultData(): array + { + return []; + } public function getTitle(): string { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/IntensityFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/IntensityFilter.php index b0c2205a0..1fd05d2b4 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/IntensityFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/IntensityFilter.php @@ -67,9 +67,12 @@ class IntensityFilter implements FilterInterface 'multiple' => false, 'expanded' => true, 'empty_data' => self::DEFAULT_CHOICE, - 'data' => self::DEFAULT_CHOICE, ]); } + public function getFormDefaultData(): array + { + return ['accepted_intensities' => self::DEFAULT_CHOICE]; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/OpenBetweenDatesFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/OpenBetweenDatesFilter.php index 07ca1de75..ebbec06a4 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/OpenBetweenDatesFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/OpenBetweenDatesFilter.php @@ -61,6 +61,10 @@ class OpenBetweenDatesFilter implements FilterInterface 'data' => new RollingDate(RollingDate::T_TODAY), ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/OriginFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/OriginFilter.php index 00febc640..8395c79f8 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/OriginFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/OriginFilter.php @@ -64,6 +64,10 @@ class OriginFilter implements FilterInterface 'expanded' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ReferrerFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ReferrerFilter.php index 2a3e5d17e..daf0d83a4 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ReferrerFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ReferrerFilter.php @@ -82,6 +82,10 @@ class ReferrerFilter implements FilterInterface 'required' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/RequestorFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/RequestorFilter.php index 3295a5b57..614889c27 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/RequestorFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/RequestorFilter.php @@ -126,9 +126,12 @@ final class RequestorFilter implements FilterInterface 'multiple' => false, 'expanded' => true, 'empty_data' => self::DEFAULT_CHOICE, - 'data' => self::DEFAULT_CHOICE, ]); } + public function getFormDefaultData(): array + { + return ['accepted_choices' => self::DEFAULT_CHOICE]; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/SocialActionFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/SocialActionFilter.php index bc1f368da..0c14ba73a 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/SocialActionFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/SocialActionFilter.php @@ -70,6 +70,10 @@ class SocialActionFilter implements FilterInterface 'multiple' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/SocialIssueFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/SocialIssueFilter.php index 917e129bf..a793bc548 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/SocialIssueFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/SocialIssueFilter.php @@ -69,6 +69,10 @@ class SocialIssueFilter implements FilterInterface 'multiple' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/StepFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/StepFilter.php index 8ee798c07..993ebe301 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/StepFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/StepFilter.php @@ -102,6 +102,10 @@ class StepFilter implements FilterInterface 'data' => new RollingDate(RollingDate::T_TODAY), ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserJobFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserJobFilter.php index 05d84d7b2..cb70fb78b 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserJobFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserJobFilter.php @@ -101,6 +101,10 @@ class UserJobFilter implements FilterInterface 'required' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserScopeFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserScopeFilter.php index bbffa4bca..580c8e334 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserScopeFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserScopeFilter.php @@ -105,6 +105,10 @@ class UserScopeFilter implements FilterInterface 'required' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserWorkingOnCourseFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserWorkingOnCourseFilter.php index 586bb645d..d078443af 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserWorkingOnCourseFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserWorkingOnCourseFilter.php @@ -42,6 +42,10 @@ readonly class UserWorkingOnCourseFilter implements FilterInterface 'multiple' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function getTitle(): string { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/ByEndDateFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/ByEndDateFilter.php index de86604e6..c0e9c4a99 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/ByEndDateFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/ByEndDateFilter.php @@ -64,6 +64,10 @@ class ByEndDateFilter implements FilterInterface 'data' => new RollingDate(RollingDate::T_TODAY), ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/ByStartDateFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/ByStartDateFilter.php index 27518599c..a40becbad 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/ByStartDateFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/ByStartDateFilter.php @@ -64,6 +64,10 @@ class ByStartDateFilter implements FilterInterface 'data' => new RollingDate(RollingDate::T_TODAY), ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/CurrentEvaluationsFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/CurrentEvaluationsFilter.php index 140f6c3cb..8841c7b9e 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/CurrentEvaluationsFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/CurrentEvaluationsFilter.php @@ -37,6 +37,10 @@ class CurrentEvaluationsFilter implements FilterInterface { //no form needed } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/EvaluationTypeFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/EvaluationTypeFilter.php index 6a0c71d55..77bae1b56 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/EvaluationTypeFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/EvaluationTypeFilter.php @@ -64,6 +64,10 @@ final class EvaluationTypeFilter implements FilterInterface 'expanded' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/MaxDateFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/MaxDateFilter.php index 4a65452a1..daa7d1954 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/MaxDateFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/MaxDateFilter.php @@ -61,6 +61,10 @@ class MaxDateFilter implements FilterInterface 'expanded' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/HouseholdFilters/CompositionFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/HouseholdFilters/CompositionFilter.php index 22761c158..a89236159 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/HouseholdFilters/CompositionFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/HouseholdFilters/CompositionFilter.php @@ -88,6 +88,10 @@ class CompositionFilter implements FilterInterface 'data' => new RollingDate(RollingDate::T_TODAY), ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/AddressRefStatusFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/AddressRefStatusFilter.php index 7580a37a3..cf777e08d 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/AddressRefStatusFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/AddressRefStatusFilter.php @@ -87,6 +87,10 @@ class AddressRefStatusFilter implements \Chill\MainBundle\Export\FilterInterface 'data' => [Address::ADDR_REFERENCE_STATUS_TO_REVIEW] ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/BirthdateFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/BirthdateFilter.php index 7ae22ddd8..9a0478b6c 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/BirthdateFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/BirthdateFilter.php @@ -71,14 +71,16 @@ class BirthdateFilter implements ExportElementValidatedInterface, FilterInterfac { $builder->add('date_from', PickRollingDateType::class, [ 'label' => 'Born after this date', - 'data' => new RollingDate(RollingDate::T_YEAR_PREVIOUS_START), ]); $builder->add('date_to', PickRollingDateType::class, [ 'label' => 'Born before this date', - 'data' => new RollingDate(RollingDate::T_TODAY), ]); } + public function getFormDefaultData(): array + { + return ['date_from' => new RollingDate(RollingDate::T_YEAR_PREVIOUS_START), 'date_to' => new RollingDate(RollingDate::T_TODAY)]; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ByHouseholdCompositionFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ByHouseholdCompositionFilter.php index 9b59549f1..d7adb5cd9 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ByHouseholdCompositionFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ByHouseholdCompositionFilter.php @@ -89,6 +89,10 @@ class ByHouseholdCompositionFilter implements FilterInterface 'data' => new RollingDate(RollingDate::T_TODAY), ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/DeadOrAliveFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/DeadOrAliveFilter.php index 384d6698a..8b2444ca2 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/DeadOrAliveFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/DeadOrAliveFilter.php @@ -102,9 +102,12 @@ class DeadOrAliveFilter implements FilterInterface $builder->add('date_calc', PickRollingDateType::class, [ 'label' => 'Filter in relation to this date', - 'data' => new RollingDate(RollingDate::T_TODAY), ]); } + public function getFormDefaultData(): array + { + return ['date_calc' => new RollingDate(RollingDate::T_TODAY)]; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/DeathdateFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/DeathdateFilter.php index 0ac4b3173..7805331a5 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/DeathdateFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/DeathdateFilter.php @@ -72,14 +72,16 @@ class DeathdateFilter implements ExportElementValidatedInterface, FilterInterfac { $builder->add('date_from', PickRollingDateType::class, [ 'label' => 'Death after this date', - 'data' => new RollingDate(RollingDate::T_YEAR_PREVIOUS_START), ]); $builder->add('date_to', PickRollingDateType::class, [ 'label' => 'Deathdate before', - 'data' => new RollingDate(RollingDate::T_TODAY), ]); } + public function getFormDefaultData(): array + { + return ['date_from' => new RollingDate(RollingDate::T_YEAR_PREVIOUS_START), 'date_to' => new RollingDate(RollingDate::T_TODAY)]; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/GenderFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/GenderFilter.php index 739945b98..182006bbc 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/GenderFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/GenderFilter.php @@ -89,6 +89,10 @@ class GenderFilter implements 'expanded' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/GeographicalUnitFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/GeographicalUnitFilter.php index 79f5cb2d4..7efeca49e 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/GeographicalUnitFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/GeographicalUnitFilter.php @@ -105,6 +105,10 @@ class GeographicalUnitFilter implements \Chill\MainBundle\Export\FilterInterface 'multiple' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/MaritalStatusFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/MaritalStatusFilter.php index 47a75871c..021c22fc6 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/MaritalStatusFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/MaritalStatusFilter.php @@ -56,6 +56,10 @@ class MaritalStatusFilter implements FilterInterface 'expanded' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/NationalityFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/NationalityFilter.php index b1d77d60e..e5102128b 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/NationalityFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/NationalityFilter.php @@ -67,6 +67,10 @@ class NationalityFilter implements 'placeholder' => 'Choose countries', ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ResidentialAddressAtThirdpartyFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ResidentialAddressAtThirdpartyFilter.php index 21bb40947..8f22750a5 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ResidentialAddressAtThirdpartyFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ResidentialAddressAtThirdpartyFilter.php @@ -107,9 +107,12 @@ class ResidentialAddressAtThirdpartyFilter implements FilterInterface $builder->add('date_calc', PickRollingDateType::class, [ 'label' => 'Date during which residential address was valid', - 'data' => new RollingDate(RollingDate::T_TODAY), ]); } + public function getFormDefaultData(): array + { + return ['date_calc' => new RollingDate(RollingDate::T_TODAY)]; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ResidentialAddressAtUserFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ResidentialAddressAtUserFilter.php index bd55c5b80..62b142420 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ResidentialAddressAtUserFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ResidentialAddressAtUserFilter.php @@ -82,9 +82,12 @@ class ResidentialAddressAtUserFilter implements FilterInterface { $builder->add('date_calc', PickRollingDateType::class, [ 'label' => 'Date during which residential address was valid', - 'data' => new RollingDate(RollingDate::T_TODAY), ]); } + public function getFormDefaultData(): array + { + return ['date_calc' => new RollingDate(RollingDate::T_TODAY)]; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/WithoutHouseholdComposition.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/WithoutHouseholdComposition.php index c4644fc11..9f5ed90b5 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/WithoutHouseholdComposition.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/WithoutHouseholdComposition.php @@ -66,9 +66,12 @@ class WithoutHouseholdComposition implements FilterInterface $builder ->add('calc_date', PickRollingDateType::class, [ 'label' => 'export.filter.person.by_no_composition.Date calc', - 'data' => new RollingDate(RollingDate::T_TODAY), ]); } + public function getFormDefaultData(): array + { + return ['calc_date' => new RollingDate(RollingDate::T_TODAY)]; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/AccompanyingPeriodWorkEndDateBetweenDateFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/AccompanyingPeriodWorkEndDateBetweenDateFilter.php index b13c49e9a..45d86bc97 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/AccompanyingPeriodWorkEndDateBetweenDateFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/AccompanyingPeriodWorkEndDateBetweenDateFilter.php @@ -44,6 +44,10 @@ final readonly class AccompanyingPeriodWorkEndDateBetweenDateFilter implements F ]) ; } + public function getFormDefaultData(): array + { + return []; + } public function getTitle(): string { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/AccompanyingPeriodWorkStartDateBetweenDateFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/AccompanyingPeriodWorkStartDateBetweenDateFilter.php index e9526a9a5..f4a914203 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/AccompanyingPeriodWorkStartDateBetweenDateFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/AccompanyingPeriodWorkStartDateBetweenDateFilter.php @@ -44,6 +44,10 @@ final readonly class AccompanyingPeriodWorkStartDateBetweenDateFilter implements ]) ; } + public function getFormDefaultData(): array + { + return []; + } public function getTitle(): string { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/CurrentActionFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/CurrentActionFilter.php index cbdb64d8d..e99590025 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/CurrentActionFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/CurrentActionFilter.php @@ -37,6 +37,10 @@ class CurrentActionFilter implements FilterInterface { //no form } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/JobFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/JobFilter.php index 144bf3260..265c8e24d 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/JobFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/JobFilter.php @@ -76,6 +76,10 @@ class JobFilter implements FilterInterface 'expanded' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/ReferrerFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/ReferrerFilter.php index 8d0da32fb..bddcfbf9b 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/ReferrerFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/ReferrerFilter.php @@ -57,6 +57,10 @@ class ReferrerFilter implements FilterInterface 'multiple' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/ScopeFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/ScopeFilter.php index 315025722..737759c3e 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/ScopeFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/ScopeFilter.php @@ -76,6 +76,10 @@ class ScopeFilter implements FilterInterface 'expanded' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/SocialWorkTypeFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/SocialWorkTypeFilter.php index 11fd0ed9d..25bfc17a0 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/SocialWorkTypeFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/SocialWorkTypeFilter.php @@ -110,6 +110,10 @@ class SocialWorkTypeFilter implements FilterInterface $this->iterableToIdTransformer(Result::class) ); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillReportBundle/Export/Filter/ReportDateFilter.php b/src/Bundle/ChillReportBundle/Export/Filter/ReportDateFilter.php index 79bad4f52..cb8e7d1d0 100644 --- a/src/Bundle/ChillReportBundle/Export/Filter/ReportDateFilter.php +++ b/src/Bundle/ChillReportBundle/Export/Filter/ReportDateFilter.php @@ -67,14 +67,16 @@ class ReportDateFilter implements FilterInterface { $builder->add('date_from', PickRollingDateType::class, [ 'label' => 'Report is after this date', - 'data' => new RollingDate(RollingDate::T_YEAR_PREVIOUS_START), ]); $builder->add('date_to', PickRollingDateType::class, [ 'label' => 'Report is before this date', - 'data' => new RollingDate(RollingDate::T_TODAY), ]); } + public function getFormDefaultData(): array + { + return ['date_from' => new RollingDate(RollingDate::T_YEAR_PREVIOUS_START), 'date_to' => new RollingDate(RollingDate::T_TODAY)]; + } public function describeAction($data, $format = 'string') { From 933e9f75b3035bc575f6d2fbd6246f064af977cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Mon, 5 Jun 2023 17:21:43 +0200 Subject: [PATCH 132/321] publish namespace to every app using this package --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index d3567bca0..4ff7349d7 100644 --- a/composer.json +++ b/composer.json @@ -104,7 +104,8 @@ "Chill\\ReportBundle\\": "src/Bundle/ChillReportBundle", "Chill\\TaskBundle\\": "src/Bundle/ChillTaskBundle", "Chill\\ThirdPartyBundle\\": "src/Bundle/ChillThirdPartyBundle", - "Chill\\WopiBundle\\": "src/Bundle/ChillWopiBundle/src" + "Chill\\WopiBundle\\": "src/Bundle/ChillWopiBundle/src", + "Utils\\Rector\\": "utils/rector/src" } }, "autoload-dev": { @@ -112,7 +113,6 @@ "App\\": "tests/app/src/", "Chill\\DocGeneratorBundle\\Tests\\": "src/Bundle/ChillDocGeneratorBundle/tests", "Chill\\WopiBundle\\Tests\\": "src/Bundle/ChillDocGeneratorBundle/tests", - "Utils\\Rector\\": "utils/rector/src", "Utils\\Rector\\Tests\\": "utils/rector/tests" } }, From 73bc95306ec7d1bee95fb5985fd292755d543dc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Mon, 5 Jun 2023 17:29:37 +0200 Subject: [PATCH 133/321] move rector rules to a shareable namespace --- composer.json | 4 ++-- ...BundleAddFormDefaultDataOnExportFilterAggregatorRector.php | 2 +- ...leAddFormDefaultDataOnExportFilterAggregatorRectorTest.php | 2 +- .../config/config.php | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/composer.json b/composer.json index 4ff7349d7..a128b1b77 100644 --- a/composer.json +++ b/composer.json @@ -105,7 +105,7 @@ "Chill\\TaskBundle\\": "src/Bundle/ChillTaskBundle", "Chill\\ThirdPartyBundle\\": "src/Bundle/ChillThirdPartyBundle", "Chill\\WopiBundle\\": "src/Bundle/ChillWopiBundle/src", - "Utils\\Rector\\": "utils/rector/src" + "Chill\\Utils\\Rector\\": "utils/rector/src" } }, "autoload-dev": { @@ -113,7 +113,7 @@ "App\\": "tests/app/src/", "Chill\\DocGeneratorBundle\\Tests\\": "src/Bundle/ChillDocGeneratorBundle/tests", "Chill\\WopiBundle\\Tests\\": "src/Bundle/ChillDocGeneratorBundle/tests", - "Utils\\Rector\\Tests\\": "utils/rector/tests" + "Chill\\Utils\\Rector\\Tests\\": "utils/rector/tests" } }, "config": { diff --git a/utils/rector/src/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector.php b/utils/rector/src/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector.php index 5fe993180..a6a375088 100644 --- a/utils/rector/src/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector.php +++ b/utils/rector/src/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector.php @@ -9,7 +9,7 @@ declare(strict_types=1); * the LICENSE file that was distributed with this source code. */ -namespace Utils\Rector\Rector; +namespace Chill\Utils\Rector\Rector; use Chill\MainBundle\Export\AggregatorInterface; use Chill\MainBundle\Export\DirectExportInterface; diff --git a/utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRectorTest.php b/utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRectorTest.php index 800d2876f..89606e970 100644 --- a/utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRectorTest.php +++ b/utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRectorTest.php @@ -9,7 +9,7 @@ declare(strict_types=1); * the LICENSE file that was distributed with this source code. */ -namespace Utils\Rector\Tests\ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector; +namespace Chill\Utils\Rector\Tests\ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector; use Rector\Testing\PHPUnit\AbstractRectorTestCase; use Symplify\SmartFileSystem\SmartFileInfo; diff --git a/utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/config/config.php b/utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/config/config.php index d8b63bfd5..b59504c84 100644 --- a/utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/config/config.php +++ b/utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/config/config.php @@ -10,5 +10,5 @@ declare(strict_types=1); */ return static function (\Rector\Config\RectorConfig $rectorConfig): void { - $rectorConfig->rule(\Utils\Rector\Rector\ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector::class); + $rectorConfig->rule(\Chill\Utils\Rector\Rector\ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector::class); }; From f10c50231fa8a6a1f0c5f8f1d04902fa0db3ac1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Mon, 5 Jun 2023 17:40:19 +0200 Subject: [PATCH 134/321] apply rector rules on list interfaces --- ...aultDataOnExportFilterAggregatorRector.php | 2 + ...th-no-method-get-form-default-data.php.inc | 135 ++++++++++++++++++ 2 files changed, 137 insertions(+) create mode 100644 utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/Fixture/list-with-no-method-get-form-default-data.php.inc diff --git a/utils/rector/src/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector.php b/utils/rector/src/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector.php index a6a375088..237aa17b8 100644 --- a/utils/rector/src/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector.php +++ b/utils/rector/src/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector.php @@ -15,6 +15,7 @@ use Chill\MainBundle\Export\AggregatorInterface; use Chill\MainBundle\Export\DirectExportInterface; use Chill\MainBundle\Export\ExportInterface; use Chill\MainBundle\Export\FilterInterface; +use Chill\MainBundle\Export\ListInterface; use PhpParser\Node; use Rector\Core\Rector\AbstractRector; use Rector\Symfony\NodeAnalyzer\ClassAnalyzer; @@ -51,6 +52,7 @@ class ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector extends Abstra && !$this->classAnalyzer->hasImplements($node, AggregatorInterface::class) && !$this->classAnalyzer->hasImplements($node, ExportInterface::class) && !$this->classAnalyzer->hasImplements($node, DirectExportInterface::class) + && !$this->classAnalyzer->hasImplements($node, ListInterface::class) ) { return null; } diff --git a/utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/Fixture/list-with-no-method-get-form-default-data.php.inc b/utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/Fixture/list-with-no-method-get-form-default-data.php.inc new file mode 100644 index 000000000..99cea7155 --- /dev/null +++ b/utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/Fixture/list-with-no-method-get-form-default-data.php.inc @@ -0,0 +1,135 @@ + +----- + From db142217293430bdf4a19e6f11b07ad71de7c02f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Mon, 5 Jun 2023 17:42:37 +0200 Subject: [PATCH 135/321] fix cs --- src/Bundle/ChillMainBundle/Export/ExportElementInterface.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Bundle/ChillMainBundle/Export/ExportElementInterface.php b/src/Bundle/ChillMainBundle/Export/ExportElementInterface.php index b0441c829..b8cca4ed0 100644 --- a/src/Bundle/ChillMainBundle/Export/ExportElementInterface.php +++ b/src/Bundle/ChillMainBundle/Export/ExportElementInterface.php @@ -19,7 +19,6 @@ use Symfony\Component\Form\FormBuilderInterface; */ interface ExportElementInterface { - /** * get a title, which will be used in UI (and translated). * From 938027cc1e7fbd3f0f2268fb98a8975f23046b5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Mon, 5 Jun 2023 17:54:00 +0200 Subject: [PATCH 136/321] apply fixes for list --- .../Export/Export/LinkedToACP/ListActivity.php | 4 ++++ .../Export/Export/LinkedToPerson/ListActivity.php | 4 ++++ .../src/Export/Export/ListAsideActivity.php | 4 ++++ .../ChillMainBundle/Export/Formatter/CSVListFormatter.php | 8 +++++++- .../Export/Formatter/CSVPivotedListFormatter.php | 6 +++++- .../Export/Formatter/SpreadsheetListFormatter.php | 6 +++++- .../Export/Export/ListAccompanyingPeriod.php | 4 ++++ .../Export/Export/ListAccompanyingPeriodWork.php | 5 ++++- .../ChillPersonBundle/Export/Export/ListEvaluation.php | 5 ++++- .../Export/Export/ListHouseholdInPeriod.php | 5 ++++- src/Bundle/ChillPersonBundle/Export/Export/ListPerson.php | 6 ++++-- .../Export/Export/ListPersonWithAccompanyingPeriod.php | 6 ++++-- src/Bundle/ChillReportBundle/Export/Export/ReportList.php | 5 ++++- 13 files changed, 57 insertions(+), 11 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/ListActivity.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/ListActivity.php index 026e16f90..9ed6bcda2 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/ListActivity.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/ListActivity.php @@ -44,6 +44,10 @@ class ListActivity implements ListInterface, GroupedExportInterface { $this->helper->buildForm($builder); } + public function getFormDefaultData(): array + { + return []; + } public function getAllowedFormattersTypes() { diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/ListActivity.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/ListActivity.php index 60110c9a8..d14111ba7 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/ListActivity.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/ListActivity.php @@ -88,6 +88,10 @@ class ListActivity implements ListInterface, GroupedExportInterface ])], ]); } + public function getFormDefaultData(): array + { + return []; + } public function getAllowedFormattersTypes() { diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Export/ListAsideActivity.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Export/ListAsideActivity.php index aee168174..b46e120b5 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Export/ListAsideActivity.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Export/ListAsideActivity.php @@ -73,6 +73,10 @@ final class ListAsideActivity implements ListInterface, GroupedExportInterface public function buildForm(FormBuilderInterface $builder) { } + public function getFormDefaultData(): array + { + return []; + } public function getAllowedFormattersTypes() { diff --git a/src/Bundle/ChillMainBundle/Export/Formatter/CSVListFormatter.php b/src/Bundle/ChillMainBundle/Export/Formatter/CSVListFormatter.php index b84c80118..70d80b74b 100644 --- a/src/Bundle/ChillMainBundle/Export/Formatter/CSVListFormatter.php +++ b/src/Bundle/ChillMainBundle/Export/Formatter/CSVListFormatter.php @@ -85,10 +85,16 @@ class CSVListFormatter implements FormatterInterface 'expanded' => true, 'multiple' => false, 'label' => 'Add a number on first column', - 'data' => true, ]); } + public function getFormDefaultData(array $aggregatorAliases): array + { + return ['numerotation' => true]; + } + + + public function getName() { return 'CSV vertical list'; diff --git a/src/Bundle/ChillMainBundle/Export/Formatter/CSVPivotedListFormatter.php b/src/Bundle/ChillMainBundle/Export/Formatter/CSVPivotedListFormatter.php index 63d691443..cce0fa1e4 100644 --- a/src/Bundle/ChillMainBundle/Export/Formatter/CSVPivotedListFormatter.php +++ b/src/Bundle/ChillMainBundle/Export/Formatter/CSVPivotedListFormatter.php @@ -80,10 +80,14 @@ class CSVPivotedListFormatter implements FormatterInterface 'expanded' => true, 'multiple' => false, 'label' => 'Add a number on first column', - 'data' => true, ]); } + public function getFormDefaultData(array $aggregatorAliases): array + { + return ['numerotation' => true]; + } + public function getName() { return 'CSV horizontal list'; diff --git a/src/Bundle/ChillMainBundle/Export/Formatter/SpreadsheetListFormatter.php b/src/Bundle/ChillMainBundle/Export/Formatter/SpreadsheetListFormatter.php index 0e5e339ea..34960d8d2 100644 --- a/src/Bundle/ChillMainBundle/Export/Formatter/SpreadsheetListFormatter.php +++ b/src/Bundle/ChillMainBundle/Export/Formatter/SpreadsheetListFormatter.php @@ -104,10 +104,14 @@ class SpreadsheetListFormatter implements FormatterInterface 'expanded' => true, 'multiple' => false, 'label' => 'Add a number on first column', - 'data' => true, ]); } + public function getFormDefaultData(array $aggregatorAliases): array + { + return ['format' => 'xlsx', 'numerotation' => true]; + } + public function getName() { return 'Spreadsheet list formatter (.xlsx, .ods)'; diff --git a/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriod.php b/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriod.php index 0647460dd..e5e724b6c 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriod.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriod.php @@ -144,6 +144,10 @@ class ListAccompanyingPeriod implements ListInterface, GroupedExportInterface 'required' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function getAllowedFormattersTypes() { diff --git a/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriodWork.php b/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriodWork.php index 00fa8adb1..c437454c2 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriodWork.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriodWork.php @@ -135,9 +135,12 @@ class ListAccompanyingPeriodWork implements ListInterface, GroupedExportInterfac 'label' => 'export.list.acpw.Date of calculation for associated elements', 'help' => 'export.list.acpw.help_description', 'required' => true, - 'data' => new RollingDate(RollingDate::T_TODAY), ]); } + public function getFormDefaultData(): array + { + return ['calc_date' => new RollingDate(RollingDate::T_TODAY)]; + } public function getAllowedFormattersTypes() { diff --git a/src/Bundle/ChillPersonBundle/Export/Export/ListEvaluation.php b/src/Bundle/ChillPersonBundle/Export/Export/ListEvaluation.php index f0985436b..c3e273733 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/ListEvaluation.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/ListEvaluation.php @@ -123,9 +123,12 @@ class ListEvaluation implements ListInterface, GroupedExportInterface 'label' => 'export.list.eval.Date of calculation for associated elements', 'help' => 'export.list.eval.help_description', 'required' => true, - 'data' => new RollingDate(RollingDate::T_TODAY), ]); } + public function getFormDefaultData(): array + { + return ['calc_date' => new RollingDate(RollingDate::T_TODAY)]; + } public function getAllowedFormattersTypes() { diff --git a/src/Bundle/ChillPersonBundle/Export/Export/ListHouseholdInPeriod.php b/src/Bundle/ChillPersonBundle/Export/Export/ListHouseholdInPeriod.php index 8894d145d..4dcc89495 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/ListHouseholdInPeriod.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/ListHouseholdInPeriod.php @@ -75,10 +75,13 @@ class ListHouseholdInPeriod implements ListInterface, GroupedExportInterface ->add('calc_date', PickRollingDateType::class, [ 'label' => 'export.list.household.Date of calculation for associated elements', 'help' => 'export.list.household.help_description', - 'data' => new RollingDate(RollingDate::T_TODAY), 'required' => true, ]); } + public function getFormDefaultData(): array + { + return ['calc_date' => new RollingDate(RollingDate::T_TODAY)]; + } public function getAllowedFormattersTypes() { diff --git a/src/Bundle/ChillPersonBundle/Export/Export/ListPerson.php b/src/Bundle/ChillPersonBundle/Export/Export/ListPerson.php index 8145fd658..12fb0ce5d 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/ListPerson.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/ListPerson.php @@ -107,17 +107,19 @@ class ListPerson implements ExportElementValidatedInterface, ListInterface, Grou } }, ])], - 'data' => array_values($choices), ]); // add a date field for addresses $builder->add('address_date', ChillDateType::class, [ 'label' => 'Data valid at this date', 'help' => 'Data regarding center, addresses, and so on will be computed at this date', - 'data' => new DateTimeImmutable(), 'input' => 'datetime_immutable', ]); } + public function getFormDefaultData(): array + { + return ['fields' => array_values($choices), 'address_date' => new DateTimeImmutable()]; + } public function getAllowedFormattersTypes() { diff --git a/src/Bundle/ChillPersonBundle/Export/Export/ListPersonWithAccompanyingPeriod.php b/src/Bundle/ChillPersonBundle/Export/Export/ListPersonWithAccompanyingPeriod.php index 7cb066e87..fbdc7f391 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/ListPersonWithAccompanyingPeriod.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/ListPersonWithAccompanyingPeriod.php @@ -80,17 +80,19 @@ class ListPersonWithAccompanyingPeriod implements ExportElementValidatedInterfac } }, ])], - 'data' => array_values($choices), ]); // add a date field for addresses $builder->add('address_date', ChillDateType::class, [ 'label' => 'Data valid at this date', 'help' => 'Data regarding center, addresses, and so on will be computed at this date', - 'data' => new DateTimeImmutable(), 'input' => 'datetime_immutable', ]); } + public function getFormDefaultData(): array + { + return ['fields' => array_values($choices), 'address_date' => new DateTimeImmutable()]; + } public function getAllowedFormattersTypes() { diff --git a/src/Bundle/ChillReportBundle/Export/Export/ReportList.php b/src/Bundle/ChillReportBundle/Export/Export/ReportList.php index 9adae0097..c551bfb11 100644 --- a/src/Bundle/ChillReportBundle/Export/Export/ReportList.php +++ b/src/Bundle/ChillReportBundle/Export/Export/ReportList.php @@ -137,11 +137,14 @@ class ReportList implements ExportElementValidatedInterface, ListInterface // add a date field for addresses $builder->add('address_date', ChillDateType::class, [ 'label' => 'Address valid at this date', - 'data' => new DateTime(), 'required' => false, 'block_name' => 'list_export_form_address_date', ]); } + public function getFormDefaultData(): array + { + return ['address_date' => new DateTime()]; + } public function getAllowedFormattersTypes() { From cc30c81fd7eb18e7258b95dc7adfef14f78b6a73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Mon, 5 Jun 2023 17:54:25 +0200 Subject: [PATCH 137/321] change chill rule namespace --- rector.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rector.php b/rector.php index b65dc2a59..c2e752c32 100644 --- a/rector.php +++ b/rector.php @@ -25,7 +25,7 @@ return static function (RectorConfig $rectorConfig): void { ]); // chill rules - $rectorConfig->rule(\Utils\Rector\Rector\ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector::class); + $rectorConfig->rule(\Chill\Utils\Rector\Rector\ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector::class); // skip some path... $rectorConfig->skip([ From fb1b28407a190b3b743622357348e5937693adef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Mon, 5 Jun 2023 17:21:43 +0200 Subject: [PATCH 138/321] publish namespace to every app using this package --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index d3567bca0..4ff7349d7 100644 --- a/composer.json +++ b/composer.json @@ -104,7 +104,8 @@ "Chill\\ReportBundle\\": "src/Bundle/ChillReportBundle", "Chill\\TaskBundle\\": "src/Bundle/ChillTaskBundle", "Chill\\ThirdPartyBundle\\": "src/Bundle/ChillThirdPartyBundle", - "Chill\\WopiBundle\\": "src/Bundle/ChillWopiBundle/src" + "Chill\\WopiBundle\\": "src/Bundle/ChillWopiBundle/src", + "Utils\\Rector\\": "utils/rector/src" } }, "autoload-dev": { @@ -112,7 +113,6 @@ "App\\": "tests/app/src/", "Chill\\DocGeneratorBundle\\Tests\\": "src/Bundle/ChillDocGeneratorBundle/tests", "Chill\\WopiBundle\\Tests\\": "src/Bundle/ChillDocGeneratorBundle/tests", - "Utils\\Rector\\": "utils/rector/src", "Utils\\Rector\\Tests\\": "utils/rector/tests" } }, From 1e8fec5cbd67fc1dd7d7970d5041f079651a49e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Mon, 5 Jun 2023 17:29:37 +0200 Subject: [PATCH 139/321] move rector rules to a shareable namespace --- composer.json | 4 ++-- ...BundleAddFormDefaultDataOnExportFilterAggregatorRector.php | 2 +- ...leAddFormDefaultDataOnExportFilterAggregatorRectorTest.php | 2 +- .../config/config.php | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/composer.json b/composer.json index 4ff7349d7..a128b1b77 100644 --- a/composer.json +++ b/composer.json @@ -105,7 +105,7 @@ "Chill\\TaskBundle\\": "src/Bundle/ChillTaskBundle", "Chill\\ThirdPartyBundle\\": "src/Bundle/ChillThirdPartyBundle", "Chill\\WopiBundle\\": "src/Bundle/ChillWopiBundle/src", - "Utils\\Rector\\": "utils/rector/src" + "Chill\\Utils\\Rector\\": "utils/rector/src" } }, "autoload-dev": { @@ -113,7 +113,7 @@ "App\\": "tests/app/src/", "Chill\\DocGeneratorBundle\\Tests\\": "src/Bundle/ChillDocGeneratorBundle/tests", "Chill\\WopiBundle\\Tests\\": "src/Bundle/ChillDocGeneratorBundle/tests", - "Utils\\Rector\\Tests\\": "utils/rector/tests" + "Chill\\Utils\\Rector\\Tests\\": "utils/rector/tests" } }, "config": { diff --git a/utils/rector/src/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector.php b/utils/rector/src/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector.php index 5fe993180..a6a375088 100644 --- a/utils/rector/src/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector.php +++ b/utils/rector/src/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector.php @@ -9,7 +9,7 @@ declare(strict_types=1); * the LICENSE file that was distributed with this source code. */ -namespace Utils\Rector\Rector; +namespace Chill\Utils\Rector\Rector; use Chill\MainBundle\Export\AggregatorInterface; use Chill\MainBundle\Export\DirectExportInterface; diff --git a/utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRectorTest.php b/utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRectorTest.php index 800d2876f..89606e970 100644 --- a/utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRectorTest.php +++ b/utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRectorTest.php @@ -9,7 +9,7 @@ declare(strict_types=1); * the LICENSE file that was distributed with this source code. */ -namespace Utils\Rector\Tests\ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector; +namespace Chill\Utils\Rector\Tests\ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector; use Rector\Testing\PHPUnit\AbstractRectorTestCase; use Symplify\SmartFileSystem\SmartFileInfo; diff --git a/utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/config/config.php b/utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/config/config.php index d8b63bfd5..b59504c84 100644 --- a/utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/config/config.php +++ b/utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/config/config.php @@ -10,5 +10,5 @@ declare(strict_types=1); */ return static function (\Rector\Config\RectorConfig $rectorConfig): void { - $rectorConfig->rule(\Utils\Rector\Rector\ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector::class); + $rectorConfig->rule(\Chill\Utils\Rector\Rector\ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector::class); }; From 1a037180143db51be3d72caa483e9cc029415c38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Mon, 5 Jun 2023 17:42:37 +0200 Subject: [PATCH 140/321] fix cs --- src/Bundle/ChillMainBundle/Export/ExportElementInterface.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Bundle/ChillMainBundle/Export/ExportElementInterface.php b/src/Bundle/ChillMainBundle/Export/ExportElementInterface.php index b0441c829..b8cca4ed0 100644 --- a/src/Bundle/ChillMainBundle/Export/ExportElementInterface.php +++ b/src/Bundle/ChillMainBundle/Export/ExportElementInterface.php @@ -19,7 +19,6 @@ use Symfony\Component\Form\FormBuilderInterface; */ interface ExportElementInterface { - /** * get a title, which will be used in UI (and translated). * From a28740c46c537596955b9e0517b49691d37d68e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Mon, 5 Jun 2023 17:54:25 +0200 Subject: [PATCH 141/321] change chill rule namespace --- rector.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rector.php b/rector.php index ec9a0c684..c2e752c32 100644 --- a/rector.php +++ b/rector.php @@ -24,6 +24,9 @@ return static function (RectorConfig $rectorConfig): void { LevelSetList::UP_TO_PHP_74 ]); + // chill rules + $rectorConfig->rule(\Chill\Utils\Rector\Rector\ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector::class); + // skip some path... $rectorConfig->skip([ // make rector stuck for some files From 88d363fc0c7cf54d31e37744d0ed7613e01e76ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Mon, 5 Jun 2023 17:40:19 +0200 Subject: [PATCH 142/321] apply rector rules on list interfaces --- ...aultDataOnExportFilterAggregatorRector.php | 2 + ...th-no-method-get-form-default-data.php.inc | 135 ++++++++++++++++++ 2 files changed, 137 insertions(+) create mode 100644 utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/Fixture/list-with-no-method-get-form-default-data.php.inc diff --git a/utils/rector/src/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector.php b/utils/rector/src/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector.php index a6a375088..237aa17b8 100644 --- a/utils/rector/src/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector.php +++ b/utils/rector/src/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector.php @@ -15,6 +15,7 @@ use Chill\MainBundle\Export\AggregatorInterface; use Chill\MainBundle\Export\DirectExportInterface; use Chill\MainBundle\Export\ExportInterface; use Chill\MainBundle\Export\FilterInterface; +use Chill\MainBundle\Export\ListInterface; use PhpParser\Node; use Rector\Core\Rector\AbstractRector; use Rector\Symfony\NodeAnalyzer\ClassAnalyzer; @@ -51,6 +52,7 @@ class ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector extends Abstra && !$this->classAnalyzer->hasImplements($node, AggregatorInterface::class) && !$this->classAnalyzer->hasImplements($node, ExportInterface::class) && !$this->classAnalyzer->hasImplements($node, DirectExportInterface::class) + && !$this->classAnalyzer->hasImplements($node, ListInterface::class) ) { return null; } diff --git a/utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/Fixture/list-with-no-method-get-form-default-data.php.inc b/utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/Fixture/list-with-no-method-get-form-default-data.php.inc new file mode 100644 index 000000000..99cea7155 --- /dev/null +++ b/utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/Fixture/list-with-no-method-get-form-default-data.php.inc @@ -0,0 +1,135 @@ + +----- + From 7fab411b96c23687eaa96e7a6726a2233fd31ecc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Mon, 5 Jun 2023 18:10:55 +0200 Subject: [PATCH 143/321] remove stubs --- .../Aggregator/PersonAggregators/MaritalStatusAggregator.php | 1 - .../Aggregator/PersonAggregators/NationalityAggregator.php | 1 - .../ChillPersonBundle/Export/Filter/PersonFilters/AgeFilter.php | 1 - 3 files changed, 3 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/MaritalStatusAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/MaritalStatusAggregator.php index c311aadf3..508efd3ad 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/MaritalStatusAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/MaritalStatusAggregator.php @@ -48,7 +48,6 @@ final class MaritalStatusAggregator implements AggregatorInterface public function applyOn() { - return 'abcde'; return Declarations::PERSON_TYPE; } diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/NationalityAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/NationalityAggregator.php index b1bd7a085..57721f55c 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/NationalityAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/NationalityAggregator.php @@ -88,7 +88,6 @@ final class NationalityAggregator implements AggregatorInterface, ExportElementV public function applyOn() { - return 'abcde'; return 'person'; } diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/AgeFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/AgeFilter.php index 66db7e95b..f06e42c1f 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/AgeFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/AgeFilter.php @@ -73,7 +73,6 @@ class AgeFilter implements ExportElementValidatedInterface, FilterInterface public function applyOn() { - return 'abcde'; return Declarations::PERSON_TYPE; } From cf576dca7bf2d622665efd68eb2fd0061c9a9b4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Mon, 5 Jun 2023 18:16:32 +0200 Subject: [PATCH 144/321] fix missing choices in getFormDefaultData with automatic generation --- .../ChillMainBundle/Export/Formatter/CSVFormatter.php | 5 +++++ src/Bundle/ChillPersonBundle/Export/Export/ListPerson.php | 8 ++++++++ .../Export/Export/ListPersonWithAccompanyingPeriod.php | 2 ++ 3 files changed, 15 insertions(+) diff --git a/src/Bundle/ChillMainBundle/Export/Formatter/CSVFormatter.php b/src/Bundle/ChillMainBundle/Export/Formatter/CSVFormatter.php index c8b20a88b..0e4114849 100644 --- a/src/Bundle/ChillMainBundle/Export/Formatter/CSVFormatter.php +++ b/src/Bundle/ChillMainBundle/Export/Formatter/CSVFormatter.php @@ -86,6 +86,11 @@ class CSVFormatter implements FormatterInterface } } + public function getFormDefaultData(array $aggregatorAliases): array + { + return []; + } + public function gatherFiltersDescriptions() { $descriptions = []; diff --git a/src/Bundle/ChillPersonBundle/Export/Export/ListPerson.php b/src/Bundle/ChillPersonBundle/Export/Export/ListPerson.php index 12fb0ce5d..467bc02ea 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/ListPerson.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/ListPerson.php @@ -118,6 +118,14 @@ class ListPerson implements ExportElementValidatedInterface, ListInterface, Grou } public function getFormDefaultData(): array { + $choices = array_combine(ListPersonHelper::FIELDS, ListPersonHelper::FIELDS); + + foreach ($this->getCustomFields() as $cf) { + $choices[$this->translatableStringHelper->localize($cf->getName())] + = + $cf->getSlug(); + } + return ['fields' => array_values($choices), 'address_date' => new DateTimeImmutable()]; } diff --git a/src/Bundle/ChillPersonBundle/Export/Export/ListPersonWithAccompanyingPeriod.php b/src/Bundle/ChillPersonBundle/Export/Export/ListPersonWithAccompanyingPeriod.php index fbdc7f391..e8e495cc7 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/ListPersonWithAccompanyingPeriod.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/ListPersonWithAccompanyingPeriod.php @@ -91,6 +91,8 @@ class ListPersonWithAccompanyingPeriod implements ExportElementValidatedInterfac } public function getFormDefaultData(): array { + $choices = array_combine(ListPersonHelper::FIELDS, ListPersonHelper::FIELDS); + return ['fields' => array_values($choices), 'address_date' => new DateTimeImmutable()]; } From 12fdfd81c4a9214af763e5b0279856549cacf0d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 6 Jun 2023 09:37:43 +0200 Subject: [PATCH 145/321] remove empty data which sparkle a bug in RadioListMapper --- .../Export/Aggregator/ACPAggregators/DateAggregator.php | 9 --------- .../Export/Filter/ACPFilters/EmergencyFilter.php | 1 - .../AccompanyingCourseFilters/ConfidentialFilter.php | 3 +-- .../Filter/AccompanyingCourseFilters/EmergencyFilter.php | 3 +-- 4 files changed, 2 insertions(+), 14 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/DateAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/DateAggregator.php index ea2fa5ee4..e0fa215f3 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/DateAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/DateAggregator.php @@ -29,14 +29,6 @@ class DateAggregator implements AggregatorInterface private const DEFAULT_CHOICE = 'year'; - private TranslatorInterface $translator; - - public function __construct( - TranslatorInterface $translator - ) { - $this->translator = $translator; - } - public function addRole(): ?string { return null; @@ -83,7 +75,6 @@ class DateAggregator implements AggregatorInterface 'choices' => self::CHOICES, 'multiple' => false, 'expanded' => true, - 'empty_data' => self::DEFAULT_CHOICE, ]); } public function getFormDefaultData(): array diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/EmergencyFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/EmergencyFilter.php index 807ba3903..d5792d6d5 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/EmergencyFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/EmergencyFilter.php @@ -67,7 +67,6 @@ class EmergencyFilter implements FilterInterface 'choices' => self::CHOICES, 'multiple' => false, 'expanded' => true, - 'empty_data' => self::DEFAULT_CHOICE, ]); } public function getFormDefaultData(): array diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ConfidentialFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ConfidentialFilter.php index b9db9f439..58085f762 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ConfidentialFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ConfidentialFilter.php @@ -26,7 +26,7 @@ class ConfidentialFilter implements FilterInterface 'is confidential' => true, ]; - private const DEFAULT_CHOICE = false; + private const DEFAULT_CHOICE = 'false'; private TranslatorInterface $translator; @@ -66,7 +66,6 @@ class ConfidentialFilter implements FilterInterface 'choices' => self::CHOICES, 'multiple' => false, 'expanded' => true, - 'empty_data' => self::DEFAULT_CHOICE, ]); } public function getFormDefaultData(): array diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/EmergencyFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/EmergencyFilter.php index 6fc60f6e9..897a4db2d 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/EmergencyFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/EmergencyFilter.php @@ -26,7 +26,7 @@ class EmergencyFilter implements FilterInterface 'is not emergency' => false, ]; - private const DEFAULT_CHOICE = false; + private const DEFAULT_CHOICE = 'false'; private TranslatorInterface $translator; @@ -66,7 +66,6 @@ class EmergencyFilter implements FilterInterface 'choices' => self::CHOICES, 'multiple' => false, 'expanded' => true, - 'empty_data' => self::DEFAULT_CHOICE, ]); } public function getFormDefaultData(): array From 7e8dbbe873154666717b77bf1dde9ec0decbbae3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 6 Jun 2023 09:57:06 +0200 Subject: [PATCH 146/321] link to update aggregator and filters from saved export and then execute --- .../views/SavedExport/index.html.twig | 28 +++++++++++++------ .../translations/messages.fr.yml | 4 ++- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Resources/views/SavedExport/index.html.twig b/src/Bundle/ChillMainBundle/Resources/views/SavedExport/index.html.twig index fd0cda2a7..7e0517e31 100644 --- a/src/Bundle/ChillMainBundle/Resources/views/SavedExport/index.html.twig +++ b/src/Bundle/ChillMainBundle/Resources/views/SavedExport/index.html.twig @@ -22,18 +22,28 @@

            {{ s.export.title|trans }}

            {{ s.saved.title }}

            - +
            {{ 'saved_export.Created on %date%'|trans({'%date%': s.saved.createdAt|format_datetime('long', 'short')}) }}
            - +
            {{ s.saved.description|chill_markdown_to_html }}
            - +
            @@ -54,13 +64,13 @@

            {{ s.export.title|trans }}

            {{ s.saved.title }}

            - +
            {{ 'saved_export.Created on %date%'|trans({'%date%': s.saved.createdAt|format_datetime('long', 'short')}) }}
            - +
            {{ s.saved.description|chill_markdown_to_html }}
            - +
            • diff --git a/src/Bundle/ChillMainBundle/translations/messages.fr.yml b/src/Bundle/ChillMainBundle/translations/messages.fr.yml index 78de523c4..4a85db149 100644 --- a/src/Bundle/ChillMainBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillMainBundle/translations/messages.fr.yml @@ -598,7 +598,9 @@ saved_export: Export is deleted: L'export est supprimé Saved export is saved!: L'export est enregistré Created on %date%: Créé le %date% - + update_title_and_description: Modifier le titre et la description + update_filters_aggregators_and_execute: Modifier les filtres et regroupements et télécharger + execute: Télécharger absence: # single letter for absence From ad82685c02b56e848b3ace2581ebd52239d43a86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 6 Jun 2023 10:49:00 +0200 Subject: [PATCH 147/321] allow to edit existing saved export with new export options --- .../Controller/ExportController.php | 33 +++++++++++++++++-- .../Export/ExportFormHelper.php | 1 - .../Resources/views/Export/download.html.twig | 32 +++++++++++++----- .../translations/messages.fr.yml | 1 + 4 files changed, 55 insertions(+), 12 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Controller/ExportController.php b/src/Bundle/ChillMainBundle/Controller/ExportController.php index 2ad6377a6..e8ee9b97b 100644 --- a/src/Bundle/ChillMainBundle/Controller/ExportController.php +++ b/src/Bundle/ChillMainBundle/Controller/ExportController.php @@ -127,6 +127,7 @@ class ExportController extends AbstractController 'alias' => $alias, 'export' => $export, 'export_group' => $this->getExportGroup($export), + 'saved_export' => $savedExport, ]; if ($formater instanceof \Chill\MainBundle\Export\Formatter\CSVListFormatter) { @@ -245,6 +246,28 @@ class ExportController extends AbstractController } } + /** + * @Route("/{_locale}/export/saved/update-from-key/{id}/{key}", name="chill_main_export_saved_edit_options_from_key") + */ + public function editSavedExportOptionsFromKey(SavedExport $savedExport, string $key): Response + { + $this->denyAccessUnlessGranted('ROLE_USER'); + $user = $this->getUser(); + + if (!$user instanceof User) { + throw new AccessDeniedHttpException(); + } + + $data = $this->rebuildRawData($key); + + $savedExport + ->setOptions($data); + + $this->entityManager->flush(); + + return $this->redirectToRoute('chill_main_export_saved_edit', ['id' => $savedExport->getId()]); + } + /** * @Route("/{_locale}/export/save-from-key/{alias}/{key}", name="chill_main_export_save_from_key") */ @@ -478,7 +501,9 @@ class ExportController extends AbstractController if (null === $dataFormatter && $export instanceof \Chill\MainBundle\Export\ExportInterface) { return $this->redirectToRoute('chill_main_export_new', [ - 'alias' => $alias, 'step' => $this->getNextStep('generate', $export, true), + 'alias' => $alias, + 'step' => $this->getNextStep('generate', $export, true), + 'from_saved' => $savedExport?->getId() ?? '', ]); } @@ -499,7 +524,11 @@ class ExportController extends AbstractController $this->session->remove('formatter_step_raw'); $this->session->remove('formatter_step'); - return $this->redirectToRoute('chill_main_export_download', ['key' => $key, 'alias' => $alias]); + return $this->redirectToRoute('chill_main_export_download', [ + 'key' => $key, + 'alias' => $alias, + 'from_saved' => $savedExport?->getId(), + ]); } private function rebuildData($key, ?SavedExport $savedExport) diff --git a/src/Bundle/ChillMainBundle/Export/ExportFormHelper.php b/src/Bundle/ChillMainBundle/Export/ExportFormHelper.php index 3deb2acbc..c2127fb36 100644 --- a/src/Bundle/ChillMainBundle/Export/ExportFormHelper.php +++ b/src/Bundle/ChillMainBundle/Export/ExportFormHelper.php @@ -147,7 +147,6 @@ final readonly class ExportFormHelper SavedExport $savedExport, array $formOptions ): array { - dump(__METHOD__); $builder = $this->formFactory ->createBuilder( FormType::class, diff --git a/src/Bundle/ChillMainBundle/Resources/views/Export/download.html.twig b/src/Bundle/ChillMainBundle/Resources/views/Export/download.html.twig index 1e69c5a49..bd7dbf7e9 100644 --- a/src/Bundle/ChillMainBundle/Resources/views/Export/download.html.twig +++ b/src/Bundle/ChillMainBundle/Resources/views/Export/download.html.twig @@ -1,5 +1,5 @@ {# - * Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS, + * Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS, / * * This program is free software: you can redistribute it and/or modify @@ -19,7 +19,7 @@ {% extends "@ChillMain/layout.html.twig" %} {% block title "Download export"|trans ~ export.title|trans %} - + {% block js %} {% endblock %} - + {% block content %}
              - + {{ include('@ChillMain/Export/_breadcrumb.html.twig') }} - +

              {{ export.title|trans }}

              {{ "Download export"|trans }}

              - +
              {{ 'Back to the list'|trans }} {% if not app.request.query.has('prevent_save') %} + {% if saved_export is null %}
            • {{ 'Save'|trans }}
            • + {% else %} +
            • + +
            • + {% endif %} {% endif %}
            -{% endblock content %} \ No newline at end of file +{% endblock content %} diff --git a/src/Bundle/ChillMainBundle/translations/messages.fr.yml b/src/Bundle/ChillMainBundle/translations/messages.fr.yml index 4a85db149..bbe3d23fb 100644 --- a/src/Bundle/ChillMainBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillMainBundle/translations/messages.fr.yml @@ -601,6 +601,7 @@ saved_export: update_title_and_description: Modifier le titre et la description update_filters_aggregators_and_execute: Modifier les filtres et regroupements et télécharger execute: Télécharger + Update existing: Mettre à jour le rapport enregistré existant absence: # single letter for absence From c3ac3827117f44cda4e2d33c9e03979a787045fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 6 Jun 2023 09:57:06 +0200 Subject: [PATCH 148/321] link to update aggregator and filters from saved export and then execute --- .../views/SavedExport/index.html.twig | 28 +++++++++++++------ .../translations/messages.fr.yml | 4 ++- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Resources/views/SavedExport/index.html.twig b/src/Bundle/ChillMainBundle/Resources/views/SavedExport/index.html.twig index fd0cda2a7..7e0517e31 100644 --- a/src/Bundle/ChillMainBundle/Resources/views/SavedExport/index.html.twig +++ b/src/Bundle/ChillMainBundle/Resources/views/SavedExport/index.html.twig @@ -22,18 +22,28 @@

            {{ s.export.title|trans }}

            {{ s.saved.title }}

            - +
            {{ 'saved_export.Created on %date%'|trans({'%date%': s.saved.createdAt|format_datetime('long', 'short')}) }}
            - +
            {{ s.saved.description|chill_markdown_to_html }}
            - +
            @@ -54,13 +64,13 @@

            {{ s.export.title|trans }}

            {{ s.saved.title }}

            - +
            {{ 'saved_export.Created on %date%'|trans({'%date%': s.saved.createdAt|format_datetime('long', 'short')}) }}
            - +
            {{ s.saved.description|chill_markdown_to_html }}
            - +
            • diff --git a/src/Bundle/ChillMainBundle/translations/messages.fr.yml b/src/Bundle/ChillMainBundle/translations/messages.fr.yml index 78de523c4..4a85db149 100644 --- a/src/Bundle/ChillMainBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillMainBundle/translations/messages.fr.yml @@ -598,7 +598,9 @@ saved_export: Export is deleted: L'export est supprimé Saved export is saved!: L'export est enregistré Created on %date%: Créé le %date% - + update_title_and_description: Modifier le titre et la description + update_filters_aggregators_and_execute: Modifier les filtres et regroupements et télécharger + execute: Télécharger absence: # single letter for absence From b4614974c0ba7d95fc3814d249dad7a35d3e508f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 6 Jun 2023 10:49:00 +0200 Subject: [PATCH 149/321] allow to edit existing saved export with new export options --- .../Controller/ExportController.php | 33 +++++++++++++++++-- .../Export/ExportFormHelper.php | 1 - .../Resources/views/Export/download.html.twig | 32 +++++++++++++----- .../translations/messages.fr.yml | 1 + 4 files changed, 55 insertions(+), 12 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Controller/ExportController.php b/src/Bundle/ChillMainBundle/Controller/ExportController.php index 2ad6377a6..e8ee9b97b 100644 --- a/src/Bundle/ChillMainBundle/Controller/ExportController.php +++ b/src/Bundle/ChillMainBundle/Controller/ExportController.php @@ -127,6 +127,7 @@ class ExportController extends AbstractController 'alias' => $alias, 'export' => $export, 'export_group' => $this->getExportGroup($export), + 'saved_export' => $savedExport, ]; if ($formater instanceof \Chill\MainBundle\Export\Formatter\CSVListFormatter) { @@ -245,6 +246,28 @@ class ExportController extends AbstractController } } + /** + * @Route("/{_locale}/export/saved/update-from-key/{id}/{key}", name="chill_main_export_saved_edit_options_from_key") + */ + public function editSavedExportOptionsFromKey(SavedExport $savedExport, string $key): Response + { + $this->denyAccessUnlessGranted('ROLE_USER'); + $user = $this->getUser(); + + if (!$user instanceof User) { + throw new AccessDeniedHttpException(); + } + + $data = $this->rebuildRawData($key); + + $savedExport + ->setOptions($data); + + $this->entityManager->flush(); + + return $this->redirectToRoute('chill_main_export_saved_edit', ['id' => $savedExport->getId()]); + } + /** * @Route("/{_locale}/export/save-from-key/{alias}/{key}", name="chill_main_export_save_from_key") */ @@ -478,7 +501,9 @@ class ExportController extends AbstractController if (null === $dataFormatter && $export instanceof \Chill\MainBundle\Export\ExportInterface) { return $this->redirectToRoute('chill_main_export_new', [ - 'alias' => $alias, 'step' => $this->getNextStep('generate', $export, true), + 'alias' => $alias, + 'step' => $this->getNextStep('generate', $export, true), + 'from_saved' => $savedExport?->getId() ?? '', ]); } @@ -499,7 +524,11 @@ class ExportController extends AbstractController $this->session->remove('formatter_step_raw'); $this->session->remove('formatter_step'); - return $this->redirectToRoute('chill_main_export_download', ['key' => $key, 'alias' => $alias]); + return $this->redirectToRoute('chill_main_export_download', [ + 'key' => $key, + 'alias' => $alias, + 'from_saved' => $savedExport?->getId(), + ]); } private function rebuildData($key, ?SavedExport $savedExport) diff --git a/src/Bundle/ChillMainBundle/Export/ExportFormHelper.php b/src/Bundle/ChillMainBundle/Export/ExportFormHelper.php index 3deb2acbc..c2127fb36 100644 --- a/src/Bundle/ChillMainBundle/Export/ExportFormHelper.php +++ b/src/Bundle/ChillMainBundle/Export/ExportFormHelper.php @@ -147,7 +147,6 @@ final readonly class ExportFormHelper SavedExport $savedExport, array $formOptions ): array { - dump(__METHOD__); $builder = $this->formFactory ->createBuilder( FormType::class, diff --git a/src/Bundle/ChillMainBundle/Resources/views/Export/download.html.twig b/src/Bundle/ChillMainBundle/Resources/views/Export/download.html.twig index 1e69c5a49..bd7dbf7e9 100644 --- a/src/Bundle/ChillMainBundle/Resources/views/Export/download.html.twig +++ b/src/Bundle/ChillMainBundle/Resources/views/Export/download.html.twig @@ -1,5 +1,5 @@ {# - * Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS, + * Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS, / * * This program is free software: you can redistribute it and/or modify @@ -19,7 +19,7 @@ {% extends "@ChillMain/layout.html.twig" %} {% block title "Download export"|trans ~ export.title|trans %} - + {% block js %} {% endblock %} - + {% block content %}
              - + {{ include('@ChillMain/Export/_breadcrumb.html.twig') }} - +

              {{ export.title|trans }}

              {{ "Download export"|trans }}

              - +
              {{ 'Back to the list'|trans }} {% if not app.request.query.has('prevent_save') %} + {% if saved_export is null %}
            • {{ 'Save'|trans }}
            • + {% else %} +
            • + +
            • + {% endif %} {% endif %}
            -{% endblock content %} \ No newline at end of file +{% endblock content %} diff --git a/src/Bundle/ChillMainBundle/translations/messages.fr.yml b/src/Bundle/ChillMainBundle/translations/messages.fr.yml index 4a85db149..bbe3d23fb 100644 --- a/src/Bundle/ChillMainBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillMainBundle/translations/messages.fr.yml @@ -601,6 +601,7 @@ saved_export: update_title_and_description: Modifier le titre et la description update_filters_aggregators_and_execute: Modifier les filtres et regroupements et télécharger execute: Télécharger + Update existing: Mettre à jour le rapport enregistré existant absence: # single letter for absence From 05822e7e4af50bec73888ff61adf189519929c5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 6 Jun 2023 10:52:12 +0200 Subject: [PATCH 150/321] add changelog --- .changes/unreleased/Feature-20230606-105153.yaml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changes/unreleased/Feature-20230606-105153.yaml diff --git a/.changes/unreleased/Feature-20230606-105153.yaml b/.changes/unreleased/Feature-20230606-105153.yaml new file mode 100644 index 000000000..00c3ab1da --- /dev/null +++ b/.changes/unreleased/Feature-20230606-105153.yaml @@ -0,0 +1,6 @@ +kind: Feature +body: 'Edit saved exports options: the saved exports options (forms, filters, aggregators) + are now editable.' +time: 2023-06-06T10:51:53.331701352+02:00 +custom: + Issue: "110" From aa6479fbf93757b0a594d8de5b748cabf1b31593 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 6 Jun 2023 11:14:14 +0200 Subject: [PATCH 151/321] doc for rector rule [ci-skip] --- ...aultDataOnExportFilterAggregatorRector.php | 54 ++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/utils/rector/src/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector.php b/utils/rector/src/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector.php index 237aa17b8..e6bf4a75a 100644 --- a/utils/rector/src/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector.php +++ b/utils/rector/src/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector.php @@ -32,7 +32,59 @@ class ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector extends Abstra { return new RuleDefinition( 'Add a getFormDefault data method on exports, filters and aggregators, filled with default data', - [] + [ + <<add('foo', PickRollingDateType::class, [ + 'label' => 'Test thing', + 'data' => new RollingDate(RollingDate::T_TODAY) + ]); + + $builder->add('baz', TextType::class, [ + 'label' => 'OrNiCar', + 'data' => 'Castor' + ]); + } +} +PHP, +<<add('foo', PickRollingDateType::class, [ + 'label' => 'Test thing', + 'data' => new RollingDate(RollingDate::T_TODAY) + ]); + + $builder->add('baz', TextType::class, [ + 'label' => 'OrNiCar', + 'data' => 'Castor' + ]); + } + public function getFormDefaultData(): array + { + return ['foo' => new RollingDate(RollingDate::T_TODAY), 'baz' => 'Castor']; + } +} +PHP + ] ); } From 0fd36a319633ced130f21b2e33a0f44ff7cee34d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 6 Jun 2023 14:40:24 +0200 Subject: [PATCH 152/321] fix list of "my accompanying periods" --- .../unreleased/Fixed-20230606-143955.yaml | 6 +++++ .../UserAccompanyingPeriodController.php | 23 +++++++++++++++---- .../user_periods_list.html.twig | 9 ++++++++ 3 files changed, 34 insertions(+), 4 deletions(-) create mode 100644 .changes/unreleased/Fixed-20230606-143955.yaml diff --git a/.changes/unreleased/Fixed-20230606-143955.yaml b/.changes/unreleased/Fixed-20230606-143955.yaml new file mode 100644 index 000000000..a7ab6b6a1 --- /dev/null +++ b/.changes/unreleased/Fixed-20230606-143955.yaml @@ -0,0 +1,6 @@ +kind: Fixed +body: 'List of "my accompanying periods": separate the active and closed periods in + two different lists, and show the inactive_long and inactive_short periods' +time: 2023-06-06T14:39:55.68417576+02:00 +custom: + Issue: "111" diff --git a/src/Bundle/ChillPersonBundle/Controller/UserAccompanyingPeriodController.php b/src/Bundle/ChillPersonBundle/Controller/UserAccompanyingPeriodController.php index 658fdb7be..1b67014b3 100644 --- a/src/Bundle/ChillPersonBundle/Controller/UserAccompanyingPeriodController.php +++ b/src/Bundle/ChillPersonBundle/Controller/UserAccompanyingPeriodController.php @@ -12,9 +12,11 @@ declare(strict_types=1); namespace Chill\PersonBundle\Controller; use Chill\MainBundle\Pagination\PaginatorFactory; +use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Repository\AccompanyingPeriodRepository; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; class UserAccompanyingPeriodController extends AbstractController @@ -32,12 +34,24 @@ class UserAccompanyingPeriodController extends AbstractController /** * @Route("/{_locale}/person/accompanying-periods/my", name="chill_person_accompanying_period_user") */ - public function listAction(Request $request) + public function listAction(Request $request): Response { - $total = $this->accompanyingPeriodRepository->countBy(['user' => $this->getUser(), 'step' => ['CONFIRMED', 'CLOSED']]); + $active = $request->query->getBoolean('active', true); + $steps = match ($active) { + true => [ + AccompanyingPeriod::STEP_CONFIRMED, + AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_LONG, + AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_SHORT, + ], + false => [ + AccompanyingPeriod::STEP_CLOSED, + ] + }; + + $total = $this->accompanyingPeriodRepository->countBy(['user' => $this->getUser(), 'step' => $steps]); $pagination = $this->paginatorFactory->create($total); $accompanyingPeriods = $this->accompanyingPeriodRepository->findBy( - ['user' => $this->getUser(), 'step' => ['CONFIRMED', 'CLOSED']], + ['user' => $this->getUser(), 'step' => $steps], ['openingDate' => 'DESC'], $pagination->getItemsPerPage(), $pagination->getCurrentPageFirstItemNumber() @@ -46,13 +60,14 @@ class UserAccompanyingPeriodController extends AbstractController return $this->render('@ChillPerson/AccompanyingPeriod/user_periods_list.html.twig', [ 'accompanyingPeriods' => $accompanyingPeriods, 'pagination' => $pagination, + 'active' => $active, ]); } /** * @Route("/{_locale}/person/accompanying-periods/my/drafts", name="chill_person_accompanying_period_draft_user") */ - public function listDraftsAction(Request $request) + public function listDraftsAction(): Response { $total = $this->accompanyingPeriodRepository->countBy(['user' => $this->getUser(), 'step' => 'DRAFT']); $pagination = $this->paginatorFactory->create($total); diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/user_periods_list.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/user_periods_list.html.twig index 031e0728c..38e055378 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/user_periods_list.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/user_periods_list.html.twig @@ -17,6 +17,15 @@

            {{ 'My accompanying periods'|trans }}

            + +

            {{ 'Number of periods'|trans }}: {{ pagination.totalItems }}

            From 88f48d474fd33a06887083e666c4f26caf93b5af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 6 Jun 2023 17:08:38 +0200 Subject: [PATCH 153/321] fix association's annotation between PersonCenterCurrent and Person entities --- .changes/unreleased/Fixed-20230606-170742.yaml | 6 ++++++ .../ChillPersonBundle/Entity/Person/PersonCenterCurrent.php | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 .changes/unreleased/Fixed-20230606-170742.yaml diff --git a/.changes/unreleased/Fixed-20230606-170742.yaml b/.changes/unreleased/Fixed-20230606-170742.yaml new file mode 100644 index 000000000..0bd65b6cf --- /dev/null +++ b/.changes/unreleased/Fixed-20230606-170742.yaml @@ -0,0 +1,6 @@ +kind: Fixed +body: use the correct annotation for the association between PersonCurrentCenter and + Person +time: 2023-06-06T17:07:42.060486553+02:00 +custom: + Issue: "" diff --git a/src/Bundle/ChillPersonBundle/Entity/Person/PersonCenterCurrent.php b/src/Bundle/ChillPersonBundle/Entity/Person/PersonCenterCurrent.php index 6d67fbbbb..6de73de0d 100644 --- a/src/Bundle/ChillPersonBundle/Entity/Person/PersonCenterCurrent.php +++ b/src/Bundle/ChillPersonBundle/Entity/Person/PersonCenterCurrent.php @@ -45,7 +45,7 @@ class PersonCenterCurrent private ?int $id = null; /** - * @ORM\ManyToOne(targetEntity=Person::class, inversedBy="centerCurrent") + * @ORM\OneToOne(targetEntity=Person::class, inversedBy="centerCurrent") */ private Person $person; From 73b95732db02d9ff6095cdb05d19e09051af5655 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 7 Jun 2023 13:06:10 +0200 Subject: [PATCH 154/321] Add new methods to RegroupmentRepository and fix association Regroupment/Center --- .changes/unreleased/DX-20230607-130344.yaml | 6 +++++ src/Bundle/ChillMainBundle/Entity/Center.php | 17 +++++++++++- .../ChillMainBundle/Entity/Regroupment.php | 25 ++++++++++++++++-- .../ChillMainBundle/Form/RegroupmentType.php | 2 +- .../Repository/RegroupmentRepository.php | 26 +++++++++++++++++++ 5 files changed, 72 insertions(+), 4 deletions(-) create mode 100644 .changes/unreleased/DX-20230607-130344.yaml diff --git a/.changes/unreleased/DX-20230607-130344.yaml b/.changes/unreleased/DX-20230607-130344.yaml new file mode 100644 index 000000000..c7774c395 --- /dev/null +++ b/.changes/unreleased/DX-20230607-130344.yaml @@ -0,0 +1,6 @@ +kind: DX +body: Add methods to RegroupmentRepository and fullfill Center / Regroupment Doctrine + mapping +time: 2023-06-07T13:03:44.177864269+02:00 +custom: + Issue: "" diff --git a/src/Bundle/ChillMainBundle/Entity/Center.php b/src/Bundle/ChillMainBundle/Entity/Center.php index 5ca051ec0..0d5402409 100644 --- a/src/Bundle/ChillMainBundle/Entity/Center.php +++ b/src/Bundle/ChillMainBundle/Entity/Center.php @@ -48,12 +48,19 @@ class Center implements HasCenterInterface */ private string $name = ''; + /** + * @var Collection + * @ORM\ManyToMany(targetEntity=Regroupment::class, mappedBy="centers") + */ + private Collection $regroupments; + /** * Center constructor. */ public function __construct() { - $this->groupCenters = new \Doctrine\Common\Collections\ArrayCollection(); + $this->groupCenters = new ArrayCollection(); + $this->regroupments = new ArrayCollection(); } /** @@ -106,6 +113,14 @@ class Center implements HasCenterInterface return $this->name; } + /** + * @return Collection + */ + public function getRegroupments(): Collection + { + return $this->regroupments; + } + /** * @param $name * diff --git a/src/Bundle/ChillMainBundle/Entity/Regroupment.php b/src/Bundle/ChillMainBundle/Entity/Regroupment.php index 96953abf5..c5d9525cf 100644 --- a/src/Bundle/ChillMainBundle/Entity/Regroupment.php +++ b/src/Bundle/ChillMainBundle/Entity/Regroupment.php @@ -22,11 +22,12 @@ use Doctrine\ORM\Mapping as ORM; class Regroupment { /** - * @var Center * @ORM\ManyToMany( - * targetEntity=Center::class + * targetEntity=Center::class, + * inversedBy="regroupments" * ) * @ORM\Id + * @var Collection
            */ private Collection $centers; @@ -52,6 +53,26 @@ class Regroupment $this->centers = new ArrayCollection(); } + public function addCenter(Center $center): self + { + if (!$this->centers->contains($center)) { + $this->centers->add($center); + $center->getRegroupments()->add($this); + } + + return $this; + } + + public function removeCenter(Center $center): self + { + if ($this->centers->contains($center)) { + $this->centers->removeElement($center); + $center->getRegroupments()->removeElement($this); + } + + return $this; + } + public function getCenters(): Collection { return $this->centers; diff --git a/src/Bundle/ChillMainBundle/Form/RegroupmentType.php b/src/Bundle/ChillMainBundle/Form/RegroupmentType.php index bc8e6684f..22814598a 100644 --- a/src/Bundle/ChillMainBundle/Form/RegroupmentType.php +++ b/src/Bundle/ChillMainBundle/Form/RegroupmentType.php @@ -31,7 +31,7 @@ class RegroupmentType extends AbstractType ->add('centers', EntityType::class, [ 'class' => Center::class, 'multiple' => true, - 'attr' => ['class' => 'select2'], + 'expanded' => true, ]) ->add('isActive', CheckboxType::class, [ 'label' => 'Actif ?', diff --git a/src/Bundle/ChillMainBundle/Repository/RegroupmentRepository.php b/src/Bundle/ChillMainBundle/Repository/RegroupmentRepository.php index a28f2f341..84e2efe81 100644 --- a/src/Bundle/ChillMainBundle/Repository/RegroupmentRepository.php +++ b/src/Bundle/ChillMainBundle/Repository/RegroupmentRepository.php @@ -14,6 +14,8 @@ namespace Chill\MainBundle\Repository; use Chill\MainBundle\Entity\Regroupment; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityRepository; +use Doctrine\ORM\NonUniqueResultException; +use Doctrine\ORM\NoResultException; use Doctrine\Persistence\ObjectRepository; final class RegroupmentRepository implements ObjectRepository @@ -59,6 +61,30 @@ final class RegroupmentRepository implements ObjectRepository return $this->repository->findOneBy($criteria, $orderBy); } + /** + * @throws NonUniqueResultException + * @throws NoResultException + */ + public function findOneByName(string $name): ?Regroupment + { + return $this->repository->createQueryBuilder('r') + ->where('LOWER(r.name) = LOWER(:searched)') + ->setParameter('searched', $name) + ->getQuery() + ->getSingleResult(); + } + + /** + * @return array + */ + public function findRegroupmentAssociatedToAnyCenter(): array + { + return $this->repository->createQueryBuilder('r') + ->where('SIZE(r.centers) = 0') + ->getQuery() + ->getResult(); + } + public function getClassName() { return Regroupment::class; From c73beef3aff5d73111f675b19dc13e0fbeb20909 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Wed, 7 Jun 2023 13:25:48 +0200 Subject: [PATCH 155/321] FIX [rights][household] check rights to be able to create a parcours from within household --- .../views/Household/accompanying_period.html.twig | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Resources/views/Household/accompanying_period.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/Household/accompanying_period.html.twig index acd251735..e71559585 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/Household/accompanying_period.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/Household/accompanying_period.html.twig @@ -41,12 +41,14 @@
          • {# TODO: add ACL to check if user is allowed to edit household? #} -
          • - - {{ 'Create an accompanying period'|trans }} - -
          • + {% if is_granted('CHILL_PERSON_HOUSEHOLD_EDIT', household) %} +
          • + + {{ 'Create an accompanying period'|trans }} + +
          • + {% endif %}
          From 520d5ab6d4698874bfae1d78510fb4ef735b152c Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Wed, 7 Jun 2023 13:30:53 +0200 Subject: [PATCH 156/321] FIX [rights][menu] dont show menu item parcours if user doesn't have the proper rights --- .../Menu/HouseholdMenuBuilder.php | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Menu/HouseholdMenuBuilder.php b/src/Bundle/ChillPersonBundle/Menu/HouseholdMenuBuilder.php index 074c27027..65b751bc2 100644 --- a/src/Bundle/ChillPersonBundle/Menu/HouseholdMenuBuilder.php +++ b/src/Bundle/ChillPersonBundle/Menu/HouseholdMenuBuilder.php @@ -12,7 +12,9 @@ declare(strict_types=1); namespace Chill\PersonBundle\Menu; use Chill\MainBundle\Routing\LocalMenuBuilderInterface; +use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter; use Knp\Menu\MenuItem; +use Symfony\Component\Security\Core\Security; use Symfony\Contracts\Translation\TranslatorInterface; class HouseholdMenuBuilder implements LocalMenuBuilderInterface @@ -22,9 +24,12 @@ class HouseholdMenuBuilder implements LocalMenuBuilderInterface */ protected $translator; - public function __construct(TranslatorInterface $translator) + private Security $security; + + public function __construct(TranslatorInterface $translator, Security $security) { $this->translator = $translator; + $this->security = $security; } public function buildMenu($menuId, MenuItem $menu, array $parameters): void @@ -53,12 +58,15 @@ class HouseholdMenuBuilder implements LocalMenuBuilderInterface ], ]) ->setExtras(['order' => 17]); - $menu->addChild($this->translator->trans('household.Accompanying period'), [ - 'route' => 'chill_person_household_accompanying_period', - 'routeParameters' => [ - 'household_id' => $household->getId(), - ], ]) - ->setExtras(['order' => 20]); + if ($this->security->isGranted(AccompanyingPeriodVoter::SEE, $parameters['household'])) + { + $menu->addChild($this->translator->trans('household.Accompanying period'), [ + 'route' => 'chill_person_household_accompanying_period', + 'routeParameters' => [ + 'household_id' => $household->getId(), + ],]) + ->setExtras(['order' => 20]); + } $menu->addChild($this->translator->trans('household.Addresses'), [ 'route' => 'chill_person_household_addresses', From 199223293e6b1f9b7da78649a670d18dad63b596 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 7 Jun 2023 13:36:26 +0200 Subject: [PATCH 157/321] rename method --- src/Bundle/ChillMainBundle/Repository/RegroupmentRepository.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Bundle/ChillMainBundle/Repository/RegroupmentRepository.php b/src/Bundle/ChillMainBundle/Repository/RegroupmentRepository.php index 84e2efe81..c115d5d98 100644 --- a/src/Bundle/ChillMainBundle/Repository/RegroupmentRepository.php +++ b/src/Bundle/ChillMainBundle/Repository/RegroupmentRepository.php @@ -77,7 +77,7 @@ final class RegroupmentRepository implements ObjectRepository /** * @return array */ - public function findRegroupmentAssociatedToAnyCenter(): array + public function findRegroupmentAssociatedToNoCenter(): array { return $this->repository->createQueryBuilder('r') ->where('SIZE(r.centers) = 0') From 23ee29ab0de50ed8447d2cceb812b0d83fcabb90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 7 Jun 2023 11:39:19 +0000 Subject: [PATCH 158/321] Apply 1 suggestion(s) to 1 file(s) --- .../Resources/views/Household/accompanying_period.html.twig | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Bundle/ChillPersonBundle/Resources/views/Household/accompanying_period.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/Household/accompanying_period.html.twig index e71559585..c734eee8e 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/Household/accompanying_period.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/Household/accompanying_period.html.twig @@ -40,7 +40,6 @@ {{ 'Household summary'|trans }}
        • - {# TODO: add ACL to check if user is allowed to edit household? #} {% if is_granted('CHILL_PERSON_HOUSEHOLD_EDIT', household) %}
        • Date: Wed, 7 Jun 2023 17:39:28 +0200 Subject: [PATCH 159/321] FIX [php-cs-fixer] --- src/Bundle/ChillPersonBundle/Menu/HouseholdMenuBuilder.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Menu/HouseholdMenuBuilder.php b/src/Bundle/ChillPersonBundle/Menu/HouseholdMenuBuilder.php index 65b751bc2..13291bdd1 100644 --- a/src/Bundle/ChillPersonBundle/Menu/HouseholdMenuBuilder.php +++ b/src/Bundle/ChillPersonBundle/Menu/HouseholdMenuBuilder.php @@ -58,8 +58,7 @@ class HouseholdMenuBuilder implements LocalMenuBuilderInterface ], ]) ->setExtras(['order' => 17]); - if ($this->security->isGranted(AccompanyingPeriodVoter::SEE, $parameters['household'])) - { + if ($this->security->isGranted(AccompanyingPeriodVoter::SEE, $parameters['household'])) { $menu->addChild($this->translator->trans('household.Accompanying period'), [ 'route' => 'chill_person_household_accompanying_period', 'routeParameters' => [ From f5b71a0c413a92a76081c49b9023c97231bbf46e Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Wed, 7 Jun 2023 17:47:23 +0200 Subject: [PATCH 160/321] DX [changie] entry added --- .changes/unreleased/Security-20230607-174702.yaml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .changes/unreleased/Security-20230607-174702.yaml diff --git a/.changes/unreleased/Security-20230607-174702.yaml b/.changes/unreleased/Security-20230607-174702.yaml new file mode 100644 index 000000000..ecdc1d191 --- /dev/null +++ b/.changes/unreleased/Security-20230607-174702.yaml @@ -0,0 +1,7 @@ +kind: Security +body: Rights are checked for display of 'accompanying period' tab in household menu. + Rights are also checked for creation of 'accompanying period' from within household + context +time: 2023-06-07T17:47:02.488819553+02:00 +custom: + Issue: "105" From ad72192e2431bf7abeeceb7c8e824b11bf124b91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 8 Jun 2023 11:24:01 +0200 Subject: [PATCH 161/321] doc: for database printciples --- .changes/unreleased/DX-20230608-112417.yaml | 5 + .../development/database-principles.rst | 84 ++++++++++ .../development/database/table_list.csv | 155 ++++++++++++++++++ docs/source/development/index.rst | 1 + 4 files changed, 245 insertions(+) create mode 100644 .changes/unreleased/DX-20230608-112417.yaml create mode 100644 docs/source/development/database-principles.rst create mode 100644 docs/source/development/database/table_list.csv diff --git a/.changes/unreleased/DX-20230608-112417.yaml b/.changes/unreleased/DX-20230608-112417.yaml new file mode 100644 index 000000000..7091808ec --- /dev/null +++ b/.changes/unreleased/DX-20230608-112417.yaml @@ -0,0 +1,5 @@ +kind: DX +body: Documentation for database principles +time: 2023-06-08T11:24:17.701892874+02:00 +custom: + Issue: "" diff --git a/docs/source/development/database-principles.rst b/docs/source/development/database-principles.rst new file mode 100644 index 000000000..0b4a33f04 --- /dev/null +++ b/docs/source/development/database-principles.rst @@ -0,0 +1,84 @@ + +.. database-principles: + +Principes de la base de données +############################### + +Cette page donne une compréhension globale de la base de donnée de Chill, et explique quelques détails d'implémentations qui permettent d'accélérer les traitements à partir de la base de donnée, ou de l'exploiter plus aisément. + +Cette page est rédigée en français. + +.. note:: + + La stabilité du schéma de la base de donnée n'est pas garantie. + + Toutefois, ce dernier évolue relativement peu. Il est rare que des tables ou des colonnes soient supprimées ou renommées. Mais il n'est pas garanti que cela puisse arriver. + +Généralités +=========== + +Une liste commentée de toutes les tables :download:`est disponible au format CSV <./database/table_list.csv`. + +Schéma et conventions de nommage +-------------------------------- + +Au début de l'histoire de Chill, les schémas postgresql n'étaient pas exploités. Les données étaient stockées dans le schéma :code:`public`. + +Par la suite, des nouveaux bundles sont apparus, et les tables ont été classées dans des schémas dédiés. + +A l'heure actuelle: + +- pour les anciens bundle, ceux qui ont déjà des tables dans le schéma public, les nouvelles tables sont ajoutées à ce schéma. Elles sont préfixées par :code:`chill__`; +- pour les bundles plus récents, les tables sont créées dans le schéma dédié + +Données avec de l'historicité +----------------------------- + +Certaines données sont historisées: + +- les référents d'un parcours; +- les statuts d'un parcours; +- la liaison entre les centres et les usagers; +- etc. + +Dans ces cas-là, Chill crée généralement deux colonnes, qui sont habituellement nommées :code:`startDate` et :code:`endDate`. Lorsque la colonne :code:`endDate` est à :code:`NULL`, cela signifie que la période n'est pas "fermée". La colonne :code:`startDate` n'est pas nullable. + +Dans certains cas, la donnée actuelle (référent d'un parcours, par exemple) est également répétée au niveau de la table en elle-même. Par exemple, la table des parcours :code:`chill_person_accompanying_period` comporte une colonne :code:`step` (le statut du parcours) et :code:`user_id` (id du référent) en plus de l'historique. Bien que redondant, cela simplifie les traitements. + +Relations particulières +======================= + +Usagers, ménages, adresses +-------------------------- + +Les usagers ont une adresse au travers des ménages: dans l'interface, l'adresse est inscrite dans le dossier du ménage, et elle est "donnée" aux usagers membres du ménage, **et** qui partagent l'adresse de ce ménage. En effet, il est possible que des usagers "appartiennent" à un ménage sans y être domicilié: c'est le cas, par exemple, des enfants en garde alternée. + +L'historique de l'appartenance des usagers au ménage est conservée, de même que l'historique des adresses pour un même ménage. + +Les tables en jeu sont les suivantes: + +- la table :code:`chill_person_person` liste les usagers; +- la table :code:`chill_person_household_members` liste les appartenances au ménage: il s'agit de la jointure entre les usagers et les ménages: + - les colonnes :code:`startDate` et :code:`endDate` indiquent la date de début et la date de fin de l'appartenance; + - la colonne :code:`shareHousehold` indique si l'utilisateur partage l'adresse du ménage (si oui, sa valeur est :code:`TRUE`) +- la table :code:`chill_person_household` liste les ménages +- la table :code:`chill_person_household_to_addresses` associe les ménages aux adresses; +- la table :code:`chill_main_address` contient les adresses, en indiquant la date de début de validité (:code:`validFrom`) et la fin de validité (:code:`validTo`). + +Pour simplifier la résolution des adresses et des usagers, deux vues ont été mises en œuvre: + +- la vue :code:`view_chill_person_household_address` reprend, pour chaque usager, l'historique des appartenances au ménage découpée par l'historique des adresses d'un ménage. + Autrement dit, une ligne est créée à chaque fois qu'un usager change de ménage, ou qu'un ménage change d'adresse. Il est donc possible de retrouver l'historique complet des adresses pour un usager donné via cette table. +- la vue :code:`view_chill_person_current_address` reprend l'adresse actuelle des usagers. + +Adresses et unités géographiques +-------------------------------- + +Chill propose des statistiques sur la localisation des adresses par rapport à des zones géographiques (:code:`chill_main_geographical_unit`). + +Comme la résolution géographique des adresses est coûteuse en CPU et en temps de traitement, une vue matérialisée a été créée: :code:`view_chill_main_address_geographical_unit`. Elle est rafraichie quotidiennement dans la base de donnée de production. + +Liste des tables et commentaires +================================ + + diff --git a/docs/source/development/database/table_list.csv b/docs/source/development/database/table_list.csv new file mode 100644 index 000000000..fe688318d --- /dev/null +++ b/docs/source/development/database/table_list.csv @@ -0,0 +1,155 @@ +order,table_schema,table_name,commentaire +1,chill_3party,party_category,Catégorie de tiers +2,chill_3party,party_center,Association entre les tiers et les centres (déprécié) +3,chill_3party,party_profession,Profession du tiers (déprécié) +4,chill_3party,third_party,Tiers +5,chill_3party,thirdparty_category,association tiers - catégories +6,chill_asideactivity,asideactivity,Activités annexes +7,chill_asideactivity,asideactivitycategory,Catégories d'activités annexes +8,chill_budget,charge,Charges du budget +9,chill_budget,charge_type,Types de charges +10,chill_budget,resource,Ressources du budget +11,chill_budget,resource_type,Types de ressources +12,chill_calendar,calendar,Rendez-vous +13,chill_calendar,calendar_doc,Document du rendez-vous +14,chill_calendar,calendar_range,Plage de disponibilité +15,chill_calendar,calendar_to_persons,association rendez-vous - usagers +16,chill_calendar,calendar_to_thirdparties,association rendez-vous - tiers +17,chill_calendar,cancel_reason,Motifs d'annulations +18,chill_calendar,invite,Invitation aux rendez-vous +19,chill_doc,accompanyingcourse_document,Documents associés aux parcours +20,chill_doc,document_category,Catégories de documents +21,chill_doc,person_document,Documents associés à l'usagers +22,chill_doc,stored_object,Documents +23,chill_task,recurring_task,Tâches récurrentes (non utilisé) +24,chill_task,single_task,Tâches +25,chill_task,single_task_place_event,Historique des transitions des tâches +26,chill_vendee,adressederelais, +27,chill_vendee,center_polygon +28,chill_vendee,entourage, +29,chill_vendee,geographical_unit +30,chill_vendee,geographical_unit_association +31,chill_vendee,mobilite +32,chill_vendee,niveauetude +33,chill_vendee,security_profile +34,chill_vendee,security_profile_action +35,chill_vendee,security_profile_jobs +36,chill_vendee,situationprofessionelle +37,chill_vendee,statutlogement +38,chill_vendee,tempsdetravail +39,chill_vendee,titredesejour +40,chill_vendee,vendee_person +41,chill_vendee,vendee_person_mineur +42,chill_vendee,vendeeperson_entourage +43,chill_vendee,vendeepersonmineur_adressederelais +44,public,accompanying_periods_scopes,Services associés aux parcours +45,public,activity,Échanges +46,public,activity_activityreason,s +47,public,activity_person, +48,public,activity_storedobject, +49,public,activity_thirdparty, +50,public,activity_user, +51,public,activityreason,Sujets d'échange +52,public,activityreasoncategory,Catégories de sujets +53,public,activitytpresence,Présence aux échanges +54,public,activitytype,Types d'échanges +55,public,activitytypecategory,Catégories de types d'échanges +56,public,centers,"Centres (territoires, agences, etc.)" +57,public,chill_activity_activity_chill_person_socialaction, +58,public,chill_activity_activity_chill_person_socialissue +59,public,chill_docgen_template,Gabarits de documents +60,public,chill_main_address,Adresses +61,public,chill_main_address_legacy,Anciennes adresses (dépréciés) +62,public,chill_main_address_reference,Adresses de référence +63,public,chill_main_civility,Civilités +64,public,chill_main_cronjob_execution,Dernière exécution des tâche cron +65,public,chill_main_geographical_unit,Unités géographiques +66,public,chill_main_geographical_unit_layer,Couches d'unités géographiques +67,public,chill_main_location,Localisations +68,public,chill_main_location_type,Types de localisations +69,public,chill_main_notification,Notifications +70,public,chill_main_notification_addresses_unread +71,public,chill_main_notification_addresses_user +72,public,chill_main_notification_comment, +73,public,chill_main_postal_code,Code postaux +74,public,chill_main_saved_export,Exports enregistrés +75,public,chill_main_user_job,Métiers +76,public,chill_main_workflow_entity,Workflows +77,public,chill_main_workflow_entity_comment +78,public,chill_main_workflow_entity_step,Etapes du workflow +79,public,chill_main_workflow_entity_step_cc_user, +80,public,chill_main_workflow_entity_step_user +81,public,chill_main_workflow_entity_step_user_by_accesskey, +82,public,chill_main_workflow_entity_subscriber_to_final, +83,public,chill_main_workflow_entity_subscriber_to_step +84,public,chill_person_accompanying_period,Parcours d'accompagnement +85,public,chill_person_accompanying_period_closingmotive,Motifs de cloture des parcours +86,public,chill_person_accompanying_period_comment,Commentaires des parcours +87,public,chill_person_accompanying_period_location_history,Historique de la localisatio ndes parcours +88,public,chill_person_accompanying_period_origin,Origine des parcours +89,public,chill_person_accompanying_period_participation,Appartenance des usagers au parcours +90,public,chill_person_accompanying_period_resource,Personnes ressources d'un parcours +91,public,chill_person_accompanying_period_social_issues, +92,public,chill_person_accompanying_period_step_history +93,public,chill_person_accompanying_period_user_history +94,public,chill_person_accompanying_period_work,Actions d'accompagnements +95,public,chill_person_accompanying_period_work_evaluation,Évaluations (dans les actions d'accompagnements) +96,public,chill_person_accompanying_period_work_evaluation_document,Documents des évaluations +97,public,chill_person_accompanying_period_work_goal,Objectifs d'une actions +98,public,chill_person_accompanying_period_work_goal_result,Objectifs et résultats d'une action +99,public,chill_person_accompanying_period_work_person,Usagers associés à une actions +100,public,chill_person_accompanying_period_work_referrer,Référents d'une actions +101,public,chill_person_accompanying_period_work_result,Résultats d'une action +102,public,chill_person_accompanying_period_work_third_party,Tiers traitants d'une action +103,public,chill_person_alt_name,"Noms supplémentaires d'un usager (nom marital, etc.)" +104,public,chill_person_household,Ménages +105,public,chill_person_household_composition, +106,public,chill_person_household_composition_type,Types de composition de ménage +107,public,chill_person_household_members,Membres du ménages +108,public,chill_person_household_position,Positions dans le ménage +109,public,chill_person_household_to_addresses,Association adresses - ménages +110,public,chill_person_marital_status,Etats civils +111,public,chill_person_not_duplicate, +112,public,chill_person_person,Usagers +113,public,chill_person_person_center_history,Historique des centres d'un usagers +114,public,chill_person_persons_to_addresses,Déprécié +115,public,chill_person_phone,Numéros d etéléphone supplémentaires d'un usager +116,public,chill_person_relations,Types de relations de filiation +117,public,chill_person_relationships,Relations de filiations +118,public,chill_person_residential_address,Adresses de résidences +119,public,chill_person_resource,Personnes ressources (pour les personnes) +120,public,chill_person_resource_kind,Type de personnes ressources +121,public,chill_person_social_action,Liste des actions d'accompagnement +122,public,chill_person_social_action_goal,Objectifs associés à une action +123,public,chill_person_social_action_result,Résultats associés à une action +124,public,chill_person_social_issue,Problématiques sociales +125,public,chill_person_social_work_evaluation,Evaluations disponibles +126,public,chill_person_social_work_evaluation_action,Associations entre les évaluations et les actions +127,public,chill_person_social_work_goal,Objectifs disponibles pour une actions +128,public,chill_person_social_work_goal_result,Objectifs et résultats disponible pour une action +129,public,chill_person_social_work_result,Résultats disponibles pour une action +130,public,country,Pays +131,public,custom_field_long_choice_options, +132,public,customfield +133,public,customfieldsdefaultgroup +134,public,customfieldsgroup +135,public,geography_columns,Table liée à postgis +136,public,geometry_columns,Table liée à postgis +137,public,group_centers, +138,public,language,Langues +139,public,messenger_messages,Table système +140,public,migration_versions,Table système +141,public,permission_groups +142,public,permissionsgroup_rolescope +143,public,persons_spoken_languages +144,public,regroupment,Regroupement de centres +145,public,regroupment_center, +146,public,role_scopes, +147,public,scopes,Services +148,public,spatial_ref_sys,Table système (postgis) +149,public,user_groupcenter, +150,public,users,Utilisateurs +151,public,view_chill_person_accompanying_period_info, +152,public,view_chill_person_current_address +153,public,view_chill_person_household_address +154,public,view_chill_person_person_center_history_current diff --git a/docs/source/development/index.rst b/docs/source/development/index.rst index fd9ae43ba..768d29ce0 100644 --- a/docs/source/development/index.rst +++ b/docs/source/development/index.rst @@ -36,6 +36,7 @@ As Chill rely on the `symfony `_ framework, reading the fram Assets Cron Jobs Info about entities + Info about database (in French) Layout and UI ************** From 727e9d0f74fa53818ca0cadd2f9da1470e1e91b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Mon, 12 Jun 2023 17:58:27 +0200 Subject: [PATCH 162/321] WIP: fix loading of activity document --- ...=> ActivityDocumentACLAwareRepository.php} | 113 +++++++----------- ...ityDocumentACLAwareRepositoryInterface.php | 28 +++++ .../Repository/ActivityRepository.php | 1 - ...anyingPeriodActivityGenericDocProvider.php | 20 +++- .../PersonActivityGenericDocProvider.php | 19 ++- ...ActivityDocumentACLAwareRepositoryTest.php | 113 ++++++++++++++++++ 6 files changed, 209 insertions(+), 85 deletions(-) rename src/Bundle/ChillActivityBundle/Repository/{PersonActivityDocumentACLAwareRepository.php => ActivityDocumentACLAwareRepository.php} (69%) create mode 100644 src/Bundle/ChillActivityBundle/Repository/ActivityDocumentACLAwareRepositoryInterface.php create mode 100644 src/Bundle/ChillActivityBundle/Tests/Repository/ActivityDocumentACLAwareRepositoryTest.php diff --git a/src/Bundle/ChillActivityBundle/Repository/PersonActivityDocumentACLAwareRepository.php b/src/Bundle/ChillActivityBundle/Repository/ActivityDocumentACLAwareRepository.php similarity index 69% rename from src/Bundle/ChillActivityBundle/Repository/PersonActivityDocumentACLAwareRepository.php rename to src/Bundle/ChillActivityBundle/Repository/ActivityDocumentACLAwareRepository.php index 84bb08fb4..f3f61ad3d 100644 --- a/src/Bundle/ChillActivityBundle/Repository/PersonActivityDocumentACLAwareRepository.php +++ b/src/Bundle/ChillActivityBundle/Repository/ActivityDocumentACLAwareRepository.php @@ -23,16 +23,18 @@ use Chill\DocStoreBundle\Security\Authorization\PersonDocumentVoter; use Chill\MainBundle\Entity\Scope; use Chill\MainBundle\Security\Authorization\AuthorizationHelperForCurrentUserInterface; use Chill\MainBundle\Security\Resolver\CenterResolverManagerInterface; +use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\Person; use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodWorkVoter; use DateTimeImmutable; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\EntityManagerInterface; +use Doctrine\ORM\Mapping\MappingException; use Doctrine\ORM\QueryBuilder; use Symfony\Component\HttpKernel\HttpCache\Store; use Symfony\Component\Security\Core\Security; -class PersonActivityDocumentACLAwareRepository implements PersonDocumentACLAwareRepositoryInterface +final readonly class ActivityDocumentACLAwareRepository implements ActivityDocumentACLAwareRepositoryInterface { public function __construct( private EntityManagerInterface $em, @@ -42,26 +44,43 @@ class PersonActivityDocumentACLAwareRepository implements PersonDocumentACLAware { } - public function buildQueryByPerson(Person $person): QueryBuilder + public function buildFetchQueryActivityDocumentLinkedToPersonFromPersonContext(Person $person, ?DateTimeImmutable $startDate = null, ?DateTimeImmutable $endDate = null, ?string $content = null): FetchQueryInterface { - $qb = $this->em->getRepository(PersonDocument::class)->createQueryBuilder('d'); - - $qb - ->where($qb->expr()->eq('d.person', ':person')) - ->setParameter('person', $person); - - return $qb; - } - - - public function buildFetchQueryForPerson(Person $person, ?DateTimeImmutable $startDate = null, ?DateTimeImmutable $endDate = null, ?string $content = null): FetchQueryInterface - { - $query = $this->buildBaseFetchQueryForPerson($person, $startDate, $endDate, $content); + $query = $this->buildBaseFetchQueryActivityDocumentLinkedToPersonFromPersonContext($person, $startDate, $endDate, $content); return $this->addFetchQueryByPersonACL($query, $person); } - public function buildBaseFetchQueryForPerson(Person $person, ?DateTimeImmutable $startDate = null, ?DateTimeImmutable $endDate = null, ?string $content = null): FetchQuery + public function buildBaseFetchQueryActivityDocumentLinkedToPersonFromPersonContext(Person $person, ?DateTimeImmutable $startDate = null, ?DateTimeImmutable $endDate = null, ?string $content = null): FetchQuery + { + $storedObjectMetadata = $this->em->getClassMetadata(StoredObject::class); + $activityMetadata = $this->em->getClassMetadata(Activity::class); + + $query = new FetchQuery( + PersonDocumentGenericDocProvider::KEY, + sprintf('jsonb_build_object(\'id\', stored_obj.%s, \'activity_id\', activity.%s)', $storedObjectMetadata->getSingleIdentifierColumnName(), $activityMetadata->getSingleIdentifierColumnName()), + sprintf('stored_obj.%s', $storedObjectMetadata->getColumnName('createdAt')), + sprintf('%s AS stored_obj', $storedObjectMetadata->getSchemaName().'.'.$storedObjectMetadata->getTableName()) + ); + + $query->addJoinClause( + 'JOIN public.activity_storedobject activity_doc ON activity_doc.storedobject_id = stored_obj.id' + ); + + $query->addJoinClause( + 'JOIN public.activity activity ON activity.id = activity_doc.activity_id' + ); + + $query->addWhereClause( + sprintf('activity.%s = ?', $activityMetadata->getSingleAssociationJoinColumnName('person')), + [$person->getId()], + [Types::INTEGER] + ); + + return $this->addWhereClauses($query, $startDate, $endDate, $content); + } + + public function buildFetchQueryActivityDocumentLinkedToAccompanyingPeriodFromPersonContext(Person $person, ?DateTimeImmutable $startDate = null, ?DateTimeImmutable $endDate = null, ?string $content = null): FetchQuery { $storedObjectMetadata = $this->em->getClassMetadata(StoredObject::class); $activityMetadata = $this->em->getClassMetadata(Activity::class); @@ -109,11 +128,12 @@ class PersonActivityDocumentACLAwareRepository implements PersonDocumentACLAware $query->addWhereClause(sprintf('(%s)', implode(' OR ', $or)), $orParams, $orTypes); -/* $query->addWhereClause( - 'activity.person_id = ?', - [$person->getId()], - [Types::INTEGER] - );*/ + return $this->addWhereClauses($query, $startDate, $endDate, $content); + } + + private function addWhereClauses(FetchQuery $query, ?DateTimeImmutable $startDate = null, ?DateTimeImmutable $endDate = null, ?string $content = null): FetchQuery + { + $storedObjectMetadata = $this->em->getClassMetadata(StoredObject::class); if (null !== $startDate) { $query->addWhereClause( @@ -131,7 +151,7 @@ class PersonActivityDocumentACLAwareRepository implements PersonDocumentACLAware ); } - if (null !== $content) { + if (null !== $content or '' !== $content) { $query->addWhereClause( 'stored_obj.title ilike ?', ['%' . $content . '%'], @@ -142,55 +162,6 @@ class PersonActivityDocumentACLAwareRepository implements PersonDocumentACLAware return $query; } - public function countByPerson(Person $person): int - { - $qb = $this->buildQueryByPerson($person)->select('COUNT(d)'); - - $this->addACL($qb, $person); - - return $qb->getQuery()->getSingleScalarResult(); - } - - public function findByPerson(Person $person, array $orderBy = [], int $limit = 20, int $offset = 0): array - { - $qb = $this->buildQueryByPerson($person)->select('d'); - - $this->addACL($qb, $person); - - foreach ($orderBy as $field => $order) { - $qb->addOrderBy('d.' . $field, $order); - } - - $qb->setFirstResult($offset)->setMaxResults($limit); - - return $qb->getQuery()->getResult(); - } - - private function addACL(QueryBuilder $qb, Person $person): void - { - $reachableScopes = []; - - foreach ($this->centerResolverManager->resolveCenters($person) as $center) { - $reachableScopes = [ - ...$reachableScopes, - ...$this->authorizationHelperForCurrentUser - ->getReachableScopes( - ActivityVoter::SEE, - $center - ) - ]; - } - - if ([] === $reachableScopes) { - $qb->andWhere("'FALSE' = 'TRUE'"); - - return; - } - - $qb->andWhere($qb->expr()->in('d.scope', ':scopes')) - ->setParameter('scopes', $reachableScopes); - } - private function addFetchQueryByPersonACL(FetchQuery $fetchQuery, Person $person): FetchQuery { $activityMetadata = $this->em->getClassMetadata(Activity::class); diff --git a/src/Bundle/ChillActivityBundle/Repository/ActivityDocumentACLAwareRepositoryInterface.php b/src/Bundle/ChillActivityBundle/Repository/ActivityDocumentACLAwareRepositoryInterface.php new file mode 100644 index 000000000..eb9e82cbe --- /dev/null +++ b/src/Bundle/ChillActivityBundle/Repository/ActivityDocumentACLAwareRepositoryInterface.php @@ -0,0 +1,28 @@ +security->isGranted(ActivityVoter::SEE, $accompanyingPeriod); } + + public function isAllowedForPerson(Person $person): bool + { + return $this->security->isGranted(AccompanyingPeriodVoter::SEE, $person); + } + + public function buildFetchQueryForPerson(Person $person, ?DateTimeImmutable $startDate = null, ?DateTimeImmutable $endDate = null, ?string $content = null, ?string $origin = null): FetchQueryInterface + { + return $this->activityDocumentACLAwareRepository + ->buildFetchQueryActivityDocumentLinkedToAccompanyingPeriodFromPersonContext($person, $startDate, $endDate, $content); + } } diff --git a/src/Bundle/ChillActivityBundle/Service/GenericDoc/Providers/PersonActivityGenericDocProvider.php b/src/Bundle/ChillActivityBundle/Service/GenericDoc/Providers/PersonActivityGenericDocProvider.php index d00a23e79..b1bd1d712 100644 --- a/src/Bundle/ChillActivityBundle/Service/GenericDoc/Providers/PersonActivityGenericDocProvider.php +++ b/src/Bundle/ChillActivityBundle/Service/GenericDoc/Providers/PersonActivityGenericDocProvider.php @@ -11,7 +11,8 @@ declare(strict_types=1); namespace Chill\ActivityBundle\Service\GenericDoc\Providers; -use Chill\ActivityBundle\Repository\PersonActivityDocumentACLAwareRepository; +use Chill\ActivityBundle\Repository\ActivityDocumentACLAwareRepository; +use Chill\ActivityBundle\Repository\ActivityDocumentACLAwareRepositoryInterface; use Chill\ActivityBundle\Security\Authorization\ActivityVoter; use Chill\DocStoreBundle\GenericDoc\FetchQueryInterface; use Chill\DocStoreBundle\GenericDoc\GenericDocForPersonProviderInterface; @@ -21,24 +22,20 @@ use DateTimeImmutable; use Doctrine\ORM\EntityManagerInterface; use Symfony\Component\Security\Core\Security; -final class PersonActivityGenericDocProvider implements GenericDocForPersonProviderInterface +final readonly class PersonActivityGenericDocProvider implements GenericDocForPersonProviderInterface { public const KEY = 'person_activity_document'; - private Security $security; - - private PersonActivityDocumentACLAwareRepository $personActivityDocumentACLAwareRepository; - - public function __construct(Security $security, PersonActivityDocumentACLAwareRepository $personActivityDocumentACLAwareRepository -) + public function __construct( + private Security $security, + private ActivityDocumentACLAwareRepositoryInterface $personActivityDocumentACLAwareRepository, + ) { - $this->security = $security; - $this->personActivityDocumentACLAwareRepository = $personActivityDocumentACLAwareRepository; } public function buildFetchQueryForPerson(Person $person, ?DateTimeImmutable $startDate = null, ?DateTimeImmutable $endDate = null, ?string $content = null, ?string $origin = null): FetchQueryInterface { - return $this->personActivityDocumentACLAwareRepository->buildFetchQueryForPerson( + return $this->personActivityDocumentACLAwareRepository->buildFetchQueryActivityDocumentLinkedToPersonFromPersonContext( $person, $startDate, $endDate, diff --git a/src/Bundle/ChillActivityBundle/Tests/Repository/ActivityDocumentACLAwareRepositoryTest.php b/src/Bundle/ChillActivityBundle/Tests/Repository/ActivityDocumentACLAwareRepositoryTest.php new file mode 100644 index 000000000..7390963fc --- /dev/null +++ b/src/Bundle/ChillActivityBundle/Tests/Repository/ActivityDocumentACLAwareRepositoryTest.php @@ -0,0 +1,113 @@ +entityManager = self::$container->get(EntityManagerInterface::class); + $this->centerResolverManager = self::$container->get(CenterResolverManagerInterface::class); + $this->authorizationHelperForCurrentUser = self::$container->get(AuthorizationHelperForCurrentUserInterface::class); + $this->security = self::$container->get(Security::class); + } + + /** + * @dataProvider provideDataForPerson + */ + public function testBuildFetchQueryActivityDocumentLinkedToPersonFromPersonContext(Person $person, array $reachableScopes, bool $_unused, ?\DateTimeImmutable $startDate, ?\DateTimeImmutable $endDate, ?string $content): void + { + $authorizationHelper = $this->prophesize(AuthorizationHelperForCurrentUserInterface::class); + $authorizationHelper->getReachableScopes(ActivityVoter::SEE, Argument::any()) + ->willReturn($reachableScopes); + + $repository = new ActivityDocumentACLAwareRepository( + $this->entityManager, + $this->centerResolverManager, + $authorizationHelper->reveal(), + $this->security + ); + + $query = $repository->buildFetchQueryActivityDocumentLinkedToPersonFromPersonContext($person, $startDate, $endDate, $content); + ['sql' => $sql, 'params' => $params, 'types' => $types] = (new FetchQueryToSqlBuilder())->toSql($query); + + $nb = $this->entityManager->getConnection()->fetchOne("SELECT COUNT(*) FROM ({$sql}) sq", $params, $types); + + self::assertIsInt($nb); + } + + /** + * @dataProvider provideDataForPerson + */ + public function testBuildFetchQueryActivityDocumentLinkedToAccompanyingPeriodFromPersonContext(Person $person, array $_unused, bool $canSeePeriod, ?\DateTimeImmutable $startDate, ?\DateTimeImmutable $endDate, ?string $content): void + { + $security = $this->prophesize(Security::class); + $security->isGranted(ActivityVoter::SEE, Argument::type(AccompanyingPeriod::class)) + ->willReturn($canSeePeriod); + + $repository = new ActivityDocumentACLAwareRepository( + $this->entityManager, + $this->centerResolverManager, + $this->authorizationHelperForCurrentUser, + $security->reveal() + ); + + $query = $repository->buildFetchQueryActivityDocumentLinkedToAccompanyingPeriodFromPersonContext($person, $startDate, $endDate, $content); + + ['sql' => $sql, 'params' => $params, 'types' => $types] = (new FetchQueryToSqlBuilder())->toSql($query); + + $nb = $this->entityManager->getConnection()->fetchOne("SELECT COUNT(*) FROM ({$sql}) sq", $params, $types); + + self::assertIsInt($nb); + } + + public function provideDataForPerson(): iterable + { + $this->setUp(); + + if (null === $person = $this->entityManager->createQuery("SELECT p FROM " . Person::class . " p WHERE SIZE(p.accompanyingPeriodParticipations) > 0 ") + ->setMaxResults(1) + ->getSingleResult()) { + throw new \RuntimeException("no person in dtabase"); + } + + if ([] === $scopes = $this->entityManager->createQuery("SELECT s FROM " . Scope::class . " s ")->setMaxResults(5)->getResult()) { + throw new \RuntimeException("no scopes in database"); + } + + yield [$person, [], true, null, null, null]; + yield [$person, $scopes, true, null, null, null]; + yield [$person, $scopes, true, new \DateTimeImmutable("1 month ago"), null, null]; + yield [$person, $scopes, true, new \DateTimeImmutable("1 month ago"), new \DateTimeImmutable("1 week ago"), null]; + yield [$person, $scopes, true, new \DateTimeImmutable("1 month ago"), new \DateTimeImmutable("1 week ago"), "content"]; + yield [$person, $scopes, true, null, new \DateTimeImmutable("1 week ago"), "content"]; + yield [$person, [], true, new \DateTimeImmutable("1 month ago"), new \DateTimeImmutable("1 week ago"), "content"]; + } + +} From 1d7279c022041a9d13a520f849a640325e1d61bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Mon, 12 Jun 2023 18:03:39 +0200 Subject: [PATCH 163/321] release v2.1.0 --- .changes/unreleased/DX-20230607-130344.yaml | 6 ------ .changes/unreleased/Fixed-20230606-143955.yaml | 6 ------ .../unreleased/Security-20230607-174702.yaml | 7 ------- .changes/v2.1.0.md | 17 +++++++++++++++++ CHANGELOG.md | 18 ++++++++++++++++++ 5 files changed, 35 insertions(+), 19 deletions(-) delete mode 100644 .changes/unreleased/DX-20230607-130344.yaml delete mode 100644 .changes/unreleased/Fixed-20230606-143955.yaml delete mode 100644 .changes/unreleased/Security-20230607-174702.yaml create mode 100644 .changes/v2.1.0.md diff --git a/.changes/unreleased/DX-20230607-130344.yaml b/.changes/unreleased/DX-20230607-130344.yaml deleted file mode 100644 index c7774c395..000000000 --- a/.changes/unreleased/DX-20230607-130344.yaml +++ /dev/null @@ -1,6 +0,0 @@ -kind: DX -body: Add methods to RegroupmentRepository and fullfill Center / Regroupment Doctrine - mapping -time: 2023-06-07T13:03:44.177864269+02:00 -custom: - Issue: "" diff --git a/.changes/unreleased/Fixed-20230606-143955.yaml b/.changes/unreleased/Fixed-20230606-143955.yaml deleted file mode 100644 index a7ab6b6a1..000000000 --- a/.changes/unreleased/Fixed-20230606-143955.yaml +++ /dev/null @@ -1,6 +0,0 @@ -kind: Fixed -body: 'List of "my accompanying periods": separate the active and closed periods in - two different lists, and show the inactive_long and inactive_short periods' -time: 2023-06-06T14:39:55.68417576+02:00 -custom: - Issue: "111" diff --git a/.changes/unreleased/Security-20230607-174702.yaml b/.changes/unreleased/Security-20230607-174702.yaml deleted file mode 100644 index ecdc1d191..000000000 --- a/.changes/unreleased/Security-20230607-174702.yaml +++ /dev/null @@ -1,7 +0,0 @@ -kind: Security -body: Rights are checked for display of 'accompanying period' tab in household menu. - Rights are also checked for creation of 'accompanying period' from within household - context -time: 2023-06-07T17:47:02.488819553+02:00 -custom: - Issue: "105" diff --git a/.changes/v2.1.0.md b/.changes/v2.1.0.md new file mode 100644 index 000000000..ade83aee0 --- /dev/null +++ b/.changes/v2.1.0.md @@ -0,0 +1,17 @@ +## v2.1.0 - 2023-06-12 + +### Feature + +* [docgen] allow to pick a third party when generating a document in context Activity, AccompanyingPeriod + +### Fixed + +* ([#111](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/111)) List of "my accompanying periods": separate the active and closed periods in two different lists, and show the inactive_long and inactive_short periods + +### Security + +* ([#105](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/105)) Rights are checked for display of 'accompanying period' tab in household menu. Rights are also checked for creation of 'accompanying period' from within household context + +### DX + +* Add methods to RegroupmentRepository and fullfill Center / Regroupment Doctrine mapping diff --git a/CHANGELOG.md b/CHANGELOG.md index 5475b20b8..f10f12f9b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,24 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), and is generated by [Changie](https://github.com/miniscruff/changie). +## v2.1.0 - 2023-06-12 + +### Feature + +* [docgen] allow to pick a third party when generating a document in context Activity, AccompanyingPeriod + +### Fixed + +* ([#111](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/111)) List of "my accompanying periods": separate the active and closed periods in two different lists, and show the inactive_long and inactive_short periods + +### Security + +* ([#105](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/105)) Rights are checked for display of 'accompanying period' tab in household menu. Rights are also checked for creation of 'accompanying period' from within household context + +### DX + +* Add methods to RegroupmentRepository and fullfill Center / Regroupment Doctrine mapping + ## 2.0.0 * this is a release to relaunch our proceess of release with semantic versioning From 4456fb3749a78544451f6561605dd6db5a3b26c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 13 Jun 2023 11:01:40 +0200 Subject: [PATCH 164/321] Fixing generic doc providers from calendar + fix cs --- .../ActivityDocumentACLAwareRepository.php | 4 +- ...ityDocumentACLAwareRepositoryInterface.php | 9 ++ ...anyingPeriodActivityGenericDocProvider.php | 2 +- .../PersonActivityGenericDocProvider.php | 3 +- ...anyingPeriodActivityGenericDocRenderer.php | 1 - ...ActivityDocumentACLAwareRepositoryTest.php | 13 ++ ...anyingPeriodCalendarGenericDocProvider.php | 113 +++++++++++++-- .../PersonCalendarGenericDocProvider.php | 51 +++---- .../AccompanyingCourseDocumentProvider.php | 54 +++++++ ...ngPeriodCalendarGenericDocProviderTest.php | 134 ++++++++++++++++++ .../PersonCalendarGenericDocProviderTest.php | 70 +++++++++ 11 files changed, 401 insertions(+), 53 deletions(-) create mode 100644 src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/AccompanyingCourseDocumentProvider.php create mode 100644 src/Bundle/ChillPersonBundle/Tests/Service/GenericDoc/Providers/AccompanyingPeriodCalendarGenericDocProviderTest.php create mode 100644 src/Bundle/ChillPersonBundle/Tests/Service/GenericDoc/Providers/PersonCalendarGenericDocProviderTest.php diff --git a/src/Bundle/ChillActivityBundle/Repository/ActivityDocumentACLAwareRepository.php b/src/Bundle/ChillActivityBundle/Repository/ActivityDocumentACLAwareRepository.php index f3f61ad3d..180d7fc4a 100644 --- a/src/Bundle/ChillActivityBundle/Repository/ActivityDocumentACLAwareRepository.php +++ b/src/Bundle/ChillActivityBundle/Repository/ActivityDocumentACLAwareRepository.php @@ -40,8 +40,8 @@ final readonly class ActivityDocumentACLAwareRepository implements ActivityDocum private EntityManagerInterface $em, private CenterResolverManagerInterface $centerResolverManager, private AuthorizationHelperForCurrentUserInterface $authorizationHelperForCurrentUser, - private Security $security) - { + private Security $security + ) { } public function buildFetchQueryActivityDocumentLinkedToPersonFromPersonContext(Person $person, ?DateTimeImmutable $startDate = null, ?DateTimeImmutable $endDate = null, ?string $content = null): FetchQueryInterface diff --git a/src/Bundle/ChillActivityBundle/Repository/ActivityDocumentACLAwareRepositoryInterface.php b/src/Bundle/ChillActivityBundle/Repository/ActivityDocumentACLAwareRepositoryInterface.php index eb9e82cbe..9f4a9c0f8 100644 --- a/src/Bundle/ChillActivityBundle/Repository/ActivityDocumentACLAwareRepositoryInterface.php +++ b/src/Bundle/ChillActivityBundle/Repository/ActivityDocumentACLAwareRepositoryInterface.php @@ -1,5 +1,14 @@ getSchemaName().'.'.$classMetadata->getTableName().' AS cd' ); $query->addJoinClause( - sprintf('JOIN %s doc_store ON doc_store.%s = cd.%s', - $storedObjectMetadata->getSchemaName().'.'.$storedObjectMetadata->getTableName(), - $storedObjectMetadata->getColumnName('id'), - $classMetadata->getSingleAssociationJoinColumnName('storedObject') - )); + sprintf( + 'JOIN %s doc_store ON doc_store.%s = cd.%s', + $storedObjectMetadata->getSchemaName().'.'.$storedObjectMetadata->getTableName(), + $storedObjectMetadata->getColumnName('id'), + $classMetadata->getSingleAssociationJoinColumnName('storedObject') + ) + ); $query->addJoinClause( - sprintf('JOIN %s calendar ON calendar.%s = cd.%s', + sprintf( + 'JOIN %s calendar ON calendar.%s = cd.%s', $calendarMetadata->getSchemaName().'.'.$calendarMetadata->getTableName(), $calendarMetadata->getColumnName('id'), $classMetadata->getSingleAssociationJoinColumnName('calendar') @@ -65,12 +76,91 @@ final class AccompanyingPeriodCalendarGenericDocProvider implements GenericDocFo ); $query->addWhereClause( - sprintf('calendar.%s = ?', - $calendarMetadata->getAssociationMapping('accompanyingPeriod')['joinColumns'][0]['name']), + sprintf( + 'calendar.%s = ?', + $calendarMetadata->getAssociationMapping('accompanyingPeriod')['joinColumns'][0]['name'] + ), [$accompanyingPeriod->getId()], [Types::INTEGER] ); + return $query; + } + + public function isAllowedForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod): bool + { + return $this->security->isGranted(CalendarVoter::SEE, $accompanyingPeriod); + } + + public function buildFetchQueryForPerson(Person $person, ?DateTimeImmutable $startDate = null, ?DateTimeImmutable $endDate = null, ?string $content = null, ?string $origin = null): FetchQueryInterface + { + $classMetadata = $this->em->getClassMetadata(CalendarDoc::class); + $storedObjectMetadata = $this->em->getClassMetadata(StoredObject::class); + $calendarMetadata = $this->em->getClassMetadata(Calendar::class); + + $query = new FetchQuery( + self::KEY, + sprintf("jsonb_build_object('id', cd.%s)", $classMetadata->getColumnName('id')), + 'cd.'.$storedObjectMetadata->getColumnName('createdAt'), + $classMetadata->getSchemaName().'.'.$classMetadata->getTableName().' AS cd' + ); + $query->addJoinClause( + sprintf( + 'JOIN %s doc_store ON doc_store.%s = cd.%s', + $storedObjectMetadata->getSchemaName().'.'.$storedObjectMetadata->getTableName(), + $storedObjectMetadata->getColumnName('id'), + $classMetadata->getSingleAssociationJoinColumnName('storedObject') + ) + ); + + $query->addJoinClause( + sprintf( + 'JOIN %s calendar ON calendar.%s = cd.%s', + $calendarMetadata->getSchemaName().'.'.$calendarMetadata->getTableName(), + $calendarMetadata->getColumnName('id'), + $classMetadata->getSingleAssociationJoinColumnName('calendar') + ) + ); + + // get the documents associated with accompanying periods in which person participates + $or = []; + $orParams = []; + $orTypes = []; + foreach ($person->getAccompanyingPeriodParticipations() as $participation) { + if (!$this->security->isGranted(CalendarVoter::SEE, $participation->getAccompanyingPeriod())) { + continue; + } + + $or[] = sprintf( + '(calendar.%s = ? AND cd.%s BETWEEN ?::date AND COALESCE(?::date, \'infinity\'::date))', + $calendarMetadata->getSingleAssociationJoinColumnName('accompanyingPeriod'), + $storedObjectMetadata->getColumnName('createdAt') + ); + $orParams = [...$orParams, $participation->getAccompanyingPeriod()->getId(), + DateTimeImmutable::createFromInterface($participation->getStartDate()), + null === $participation->getEndDate() ? null : DateTimeImmutable::createFromInterface($participation->getEndDate())]; + $orTypes = [...$orTypes, Types::INTEGER, Types::DATE_IMMUTABLE, Types::DATE_IMMUTABLE]; + } + + if ([] === $or) { + $query->addWhereClause('TRUE = FALSE'); + + return $query; + } + return $this->addWhereClausesToQuery($query, $startDate, $endDate, $content); + } + + public function isAllowedForPerson(Person $person): bool + { + // check that the person is allowed to see an accompanying period. If yes, the + // ACL on each accompanying period will be checked when the query is build + return $this->security->isGranted(AccompanyingPeriodVoter::SEE, $person); + } + + private function addWhereClausesToQuery(FetchQuery $query, ?DateTimeImmutable $startDate, ?DateTimeImmutable $endDate, ?string $content): FetchQuery + { + $storedObjectMetadata = $this->em->getClassMetadata(StoredObject::class); + if (null !== $startDate) { $query->addWhereClause( sprintf('doc_store.%s >= ?', $storedObjectMetadata->getColumnName('createdAt')), @@ -98,10 +188,5 @@ final class AccompanyingPeriodCalendarGenericDocProvider implements GenericDocFo return $query; } - public function isAllowedForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod): bool - { - return $this->security->isGranted(CalendarVoter::SEE, $accompanyingPeriod); - } - } diff --git a/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Providers/PersonCalendarGenericDocProvider.php b/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Providers/PersonCalendarGenericDocProvider.php index 640f0d197..f5d4b3cbb 100644 --- a/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Providers/PersonCalendarGenericDocProvider.php +++ b/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Providers/PersonCalendarGenericDocProvider.php @@ -24,9 +24,15 @@ use DateTimeImmutable; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Mapping\MappingException; +use Service\GenericDoc\Providers\PersonCalendarGenericDocProviderTest; use Symfony\Component\Security\Core\Security; -final class PersonCalendarGenericDocProvider implements GenericDocForPersonProviderInterface +/** + * Provide calendar documents for calendar associated to persons + * + * @see PersonCalendarGenericDocProviderTest + */ +final readonly class PersonCalendarGenericDocProvider implements GenericDocForPersonProviderInterface { public const KEY = 'person_calendar_document'; @@ -36,7 +42,6 @@ final class PersonCalendarGenericDocProvider implements GenericDocForPersonProvi ) { } - private function addWhereClausesToQuery(FetchQuery $query, ?\DateTimeImmutable $startDate = null, ?\DateTimeImmutable $endDate = null, ?string $content = null): FetchQuery { $storedObjectMetadata = $this->em->getClassMetadata(StoredObject::class); @@ -84,50 +89,30 @@ final class PersonCalendarGenericDocProvider implements GenericDocForPersonProvi $classMetadata->getSchemaName().'.'.$classMetadata->getTableName().' AS cd' ); $query->addJoinClause( - sprintf('JOIN %s doc_store ON doc_store.%s = cd.%s', + sprintf( + 'JOIN %s doc_store ON doc_store.%s = cd.%s', $storedObjectMetadata->getSchemaName().'.'.$storedObjectMetadata->getTableName(), $storedObjectMetadata->getColumnName('id'), $classMetadata->getSingleAssociationJoinColumnName('storedObject') - )); + ) + ); $query->addJoinClause( - sprintf('JOIN %s calendar ON calendar.%s = cd.%s', + sprintf( + 'JOIN %s calendar ON calendar.%s = cd.%s', $calendarMetadata->getSchemaName().'.'.$calendarMetadata->getTableName(), $calendarMetadata->getColumnName('id'), $classMetadata->getSingleAssociationJoinColumnName('calendar') ) ); - // get the documents associated with accompanying periods in which person participates - $or = []; - $orParams = []; - $orTypes = []; - foreach ($person->getAccompanyingPeriodParticipations() as $participation) { - if (!$this->security->isGranted(CalendarVoter::SEE, $participation->getAccompanyingPeriod())) { - continue; - } - - $or[] = sprintf( - '(calendar.%s = ? AND cd.%s BETWEEN ?::date AND COALESCE(?::date, \'infinity\'::date))', - $calendarMetadata->getSingleAssociationJoinColumnName('accompanyingPeriod'), - $storedObjectMetadata->getColumnName('createdAt') - ); - $orParams = [...$orParams, $participation->getAccompanyingPeriod()->getId(), - DateTimeImmutable::createFromInterface($participation->getStartDate()), - null === $participation->getEndDate() ? null : DateTimeImmutable::createFromInterface($participation->getEndDate())]; - $orTypes = [...$orTypes, Types::INTEGER, Types::DATE_IMMUTABLE, Types::DATE_IMMUTABLE]; - } - - if ([] === $or) { - $query->addWhereClause('TRUE = FALSE'); - - return $query; - } - -// $query->addWhereClause(sprintf('(%s)', implode(' OR ', $or)), $orParams, $orTypes); + $query->addWhereClause( + sprintf('calendar.%s = ?', $calendarMetadata->getSingleAssociationJoinColumnName('person')), + [$person->getId()], + [Types::INTEGER] + ); return $this->addWhereClausesToQuery($query, $startDate, $endDate, $content); - } /** diff --git a/src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/AccompanyingCourseDocumentProvider.php b/src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/AccompanyingCourseDocumentProvider.php new file mode 100644 index 000000000..163d17458 --- /dev/null +++ b/src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/AccompanyingCourseDocumentProvider.php @@ -0,0 +1,54 @@ +entityManager->getClassMetadata(AccompanyingCourseDocument::class); + + $query = new FetchQuery( + 'accompanying_course_document', + sprintf('jsonb_build_object(\'id\', %s)', $classMetadata->getIdentifierColumnNames()[0]), + sprintf($classMetadata->getColumnName('date')), + $classMetadata->getSchemaName() . '.' . $classMetadata->getTableName() + ); + + $query->addWhereClause( + sprintf('%s = ?', $classMetadata->getSingleAssociationJoinColumnName('course')), + [$accompanyingPeriod->getId()] + ); + + return $query; + } + + public function isAllowedForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod): bool + { + return $this->security->isGranted(AccompanyingCourseDocumentVoter::SEE, $accompanyingPeriod); + } +} diff --git a/src/Bundle/ChillPersonBundle/Tests/Service/GenericDoc/Providers/AccompanyingPeriodCalendarGenericDocProviderTest.php b/src/Bundle/ChillPersonBundle/Tests/Service/GenericDoc/Providers/AccompanyingPeriodCalendarGenericDocProviderTest.php new file mode 100644 index 000000000..8aff23673 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Service/GenericDoc/Providers/AccompanyingPeriodCalendarGenericDocProviderTest.php @@ -0,0 +1,134 @@ +security = self::$container->get(Security::class); + $this->entityManager = self::$container->get(EntityManagerInterface::class); + } + + /** + * @dataProvider provideDataForAccompanyingPeriod + */ + public function testBuildFetchQueryForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod, ?\DateTimeImmutable $startDate, ?\DateTimeImmutable $endDate, ?string $content): void + { + $provider = new AccompanyingPeriodCalendarGenericDocProvider($this->security, $this->entityManager); + + $query = $provider->buildFetchQueryForAccompanyingPeriod($accompanyingPeriod, $startDate, $endDate, $content); + + ['sql' => $sql, 'params' => $params, 'types' => $types] = (new FetchQueryToSqlBuilder())->toSql($query); + + $nb = $this->entityManager->getConnection()->fetchOne("SELECT COUNT(*) FROM ({$sql}) AS sq", $params, $types); + + self::assertIsInt($nb); + } + + /** + * @dataProvider provideDataForPerson + */ + public function testBuildFetchQueryForPerson(Person $person, ?\DateTimeImmutable $startDate, ?\DateTimeImmutable $endDate, ?string $content): void + { + $security = $this->prophesize(Security::class); + $security->isGranted(CalendarVoter::SEE, Argument::any())->willReturn(true); + + $provider = new AccompanyingPeriodCalendarGenericDocProvider($security->reveal(), $this->entityManager); + + $query = $provider->buildFetchQueryForPerson($person, $startDate, $endDate, $content); + + ['sql' => $sql, 'params' => $params, 'types' => $types] = (new FetchQueryToSqlBuilder())->toSql($query); + + $nb = $this->entityManager->getConnection()->fetchOne("SELECT COUNT(*) FROM ({$sql}) AS sq", $params, $types); + + self::assertIsInt($nb); + self::assertStringNotContainsStringIgnoringCase('FALSE = TRUE', $sql); + self::assertStringNotContainsStringIgnoringCase('TRUE = FALSE', $sql); + } + + /** + * @dataProvider provideDataForPerson + */ + public function testBuildFetchQueryForPersonWithoutAnyRight(Person $person, ?\DateTimeImmutable $startDate, ?\DateTimeImmutable $endDate, ?string $content): void + { + $security = $this->prophesize(Security::class); + $security->isGranted(CalendarVoter::SEE, Argument::any())->willReturn(false); + + $provider = new AccompanyingPeriodCalendarGenericDocProvider($security->reveal(), $this->entityManager); + + $query = $provider->buildFetchQueryForPerson($person, $startDate, $endDate, $content); + + ['sql' => $sql, 'params' => $params, 'types' => $types] = (new FetchQueryToSqlBuilder())->toSql($query); + + $nb = $this->entityManager->getConnection()->fetchOne("SELECT COUNT(*) FROM ({$sql}) AS sq", $params, $types); + + self::assertIsInt($nb); + self::assertStringContainsStringIgnoringCase('TRUE = FALSE', $sql); + } + + public function provideDataForPerson(): iterable + { + $this->setUp(); + + if (null === $person = $this->entityManager->createQuery("SELECT p FROM " . Person::class . " p WHERE SIZE(p.accompanyingPeriodParticipations) > 0") + ->setMaxResults(1)->getSingleResult()) { + throw new \RuntimeException("There is no person"); + } + + yield [$person, null, null, null]; + yield [$person, new \DateTimeImmutable("1 year ago"), null, null]; + yield [$person, new \DateTimeImmutable("1 year ago"), new \DateTimeImmutable("6 month ago"), null]; + yield [$person, new \DateTimeImmutable("1 year ago"), new \DateTimeImmutable("6 month ago"), "text"]; + yield [$person, null, null, "text"]; + yield [$person, null, new \DateTimeImmutable("6 month ago"), null]; + } + + public function provideDataForAccompanyingPeriod(): iterable + { + $this->setUp(); + + if (null === $period = $this->entityManager->createQuery("SELECT p FROM " . AccompanyingPeriod::class . " p ") + ->setMaxResults(1)->getSingleResult()) { + throw new \RuntimeException("There is no accompanying period"); + } + + yield [$period, null, null, null]; + yield [$period, new \DateTimeImmutable("1 year ago"), null, null]; + yield [$period, new \DateTimeImmutable("1 year ago"), new \DateTimeImmutable("6 month ago"), null]; + yield [$period, new \DateTimeImmutable("1 year ago"), new \DateTimeImmutable("6 month ago"), "text"]; + yield [$period, null, null, "text"]; + yield [$period, null, new \DateTimeImmutable("6 month ago"), null]; + } +} diff --git a/src/Bundle/ChillPersonBundle/Tests/Service/GenericDoc/Providers/PersonCalendarGenericDocProviderTest.php b/src/Bundle/ChillPersonBundle/Tests/Service/GenericDoc/Providers/PersonCalendarGenericDocProviderTest.php new file mode 100644 index 000000000..dbad052ca --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Service/GenericDoc/Providers/PersonCalendarGenericDocProviderTest.php @@ -0,0 +1,70 @@ +security = self::$container->get(Security::class); + $this->entityManager = self::$container->get(EntityManagerInterface::class); + } + + /** + * @dataProvider provideDataForPerson + */ + public function testBuildFetchQueryForPerson(Person $person, ?\DateTimeImmutable $startDate, ?\DateTimeImmutable $endDate, ?string $content): void + { + $provider = new PersonCalendarGenericDocProvider($this->security, $this->entityManager); + + $query = $provider->buildFetchQueryForPerson($person, $startDate, $endDate, $content); + + ['sql' => $sql, 'params' => $params, 'types' => $types] = (new FetchQueryToSqlBuilder())->toSql($query); + + $nb = $this->entityManager->getConnection()->fetchOne("SELECT COUNT(*) FROM ({$sql}) AS sq", $params, $types); + + self::assertIsInt($nb); + } + + public function provideDataForPerson(): iterable + { + $this->setUp(); + + if (null === $person = $this->entityManager->createQuery("SELECT p FROM " . Person::class . " p ") + ->setMaxResults(1)->getSingleResult()) { + throw new \RuntimeException("There is no person"); + } + + yield [$person, null, null, null]; + yield [$person, new \DateTimeImmutable("1 year ago"), null, null]; + yield [$person, new \DateTimeImmutable("1 year ago"), new \DateTimeImmutable("6 month ago"), null]; + yield [$person, new \DateTimeImmutable("1 year ago"), new \DateTimeImmutable("6 month ago"), "text"]; + yield [$person, null, null, "text"]; + yield [$person, null, new \DateTimeImmutable("6 month ago"), null]; + } +} From 1f1ebb6adb0f4c3c823ed803dd745848bc9aad75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 13 Jun 2023 11:30:00 +0200 Subject: [PATCH 165/321] fix mismatch for key in different providers --- .../Repository/ActivityDocumentACLAwareRepository.php | 6 ++++-- .../AccompanyingCourseDocumentGenericDocRenderer.php | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Repository/ActivityDocumentACLAwareRepository.php b/src/Bundle/ChillActivityBundle/Repository/ActivityDocumentACLAwareRepository.php index 180d7fc4a..3ca9281af 100644 --- a/src/Bundle/ChillActivityBundle/Repository/ActivityDocumentACLAwareRepository.php +++ b/src/Bundle/ChillActivityBundle/Repository/ActivityDocumentACLAwareRepository.php @@ -13,6 +13,8 @@ namespace Chill\ActivityBundle\Repository; use Chill\ActivityBundle\Entity\Activity; use Chill\ActivityBundle\Security\Authorization\ActivityVoter; +use Chill\ActivityBundle\Service\GenericDoc\Providers\AccompanyingPeriodActivityGenericDocProvider; +use Chill\ActivityBundle\Service\GenericDoc\Providers\PersonActivityGenericDocProvider; use Chill\DocStoreBundle\Entity\PersonDocument; use Chill\DocStoreBundle\Entity\StoredObject; use Chill\DocStoreBundle\GenericDoc\FetchQuery; @@ -57,7 +59,7 @@ final readonly class ActivityDocumentACLAwareRepository implements ActivityDocum $activityMetadata = $this->em->getClassMetadata(Activity::class); $query = new FetchQuery( - PersonDocumentGenericDocProvider::KEY, + PersonActivityGenericDocProvider::KEY, sprintf('jsonb_build_object(\'id\', stored_obj.%s, \'activity_id\', activity.%s)', $storedObjectMetadata->getSingleIdentifierColumnName(), $activityMetadata->getSingleIdentifierColumnName()), sprintf('stored_obj.%s', $storedObjectMetadata->getColumnName('createdAt')), sprintf('%s AS stored_obj', $storedObjectMetadata->getSchemaName().'.'.$storedObjectMetadata->getTableName()) @@ -86,7 +88,7 @@ final readonly class ActivityDocumentACLAwareRepository implements ActivityDocum $activityMetadata = $this->em->getClassMetadata(Activity::class); $query = new FetchQuery( - PersonDocumentGenericDocProvider::KEY, + AccompanyingPeriodActivityGenericDocProvider::KEY, sprintf('jsonb_build_object(\'id\', stored_obj.%s, \'activity_id\', activity.%s)', $storedObjectMetadata->getSingleIdentifierColumnName(), $activityMetadata->getSingleIdentifierColumnName()), sprintf('stored_obj.%s', $storedObjectMetadata->getColumnName('createdAt')), sprintf('%s AS stored_obj', $storedObjectMetadata->getSchemaName().'.'.$storedObjectMetadata->getTableName()) diff --git a/src/Bundle/ChillDocStoreBundle/GenericDoc/Renderer/AccompanyingCourseDocumentGenericDocRenderer.php b/src/Bundle/ChillDocStoreBundle/GenericDoc/Renderer/AccompanyingCourseDocumentGenericDocRenderer.php index 052153be8..d9c33373e 100644 --- a/src/Bundle/ChillDocStoreBundle/GenericDoc/Renderer/AccompanyingCourseDocumentGenericDocRenderer.php +++ b/src/Bundle/ChillDocStoreBundle/GenericDoc/Renderer/AccompanyingCourseDocumentGenericDocRenderer.php @@ -40,6 +40,7 @@ final readonly class AccompanyingCourseDocumentGenericDocRenderer implements Gen public function getTemplateData(GenericDocDTO $genericDocDTO, $options = []): array { + dump($genericDocDTO); if (AccompanyingCourseDocumentGenericDocProvider::KEY === $genericDocDTO->key) { return [ 'document' => $doc = $this->accompanyingCourseDocumentRepository->find($genericDocDTO->identifiers['id']), @@ -47,10 +48,9 @@ final readonly class AccompanyingCourseDocumentGenericDocRenderer implements Gen 'options' => $options, ]; } - // this is a person return [ - 'document' => $doc = $this->personDocumentRepository->find($genericDocDTO->identifiers['id']), + 'document' => $doc = dump($this->personDocumentRepository->find($genericDocDTO->identifiers['id'])), 'person' => $doc->getPerson(), 'options' => $options, ]; From 909d2dfb60de67059d1391409ba5a42c2bdd754d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 13 Jun 2023 15:00:16 +0200 Subject: [PATCH 166/321] layout for rendering list --- .../Resources/public/chill/chillactivity.scss | 24 +++++++++++ .../GenericDoc/activity_document.html.twig | 32 +++++++------- ...anyingPeriodActivityGenericDocRenderer.php | 4 +- .../translations/messages.fr.yml | 5 +++ .../Resources/public/chill/chill.js | 1 + .../Resources/public/chill/scss/badge.scss | 25 +++++++++++ .../Resources/public/chill/scss/calendar.scss | 2 +- .../GenericDoc/calendar_document.html.twig | 42 +++++++++++-------- ...anyingPeriodCalendarGenericDocRenderer.php | 3 +- .../chill.webpack.config.js | 2 + .../translations/messages.fr.yml | 4 +- .../GenericDoc/GenericDocDTO.php | 5 +++ ...anyingCourseDocumentGenericDocRenderer.php | 5 ++- .../Resources/views/List/list_item.html.twig | 10 ++++- .../translations/messages.fr.yml | 1 + .../chill/scss/accompanying_period_work.scss | 22 ++++++++++ .../GenericDoc/evaluation_document.html.twig | 23 +++++----- ...PeriodWorkEvaluationGenericDocRenderer.php | 4 +- 18 files changed, 162 insertions(+), 52 deletions(-) create mode 100644 src/Bundle/ChillCalendarBundle/Resources/public/chill/chill.js create mode 100644 src/Bundle/ChillCalendarBundle/Resources/public/chill/scss/badge.scss diff --git a/src/Bundle/ChillActivityBundle/Resources/public/chill/chillactivity.scss b/src/Bundle/ChillActivityBundle/Resources/public/chill/chillactivity.scss index d70bd28c3..13de8dfc0 100644 --- a/src/Bundle/ChillActivityBundle/Resources/public/chill/chillactivity.scss +++ b/src/Bundle/ChillActivityBundle/Resources/public/chill/chillactivity.scss @@ -1,5 +1,7 @@ // Access to Bootstrap variables and mixins @import '~ChillMainAssets/module/bootstrap/shared'; +@import '~ChillPersonAssets/chill/scss/mixins.scss'; +@import 'bootstrap/scss/_badge.scss'; //// ACTIVITY CREATION // first step: select type page @@ -96,3 +98,25 @@ li.document-list-item { justify-content: space-between; margin-bottom: 0.3rem; } + +.badge-activity-type { + display: inline-block; + background-color: #f3f3f3; + + .title_label { + @include chill_badge(#9acd32); + } + + .title_action { + padding: var(--bs-badge-padding-y) var(--bs-badge-padding-x); + margin-right: 1rem; + + font-size: var(--bs-badge-font-size); + font-weight: var(--bs-badge-font-weight); + line-height: 1; + color: var(--bs-badge-color); + text-align: center; + white-space: nowrap; + vertical-align: baseline; + } +} diff --git a/src/Bundle/ChillActivityBundle/Resources/views/GenericDoc/activity_document.html.twig b/src/Bundle/ChillActivityBundle/Resources/views/GenericDoc/activity_document.html.twig index 11aeeeca1..5b9547675 100644 --- a/src/Bundle/ChillActivityBundle/Resources/views/GenericDoc/activity_document.html.twig +++ b/src/Bundle/ChillActivityBundle/Resources/views/GenericDoc/activity_document.html.twig @@ -20,8 +20,25 @@ {% elseif document.isFailure %}
          {{ 'docgen.Doc generation failed'|trans }}
          {% endif %} + +
          + {% if activity.accompanyingPeriod is not null and context == 'person' %} + + {{ activity.accompanyingPeriod.id }} +   + {% endif %} +
          + + + {{ activity.type.name | localize_translatable_string }} + {% if activity.emergency %} + {{ 'Emergency'|trans|upper }} + {% endif %} + +
          +
          - {{ document.title }} + {{ document.title|chill_print_or_message("No title") }}
          {% if document.hasTemplate %}
          @@ -39,19 +56,6 @@
        -
        -
        -

        - - - {{ activity.type.name | localize_translatable_string }} - {% if activity.emergency %} - {{ 'Emergency'|trans|upper }} - {% endif %} - -

        -
        -
        diff --git a/src/Bundle/ChillActivityBundle/Service/GenericDoc/Renderers/AccompanyingPeriodActivityGenericDocRenderer.php b/src/Bundle/ChillActivityBundle/Service/GenericDoc/Renderers/AccompanyingPeriodActivityGenericDocRenderer.php index a07137206..c465dbca1 100644 --- a/src/Bundle/ChillActivityBundle/Service/GenericDoc/Renderers/AccompanyingPeriodActivityGenericDocRenderer.php +++ b/src/Bundle/ChillActivityBundle/Service/GenericDoc/Renderers/AccompanyingPeriodActivityGenericDocRenderer.php @@ -17,6 +17,7 @@ use Chill\ActivityBundle\Service\GenericDoc\Providers\PersonActivityGenericDocPr use Chill\DocStoreBundle\GenericDoc\GenericDocDTO; use Chill\DocStoreBundle\GenericDoc\Twig\GenericDocRendererInterface; use Chill\DocStoreBundle\Repository\StoredObjectRepository; +use Chill\PersonBundle\Entity\AccompanyingPeriod; final class AccompanyingPeriodActivityGenericDocRenderer implements GenericDocRendererInterface { @@ -44,7 +45,8 @@ final class AccompanyingPeriodActivityGenericDocRenderer implements GenericDocRe { return [ 'activity' => $this->activityRepository->find($genericDocDTO->identifiers['activity_id']), - 'document' => $this->objectRepository->find($genericDocDTO->identifiers['id']) + 'document' => $this->objectRepository->find($genericDocDTO->identifiers['id']), + 'context' => $genericDocDTO->getContext(), ]; } } diff --git a/src/Bundle/ChillActivityBundle/translations/messages.fr.yml b/src/Bundle/ChillActivityBundle/translations/messages.fr.yml index 042fccc69..abef160d3 100644 --- a/src/Bundle/ChillActivityBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillActivityBundle/translations/messages.fr.yml @@ -372,3 +372,8 @@ export: is sent: envoyé is received: reçu Group activity by sentreceived: Grouper les échanges par envoyé / reçu + +generic_doc: + filter: + keys: + accompanying_period_activity_document: Document des échanges des parcours diff --git a/src/Bundle/ChillCalendarBundle/Resources/public/chill/chill.js b/src/Bundle/ChillCalendarBundle/Resources/public/chill/chill.js new file mode 100644 index 000000000..56a8ce563 --- /dev/null +++ b/src/Bundle/ChillCalendarBundle/Resources/public/chill/chill.js @@ -0,0 +1 @@ +import './scss/badge.scss'; diff --git a/src/Bundle/ChillCalendarBundle/Resources/public/chill/scss/badge.scss b/src/Bundle/ChillCalendarBundle/Resources/public/chill/scss/badge.scss new file mode 100644 index 000000000..ffcda8f0f --- /dev/null +++ b/src/Bundle/ChillCalendarBundle/Resources/public/chill/scss/badge.scss @@ -0,0 +1,25 @@ +@import '~ChillPersonAssets/chill/scss/mixins.scss'; +@import '~ChillMainAssets/module/bootstrap/shared'; + +.badge-calendar { + display: inline-block; + background-color: #f3f3f3; + + .title_label { + @include chill_badge($chill-l-gray); + } + + .title_action { + padding: var(--bs-badge-padding-y) var(--bs-badge-padding-x); + margin-right: 1rem; + + font-size: var(--bs-badge-font-size); + font-weight: var(--bs-badge-font-weight); + line-height: 1; + color: var(--bs-badge-color); + text-align: center; + white-space: nowrap; + vertical-align: baseline; + } +} + diff --git a/src/Bundle/ChillCalendarBundle/Resources/public/chill/scss/calendar.scss b/src/Bundle/ChillCalendarBundle/Resources/public/chill/scss/calendar.scss index a2c0c4b89..ce54b0fa8 100644 --- a/src/Bundle/ChillCalendarBundle/Resources/public/chill/scss/calendar.scss +++ b/src/Bundle/ChillCalendarBundle/Resources/public/chill/scss/calendar.scss @@ -17,4 +17,4 @@ span.calendarRangeItems { text-decoration: none; padding: 3px; } -} \ No newline at end of file +} diff --git a/src/Bundle/ChillCalendarBundle/Resources/views/GenericDoc/calendar_document.html.twig b/src/Bundle/ChillCalendarBundle/Resources/views/GenericDoc/calendar_document.html.twig index 4cd369366..facf5be50 100644 --- a/src/Bundle/ChillCalendarBundle/Resources/views/GenericDoc/calendar_document.html.twig +++ b/src/Bundle/ChillCalendarBundle/Resources/views/GenericDoc/calendar_document.html.twig @@ -12,11 +12,31 @@ {% elseif document.storedObject.isFailure %}
        {{ 'docgen.Doc generation failed'|trans }}
        {% endif %} -
        - {{ document.storedObject.title }} -
        +
        - {{ 'chill_calendar.Document'|trans }} + {% if c.accompanyingPeriod is not null and context == 'person' %} + + {{ c.accompanyingPeriod.id }} +   + {% endif %} + + + + + {{ 'Calendar'|trans }} + {% if c.endDate.diff(c.startDate).days >= 1 %} + {{ c.startDate|format_datetime('short', 'short') }} + - {{ c.endDate|format_datetime('short', 'short') }} + {% else %} + {{ c.startDate|format_datetime('short', 'short') }} + - {{ c.endDate|format_datetime('none', 'short') }} + {% endif %} + + +
        + +
        + {{ document.storedObject.title|chill_print_or_message("No title") }}
        {% if document.storedObject.hasTemplate %}
        @@ -34,20 +54,6 @@
        -
        -
        -

        - {% if c.endDate.diff(c.startDate).days >= 1 %} - {{ c.startDate|format_datetime('short', 'short') }} - - {{ c.endDate|format_datetime('short', 'short') }} - {% else %} - {{ c.startDate|format_datetime('short', 'short') }} - - {{ c.endDate|format_datetime('none', 'short') }} - {% endif %} -

        -
        -
        -
        {{ mmm.createdBy(document) }} diff --git a/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Renderers/AccompanyingPeriodCalendarGenericDocRenderer.php b/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Renderers/AccompanyingPeriodCalendarGenericDocRenderer.php index d9636d99d..b15c091c6 100644 --- a/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Renderers/AccompanyingPeriodCalendarGenericDocRenderer.php +++ b/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Renderers/AccompanyingPeriodCalendarGenericDocRenderer.php @@ -39,7 +39,8 @@ final class AccompanyingPeriodCalendarGenericDocRenderer implements GenericDocRe public function getTemplateData(GenericDocDTO $genericDocDTO, $options = []): array { return [ - 'document' => $this->repository->find($genericDocDTO->identifiers['id']) + 'document' => $this->repository->find($genericDocDTO->identifiers['id']), + 'context' => $genericDocDTO->getContext(), ]; } } diff --git a/src/Bundle/ChillCalendarBundle/chill.webpack.config.js b/src/Bundle/ChillCalendarBundle/chill.webpack.config.js index e82210087..9d45a3142 100644 --- a/src/Bundle/ChillCalendarBundle/chill.webpack.config.js +++ b/src/Bundle/ChillCalendarBundle/chill.webpack.config.js @@ -1,6 +1,8 @@ // this file loads all assets from the Chill calendar bundle module.exports = function(encore, entries) { + entries.push(__dirname + '/Resources/public/chill/chill.js'); + encore.addAliases({ ChillCalendarAssets: __dirname + '/Resources/public' }); diff --git a/src/Bundle/ChillCalendarBundle/translations/messages.fr.yml b/src/Bundle/ChillCalendarBundle/translations/messages.fr.yml index 99aae1082..c56d7835f 100644 --- a/src/Bundle/ChillCalendarBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillCalendarBundle/translations/messages.fr.yml @@ -151,5 +151,5 @@ CHILL_CALENDAR_CALENDAR_SEE: Voir les rendez-vous generic_doc: filter: keys: - accompanying_period_calendar_document: Document des rendez-vous - person_calendar_document: Document des rendez-vous de la personne + accompanying_period_calendar_document: Document des rendez-vous des parcours + person_calendar_document: Document des rendez-vous de l'usager diff --git a/src/Bundle/ChillDocStoreBundle/GenericDoc/GenericDocDTO.php b/src/Bundle/ChillDocStoreBundle/GenericDoc/GenericDocDTO.php index 25a96750c..fe9bf7e4f 100644 --- a/src/Bundle/ChillDocStoreBundle/GenericDoc/GenericDocDTO.php +++ b/src/Bundle/ChillDocStoreBundle/GenericDoc/GenericDocDTO.php @@ -23,4 +23,9 @@ final readonly class GenericDocDTO public AccompanyingPeriod|Person $linked, ) { } + + public function getContext(): string + { + return $this->linked instanceof AccompanyingPeriod ? 'accompanying-period' : 'person'; + } } diff --git a/src/Bundle/ChillDocStoreBundle/GenericDoc/Renderer/AccompanyingCourseDocumentGenericDocRenderer.php b/src/Bundle/ChillDocStoreBundle/GenericDoc/Renderer/AccompanyingCourseDocumentGenericDocRenderer.php index d9c33373e..c32620030 100644 --- a/src/Bundle/ChillDocStoreBundle/GenericDoc/Renderer/AccompanyingCourseDocumentGenericDocRenderer.php +++ b/src/Bundle/ChillDocStoreBundle/GenericDoc/Renderer/AccompanyingCourseDocumentGenericDocRenderer.php @@ -40,19 +40,20 @@ final readonly class AccompanyingCourseDocumentGenericDocRenderer implements Gen public function getTemplateData(GenericDocDTO $genericDocDTO, $options = []): array { - dump($genericDocDTO); if (AccompanyingCourseDocumentGenericDocProvider::KEY === $genericDocDTO->key) { return [ 'document' => $doc = $this->accompanyingCourseDocumentRepository->find($genericDocDTO->identifiers['id']), 'accompanyingCourse' => $doc->getCourse(), 'options' => $options, + 'context' => $genericDocDTO->getContext(), ]; } // this is a person return [ - 'document' => $doc = dump($this->personDocumentRepository->find($genericDocDTO->identifiers['id'])), + 'document' => $doc = $this->personDocumentRepository->find($genericDocDTO->identifiers['id']), 'person' => $doc->getPerson(), 'options' => $options, + 'context' => $genericDocDTO->getContext(), ]; } } diff --git a/src/Bundle/ChillDocStoreBundle/Resources/views/List/list_item.html.twig b/src/Bundle/ChillDocStoreBundle/Resources/views/List/list_item.html.twig index 8dea4bbe7..9be38074d 100644 --- a/src/Bundle/ChillDocStoreBundle/Resources/views/List/list_item.html.twig +++ b/src/Bundle/ChillDocStoreBundle/Resources/views/List/list_item.html.twig @@ -10,8 +10,16 @@ {% elseif document.object.isFailure %}
        {{ 'docgen.Doc generation failed'|trans }}
        {% endif %} + + {% if context == 'person' and accompanyingCourse is defined %} +
        + + {{ accompanyingCourse.id }} +   +
        + {% endif %}
        - {{ document.title }} + {{ document.title|chill_print_or_message("No title") }}
        {% if document.object.type is not empty %}
        diff --git a/src/Bundle/ChillMainBundle/translations/messages.fr.yml b/src/Bundle/ChillMainBundle/translations/messages.fr.yml index 78de523c4..f8f231a7c 100644 --- a/src/Bundle/ChillMainBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillMainBundle/translations/messages.fr.yml @@ -42,6 +42,7 @@ by_user: "par " lifecycleUpdate: Evenements de création et mise à jour address_fields: Données liées à l'adresse Datas: Données +No title: Aucun titre inactive: inactif diff --git a/src/Bundle/ChillPersonBundle/Resources/public/chill/scss/accompanying_period_work.scss b/src/Bundle/ChillPersonBundle/Resources/public/chill/scss/accompanying_period_work.scss index a12f1554c..e82029a1f 100644 --- a/src/Bundle/ChillPersonBundle/Resources/public/chill/scss/accompanying_period_work.scss +++ b/src/Bundle/ChillPersonBundle/Resources/public/chill/scss/accompanying_period_work.scss @@ -1,3 +1,25 @@ +.badge-accompanying-work-type { + display: inline-block; + background-color: #f3f3f3; + + .title_label { + @include chill_badge(#e2793d); + } + + .title_action { + padding: var(--bs-badge-padding-y) var(--bs-badge-padding-x); + margin-right: 1rem; + + font-size: var(--bs-badge-font-size); + font-weight: var(--bs-badge-font-weight); + line-height: 1; + color: var(--bs-badge-color); + text-align: center; + white-space: nowrap; + vertical-align: baseline; + } +} + /// AccompanyingCourse Work Pages div.accompanying-course-work { diff --git a/src/Bundle/ChillPersonBundle/Resources/views/GenericDoc/evaluation_document.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/GenericDoc/evaluation_document.html.twig index 255139bb4..ae54d077b 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/GenericDoc/evaluation_document.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/GenericDoc/evaluation_document.html.twig @@ -12,8 +12,19 @@ {% elseif document.storedObject.isFailure %}
        {{ 'docgen.Doc generation failed'|trans }}
        {% endif %} +
        + {% if context == 'person' %} + + {{ w.accompanyingPeriod.id }} +   + {% endif %} +
        + + {{ w.socialAction|chill_entity_render_string }} > {{ document.accompanyingPeriodWorkEvaluation.evaluation.title|localize_translatable_string }} +
        +
        - {{ document.title }} + {{ document.title|chill_print_or_message("No title") }}
        {% if document.storedObject.type is not empty %}
        @@ -36,16 +47,6 @@
        -
        -
        -

        - - {{ w.socialAction|chill_entity_render_string }} > {{ document.accompanyingPeriodWorkEvaluation.evaluation.title|localize_translatable_string }} - -

        -
        -
        -
        {{ mmm.createdBy(document) }} diff --git a/src/Bundle/ChillPersonBundle/Service/GenericDoc/Renderer/AccompanyingPeriodWorkEvaluationGenericDocRenderer.php b/src/Bundle/ChillPersonBundle/Service/GenericDoc/Renderer/AccompanyingPeriodWorkEvaluationGenericDocRenderer.php index 5da8297fb..9810fe7a1 100644 --- a/src/Bundle/ChillPersonBundle/Service/GenericDoc/Renderer/AccompanyingPeriodWorkEvaluationGenericDocRenderer.php +++ b/src/Bundle/ChillPersonBundle/Service/GenericDoc/Renderer/AccompanyingPeriodWorkEvaluationGenericDocRenderer.php @@ -13,6 +13,7 @@ namespace Chill\PersonBundle\Service\GenericDoc\Renderer; use Chill\DocStoreBundle\GenericDoc\GenericDocDTO; use Chill\DocStoreBundle\GenericDoc\Twig\GenericDocRendererInterface; +use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Repository\AccompanyingPeriod\AccompanyingPeriodWorkEvaluationDocumentRepository; use Chill\PersonBundle\Service\GenericDoc\Providers\AccompanyingPeriodWorkEvaluationGenericDocProvider; @@ -36,7 +37,8 @@ final readonly class AccompanyingPeriodWorkEvaluationGenericDocRenderer implemen public function getTemplateData(GenericDocDTO $genericDocDTO, $options = []): array { return [ - 'document' => $this->accompanyingPeriodWorkEvaluationDocumentRepository->find($genericDocDTO->identifiers['id']) + 'document' => $this->accompanyingPeriodWorkEvaluationDocumentRepository->find($genericDocDTO->identifiers['id']), + 'context' => $genericDocDTO->getContext(), ]; } } From 29140d9374f534f7d21f29000948f0d36d5610c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 13 Jun 2023 15:16:03 +0200 Subject: [PATCH 167/321] add changelog entry --- .changes/unreleased/Feature-20230613-151546.yaml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changes/unreleased/Feature-20230613-151546.yaml diff --git a/.changes/unreleased/Feature-20230613-151546.yaml b/.changes/unreleased/Feature-20230613-151546.yaml new file mode 100644 index 000000000..e66076aa5 --- /dev/null +++ b/.changes/unreleased/Feature-20230613-151546.yaml @@ -0,0 +1,5 @@ +kind: Feature +body: Get an unified list of document in person and accompanying period context +time: 2023-06-13T15:15:46.146899906+02:00 +custom: + Issue: "103" From c4dd46a03c8e10020adc8186deea894617b2a2ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 13 Jun 2023 15:26:21 +0200 Subject: [PATCH 168/321] fix phpstan issues --- .../ChillReportBundle/DataFixtures/ORM/LoadReports.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Bundle/ChillReportBundle/DataFixtures/ORM/LoadReports.php b/src/Bundle/ChillReportBundle/DataFixtures/ORM/LoadReports.php index db4646eed..30477f269 100644 --- a/src/Bundle/ChillReportBundle/DataFixtures/ORM/LoadReports.php +++ b/src/Bundle/ChillReportBundle/DataFixtures/ORM/LoadReports.php @@ -166,7 +166,7 @@ class LoadReports extends AbstractFixture implements ContainerAwareInterface, Or /** * pick a random choice. * - * @return string|string[] the array of slug if multiple, a single slug otherwise + * @return string|string[] */ private function getRandomChoice(CustomField $field) { @@ -211,6 +211,8 @@ class LoadReports extends AbstractFixture implements ContainerAwareInterface, Or return $result; } } + + return $picked; } /** @@ -226,7 +228,7 @@ class LoadReports extends AbstractFixture implements ContainerAwareInterface, Or /** * pick a choice within a 'choices' options (for choice type). * - * @return the slug of the selected choice + * @return string the slug of the selected choice */ private function pickChoice(array $choices) { From 24049b9dfcceb83764d0cbc044de18268caf9dbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 13 Jun 2023 15:33:03 +0200 Subject: [PATCH 169/321] remove unused file --- .../AccompanyingCourseDocumentProvider.php | 54 ------------------- 1 file changed, 54 deletions(-) delete mode 100644 src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/AccompanyingCourseDocumentProvider.php diff --git a/src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/AccompanyingCourseDocumentProvider.php b/src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/AccompanyingCourseDocumentProvider.php deleted file mode 100644 index 163d17458..000000000 --- a/src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/AccompanyingCourseDocumentProvider.php +++ /dev/null @@ -1,54 +0,0 @@ -entityManager->getClassMetadata(AccompanyingCourseDocument::class); - - $query = new FetchQuery( - 'accompanying_course_document', - sprintf('jsonb_build_object(\'id\', %s)', $classMetadata->getIdentifierColumnNames()[0]), - sprintf($classMetadata->getColumnName('date')), - $classMetadata->getSchemaName() . '.' . $classMetadata->getTableName() - ); - - $query->addWhereClause( - sprintf('%s = ?', $classMetadata->getSingleAssociationJoinColumnName('course')), - [$accompanyingPeriod->getId()] - ); - - return $query; - } - - public function isAllowedForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod): bool - { - return $this->security->isGranted(AccompanyingCourseDocumentVoter::SEE, $accompanyingPeriod); - } -} From 5495b1cb447b2763948776dd3fc4440d9a73e485 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 13 Jun 2023 15:33:10 +0200 Subject: [PATCH 170/321] fix condition --- .../Repository/ActivityDocumentACLAwareRepository.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Bundle/ChillActivityBundle/Repository/ActivityDocumentACLAwareRepository.php b/src/Bundle/ChillActivityBundle/Repository/ActivityDocumentACLAwareRepository.php index 3ca9281af..ce70409ba 100644 --- a/src/Bundle/ChillActivityBundle/Repository/ActivityDocumentACLAwareRepository.php +++ b/src/Bundle/ChillActivityBundle/Repository/ActivityDocumentACLAwareRepository.php @@ -153,7 +153,7 @@ final readonly class ActivityDocumentACLAwareRepository implements ActivityDocum ); } - if (null !== $content or '' !== $content) { + if (null !== $content and '' !== $content) { $query->addWhereClause( 'stored_obj.title ilike ?', ['%' . $content . '%'], From c683123ecaf9efb4b65ad6a616115eea7796f151 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 13 Jun 2023 15:47:06 +0200 Subject: [PATCH 171/321] set blinking animation on item-row, not just on the input --- .../AccompanyingCourseWorkEdit/components/FormEvaluation.vue | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/components/FormEvaluation.vue b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/components/FormEvaluation.vue index 10bac43b3..3788c3454 100644 --- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/components/FormEvaluation.vue +++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/components/FormEvaluation.vue @@ -79,14 +79,13 @@
        {{ $t('Documents') }} :
        -
        +
        Date: Tue, 13 Jun 2023 15:49:16 +0200 Subject: [PATCH 172/321] add changelog entry --- .changes/unreleased/Feature-20230613-154903.yaml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .changes/unreleased/Feature-20230613-154903.yaml diff --git a/.changes/unreleased/Feature-20230613-154903.yaml b/.changes/unreleased/Feature-20230613-154903.yaml new file mode 100644 index 000000000..7506bf473 --- /dev/null +++ b/.changes/unreleased/Feature-20230613-154903.yaml @@ -0,0 +1,7 @@ +kind: Feature +body: When navigating from a workflow regarding to an evaluation's document to an + accompanying course, scroll directly to the document, and blink to highlight this + document +time: 2023-06-13T15:49:03.663438985+02:00 +custom: + Issue: "" From a136a278daa4e10dd30be72b1bfbcc5142252fc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 13 Jun 2023 15:53:50 +0200 Subject: [PATCH 173/321] remove console.log --- .../public/vuejs/_components/Entity/PersonRenderBox.vue | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/_components/Entity/PersonRenderBox.vue b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/_components/Entity/PersonRenderBox.vue index 809859114..2576efd35 100644 --- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/_components/Entity/PersonRenderBox.vue +++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/_components/Entity/PersonRenderBox.vue @@ -261,7 +261,6 @@ export default { return this.person.gender === 'woman' ? 'person.gender.woman' : this.person.gender === 'man' ? 'person.gender.man' : this.person.gender === 'neuter' ? 'person.gender.neuter' : 'person.gender.undefined'; }, birthdate: function () { - console.log('debug birthdate', this.person.birthdate.datetime, ISOToDate(this.person.birthdate.datetime), new Date(this.person.birthdate.datetime)); if (this.person.birthdate !== null || this.person.birthdate === "undefined") { return ISOToDate(this.person.birthdate.datetime); } else { From fadc007bfe6c6cd19d4b5acf3046d1cac286b93d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 13 Jun 2023 15:55:05 +0200 Subject: [PATCH 174/321] add changelog entry --- .changes/unreleased/Fixed-20230613-155453.yaml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changes/unreleased/Fixed-20230613-155453.yaml diff --git a/.changes/unreleased/Fixed-20230613-155453.yaml b/.changes/unreleased/Fixed-20230613-155453.yaml new file mode 100644 index 000000000..f183c3a17 --- /dev/null +++ b/.changes/unreleased/Fixed-20230613-155453.yaml @@ -0,0 +1,5 @@ +kind: Fixed +body: Fix birthdate timezone in PersonRenderBox +time: 2023-06-13T15:54:53.125120559+02:00 +custom: + Issue: "58" From cb4de1f3d2666af9f29143661cb092425a0777ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 13 Jun 2023 22:58:08 +0200 Subject: [PATCH 175/321] Fixes for work rendering without "onlyone" parameter --- .../_objectifs_results_evaluations.html.twig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/_objectifs_results_evaluations.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/_objectifs_results_evaluations.html.twig index 51621f432..da6ec6e32 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/_objectifs_results_evaluations.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/_objectifs_results_evaluations.html.twig @@ -65,7 +65,7 @@
    - {% if onlyone %} + {% if onlyone|default(false) %} {% for e in w.accompanyingPeriodWorkEvaluations %} {% if evalId is defined and evalId == e.id %} @@ -275,7 +275,7 @@ 'entityClass': 'Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluationDocument', 'entityId': d.id }) }}"> {% endif %} - + {{ d.storedObject|chill_document_button_group(d.title, is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_UPDATE', w), {'small': true}) }} From 3879e5cd9bc1c554a551fe519598eb48d111dcf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 13 Jun 2023 23:03:15 +0200 Subject: [PATCH 176/321] Notification: fix counter, and allow to add more related entity in a single query Sometimes, there are entities which embed other entities, which in turn have notification. This more parameter allow to fetch notification and counter for those embedded entities in a single query. --- .../Notification/NotificationPresence.php | 23 ++-- .../NotificationTwigExtensionRuntime.php | 18 ++- .../Repository/NotificationRepository.php | 104 +++++++++++++----- ...ension_counter_notifications_for.html.twig | 2 +- 4 files changed, 105 insertions(+), 42 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Notification/NotificationPresence.php b/src/Bundle/ChillMainBundle/Notification/NotificationPresence.php index c09b845d7..a6e02c4ea 100644 --- a/src/Bundle/ChillMainBundle/Notification/NotificationPresence.php +++ b/src/Bundle/ChillMainBundle/Notification/NotificationPresence.php @@ -34,9 +34,13 @@ class NotificationPresence $this->notificationRepository = $notificationRepository; } - public function countNotificationsForClassAndEntity(string $relatedEntityClass, int $relatedEntityId): array + /** + * @param list $more + * @return array{unread: int, sent: int, total: int} + */ + public function countNotificationsForClassAndEntity(string $relatedEntityClass, int $relatedEntityId, array $more = [], array $options = []): array { - if (array_key_exists($relatedEntityClass, $this->cache) && array_key_exists($relatedEntityId, $this->cache[$relatedEntityClass])) { + if ([] === $more && array_key_exists($relatedEntityClass, $this->cache) && array_key_exists($relatedEntityId, $this->cache[$relatedEntityClass])) { return $this->cache[$relatedEntityClass][$relatedEntityId]; } @@ -46,21 +50,25 @@ class NotificationPresence $counter = $this->notificationRepository->countNotificationByRelatedEntityAndUserAssociated( $relatedEntityClass, $relatedEntityId, - $user + $user, + $more ); - $this->cache[$relatedEntityClass][$relatedEntityId] = $counter; + if ([] === $more) { + $this->cache[$relatedEntityClass][$relatedEntityId] = $counter; + } return $counter; } - return ['unread' => 0, 'read' => 0]; + return ['unread' => 0, 'sent' => 0, 'total' => 0]; } /** + * @param list $more * @return array|Notification[] */ - public function getNotificationsForClassAndEntity(string $relatedEntityClass, int $relatedEntityId): array + public function getNotificationsForClassAndEntity(string $relatedEntityClass, int $relatedEntityId, array $more = []): array { $user = $this->security->getUser(); @@ -68,7 +76,8 @@ class NotificationPresence return $this->notificationRepository->findNotificationByRelatedEntityAndUserAssociated( $relatedEntityClass, $relatedEntityId, - $user + $user, + $more ); } diff --git a/src/Bundle/ChillMainBundle/Notification/Templating/NotificationTwigExtensionRuntime.php b/src/Bundle/ChillMainBundle/Notification/Templating/NotificationTwigExtensionRuntime.php index 0720c6da6..a8751374e 100644 --- a/src/Bundle/ChillMainBundle/Notification/Templating/NotificationTwigExtensionRuntime.php +++ b/src/Bundle/ChillMainBundle/Notification/Templating/NotificationTwigExtensionRuntime.php @@ -34,24 +34,30 @@ class NotificationTwigExtensionRuntime implements RuntimeExtensionInterface $this->urlGenerator = $urlGenerator; } - public function counterNotificationFor(Environment $environment, string $relatedEntityClass, int $relatedEntityId, array $options = []): string + public function counterNotificationFor(Environment $environment, string $relatedEntityClass, int $relatedEntityId, array $more = [], array $options = []): string { return $environment->render( '@ChillMain/Notification/extension_counter_notifications_for.html.twig', [ - 'counter' => $this->notificationPresence->countNotificationsForClassAndEntity($relatedEntityClass, $relatedEntityId), + 'counter' => $this->notificationPresence->countNotificationsForClassAndEntity($relatedEntityClass, $relatedEntityId, $more), ] ); } - public function countNotificationsFor(string $relatedEntityClass, int $relatedEntityId, array $options = []): array + /** + * @param list $more + */ + public function countNotificationsFor(string $relatedEntityClass, int $relatedEntityId, array $more = [], array $options = []): array { - return $this->notificationPresence->countNotificationsForClassAndEntity($relatedEntityClass, $relatedEntityId); + return $this->notificationPresence->countNotificationsForClassAndEntity($relatedEntityClass, $relatedEntityId, $more); } - public function listNotificationsFor(Environment $environment, string $relatedEntityClass, int $relatedEntityId, array $options = []): string + /** + * @param list $more + */ + public function listNotificationsFor(Environment $environment, string $relatedEntityClass, int $relatedEntityId, array $more = [], array $options = []): string { - $notifications = $this->notificationPresence->getNotificationsForClassAndEntity($relatedEntityClass, $relatedEntityId); + $notifications = $this->notificationPresence->getNotificationsForClassAndEntity($relatedEntityClass, $relatedEntityId, $more); if ([] === $notifications) { return ''; diff --git a/src/Bundle/ChillMainBundle/Repository/NotificationRepository.php b/src/Bundle/ChillMainBundle/Repository/NotificationRepository.php index 72f9ea5d1..fe42578d9 100644 --- a/src/Bundle/ChillMainBundle/Repository/NotificationRepository.php +++ b/src/Bundle/ChillMainBundle/Repository/NotificationRepository.php @@ -29,6 +29,15 @@ final class NotificationRepository implements ObjectRepository private EntityRepository $repository; + private const BASE_COUNTER_SQL = <<<'SQL' + SELECT + SUM((EXISTS (SELECT 1 AS c FROM chill_main_notification_addresses_unread cmnau WHERE user_id = :userid and cmnau.notification_id = cmn.id))::int) AS unread, + SUM((cmn.sender_id = :userid)::int) AS sent, + SUM((EXISTS (SELECT 1 AS c FROM chill_main_notification_addresses_user cmnau_all WHERE user_id = :userid and cmnau_all.notification_id = cmn.id))::int) + SUM((cmn.sender_id = :userid)::int) AS total + FROM chill_main_notification cmn + SQL; + + public function __construct(EntityManagerInterface $entityManager) { $this->em = $entityManager; @@ -51,29 +60,45 @@ final class NotificationRepository implements ObjectRepository ->getSingleScalarResult(); } - public function countNotificationByRelatedEntityAndUserAssociated(string $relatedEntityClass, int $relatedEntityId, User $user): array + /** + * @param list $more + * @return array{unread: int, sent: int, total: int} + */ + public function countNotificationByRelatedEntityAndUserAssociated(string $relatedEntityClass, int $relatedEntityId, User $user, array $more = []): array { - if (null === $this->notificationByRelatedEntityAndUserAssociatedStatement) { - $sql = - 'SELECT - SUM((EXISTS (SELECT 1 AS c FROM chill_main_notification_addresses_unread cmnau WHERE user_id = :userid and cmnau.notification_id = cmn.id))::int) AS unread, - SUM((cmn.sender_id = :userid)::int) AS sent, - COUNT(cmn.*) AS total - FROM chill_main_notification cmn - WHERE relatedentityclass = :relatedEntityClass AND relatedentityid = :relatedEntityId AND sender_id IS NOT NULL'; + $sqlParams = ['relatedEntityClass' => $relatedEntityClass, 'relatedEntityId' => $relatedEntityId, 'userid' => $user->getId()]; - $this->notificationByRelatedEntityAndUserAssociatedStatement = - $this->em->getConnection()->prepare($sql); + if ([] === $more) { + if (null === $this->notificationByRelatedEntityAndUserAssociatedStatement) { + $sql = self::BASE_COUNTER_SQL . ' WHERE relatedentityclass = :relatedEntityClass AND relatedentityid = :relatedEntityId AND sender_id IS NOT NULL'; + + $this->notificationByRelatedEntityAndUserAssociatedStatement = + $this->em->getConnection()->prepare($sql); + } + + $results = $this->notificationByRelatedEntityAndUserAssociatedStatement + ->executeQuery($sqlParams); + + $result = $results->fetchAssociative(); + + $results->free(); + } else { + $wheres = []; + foreach ([ + ['relatedEntityClass' => $relatedEntityClass, 'relatedEntityId' => $relatedEntityId], + ...$more + ] as $k => ['relatedEntityClass' => $relClass, 'relatedEntityId' => $relId]) { + $wheres[] = "(relatedEntityClass = :relatedEntityClass_{$k} AND relatedEntityId = :relatedEntityId_{$k})"; + $sqlParams["relatedEntityClass_{$k}"] = $relClass; + $sqlParams["relatedEntityId_{$k}"] = $relId; + } + + $sql = self::BASE_COUNTER_SQL . ' WHERE sender_id IS NOT NULL AND (' . implode(' OR ', $wheres) . ')'; + + $result = $this->em->getConnection()->fetchAssociative($sql, $sqlParams); } - $results = $this->notificationByRelatedEntityAndUserAssociatedStatement - ->executeQuery(['relatedEntityClass' => $relatedEntityClass, 'relatedEntityId' => $relatedEntityId, 'userid' => $user->getId()]); - - $result = $results->fetchAssociative(); - - $results->free(); - - return $result; + return array_map(fn (?int $number) => $number ?? 0, $result); } public function countUnreadByUser(User $user): int @@ -167,8 +192,8 @@ final class NotificationRepository implements ObjectRepository } /** - * @param mixed|null $limit - * @param mixed|null $offset + * @param int|null $limit + * @param int|null $offset * * @return Notification[] */ @@ -178,13 +203,15 @@ final class NotificationRepository implements ObjectRepository } /** + * @param list $more * @return array|Notification[] */ - public function findNotificationByRelatedEntityAndUserAssociated(string $relatedEntityClass, int $relatedEntityId, User $user): array + public function findNotificationByRelatedEntityAndUserAssociated(string $relatedEntityClass, int $relatedEntityId, User $user, array $more): array { return - $this->buildQueryNotificationByRelatedEntityAndUserAssociated($relatedEntityClass, $relatedEntityId, $user) + $this->buildQueryNotificationByRelatedEntityAndUserAssociated($relatedEntityClass, $relatedEntityId, $user, $more) ->select('n') + ->addOrderBy('n.date', 'DESC') ->getQuery() ->getResult(); } @@ -222,13 +249,36 @@ final class NotificationRepository implements ObjectRepository return Notification::class; } - private function buildQueryNotificationByRelatedEntityAndUserAssociated(string $relatedEntityClass, int $relatedEntityId, User $user): QueryBuilder + /** + * @param list $more + */ + private function buildQueryNotificationByRelatedEntityAndUserAssociated(string $relatedEntityClass, int $relatedEntityId, User $user, array $more = []): QueryBuilder { $qb = $this->repository->createQueryBuilder('n'); + // add condition for related entity (in main arguments, and in more) + $or = $qb->expr()->orX($qb->expr()->andX( + $qb->expr()->eq('n.relatedEntityClass', ':relatedEntityClass'), + $qb->expr()->eq('n.relatedEntityId', ':relatedEntityId') + )); $qb - ->where($qb->expr()->eq('n.relatedEntityClass', ':relatedEntityClass')) - ->andWhere($qb->expr()->eq('n.relatedEntityId', ':relatedEntityId')) + ->setParameter('relatedEntityClass', $relatedEntityClass) + ->setParameter('relatedEntityId', $relatedEntityId); + + foreach ($more as $k => ['relatedEntityClass' => $relatedClass, 'relatedEntityId' => $relatedId]) { + $or->add( + $qb->expr()->andX( + $qb->expr()->eq('n.relatedEntityClass', ':relatedEntityClass_'.$k), + $qb->expr()->eq('n.relatedEntityId', ':relatedEntityId_'.$k) + ) + ); + $qb + ->setParameter('relatedEntityClass_'.$k, $relatedClass) + ->setParameter('relatedEntityId_'.$k, $relatedId); + } + + $qb + ->andWhere($or) ->andWhere($qb->expr()->isNotNull('n.sender')) ->andWhere( $qb->expr()->orX( @@ -236,8 +286,6 @@ final class NotificationRepository implements ObjectRepository $qb->expr()->eq('n.sender', ':user') ) ) - ->setParameter('relatedEntityClass', $relatedEntityClass) - ->setParameter('relatedEntityId', $relatedEntityId) ->setParameter('user', $user); return $qb; diff --git a/src/Bundle/ChillMainBundle/Resources/views/Notification/extension_counter_notifications_for.html.twig b/src/Bundle/ChillMainBundle/Resources/views/Notification/extension_counter_notifications_for.html.twig index d92e4230e..0e64e9f6a 100644 --- a/src/Bundle/ChillMainBundle/Resources/views/Notification/extension_counter_notifications_for.html.twig +++ b/src/Bundle/ChillMainBundle/Resources/views/Notification/extension_counter_notifications_for.html.twig @@ -9,4 +9,4 @@ {{ 'notification.counter unread notifications'|trans({'unread': counter.unread }) }} {% endif %} - \ No newline at end of file + From a6b451df98e60e3b7e9b56c85dd8e13194f58619 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 13 Jun 2023 23:04:41 +0200 Subject: [PATCH 177/321] Fix counter on notification for document, using "more" parameter The counter now show results for embedded document, in the accompanying period work list. --- .../AccompanyingCourseWork/_macros.html.twig | 20 ++++++++++++++----- .../AccompanyingCourseWork/show.html.twig | 15 +++++++++++++- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/_macros.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/_macros.html.twig index 10a0f94c7..b04e9483a 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/_macros.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/_macros.html.twig @@ -1,7 +1,17 @@ -{% macro metadata(w) %} - {% set notif_counter = chill_count_notifications('Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWork', w.id) %} - {% if notif_counter.total > 0 %} - {{ chill_counter_notifications('Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWork', w.id) }} +{% macro metadata(w, include_notif_counter = true) %} + {% if include_notif_counter == true %} + {% set more = [] %} + {% for e in w.accompanyingPeriodWorkEvaluations %} + {% for d in e.documents %} + {% set more = more|merge([{'relatedEntityClass': 'Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluationDocument', 'relatedEntityId': d.id}]) %} + {% endfor %} + {% endfor %} + + {% set notif_counter = chill_count_notifications('Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWork', w.id, more) %} + + {% if notif_counter.total > 0 %} + {{ chill_counter_notifications('Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWork', w.id, more) }} + {% endif %} {% endif %} {% import '@ChillPerson/Macro/updatedBy.html.twig' as macro %} {{ macro.updatedBy(w) }} @@ -20,4 +30,4 @@ {% endfor %} {% endfor %} {{ chill_entity_workflow_list('Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWork', w.id, [], suppEvaluations) }} -{% endmacro %} \ No newline at end of file +{% endmacro %} diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/show.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/show.html.twig index d32c1b700..438a6fb7f 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/show.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/show.html.twig @@ -27,7 +27,20 @@ 'displayContent': 'long', 'itemBlocClass': 'uniq extended', } %} -
    {{ macro.metadata(work) }}
    +
    {{ macro.metadata(work, false) }}
    + + +
    + {% set more = [] %} + {% for e in work.accompanyingPeriodWorkEvaluations %} + {% for d in e.documents %} + {% set more = more|merge([{'relatedEntityClass': 'Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluationDocument', 'relatedEntityId': d.id}]) %} + {% endfor %} + {% endfor %} + {% set notifications = chill_list_notifications('Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWork', work.id, more) %} + {% if notifications is not empty %} + {{ notifications|raw }} + {% endif %}
      From 56957250bad8f21e63d928f6d8db7c63ec0965d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 13 Jun 2023 23:05:09 +0200 Subject: [PATCH 178/321] re-use the display of workflow for the notification on evaluation document --- ...kEvaluationDocumentNotificationHandler.php | 3 +- ...EvaluationDocumentInNotification.html.twig | 143 ++++++++++++++---- 2 files changed, 119 insertions(+), 27 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Notification/AccompanyingPeriodWorkEvaluationDocumentNotificationHandler.php b/src/Bundle/ChillPersonBundle/Notification/AccompanyingPeriodWorkEvaluationDocumentNotificationHandler.php index f5ce07c8e..4dcb03489 100644 --- a/src/Bundle/ChillPersonBundle/Notification/AccompanyingPeriodWorkEvaluationDocumentNotificationHandler.php +++ b/src/Bundle/ChillPersonBundle/Notification/AccompanyingPeriodWorkEvaluationDocumentNotificationHandler.php @@ -35,7 +35,8 @@ final class AccompanyingPeriodWorkEvaluationDocumentNotificationHandler implemen { return [ 'notification' => $notification, - 'document' => $this->accompanyingPeriodWorkEvaluationDocumentRepository->find($notification->getRelatedEntityId()), + 'document' => $doc = $this->accompanyingPeriodWorkEvaluationDocumentRepository->find($notification->getRelatedEntityId()), + 'evaluation' => $doc?->getAccompanyingPeriodWorkEvaluation(), ]; } diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showEvaluationDocumentInNotification.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showEvaluationDocumentInNotification.html.twig index b4df52254..0341e42e5 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showEvaluationDocumentInNotification.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showEvaluationDocumentInNotification.html.twig @@ -1,32 +1,123 @@ -{% macro recordAction(document) %} - {% import "@ChillDocStore/Macro/macro_mimeicon.html.twig" as mm %} -
      -
    {{ 'Budget element type'|trans }} @@ -80,10 +80,9 @@ {% set result = (totalResources - totalCharges) %} - +
    - @@ -91,7 +90,6 @@ - diff --git a/src/Bundle/ChillBudgetBundle/Resources/views/Person/index.html.twig b/src/Bundle/ChillBudgetBundle/Resources/views/Person/index.html.twig index 959df3d62..18d04b889 100644 --- a/src/Bundle/ChillBudgetBundle/Resources/views/Person/index.html.twig +++ b/src/Bundle/ChillBudgetBundle/Resources/views/Person/index.html.twig @@ -17,17 +17,15 @@ {% block content %}

    {{ title }}

    -{% include 'ChillBudgetBundle:Budget:_budget.html.twig' with { +{% include '@ChillBudget/Budget/_budget.html.twig' with { 'resources': resources, 'charges': charges, 'person': person } %} -
    -

    {{ 'Budget calculator'|trans }}

    -
    - {{ table_results(charges, resources) }} -
    +
    +

    {{ 'Budget calculator'|trans }}

    + {{ table_results(charges, resources) }}
    {% if is_granted('CHILL_BUDGET_ELEMENT_CREATE', person) %} From d8d517017ddcd03bd85ecc0a21f73f94076384f1 Mon Sep 17 00:00:00 2001 From: Lucas Silva Date: Thu, 30 Mar 2023 14:31:02 +0200 Subject: [PATCH 007/321] switching to new syntax --- .../AccompanyingPeriodNotificationHandler.php | 2 +- ...dWorkEvaluationDocumentNotificationHandler.php | 2 +- .../AccompanyingPeriodWorkNotificationHandler.php | 2 +- ...showEvaluationDocumentInNotification.html.twig | 15 ++++++++++----- .../showInNotification.html.twig | 2 +- .../showInNotification.html.twig | 3 +-- 6 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Notification/AccompanyingPeriodNotificationHandler.php b/src/Bundle/ChillPersonBundle/Notification/AccompanyingPeriodNotificationHandler.php index 486209453..2492e9a41 100644 --- a/src/Bundle/ChillPersonBundle/Notification/AccompanyingPeriodNotificationHandler.php +++ b/src/Bundle/ChillPersonBundle/Notification/AccompanyingPeriodNotificationHandler.php @@ -27,7 +27,7 @@ final class AccompanyingPeriodNotificationHandler implements NotificationHandler public function getTemplate(Notification $notification, array $options = []): string { - return 'ChillPersonBundle:AccompanyingPeriod:showInNotification.html.twig'; + return '@ChillPerson/AccompanyingPeriod/showInNotification.html.twig'; } public function getTemplateData(Notification $notification, array $options = []): array diff --git a/src/Bundle/ChillPersonBundle/Notification/AccompanyingPeriodWorkEvaluationDocumentNotificationHandler.php b/src/Bundle/ChillPersonBundle/Notification/AccompanyingPeriodWorkEvaluationDocumentNotificationHandler.php index 1f3ed0fb6..f5ce07c8e 100644 --- a/src/Bundle/ChillPersonBundle/Notification/AccompanyingPeriodWorkEvaluationDocumentNotificationHandler.php +++ b/src/Bundle/ChillPersonBundle/Notification/AccompanyingPeriodWorkEvaluationDocumentNotificationHandler.php @@ -28,7 +28,7 @@ final class AccompanyingPeriodWorkEvaluationDocumentNotificationHandler implemen public function getTemplate(Notification $notification, array $options = []): string { - return 'ChillPersonBundle:AccompanyingCourseWork:showEvaluationDocumentInNotification.html.twig'; + return '@ChillPerson/AccompanyingCourseWork/showEvaluationDocumentInNotification.html.twig'; } public function getTemplateData(Notification $notification, array $options = []): array diff --git a/src/Bundle/ChillPersonBundle/Notification/AccompanyingPeriodWorkNotificationHandler.php b/src/Bundle/ChillPersonBundle/Notification/AccompanyingPeriodWorkNotificationHandler.php index dbb30e983..b111c131f 100644 --- a/src/Bundle/ChillPersonBundle/Notification/AccompanyingPeriodWorkNotificationHandler.php +++ b/src/Bundle/ChillPersonBundle/Notification/AccompanyingPeriodWorkNotificationHandler.php @@ -28,7 +28,7 @@ final class AccompanyingPeriodWorkNotificationHandler implements NotificationHan public function getTemplate(Notification $notification, array $options = []): string { - return 'ChillPersonBundle:AccompanyingCourseWork:showInNotification.html.twig'; + return '@ChillPerson/AccompanyingCourseWork/showInNotification.html.twig'; } public function getTemplateData(Notification $notification, array $options = []): array diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showEvaluationDocumentInNotification.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showEvaluationDocumentInNotification.html.twig index 83ba7bf91..f4c9c1bf7 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showEvaluationDocumentInNotification.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showEvaluationDocumentInNotification.html.twig @@ -5,13 +5,18 @@ {% endmacro %} {% if document is not null %} +
    {% if is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_EVALUATION_DOCUMENT_SHOW', document) %} - {% include 'ChillPersonBundle:AccompanyingCourseWork:_objectifs_results_evaluations.html.twig' with { - 'w': document.accompanyingPeriodWorkEvaluation.accompanyingPeriodWork, - 'd': document.storedObject, - 'displayContent': 'long', - } %} +
    + {% include '@ChillPerson/AccompanyingCourseWork/_objectifs_results_evaluations.html.twig' with { + 'w': document.accompanyingPeriodWorkEvaluation.accompanyingPeriodWork, + 'd': document.storedObject, + 'displayContent': 'short', + 'recordAction': _self.recordAction(document) + } %} +
    + {% else %}
    {{ 'This is the minimal period details'|trans ~ ': ' ~ document.id }}
    diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showInNotification.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showInNotification.html.twig index 311692030..4ee561381 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showInNotification.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showInNotification.html.twig @@ -7,7 +7,7 @@ {% if work is not null %}
    {% if is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_SEE', work) %} - {% include 'ChillPersonBundle:AccompanyingCourseWork:_item.html.twig' with { + {% include "@ChillPerson/AccompanyingCourseWork/_item.html.twig" with { 'itemBlocClass': 'bg-chill-llight-gray', 'displayAction': true, 'displayContent': 'short', diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/showInNotification.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/showInNotification.html.twig index d6d13cd17..37563c947 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/showInNotification.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/showInNotification.html.twig @@ -6,10 +6,9 @@ {% endmacro %} {% if period is not null %} - {{ dump(period) }}
    {% if is_granted('CHILL_PERSON_ACCOMPANYING_PERIOD_SEE', period) %} - {% include 'ChillPersonBundle:AccompanyingPeriod:_list_item.html.twig' with { + {% include "@ChillPerson/AccompanyingPeriod/_list_item.html.twig" with { 'recordAction': _self.recordAction(notification.relatedEntityId), 'itemBlocClass': 'bg-chill-llight-gray' } %} From 3576f7f14f415c7ce3d1706ac8940a2a9723134a Mon Sep 17 00:00:00 2001 From: Lucas Silva Date: Thu, 30 Mar 2023 14:32:00 +0200 Subject: [PATCH 008/321] Finishing evaluation document view and fixing dropdown in show --- .../AccompanyingCourseWork/_item.html.twig | 134 +++++++++--------- .../_objectifs_results_evaluations.html.twig | 12 +- .../AccompanyingCourseWork/index.html.twig | 3 +- .../AccompanyingCourseWork/show.html.twig | 4 +- ...EvaluationDocumentInNotification.html.twig | 17 ++- .../showInNotification.html.twig | 6 +- 6 files changed, 100 insertions(+), 76 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/_item.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/_item.html.twig index 76c61407d..2a6dea8a1 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/_item.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/_item.html.twig @@ -5,7 +5,8 @@ # - displayAction: [true|false] default: false # - displayFontSmall: [true|false] default: false #} -
    +

    @@ -111,8 +112,9 @@

    {% if displayContent is not defined or displayContent == 'short' %} -
    - {% include 'ChillPersonBundle:AccompanyingCourseWork:_objectifs_results_evaluations.html.twig' with { +
    + {% include '@ChillPerson/AccompanyingCourseWork/_objectifs_results_evaluations.html.twig' with { 'displayContent': displayContent } %}
    @@ -121,42 +123,43 @@ {% if displayContent is not defined or displayContent == 'short' %}
    - {% import '@ChillPerson/AccompanyingCourseWork/_macros.html.twig' as macro %} + {% import '@ChillPerson/AccompanyingCourseWork/_macros.html.twig' as macro %}
    {{ macro.metadata(w) }}
    {% if displayAction is defined and displayAction == true %} -
      +
        + {% if displayNotification is defined and displayNotification == true %} +
      • + -
      • - - - -
      • -
      • {{ macro.workflowButton(w) }}
      • -
      • - -
      • - {% if is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_UPDATE', w) %} + + + {% endif %} +
      • {{ macro.workflowButton(w) }}
      • -
      • - {% endif %} - {% if is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_DELETE', w) %} -
      • - -
      • - {% endif %} -
      + {% if is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_UPDATE', w) %} +
    • + +
    • + {% endif %} + {% if is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_DELETE', w) %} +
    • + +
    • + {% endif %} +
    {% endif %}
    {% endif %} @@ -164,47 +167,50 @@
    {# - # This is for 'long' version of content - # Note: this include is wrapped in a flex-table container. - # We start by closing the flex-table so we can add more. - # At the end we leave the last flex-table open, as it will be closed in the container. +# This is for 'long' version of content +# Note: this include is wrapped in a flex-table container. +# We start by closing the flex-table so we can add more. +# At the end we leave the last flex-table open, as it will be closed in the container. #} {% if displayContent is defined and displayContent == 'long' %} +
    + +{% if w.results|length > 0 or w.goals|length > 0 or w.accompanyingPeriodWorkEvaluations|length > 0 %} +

    {{ 'Dispositifs' }}

    + +
    {# new flex-table wrapper #} +
    + {% include 'ChillPersonBundle:AccompanyingCourseWork:_objectifs_results_evaluations.html.twig' with { + 'displayContent': displayContent + } %} +
    +{% endif %} - {% if w.results|length > 0 or w.goals|length > 0 or w.accompanyingPeriodWorkEvaluations|length > 0 %} -

    {{ 'Dispositifs' }}

    +

    {{ 'Comments'|trans }}

    -
    {# new flex-table wrapper #} -
    - {% include 'ChillPersonBundle:AccompanyingCourseWork:_objectifs_results_evaluations.html.twig' with { - 'displayContent': displayContent - } %} -
    +
    +
    +

    Public

    + {% if w.note is not empty %} +
    + {{ w.note|chill_entity_render_box({'metadata': true }) }} +
    + {% else %} + {{ 'No comment associated'|trans }} + {% endif %} +
    + {% if w.privateComment.hasCommentForUser(app.user) %} +
    +

    Privé

    +
    + {{ w.privateComment.commentForUser(app.user)|chill_markdown_to_html }} +
    {% endif %} - -

    {{ 'Comments'|trans }}

    - -
    -
    -

    Public

    - {% if w.note is not empty %} -
    - {{ w.note|chill_entity_render_box({'metadata': true }) }} -
    - {% else %} - {{ 'No comment associated'|trans }} - {% endif %} -
    - {% if w.privateComment.hasCommentForUser(app.user) %} -
    -

    Privé

    -
    - {{ w.privateComment.commentForUser(app.user)|chill_markdown_to_html }} -
    -
    - {% endif %} {# Here flex-table stay open ! read above #} -{% endif %} + {% endif %} diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/_objectifs_results_evaluations.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/_objectifs_results_evaluations.html.twig index 4f5d36230..e66dde463 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/_objectifs_results_evaluations.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/_objectifs_results_evaluations.html.twig @@ -118,9 +118,15 @@ {% endif %} {% endif %} + + + {% if recordAction is defined %} + {{ recordAction }} + {% endif %} + {% if displayContent is defined and displayContent == 'long' %} {% if e.comment is not empty %} @@ -136,9 +142,9 @@
    - + {% endfor %} diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/index.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/index.html.twig index 9214bd30d..ab1989f63 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/index.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/index.html.twig @@ -26,7 +26,8 @@ 'displayAction': true, 'displayContent': 'short', 'displayFontSmall': true, - 'itemBlocClass': '' + 'itemBlocClass': '', + 'displayNotification': true } %} {% endfor %} diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/show.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/show.html.twig index 73b871260..96b47e6c9 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/show.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/show.html.twig @@ -43,10 +43,10 @@ {% else %} diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showEvaluationDocumentInNotification.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showEvaluationDocumentInNotification.html.twig index f4c9c1bf7..6d5d22a7d 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showEvaluationDocumentInNotification.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showEvaluationDocumentInNotification.html.twig @@ -1,8 +1,17 @@ {% macro recordAction(document) %} -
  • - -
  • + {% import "@ChillDocStore/Macro/macro_mimeicon.html.twig" as mm %} +
    + +
        {{ 'Budget calculator result'|trans }}
    {{ 'The balance'|trans }}  {{ result|format_currency('EUR') }}
    {{ d.title }} {{ mm.mimeIcon(d.storedObject.type) }} - - + + {{ d.storedObject|chill_document_button_group(d.title, is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_UPDATE', w), {'small': true}) }}
    + + + + + +
    {{ document.title }}{{ mm.mimeIcon(document.storedObject.type) }}
    + {% endmacro %} {% if document is not null %} diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showInNotification.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showInNotification.html.twig index 4ee561381..9b06e306c 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showInNotification.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showInNotification.html.twig @@ -1,7 +1,8 @@ {% macro recordAction(work) %}
  • - +
  • {% endmacro %} {% if work is not null %} @@ -12,6 +13,7 @@ 'displayAction': true, 'displayContent': 'short', 'displayFontSmall': true, + 'displayNotification:':true, 'w': work } %} {% else %} From fe3d4370966e41c411e02f82adc23f73f1787d54 Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Mon, 24 Apr 2023 12:12:10 +0200 Subject: [PATCH 009/321] improve title hierarchy coherence --- .../Resources/views/Budget/_budget.html.twig | 2 +- .../Resources/views/Budget/_current_budget.html.twig | 4 +++- .../Resources/views/Household/index.html.twig | 2 +- src/Bundle/ChillBudgetBundle/translations/messages.fr.yml | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_budget.html.twig b/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_budget.html.twig index e11a822cd..e75b83ee8 100644 --- a/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_budget.html.twig +++ b/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_budget.html.twig @@ -45,7 +45,7 @@ {% endif %} {% if pastCharges|length > 0 or pastResources|length > 0 %} -

    {{ 'Past budget'|trans }}

    a +

    {{ 'Past budget'|trans }}

    {% include '@ChillBudget/Budget/_past_budget.html.twig' with { 'pastCharges': pastCharges, 'pastResources': pastResources, diff --git a/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_current_budget.html.twig b/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_current_budget.html.twig index 98e784cc5..27a77df1d 100644 --- a/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_current_budget.html.twig +++ b/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_current_budget.html.twig @@ -1,6 +1,8 @@ {% from '@ChillBudget/Budget/_macros.html.twig' import table_elements, table_results %} -{#

    {{ 'Actual budget'|trans }}

    #} +{# +

    {{ 'Actual budget'|trans }}

    +#}

    {{ 'Actual resources'|trans }}

    diff --git a/src/Bundle/ChillBudgetBundle/Resources/views/Household/index.html.twig b/src/Bundle/ChillBudgetBundle/Resources/views/Household/index.html.twig index c2533e4c0..310220df1 100644 --- a/src/Bundle/ChillBudgetBundle/Resources/views/Household/index.html.twig +++ b/src/Bundle/ChillBudgetBundle/Resources/views/Household/index.html.twig @@ -33,7 +33,7 @@ #} {% if household.getCurrentMembers|length > 0 %} -

    {{ 'Current budget household members'|trans }}

    +

    {{ 'Budget household members'|trans }}

    {% for hm in household.getCurrentMembers %} {% set member = hm.person %} diff --git a/src/Bundle/ChillBudgetBundle/translations/messages.fr.yml b/src/Bundle/ChillBudgetBundle/translations/messages.fr.yml index a5e5490a0..5d71f4228 100644 --- a/src/Bundle/ChillBudgetBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillBudgetBundle/translations/messages.fr.yml @@ -3,7 +3,7 @@ Resource: Ressource Charge: Charge Budget for %name%: Budget de %name% Budget for household %household%: Budget du ménage -Current budget household members: Budget actuel des membres du ménage +Budget household members: Budget des membres du ménage Show budget of %name%: Montrer budget de %name% See complete budget: Voir budget complet Hide budget: Masquer From 241e605ea6de96a2dc5ec9e594585869ed3ed118 Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Mon, 24 Apr 2023 12:22:41 +0200 Subject: [PATCH 010/321] - style of h3 subtitle --- .../Resources/public/page/chillbudget.scss | 7 ++++++- .../Resources/views/Budget/_budget.html.twig | 6 +++--- .../Resources/views/Person/index.html.twig | 2 +- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/Bundle/ChillBudgetBundle/Resources/public/page/chillbudget.scss b/src/Bundle/ChillBudgetBundle/Resources/public/page/chillbudget.scss index 20a87cce2..82230d13b 100644 --- a/src/Bundle/ChillBudgetBundle/Resources/public/page/chillbudget.scss +++ b/src/Bundle/ChillBudgetBundle/Resources/public/page/chillbudget.scss @@ -2,6 +2,11 @@ margin-top: 1rem; margin-bottom: 1rem; padding: 1rem; + &::before { + font: normal normal normal 20px/1 ForkAwesome; + margin-right: 0.5em; + content: "\f061"; + } } .family-title { margin-bottom: 1rem !important; @@ -58,4 +63,4 @@ button[aria-expanded="true"] > span.folded, button[aria-expanded="false"] > span.unfolded { display: none; } button[aria-expanded="false"] > span.folded, -button[aria-expanded="true"] > span.unfolded { display: inline; } \ No newline at end of file +button[aria-expanded="true"] > span.unfolded { display: inline; } diff --git a/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_budget.html.twig b/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_budget.html.twig index e75b83ee8..8a3fa6de2 100644 --- a/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_budget.html.twig +++ b/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_budget.html.twig @@ -32,7 +32,7 @@ {% endif %} {% endfor %} -

    {{ 'Actual budget'|trans }}

    +

    {{ 'Actual budget'|trans }}

    {% if actualCharges|length > 0 or actualResources|length > 0 %} {% include '@ChillBudget/Budget/_current_budget.html.twig' with { 'actualResources': actualResources, @@ -45,7 +45,7 @@ {% endif %} {% if pastCharges|length > 0 or pastResources|length > 0 %} -

    {{ 'Past budget'|trans }}

    +

    {{ 'Past budget'|trans }}

    {% include '@ChillBudget/Budget/_past_budget.html.twig' with { 'pastCharges': pastCharges, 'pastResources': pastResources, @@ -54,7 +54,7 @@ {% endif %} {% if futureCharges|length > 0 or futureResources|length > 0 %} -

    {{ 'Future budget'|trans }}

    +

    {{ 'Future budget'|trans }}

    {% include '@ChillBudget/Budget/_future_budget.html.twig' with { 'futureResources': futureResources, 'futureCharges': futureCharges, diff --git a/src/Bundle/ChillBudgetBundle/Resources/views/Person/index.html.twig b/src/Bundle/ChillBudgetBundle/Resources/views/Person/index.html.twig index 18d04b889..c365b9b84 100644 --- a/src/Bundle/ChillBudgetBundle/Resources/views/Person/index.html.twig +++ b/src/Bundle/ChillBudgetBundle/Resources/views/Person/index.html.twig @@ -24,7 +24,7 @@ } %}
    -

    {{ 'Budget calculator'|trans }}

    +

    {{ 'Budget calculator'|trans }}

    {{ table_results(charges, resources) }}
    From be965e8698c0ffec07b51fcca4a1e637aa18e735 Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Mon, 24 Apr 2023 13:01:58 +0200 Subject: [PATCH 011/321] - improve title hierarchy and ergonomie --- .../Resources/public/page/chillbudget.scss | 20 +++++++++++--- .../Resources/views/Budget/_budget.html.twig | 6 ++--- .../views/Budget/_current_budget.html.twig | 12 +++------ .../views/Budget/_future_budget.html.twig | 27 +++++++------------ .../views/Budget/_past_budget.html.twig | 26 ++++++------------ .../Resources/views/Household/index.html.twig | 12 ++++----- .../Resources/views/Person/index.html.twig | 2 +- .../translations/messages.fr.yml | 6 ++--- 8 files changed, 49 insertions(+), 62 deletions(-) diff --git a/src/Bundle/ChillBudgetBundle/Resources/public/page/chillbudget.scss b/src/Bundle/ChillBudgetBundle/Resources/public/page/chillbudget.scss index 82230d13b..cca1b1a4a 100644 --- a/src/Bundle/ChillBudgetBundle/Resources/public/page/chillbudget.scss +++ b/src/Bundle/ChillBudgetBundle/Resources/public/page/chillbudget.scss @@ -1,4 +1,4 @@ -.subtitle { +h3.subtitle { margin-top: 1rem; margin-bottom: 1rem; padding: 1rem; @@ -8,22 +8,34 @@ content: "\f061"; } } -.family-title { + +$col_charge: #e03851d7; +$col_resource: #6d9e63d8; + +h4.family-title { + margin-top: 1.5rem; margin-bottom: 1rem !important; + padding-left: 0.7em; + i { + margin-right: 0.4em; + } + &.charge i { color: $col_charge; } + &.resource i { color: $col_resource; } } .budget-table th { th { color: white; } } + .budget-table { th.charge { - background-color: #e03851d7; + background-color: $col_charge; } } .budget-table { th.resource { - background-color: #6d9e63d8; + background-color: $col_resource; } } .budget-table { diff --git a/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_budget.html.twig b/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_budget.html.twig index 8a3fa6de2..e75b83ee8 100644 --- a/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_budget.html.twig +++ b/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_budget.html.twig @@ -32,7 +32,7 @@ {% endif %} {% endfor %} -

    {{ 'Actual budget'|trans }}

    +

    {{ 'Actual budget'|trans }}

    {% if actualCharges|length > 0 or actualResources|length > 0 %} {% include '@ChillBudget/Budget/_current_budget.html.twig' with { 'actualResources': actualResources, @@ -45,7 +45,7 @@ {% endif %} {% if pastCharges|length > 0 or pastResources|length > 0 %} -

    {{ 'Past budget'|trans }}

    +

    {{ 'Past budget'|trans }}

    {% include '@ChillBudget/Budget/_past_budget.html.twig' with { 'pastCharges': pastCharges, 'pastResources': pastResources, @@ -54,7 +54,7 @@ {% endif %} {% if futureCharges|length > 0 or futureResources|length > 0 %} -

    {{ 'Future budget'|trans }}

    +

    {{ 'Future budget'|trans }}

    {% include '@ChillBudget/Budget/_future_budget.html.twig' with { 'futureResources': futureResources, 'futureCharges': futureCharges, diff --git a/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_current_budget.html.twig b/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_current_budget.html.twig index 27a77df1d..d8626aee2 100644 --- a/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_current_budget.html.twig +++ b/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_current_budget.html.twig @@ -1,20 +1,14 @@ {% from '@ChillBudget/Budget/_macros.html.twig' import table_elements, table_results %} -{# -

    {{ 'Actual budget'|trans }}

    -#} - -
    -

    {{ 'Actual resources'|trans }}

    +
    +

    {{ 'Actual resources'|trans }}

    {% if actualResources|length > 0 %} {{ table_elements(actualResources, 'resource') }} {% else %} {{ 'No resources registered'|trans }} {% endif %} -
    -
    -

    {{ 'Actual charges'|trans }}

    +

    {{ 'Actual charges'|trans }}

    {% if actualCharges|length > 0 %} {{ table_elements(actualCharges, 'charge') }} {% else %} diff --git a/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_future_budget.html.twig b/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_future_budget.html.twig index 1547d8749..62f4e3e96 100644 --- a/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_future_budget.html.twig +++ b/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_future_budget.html.twig @@ -20,32 +20,23 @@ aria-labelledby="heading_future_{{ entity.id }}" data-bs-parent="#future_{{ entity.id }}"> -
    -

    {{ 'Future resources'|trans }}

    +
    +

    {{ 'Future resources'|trans }}

    {% if futureResources|length > 0 %} -
    - {{ table_elements(futureResources, 'resource') }} -
    + {{ table_elements(futureResources, 'resource') }} {% else %} -
    - {{ 'No future resources registered'|trans }} -
    + {{ 'No future resources registered'|trans }} {% endif %} -
    -
    -

    {{ 'Future charges'|trans }}

    + +

    {{ 'Future charges'|trans }}

    {% if futureCharges|length > 0 %} -
    - {{ table_elements(futureCharges, 'charge') }} -
    + {{ table_elements(futureCharges, 'charge') }} {% else %} -
    - {{ 'No future charges registered'|trans }} -
    + {{ 'No future charges registered'|trans }} {% endif %}
    -
    \ No newline at end of file +
    diff --git a/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_past_budget.html.twig b/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_past_budget.html.twig index 14573048e..ad0a12755 100644 --- a/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_past_budget.html.twig +++ b/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_past_budget.html.twig @@ -20,34 +20,24 @@ aria-labelledby="heading_past_{{ entity.id }}" data-bs-parent="#past_{{ entity.id }}"> -
    -

    {{ 'Past resources'|trans }}

    +
    +

    {{ 'Past resources'|trans }}

    {% if pastResources|length > 0 %} -
    - {{ table_elements(pastResources, 'resource') }} -
    + {{ table_elements(pastResources, 'resource') }} {% else %} -
    - {{ 'No past resources registered'|trans }} -
    + {{ 'No past resources registered'|trans }} {% endif %} -
    -
    -

    {{ 'Past charges'|trans }}

    +

    {{ 'Past charges'|trans }}

    {% if pastCharges|length > 0 %} -
    - {{ table_elements(pastCharges, 'charge') }} -
    + {{ table_elements(pastCharges, 'charge') }} {% else %} -
    - {{ 'No past charges registered'|trans }} -
    + {{ 'No past charges registered'|trans }} {% endif %}
    - \ No newline at end of file + diff --git a/src/Bundle/ChillBudgetBundle/Resources/views/Household/index.html.twig b/src/Bundle/ChillBudgetBundle/Resources/views/Household/index.html.twig index 310220df1..1df92b297 100644 --- a/src/Bundle/ChillBudgetBundle/Resources/views/Household/index.html.twig +++ b/src/Bundle/ChillBudgetBundle/Resources/views/Household/index.html.twig @@ -24,16 +24,14 @@ } %} {# -
    -

    {{ 'Budget calculator'|trans }}

    -
    - {{ table_results(wholeCharges, wholeResources) }} -
    +
    +

    {{ 'Budget calculator'|trans }}

    + {{ table_results(wholeCharges, wholeResources) }}
    #} {% if household.getCurrentMembers|length > 0 %} -

    {{ 'Budget household members'|trans }}

    +

    {{ 'Budget household members'|trans }}

    {% for hm in household.getCurrentMembers %} {% set member = hm.person %} @@ -57,6 +55,8 @@ aria-labelledby="heading_{{ member.id }}" data-bs-parent="#nonCurrent"> +

    {{ 'Budget for %name%'|trans({'%name%': member.firstName ~ " " ~ member.lastName }) }}

    + {% include 'ChillBudgetBundle:Budget:_budget.html.twig' with { 'resources': member.getBudgetResources, 'charges': member.getBudgetCharges, diff --git a/src/Bundle/ChillBudgetBundle/Resources/views/Person/index.html.twig b/src/Bundle/ChillBudgetBundle/Resources/views/Person/index.html.twig index c365b9b84..18d04b889 100644 --- a/src/Bundle/ChillBudgetBundle/Resources/views/Person/index.html.twig +++ b/src/Bundle/ChillBudgetBundle/Resources/views/Person/index.html.twig @@ -24,7 +24,7 @@ } %}
    -

    {{ 'Budget calculator'|trans }}

    +

    {{ 'Budget calculator'|trans }}

    {{ table_results(charges, resources) }}
    diff --git a/src/Bundle/ChillBudgetBundle/translations/messages.fr.yml b/src/Bundle/ChillBudgetBundle/translations/messages.fr.yml index 5d71f4228..73add43ed 100644 --- a/src/Bundle/ChillBudgetBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillBudgetBundle/translations/messages.fr.yml @@ -9,17 +9,17 @@ See complete budget: Voir budget complet Hide budget: Masquer Hide budget of %name%: Masquer budget de %name% Resource element type: Nature de la ressource -Actual budget: Éléments actuels du budget +Actual budget: Éléments actuels Actual resources: Ressources actuelles Actual resources for %name%: Ressources actuelles de %name% Actual charges for %name%: Charges actuelles de %name% Actual charges: Charges actuelles -Past budget: Éléments du budget passé +Past budget: Éléments passés Show past budget: Montrer budget passé Show future budget: Montrer budget future Past resources: Ressources passées Past charges: Charges passées -Future budget: Futurs éléments du budget +Future budget: Éléments futurs Future resources: Ressources futures Future charges: Charges futures Budget element type: Nature From cb0ff88318856f0b9369c1996b9e90596c85794f Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Mon, 24 Apr 2023 13:29:45 +0200 Subject: [PATCH 012/321] Fix action column width --- .../Resources/public/page/chillbudget.scss | 24 ++++--------------- .../Resources/views/Budget/_macros.html.twig | 21 +++++++--------- 2 files changed, 14 insertions(+), 31 deletions(-) diff --git a/src/Bundle/ChillBudgetBundle/Resources/public/page/chillbudget.scss b/src/Bundle/ChillBudgetBundle/Resources/public/page/chillbudget.scss index cca1b1a4a..79f40dc76 100644 --- a/src/Bundle/ChillBudgetBundle/Resources/public/page/chillbudget.scss +++ b/src/Bundle/ChillBudgetBundle/Resources/public/page/chillbudget.scss @@ -28,29 +28,15 @@ h4.family-title { } } -.budget-table { - th.charge { - background-color: $col_charge; - } -} -.budget-table { - th.resource { - background-color: $col_resource; - } -} -.budget-table { +table.budget-table { th, td { padding: 10px; text-align: right; } - td.column-wide { - width: 20%; - } - td.column-small { - width: 15%; - &.right { - align-items: right; - } + th.charge { background-color: $col_charge; } + th.resource { background-color: $col_resource; } + td.column-fixed { + width: 9.5em; } } diff --git a/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_macros.html.twig b/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_macros.html.twig index 42090984a..70e96d96c 100644 --- a/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_macros.html.twig +++ b/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_macros.html.twig @@ -13,25 +13,22 @@ {% for f in elements %} {% set total = total + f.amount %}
    - - - {% if f.isResource %} - {{ f.resource.name|localize_translatable_string }} - {% else %} - {{ f.charge.name|localize_translatable_string }} - {% endif %} - + + {% if f.isResource %} + {{ f.resource.name|localize_translatable_string }} + {% else %} + {{ f.charge.name|localize_translatable_string }} + {% endif %} {{ f.amount|format_currency('EUR') }} + {{ f.amount|format_currency('EUR') }} {% if f.endDate is not null %} {{ f.startDate|format_date('short') ~ ' - ' ~ f.endDate|format_date('short') }} {% else %} {{ 'depuis le ' ~ f.startDate|format_date('short') }} {% endif %} +
      {% if is_granted('CHILL_BUDGET_ELEMENT_SEE', f) %}
    • From 8fd9010ea5affa9dac91bcb6dd12416fc229d2c4 Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Mon, 24 Apr 2023 14:44:26 +0200 Subject: [PATCH 013/321] fix event bundle stuffs - adapt event templates - event bundle: fix deprecated deps injections - fix error with n=0 not iterated into querybuilder with centers loop --- .../Resources/views/Event/list.html.twig | 10 ++++-- .../views/Event/listByPerson.html.twig | 2 +- .../views/Event/newPickCenter.html.twig | 4 +-- .../Resources/views/Event/show.html.twig | 20 +++++------ .../ChillEventBundle/Search/EventSearch.php | 35 ++++++++++--------- .../config/services/repositories.yaml | 2 +- .../config/services/search.yaml | 15 ++++---- .../translations/messages.fr.yml | 2 +- 8 files changed, 47 insertions(+), 43 deletions(-) diff --git a/src/Bundle/ChillEventBundle/Resources/views/Event/list.html.twig b/src/Bundle/ChillEventBundle/Resources/views/Event/list.html.twig index 8d5f49da8..d6f871125 100644 --- a/src/Bundle/ChillEventBundle/Resources/views/Event/list.html.twig +++ b/src/Bundle/ChillEventBundle/Resources/views/Event/list.html.twig @@ -2,11 +2,15 @@

      {% transchoice total with { '%pattern%' : pattern } %}%total% events match the search %pattern%{% endtranschoice %}

      + {% if events|length > 0 %}

      {{ 'Results %start%-%end% of %total%'|trans({ '%start%' : start, '%end%': start + events|length, '%total%' : total } ) }}

      - - +
      @@ -25,7 +29,7 @@
      • {# {% if is_granted('CHILL_EVENT_SEE_DETAILS', event) %} #} - + {{ 'See'|trans }} {# {% endif %} #} diff --git a/src/Bundle/ChillEventBundle/Resources/views/Event/listByPerson.html.twig b/src/Bundle/ChillEventBundle/Resources/views/Event/listByPerson.html.twig index ef2dae85c..ec9ebf76a 100644 --- a/src/Bundle/ChillEventBundle/Resources/views/Event/listByPerson.html.twig +++ b/src/Bundle/ChillEventBundle/Resources/views/Event/listByPerson.html.twig @@ -24,7 +24,7 @@ {% block content %}

        {{ 'Events participation' |trans }}

        -
      {{ 'Name'|trans }}
      +
      diff --git a/src/Bundle/ChillEventBundle/Resources/views/Event/newPickCenter.html.twig b/src/Bundle/ChillEventBundle/Resources/views/Event/newPickCenter.html.twig index a10d754e6..71c68002a 100644 --- a/src/Bundle/ChillEventBundle/Resources/views/Event/newPickCenter.html.twig +++ b/src/Bundle/ChillEventBundle/Resources/views/Event/newPickCenter.html.twig @@ -18,10 +18,10 @@
    • - {{ form_widget(form.submit, { 'attr' : { 'class' : 'btn btn-chill-green' } }) }} + {{ form_widget(form.submit, { 'attr' : { 'class' : 'btn btn-submit' } }) }}
    • - + {{ form_end(form) }} {% endblock %} diff --git a/src/Bundle/ChillEventBundle/Resources/views/Event/show.html.twig b/src/Bundle/ChillEventBundle/Resources/views/Event/show.html.twig index 4ce92a200..31eaf0df6 100644 --- a/src/Bundle/ChillEventBundle/Resources/views/Event/show.html.twig +++ b/src/Bundle/ChillEventBundle/Resources/views/Event/show.html.twig @@ -1,14 +1,14 @@ {% extends '@ChillEvent/layout.html.twig' %} {% block title 'Event : %label%'|trans({ '%label%' : event.name } ) %} - -{% import 'ChillPersonBundle:Person:macro.html.twig' as person_macro %} + +{% import 'ChillPersonBundle:Person:macro.html.twig' as person_macro %} {% block event_content -%}

      {{ 'Details of an event'|trans }}

      -
      {{ 'Date'|trans }}
      +
      @@ -33,7 +33,7 @@
      {{ 'Name'|trans }}
      - +
        {% set returnPath = app.request.get('return_path') %} @@ -64,13 +64,13 @@
      - +

      {{ 'Participations'|trans }}

      {% set count = event.participations|length %}

      {% transchoice count %}%count% participations to this event{% endtranschoice %}

      - + {% if count > 0 %} - +
      @@ -108,10 +108,10 @@ {% endfor %}
      {{ 'Person'|trans }}
      - - + + {% endif %} - +
        {% if count > 0 %}
      • {{ 'Edit all the participations'|trans }}
      • diff --git a/src/Bundle/ChillEventBundle/Search/EventSearch.php b/src/Bundle/ChillEventBundle/Search/EventSearch.php index a7ac22592..6bb3d435d 100644 --- a/src/Bundle/ChillEventBundle/Search/EventSearch.php +++ b/src/Bundle/ChillEventBundle/Search/EventSearch.php @@ -12,13 +12,14 @@ declare(strict_types=1); namespace Chill\EventBundle\Search; use Chill\EventBundle\Entity\Event; +use Chill\EventBundle\Repository\EventRepository; use Chill\MainBundle\Pagination\PaginatorFactory; use Chill\MainBundle\Search\AbstractSearch; use Chill\MainBundle\Search\SearchInterface; use Chill\MainBundle\Security\Authorization\AuthorizationHelper; -use Doctrine\ORM\EntityRepository; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; +use Symfony\Component\Security\Core\Security; use Symfony\Component\Templating\EngineInterface as TemplatingEngine; use function count; @@ -40,15 +41,17 @@ class EventSearch extends AbstractSearch { public const NAME = 'event_regular'; + private $security; + /** - * @var EntityRepository + * @var EventRepository */ private $er; /** * @var AuthorizationHelper */ - private $helper; + private $authorizationHelper; /** * @var PaginatorFactory @@ -60,21 +63,16 @@ class EventSearch extends AbstractSearch */ private $templating; - /** - * @var \Chill\MainBundle\Entity\User - */ - private $user; - public function __construct( - TokenStorageInterface $tokenStorage, - EntityRepository $eventRepository, + Security $security, + EventRepository $eventRepository, AuthorizationHelper $authorizationHelper, TemplatingEngine $templating, PaginatorFactory $paginatorFactory ) { - $this->user = $tokenStorage->getToken()->getUser(); + $this->security = $security; $this->er = $eventRepository; - $this->helper = $authorizationHelper; + $this->authorizationHelper = $authorizationHelper; $this->templating = $templating; $this->paginationFactory = $paginatorFactory; } @@ -101,7 +99,7 @@ class EventSearch extends AbstractSearch if ('html' === $format) { return $this->templating->render( - 'ChillEventBundle:Event:list.html.twig', + '@ChillEvent/Event/list.html.twig', [ 'events' => $this->search($terms, $start, $limit, $options), 'pattern' => $this->recomposePattern($terms, $this->getAvailableTerms(), $terms['_domain']), @@ -140,8 +138,10 @@ class EventSearch extends AbstractSearch protected function composeQuery(QueryBuilder &$qb, $terms) { // add security clauses - $reachableCenters = $this->helper - ->getReachableCenters($this->user, 'CHILL_EVENT_SEE'); + $reachableCenters = $this->authorizationHelper->getReachableCenters( + $this->security->getUser(), + 'CHILL_EVENT_SEE' + ); if (count($reachableCenters) === 0) { // add a clause to block all events @@ -152,8 +152,9 @@ class EventSearch extends AbstractSearch $orWhere = $qb->expr()->orX(); foreach ($reachableCenters as $center) { - $circles = $this->helper->getReachableScopes( - $this->user, + $n = $n+1; + $circles = $this->authorizationHelper->getReachableScopes( + $this->security->getUser(), 'CHILL_EVENT_SEE', $center ); diff --git a/src/Bundle/ChillEventBundle/config/services/repositories.yaml b/src/Bundle/ChillEventBundle/config/services/repositories.yaml index 4d627f625..ff20d094e 100644 --- a/src/Bundle/ChillEventBundle/config/services/repositories.yaml +++ b/src/Bundle/ChillEventBundle/config/services/repositories.yaml @@ -17,7 +17,7 @@ services: factory: ['@doctrine.orm.entity_manager', getRepository] arguments: - 'Chill\EventBundle\Entity\Role' - + chill_event.repository.status: class: Doctrine\ORM\EntityRepository factory: ['@doctrine.orm.entity_manager', getRepository] diff --git a/src/Bundle/ChillEventBundle/config/services/search.yaml b/src/Bundle/ChillEventBundle/config/services/search.yaml index 2df3db26f..5c55fc388 100644 --- a/src/Bundle/ChillEventBundle/config/services/search.yaml +++ b/src/Bundle/ChillEventBundle/config/services/search.yaml @@ -1,12 +1,11 @@ services: - chill_event.search_events: - class: Chill\EventBundle\Search\EventSearch + Chill\EventBundle\Search\EventSearch: arguments: - - "@security.token_storage" - - "@chill_event.repository.event" - - "@chill.main.security.authorization.helper" - - "@templating" - - "@chill_main.paginator_factory" + $security: '@Symfony\Component\Security\Core\Security' + $eventRepository: "@chill_event.repository.event" + $authorizationHelper: "@chill.main.security.authorization.helper" + $templating: "@templating" + $paginatorFactory: "@chill_main.paginator_factory" tags: - { name: chill.search, alias: 'event_regular' } - + diff --git a/src/Bundle/ChillEventBundle/translations/messages.fr.yml b/src/Bundle/ChillEventBundle/translations/messages.fr.yml index 8810c040a..6b6ac220f 100644 --- a/src/Bundle/ChillEventBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillEventBundle/translations/messages.fr.yml @@ -30,7 +30,7 @@ The event was created: L'événement a été créé #crud participation Edit all the participations: Modifier toutes les participations -Edit the participation: Modifier la participation +Edit the participation: Modifier la participation à l'événement Participation Edit: Modifier une participation Add a participation: Ajouter un participant Participation creation: Ajouter une participation From cdaca533a02967ef36301564446da12b8f5ec2b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 25 Apr 2023 17:37:27 +0200 Subject: [PATCH 014/321] Feature: [export] allow to check multiple geographical layers in geographical aggregators BC: saved exports which activated this layers won't work any more. This is the query to find them: ```sql SELECT * FROM chill_main_saved_export WHERE options->'export'->'export'->'aggregators'->'accompanyingcourse_geographicalunitstat_aggregator'->>'enabled' = '1' ``` --- .../GeographicalUnitStatAggregator.php | 4 +++- .../PersonAggregators/GeographicalUnitAggregator.php | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/GeographicalUnitStatAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/GeographicalUnitStatAggregator.php index 80781b823..6f10dbaa7 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/GeographicalUnitStatAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/GeographicalUnitStatAggregator.php @@ -98,7 +98,7 @@ final class GeographicalUnitStatAggregator implements AggregatorInterface 'acp_geog_units' ); - $qb->andWhere($qb->expr()->eq('acp_geog_units.layer', ':acp_geog_unit_layer')); + $qb->andWhere($qb->expr()->in('acp_geog_units.layer', ':acp_geog_unit_layer')); $qb->setParameter('acp_geog_unit_layer', $data['level']); @@ -131,6 +131,8 @@ final class GeographicalUnitStatAggregator implements AggregatorInterface 'choice_label' => function (GeographicalUnitLayer $item) { return $this->translatableStringHelper->localize($item->getName()); }, + 'multiple' => true, + 'expanded' => true, ]); } diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/GeographicalUnitAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/GeographicalUnitAggregator.php index 6193f3c61..9d34edfca 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/GeographicalUnitAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/GeographicalUnitAggregator.php @@ -103,6 +103,8 @@ class GeographicalUnitAggregator implements AggregatorInterface 'choice_label' => function (GeographicalUnitLayer $item) { return $this->translatableStringHelper->localize($item->getName()); }, + 'multiple' => true, + 'expanded' => true, ]); } From ba43b6b02579406da96131827ccb749567f59016 Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Tue, 25 Apr 2023 15:41:28 +0200 Subject: [PATCH 015/321] Fix: align ux design styles to chill theme --- .../views/Button/button_group.html.twig | 2 +- .../AccompanyingCourseWork/_item.html.twig | 2 +- .../_objectifs_results_evaluations.html.twig | 17 +++++++++-------- .../views/AccompanyingCourseWork/show.html.twig | 11 +++++------ ...owEvaluationDocumentInNotification.html.twig | 17 +++++++++-------- .../showInNotification.html.twig | 2 +- 6 files changed, 26 insertions(+), 25 deletions(-) diff --git a/src/Bundle/ChillDocStoreBundle/Resources/views/Button/button_group.html.twig b/src/Bundle/ChillDocStoreBundle/Resources/views/Button/button_group.html.twig index f83cafd51..2babe1ad9 100644 --- a/src/Bundle/ChillDocStoreBundle/Resources/views/Button/button_group.html.twig +++ b/src/Bundle/ChillDocStoreBundle/Resources/views/Button/button_group.html.twig @@ -1,5 +1,5 @@ {%- import "@ChillDocStore/Macro/macro.html.twig" as m -%} -
        {% if displayNotification is defined and displayNotification == true %}
      • - diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/_objectifs_results_evaluations.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/_objectifs_results_evaluations.html.twig index e66dde463..4ab0b6e08 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/_objectifs_results_evaluations.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/_objectifs_results_evaluations.html.twig @@ -118,9 +118,7 @@
      • {% endif %} {% endif %} -
      -
    {% if recordAction is defined %} @@ -136,16 +134,19 @@ {% import "@ChillDocStore/Macro/macro.html.twig" as m %} {% import "@ChillDocStore/Macro/macro_mimeicon.html.twig" as mm %} {% if e.documents|length > 0 %} - - +
    {% for d in e.documents %} - + - - {% endfor %}
    {{ d.title }} {{ mm.mimeIcon(d.storedObject.type) }} - + + + {{ d.storedObject|chill_document_button_group(d.title, is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_UPDATE', w), {'small': true}) }} {{ d.storedObject|chill_document_button_group(d.title, is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_UPDATE', w), {'small': true}) }}
    diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/show.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/show.html.twig index 96b47e6c9..8d508539d 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/show.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/show.html.twig @@ -35,7 +35,6 @@ {{ 'Back to the list'|trans }} -
  • {{ macro.workflowButton(work) }}
  • {% if accompanyingCourse.hasUser and accompanyingCourse.user is not same as(app.user) %} @@ -46,21 +45,21 @@ {{ 'notification.Notify referrer'|trans }}
  • - "{{ 'notification.Notify any'|trans }}" + {{ 'notification.Notify any'|trans }}
  • {% else %} - + - {% endif %} +
  • {{ macro.workflowButton(work) }}
  • {% if is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_UPDATE', work) %}
  • - + >{{ 'Edit'|trans }}
  • {% endif %} {% if is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_DELETE', work) %} diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showEvaluationDocumentInNotification.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showEvaluationDocumentInNotification.html.twig index 6d5d22a7d..4ea70d9f0 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showEvaluationDocumentInNotification.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showEvaluationDocumentInNotification.html.twig @@ -1,23 +1,24 @@ {% macro recordAction(document) %} {% import "@ChillDocStore/Macro/macro_mimeicon.html.twig" as mm %}
    - - +
    - - - + + + title="{{ 'See the document'|trans }}"> +
    {{ document.title }}{{ mm.mimeIcon(document.storedObject.type) }}{{ document.title }}{{ mm.mimeIcon(document.storedObject.type) }} +
    {% endmacro %} {% if document is not null %} -
    +
    {% if is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_EVALUATION_DOCUMENT_SHOW', document) %} -
    +
    {% include '@ChillPerson/AccompanyingCourseWork/_objectifs_results_evaluations.html.twig' with { 'w': document.accompanyingPeriodWorkEvaluation.accompanyingPeriodWork, 'd': document.storedObject, diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showInNotification.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showInNotification.html.twig index 9b06e306c..fdafcc040 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showInNotification.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showInNotification.html.twig @@ -6,7 +6,7 @@ {% endmacro %} {% if work is not null %} -
    +
    {% if is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_SEE', work) %} {% include "@ChillPerson/AccompanyingCourseWork/_item.html.twig" with { 'itemBlocClass': 'bg-chill-llight-gray', From 67b32341d17209061c2c00f3527338df71862027 Mon Sep 17 00:00:00 2001 From: Lucas Silva Date: Thu, 27 Apr 2023 10:58:31 +0200 Subject: [PATCH 016/321] adding referer in list action --- .../AccompanyingCourseWork/_item.html.twig | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/_item.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/_item.html.twig index 7891d8cd4..4c056eec5 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/_item.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/_item.html.twig @@ -133,10 +133,23 @@
      {% if displayNotification is defined and displayNotification == true %}
    • - - - +
      + {% if accompanyingCourse.hasUser and accompanyingCourse.user is not same as(app.user) %} + + + {% else %} + + + {% endif %} +
    • {% endif %}
    • {{ macro.workflowButton(w) }}
    • From 0a2f41c8a0acd6587638a93b2a44f4859c28618b Mon Sep 17 00:00:00 2001 From: Lucas Silva Date: Thu, 27 Apr 2023 10:59:09 +0200 Subject: [PATCH 017/321] adding button notification in edit view of a work. --- .../vuejs/AccompanyingCourseWorkEdit/App.vue | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/App.vue b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/App.vue index 755e4455c..e6ee7de79 100644 --- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/App.vue +++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/App.vue @@ -296,7 +296,13 @@ @go-to-generate-workflow="goToGenerateWorkflow" > - +
    • + +
    diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/_objectifs_results_evaluations.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/_objectifs_results_evaluations.html.twig index 57305095d..fc2891ca6 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/_objectifs_results_evaluations.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/_objectifs_results_evaluations.html.twig @@ -3,6 +3,7 @@ # - displayContent: [short|long] default: short #} {% if w.results|length > 0 %} + @@ -64,9 +65,11 @@ - {% for e in w.accompanyingPeriodWorkEvaluations %} - - + + - - {% endfor %} + + + {% endfor %} + {% endif %}

    {{ 'accompanying_course_work.goal'|trans }}

    + {% if onlyone %} + {% for e in w.accompanyingPeriodWorkEvaluations %} + {% if evalId is defined and evalId == e.id %} +
    • {{ e.evaluation.title|localize_translatable_string }} @@ -78,13 +81,15 @@ {% if e.endDate %}
    • - {{ 'accompanying_course_work.end_date'|trans ~ ' : ' }} + {{ 'accompanying_course_work.end_date'|trans ~ ' : ' }} {{ e.endDate|format_date('short') }}
    • {% else %} {% if displayContent is defined and displayContent == 'long' %}
    • - {{ 'accompanying_course_work.end_date'|trans ~ ' : ' }} + {{ 'accompanying_course_work.end_date'|trans ~ ' : ' }} {{ 'Not given'|trans }}
    • {% endif %} @@ -92,13 +97,15 @@ {% if e.maxDate %}
    • - {{ 'accompanying_course_work.max_date'|trans ~ ' : ' }} + {{ 'accompanying_course_work.max_date'|trans ~ ' : ' }} {{ e.maxDate|format_date('short') }}
    • {% else %} {% if displayContent is defined and displayContent == 'long' %}
    • - {{ 'accompanying_course_work.max_date'|trans ~ ' : ' }} + {{ 'accompanying_course_work.max_date'|trans ~ ' : ' }} {{ 'Not given'|trans }}
    • {% endif %} @@ -107,13 +114,15 @@ {% if e.warningInterval and e.warningInterval.d > 0 %}
    • {% set days = (e.warningInterval.d + e.warningInterval.m * 30) %} - {{ 'accompanying_course_work.warning_interval'|trans ~ ' : ' }} + {{ 'accompanying_course_work.warning_interval'|trans ~ ' : ' }} {{ 'accompanying_course_work.%days% days before max_date'|trans({'%days%': days }) }}
    • {% else %} {% if displayContent is defined and displayContent == 'long' %}
    • - {{ 'accompanying_course_work.warning_interval'|trans ~ ' : ' }} + {{ 'accompanying_course_work.warning_interval'|trans ~ ' : ' }} {{ 'Not given'|trans }}
    • {% endif %} @@ -122,55 +131,145 @@ {% if e.timeSpent is not null and e.timeSpent > 0 %}
    • {% set minutes = (e.timeSpent / 60) %} - {{ 'accompanying_course_work.timeSpent'|trans ~ ' : ' }} {{ 'duration.minute'|trans({ '{m}' : minutes }) }} + {{ 'accompanying_course_work.timeSpent'|trans ~ ' : ' }} {{ 'duration.minute'|trans({ '{m}' : minutes }) }}
    • {% elseif displayContent is defined and displayContent == 'long' %}
    • - {{ 'accompanying_course_work.timeSpent'|trans ~ ' : ' }} + {{ 'accompanying_course_work.timeSpent'|trans ~ ' : ' }} {{ 'Not given'|trans }}
    • {% endif %}
    - {% if recordAction is defined %} - {{ recordAction }} - {% endif %} + {% endif %} - {% if displayContent is defined and displayContent == 'long' %} - {% if e.comment is not empty %} -
    {{ e.comment|chill_entity_render_box }}
    + {% endfor %} + {% if recordAction is defined %} + {{ recordAction }} + {% endif %} + {% else %} + {% for e in w.accompanyingPeriodWorkEvaluations %} +
    +
      +
    • + {{ e.evaluation.title|localize_translatable_string }} +
        +
      • + {{ 'accompanying_course_work.start_date'|trans ~ ' : ' }} + {{ e.startDate|format_date('short') }} +
      • + + {% if e.endDate %} +
      • + {{ 'accompanying_course_work.end_date'|trans ~ ' : ' }} + {{ e.endDate|format_date('short') }} +
      • + {% else %} + {% if displayContent is defined and displayContent == 'long' %} +
      • + {{ 'accompanying_course_work.end_date'|trans ~ ' : ' }} + {{ 'Not given'|trans }} +
      • + {% endif %} + {% endif %} + + {% if e.maxDate %} +
      • + {{ 'accompanying_course_work.max_date'|trans ~ ' : ' }} + {{ e.maxDate|format_date('short') }} +
      • + {% else %} + {% if displayContent is defined and displayContent == 'long' %} +
      • + {{ 'accompanying_course_work.max_date'|trans ~ ' : ' }} + {{ 'Not given'|trans }} +
      • + {% endif %} + {% endif %} + + {% if e.warningInterval and e.warningInterval.d > 0 %} +
      • + {% set days = (e.warningInterval.d + e.warningInterval.m * 30) %} + {{ 'accompanying_course_work.warning_interval'|trans ~ ' : ' }} + {{ 'accompanying_course_work.%days% days before max_date'|trans({'%days%': days }) }} +
      • + {% else %} + {% if displayContent is defined and displayContent == 'long' %} +
      • + {{ 'accompanying_course_work.warning_interval'|trans ~ ' : ' }} + {{ 'Not given'|trans }} +
      • + {% endif %} + {% endif %} + + {% if e.timeSpent is not null and e.timeSpent > 0 %} +
      • + {% set minutes = (e.timeSpent / 60) %} + {{ 'accompanying_course_work.timeSpent'|trans ~ ' : ' }} {{ 'duration.minute'|trans({ '{m}' : minutes }) }} +
      • + {% elseif displayContent is defined and displayContent == 'long' %} +
      • + {{ 'accompanying_course_work.timeSpent'|trans ~ ' : ' }} + {{ 'Not given'|trans }} +
      • + {% endif %} +
      +
    • +
    + {% if recordAction is defined %} + {{ recordAction }} {% endif %} - {% import "@ChillDocStore/Macro/macro.html.twig" as m %} - {% import "@ChillDocStore/Macro/macro_mimeicon.html.twig" as mm %} - {% if e.documents|length > 0 %} - - {% for d in e.documents %} - - - - - - {% endfor %} -
    {{ d.title }}{{ mm.mimeIcon(d.storedObject.type) }} - - {{ d.storedObject|chill_document_button_group(d.title, is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_UPDATE', w), {'small': true}) }} -
    - {% else %} - {{ 'No document found'|trans }} + {% if displayContent is defined and displayContent == 'long' %} + + {% if e.comment is not empty %} +
    {{ e.comment|chill_entity_render_box }}
    + {% endif %} + + {% import "@ChillDocStore/Macro/macro.html.twig" as m %} + {% import "@ChillDocStore/Macro/macro_mimeicon.html.twig" as mm %} + {% if e.documents|length > 0 %} + + {% for d in e.documents %} + + + + + + {% endfor %} +
    {{ d.title }}{{ mm.mimeIcon(d.storedObject.type) }} + + {{ d.storedObject|chill_document_button_group(d.title, is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_UPDATE', w), {'small': true}) }} +
    + {% else %} + {{ 'No document found'|trans }} + {% endif %} + + {% endif %} - - - {% endif %} -
    {% endif %} diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showEvaluationDocumentInNotification.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showEvaluationDocumentInNotification.html.twig index 4ea70d9f0..b4df52254 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showEvaluationDocumentInNotification.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/showEvaluationDocumentInNotification.html.twig @@ -23,7 +23,9 @@ 'w': document.accompanyingPeriodWorkEvaluation.accompanyingPeriodWork, 'd': document.storedObject, 'displayContent': 'short', - 'recordAction': _self.recordAction(document) + 'recordAction': _self.recordAction(document), + 'onlyone' : true, + 'evalId': document.accompanyingPeriodWorkEvaluation.id } %}
    From 1a66a081425475f5aa54559fbac2afa9db9632b7 Mon Sep 17 00:00:00 2001 From: Lucas Silva Date: Thu, 27 Apr 2023 16:01:35 +0200 Subject: [PATCH 019/321] Button in vue edit --- .../components/FormEvaluation.vue | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/components/FormEvaluation.vue b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/components/FormEvaluation.vue index 7dcb595a3..6d40acae5 100644 --- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/components/FormEvaluation.vue +++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/components/FormEvaluation.vue @@ -103,6 +103,11 @@
      + +
    • + +
    • { console.log(e); throw e; }); }, + goToGenerateDocumentNotification(document){ + const callback = (data) => { + let evaluation = data.accompanyingPeriodWorkEvaluations.find(e => e.key === this.evaluation.key); + window.location.assign(`/fr/notification/create?entityClass=Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluationDocument&entityId=${document.id}&returnPath=/fr/person/accompanying-period/work/${evaluation.id}/edit`) + }; + return this.$store.dispatch('submit', callback) + .catch(e => {console.log(e); throw e}); + } }, } From f2e1c73f37be6a78a1786fe0ddd9629c2babfc0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 18 Apr 2023 21:16:40 +0200 Subject: [PATCH 020/321] Build parts to track info on accompanying period --- .../ChillMainBundle/ChillMainBundle.php | 3 + .../SynchronizeEntityInfoViewsCommand.php | 40 ++++++++++ .../EntityInfo/ViewEntityInfoManager.php | 48 +++++++++++ .../ViewEntityInfoProviderInterface.php | 19 +++++ .../ChillMainBundle/config/services.yaml | 4 + .../config/services/command.yaml | 4 + .../ChillPersonBundle/ChillPersonBundle.php | 3 + .../AccompanyingPeriodInfo.php | 79 +++++++++++++++++++ .../AccompanyingPeriodInfoQueryBuilder.php | 49 ++++++++++++ ...kEndQueryPartForAccompanyingPeriodInfo.php | 64 +++++++++++++++ ...tartQueryPartForAccompanyingPeriodInfo.php | 64 +++++++++++++++ ...nyingPeriodInfoUnionQueryPartInterface.php | 36 +++++++++ ...companyingPeriodViewEntityInfoProvider.php | 42 ++++++++++ .../ChillPersonBundle/config/services.yaml | 4 + 14 files changed, 459 insertions(+) create mode 100644 src/Bundle/ChillMainBundle/Command/SynchronizeEntityInfoViewsCommand.php create mode 100644 src/Bundle/ChillMainBundle/Service/EntityInfo/ViewEntityInfoManager.php create mode 100644 src/Bundle/ChillMainBundle/Service/EntityInfo/ViewEntityInfoProviderInterface.php create mode 100644 src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/AccompanyingPeriodInfo.php create mode 100644 src/Bundle/ChillPersonBundle/Service/EntityInfo/AccompanyingPeriodInfoQueryBuilder.php create mode 100644 src/Bundle/ChillPersonBundle/Service/EntityInfo/AccompanyingPeriodInfoQueryPart/AccompanyingPeriodWorkEndQueryPartForAccompanyingPeriodInfo.php create mode 100644 src/Bundle/ChillPersonBundle/Service/EntityInfo/AccompanyingPeriodInfoQueryPart/AccompanyingPeriodWorkStartQueryPartForAccompanyingPeriodInfo.php create mode 100644 src/Bundle/ChillPersonBundle/Service/EntityInfo/AccompanyingPeriodInfoUnionQueryPartInterface.php create mode 100644 src/Bundle/ChillPersonBundle/Service/EntityInfo/AccompanyingPeriodViewEntityInfoProvider.php diff --git a/src/Bundle/ChillMainBundle/ChillMainBundle.php b/src/Bundle/ChillMainBundle/ChillMainBundle.php index 9e276311d..8e115fa4f 100644 --- a/src/Bundle/ChillMainBundle/ChillMainBundle.php +++ b/src/Bundle/ChillMainBundle/ChillMainBundle.php @@ -30,6 +30,7 @@ use Chill\MainBundle\Search\SearchApiInterface; use Chill\MainBundle\Security\ProvideRoleInterface; use Chill\MainBundle\Security\Resolver\CenterResolverInterface; use Chill\MainBundle\Security\Resolver\ScopeResolverInterface; +use Chill\MainBundle\Service\EntityInfo\ViewEntityInfoProviderInterface; use Chill\MainBundle\Templating\Entity\ChillEntityRenderInterface; use Chill\MainBundle\Templating\UI\NotificationCounterInterface; use Chill\MainBundle\Workflow\EntityWorkflowHandlerInterface; @@ -62,6 +63,8 @@ class ChillMainBundle extends Bundle ->addTag('chill_main.workflow_handler'); $container->registerForAutoconfiguration(CronJobInterface::class) ->addTag('chill_main.cron_job'); + $container->registerForAutoconfiguration(ViewEntityInfoProviderInterface::class) + ->addTag('chill_main.entity_info_provider'); $container->addCompilerPass(new SearchableServicesCompilerPass()); $container->addCompilerPass(new ConfigConsistencyCompilerPass()); diff --git a/src/Bundle/ChillMainBundle/Command/SynchronizeEntityInfoViewsCommand.php b/src/Bundle/ChillMainBundle/Command/SynchronizeEntityInfoViewsCommand.php new file mode 100644 index 000000000..c3dc8a87c --- /dev/null +++ b/src/Bundle/ChillMainBundle/Command/SynchronizeEntityInfoViewsCommand.php @@ -0,0 +1,40 @@ +setDescription('Update or create sql views which provide info for various entities'); + } + + protected function execute(InputInterface $input, OutputInterface $output): int + { + $this->viewEntityInfoManager->synchronizeOnDB(); + + return 0; + } + +} diff --git a/src/Bundle/ChillMainBundle/Service/EntityInfo/ViewEntityInfoManager.php b/src/Bundle/ChillMainBundle/Service/EntityInfo/ViewEntityInfoManager.php new file mode 100644 index 000000000..6b7b81224 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Service/EntityInfo/ViewEntityInfoManager.php @@ -0,0 +1,48 @@ +connection->transactional(function (Connection $conn): void { + foreach ($this->vienEntityInfoProviders as $viewProvider) { + foreach ($this->createOrReplaceViewSQL($viewProvider, $viewProvider->getViewName()) as $sql) { + $conn->executeQuery($sql); + } + } + }); + } + + /** + * @return array + */ + private function createOrReplaceViewSQL(ViewEntityInfoProviderInterface $viewProvider, string $viewName): array + { + return [ + "DROP VIEW IF EXISTS {$viewName}", + sprintf("CREATE VIEW {$viewName} AS %s", $viewProvider->getViewQuery()) + ]; + } +} diff --git a/src/Bundle/ChillMainBundle/Service/EntityInfo/ViewEntityInfoProviderInterface.php b/src/Bundle/ChillMainBundle/Service/EntityInfo/ViewEntityInfoProviderInterface.php new file mode 100644 index 000000000..392c0f82c --- /dev/null +++ b/src/Bundle/ChillMainBundle/Service/EntityInfo/ViewEntityInfoProviderInterface.php @@ -0,0 +1,19 @@ +addWidgetFactory(new PersonListWidgetFactory()); $container->addCompilerPass(new AccompanyingPeriodTimelineCompilerPass()); + $container->registerForAutoconfiguration(AccompanyingPeriodInfoUnionQueryPartInterface::class) + ->addTag('chill_person.accompanying_period_info_part'); } } diff --git a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/AccompanyingPeriodInfo.php b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/AccompanyingPeriodInfo.php new file mode 100644 index 000000000..795247eda --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/AccompanyingPeriodInfo.php @@ -0,0 +1,79 @@ + $query->getAccompanyingPeriodIdColumn(), + '{related_entity_column_id}' => $query->getRelatedEntityColumn(), + '{related_entity_id_column_id}' => $query->getRelatedEntityIdColumn(), + '{user_id}' => $query->getUserIdColumn(), + '{datetime}' => $query->getDateTimeColumn(), + '{discriminator}' => $query->getDiscriminator(), + '{metadata}' => $query->getMetadataColumn(), + '{from_statement}' => $query->getFromStatement(), + '{where_statement}' => '' === $query->getWhereClause() ? '' : 'WHERE '.$query->getWhereClause(), + ] + ); + } +} diff --git a/src/Bundle/ChillPersonBundle/Service/EntityInfo/AccompanyingPeriodInfoQueryPart/AccompanyingPeriodWorkEndQueryPartForAccompanyingPeriodInfo.php b/src/Bundle/ChillPersonBundle/Service/EntityInfo/AccompanyingPeriodInfoQueryPart/AccompanyingPeriodWorkEndQueryPartForAccompanyingPeriodInfo.php new file mode 100644 index 000000000..8ba9b9640 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Service/EntityInfo/AccompanyingPeriodInfoQueryPart/AccompanyingPeriodWorkEndQueryPartForAccompanyingPeriodInfo.php @@ -0,0 +1,64 @@ + $this->builder->buildQuery($part), + iterator_to_array($this->unions) + ) + ); + } + + public function getViewName(): string + { + return 'view_chill_person_accompanying_period_info'; + } +} diff --git a/src/Bundle/ChillPersonBundle/config/services.yaml b/src/Bundle/ChillPersonBundle/config/services.yaml index f989b5dda..45548d843 100644 --- a/src/Bundle/ChillPersonBundle/config/services.yaml +++ b/src/Bundle/ChillPersonBundle/config/services.yaml @@ -98,3 +98,7 @@ services: autowire: true autoconfigure: true resource: '../Workflow/' + + Chill\PersonBundle\Service\EntityInfo\AccompanyingPeriodViewEntityInfoProvider: + arguments: + $unions: !tagged_iterator chill_person.accompanying_period_info_part From 4974995ea2f4e4f89adf2619c799c0a7d6cc9fa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 19 Apr 2023 17:32:32 +0200 Subject: [PATCH 021/321] Feature: add evaluation info to accompangyin preiod info --- ...nMaxQueryPartForAccompanyingPeriodInfo.php | 66 +++++++++++++++++++ ...tartQueryPartForAccompanyingPeriodInfo.php | 66 +++++++++++++++++++ ...DateQueryPartForAccompanyingPeriodInfo.php | 65 ++++++++++++++++++ 3 files changed, 197 insertions(+) create mode 100644 src/Bundle/ChillPersonBundle/Service/EntityInfo/AccompanyingPeriodInfoQueryPart/AccompanyingPeriodWorkEvaluationMaxQueryPartForAccompanyingPeriodInfo.php create mode 100644 src/Bundle/ChillPersonBundle/Service/EntityInfo/AccompanyingPeriodInfoQueryPart/AccompanyingPeriodWorkEvaluationStartQueryPartForAccompanyingPeriodInfo.php create mode 100644 src/Bundle/ChillPersonBundle/Service/EntityInfo/AccompanyingPeriodInfoQueryPart/AccompanyingPeriodWorkEvaluationWarningDateQueryPartForAccompanyingPeriodInfo.php diff --git a/src/Bundle/ChillPersonBundle/Service/EntityInfo/AccompanyingPeriodInfoQueryPart/AccompanyingPeriodWorkEvaluationMaxQueryPartForAccompanyingPeriodInfo.php b/src/Bundle/ChillPersonBundle/Service/EntityInfo/AccompanyingPeriodInfoQueryPart/AccompanyingPeriodWorkEvaluationMaxQueryPartForAccompanyingPeriodInfo.php new file mode 100644 index 000000000..b89f77460 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Service/EntityInfo/AccompanyingPeriodInfoQueryPart/AccompanyingPeriodWorkEvaluationMaxQueryPartForAccompanyingPeriodInfo.php @@ -0,0 +1,66 @@ + Date: Thu, 20 Apr 2023 12:41:04 +0200 Subject: [PATCH 022/321] Feature: takes document and evaluation update into account for AccompanyingPeriodInfo --- ...dateQueryPartForAccompanyingPeriodInfo.php | 65 ++++++++++++++++++ ...dateQueryPartForAccompanyingPeriodInfo.php | 67 +++++++++++++++++++ ...DateQueryPartForAccompanyingPeriodInfo.php | 2 +- 3 files changed, 133 insertions(+), 1 deletion(-) create mode 100644 src/Bundle/ChillPersonBundle/Service/EntityInfo/AccompanyingPeriodInfoQueryPart/AccompanyingPeriodWorkEvaluationDocumentUpdateQueryPartForAccompanyingPeriodInfo.php create mode 100644 src/Bundle/ChillPersonBundle/Service/EntityInfo/AccompanyingPeriodInfoQueryPart/AccompanyingPeriodWorkEvaluationUpdateQueryPartForAccompanyingPeriodInfo.php diff --git a/src/Bundle/ChillPersonBundle/Service/EntityInfo/AccompanyingPeriodInfoQueryPart/AccompanyingPeriodWorkEvaluationDocumentUpdateQueryPartForAccompanyingPeriodInfo.php b/src/Bundle/ChillPersonBundle/Service/EntityInfo/AccompanyingPeriodInfoQueryPart/AccompanyingPeriodWorkEvaluationDocumentUpdateQueryPartForAccompanyingPeriodInfo.php new file mode 100644 index 000000000..68d761cc2 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Service/EntityInfo/AccompanyingPeriodInfoQueryPart/AccompanyingPeriodWorkEvaluationDocumentUpdateQueryPartForAccompanyingPeriodInfo.php @@ -0,0 +1,65 @@ + Date: Thu, 20 Apr 2023 16:22:16 +0200 Subject: [PATCH 023/321] Feature: takes activity into account for AccompanyingPeriodInfo --- ...DateQueryPartForAccompanyingPeriodInfo.php | 64 +++++++++++++++++++ .../ChillActivityBundle/config/services.yaml | 5 +- .../Entity/AccompanyingPeriod.php | 9 +++ 3 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 src/Bundle/ChillActivityBundle/Service/EntityInfo/AccompanyingPeriodInfoQueryPart/ActivityUsersDateQueryPartForAccompanyingPeriodInfo.php diff --git a/src/Bundle/ChillActivityBundle/Service/EntityInfo/AccompanyingPeriodInfoQueryPart/ActivityUsersDateQueryPartForAccompanyingPeriodInfo.php b/src/Bundle/ChillActivityBundle/Service/EntityInfo/AccompanyingPeriodInfoQueryPart/ActivityUsersDateQueryPartForAccompanyingPeriodInfo.php new file mode 100644 index 000000000..bb70d6e87 --- /dev/null +++ b/src/Bundle/ChillActivityBundle/Service/EntityInfo/AccompanyingPeriodInfoQueryPart/ActivityUsersDateQueryPartForAccompanyingPeriodInfo.php @@ -0,0 +1,64 @@ + Date: Fri, 21 Apr 2023 14:59:04 +0200 Subject: [PATCH 024/321] Feature: Change accompanying period info step in a cronjob --- composer.json | 1 + .../ChillMainBundle/config/services.yaml | 3 + .../config/services/clock.yaml | 4 + .../AccompanyingPeriodStepChangeCronjob.php | 46 +++++++++ ...mpanyingPeriodStepChangeMessageHandler.php | 38 ++++++++ ...mpanyingPeriodStepChangeRequestMessage.php | 47 ++++++++++ .../AccompanyingPeriodStepChangeRequestor.php | 88 ++++++++++++++++++ .../AccompanyingPeriodStepChanger.php | 58 ++++++++++++ .../ChillPersonExtension.php | 39 ++++++-- .../DependencyInjection/Configuration.php | 9 ++ .../Entity/AccompanyingPeriod.php | 11 ++- .../AccompanyingPeriodInfoRepository.php | 93 +++++++++++++++++++ ...ompanyingPeriodInfoRepositoryInterface.php | 38 ++++++++ ...ccompanyingPeriodStepChangeCronjobTest.php | 55 +++++++++++ .../config/services/accompanyingPeriod.yaml | 5 + 15 files changed, 527 insertions(+), 8 deletions(-) create mode 100644 src/Bundle/ChillMainBundle/config/services/clock.yaml create mode 100644 src/Bundle/ChillPersonBundle/AccompanyingPeriod/Lifecycle/AccompanyingPeriodStepChangeCronjob.php create mode 100644 src/Bundle/ChillPersonBundle/AccompanyingPeriod/Lifecycle/AccompanyingPeriodStepChangeMessageHandler.php create mode 100644 src/Bundle/ChillPersonBundle/AccompanyingPeriod/Lifecycle/AccompanyingPeriodStepChangeRequestMessage.php create mode 100644 src/Bundle/ChillPersonBundle/AccompanyingPeriod/Lifecycle/AccompanyingPeriodStepChangeRequestor.php create mode 100644 src/Bundle/ChillPersonBundle/AccompanyingPeriod/Lifecycle/AccompanyingPeriodStepChanger.php create mode 100644 src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/AccompanyingPeriodInfoRepository.php create mode 100644 src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/AccompanyingPeriodInfoRepositoryInterface.php create mode 100644 src/Bundle/ChillPersonBundle/Tests/AccompanyingPeriod/Lifecycle/AccompanyingPeriodStepChangeCronjobTest.php diff --git a/composer.json b/composer.json index b47856954..f6d3eb27a 100644 --- a/composer.json +++ b/composer.json @@ -34,6 +34,7 @@ "sensio/framework-extra-bundle": "^5.5", "spomky-labs/base64url": "^2.0", "symfony/browser-kit": "^4.4", + "symfony/clock": "^6.2", "symfony/css-selector": "^4.4", "symfony/expression-language": "^4.4", "symfony/form": "^4.4", diff --git a/src/Bundle/ChillMainBundle/config/services.yaml b/src/Bundle/ChillMainBundle/config/services.yaml index 54153ccfb..5976cb8b0 100644 --- a/src/Bundle/ChillMainBundle/config/services.yaml +++ b/src/Bundle/ChillMainBundle/config/services.yaml @@ -1,6 +1,9 @@ parameters: # cl_chill_main.example.class: Chill\MainBundle\Example +imports: + - ./services/clock.yaml + services: _defaults: autowire: true diff --git a/src/Bundle/ChillMainBundle/config/services/clock.yaml b/src/Bundle/ChillMainBundle/config/services/clock.yaml new file mode 100644 index 000000000..0629cd869 --- /dev/null +++ b/src/Bundle/ChillMainBundle/config/services/clock.yaml @@ -0,0 +1,4 @@ +# temporary, waiting for symfony 6.0 to load clock +services: + Symfony\Component\Clock\NativeClock: ~ + Symfony\Component\Clock\ClockInterface: '@Symfony\Component\Clock\NativeClock' diff --git a/src/Bundle/ChillPersonBundle/AccompanyingPeriod/Lifecycle/AccompanyingPeriodStepChangeCronjob.php b/src/Bundle/ChillPersonBundle/AccompanyingPeriod/Lifecycle/AccompanyingPeriodStepChangeCronjob.php new file mode 100644 index 000000000..bec31d45d --- /dev/null +++ b/src/Bundle/ChillPersonBundle/AccompanyingPeriod/Lifecycle/AccompanyingPeriodStepChangeCronjob.php @@ -0,0 +1,46 @@ +clock->now(); + + if ($now->sub(new \DateInterval('P1D')) < $cronJobExecution->getLastStart()) { + return false; + } + + return in_array((int) $now->format('H'), [1, 2, 3, 4, 5, 6], true); + } + + public function getKey(): string + { + return 'accompanying-period-step-change'; + } + + public function run(): void + { + ($this->requestor)(); + } +} diff --git a/src/Bundle/ChillPersonBundle/AccompanyingPeriod/Lifecycle/AccompanyingPeriodStepChangeMessageHandler.php b/src/Bundle/ChillPersonBundle/AccompanyingPeriod/Lifecycle/AccompanyingPeriodStepChangeMessageHandler.php new file mode 100644 index 000000000..881b3999a --- /dev/null +++ b/src/Bundle/ChillPersonBundle/AccompanyingPeriod/Lifecycle/AccompanyingPeriodStepChangeMessageHandler.php @@ -0,0 +1,38 @@ +accompanyingPeriodRepository->find($message->getPeriodId())) { + throw new \RuntimeException(self::LOG_PREFIX . 'Could not find period with this id: '. $message->getPeriodId()); + } + + ($this->changer)($period, $message->getTransition()); + } + +} diff --git a/src/Bundle/ChillPersonBundle/AccompanyingPeriod/Lifecycle/AccompanyingPeriodStepChangeRequestMessage.php b/src/Bundle/ChillPersonBundle/AccompanyingPeriod/Lifecycle/AccompanyingPeriodStepChangeRequestMessage.php new file mode 100644 index 000000000..457e78d35 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/AccompanyingPeriod/Lifecycle/AccompanyingPeriodStepChangeRequestMessage.php @@ -0,0 +1,47 @@ +periodId = $period; + } else { + if (null !== $id = $period->getId()) { + $this->periodId = $id; + } + + throw new \LogicException("This AccompanyingPeriod does not have and id yet"); + } + } + + public function getPeriodId(): int + { + return $this->periodId; + } + + public function getTransition(): string + { + return $this->transition; + } +} diff --git a/src/Bundle/ChillPersonBundle/AccompanyingPeriod/Lifecycle/AccompanyingPeriodStepChangeRequestor.php b/src/Bundle/ChillPersonBundle/AccompanyingPeriod/Lifecycle/AccompanyingPeriodStepChangeRequestor.php new file mode 100644 index 000000000..3d4979608 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/AccompanyingPeriod/Lifecycle/AccompanyingPeriodStepChangeRequestor.php @@ -0,0 +1,88 @@ +get('chill_person')['accompanying_period_lifecycle_delays']; + $this->isMarkInactive = $config['mark_inactive']; + $this->intervalForShortInactive = new \DateInterval($config['mark_inactive_short_after']); + $this->intervalForLongInactive = new \DateInterval($config['mark_inactive_long_after']); + } + + public function __invoke(): void + { + if (!$this->isMarkInactive) { + return; + } + + // get the oldest ones first + foreach ( + $olders = $this->accompanyingPeriodInfoRepository->findAccompanyingPeriodIdInactiveAfter( + $this->intervalForLongInactive, + [AccompanyingPeriod::STEP_CONFIRMED, AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_SHORT] + ) as $accompanyingPeriodId + ) { + $this->logger->debug('request mark period as inactive_short', ['period' => $accompanyingPeriodId]); + $this->messageBus->dispatch(new AccompanyingPeriodStepChangeRequestMessage($accompanyingPeriodId, 'mark_inactive_long')); + } + + // the newest + foreach ( + $this->accompanyingPeriodInfoRepository->findAccompanyingPeriodIdInactiveAfter( + $this->intervalForShortInactive, + [AccompanyingPeriod::STEP_CONFIRMED] + ) as $accompanyingPeriodId + ) { + if (in_array($accompanyingPeriodId, $olders, true)) { + continue; + } + + $this->logger->debug('request mark period as inactive_long', ['period' => $accompanyingPeriodId]); + $this->messageBus->dispatch(new AccompanyingPeriodStepChangeRequestMessage($accompanyingPeriodId, 'mark_inactive_short')); + } + + // a new event has been created => remove inactive long, or short + foreach ( + $this->accompanyingPeriodInfoRepository->findAccompanyingPeriodIdActiveSince( + $this->intervalForShortInactive, + [AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_SHORT, AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_LONG] + ) as $accompanyingPeriodId + ) { + $this->logger->debug('request mark period as active', ['period' => $accompanyingPeriodId]); + $this->messageBus->dispatch(new AccompanyingPeriodStepChangeRequestMessage($accompanyingPeriodId, 'mark_active')); + } + } + +} diff --git a/src/Bundle/ChillPersonBundle/AccompanyingPeriod/Lifecycle/AccompanyingPeriodStepChanger.php b/src/Bundle/ChillPersonBundle/AccompanyingPeriod/Lifecycle/AccompanyingPeriodStepChanger.php new file mode 100644 index 000000000..05dfee6db --- /dev/null +++ b/src/Bundle/ChillPersonBundle/AccompanyingPeriod/Lifecycle/AccompanyingPeriodStepChanger.php @@ -0,0 +1,58 @@ +workflowRegistry->get($period, $workflowName); + + if (!$workflow->can($period, $transition)) { + $this->logger->info(self::LOG_PREFIX . 'not able to apply the transition on period', [ + 'period_id' => $period->getId(), + 'transition' => $transition + ]); + + return; + } + + $workflow->apply($period, $transition); + + $this->entityManager->flush(); + + $this->logger->info(self::LOG_PREFIX . 'could apply a transition', [ + 'period_id' => $period->getId(), + 'transition' => $transition + ]); + } +} diff --git a/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php b/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php index 6a2dc924e..569dd1502 100644 --- a/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php +++ b/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php @@ -15,6 +15,7 @@ use Chill\MainBundle\DependencyInjection\MissingBundleException; use Chill\MainBundle\Security\Authorization\ChillExportVoter; use Chill\PersonBundle\Controller\HouseholdCompositionTypeApiController; use Chill\PersonBundle\Doctrine\DQL\AddressPart; +use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodCommentVoter; use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodResourceVoter; use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter; @@ -1010,18 +1011,42 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac ], 'initial_marking' => 'DRAFT', 'places' => [ - 'DRAFT', - 'CONFIRMED', - 'CLOSED', + AccompanyingPeriod::STEP_DRAFT, + AccompanyingPeriod::STEP_CONFIRMED, + AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_SHORT, + AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_LONG, + AccompanyingPeriod::STEP_CLOSED, ], 'transitions' => [ 'confirm' => [ - 'from' => 'DRAFT', - 'to' => 'CONFIRMED', + 'from' => AccompanyingPeriod::STEP_DRAFT, + 'to' => AccompanyingPeriod::STEP_CONFIRMED, + ], + 'mark_inactive_short' => [ + 'from' => AccompanyingPeriod::STEP_CONFIRMED, + 'to' => AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_SHORT, + ], + 'mark_inactive_long' => [ + 'from' => [ + AccompanyingPeriod::STEP_CONFIRMED, + AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_SHORT + ], + 'to' => AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_LONG, + ], + 'mark_active' => [ + 'from' => [ + AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_LONG, + AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_SHORT, + ], + 'to' => AccompanyingPeriod::STEP_CONFIRMED ], 'close' => [ - 'from' => 'CONFIRMED', - 'to' => 'CLOSED', + 'from' => [ + AccompanyingPeriod::STEP_CONFIRMED, + AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_SHORT, + AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_LONG, + ], + 'to' => AccompanyingPeriod::STEP_CLOSED, ], ], ], diff --git a/src/Bundle/ChillPersonBundle/DependencyInjection/Configuration.php b/src/Bundle/ChillPersonBundle/DependencyInjection/Configuration.php index a591663ad..64ca07066 100644 --- a/src/Bundle/ChillPersonBundle/DependencyInjection/Configuration.php +++ b/src/Bundle/ChillPersonBundle/DependencyInjection/Configuration.php @@ -128,6 +128,15 @@ class Configuration implements ConfigurationInterface ->info('Can we have more than one simultaneous accompanying period in the same time. Default false.') ->defaultValue(false) ->end() + ->arrayNode('accompanying_period_lifecycle_delays') + ->addDefaultsIfNotSet() + ->info('Delays before marking an accompanying period as inactive') + ->children() + ->booleanNode('mark_inactive')->defaultTrue()->end() + ->scalarNode('mark_inactive_short_after')->defaultValue('P6M')->end() + ->scalarNode('mark_inactive_long_after')->defaultValue('P2Y')->end() + ->end() + ->end() // end of 'accompanying_period_lifecycle_delays ->end() // children of 'root', parent = root ; diff --git a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php index f7eeec28e..a724596a9 100644 --- a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php +++ b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php @@ -116,7 +116,16 @@ class AccompanyingPeriod implements * confirmed, but no activity (Activity, AccompanyingPeriod, ...) * has been associated, or updated, within this accompanying period. */ - public const STEP_CONFIRMED_INACTIVE = 'CONFIRMED_INACTIVE'; + public const STEP_CONFIRMED_INACTIVE_SHORT = 'CONFIRMED_INACTIVE_SHORT'; + + /** + * Mark an accompanying period as confirmed, but inactive + * + * this means that the accompanying period **is** + * confirmed, but no activity (Activity, AccompanyingPeriod, ...) + * has been associated, or updated, within this accompanying period. + */ + public const STEP_CONFIRMED_INACTIVE_LONG = 'CONFIRMED_INACTIVE_LONG'; /** * Mark an accompanying period as "draft". diff --git a/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/AccompanyingPeriodInfoRepository.php b/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/AccompanyingPeriodInfoRepository.php new file mode 100644 index 000000000..57925b131 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/AccompanyingPeriodInfoRepository.php @@ -0,0 +1,93 @@ +entityRepository = $em->getRepository($this->getClassName()); + } + + public function findAccompanyingPeriodIdInactiveAfter(DateInterval $interval, array $statuses = []): array + { + $query = $this->em->createQuery(); + $baseDql = 'SELECT DISTINCT IDENTITY(ai.accompanyingPeriod) FROM '.AccompanyingPeriodInfo::class.' ai JOIN ai.accompanyingPeriod a WHERE NOT EXISTS + (SELECT 1 FROM ' . AccompanyingPeriodInfo::class . ' aiz WHERE aiz.infoDate > :after AND IDENTITY(aiz.accompanyingPeriod) = IDENTITY(ai.accompanyingPeriod))'; + + if ([] !== $statuses) { + $dql = $baseDql . ' AND a.step IN (:statuses)'; + $query->setParameter('statuses', $statuses); + } else { + $dql = $baseDql; + } + + return $query->setDQL($dql) + ->setParameter('after', $this->clock->now()->sub($interval)) + ->getSingleColumnResult(); + } + + public function findAccompanyingPeriodIdActiveSince(DateInterval $interval, array $statuses = []): array + { + $query = $this->em->createQuery(); + $baseDql = 'SELECT DISTINCT IDENTITY(ai.accompanyingPeriod) FROM ' . AccompanyingPeriodInfo::class . ' ai + JOIN ai.accompanyingPeriod a WHERE ai.infoDate > :after'; + + if ([] !== $statuses) { + $dql = $baseDql . ' AND a.step IN (:statuses)'; + $query->setParameter('statuses', $statuses); + } else { + $dql = $baseDql; + } + + return $query->setDQL($dql) + ->setParameter('after', $this->clock->now()->sub($interval)) + ->getSingleColumnResult(); + } + + public function find($id): ?AccompanyingPeriodInfo + { + throw new LogicException("Calling an accompanying period info by his id does not make sense"); + } + + public function findAll(): array + { + return $this->entityRepository->findAll(); + } + + public function findBy(array $criteria, ?array $orderBy = null, ?int $limit = null, ?int $offset = null): array + { + return $this->entityRepository->findBy($criteria, $orderBy, $limit, $offset); + } + + public function findOneBy(array $criteria): ?AccompanyingPeriodInfo + { + return $this->entityRepository->findOneBy($criteria); + } + + public function getClassName(): string + { + return AccompanyingPeriodInfo::class; + } + +} diff --git a/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/AccompanyingPeriodInfoRepositoryInterface.php b/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/AccompanyingPeriodInfoRepositoryInterface.php new file mode 100644 index 000000000..07397cd48 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/AccompanyingPeriodInfoRepositoryInterface.php @@ -0,0 +1,38 @@ + + */ +interface AccompanyingPeriodInfoRepositoryInterface extends ObjectRepository +{ + /** + * Return a list of id for inactive accompanying periods + * + * @param \DateInterval $interval + * @param list $statuses + * @return list + */ + public function findAccompanyingPeriodIdInactiveAfter(\DateInterval $interval, array $statuses = []): array; + + /** + * @param \DateInterval $interval + * @param list $statuses + * @return list + */ + public function findAccompanyingPeriodIdActiveSince(\DateInterval $interval, array $statuses = []): array; +} diff --git a/src/Bundle/ChillPersonBundle/Tests/AccompanyingPeriod/Lifecycle/AccompanyingPeriodStepChangeCronjobTest.php b/src/Bundle/ChillPersonBundle/Tests/AccompanyingPeriod/Lifecycle/AccompanyingPeriodStepChangeCronjobTest.php new file mode 100644 index 000000000..5c3c29179 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/AccompanyingPeriod/Lifecycle/AccompanyingPeriodStepChangeCronjobTest.php @@ -0,0 +1,55 @@ +prophesize(AccompanyingPeriodStepChangeRequestor::class); + $clock = new MockClock($datetime); + + $cronJob = new AccompanyingPeriodStepChangeCronjob($clock, $requestor->reveal()); + $cronJobExecution = (new CronJobExecution($cronJob->getKey()))->setLastStart($lastExecutionStart); + + $this->assertEquals($canRun, $cronJob->canRun($cronJobExecution)); + } + + public function provideRunTimes(): iterable + { + // can run, during the night + yield ['2023-01-15T01:00:00+02:00', new \DateTimeImmutable('2023-01-14T00:00:00+02:00'), true]; + + // can not run, not during the night + yield ['2023-01-15T10:00:00+02:00', new \DateTimeImmutable('2023-01-14T00:00:00+02:00'), false]; + + // can not run: not enough elapsed time + yield ['2023-01-15T01:00:00+02:00', new \DateTimeImmutable('2023-01-15T00:30:00+02:00'), false]; + } + +} diff --git a/src/Bundle/ChillPersonBundle/config/services/accompanyingPeriod.yaml b/src/Bundle/ChillPersonBundle/config/services/accompanyingPeriod.yaml index 7d7f9072d..e6b35de77 100644 --- a/src/Bundle/ChillPersonBundle/config/services/accompanyingPeriod.yaml +++ b/src/Bundle/ChillPersonBundle/config/services/accompanyingPeriod.yaml @@ -25,6 +25,11 @@ services: autowire: true autoconfigure: true + Chill\PersonBundle\AccompanyingPeriod\Lifecycle\: + resource: './../../AccompanyingPeriod/Lifecycle' + autowire: true + autoconfigure: true + Chill\PersonBundle\AccompanyingPeriod\Events\UserRefEventSubscriber: autowire: true autoconfigure: true From fcbc00d0f1b5c7490d3965c4bce1fe8314f8cb00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Fri, 21 Apr 2023 15:59:33 +0200 Subject: [PATCH 025/321] Feature: force to add updatedAt and createdAt even if no user iss associated --- .../Event/TrackCreateUpdateSubscriber.php | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Doctrine/Event/TrackCreateUpdateSubscriber.php b/src/Bundle/ChillMainBundle/Doctrine/Event/TrackCreateUpdateSubscriber.php index bf493c344..26a302b13 100644 --- a/src/Bundle/ChillMainBundle/Doctrine/Event/TrackCreateUpdateSubscriber.php +++ b/src/Bundle/ChillMainBundle/Doctrine/Event/TrackCreateUpdateSubscriber.php @@ -41,12 +41,12 @@ class TrackCreateUpdateSubscriber implements EventSubscriber { $object = $args->getObject(); - if ( - $object instanceof TrackCreationInterface - && $this->security->getUser() instanceof User - ) { - $object->setCreatedBy($this->security->getUser()); + if ($object instanceof TrackCreationInterface) { $object->setCreatedAt(new DateTimeImmutable('now')); + + if ($this->security->getUser() instanceof User) { + $object->setCreatedBy($this->security->getUser()); + } } $this->onUpdate($object); @@ -61,12 +61,12 @@ class TrackCreateUpdateSubscriber implements EventSubscriber protected function onUpdate(object $object): void { - if ( - $object instanceof TrackUpdateInterface - && $this->security->getUser() instanceof User - ) { - $object->setUpdatedBy($this->security->getUser()); - $object->setUpdatedAt(new DateTimeImmutable('now')); + if ($object instanceof TrackUpdateInterface) { + $object->setUpdatedAt(new DateTimeImmutable('now')); + + if ($this->security->getUser() instanceof User) { + $object->setUpdatedBy($this->security->getUser()); + } } } } From c5989de12059b990c913ecd093d1dd32b3819cce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Mon, 24 Apr 2023 15:38:53 +0200 Subject: [PATCH 026/321] Feature: Adapt UI to show new steps --- .../public/vuejs/AccompanyingCourse/App.vue | 2 +- .../vuejs/AccompanyingCourse/components/Banner.vue | 14 ++++++++++++-- .../public/vuejs/AccompanyingCourse/js/i18n.js | 4 +++- .../views/Person/list_with_period.html.twig | 12 +++++++----- 4 files changed, 23 insertions(+), 9 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/App.vue b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/App.vue index 51fc2c1d0..c66214b0b 100644 --- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/App.vue +++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/App.vue @@ -14,7 +14,7 @@ - + diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/components/Banner.vue b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/components/Banner.vue index dcade7e0f..fb8a09784 100644 --- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/components/Banner.vue +++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/components/Banner.vue @@ -11,12 +11,22 @@ {{ $t('course.step.draft') }} - - + + {{ $t('course.step.active') }} + + + {{ $t('course.step.inactive_short') }} + + + + + {{ $t('course.step.inactive_long') }} + + {{ $t('course.open_at') }}{{ $d(accompanyingCourse.openingDate.datetime, 'text') }} diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/js/i18n.js b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/js/i18n.js index 8bbd5c4ca..1a46a79ca 100644 --- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/js/i18n.js +++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/js/i18n.js @@ -21,7 +21,9 @@ const appMessages = { step: { draft: "Brouillon", active: "En file active", - closed: "Cloturé" + closed: "Cloturé", + inactive_short: "Hors file active", + inactive_long: "Pré-archivé", }, open_at: "ouvert le ", by: "par ", diff --git a/src/Bundle/ChillPersonBundle/Resources/views/Person/list_with_period.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/Person/list_with_period.html.twig index 4497b8226..4735fb5a3 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/Person/list_with_period.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/Person/list_with_period.html.twig @@ -52,11 +52,13 @@ {% endif %} {% if acp.step == 'DRAFT' %} - {{ 'course.draft'|trans }} - {% endif %} - - {% if acp.step == 'CLOSED' %} - {{ 'course.closed'|trans }} + {{ 'course.draft'|trans }} + {% elseif acp.step == 'CLOSED' %} + {{ 'course.closed'|trans }} + {% elseif acp.step == 'CONFIRMED_INACTIVE_SHORT' %} + {{ 'course.inactive_short'|trans }} + {% elseif acp.step == 'CONFIRMED_INACTIVE_LONG' %} + {{ 'course.inactive_long'|trans }} {% endif %}
    From e80a6e417b271428a646e214c9e54dce30d76cad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Mon, 24 Apr 2023 15:39:39 +0200 Subject: [PATCH 027/321] Feature: Track update of entities if no user is associated to the request This happens in scripts/cli (messenger, ...) --- .../Doctrine/Event/TrackCreateUpdateSubscriber.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Doctrine/Event/TrackCreateUpdateSubscriber.php b/src/Bundle/ChillMainBundle/Doctrine/Event/TrackCreateUpdateSubscriber.php index 26a302b13..166003f73 100644 --- a/src/Bundle/ChillMainBundle/Doctrine/Event/TrackCreateUpdateSubscriber.php +++ b/src/Bundle/ChillMainBundle/Doctrine/Event/TrackCreateUpdateSubscriber.php @@ -62,11 +62,11 @@ class TrackCreateUpdateSubscriber implements EventSubscriber protected function onUpdate(object $object): void { if ($object instanceof TrackUpdateInterface) { - $object->setUpdatedAt(new DateTimeImmutable('now')); + $object->setUpdatedAt(new DateTimeImmutable('now')); - if ($this->security->getUser() instanceof User) { - $object->setUpdatedBy($this->security->getUser()); - } + if ($this->security->getUser() instanceof User) { + $object->setUpdatedBy($this->security->getUser()); + } } } } From 229af2e4f98a48cbaa25cb1e9ea8b790d1bd92c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Mon, 24 Apr 2023 15:40:20 +0200 Subject: [PATCH 028/321] Feature: Adapt filters and aggregators with new steps --- .../translations/messages.fr.yml | 1 + .../Entity/AccompanyingPeriod.php | 5 ++-- .../StepAggregator.php | 12 ++++++-- .../Export/Export/ListAccompanyingPeriod.php | 30 +++++++++++++++++++ .../AccompanyingCourseFilters/StepFilter.php | 10 ++++--- .../StepFilterTest.php | 2 ++ .../translations/messages.fr.yml | 17 +++++++++-- 7 files changed, 64 insertions(+), 13 deletions(-) diff --git a/src/Bundle/ChillMainBundle/translations/messages.fr.yml b/src/Bundle/ChillMainBundle/translations/messages.fr.yml index b8349ce2e..14de6dbf0 100644 --- a/src/Bundle/ChillMainBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillMainBundle/translations/messages.fr.yml @@ -564,6 +564,7 @@ export: _as_string: Adresse formattée confidential: Adresse confidentielle ? isNoAddress: Adresse incomplète ? + steps: Escaliers _lat: Latitude _lon: Longitude diff --git a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php index a724596a9..a8e191df3 100644 --- a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php +++ b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php @@ -358,6 +358,7 @@ class AccompanyingPeriod implements /** * @ORM\Column(type="string", length=32, nullable=true) * @Groups({"read"}) + * @var AccompanyingPeriod::STEP_* */ private string $step = self::STEP_DRAFT; @@ -730,11 +731,9 @@ class AccompanyingPeriod implements if ($this->getStep() === self::STEP_DRAFT) { return [[self::STEP_DRAFT]]; } - - if ($this->getStep() === self::STEP_CONFIRMED) { + if (str_starts_with($this->getStep(), 'CONFIRM')) { return [[self::STEP_DRAFT, self::STEP_CONFIRMED]]; } - if ($this->getStep() === self::STEP_CLOSED) { return [[self::STEP_DRAFT, self::STEP_CONFIRMED, self::STEP_CLOSED]]; } diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/StepAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/StepAggregator.php index 84dbd4e69..85cfc3190 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/StepAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/StepAggregator.php @@ -86,13 +86,19 @@ final class StepAggregator implements AggregatorInterface return function ($value): string { switch ($value) { case AccompanyingPeriod::STEP_DRAFT: - return $this->translator->trans('Draft'); + return $this->translator->trans('course.draft'); case AccompanyingPeriod::STEP_CONFIRMED: - return $this->translator->trans('Confirmed'); + return $this->translator->trans('course.confirmed'); case AccompanyingPeriod::STEP_CLOSED: - return $this->translator->trans('Closed'); + return $this->translator->trans('course.closed'); + + case AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_SHORT: + return $this->translator->trans('course.inactive_short'); + + case AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_LONG: + return $this->translator->trans('course.inactive_long'); case '_header': return 'Step'; diff --git a/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriod.php b/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriod.php index 045039930..3fd7ee01a 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriod.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriod.php @@ -41,6 +41,7 @@ use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Query\Expr\Join; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; +use Symfony\Contracts\Translation\TranslatorInterface; use function strlen; class ListAccompanyingPeriod implements ListInterface, GroupedExportInterface @@ -100,6 +101,8 @@ class ListAccompanyingPeriod implements ListInterface, GroupedExportInterface private TranslatableStringHelperInterface $translatableStringHelper; + private TranslatorInterface $translator; + private UserHelper $userHelper; public function __construct( @@ -113,6 +116,7 @@ class ListAccompanyingPeriod implements ListInterface, GroupedExportInterface SocialIssueRepository $socialIssueRepository, SocialIssueRender $socialIssueRender, TranslatableStringHelperInterface $translatableStringHelper, + TranslatorInterface $translator, RollingDateConverterInterface $rollingDateConverter, UserHelper $userHelper ) { @@ -126,6 +130,7 @@ class ListAccompanyingPeriod implements ListInterface, GroupedExportInterface $this->thirdPartyRender = $thirdPartyRender; $this->thirdPartyRepository = $thirdPartyRepository; $this->translatableStringHelper = $translatableStringHelper; + $this->translator = $translator; $this->rollingDateConverter = $rollingDateConverter; $this->userHelper = $userHelper; } @@ -250,6 +255,31 @@ class ListAccompanyingPeriod implements ListInterface, GroupedExportInterface ); }; + case 'step': + return function ($value) { + return match ($value) { + '_header' => 'export.list.acp.step', + null => '', + AccompanyingPeriod::STEP_DRAFT => $this->translator->trans('course.draft'), + AccompanyingPeriod::STEP_CONFIRMED => $this->translator->trans('course.confirmed'), + AccompanyingPeriod::STEP_CLOSED => $this->translator->trans('course.closed'), + AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_SHORT => $this->translator->trans('course.inactive_short'), + AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_LONG => $this->translator->trans('course.inactive_long'), + default => $value, + }; + }; + + case 'intensity': + return function ($value) { + return match ($value) { + '_header' => 'export.list.acp.intensity', + null => '', + AccompanyingPeriod::INTENSITY_OCCASIONAL => $this->translator->trans('occasional'), + AccompanyingPeriod::INTENSITY_REGULAR => $this->translator->trans('regular'), + default => $value, + }; + }; + default: return static function ($value) use ($key) { if ('_header' === $value) { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/StepFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/StepFilter.php index 240b093b5..8ee798c07 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/StepFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/StepFilter.php @@ -32,9 +32,11 @@ class StepFilter implements FilterInterface private const P = 'acp_step_filter_date'; private const STEPS = [ - 'Draft' => AccompanyingPeriod::STEP_DRAFT, - 'Confirmed' => AccompanyingPeriod::STEP_CONFIRMED, - 'Closed' => AccompanyingPeriod::STEP_CLOSED, + 'course.draft' => AccompanyingPeriod::STEP_DRAFT, + 'course.confirmed' => AccompanyingPeriod::STEP_CONFIRMED, + 'course.closed' => AccompanyingPeriod::STEP_CLOSED, + 'course.inactive_short' => AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_SHORT, + 'course.inactive_long' => AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_LONG, ]; private RollingDateConverterInterface $rollingDateConverter; @@ -96,7 +98,7 @@ class StepFilter implements FilterInterface 'data' => self::DEFAULT_CHOICE, ]) ->add('calc_date', PickRollingDateType::class, [ - 'label' => 'export.acp.filter.by_step.date_calc', + 'label' => 'export.filter.course.by_step.date_calc', 'data' => new RollingDate(RollingDate::T_TODAY), ]); } diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Filter/AccompanyingCourseFilters/StepFilterTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Filter/AccompanyingCourseFilters/StepFilterTest.php index 9388aa8ae..42eec5823 100644 --- a/src/Bundle/ChillPersonBundle/Tests/Export/Filter/AccompanyingCourseFilters/StepFilterTest.php +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Filter/AccompanyingCourseFilters/StepFilterTest.php @@ -40,6 +40,8 @@ final class StepFilterTest extends AbstractFilterTest return [ ['accepted_steps' => AccompanyingPeriod::STEP_DRAFT], ['accepted_steps' => AccompanyingPeriod::STEP_CONFIRMED], + ['accepted_steps' => AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_LONG], + ['accepted_steps' => AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_SHORT], ['accepted_steps' => AccompanyingPeriod::STEP_CLOSED], ]; } diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index d33957ea7..0cdc9e601 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -57,7 +57,7 @@ Add new phone: Ajouter un numéro de téléphone Remove phone: Supprimer 'Notes on contact information': 'Remarques sur les informations de contact' 'Remarks': 'Remarques' -'Spoken languages': 'Langues parlées' +Spoken languages': 'Langues parlées' 'Unknown spoken languages': 'Langues parlées inconnues' Male: Homme Female: Femme @@ -237,8 +237,12 @@ No referrer: Pas d'agent traitant Some peoples does not belong to any household currently. Add them to an household soon: Certains usagers n'appartiennent à aucun ménage actuellement. Renseignez leur ménage dès que possible. Add to household now: Ajouter à un ménage Any resource for this accompanying course: Aucun interlocuteur privilégié pour ce parcours -course.draft: Brouillon -course.closed: Clôturé +course: + draft: Brouillon + closed: Clôturé + inactive_short: Hors file active + inactive_long: Pré-archivé + confirmed: Confirmé Origin: Origine de la demande Delete accompanying period: Supprimer le parcours d'accompagnement Are you sure you want to remove the accompanying period "%id%" ?: Êtes-vous sûr de vouloir supprimer le parcours d'accompagnement %id% ? @@ -1072,6 +1076,8 @@ export: Status: Statut course: + by_step: + date_calc: Date de prise en compte du statut by_user_scope: Computation date for referrer: Date à laquelle le référent était actif by_referrer: @@ -1095,12 +1101,15 @@ export: id: Identifiant du parcours openingDate: Date d'ouverture du parcours closingDate: Date de fermeture du parcours + closingMotive: Motif de cloture + job: Métier confidential: Confidentiel emergency: Urgent intensity: Intensité createdAt: Créé le updatedAt: Dernière mise à jour le acpOrigin: Origine du parcours + origin: Origine du parcourse acpClosingMotive: Motif de fermeture acpJob: Métier du parcours createdBy: Créé par @@ -1120,6 +1129,8 @@ export: acprequestorPerson: Nom du demandeur usager scopes: Services socialIssues: Problématiques sociales + requestorPerson: Demandeur (personne) + requestorThirdParty: Demandeur (tiers) eval: List of evaluations: Liste des évaluations Generate a list of evaluations, filtered on different parameters: Génère une liste des évaluations, filtrée sur différents paramètres. From 5b729e1cb190883593acfe504d1d06888b7fa870 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 27 Apr 2023 12:01:47 +0200 Subject: [PATCH 029/321] add dev docs --- docs/source/development/entity-info.rst | 203 ++++++++++++++++++++++++ docs/source/development/index.rst | 1 + docs/source/development/timelines.rst | 100 ++++++------ 3 files changed, 255 insertions(+), 49 deletions(-) create mode 100644 docs/source/development/entity-info.rst diff --git a/docs/source/development/entity-info.rst b/docs/source/development/entity-info.rst new file mode 100644 index 000000000..72d8b70ea --- /dev/null +++ b/docs/source/development/entity-info.rst @@ -0,0 +1,203 @@ + +.. Copyright (C) 2014 Champs Libres Cooperative SCRLFS +Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU Free Documentation License, Version 1.3 +or any later version published by the Free Software Foundation; +with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. +A copy of the license is included in the section entitled "GNU +Free Documentation License". + +.. _entity-info: + +Stats about event on entity in php world +######################################## + +It is necessary to be able to gather information about events for some entities: + +- when the event has been done; +- who did it; +- ... + +Those "infos" are not linked with right management, like describe in :ref:`timelines`. + + +“infos” for some stats and info about an entity +----------------------------------------------- + +Building an info means: + +- create an Entity, and map this entity to a SQL view (not a regular table); +- use the framework to build this entity dynamically. + +A framework api is built to be able to build multiple “infos” entities +through “union” views: + +- use a command ``bin/console chill:db:sync-views`` to synchronize view (create view if it does not exists, or update + views when new SQL parts are added in the UNION query. Internally, this command call a new ``ViewEntityInfoManager``, + which iterate over available views to build the SQL; +- one can create a new “view entity info” by implementing a + ``ViewEntityInfoProviderInterface`` +- this implementation of the interface is free to create another + interface for building each part of the UNION query. This interface + is created for AccompanyingPeriodInfo: + ``Chill\PersonBundle\Service\EntityInfo\AccompanyingPeriodInfoUnionQueryPartInterface`` + +So, converting new “events” into rows for ``AccompanyingPeriodInfo`` is +just implementing this interface! + +Implementation for AccompanyingPeriod (``AccompanyingPeriod/AccompanyingPeriodInfo``) +------------------------------------------------------------------------------------- + +A class is created for computing some statistical info for an +AccompanyingPeriod: ``AccompanyingPeriod/AccompanyingPeriodInfo``. This +contains information about “something happens”, who did it and when. + +Having those info in table answer some questions like: + +- when is the last and the first action (AccompanyingPeriodWork, + Activity, AccompanyingPeriodWorkEvaluation, …) on the period; +- who is “acting” on the period, and when is the last “action” for each + user. + +The AccompanyingPeriod info is mapped to a SQL view, not a table. The +sql view is built dynamically (see below), and gather infos from +ActivityBundle, PersonBundle, CalendarBundle, … It is possible to create +custom bundle and add info on this view. + +.. code:: php + + /** + * + * @ORM\Entity() + * @ORM\Table(name="view_chill_person_accompanying_period_info") <==== THIS IS A VIEW, NOT A TABLE + */ + class AccompanyingPeriodInfo + { + // ... + } + +Why do we need this ? +~~~~~~~~~~~~~~~~~~~~~ + +For multiple jobs in PHP world: + +- moving the accompanying period to another steps when inactive, + automatically; +- listing all the users which are intervening on the action on a new + “Liste des intervenants” page; +- filtering on exports + +Later, we will launch automatic anonymise for accompanying period and +all related entities through this information. + +How is built the SQL views which is mapped to “info” entities ? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The AccompanyingPeriodInfo entity is mapped by a SQL view (not a regular +table). + +The sql view is built dynamically, it is a SQL view like this, for now (April 2023): + +.. code:: sql + + create view view_chill_person_accompanying_period_info + (accompanyingperiod_id, relatedentity, relatedentityid, user_id, infodate, discriminator, metadata) as + SELECT w.accompanyingperiod_id, + 'Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork'::text AS relatedentity, + w.id AS relatedentityid, + cpapwr.user_id, + w.enddate AS infodate, + 'accompanying_period_work_end'::text AS discriminator, + '{}'::jsonb AS metadata + FROM chill_person_accompanying_period_work w + LEFT JOIN chill_person_accompanying_period_work_referrer cpapwr ON w.id = cpapwr.accompanyingperiodwork_id + WHERE w.enddate IS NOT NULL + UNION + SELECT cpapw.accompanyingperiod_id, + 'Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluation'::text AS relatedentity, + e.id AS relatedentityid, + e.updatedby_id AS user_id, + e.updatedat AS infodate, + 'accompanying_period_work_evaluation_updated_at'::text AS discriminator, + '{}'::jsonb AS metadata + FROM chill_person_accompanying_period_work_evaluation e + JOIN chill_person_accompanying_period_work cpapw ON cpapw.id = e.accompanyingperiodwork_id + WHERE e.updatedat IS NOT NULL + UNION + SELECT cpapw.accompanyingperiod_id, + 'Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluation'::text AS relatedentity, + e.id AS relatedentityid, + cpapwr.user_id, + e.maxdate AS infodate, + 'accompanying_period_work_evaluation_start'::text AS discriminator, + '{}'::jsonb AS metadata + FROM chill_person_accompanying_period_work_evaluation e + JOIN chill_person_accompanying_period_work cpapw ON cpapw.id = e.accompanyingperiodwork_id + LEFT JOIN chill_person_accompanying_period_work_referrer cpapwr ON cpapw.id = cpapwr.accompanyingperiodwork_id + WHERE e.maxdate IS NOT NULL + UNION + SELECT cpapw.accompanyingperiod_id, + 'Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluation'::text AS relatedentity, + e.id AS relatedentityid, + cpapwr.user_id, + e.startdate AS infodate, + 'accompanying_period_work_evaluation_start'::text AS discriminator, + '{}'::jsonb AS metadata + FROM chill_person_accompanying_period_work_evaluation e + JOIN chill_person_accompanying_period_work cpapw ON cpapw.id = e.accompanyingperiodwork_id + LEFT JOIN chill_person_accompanying_period_work_referrer cpapwr ON cpapw.id = cpapwr.accompanyingperiodwork_id + UNION + SELECT cpapw.accompanyingperiod_id, + 'Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluationDocument'::text AS relatedentity, + doc.id AS relatedentityid, + doc.updatedby_id AS user_id, + doc.updatedat AS infodate, + 'accompanying_period_work_evaluation_document_updated_at'::text AS discriminator, + '{}'::jsonb AS metadata + FROM chill_person_accompanying_period_work_evaluation_document doc + JOIN chill_person_accompanying_period_work_evaluation e ON doc.accompanyingperiodworkevaluation_id = e.id + JOIN chill_person_accompanying_period_work cpapw ON cpapw.id = e.accompanyingperiodwork_id + WHERE doc.updatedat IS NOT NULL + UNION + SELECT cpapw.accompanyingperiod_id, + 'Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluation'::text AS relatedentity, + e.id AS relatedentityid, + cpapwr.user_id, + e.maxdate AS infodate, + 'accompanying_period_work_evaluation_max'::text AS discriminator, + '{}'::jsonb AS metadata + FROM chill_person_accompanying_period_work_evaluation e + JOIN chill_person_accompanying_period_work cpapw ON cpapw.id = e.accompanyingperiodwork_id + LEFT JOIN chill_person_accompanying_period_work_referrer cpapwr ON cpapw.id = cpapwr.accompanyingperiodwork_id + WHERE e.maxdate IS NOT NULL + UNION + SELECT w.accompanyingperiod_id, + 'Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork'::text AS relatedentity, + w.id AS relatedentityid, + cpapwr.user_id, + w.startdate AS infodate, + 'accompanying_period_work_start'::text AS discriminator, + '{}'::jsonb AS metadata + FROM chill_person_accompanying_period_work w + LEFT JOIN chill_person_accompanying_period_work_referrer cpapwr ON w.id = cpapwr.accompanyingperiodwork_id + UNION + SELECT activity.accompanyingperiod_id, + 'Chill\ActivityBundle\Entity\Activity'::text AS relatedentity, + activity.id AS relatedentityid, + au.user_id, + activity.date AS infodate, + 'activity_date'::text AS discriminator, + '{}'::jsonb AS metadata + FROM activity + LEFT JOIN activity_user au ON activity.id = au.activity_id + WHERE activity.accompanyingperiod_id IS NOT NULL; + +As you can see, the view gather multiple SELECT queries and bind them +with UNION. + +Each SELECT query is built dynamically, through a class implementing an +interface: ``Chill\PersonBundle\Service\EntityInfo\AccompanyingPeriodInfoUnionQueryPartInterface``, `like +here `__ + +To add new `SELECT` query in different `UNION` parts in the sql view, create a +service and implements this interface: ``Chill\PersonBundle\Service\EntityInfo\AccompanyingPeriodInfoUnionQueryPartInterface``. diff --git a/docs/source/development/index.rst b/docs/source/development/index.rst index 52c541c8e..fd9ae43ba 100644 --- a/docs/source/development/index.rst +++ b/docs/source/development/index.rst @@ -35,6 +35,7 @@ As Chill rely on the `symfony `_ framework, reading the fram manual/index.rst Assets Cron Jobs + Info about entities Layout and UI ************** diff --git a/docs/source/development/timelines.rst b/docs/source/development/timelines.rst index afabdb398..51c0a1bad 100644 --- a/docs/source/development/timelines.rst +++ b/docs/source/development/timelines.rst @@ -6,6 +6,8 @@ A copy of the license is included in the section entitled "GNU Free Documentation License". +.. _timelines: + Timelines ********* @@ -18,24 +20,24 @@ Concept From an user point of view -------------------------- -Chill has two objectives : +Chill has two objectives : * make the administrative tasks more lightweight ; * help social workers to have all information they need to work To reach this second objective, Chill provides a special view: **timeline**. On a timeline view, information is gathered and shown on a single page, from the most recent event to the oldest one. -The information gathered is linked to a *context*. This *context* may be, for instance : +The information gathered is linked to a *context*. This *context* may be, for instance : * a person : events linked to this person are shown on the page ; * a center: events linked to a center are shown. They may concern different peoples ; -* ... +* ... In other word, the *context* is the kind of argument that will be used in the event's query. Let us recall that only the data the user has allowed to see should be shown. -.. seealso:: +.. seealso:: `The issue where the subject was first discussed `_ @@ -43,30 +45,30 @@ Let us recall that only the data the user has allowed to see should be shown. For developers -------------- -The `Main` bundle provides interfaces and services to help to build timelines. +The `Main` bundle provides interfaces and services to help to build timelines. If a bundle wants to *push* information in a timeline, it should be create a service which implements `Chill\MainBundle\Timeline\TimelineProviderInterface`, and tag is with `chill.timeline` and arguments defining the supported context (you may use multiple `chill.timeline` tags in order to support multiple context with a single service/class). -If a bundle wants to provide a new context for a timeline, the service `chill.main.timeline_builder` will helps to gather timeline's services supporting the defined context, and run queries across the models. +If a bundle wants to provide a new context for a timeline, the service `chill.main.timeline_builder` will helps to gather timeline's services supporting the defined context, and run queries across the models. .. _understanding-queries : Understanding queries ^^^^^^^^^^^^^^^^^^^^^ -Due to the fact that timelines should show only the X last events from Y differents tables, queries for a timeline may consume a lot of resources: at first on the database, and then on the ORM part, which will have to deserialize DB data to PHP classes, which may not be used if they are not part of the "last X events". +Due to the fact that timelines should show only the X last events from Y differents tables, queries for a timeline may consume a lot of resources: at first on the database, and then on the ORM part, which will have to deserialize DB data to PHP classes, which may not be used if they are not part of the "last X events". -To avoid such load on database, the objects are queried in two steps : +To avoid such load on database, the objects are queried in two steps : 1. An UNION request which gather the last X events, ordered by date. The data retrieved are the ID, the date, and a string key: a type. This type discriminates the data type. -2. The PHP objects are queried by ID, the type helps the program to link id with the kind of objects. +2. The PHP objects are queried by ID, the type helps the program to link id with the kind of objects. Those methods should ensure that only X PHP objects will be gathered and build by the ORM. What does the master timeline builder service ? ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - When the service `chill.main.timeline_builder` is instanciated, the service is informed of each service taggued with `chill.timeline` tags. Then, + When the service `chill.main.timeline_builder` is instanciated, the service is informed of each service taggued with `chill.timeline` tags. Then, 1. The service build an UNION query by assembling column and tables names provided by the `fetchQuery` result ; 2. The UNION query is run, the result contains an id and a type for each row (see :ref:`above `) @@ -84,7 +86,7 @@ To push events on a timeline : Implementing the TimelineProviderInterface ------------------------------------------ -The has the following signature : +The has the following signature : .. code-block:: php @@ -92,19 +94,19 @@ The has the following signature : interface TimelineProviderInterface { - - /** - * + + /** + * * @param string $context * @param mixed[] $args the argument to the context. * @return TimelineSingleQuery * @throw \LogicException if the context is not supported */ public function fetchQuery($context, array $args); - + /** * Indicate if the result type may be handled by the service - * + * * @param string $type the key present in the SELECT query * @return boolean */ @@ -113,42 +115,42 @@ The has the following signature : /** * fetch entities from db into an associative array. The keys **MUST BE** * the id - * - * All ids returned by all SELECT queries + * + * All ids returned by all SELECT queries * (@see TimeLineProviderInterface::fetchQuery) and with the type * supported by the provider (@see TimelineProviderInterface::supportsType) * will be passed as argument. - * + * * @param array $ids an array of id * @return mixed[] an associative array of entities, with id as key */ public function getEntities(array $ids); - + /** * return an associative array with argument to render the entity * in an html template, which will be included in the timeline page - * + * * The result must have the following key : - * + * * - `template` : the template FQDN * - `template_data`: the data required by the template - * - * + * + * * Example: - * + * * ``` - * array( + * array( * 'template' => 'ChillMyBundle:timeline:template.html.twig', * 'template_data' => array( - * 'accompanyingPeriod' => $entity, - * 'person' => $args['person'] + * 'accompanyingPeriod' => $entity, + * 'person' => $args['person'] * ) * ); * ``` - * + * * `$context` and `$args` are defined by the bundle which will call the timeline - * rendering. - * + * rendering. + * * @param type $entity * @param type $context * @param array $args @@ -156,7 +158,7 @@ The has the following signature : * @throws \LogicException if the context is not supported */ public function getEntityTemplate($entity, $context, array $args); - + } @@ -176,7 +178,7 @@ The parameters should be replaced into the query by :code:`?`. They will be repl `$context` and `$args` are defined by the bundle which will call the timeline rendering. You may use them to build a different query depending on this context. -For instance, if the context is `'person'`, the args will be this array : +For instance, if the context is `'person'`, the args will be this array : .. code-block:: php @@ -197,7 +199,7 @@ You should find in the bundle documentation which contexts are arguments the bun .. note:: - We encourage to use `ClassMetaData` to define column names arguments. If you change your column names, changes will be reflected automatically during the execution of your code. + We encourage to use `ClassMetaData` to define column names arguments. If you change your column names, changes will be reflected automatically during the execution of your code. Example of an implementation : @@ -215,13 +217,13 @@ Example of an implementation : */ class TimelineReportProvider implements TimelineProviderInterface { - + /** * * @var EntityManager */ protected $em; - + public function __construct(EntityManager $em) { $this->em = $em; @@ -230,9 +232,9 @@ Example of an implementation : public function fetchQuery($context, array $args) { $this->checkContext($context); - + $metadata = $this->em->getClassMetadata('ChillReportBundle:Report'); - + return TimelineSingleQuery::fromArray([ 'id' => $metadata->getColumnName('id'), 'type' => 'report', @@ -254,11 +256,11 @@ Example of an implementation : The `supportsType` function ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -This function indicate to the master `chill.main.timeline_builder` service (which orchestrate the build of UNION queries) that the service supports the type indicated in the result's array of the `fetchQuery` function. +This function indicate to the master `chill.main.timeline_builder` service (which orchestrate the build of UNION queries) that the service supports the type indicated in the result's array of the `fetchQuery` function. -The implementation of our previous example will be : +The implementation of our previous example will be : -.. code-block:: php +.. code-block:: php namespace Chill\ReportBundle\Timeline; @@ -272,7 +274,7 @@ The implementation of our previous example will be : //... /** - * + * * {@inheritDoc} */ public function supportsType($type) @@ -304,12 +306,12 @@ The results **must be** an array where the id given by the UNION query (remember { $reports = $this->em->getRepository('ChillReportBundle:Report') ->findBy(array('id' => $ids)); - + $result = array(); foreach($reports as $report) { $result[$report->getId()] = $report; } - + return $result; } @@ -318,9 +320,9 @@ The results **must be** an array where the id given by the UNION query (remember The `getEntityTemplate` function ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -This is where the master service will collect information to render the entity. +This is where the master service will collect information to render the entity. -The result must be an associative array with : +The result must be an associative array with : - **template** is the FQDN of the template ; - **template_data** is an associative array where keys are the variables'names for this template, and values are the values. @@ -332,8 +334,8 @@ Example : array( 'template' => 'ChillMyBundle:timeline:template.html.twig', 'template_data' => array( - 'period' => $entity, - 'person' => $args['person'] + 'period' => $entity, + 'person' => $args['person'] ) ); @@ -349,7 +351,7 @@ Create a timeline with his own context You have to create a Controller which will execute the service `chill.main.timeline_builder`. Using the `Chill\MainBundle\Timeline\TimelineBuilder::getTimelineHTML` function, you will get an HTML representation of the timeline, which you may include with twig `raw` filter. -Example : +Example : .. code-block:: php From c73e57ad73793785252428cc51996935bf63c663 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 27 Apr 2023 12:21:25 +0200 Subject: [PATCH 030/321] doc: add info about syncrhonizing views --- docs/source/installation/index.rst | 22 +++++++++++++++++++++- docs/source/installation/prod.rst | 8 ++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/docs/source/installation/index.rst b/docs/source/installation/index.rst index 852a2a6d0..910122196 100644 --- a/docs/source/installation/index.rst +++ b/docs/source/installation/index.rst @@ -151,6 +151,7 @@ This script will : # mount into to container ./docker-php.sh + bin/console chill:db:sync-views # and load fixtures bin/console doctrine:migrations:migrate @@ -161,7 +162,7 @@ Chill will be available at ``http://localhost:8001.`` Currently, there isn't any # mount into to container ./docker-php.sh - # and load fixtures + # and load fixtures (do not this for production) bin/console doctrine:fixtures:load --purge-with-truncate There are several users available: @@ -204,8 +205,10 @@ How to create the database schema (= run migrations) ? # if a container is running ./docker-php.sh bin/console doctrine:migrations:migrate + bin/console chill:db:sync-views # if not docker-compose run --user $(id -u) php bin/console doctrine:migrations:migrate + docker-compose run --user $(id -u) php bin/console chill:db:sync-views How to read the email sent by the program ? @@ -236,6 +239,23 @@ How to open a terminal in the project # if not docker-compose run --user $(id -u) php /bin/bash +How to run cron-jobs ? +====================== + +Some command must be executed in :ref:`cron jobs `. To execute them: + +.. code-block:: bash + + # if a container is running + ./docker-php.sh + bin/console chill:cron-job:execute + # some of them are executed only during the night. So, we have to force the execution during the day: + bin/console chill:cron-job:execute 'name-of-the-cron' + # if not + docker-compose run --user $(id -u) php bin/console chill:cron-job:execute + # some of them are executed only during the night. So, we have to force the execution during the day: + docker-compose run --user $(id -u) php bin/console chill:cron-job:execute 'name-of-the-cron' + How to run composer ? ===================== diff --git a/docs/source/installation/prod.rst b/docs/source/installation/prod.rst index f51141e8d..21da15267 100644 --- a/docs/source/installation/prod.rst +++ b/docs/source/installation/prod.rst @@ -38,6 +38,14 @@ This should be adapted to your needs: * Think about how you will backup your database. Some adminsys find easier to store database outside of docker, which might be easier to administrate or replicate. +Run migrations on each update +============================= + +Every time you start a new version, you should apply update the sql schema: + +- running ``bin/console doctrine:migration:migrate`` to run sql migration; +- synchonizing sql views to the last state: ``bin/console chill:db:sync-views`` + Cron jobs ========= From ea4294d12d8b5c3b6532e35a9074569df5568c23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 27 Apr 2023 22:45:25 +0200 Subject: [PATCH 031/321] add start date's accompanying period in accompanyingperiod info --- ...tartQueryPartForAccompanyingPeriodInfo.php | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 src/Bundle/ChillPersonBundle/Service/EntityInfo/AccompanyingPeriodInfoQueryPart/AccompanyingPeriodStartQueryPartForAccompanyingPeriodInfo.php diff --git a/src/Bundle/ChillPersonBundle/Service/EntityInfo/AccompanyingPeriodInfoQueryPart/AccompanyingPeriodStartQueryPartForAccompanyingPeriodInfo.php b/src/Bundle/ChillPersonBundle/Service/EntityInfo/AccompanyingPeriodInfoQueryPart/AccompanyingPeriodStartQueryPartForAccompanyingPeriodInfo.php new file mode 100644 index 000000000..19272900a --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Service/EntityInfo/AccompanyingPeriodInfoQueryPart/AccompanyingPeriodStartQueryPartForAccompanyingPeriodInfo.php @@ -0,0 +1,63 @@ + Date: Thu, 27 Apr 2023 22:45:45 +0200 Subject: [PATCH 032/321] add migration to fix existing period steps --- .../migrations/Version20230427102309.php | 189 ++++++++++++++++++ 1 file changed, 189 insertions(+) create mode 100644 src/Bundle/ChillPersonBundle/migrations/Version20230427102309.php diff --git a/src/Bundle/ChillPersonBundle/migrations/Version20230427102309.php b/src/Bundle/ChillPersonBundle/migrations/Version20230427102309.php new file mode 100644 index 000000000..7398a2292 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/migrations/Version20230427102309.php @@ -0,0 +1,189 @@ +addSql(<<<'SQL' + CREATE TEMPORARY TABLE acc_period_info AS + SELECT a.id AS accompanyingperiod_id, + 'Chill\PersonBundle\Entity\AccompanyingPeriod'::text AS relatedentity, + a.id AS relatedentityid, + NULL::integer AS user_id, + a.openingdate AS infodate, + 'accompanying_period_start'::text AS discriminator, + '{}'::jsonb AS metadata + FROM chill_person_accompanying_period a + UNION + SELECT w.accompanyingperiod_id, + 'Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork'::text AS relatedentity, + w.id AS relatedentityid, + cpapwr.user_id, + w.enddate AS infodate, + 'accompanying_period_work_end'::text AS discriminator, + '{}'::jsonb AS metadata + FROM chill_person_accompanying_period_work w + LEFT JOIN chill_person_accompanying_period_work_referrer cpapwr ON w.id = cpapwr.accompanyingperiodwork_id + WHERE w.enddate IS NOT NULL + UNION + SELECT cpapw.accompanyingperiod_id, + 'Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluation'::text AS relatedentity, + e.id AS relatedentityid, + e.updatedby_id AS user_id, + e.updatedat AS infodate, + 'accompanying_period_work_evaluation_updated_at'::text AS discriminator, + '{}'::jsonb AS metadata + FROM chill_person_accompanying_period_work_evaluation e + JOIN chill_person_accompanying_period_work cpapw ON cpapw.id = e.accompanyingperiodwork_id + WHERE e.updatedat IS NOT NULL + UNION + SELECT cpapw.accompanyingperiod_id, + 'Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluation'::text AS relatedentity, + e.id AS relatedentityid, + cpapwr.user_id, + e.maxdate AS infodate, + 'accompanying_period_work_evaluation_start'::text AS discriminator, + '{}'::jsonb AS metadata + FROM chill_person_accompanying_period_work_evaluation e + JOIN chill_person_accompanying_period_work cpapw ON cpapw.id = e.accompanyingperiodwork_id + LEFT JOIN chill_person_accompanying_period_work_referrer cpapwr ON cpapw.id = cpapwr.accompanyingperiodwork_id + WHERE e.maxdate IS NOT NULL + UNION + SELECT cpapw.accompanyingperiod_id, + 'Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluation'::text AS relatedentity, + e.id AS relatedentityid, + cpapwr.user_id, + e.startdate AS infodate, + 'accompanying_period_work_evaluation_start'::text AS discriminator, + '{}'::jsonb AS metadata + FROM chill_person_accompanying_period_work_evaluation e + JOIN chill_person_accompanying_period_work cpapw ON cpapw.id = e.accompanyingperiodwork_id + LEFT JOIN chill_person_accompanying_period_work_referrer cpapwr ON cpapw.id = cpapwr.accompanyingperiodwork_id + UNION + SELECT cpapw.accompanyingperiod_id, + 'Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluationDocument'::text AS relatedentity, + doc.id AS relatedentityid, + doc.updatedby_id AS user_id, + doc.updatedat AS infodate, + 'accompanying_period_work_evaluation_document_updated_at'::text AS discriminator, + '{}'::jsonb AS metadata + FROM chill_person_accompanying_period_work_evaluation_document doc + JOIN chill_person_accompanying_period_work_evaluation e ON doc.accompanyingperiodworkevaluation_id = e.id + JOIN chill_person_accompanying_period_work cpapw ON cpapw.id = e.accompanyingperiodwork_id + WHERE doc.updatedat IS NOT NULL + UNION + SELECT cpapw.accompanyingperiod_id, + 'Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluation'::text AS relatedentity, + e.id AS relatedentityid, + cpapwr.user_id, + e.maxdate AS infodate, + 'accompanying_period_work_evaluation_max'::text AS discriminator, + '{}'::jsonb AS metadata + FROM chill_person_accompanying_period_work_evaluation e + JOIN chill_person_accompanying_period_work cpapw ON cpapw.id = e.accompanyingperiodwork_id + LEFT JOIN chill_person_accompanying_period_work_referrer cpapwr ON cpapw.id = cpapwr.accompanyingperiodwork_id + WHERE e.maxdate IS NOT NULL + UNION + SELECT w.accompanyingperiod_id, + 'Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork'::text AS relatedentity, + w.id AS relatedentityid, + cpapwr.user_id, + w.startdate AS infodate, + 'accompanying_period_work_start'::text AS discriminator, + '{}'::jsonb AS metadata + FROM chill_person_accompanying_period_work w + LEFT JOIN chill_person_accompanying_period_work_referrer cpapwr ON w.id = cpapwr.accompanyingperiodwork_id + UNION + SELECT activity.accompanyingperiod_id, + 'Chill\ActivityBundle\Entity\Activity'::text AS relatedentity, + activity.id AS relatedentityid, + au.user_id, + activity.date AS infodate, + 'activity_date'::text AS discriminator, + '{}'::jsonb AS metadata + FROM activity + LEFT JOIN activity_user au ON activity.id = au.activity_id + WHERE activity.accompanyingperiod_id IS NOT NULL; + SQL); + + // create a table to store oldest inactives + $this->addSql(<<<'SQL' + CREATE TEMPORARY TABLE inactive_long AS + SELECT a.accompanyingperiod_id, MAX(infodate) AS last_date + FROM acc_period_info a JOIN chill_person_accompanying_period acp ON acp.id = a.accompanyingperiod_id + WHERE + NOT EXISTS (SELECT 1 FROM acc_period_info WHERE infodate > (NOW() - '2 years'::interval) AND acc_period_info.accompanyingperiod_id = a.accompanyingperiod_id) + AND acp.step LIKE 'CONFIRMED' + GROUP BY accompanyingperiod_id; + SQL); + + $this->addSql(<<<'SQL' + UPDATE chill_person_accompanying_period_step_history SET enddate = GREATEST(last_date + '2 years'::interval, startdate) + FROM inactive_long WHERE inactive_long.accompanyingperiod_id = period_id AND enddate IS NULL; + SQL); + + $this->addSql(<<<'SQL' + INSERT INTO chill_person_accompanying_period_step_history (id, period_id, enddate, startdate, step, createdat, updatedat) + SELECT nextval('chill_person_accompanying_period_step_history_id_seq'), accompanyingperiod_id, NULL, last_date + '2 years'::interval, 'CONFIRMED_INACTIVE_LONG', NOW(), NOW() + FROM inactive_long; + SQL); + + $this->addSql(<<<'SQL' + UPDATE chill_person_accompanying_period a SET step = 'CONFIRMED_INACTIVE_LONG' FROM inactive_long inactive WHERE a.id = inactive.accompanyingperiod_id; + SQL); + + $this->addSql(<<<'SQL' + DROP TABLE inactive_long + SQL); + + $this->addSql(<<<'SQL' + CREATE TEMPORARY TABLE inactive_long AS + SELECT a.accompanyingperiod_id, MAX(infodate) AS last_date + FROM acc_period_info a JOIN chill_person_accompanying_period acp ON acp.id = a.accompanyingperiod_id + WHERE + NOT EXISTS (SELECT 1 FROM acc_period_info WHERE infodate > (NOW() - '6 months'::interval) AND acc_period_info.accompanyingperiod_id = a.accompanyingperiod_id) + AND acp.step LIKE 'CONFIRMED' + GROUP BY accompanyingperiod_id; + SQL); + + $this->addSql(<<<'SQL' + UPDATE chill_person_accompanying_period_step_history SET enddate = GREATEST(last_date + '6 months'::interval, startdate) + FROM inactive_long WHERE inactive_long.accompanyingperiod_id = period_id AND enddate IS NULL; + SQL); + + $this->addSql(<<<'SQL' + INSERT INTO chill_person_accompanying_period_step_history (id, period_id, enddate, startdate, step, createdat, updatedat) + SELECT nextval('chill_person_accompanying_period_step_history_id_seq'), accompanyingperiod_id, NULL, last_date + '6 months'::interval, 'CONFIRMED_INACTIVE_SHORT', NOW(), NOW() + FROM inactive_long; + SQL); + + $this->addSql(<<<'SQL' + UPDATE chill_person_accompanying_period a SET step = 'CONFIRMED_INACTIVE_SHORT' FROM inactive_long inactive WHERE a.id = inactive.accompanyingperiod_id; + SQL); + } + + public function down(Schema $schema): void + { + $this->throwIrreversibleMigrationException(); + } +} From f75b90cb26994827dbafdda8b03ab546283dc4f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Fri, 28 Apr 2023 11:49:09 +0200 Subject: [PATCH 033/321] Feature: [export] add filters regarding to accompanying period infos --- ...ccompanyingPeriodInfoWithinDatesFilter.php | 91 +++++++++++++++++++ .../UserWorkingOnCourseFilter.php | 88 ++++++++++++++++++ .../services/exports_accompanying_course.yaml | 7 ++ .../translations/messages.fr.yml | 8 ++ 4 files changed, 194 insertions(+) create mode 100644 src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HavingAnAccompanyingPeriodInfoWithinDatesFilter.php create mode 100644 src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserWorkingOnCourseFilter.php diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HavingAnAccompanyingPeriodInfoWithinDatesFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HavingAnAccompanyingPeriodInfoWithinDatesFilter.php new file mode 100644 index 000000000..7069a1d80 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HavingAnAccompanyingPeriodInfoWithinDatesFilter.php @@ -0,0 +1,91 @@ +add('start_date', PickRollingDateType::class, [ + 'label' => 'export.filter.course.having_info_within_interval.start_date', + 'data' => new RollingDate(RollingDate::T_TODAY), + ]) + ->add('end_date', PickRollingDateType::class, [ + 'label' => 'export.filter.course.having_info_within_interval.end_date', + 'data' => new RollingDate(RollingDate::T_TODAY), + ]) + ; + } + + public function getTitle(): string + { + return 'export.filter.course.having_info_within_interval.title'; + } + + public function describeAction($data, $format = 'string'): array + { + return [ + 'export.filter.course.having_info_within_interval.Only course with events between %startDate% and %endDate%', + [ + '%startDate%' => $this->rollingDateConverter->convert($data['start_date'])->format('d-m-Y'), + '%endDate%' => $this->rollingDateConverter->convert($data['end_date'])->format('d-m-Y'), + ] + ]; + } + + public function addRole(): ?string + { + return null; + } + + public function alterQuery(QueryBuilder $qb, $data): void + { + $ai = 'having_ai_within_interval_acc_info'; + $as = 'having_ai_within_interval_start_date'; + $ae = 'having_ai_within_interval_end_date'; + + $qb + ->andWhere( + $qb->expr()->exists( + 'SELECT 1 FROM ' . AccompanyingPeriodInfo::class . " {$ai} WHERE {$ai}.infoDate BETWEEN :{$as} AND :{$ae} AND IDENTITY({$ai}.accompanyingPeriod) = acp.id" + ) + ) + ->setParameter($as, $this->rollingDateConverter->convert($data['start_date']), Types::DATETIME_IMMUTABLE) + ->setParameter($ae, $this->rollingDateConverter->convert($data['end_date']), Types::DATETIME_IMMUTABLE); + } + + public function applyOn(): string + { + return Declarations::ACP_TYPE; + } +} diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserWorkingOnCourseFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserWorkingOnCourseFilter.php new file mode 100644 index 000000000..586bb645d --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserWorkingOnCourseFilter.php @@ -0,0 +1,88 @@ +add('users', PickUserDynamicType::class, [ + 'multiple' => true, + ]); + } + + public function getTitle(): string + { + return 'export.filter.course.by_user_working.title'; + } + + public function describeAction($data, $format = 'string'): array + { + return [ + 'export.filter.course.by_user_working.Filtered by user working on course: only %users%', [ + '%users%' => implode( + ', ', + array_map( + fn (User $u) => $this->userRender->renderString($u, []), + $data['users'] + ) + ), + ], + ]; + } + + public function addRole(): ?string + { + return null; + } + + public function alterQuery(QueryBuilder $qb, $data): void + { + $qb + ->andWhere( + $qb->expr()->exists( + "SELECT 1 FROM " . AccompanyingPeriod\AccompanyingPeriodInfo::class . " " . self::AI_ALIAS . " " . + "WHERE " . self::AI_ALIAS . ".user IN (:" . self::AI_USERS .") AND IDENTITY(" . self::AI_ALIAS . ".accompanyingPeriod) = acp.id" + ) + ) + ->setParameter(self::AI_USERS, $data['users']) + ; + } + + public function applyOn(): string + { + return Declarations::ACP_TYPE; + } +} diff --git a/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_course.yaml b/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_course.yaml index bb2cfa556..adde8d336 100644 --- a/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_course.yaml +++ b/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_course.yaml @@ -128,6 +128,13 @@ services: tags: - { name: chill.export_filter, alias: accompanyingcourse_creator_job_filter } + Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\UserWorkingOnCourseFilter: + tags: + - { name: chill.export_filter, alias: accompanyingcourse_user_working_on_filter } + + Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\HavingAnAccompanyingPeriodInfoWithinDatesFilter: + tags: + - { name: chill.export_filter, alias: accompanyingcourse_info_within_filter } ## Aggregators chill.person.export.aggregator_referrer_scope: diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index 0cdc9e601..9b9f1fde2 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -1076,6 +1076,14 @@ export: Status: Statut course: + having_info_within_interval: + title: Filter les parcours ayant reçu une intervention entre deux dates + start_date: Début de la période + end_date: Fin de la période + Only course with events between %startDate% and %endDate%: Seulement les parcours ayant reçu une intervention entre le %startDate% et le %endDate% + by_user_working: + title: Filter les parcours par intervenant + 'Filtered by user working on course: only %users%': 'Filtré par intervenants sur le parcours: seulement %users%' by_step: date_calc: Date de prise en compte du statut by_user_scope: From 36413f16c32bd1a76d4d8e1f1a9ae46779b44597 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Fri, 28 Apr 2023 11:51:16 +0200 Subject: [PATCH 034/321] DX: convert closure to arrow function --- .../Export/Export/ListAccompanyingPeriod.php | 34 ++++++++----------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriod.php b/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriod.php index 3fd7ee01a..23b104ac4 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriod.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriod.php @@ -256,28 +256,24 @@ class ListAccompanyingPeriod implements ListInterface, GroupedExportInterface }; case 'step': - return function ($value) { - return match ($value) { - '_header' => 'export.list.acp.step', - null => '', - AccompanyingPeriod::STEP_DRAFT => $this->translator->trans('course.draft'), - AccompanyingPeriod::STEP_CONFIRMED => $this->translator->trans('course.confirmed'), - AccompanyingPeriod::STEP_CLOSED => $this->translator->trans('course.closed'), - AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_SHORT => $this->translator->trans('course.inactive_short'), - AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_LONG => $this->translator->trans('course.inactive_long'), - default => $value, - }; + return fn($value) => match ($value) { + '_header' => 'export.list.acp.step', + null => '', + AccompanyingPeriod::STEP_DRAFT => $this->translator->trans('course.draft'), + AccompanyingPeriod::STEP_CONFIRMED => $this->translator->trans('course.confirmed'), + AccompanyingPeriod::STEP_CLOSED => $this->translator->trans('course.closed'), + AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_SHORT => $this->translator->trans('course.inactive_short'), + AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_LONG => $this->translator->trans('course.inactive_long'), + default => $value, }; case 'intensity': - return function ($value) { - return match ($value) { - '_header' => 'export.list.acp.intensity', - null => '', - AccompanyingPeriod::INTENSITY_OCCASIONAL => $this->translator->trans('occasional'), - AccompanyingPeriod::INTENSITY_REGULAR => $this->translator->trans('regular'), - default => $value, - }; + return fn($value) => match ($value) { + '_header' => 'export.list.acp.intensity', + null => '', + AccompanyingPeriod::INTENSITY_OCCASIONAL => $this->translator->trans('occasional'), + AccompanyingPeriod::INTENSITY_REGULAR => $this->translator->trans('regular'), + default => $value, }; default: From ab5ad7ae148c7044f7d4a616bf3ec071887aebec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Fri, 28 Apr 2023 12:02:31 +0200 Subject: [PATCH 035/321] fix cs --- .../Export/Export/ListAccompanyingPeriod.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriod.php b/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriod.php index 23b104ac4..0647460dd 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriod.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriod.php @@ -256,7 +256,7 @@ class ListAccompanyingPeriod implements ListInterface, GroupedExportInterface }; case 'step': - return fn($value) => match ($value) { + return fn ($value) => match ($value) { '_header' => 'export.list.acp.step', null => '', AccompanyingPeriod::STEP_DRAFT => $this->translator->trans('course.draft'), @@ -268,7 +268,7 @@ class ListAccompanyingPeriod implements ListInterface, GroupedExportInterface }; case 'intensity': - return fn($value) => match ($value) { + return fn ($value) => match ($value) { '_header' => 'export.list.acp.intensity', null => '', AccompanyingPeriod::INTENSITY_OCCASIONAL => $this->translator->trans('occasional'), From 997f3cdb098b63ab6c36cc3225d2a265db0de771 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Fri, 28 Apr 2023 12:37:28 +0200 Subject: [PATCH 036/321] Feature: [exports] add filters for start and end date for accompanying period works --- ...yingPeriodWorkEndDateBetweenDateFilter.php | 114 ++++++++++++++++++ ...ngPeriodWorkStartDateBetweenDateFilter.php | 114 ++++++++++++++++++ .../services/exports_social_actions.yaml | 14 ++- .../translations/messages.fr.yml | 15 +++ 4 files changed, 256 insertions(+), 1 deletion(-) create mode 100644 src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/AccompanyingPeriodWorkEndDateBetweenDateFilter.php create mode 100644 src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/AccompanyingPeriodWorkStartDateBetweenDateFilter.php diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/AccompanyingPeriodWorkEndDateBetweenDateFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/AccompanyingPeriodWorkEndDateBetweenDateFilter.php new file mode 100644 index 000000000..b13c49e9a --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/AccompanyingPeriodWorkEndDateBetweenDateFilter.php @@ -0,0 +1,114 @@ +add('start_date', PickRollingDateType::class, [ + 'label' => 'export.filter.work.end_between_dates.start_date', + 'data' => new RollingDate(RollingDate::T_TODAY), + ]) + ->add('end_date', PickRollingDateType::class, [ + 'label' => 'export.filter.work.end_between_dates.end_date', + 'data' => new RollingDate(RollingDate::T_TODAY), + ]) + ->add('keep_null', CheckboxType::class, [ + 'label' => 'export.filter.work.end_between_dates.keep_null', + 'help' => 'export.filter.work.end_between_dates.keep_null_help', + ]) + ; + } + + public function getTitle(): string + { + return 'export.filter.work.end_between_dates.title'; + } + + public function describeAction($data, $format = 'string'): array + { + return [ + 'export.filter.work.end_between_dates.Only where end date is between %endDate% and %endDate%', + [ + '%startDate%' => null !== $data['start_date'] ? $this->rollingDateConverter->convert($data['start_date'])->format('d-m-Y') : '', + '%endDate%' => null !== $data['end_date'] ? $this->rollingDateConverter->convert($data['end_date'])->format('d-m-Y') : '', + ] + ]; + } + + public function addRole(): ?string + { + return null; + } + + public function alterQuery(QueryBuilder $qb, $data): void + { + $as = 'acc_pe_work_end_between_filter_start'; + $ae = 'acc_pe_work_end_between_filter_end'; + + $start = match ($data['keep_null']) { + true => $qb->expr()->orX( + $qb->expr()->lte('acpw.endDate', ':'.$ae), + $qb->expr()->isNull('acpw.endDate') + ), + false => $qb->expr()->andX( + $qb->expr()->lte('acpw.endDate', ':'.$ae), + $qb->expr()->isNotNull('acpw.endDate') + ), + default => throw new \LogicException("This value is not supported"), + }; + $end = match ($data['keep_null']) { + true => $qb->expr()->orX( + $qb->expr()->gt('acpw.endDate', ':'.$as), + $qb->expr()->isNull('acpw.endDate') + ), + false => $qb->expr()->andX( + $qb->expr()->gt('acpw.endDate', ':'.$as), + $qb->expr()->isNotNull('acpw.endDate') + ), + default => throw new \LogicException("This value is not supported"), + }; + + if (null !== $data['start_date']) { + $qb + ->andWhere($start) + ->setParameter($as, $this->rollingDateConverter->convert($data['start_date'])); + } + + if (null !== $data['end_date']) { + $qb + ->andWhere($end) + ->setParameter($ae, $this->rollingDateConverter->convert($data['end_date'])); + } + } + + public function applyOn(): string + { + return Declarations::SOCIAL_WORK_ACTION_TYPE; + } +} diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/AccompanyingPeriodWorkStartDateBetweenDateFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/AccompanyingPeriodWorkStartDateBetweenDateFilter.php new file mode 100644 index 000000000..e9526a9a5 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/AccompanyingPeriodWorkStartDateBetweenDateFilter.php @@ -0,0 +1,114 @@ +add('start_date', PickRollingDateType::class, [ + 'label' => 'export.filter.work.start_between_dates.start_date', + 'data' => new RollingDate(RollingDate::T_TODAY), + ]) + ->add('end_date', PickRollingDateType::class, [ + 'label' => 'export.filter.work.start_between_dates.end_date', + 'data' => new RollingDate(RollingDate::T_TODAY), + ]) + ->add('keep_null', CheckboxType::class, [ + 'label' => 'export.filter.work.start_between_dates.keep_null', + 'help' => 'export.filter.work.start_between_dates.keep_null_help', + ]) + ; + } + + public function getTitle(): string + { + return 'export.filter.work.start_between_dates.title'; + } + + public function describeAction($data, $format = 'string'): array + { + return [ + 'export.filter.work.start_between_dates.Only where start date is between %startDate% and %endDate%', + [ + '%startDate%' => null !== $data['start_date'] ? $this->rollingDateConverter->convert($data['start_date'])->format('d-m-Y') : '', + '%endDate%' => null !== $data['end_date'] ? $this->rollingDateConverter->convert($data['end_date'])->format('d-m-Y') : '', + ] + ]; + } + + public function addRole(): ?string + { + return null; + } + + public function alterQuery(QueryBuilder $qb, $data): void + { + $as = 'acc_pe_work_start_between_filter_start'; + $ae = 'acc_pe_work_start_between_filter_end'; + + $start = match ($data['keep_null']) { + true => $qb->expr()->orX( + $qb->expr()->lte('acpw.startDate', ':'.$ae), + $qb->expr()->isNull('acpw.startDate') + ), + false => $qb->expr()->andX( + $qb->expr()->lte('acpw.startDate', ':'.$ae), + $qb->expr()->isNotNull('acpw.startDate') + ), + default => throw new \LogicException("This value is not supported"), + }; + $end = match ($data['keep_null']) { + true => $qb->expr()->orX( + $qb->expr()->gt('acpw.startDate', ':'.$as), + $qb->expr()->isNull('acpw.startDate') + ), + false => $qb->expr()->andX( + $qb->expr()->gt('acpw.startDate', ':'.$as), + $qb->expr()->isNotNull('acpw.startDate') + ), + default => throw new \LogicException("This value is not supported"), + }; + + if (null !== $data['start_date']) { + $qb + ->andWhere($start) + ->setParameter($as, $this->rollingDateConverter->convert($data['start_date'])); + } + + if (null !== $data['end_date']) { + $qb + ->andWhere($end) + ->setParameter($ae, $this->rollingDateConverter->convert($data['end_date'])); + } + } + + public function applyOn(): string + { + return Declarations::SOCIAL_WORK_ACTION_TYPE; + } +} diff --git a/src/Bundle/ChillPersonBundle/config/services/exports_social_actions.yaml b/src/Bundle/ChillPersonBundle/config/services/exports_social_actions.yaml index ecf0ec399..5f6c2690d 100644 --- a/src/Bundle/ChillPersonBundle/config/services/exports_social_actions.yaml +++ b/src/Bundle/ChillPersonBundle/config/services/exports_social_actions.yaml @@ -48,7 +48,19 @@ services: tags: - { name: chill.export_filter, alias: social_work_actions_current_filter } - ## AGGREGATORS + Chill\PersonBundle\Export\Filter\SocialWorkFilters\AccompanyingPeriodWorkStartDateBetweenDateFilter: + autowire: true + autoconfigure: true + tags: + - { name: chill.export_filter, alias: social_work_actions_start_btw_dates_filter } + + Chill\PersonBundle\Export\Filter\SocialWorkFilters\AccompanyingPeriodWorkEndDateBetweenDateFilter: + autowire: true + autoconfigure: true + tags: + - { name: chill.export_filter, alias: social_work_actions_end_btw_dates_filter } + + ## AGGREGATORS chill.person.export.aggregator_action_type: class: Chill\PersonBundle\Export\Aggregator\SocialWorkAggregators\ActionTypeAggregator autowire: true diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index d33957ea7..471333df2 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -1083,6 +1083,21 @@ export: Calculation date: Date de la localisation creator_job: 'Filtered by creator job: only %jobs%': 'Filtré par métier du créateur: seulement %jobs%' + work: + start_between_dates: + title: Filtre les actions d'accompagnement dont la date d'ouverture est entre deux dates + start_date: Date de début + end_date: Date de fin + keep_null: Conserver les actions dont la date de début n'est pas indiquée + keep_null_help: Si coché, les actions dont la date de début est vide seront prises en compte. Si non coché, elles ne seront pas comptabilisée. + Only where start date is between %startDate% and %endDate%: Seulement les actions dont la date de début est entre le %startDate% et le %endDate% + end_between_dates: + title: Filtre les actions d'accompagnement dont la date de clotûre est entre deux dates (ou l'action est toujours ouverte) + start_date: Date de début + end_date: Date de fin + keep_null: Conserver les actions dont la date de fin n'est pas indiquée (actions en cours) + keep_null_help: Si coché, les actions dont la date de fin est vide seront prises en compte. Si non coché, elles ne seront pas comptabilisée. + Only where start date is between %startDate% and %endDate%: Seulement les actions dont la date de fin est entre le %startDate% et le %endDate% list: person_with_acp: List peoples having an accompanying period: Liste des usagers ayant un parcours d'accompagnement From 3e3f20993d758c719dea09062bb76dfd6b52df47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Fri, 28 Apr 2023 15:55:41 +0200 Subject: [PATCH 037/321] fix migration after test on real data --- .../migrations/Version20230427102309.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/migrations/Version20230427102309.php b/src/Bundle/ChillPersonBundle/migrations/Version20230427102309.php index 7398a2292..662c11d9a 100644 --- a/src/Bundle/ChillPersonBundle/migrations/Version20230427102309.php +++ b/src/Bundle/ChillPersonBundle/migrations/Version20230427102309.php @@ -144,8 +144,9 @@ final class Version20230427102309 extends AbstractMigration $this->addSql(<<<'SQL' INSERT INTO chill_person_accompanying_period_step_history (id, period_id, enddate, startdate, step, createdat, updatedat) - SELECT nextval('chill_person_accompanying_period_step_history_id_seq'), accompanyingperiod_id, NULL, last_date + '2 years'::interval, 'CONFIRMED_INACTIVE_LONG', NOW(), NOW() - FROM inactive_long; + SELECT nextval('chill_person_accompanying_period_step_history_id_seq'), period_id, NULL, sq.g, 'CONFIRMED_INACTIVE_LONG', NOW(), NOW() + FROM (SELECT GREATEST(MAX(startdate), MAX(enddate)) AS g, period_id FROM chill_person_accompanying_period_step_history GROUP BY period_id) AS sq + JOIN inactive_long ON sq.period_id = inactive_long.accompanyingperiod_id SQL); $this->addSql(<<<'SQL' @@ -173,8 +174,9 @@ final class Version20230427102309 extends AbstractMigration $this->addSql(<<<'SQL' INSERT INTO chill_person_accompanying_period_step_history (id, period_id, enddate, startdate, step, createdat, updatedat) - SELECT nextval('chill_person_accompanying_period_step_history_id_seq'), accompanyingperiod_id, NULL, last_date + '6 months'::interval, 'CONFIRMED_INACTIVE_SHORT', NOW(), NOW() - FROM inactive_long; + SELECT nextval('chill_person_accompanying_period_step_history_id_seq'), period_id, NULL, sq.g, 'CONFIRMED_INACTIVE_SHORT', NOW(), NOW() + FROM (SELECT GREATEST(MAX(startdate), MAX(enddate)) AS g, period_id FROM chill_person_accompanying_period_step_history GROUP BY period_id) AS sq + JOIN inactive_long ON sq.period_id = inactive_long.accompanyingperiod_id SQL); $this->addSql(<<<'SQL' From 2554da9dd81b9fc94b12ee44a8d9bfbe6b468274 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Fri, 28 Apr 2023 23:16:13 +0200 Subject: [PATCH 038/321] Fix: urgent fix for EntityToJsonTransformer The throw on error flag imposes us to propose a valid json string for decoding --- .../Form/Type/DataTransformer/EntityToJsonTransformer.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Form/Type/DataTransformer/EntityToJsonTransformer.php b/src/Bundle/ChillMainBundle/Form/Type/DataTransformer/EntityToJsonTransformer.php index 529bd9789..7dff8d672 100644 --- a/src/Bundle/ChillMainBundle/Form/Type/DataTransformer/EntityToJsonTransformer.php +++ b/src/Bundle/ChillMainBundle/Form/Type/DataTransformer/EntityToJsonTransformer.php @@ -43,6 +43,10 @@ class EntityToJsonTransformer implements DataTransformerInterface public function reverseTransform($value) { + if ("" === $value) { + return null; + } + $denormalized = json_decode($value, true, 512, JSON_THROW_ON_ERROR); if ($this->multiple) { @@ -56,10 +60,6 @@ class EntityToJsonTransformer implements DataTransformerInterface ); } - if ('' === $value) { - return null; - } - return $this->denormalizeOne($denormalized); } From a0ae1f0d0f96e9036db1e24514f922f157fe9173 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Wed, 3 May 2023 12:11:00 +0200 Subject: [PATCH 039/321] FIX [budget] display budget element comment if it is of kind 'autre' --- .../Resources/views/Budget/_macros.html.twig | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_macros.html.twig b/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_macros.html.twig index 70e96d96c..dfa286af4 100644 --- a/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_macros.html.twig +++ b/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_macros.html.twig @@ -16,8 +16,14 @@
    {% if f.isResource %} {{ f.resource.name|localize_translatable_string }} + {% if f.resource.getKind is same as 'other' %} + : {{ f.getComment }} + {% endif %} {% else %} {{ f.charge.name|localize_translatable_string }} + {% if f.charge.getKind is same as 'other' %} + : {{ f.getComment }} + {% endif %} {% endif %} {{ f.amount|format_currency('EUR') }}{{ mm.mimeIcon(d.storedObject.type) }} - + {% if accompanyingCourse.hasUser and accompanyingCourse.user is not same as(app.user) %} + + + {% else %} + + {% endif %} + {{ d.storedObject|chill_document_button_group(d.title, is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_UPDATE', w), {'small': true}) }}
    - - - - - -
    {{ document.title }}{{ mm.mimeIcon(document.storedObject.type) }} - -
    -
    -{% endmacro %} {% if document is not null %} - + {% import "@ChillDocStore/Macro/macro_mimeicon.html.twig" as mm %}
    {% if is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_EVALUATION_DOCUMENT_SHOW', document) %} -
    - {% include '@ChillPerson/AccompanyingCourseWork/_objectifs_results_evaluations.html.twig' with { - 'w': document.accompanyingPeriodWorkEvaluation.accompanyingPeriodWork, - 'd': document.storedObject, - 'displayContent': 'short', - 'recordAction': _self.recordAction(document), - 'onlyone' : true, - 'evalId': document.accompanyingPeriodWorkEvaluation.id - } %} + {% set doc = document %} +
    +
    +

    {{ "Document"|trans }}: {{ doc.title }}

    +
    +
    +

    + + + {{ evaluation.accompanyingPeriodWork.socialAction|chill_entity_render_string }} +
      +
    • + {{ 'accompanying_course_work.start_date'|trans ~ ' : ' }} + {{ evaluation.accompanyingPeriodWork.startDate|format_date('short') }} +
    • + {% if evaluation.accompanyingPeriodWork.endDate %} +
    • + {{ 'accompanying_course_work.end_date'|trans ~ ' : ' }} + {{ evaluation.accompanyingPeriodWork.endDate|format_date('short') }} +
    • + {% endif %} +
    +
    +

    +
    +
    +
    +

    + {{ 'Participants'|trans }} +

    +
    +
    + {% for p in evaluation.accompanyingPeriodWork.persons %} + {% include '@ChillMain/OnTheFly/_insert_vue_onthefly.html.twig' with { + targetEntity: { name: 'person', id: p.id }, + action: 'show', + displayBadge: true, + buttonText: p|chill_entity_render_string, + isDead: p.deathdate is not null + } %} + {% endfor %} +
    +
    +
    + + + + + + + + + + + +
    +

    + {{ 'Évaluation'|trans }} +

    +
    +
      +
    • + {{ evaluation.evaluation.title|localize_translatable_string }} +
        +
      • + {{ 'accompanying_course_work.start_date'|trans ~ ' : ' }} + {{ evaluation.startDate|format_date('short') }} +
      • + {% if evaluation.endDate %} +
      • + {{ 'accompanying_course_work.end_date'|trans ~ ' : ' }} + {{ evaluation.endDate|format_date('short') }} +
      • + {% endif %} + {% if evaluation.maxDate %} +
      • + {{ 'accompanying_course_work.max_date'|trans ~ ' : ' }} + {{ evaluation.maxDate|format_date('short') }} +
      • + {% endif %} + {% if evaluation.warningInterval and evaluation.warningInterval.d > 0 %} +
      • + {% set days = (evaluation.warningInterval.d + evaluation.warningInterval.m * 30) %} + {{ 'accompanying_course_work.warning_interval'|trans ~ ' : ' }} + {{ 'accompanying_course_work.%days% days before max_date'|trans({'%days%': days }) }} +
      • + {% endif %} +
      • + {% if evaluation.createdBy is not null %} + créé par + {{ evaluation.createdBy.username }} + {% endif %} + {% if evaluation.createdAt is not null %} + {{ 'le'|trans }} + {{ evaluation.createdAt|format_date('short') }} + {% endif %} +
      • +
      + {% if evaluation.comment %} +
      + {{ evaluation.comment }} +
      + {% endif %} +
    • +
    +
    +
    +
    +
      +
    • + +
    • +
    +
    {% else %} From d815b4428011049720d34422e9ebfd663dfd9099 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 13 Jun 2023 23:05:34 +0200 Subject: [PATCH 179/321] DX: more type-hinting on AccompanyingPeriodWork --- .../Entity/AccompanyingPeriod/AccompanyingPeriodWork.php | 4 ++++ .../AccompanyingPeriod/AccompanyingPeriodWorkEvaluation.php | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/AccompanyingPeriodWork.php b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/AccompanyingPeriodWork.php index 5361012b3..e3b2883be 100644 --- a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/AccompanyingPeriodWork.php +++ b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/AccompanyingPeriodWork.php @@ -59,6 +59,7 @@ class AccompanyingPeriodWork implements AccompanyingPeriodLinkedWithSocialIssues * ) * @Serializer\Groups({"read", "docgen:read"}) * @ORM\OrderBy({"startDate": "DESC", "id": "DESC"}) + * @var Collection * * @internal /!\ the serialization for write evaluations is handled in `AccompanyingPeriodWorkDenormalizer` */ @@ -278,6 +279,9 @@ class AccompanyingPeriodWork implements AccompanyingPeriodLinkedWithSocialIssues return $this->accompanyingPeriod; } + /** + * @return Collection + */ public function getAccompanyingPeriodWorkEvaluations(): Collection { return $this->accompanyingPeriodWorkEvaluations; diff --git a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/AccompanyingPeriodWorkEvaluation.php b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/AccompanyingPeriodWorkEvaluation.php index 8780f7d17..d35ffc900 100644 --- a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/AccompanyingPeriodWorkEvaluation.php +++ b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/AccompanyingPeriodWorkEvaluation.php @@ -79,6 +79,7 @@ class AccompanyingPeriodWorkEvaluation implements TrackCreationInterface, TrackU * ) * @ORM\OrderBy({"createdAt": "DESC", "id": "DESC"}) * @Serializer\Groups({"read"}) + * @var Collection */ private Collection $documents; @@ -204,7 +205,7 @@ class AccompanyingPeriodWorkEvaluation implements TrackCreationInterface, TrackU } /** - * @return Collection + * @return Collection */ public function getDocuments() { From 3b9fae3b49220c7f32c98837cfaa4aab6b31d945 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 13 Jun 2023 23:06:50 +0200 Subject: [PATCH 180/321] add changelog --- .changes/unreleased/Feature-20230613-230640.yaml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changes/unreleased/Feature-20230613-230640.yaml diff --git a/.changes/unreleased/Feature-20230613-230640.yaml b/.changes/unreleased/Feature-20230613-230640.yaml new file mode 100644 index 000000000..18694c724 --- /dev/null +++ b/.changes/unreleased/Feature-20230613-230640.yaml @@ -0,0 +1,5 @@ +kind: Feature +body: Add notification to accompanying period work and work's evaluation's documents +time: 2023-06-13T23:06:40.090777525+02:00 +custom: + Issue: "" From 8a91be4ef39ae9ab8199664ee6d0a3fa77ef1abb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 13 Jun 2023 23:09:08 +0200 Subject: [PATCH 181/321] add changelog [ci-skip] --- .changes/unreleased/Fixed-20230613-230838.yaml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changes/unreleased/Fixed-20230613-230838.yaml diff --git a/.changes/unreleased/Fixed-20230613-230838.yaml b/.changes/unreleased/Fixed-20230613-230838.yaml new file mode 100644 index 000000000..816f4f8d4 --- /dev/null +++ b/.changes/unreleased/Fixed-20230613-230838.yaml @@ -0,0 +1,5 @@ +kind: Fixed +body: Fix the notification counter +time: 2023-06-13T23:08:38.67342897+02:00 +custom: + Issue: "55" From 8fabfdd5c023571429ba5b2efa13d20b27c9fd96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 14 Jun 2023 22:54:18 +0200 Subject: [PATCH 182/321] Feature: [export] filter on accompanying period step: allow to check multiple steps --- .../unreleased/Feature-20230614-224720.yaml | 6 +++++ .../AccompanyingCourseFilters/StepFilter.php | 27 ++++++++++++------- 2 files changed, 24 insertions(+), 9 deletions(-) create mode 100644 .changes/unreleased/Feature-20230614-224720.yaml diff --git a/.changes/unreleased/Feature-20230614-224720.yaml b/.changes/unreleased/Feature-20230614-224720.yaml new file mode 100644 index 000000000..3f86b022f --- /dev/null +++ b/.changes/unreleased/Feature-20230614-224720.yaml @@ -0,0 +1,6 @@ +kind: Feature +body: '[Export] Filter accompanying period by step at date: allow to pick multiple + steps' +time: 2023-06-14T22:47:20.577100599+02:00 +custom: + Issue: "113" diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/StepFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/StepFilter.php index 8ee798c07..539aa9940 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/StepFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/StepFilter.php @@ -27,7 +27,11 @@ class StepFilter implements FilterInterface { private const A = 'acp_filter_bystep_stephistories'; - private const DEFAULT_CHOICE = AccompanyingPeriod::STEP_CONFIRMED; + private const DEFAULT_CHOICE = [ + AccompanyingPeriod::STEP_CONFIRMED, + AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_SHORT, + AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_LONG, + ]; private const P = 'acp_step_filter_date'; @@ -79,7 +83,7 @@ class StepFilter implements FilterInterface $qb->expr()->in(self::A . '.step', ':acp_filter_by_step_steps') ) ->setParameter(self::P, $this->rollingDateConverter->convert($data['calc_date'])) - ->setParameter('acp_filter_by_step_steps', $data['accepted_steps']); + ->setParameter('acp_filter_by_step_steps', $data['accepted_steps_multi']); } public function applyOn() @@ -90,25 +94,30 @@ class StepFilter implements FilterInterface public function buildForm(FormBuilderInterface $builder) { $builder - ->add('accepted_steps', ChoiceType::class, [ + ->add('accepted_steps_multi', ChoiceType::class, [ 'choices' => self::STEPS, - 'multiple' => false, + 'multiple' => true, 'expanded' => true, - 'empty_data' => self::DEFAULT_CHOICE, - 'data' => self::DEFAULT_CHOICE, ]) ->add('calc_date', PickRollingDateType::class, [ 'label' => 'export.filter.course.by_step.date_calc', - 'data' => new RollingDate(RollingDate::T_TODAY), ]); } + public function getFormDefaultData(): array + { + return [ + 'accepted_steps_multi' => self::DEFAULT_CHOICE, + 'calc_date' => new RollingDate(RollingDate::T_TODAY), + ]; + } + public function describeAction($data, $format = 'string') { - $step = array_flip(self::STEPS)[$data['accepted_steps']]; + $steps = array_map(fn (string $step) => $this->translator->trans(array_flip(self::STEPS)[$step]), $data['accepted_steps_multi']); return ['Filtered by steps: only %step%', [ - '%step%' => $this->translator->trans($step), + '%step%' => implode(', ', $steps), ]]; } From 398b63386393cd11a0a154e9a469ffc483d61aca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 14 Jun 2023 23:29:18 +0200 Subject: [PATCH 183/321] DX: simplify overlapsI expression in postgresql --- .changes/unreleased/DX-20230614-233000.yaml | 5 +++++ src/Bundle/ChillMainBundle/Doctrine/DQL/OverlapsI.php | 6 ++---- 2 files changed, 7 insertions(+), 4 deletions(-) create mode 100644 .changes/unreleased/DX-20230614-233000.yaml diff --git a/.changes/unreleased/DX-20230614-233000.yaml b/.changes/unreleased/DX-20230614-233000.yaml new file mode 100644 index 000000000..ca4a3171b --- /dev/null +++ b/.changes/unreleased/DX-20230614-233000.yaml @@ -0,0 +1,5 @@ +kind: DX +body: 'DQL function OVERLAPSI: simplify expression in postgresql' +time: 2023-06-14T23:30:00.217427234+02:00 +custom: + Issue: "" diff --git a/src/Bundle/ChillMainBundle/Doctrine/DQL/OverlapsI.php b/src/Bundle/ChillMainBundle/Doctrine/DQL/OverlapsI.php index 29642dc15..d39c1451c 100644 --- a/src/Bundle/ChillMainBundle/Doctrine/DQL/OverlapsI.php +++ b/src/Bundle/ChillMainBundle/Doctrine/DQL/OverlapsI.php @@ -90,16 +90,14 @@ class OverlapsI extends FunctionNode if ($part instanceof PathExpression) { return sprintf( - "CASE WHEN %s IS NOT NULL THEN %s ELSE '%s'::date END", - $part->dispatch($sqlWalker), + "COALESCE(%s, '%s'::date)", $part->dispatch($sqlWalker), $p ); } return sprintf( - "CASE WHEN %s::date IS NOT NULL THEN %s::date ELSE '%s'::date END", - $part->dispatch($sqlWalker), + "COALESCE(%s::date, '%s'::date)", $part->dispatch($sqlWalker), $p ); From fe936ac0f2aab826149a226efb5d631efc0d76b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 14 Jun 2023 23:31:43 +0200 Subject: [PATCH 184/321] Feature: [export][course] filter course by step, between two dates --- .../unreleased/Feature-20230614-233107.yaml | 5 + .../StepFilterBetweenDates.php | 125 ++++++++++++++++++ .../{StepFilter.php => StepFilterOnDate.php} | 5 +- .../StepFilterTest.php | 4 +- .../services/exports_accompanying_course.yaml | 7 +- .../translations/messages.fr.yml | 7 +- 6 files changed, 146 insertions(+), 7 deletions(-) create mode 100644 .changes/unreleased/Feature-20230614-233107.yaml create mode 100644 src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/StepFilterBetweenDates.php rename src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/{StepFilter.php => StepFilterOnDate.php} (95%) diff --git a/.changes/unreleased/Feature-20230614-233107.yaml b/.changes/unreleased/Feature-20230614-233107.yaml new file mode 100644 index 000000000..2d0e502f2 --- /dev/null +++ b/.changes/unreleased/Feature-20230614-233107.yaml @@ -0,0 +1,5 @@ +kind: Feature +body: '[export] add a filter on accompanying period: filter by step between two dates' +time: 2023-06-14T23:31:07.979389911+02:00 +custom: + Issue: "113" diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/StepFilterBetweenDates.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/StepFilterBetweenDates.php new file mode 100644 index 000000000..9033c64b3 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/StepFilterBetweenDates.php @@ -0,0 +1,125 @@ + AccompanyingPeriod::STEP_DRAFT, + 'course.confirmed' => AccompanyingPeriod::STEP_CONFIRMED, + 'course.closed' => AccompanyingPeriod::STEP_CLOSED, + 'course.inactive_short' => AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_SHORT, + 'course.inactive_long' => AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_LONG, + ]; + + private RollingDateConverterInterface $rollingDateConverter; + + private TranslatorInterface $translator; + + public function __construct( + RollingDateConverterInterface $rollingDateConverter, + TranslatorInterface $translator + ) { + $this->rollingDateConverter = $rollingDateConverter; + $this->translator = $translator; + } + + public function addRole(): ?string + { + return null; + } + + public function alterQuery(QueryBuilder $qb, $data) + { + $alias = 'acp_filter_by_step_between_dat_alias'; + $steps = 'acp_filter_by_step_between_dat_steps'; + $from = 'acp_filter_by_step_between_dat_from'; + $to = 'acp_filter_by_step_between_dat_to'; + + $qb + ->andWhere( + $qb->expr()->exists( + "SELECT 1 FROM " . AccompanyingPeriod\AccompanyingPeriodStepHistory::class . " {$alias} " . + "WHERE {$alias}.step IN (:{$steps}) AND OVERLAPSI ({$alias}.startDate, {$alias}.endDate),(:{$from}, :{$to}) = TRUE " . + "AND {$alias}.period = acp" + ) + ) + ->setParameter($from, $this->rollingDateConverter->convert($data['date_from'])) + ->setParameter($to, $this->rollingDateConverter->convert($data['date_to'])) + ->setParameter($steps, $data['accepted_steps_multi']); + } + + public function applyOn() + { + return Declarations::ACP_TYPE; + } + + public function buildForm(FormBuilderInterface $builder) + { + $builder + ->add('accepted_steps_multi', ChoiceType::class, [ + 'label' => 'export.filter.course.by_step.steps', + 'choices' => self::STEPS, + 'multiple' => true, + 'expanded' => true, + ]) + ->add('date_from', PickRollingDateType::class, [ + 'label' => 'export.filter.course.by_step.date_from', + ]) + ->add('date_to', PickRollingDateType::class, [ + 'label' => 'export.filter.course.by_step.date_to', + ]); + } + + public function getFormDefaultData(): array + { + return [ + 'accepted_steps_multi' => self::DEFAULT_CHOICE, + 'date_from' => new RollingDate(RollingDate::T_YEAR_CURRENT_START), + 'date_to' => new RollingDate(RollingDate::T_TODAY), + ]; + } + + public function describeAction($data, $format = 'string') + { + $steps = array_map(fn (string $step) => $this->translator->trans(array_flip(self::STEPS)[$step]), $data['accepted_steps_multi']); + + return ['export.filter.course.by_step.Filtered by steps: only %step% and between %date_from% and %date_to%', [ + '%step%' => implode(', ', $steps), + '%date_from%' => $this->rollingDateConverter->convert($data['date_from'])->format('d-m-Y'), + '%date_to%' => $this->rollingDateConverter->convert($data['date_to'])->format('d-m-Y'), + ]]; + } + + public function getTitle() + { + return 'export.filter.course.by_step.Filter by step between dates'; + } +} diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/StepFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/StepFilterOnDate.php similarity index 95% rename from src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/StepFilter.php rename to src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/StepFilterOnDate.php index 539aa9940..357ed6f30 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/StepFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/StepFilterOnDate.php @@ -23,7 +23,7 @@ use Symfony\Component\Form\FormBuilderInterface; use Symfony\Contracts\Translation\TranslatorInterface; use function in_array; -class StepFilter implements FilterInterface +class StepFilterOnDate implements FilterInterface { private const A = 'acp_filter_bystep_stephistories'; @@ -95,6 +95,7 @@ class StepFilter implements FilterInterface { $builder ->add('accepted_steps_multi', ChoiceType::class, [ + 'label' => 'export.filter.course.by_step.steps', 'choices' => self::STEPS, 'multiple' => true, 'expanded' => true, @@ -123,6 +124,6 @@ class StepFilter implements FilterInterface public function getTitle() { - return 'Filter by step'; + return 'export.filter.course.by_step.Filter by step'; } } diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Filter/AccompanyingCourseFilters/StepFilterTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Filter/AccompanyingCourseFilters/StepFilterTest.php index 42eec5823..1b6224487 100644 --- a/src/Bundle/ChillPersonBundle/Tests/Export/Filter/AccompanyingCourseFilters/StepFilterTest.php +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Filter/AccompanyingCourseFilters/StepFilterTest.php @@ -13,7 +13,7 @@ namespace Chill\PersonBundle\Tests\Export\Filter\AccompanyingCourseFilters; use Chill\MainBundle\Test\Export\AbstractFilterTest; use Chill\PersonBundle\Entity\AccompanyingPeriod; -use Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\StepFilter; +use Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\StepFilterOnDate; /** * @internal @@ -21,7 +21,7 @@ use Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\StepFilter; */ final class StepFilterTest extends AbstractFilterTest { - private StepFilter $filter; + private StepFilterOnDate $filter; protected function setUp(): void { diff --git a/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_course.yaml b/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_course.yaml index adde8d336..c299bbaaa 100644 --- a/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_course.yaml +++ b/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_course.yaml @@ -28,11 +28,14 @@ services: tags: - { name: chill.export_filter, alias: accompanyingcourse_socialissue_filter } - chill.person.export.filter_step: - class: Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\StepFilter + Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\StepFilterOnDate: tags: - { name: chill.export_filter, alias: accompanyingcourse_step_filter } + Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\StepFilterBetweenDates: + tags: + - { name: chill.export_filter, alias: accompanyingcourse_step_filter_between_dates } + chill.person.export.filter_geographicalunitstat: class: Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\GeographicalUnitStatFilter tags: diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index 5cc9ee1f1..bdb93afc0 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -473,7 +473,6 @@ Accepted socialissues: Problématiques sociales "Filtered by socialissues: only %socialissues%": "Filtré par problématique sociale: uniquement %socialissues%" Group by social issue: Grouper les parcours par problématiques sociales -Filter by step: Filtrer les parcours par statut du parcours Accepted steps: Statuts Step: Statut "Filtered by steps: only %step%": "Filtré par statut du parcours: uniquement %step%" @@ -1085,7 +1084,13 @@ export: title: Filter les parcours par intervenant 'Filtered by user working on course: only %users%': 'Filtré par intervenants sur le parcours: seulement %users%' by_step: + Filter by step: Filtrer les parcours par statut du parcours + Filter by step between dates: Filtrer les parcours par statut du parcours entre deux dates + steps: Statuts retenus date_calc: Date de prise en compte du statut + date_from: Statuts acquis après cette date + date_to: Statuts acquis avant cette date + 'Filtered by steps: only %step% and between %date_from% and %date_to%': 'Filtré par statut: seulement %step%, entre %date_from% et %date_to%' by_user_scope: Computation date for referrer: Date à laquelle le référent était actif by_referrer: From 3fb97c3945f4e61ba118e7d9be16cc5d830338f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Fri, 16 Jun 2023 14:07:49 +0200 Subject: [PATCH 185/321] DX: comment the examples in rule definition As this is genearte error in both phpunits and php-cs-fixer --- ...BundleAddFormDefaultDataOnExportFilterAggregatorRector.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/utils/rector/src/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector.php b/utils/rector/src/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector.php index e6bf4a75a..fe996c987 100644 --- a/utils/rector/src/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector.php +++ b/utils/rector/src/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector.php @@ -32,7 +32,7 @@ class ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector extends Abstra { return new RuleDefinition( 'Add a getFormDefault data method on exports, filters and aggregators, filled with default data', - [ + [/* << new RollingDate(RollingDate::T_TODAY), 'baz' => 'Castor']; } } -PHP +PHP */ ] ); } From c52ba06ea0a29e1149046ab24d21d53fb2f17453 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Fri, 16 Jun 2023 15:26:49 +0200 Subject: [PATCH 186/321] adapt rector rules for chained builder->add --- ...aultDataOnExportFilterAggregatorRector.php | 113 ++++++++++++------ ...-default-data-with-chained-builder.php.inc | 111 +++++++++++++++++ 2 files changed, 188 insertions(+), 36 deletions(-) create mode 100644 utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/Fixture/filter-multiple-reuse-data-on-form-default-data-with-chained-builder.php.inc diff --git a/utils/rector/src/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector.php b/utils/rector/src/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector.php index fe996c987..cc54a24f1 100644 --- a/utils/rector/src/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector.php +++ b/utils/rector/src/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector.php @@ -183,43 +183,11 @@ PHP */ if ($stmt instanceof Node\Stmt\Expression // it must be a method call && $stmt->expr instanceof Node\Expr\MethodCall - // the method call must be "add" - && $stmt->expr->name instanceof Node\Identifier - && $stmt->expr->name->name === 'add' - // and the method call must apply on the builder (compare with builderName) - && $stmt->expr->var instanceof Node\Expr\Variable - && $stmt->expr->var->name === $builderName - // it must have a first argument, a string - // TODO what happens if a value, or a const ? - && ($stmt->expr->args[0] ?? null) instanceof Node\Arg - && $stmt->expr->args[0]->value instanceof Node\Scalar\String_ - // and a third argument, an array - && ($stmt->expr->args[2] ?? null) instanceof Node\Arg - && $stmt->expr->args[2]->value instanceof Node\Expr\Array_ + && false !== ($results = $this->handleMethodCallBuilderAdd($stmt->expr, $builderName)) ) { - - // we parse on the 3rd argument, to find if there is an 'empty_data' key - $emptyDataIndex = null; - foreach ($stmt->expr->args[2]->value->items as $arrayItemIndex => $item) { - /* @phpstan-ignore-next-line */ - if ($item->key->value === 'data') { - $k = $stmt->expr->args[0]->value->value; - $emptyDataToReplace[$k] = $item->value; - $emptyDataIndex = $arrayItemIndex; - } - } - - if (null !== $emptyDataIndex) { - $stmt->expr->args[2]->value->items = array_values( - array_filter( - $stmt->expr->args[2]->value->items, - /* @phpstan-ignore-next-line */ - fn (Node\Expr\ArrayItem $item) => $item->key->value !== 'data' - ) - ); - } - - $newStmts[] = $stmt; + ['stmt' => $newMethodCAll, 'emptyDataToReplace' => $newEmptyDataToReplace] = $results; + $newStmts[] = new Node\Stmt\Expression($newMethodCAll); + $emptyDataToReplace = [...$emptyDataToReplace, ...$newEmptyDataToReplace]; } else { $newStmts[] = $stmt; } @@ -229,4 +197,77 @@ PHP */ return ['build_form_method' => $buildFormMethod, "empty_to_replace" => $emptyDataToReplace]; } + + private function handleMethodCallBuilderAdd(Node\Expr\MethodCall $methodCall, string $builderName): array|false + { + $emptyDataToReplace = []; + // check for chained method call + if ( + // this means that the MethodCall apply on another method call: a chained + $methodCall->var instanceof Node\Expr\MethodCall + ) { + // as this is chained, we make a recursion on this method + + $resultFormDeepMethodCall = $this->handleMethodCallBuilderAdd($methodCall->var, $builderName); + + if (false === $resultFormDeepMethodCall) { + return false; + } + + ['stmt' => $chainedMethodCall, 'emptyDataToReplace' => $newEmptyDataToReplace] = $resultFormDeepMethodCall; + $emptyDataToReplace = $newEmptyDataToReplace; + $methodCall->var = $chainedMethodCall; + } + + if ( + $methodCall->var instanceof Node\Expr\Variable + ) { + if ($methodCall->var->name !== $builderName) { + // ho, this does not apply on a builder, so we cancel all the method calls + return false; + } + } + + if ($methodCall->name instanceof Node\Identifier && $methodCall->name->name !== 'add') { + return ['stmt' => $methodCall, 'emptyDataToReplace' => $emptyDataToReplace]; + } + + if ( + // the method call must be "add" + $methodCall->name instanceof Node\Identifier + && $methodCall->name->name === 'add' + // it must have a first argument, a string + // TODO what happens if a value, or a const ? + && ($methodCall->args[0] ?? null) instanceof Node\Arg + && $methodCall->args[0]->value instanceof Node\Scalar\String_ + // and a third argument, an array + && ($methodCall->args[2] ?? null) instanceof Node\Arg + && $methodCall->args[2]->value instanceof Node\Expr\Array_ + ) { + // we parse on the 3rd argument, to find if there is an 'empty_data' key + $emptyDataIndex = null; + foreach ($methodCall->args[2]->value->items as $arrayItemIndex => $item) { + /* @phpstan-ignore-next-line */ + if ($item->key->value === 'data' or $item->key->value === 'empty_data') { + $k = $methodCall->args[0]->value->value; + $emptyDataToReplace[$k] = $item->value; + $emptyDataIndex = $arrayItemIndex; + } + } + + if (null !== $emptyDataIndex) { + $methodCall->args[2]->value->items = array_values( + array_filter( + $methodCall->args[2]->value->items, + /* @phpstan-ignore-next-line */ + fn (Node\Expr\ArrayItem $item) => $item->key->value !== 'data' + ) + ); + } + + return ['stmt' => $methodCall, 'emptyDataToReplace' => $emptyDataToReplace]; + } + + throw new \RuntimeException("Not supported situation"); + } } diff --git a/utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/Fixture/filter-multiple-reuse-data-on-form-default-data-with-chained-builder.php.inc b/utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/Fixture/filter-multiple-reuse-data-on-form-default-data-with-chained-builder.php.inc new file mode 100644 index 000000000..ed46f6381 --- /dev/null +++ b/utils/rector/tests/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector/Fixture/filter-multiple-reuse-data-on-form-default-data-with-chained-builder.php.inc @@ -0,0 +1,111 @@ +add('foo', PickRollingDateType::class, [ + 'label' => 'Test thing', + 'data' => new RollingDate(RollingDate::T_TODAY) + ]) + ->anotherCall('test') + ->add('baz', TextType::class, [ + 'label' => 'OrNiCar', + 'data' => 'Castor' + ]) + ->baz('foo'); + } + + public function getTitle() + { + // TODO: Implement getTitle() method. + } + + public function addRole(): ?string + { + // TODO: Implement addRole() method. + } + + public function alterQuery(QueryBuilder $qb, $data) + { + // TODO: Implement alterQuery() method. + } + + public function applyOn() + { + // TODO: Implement applyOn() method. + } +} +?> +----- +add('foo', PickRollingDateType::class, [ + 'label' => 'Test thing' + ]) + ->anotherCall('test') + ->add('baz', TextType::class, [ + 'label' => 'OrNiCar' + ]) + ->baz('foo'); + } + public function getFormDefaultData(): array + { + return ['foo' => new RollingDate(RollingDate::T_TODAY), 'baz' => 'Castor']; + } + + public function getTitle() + { + // TODO: Implement getTitle() method. + } + + public function addRole(): ?string + { + // TODO: Implement addRole() method. + } + + public function alterQuery(QueryBuilder $qb, $data) + { + // TODO: Implement alterQuery() method. + } + + public function applyOn() + { + // TODO: Implement applyOn() method. + } +} +?> From 960acb8c0ac32467743bab2f9b09c3f3580af353 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Sun, 18 Jun 2023 11:57:26 +0200 Subject: [PATCH 187/321] Revert "apply rector rules for exports" This reverts commit 3adf3625 --- docs/source/_static/code/exports/BirthdateFilter.php | 6 ++---- docs/source/_static/code/exports/CountPerson.php | 4 ---- .../ACPAggregators/ByActivityNumberAggregator.php | 4 ---- .../Aggregator/ACPAggregators/ByCreatorAggregator.php | 4 ---- .../ACPAggregators/BySocialActionAggregator.php | 4 ---- .../Aggregator/ACPAggregators/BySocialIssueAggregator.php | 4 ---- .../Aggregator/ACPAggregators/ByThirdpartyAggregator.php | 4 ---- .../Aggregator/ACPAggregators/CreatorScopeAggregator.php | 4 ---- .../Export/Aggregator/ACPAggregators/DateAggregator.php | 6 ++---- .../Aggregator/ACPAggregators/LocationTypeAggregator.php | 4 ---- .../Export/Aggregator/ActivityTypeAggregator.php | 4 ---- .../Export/Aggregator/ActivityUserAggregator.php | 4 ---- .../Export/Aggregator/ActivityUsersAggregator.php | 4 ---- .../Export/Aggregator/ActivityUsersJobAggregator.php | 4 ---- .../Export/Aggregator/ActivityUsersScopeAggregator.php | 4 ---- .../PersonAggregators/ActivityReasonAggregator.php | 4 ---- .../Export/Aggregator/SentReceivedAggregator.php | 4 ---- .../Export/Export/LinkedToACP/AvgActivityDuration.php | 4 ---- .../Export/LinkedToACP/AvgActivityVisitDuration.php | 4 ---- .../Export/Export/LinkedToACP/CountActivity.php | 4 ---- .../Export/Export/LinkedToACP/SumActivityDuration.php | 4 ---- .../Export/LinkedToACP/SumActivityVisitDuration.php | 4 ---- .../Export/Export/LinkedToPerson/CountActivity.php | 4 ---- .../Export/Export/LinkedToPerson/StatActivityDuration.php | 4 ---- .../Export/Filter/ACPFilters/ActivityTypeFilter.php | 4 ---- .../Export/Filter/ACPFilters/ByCreatorFilter.php | 4 ---- .../Export/Filter/ACPFilters/BySocialActionFilter.php | 4 ---- .../Export/Filter/ACPFilters/BySocialIssueFilter.php | 4 ---- .../Export/Filter/ACPFilters/EmergencyFilter.php | 6 ++---- .../Export/Filter/ACPFilters/HasNoActivityFilter.php | 4 ---- .../Export/Filter/ACPFilters/LocationFilter.php | 4 ---- .../Export/Filter/ACPFilters/LocationTypeFilter.php | 4 ---- .../Export/Filter/ACPFilters/SentReceivedFilter.php | 5 +---- .../Export/Filter/ACPFilters/UserFilter.php | 4 ---- .../Export/Filter/ACPFilters/UserScopeFilter.php | 4 ---- .../Export/Filter/ActivityDateFilter.php | 4 ---- .../Export/Filter/ActivityTypeFilter.php | 4 ---- .../Export/Filter/ActivityUsersFilter.php | 4 ---- .../Export/Filter/PersonFilters/ActivityReasonFilter.php | 4 ---- .../PersonHavingActivityBetweenDateFilter.php | 7 +++---- .../ChillActivityBundle/Export/Filter/UsersJobFilter.php | 4 ---- .../Export/Filter/UsersScopeFilter.php | 4 ---- .../src/Export/Aggregator/ByActivityTypeAggregator.php | 4 ---- .../src/Export/Aggregator/ByUserJobAggregator.php | 4 ---- .../src/Export/Aggregator/ByUserScopeAggregator.php | 4 ---- .../src/Export/Export/AvgAsideActivityDuration.php | 4 ---- .../src/Export/Export/CountAsideActivity.php | 4 ---- .../src/Export/Export/SumAsideActivityDuration.php | 4 ---- .../src/Export/Filter/ByActivityTypeFilter.php | 4 ---- .../src/Export/Filter/ByDateFilter.php | 4 ---- .../src/Export/Filter/ByUserFilter.php | 4 ---- .../src/Export/Filter/ByUserJobFilter.php | 4 ---- .../src/Export/Filter/ByUserScopeFilter.php | 4 ---- .../Export/Aggregator/AgentAggregator.php | 4 ---- .../Export/Aggregator/CancelReasonAggregator.php | 4 ---- .../Export/Aggregator/JobAggregator.php | 4 ---- .../Export/Aggregator/LocationAggregator.php | 4 ---- .../Export/Aggregator/LocationTypeAggregator.php | 4 ---- .../Export/Aggregator/MonthYearAggregator.php | 4 ---- .../Export/Aggregator/ScopeAggregator.php | 4 ---- .../Export/Aggregator/UrgencyAggregator.php | 4 ---- .../ChillCalendarBundle/Export/Export/CountCalendars.php | 4 ---- .../Export/Export/StatCalendarAvgDuration.php | 4 ---- .../Export/Export/StatCalendarSumDuration.php | 4 ---- .../ChillCalendarBundle/Export/Filter/AgentFilter.php | 4 ---- .../Export/Filter/BetweenDatesFilter.php | 4 ---- .../Export/Filter/CalendarRangeFilter.php | 5 +---- .../ChillCalendarBundle/Export/Filter/JobFilter.php | 4 ---- .../ChillCalendarBundle/Export/Filter/ScopeFilter.php | 4 ---- .../AdministrativeLocationAggregator.php | 4 ---- .../ByActionNumberAggregator.php | 4 ---- .../ClosingMotiveAggregator.php | 4 ---- .../ConfidentialAggregator.php | 4 ---- .../CreatorJobAggregator.php | 4 ---- .../AccompanyingCourseAggregators/DurationAggregator.php | 4 ---- .../AccompanyingCourseAggregators/EmergencyAggregator.php | 4 ---- .../EvaluationAggregator.php | 4 ---- .../GeographicalUnitStatAggregator.php | 4 ---- .../AccompanyingCourseAggregators/IntensityAggregator.php | 4 ---- .../AccompanyingCourseAggregators/OriginAggregator.php | 4 ---- .../AccompanyingCourseAggregators/ReferrerAggregator.php | 5 +---- .../ReferrerScopeAggregator.php | 5 +---- .../AccompanyingCourseAggregators/RequestorAggregator.php | 4 ---- .../AccompanyingCourseAggregators/ScopeAggregator.php | 4 ---- .../SocialActionAggregator.php | 4 ---- .../SocialIssueAggregator.php | 4 ---- .../AccompanyingCourseAggregators/StepAggregator.php | 8 +++----- .../AccompanyingCourseAggregators/UserJobAggregator.php | 4 ---- .../EvaluationAggregators/ByEndDateAggregator.php | 5 +---- .../EvaluationAggregators/ByMaxDateAggregator.php | 5 +---- .../EvaluationAggregators/ByStartDateAggregator.php | 5 +---- .../EvaluationAggregators/EvaluationTypeAggregator.php | 4 ---- .../EvaluationAggregators/HavingEndDateAggregator.php | 4 ---- .../HouseholdAggregators/ChildrenNumberAggregator.php | 8 +++----- .../HouseholdAggregators/CompositionAggregator.php | 8 +++----- .../Export/Aggregator/PersonAggregators/AgeAggregator.php | 5 +---- .../ByHouseholdCompositionAggregator.php | 5 +---- .../PersonAggregators/CountryOfBirthAggregator.php | 4 ---- .../Aggregator/PersonAggregators/GenderAggregator.php | 4 ---- .../PersonAggregators/GeographicalUnitAggregator.php | 4 ---- .../PersonAggregators/HouseholdPositionAggregator.php | 5 +---- .../SocialWorkAggregators/ActionTypeAggregator.php | 4 ---- .../SocialWorkAggregators/CurrentActionAggregator.php | 4 ---- .../Aggregator/SocialWorkAggregators/GoalAggregator.php | 4 ---- .../SocialWorkAggregators/GoalResultAggregator.php | 4 ---- .../Aggregator/SocialWorkAggregators/JobAggregator.php | 4 ---- .../SocialWorkAggregators/ReferrerAggregator.php | 4 ---- .../Aggregator/SocialWorkAggregators/ResultAggregator.php | 4 ---- .../Aggregator/SocialWorkAggregators/ScopeAggregator.php | 4 ---- .../Export/Export/CountAccompanyingCourse.php | 4 ---- .../Export/Export/CountAccompanyingPeriodWork.php | 4 ---- .../ChillPersonBundle/Export/Export/CountEvaluation.php | 4 ---- .../ChillPersonBundle/Export/Export/CountHousehold.php | 5 +---- .../Export/Export/CountPersonWithAccompanyingCourse.php | 4 ---- .../Export/Export/ListPersonDuplicate.php | 5 +---- .../Export/Export/StatAccompanyingCourseDuration.php | 5 +---- .../AccompanyingCourseFilters/ActiveOnDateFilter.php | 8 +++----- .../ActiveOneDayBetweenDatesFilter.php | 4 ---- .../AdministrativeLocationFilter.php | 4 ---- .../AccompanyingCourseFilters/ClosingMotiveFilter.php | 4 ---- .../AccompanyingCourseFilters/ConfidentialFilter.php | 6 ++---- .../Filter/AccompanyingCourseFilters/CreatorFilter.php | 4 ---- .../Filter/AccompanyingCourseFilters/CreatorJobFilter.php | 4 ---- .../Filter/AccompanyingCourseFilters/EmergencyFilter.php | 6 ++---- .../Filter/AccompanyingCourseFilters/EvaluationFilter.php | 4 ---- .../GeographicalUnitStatFilter.php | 4 ---- .../AccompanyingCourseFilters/HasNoActionFilter.php | 4 ---- .../AccompanyingCourseFilters/HasNoReferrerFilter.php | 5 +---- .../HasTemporaryLocationFilter.php | 4 ---- .../HavingAnAccompanyingPeriodInfoWithinDatesFilter.php | 4 ---- .../Filter/AccompanyingCourseFilters/IntensityFilter.php | 5 +---- .../AccompanyingCourseFilters/OpenBetweenDatesFilter.php | 4 ---- .../Filter/AccompanyingCourseFilters/OriginFilter.php | 4 ---- .../Filter/AccompanyingCourseFilters/ReferrerFilter.php | 4 ---- .../Filter/AccompanyingCourseFilters/RequestorFilter.php | 5 +---- .../AccompanyingCourseFilters/SocialActionFilter.php | 4 ---- .../AccompanyingCourseFilters/SocialIssueFilter.php | 4 ---- .../Filter/AccompanyingCourseFilters/StepFilter.php | 4 ---- .../Filter/AccompanyingCourseFilters/UserJobFilter.php | 4 ---- .../Filter/AccompanyingCourseFilters/UserScopeFilter.php | 4 ---- .../UserWorkingOnCourseFilter.php | 4 ---- .../Export/Filter/EvaluationFilters/ByEndDateFilter.php | 4 ---- .../Export/Filter/EvaluationFilters/ByStartDateFilter.php | 4 ---- .../Filter/EvaluationFilters/CurrentEvaluationsFilter.php | 4 ---- .../Filter/EvaluationFilters/EvaluationTypeFilter.php | 4 ---- .../Export/Filter/EvaluationFilters/MaxDateFilter.php | 4 ---- .../Export/Filter/HouseholdFilters/CompositionFilter.php | 4 ---- .../Filter/PersonFilters/AddressRefStatusFilter.php | 4 ---- .../Export/Filter/PersonFilters/BirthdateFilter.php | 6 ++---- .../Filter/PersonFilters/ByHouseholdCompositionFilter.php | 4 ---- .../Export/Filter/PersonFilters/DeadOrAliveFilter.php | 5 +---- .../Export/Filter/PersonFilters/DeathdateFilter.php | 6 ++---- .../Export/Filter/PersonFilters/GenderFilter.php | 4 ---- .../Filter/PersonFilters/GeographicalUnitFilter.php | 4 ---- .../Export/Filter/PersonFilters/MaritalStatusFilter.php | 4 ---- .../Export/Filter/PersonFilters/NationalityFilter.php | 4 ---- .../ResidentialAddressAtThirdpartyFilter.php | 5 +---- .../PersonFilters/ResidentialAddressAtUserFilter.php | 5 +---- .../Filter/PersonFilters/WithoutHouseholdComposition.php | 5 +---- .../AccompanyingPeriodWorkEndDateBetweenDateFilter.php | 4 ---- .../AccompanyingPeriodWorkStartDateBetweenDateFilter.php | 4 ---- .../Filter/SocialWorkFilters/CurrentActionFilter.php | 4 ---- .../Export/Filter/SocialWorkFilters/JobFilter.php | 4 ---- .../Export/Filter/SocialWorkFilters/ReferrerFilter.php | 4 ---- .../Export/Filter/SocialWorkFilters/ScopeFilter.php | 4 ---- .../Filter/SocialWorkFilters/SocialWorkTypeFilter.php | 4 ---- .../ChillReportBundle/Export/Filter/ReportDateFilter.php | 6 ++---- 167 files changed, 51 insertions(+), 672 deletions(-) diff --git a/docs/source/_static/code/exports/BirthdateFilter.php b/docs/source/_static/code/exports/BirthdateFilter.php index e25d8b42f..64c1d53a9 100644 --- a/docs/source/_static/code/exports/BirthdateFilter.php +++ b/docs/source/_static/code/exports/BirthdateFilter.php @@ -62,6 +62,7 @@ class BirthdateFilter implements ExportElementValidatedInterface, FilterInterfac { $builder->add('date_from', DateType::class, [ 'label' => 'Born after this date', + 'data' => new DateTime(), 'attr' => ['class' => 'datepicker'], 'widget' => 'single_text', 'format' => 'dd-MM-yyyy', @@ -69,15 +70,12 @@ class BirthdateFilter implements ExportElementValidatedInterface, FilterInterfac $builder->add('date_to', DateType::class, [ 'label' => 'Born before this date', + 'data' => new DateTime(), 'attr' => ['class' => 'datepicker'], 'widget' => 'single_text', 'format' => 'dd-MM-yyyy', ]); } - public function getFormDefaultData(): array - { - return ['date_from' => new DateTime(), 'date_to' => new DateTime()]; - } // here, we create a simple string which will describe the action of // the filter in the Response diff --git a/docs/source/_static/code/exports/CountPerson.php b/docs/source/_static/code/exports/CountPerson.php index be800e52c..afe19c73b 100644 --- a/docs/source/_static/code/exports/CountPerson.php +++ b/docs/source/_static/code/exports/CountPerson.php @@ -36,10 +36,6 @@ class CountPerson implements ExportInterface { // this export does not add any form } - public function getFormDefaultData(): array - { - return []; - } public function getAllowedFormattersTypes() { diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByActivityNumberAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByActivityNumberAggregator.php index c23db738e..5c6656009 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByActivityNumberAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByActivityNumberAggregator.php @@ -40,10 +40,6 @@ class ByActivityNumberAggregator implements AggregatorInterface { // No form needed } - public function getFormDefaultData(): array - { - return []; - } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByCreatorAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByCreatorAggregator.php index 917459de3..69149737b 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByCreatorAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByCreatorAggregator.php @@ -52,10 +52,6 @@ class ByCreatorAggregator implements AggregatorInterface { // no form } - public function getFormDefaultData(): array - { - return []; - } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/BySocialActionAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/BySocialActionAggregator.php index 1a75357ae..89732412d 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/BySocialActionAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/BySocialActionAggregator.php @@ -57,10 +57,6 @@ class BySocialActionAggregator implements AggregatorInterface { // no form } - public function getFormDefaultData(): array - { - return []; - } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/BySocialIssueAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/BySocialIssueAggregator.php index 9100a8c8f..158e87664 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/BySocialIssueAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/BySocialIssueAggregator.php @@ -57,10 +57,6 @@ class BySocialIssueAggregator implements AggregatorInterface { // no form } - public function getFormDefaultData(): array - { - return []; - } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByThirdpartyAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByThirdpartyAggregator.php index ac05b153c..c3ca6d59c 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByThirdpartyAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByThirdpartyAggregator.php @@ -57,10 +57,6 @@ class ByThirdpartyAggregator implements AggregatorInterface { // no form } - public function getFormDefaultData(): array - { - return []; - } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/CreatorScopeAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/CreatorScopeAggregator.php index a4b5258e2..2c7ec1483 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/CreatorScopeAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/CreatorScopeAggregator.php @@ -57,10 +57,6 @@ class CreatorScopeAggregator implements AggregatorInterface { // no form } - public function getFormDefaultData(): array - { - return []; - } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/DateAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/DateAggregator.php index e0fa215f3..a2f465a38 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/DateAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/DateAggregator.php @@ -75,12 +75,10 @@ class DateAggregator implements AggregatorInterface 'choices' => self::CHOICES, 'multiple' => false, 'expanded' => true, + 'empty_data' => self::DEFAULT_CHOICE, + 'data' => self::DEFAULT_CHOICE, ]); } - public function getFormDefaultData(): array - { - return ['frequency' => self::DEFAULT_CHOICE]; - } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/LocationTypeAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/LocationTypeAggregator.php index c72609e2c..ec4ce6315 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/LocationTypeAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/LocationTypeAggregator.php @@ -57,10 +57,6 @@ class LocationTypeAggregator implements AggregatorInterface { // no form } - public function getFormDefaultData(): array - { - return []; - } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityTypeAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityTypeAggregator.php index a74428b4a..7cd16718e 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityTypeAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityTypeAggregator.php @@ -60,10 +60,6 @@ class ActivityTypeAggregator implements AggregatorInterface { // no form required for this aggregator } - public function getFormDefaultData(): array - { - return []; - } public function getLabels($key, array $values, $data): Closure { diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUserAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUserAggregator.php index 2fab2af83..9bde692c6 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUserAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUserAggregator.php @@ -58,10 +58,6 @@ class ActivityUserAggregator implements AggregatorInterface { // nothing to add } - public function getFormDefaultData(): array - { - return []; - } public function getLabels($key, $values, $data): Closure { diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersAggregator.php index e1e9f161d..139f2743e 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersAggregator.php @@ -56,10 +56,6 @@ class ActivityUsersAggregator implements AggregatorInterface { // nothing to add on the form } - public function getFormDefaultData(): array - { - return []; - } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersJobAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersJobAggregator.php index 721078989..5741a0e58 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersJobAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersJobAggregator.php @@ -55,10 +55,6 @@ class ActivityUsersJobAggregator implements \Chill\MainBundle\Export\AggregatorI { // nothing to add in the form } - public function getFormDefaultData(): array - { - return []; - } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersScopeAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersScopeAggregator.php index d7932e9e8..15da300be 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersScopeAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersScopeAggregator.php @@ -55,10 +55,6 @@ class ActivityUsersScopeAggregator implements \Chill\MainBundle\Export\Aggregato { // nothing to add in the form } - public function getFormDefaultData(): array - { - return []; - } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/PersonAggregators/ActivityReasonAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/PersonAggregators/ActivityReasonAggregator.php index 2537f2cf6..eaccf95cb 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/PersonAggregators/ActivityReasonAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/PersonAggregators/ActivityReasonAggregator.php @@ -110,10 +110,6 @@ class ActivityReasonAggregator implements AggregatorInterface, ExportElementVali ] ); } - public function getFormDefaultData(): array - { - return []; - } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/SentReceivedAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/SentReceivedAggregator.php index ae1dae375..5f772e156 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/SentReceivedAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/SentReceivedAggregator.php @@ -47,10 +47,6 @@ class SentReceivedAggregator implements AggregatorInterface { // No form needed } - public function getFormDefaultData(): array - { - return []; - } public function getLabels($key, array $values, $data): callable { diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityDuration.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityDuration.php index 6930784d3..34771d077 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityDuration.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityDuration.php @@ -39,10 +39,6 @@ class AvgActivityDuration implements ExportInterface, GroupedExportInterface public function buildForm(FormBuilderInterface $builder) { } - public function getFormDefaultData(): array - { - return []; - } public function getAllowedFormattersTypes(): array { diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityVisitDuration.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityVisitDuration.php index f1e926c64..df21362cd 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityVisitDuration.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityVisitDuration.php @@ -40,10 +40,6 @@ class AvgActivityVisitDuration implements ExportInterface, GroupedExportInterfac { // TODO: Implement buildForm() method. } - public function getFormDefaultData(): array - { - return []; - } public function getAllowedFormattersTypes(): array { diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/CountActivity.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/CountActivity.php index d473a925a..6b7b1562d 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/CountActivity.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/CountActivity.php @@ -39,10 +39,6 @@ class CountActivity implements ExportInterface, GroupedExportInterface public function buildForm(FormBuilderInterface $builder) { } - public function getFormDefaultData(): array - { - return []; - } public function getAllowedFormattersTypes(): array { diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityDuration.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityDuration.php index 8adb3b77f..e916cab54 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityDuration.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityDuration.php @@ -40,10 +40,6 @@ class SumActivityDuration implements ExportInterface, GroupedExportInterface { // TODO: Implement buildForm() method. } - public function getFormDefaultData(): array - { - return []; - } public function getAllowedFormattersTypes(): array { diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityVisitDuration.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityVisitDuration.php index cc424e68b..18a47289c 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityVisitDuration.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityVisitDuration.php @@ -40,10 +40,6 @@ class SumActivityVisitDuration implements ExportInterface, GroupedExportInterfac { // TODO: Implement buildForm() method. } - public function getFormDefaultData(): array - { - return []; - } public function getAllowedFormattersTypes(): array { diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/CountActivity.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/CountActivity.php index 6360251b3..4246df173 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/CountActivity.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/CountActivity.php @@ -35,10 +35,6 @@ class CountActivity implements ExportInterface, GroupedExportInterface public function buildForm(FormBuilderInterface $builder) { } - public function getFormDefaultData(): array - { - return []; - } public function getAllowedFormattersTypes() { diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/StatActivityDuration.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/StatActivityDuration.php index e68d47cd3..050034954 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/StatActivityDuration.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/StatActivityDuration.php @@ -53,10 +53,6 @@ class StatActivityDuration implements ExportInterface, GroupedExportInterface public function buildForm(FormBuilderInterface $builder) { } - public function getFormDefaultData(): array - { - return []; - } public function getAllowedFormattersTypes() { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/ActivityTypeFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/ActivityTypeFilter.php index 4ffc3b38c..c6616a4c6 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/ActivityTypeFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/ActivityTypeFilter.php @@ -68,10 +68,6 @@ class ActivityTypeFilter implements FilterInterface 'expanded' => true, ]); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/ByCreatorFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/ByCreatorFilter.php index add9c7c3d..322393f32 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/ByCreatorFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/ByCreatorFilter.php @@ -52,10 +52,6 @@ class ByCreatorFilter implements FilterInterface 'multiple' => true, ]); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/BySocialActionFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/BySocialActionFilter.php index 08f6bbbc3..d0c1b0fc7 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/BySocialActionFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/BySocialActionFilter.php @@ -60,10 +60,6 @@ class BySocialActionFilter implements FilterInterface 'multiple' => true, ]); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/BySocialIssueFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/BySocialIssueFilter.php index bd6e2ef4a..bbb882a65 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/BySocialIssueFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/BySocialIssueFilter.php @@ -60,10 +60,6 @@ class BySocialIssueFilter implements FilterInterface 'multiple' => true, ]); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/EmergencyFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/EmergencyFilter.php index d5792d6d5..b79c2ca10 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/EmergencyFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/EmergencyFilter.php @@ -67,12 +67,10 @@ class EmergencyFilter implements FilterInterface 'choices' => self::CHOICES, 'multiple' => false, 'expanded' => true, + 'empty_data' => self::DEFAULT_CHOICE, + 'data' => self::DEFAULT_CHOICE, ]); } - public function getFormDefaultData(): array - { - return ['accepted_emergency' => self::DEFAULT_CHOICE]; - } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/HasNoActivityFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/HasNoActivityFilter.php index b5dab4009..570f42ae0 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/HasNoActivityFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/HasNoActivityFilter.php @@ -44,10 +44,6 @@ class HasNoActivityFilter implements FilterInterface { //no form needed } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/LocationFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/LocationFilter.php index 312f3a6a0..3d69d1633 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/LocationFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/LocationFilter.php @@ -46,10 +46,6 @@ class LocationFilter implements FilterInterface 'label' => 'pick location', ]); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/LocationTypeFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/LocationTypeFilter.php index 1c3415460..5fe928b6c 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/LocationTypeFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/LocationTypeFilter.php @@ -65,10 +65,6 @@ class LocationTypeFilter implements FilterInterface //'label' => false, ]); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/SentReceivedFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/SentReceivedFilter.php index 0f2a1c7e4..8daa7a781 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/SentReceivedFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/SentReceivedFilter.php @@ -69,12 +69,9 @@ class SentReceivedFilter implements FilterInterface 'multiple' => false, 'expanded' => true, 'empty_data' => self::DEFAULT_CHOICE, + 'data' => self::DEFAULT_CHOICE, ]); } - public function getFormDefaultData(): array - { - return ['accepted_sentreceived' => self::DEFAULT_CHOICE]; - } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/UserFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/UserFilter.php index 9ae988579..6350f3ace 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/UserFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/UserFilter.php @@ -61,10 +61,6 @@ class UserFilter implements FilterInterface 'label' => 'Creators', ]); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/UserScopeFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/UserScopeFilter.php index adb1e94f1..4319c100a 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/UserScopeFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/UserScopeFilter.php @@ -71,10 +71,6 @@ class UserScopeFilter implements FilterInterface 'expanded' => true, ]); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ActivityDateFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ActivityDateFilter.php index d1e69fe28..f2216c929 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ActivityDateFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ActivityDateFilter.php @@ -127,10 +127,6 @@ class ActivityDateFilter implements FilterInterface } }); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ActivityTypeFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ActivityTypeFilter.php index 8dfcb543c..b9d39c3ce 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ActivityTypeFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ActivityTypeFilter.php @@ -78,10 +78,6 @@ class ActivityTypeFilter implements ExportElementValidatedInterface, FilterInter ], ]); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ActivityUsersFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ActivityUsersFilter.php index a63ca2629..2f6cd8462 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ActivityUsersFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ActivityUsersFilter.php @@ -56,10 +56,6 @@ class ActivityUsersFilter implements FilterInterface 'label' => 'Users', ]); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/PersonFilters/ActivityReasonFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/PersonFilters/ActivityReasonFilter.php index 31cfde6b6..c55d579e4 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/PersonFilters/ActivityReasonFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/PersonFilters/ActivityReasonFilter.php @@ -82,10 +82,6 @@ class ActivityReasonFilter implements ExportElementValidatedInterface, FilterInt 'expanded' => false, ]); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/PersonFilters/PersonHavingActivityBetweenDateFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/PersonFilters/PersonHavingActivityBetweenDateFilter.php index 490b5fd0c..e3c85fe9c 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/PersonFilters/PersonHavingActivityBetweenDateFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/PersonFilters/PersonHavingActivityBetweenDateFilter.php @@ -112,6 +112,7 @@ class PersonHavingActivityBetweenDateFilter implements ExportElementValidatedInt { $builder->add('date_from', DateType::class, [ 'label' => 'Implied in an activity after this date', + 'data' => new DateTime(), 'attr' => ['class' => 'datepicker'], 'widget' => 'single_text', 'format' => 'dd-MM-yyyy', @@ -119,6 +120,7 @@ class PersonHavingActivityBetweenDateFilter implements ExportElementValidatedInt $builder->add('date_to', DateType::class, [ 'label' => 'Implied in an activity before this date', + 'data' => new DateTime(), 'attr' => ['class' => 'datepicker'], 'widget' => 'single_text', 'format' => 'dd-MM-yyyy', @@ -128,6 +130,7 @@ class PersonHavingActivityBetweenDateFilter implements ExportElementValidatedInt 'class' => ActivityReason::class, 'choice_label' => fn (ActivityReason $reason): ?string => $this->translatableStringHelper->localize($reason->getName()), 'group_by' => fn (ActivityReason $reason): ?string => $this->translatableStringHelper->localize($reason->getCategory()->getName()), + 'data' => $this->activityReasonRepository->findAll(), 'multiple' => true, 'expanded' => false, 'label' => 'Activity reasons for those activities', @@ -173,10 +176,6 @@ class PersonHavingActivityBetweenDateFilter implements ExportElementValidatedInt } }); } - public function getFormDefaultData(): array - { - return ['date_from' => new DateTime(), 'date_to' => new DateTime(), 'reasons' => $this->activityReasonRepository->findAll()]; - } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/UsersJobFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/UsersJobFilter.php index e85b2d247..b52ef441c 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/UsersJobFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/UsersJobFilter.php @@ -60,10 +60,6 @@ class UsersJobFilter implements FilterInterface 'expanded' => true, ]); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/UsersScopeFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/UsersScopeFilter.php index 07ff509ce..61b12264e 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/UsersScopeFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/UsersScopeFilter.php @@ -67,10 +67,6 @@ class UsersScopeFilter implements FilterInterface 'expanded' => true, ]); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByActivityTypeAggregator.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByActivityTypeAggregator.php index 8ae43534d..32418e3c3 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByActivityTypeAggregator.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByActivityTypeAggregator.php @@ -50,10 +50,6 @@ class ByActivityTypeAggregator implements AggregatorInterface { // No form needed } - public function getFormDefaultData(): array - { - return []; - } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByUserJobAggregator.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByUserJobAggregator.php index f09a704e2..d2fe7c2f2 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByUserJobAggregator.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByUserJobAggregator.php @@ -57,10 +57,6 @@ class ByUserJobAggregator implements AggregatorInterface { // nothing to add in the form } - public function getFormDefaultData(): array - { - return []; - } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByUserScopeAggregator.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByUserScopeAggregator.php index 3dd465db2..6c06ee756 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByUserScopeAggregator.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByUserScopeAggregator.php @@ -57,10 +57,6 @@ class ByUserScopeAggregator implements AggregatorInterface { // nothing to add in the form } - public function getFormDefaultData(): array - { - return []; - } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Export/AvgAsideActivityDuration.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Export/AvgAsideActivityDuration.php index 2b28062f6..f3db629cb 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Export/AvgAsideActivityDuration.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Export/AvgAsideActivityDuration.php @@ -34,10 +34,6 @@ class AvgAsideActivityDuration implements ExportInterface, GroupedExportInterfac public function buildForm(FormBuilderInterface $builder) { } - public function getFormDefaultData(): array - { - return []; - } public function getAllowedFormattersTypes(): array { diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Export/CountAsideActivity.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Export/CountAsideActivity.php index 91210f764..9204fad4b 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Export/CountAsideActivity.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Export/CountAsideActivity.php @@ -34,10 +34,6 @@ class CountAsideActivity implements ExportInterface, GroupedExportInterface public function buildForm(FormBuilderInterface $builder) { } - public function getFormDefaultData(): array - { - return []; - } public function getAllowedFormattersTypes(): array { diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Export/SumAsideActivityDuration.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Export/SumAsideActivityDuration.php index 741f129f1..af17a2591 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Export/SumAsideActivityDuration.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Export/SumAsideActivityDuration.php @@ -34,10 +34,6 @@ class SumAsideActivityDuration implements ExportInterface, GroupedExportInterfac public function buildForm(FormBuilderInterface $builder) { } - public function getFormDefaultData(): array - { - return []; - } public function getAllowedFormattersTypes(): array { diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByActivityTypeFilter.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByActivityTypeFilter.php index 3d389f5b3..3ad8e0e93 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByActivityTypeFilter.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByActivityTypeFilter.php @@ -76,10 +76,6 @@ class ByActivityTypeFilter implements FilterInterface }, ]); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByDateFilter.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByDateFilter.php index 5019c3597..7a1b6f4dc 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByDateFilter.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByDateFilter.php @@ -119,10 +119,6 @@ class ByDateFilter implements FilterInterface } }); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserFilter.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserFilter.php index 2858d3417..795c813cd 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserFilter.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserFilter.php @@ -53,10 +53,6 @@ class ByUserFilter implements FilterInterface 'label' => 'Creators', ]); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserJobFilter.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserJobFilter.php index 55f477768..86194b123 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserJobFilter.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserJobFilter.php @@ -60,10 +60,6 @@ class ByUserJobFilter implements FilterInterface 'expanded' => true, ]); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserScopeFilter.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserScopeFilter.php index 8fa51866d..4342e11eb 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserScopeFilter.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserScopeFilter.php @@ -67,10 +67,6 @@ class ByUserScopeFilter implements FilterInterface 'expanded' => true, ]); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/AgentAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/AgentAggregator.php index 1b1b170b8..e1de9f399 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/AgentAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/AgentAggregator.php @@ -58,10 +58,6 @@ final class AgentAggregator implements AggregatorInterface { // no form } - public function getFormDefaultData(): array - { - return []; - } public function getLabels($key, array $values, $data): Closure { diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/CancelReasonAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/CancelReasonAggregator.php index a9967c470..611cb6d79 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/CancelReasonAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/CancelReasonAggregator.php @@ -59,10 +59,6 @@ class CancelReasonAggregator implements AggregatorInterface { // no form } - public function getFormDefaultData(): array - { - return []; - } public function getLabels($key, array $values, $data): Closure { diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/JobAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/JobAggregator.php index 51291b49e..23292a5b0 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/JobAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/JobAggregator.php @@ -58,10 +58,6 @@ final class JobAggregator implements AggregatorInterface { // no form } - public function getFormDefaultData(): array - { - return []; - } public function getLabels($key, array $values, $data): Closure { diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationAggregator.php index 952d0c5d5..940000f47 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationAggregator.php @@ -52,10 +52,6 @@ final class LocationAggregator implements AggregatorInterface { // no form } - public function getFormDefaultData(): array - { - return []; - } public function getLabels($key, array $values, $data): Closure { diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationTypeAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationTypeAggregator.php index a9b369af0..6574e3934 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationTypeAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationTypeAggregator.php @@ -58,10 +58,6 @@ final class LocationTypeAggregator implements AggregatorInterface { // no form } - public function getFormDefaultData(): array - { - return []; - } public function getLabels($key, array $values, $data): Closure { diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/MonthYearAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/MonthYearAggregator.php index b3c2aaf19..7b2a5e898 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/MonthYearAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/MonthYearAggregator.php @@ -40,10 +40,6 @@ class MonthYearAggregator implements AggregatorInterface { // No form needed } - public function getFormDefaultData(): array - { - return []; - } public function getLabels($key, array $values, $data): Closure { diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/ScopeAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/ScopeAggregator.php index 01874b0e2..3aff3e0d8 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/ScopeAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/ScopeAggregator.php @@ -58,10 +58,6 @@ final class ScopeAggregator implements AggregatorInterface { // no form } - public function getFormDefaultData(): array - { - return []; - } public function getLabels($key, array $values, $data): Closure { diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/UrgencyAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/UrgencyAggregator.php index 66ab8b42e..ad5910461 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/UrgencyAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/UrgencyAggregator.php @@ -56,10 +56,6 @@ class UrgencyAggregator implements AggregatorInterface { // no form } - public function getFormDefaultData(): array - { - return []; - } public function getLabels($key, array $values, $data): Closure { diff --git a/src/Bundle/ChillCalendarBundle/Export/Export/CountCalendars.php b/src/Bundle/ChillCalendarBundle/Export/Export/CountCalendars.php index e0391948e..9d3f00f99 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Export/CountCalendars.php +++ b/src/Bundle/ChillCalendarBundle/Export/Export/CountCalendars.php @@ -36,10 +36,6 @@ class CountCalendars implements ExportInterface, GroupedExportInterface { // No form necessary } - public function getFormDefaultData(): array - { - return []; - } public function getAllowedFormattersTypes(): array { diff --git a/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarAvgDuration.php b/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarAvgDuration.php index dcbfb695b..14dd42d6b 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarAvgDuration.php +++ b/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarAvgDuration.php @@ -36,10 +36,6 @@ class StatCalendarAvgDuration implements ExportInterface, GroupedExportInterface { // no form needed } - public function getFormDefaultData(): array - { - return []; - } public function getAllowedFormattersTypes(): array { diff --git a/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarSumDuration.php b/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarSumDuration.php index 7f509a896..1d31bfa26 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarSumDuration.php +++ b/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarSumDuration.php @@ -36,10 +36,6 @@ class StatCalendarSumDuration implements ExportInterface, GroupedExportInterface { // no form needed } - public function getFormDefaultData(): array - { - return []; - } public function getAllowedFormattersTypes(): array { diff --git a/src/Bundle/ChillCalendarBundle/Export/Filter/AgentFilter.php b/src/Bundle/ChillCalendarBundle/Export/Filter/AgentFilter.php index 0cef89c20..b58cee594 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Filter/AgentFilter.php +++ b/src/Bundle/ChillCalendarBundle/Export/Filter/AgentFilter.php @@ -63,10 +63,6 @@ class AgentFilter implements FilterInterface 'expanded' => true, ]); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillCalendarBundle/Export/Filter/BetweenDatesFilter.php b/src/Bundle/ChillCalendarBundle/Export/Filter/BetweenDatesFilter.php index 71dc95e60..59019ac03 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Filter/BetweenDatesFilter.php +++ b/src/Bundle/ChillCalendarBundle/Export/Filter/BetweenDatesFilter.php @@ -67,10 +67,6 @@ class BetweenDatesFilter implements FilterInterface 'data' => new RollingDate(RollingDate::T_TODAY), ]); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillCalendarBundle/Export/Filter/CalendarRangeFilter.php b/src/Bundle/ChillCalendarBundle/Export/Filter/CalendarRangeFilter.php index 5ffb7c01f..d6c38e163 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Filter/CalendarRangeFilter.php +++ b/src/Bundle/ChillCalendarBundle/Export/Filter/CalendarRangeFilter.php @@ -69,12 +69,9 @@ class CalendarRangeFilter implements FilterInterface 'multiple' => false, 'expanded' => true, 'empty_data' => self::DEFAULT_CHOICE, + 'data' => self::DEFAULT_CHOICE, ]); } - public function getFormDefaultData(): array - { - return ['hasCalendarRange' => self::DEFAULT_CHOICE]; - } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillCalendarBundle/Export/Filter/JobFilter.php b/src/Bundle/ChillCalendarBundle/Export/Filter/JobFilter.php index d02bb8e9d..69fb24447 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Filter/JobFilter.php +++ b/src/Bundle/ChillCalendarBundle/Export/Filter/JobFilter.php @@ -76,10 +76,6 @@ class JobFilter implements FilterInterface 'expanded' => true, ]); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillCalendarBundle/Export/Filter/ScopeFilter.php b/src/Bundle/ChillCalendarBundle/Export/Filter/ScopeFilter.php index d8a40da72..08d9ae023 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Filter/ScopeFilter.php +++ b/src/Bundle/ChillCalendarBundle/Export/Filter/ScopeFilter.php @@ -76,10 +76,6 @@ class ScopeFilter implements FilterInterface 'expanded' => true, ]); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/AdministrativeLocationAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/AdministrativeLocationAggregator.php index 56fdc07d7..96deac574 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/AdministrativeLocationAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/AdministrativeLocationAggregator.php @@ -57,10 +57,6 @@ class AdministrativeLocationAggregator implements AggregatorInterface { // no form } - public function getFormDefaultData(): array - { - return []; - } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ByActionNumberAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ByActionNumberAggregator.php index 104b934ca..2dffccbbb 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ByActionNumberAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ByActionNumberAggregator.php @@ -39,10 +39,6 @@ class ByActionNumberAggregator implements AggregatorInterface { // No form needed } - public function getFormDefaultData(): array - { - return []; - } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ClosingMotiveAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ClosingMotiveAggregator.php index 73cfdc7b9..342958361 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ClosingMotiveAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ClosingMotiveAggregator.php @@ -52,10 +52,6 @@ class ClosingMotiveAggregator implements AggregatorInterface { // no form } - public function getFormDefaultData(): array - { - return []; - } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ConfidentialAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ConfidentialAggregator.php index 4ad18030e..e9b9e28fa 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ConfidentialAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ConfidentialAggregator.php @@ -48,10 +48,6 @@ class ConfidentialAggregator implements AggregatorInterface { // no form } - public function getFormDefaultData(): array - { - return []; - } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/CreatorJobAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/CreatorJobAggregator.php index 5a060bcd7..c336a8887 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/CreatorJobAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/CreatorJobAggregator.php @@ -57,10 +57,6 @@ class CreatorJobAggregator implements AggregatorInterface { // No form needed } - public function getFormDefaultData(): array - { - return []; - } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/DurationAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/DurationAggregator.php index 581c7d6e5..0dc66e81e 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/DurationAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/DurationAggregator.php @@ -84,10 +84,6 @@ final class DurationAggregator implements AggregatorInterface 'expanded' => true, ]); } - public function getFormDefaultData(): array - { - return []; - } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/EmergencyAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/EmergencyAggregator.php index 4429c7b62..02f9f5cd9 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/EmergencyAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/EmergencyAggregator.php @@ -48,10 +48,6 @@ class EmergencyAggregator implements AggregatorInterface { // no form } - public function getFormDefaultData(): array - { - return []; - } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/EvaluationAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/EvaluationAggregator.php index 119fa50b7..b6436efc0 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/EvaluationAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/EvaluationAggregator.php @@ -61,10 +61,6 @@ final class EvaluationAggregator implements AggregatorInterface { // no form } - public function getFormDefaultData(): array - { - return []; - } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/GeographicalUnitStatAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/GeographicalUnitStatAggregator.php index 22b21d352..d001cbef7 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/GeographicalUnitStatAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/GeographicalUnitStatAggregator.php @@ -133,10 +133,6 @@ final class GeographicalUnitStatAggregator implements AggregatorInterface 'expanded' => true, ]); } - public function getFormDefaultData(): array - { - return []; - } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/IntensityAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/IntensityAggregator.php index ac55d7734..a3618f40f 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/IntensityAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/IntensityAggregator.php @@ -48,10 +48,6 @@ class IntensityAggregator implements AggregatorInterface { // no form } - public function getFormDefaultData(): array - { - return []; - } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/OriginAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/OriginAggregator.php index 1d01920d5..37d0c7b20 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/OriginAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/OriginAggregator.php @@ -59,10 +59,6 @@ final class OriginAggregator implements AggregatorInterface { // no form } - public function getFormDefaultData(): array - { - return []; - } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ReferrerAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ReferrerAggregator.php index 7b826600a..a09097fd2 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ReferrerAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ReferrerAggregator.php @@ -81,14 +81,11 @@ final class ReferrerAggregator implements AggregatorInterface { $builder ->add('date_calc', PickRollingDateType::class, [ + 'data' => new RollingDate(RollingDate::T_TODAY), 'label' => 'export.aggregator.course.by_referrer.Computation date for referrer', 'required' => true, ]); } - public function getFormDefaultData(): array - { - return ['date_calc' => new RollingDate(RollingDate::T_TODAY)]; - } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ReferrerScopeAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ReferrerScopeAggregator.php index adfd9b489..ccbd21da1 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ReferrerScopeAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ReferrerScopeAggregator.php @@ -88,14 +88,11 @@ class ReferrerScopeAggregator implements AggregatorInterface public function buildForm(FormBuilderInterface $builder) { $builder->add('date_calc', PickRollingDateType::class, [ + 'data' => new RollingDate(RollingDate::T_TODAY), 'label' => 'export.aggregator.course.by_user_scope.Computation date for referrer', 'required' => true, ]); } - public function getFormDefaultData(): array - { - return ['date_calc' => new RollingDate(RollingDate::T_TODAY)]; - } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/RequestorAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/RequestorAggregator.php index 3baf9bd33..7b5cf0edd 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/RequestorAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/RequestorAggregator.php @@ -69,10 +69,6 @@ final class RequestorAggregator implements AggregatorInterface { // no form } - public function getFormDefaultData(): array - { - return []; - } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ScopeAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ScopeAggregator.php index 253727c89..8f34661bb 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ScopeAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ScopeAggregator.php @@ -57,10 +57,6 @@ final class ScopeAggregator implements AggregatorInterface { // no form } - public function getFormDefaultData(): array - { - return []; - } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/SocialActionAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/SocialActionAggregator.php index b82b47ad0..3bdd6549e 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/SocialActionAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/SocialActionAggregator.php @@ -58,10 +58,6 @@ final class SocialActionAggregator implements AggregatorInterface { // no form } - public function getFormDefaultData(): array - { - return []; - } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/SocialIssueAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/SocialIssueAggregator.php index 29fcba4a2..12fa5a454 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/SocialIssueAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/SocialIssueAggregator.php @@ -58,10 +58,6 @@ final class SocialIssueAggregator implements AggregatorInterface { // no form } - public function getFormDefaultData(): array - { - return []; - } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/StepAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/StepAggregator.php index 7632f72f0..85cfc3190 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/StepAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/StepAggregator.php @@ -76,11 +76,9 @@ final class StepAggregator implements AggregatorInterface public function buildForm(FormBuilderInterface $builder) { - $builder->add('on_date', PickRollingDateType::class, []); - } - public function getFormDefaultData(): array - { - return ['on_date' => new RollingDate(RollingDate::T_TODAY)]; + $builder->add('on_date', PickRollingDateType::class, [ + 'data' => new RollingDate(RollingDate::T_TODAY), + ]); } public function getLabels($key, array $values, $data) diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/UserJobAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/UserJobAggregator.php index 13d1e3f83..a8acdcf12 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/UserJobAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/UserJobAggregator.php @@ -57,10 +57,6 @@ final class UserJobAggregator implements AggregatorInterface { // no form } - public function getFormDefaultData(): array - { - return []; - } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/ByEndDateAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/ByEndDateAggregator.php index cb66fa600..2f4275c49 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/ByEndDateAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/ByEndDateAggregator.php @@ -75,12 +75,9 @@ class ByEndDateAggregator implements AggregatorInterface 'multiple' => false, 'expanded' => true, 'empty_data' => self::DEFAULT_CHOICE, + 'data' => self::DEFAULT_CHOICE, ]); } - public function getFormDefaultData(): array - { - return ['frequency' => self::DEFAULT_CHOICE]; - } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/ByMaxDateAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/ByMaxDateAggregator.php index af6dfc465..9283fd9dc 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/ByMaxDateAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/ByMaxDateAggregator.php @@ -75,12 +75,9 @@ class ByMaxDateAggregator implements AggregatorInterface 'multiple' => false, 'expanded' => true, 'empty_data' => self::DEFAULT_CHOICE, + 'data' => self::DEFAULT_CHOICE, ]); } - public function getFormDefaultData(): array - { - return ['frequency' => self::DEFAULT_CHOICE]; - } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/ByStartDateAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/ByStartDateAggregator.php index 87a6a672b..cd183b25e 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/ByStartDateAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/ByStartDateAggregator.php @@ -75,12 +75,9 @@ class ByStartDateAggregator implements AggregatorInterface 'multiple' => false, 'expanded' => true, 'empty_data' => self::DEFAULT_CHOICE, + 'data' => self::DEFAULT_CHOICE, ]); } - public function getFormDefaultData(): array - { - return ['frequency' => self::DEFAULT_CHOICE]; - } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/EvaluationTypeAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/EvaluationTypeAggregator.php index a48ed763d..0c13611cb 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/EvaluationTypeAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/EvaluationTypeAggregator.php @@ -52,10 +52,6 @@ class EvaluationTypeAggregator implements AggregatorInterface { // no form } - public function getFormDefaultData(): array - { - return []; - } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/HavingEndDateAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/HavingEndDateAggregator.php index e710949fd..e33bb326f 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/HavingEndDateAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/HavingEndDateAggregator.php @@ -48,10 +48,6 @@ class HavingEndDateAggregator implements AggregatorInterface { // No form needed } - public function getFormDefaultData(): array - { - return []; - } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/HouseholdAggregators/ChildrenNumberAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/HouseholdAggregators/ChildrenNumberAggregator.php index 1c5b3dc2c..0c9bc623f 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/HouseholdAggregators/ChildrenNumberAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/HouseholdAggregators/ChildrenNumberAggregator.php @@ -72,11 +72,9 @@ class ChildrenNumberAggregator implements AggregatorInterface public function buildForm(FormBuilderInterface $builder) { - $builder->add('on_date', PickRollingDateType::class, []); - } - public function getFormDefaultData(): array - { - return ['on_date' => new RollingDate(RollingDate::T_TODAY)]; + $builder->add('on_date', PickRollingDateType::class, [ + 'data' => new RollingDate(RollingDate::T_TODAY), + ]); } public function getLabels($key, array $values, $data) diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/HouseholdAggregators/CompositionAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/HouseholdAggregators/CompositionAggregator.php index 62fc20173..52bcd88e5 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/HouseholdAggregators/CompositionAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/HouseholdAggregators/CompositionAggregator.php @@ -77,11 +77,9 @@ class CompositionAggregator implements AggregatorInterface public function buildForm(FormBuilderInterface $builder) { - $builder->add('on_date', PickRollingDateType::class, []); - } - public function getFormDefaultData(): array - { - return ['on_date' => new RollingDate(RollingDate::T_TODAY)]; + $builder->add('on_date', PickRollingDateType::class, [ + 'data' => new RollingDate(RollingDate::T_TODAY), + ]); } public function getLabels($key, array $values, $data) diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/AgeAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/AgeAggregator.php index 2a63e475a..365a73704 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/AgeAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/AgeAggregator.php @@ -50,15 +50,12 @@ final class AgeAggregator implements AggregatorInterface, ExportElementValidated { $builder->add('date_age_calculation', DateType::class, [ 'label' => 'Calculate age in relation to this date', + 'data' => new DateTime(), 'attr' => ['class' => 'datepicker'], 'widget' => 'single_text', 'format' => 'dd-MM-yyyy', ]); } - public function getFormDefaultData(): array - { - return ['date_age_calculation' => new DateTime()]; - } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/ByHouseholdCompositionAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/ByHouseholdCompositionAggregator.php index 16b62c2b5..80f0faa17 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/ByHouseholdCompositionAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/ByHouseholdCompositionAggregator.php @@ -94,12 +94,9 @@ class ByHouseholdCompositionAggregator implements AggregatorInterface { $builder->add('date_calc', PickRollingDateType::class, [ 'label' => 'export.aggregator.person.by_household_composition.Calc date', + 'data' => new RollingDate(RollingDate::T_TODAY), ]); } - public function getFormDefaultData(): array - { - return ['date_calc' => new RollingDate(RollingDate::T_TODAY)]; - } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/CountryOfBirthAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/CountryOfBirthAggregator.php index 90882245e..3d785b586 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/CountryOfBirthAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/CountryOfBirthAggregator.php @@ -108,10 +108,6 @@ final class CountryOfBirthAggregator implements AggregatorInterface, ExportEleme 'multiple' => false, ]); } - public function getFormDefaultData(): array - { - return []; - } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/GenderAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/GenderAggregator.php index dbe3d19d3..f76420047 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/GenderAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/GenderAggregator.php @@ -48,10 +48,6 @@ final class GenderAggregator implements AggregatorInterface public function buildForm(FormBuilderInterface $builder) { } - public function getFormDefaultData(): array - { - return []; - } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/GeographicalUnitAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/GeographicalUnitAggregator.php index 6c6ed340f..5d73c1fdd 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/GeographicalUnitAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/GeographicalUnitAggregator.php @@ -105,10 +105,6 @@ class GeographicalUnitAggregator implements AggregatorInterface 'expanded' => true, ]); } - public function getFormDefaultData(): array - { - return []; - } public static function getDefaultAlias(): string { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/HouseholdPositionAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/HouseholdPositionAggregator.php index 63d84d4da..107634803 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/HouseholdPositionAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/HouseholdPositionAggregator.php @@ -90,12 +90,9 @@ final class HouseholdPositionAggregator implements AggregatorInterface, ExportEl { $builder->add('date_position', PickRollingDateType::class, [ 'label' => 'Household position in relation to this date', + 'data' => new RollingDate(RollingDate::T_TODAY), ]); } - public function getFormDefaultData(): array - { - return ['date_position' => new RollingDate(RollingDate::T_TODAY)]; - } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ActionTypeAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ActionTypeAggregator.php index 66c87d94f..c1fccb968 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ActionTypeAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ActionTypeAggregator.php @@ -75,10 +75,6 @@ final class ActionTypeAggregator implements AggregatorInterface { // no form } - public function getFormDefaultData(): array - { - return []; - } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/CurrentActionAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/CurrentActionAggregator.php index 539c9f286..58fcb2874 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/CurrentActionAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/CurrentActionAggregator.php @@ -51,10 +51,6 @@ class CurrentActionAggregator implements AggregatorInterface { // No form needed } - public function getFormDefaultData(): array - { - return []; - } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/GoalAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/GoalAggregator.php index 4c0e8b393..8cc6a25da 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/GoalAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/GoalAggregator.php @@ -55,10 +55,6 @@ final class GoalAggregator implements AggregatorInterface { // no form } - public function getFormDefaultData(): array - { - return []; - } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/GoalResultAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/GoalResultAggregator.php index c99ee85ea..17b263d7e 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/GoalResultAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/GoalResultAggregator.php @@ -68,10 +68,6 @@ class GoalResultAggregator implements AggregatorInterface { // no form } - public function getFormDefaultData(): array - { - return []; - } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/JobAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/JobAggregator.php index 8271c90e3..cbf07091f 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/JobAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/JobAggregator.php @@ -57,10 +57,6 @@ final class JobAggregator implements AggregatorInterface { // no form } - public function getFormDefaultData(): array - { - return []; - } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ReferrerAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ReferrerAggregator.php index 047504224..0fe53b707 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ReferrerAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ReferrerAggregator.php @@ -57,10 +57,6 @@ final class ReferrerAggregator implements AggregatorInterface { // no form } - public function getFormDefaultData(): array - { - return []; - } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ResultAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ResultAggregator.php index 3cce7b283..2e46673da 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ResultAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ResultAggregator.php @@ -55,10 +55,6 @@ final class ResultAggregator implements AggregatorInterface { // no form } - public function getFormDefaultData(): array - { - return []; - } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ScopeAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ScopeAggregator.php index 0828b5d0d..243263b83 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ScopeAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ScopeAggregator.php @@ -57,10 +57,6 @@ final class ScopeAggregator implements AggregatorInterface { // no form } - public function getFormDefaultData(): array - { - return []; - } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Export/CountAccompanyingCourse.php b/src/Bundle/ChillPersonBundle/Export/Export/CountAccompanyingCourse.php index 75583dfa0..978f88a10 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/CountAccompanyingCourse.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/CountAccompanyingCourse.php @@ -39,10 +39,6 @@ class CountAccompanyingCourse implements ExportInterface, GroupedExportInterface { // Nothing to add here } - public function getFormDefaultData(): array - { - return []; - } public function getAllowedFormattersTypes(): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Export/CountAccompanyingPeriodWork.php b/src/Bundle/ChillPersonBundle/Export/Export/CountAccompanyingPeriodWork.php index 8a035bdcd..122ee14d9 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/CountAccompanyingPeriodWork.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/CountAccompanyingPeriodWork.php @@ -38,10 +38,6 @@ class CountAccompanyingPeriodWork implements ExportInterface, GroupedExportInter { // No form necessary? } - public function getFormDefaultData(): array - { - return []; - } public function getAllowedFormattersTypes(): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Export/CountEvaluation.php b/src/Bundle/ChillPersonBundle/Export/Export/CountEvaluation.php index 3de433e2e..1613b63d3 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/CountEvaluation.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/CountEvaluation.php @@ -37,10 +37,6 @@ class CountEvaluation implements ExportInterface, GroupedExportInterface { // TODO: Implement buildForm() method. } - public function getFormDefaultData(): array - { - return []; - } public function getAllowedFormattersTypes(): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Export/CountHousehold.php b/src/Bundle/ChillPersonBundle/Export/Export/CountHousehold.php index 05e32fde6..0b693b9d8 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/CountHousehold.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/CountHousehold.php @@ -46,14 +46,11 @@ class CountHousehold implements ExportInterface, GroupedExportInterface { $builder ->add('calc_date', PickRollingDateType::class, [ + 'data' => new RollingDate(RollingDate::T_TODAY), 'label' => self::TR_PREFIX . 'Date of calculation of household members', 'required' => false, ]); } - public function getFormDefaultData(): array - { - return ['calc_date' => new RollingDate(RollingDate::T_TODAY)]; - } public function getAllowedFormattersTypes(): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Export/CountPersonWithAccompanyingCourse.php b/src/Bundle/ChillPersonBundle/Export/Export/CountPersonWithAccompanyingCourse.php index ae7238d4e..e52cc83b1 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/CountPersonWithAccompanyingCourse.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/CountPersonWithAccompanyingCourse.php @@ -39,10 +39,6 @@ class CountPersonWithAccompanyingCourse implements ExportInterface, GroupedExpor { // TODO: Implement buildForm() method. } - public function getFormDefaultData(): array - { - return []; - } public function getAllowedFormattersTypes(): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Export/ListPersonDuplicate.php b/src/Bundle/ChillPersonBundle/Export/Export/ListPersonDuplicate.php index e7c105604..e40ffccce 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/ListPersonDuplicate.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/ListPersonDuplicate.php @@ -74,12 +74,9 @@ class ListPersonDuplicate implements DirectExportInterface, ExportElementValidat { $builder->add('precision', NumberType::class, [ 'label' => 'Precision', + 'data' => self::PRECISION_DEFAULT_VALUE, ]); } - public function getFormDefaultData(): array - { - return ['precision' => self::PRECISION_DEFAULT_VALUE]; - } public function generate(array $acl, array $data = []): Response { diff --git a/src/Bundle/ChillPersonBundle/Export/Export/StatAccompanyingCourseDuration.php b/src/Bundle/ChillPersonBundle/Export/Export/StatAccompanyingCourseDuration.php index 66b47131d..31ca41cbb 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/StatAccompanyingCourseDuration.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/StatAccompanyingCourseDuration.php @@ -41,12 +41,9 @@ class StatAccompanyingCourseDuration implements ExportInterface, GroupedExportIn { $builder->add('closingdate', ChillDateType::class, [ 'label' => 'Closingdate to apply', + 'data' => new DateTime('now'), ]); } - public function getFormDefaultData(): array - { - return ['closingdate' => new DateTime('now')]; - } public function getAllowedFormattersTypes(): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ActiveOnDateFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ActiveOnDateFilter.php index fcb4d67fb..3fa8d711f 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ActiveOnDateFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ActiveOnDateFilter.php @@ -67,11 +67,9 @@ class ActiveOnDateFilter implements FilterInterface public function buildForm(FormBuilderInterface $builder) { $builder - ->add('on_date', PickRollingDateType::class, []); - } - public function getFormDefaultData(): array - { - return ['on_date' => new RollingDate(RollingDate::T_TODAY)]; + ->add('on_date', PickRollingDateType::class, [ + 'data' => new RollingDate(RollingDate::T_TODAY), + ]); } public function describeAction($data, $format = 'string'): array diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ActiveOneDayBetweenDatesFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ActiveOneDayBetweenDatesFilter.php index f693a6d04..f713e8a97 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ActiveOneDayBetweenDatesFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ActiveOneDayBetweenDatesFilter.php @@ -63,10 +63,6 @@ class ActiveOneDayBetweenDatesFilter implements FilterInterface 'data' => new RollingDate(RollingDate::T_TODAY), ]); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/AdministrativeLocationFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/AdministrativeLocationFilter.php index aa1abb36e..c74e309b2 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/AdministrativeLocationFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/AdministrativeLocationFilter.php @@ -53,10 +53,6 @@ class AdministrativeLocationFilter implements FilterInterface 'multiple' => true, ]); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ClosingMotiveFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ClosingMotiveFilter.php index 153b2ecbd..e57370f30 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ClosingMotiveFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ClosingMotiveFilter.php @@ -64,10 +64,6 @@ class ClosingMotiveFilter implements FilterInterface 'expanded' => true, ]); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ConfidentialFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ConfidentialFilter.php index 58085f762..4be284b2d 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ConfidentialFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ConfidentialFilter.php @@ -66,12 +66,10 @@ class ConfidentialFilter implements FilterInterface 'choices' => self::CHOICES, 'multiple' => false, 'expanded' => true, + 'empty_data' => self::DEFAULT_CHOICE, + 'data' => self::DEFAULT_CHOICE, ]); } - public function getFormDefaultData(): array - { - return ['accepted_confidentials' => self::DEFAULT_CHOICE]; - } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/CreatorFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/CreatorFilter.php index 8a8a24013..b13947e60 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/CreatorFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/CreatorFilter.php @@ -50,10 +50,6 @@ class CreatorFilter implements FilterInterface 'label' => false, ]); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/CreatorJobFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/CreatorJobFilter.php index 5faeb850f..f585cfafb 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/CreatorJobFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/CreatorJobFilter.php @@ -69,10 +69,6 @@ class CreatorJobFilter implements FilterInterface 'label' => 'Job', ]); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/EmergencyFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/EmergencyFilter.php index 897a4db2d..d31b93bd4 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/EmergencyFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/EmergencyFilter.php @@ -66,12 +66,10 @@ class EmergencyFilter implements FilterInterface 'choices' => self::CHOICES, 'multiple' => false, 'expanded' => true, + 'empty_data' => self::DEFAULT_CHOICE, + 'data' => self::DEFAULT_CHOICE, ]); } - public function getFormDefaultData(): array - { - return ['accepted_emergency' => self::DEFAULT_CHOICE]; - } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/EvaluationFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/EvaluationFilter.php index a6fb3583d..ab7f4257e 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/EvaluationFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/EvaluationFilter.php @@ -75,10 +75,6 @@ class EvaluationFilter implements FilterInterface 'attr' => ['class' => 'select2'], ]); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/GeographicalUnitStatFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/GeographicalUnitStatFilter.php index b4ffed280..d35565c80 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/GeographicalUnitStatFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/GeographicalUnitStatFilter.php @@ -114,10 +114,6 @@ class GeographicalUnitStatFilter implements FilterInterface 'multiple' => true, ]); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HasNoActionFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HasNoActionFilter.php index 4820116c0..54c28d027 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HasNoActionFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HasNoActionFilter.php @@ -38,10 +38,6 @@ class HasNoActionFilter implements FilterInterface { // no form } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HasNoReferrerFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HasNoReferrerFilter.php index 6d01ea7c2..4c682a56a 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HasNoReferrerFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HasNoReferrerFilter.php @@ -65,12 +65,9 @@ class HasNoReferrerFilter implements FilterInterface $builder ->add('calc_date', PickRollingDateType::class, [ 'label' => 'Has no referrer on this date', + 'data' => new RollingDate(RollingDate::T_TODAY), ]); } - public function getFormDefaultData(): array - { - return ['calc_date' => new RollingDate(RollingDate::T_TODAY)]; - } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HasTemporaryLocationFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HasTemporaryLocationFilter.php index f9b2f2bd6..615ace4c6 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HasTemporaryLocationFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HasTemporaryLocationFilter.php @@ -95,10 +95,6 @@ class HasTemporaryLocationFilter implements FilterInterface 'data' => new RollingDate(RollingDate::T_TODAY), ]); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HavingAnAccompanyingPeriodInfoWithinDatesFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HavingAnAccompanyingPeriodInfoWithinDatesFilter.php index cdc771b19..7069a1d80 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HavingAnAccompanyingPeriodInfoWithinDatesFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HavingAnAccompanyingPeriodInfoWithinDatesFilter.php @@ -46,10 +46,6 @@ final readonly class HavingAnAccompanyingPeriodInfoWithinDatesFilter implements ]) ; } - public function getFormDefaultData(): array - { - return []; - } public function getTitle(): string { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/IntensityFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/IntensityFilter.php index 1fd05d2b4..b0c2205a0 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/IntensityFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/IntensityFilter.php @@ -67,12 +67,9 @@ class IntensityFilter implements FilterInterface 'multiple' => false, 'expanded' => true, 'empty_data' => self::DEFAULT_CHOICE, + 'data' => self::DEFAULT_CHOICE, ]); } - public function getFormDefaultData(): array - { - return ['accepted_intensities' => self::DEFAULT_CHOICE]; - } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/OpenBetweenDatesFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/OpenBetweenDatesFilter.php index ebbec06a4..07ca1de75 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/OpenBetweenDatesFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/OpenBetweenDatesFilter.php @@ -61,10 +61,6 @@ class OpenBetweenDatesFilter implements FilterInterface 'data' => new RollingDate(RollingDate::T_TODAY), ]); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/OriginFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/OriginFilter.php index 8395c79f8..00febc640 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/OriginFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/OriginFilter.php @@ -64,10 +64,6 @@ class OriginFilter implements FilterInterface 'expanded' => true, ]); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ReferrerFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ReferrerFilter.php index daf0d83a4..2a3e5d17e 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ReferrerFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ReferrerFilter.php @@ -82,10 +82,6 @@ class ReferrerFilter implements FilterInterface 'required' => true, ]); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/RequestorFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/RequestorFilter.php index 614889c27..3295a5b57 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/RequestorFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/RequestorFilter.php @@ -126,12 +126,9 @@ final class RequestorFilter implements FilterInterface 'multiple' => false, 'expanded' => true, 'empty_data' => self::DEFAULT_CHOICE, + 'data' => self::DEFAULT_CHOICE, ]); } - public function getFormDefaultData(): array - { - return ['accepted_choices' => self::DEFAULT_CHOICE]; - } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/SocialActionFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/SocialActionFilter.php index 0c14ba73a..bc1f368da 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/SocialActionFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/SocialActionFilter.php @@ -70,10 +70,6 @@ class SocialActionFilter implements FilterInterface 'multiple' => true, ]); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/SocialIssueFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/SocialIssueFilter.php index a793bc548..917e129bf 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/SocialIssueFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/SocialIssueFilter.php @@ -69,10 +69,6 @@ class SocialIssueFilter implements FilterInterface 'multiple' => true, ]); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/StepFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/StepFilter.php index 993ebe301..8ee798c07 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/StepFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/StepFilter.php @@ -102,10 +102,6 @@ class StepFilter implements FilterInterface 'data' => new RollingDate(RollingDate::T_TODAY), ]); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserJobFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserJobFilter.php index cb70fb78b..05d84d7b2 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserJobFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserJobFilter.php @@ -101,10 +101,6 @@ class UserJobFilter implements FilterInterface 'required' => true, ]); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserScopeFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserScopeFilter.php index 580c8e334..bbffa4bca 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserScopeFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserScopeFilter.php @@ -105,10 +105,6 @@ class UserScopeFilter implements FilterInterface 'required' => true, ]); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserWorkingOnCourseFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserWorkingOnCourseFilter.php index d078443af..586bb645d 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserWorkingOnCourseFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserWorkingOnCourseFilter.php @@ -42,10 +42,6 @@ readonly class UserWorkingOnCourseFilter implements FilterInterface 'multiple' => true, ]); } - public function getFormDefaultData(): array - { - return []; - } public function getTitle(): string { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/ByEndDateFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/ByEndDateFilter.php index c0e9c4a99..de86604e6 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/ByEndDateFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/ByEndDateFilter.php @@ -64,10 +64,6 @@ class ByEndDateFilter implements FilterInterface 'data' => new RollingDate(RollingDate::T_TODAY), ]); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/ByStartDateFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/ByStartDateFilter.php index a40becbad..27518599c 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/ByStartDateFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/ByStartDateFilter.php @@ -64,10 +64,6 @@ class ByStartDateFilter implements FilterInterface 'data' => new RollingDate(RollingDate::T_TODAY), ]); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/CurrentEvaluationsFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/CurrentEvaluationsFilter.php index 8841c7b9e..140f6c3cb 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/CurrentEvaluationsFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/CurrentEvaluationsFilter.php @@ -37,10 +37,6 @@ class CurrentEvaluationsFilter implements FilterInterface { //no form needed } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/EvaluationTypeFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/EvaluationTypeFilter.php index 77bae1b56..6a0c71d55 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/EvaluationTypeFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/EvaluationTypeFilter.php @@ -64,10 +64,6 @@ final class EvaluationTypeFilter implements FilterInterface 'expanded' => true, ]); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/MaxDateFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/MaxDateFilter.php index daa7d1954..4a65452a1 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/MaxDateFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/MaxDateFilter.php @@ -61,10 +61,6 @@ class MaxDateFilter implements FilterInterface 'expanded' => true, ]); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/HouseholdFilters/CompositionFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/HouseholdFilters/CompositionFilter.php index a89236159..22761c158 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/HouseholdFilters/CompositionFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/HouseholdFilters/CompositionFilter.php @@ -88,10 +88,6 @@ class CompositionFilter implements FilterInterface 'data' => new RollingDate(RollingDate::T_TODAY), ]); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/AddressRefStatusFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/AddressRefStatusFilter.php index cf777e08d..7580a37a3 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/AddressRefStatusFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/AddressRefStatusFilter.php @@ -87,10 +87,6 @@ class AddressRefStatusFilter implements \Chill\MainBundle\Export\FilterInterface 'data' => [Address::ADDR_REFERENCE_STATUS_TO_REVIEW] ]); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/BirthdateFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/BirthdateFilter.php index 9a0478b6c..7ae22ddd8 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/BirthdateFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/BirthdateFilter.php @@ -71,16 +71,14 @@ class BirthdateFilter implements ExportElementValidatedInterface, FilterInterfac { $builder->add('date_from', PickRollingDateType::class, [ 'label' => 'Born after this date', + 'data' => new RollingDate(RollingDate::T_YEAR_PREVIOUS_START), ]); $builder->add('date_to', PickRollingDateType::class, [ 'label' => 'Born before this date', + 'data' => new RollingDate(RollingDate::T_TODAY), ]); } - public function getFormDefaultData(): array - { - return ['date_from' => new RollingDate(RollingDate::T_YEAR_PREVIOUS_START), 'date_to' => new RollingDate(RollingDate::T_TODAY)]; - } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ByHouseholdCompositionFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ByHouseholdCompositionFilter.php index d7adb5cd9..9b59549f1 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ByHouseholdCompositionFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ByHouseholdCompositionFilter.php @@ -89,10 +89,6 @@ class ByHouseholdCompositionFilter implements FilterInterface 'data' => new RollingDate(RollingDate::T_TODAY), ]); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/DeadOrAliveFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/DeadOrAliveFilter.php index 8b2444ca2..384d6698a 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/DeadOrAliveFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/DeadOrAliveFilter.php @@ -102,12 +102,9 @@ class DeadOrAliveFilter implements FilterInterface $builder->add('date_calc', PickRollingDateType::class, [ 'label' => 'Filter in relation to this date', + 'data' => new RollingDate(RollingDate::T_TODAY), ]); } - public function getFormDefaultData(): array - { - return ['date_calc' => new RollingDate(RollingDate::T_TODAY)]; - } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/DeathdateFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/DeathdateFilter.php index 7805331a5..0ac4b3173 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/DeathdateFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/DeathdateFilter.php @@ -72,16 +72,14 @@ class DeathdateFilter implements ExportElementValidatedInterface, FilterInterfac { $builder->add('date_from', PickRollingDateType::class, [ 'label' => 'Death after this date', + 'data' => new RollingDate(RollingDate::T_YEAR_PREVIOUS_START), ]); $builder->add('date_to', PickRollingDateType::class, [ 'label' => 'Deathdate before', + 'data' => new RollingDate(RollingDate::T_TODAY), ]); } - public function getFormDefaultData(): array - { - return ['date_from' => new RollingDate(RollingDate::T_YEAR_PREVIOUS_START), 'date_to' => new RollingDate(RollingDate::T_TODAY)]; - } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/GenderFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/GenderFilter.php index 182006bbc..739945b98 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/GenderFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/GenderFilter.php @@ -89,10 +89,6 @@ class GenderFilter implements 'expanded' => true, ]); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/GeographicalUnitFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/GeographicalUnitFilter.php index 7efeca49e..79f5cb2d4 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/GeographicalUnitFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/GeographicalUnitFilter.php @@ -105,10 +105,6 @@ class GeographicalUnitFilter implements \Chill\MainBundle\Export\FilterInterface 'multiple' => true, ]); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/MaritalStatusFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/MaritalStatusFilter.php index 021c22fc6..47a75871c 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/MaritalStatusFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/MaritalStatusFilter.php @@ -56,10 +56,6 @@ class MaritalStatusFilter implements FilterInterface 'expanded' => true, ]); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/NationalityFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/NationalityFilter.php index e5102128b..b1d77d60e 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/NationalityFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/NationalityFilter.php @@ -67,10 +67,6 @@ class NationalityFilter implements 'placeholder' => 'Choose countries', ]); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ResidentialAddressAtThirdpartyFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ResidentialAddressAtThirdpartyFilter.php index 8f22750a5..21bb40947 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ResidentialAddressAtThirdpartyFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ResidentialAddressAtThirdpartyFilter.php @@ -107,12 +107,9 @@ class ResidentialAddressAtThirdpartyFilter implements FilterInterface $builder->add('date_calc', PickRollingDateType::class, [ 'label' => 'Date during which residential address was valid', + 'data' => new RollingDate(RollingDate::T_TODAY), ]); } - public function getFormDefaultData(): array - { - return ['date_calc' => new RollingDate(RollingDate::T_TODAY)]; - } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ResidentialAddressAtUserFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ResidentialAddressAtUserFilter.php index 62b142420..bd55c5b80 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ResidentialAddressAtUserFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ResidentialAddressAtUserFilter.php @@ -82,12 +82,9 @@ class ResidentialAddressAtUserFilter implements FilterInterface { $builder->add('date_calc', PickRollingDateType::class, [ 'label' => 'Date during which residential address was valid', + 'data' => new RollingDate(RollingDate::T_TODAY), ]); } - public function getFormDefaultData(): array - { - return ['date_calc' => new RollingDate(RollingDate::T_TODAY)]; - } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/WithoutHouseholdComposition.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/WithoutHouseholdComposition.php index 9f5ed90b5..c4644fc11 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/WithoutHouseholdComposition.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/WithoutHouseholdComposition.php @@ -66,12 +66,9 @@ class WithoutHouseholdComposition implements FilterInterface $builder ->add('calc_date', PickRollingDateType::class, [ 'label' => 'export.filter.person.by_no_composition.Date calc', + 'data' => new RollingDate(RollingDate::T_TODAY), ]); } - public function getFormDefaultData(): array - { - return ['calc_date' => new RollingDate(RollingDate::T_TODAY)]; - } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/AccompanyingPeriodWorkEndDateBetweenDateFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/AccompanyingPeriodWorkEndDateBetweenDateFilter.php index 45d86bc97..b13c49e9a 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/AccompanyingPeriodWorkEndDateBetweenDateFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/AccompanyingPeriodWorkEndDateBetweenDateFilter.php @@ -44,10 +44,6 @@ final readonly class AccompanyingPeriodWorkEndDateBetweenDateFilter implements F ]) ; } - public function getFormDefaultData(): array - { - return []; - } public function getTitle(): string { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/AccompanyingPeriodWorkStartDateBetweenDateFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/AccompanyingPeriodWorkStartDateBetweenDateFilter.php index f4a914203..e9526a9a5 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/AccompanyingPeriodWorkStartDateBetweenDateFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/AccompanyingPeriodWorkStartDateBetweenDateFilter.php @@ -44,10 +44,6 @@ final readonly class AccompanyingPeriodWorkStartDateBetweenDateFilter implements ]) ; } - public function getFormDefaultData(): array - { - return []; - } public function getTitle(): string { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/CurrentActionFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/CurrentActionFilter.php index e99590025..cbdb64d8d 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/CurrentActionFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/CurrentActionFilter.php @@ -37,10 +37,6 @@ class CurrentActionFilter implements FilterInterface { //no form } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/JobFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/JobFilter.php index 265c8e24d..144bf3260 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/JobFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/JobFilter.php @@ -76,10 +76,6 @@ class JobFilter implements FilterInterface 'expanded' => true, ]); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/ReferrerFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/ReferrerFilter.php index bddcfbf9b..8d0da32fb 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/ReferrerFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/ReferrerFilter.php @@ -57,10 +57,6 @@ class ReferrerFilter implements FilterInterface 'multiple' => true, ]); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/ScopeFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/ScopeFilter.php index 737759c3e..315025722 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/ScopeFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/ScopeFilter.php @@ -76,10 +76,6 @@ class ScopeFilter implements FilterInterface 'expanded' => true, ]); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/SocialWorkTypeFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/SocialWorkTypeFilter.php index 25bfc17a0..11fd0ed9d 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/SocialWorkTypeFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/SocialWorkTypeFilter.php @@ -110,10 +110,6 @@ class SocialWorkTypeFilter implements FilterInterface $this->iterableToIdTransformer(Result::class) ); } - public function getFormDefaultData(): array - { - return []; - } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillReportBundle/Export/Filter/ReportDateFilter.php b/src/Bundle/ChillReportBundle/Export/Filter/ReportDateFilter.php index cb8e7d1d0..79bad4f52 100644 --- a/src/Bundle/ChillReportBundle/Export/Filter/ReportDateFilter.php +++ b/src/Bundle/ChillReportBundle/Export/Filter/ReportDateFilter.php @@ -67,16 +67,14 @@ class ReportDateFilter implements FilterInterface { $builder->add('date_from', PickRollingDateType::class, [ 'label' => 'Report is after this date', + 'data' => new RollingDate(RollingDate::T_YEAR_PREVIOUS_START), ]); $builder->add('date_to', PickRollingDateType::class, [ 'label' => 'Report is before this date', + 'data' => new RollingDate(RollingDate::T_TODAY), ]); } - public function getFormDefaultData(): array - { - return ['date_from' => new RollingDate(RollingDate::T_YEAR_PREVIOUS_START), 'date_to' => new RollingDate(RollingDate::T_TODAY)]; - } public function describeAction($data, $format = 'string') { From 50de389bc7a6b6c75b4033b33de93dad7f3b5750 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Sun, 18 Jun 2023 11:58:42 +0200 Subject: [PATCH 188/321] Revert "apply fixes for list" This reverts commit 938027cc --- .../Export/Export/LinkedToACP/ListActivity.php | 4 ---- .../Export/Export/LinkedToPerson/ListActivity.php | 4 ---- .../src/Export/Export/ListAsideActivity.php | 4 ---- .../ChillMainBundle/Export/Formatter/CSVListFormatter.php | 8 +------- .../Export/Formatter/CSVPivotedListFormatter.php | 6 +----- .../Export/Formatter/SpreadsheetListFormatter.php | 6 +----- .../Export/Export/ListAccompanyingPeriod.php | 4 ---- .../Export/Export/ListAccompanyingPeriodWork.php | 5 +---- .../ChillPersonBundle/Export/Export/ListEvaluation.php | 5 +---- .../Export/Export/ListHouseholdInPeriod.php | 5 +---- .../Export/Export/ListPersonWithAccompanyingPeriod.php | 8 ++------ src/Bundle/ChillReportBundle/Export/Export/ReportList.php | 5 +---- 12 files changed, 9 insertions(+), 55 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/ListActivity.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/ListActivity.php index 9ed6bcda2..026e16f90 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/ListActivity.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/ListActivity.php @@ -44,10 +44,6 @@ class ListActivity implements ListInterface, GroupedExportInterface { $this->helper->buildForm($builder); } - public function getFormDefaultData(): array - { - return []; - } public function getAllowedFormattersTypes() { diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/ListActivity.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/ListActivity.php index d14111ba7..60110c9a8 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/ListActivity.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/ListActivity.php @@ -88,10 +88,6 @@ class ListActivity implements ListInterface, GroupedExportInterface ])], ]); } - public function getFormDefaultData(): array - { - return []; - } public function getAllowedFormattersTypes() { diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Export/ListAsideActivity.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Export/ListAsideActivity.php index b46e120b5..aee168174 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Export/ListAsideActivity.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Export/ListAsideActivity.php @@ -73,10 +73,6 @@ final class ListAsideActivity implements ListInterface, GroupedExportInterface public function buildForm(FormBuilderInterface $builder) { } - public function getFormDefaultData(): array - { - return []; - } public function getAllowedFormattersTypes() { diff --git a/src/Bundle/ChillMainBundle/Export/Formatter/CSVListFormatter.php b/src/Bundle/ChillMainBundle/Export/Formatter/CSVListFormatter.php index 70d80b74b..b84c80118 100644 --- a/src/Bundle/ChillMainBundle/Export/Formatter/CSVListFormatter.php +++ b/src/Bundle/ChillMainBundle/Export/Formatter/CSVListFormatter.php @@ -85,16 +85,10 @@ class CSVListFormatter implements FormatterInterface 'expanded' => true, 'multiple' => false, 'label' => 'Add a number on first column', + 'data' => true, ]); } - public function getFormDefaultData(array $aggregatorAliases): array - { - return ['numerotation' => true]; - } - - - public function getName() { return 'CSV vertical list'; diff --git a/src/Bundle/ChillMainBundle/Export/Formatter/CSVPivotedListFormatter.php b/src/Bundle/ChillMainBundle/Export/Formatter/CSVPivotedListFormatter.php index cce0fa1e4..63d691443 100644 --- a/src/Bundle/ChillMainBundle/Export/Formatter/CSVPivotedListFormatter.php +++ b/src/Bundle/ChillMainBundle/Export/Formatter/CSVPivotedListFormatter.php @@ -80,14 +80,10 @@ class CSVPivotedListFormatter implements FormatterInterface 'expanded' => true, 'multiple' => false, 'label' => 'Add a number on first column', + 'data' => true, ]); } - public function getFormDefaultData(array $aggregatorAliases): array - { - return ['numerotation' => true]; - } - public function getName() { return 'CSV horizontal list'; diff --git a/src/Bundle/ChillMainBundle/Export/Formatter/SpreadsheetListFormatter.php b/src/Bundle/ChillMainBundle/Export/Formatter/SpreadsheetListFormatter.php index 34960d8d2..0e5e339ea 100644 --- a/src/Bundle/ChillMainBundle/Export/Formatter/SpreadsheetListFormatter.php +++ b/src/Bundle/ChillMainBundle/Export/Formatter/SpreadsheetListFormatter.php @@ -104,14 +104,10 @@ class SpreadsheetListFormatter implements FormatterInterface 'expanded' => true, 'multiple' => false, 'label' => 'Add a number on first column', + 'data' => true, ]); } - public function getFormDefaultData(array $aggregatorAliases): array - { - return ['format' => 'xlsx', 'numerotation' => true]; - } - public function getName() { return 'Spreadsheet list formatter (.xlsx, .ods)'; diff --git a/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriod.php b/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriod.php index e5e724b6c..0647460dd 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriod.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriod.php @@ -144,10 +144,6 @@ class ListAccompanyingPeriod implements ListInterface, GroupedExportInterface 'required' => true, ]); } - public function getFormDefaultData(): array - { - return []; - } public function getAllowedFormattersTypes() { diff --git a/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriodWork.php b/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriodWork.php index c437454c2..00fa8adb1 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriodWork.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriodWork.php @@ -135,12 +135,9 @@ class ListAccompanyingPeriodWork implements ListInterface, GroupedExportInterfac 'label' => 'export.list.acpw.Date of calculation for associated elements', 'help' => 'export.list.acpw.help_description', 'required' => true, + 'data' => new RollingDate(RollingDate::T_TODAY), ]); } - public function getFormDefaultData(): array - { - return ['calc_date' => new RollingDate(RollingDate::T_TODAY)]; - } public function getAllowedFormattersTypes() { diff --git a/src/Bundle/ChillPersonBundle/Export/Export/ListEvaluation.php b/src/Bundle/ChillPersonBundle/Export/Export/ListEvaluation.php index c3e273733..f0985436b 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/ListEvaluation.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/ListEvaluation.php @@ -123,12 +123,9 @@ class ListEvaluation implements ListInterface, GroupedExportInterface 'label' => 'export.list.eval.Date of calculation for associated elements', 'help' => 'export.list.eval.help_description', 'required' => true, + 'data' => new RollingDate(RollingDate::T_TODAY), ]); } - public function getFormDefaultData(): array - { - return ['calc_date' => new RollingDate(RollingDate::T_TODAY)]; - } public function getAllowedFormattersTypes() { diff --git a/src/Bundle/ChillPersonBundle/Export/Export/ListHouseholdInPeriod.php b/src/Bundle/ChillPersonBundle/Export/Export/ListHouseholdInPeriod.php index 4dcc89495..8894d145d 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/ListHouseholdInPeriod.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/ListHouseholdInPeriod.php @@ -75,13 +75,10 @@ class ListHouseholdInPeriod implements ListInterface, GroupedExportInterface ->add('calc_date', PickRollingDateType::class, [ 'label' => 'export.list.household.Date of calculation for associated elements', 'help' => 'export.list.household.help_description', + 'data' => new RollingDate(RollingDate::T_TODAY), 'required' => true, ]); } - public function getFormDefaultData(): array - { - return ['calc_date' => new RollingDate(RollingDate::T_TODAY)]; - } public function getAllowedFormattersTypes() { diff --git a/src/Bundle/ChillPersonBundle/Export/Export/ListPersonWithAccompanyingPeriod.php b/src/Bundle/ChillPersonBundle/Export/Export/ListPersonWithAccompanyingPeriod.php index e8e495cc7..7cb066e87 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/ListPersonWithAccompanyingPeriod.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/ListPersonWithAccompanyingPeriod.php @@ -80,21 +80,17 @@ class ListPersonWithAccompanyingPeriod implements ExportElementValidatedInterfac } }, ])], + 'data' => array_values($choices), ]); // add a date field for addresses $builder->add('address_date', ChillDateType::class, [ 'label' => 'Data valid at this date', 'help' => 'Data regarding center, addresses, and so on will be computed at this date', + 'data' => new DateTimeImmutable(), 'input' => 'datetime_immutable', ]); } - public function getFormDefaultData(): array - { - $choices = array_combine(ListPersonHelper::FIELDS, ListPersonHelper::FIELDS); - - return ['fields' => array_values($choices), 'address_date' => new DateTimeImmutable()]; - } public function getAllowedFormattersTypes() { diff --git a/src/Bundle/ChillReportBundle/Export/Export/ReportList.php b/src/Bundle/ChillReportBundle/Export/Export/ReportList.php index c551bfb11..9adae0097 100644 --- a/src/Bundle/ChillReportBundle/Export/Export/ReportList.php +++ b/src/Bundle/ChillReportBundle/Export/Export/ReportList.php @@ -137,14 +137,11 @@ class ReportList implements ExportElementValidatedInterface, ListInterface // add a date field for addresses $builder->add('address_date', ChillDateType::class, [ 'label' => 'Address valid at this date', + 'data' => new DateTime(), 'required' => false, 'block_name' => 'list_export_form_address_date', ]); } - public function getFormDefaultData(): array - { - return ['address_date' => new DateTime()]; - } public function getAllowedFormattersTypes() { From 21f11fb034db2cb8d7411480265fff7be29ae145 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Sun, 18 Jun 2023 21:36:40 +0200 Subject: [PATCH 189/321] execute rector run on filters and aggregators --- docs/source/_static/code/exports/BirthdateFilter.php | 6 ++++-- docs/source/_static/code/exports/CountPerson.php | 4 ++++ .../ACPAggregators/ByActivityNumberAggregator.php | 4 ++++ .../ACPAggregators/ByCreatorAggregator.php | 4 ++++ .../ACPAggregators/BySocialActionAggregator.php | 4 ++++ .../ACPAggregators/BySocialIssueAggregator.php | 4 ++++ .../ACPAggregators/ByThirdpartyAggregator.php | 4 ++++ .../ACPAggregators/CreatorScopeAggregator.php | 4 ++++ .../Aggregator/ACPAggregators/DateAggregator.php | 5 ++++- .../ACPAggregators/LocationTypeAggregator.php | 4 ++++ .../Export/Aggregator/ActivityTypeAggregator.php | 4 ++++ .../Export/Aggregator/ActivityUserAggregator.php | 4 ++++ .../Export/Aggregator/ActivityUsersAggregator.php | 4 ++++ .../Export/Aggregator/ActivityUsersJobAggregator.php | 4 ++++ .../Aggregator/ActivityUsersScopeAggregator.php | 4 ++++ .../PersonAggregators/ActivityReasonAggregator.php | 4 ++++ .../Export/Aggregator/SentReceivedAggregator.php | 4 ++++ .../Export/LinkedToACP/AvgActivityDuration.php | 4 ++++ .../Export/LinkedToACP/AvgActivityVisitDuration.php | 4 ++++ .../Export/Export/LinkedToACP/CountActivity.php | 4 ++++ .../Export/Export/LinkedToACP/ListActivity.php | 4 ++++ .../Export/LinkedToACP/SumActivityDuration.php | 4 ++++ .../Export/LinkedToACP/SumActivityVisitDuration.php | 4 ++++ .../Export/Export/LinkedToPerson/CountActivity.php | 4 ++++ .../Export/Export/LinkedToPerson/ListActivity.php | 4 ++++ .../Export/LinkedToPerson/StatActivityDuration.php | 4 ++++ .../Export/Filter/ACPFilters/ActivityTypeFilter.php | 4 ++++ .../Export/Filter/ACPFilters/ByCreatorFilter.php | 4 ++++ .../Filter/ACPFilters/BySocialActionFilter.php | 4 ++++ .../Export/Filter/ACPFilters/BySocialIssueFilter.php | 4 ++++ .../Export/Filter/ACPFilters/EmergencyFilter.php | 5 ++++- .../Export/Filter/ACPFilters/HasNoActivityFilter.php | 4 ++++ .../Export/Filter/ACPFilters/LocationFilter.php | 4 ++++ .../Export/Filter/ACPFilters/LocationTypeFilter.php | 4 ++++ .../Export/Filter/ACPFilters/SentReceivedFilter.php | 5 ++++- .../Export/Filter/ACPFilters/UserFilter.php | 4 ++++ .../Export/Filter/ACPFilters/UserScopeFilter.php | 4 ++++ .../Export/Filter/ActivityDateFilter.php | 6 ++++-- .../Export/Filter/ActivityTypeFilter.php | 4 ++++ .../Export/Filter/ActivityUsersFilter.php | 4 ++++ .../Filter/PersonFilters/ActivityReasonFilter.php | 4 ++++ .../PersonHavingActivityBetweenDateFilter.php | 7 ++++--- .../Export/Filter/UsersJobFilter.php | 4 ++++ .../Export/Filter/UsersScopeFilter.php | 4 ++++ .../Export/Aggregator/ByActivityTypeAggregator.php | 4 ++++ .../src/Export/Aggregator/ByUserJobAggregator.php | 4 ++++ .../src/Export/Aggregator/ByUserScopeAggregator.php | 4 ++++ .../src/Export/Export/AvgAsideActivityDuration.php | 4 ++++ .../src/Export/Export/CountAsideActivity.php | 4 ++++ .../src/Export/Export/ListAsideActivity.php | 4 ++++ .../src/Export/Export/SumAsideActivityDuration.php | 4 ++++ .../src/Export/Filter/ByActivityTypeFilter.php | 4 ++++ .../src/Export/Filter/ByDateFilter.php | 6 ++++-- .../src/Export/Filter/ByUserFilter.php | 4 ++++ .../src/Export/Filter/ByUserJobFilter.php | 4 ++++ .../src/Export/Filter/ByUserScopeFilter.php | 4 ++++ .../Export/Aggregator/AgentAggregator.php | 4 ++++ .../Export/Aggregator/CancelReasonAggregator.php | 4 ++++ .../Export/Aggregator/JobAggregator.php | 4 ++++ .../Export/Aggregator/LocationAggregator.php | 4 ++++ .../Export/Aggregator/LocationTypeAggregator.php | 4 ++++ .../Export/Aggregator/MonthYearAggregator.php | 4 ++++ .../Export/Aggregator/ScopeAggregator.php | 4 ++++ .../Export/Aggregator/UrgencyAggregator.php | 4 ++++ .../Export/Export/CountCalendars.php | 4 ++++ .../Export/Export/StatCalendarAvgDuration.php | 4 ++++ .../Export/Export/StatCalendarSumDuration.php | 4 ++++ .../Export/Filter/AgentFilter.php | 4 ++++ .../Export/Filter/BetweenDatesFilter.php | 12 ++++++------ .../Export/Filter/CalendarRangeFilter.php | 5 ++++- .../ChillCalendarBundle/Export/Filter/JobFilter.php | 4 ++++ .../Export/Filter/ScopeFilter.php | 4 ++++ .../Export/Formatter/CSVListFormatter.php | 6 +++++- .../Export/Formatter/CSVPivotedListFormatter.php | 5 +++++ .../Export/Formatter/SpreadsheetListFormatter.php | 6 +++++- .../AdministrativeLocationAggregator.php | 4 ++++ .../ByActionNumberAggregator.php | 4 ++++ .../ClosingMotiveAggregator.php | 4 ++++ .../ConfidentialAggregator.php | 4 ++++ .../CreatorJobAggregator.php | 4 ++++ .../DurationAggregator.php | 4 ++++ .../EmergencyAggregator.php | 4 ++++ .../EvaluationAggregator.php | 4 ++++ .../GeographicalUnitStatAggregator.php | 5 ++++- .../IntensityAggregator.php | 4 ++++ .../OriginAggregator.php | 4 ++++ .../ReferrerAggregator.php | 5 ++++- .../ReferrerScopeAggregator.php | 5 ++++- .../RequestorAggregator.php | 4 ++++ .../ScopeAggregator.php | 4 ++++ .../SocialActionAggregator.php | 4 ++++ .../SocialIssueAggregator.php | 4 ++++ .../AccompanyingCourseAggregators/StepAggregator.php | 8 +++++--- .../UserJobAggregator.php | 4 ++++ .../EvaluationAggregators/ByEndDateAggregator.php | 5 ++++- .../EvaluationAggregators/ByMaxDateAggregator.php | 5 ++++- .../EvaluationAggregators/ByStartDateAggregator.php | 5 ++++- .../EvaluationTypeAggregator.php | 4 ++++ .../HavingEndDateAggregator.php | 4 ++++ .../ChildrenNumberAggregator.php | 8 +++++--- .../HouseholdAggregators/CompositionAggregator.php | 8 +++++--- .../Aggregator/PersonAggregators/AgeAggregator.php | 5 ++++- .../ByHouseholdCompositionAggregator.php | 5 ++++- .../PersonAggregators/CountryOfBirthAggregator.php | 4 ++++ .../PersonAggregators/GenderAggregator.php | 4 ++++ .../PersonAggregators/GeographicalUnitAggregator.php | 5 ++++- .../HouseholdPositionAggregator.php | 5 ++++- .../SocialWorkAggregators/ActionTypeAggregator.php | 4 ++++ .../CurrentActionAggregator.php | 4 ++++ .../SocialWorkAggregators/GoalAggregator.php | 4 ++++ .../SocialWorkAggregators/GoalResultAggregator.php | 4 ++++ .../SocialWorkAggregators/JobAggregator.php | 4 ++++ .../SocialWorkAggregators/ReferrerAggregator.php | 4 ++++ .../SocialWorkAggregators/ResultAggregator.php | 4 ++++ .../SocialWorkAggregators/ScopeAggregator.php | 4 ++++ .../Export/Export/CountAccompanyingCourse.php | 4 ++++ .../Export/Export/CountAccompanyingPeriodWork.php | 4 ++++ .../Export/Export/CountEvaluation.php | 4 ++++ .../Export/Export/CountHousehold.php | 5 ++++- .../Export/CountPersonWithAccompanyingCourse.php | 4 ++++ .../Export/Export/ListAccompanyingPeriod.php | 4 ++++ .../Export/Export/ListAccompanyingPeriodWork.php | 5 ++++- .../Export/Export/ListEvaluation.php | 5 ++++- .../Export/Export/ListHouseholdInPeriod.php | 5 ++++- .../Export/Export/ListPersonDuplicate.php | 5 ++++- .../Export/ListPersonWithAccompanyingPeriod.php | 10 ++++++---- .../Export/Export/StatAccompanyingCourseDuration.php | 5 ++++- .../AccompanyingCourseFilters/ActiveOnDateFilter.php | 8 +++++--- .../ActiveOneDayBetweenDatesFilter.php | 12 ++++++------ .../AdministrativeLocationFilter.php | 4 ++++ .../ClosingMotiveFilter.php | 4 ++++ .../AccompanyingCourseFilters/ConfidentialFilter.php | 9 ++++++--- .../AccompanyingCourseFilters/CreatorFilter.php | 4 ++++ .../AccompanyingCourseFilters/CreatorJobFilter.php | 4 ++++ .../AccompanyingCourseFilters/EmergencyFilter.php | 9 ++++++--- .../AccompanyingCourseFilters/EvaluationFilter.php | 4 ++++ .../GeographicalUnitStatFilter.php | 5 ++++- .../AccompanyingCourseFilters/HasNoActionFilter.php | 4 ++++ .../HasNoReferrerFilter.php | 5 ++++- .../HasTemporaryLocationFilter.php | 5 ++++- ...vingAnAccompanyingPeriodInfoWithinDatesFilter.php | 9 +++++---- .../AccompanyingCourseFilters/IntensityFilter.php | 5 ++++- .../OpenBetweenDatesFilter.php | 12 ++++++------ .../AccompanyingCourseFilters/OriginFilter.php | 4 ++++ .../AccompanyingCourseFilters/ReferrerFilter.php | 5 ++++- .../AccompanyingCourseFilters/RequestorFilter.php | 5 ++++- .../AccompanyingCourseFilters/SocialActionFilter.php | 4 ++++ .../AccompanyingCourseFilters/SocialIssueFilter.php | 4 ++++ .../Filter/AccompanyingCourseFilters/StepFilter.php | 6 ++++-- .../AccompanyingCourseFilters/UserJobFilter.php | 5 ++++- .../AccompanyingCourseFilters/UserScopeFilter.php | 5 ++++- .../UserWorkingOnCourseFilter.php | 4 ++++ .../Filter/EvaluationFilters/ByEndDateFilter.php | 6 ++++-- .../Filter/EvaluationFilters/ByStartDateFilter.php | 6 ++++-- .../EvaluationFilters/CurrentEvaluationsFilter.php | 4 ++++ .../EvaluationFilters/EvaluationTypeFilter.php | 4 ++++ .../Filter/EvaluationFilters/MaxDateFilter.php | 4 ++++ .../Filter/HouseholdFilters/CompositionFilter.php | 8 +++++--- .../Filter/PersonFilters/AddressRefStatusFilter.php | 8 +++++--- .../Export/Filter/PersonFilters/BirthdateFilter.php | 6 ++++-- .../PersonFilters/ByHouseholdCompositionFilter.php | 5 ++++- .../Filter/PersonFilters/DeadOrAliveFilter.php | 5 ++++- .../Export/Filter/PersonFilters/DeathdateFilter.php | 6 ++++-- .../Export/Filter/PersonFilters/GenderFilter.php | 4 ++++ .../Filter/PersonFilters/GeographicalUnitFilter.php | 5 ++++- .../Filter/PersonFilters/MaritalStatusFilter.php | 4 ++++ .../Filter/PersonFilters/NationalityFilter.php | 4 ++++ .../ResidentialAddressAtThirdpartyFilter.php | 5 ++++- .../PersonFilters/ResidentialAddressAtUserFilter.php | 5 ++++- .../PersonFilters/WithoutHouseholdComposition.php | 5 ++++- ...ccompanyingPeriodWorkEndDateBetweenDateFilter.php | 9 +++++---- ...ompanyingPeriodWorkStartDateBetweenDateFilter.php | 9 +++++---- .../Filter/SocialWorkFilters/CurrentActionFilter.php | 4 ++++ .../Export/Filter/SocialWorkFilters/JobFilter.php | 4 ++++ .../Filter/SocialWorkFilters/ReferrerFilter.php | 4 ++++ .../Export/Filter/SocialWorkFilters/ScopeFilter.php | 4 ++++ .../SocialWorkFilters/SocialWorkTypeFilter.php | 5 +++++ .../ChillReportBundle/Export/Export/ReportList.php | 7 ++++--- .../Export/Filter/ReportDateFilter.php | 6 ++++-- 179 files changed, 741 insertions(+), 118 deletions(-) diff --git a/docs/source/_static/code/exports/BirthdateFilter.php b/docs/source/_static/code/exports/BirthdateFilter.php index 64c1d53a9..e25d8b42f 100644 --- a/docs/source/_static/code/exports/BirthdateFilter.php +++ b/docs/source/_static/code/exports/BirthdateFilter.php @@ -62,7 +62,6 @@ class BirthdateFilter implements ExportElementValidatedInterface, FilterInterfac { $builder->add('date_from', DateType::class, [ 'label' => 'Born after this date', - 'data' => new DateTime(), 'attr' => ['class' => 'datepicker'], 'widget' => 'single_text', 'format' => 'dd-MM-yyyy', @@ -70,12 +69,15 @@ class BirthdateFilter implements ExportElementValidatedInterface, FilterInterfac $builder->add('date_to', DateType::class, [ 'label' => 'Born before this date', - 'data' => new DateTime(), 'attr' => ['class' => 'datepicker'], 'widget' => 'single_text', 'format' => 'dd-MM-yyyy', ]); } + public function getFormDefaultData(): array + { + return ['date_from' => new DateTime(), 'date_to' => new DateTime()]; + } // here, we create a simple string which will describe the action of // the filter in the Response diff --git a/docs/source/_static/code/exports/CountPerson.php b/docs/source/_static/code/exports/CountPerson.php index afe19c73b..be800e52c 100644 --- a/docs/source/_static/code/exports/CountPerson.php +++ b/docs/source/_static/code/exports/CountPerson.php @@ -36,6 +36,10 @@ class CountPerson implements ExportInterface { // this export does not add any form } + public function getFormDefaultData(): array + { + return []; + } public function getAllowedFormattersTypes() { diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByActivityNumberAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByActivityNumberAggregator.php index 5c6656009..c23db738e 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByActivityNumberAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByActivityNumberAggregator.php @@ -40,6 +40,10 @@ class ByActivityNumberAggregator implements AggregatorInterface { // No form needed } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByCreatorAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByCreatorAggregator.php index 69149737b..917459de3 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByCreatorAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByCreatorAggregator.php @@ -52,6 +52,10 @@ class ByCreatorAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/BySocialActionAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/BySocialActionAggregator.php index 89732412d..1a75357ae 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/BySocialActionAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/BySocialActionAggregator.php @@ -57,6 +57,10 @@ class BySocialActionAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/BySocialIssueAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/BySocialIssueAggregator.php index 158e87664..9100a8c8f 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/BySocialIssueAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/BySocialIssueAggregator.php @@ -57,6 +57,10 @@ class BySocialIssueAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByThirdpartyAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByThirdpartyAggregator.php index c3ca6d59c..ac05b153c 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByThirdpartyAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByThirdpartyAggregator.php @@ -57,6 +57,10 @@ class ByThirdpartyAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/CreatorScopeAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/CreatorScopeAggregator.php index 2c7ec1483..a4b5258e2 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/CreatorScopeAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/CreatorScopeAggregator.php @@ -57,6 +57,10 @@ class CreatorScopeAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/DateAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/DateAggregator.php index a2f465a38..4ede5b4c4 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/DateAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/DateAggregator.php @@ -76,9 +76,12 @@ class DateAggregator implements AggregatorInterface 'multiple' => false, 'expanded' => true, 'empty_data' => self::DEFAULT_CHOICE, - 'data' => self::DEFAULT_CHOICE, ]); } + public function getFormDefaultData(): array + { + return ['frequency' => self::DEFAULT_CHOICE]; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/LocationTypeAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/LocationTypeAggregator.php index ec4ce6315..c72609e2c 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/LocationTypeAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/LocationTypeAggregator.php @@ -57,6 +57,10 @@ class LocationTypeAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityTypeAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityTypeAggregator.php index 7cd16718e..a74428b4a 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityTypeAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityTypeAggregator.php @@ -60,6 +60,10 @@ class ActivityTypeAggregator implements AggregatorInterface { // no form required for this aggregator } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data): Closure { diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUserAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUserAggregator.php index 9bde692c6..2fab2af83 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUserAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUserAggregator.php @@ -58,6 +58,10 @@ class ActivityUserAggregator implements AggregatorInterface { // nothing to add } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, $values, $data): Closure { diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersAggregator.php index 139f2743e..e1e9f161d 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersAggregator.php @@ -56,6 +56,10 @@ class ActivityUsersAggregator implements AggregatorInterface { // nothing to add on the form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersJobAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersJobAggregator.php index 5741a0e58..721078989 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersJobAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersJobAggregator.php @@ -55,6 +55,10 @@ class ActivityUsersJobAggregator implements \Chill\MainBundle\Export\AggregatorI { // nothing to add in the form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersScopeAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersScopeAggregator.php index 15da300be..d7932e9e8 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersScopeAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersScopeAggregator.php @@ -55,6 +55,10 @@ class ActivityUsersScopeAggregator implements \Chill\MainBundle\Export\Aggregato { // nothing to add in the form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/PersonAggregators/ActivityReasonAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/PersonAggregators/ActivityReasonAggregator.php index eaccf95cb..2537f2cf6 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/PersonAggregators/ActivityReasonAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/PersonAggregators/ActivityReasonAggregator.php @@ -110,6 +110,10 @@ class ActivityReasonAggregator implements AggregatorInterface, ExportElementVali ] ); } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/SentReceivedAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/SentReceivedAggregator.php index 5f772e156..ae1dae375 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/SentReceivedAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/SentReceivedAggregator.php @@ -47,6 +47,10 @@ class SentReceivedAggregator implements AggregatorInterface { // No form needed } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data): callable { diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityDuration.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityDuration.php index 34771d077..6930784d3 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityDuration.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityDuration.php @@ -39,6 +39,10 @@ class AvgActivityDuration implements ExportInterface, GroupedExportInterface public function buildForm(FormBuilderInterface $builder) { } + public function getFormDefaultData(): array + { + return []; + } public function getAllowedFormattersTypes(): array { diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityVisitDuration.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityVisitDuration.php index df21362cd..f1e926c64 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityVisitDuration.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityVisitDuration.php @@ -40,6 +40,10 @@ class AvgActivityVisitDuration implements ExportInterface, GroupedExportInterfac { // TODO: Implement buildForm() method. } + public function getFormDefaultData(): array + { + return []; + } public function getAllowedFormattersTypes(): array { diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/CountActivity.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/CountActivity.php index 6b7b1562d..d473a925a 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/CountActivity.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/CountActivity.php @@ -39,6 +39,10 @@ class CountActivity implements ExportInterface, GroupedExportInterface public function buildForm(FormBuilderInterface $builder) { } + public function getFormDefaultData(): array + { + return []; + } public function getAllowedFormattersTypes(): array { diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/ListActivity.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/ListActivity.php index 026e16f90..9ed6bcda2 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/ListActivity.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/ListActivity.php @@ -44,6 +44,10 @@ class ListActivity implements ListInterface, GroupedExportInterface { $this->helper->buildForm($builder); } + public function getFormDefaultData(): array + { + return []; + } public function getAllowedFormattersTypes() { diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityDuration.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityDuration.php index e916cab54..8adb3b77f 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityDuration.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityDuration.php @@ -40,6 +40,10 @@ class SumActivityDuration implements ExportInterface, GroupedExportInterface { // TODO: Implement buildForm() method. } + public function getFormDefaultData(): array + { + return []; + } public function getAllowedFormattersTypes(): array { diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityVisitDuration.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityVisitDuration.php index 18a47289c..cc424e68b 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityVisitDuration.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityVisitDuration.php @@ -40,6 +40,10 @@ class SumActivityVisitDuration implements ExportInterface, GroupedExportInterfac { // TODO: Implement buildForm() method. } + public function getFormDefaultData(): array + { + return []; + } public function getAllowedFormattersTypes(): array { diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/CountActivity.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/CountActivity.php index 4246df173..6360251b3 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/CountActivity.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/CountActivity.php @@ -35,6 +35,10 @@ class CountActivity implements ExportInterface, GroupedExportInterface public function buildForm(FormBuilderInterface $builder) { } + public function getFormDefaultData(): array + { + return []; + } public function getAllowedFormattersTypes() { diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/ListActivity.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/ListActivity.php index 60110c9a8..d14111ba7 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/ListActivity.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/ListActivity.php @@ -88,6 +88,10 @@ class ListActivity implements ListInterface, GroupedExportInterface ])], ]); } + public function getFormDefaultData(): array + { + return []; + } public function getAllowedFormattersTypes() { diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/StatActivityDuration.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/StatActivityDuration.php index 050034954..e68d47cd3 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/StatActivityDuration.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/StatActivityDuration.php @@ -53,6 +53,10 @@ class StatActivityDuration implements ExportInterface, GroupedExportInterface public function buildForm(FormBuilderInterface $builder) { } + public function getFormDefaultData(): array + { + return []; + } public function getAllowedFormattersTypes() { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/ActivityTypeFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/ActivityTypeFilter.php index c6616a4c6..4ffc3b38c 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/ActivityTypeFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/ActivityTypeFilter.php @@ -68,6 +68,10 @@ class ActivityTypeFilter implements FilterInterface 'expanded' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/ByCreatorFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/ByCreatorFilter.php index 322393f32..add9c7c3d 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/ByCreatorFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/ByCreatorFilter.php @@ -52,6 +52,10 @@ class ByCreatorFilter implements FilterInterface 'multiple' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/BySocialActionFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/BySocialActionFilter.php index d0c1b0fc7..08f6bbbc3 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/BySocialActionFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/BySocialActionFilter.php @@ -60,6 +60,10 @@ class BySocialActionFilter implements FilterInterface 'multiple' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/BySocialIssueFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/BySocialIssueFilter.php index bbb882a65..bd6e2ef4a 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/BySocialIssueFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/BySocialIssueFilter.php @@ -60,6 +60,10 @@ class BySocialIssueFilter implements FilterInterface 'multiple' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/EmergencyFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/EmergencyFilter.php index b79c2ca10..807ba3903 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/EmergencyFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/EmergencyFilter.php @@ -68,9 +68,12 @@ class EmergencyFilter implements FilterInterface 'multiple' => false, 'expanded' => true, 'empty_data' => self::DEFAULT_CHOICE, - 'data' => self::DEFAULT_CHOICE, ]); } + public function getFormDefaultData(): array + { + return ['accepted_emergency' => self::DEFAULT_CHOICE]; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/HasNoActivityFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/HasNoActivityFilter.php index 570f42ae0..b5dab4009 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/HasNoActivityFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/HasNoActivityFilter.php @@ -44,6 +44,10 @@ class HasNoActivityFilter implements FilterInterface { //no form needed } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/LocationFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/LocationFilter.php index 3d69d1633..312f3a6a0 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/LocationFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/LocationFilter.php @@ -46,6 +46,10 @@ class LocationFilter implements FilterInterface 'label' => 'pick location', ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/LocationTypeFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/LocationTypeFilter.php index 5fe928b6c..1c3415460 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/LocationTypeFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/LocationTypeFilter.php @@ -65,6 +65,10 @@ class LocationTypeFilter implements FilterInterface //'label' => false, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/SentReceivedFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/SentReceivedFilter.php index 8daa7a781..0f2a1c7e4 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/SentReceivedFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/SentReceivedFilter.php @@ -69,9 +69,12 @@ class SentReceivedFilter implements FilterInterface 'multiple' => false, 'expanded' => true, 'empty_data' => self::DEFAULT_CHOICE, - 'data' => self::DEFAULT_CHOICE, ]); } + public function getFormDefaultData(): array + { + return ['accepted_sentreceived' => self::DEFAULT_CHOICE]; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/UserFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/UserFilter.php index 6350f3ace..9ae988579 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/UserFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/UserFilter.php @@ -61,6 +61,10 @@ class UserFilter implements FilterInterface 'label' => 'Creators', ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/UserScopeFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/UserScopeFilter.php index 4319c100a..adb1e94f1 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/UserScopeFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/UserScopeFilter.php @@ -71,6 +71,10 @@ class UserScopeFilter implements FilterInterface 'expanded' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ActivityDateFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ActivityDateFilter.php index f2216c929..e582acc12 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ActivityDateFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ActivityDateFilter.php @@ -80,11 +80,9 @@ class ActivityDateFilter implements FilterInterface $builder ->add('date_from', PickRollingDateType::class, [ 'label' => 'Activities after this date', - 'data' => new RollingDate(RollingDate::T_YEAR_PREVIOUS_START), ]) ->add('date_to', PickRollingDateType::class, [ 'label' => 'Activities before this date', - 'data' => new RollingDate(RollingDate::T_TODAY), ]); $builder->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) { @@ -127,6 +125,10 @@ class ActivityDateFilter implements FilterInterface } }); } + public function getFormDefaultData(): array + { + return ['date_from' => new RollingDate(RollingDate::T_YEAR_PREVIOUS_START), 'date_to' => new RollingDate(RollingDate::T_TODAY)]; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ActivityTypeFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ActivityTypeFilter.php index b9d39c3ce..8dfcb543c 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ActivityTypeFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ActivityTypeFilter.php @@ -78,6 +78,10 @@ class ActivityTypeFilter implements ExportElementValidatedInterface, FilterInter ], ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ActivityUsersFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ActivityUsersFilter.php index 2f6cd8462..a63ca2629 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ActivityUsersFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ActivityUsersFilter.php @@ -56,6 +56,10 @@ class ActivityUsersFilter implements FilterInterface 'label' => 'Users', ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/PersonFilters/ActivityReasonFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/PersonFilters/ActivityReasonFilter.php index c55d579e4..31cfde6b6 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/PersonFilters/ActivityReasonFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/PersonFilters/ActivityReasonFilter.php @@ -82,6 +82,10 @@ class ActivityReasonFilter implements ExportElementValidatedInterface, FilterInt 'expanded' => false, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/PersonFilters/PersonHavingActivityBetweenDateFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/PersonFilters/PersonHavingActivityBetweenDateFilter.php index e3c85fe9c..490b5fd0c 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/PersonFilters/PersonHavingActivityBetweenDateFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/PersonFilters/PersonHavingActivityBetweenDateFilter.php @@ -112,7 +112,6 @@ class PersonHavingActivityBetweenDateFilter implements ExportElementValidatedInt { $builder->add('date_from', DateType::class, [ 'label' => 'Implied in an activity after this date', - 'data' => new DateTime(), 'attr' => ['class' => 'datepicker'], 'widget' => 'single_text', 'format' => 'dd-MM-yyyy', @@ -120,7 +119,6 @@ class PersonHavingActivityBetweenDateFilter implements ExportElementValidatedInt $builder->add('date_to', DateType::class, [ 'label' => 'Implied in an activity before this date', - 'data' => new DateTime(), 'attr' => ['class' => 'datepicker'], 'widget' => 'single_text', 'format' => 'dd-MM-yyyy', @@ -130,7 +128,6 @@ class PersonHavingActivityBetweenDateFilter implements ExportElementValidatedInt 'class' => ActivityReason::class, 'choice_label' => fn (ActivityReason $reason): ?string => $this->translatableStringHelper->localize($reason->getName()), 'group_by' => fn (ActivityReason $reason): ?string => $this->translatableStringHelper->localize($reason->getCategory()->getName()), - 'data' => $this->activityReasonRepository->findAll(), 'multiple' => true, 'expanded' => false, 'label' => 'Activity reasons for those activities', @@ -176,6 +173,10 @@ class PersonHavingActivityBetweenDateFilter implements ExportElementValidatedInt } }); } + public function getFormDefaultData(): array + { + return ['date_from' => new DateTime(), 'date_to' => new DateTime(), 'reasons' => $this->activityReasonRepository->findAll()]; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/UsersJobFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/UsersJobFilter.php index b52ef441c..e85b2d247 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/UsersJobFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/UsersJobFilter.php @@ -60,6 +60,10 @@ class UsersJobFilter implements FilterInterface 'expanded' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/UsersScopeFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/UsersScopeFilter.php index 61b12264e..07ff509ce 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/UsersScopeFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/UsersScopeFilter.php @@ -67,6 +67,10 @@ class UsersScopeFilter implements FilterInterface 'expanded' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByActivityTypeAggregator.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByActivityTypeAggregator.php index 32418e3c3..8ae43534d 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByActivityTypeAggregator.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByActivityTypeAggregator.php @@ -50,6 +50,10 @@ class ByActivityTypeAggregator implements AggregatorInterface { // No form needed } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByUserJobAggregator.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByUserJobAggregator.php index d2fe7c2f2..f09a704e2 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByUserJobAggregator.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByUserJobAggregator.php @@ -57,6 +57,10 @@ class ByUserJobAggregator implements AggregatorInterface { // nothing to add in the form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByUserScopeAggregator.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByUserScopeAggregator.php index 6c06ee756..3dd465db2 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByUserScopeAggregator.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByUserScopeAggregator.php @@ -57,6 +57,10 @@ class ByUserScopeAggregator implements AggregatorInterface { // nothing to add in the form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Export/AvgAsideActivityDuration.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Export/AvgAsideActivityDuration.php index f3db629cb..2b28062f6 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Export/AvgAsideActivityDuration.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Export/AvgAsideActivityDuration.php @@ -34,6 +34,10 @@ class AvgAsideActivityDuration implements ExportInterface, GroupedExportInterfac public function buildForm(FormBuilderInterface $builder) { } + public function getFormDefaultData(): array + { + return []; + } public function getAllowedFormattersTypes(): array { diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Export/CountAsideActivity.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Export/CountAsideActivity.php index 9204fad4b..91210f764 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Export/CountAsideActivity.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Export/CountAsideActivity.php @@ -34,6 +34,10 @@ class CountAsideActivity implements ExportInterface, GroupedExportInterface public function buildForm(FormBuilderInterface $builder) { } + public function getFormDefaultData(): array + { + return []; + } public function getAllowedFormattersTypes(): array { diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Export/ListAsideActivity.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Export/ListAsideActivity.php index aee168174..b46e120b5 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Export/ListAsideActivity.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Export/ListAsideActivity.php @@ -73,6 +73,10 @@ final class ListAsideActivity implements ListInterface, GroupedExportInterface public function buildForm(FormBuilderInterface $builder) { } + public function getFormDefaultData(): array + { + return []; + } public function getAllowedFormattersTypes() { diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Export/SumAsideActivityDuration.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Export/SumAsideActivityDuration.php index af17a2591..741f129f1 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Export/SumAsideActivityDuration.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Export/SumAsideActivityDuration.php @@ -34,6 +34,10 @@ class SumAsideActivityDuration implements ExportInterface, GroupedExportInterfac public function buildForm(FormBuilderInterface $builder) { } + public function getFormDefaultData(): array + { + return []; + } public function getAllowedFormattersTypes(): array { diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByActivityTypeFilter.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByActivityTypeFilter.php index 3ad8e0e93..3d389f5b3 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByActivityTypeFilter.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByActivityTypeFilter.php @@ -76,6 +76,10 @@ class ByActivityTypeFilter implements FilterInterface }, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByDateFilter.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByDateFilter.php index 7a1b6f4dc..98a254bc4 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByDateFilter.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByDateFilter.php @@ -72,11 +72,9 @@ class ByDateFilter implements FilterInterface $builder ->add('date_from', PickRollingDateType::class, [ 'label' => 'export.filter.Aside activities after this date', - 'data' => new RollingDate(RollingDate::T_YEAR_PREVIOUS_START), ]) ->add('date_to', PickRollingDateType::class, [ 'label' => 'export.filter.Aside activities before this date', - 'data' => new RollingDate(RollingDate::T_TODAY), ]); $builder->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) { @@ -119,6 +117,10 @@ class ByDateFilter implements FilterInterface } }); } + public function getFormDefaultData(): array + { + return ['date_from' => new RollingDate(RollingDate::T_YEAR_PREVIOUS_START), 'date_to' => new RollingDate(RollingDate::T_TODAY)]; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserFilter.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserFilter.php index 795c813cd..2858d3417 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserFilter.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserFilter.php @@ -53,6 +53,10 @@ class ByUserFilter implements FilterInterface 'label' => 'Creators', ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserJobFilter.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserJobFilter.php index 86194b123..55f477768 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserJobFilter.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserJobFilter.php @@ -60,6 +60,10 @@ class ByUserJobFilter implements FilterInterface 'expanded' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserScopeFilter.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserScopeFilter.php index 4342e11eb..8fa51866d 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserScopeFilter.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserScopeFilter.php @@ -67,6 +67,10 @@ class ByUserScopeFilter implements FilterInterface 'expanded' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/AgentAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/AgentAggregator.php index e1de9f399..1b1b170b8 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/AgentAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/AgentAggregator.php @@ -58,6 +58,10 @@ final class AgentAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data): Closure { diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/CancelReasonAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/CancelReasonAggregator.php index 611cb6d79..a9967c470 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/CancelReasonAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/CancelReasonAggregator.php @@ -59,6 +59,10 @@ class CancelReasonAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data): Closure { diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/JobAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/JobAggregator.php index 23292a5b0..51291b49e 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/JobAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/JobAggregator.php @@ -58,6 +58,10 @@ final class JobAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data): Closure { diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationAggregator.php index 940000f47..952d0c5d5 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationAggregator.php @@ -52,6 +52,10 @@ final class LocationAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data): Closure { diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationTypeAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationTypeAggregator.php index 6574e3934..a9b369af0 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationTypeAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationTypeAggregator.php @@ -58,6 +58,10 @@ final class LocationTypeAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data): Closure { diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/MonthYearAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/MonthYearAggregator.php index 7b2a5e898..b3c2aaf19 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/MonthYearAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/MonthYearAggregator.php @@ -40,6 +40,10 @@ class MonthYearAggregator implements AggregatorInterface { // No form needed } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data): Closure { diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/ScopeAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/ScopeAggregator.php index 3aff3e0d8..01874b0e2 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/ScopeAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/ScopeAggregator.php @@ -58,6 +58,10 @@ final class ScopeAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data): Closure { diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/UrgencyAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/UrgencyAggregator.php index ad5910461..66ab8b42e 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/UrgencyAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/UrgencyAggregator.php @@ -56,6 +56,10 @@ class UrgencyAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data): Closure { diff --git a/src/Bundle/ChillCalendarBundle/Export/Export/CountCalendars.php b/src/Bundle/ChillCalendarBundle/Export/Export/CountCalendars.php index 9d3f00f99..e0391948e 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Export/CountCalendars.php +++ b/src/Bundle/ChillCalendarBundle/Export/Export/CountCalendars.php @@ -36,6 +36,10 @@ class CountCalendars implements ExportInterface, GroupedExportInterface { // No form necessary } + public function getFormDefaultData(): array + { + return []; + } public function getAllowedFormattersTypes(): array { diff --git a/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarAvgDuration.php b/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarAvgDuration.php index 14dd42d6b..dcbfb695b 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarAvgDuration.php +++ b/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarAvgDuration.php @@ -36,6 +36,10 @@ class StatCalendarAvgDuration implements ExportInterface, GroupedExportInterface { // no form needed } + public function getFormDefaultData(): array + { + return []; + } public function getAllowedFormattersTypes(): array { diff --git a/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarSumDuration.php b/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarSumDuration.php index 1d31bfa26..7f509a896 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarSumDuration.php +++ b/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarSumDuration.php @@ -36,6 +36,10 @@ class StatCalendarSumDuration implements ExportInterface, GroupedExportInterface { // no form needed } + public function getFormDefaultData(): array + { + return []; + } public function getAllowedFormattersTypes(): array { diff --git a/src/Bundle/ChillCalendarBundle/Export/Filter/AgentFilter.php b/src/Bundle/ChillCalendarBundle/Export/Filter/AgentFilter.php index b58cee594..0cef89c20 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Filter/AgentFilter.php +++ b/src/Bundle/ChillCalendarBundle/Export/Filter/AgentFilter.php @@ -63,6 +63,10 @@ class AgentFilter implements FilterInterface 'expanded' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillCalendarBundle/Export/Filter/BetweenDatesFilter.php b/src/Bundle/ChillCalendarBundle/Export/Filter/BetweenDatesFilter.php index 59019ac03..4260ecd99 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Filter/BetweenDatesFilter.php +++ b/src/Bundle/ChillCalendarBundle/Export/Filter/BetweenDatesFilter.php @@ -60,12 +60,12 @@ class BetweenDatesFilter implements FilterInterface public function buildForm(FormBuilderInterface $builder) { $builder - ->add('date_from', PickRollingDateType::class, [ - 'data' => new RollingDate(RollingDate::T_YEAR_PREVIOUS_START), - ]) - ->add('date_to', PickRollingDateType::class, [ - 'data' => new RollingDate(RollingDate::T_TODAY), - ]); + ->add('date_from', PickRollingDateType::class, []) + ->add('date_to', PickRollingDateType::class, []); + } + public function getFormDefaultData(): array + { + return ['date_from' => new RollingDate(RollingDate::T_YEAR_PREVIOUS_START), 'date_to' => new RollingDate(RollingDate::T_TODAY)]; } public function describeAction($data, $format = 'string'): array diff --git a/src/Bundle/ChillCalendarBundle/Export/Filter/CalendarRangeFilter.php b/src/Bundle/ChillCalendarBundle/Export/Filter/CalendarRangeFilter.php index d6c38e163..5ffb7c01f 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Filter/CalendarRangeFilter.php +++ b/src/Bundle/ChillCalendarBundle/Export/Filter/CalendarRangeFilter.php @@ -69,9 +69,12 @@ class CalendarRangeFilter implements FilterInterface 'multiple' => false, 'expanded' => true, 'empty_data' => self::DEFAULT_CHOICE, - 'data' => self::DEFAULT_CHOICE, ]); } + public function getFormDefaultData(): array + { + return ['hasCalendarRange' => self::DEFAULT_CHOICE]; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillCalendarBundle/Export/Filter/JobFilter.php b/src/Bundle/ChillCalendarBundle/Export/Filter/JobFilter.php index 69fb24447..d02bb8e9d 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Filter/JobFilter.php +++ b/src/Bundle/ChillCalendarBundle/Export/Filter/JobFilter.php @@ -76,6 +76,10 @@ class JobFilter implements FilterInterface 'expanded' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillCalendarBundle/Export/Filter/ScopeFilter.php b/src/Bundle/ChillCalendarBundle/Export/Filter/ScopeFilter.php index 08d9ae023..d8a40da72 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Filter/ScopeFilter.php +++ b/src/Bundle/ChillCalendarBundle/Export/Filter/ScopeFilter.php @@ -76,6 +76,10 @@ class ScopeFilter implements FilterInterface 'expanded' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillMainBundle/Export/Formatter/CSVListFormatter.php b/src/Bundle/ChillMainBundle/Export/Formatter/CSVListFormatter.php index b84c80118..d11aea068 100644 --- a/src/Bundle/ChillMainBundle/Export/Formatter/CSVListFormatter.php +++ b/src/Bundle/ChillMainBundle/Export/Formatter/CSVListFormatter.php @@ -85,10 +85,14 @@ class CSVListFormatter implements FormatterInterface 'expanded' => true, 'multiple' => false, 'label' => 'Add a number on first column', - 'data' => true, ]); } + public function getFormDefaultData(array $aggregatorAliases): array + { + return ['numerotation' => true]; + } + public function getName() { return 'CSV vertical list'; diff --git a/src/Bundle/ChillMainBundle/Export/Formatter/CSVPivotedListFormatter.php b/src/Bundle/ChillMainBundle/Export/Formatter/CSVPivotedListFormatter.php index 63d691443..ae4d3629f 100644 --- a/src/Bundle/ChillMainBundle/Export/Formatter/CSVPivotedListFormatter.php +++ b/src/Bundle/ChillMainBundle/Export/Formatter/CSVPivotedListFormatter.php @@ -84,6 +84,11 @@ class CSVPivotedListFormatter implements FormatterInterface ]); } + public function getFormDefaultData(array $aggregatorAliases): array + { + return ['numerotation' => true]; + } + public function getName() { return 'CSV horizontal list'; diff --git a/src/Bundle/ChillMainBundle/Export/Formatter/SpreadsheetListFormatter.php b/src/Bundle/ChillMainBundle/Export/Formatter/SpreadsheetListFormatter.php index 0e5e339ea..b82ab8f61 100644 --- a/src/Bundle/ChillMainBundle/Export/Formatter/SpreadsheetListFormatter.php +++ b/src/Bundle/ChillMainBundle/Export/Formatter/SpreadsheetListFormatter.php @@ -104,10 +104,14 @@ class SpreadsheetListFormatter implements FormatterInterface 'expanded' => true, 'multiple' => false, 'label' => 'Add a number on first column', - 'data' => true, ]); } + public function getFormDefaultData(array $aggregatorAliases): array + { + return ['numerotation' => true, 'format' => 'xlsx']; + } + public function getName() { return 'Spreadsheet list formatter (.xlsx, .ods)'; diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/AdministrativeLocationAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/AdministrativeLocationAggregator.php index 96deac574..56fdc07d7 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/AdministrativeLocationAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/AdministrativeLocationAggregator.php @@ -57,6 +57,10 @@ class AdministrativeLocationAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ByActionNumberAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ByActionNumberAggregator.php index 2dffccbbb..104b934ca 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ByActionNumberAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ByActionNumberAggregator.php @@ -39,6 +39,10 @@ class ByActionNumberAggregator implements AggregatorInterface { // No form needed } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ClosingMotiveAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ClosingMotiveAggregator.php index 342958361..73cfdc7b9 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ClosingMotiveAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ClosingMotiveAggregator.php @@ -52,6 +52,10 @@ class ClosingMotiveAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ConfidentialAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ConfidentialAggregator.php index e9b9e28fa..4ad18030e 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ConfidentialAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ConfidentialAggregator.php @@ -48,6 +48,10 @@ class ConfidentialAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/CreatorJobAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/CreatorJobAggregator.php index c336a8887..5a060bcd7 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/CreatorJobAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/CreatorJobAggregator.php @@ -57,6 +57,10 @@ class CreatorJobAggregator implements AggregatorInterface { // No form needed } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/DurationAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/DurationAggregator.php index 0dc66e81e..581c7d6e5 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/DurationAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/DurationAggregator.php @@ -84,6 +84,10 @@ final class DurationAggregator implements AggregatorInterface 'expanded' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/EmergencyAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/EmergencyAggregator.php index 02f9f5cd9..4429c7b62 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/EmergencyAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/EmergencyAggregator.php @@ -48,6 +48,10 @@ class EmergencyAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/EvaluationAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/EvaluationAggregator.php index b6436efc0..119fa50b7 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/EvaluationAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/EvaluationAggregator.php @@ -61,6 +61,10 @@ final class EvaluationAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/GeographicalUnitStatAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/GeographicalUnitStatAggregator.php index d001cbef7..a83634830 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/GeographicalUnitStatAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/GeographicalUnitStatAggregator.php @@ -121,7 +121,6 @@ final class GeographicalUnitStatAggregator implements AggregatorInterface ->add('date_calc', PickRollingDateType::class, [ 'label' => 'Compute geographical location at date', 'required' => true, - 'data' => new RollingDate(RollingDate::T_TODAY), ]) ->add('level', EntityType::class, [ 'label' => 'Geographical layer', @@ -133,6 +132,10 @@ final class GeographicalUnitStatAggregator implements AggregatorInterface 'expanded' => true, ]); } + public function getFormDefaultData(): array + { + return ['date_calc' => new RollingDate(RollingDate::T_TODAY)]; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/IntensityAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/IntensityAggregator.php index a3618f40f..ac55d7734 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/IntensityAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/IntensityAggregator.php @@ -48,6 +48,10 @@ class IntensityAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/OriginAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/OriginAggregator.php index 37d0c7b20..1d01920d5 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/OriginAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/OriginAggregator.php @@ -59,6 +59,10 @@ final class OriginAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ReferrerAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ReferrerAggregator.php index a09097fd2..7b826600a 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ReferrerAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ReferrerAggregator.php @@ -81,11 +81,14 @@ final class ReferrerAggregator implements AggregatorInterface { $builder ->add('date_calc', PickRollingDateType::class, [ - 'data' => new RollingDate(RollingDate::T_TODAY), 'label' => 'export.aggregator.course.by_referrer.Computation date for referrer', 'required' => true, ]); } + public function getFormDefaultData(): array + { + return ['date_calc' => new RollingDate(RollingDate::T_TODAY)]; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ReferrerScopeAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ReferrerScopeAggregator.php index ccbd21da1..adfd9b489 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ReferrerScopeAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ReferrerScopeAggregator.php @@ -88,11 +88,14 @@ class ReferrerScopeAggregator implements AggregatorInterface public function buildForm(FormBuilderInterface $builder) { $builder->add('date_calc', PickRollingDateType::class, [ - 'data' => new RollingDate(RollingDate::T_TODAY), 'label' => 'export.aggregator.course.by_user_scope.Computation date for referrer', 'required' => true, ]); } + public function getFormDefaultData(): array + { + return ['date_calc' => new RollingDate(RollingDate::T_TODAY)]; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/RequestorAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/RequestorAggregator.php index 7b5cf0edd..3baf9bd33 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/RequestorAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/RequestorAggregator.php @@ -69,6 +69,10 @@ final class RequestorAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ScopeAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ScopeAggregator.php index 8f34661bb..253727c89 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ScopeAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ScopeAggregator.php @@ -57,6 +57,10 @@ final class ScopeAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/SocialActionAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/SocialActionAggregator.php index 3bdd6549e..b82b47ad0 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/SocialActionAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/SocialActionAggregator.php @@ -58,6 +58,10 @@ final class SocialActionAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/SocialIssueAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/SocialIssueAggregator.php index 12fa5a454..29fcba4a2 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/SocialIssueAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/SocialIssueAggregator.php @@ -58,6 +58,10 @@ final class SocialIssueAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/StepAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/StepAggregator.php index 85cfc3190..7632f72f0 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/StepAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/StepAggregator.php @@ -76,9 +76,11 @@ final class StepAggregator implements AggregatorInterface public function buildForm(FormBuilderInterface $builder) { - $builder->add('on_date', PickRollingDateType::class, [ - 'data' => new RollingDate(RollingDate::T_TODAY), - ]); + $builder->add('on_date', PickRollingDateType::class, []); + } + public function getFormDefaultData(): array + { + return ['on_date' => new RollingDate(RollingDate::T_TODAY)]; } public function getLabels($key, array $values, $data) diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/UserJobAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/UserJobAggregator.php index a8acdcf12..13d1e3f83 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/UserJobAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/UserJobAggregator.php @@ -57,6 +57,10 @@ final class UserJobAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/ByEndDateAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/ByEndDateAggregator.php index 2f4275c49..cb66fa600 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/ByEndDateAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/ByEndDateAggregator.php @@ -75,9 +75,12 @@ class ByEndDateAggregator implements AggregatorInterface 'multiple' => false, 'expanded' => true, 'empty_data' => self::DEFAULT_CHOICE, - 'data' => self::DEFAULT_CHOICE, ]); } + public function getFormDefaultData(): array + { + return ['frequency' => self::DEFAULT_CHOICE]; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/ByMaxDateAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/ByMaxDateAggregator.php index 9283fd9dc..af6dfc465 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/ByMaxDateAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/ByMaxDateAggregator.php @@ -75,9 +75,12 @@ class ByMaxDateAggregator implements AggregatorInterface 'multiple' => false, 'expanded' => true, 'empty_data' => self::DEFAULT_CHOICE, - 'data' => self::DEFAULT_CHOICE, ]); } + public function getFormDefaultData(): array + { + return ['frequency' => self::DEFAULT_CHOICE]; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/ByStartDateAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/ByStartDateAggregator.php index cd183b25e..87a6a672b 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/ByStartDateAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/ByStartDateAggregator.php @@ -75,9 +75,12 @@ class ByStartDateAggregator implements AggregatorInterface 'multiple' => false, 'expanded' => true, 'empty_data' => self::DEFAULT_CHOICE, - 'data' => self::DEFAULT_CHOICE, ]); } + public function getFormDefaultData(): array + { + return ['frequency' => self::DEFAULT_CHOICE]; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/EvaluationTypeAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/EvaluationTypeAggregator.php index 0c13611cb..a48ed763d 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/EvaluationTypeAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/EvaluationTypeAggregator.php @@ -52,6 +52,10 @@ class EvaluationTypeAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/HavingEndDateAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/HavingEndDateAggregator.php index e33bb326f..e710949fd 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/HavingEndDateAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/HavingEndDateAggregator.php @@ -48,6 +48,10 @@ class HavingEndDateAggregator implements AggregatorInterface { // No form needed } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/HouseholdAggregators/ChildrenNumberAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/HouseholdAggregators/ChildrenNumberAggregator.php index 0c9bc623f..1c5b3dc2c 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/HouseholdAggregators/ChildrenNumberAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/HouseholdAggregators/ChildrenNumberAggregator.php @@ -72,9 +72,11 @@ class ChildrenNumberAggregator implements AggregatorInterface public function buildForm(FormBuilderInterface $builder) { - $builder->add('on_date', PickRollingDateType::class, [ - 'data' => new RollingDate(RollingDate::T_TODAY), - ]); + $builder->add('on_date', PickRollingDateType::class, []); + } + public function getFormDefaultData(): array + { + return ['on_date' => new RollingDate(RollingDate::T_TODAY)]; } public function getLabels($key, array $values, $data) diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/HouseholdAggregators/CompositionAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/HouseholdAggregators/CompositionAggregator.php index 52bcd88e5..62fc20173 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/HouseholdAggregators/CompositionAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/HouseholdAggregators/CompositionAggregator.php @@ -77,9 +77,11 @@ class CompositionAggregator implements AggregatorInterface public function buildForm(FormBuilderInterface $builder) { - $builder->add('on_date', PickRollingDateType::class, [ - 'data' => new RollingDate(RollingDate::T_TODAY), - ]); + $builder->add('on_date', PickRollingDateType::class, []); + } + public function getFormDefaultData(): array + { + return ['on_date' => new RollingDate(RollingDate::T_TODAY)]; } public function getLabels($key, array $values, $data) diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/AgeAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/AgeAggregator.php index 365a73704..2a63e475a 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/AgeAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/AgeAggregator.php @@ -50,12 +50,15 @@ final class AgeAggregator implements AggregatorInterface, ExportElementValidated { $builder->add('date_age_calculation', DateType::class, [ 'label' => 'Calculate age in relation to this date', - 'data' => new DateTime(), 'attr' => ['class' => 'datepicker'], 'widget' => 'single_text', 'format' => 'dd-MM-yyyy', ]); } + public function getFormDefaultData(): array + { + return ['date_age_calculation' => new DateTime()]; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/ByHouseholdCompositionAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/ByHouseholdCompositionAggregator.php index 80f0faa17..16b62c2b5 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/ByHouseholdCompositionAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/ByHouseholdCompositionAggregator.php @@ -94,9 +94,12 @@ class ByHouseholdCompositionAggregator implements AggregatorInterface { $builder->add('date_calc', PickRollingDateType::class, [ 'label' => 'export.aggregator.person.by_household_composition.Calc date', - 'data' => new RollingDate(RollingDate::T_TODAY), ]); } + public function getFormDefaultData(): array + { + return ['date_calc' => new RollingDate(RollingDate::T_TODAY)]; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/CountryOfBirthAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/CountryOfBirthAggregator.php index 3d785b586..90882245e 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/CountryOfBirthAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/CountryOfBirthAggregator.php @@ -108,6 +108,10 @@ final class CountryOfBirthAggregator implements AggregatorInterface, ExportEleme 'multiple' => false, ]); } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/GenderAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/GenderAggregator.php index f76420047..dbe3d19d3 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/GenderAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/GenderAggregator.php @@ -48,6 +48,10 @@ final class GenderAggregator implements AggregatorInterface public function buildForm(FormBuilderInterface $builder) { } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/GeographicalUnitAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/GeographicalUnitAggregator.php index 5d73c1fdd..a72d91db2 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/GeographicalUnitAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/GeographicalUnitAggregator.php @@ -93,7 +93,6 @@ class GeographicalUnitAggregator implements AggregatorInterface ->add('date_calc', PickRollingDateType::class, [ 'label' => 'Address valid at this date', 'required' => true, - 'data' => new RollingDate(RollingDate::T_TODAY), ]) ->add('level', EntityType::class, [ 'label' => 'Geographical layer', @@ -105,6 +104,10 @@ class GeographicalUnitAggregator implements AggregatorInterface 'expanded' => true, ]); } + public function getFormDefaultData(): array + { + return ['date_calc' => new RollingDate(RollingDate::T_TODAY)]; + } public static function getDefaultAlias(): string { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/HouseholdPositionAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/HouseholdPositionAggregator.php index 107634803..63d84d4da 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/HouseholdPositionAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/HouseholdPositionAggregator.php @@ -90,9 +90,12 @@ final class HouseholdPositionAggregator implements AggregatorInterface, ExportEl { $builder->add('date_position', PickRollingDateType::class, [ 'label' => 'Household position in relation to this date', - 'data' => new RollingDate(RollingDate::T_TODAY), ]); } + public function getFormDefaultData(): array + { + return ['date_position' => new RollingDate(RollingDate::T_TODAY)]; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ActionTypeAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ActionTypeAggregator.php index c1fccb968..66c87d94f 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ActionTypeAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ActionTypeAggregator.php @@ -75,6 +75,10 @@ final class ActionTypeAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/CurrentActionAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/CurrentActionAggregator.php index 58fcb2874..539c9f286 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/CurrentActionAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/CurrentActionAggregator.php @@ -51,6 +51,10 @@ class CurrentActionAggregator implements AggregatorInterface { // No form needed } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/GoalAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/GoalAggregator.php index 8cc6a25da..4c0e8b393 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/GoalAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/GoalAggregator.php @@ -55,6 +55,10 @@ final class GoalAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/GoalResultAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/GoalResultAggregator.php index 17b263d7e..c99ee85ea 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/GoalResultAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/GoalResultAggregator.php @@ -68,6 +68,10 @@ class GoalResultAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/JobAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/JobAggregator.php index cbf07091f..8271c90e3 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/JobAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/JobAggregator.php @@ -57,6 +57,10 @@ final class JobAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ReferrerAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ReferrerAggregator.php index 0fe53b707..047504224 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ReferrerAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ReferrerAggregator.php @@ -57,6 +57,10 @@ final class ReferrerAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ResultAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ResultAggregator.php index 2e46673da..3cce7b283 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ResultAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ResultAggregator.php @@ -55,6 +55,10 @@ final class ResultAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ScopeAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ScopeAggregator.php index 243263b83..0828b5d0d 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ScopeAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ScopeAggregator.php @@ -57,6 +57,10 @@ final class ScopeAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function getLabels($key, array $values, $data) { diff --git a/src/Bundle/ChillPersonBundle/Export/Export/CountAccompanyingCourse.php b/src/Bundle/ChillPersonBundle/Export/Export/CountAccompanyingCourse.php index 978f88a10..75583dfa0 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/CountAccompanyingCourse.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/CountAccompanyingCourse.php @@ -39,6 +39,10 @@ class CountAccompanyingCourse implements ExportInterface, GroupedExportInterface { // Nothing to add here } + public function getFormDefaultData(): array + { + return []; + } public function getAllowedFormattersTypes(): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Export/CountAccompanyingPeriodWork.php b/src/Bundle/ChillPersonBundle/Export/Export/CountAccompanyingPeriodWork.php index 122ee14d9..8a035bdcd 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/CountAccompanyingPeriodWork.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/CountAccompanyingPeriodWork.php @@ -38,6 +38,10 @@ class CountAccompanyingPeriodWork implements ExportInterface, GroupedExportInter { // No form necessary? } + public function getFormDefaultData(): array + { + return []; + } public function getAllowedFormattersTypes(): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Export/CountEvaluation.php b/src/Bundle/ChillPersonBundle/Export/Export/CountEvaluation.php index 1613b63d3..3de433e2e 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/CountEvaluation.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/CountEvaluation.php @@ -37,6 +37,10 @@ class CountEvaluation implements ExportInterface, GroupedExportInterface { // TODO: Implement buildForm() method. } + public function getFormDefaultData(): array + { + return []; + } public function getAllowedFormattersTypes(): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Export/CountHousehold.php b/src/Bundle/ChillPersonBundle/Export/Export/CountHousehold.php index 0b693b9d8..05e32fde6 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/CountHousehold.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/CountHousehold.php @@ -46,11 +46,14 @@ class CountHousehold implements ExportInterface, GroupedExportInterface { $builder ->add('calc_date', PickRollingDateType::class, [ - 'data' => new RollingDate(RollingDate::T_TODAY), 'label' => self::TR_PREFIX . 'Date of calculation of household members', 'required' => false, ]); } + public function getFormDefaultData(): array + { + return ['calc_date' => new RollingDate(RollingDate::T_TODAY)]; + } public function getAllowedFormattersTypes(): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Export/CountPersonWithAccompanyingCourse.php b/src/Bundle/ChillPersonBundle/Export/Export/CountPersonWithAccompanyingCourse.php index e52cc83b1..ae7238d4e 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/CountPersonWithAccompanyingCourse.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/CountPersonWithAccompanyingCourse.php @@ -39,6 +39,10 @@ class CountPersonWithAccompanyingCourse implements ExportInterface, GroupedExpor { // TODO: Implement buildForm() method. } + public function getFormDefaultData(): array + { + return []; + } public function getAllowedFormattersTypes(): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriod.php b/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriod.php index 0647460dd..e5e724b6c 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriod.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriod.php @@ -144,6 +144,10 @@ class ListAccompanyingPeriod implements ListInterface, GroupedExportInterface 'required' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function getAllowedFormattersTypes() { diff --git a/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriodWork.php b/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriodWork.php index 00fa8adb1..c437454c2 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriodWork.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriodWork.php @@ -135,9 +135,12 @@ class ListAccompanyingPeriodWork implements ListInterface, GroupedExportInterfac 'label' => 'export.list.acpw.Date of calculation for associated elements', 'help' => 'export.list.acpw.help_description', 'required' => true, - 'data' => new RollingDate(RollingDate::T_TODAY), ]); } + public function getFormDefaultData(): array + { + return ['calc_date' => new RollingDate(RollingDate::T_TODAY)]; + } public function getAllowedFormattersTypes() { diff --git a/src/Bundle/ChillPersonBundle/Export/Export/ListEvaluation.php b/src/Bundle/ChillPersonBundle/Export/Export/ListEvaluation.php index f0985436b..c3e273733 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/ListEvaluation.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/ListEvaluation.php @@ -123,9 +123,12 @@ class ListEvaluation implements ListInterface, GroupedExportInterface 'label' => 'export.list.eval.Date of calculation for associated elements', 'help' => 'export.list.eval.help_description', 'required' => true, - 'data' => new RollingDate(RollingDate::T_TODAY), ]); } + public function getFormDefaultData(): array + { + return ['calc_date' => new RollingDate(RollingDate::T_TODAY)]; + } public function getAllowedFormattersTypes() { diff --git a/src/Bundle/ChillPersonBundle/Export/Export/ListHouseholdInPeriod.php b/src/Bundle/ChillPersonBundle/Export/Export/ListHouseholdInPeriod.php index 8894d145d..4dcc89495 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/ListHouseholdInPeriod.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/ListHouseholdInPeriod.php @@ -75,10 +75,13 @@ class ListHouseholdInPeriod implements ListInterface, GroupedExportInterface ->add('calc_date', PickRollingDateType::class, [ 'label' => 'export.list.household.Date of calculation for associated elements', 'help' => 'export.list.household.help_description', - 'data' => new RollingDate(RollingDate::T_TODAY), 'required' => true, ]); } + public function getFormDefaultData(): array + { + return ['calc_date' => new RollingDate(RollingDate::T_TODAY)]; + } public function getAllowedFormattersTypes() { diff --git a/src/Bundle/ChillPersonBundle/Export/Export/ListPersonDuplicate.php b/src/Bundle/ChillPersonBundle/Export/Export/ListPersonDuplicate.php index e40ffccce..e7c105604 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/ListPersonDuplicate.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/ListPersonDuplicate.php @@ -74,9 +74,12 @@ class ListPersonDuplicate implements DirectExportInterface, ExportElementValidat { $builder->add('precision', NumberType::class, [ 'label' => 'Precision', - 'data' => self::PRECISION_DEFAULT_VALUE, ]); } + public function getFormDefaultData(): array + { + return ['precision' => self::PRECISION_DEFAULT_VALUE]; + } public function generate(array $acl, array $data = []): Response { diff --git a/src/Bundle/ChillPersonBundle/Export/Export/ListPersonWithAccompanyingPeriod.php b/src/Bundle/ChillPersonBundle/Export/Export/ListPersonWithAccompanyingPeriod.php index 7cb066e87..370046232 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/ListPersonWithAccompanyingPeriod.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/ListPersonWithAccompanyingPeriod.php @@ -57,7 +57,6 @@ class ListPersonWithAccompanyingPeriod implements ExportElementValidatedInterfac { $choices = array_combine(ListPersonHelper::FIELDS, ListPersonHelper::FIELDS); - // Add a checkbox to select fields $builder->add('fields', ChoiceType::class, [ 'multiple' => true, 'expanded' => true, @@ -80,17 +79,20 @@ class ListPersonWithAccompanyingPeriod implements ExportElementValidatedInterfac } }, ])], - 'data' => array_values($choices), ]); - // add a date field for addresses $builder->add('address_date', ChillDateType::class, [ 'label' => 'Data valid at this date', 'help' => 'Data regarding center, addresses, and so on will be computed at this date', - 'data' => new DateTimeImmutable(), 'input' => 'datetime_immutable', ]); } + public function getFormDefaultData(): array + { + $choices = array_combine(ListPersonHelper::FIELDS, ListPersonHelper::FIELDS); + + return ['fields' => array_values($choices), 'address_date' => new DateTimeImmutable()]; + } public function getAllowedFormattersTypes() { diff --git a/src/Bundle/ChillPersonBundle/Export/Export/StatAccompanyingCourseDuration.php b/src/Bundle/ChillPersonBundle/Export/Export/StatAccompanyingCourseDuration.php index 31ca41cbb..66b47131d 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/StatAccompanyingCourseDuration.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/StatAccompanyingCourseDuration.php @@ -41,9 +41,12 @@ class StatAccompanyingCourseDuration implements ExportInterface, GroupedExportIn { $builder->add('closingdate', ChillDateType::class, [ 'label' => 'Closingdate to apply', - 'data' => new DateTime('now'), ]); } + public function getFormDefaultData(): array + { + return ['closingdate' => new DateTime('now')]; + } public function getAllowedFormattersTypes(): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ActiveOnDateFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ActiveOnDateFilter.php index 3fa8d711f..fcb4d67fb 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ActiveOnDateFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ActiveOnDateFilter.php @@ -67,9 +67,11 @@ class ActiveOnDateFilter implements FilterInterface public function buildForm(FormBuilderInterface $builder) { $builder - ->add('on_date', PickRollingDateType::class, [ - 'data' => new RollingDate(RollingDate::T_TODAY), - ]); + ->add('on_date', PickRollingDateType::class, []); + } + public function getFormDefaultData(): array + { + return ['on_date' => new RollingDate(RollingDate::T_TODAY)]; } public function describeAction($data, $format = 'string'): array diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ActiveOneDayBetweenDatesFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ActiveOneDayBetweenDatesFilter.php index f713e8a97..ae21dc724 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ActiveOneDayBetweenDatesFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ActiveOneDayBetweenDatesFilter.php @@ -56,12 +56,12 @@ class ActiveOneDayBetweenDatesFilter implements FilterInterface public function buildForm(FormBuilderInterface $builder) { $builder - ->add('date_from', PickRollingDateType::class, [ - 'data' => new RollingDate(RollingDate::T_YEAR_PREVIOUS_START), - ]) - ->add('date_to', PickRollingDateType::class, [ - 'data' => new RollingDate(RollingDate::T_TODAY), - ]); + ->add('date_from', PickRollingDateType::class, []) + ->add('date_to', PickRollingDateType::class, []); + } + public function getFormDefaultData(): array + { + return ['date_from' => new RollingDate(RollingDate::T_YEAR_PREVIOUS_START), 'date_to' => new RollingDate(RollingDate::T_TODAY)]; } public function describeAction($data, $format = 'string'): array diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/AdministrativeLocationFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/AdministrativeLocationFilter.php index c74e309b2..aa1abb36e 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/AdministrativeLocationFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/AdministrativeLocationFilter.php @@ -53,6 +53,10 @@ class AdministrativeLocationFilter implements FilterInterface 'multiple' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ClosingMotiveFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ClosingMotiveFilter.php index e57370f30..153b2ecbd 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ClosingMotiveFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ClosingMotiveFilter.php @@ -64,6 +64,10 @@ class ClosingMotiveFilter implements FilterInterface 'expanded' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ConfidentialFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ConfidentialFilter.php index 4be284b2d..8811b9930 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ConfidentialFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ConfidentialFilter.php @@ -22,8 +22,8 @@ use Symfony\Contracts\Translation\TranslatorInterface; class ConfidentialFilter implements FilterInterface { private const CHOICES = [ - 'is not confidential' => false, - 'is confidential' => true, + 'is not confidential' => 'false', + 'is confidential' => 'true', ]; private const DEFAULT_CHOICE = 'false'; @@ -67,9 +67,12 @@ class ConfidentialFilter implements FilterInterface 'multiple' => false, 'expanded' => true, 'empty_data' => self::DEFAULT_CHOICE, - 'data' => self::DEFAULT_CHOICE, ]); } + public function getFormDefaultData(): array + { + return ['accepted_confidentials' => self::DEFAULT_CHOICE]; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/CreatorFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/CreatorFilter.php index b13947e60..8a8a24013 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/CreatorFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/CreatorFilter.php @@ -50,6 +50,10 @@ class CreatorFilter implements FilterInterface 'label' => false, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/CreatorJobFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/CreatorJobFilter.php index f585cfafb..5faeb850f 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/CreatorJobFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/CreatorJobFilter.php @@ -69,6 +69,10 @@ class CreatorJobFilter implements FilterInterface 'label' => 'Job', ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/EmergencyFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/EmergencyFilter.php index d31b93bd4..f9d45c9d7 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/EmergencyFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/EmergencyFilter.php @@ -22,8 +22,8 @@ use Symfony\Contracts\Translation\TranslatorInterface; class EmergencyFilter implements FilterInterface { private const CHOICES = [ - 'is emergency' => true, - 'is not emergency' => false, + 'is emergency' => 'true', + 'is not emergency' => 'false', ]; private const DEFAULT_CHOICE = 'false'; @@ -67,9 +67,12 @@ class EmergencyFilter implements FilterInterface 'multiple' => false, 'expanded' => true, 'empty_data' => self::DEFAULT_CHOICE, - 'data' => self::DEFAULT_CHOICE, ]); } + public function getFormDefaultData(): array + { + return ['accepted_emergency' => self::DEFAULT_CHOICE]; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/EvaluationFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/EvaluationFilter.php index ab7f4257e..a6fb3583d 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/EvaluationFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/EvaluationFilter.php @@ -75,6 +75,10 @@ class EvaluationFilter implements FilterInterface 'attr' => ['class' => 'select2'], ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/GeographicalUnitStatFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/GeographicalUnitStatFilter.php index d35565c80..a20cfc08f 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/GeographicalUnitStatFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/GeographicalUnitStatFilter.php @@ -100,7 +100,6 @@ class GeographicalUnitStatFilter implements FilterInterface ->add('date_calc', PickRollingDateType::class, [ 'label' => 'Compute geographical location at date', 'required' => true, - 'data' => new RollingDate(RollingDate::T_TODAY), ]) ->add('units', ChoiceType::class, [ 'label' => 'Geographical unit', @@ -114,6 +113,10 @@ class GeographicalUnitStatFilter implements FilterInterface 'multiple' => true, ]); } + public function getFormDefaultData(): array + { + return ['date_calc' => new RollingDate(RollingDate::T_TODAY)]; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HasNoActionFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HasNoActionFilter.php index 54c28d027..4820116c0 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HasNoActionFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HasNoActionFilter.php @@ -38,6 +38,10 @@ class HasNoActionFilter implements FilterInterface { // no form } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HasNoReferrerFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HasNoReferrerFilter.php index 4c682a56a..6d01ea7c2 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HasNoReferrerFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HasNoReferrerFilter.php @@ -65,9 +65,12 @@ class HasNoReferrerFilter implements FilterInterface $builder ->add('calc_date', PickRollingDateType::class, [ 'label' => 'Has no referrer on this date', - 'data' => new RollingDate(RollingDate::T_TODAY), ]); } + public function getFormDefaultData(): array + { + return ['calc_date' => new RollingDate(RollingDate::T_TODAY)]; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HasTemporaryLocationFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HasTemporaryLocationFilter.php index 615ace4c6..ec3b4e417 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HasTemporaryLocationFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HasTemporaryLocationFilter.php @@ -92,9 +92,12 @@ class HasTemporaryLocationFilter implements FilterInterface ]) ->add('calc_date', PickRollingDateType::class, [ 'label' => 'export.filter.course.having_temporarily.Calculation date', - 'data' => new RollingDate(RollingDate::T_TODAY), ]); } + public function getFormDefaultData(): array + { + return ['calc_date' => new RollingDate(RollingDate::T_TODAY)]; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HavingAnAccompanyingPeriodInfoWithinDatesFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HavingAnAccompanyingPeriodInfoWithinDatesFilter.php index 7069a1d80..d50622502 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HavingAnAccompanyingPeriodInfoWithinDatesFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HavingAnAccompanyingPeriodInfoWithinDatesFilter.php @@ -38,13 +38,14 @@ final readonly class HavingAnAccompanyingPeriodInfoWithinDatesFilter implements $builder ->add('start_date', PickRollingDateType::class, [ 'label' => 'export.filter.course.having_info_within_interval.start_date', - 'data' => new RollingDate(RollingDate::T_TODAY), ]) ->add('end_date', PickRollingDateType::class, [ 'label' => 'export.filter.course.having_info_within_interval.end_date', - 'data' => new RollingDate(RollingDate::T_TODAY), - ]) - ; + ]); + } + public function getFormDefaultData(): array + { + return ['start_date' => new RollingDate(RollingDate::T_TODAY), 'end_date' => new RollingDate(RollingDate::T_TODAY)]; } public function getTitle(): string diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/IntensityFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/IntensityFilter.php index b0c2205a0..1fd05d2b4 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/IntensityFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/IntensityFilter.php @@ -67,9 +67,12 @@ class IntensityFilter implements FilterInterface 'multiple' => false, 'expanded' => true, 'empty_data' => self::DEFAULT_CHOICE, - 'data' => self::DEFAULT_CHOICE, ]); } + public function getFormDefaultData(): array + { + return ['accepted_intensities' => self::DEFAULT_CHOICE]; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/OpenBetweenDatesFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/OpenBetweenDatesFilter.php index 07ca1de75..e9413083f 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/OpenBetweenDatesFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/OpenBetweenDatesFilter.php @@ -54,12 +54,12 @@ class OpenBetweenDatesFilter implements FilterInterface public function buildForm(FormBuilderInterface $builder) { $builder - ->add('date_from', PickRollingDateType::class, [ - 'data' => new RollingDate(RollingDate::T_MONTH_PREVIOUS_START), - ]) - ->add('date_to', PickRollingDateType::class, [ - 'data' => new RollingDate(RollingDate::T_TODAY), - ]); + ->add('date_from', PickRollingDateType::class, []) + ->add('date_to', PickRollingDateType::class, []); + } + public function getFormDefaultData(): array + { + return ['date_from' => new RollingDate(RollingDate::T_MONTH_PREVIOUS_START), 'date_to' => new RollingDate(RollingDate::T_TODAY)]; } public function describeAction($data, $format = 'string'): array diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/OriginFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/OriginFilter.php index 00febc640..8395c79f8 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/OriginFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/OriginFilter.php @@ -64,6 +64,10 @@ class OriginFilter implements FilterInterface 'expanded' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ReferrerFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ReferrerFilter.php index 2a3e5d17e..f0bf65d49 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ReferrerFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ReferrerFilter.php @@ -77,11 +77,14 @@ class ReferrerFilter implements FilterInterface 'multiple' => true, ]) ->add('date_calc', PickRollingDateType::class, [ - 'data' => new RollingDate(RollingDate::T_TODAY), 'label' => 'export.filter.course.by_referrer.Computation date for referrer', 'required' => true, ]); } + public function getFormDefaultData(): array + { + return ['date_calc' => new RollingDate(RollingDate::T_TODAY)]; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/RequestorFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/RequestorFilter.php index 3295a5b57..614889c27 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/RequestorFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/RequestorFilter.php @@ -126,9 +126,12 @@ final class RequestorFilter implements FilterInterface 'multiple' => false, 'expanded' => true, 'empty_data' => self::DEFAULT_CHOICE, - 'data' => self::DEFAULT_CHOICE, ]); } + public function getFormDefaultData(): array + { + return ['accepted_choices' => self::DEFAULT_CHOICE]; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/SocialActionFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/SocialActionFilter.php index bc1f368da..0c14ba73a 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/SocialActionFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/SocialActionFilter.php @@ -70,6 +70,10 @@ class SocialActionFilter implements FilterInterface 'multiple' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/SocialIssueFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/SocialIssueFilter.php index 917e129bf..a793bc548 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/SocialIssueFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/SocialIssueFilter.php @@ -69,6 +69,10 @@ class SocialIssueFilter implements FilterInterface 'multiple' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/StepFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/StepFilter.php index 8ee798c07..0a816c0b6 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/StepFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/StepFilter.php @@ -95,13 +95,15 @@ class StepFilter implements FilterInterface 'multiple' => false, 'expanded' => true, 'empty_data' => self::DEFAULT_CHOICE, - 'data' => self::DEFAULT_CHOICE, ]) ->add('calc_date', PickRollingDateType::class, [ 'label' => 'export.filter.course.by_step.date_calc', - 'data' => new RollingDate(RollingDate::T_TODAY), ]); } + public function getFormDefaultData(): array + { + return ['accepted_steps' => self::DEFAULT_CHOICE, 'calc_date' => new RollingDate(RollingDate::T_TODAY)]; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserJobFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserJobFilter.php index 05d84d7b2..e7685fe4d 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserJobFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserJobFilter.php @@ -96,11 +96,14 @@ class UserJobFilter implements FilterInterface 'label' => 'Job', ]) ->add('date_calc', PickRollingDateType::class, [ - 'data' => new RollingDate(RollingDate::T_TODAY), 'label' => 'export.filter.course.by_user_scope.Computation date for referrer', 'required' => true, ]); } + public function getFormDefaultData(): array + { + return ['date_calc' => new RollingDate(RollingDate::T_TODAY)]; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserScopeFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserScopeFilter.php index bbffa4bca..7c8d84499 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserScopeFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserScopeFilter.php @@ -100,11 +100,14 @@ class UserScopeFilter implements FilterInterface 'expanded' => true, ]) ->add('date_calc', PickRollingDateType::class, [ - 'data' => new RollingDate(RollingDate::T_TODAY), 'label' => 'export.filter.course.by_user_scope.Computation date for referrer', 'required' => true, ]); } + public function getFormDefaultData(): array + { + return ['date_calc' => new RollingDate(RollingDate::T_TODAY)]; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserWorkingOnCourseFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserWorkingOnCourseFilter.php index 586bb645d..d078443af 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserWorkingOnCourseFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserWorkingOnCourseFilter.php @@ -42,6 +42,10 @@ readonly class UserWorkingOnCourseFilter implements FilterInterface 'multiple' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function getTitle(): string { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/ByEndDateFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/ByEndDateFilter.php index de86604e6..4c019cc73 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/ByEndDateFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/ByEndDateFilter.php @@ -57,13 +57,15 @@ class ByEndDateFilter implements FilterInterface $builder ->add('start_date', PickRollingDateType::class, [ 'label' => 'start period date', - 'data' => new RollingDate(RollingDate::T_YEAR_PREVIOUS_START), ]) ->add('end_date', PickRollingDateType::class, [ 'label' => 'end period date', - 'data' => new RollingDate(RollingDate::T_TODAY), ]); } + public function getFormDefaultData(): array + { + return ['start_date' => new RollingDate(RollingDate::T_YEAR_PREVIOUS_START), 'end_date' => new RollingDate(RollingDate::T_TODAY)]; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/ByStartDateFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/ByStartDateFilter.php index 27518599c..ea221e87b 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/ByStartDateFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/ByStartDateFilter.php @@ -57,13 +57,15 @@ class ByStartDateFilter implements FilterInterface $builder ->add('start_date', PickRollingDateType::class, [ 'label' => 'start period date', - 'data' => new RollingDate(RollingDate::T_YEAR_PREVIOUS_START), ]) ->add('end_date', PickRollingDateType::class, [ 'label' => 'end period date', - 'data' => new RollingDate(RollingDate::T_TODAY), ]); } + public function getFormDefaultData(): array + { + return ['start_date' => new RollingDate(RollingDate::T_YEAR_PREVIOUS_START), 'end_date' => new RollingDate(RollingDate::T_TODAY)]; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/CurrentEvaluationsFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/CurrentEvaluationsFilter.php index 140f6c3cb..8841c7b9e 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/CurrentEvaluationsFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/CurrentEvaluationsFilter.php @@ -37,6 +37,10 @@ class CurrentEvaluationsFilter implements FilterInterface { //no form needed } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/EvaluationTypeFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/EvaluationTypeFilter.php index 6a0c71d55..77bae1b56 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/EvaluationTypeFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/EvaluationTypeFilter.php @@ -64,6 +64,10 @@ final class EvaluationTypeFilter implements FilterInterface 'expanded' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/MaxDateFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/MaxDateFilter.php index 4a65452a1..daa7d1954 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/MaxDateFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/MaxDateFilter.php @@ -61,6 +61,10 @@ class MaxDateFilter implements FilterInterface 'expanded' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/HouseholdFilters/CompositionFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/HouseholdFilters/CompositionFilter.php index 22761c158..3a2cb5337 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/HouseholdFilters/CompositionFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/HouseholdFilters/CompositionFilter.php @@ -84,9 +84,11 @@ class CompositionFilter implements FilterInterface 'multiple' => true, 'expanded' => true, ]) - ->add('on_date', PickRollingDateType::class, [ - 'data' => new RollingDate(RollingDate::T_TODAY), - ]); + ->add('on_date', PickRollingDateType::class, []); + } + public function getFormDefaultData(): array + { + return ['on_date' => new RollingDate(RollingDate::T_TODAY)]; } public function describeAction($data, $format = 'string'): array diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/AddressRefStatusFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/AddressRefStatusFilter.php index 7580a37a3..5588d8c15 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/AddressRefStatusFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/AddressRefStatusFilter.php @@ -76,17 +76,19 @@ class AddressRefStatusFilter implements \Chill\MainBundle\Export\FilterInterface ->add('date_calc', PickRollingDateType::class, [ 'label' => 'Compute address at date', 'required' => true, - 'data' => new RollingDate(RollingDate::T_TODAY), ]) ->add('ref_statuses', ChoiceType::class, [ 'label' => 'export.filter.person.by_address_ref_status.Status', 'choices' => [Address::ADDR_REFERENCE_STATUS_TO_REVIEW, Address::ADDR_REFERENCE_STATUS_REVIEWED, Address::ADDR_REFERENCE_STATUS_MATCH], 'choice_label' => fn (string $item) => 'export.filter.person.by_address_ref_status.'.$item, 'multiple' => true, - 'expanded' => true, - 'data' => [Address::ADDR_REFERENCE_STATUS_TO_REVIEW] + 'expanded' => true ]); } + public function getFormDefaultData(): array + { + return ['date_calc' => new RollingDate(RollingDate::T_TODAY), 'ref_statuses' => [Address::ADDR_REFERENCE_STATUS_TO_REVIEW]]; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/BirthdateFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/BirthdateFilter.php index 7ae22ddd8..9a0478b6c 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/BirthdateFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/BirthdateFilter.php @@ -71,14 +71,16 @@ class BirthdateFilter implements ExportElementValidatedInterface, FilterInterfac { $builder->add('date_from', PickRollingDateType::class, [ 'label' => 'Born after this date', - 'data' => new RollingDate(RollingDate::T_YEAR_PREVIOUS_START), ]); $builder->add('date_to', PickRollingDateType::class, [ 'label' => 'Born before this date', - 'data' => new RollingDate(RollingDate::T_TODAY), ]); } + public function getFormDefaultData(): array + { + return ['date_from' => new RollingDate(RollingDate::T_YEAR_PREVIOUS_START), 'date_to' => new RollingDate(RollingDate::T_TODAY)]; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ByHouseholdCompositionFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ByHouseholdCompositionFilter.php index 9b59549f1..749897a53 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ByHouseholdCompositionFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ByHouseholdCompositionFilter.php @@ -86,9 +86,12 @@ class ByHouseholdCompositionFilter implements FilterInterface ]) ->add('calc_date', PickRollingDateType::class, [ 'label' => 'export.filter.person.by_composition.Date calc', - 'data' => new RollingDate(RollingDate::T_TODAY), ]); } + public function getFormDefaultData(): array + { + return ['calc_date' => new RollingDate(RollingDate::T_TODAY)]; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/DeadOrAliveFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/DeadOrAliveFilter.php index 384d6698a..8b2444ca2 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/DeadOrAliveFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/DeadOrAliveFilter.php @@ -102,9 +102,12 @@ class DeadOrAliveFilter implements FilterInterface $builder->add('date_calc', PickRollingDateType::class, [ 'label' => 'Filter in relation to this date', - 'data' => new RollingDate(RollingDate::T_TODAY), ]); } + public function getFormDefaultData(): array + { + return ['date_calc' => new RollingDate(RollingDate::T_TODAY)]; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/DeathdateFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/DeathdateFilter.php index 0ac4b3173..7805331a5 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/DeathdateFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/DeathdateFilter.php @@ -72,14 +72,16 @@ class DeathdateFilter implements ExportElementValidatedInterface, FilterInterfac { $builder->add('date_from', PickRollingDateType::class, [ 'label' => 'Death after this date', - 'data' => new RollingDate(RollingDate::T_YEAR_PREVIOUS_START), ]); $builder->add('date_to', PickRollingDateType::class, [ 'label' => 'Deathdate before', - 'data' => new RollingDate(RollingDate::T_TODAY), ]); } + public function getFormDefaultData(): array + { + return ['date_from' => new RollingDate(RollingDate::T_YEAR_PREVIOUS_START), 'date_to' => new RollingDate(RollingDate::T_TODAY)]; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/GenderFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/GenderFilter.php index 739945b98..182006bbc 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/GenderFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/GenderFilter.php @@ -89,6 +89,10 @@ class GenderFilter implements 'expanded' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/GeographicalUnitFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/GeographicalUnitFilter.php index 79f5cb2d4..ab9bb08ab 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/GeographicalUnitFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/GeographicalUnitFilter.php @@ -91,7 +91,6 @@ class GeographicalUnitFilter implements \Chill\MainBundle\Export\FilterInterface ->add('date_calc', PickRollingDateType::class, [ 'label' => 'Compute geographical location at date', 'required' => true, - 'data' => new RollingDate(RollingDate::T_TODAY), ]) ->add('units', ChoiceType::class, [ 'label' => 'Geographical unit', @@ -105,6 +104,10 @@ class GeographicalUnitFilter implements \Chill\MainBundle\Export\FilterInterface 'multiple' => true, ]); } + public function getFormDefaultData(): array + { + return ['date_calc' => new RollingDate(RollingDate::T_TODAY)]; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/MaritalStatusFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/MaritalStatusFilter.php index 47a75871c..021c22fc6 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/MaritalStatusFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/MaritalStatusFilter.php @@ -56,6 +56,10 @@ class MaritalStatusFilter implements FilterInterface 'expanded' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/NationalityFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/NationalityFilter.php index b1d77d60e..e5102128b 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/NationalityFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/NationalityFilter.php @@ -67,6 +67,10 @@ class NationalityFilter implements 'placeholder' => 'Choose countries', ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ResidentialAddressAtThirdpartyFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ResidentialAddressAtThirdpartyFilter.php index 21bb40947..8f22750a5 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ResidentialAddressAtThirdpartyFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ResidentialAddressAtThirdpartyFilter.php @@ -107,9 +107,12 @@ class ResidentialAddressAtThirdpartyFilter implements FilterInterface $builder->add('date_calc', PickRollingDateType::class, [ 'label' => 'Date during which residential address was valid', - 'data' => new RollingDate(RollingDate::T_TODAY), ]); } + public function getFormDefaultData(): array + { + return ['date_calc' => new RollingDate(RollingDate::T_TODAY)]; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ResidentialAddressAtUserFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ResidentialAddressAtUserFilter.php index bd55c5b80..62b142420 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ResidentialAddressAtUserFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ResidentialAddressAtUserFilter.php @@ -82,9 +82,12 @@ class ResidentialAddressAtUserFilter implements FilterInterface { $builder->add('date_calc', PickRollingDateType::class, [ 'label' => 'Date during which residential address was valid', - 'data' => new RollingDate(RollingDate::T_TODAY), ]); } + public function getFormDefaultData(): array + { + return ['date_calc' => new RollingDate(RollingDate::T_TODAY)]; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/WithoutHouseholdComposition.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/WithoutHouseholdComposition.php index c4644fc11..9f5ed90b5 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/WithoutHouseholdComposition.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/WithoutHouseholdComposition.php @@ -66,9 +66,12 @@ class WithoutHouseholdComposition implements FilterInterface $builder ->add('calc_date', PickRollingDateType::class, [ 'label' => 'export.filter.person.by_no_composition.Date calc', - 'data' => new RollingDate(RollingDate::T_TODAY), ]); } + public function getFormDefaultData(): array + { + return ['calc_date' => new RollingDate(RollingDate::T_TODAY)]; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/AccompanyingPeriodWorkEndDateBetweenDateFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/AccompanyingPeriodWorkEndDateBetweenDateFilter.php index b13c49e9a..e78b1d021 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/AccompanyingPeriodWorkEndDateBetweenDateFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/AccompanyingPeriodWorkEndDateBetweenDateFilter.php @@ -32,17 +32,18 @@ final readonly class AccompanyingPeriodWorkEndDateBetweenDateFilter implements F $builder ->add('start_date', PickRollingDateType::class, [ 'label' => 'export.filter.work.end_between_dates.start_date', - 'data' => new RollingDate(RollingDate::T_TODAY), ]) ->add('end_date', PickRollingDateType::class, [ 'label' => 'export.filter.work.end_between_dates.end_date', - 'data' => new RollingDate(RollingDate::T_TODAY), ]) ->add('keep_null', CheckboxType::class, [ 'label' => 'export.filter.work.end_between_dates.keep_null', 'help' => 'export.filter.work.end_between_dates.keep_null_help', - ]) - ; + ]); + } + public function getFormDefaultData(): array + { + return ['start_date' => new RollingDate(RollingDate::T_TODAY), 'end_date' => new RollingDate(RollingDate::T_TODAY)]; } public function getTitle(): string diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/AccompanyingPeriodWorkStartDateBetweenDateFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/AccompanyingPeriodWorkStartDateBetweenDateFilter.php index e9526a9a5..947e6c57c 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/AccompanyingPeriodWorkStartDateBetweenDateFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/AccompanyingPeriodWorkStartDateBetweenDateFilter.php @@ -32,17 +32,18 @@ final readonly class AccompanyingPeriodWorkStartDateBetweenDateFilter implements $builder ->add('start_date', PickRollingDateType::class, [ 'label' => 'export.filter.work.start_between_dates.start_date', - 'data' => new RollingDate(RollingDate::T_TODAY), ]) ->add('end_date', PickRollingDateType::class, [ 'label' => 'export.filter.work.start_between_dates.end_date', - 'data' => new RollingDate(RollingDate::T_TODAY), ]) ->add('keep_null', CheckboxType::class, [ 'label' => 'export.filter.work.start_between_dates.keep_null', 'help' => 'export.filter.work.start_between_dates.keep_null_help', - ]) - ; + ]); + } + public function getFormDefaultData(): array + { + return ['start_date' => new RollingDate(RollingDate::T_TODAY), 'end_date' => new RollingDate(RollingDate::T_TODAY)]; } public function getTitle(): string diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/CurrentActionFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/CurrentActionFilter.php index cbdb64d8d..e99590025 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/CurrentActionFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/CurrentActionFilter.php @@ -37,6 +37,10 @@ class CurrentActionFilter implements FilterInterface { //no form } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/JobFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/JobFilter.php index 144bf3260..265c8e24d 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/JobFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/JobFilter.php @@ -76,6 +76,10 @@ class JobFilter implements FilterInterface 'expanded' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/ReferrerFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/ReferrerFilter.php index 8d0da32fb..bddcfbf9b 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/ReferrerFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/ReferrerFilter.php @@ -57,6 +57,10 @@ class ReferrerFilter implements FilterInterface 'multiple' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string'): array { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/ScopeFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/ScopeFilter.php index 315025722..737759c3e 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/ScopeFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/ScopeFilter.php @@ -76,6 +76,10 @@ class ScopeFilter implements FilterInterface 'expanded' => true, ]); } + public function getFormDefaultData(): array + { + return []; + } public function describeAction($data, $format = 'string') { diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/SocialWorkTypeFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/SocialWorkTypeFilter.php index 11fd0ed9d..9a687b1e6 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/SocialWorkTypeFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/SocialWorkTypeFilter.php @@ -111,6 +111,11 @@ class SocialWorkTypeFilter implements FilterInterface ); } + public function getFormDefaultData(): array + { + return ['action_type' => '', 'goal' => '', 'result' => '']; + } + public function describeAction($data, $format = 'string'): array { $actionTypes = []; diff --git a/src/Bundle/ChillReportBundle/Export/Export/ReportList.php b/src/Bundle/ChillReportBundle/Export/Export/ReportList.php index 9adae0097..9d99b7e62 100644 --- a/src/Bundle/ChillReportBundle/Export/Export/ReportList.php +++ b/src/Bundle/ChillReportBundle/Export/Export/ReportList.php @@ -94,7 +94,6 @@ class ReportList implements ExportElementValidatedInterface, ListInterface $cf->getSlug(); } - // Add a checkbox to select fields $builder->add('fields', ChoiceType::class, [ 'multiple' => true, 'expanded' => true, @@ -134,14 +133,16 @@ class ReportList implements ExportElementValidatedInterface, ListInterface ])], ]); - // add a date field for addresses $builder->add('address_date', ChillDateType::class, [ 'label' => 'Address valid at this date', - 'data' => new DateTime(), 'required' => false, 'block_name' => 'list_export_form_address_date', ]); } + public function getFormDefaultData(): array + { + return ['address_date' => new DateTime()]; + } public function getAllowedFormattersTypes() { diff --git a/src/Bundle/ChillReportBundle/Export/Filter/ReportDateFilter.php b/src/Bundle/ChillReportBundle/Export/Filter/ReportDateFilter.php index 79bad4f52..cb8e7d1d0 100644 --- a/src/Bundle/ChillReportBundle/Export/Filter/ReportDateFilter.php +++ b/src/Bundle/ChillReportBundle/Export/Filter/ReportDateFilter.php @@ -67,14 +67,16 @@ class ReportDateFilter implements FilterInterface { $builder->add('date_from', PickRollingDateType::class, [ 'label' => 'Report is after this date', - 'data' => new RollingDate(RollingDate::T_YEAR_PREVIOUS_START), ]); $builder->add('date_to', PickRollingDateType::class, [ 'label' => 'Report is before this date', - 'data' => new RollingDate(RollingDate::T_TODAY), ]); } + public function getFormDefaultData(): array + { + return ['date_from' => new RollingDate(RollingDate::T_YEAR_PREVIOUS_START), 'date_to' => new RollingDate(RollingDate::T_TODAY)]; + } public function describeAction($data, $format = 'string') { From 9073f118dbf9e8f0455f2d149514efaa944302d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Sun, 18 Jun 2023 21:37:52 +0200 Subject: [PATCH 190/321] [rector] add form default data rule: handle case when there are method call on builder without add --- ...FormDefaultDataOnExportFilterAggregatorRector.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/utils/rector/src/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector.php b/utils/rector/src/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector.php index cc54a24f1..4718aedac 100644 --- a/utils/rector/src/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector.php +++ b/utils/rector/src/Rector/ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector.php @@ -138,7 +138,7 @@ PHP */ } ['build_form_method' => $buildFormMethod, 'empty_to_replace' => $emptyToReplace] - = $this->filterBuildFormMethod($node->stmts[$buildFormStmtIndex]); + = $this->filterBuildFormMethod($node->stmts[$buildFormStmtIndex], $node); $node->stmts = [ ...$stmtBefore, @@ -172,7 +172,7 @@ PHP */ * @param Node\Stmt\ClassMethod $buildFormMethod * @return array{"build_form_method": Node\Stmt\ClassMethod, "empty_to_replace": array} */ - private function filterBuildFormMethod(Node\Stmt\ClassMethod $buildFormMethod): array + private function filterBuildFormMethod(Node\Stmt\ClassMethod $buildFormMethod, Node\Stmt\Class_ $node): array { $builderName = $buildFormMethod->params[0]->var->name; @@ -183,7 +183,7 @@ PHP */ if ($stmt instanceof Node\Stmt\Expression // it must be a method call && $stmt->expr instanceof Node\Expr\MethodCall - && false !== ($results = $this->handleMethodCallBuilderAdd($stmt->expr, $builderName)) + && false !== ($results = $this->handleMethodCallBuilderAdd($stmt->expr, $builderName, $node)) ) { ['stmt' => $newMethodCAll, 'emptyDataToReplace' => $newEmptyDataToReplace] = $results; $newStmts[] = new Node\Stmt\Expression($newMethodCAll); @@ -198,7 +198,7 @@ PHP */ return ['build_form_method' => $buildFormMethod, "empty_to_replace" => $emptyDataToReplace]; } - private function handleMethodCallBuilderAdd(Node\Expr\MethodCall $methodCall, string $builderName): array|false + private function handleMethodCallBuilderAdd(Node\Expr\MethodCall $methodCall, string $builderName, Node\Stmt\Class_ $node): array|false { $emptyDataToReplace = []; // check for chained method call @@ -208,7 +208,7 @@ PHP */ ) { // as this is chained, we make a recursion on this method - $resultFormDeepMethodCall = $this->handleMethodCallBuilderAdd($methodCall->var, $builderName); + $resultFormDeepMethodCall = $this->handleMethodCallBuilderAdd($methodCall->var, $builderName, $node); if (false === $resultFormDeepMethodCall) { return false; @@ -268,6 +268,6 @@ PHP */ return ['stmt' => $methodCall, 'emptyDataToReplace' => $emptyDataToReplace]; } - throw new \RuntimeException("Not supported situation"); + return ['stmt' => $methodCall, 'emptyDataToReplace' => $emptyDataToReplace]; } } From 5a102d4989233c2023c9de703f0a5e240c32be4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Sun, 18 Jun 2023 21:44:10 +0200 Subject: [PATCH 191/321] publish new 2.2.0 version --- .changes/unreleased/DX-20230614-233000.yaml | 5 ----- .changes/unreleased/Feature-20230613-154903.yaml | 7 ------- .changes/unreleased/Feature-20230613-230640.yaml | 5 ----- .changes/unreleased/Feature-20230614-224720.yaml | 6 ------ .changes/unreleased/Feature-20230614-233107.yaml | 5 ----- .changes/unreleased/Fixed-20230606-170742.yaml | 6 ------ .changes/unreleased/Fixed-20230613-155453.yaml | 5 ----- .changes/unreleased/Fixed-20230613-230838.yaml | 5 ----- .changes/v2.2.0.md | 12 ++++++++++++ CHANGELOG.md | 13 +++++++++++++ 10 files changed, 25 insertions(+), 44 deletions(-) delete mode 100644 .changes/unreleased/DX-20230614-233000.yaml delete mode 100644 .changes/unreleased/Feature-20230613-154903.yaml delete mode 100644 .changes/unreleased/Feature-20230613-230640.yaml delete mode 100644 .changes/unreleased/Feature-20230614-224720.yaml delete mode 100644 .changes/unreleased/Feature-20230614-233107.yaml delete mode 100644 .changes/unreleased/Fixed-20230606-170742.yaml delete mode 100644 .changes/unreleased/Fixed-20230613-155453.yaml delete mode 100644 .changes/unreleased/Fixed-20230613-230838.yaml create mode 100644 .changes/v2.2.0.md diff --git a/.changes/unreleased/DX-20230614-233000.yaml b/.changes/unreleased/DX-20230614-233000.yaml deleted file mode 100644 index ca4a3171b..000000000 --- a/.changes/unreleased/DX-20230614-233000.yaml +++ /dev/null @@ -1,5 +0,0 @@ -kind: DX -body: 'DQL function OVERLAPSI: simplify expression in postgresql' -time: 2023-06-14T23:30:00.217427234+02:00 -custom: - Issue: "" diff --git a/.changes/unreleased/Feature-20230613-154903.yaml b/.changes/unreleased/Feature-20230613-154903.yaml deleted file mode 100644 index 7506bf473..000000000 --- a/.changes/unreleased/Feature-20230613-154903.yaml +++ /dev/null @@ -1,7 +0,0 @@ -kind: Feature -body: When navigating from a workflow regarding to an evaluation's document to an - accompanying course, scroll directly to the document, and blink to highlight this - document -time: 2023-06-13T15:49:03.663438985+02:00 -custom: - Issue: "" diff --git a/.changes/unreleased/Feature-20230613-230640.yaml b/.changes/unreleased/Feature-20230613-230640.yaml deleted file mode 100644 index 18694c724..000000000 --- a/.changes/unreleased/Feature-20230613-230640.yaml +++ /dev/null @@ -1,5 +0,0 @@ -kind: Feature -body: Add notification to accompanying period work and work's evaluation's documents -time: 2023-06-13T23:06:40.090777525+02:00 -custom: - Issue: "" diff --git a/.changes/unreleased/Feature-20230614-224720.yaml b/.changes/unreleased/Feature-20230614-224720.yaml deleted file mode 100644 index 3f86b022f..000000000 --- a/.changes/unreleased/Feature-20230614-224720.yaml +++ /dev/null @@ -1,6 +0,0 @@ -kind: Feature -body: '[Export] Filter accompanying period by step at date: allow to pick multiple - steps' -time: 2023-06-14T22:47:20.577100599+02:00 -custom: - Issue: "113" diff --git a/.changes/unreleased/Feature-20230614-233107.yaml b/.changes/unreleased/Feature-20230614-233107.yaml deleted file mode 100644 index 2d0e502f2..000000000 --- a/.changes/unreleased/Feature-20230614-233107.yaml +++ /dev/null @@ -1,5 +0,0 @@ -kind: Feature -body: '[export] add a filter on accompanying period: filter by step between two dates' -time: 2023-06-14T23:31:07.979389911+02:00 -custom: - Issue: "113" diff --git a/.changes/unreleased/Fixed-20230606-170742.yaml b/.changes/unreleased/Fixed-20230606-170742.yaml deleted file mode 100644 index 0bd65b6cf..000000000 --- a/.changes/unreleased/Fixed-20230606-170742.yaml +++ /dev/null @@ -1,6 +0,0 @@ -kind: Fixed -body: use the correct annotation for the association between PersonCurrentCenter and - Person -time: 2023-06-06T17:07:42.060486553+02:00 -custom: - Issue: "" diff --git a/.changes/unreleased/Fixed-20230613-155453.yaml b/.changes/unreleased/Fixed-20230613-155453.yaml deleted file mode 100644 index f183c3a17..000000000 --- a/.changes/unreleased/Fixed-20230613-155453.yaml +++ /dev/null @@ -1,5 +0,0 @@ -kind: Fixed -body: Fix birthdate timezone in PersonRenderBox -time: 2023-06-13T15:54:53.125120559+02:00 -custom: - Issue: "58" diff --git a/.changes/unreleased/Fixed-20230613-230838.yaml b/.changes/unreleased/Fixed-20230613-230838.yaml deleted file mode 100644 index 816f4f8d4..000000000 --- a/.changes/unreleased/Fixed-20230613-230838.yaml +++ /dev/null @@ -1,5 +0,0 @@ -kind: Fixed -body: Fix the notification counter -time: 2023-06-13T23:08:38.67342897+02:00 -custom: - Issue: "55" diff --git a/.changes/v2.2.0.md b/.changes/v2.2.0.md new file mode 100644 index 000000000..5371cad35 --- /dev/null +++ b/.changes/v2.2.0.md @@ -0,0 +1,12 @@ +## v2.2.0 - 2023-06-18 +### Feature +* When navigating from a workflow regarding to an evaluation's document to an accompanying course, scroll directly to the document, and blink to highlight this document +* Add notification to accompanying period work and work's evaluation's documents +* ([#113](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/113))[Export] Filter accompanying period by step at date: allow to pick multiple steps +* ([#113](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/113))[export] add a filter on accompanying period: filter by step between two dates +### Fixed +* use the correct annotation for the association between PersonCurrentCenter and Person +* ([#58](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/58))Fix birthdate timezone in PersonRenderBox +* ([#55](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/55))Fix the notification counter +### DX +* DQL function OVERLAPSI: simplify expression in postgresql diff --git a/CHANGELOG.md b/CHANGELOG.md index f10f12f9b..2c5ed9b3a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,19 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), and is generated by [Changie](https://github.com/miniscruff/changie). +## v2.2.0 - 2023-06-18 +### Feature +* When navigating from a workflow regarding to an evaluation's document to an accompanying course, scroll directly to the document, and blink to highlight this document +* Add notification to accompanying period work and work's evaluation's documents +* ([#113](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/113))[Export] Filter accompanying period by step at date: allow to pick multiple steps +* ([#113](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/113))[export] add a filter on accompanying period: filter by step between two dates +### Fixed +* use the correct annotation for the association between PersonCurrentCenter and Person +* ([#58](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/58))Fix birthdate timezone in PersonRenderBox +* ([#55](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/55))Fix the notification counter +### DX +* DQL function OVERLAPSI: simplify expression in postgresql + ## v2.1.0 - 2023-06-12 ### Feature From 4359c2dddc8d8db8ae46e4429286a081f8a6a341 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Mon, 19 Jun 2023 20:21:50 +0200 Subject: [PATCH 192/321] DX: add a space between issue number and description in changie --- .changie.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changie.yaml b/.changie.yaml index 83fd9770a..ba5454ce7 100644 --- a/.changie.yaml +++ b/.changie.yaml @@ -6,7 +6,7 @@ versionExt: md versionFormat: '## {{.Version}} - {{.Time.Format "2006-01-02"}}' kindFormat: '### {{.Kind}}' changeFormat: >- - * {{ if not (eq .Custom.Issue "") }}([#{{ .Custom.Issue }}](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/{{ .Custom.Issue }})) {{- end }}{{.Body}} + * {{ if not (eq .Custom.Issue "") }}([#{{ .Custom.Issue }}](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/{{ .Custom.Issue }})) {{ end }}{{.Body}} custom: - key: Issue label: Issue number (on chill-bundles repository) (optional) From 6c16967cdc982f17fea3d2056b08e45190484b35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Mon, 19 Jun 2023 21:00:19 +0200 Subject: [PATCH 193/321] Fix: Fix entityId and return path when add a notification on a document's evaluation --- .../unreleased/Fixed-20230619-205836.yaml | 6 ++++++ .../public/lib/entity-notification/api.ts | 20 +++++++++++++++++++ .../components/FormEvaluation.vue | 15 ++++++++------ 3 files changed, 35 insertions(+), 6 deletions(-) create mode 100644 .changes/unreleased/Fixed-20230619-205836.yaml create mode 100644 src/Bundle/ChillMainBundle/Resources/public/lib/entity-notification/api.ts diff --git a/.changes/unreleased/Fixed-20230619-205836.yaml b/.changes/unreleased/Fixed-20230619-205836.yaml new file mode 100644 index 000000000..54b292394 --- /dev/null +++ b/.changes/unreleased/Fixed-20230619-205836.yaml @@ -0,0 +1,6 @@ +kind: Fixed +body: '[notification on document evaluation] fix entityId and return path when + adding a notification on a document in an evaluation' +time: 2023-06-19T20:58:36.941795323+02:00 +custom: + Issue: "114" diff --git a/src/Bundle/ChillMainBundle/Resources/public/lib/entity-notification/api.ts b/src/Bundle/ChillMainBundle/Resources/public/lib/entity-notification/api.ts new file mode 100644 index 000000000..ce0671d82 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Resources/public/lib/entity-notification/api.ts @@ -0,0 +1,20 @@ +const buildLinkCreate = function (relatedEntityClass: string, relatedEntityId: number, to: number | null, returnPath: string | null): string +{ + const params = new URLSearchParams(); + params.append('entityClass', relatedEntityClass); + params.append('entityId', relatedEntityId.toString()); + + if (null !== to) { + params.append('tos[0]', to.toString()); + } + + if (null !== returnPath) { + params.append('returnPath', returnPath); + } + + return `/fr/notification/create?${params.toString()}`; +} + +export { + buildLinkCreate, +} diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/components/FormEvaluation.vue b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/components/FormEvaluation.vue index a4e03bd31..4ea00f73a 100644 --- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/components/FormEvaluation.vue +++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/components/FormEvaluation.vue @@ -201,6 +201,7 @@ import AddAsyncUpload from 'ChillDocStoreAssets/vuejs/_components/AddAsyncUpload import AddAsyncUploadDownloader from 'ChillDocStoreAssets/vuejs/_components/AddAsyncUploadDownloader.vue'; import ListWorkflowModal from 'ChillMainAssets/vuejs/_components/EntityWorkflow/ListWorkflowModal.vue'; import {buildLinkCreate} from 'ChillMainAssets/lib/entity-workflow/api.js'; +import {buildLinkCreate as buildLinkCreateNotification} from 'ChillMainAssets/lib/entity-notification/api'; import DocumentActionButtonsGroup from "ChillDocStoreAssets/vuejs/DocumentActionButtonsGroup.vue"; const i18n = { @@ -413,14 +414,16 @@ export default { return this.$store.dispatch('submit', callback) .catch(e => { console.log(e); throw e; }); }, - goToGenerateDocumentNotification(document, tos){ + goToGenerateDocumentNotification(document, tos) { const callback = (data) => { let evaluation = data.accompanyingPeriodWorkEvaluations.find(e => e.key === this.evaluation.key); - if (tos === true) { - window.location.assign(`/fr/notification/create?entityClass=Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluationDocument&entityId=${document.id}&tos[0]=${this.$store.state.work.accompanyingPeriod.user.id}&returnPath=/fr/person/accompanying-period/work/${evaluation.id}/edit`) - } else { - window.location.assign(`/fr/notification/create?entityClass=Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluationDocument&entityId=${document.id}&returnPath=/fr/person/accompanying-period/work/${evaluation.id}/edit`) - } + let updatedDocument = evaluation.documents.find(d => d.key === document.key); + window.location.assign(buildLinkCreateNotification( + 'Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluationDocument', + updatedDocument.id, + tos === true ? this.$store.state.work.accompanyingPeriod.user.id : null, + window.location.pathname + window.location.search + window.location.hash + )); }; return this.$store.dispatch('submit', callback) .catch(e => {console.log(e); throw e}); From 9d2dfbe610feeebfd5fd253ede70d59ffac162ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Mon, 19 Jun 2023 21:02:19 +0200 Subject: [PATCH 194/321] DX: publish release 2.2.1 --- .changes/unreleased/Fixed-20230619-205836.yaml | 6 ------ .changes/v2.2.1.md | 3 +++ CHANGELOG.md | 4 ++++ 3 files changed, 7 insertions(+), 6 deletions(-) delete mode 100644 .changes/unreleased/Fixed-20230619-205836.yaml create mode 100644 .changes/v2.2.1.md diff --git a/.changes/unreleased/Fixed-20230619-205836.yaml b/.changes/unreleased/Fixed-20230619-205836.yaml deleted file mode 100644 index 54b292394..000000000 --- a/.changes/unreleased/Fixed-20230619-205836.yaml +++ /dev/null @@ -1,6 +0,0 @@ -kind: Fixed -body: '[notification on document evaluation] fix entityId and return path when - adding a notification on a document in an evaluation' -time: 2023-06-19T20:58:36.941795323+02:00 -custom: - Issue: "114" diff --git a/.changes/v2.2.1.md b/.changes/v2.2.1.md new file mode 100644 index 000000000..c96b18585 --- /dev/null +++ b/.changes/v2.2.1.md @@ -0,0 +1,3 @@ +## v2.2.1 - 2023-06-19 +### Fixed +* ([#114](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/114)) [notification on document evaluation] fix entityId and return path when adding a notification on a document in an evaluation diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c5ed9b3a..e223fa116 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), and is generated by [Changie](https://github.com/miniscruff/changie). +## v2.2.1 - 2023-06-19 +### Fixed +* ([#114](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/114)) [notification on document evaluation] fix entityId and return path when adding a notification on a document in an evaluation + ## v2.2.0 - 2023-06-18 ### Feature * When navigating from a workflow regarding to an evaluation's document to an accompanying course, scroll directly to the document, and blink to highlight this document From 146103e87c0cf8fef61b4b6bff1d72b84f710c99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 21 Jun 2023 13:33:29 +0200 Subject: [PATCH 195/321] Fixed: Accompanyingperiod / comment: order by newest to oldest --- .changes/unreleased/Fixed-20230621-132851.yaml | 6 ++++++ src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php | 7 +++++-- 2 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 .changes/unreleased/Fixed-20230621-132851.yaml diff --git a/.changes/unreleased/Fixed-20230621-132851.yaml b/.changes/unreleased/Fixed-20230621-132851.yaml new file mode 100644 index 000000000..89fb7cdd9 --- /dev/null +++ b/.changes/unreleased/Fixed-20230621-132851.yaml @@ -0,0 +1,6 @@ +kind: Fixed +body: '[Accompanying period comments]: order comments from the most recent to the + oldest, in the list' +time: 2023-06-21T13:28:51.282714011+02:00 +custom: + Issue: "" diff --git a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php index a8e191df3..accf39db5 100644 --- a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php +++ b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php @@ -185,7 +185,9 @@ class AccompanyingPeriod implements * cascade={"persist", "remove"}, * orphanRemoval=true * ) + * @ORM\OrderBy({"createdAt": "DESC", "id": "DESC"}) * @Assert\NotBlank(groups={AccompanyingPeriod::STEP_DRAFT}) + * @var Collection */ private Collection $comments; @@ -705,10 +707,11 @@ class AccompanyingPeriod implements ->comments ->filter( static fn (Comment $c): bool => $c !== $pinnedComment - ); + ) + ; } - public function getCreatedAt(): ?DateTime + public function getCreatedAt(): DateTimeInterface { return $this->createdAt; } From 471898e6d831d708bd3e90766aee9f816a781faf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 21 Jun 2023 13:59:42 +0200 Subject: [PATCH 196/321] Fixed: filter social action to keep only currently activated --- .../unreleased/Fixed-20230621-135912.yaml | 5 ++++ .../SocialWorkSocialActionApiController.php | 21 ++++++++-------- .../Entity/SocialWork/SocialAction.php | 24 +++++++++++++++++++ .../Entity/SocialWork/SocialIssue.php | 4 ++-- .../SocialWork/SocialAction/index.html.twig | 2 +- 5 files changed, 43 insertions(+), 13 deletions(-) create mode 100644 .changes/unreleased/Fixed-20230621-135912.yaml diff --git a/.changes/unreleased/Fixed-20230621-135912.yaml b/.changes/unreleased/Fixed-20230621-135912.yaml new file mode 100644 index 000000000..676d1c21b --- /dev/null +++ b/.changes/unreleased/Fixed-20230621-135912.yaml @@ -0,0 +1,5 @@ +kind: Fixed +body: 'Api: filter social action to keep only the currently activated' +time: 2023-06-21T13:59:12.57760217+02:00 +custom: + Issue: "" diff --git a/src/Bundle/ChillPersonBundle/Controller/SocialWorkSocialActionApiController.php b/src/Bundle/ChillPersonBundle/Controller/SocialWorkSocialActionApiController.php index 4fe877a72..ae70d55f9 100644 --- a/src/Bundle/ChillPersonBundle/Controller/SocialWorkSocialActionApiController.php +++ b/src/Bundle/ChillPersonBundle/Controller/SocialWorkSocialActionApiController.php @@ -16,21 +16,19 @@ use Chill\MainBundle\Pagination\PaginatorFactory; use Chill\MainBundle\Serializer\Model\Collection; use Chill\PersonBundle\Entity\SocialWork\SocialAction; use Chill\PersonBundle\Repository\SocialWork\SocialIssueRepository; +use Symfony\Component\Clock\ClockInterface; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use function count; -class SocialWorkSocialActionApiController extends ApiController +final class SocialWorkSocialActionApiController extends ApiController { - private PaginatorFactory $paginator; - - private SocialIssueRepository $socialIssueRepository; - - public function __construct(SocialIssueRepository $socialIssueRepository, PaginatorFactory $paginator) - { - $this->socialIssueRepository = $socialIssueRepository; - $this->paginator = $paginator; + public function __construct( + private readonly SocialIssueRepository $socialIssueRepository, + private readonly PaginatorFactory $paginator, + private readonly ClockInterface $clock, + ) { } public function listBySocialIssueApi($id, Request $request) @@ -42,7 +40,10 @@ class SocialWorkSocialActionApiController extends ApiController throw $this->createNotFoundException('socialIssue not found'); } - $socialActions = $socialIssue->getRecursiveSocialActions()->toArray(); + $socialActions = SocialAction::filterRemoveDeactivatedActions( + $socialIssue->getRecursiveSocialActions()->toArray(), + \DateTime::createFromImmutable($this->clock->now()) + ); usort($socialActions, static fn (SocialAction $sa, SocialAction $sb) => $sa->getOrdering() <=> $sb->getOrdering()); diff --git a/src/Bundle/ChillPersonBundle/Entity/SocialWork/SocialAction.php b/src/Bundle/ChillPersonBundle/Entity/SocialWork/SocialAction.php index a8c68c8ce..b5b0f9101 100644 --- a/src/Bundle/ChillPersonBundle/Entity/SocialWork/SocialAction.php +++ b/src/Bundle/ChillPersonBundle/Entity/SocialWork/SocialAction.php @@ -15,6 +15,7 @@ use DateInterval; use DateTimeInterface; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; +use Doctrine\Common\Collections\ReadableCollection; use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Serializer\Annotation as Serializer; @@ -295,6 +296,19 @@ class SocialAction return 0 < $this->getChildren()->count(); } + public function isDesactivated(\DateTime $atDate): bool + { + if (null !== $this->desactivationDate && $this->desactivationDate < $atDate) { + return true; + } + + if ($this->hasParent()) { + return $this->parent->isDesactivated($atDate); + } + + return false; + } + public function hasParent(): bool { return $this->getParent() instanceof self; @@ -401,4 +415,14 @@ class SocialAction return $this; } + + public static function filterRemoveDeactivatedActions(ReadableCollection|array $actions, \DateTime $comparisonDate): ReadableCollection|array + { + $filterFn = fn (SocialAction $socialAction) => !$socialAction->isDesactivated($comparisonDate); + + return match ($actions instanceof ReadableCollection) { + true => $actions->filter($filterFn), + false => array_filter($actions, $filterFn) + }; + } } diff --git a/src/Bundle/ChillPersonBundle/Entity/SocialWork/SocialIssue.php b/src/Bundle/ChillPersonBundle/Entity/SocialWork/SocialIssue.php index 675a1a923..f12627ae3 100644 --- a/src/Bundle/ChillPersonBundle/Entity/SocialWork/SocialIssue.php +++ b/src/Bundle/ChillPersonBundle/Entity/SocialWork/SocialIssue.php @@ -253,7 +253,7 @@ class SocialIssue } /** - * @return Collection|SocialAction[] All the descendant social actions of all + * @return Collection All the descendant social actions of all * the descendants of the entity */ public function getRecursiveSocialActions(): Collection @@ -272,7 +272,7 @@ class SocialIssue } /** - * @return Collection|SocialAction[] + * @return Collection */ public function getSocialActions(): Collection { diff --git a/src/Bundle/ChillPersonBundle/Resources/views/SocialWork/SocialAction/index.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/SocialWork/SocialAction/index.html.twig index e78216f04..9e6c6e5aa 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/SocialWork/SocialAction/index.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/SocialWork/SocialAction/index.html.twig @@ -20,7 +20,7 @@ {{ entity.ordering }} {% if entity.desactivationDate is not null %} - {{ entity.desactivationDate|date('Y-m-d') }} + {{ entity.desactivationDate|format_date('medium') }} {% endif %} From 27f797d7361ac4b8234a8cb435cf7d17671ab147 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 21 Jun 2023 14:30:22 +0200 Subject: [PATCH 197/321] add changie entry for fixing filiation bug --- .changes/unreleased/Fixed-20230621-141828.yaml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changes/unreleased/Fixed-20230621-141828.yaml diff --git a/.changes/unreleased/Fixed-20230621-141828.yaml b/.changes/unreleased/Fixed-20230621-141828.yaml new file mode 100644 index 000000000..2c7f94488 --- /dev/null +++ b/.changes/unreleased/Fixed-20230621-141828.yaml @@ -0,0 +1,5 @@ +kind: Fixed +body: Fix deletion and re-creation of filiation relationship +time: 2023-06-21T14:18:28.437876316+02:00 +custom: + Issue: "82" From 659dff3d2c310951bf3a0dce6474ed375e4d5b55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Fri, 23 Jun 2023 12:19:40 +0200 Subject: [PATCH 198/321] DX: Add features to filterOrder Allow to add single checkboxes and entitychoices to filter order --- .changes/unreleased/DX-20230623-122408.yaml | 5 ++ .../Form/Type/Listing/FilterOrderType.php | 54 ++++++------- .../views/FilterOrder/base.html.twig | 50 ++++++++++-- .../Templating/Listing/FilterOrderHelper.php | 76 +++++++++++++++++-- .../Listing/FilterOrderHelperBuilder.php | 39 ++++++++++ .../Templating/Listing/Templating.php | 39 +++++++++- 6 files changed, 224 insertions(+), 39 deletions(-) create mode 100644 .changes/unreleased/DX-20230623-122408.yaml diff --git a/.changes/unreleased/DX-20230623-122408.yaml b/.changes/unreleased/DX-20230623-122408.yaml new file mode 100644 index 000000000..58dd96180 --- /dev/null +++ b/.changes/unreleased/DX-20230623-122408.yaml @@ -0,0 +1,5 @@ +kind: DX +body: '[FilterOrderHelper] add entity choice and singleCheckbox' +time: 2023-06-23T12:24:08.133491895+02:00 +custom: + Issue: "" diff --git a/src/Bundle/ChillMainBundle/Form/Type/Listing/FilterOrderType.php b/src/Bundle/ChillMainBundle/Form/Type/Listing/FilterOrderType.php index aaa6afa24..16038515d 100644 --- a/src/Bundle/ChillMainBundle/Form/Type/Listing/FilterOrderType.php +++ b/src/Bundle/ChillMainBundle/Form/Type/Listing/FilterOrderType.php @@ -13,6 +13,8 @@ namespace Chill\MainBundle\Form\Type\Listing; use Chill\MainBundle\Form\Type\ChillDateType; use Chill\MainBundle\Templating\Listing\FilterOrderHelper; +use Symfony\Bridge\Doctrine\Form\Type\EntityType; +use Symfony\Component\Form\Extension\Core\Type\CheckboxType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\Extension\Core\Type\HiddenType; use Symfony\Component\Form\Extension\Core\Type\SearchType; @@ -27,13 +29,6 @@ use function count; final class FilterOrderType extends \Symfony\Component\Form\AbstractType { - private RequestStack $requestStack; - - public function __construct(RequestStack $requestStack) - { - $this->requestStack = $requestStack; - } - public function buildForm(FormBuilderInterface $builder, array $options) { /** @var FilterOrderHelper $helper */ @@ -71,6 +66,25 @@ final class FilterOrderType extends \Symfony\Component\Form\AbstractType $builder->add($checkboxesBuilder); } + if ([] !== $helper->getEntityChoices()) { + $entityChoicesBuilder = $builder->create('entity_choices', null, ['compound' => true]); + + foreach ($helper->getEntityChoices() as $key => [ + 'label' => $label, 'choices' => $choices, 'options' => $opts, 'class' => $class + ]) { + $entityChoicesBuilder->add($key, EntityType::class, [ + 'label' => $label, + 'choices' => $choices, + 'class' => $class, + 'multiple' => true, + 'expanded' => true, + ...$opts, + ]); + } + + $builder->add($entityChoicesBuilder); + } + if (0 < count($helper->getDateRanges())) { $dateRangesBuilder = $builder->create('dateRanges', null, ['compound' => true]); @@ -97,28 +111,14 @@ final class FilterOrderType extends \Symfony\Component\Form\AbstractType $builder->add($dateRangesBuilder); } - foreach ($this->requestStack->getCurrentRequest()->query->getIterator() as $key => $value) { - switch ($key) { - case 'q': - case 'checkboxes' . $key: - case $key . '_from': - case $key . '_to': - break; + if ([] !== $helper->getSingleCheckbox()) { + $singleCheckBoxBuilder = $builder->create('single_checkboxes', null, ['compound' => true]); - case 'page': - $builder->add($key, HiddenType::class, [ - 'data' => 1, - ]); - - break; - - default: - $builder->add($key, HiddenType::class, [ - 'data' => $value, - ]); - - break; + foreach ($helper->getSingleCheckbox() as $name => ['label' => $label]) { + $singleCheckBoxBuilder->add($name, CheckboxType::class, ['label' => $label, 'required' => false]); } + + $builder->add($singleCheckBoxBuilder); } } diff --git a/src/Bundle/ChillMainBundle/Resources/views/FilterOrder/base.html.twig b/src/Bundle/ChillMainBundle/Resources/views/FilterOrder/base.html.twig index 1f1e54c72..d4a6bbdd4 100644 --- a/src/Bundle/ChillMainBundle/Resources/views/FilterOrder/base.html.twig +++ b/src/Bundle/ChillMainBundle/Resources/views/FilterOrder/base.html.twig @@ -13,13 +13,13 @@ {% if form.dateRanges is defined %} {% if form.dateRanges|length > 0 %} {% for dateRangeName, _o in form.dateRanges %} -
    +
    {% if form.dateRanges[dateRangeName].vars.label is not same as(false) %} -
    +
    {{ form_label(form.dateRanges[dateRangeName])}}
    {% endif %} -
    +
    {{ 'chill_calendar.From'|trans }} {{ form_widget(form.dateRanges[dateRangeName]['from']) }} @@ -27,7 +27,7 @@ {{ form_widget(form.dateRanges[dateRangeName]['to']) }}
    -
    +
    @@ -37,7 +37,7 @@ {% if form.checkboxes is defined %} {% if form.checkboxes|length > 0 %} {% for checkbox_name, options in form.checkboxes %} -
    +
    {% for c in form['checkboxes'][checkbox_name].children %}
    @@ -61,5 +61,45 @@ {% endfor %} {% endif %} {% endif %} + {% if form.entity_choices is defined %} + {% if form.entity_choices |length > 0 %} + {% for checkbox_name, options in form.entity_choices %} +
    + {% if form.entity_choices[checkbox_name].vars.label is not same as(false) %} +
    + {{ form_label(form.entity_choices[checkbox_name])}} +
    + {% endif %} +
    + {% for c in form['entity_choices'][checkbox_name].children %} +
    + {{ form_widget(c) }} + {{ form_label(c) }} +
    + {% endfor %} +
    +
    + +
    +
    + {% endfor %} + {% endif %} + {% endif %} + {% if form.single_checkboxes is defined %} + {% for name, _o in form.single_checkboxes %} +
    +
    + {{ form_widget(form.single_checkboxes[name]) }} +
    +
    + +
    +
    + {% endfor %} + {% endif %}
    + + {% for k,v in otherParameters %} + + {% endfor %} {{ form_end(form) }} diff --git a/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelper.php b/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelper.php index 367cc0861..28cc8e331 100644 --- a/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelper.php +++ b/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelper.php @@ -13,6 +13,8 @@ namespace Chill\MainBundle\Templating\Listing; use Chill\MainBundle\Form\Type\Listing\FilterOrderType; use DateTimeImmutable; +use Symfony\Component\Form\Extension\Core\Type\FormType; +use Symfony\Component\Form\Extension\Core\Type\HiddenType; use Symfony\Component\Form\FormFactoryInterface; use Symfony\Component\Form\FormInterface; use Symfony\Component\HttpFoundation\RequestStack; @@ -24,11 +26,16 @@ class FilterOrderHelper { private array $checkboxes = []; + /** + * @var array + */ + private array $singleCheckbox = []; + private array $dateRanges = []; private FormFactoryInterface $formFactory; - private ?string $formName = 'f'; + public const FORM_NAME = 'f'; private array $formOptions = []; @@ -40,6 +47,11 @@ class FilterOrderHelper private ?array $submitted = null; + /** + * @var array + */ + private array $entityChoices = []; + public function __construct( FormFactoryInterface $formFactory, RequestStack $requestStack @@ -48,7 +60,29 @@ class FilterOrderHelper $this->requestStack = $requestStack; } - public function addCheckbox(string $name, array $choices, ?array $default = [], ?array $trans = []): self + public function addSingleCheckbox(string $name, string $label): self + { + $this->singleCheckbox[$name] = ['label' => $label]; + + return $this; + } + + /** + * @param class-string $class + */ + public function addEntityChoice(string $name, string $class, string $label, array $choices, array $options = []): self + { + $this->entityChoices[$name] = ['label' => $label, 'class' => $class, 'choices' => $choices, 'options' => $options]; + + return $this; + } + + public function getEntityChoices(): array + { + return $this->entityChoices; + } + + public function addCheckbox(string $name, array $choices, ?array $default = [], ?array $trans = [], array $options = []): self { $missing = count($choices) - count($trans) - 1; $this->checkboxes[$name] = [ @@ -58,6 +92,7 @@ class FilterOrderHelper 0 < $missing ? array_fill(0, $missing, null) : [] ), + ...$options, ]; return $this; @@ -73,7 +108,7 @@ class FilterOrderHelper public function buildForm(): FormInterface { return $this->formFactory - ->createNamed($this->formName, $this->formType, $this->getDefaultData(), array_merge([ + ->createNamed(self::FORM_NAME, $this->formType, $this->getDefaultData(), array_merge([ 'helper' => $this, 'method' => 'GET', 'csrf_protection' => false, @@ -86,13 +121,31 @@ class FilterOrderHelper return $this->getFormData()['checkboxes'][$name]; } + public function getSingleCheckboxData(string $name): ?bool + { + return $this->getFormData()['single_checkboxes'][$name]; + } + + public function getEntityChoiceData($name): mixed + { + return $this->getFormData()['entity_choices'][$name]; + } + public function getCheckboxes(): array { return $this->checkboxes; } /** - * @return array<'to': DateTimeImmutable, 'from': DateTimeImmutable> + * @return array + */ + public function getSingleCheckbox(): array + { + return $this->singleCheckbox; + } + + /** + * @return array{to: ?DateTimeImmutable, from: ?DateTimeImmutable} */ public function getDateRangeData(string $name): array { @@ -123,7 +176,12 @@ class FilterOrderHelper private function getDefaultData(): array { - $r = []; + $r = [ + 'checkboxes' => [], + 'dateRanges' => [], + 'single_checkboxes' => [], + 'entity_choices' => [] + ]; if ($this->hasSearchBox()) { $r['q'] = ''; @@ -138,6 +196,14 @@ class FilterOrderHelper $r['dateRanges'][$name]['to'] = $defaults['to']; } + foreach ($this->singleCheckbox as $name => $c) { + $r['single_checkboxes'][$name] = false; + } + + foreach ($this->entityChoices as $name => $c) { + $r['entity_choices'][$name] = ($c['options']['multiple'] ?? true) ? [] : null; + } + return $r; } diff --git a/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelperBuilder.php b/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelperBuilder.php index d68c8c37a..e176e27c6 100644 --- a/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelperBuilder.php +++ b/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelperBuilder.php @@ -27,6 +27,16 @@ class FilterOrderHelperBuilder private ?array $searchBoxFields = null; + /** + * @var array + */ + private array $singleCheckboxes = []; + + /** + * @var array + */ + private array $entityChoices = []; + public function __construct( FormFactoryInterface $formFactory, RequestStack $requestStack @@ -35,6 +45,13 @@ class FilterOrderHelperBuilder $this->requestStack = $requestStack; } + public function addSingleCheckbox(string $name, string $label): self + { + $this->singleCheckboxes[$name] = ['label' => $label]; + + return $this; + } + public function addCheckbox(string $name, array $choices, ?array $default = [], ?array $trans = []): self { $this->checkboxes[$name] = ['choices' => $choices, 'default' => $default, 'trans' => $trans]; @@ -42,6 +59,16 @@ class FilterOrderHelperBuilder return $this; } + /** + * @param class-string $class + */ + public function addEntityChoice(string $name, string $label, string $class, array $choices, ?array $options = []): self + { + $this->entityChoices[$name] = ['label' => $label, 'class' => $class, 'choices' => $choices, 'options' => $options]; + + return $this; + } + public function addDateRange(string $name, ?string $label = null, ?DateTimeImmutable $from = null, ?DateTimeImmutable $to = null): self { $this->dateRanges[$name] = ['from' => $from, 'to' => $to, 'label' => $label]; @@ -75,6 +102,18 @@ class FilterOrderHelperBuilder $helper->addCheckbox($name, $choices, $default, $trans); } + foreach ( + $this->singleCheckboxes as $name => ['label' => $label] + ) { + $helper->addSingleCheckbox($name, $label); + } + + foreach ( + $this->entityChoices as $name => ['label' => $label, 'class' => $class, 'choices' => $choices, 'options' => $options] + ) { + $helper->addEntityChoice($name, $class, $label, $choices, $options); + } + foreach ( $this->dateRanges as $name => [ 'from' => $from, diff --git a/src/Bundle/ChillMainBundle/Templating/Listing/Templating.php b/src/Bundle/ChillMainBundle/Templating/Listing/Templating.php index bc256e24f..b91cd86e8 100644 --- a/src/Bundle/ChillMainBundle/Templating/Listing/Templating.php +++ b/src/Bundle/ChillMainBundle/Templating/Listing/Templating.php @@ -11,13 +11,23 @@ declare(strict_types=1); namespace Chill\MainBundle\Templating\Listing; +use Chill\MainBundle\Pagination\PaginatorFactory; +use Symfony\Component\HttpFoundation\RequestStack; use Twig\Environment; +use Twig\Error\LoaderError; +use Twig\Error\RuntimeError; +use Twig\Error\SyntaxError; use Twig\Extension\AbstractExtension; use Twig\TwigFilter; class Templating extends AbstractExtension { - public function getFilters() + public function __construct( + private readonly RequestStack $requestStack, + ) { + } + + public function getFilters(): array { return [ new TwigFilter('chill_render_filter_order_helper', [$this, 'renderFilterOrderHelper'], [ @@ -26,16 +36,41 @@ class Templating extends AbstractExtension ]; } + /** + * @throws SyntaxError + * @throws RuntimeError + * @throws LoaderError + */ public function renderFilterOrderHelper( Environment $environment, FilterOrderHelper $helper, ?string $template = '@ChillMain/FilterOrder/base.html.twig', ?array $options = [] - ) { + ): string { + $otherParameters = []; + + foreach ($this->requestStack->getCurrentRequest()->query->getIterator() as $key => $value) { + switch ($key) { + case FilterOrderHelper::FORM_NAME: + break; + + case PaginatorFactory::DEFAULT_CURRENT_PAGE_KEY: + // when filtering, go back to page 1 + $otherParameters[PaginatorFactory::DEFAULT_CURRENT_PAGE_KEY] = 1; + + break; + default: + $otherParameters[$key] = $value; + + break; + } + } + return $environment->render($template, [ 'helper' => $helper, 'form' => $helper->buildForm()->createView(), 'options' => $options, + 'otherParameters' => $otherParameters, ]); } } From 51544cfc48418e3492d43b232081efabf5d1772e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Fri, 23 Jun 2023 12:21:13 +0200 Subject: [PATCH 199/321] DX: improve typing of a property in UserJob --- src/Bundle/ChillMainBundle/Entity/UserJob.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Bundle/ChillMainBundle/Entity/UserJob.php b/src/Bundle/ChillMainBundle/Entity/UserJob.php index ed8bc43f3..c6bfe1aa3 100644 --- a/src/Bundle/ChillMainBundle/Entity/UserJob.php +++ b/src/Bundle/ChillMainBundle/Entity/UserJob.php @@ -37,7 +37,7 @@ class UserJob protected ?int $id = null; /** - * @var array|string[]A + * @var array * @ORM\Column(name="label", type="json") * @Serializer\Groups({"read", "docgen:read"}) * @Serializer\Context({"is-translatable": true}, groups={"docgen:read"}) From f7c11d356737351d7fda548b3bb5d0acc7b0fac4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Fri, 23 Jun 2023 12:22:24 +0200 Subject: [PATCH 200/321] Feature: Add filters on activity list --- .../unreleased/Feature-20230623-122530.yaml | 5 + .../unreleased/Feature-20230623-122702.yaml | 6 + .../Controller/ActivityController.php | 138 ++++---- .../Repository/ActivityACLAwareRepository.php | 240 ++++++++++--- .../ActivityACLAwareRepositoryInterface.php | 36 +- .../Repository/ActivityTypeRepository.php | 4 + .../ActivityTypeRepositoryInterface.php | 4 +- .../Resources/views/Activity/list.html.twig | 3 + .../ActivityACLAwareRepositoryTest.php | 325 ++++++++++++++++++ .../translations/messages.fr.yml | 8 + 10 files changed, 648 insertions(+), 121 deletions(-) create mode 100644 .changes/unreleased/Feature-20230623-122530.yaml create mode 100644 .changes/unreleased/Feature-20230623-122702.yaml create mode 100644 src/Bundle/ChillActivityBundle/Tests/Repository/ActivityACLAwareRepositoryTest.php diff --git a/.changes/unreleased/Feature-20230623-122530.yaml b/.changes/unreleased/Feature-20230623-122530.yaml new file mode 100644 index 000000000..922750ea8 --- /dev/null +++ b/.changes/unreleased/Feature-20230623-122530.yaml @@ -0,0 +1,5 @@ +kind: Feature +body: '[activity list] add filtering for activities list' +time: 2023-06-23T12:25:30.49643551+02:00 +custom: + Issue: "" diff --git a/.changes/unreleased/Feature-20230623-122702.yaml b/.changes/unreleased/Feature-20230623-122702.yaml new file mode 100644 index 000000000..e1d1b0e1f --- /dev/null +++ b/.changes/unreleased/Feature-20230623-122702.yaml @@ -0,0 +1,6 @@ +kind: Feature +body: '[activity list] in person context, show also the activities from the accompanying + periods where the person participates' +time: 2023-06-23T12:27:02.159041095+02:00 +custom: + Issue: "" diff --git a/src/Bundle/ChillActivityBundle/Controller/ActivityController.php b/src/Bundle/ChillActivityBundle/Controller/ActivityController.php index 444c663fc..07e4fcf62 100644 --- a/src/Bundle/ChillActivityBundle/Controller/ActivityController.php +++ b/src/Bundle/ChillActivityBundle/Controller/ActivityController.php @@ -18,11 +18,16 @@ use Chill\ActivityBundle\Repository\ActivityACLAwareRepositoryInterface; use Chill\ActivityBundle\Repository\ActivityRepository; use Chill\ActivityBundle\Repository\ActivityTypeCategoryRepository; use Chill\ActivityBundle\Repository\ActivityTypeRepositoryInterface; +use Chill\ActivityBundle\Repository\ActivityUserJobRepository; use Chill\ActivityBundle\Security\Authorization\ActivityVoter; use Chill\MainBundle\Entity\Embeddable\CommentEmbeddable; +use Chill\MainBundle\Entity\UserJob; use Chill\MainBundle\Repository\LocationRepository; use Chill\MainBundle\Repository\UserRepositoryInterface; use Chill\MainBundle\Security\Resolver\CenterResolverManagerInterface; +use Chill\MainBundle\Templating\Listing\FilterOrderHelper; +use Chill\MainBundle\Templating\Listing\FilterOrderHelperFactoryInterface; +use Chill\MainBundle\Templating\TranslatableStringHelperInterface; use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\Person; use Chill\PersonBundle\Privacy\PrivacyEvent; @@ -47,68 +52,25 @@ use function array_key_exists; final class ActivityController extends AbstractController { - private AccompanyingPeriodRepository $accompanyingPeriodRepository; - - private ActivityACLAwareRepositoryInterface $activityACLAwareRepository; - - private ActivityRepository $activityRepository; - - private ActivityTypeCategoryRepository $activityTypeCategoryRepository; - - private ActivityTypeRepositoryInterface $activityTypeRepository; - - private CenterResolverManagerInterface $centerResolver; - - private EntityManagerInterface $entityManager; - - private EventDispatcherInterface $eventDispatcher; - - private LocationRepository $locationRepository; - - private LoggerInterface $logger; - - private PersonRepository $personRepository; - - private SerializerInterface $serializer; - - private ThirdPartyRepository $thirdPartyRepository; - - private TranslatorInterface $translator; - - private UserRepositoryInterface $userRepository; - public function __construct( - ActivityACLAwareRepositoryInterface $activityACLAwareRepository, - ActivityTypeRepositoryInterface $activityTypeRepository, - ActivityTypeCategoryRepository $activityTypeCategoryRepository, - PersonRepository $personRepository, - ThirdPartyRepository $thirdPartyRepository, - LocationRepository $locationRepository, - ActivityRepository $activityRepository, - AccompanyingPeriodRepository $accompanyingPeriodRepository, - EntityManagerInterface $entityManager, - EventDispatcherInterface $eventDispatcher, - LoggerInterface $logger, - SerializerInterface $serializer, - UserRepositoryInterface $userRepository, - CenterResolverManagerInterface $centerResolver, - TranslatorInterface $translator + private readonly ActivityACLAwareRepositoryInterface $activityACLAwareRepository, + private readonly ActivityTypeRepositoryInterface $activityTypeRepository, + private readonly ActivityTypeCategoryRepository $activityTypeCategoryRepository, + private readonly PersonRepository $personRepository, + private readonly ThirdPartyRepository $thirdPartyRepository, + private readonly LocationRepository $locationRepository, + private readonly ActivityRepository $activityRepository, + private readonly AccompanyingPeriodRepository $accompanyingPeriodRepository, + private readonly EntityManagerInterface $entityManager, + private readonly EventDispatcherInterface $eventDispatcher, + private readonly LoggerInterface $logger, + private readonly SerializerInterface $serializer, + private readonly UserRepositoryInterface $userRepository, + private readonly CenterResolverManagerInterface $centerResolver, + private readonly TranslatorInterface $translator, + private readonly FilterOrderHelperFactoryInterface $filterOrderHelperFactory, + private readonly TranslatableStringHelperInterface $translatableStringHelper, ) { - $this->activityACLAwareRepository = $activityACLAwareRepository; - $this->activityTypeRepository = $activityTypeRepository; - $this->activityTypeCategoryRepository = $activityTypeCategoryRepository; - $this->personRepository = $personRepository; - $this->thirdPartyRepository = $thirdPartyRepository; - $this->locationRepository = $locationRepository; - $this->activityRepository = $activityRepository; - $this->accompanyingPeriodRepository = $accompanyingPeriodRepository; - $this->entityManager = $entityManager; - $this->eventDispatcher = $eventDispatcher; - $this->logger = $logger; - $this->serializer = $serializer; - $this->userRepository = $userRepository; - $this->centerResolver = $centerResolver; - $this->translator = $translator; } /** @@ -292,11 +254,27 @@ final class ActivityController extends AbstractController // TODO: add pagination [$person, $accompanyingPeriod] = $this->getEntity($request); + $filter = $this->buildFilterOrder($person ?? $accompanyingPeriod); + + $filterArgs = [ + 'my_activities' => $filter->getSingleCheckboxData('my_activities'), + 'types' => $filter->getEntityChoiceData('activity_types'), + 'jobs' => $filter->getEntityChoiceData('jobs'), + 'before' => $filter->getDateRangeData('activity_date')['to'], + 'after' => $filter->getDateRangeData('activity_date')['from'], + ]; if ($person instanceof Person) { $this->denyAccessUnlessGranted(ActivityVoter::SEE, $person); $activities = $this->activityACLAwareRepository - ->findByPerson($person, ActivityVoter::SEE, 0, null, ['date' => 'DESC', 'id' => 'DESC']); + ->findByPerson( + $person, + ActivityVoter::SEE, + 0, + null, + ['date' => 'DESC', 'id' => 'DESC'], + $filterArgs + ); $event = new PrivacyEvent($person, [ 'element_class' => Activity::class, @@ -309,7 +287,14 @@ final class ActivityController extends AbstractController $this->denyAccessUnlessGranted(ActivityVoter::SEE, $accompanyingPeriod); $activities = $this->activityACLAwareRepository - ->findByAccompanyingPeriod($accompanyingPeriod, ActivityVoter::SEE, 0, null, ['date' => 'DESC', 'id' => 'DESC']); + ->findByAccompanyingPeriod( + $accompanyingPeriod, + ActivityVoter::SEE, + 0, + null, + ['date' => 'DESC', 'id' => 'DESC'], + $filterArgs + ); $view = 'ChillActivityBundle:Activity:listAccompanyingCourse.html.twig'; } @@ -320,10 +305,39 @@ final class ActivityController extends AbstractController 'activities' => $activities, 'person' => $person, 'accompanyingCourse' => $accompanyingPeriod, + 'filter' => $filter, ] ); } + private function buildFilterOrder(AccompanyingPeriod|Person $associated): FilterOrderHelper + { + + $filterBuilder = $this->filterOrderHelperFactory->create(self::class); + $types = $this->activityACLAwareRepository->findActivityTypeByAssociated($associated); + $jobs = $this->activityACLAwareRepository->findUserJobByAssociated($associated); + + $filterBuilder + ->addDateRange('activity_date', 'activity.date') + ->addSingleCheckbox('my_activities', 'activity_filter.My activities') + ->addEntityChoice('activity_types', 'activity_filter.Types', \Chill\ActivityBundle\Entity\ActivityType::class, $types, [ + 'choice_label' => function (\Chill\ActivityBundle\Entity\ActivityType $activityType) { + $text = match ($activityType->hasCategory()) { + true => $this->translatableStringHelper->localize($activityType->getCategory()->getName()) . ' > ', + false => '', + }; + + return $text . $this->translatableStringHelper->localize($activityType->getName()); + } + ]) + ->addEntityChoice('jobs', 'activity_filter.Jobs', UserJob::class, $jobs, [ + 'choice_label' => fn (UserJob $u) => $this->translatableStringHelper->localize($u->getLabel()) + ]) + ; + + return $filterBuilder->build(); + } + public function newAction(Request $request): Response { $view = null; diff --git a/src/Bundle/ChillActivityBundle/Repository/ActivityACLAwareRepository.php b/src/Bundle/ChillActivityBundle/Repository/ActivityACLAwareRepository.php index 1f2039a2c..1fd0a57d6 100644 --- a/src/Bundle/ChillActivityBundle/Repository/ActivityACLAwareRepository.php +++ b/src/Bundle/ChillActivityBundle/Repository/ActivityACLAwareRepository.php @@ -18,67 +18,159 @@ use Chill\ActivityBundle\Security\Authorization\ActivityVoter; use Chill\MainBundle\Entity\Location; use Chill\MainBundle\Entity\LocationType; use Chill\MainBundle\Entity\Scope; -use Chill\MainBundle\Security\Authorization\AuthorizationHelper; -use Chill\MainBundle\Security\Resolver\CenterResolverDispatcherInterface; +use Chill\MainBundle\Entity\User; +use Chill\MainBundle\Entity\UserJob; +use Chill\MainBundle\Security\Authorization\AuthorizationHelperForCurrentUserInterface; +use Chill\MainBundle\Security\Resolver\CenterResolverManagerInterface; use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\Person; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\AbstractQuery; use Doctrine\ORM\EntityManagerInterface; +use Doctrine\ORM\Query\Expr\Join; use Doctrine\ORM\Query\ResultSetMappingBuilder; -use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; -use Symfony\Component\Security\Core\Role\Role; +use Doctrine\ORM\QueryBuilder; +use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\Security\Core\Security; use function count; use function in_array; -final class ActivityACLAwareRepository implements ActivityACLAwareRepositoryInterface +final readonly class ActivityACLAwareRepository implements ActivityACLAwareRepositoryInterface { - private AuthorizationHelper $authorizationHelper; - - private CenterResolverDispatcherInterface $centerResolverDispatcher; - - private EntityManagerInterface $em; - - private ActivityRepository $repository; - - private Security $security; - - private TokenStorageInterface $tokenStorage; - public function __construct( - AuthorizationHelper $authorizationHelper, - CenterResolverDispatcherInterface $centerResolverDispatcher, - TokenStorageInterface $tokenStorage, - ActivityRepository $repository, - EntityManagerInterface $em, - Security $security + private AuthorizationHelperForCurrentUserInterface $authorizationHelper, + private CenterResolverManagerInterface $centerResolverManager, + private ActivityRepository $repository, + private EntityManagerInterface $em, + private Security $security, + private RequestStack $requestStack, ) { - $this->authorizationHelper = $authorizationHelper; - $this->centerResolverDispatcher = $centerResolverDispatcher; - $this->tokenStorage = $tokenStorage; - $this->repository = $repository; - $this->em = $em; - $this->security = $security; } - public function findByAccompanyingPeriod(AccompanyingPeriod $period, string $role, ?int $start = 0, ?int $limit = 1000, ?array $orderBy = []): array + public function findByAccompanyingPeriod(AccompanyingPeriod $period, string $role, ?int $start = 0, ?int $limit = 1000, array $orderBy = ['date' => 'DESC'], array $filters = []): array { - $user = $this->security->getUser(); - $center = $this->centerResolverDispatcher->resolveCenter($period); + $qb = $this->buildBaseQuery($filters); - if (0 === count($orderBy)) { - $orderBy = ['date' => 'DESC']; + $qb->andWhere('a.accompanyingPeriod = :period')->setParameter('period', $period); + + foreach ($orderBy as $field => $order) { + $qb->addOrderBy('a.' . $field, $order); } - $scopes = $this->authorizationHelper - ->getReachableCircles($user, $role, $center); + $qb->setFirstResult(0)->setMaxResults(1000); - return $this->em->getRepository(Activity::class) - ->findByAccompanyingPeriod($period, $scopes, true, $limit, $start, $orderBy); + return $qb->getQuery()->getResult(); } + public function buildBaseQuery(array $filters): QueryBuilder + { + $qb = $this->repository + ->createQueryBuilder('a') + ; + + if (($filters['my_activities'] ?? false) and ($user = $this->security->getUser()) instanceof User) { + $qb->andWhere( + $qb->expr()->orX( + 'a.createdBy = :user', + 'a.user = :user', + ':user MEMBER OF a.users' + ) + )->setParameter('user', $user); + } + + if ([] !== ($types = $filters['types'] ?? [])) { + $qb->andWhere('a.activityType IN (:types)')->setParameter('types', $types); + } + + if ([] !== ($jobs = $filters['jobs'] ?? [])) { + $qb + ->leftJoin('a.createdBy', 'creator') + ->leftJoin('a.user', 'activity_u') + ->andWhere( + $qb->expr()->orX( + 'creator.userJob IN (:jobs)', + 'activity_u.userJob IN (:jobs)', + 'EXISTS (SELECT 1 FROM ' . User::class . ' activity_user WHERE activity_user MEMBER OF a.users AND activity_user.userJob IN (:jobs))' + ) + ) + ->setParameter('jobs', $jobs); + } + + if (null !== ($after = $filters['after'] ?? null)) { + $qb->andWhere('a.date >= :after')->setParameter('after', $after); + } + + if (null !== ($before = $filters['before'] ?? null)) { + $qb->andWhere('a.date <= :before')->setParameter('before', $before); + } + + return $qb; + } + + /** + * @param AccompanyingPeriod|Person $associated + * @return array + */ + public function findActivityTypeByAssociated(AccompanyingPeriod|Person $associated): array + { + $in = $this->em->createQueryBuilder(); + $in + ->select('1') + ->from(Activity::class, 'a'); + + if ($associated instanceof Person) { + $in = $this->filterBaseQueryByPerson($in, $associated, ActivityVoter::SEE); + } else { + $in->andWhere('a.accompanyingPeriod = :period')->setParameter('period', $associated); + } + + // join between the embedded exist query and the main query + $in->andWhere('a.activityType = t'); + + $qb = $this->em->createQueryBuilder()->setParameters($in->getParameters()); + $qb + ->select('t') + ->from(ActivityType::class, 't') + ->where( + $qb->expr()->exists($in->getDQL()) + ); + + return $qb->getQuery()->getResult(); + } + + public function findUserJobByAssociated(Person|AccompanyingPeriod $associated): array + { + $in = $this->em->createQueryBuilder(); + $in->select('IDENTITY(u.userJob)') + ->from(User::class, 'u') + ->join( + Activity::class, + 'a', + Join::WITH, + 'a.createdBy = u OR a.user = u OR u MEMBER OF a.users' + ); + + if ($associated instanceof Person) { + $in = $this->filterBaseQueryByPerson($in, $associated, ActivityVoter::SEE); + } else { + $in->andWhere('a.accompanyingPeriod = :associated'); + $in->setParameter('associated', $associated); + } + + $qb = $this->em->createQueryBuilder()->setParameters($in->getParameters()); + + $qb->select('ub', 'JSON_EXTRACT(ub.label, :lang) AS HIDDEN lang') + ->from(UserJob::class, 'ub') + ->where($qb->expr()->in('ub.id', $in->getDQL())) + ->setParameter('lang', $this->requestStack->getCurrentRequest()->getLocale()) + ->orderBy('lang') + ; + + return $qb->getQuery()->getResult(); + } + + public function findByAccompanyingPeriodSimplified(AccompanyingPeriod $period, ?int $limit = 1000): array { $rsm = new ResultSetMappingBuilder($this->em); @@ -159,25 +251,66 @@ final class ActivityACLAwareRepository implements ActivityACLAwareRepositoryInte return $nq->getResult(AbstractQuery::HYDRATE_ARRAY); } - /** - * @param array $orderBy - * - * @return Activity[]|array - */ - public function findByPerson(Person $person, string $role, ?int $start = 0, ?int $limit = 1000, ?array $orderBy = []): array + public function findByPerson(Person $person, string $role, ?int $start = 0, ?int $limit = 1000, ?array $orderBy = [], array $filters = []): array { - $user = $this->security->getUser(); - $center = $this->centerResolverDispatcher->resolveCenter($person); + $qb = $this->buildBaseQuery($filters); - if (0 === count($orderBy)) { - $orderBy = ['date' => 'DESC']; + $qb = $this->filterBaseQueryByPerson($qb, $person, $role); + + foreach ($orderBy as $field => $direction) { + $qb->addOrderBy('a.' . $field, $direction); } - $reachableScopes = $this->authorizationHelper - ->getReachableCircles($user, $role, $center); + return $qb->getQuery()->getResult(); + } - return $this->em->getRepository(Activity::class) - ->findByPersonImplied($person, $reachableScopes, $orderBy, $limit, $start); + private function filterBaseQueryByPerson(QueryBuilder $qb, Person $person, string $role): QueryBuilder + { + $orX = $qb->expr()->orX(); + $counter = 0; + foreach ($this->centerResolverManager->resolveCenters($person) as $center) { + $scopes = $this->authorizationHelper->getReachableScopes($role, $center); + + if ([] === $scopes) { + continue; + } + + $orX->add(sprintf('a.person = :person AND a.scope IN (:scopes_%d)', $counter)); + $qb->setParameter(sprintf('scopes_%d', $counter), $scopes); + $qb->setParameter('person', $person); + $counter++; + } + + foreach ($person->getAccompanyingPeriodParticipations() as $participation) { + if (!$this->security->isGranted(ActivityVoter::SEE, $participation->getAccompanyingPeriod())) { + continue; + } + + $and = $qb->expr()->andX( + sprintf('a.accompanyingPeriod = :period_%d', $counter), + sprintf('a.date >= :participation_start_%d', $counter) + ); + + $qb + ->setParameter(sprintf('period_%d', $counter), $participation->getAccompanyingPeriod()) + ->setParameter(sprintf('participation_start_%d', $counter), $participation->getStartDate()); + + if (null !== $participation->getEndDate()) { + $and->add(sprintf('a.date < :participation_end_%d', $counter)); + $qb + ->setParameter(sprintf('participation_end_%d', $counter), $participation->getEndDate()); + } + $orX->add($and); + $counter++; + } + + if (0 === $orX->count()) { + $qb->andWhere('FALSE = TRUE'); + } else { + $qb->andWhere($orX); + } + + return $qb; } public function queryTimelineIndexer(string $context, array $args = []): array @@ -226,7 +359,6 @@ final class ActivityACLAwareRepository implements ActivityACLAwareRepositoryInte // acls: $reachableCenters = $this->authorizationHelper->getReachableCenters( - $this->tokenStorage->getToken()->getUser(), ActivityVoter::SEE ); @@ -251,7 +383,7 @@ final class ActivityACLAwareRepository implements ActivityACLAwareRepositoryInte continue; } // we get all the reachable scopes for this center - $reachableScopes = $this->authorizationHelper->getReachableScopes($this->tokenStorage->getToken()->getUser(), ActivityVoter::SEE, $center); + $reachableScopes = $this->authorizationHelper->getReachableScopes(ActivityVoter::SEE, $center); // we get the ids for those scopes $reachablesScopesId = array_map( static fn (Scope $scope) => $scope->getId(), diff --git a/src/Bundle/ChillActivityBundle/Repository/ActivityACLAwareRepositoryInterface.php b/src/Bundle/ChillActivityBundle/Repository/ActivityACLAwareRepositoryInterface.php index 8cdb83524..a046ad218 100644 --- a/src/Bundle/ChillActivityBundle/Repository/ActivityACLAwareRepositoryInterface.php +++ b/src/Bundle/ChillActivityBundle/Repository/ActivityACLAwareRepositoryInterface.php @@ -11,15 +11,22 @@ declare(strict_types=1); namespace Chill\ActivityBundle\Repository; +use Chill\ActivityBundle\Entity\Activity; +use Chill\ActivityBundle\Entity\ActivityType; +use Chill\MainBundle\Entity\UserJob; use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\Person; interface ActivityACLAwareRepositoryInterface { /** - * @return Activity[]|array + * Return all the activities associated to an accompanying period and that the user is allowed to apply the given role. + * + * + * @param array{my_activities?: bool, types?: array, jobs?: array, after?: \DateTimeImmutable|null, before?: \DateTimeImmutable|null} $filters + * @return array */ - public function findByAccompanyingPeriod(AccompanyingPeriod $period, string $role, ?int $start = 0, ?int $limit = 1000, ?array $orderBy = []): array; + public function findByAccompanyingPeriod(AccompanyingPeriod $period, string $role, ?int $start = 0, ?int $limit = 1000, array $orderBy = ['date' => 'DESC'], array $filters = []): array; /** * Return a list of activities, simplified as array (not object). @@ -31,7 +38,28 @@ interface ActivityACLAwareRepositoryInterface public function findByAccompanyingPeriodSimplified(AccompanyingPeriod $period, ?int $limit = 1000): array; /** - * @return Activity[]|array + * @param array{my_activities?: bool, types?: array, jobs?: array, after?: \DateTimeImmutable|null, before?: \DateTimeImmutable|null} $filters + * @return array */ - public function findByPerson(Person $person, string $role, ?int $start = 0, ?int $limit = 1000, ?array $orderBy = []): array; + public function findByPerson(Person $person, string $role, ?int $start = 0, ?int $limit = 1000, array $orderBy = ['date' => 'DESC'], array $filters = []): array; + + + /** + * Return a list of the type for the activities associated to person or accompanying period + * + * @return array + */ + public function findActivityTypeByAssociated(AccompanyingPeriod|Person $associated): array; + + /** + * Return a list of the user job for the activities associated to person or accompanying period + * + * Associated mean the job: + * - of the creator; + * - of the user (activity.user) + * - of all the users + * + * @return array + */ + public function findUserJobByAssociated(AccompanyingPeriod|Person $associated): array; } diff --git a/src/Bundle/ChillActivityBundle/Repository/ActivityTypeRepository.php b/src/Bundle/ChillActivityBundle/Repository/ActivityTypeRepository.php index fd5d52fce..10bd1e651 100644 --- a/src/Bundle/ChillActivityBundle/Repository/ActivityTypeRepository.php +++ b/src/Bundle/ChillActivityBundle/Repository/ActivityTypeRepository.php @@ -11,9 +11,13 @@ declare(strict_types=1); namespace Chill\ActivityBundle\Repository; +use Chill\ActivityBundle\Entity\Activity; use Chill\ActivityBundle\Entity\ActivityType; +use Chill\PersonBundle\Entity\AccompanyingPeriod; +use Chill\PersonBundle\Entity\Person; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityRepository; +use Doctrine\ORM\Query\Expr\Join; final class ActivityTypeRepository implements ActivityTypeRepositoryInterface { diff --git a/src/Bundle/ChillActivityBundle/Repository/ActivityTypeRepositoryInterface.php b/src/Bundle/ChillActivityBundle/Repository/ActivityTypeRepositoryInterface.php index 2148a02f5..574faea22 100644 --- a/src/Bundle/ChillActivityBundle/Repository/ActivityTypeRepositoryInterface.php +++ b/src/Bundle/ChillActivityBundle/Repository/ActivityTypeRepositoryInterface.php @@ -12,12 +12,14 @@ declare(strict_types=1); namespace Chill\ActivityBundle\Repository; use Chill\ActivityBundle\Entity\ActivityType; +use Chill\PersonBundle\Entity\AccompanyingPeriod; +use Chill\PersonBundle\Entity\Person; use Doctrine\Persistence\ObjectRepository; interface ActivityTypeRepositoryInterface extends ObjectRepository { /** - * @return array|ActivityType[] + * @return array */ public function findAllActive(): array; } diff --git a/src/Bundle/ChillActivityBundle/Resources/views/Activity/list.html.twig b/src/Bundle/ChillActivityBundle/Resources/views/Activity/list.html.twig index 79c946f17..17ae0598b 100644 --- a/src/Bundle/ChillActivityBundle/Resources/views/Activity/list.html.twig +++ b/src/Bundle/ChillActivityBundle/Resources/views/Activity/list.html.twig @@ -86,6 +86,9 @@

    {% else %} + + {{ filter|chill_render_filter_order_helper }} +
    {% for activity in activities %} {% include 'ChillActivityBundle:Activity:_list_item.html.twig' with { diff --git a/src/Bundle/ChillActivityBundle/Tests/Repository/ActivityACLAwareRepositoryTest.php b/src/Bundle/ChillActivityBundle/Tests/Repository/ActivityACLAwareRepositoryTest.php new file mode 100644 index 000000000..e7b2117d4 --- /dev/null +++ b/src/Bundle/ChillActivityBundle/Tests/Repository/ActivityACLAwareRepositoryTest.php @@ -0,0 +1,325 @@ +authorizationHelperForCurrentUser = self::$container->get(AuthorizationHelperForCurrentUserInterface::class); + $this->centerResolverManager = self::$container->get(CenterResolverManagerInterface::class); + $this->activityRepository = self::$container->get(ActivityRepository::class); + $this->entityManager = self::$container->get(EntityManagerInterface::class); + $this->security = self::$container->get(Security::class); + + $this->requestStack = $requestStack = new RequestStack(); + $request = $this->prophesize(Request::class); + $request->getLocale()->willReturn('fr'); + $request->getDefaultLocale()->willReturn('fr'); + $requestStack->push($request->reveal()); + } + + /** + * @dataProvider provideDataFindByAccompanyingPeriod + */ + public function testFindByAccompanyingPeriod(AccompanyingPeriod $period, User $user, string $role, ?int $start = 0, ?int $limit = 1000, array $orderBy = ['date' => 'DESC'], array $filters = []): void + { + $security = $this->prophesize(Security::class); + $security->isGranted($role, $period)->willReturn(true); + $security->getUser()->willReturn($user); + + $repository = new ActivityACLAwareRepository( + $this->authorizationHelperForCurrentUser, + $this->centerResolverManager, + $this->activityRepository, + $this->entityManager, + $security->reveal(), + $this->requestStack + ); + + $actual = $repository->findByAccompanyingPeriod($period, $role, $start, $limit, $orderBy, $filters); + + self::assertIsArray($actual); + } + + /** + * @dataProvider provideDataFindByAccompanyingPeriod + */ + public function testFindActivityTypeByAccompanyingPeriod(AccompanyingPeriod $period, User $user, string $role, ?int $start = 0, ?int $limit = 1000, array $orderBy = ['date' => 'DESC'], array $filters = []): void + { + $security = $this->prophesize(Security::class); + $security->isGranted($role, $period)->willReturn(true); + $security->getUser()->willReturn($user); + + $repository = new ActivityACLAwareRepository( + $this->authorizationHelperForCurrentUser, + $this->centerResolverManager, + $this->activityRepository, + $this->entityManager, + $security->reveal(), + $this->requestStack + ); + + $actual = $repository->findActivityTypeByAssociated($period); + + self::assertIsArray($actual); + } + + /** + * @dataProvider provideDataFindByPerson + */ + public function testFindActivityTypeByPerson(Person $person, User $user, array $centers, array $scopes, string $role, ?int $start = 0, ?int $limit = 1000, ?array $orderBy = [], array $filters = []): void + { + $role = ActivityVoter::SEE; + $centerResolver = $this->prophesize(CenterResolverManagerInterface::class); + $centerResolver->resolveCenters($person)->willReturn($centers); + + $authorizationHelper = $this->prophesize(AuthorizationHelperForCurrentUserInterface::class); + $authorizationHelper->getReachableScopes($role, Argument::type(Center::class)) + ->willReturn($scopes); + + $security = $this->prophesize(Security::class); + $security->isGranted($role, Argument::type(AccompanyingPeriod::class))->willReturn(true); + $security->getUser()->willReturn($user); + + $repository = new ActivityACLAwareRepository( + $authorizationHelper->reveal(), + $centerResolver->reveal(), + $this->activityRepository, + $this->entityManager, + $security->reveal(), + $this->requestStack + ); + + $actual = $repository->findByPerson($person, $role, $start, $limit, $orderBy, $filters); + + self::assertIsArray($actual); + } + + /** + * @dataProvider provideDataFindByPerson + */ + public function testFindByPerson(Person $person, User $user, array $centers, array $scopes, string $role, ?int $start = 0, ?int $limit = 1000, ?array $orderBy = [], array $filters = []): void + { + $centerResolver = $this->prophesize(CenterResolverManagerInterface::class); + $centerResolver->resolveCenters($person)->willReturn($centers); + + $authorizationHelper = $this->prophesize(AuthorizationHelperForCurrentUserInterface::class); + $authorizationHelper->getReachableScopes($role, Argument::type(Center::class)) + ->willReturn($scopes); + + $security = $this->prophesize(Security::class); + $security->isGranted($role, Argument::type(AccompanyingPeriod::class))->willReturn(true); + $security->getUser()->willReturn($user); + + $repository = new ActivityACLAwareRepository( + $authorizationHelper->reveal(), + $centerResolver->reveal(), + $this->activityRepository, + $this->entityManager, + $security->reveal(), + $this->requestStack + ); + + $actual = $repository->findByPerson($person, $role, $start, $limit, $orderBy, $filters); + + self::assertIsArray($actual); + } + + public function provideDataFindByPerson(): iterable + { + $this->setUp(); + + /** @var Person $person */ + if (null === $person = $this->entityManager->createQueryBuilder() + ->select('p')->from(Person::class, 'p')->setMaxResults(1) + ->getQuery()->getSingleResult()) { + throw new \RuntimeException("person not found"); + } + + /** @var AccompanyingPeriod $period1 */ + if (null === $period1 = $this->entityManager + ->createQueryBuilder() + ->select('a') + ->from(AccompanyingPeriod::class, 'a') + ->setMaxResults(1) + ->getQuery() + ->getSingleResult()) { + throw new \RuntimeException("no period found"); + } + + /** @var AccompanyingPeriod $period2 */ + if (null === $period2 = $this->entityManager + ->createQueryBuilder() + ->select('a') + ->from(AccompanyingPeriod::class, 'a') + ->where('a.id > :pid') + ->setParameter('pid', $period1->getId()) + ->setMaxResults(1) + ->getQuery() + ->getSingleResult()) { + throw new \RuntimeException("no second period found"); + } + // add a period + $period1->addPerson($person); + $period2->addPerson($person); + $period1->getParticipationsContainsPerson($person)->first()->setEndDate( + (new \DateTime('now'))->add(new \DateInterval('P1M')) + ); + + if ([] === $types = $this->entityManager + ->createQueryBuilder() + ->select('t') + ->from(ActivityType::class, 't') + ->setMaxResults(2) + ->getQuery() + ->getResult()) { + throw new \RuntimeException("no types"); + } + + if ([] === $jobs = $this->entityManager + ->createQueryBuilder() + ->select('j') + ->from(UserJob::class, 'j') + ->setMaxResults(2) + ->getQuery() + ->getResult() + ) { + throw new \RuntimeException("no jobs found"); + } + + if (null === $user = $this->entityManager + ->createQueryBuilder() + ->select('u') + ->from(User::class, 'u') + ->setMaxResults(1) + ->getQuery() + ->getSingleResult() + ) { + throw new \RuntimeException("no user found"); + } + + if ([] === $centers = $this->entityManager->createQueryBuilder() + ->select('c')->from(Center::class, 'c')->setMaxResults(2)->getQuery() + ->getResult()) { + throw new \RuntimeException("no centers found"); + } + + if ([] === $scopes = $this->entityManager->createQueryBuilder() + ->select('s')->from(Scope::class, 's')->setMaxResults(2)->getQuery() + ->getResult()) { + throw new \RuntimeException("no scopes found"); + } + + yield [$person, $user, $centers, $scopes, ActivityVoter::SEE, 0, 5, ['date' => 'DESC'], []]; + yield [$person, $user, $centers, $scopes, ActivityVoter::SEE, 0, 5, ['date' => 'DESC'], ['my_activities' => true]]; + yield [$person, $user, $centers, $scopes, ActivityVoter::SEE, 0, 5, ['date' => 'DESC'], ['types' => $types]]; + yield [$person, $user, $centers, $scopes, ActivityVoter::SEE, 0, 5, ['date' => 'DESC'], ['jobs' => $jobs]]; + yield [$person, $user, $centers, $scopes, ActivityVoter::SEE, 0, 5, ['date' => 'DESC'], ['after' => new \DateTimeImmutable('1 year ago')]]; + yield [$person, $user, $centers, $scopes, ActivityVoter::SEE, 0, 5, ['date' => 'DESC'], ['before' => new \DateTimeImmutable('1 year ago')]]; + yield [$person, $user, $centers, $scopes, ActivityVoter::SEE, 0, 5, ['date' => 'DESC'], ['after' => new \DateTimeImmutable('1 year ago'), 'before' => new \DateTimeImmutable('1 month ago')]]; + } + + public function provideDataFindByAccompanyingPeriod(): iterable + { + $this->setUp(); + + if (null === $period = $this->entityManager + ->createQueryBuilder() + ->select('a') + ->from(AccompanyingPeriod::class, 'a') + ->setMaxResults(1) + ->getQuery() + ->getSingleResult()) { + throw new \RuntimeException("no period found"); + } + + if ([] === $types = $this->entityManager + ->createQueryBuilder() + ->select('t') + ->from(ActivityType::class, 't') + ->setMaxResults(2) + ->getQuery() + ->getResult()) { + throw new \RuntimeException("no types"); + } + + if ([] === $jobs = $this->entityManager + ->createQueryBuilder() + ->select('j') + ->from(UserJob::class, 'j') + ->setMaxResults(2) + ->getQuery() + ->getResult() + ) { + throw new \RuntimeException("no jobs found"); + } + + if (null === $user = $this->entityManager + ->createQueryBuilder() + ->select('u') + ->from(User::class, 'u') + ->setMaxResults(1) + ->getQuery() + ->getSingleResult() + ) { + throw new \RuntimeException("no user found"); + } + + yield [$period, $user, ActivityVoter::SEE, 0, 10, ['date' => 'DESC'], []]; + yield [$period, $user, ActivityVoter::SEE, 0, 10, ['date' => 'DESC'], ['my_activities' => true]]; + yield [$period, $user, ActivityVoter::SEE, 0, 10, ['date' => 'DESC'], ['types' => $types]]; + yield [$period, $user, ActivityVoter::SEE, 0, 10, ['date' => 'DESC'], ['jobs' => $jobs]]; + yield [$period, $user, ActivityVoter::SEE, 0, 10, ['date' => 'DESC'], ['after' => new \DateTimeImmutable('1 year ago')]]; + yield [$period, $user, ActivityVoter::SEE, 0, 10, ['date' => 'DESC'], ['before' => new \DateTimeImmutable('1 year ago')]]; + yield [$period, $user, ActivityVoter::SEE, 0, 10, ['date' => 'DESC'], ['after' => new \DateTimeImmutable('1 year ago'), 'before' => new \DateTimeImmutable('1 month ago')]]; + } +} diff --git a/src/Bundle/ChillActivityBundle/translations/messages.fr.yml b/src/Bundle/ChillActivityBundle/translations/messages.fr.yml index 042fccc69..1229494bb 100644 --- a/src/Bundle/ChillActivityBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillActivityBundle/translations/messages.fr.yml @@ -83,12 +83,20 @@ Third persons: Tiers non-pro. Others persons: Usagers Third parties: Tiers professionnels Users concerned: T(M)S + activity: + date: Date de l'échange Insert a document: Insérer un document Remove a document: Supprimer le document comment: Commentaire No documents: Aucun document +# activity filter in list page +activity_filter: + My activities: Mes échanges (où j'interviens) + Types: Par type d'échange + Jobs: Par métier impliqué + #timeline '%user% has done an %activity_type%': '%user% a effectué un échange de type "%activity_type%"' From 0e5f1b4ab9c7d8e693332d42709841249e68a0eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Fri, 23 Jun 2023 12:44:54 +0200 Subject: [PATCH 201/321] Feature: [activity list] add pagination --- .../unreleased/Feature-20230623-124438.yaml | 5 +++ .../Controller/ActivityController.php | 18 +++++--- .../Repository/ActivityACLAwareRepository.php | 43 ++++++++++++++++++- .../ActivityACLAwareRepositoryInterface.php | 10 +++++ .../Resources/views/Activity/list.html.twig | 6 ++- 5 files changed, 74 insertions(+), 8 deletions(-) create mode 100644 .changes/unreleased/Feature-20230623-124438.yaml diff --git a/.changes/unreleased/Feature-20230623-124438.yaml b/.changes/unreleased/Feature-20230623-124438.yaml new file mode 100644 index 000000000..bc199d3bb --- /dev/null +++ b/.changes/unreleased/Feature-20230623-124438.yaml @@ -0,0 +1,5 @@ +kind: Feature +body: '[activity list] add pagination to the list of activities' +time: 2023-06-23T12:44:38.879098862+02:00 +custom: + Issue: "" diff --git a/src/Bundle/ChillActivityBundle/Controller/ActivityController.php b/src/Bundle/ChillActivityBundle/Controller/ActivityController.php index 07e4fcf62..63639c149 100644 --- a/src/Bundle/ChillActivityBundle/Controller/ActivityController.php +++ b/src/Bundle/ChillActivityBundle/Controller/ActivityController.php @@ -22,6 +22,7 @@ use Chill\ActivityBundle\Repository\ActivityUserJobRepository; use Chill\ActivityBundle\Security\Authorization\ActivityVoter; use Chill\MainBundle\Entity\Embeddable\CommentEmbeddable; use Chill\MainBundle\Entity\UserJob; +use Chill\MainBundle\Pagination\PaginatorFactory; use Chill\MainBundle\Repository\LocationRepository; use Chill\MainBundle\Repository\UserRepositoryInterface; use Chill\MainBundle\Security\Resolver\CenterResolverManagerInterface; @@ -70,6 +71,7 @@ final class ActivityController extends AbstractController private readonly TranslatorInterface $translator, private readonly FilterOrderHelperFactoryInterface $filterOrderHelperFactory, private readonly TranslatableStringHelperInterface $translatableStringHelper, + private readonly PaginatorFactory $paginatorFactory, ) { } @@ -251,7 +253,6 @@ final class ActivityController extends AbstractController { $view = null; $activities = []; - // TODO: add pagination [$person, $accompanyingPeriod] = $this->getEntity($request); $filter = $this->buildFilterOrder($person ?? $accompanyingPeriod); @@ -266,12 +267,14 @@ final class ActivityController extends AbstractController if ($person instanceof Person) { $this->denyAccessUnlessGranted(ActivityVoter::SEE, $person); + $count = $this->activityACLAwareRepository->countByPerson($person, ActivityVoter::SEE, $filterArgs); + $paginator = $this->paginatorFactory->create($count); $activities = $this->activityACLAwareRepository ->findByPerson( $person, ActivityVoter::SEE, - 0, - null, + $paginator->getCurrentPageFirstItemNumber(), + $paginator->getItemsPerPage(), ['date' => 'DESC', 'id' => 'DESC'], $filterArgs ); @@ -286,17 +289,21 @@ final class ActivityController extends AbstractController } elseif ($accompanyingPeriod instanceof AccompanyingPeriod) { $this->denyAccessUnlessGranted(ActivityVoter::SEE, $accompanyingPeriod); + $count = $this->activityACLAwareRepository->countByAccompanyingPeriod($accompanyingPeriod, ActivityVoter::SEE, $filterArgs); + $paginator = $this->paginatorFactory->create($count); $activities = $this->activityACLAwareRepository ->findByAccompanyingPeriod( $accompanyingPeriod, ActivityVoter::SEE, - 0, - null, + $paginator->getCurrentPageFirstItemNumber(), + $paginator->getItemsPerPage(), ['date' => 'DESC', 'id' => 'DESC'], $filterArgs ); $view = 'ChillActivityBundle:Activity:listAccompanyingCourse.html.twig'; + } else { + throw new \LogicException("Unsupported"); } return $this->render( @@ -306,6 +313,7 @@ final class ActivityController extends AbstractController 'person' => $person, 'accompanyingCourse' => $accompanyingPeriod, 'filter' => $filter, + 'paginator' => $paginator, ] ); } diff --git a/src/Bundle/ChillActivityBundle/Repository/ActivityACLAwareRepository.php b/src/Bundle/ChillActivityBundle/Repository/ActivityACLAwareRepository.php index 1fd0a57d6..1544dd764 100644 --- a/src/Bundle/ChillActivityBundle/Repository/ActivityACLAwareRepository.php +++ b/src/Bundle/ChillActivityBundle/Repository/ActivityACLAwareRepository.php @@ -27,6 +27,8 @@ use Chill\PersonBundle\Entity\Person; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\AbstractQuery; use Doctrine\ORM\EntityManagerInterface; +use Doctrine\ORM\NonUniqueResultException; +use Doctrine\ORM\NoResultException; use Doctrine\ORM\Query\Expr\Join; use Doctrine\ORM\Query\ResultSetMappingBuilder; use Doctrine\ORM\QueryBuilder; @@ -48,6 +50,33 @@ final readonly class ActivityACLAwareRepository implements ActivityACLAwareRepos ) { } + /** + * @throws NonUniqueResultException + * @throws NoResultException + */ + public function countByAccompanyingPeriod(AccompanyingPeriod $period, string $role, array $filters = []): int + { + $qb = $this->buildBaseQuery($filters); + + $qb + ->select('COUNT(a)') + ->andWhere('a.accompanyingPeriod = :period')->setParameter('period', $period); + + return $qb->getQuery()->getSingleScalarResult(); + } + + public function countByPerson(Person $person, string $role, array $filters = []): int + { + $qb = $this->buildBaseQuery($filters); + + $qb = $this->filterBaseQueryByPerson($qb, $person, $role); + + $qb->select('COUNT(a)'); + + return $qb->getQuery()->getSingleScalarResult(); + } + + public function findByAccompanyingPeriod(AccompanyingPeriod $period, string $role, ?int $start = 0, ?int $limit = 1000, array $orderBy = ['date' => 'DESC'], array $filters = []): array { $qb = $this->buildBaseQuery($filters); @@ -58,7 +87,12 @@ final readonly class ActivityACLAwareRepository implements ActivityACLAwareRepos $qb->addOrderBy('a.' . $field, $order); } - $qb->setFirstResult(0)->setMaxResults(1000); + if (null !== $start) { + $qb->setFirstResult($start); + } + if (null !== $limit) { + $qb->setMaxResults($limit); + } return $qb->getQuery()->getResult(); } @@ -261,6 +295,13 @@ final readonly class ActivityACLAwareRepository implements ActivityACLAwareRepos $qb->addOrderBy('a.' . $field, $direction); } + if (null !== $start) { + $qb->setFirstResult($start); + } + if (null !== $limit) { + $qb->setMaxResults($limit); + } + return $qb->getQuery()->getResult(); } diff --git a/src/Bundle/ChillActivityBundle/Repository/ActivityACLAwareRepositoryInterface.php b/src/Bundle/ChillActivityBundle/Repository/ActivityACLAwareRepositoryInterface.php index a046ad218..474d8ad16 100644 --- a/src/Bundle/ChillActivityBundle/Repository/ActivityACLAwareRepositoryInterface.php +++ b/src/Bundle/ChillActivityBundle/Repository/ActivityACLAwareRepositoryInterface.php @@ -28,6 +28,16 @@ interface ActivityACLAwareRepositoryInterface */ public function findByAccompanyingPeriod(AccompanyingPeriod $period, string $role, ?int $start = 0, ?int $limit = 1000, array $orderBy = ['date' => 'DESC'], array $filters = []): array; + /** + * @param array{my_activities?: bool, types?: array, jobs?: array, after?: \DateTimeImmutable|null, before?: \DateTimeImmutable|null} $filters + */ + public function countByAccompanyingPeriod(AccompanyingPeriod $period, string $role, array $filters = []): int; + + /** + * @param array{my_activities?: bool, types?: array, jobs?: array, after?: \DateTimeImmutable|null, before?: \DateTimeImmutable|null} $filters + */ + public function countByPerson(Person $person, string $role, array $filters = []): int; + /** * Return a list of activities, simplified as array (not object). * diff --git a/src/Bundle/ChillActivityBundle/Resources/views/Activity/list.html.twig b/src/Bundle/ChillActivityBundle/Resources/views/Activity/list.html.twig index 17ae0598b..dd78c9396 100644 --- a/src/Bundle/ChillActivityBundle/Resources/views/Activity/list.html.twig +++ b/src/Bundle/ChillActivityBundle/Resources/views/Activity/list.html.twig @@ -80,6 +80,8 @@
    + {{ filter|chill_render_filter_order_helper }} + {% if activities|length == 0 %}

    {{ "There isn't any activities."|trans }} @@ -87,8 +89,6 @@ {% else %} - {{ filter|chill_render_filter_order_helper }} -

    {% for activity in activities %} {% include 'ChillActivityBundle:Activity:_list_item.html.twig' with { @@ -99,4 +99,6 @@
    {% endif %} + {{ chill_pagination(paginator) }} +
    From 9978b6a6e410028907579e41856145bbe95ba733 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Fri, 23 Jun 2023 13:04:13 +0200 Subject: [PATCH 202/321] Fix: fix the loading of pickCenterType when no regroupments exists and defaults of SocialWorkTypeFilter --- .../DataMapper/ExportPickCenterDataMapper.php | 29 +++++-------------- .../Form/Type/Export/PickCenterType.php | 2 +- .../SocialWorkTypeFilter.php | 2 +- 3 files changed, 9 insertions(+), 24 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Form/DataMapper/ExportPickCenterDataMapper.php b/src/Bundle/ChillMainBundle/Form/DataMapper/ExportPickCenterDataMapper.php index c88f1dfe3..d4dc4719d 100644 --- a/src/Bundle/ChillMainBundle/Form/DataMapper/ExportPickCenterDataMapper.php +++ b/src/Bundle/ChillMainBundle/Form/DataMapper/ExportPickCenterDataMapper.php @@ -20,38 +20,23 @@ use Symfony\Component\Form\FormInterface; use function array_key_exists; use function count; -class ExportPickCenterDataMapper implements DataMapperInterface +final readonly class ExportPickCenterDataMapper implements DataMapperInterface { - public function __construct( - private RegroupmentRepository $regroupmentRepository, - ) { - } - - public function mapDataToForms($data, $forms): void + public function mapDataToForms($viewData, $forms): void { - if (null === $data) { + if (null === $viewData) { return; } /** @var array $form */ $form = iterator_to_array($forms); - $pickedRegroupment = []; + $form['center']->setData($viewData); - foreach ($this->regroupmentRepository->findAll() as $regroupment) { - /** @phpstan-ignore-next-line */ - [$contained, $notContained] = $regroupment->getCenters()->partition(static fn (int $id, Center $center): bool => false); - - if (0 === count($notContained)) { - $pickedRegroupment[] = $regroupment; - } - } - - $form['regroupment']->setData([]); - $form['center']->setData($data); + // NOTE: we do not map back the regroupments } - public function mapFormsToData($forms, &$data): void + public function mapFormsToData($forms, &$viewData): void { /** @var array $forms */ $forms = iterator_to_array($forms); @@ -71,6 +56,6 @@ class ExportPickCenterDataMapper implements DataMapperInterface } } - $data = array_values($centers); + $viewData = array_values($centers); } } diff --git a/src/Bundle/ChillMainBundle/Form/Type/Export/PickCenterType.php b/src/Bundle/ChillMainBundle/Form/Type/Export/PickCenterType.php index b2d903909..d33ab2ade 100644 --- a/src/Bundle/ChillMainBundle/Form/Type/Export/PickCenterType.php +++ b/src/Bundle/ChillMainBundle/Form/Type/Export/PickCenterType.php @@ -77,7 +77,7 @@ final class PickCenterType extends AbstractType ]); } - $builder->setDataMapper(new ExportPickCenterDataMapper($this->regroupmentRepository)); + $builder->setDataMapper(new ExportPickCenterDataMapper()); } public function configureOptions(OptionsResolver $resolver) diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/SocialWorkTypeFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/SocialWorkTypeFilter.php index 9a687b1e6..e97834319 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/SocialWorkTypeFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/SocialWorkTypeFilter.php @@ -113,7 +113,7 @@ class SocialWorkTypeFilter implements FilterInterface public function getFormDefaultData(): array { - return ['action_type' => '', 'goal' => '', 'result' => '']; + return ['action_type' => [], 'goal' => [], 'result' => []]; } public function describeAction($data, $format = 'string'): array From 0e9597bf777ec47b12e524e5b9d4093e5a563a0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Sun, 25 Jun 2023 15:47:30 +0200 Subject: [PATCH 203/321] fix handling of DirectExportInterface --- .../Export/ExportFormHelper.php | 24 +++++++++++-------- .../ChillMainBundle/Export/ExportManager.php | 10 +++++--- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Export/ExportFormHelper.php b/src/Bundle/ChillMainBundle/Export/ExportFormHelper.php index c2127fb36..5271fb223 100644 --- a/src/Bundle/ChillMainBundle/Export/ExportFormHelper.php +++ b/src/Bundle/ChillMainBundle/Export/ExportFormHelper.php @@ -72,17 +72,21 @@ final readonly class ExportFormHelper ]; } - $allowedFormatters = $this->exportManager - ->getFormattersByTypes($export->getAllowedFormattersTypes()); - $choices = []; - foreach (array_keys(iterator_to_array($allowedFormatters)) as $alias) { - $choices[] = $alias; - } + if ($export instanceof ExportInterface) { + $allowedFormatters = $this->exportManager + ->getFormattersByTypes($export->getAllowedFormattersTypes()); + $choices = []; + foreach (array_keys(iterator_to_array($allowedFormatters)) as $alias) { + $choices[] = $alias; + } - $data[ExportType::PICK_FORMATTER_KEY]['alias'] = match (count($choices)) { - 1 => $choices[0], - default => null, - }; + $data[ExportType::PICK_FORMATTER_KEY]['alias'] = match (count($choices)) { + 1 => $choices[0], + default => null, + }; + } else { + unset($data[ExportType::PICK_FORMATTER_KEY]); + } return $data; } diff --git a/src/Bundle/ChillMainBundle/Export/ExportManager.php b/src/Bundle/ChillMainBundle/Export/ExportManager.php index 7ad880642..3f9c839a5 100644 --- a/src/Bundle/ChillMainBundle/Export/ExportManager.php +++ b/src/Bundle/ChillMainBundle/Export/ExportManager.php @@ -113,8 +113,12 @@ class ExportManager * * @return FilterInterface[] a \Generator that contains filters. The key is the filter's alias */ - public function &getFiltersApplyingOn(ExportInterface $export, ?array $centers = null) + public function &getFiltersApplyingOn(ExportInterface|DirectExportInterface $export, ?array $centers = null): iterable { + if ($export instanceof DirectExportInterface) { + return; + } + foreach ($this->filters as $alias => $filter) { if ( in_array($filter->applyOn(), $export->supportsModifiers(), true) @@ -132,9 +136,9 @@ class ExportManager * * @return null|iterable a \Generator that contains aggretagors. The key is the filter's alias */ - public function &getAggregatorsApplyingOn(ExportInterface $export, ?array $centers = null): ?iterable + public function &getAggregatorsApplyingOn(ExportInterface|DirectExportInterface $export, ?array $centers = null): ?iterable { - if ($export instanceof ListInterface) { + if ($export instanceof ListInterface || $export instanceof DirectExportInterface) { return; } From cd7a80b680fb5f6e95a88d4666c8c12ee12afdd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Mon, 26 Jun 2023 11:05:20 +0000 Subject: [PATCH 204/321] Do a release automatically using ci/cd when tag is created --- .gitlab-ci.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 3f1d75ed5..aa1eff8b1 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -34,6 +34,7 @@ variables: stages: - Composer install - Tests + - Deploy build: stage: Composer install @@ -121,3 +122,14 @@ unit_tests: paths: - bin - tests/app/vendor/ + +release: + stage: Deploy + image: registry.gitlab.com/gitlab-org/release-cli:latest + rules: + - if: $CI_COMMIT_TAG + script: + - echo "running release_job" + release: + tag_name: '$CI_COMMIT_TAG' + description: "./.changes/v$CI_COMMIT_TAG.md" From c0ae2f8ed9aceb6c6c4d4d6a2823604667145357 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Mon, 26 Jun 2023 14:27:07 +0200 Subject: [PATCH 205/321] publish on version 2.2.2 --- .changes/unreleased/Fixed-20230621-132851.yaml | 6 ------ .changes/unreleased/Fixed-20230621-135912.yaml | 5 ----- .changes/unreleased/Fixed-20230621-141828.yaml | 5 ----- .changes/v2.2.2.md | 5 +++++ CHANGELOG.md | 6 ++++++ 5 files changed, 11 insertions(+), 16 deletions(-) delete mode 100644 .changes/unreleased/Fixed-20230621-132851.yaml delete mode 100644 .changes/unreleased/Fixed-20230621-135912.yaml delete mode 100644 .changes/unreleased/Fixed-20230621-141828.yaml create mode 100644 .changes/v2.2.2.md diff --git a/.changes/unreleased/Fixed-20230621-132851.yaml b/.changes/unreleased/Fixed-20230621-132851.yaml deleted file mode 100644 index 89fb7cdd9..000000000 --- a/.changes/unreleased/Fixed-20230621-132851.yaml +++ /dev/null @@ -1,6 +0,0 @@ -kind: Fixed -body: '[Accompanying period comments]: order comments from the most recent to the - oldest, in the list' -time: 2023-06-21T13:28:51.282714011+02:00 -custom: - Issue: "" diff --git a/.changes/unreleased/Fixed-20230621-135912.yaml b/.changes/unreleased/Fixed-20230621-135912.yaml deleted file mode 100644 index 676d1c21b..000000000 --- a/.changes/unreleased/Fixed-20230621-135912.yaml +++ /dev/null @@ -1,5 +0,0 @@ -kind: Fixed -body: 'Api: filter social action to keep only the currently activated' -time: 2023-06-21T13:59:12.57760217+02:00 -custom: - Issue: "" diff --git a/.changes/unreleased/Fixed-20230621-141828.yaml b/.changes/unreleased/Fixed-20230621-141828.yaml deleted file mode 100644 index 2c7f94488..000000000 --- a/.changes/unreleased/Fixed-20230621-141828.yaml +++ /dev/null @@ -1,5 +0,0 @@ -kind: Fixed -body: Fix deletion and re-creation of filiation relationship -time: 2023-06-21T14:18:28.437876316+02:00 -custom: - Issue: "82" diff --git a/.changes/v2.2.2.md b/.changes/v2.2.2.md new file mode 100644 index 000000000..61d194b6d --- /dev/null +++ b/.changes/v2.2.2.md @@ -0,0 +1,5 @@ +## v2.2.2 - 2023-06-26 +### Fixed +* [Accompanying period comments]: order comments from the most recent to the oldest, in the list +* Api: filter social action to keep only the currently activated +* ([#82](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/82)) Fix deletion and re-creation of filiation relationship diff --git a/CHANGELOG.md b/CHANGELOG.md index e223fa116..ab33c7fc4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,12 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), and is generated by [Changie](https://github.com/miniscruff/changie). +## v2.2.2 - 2023-06-26 +### Fixed +* [Accompanying period comments]: order comments from the most recent to the oldest, in the list +* Api: filter social action to keep only the currently activated +* ([#82](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/82)) Fix deletion and re-creation of filiation relationship + ## v2.2.1 - 2023-06-19 ### Fixed * ([#114](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/114)) [notification on document evaluation] fix entityId and return path when adding a notification on a document in an evaluation From f19b939bd429dde6f7f502cee896324f71f97ae9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 27 Jun 2023 11:04:22 +0200 Subject: [PATCH 206/321] Fixed: rights on the action list in accompanying period main's page Add is_granted check on the action: - if update action is allowed, open in update mode; - if see action is allowed, open in see mode; - fallback to an inactive link (should not happens) --- .../unreleased/Fixed-20230627-110233.yaml | 6 +++++ ...st_recent_by_accompanying_period.html.twig | 26 ++++++++++--------- 2 files changed, 20 insertions(+), 12 deletions(-) create mode 100644 .changes/unreleased/Fixed-20230627-110233.yaml diff --git a/.changes/unreleased/Fixed-20230627-110233.yaml b/.changes/unreleased/Fixed-20230627-110233.yaml new file mode 100644 index 000000000..58bb23933 --- /dev/null +++ b/.changes/unreleased/Fixed-20230627-110233.yaml @@ -0,0 +1,6 @@ +kind: Fixed +body: On the accompanying course page, open the action on view mode if the user does + not have right to update them (i.e. if the accompanying period is closed) +time: 2023-06-27T11:02:33.027807027+02:00 +custom: + Issue: "116" diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/list_recent_by_accompanying_period.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/list_recent_by_accompanying_period.html.twig index 92b2e3920..897f19b46 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/list_recent_by_accompanying_period.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/list_recent_by_accompanying_period.html.twig @@ -1,9 +1,11 @@ - From a93051d157cb4b0f59ee550bd7ff86b8c1b5eac2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 27 Jun 2023 11:13:07 +0200 Subject: [PATCH 207/321] [export] set the default date for accompanying period list --- .changes/unreleased/Feature-20230627-111222.yaml | 6 ++++++ .../Export/Export/ListAccompanyingPeriod.php | 5 ++++- 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 .changes/unreleased/Feature-20230627-111222.yaml diff --git a/.changes/unreleased/Feature-20230627-111222.yaml b/.changes/unreleased/Feature-20230627-111222.yaml new file mode 100644 index 000000000..1946b9332 --- /dev/null +++ b/.changes/unreleased/Feature-20230627-111222.yaml @@ -0,0 +1,6 @@ +kind: Feature +body: '[export] Set the default date of calculation of the accompanying period''s + list as "today"' +time: 2023-06-27T11:12:22.296330037+02:00 +custom: + Issue: "" diff --git a/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriod.php b/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriod.php index e5e724b6c..294b9ce9a 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriod.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriod.php @@ -20,6 +20,7 @@ use Chill\MainBundle\Export\Helper\ExportAddressHelper; use Chill\MainBundle\Export\Helper\UserHelper; use Chill\MainBundle\Export\ListInterface; use Chill\MainBundle\Form\Type\PickRollingDateType; +use Chill\MainBundle\Service\RollingDate\RollingDate; use Chill\MainBundle\Service\RollingDate\RollingDateConverterInterface; use Chill\MainBundle\Templating\TranslatableStringHelperInterface; use Chill\PersonBundle\Entity\AccompanyingPeriod; @@ -146,7 +147,9 @@ class ListAccompanyingPeriod implements ListInterface, GroupedExportInterface } public function getFormDefaultData(): array { - return []; + return [ + 'calc_date' => new RollingDate(RollingDate::T_TODAY) + ]; } public function getAllowedFormattersTypes() From 90be68002a4765520faae3e15f2caff62727c66c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 27 Jun 2023 15:30:16 +0200 Subject: [PATCH 208/321] add possibility to add long text in changelog --- .changie.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.changie.yaml b/.changie.yaml index ba5454ce7..8a25ed695 100644 --- a/.changie.yaml +++ b/.changie.yaml @@ -5,8 +5,11 @@ changelogPath: CHANGELOG.md versionExt: md versionFormat: '## {{.Version}} - {{.Time.Format "2006-01-02"}}' kindFormat: '### {{.Kind}}' +# Note: it is possible to add a `.custom.Long` text manually into the yaml file produced by `changie new`. This will add a long description. changeFormat: >- - * {{ if not (eq .Custom.Issue "") }}([#{{ .Custom.Issue }}](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/{{ .Custom.Issue }})) {{ end }}{{.Body}} + * {{ if not (eq .Custom.Issue "") }}([#{{ .Custom.Issue }}](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/{{ .Custom.Issue }})) {{ end }}{{.Body}} {{ if not (eq .Custom.Long "") }} + + {{ .Custom.Long }}{{ end }} custom: - key: Issue label: Issue number (on chill-bundles repository) (optional) From a7c3089736020e20192e71d34189ca638c5972e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 27 Jun 2023 15:30:44 +0200 Subject: [PATCH 209/321] Feature: avoid duplicates for the same period in acc period user history --- .../unreleased/Feature-20230627-151615.yaml | 28 +++++++++++++++ .../migrations/Version20230627130331.php | 36 +++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 .changes/unreleased/Feature-20230627-151615.yaml create mode 100644 src/Bundle/ChillPersonBundle/migrations/Version20230627130331.php diff --git a/.changes/unreleased/Feature-20230627-151615.yaml b/.changes/unreleased/Feature-20230627-151615.yaml new file mode 100644 index 000000000..499e874dc --- /dev/null +++ b/.changes/unreleased/Feature-20230627-151615.yaml @@ -0,0 +1,28 @@ +kind: Feature +body: "Force accompanying period user history to be unique for the same period and + stardate/enddate [:warning: may encounter migration issue]" +time: 2023-06-27T15:16:15.775571488+02:00 +custom: + Issue: "" + Long: "If some issue is encountered during migration, use this SQL to find the line which are in conflict, examine the problem and delete some of the concerning line + + ```sql + + -- to see the line which are in conflict with another one + + SELECT o.* + + FROM chill_person_accompanying_period_user_history o + + JOIN chill_person_accompanying_period_user_history c ON o.id < c.id AND o.accompanyingperiod_id = c.accompanyingperiod_id + + WHERE tsrange(o.startdate, o.enddate, '[)') && tsrange(c.startdate, c.enddate, '[)') + + ORDER BY accompanyingperiod_id; + + -- to examine line in conflict for a given accompanyingperiod_id (given by the previous query) + + SELECT * FROM chill_person_accompanying_period_user_history WHERE accompanyingperiod_id = IIIIDDDD order by startdate, enddate; + + ``` + " diff --git a/src/Bundle/ChillPersonBundle/migrations/Version20230627130331.php b/src/Bundle/ChillPersonBundle/migrations/Version20230627130331.php new file mode 100644 index 000000000..63f160997 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/migrations/Version20230627130331.php @@ -0,0 +1,36 @@ +addSql('ALTER TABLE chill_person_accompanying_period_user_history + ADD CONSTRAINT acc_period_user_history_not_overlaps + EXCLUDE USING GIST (accompanyingperiod_id with =, tsrange(startdate, enddate) with &&) + DEFERRABLE INITIALLY DEFERRED'); + } + + public function down(Schema $schema): void + { + $this->addSql('ALTER TABLE chill_person_accompanying_period_user_history DROP CONSTRAINT acc_period_user_history_not_overlaps'); + } +} From 687ff63ce7218da27b1b11fa033c1d9398ffeabc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 27 Jun 2023 16:00:05 +0200 Subject: [PATCH 210/321] Rename label of filter in French: "parcours actif" => "parcours ouvert", and "filtrer les parcours ouverts" => "Filtrer les parcours dont la date d''ouverture" --- .changes/unreleased/Feature-20230627-155925.yaml | 6 ++++++ .../ChillPersonBundle/translations/messages.fr.yml | 14 +++++++------- 2 files changed, 13 insertions(+), 7 deletions(-) create mode 100644 .changes/unreleased/Feature-20230627-155925.yaml diff --git a/.changes/unreleased/Feature-20230627-155925.yaml b/.changes/unreleased/Feature-20230627-155925.yaml new file mode 100644 index 000000000..b134adab5 --- /dev/null +++ b/.changes/unreleased/Feature-20230627-155925.yaml @@ -0,0 +1,6 @@ +kind: Feature +body: 'Rename label of filter in French: "parcours actif" => "parcours ouvert", and + "filtrer les parcours ouverts" => "Filtrer les parcours dont la date d''ouverture"' +time: 2023-06-27T15:59:25.442854464+02:00 +custom: + Issue: "" diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index bdb93afc0..188c31f1a 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -555,22 +555,22 @@ is regular: le parcours est régulier Intensity: Intensité Group by intensity: Grouper les parcours par intensité -Filter by active on date: Filtrer les parcours actifs à une date -On date: Actifs à cette date -"Filtered by actives courses: active on %ondate%": "Filtrer les parcours actifs: actifs le %ondate%" +Filter by active on date: Filtrer les parcours ouverts à une date +On date: A l'état ouvert à cette date +"Filtered by actives courses: active on %ondate%": "Filtrer les parcours ouverts: actifs le %ondate%" -Filter by active at least one day between dates: Filtrer les parcours actifs au moins un jour dans la période -"Filtered by actives courses: at least one day between %datefrom% and %dateto%": "Filtrer les parcours actifs: au moins un jour entre le %datefrom% et le %dateto%" +Filter by active at least one day between dates: Filtrer les parcours ouverts au moins un jour dans la période +"Filtered by actives courses: at least one day between %datefrom% and %dateto%": "Filtrer les parcours ouverts: au moins un jour entre le %datefrom% et le %dateto%" Filter by referrers: Filtrer les parcours par référent Accepted referrers: Référents "Filtered by referrer: only %referrers%": "Filtré par référent: uniquement %referrers%" Group by referrers: Grouper les parcours par référent -Filter by opened between dates: Filtrer les parcours ouverts entre deux dates +Filter by opened between dates: Filtrer les parcours dont la date d'ouverture est comprise entre deux dates Date from: Date de début Date to: Date de fin -"Filtered by opening dates: between %datefrom% and %dateto%": "Filtrer les parcours ouverts entre deux dates: entre le %datefrom% et le %dateto%" +"Filtered by opening dates: between %datefrom% and %dateto%": "Filtrer les parcours dont la date d'ouverture est comprise entre le %datefrom% et le %dateto%" Filter by temporary location: Filtrer les parcours avec une localisation temporaire Filter by which has no referrer: Filtrer les parcours sans référent From 7a1feaa8cb2e09560953eb087e05e285be5c2405 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 27 Jun 2023 18:20:41 +0200 Subject: [PATCH 211/321] show documents from person in list of document from course --- .../PersonDocumentGenericDocProvider.php | 16 +++- .../PersonDocumentACLAwareRepository.php | 89 ++++++++++++++++--- ...sonDocumentACLAwareRepositoryInterface.php | 8 ++ .../Resources/views/List/list_item.html.twig | 9 +- .../PersonDocumentACLAwareRepositoryTest.php | 61 ++++++++++++- .../translations/messages.fr.yml | 2 + .../Entity/AccompanyingPeriod.php | 2 + .../translations/messages.fr.yml | 1 - 8 files changed, 171 insertions(+), 17 deletions(-) diff --git a/src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/PersonDocumentGenericDocProvider.php b/src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/PersonDocumentGenericDocProvider.php index 08a0df960..613f8d758 100644 --- a/src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/PersonDocumentGenericDocProvider.php +++ b/src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/PersonDocumentGenericDocProvider.php @@ -12,14 +12,16 @@ declare(strict_types=1); namespace Chill\DocStoreBundle\GenericDoc\Providers; use Chill\DocStoreBundle\GenericDoc\FetchQueryInterface; +use Chill\DocStoreBundle\GenericDoc\GenericDocForAccompanyingPeriodProviderInterface; use Chill\DocStoreBundle\GenericDoc\GenericDocForPersonProviderInterface; use Chill\DocStoreBundle\Repository\PersonDocumentACLAwareRepositoryInterface; use Chill\DocStoreBundle\Security\Authorization\PersonDocumentVoter; +use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\Person; use DateTimeImmutable; use Symfony\Component\Security\Core\Security; -final readonly class PersonDocumentGenericDocProvider implements GenericDocForPersonProviderInterface +final readonly class PersonDocumentGenericDocProvider implements GenericDocForPersonProviderInterface, GenericDocForAccompanyingPeriodProviderInterface { public const KEY = 'person_document'; @@ -48,4 +50,16 @@ final readonly class PersonDocumentGenericDocProvider implements GenericDocForPe { return $this->security->isGranted(PersonDocumentVoter::SEE, $person); } + + public function buildFetchQueryForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod, ?\DateTimeImmutable $startDate = null, ?\DateTimeImmutable $endDate = null, ?string $content = null, ?string $origin = null): FetchQueryInterface + { + return $this->personDocumentACLAwareRepository->buildFetchQueryForAccompanyingPeriod($accompanyingPeriod, $startDate, $endDate, $content); + } + + public function isAllowedForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod): bool + { + // we assume that the user is allowed to see at least one person of the course + // this will be double checked when running the query + return true; + } } diff --git a/src/Bundle/ChillDocStoreBundle/Repository/PersonDocumentACLAwareRepository.php b/src/Bundle/ChillDocStoreBundle/Repository/PersonDocumentACLAwareRepository.php index 5d85541aa..26a42b894 100644 --- a/src/Bundle/ChillDocStoreBundle/Repository/PersonDocumentACLAwareRepository.php +++ b/src/Bundle/ChillDocStoreBundle/Repository/PersonDocumentACLAwareRepository.php @@ -22,6 +22,8 @@ use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface; use Chill\MainBundle\Security\Resolver\CenterResolverDispatcher; use Chill\MainBundle\Security\Resolver\CenterResolverDispatcherInterface; use Chill\MainBundle\Security\Resolver\CenterResolverManagerInterface; +use Chill\PersonBundle\Entity\AccompanyingPeriod; +use Chill\PersonBundle\Entity\AccompanyingPeriodParticipation; use Chill\PersonBundle\Entity\Person; use DateTimeImmutable; use Doctrine\DBAL\Types\Types; @@ -29,19 +31,14 @@ use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Security\Core\Security; -class PersonDocumentACLAwareRepository implements PersonDocumentACLAwareRepositoryInterface +final readonly class PersonDocumentACLAwareRepository implements PersonDocumentACLAwareRepositoryInterface { - private AuthorizationHelperForCurrentUserInterface $authorizationHelperForCurrentUser; - - private CenterResolverManagerInterface $centerResolverManager; - - private EntityManagerInterface $em; - - public function __construct(EntityManagerInterface $em, CenterResolverManagerInterface $centerResolverManager, AuthorizationHelperForCurrentUserInterface $authorizationHelperForCurrentUser) - { - $this->em = $em; - $this->centerResolverManager = $centerResolverManager; - $this->authorizationHelperForCurrentUser = $authorizationHelperForCurrentUser; + public function __construct( + private EntityManagerInterface $em, + private CenterResolverManagerInterface $centerResolverManager, + private AuthorizationHelperForCurrentUserInterface $authorizationHelperForCurrentUser, + private Security $security, + ) { } public function buildQueryByPerson(Person $person): QueryBuilder @@ -63,6 +60,66 @@ class PersonDocumentACLAwareRepository implements PersonDocumentACLAwareReposito return $this->addFetchQueryByPersonACL($query, $person); } + public function buildFetchQueryForAccompanyingPeriod(AccompanyingPeriod $period, ?\DateTimeImmutable $startDate = null, ?\DateTimeImmutable $endDate = null, ?string $content = null): FetchQueryInterface + { + $personDocMetadata = $this->em->getClassMetadata(PersonDocument::class); + $participationMetadata = $this->em->getClassMetadata(AccompanyingPeriodParticipation::class); + + $query = new FetchQuery( + PersonDocumentGenericDocProvider::KEY, + sprintf('jsonb_build_object(\'id\', person_document.%s)', $personDocMetadata->getSingleIdentifierColumnName()), + sprintf('person_document.%s', $personDocMetadata->getColumnName('date')), + sprintf('%s AS person_document', $personDocMetadata->getSchemaName().'.'.$personDocMetadata->getTableName()) + ); + + $query->addJoinClause( + sprintf( + 'JOIN %s AS participation ON participation.%s = person_document.%s '. + 'AND person_document.%s BETWEEN participation.%s AND COALESCE(participation.%s, \'infinity\'::date)', + $participationMetadata->getTableName(), + $participationMetadata->getSingleAssociationJoinColumnName('person'), + $personDocMetadata->getSingleAssociationJoinColumnName('person'), + $personDocMetadata->getColumnName('date'), + $participationMetadata->getColumnName('startDate'), + $participationMetadata->getColumnName('endDate') + ) + ); + + $query->addWhereClause( + sprintf('participation.%s = ?', $participationMetadata->getSingleAssociationJoinColumnName('accompanyingPeriod')), + [$period->getId()], + [Types::INTEGER] + ); + + // can we see the document for this person ? + $orPersonId = []; + foreach ($period->getParticipations() as $participation) { + if (!$this->security->isGranted(PersonDocumentVoter::SEE, $participation->getPerson())) { + continue; + } + $orPersonId[] = $participation->getPerson()->getId(); + + } + + if ([] === $orPersonId) { + $query->addWhereClause('FALSE = TRUE'); + + return $query; + } + + $query->addWhereClause( + sprintf( + 'participation.%s IN (%s)', + $participationMetadata->getSingleAssociationJoinColumnName('person'), + implode(', ', array_fill(0, count($orPersonId), '?')) + ), + $orPersonId, + array_fill(0, count($orPersonId), Types::INTEGER) + ); + + return $this->addFilterClauses($query, $startDate, $endDate, $content); + } + public function buildBaseFetchQueryForPerson(Person $person, ?DateTimeImmutable $startDate = null, ?DateTimeImmutable $endDate = null, ?string $content = null): FetchQuery { $personDocMetadata = $this->em->getClassMetadata(PersonDocument::class); @@ -80,6 +137,13 @@ class PersonDocumentACLAwareRepository implements PersonDocumentACLAwareReposito [Types::INTEGER] ); + return $this->addFilterClauses($query, $startDate, $endDate, $content); + } + + private function addFilterClauses(FetchQuery $query, ?DateTimeImmutable $startDate = null, ?DateTimeImmutable $endDate = null, ?string $content = null): FetchQuery + { + $personDocMetadata = $this->em->getClassMetadata(PersonDocument::class); + if (null !== $startDate) { $query->addWhereClause( sprintf('? <= %s', $personDocMetadata->getColumnName('date')), @@ -107,7 +171,6 @@ class PersonDocumentACLAwareRepository implements PersonDocumentACLAwareReposito [Types::STRING, Types::STRING] ); } - return $query; } diff --git a/src/Bundle/ChillDocStoreBundle/Repository/PersonDocumentACLAwareRepositoryInterface.php b/src/Bundle/ChillDocStoreBundle/Repository/PersonDocumentACLAwareRepositoryInterface.php index 0b5e26792..f1bc70812 100644 --- a/src/Bundle/ChillDocStoreBundle/Repository/PersonDocumentACLAwareRepositoryInterface.php +++ b/src/Bundle/ChillDocStoreBundle/Repository/PersonDocumentACLAwareRepositoryInterface.php @@ -12,6 +12,7 @@ declare(strict_types=1); namespace Chill\DocStoreBundle\Repository; use Chill\DocStoreBundle\GenericDoc\FetchQueryInterface; +use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\Person; interface PersonDocumentACLAwareRepositoryInterface @@ -32,4 +33,11 @@ interface PersonDocumentACLAwareRepositoryInterface ?\DateTimeImmutable $endDate = null, ?string $content = null ): FetchQueryInterface; + + public function buildFetchQueryForAccompanyingPeriod( + AccompanyingPeriod $period, + ?\DateTimeImmutable $startDate = null, + ?\DateTimeImmutable $endDate = null, + ?string $content = null + ): FetchQueryInterface; } diff --git a/src/Bundle/ChillDocStoreBundle/Resources/views/List/list_item.html.twig b/src/Bundle/ChillDocStoreBundle/Resources/views/List/list_item.html.twig index 9be38074d..58504b095 100644 --- a/src/Bundle/ChillDocStoreBundle/Resources/views/List/list_item.html.twig +++ b/src/Bundle/ChillDocStoreBundle/Resources/views/List/list_item.html.twig @@ -17,7 +17,14 @@ {{ accompanyingCourse.id }}  
    - {% endif %} + {% elseif context == 'accompanying-period' and person is defined %} +
    + + {{ 'Document from person %name%'|trans({ '%name%': document.person|chill_entity_render_string }) }} +   +
    + + {% endif %}
    {{ document.title|chill_print_or_message("No title") }}
    diff --git a/src/Bundle/ChillDocStoreBundle/Tests/Repository/PersonDocumentACLAwareRepositoryTest.php b/src/Bundle/ChillDocStoreBundle/Tests/Repository/PersonDocumentACLAwareRepositoryTest.php index 98fca5622..fd611042c 100644 --- a/src/Bundle/ChillDocStoreBundle/Tests/Repository/PersonDocumentACLAwareRepositoryTest.php +++ b/src/Bundle/ChillDocStoreBundle/Tests/Repository/PersonDocumentACLAwareRepositoryTest.php @@ -21,12 +21,14 @@ use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface; use Chill\MainBundle\Security\Resolver\CenterResolverDispatcher; use Chill\MainBundle\Security\Resolver\CenterResolverDispatcherInterface; use Chill\MainBundle\Security\Resolver\CenterResolverManagerInterface; +use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\Person; use DateTimeImmutable; use Doctrine\ORM\EntityManagerInterface; use Prophecy\Argument; use Prophecy\PhpUnit\ProphecyTrait; use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; +use Symfony\Component\Security\Core\Security; /** * @internal @@ -66,7 +68,8 @@ class PersonDocumentACLAwareRepositoryTest extends KernelTestCase $repository = new PersonDocumentACLAwareRepository( $this->entityManager, $centerManager->reveal(), - $authorizationHelper->reveal() + $authorizationHelper->reveal(), + $this->prophesize(Security::class)->reveal() ); $person = $this->entityManager->createQuery("SELECT p FROM " . Person::class . " p") @@ -86,6 +89,62 @@ class PersonDocumentACLAwareRepositoryTest extends KernelTestCase self::assertIsInt($nb, "test that the query could be executed"); } + /** + * @dataProvider provideDateForFetchQueryForAccompanyingPeriod + */ + public function testBuildFetchQueryForAccompanyingPeriod( + AccompanyingPeriod $period, + ?\DateTimeImmutable $startDate = null, + ?\DateTimeImmutable $endDate = null, + ?string $content = null + ): void { + $centerManager = $this->prophesize(CenterResolverManagerInterface::class); + $centerManager->resolveCenters(Argument::type(Person::class)) + ->willReturn([new Center()]); + + $scopes = $this->scopeRepository->findAll(); + $authorizationHelper = $this->prophesize(AuthorizationHelperForCurrentUserInterface::class); + $authorizationHelper->getReachableScopes(PersonDocumentVoter::SEE, Argument::any())->willReturn($scopes); + + $security = $this->prophesize(Security::class); + $security->isGranted(PersonDocumentVoter::SEE, Argument::type(Person::class))->willReturn(true); + + $repository = new PersonDocumentACLAwareRepository( + $this->entityManager, + $centerManager->reveal(), + $authorizationHelper->reveal(), + $security->reveal() + ); + + $query = $repository->buildFetchQueryForAccompanyingPeriod($period, $startDate, $endDate, $content); + ['sql' => $sql, 'params' => $params, 'types' => $types] = (new FetchQueryToSqlBuilder())->toSql($query); + + $nb = $this->entityManager->getConnection() + ->fetchOne("SELECT COUNT(*) FROM ({$sql}) AS sq", $params, $types); + + self::assertIsInt($nb, "test that the query could be executed"); + } + + public function provideDateForFetchQueryForAccompanyingPeriod(): iterable + { + $this->setUp(); + + if (null === $period = $this->entityManager->createQuery( + "SELECT p FROM " . AccompanyingPeriod::class . " p WHERE SIZE(p.participations) > 0" + ) + ->setMaxResults(1)->getSingleResult()) { + throw new \RuntimeException("no course found"); + } + + yield [$period, null, null, null]; + yield [$period, new DateTimeImmutable('1 year ago'), null, null]; + yield [$period, null, new DateTimeImmutable('1 year ago'), null]; + yield [$period, new DateTimeImmutable('2 years ago'), new DateTimeImmutable('1 year ago'), null]; + yield [$period, null, null, 'test']; + yield [$period, new DateTimeImmutable('2 years ago'), new DateTimeImmutable('1 year ago'), 'test']; + + } + public function provideDataBuildFetchQueryForPerson(): iterable { yield [null, null, null]; diff --git a/src/Bundle/ChillDocStoreBundle/translations/messages.fr.yml b/src/Bundle/ChillDocStoreBundle/translations/messages.fr.yml index 1dde57eee..d4531fa2b 100644 --- a/src/Bundle/ChillDocStoreBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillDocStoreBundle/translations/messages.fr.yml @@ -18,6 +18,7 @@ No document found: Aucun document trouvé The document is successfully registered: Le document est enregistré The document is successfully updated: Le document est mis à jour Any description: Aucune description +Document from person %name%: Document de l'usager %name% document: Any title: Aucun titre @@ -26,6 +27,7 @@ generic_doc: filter: keys: accompanying_course_document: Document du parcours + person_document: Documents de l'usager date-range: Date du document # delete diff --git a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php index a8e191df3..18ad2da7d 100644 --- a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php +++ b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php @@ -269,6 +269,7 @@ class AccompanyingPeriod implements * cascade={"persist", "refresh", "remove", "merge", "detach"}) * @Groups({"read", "docgen:read"}) * @ParticipationOverlap(groups={AccompanyingPeriod::STEP_DRAFT, AccompanyingPeriod::STEP_CONFIRMED}) + * @var Collection */ private Collection $participations; @@ -870,6 +871,7 @@ class AccompanyingPeriod implements /** * Get Participations Collection. + * @return Collection */ public function getParticipations(): Collection { diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index 6205fabae..aeaa2bb3f 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -1236,4 +1236,3 @@ generic_doc: filter: keys: accompanying_period_work_evaluation_document: Document des actions d'accompagnement - person_document: Documents de la personne From 4632c18d930dcdd794ad849e9f98ccc243e44509 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 27 Jun 2023 18:26:41 +0200 Subject: [PATCH 212/321] restore feature: generate a document from period --- .../views/GenericDoc/accompanying_period_list.html.twig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Bundle/ChillDocStoreBundle/Resources/views/GenericDoc/accompanying_period_list.html.twig b/src/Bundle/ChillDocStoreBundle/Resources/views/GenericDoc/accompanying_period_list.html.twig index f76e4b984..b22c7d00f 100644 --- a/src/Bundle/ChillDocStoreBundle/Resources/views/GenericDoc/accompanying_period_list.html.twig +++ b/src/Bundle/ChillDocStoreBundle/Resources/views/GenericDoc/accompanying_period_list.html.twig @@ -8,12 +8,14 @@ {% block js %} {{ parent() }} + {{ encore_entry_script_tags('mod_docgen_picktemplate') }} {{ encore_entry_script_tags('mod_entity_workflow_pick') }} {{ encore_entry_script_tags('mod_document_action_buttons_group') }} {% endblock %} {% block css %} {{ parent() }} + {{ encore_entry_script_tags('mod_docgen_picktemplate') }} {{ encore_entry_link_tags('mod_entity_workflow_pick') }} {{ encore_entry_link_tags('mod_document_action_buttons_group') }} {% endblock %} @@ -36,6 +38,8 @@ {{ chill_pagination(pagination) }} +
    + {% if is_granted('CHILL_ACCOMPANYING_COURSE_DOCUMENT_CREATE', accompanyingCourse) %}
    • From da50fbc1fb7bdea6b6b62bd9f79c5202c8982fe1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 27 Jun 2023 18:46:04 +0200 Subject: [PATCH 213/321] update for release v2.3.0 --- .../unreleased/Feature-20230606-105153.yaml | 6 --- .../unreleased/Feature-20230613-151546.yaml | 5 --- .../unreleased/Feature-20230627-111222.yaml | 6 --- .../unreleased/Feature-20230627-151615.yaml | 28 ------------ .../unreleased/Feature-20230627-155925.yaml | 6 --- .changes/v2.3.0.md | 42 ++++++++++++++++++ CHANGELOG.md | 43 +++++++++++++++++++ 7 files changed, 85 insertions(+), 51 deletions(-) delete mode 100644 .changes/unreleased/Feature-20230606-105153.yaml delete mode 100644 .changes/unreleased/Feature-20230613-151546.yaml delete mode 100644 .changes/unreleased/Feature-20230627-111222.yaml delete mode 100644 .changes/unreleased/Feature-20230627-151615.yaml delete mode 100644 .changes/unreleased/Feature-20230627-155925.yaml create mode 100644 .changes/v2.3.0.md diff --git a/.changes/unreleased/Feature-20230606-105153.yaml b/.changes/unreleased/Feature-20230606-105153.yaml deleted file mode 100644 index 00c3ab1da..000000000 --- a/.changes/unreleased/Feature-20230606-105153.yaml +++ /dev/null @@ -1,6 +0,0 @@ -kind: Feature -body: 'Edit saved exports options: the saved exports options (forms, filters, aggregators) - are now editable.' -time: 2023-06-06T10:51:53.331701352+02:00 -custom: - Issue: "110" diff --git a/.changes/unreleased/Feature-20230613-151546.yaml b/.changes/unreleased/Feature-20230613-151546.yaml deleted file mode 100644 index e66076aa5..000000000 --- a/.changes/unreleased/Feature-20230613-151546.yaml +++ /dev/null @@ -1,5 +0,0 @@ -kind: Feature -body: Get an unified list of document in person and accompanying period context -time: 2023-06-13T15:15:46.146899906+02:00 -custom: - Issue: "103" diff --git a/.changes/unreleased/Feature-20230627-111222.yaml b/.changes/unreleased/Feature-20230627-111222.yaml deleted file mode 100644 index 1946b9332..000000000 --- a/.changes/unreleased/Feature-20230627-111222.yaml +++ /dev/null @@ -1,6 +0,0 @@ -kind: Feature -body: '[export] Set the default date of calculation of the accompanying period''s - list as "today"' -time: 2023-06-27T11:12:22.296330037+02:00 -custom: - Issue: "" diff --git a/.changes/unreleased/Feature-20230627-151615.yaml b/.changes/unreleased/Feature-20230627-151615.yaml deleted file mode 100644 index 499e874dc..000000000 --- a/.changes/unreleased/Feature-20230627-151615.yaml +++ /dev/null @@ -1,28 +0,0 @@ -kind: Feature -body: "Force accompanying period user history to be unique for the same period and - stardate/enddate [:warning: may encounter migration issue]" -time: 2023-06-27T15:16:15.775571488+02:00 -custom: - Issue: "" - Long: "If some issue is encountered during migration, use this SQL to find the line which are in conflict, examine the problem and delete some of the concerning line - - ```sql - - -- to see the line which are in conflict with another one - - SELECT o.* - - FROM chill_person_accompanying_period_user_history o - - JOIN chill_person_accompanying_period_user_history c ON o.id < c.id AND o.accompanyingperiod_id = c.accompanyingperiod_id - - WHERE tsrange(o.startdate, o.enddate, '[)') && tsrange(c.startdate, c.enddate, '[)') - - ORDER BY accompanyingperiod_id; - - -- to examine line in conflict for a given accompanyingperiod_id (given by the previous query) - - SELECT * FROM chill_person_accompanying_period_user_history WHERE accompanyingperiod_id = IIIIDDDD order by startdate, enddate; - - ``` - " diff --git a/.changes/unreleased/Feature-20230627-155925.yaml b/.changes/unreleased/Feature-20230627-155925.yaml deleted file mode 100644 index b134adab5..000000000 --- a/.changes/unreleased/Feature-20230627-155925.yaml +++ /dev/null @@ -1,6 +0,0 @@ -kind: Feature -body: 'Rename label of filter in French: "parcours actif" => "parcours ouvert", and - "filtrer les parcours ouverts" => "Filtrer les parcours dont la date d''ouverture"' -time: 2023-06-27T15:59:25.442854464+02:00 -custom: - Issue: "" diff --git a/.changes/v2.3.0.md b/.changes/v2.3.0.md new file mode 100644 index 000000000..827a338de --- /dev/null +++ b/.changes/v2.3.0.md @@ -0,0 +1,42 @@ +## v2.3.0 - 2023-06-27 +### Feature +* ([#110](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/110)) Edit saved exports options: the saved exports options (forms, filters, aggregators) are now editable. +* ([#103](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/103)) Get an unified list of document in person and accompanying period context +* [export] Set the default date of calculation of the accompanying period's list as "today" +* Force accompanying period user history to be unique for the same period and stardate/enddate [:warning: may encounter migration issue] + + If some issue is encountered during migration, use this SQL to find the line which are in conflict, examine the problem and delete some of the concerning line +* + ```sql + -- to see the line which are in conflict with another one + SELECT o.* + FROM chill_person_accompanying_period_user_history o + JOIN chill_person_accompanying_period_user_history c ON o.id < c.id AND o.accompanyingperiod_id = c.accompanyingperiod_id + WHERE tsrange(o.startdate, o.enddate, '[)') && tsrange(c.startdate, c.enddate, '[)') + ORDER BY accompanyingperiod_id; + -- to examine line in conflict for a given accompanyingperiod_id (given by the previous query) + SELECT * FROM chill_person_accompanying_period_user_history WHERE accompanyingperiod_id = IIIIDDDD order by startdate, enddate; + ``` +* Rename label of filter in French: "parcours actif" => "parcours ouvert", and "filtrer les parcours ouverts" => "Filtrer les parcours dont la date d'ouverture" + +### Traduction francophone des principaux changements + +* Les exports enregistrés sont éditables par l'utilisateur; +* L'onglet "Document" dans les parcours et les dossiers d'usager affiche désormais les documents ajoutés à différents endroits. + + Pour les parcours, il s'agit de: + + - documents ajoutés directement dans le parcours; + - documents des échanges; + - documents des rendez-vous; + - documents des évaluations; + - documents directement ajoutés dans le dossier des usagers concernés par le parcours; + + Pour les usagers, il s'agit de: + + - documents des échanges; + - documents des parcours; + - documents des rendez-vous; + - documents des actions, des échanges, des rendez-vous, des évaluations ajoutés dans les parcours. +* Dans la liste des parcours, la date de calcul des éléments associés est "aujourd'hui" par défaut. +* Dans les exports, renommage des libellés des filtres: "parcours actif" => "parcours ouvert", et "filtrer les parcours ouverts" => "Filtrer les parcours dont la date d'ouverture" diff --git a/CHANGELOG.md b/CHANGELOG.md index ab33c7fc4..93ff93556 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,49 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), and is generated by [Changie](https://github.com/miniscruff/changie). +## v2.3.0 - 2023-06-27 +### Feature +* ([#110](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/110)) Edit saved exports options: the saved exports options (forms, filters, aggregators) are now editable. +* ([#103](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/103)) Get an unified list of document in person and accompanying period context +* [export] Set the default date of calculation of the accompanying period's list as "today" +* Force accompanying period user history to be unique for the same period and stardate/enddate [:warning: may encounter migration issue] + + If some issue is encountered during migration, use this SQL to find the line which are in conflict, examine the problem and delete some of the concerning line +* + ```sql + -- to see the line which are in conflict with another one + SELECT o.* + FROM chill_person_accompanying_period_user_history o + JOIN chill_person_accompanying_period_user_history c ON o.id < c.id AND o.accompanyingperiod_id = c.accompanyingperiod_id + WHERE tsrange(o.startdate, o.enddate, '[)') && tsrange(c.startdate, c.enddate, '[)') + ORDER BY accompanyingperiod_id; + -- to examine line in conflict for a given accompanyingperiod_id (given by the previous query) + SELECT * FROM chill_person_accompanying_period_user_history WHERE accompanyingperiod_id = IIIIDDDD order by startdate, enddate; + ``` +* Rename label of filter in French: "parcours actif" => "parcours ouvert", and "filtrer les parcours ouverts" => "Filtrer les parcours dont la date d'ouverture" + +### Traduction francophone des principaux changements + +* Les exports enregistrés sont éditables par l'utilisateur; +* L'onglet "Document" dans les parcours et les dossiers d'usager affiche désormais les documents ajoutés à différents endroits. + + Pour les parcours, il s'agit de: + + - documents ajoutés directement dans le parcours; + - documents des échanges; + - documents des rendez-vous; + - documents des évaluations; + - documents directement ajoutés dans le dossier des usagers concernés par le parcours; + + Pour les usagers, il s'agit de: + + - documents des échanges; + - documents des parcours; + - documents des rendez-vous; + - documents des actions, des échanges, des rendez-vous, des évaluations ajoutés dans les parcours. +* Dans la liste des parcours, la date de calcul des éléments associés est "aujourd'hui" par défaut. +* Dans les exports, renommage des libellés des filtres: "parcours actif" => "parcours ouvert", et "filtrer les parcours ouverts" => "Filtrer les parcours dont la date d'ouverture" + ## v2.2.2 - 2023-06-26 ### Fixed * [Accompanying period comments]: order comments from the most recent to the oldest, in the list From 90e868779976c529c792cca5e0f0ecc6c389ea7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 28 Jun 2023 17:01:42 +0200 Subject: [PATCH 214/321] Fixed: [export] rename label on CurrentActionFilter --- .changes/unreleased/Fixed-20230628-170055.yaml | 6 ++++++ .../Export/Filter/SocialWorkFilters/CurrentActionFilter.php | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 .changes/unreleased/Fixed-20230628-170055.yaml diff --git a/.changes/unreleased/Fixed-20230628-170055.yaml b/.changes/unreleased/Fixed-20230628-170055.yaml new file mode 100644 index 000000000..7f9ec3028 --- /dev/null +++ b/.changes/unreleased/Fixed-20230628-170055.yaml @@ -0,0 +1,6 @@ +kind: Fixed +body: '[export] Rename label for CurrentActionFilter (on accompanying period work) + to make precision between "ouvert" and "sans date de fin"' +time: 2023-06-28T17:00:55.206937751+02:00 +custom: + Issue: "" diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/CurrentActionFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/CurrentActionFilter.php index e99590025..09551a3c5 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/CurrentActionFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/CurrentActionFilter.php @@ -44,11 +44,11 @@ class CurrentActionFilter implements FilterInterface public function describeAction($data, $format = 'string'): array { - return ['Filtered by current action']; + return ['Filtered actions without end date']; } public function getTitle(): string { - return 'Filter by current actions'; + return 'Filter actions without end date'; } } From 347eda05df8ec3a2b6f106c7a0470970270543cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 29 Jun 2023 12:44:28 +0200 Subject: [PATCH 215/321] Fix: force the consistency of location in accompanying period - internally, the entity remove the addressLocation when the personLocation is set, and vice-versa; - this commit add a migration which may solve the case when both case happens (priority to personLocation + keep the history) - add a constraint on the database to avoid such situation --- .../unreleased/Fixed-20230629-124412.yaml | 6 +++ .../Entity/AccompanyingPeriod.php | 5 ++- .../Tests/Entity/AccompanyingPeriodTest.php | 33 +++++++++++--- .../migrations/Version20230628152138.php | 45 +++++++++++++++++++ .../translations/messages.fr.yml | 4 +- 5 files changed, 85 insertions(+), 8 deletions(-) create mode 100644 .changes/unreleased/Fixed-20230629-124412.yaml create mode 100644 src/Bundle/ChillPersonBundle/migrations/Version20230628152138.php diff --git a/.changes/unreleased/Fixed-20230629-124412.yaml b/.changes/unreleased/Fixed-20230629-124412.yaml new file mode 100644 index 000000000..7fc3d3eb0 --- /dev/null +++ b/.changes/unreleased/Fixed-20230629-124412.yaml @@ -0,0 +1,6 @@ +kind: Fixed +body: Force the db to have either a person_location or a address_location, and avoid + to have both also internally in the entity +time: 2023-06-29T12:44:12.019663991+02:00 +custom: + Issue: "" diff --git a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php index ba2fca2af..07e1bafe4 100644 --- a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php +++ b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php @@ -786,7 +786,7 @@ class AccompanyingPeriod implements } /** - * @return Collection|AccompanyingPeriodLocationHistory[] + * @return Collection */ public function getLocationHistories(): Collection { @@ -797,6 +797,7 @@ class AccompanyingPeriod implements * Get where the location is. * * @Groups({"read"}) + * @return 'person'|'address'|'none' */ public function getLocationStatus(): string { @@ -1209,6 +1210,7 @@ class AccompanyingPeriod implements $this->addressLocation = $addressLocation; if (null !== $addressLocation) { + $this->setPersonLocation(null); $locationHistory = new AccompanyingPeriodLocationHistory(); $locationHistory ->setStartDate(new DateTimeImmutable('now')) @@ -1327,6 +1329,7 @@ class AccompanyingPeriod implements $this->personLocation = $person; if (null !== $person) { + $this->setAddressLocation(null); $locationHistory = new AccompanyingPeriodLocationHistory(); $locationHistory ->setStartDate(new DateTimeImmutable('now')) diff --git a/src/Bundle/ChillPersonBundle/Tests/Entity/AccompanyingPeriodTest.php b/src/Bundle/ChillPersonBundle/Tests/Entity/AccompanyingPeriodTest.php index 0a9c22df1..dad574000 100644 --- a/src/Bundle/ChillPersonBundle/Tests/Entity/AccompanyingPeriodTest.php +++ b/src/Bundle/ChillPersonBundle/Tests/Entity/AccompanyingPeriodTest.php @@ -138,12 +138,14 @@ final class AccompanyingPeriodTest extends \PHPUnit\Framework\TestCase $this->assertCount(1, $period->getLocationHistories()); $this->assertSame($address, $period->getLocationHistories()->first()->getAddressLocation()); + $this->assertNull($period->getLocationHistories()->first()->getPersonLocation()); $period->setPersonLocation($person); $period->setAddressLocation(null); $this->assertCount(2, $period->getLocationHistories()); $this->assertSame($person, $period->getLocationHistories()->last()->getPersonLocation()); + $this->assertNull($period->getLocationHistories()->last()->getAddressLocation()); $period->setAddressLocation($address); $period->setPersonLocation(null); @@ -172,14 +174,35 @@ final class AccompanyingPeriodTest extends \PHPUnit\Framework\TestCase } while ($iterator->valid()); } - public function testIsClosed() - { - $period = new AccompanyingPeriod(new DateTime()); - $period->setClosingDate(new DateTime('tomorrow')); - $this->assertFalse($period->isOpen()); + public function testHistoryLocationNotHavingBothAtStart() + { + $period = new AccompanyingPeriod(); + $person = new Person(); + $address = new Address(); + + $period->setAddressLocation($address); + $period->setPersonLocation($person); + + $period->setStep(AccompanyingPeriod::STEP_CONFIRMED); + + $this->assertCount(1, $period->getLocationHistories()); + + self::assertNull($period->getAddressLocation()); + self::assertNull($period->getLocationHistories()->first()->getAddressLocation()); + self::assertSame($person, $period->getLocationHistories()->first()->getPersonLocation()); + self::assertSame($person, $period->getPersonLocation()); + self::assertEquals('person', $period->getLocationStatus()); } + public function testIsClosed() + { + $period = new AccompanyingPeriod(new DateTime()); + $period->setClosingDate(new DateTime('tomorrow')); + + $this->assertFalse($period->isOpen()); + } + public function testIsOpen() { $period = new AccompanyingPeriod(new DateTime()); diff --git a/src/Bundle/ChillPersonBundle/migrations/Version20230628152138.php b/src/Bundle/ChillPersonBundle/migrations/Version20230628152138.php new file mode 100644 index 000000000..240b99dbf --- /dev/null +++ b/src/Bundle/ChillPersonBundle/migrations/Version20230628152138.php @@ -0,0 +1,45 @@ +addSql('UPDATE chill_person_accompanying_period SET addresslocation_id = NULL + where personlocation_id IS NOT NULL AND addresslocation_id IS NOT NULL'); + $this->addSql('INSERT INTO chill_person_accompanying_period_location_history + (id, period_id, startdate, enddate, createdat, personlocation_id, addresslocation_id, createdby_id) + SELECT nextval(\'chill_person_accompanying_period_location_history_id_seq\'), period_id, startdate, startdate, now(), null, addresslocation_id, null + FROM chill_person_accompanying_period_location_history + WHERE personlocation_id IS NOT NULL AND addresslocation_id IS NOT NULL + '); + $this->addSql('UPDATE chill_person_accompanying_period_location_history SET addresslocation_id = NULL WHERE addresslocation_id IS NOT NULL AND personlocation_id IS NOT NULL'); + + $this->addSql('ALTER TABLE chill_person_accompanying_period ADD CONSTRAINT location_check CHECK (personlocation_id IS NULL OR addresslocation_id IS NULL)'); + $this->addSql('ALTER TABLE chill_person_accompanying_period_location_history ADD CONSTRAINT location_check CHECK (personlocation_id IS NULL OR addresslocation_id IS NULL)'); + } + + public function down(Schema $schema): void + { + $this->addSql('ALTER TABLE chill_person_accompanying_period DROP CONSTRAINT location_check'); + $this->addSql('ALTER TABLE chill_person_accompanying_period_location_history DROP CONSTRAINT location_check'); + } +} diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index 12647d04c..7387ccf1c 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -585,8 +585,8 @@ Filter by creator job: Filtrer les parcours par métier du créateur 'Filtered by creator job: only %jobs%': 'Filtré par métier du créateur: uniquement %jobs%' Group by creator job: Grouper les parcours par métier du créateur -Filter by current actions: Filtrer les actions en cours -Filtered by current action: 'Filtré: uniquement les actions en cours (sans date de fin)' +Filter actions without end date: Filtre les actions sans date de fin (ouvertes) +Filtered actions without end date: 'Filtré: uniquement les actions sans date de fin (ouvertes)' Filter by start date evaluations: Filtrer les évaluations par date de début Filter by end date evaluations: Filtrer les évaluations par date de fin start period date: Date de début de la période From 56940d830c46fa789cc12fd29a00cb0e8cda92b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 29 Jun 2023 17:45:39 +0200 Subject: [PATCH 216/321] fix typos --- .../ChillAsideActivityBundle/src/translations/messages.fr.yml | 3 ++- src/Bundle/ChillPersonBundle/translations/messages.fr.yml | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Bundle/ChillAsideActivityBundle/src/translations/messages.fr.yml b/src/Bundle/ChillAsideActivityBundle/src/translations/messages.fr.yml index cc428390c..25d07bd22 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/translations/messages.fr.yml +++ b/src/Bundle/ChillAsideActivityBundle/src/translations/messages.fr.yml @@ -176,11 +176,12 @@ export: agent_id: Utilisateur creator_id: Créateur main_scope: Service principal de l'utilisateur - main_center: Centre principal de l'utilisteur + main_center: Centre principal de l'utilisateur aside_activity_type: Catégorie d'activité annexe date: Date duration: Durée note: Note + id: Identifiant Exports of aside activities: Exports des activités annexes Count aside activities: Nombre d'activités annexes diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index 7387ccf1c..01383c050 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -1137,7 +1137,7 @@ export: createdAt: Créé le updatedAt: Dernière mise à jour le acpOrigin: Origine du parcours - origin: Origine du parcourse + origin: Origine du parcours acpClosingMotive: Motif de fermeture acpJob: Métier du parcours createdBy: Créé par From 31745bc25213a834bc2e5a5ecf04307494694bb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 29 Jun 2023 17:52:26 +0200 Subject: [PATCH 217/321] [export] order center alphabetically when generating an export --- src/Bundle/ChillMainBundle/Form/Type/Export/PickCenterType.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Bundle/ChillMainBundle/Form/Type/Export/PickCenterType.php b/src/Bundle/ChillMainBundle/Form/Type/Export/PickCenterType.php index d33ab2ade..c51676b32 100644 --- a/src/Bundle/ChillMainBundle/Form/Type/Export/PickCenterType.php +++ b/src/Bundle/ChillMainBundle/Form/Type/Export/PickCenterType.php @@ -57,6 +57,9 @@ final class PickCenterType extends AbstractType $export->requiredRole() ); + // order alphabetically + usort($centers, fn (Center $a, Center $b) => $a->getCenter() <=> $b->getName()); + $builder->add('center', EntityType::class, [ 'class' => Center::class, 'choices' => $centers, From c019fffbe74838d04da2204754b94d8a4200f6ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 29 Jun 2023 17:53:01 +0200 Subject: [PATCH 218/321] fix cs --- .../Tests/Entity/AccompanyingPeriodTest.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Tests/Entity/AccompanyingPeriodTest.php b/src/Bundle/ChillPersonBundle/Tests/Entity/AccompanyingPeriodTest.php index dad574000..bb7e2e80a 100644 --- a/src/Bundle/ChillPersonBundle/Tests/Entity/AccompanyingPeriodTest.php +++ b/src/Bundle/ChillPersonBundle/Tests/Entity/AccompanyingPeriodTest.php @@ -195,13 +195,13 @@ final class AccompanyingPeriodTest extends \PHPUnit\Framework\TestCase self::assertEquals('person', $period->getLocationStatus()); } - public function testIsClosed() - { - $period = new AccompanyingPeriod(new DateTime()); - $period->setClosingDate(new DateTime('tomorrow')); + public function testIsClosed() + { + $period = new AccompanyingPeriod(new DateTime()); + $period->setClosingDate(new DateTime('tomorrow')); - $this->assertFalse($period->isOpen()); - } + $this->assertFalse($period->isOpen()); + } public function testIsOpen() { From 4a5ac170ba30f548edaee801f08395ffa086cda0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 29 Jun 2023 13:16:40 +0200 Subject: [PATCH 219/321] [export] add dates for filter "user working on course" --- .../unreleased/Feature-20230629-131558.yaml | 6 +++ .../UserWorkingOnCourseFilter.php | 40 ++++++++++++++----- .../translations/messages.fr.yml | 4 +- 3 files changed, 40 insertions(+), 10 deletions(-) create mode 100644 .changes/unreleased/Feature-20230629-131558.yaml diff --git a/.changes/unreleased/Feature-20230629-131558.yaml b/.changes/unreleased/Feature-20230629-131558.yaml new file mode 100644 index 000000000..42d731c4f --- /dev/null +++ b/.changes/unreleased/Feature-20230629-131558.yaml @@ -0,0 +1,6 @@ +kind: Feature +body: '[export] on "filter by user working" on accompanying period, add two dates + to filters intervention within a period' +time: 2023-06-29T13:15:58.070316708+02:00 +custom: + Issue: "113" diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserWorkingOnCourseFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserWorkingOnCourseFilter.php index d078443af..1f9bfc61a 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserWorkingOnCourseFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserWorkingOnCourseFilter.php @@ -13,7 +13,10 @@ namespace Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters; use Chill\MainBundle\Entity\User; use Chill\MainBundle\Export\FilterInterface; +use Chill\MainBundle\Form\Type\PickRollingDateType; use Chill\MainBundle\Form\Type\PickUserDynamicType; +use Chill\MainBundle\Service\RollingDate\RollingDate; +use Chill\MainBundle\Service\RollingDate\RollingDateConverterInterface; use Chill\MainBundle\Templating\Entity\UserRender; use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Export\Declarations; @@ -27,11 +30,9 @@ use Symfony\Component\Form\FormBuilderInterface; */ readonly class UserWorkingOnCourseFilter implements FilterInterface { - private const AI_ALIAS = 'user_working_on_course_filter_acc_info'; - private const AI_USERS = 'user_working_on_course_filter_users'; - public function __construct( private UserRender $userRender, + private RollingDateConverterInterface $rollingDateConverter, ) { } @@ -40,11 +41,23 @@ readonly class UserWorkingOnCourseFilter implements FilterInterface $builder ->add('users', PickUserDynamicType::class, [ 'multiple' => true, - ]); + ]) + ->add('start_date', PickRollingDateType::class, [ + 'label' => 'export.filter.course.by_user_working.User working after' + ]) + ->add('end_date', PickRollingDateType::class, [ + 'label' => 'export.filter.course.by_user_working.User working before' + ]) + ; } + public function getFormDefaultData(): array { - return []; + return [ + 'users' => [], + 'start_date' => new RollingDate(RollingDate::T_YEAR_CURRENT_START), + 'end_date' => new RollingDate(RollingDate::T_TODAY), + ]; } public function getTitle(): string @@ -55,7 +68,7 @@ readonly class UserWorkingOnCourseFilter implements FilterInterface public function describeAction($data, $format = 'string'): array { return [ - 'export.filter.course.by_user_working.Filtered by user working on course: only %users%', [ + 'export.filter.course.by_user_working.Filtered by user working on course: only %users%, between %start_date% and %end_date%', [ '%users%' => implode( ', ', array_map( @@ -63,6 +76,8 @@ readonly class UserWorkingOnCourseFilter implements FilterInterface $data['users'] ) ), + '%start_date%' => $this->rollingDateConverter->convert($data['start_date'])?->format('d-m-Y'), + '%end_date%' => $this->rollingDateConverter->convert($data['end_date'])?->format('d-m-Y'), ], ]; } @@ -74,14 +89,21 @@ readonly class UserWorkingOnCourseFilter implements FilterInterface public function alterQuery(QueryBuilder $qb, $data): void { + $ai_alias = 'user_working_on_course_filter_acc_info'; + $ai_users = 'user_working_on_course_filter_users'; + $start = 'acp_use_work_on_start'; + $end = 'acp_use_work_on_end'; + $qb ->andWhere( $qb->expr()->exists( - "SELECT 1 FROM " . AccompanyingPeriod\AccompanyingPeriodInfo::class . " " . self::AI_ALIAS . " " . - "WHERE " . self::AI_ALIAS . ".user IN (:" . self::AI_USERS .") AND IDENTITY(" . self::AI_ALIAS . ".accompanyingPeriod) = acp.id" + "SELECT 1 FROM " . AccompanyingPeriod\AccompanyingPeriodInfo::class . " {$ai_alias} " . + "WHERE {$ai_alias}.user IN (:{$ai_users}) AND IDENTITY({$ai_alias}.accompanyingPeriod) = acp.id AND {$ai_alias}.infoDate >= :{$start} and {$ai_alias}.infoDate < :{$end}" ) ) - ->setParameter(self::AI_USERS, $data['users']) + ->setParameter($ai_users, $data['users']) + ->setParameter($start, $this->rollingDateConverter->convert($data['start_date'])) + ->setParameter($end, $this->rollingDateConverter->convert($data['end_date'])) ; } diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index 01383c050..464e8fa67 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -1082,7 +1082,9 @@ export: Only course with events between %startDate% and %endDate%: Seulement les parcours ayant reçu une intervention entre le %startDate% et le %endDate% by_user_working: title: Filter les parcours par intervenant - 'Filtered by user working on course: only %users%': 'Filtré par intervenants sur le parcours: seulement %users%' + 'Filtered by user working on course: only %users%, between %start_date% and %end_date%': 'Filtré par intervenants sur le parcours: seulement %users%, entre le %start_date% et le %end_date%' + User working after: Intervention après le + User working before: Intervention avant le by_step: Filter by step: Filtrer les parcours par statut du parcours Filter by step between dates: Filtrer les parcours par statut du parcours entre deux dates From 393e59e22bdab368ca6ca53fea6e079a8f1a19ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 29 Jun 2023 16:00:50 +0200 Subject: [PATCH 220/321] DX: Rolling date: allow to receive a null parameter (RollingDate) When receiving a null parameter (a null rolling date), it will return null --- .changes/unreleased/DX-20230629-160029.yaml | 5 +++++ .../Service/RollingDate/RollingDateConverter.php | 6 +++++- .../Service/RollingDate/RollingDateConverterInterface.php | 6 +++++- 3 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 .changes/unreleased/DX-20230629-160029.yaml diff --git a/.changes/unreleased/DX-20230629-160029.yaml b/.changes/unreleased/DX-20230629-160029.yaml new file mode 100644 index 000000000..b83befec6 --- /dev/null +++ b/.changes/unreleased/DX-20230629-160029.yaml @@ -0,0 +1,5 @@ +kind: DX +body: 'Rolling Date: can receive a null parameter' +time: 2023-06-29T16:00:29.664814895+02:00 +custom: + Issue: "" diff --git a/src/Bundle/ChillMainBundle/Service/RollingDate/RollingDateConverter.php b/src/Bundle/ChillMainBundle/Service/RollingDate/RollingDateConverter.php index 026ff7a8a..72ad89c58 100644 --- a/src/Bundle/ChillMainBundle/Service/RollingDate/RollingDateConverter.php +++ b/src/Bundle/ChillMainBundle/Service/RollingDate/RollingDateConverter.php @@ -18,8 +18,12 @@ use UnexpectedValueException; class RollingDateConverter implements RollingDateConverterInterface { - public function convert(RollingDate $rollingDate): DateTimeImmutable + public function convert(?RollingDate $rollingDate): ?DateTimeImmutable { + if (null === $rollingDate) { + return null; + } + switch ($rollingDate->getRoll()) { case RollingDate::T_MONTH_CURRENT_START: return $this->toBeginOfMonth($rollingDate->getPivotDate()); diff --git a/src/Bundle/ChillMainBundle/Service/RollingDate/RollingDateConverterInterface.php b/src/Bundle/ChillMainBundle/Service/RollingDate/RollingDateConverterInterface.php index b20a5ced2..6c7d9a5bd 100644 --- a/src/Bundle/ChillMainBundle/Service/RollingDate/RollingDateConverterInterface.php +++ b/src/Bundle/ChillMainBundle/Service/RollingDate/RollingDateConverterInterface.php @@ -15,5 +15,9 @@ use DateTimeImmutable; interface RollingDateConverterInterface { - public function convert(RollingDate $rollingDate): DateTimeImmutable; + /** + * @param RollingDate|null $rollingDate + * @return ($rollingDate is null ? null : DateTimeImmutable) + */ + public function convert(?RollingDate $rollingDate): ?DateTimeImmutable; } From 5a395b160fd990d423887a6451a15f1f52768f6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 29 Jun 2023 17:39:26 +0200 Subject: [PATCH 221/321] [export] add aggregator and filter related to AccompanyingPeriodInfo + Center aggregator for Person see #113 --- .../unreleased/Feature-20230629-173445.yaml | 5 + .../unreleased/Feature-20230629-173509.yaml | 5 + .../unreleased/Feature-20230629-173544.yaml | 5 + .../unreleased/Feature-20230629-173617.yaml | 5 + .../unreleased/Feature-20230629-173822.yaml | 5 + .../unreleased/Feature-20230629-173844.yaml | 5 + exports_alias_conventions.md | 3 + .../JobWorkingOnCourseAggregator.php | 100 +++++++++++++ .../ScopeWorkingOnCourseAggregator.php | 101 ++++++++++++++ .../UserWorkingOnCourseAggregator.php | 100 +++++++++++++ .../PersonAggregators/CenterAggregator.php | 103 ++++++++++++++ .../JobWorkingOnCourseFilter.php | 130 +++++++++++++++++ .../OpenBetweenDatesFilter.php | 2 +- .../ScopeWorkingOnCourseFilter.php | 132 ++++++++++++++++++ .../services/exports_accompanying_course.yaml | 20 +++ .../config/services/exports_person.yaml | 5 + .../translations/messages.fr.yml | 28 +++- 17 files changed, 751 insertions(+), 3 deletions(-) create mode 100644 .changes/unreleased/Feature-20230629-173445.yaml create mode 100644 .changes/unreleased/Feature-20230629-173509.yaml create mode 100644 .changes/unreleased/Feature-20230629-173544.yaml create mode 100644 .changes/unreleased/Feature-20230629-173617.yaml create mode 100644 .changes/unreleased/Feature-20230629-173822.yaml create mode 100644 .changes/unreleased/Feature-20230629-173844.yaml create mode 100644 src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/JobWorkingOnCourseAggregator.php create mode 100644 src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ScopeWorkingOnCourseAggregator.php create mode 100644 src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/UserWorkingOnCourseAggregator.php create mode 100644 src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/CenterAggregator.php create mode 100644 src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/JobWorkingOnCourseFilter.php create mode 100644 src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ScopeWorkingOnCourseFilter.php diff --git a/.changes/unreleased/Feature-20230629-173445.yaml b/.changes/unreleased/Feature-20230629-173445.yaml new file mode 100644 index 000000000..2d3642a85 --- /dev/null +++ b/.changes/unreleased/Feature-20230629-173445.yaml @@ -0,0 +1,5 @@ +kind: Feature +body: '[export] Add an aggregator by user''s job working on a course' +time: 2023-06-29T17:34:45.278993433+02:00 +custom: + Issue: "113" diff --git a/.changes/unreleased/Feature-20230629-173509.yaml b/.changes/unreleased/Feature-20230629-173509.yaml new file mode 100644 index 000000000..95fd23458 --- /dev/null +++ b/.changes/unreleased/Feature-20230629-173509.yaml @@ -0,0 +1,5 @@ +kind: Feature +body: '[export] add an aggregator by user''s scope working on a course' +time: 2023-06-29T17:35:09.548758741+02:00 +custom: + Issue: "113" diff --git a/.changes/unreleased/Feature-20230629-173544.yaml b/.changes/unreleased/Feature-20230629-173544.yaml new file mode 100644 index 000000000..94e79bc6d --- /dev/null +++ b/.changes/unreleased/Feature-20230629-173544.yaml @@ -0,0 +1,5 @@ +kind: Feature +body: '[export] on aggregator "user working on a course"' +time: 2023-06-29T17:35:44.998468724+02:00 +custom: + Issue: "" diff --git a/.changes/unreleased/Feature-20230629-173617.yaml b/.changes/unreleased/Feature-20230629-173617.yaml new file mode 100644 index 000000000..445b85cff --- /dev/null +++ b/.changes/unreleased/Feature-20230629-173617.yaml @@ -0,0 +1,5 @@ +kind: Feature +body: '[export] add a center aggregator for Person' +time: 2023-06-29T17:36:17.635876613+02:00 +custom: + Issue: "113" diff --git a/.changes/unreleased/Feature-20230629-173822.yaml b/.changes/unreleased/Feature-20230629-173822.yaml new file mode 100644 index 000000000..6a1569d00 --- /dev/null +++ b/.changes/unreleased/Feature-20230629-173822.yaml @@ -0,0 +1,5 @@ +kind: Feature +body: '[export] add a filter on "job working on a course"' +time: 2023-06-29T17:38:22.682951416+02:00 +custom: + Issue: "113" diff --git a/.changes/unreleased/Feature-20230629-173844.yaml b/.changes/unreleased/Feature-20230629-173844.yaml new file mode 100644 index 000000000..f307ebf57 --- /dev/null +++ b/.changes/unreleased/Feature-20230629-173844.yaml @@ -0,0 +1,5 @@ +kind: Feature +body: '[export] Add a filter on "scope working on a course"' +time: 2023-06-29T17:38:44.238287822+02:00 +custom: + Issue: "113" diff --git a/exports_alias_conventions.md b/exports_alias_conventions.md index fd7844691..64df91030 100644 --- a/exports_alias_conventions.md +++ b/exports_alias_conventions.md @@ -18,6 +18,7 @@ These are alias conventions : | | SocialIssue::class | acp.socialIssues | acpsocialissue | | | User::class | acp.user | acpuser | | | AccompanyingPeriopStepHistory::class | acp.stepHistories | acpstephistories | +| | AccompanyingPeriodInfo::class | not existing (using custom WITH clause) | acpinfo | | AccompanyingPeriodWork::class | | | acpw | | | AccompanyingPeriodWorkEvaluation::class | acpw.accompanyingPeriodWorkEvaluations | workeval | | | User::class | acpw.referrers | acpwuser | @@ -28,6 +29,8 @@ These are alias conventions : | | Person::class | acppart.person | partperson | | AccompanyingPeriodWorkEvaluation::class | | | workeval | | | Evaluation::class | workeval.evaluation | eval | +| AccompanyingPeriodInfo::class | | | acpinfo | +| | User::class | acpinfo.user | acpinfo_user | | Goal::class | | | goal | | | Result::class | goal.results | goalresult | | Person::class | | | person | diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/JobWorkingOnCourseAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/JobWorkingOnCourseAggregator.php new file mode 100644 index 000000000..e93300e85 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/JobWorkingOnCourseAggregator.php @@ -0,0 +1,100 @@ +userJobRepository->find((int) $jobId)) { + return ''; + } + + return $this->translatableStringHelper->localize($job->getLabel()); + }; + } + + public function getQueryKeys($data) + { + return [self::COLUMN_NAME]; + } + + public function getTitle() + { + return 'export.aggregator.course.by_job_working.title'; + } + + public function addRole(): ?string + { + return null; + } + + public function alterQuery(QueryBuilder $qb, $data) + { + if (!in_array('acpinfo', $qb->getAllAliases(), true)) { + $qb->leftJoin( + AccompanyingPeriodInfo::class, + 'acpinfo', + Join::WITH, + 'acp.id = IDENTITY(acpinfo.accompanyingPeriod)' + ); + } + + if (!in_array('acpinfo_user', $qb->getAllAliases(), true)) { + $qb->leftJoin('acpinfo.user', 'acpinfo_user'); + } + + $qb->addSelect('IDENTITY(acpinfo_user.userJob) AS ' . self::COLUMN_NAME); + $qb->addGroupBy(self::COLUMN_NAME); + } + + public function applyOn() + { + return Declarations::ACP_TYPE; + } +} diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ScopeWorkingOnCourseAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ScopeWorkingOnCourseAggregator.php new file mode 100644 index 000000000..b9f493af9 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ScopeWorkingOnCourseAggregator.php @@ -0,0 +1,101 @@ +scopeRepository->find((int) $scopeId)) { + return ''; + } + + return $this->translatableStringHelper->localize($scope->getName()); + }; + } + + public function getQueryKeys($data) + { + return [self::COLUMN_NAME]; + } + + public function getTitle() + { + return 'export.aggregator.course.by_scope_working.title'; + } + + public function addRole(): ?string + { + return null; + } + + public function alterQuery(QueryBuilder $qb, $data) + { + if (!in_array('acpinfo', $qb->getAllAliases(), true)) { + $qb->leftJoin( + AccompanyingPeriodInfo::class, + 'acpinfo', + Join::WITH, + 'acp.id = IDENTITY(acpinfo.accompanyingPeriod)' + ); + } + + if (!in_array('acpinfo_user', $qb->getAllAliases(), true)) { + $qb->leftJoin('acpinfo.user', 'acpinfo_user'); + } + + $qb->addSelect('IDENTITY(acpinfo_user.mainScope) AS ' . self::COLUMN_NAME); + $qb->addGroupBy(self::COLUMN_NAME); + } + + public function applyOn() + { + return Declarations::ACP_TYPE; + } +} diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/UserWorkingOnCourseAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/UserWorkingOnCourseAggregator.php new file mode 100644 index 000000000..b4941fa01 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/UserWorkingOnCourseAggregator.php @@ -0,0 +1,100 @@ +userRepository->find((int) $userId)) { + return ''; + } + + return $this->userRender->renderString($user, []); + }; + } + + public function getQueryKeys($data) + { + return [self::COLUMN_NAME]; + } + + public function getTitle() + { + return 'export.aggregator.course.by_user_working.title'; + } + + public function addRole(): ?string + { + return null; + } + + public function alterQuery(QueryBuilder $qb, $data) + { + if (!in_array('acpinfo', $qb->getAllAliases(), true)) { + $qb->leftJoin( + AccompanyingPeriodInfo::class, + 'acpinfo', + Join::WITH, + 'acp.id = IDENTITY(acpinfo.accompanyingPeriod)' + ); + } + + if (!in_array('acpinfo_user', $qb->getAllAliases(), true)) { + $qb->leftJoin('acpinfo.user', 'acpinfo_user'); + } + + $qb->addSelect('acpinfo_user.id AS ' . self::COLUMN_NAME); + $qb->addGroupBy('acpinfo_user.id'); + } + + public function applyOn() + { + return Declarations::ACP_TYPE; + } +} diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/CenterAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/CenterAggregator.php new file mode 100644 index 000000000..9be0b0c7e --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/CenterAggregator.php @@ -0,0 +1,103 @@ +add('at_date', PickRollingDateType::class, [ + 'label' => 'export.aggregator.person.by_center.at_date', + ]); + } + + public function getFormDefaultData(): array + { + return [ + 'at_date' => new RollingDate(RollingDate::T_TODAY) + ]; + } + + public function getLabels($key, array $values, $data): Closure + { + return function (int|string|null $value) { + if (null === $value || '' === $value) { + return ''; + } + + if ('_header' === $value) { + return 'export.aggregator.person.by_center.center'; + } + + return (string) $this->centerRepository->find((int) $value)?->getName(); + }; + } + + public function getQueryKeys($data) + { + return [self::COLUMN_NAME]; + } + + public function getTitle() + { + return 'export.aggregator.person.by_center.title'; + } + + public function addRole(): ?string + { + return null; + } + + public function alterQuery(QueryBuilder $qb, $data) + { + $alias = 'pers_center_agg'; + $atDate = 'pers_center_agg_at_date'; + + $qb->leftJoin('person.centerHistory', $alias); + $qb + ->andWhere( + $qb->expr()->lte($alias.'.startDate', ':'.$atDate), + )->andWhere( + $qb->expr()->orX( + $qb->expr()->isNull($alias.'.endDate'), + $qb->expr()->gt($alias.'.endDate', ':'.$atDate) + ) + ); + $qb->setParameter($atDate, $this->rollingDateConverter->convert($data['at_date'])); + + $qb->addSelect("IDENTITY({$alias}.center) AS " . self::COLUMN_NAME); + $qb->addGroupBy(self::COLUMN_NAME); + } + + public function applyOn() + { + return Declarations::PERSON_TYPE; + } +} diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/JobWorkingOnCourseFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/JobWorkingOnCourseFilter.php new file mode 100644 index 000000000..63a668b6d --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/JobWorkingOnCourseFilter.php @@ -0,0 +1,130 @@ +userJobRepository->findAllActive(); + usort($jobs, fn (UserJob $a, UserJob $b) => $this->translatableStringHelper->localize($a->getLabel()) <=> $this->translatableStringHelper->localize($b->getLabel())); + + $builder + ->add('jobs', EntityType::class, [ + 'class' => UserJob::class, + 'choices' => $jobs, + 'choice_label' => fn (UserJob $userJob) => $this->translatableStringHelper->localize($userJob->getLabel()), + 'multiple' => true, + 'expanded' => true, + ]) + ->add('start_date', PickRollingDateType::class, [ + 'label' => 'export.filter.course.by_job_working.Job working after' + ]) + ->add('end_date', PickRollingDateType::class, [ + 'label' => 'export.filter.course.by_job_working.Job working before' + ]) + ; + } + + public function getFormDefaultData(): array + { + return [ + 'jobs' => [], + 'start_date' => new RollingDate(RollingDate::T_YEAR_CURRENT_START), + 'end_date' => new RollingDate(RollingDate::T_TODAY), + ]; + } + + public function getTitle(): string + { + return 'export.filter.course.by_job_working.title'; + } + + public function describeAction($data, $format = 'string'): array + { + return [ + 'export.filter.course.by_job_working.Filtered by job working on course: only %jobs%, between %start_date% and %end_date%', [ + '%jobs%' => implode( + ', ', + array_map( + fn (UserJob $userJob) => $this->translatableStringHelper->localize($userJob->getLabel()), + $data['jobs'] + ) + ), + '%start_date%' => $this->rollingDateConverter->convert($data['start_date'])?->format('d-m-Y'), + '%end_date%' => $this->rollingDateConverter->convert($data['end_date'])?->format('d-m-Y'), + ], + ]; + } + + public function addRole(): ?string + { + return null; + } + + public function alterQuery(QueryBuilder $qb, $data): void + { + $ai_alias = 'jobs_working_on_course_filter_acc_info'; + $ai_user_alias = 'jobs_working_on_course_filter_user'; + $ai_jobs = 'jobs_working_on_course_filter_jobs'; + $start = 'acp_jobs_work_on_start'; + $end = 'acp_jobs_work_on_end'; + + $qb + ->andWhere( + $qb->expr()->exists( + "SELECT 1 FROM " . AccompanyingPeriod\AccompanyingPeriodInfo::class . " {$ai_alias} JOIN {$ai_alias}.user {$ai_user_alias} " . + "WHERE IDENTITY({$ai_alias}.accompanyingPeriod) = acp.id + AND {$ai_user_alias}.userJob IN (:{$ai_jobs}) + AND {$ai_alias}.infoDate >= :{$start} and {$ai_alias}.infoDate < :{$end} + " + ) + ) + ->setParameter($ai_jobs, $data['jobs']) + ->setParameter($start, $this->rollingDateConverter->convert($data['start_date'])) + ->setParameter($end, $this->rollingDateConverter->convert($data['end_date'])) + ; + } + + public function applyOn(): string + { + return Declarations::ACP_TYPE; + } +} diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/OpenBetweenDatesFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/OpenBetweenDatesFilter.php index e9413083f..69fdd7bc0 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/OpenBetweenDatesFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/OpenBetweenDatesFilter.php @@ -38,7 +38,7 @@ class OpenBetweenDatesFilter implements FilterInterface { $clause = $qb->expr()->andX( $qb->expr()->gte('acp.openingDate', ':datefrom'), - $qb->expr()->lte('acp.openingDate', ':dateto') + $qb->expr()->lt('acp.openingDate', ':dateto') ); $qb->andWhere($clause); diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ScopeWorkingOnCourseFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ScopeWorkingOnCourseFilter.php new file mode 100644 index 000000000..b9787bf52 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ScopeWorkingOnCourseFilter.php @@ -0,0 +1,132 @@ +scopeRepository->findAllActive(); + usort($scopes, fn (Scope $a, Scope $b) => $this->translatableStringHelper->localize($a->getName()) <=> $this->translatableStringHelper->localize($b->getName())); + + $builder + ->add('scopes', EntityType::class, [ + 'class' => Scope::class, + 'choices' => $scopes, + 'choice_label' => fn (Scope $scope) => $this->translatableStringHelper->localize($scope->getName()), + 'multiple' => true, + 'expanded' => true, + ]) + ->add('start_date', PickRollingDateType::class, [ + 'label' => 'export.filter.course.by_scope_working.Scope working after' + ]) + ->add('end_date', PickRollingDateType::class, [ + 'label' => 'export.filter.course.by_scope_working.Scope working before' + ]) + ; + } + + public function getFormDefaultData(): array + { + return [ + 'scopes' => [], + 'start_date' => new RollingDate(RollingDate::T_YEAR_CURRENT_START), + 'end_date' => new RollingDate(RollingDate::T_TODAY), + ]; + } + + public function getTitle(): string + { + return 'export.filter.course.by_scope_working.title'; + } + + public function describeAction($data, $format = 'string'): array + { + return [ + 'export.filter.course.by_scope_working.Filtered by scope working on course: only %scopes%, between %start_date% and %end_date%', [ + '%scopes%' => implode( + ', ', + array_map( + fn (Scope $scope) => $this->translatableStringHelper->localize($scope->getName()), + $data['scopes'] + ) + ), + '%start_date%' => $this->rollingDateConverter->convert($data['start_date'])?->format('d-m-Y'), + '%end_date%' => $this->rollingDateConverter->convert($data['end_date'])?->format('d-m-Y'), + ], + ]; + } + + public function addRole(): ?string + { + return null; + } + + public function alterQuery(QueryBuilder $qb, $data): void + { + $ai_alias = 'scopes_working_on_course_filter_acc_info'; + $ai_user_alias = 'scopes_working_on_course_filter_user'; + $ai_scopes = 'scopes_working_on_course_filter_scopes'; + $start = 'acp_scopes_work_on_start'; + $end = 'acp_scopes_work_on_end'; + + $qb + ->andWhere( + $qb->expr()->exists( + "SELECT 1 FROM " . AccompanyingPeriod\AccompanyingPeriodInfo::class . " {$ai_alias} JOIN {$ai_alias}.user {$ai_user_alias} " . + "WHERE IDENTITY({$ai_alias}.accompanyingPeriod) = acp.id + AND {$ai_user_alias}.mainScope IN (:{$ai_scopes}) + AND {$ai_alias}.infoDate >= :{$start} and {$ai_alias}.infoDate < :{$end} + " + ) + ) + ->setParameter($ai_scopes, $data['scopes']) + ->setParameter($start, $this->rollingDateConverter->convert($data['start_date'])) + ->setParameter($end, $this->rollingDateConverter->convert($data['end_date'])) + ; + } + + public function applyOn(): string + { + return Declarations::ACP_TYPE; + } +} diff --git a/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_course.yaml b/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_course.yaml index c299bbaaa..c5a2dba68 100644 --- a/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_course.yaml +++ b/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_course.yaml @@ -135,6 +135,14 @@ services: tags: - { name: chill.export_filter, alias: accompanyingcourse_user_working_on_filter } + Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\JobWorkingOnCourseFilter: + tags: + - { name: chill.export_filter, alias: accompanyingcourse_job_working_on_filter } + + Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\ScopeWorkingOnCourseFilter: + tags: + - { name: chill.export_filter, alias: accompanyingcourse_scope_working_on_filter } + Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\HavingAnAccompanyingPeriodInfoWithinDatesFilter: tags: - { name: chill.export_filter, alias: accompanyingcourse_info_within_filter } @@ -231,3 +239,15 @@ services: Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators\CreatorJobAggregator: tags: - { name: chill.export_aggregator, alias: accompanyingcourse_creator_job_aggregator } + + Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators\UserWorkingOnCourseAggregator: + tags: + - { name: chill.export_aggregator, alias: accompanyingcourse_user_working_on_course_aggregator } + + Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators\JobWorkingOnCourseAggregator: + tags: + - { name: chill.export_aggregator, alias: accompanyingcourse_job_working_on_course_aggregator } + + Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators\ScopeWorkingOnCourseAggregator: + tags: + - { name: chill.export_aggregator, alias: accompanyingcourse_scope_working_on_course_aggregator } diff --git a/src/Bundle/ChillPersonBundle/config/services/exports_person.yaml b/src/Bundle/ChillPersonBundle/config/services/exports_person.yaml index bf372ea06..64360aee9 100644 --- a/src/Bundle/ChillPersonBundle/config/services/exports_person.yaml +++ b/src/Bundle/ChillPersonBundle/config/services/exports_person.yaml @@ -177,3 +177,8 @@ services: tags: - { name: chill.export_aggregator, alias: person_household_compo_aggregator } + Chill\PersonBundle\Export\Aggregator\PersonAggregators\CenterAggregator: + tags: + - { name: chill.export_aggregator, alias: person_center_aggregator } + + diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index 464e8fa67..2f7800e2b 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -372,7 +372,7 @@ Count people participating in an accompanying course by various parameters.: Com Exports of accompanying courses: Exports des parcours d'accompagnement Count accompanying courses: Nombre de parcours Count accompanying courses by various parameters: Compte le nombre de parcours en fonction de différents filtres. -Accompanying courses participation duration and number of participations: Durée moyenne et nombre des participation des usagers aux parcours +Accompanying courses participation duration and number of participations: Durée moyenne et nombre des participations des usagers aux parcours Create an average of accompanying courses duration of each person participation to accompanying course, according to filters on persons, accompanying course: Crée un rapport qui comptabilise la moyenne de la durée de participation de chaque usager concerné aux parcours, avec différents filtres, notamment sur les usagers concernés. Closingdate to apply: Date de fin à prendre en compte lorsque le parcours n'est pas clotûré @@ -1016,6 +1016,11 @@ export: Household composition: Composition du ménage Group course by household composition: Grouper les usagers par composition familiale Calc date: Date de calcul de la composition du ménage + by_center: + title: Grouper les usagers par centre + at_date: Date de calcul du centre + center: Centre de l'usager + course: by_referrer: Computation date for referrer: Date à laquelle le référent était actif @@ -1032,6 +1037,15 @@ export: Number of actions: Nombre d'actions by_creator_job: Creator's job: Métier du créateur + by_user_working: + title: Grouper les parcours par intervenant + user: Intervenant + by_job_working: + title: Grouper les parcours par métier de l'intervenant + job: Métier de l'intervenant + by_scope_working: + title: Grouper les parcours par service de l'intervenant + scope: Service de l'intervenant course_work: by_current_action: Current action ?: Action en cours ? @@ -1081,10 +1095,20 @@ export: end_date: Fin de la période Only course with events between %startDate% and %endDate%: Seulement les parcours ayant reçu une intervention entre le %startDate% et le %endDate% by_user_working: - title: Filter les parcours par intervenant + title: Filter les parcours par intervenant, entre deux dates 'Filtered by user working on course: only %users%, between %start_date% and %end_date%': 'Filtré par intervenants sur le parcours: seulement %users%, entre le %start_date% et le %end_date%' User working after: Intervention après le User working before: Intervention avant le + by_job_working: + title: Filtrer les parcours par métier de l'intervenant, entre deux dates + 'Filtered by job working on course: only %jobs%, between %start_date% and %end_date%': 'Filtré par métier des intervenants sur le parcours: seulement %jobs%, entre le %start_date% et le %end_date%' + Job working after: Intervention après le + Job working before: Intervention avant le + by_scope_working: + title: Filtrer les parcours par service de l'intervenant, entre deux dates + 'Filtered by scope working on course: only %scopes%, between %start_date% and %end_date%': 'Filtré par service des intervenants sur le parcours: seulement %scopes%, entre le %start_date% et le %end_date%' + Scope working after: Intervention après le + Scope working before: Intervention avant le by_step: Filter by step: Filtrer les parcours par statut du parcours Filter by step between dates: Filtrer les parcours par statut du parcours entre deux dates From b7df62d4f55201ded3a689b5a358cd43d099c69a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 29 Jun 2023 23:15:15 +0200 Subject: [PATCH 222/321] [export] use a rolling date on age aggregator (Person) This query allow to detects the saved export which won't work any more: ```sql select s.id, user_id, description, title, u.label from chill_main_saved_export s join users u on u.id = s.user_id WHERE options->'export'->'export'->'aggregators'->'person_age_aggregator'->'enabled' is not null; ``` --- .../unreleased/Fixed-20230629-231503.yaml | 5 +++ .../PersonAggregators/AgeAggregator.php | 31 +++++++------------ 2 files changed, 16 insertions(+), 20 deletions(-) create mode 100644 .changes/unreleased/Fixed-20230629-231503.yaml diff --git a/.changes/unreleased/Fixed-20230629-231503.yaml b/.changes/unreleased/Fixed-20230629-231503.yaml new file mode 100644 index 000000000..e021d1fda --- /dev/null +++ b/.changes/unreleased/Fixed-20230629-231503.yaml @@ -0,0 +1,5 @@ +kind: Fixed +body: '[export] set rolling date on person age aggregator' +time: 2023-06-29T23:15:03.20841309+02:00 +custom: + Issue: "" diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/AgeAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/AgeAggregator.php index 2a63e475a..e3d364fa2 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/AgeAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/AgeAggregator.php @@ -13,20 +13,18 @@ namespace Chill\PersonBundle\Export\Aggregator\PersonAggregators; use Chill\MainBundle\Export\AggregatorInterface; use Chill\MainBundle\Export\ExportElementValidatedInterface; -use DateTime; +use Chill\MainBundle\Form\Type\PickRollingDateType; +use Chill\MainBundle\Service\RollingDate\RollingDate; +use Chill\MainBundle\Service\RollingDate\RollingDateConverterInterface; use Doctrine\ORM\QueryBuilder; -use Symfony\Component\Form\Extension\Core\Type\DateType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Validator\Context\ExecutionContextInterface; -use Symfony\Contracts\Translation\TranslatorInterface; -final class AgeAggregator implements AggregatorInterface, ExportElementValidatedInterface +final readonly class AgeAggregator implements AggregatorInterface, ExportElementValidatedInterface { - private TranslatorInterface $translator; - - public function __construct(TranslatorInterface $translator) - { - $this->translator = $translator; + public function __construct( + private RollingDateConverterInterface $rollingDateConverter, + ) { } public function addRole(): ?string @@ -37,7 +35,7 @@ final class AgeAggregator implements AggregatorInterface, ExportElementValidated public function alterQuery(QueryBuilder $qb, $data) { $qb->addSelect('DATE_DIFF(:date_age_calculation, person.birthdate)/365 as person_age'); - $qb->setParameter('date_age_calculation', $data['date_age_calculation']); + $qb->setParameter('date_age_calculation', $this->rollingDateConverter->convert($data['date_age_calculation'])); $qb->addGroupBy('person_age'); } @@ -48,16 +46,13 @@ final class AgeAggregator implements AggregatorInterface, ExportElementValidated public function buildForm(FormBuilderInterface $builder) { - $builder->add('date_age_calculation', DateType::class, [ + $builder->add('date_age_calculation', PickRollingDateType::class, [ 'label' => 'Calculate age in relation to this date', - 'attr' => ['class' => 'datepicker'], - 'widget' => 'single_text', - 'format' => 'dd-MM-yyyy', ]); } public function getFormDefaultData(): array { - return ['date_age_calculation' => new DateTime()]; + return ['date_age_calculation' => new RollingDate(RollingDate::T_TODAY)]; } public function getLabels($key, array $values, $data) @@ -67,11 +62,7 @@ final class AgeAggregator implements AggregatorInterface, ExportElementValidated return 'Age'; } - if (null === $value) { - return $this->translator->trans('without data'); - } - - return $value; + return $value ?? ''; }; } From c8b62d990a6572fa123b0b0b6b137910698f090f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Fri, 30 Jun 2023 17:12:09 +0200 Subject: [PATCH 223/321] fixes for exports and list --- .changes/unreleased/Fixed-20230630-171119.yaml | 5 +++++ .changes/unreleased/Fixed-20230630-171153.yaml | 5 +++++ .../Export/Export/CountAccompanyingCourse.php | 1 - .../Export/Export/CountAccompanyingPeriodWork.php | 1 - .../Export/Export/CountEvaluation.php | 1 - .../Export/Export/ListAccompanyingPeriod.php | 14 +++++--------- 6 files changed, 15 insertions(+), 12 deletions(-) create mode 100644 .changes/unreleased/Fixed-20230630-171119.yaml create mode 100644 .changes/unreleased/Fixed-20230630-171153.yaml diff --git a/.changes/unreleased/Fixed-20230630-171119.yaml b/.changes/unreleased/Fixed-20230630-171119.yaml new file mode 100644 index 000000000..f3185ace2 --- /dev/null +++ b/.changes/unreleased/Fixed-20230630-171119.yaml @@ -0,0 +1,5 @@ +kind: Fixed +body: '[export] fix list when a person locating a course is without address' +time: 2023-06-30T17:11:19.454081914+02:00 +custom: + Issue: "" diff --git a/.changes/unreleased/Fixed-20230630-171153.yaml b/.changes/unreleased/Fixed-20230630-171153.yaml new file mode 100644 index 000000000..c09bd93d0 --- /dev/null +++ b/.changes/unreleased/Fixed-20230630-171153.yaml @@ -0,0 +1,5 @@ +kind: Fixed +body: '[export] remove unused condition on course about duration participation' +time: 2023-06-30T17:11:53.076615549+02:00 +custom: + Issue: "" diff --git a/src/Bundle/ChillPersonBundle/Export/Export/CountAccompanyingCourse.php b/src/Bundle/ChillPersonBundle/Export/Export/CountAccompanyingCourse.php index 75583dfa0..58ef24e42 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/CountAccompanyingCourse.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/CountAccompanyingCourse.php @@ -101,7 +101,6 @@ class CountAccompanyingCourse implements ExportInterface, GroupedExportInterface ->andWhere('acp.step != :count_acp_step') ->leftJoin('acp.participations', 'acppart') ->leftJoin('acppart.person', 'person') - ->andWhere('acppart.startDate != acppart.endDate OR acppart.endDate IS NULL') ->andWhere( $qb->expr()->exists( 'SELECT 1 FROM ' . PersonCenterHistory::class . ' acl_count_person_history WHERE acl_count_person_history.person = person diff --git a/src/Bundle/ChillPersonBundle/Export/Export/CountAccompanyingPeriodWork.php b/src/Bundle/ChillPersonBundle/Export/Export/CountAccompanyingPeriodWork.php index 8a035bdcd..cf9feb3af 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/CountAccompanyingPeriodWork.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/CountAccompanyingPeriodWork.php @@ -101,7 +101,6 @@ class CountAccompanyingPeriodWork implements ExportInterface, GroupedExportInter ->join('acpw.accompanyingPeriod', 'acp') ->join('acp.participations', 'acppart') ->join('acppart.person', 'person') - ->andWhere('acppart.startDate != acppart.endDate OR acppart.endDate IS NULL') ->andWhere( $qb->expr()->exists( 'SELECT 1 FROM ' . PersonCenterHistory::class . ' acl_count_person_history WHERE acl_count_person_history.person = person diff --git a/src/Bundle/ChillPersonBundle/Export/Export/CountEvaluation.php b/src/Bundle/ChillPersonBundle/Export/Export/CountEvaluation.php index 3de433e2e..d9795e3ba 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/CountEvaluation.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/CountEvaluation.php @@ -101,7 +101,6 @@ class CountEvaluation implements ExportInterface, GroupedExportInterface ->join('acpw.accompanyingPeriod', 'acp') ->join('acp.participations', 'acppart') ->join('acppart.person', 'person') - ->andWhere('acppart.startDate != acppart.endDate OR acppart.endDate IS NULL') ->andWhere( $qb->expr()->exists( 'SELECT 1 FROM ' . PersonCenterHistory::class . ' acl_count_person_history WHERE acl_count_person_history.person = person diff --git a/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriod.php b/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriod.php index 294b9ce9a..af66ab312 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriod.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriod.php @@ -416,15 +416,11 @@ class ListAccompanyingPeriod implements ListInterface, GroupedExportInterface ) ) ) - ->leftJoin(PersonHouseholdAddress::class, 'personAddress', Join::WITH, 'locationHistory.personLocation = personAddress.person') - ->andWhere( - $qb->expr()->orX( - $qb->expr()->isNull('personAddress'), - $qb->expr()->andX( - $qb->expr()->lte('personAddress.validFrom', ':calcDate'), - $qb->expr()->orX($qb->expr()->isNull('personAddress.validTo'), $qb->expr()->gt('personAddress.validTo', ':calcDate')) - ) - ) + ->leftJoin( + PersonHouseholdAddress::class, + 'personAddress', + Join::WITH, + 'locationHistory.personLocation = personAddress.person AND (personAddress.validFrom <= :calcDate AND (personAddress.validTo IS NULL OR personAddress.validTo > :calcDate))' ) ->leftJoin(Address::class, 'acp_address', Join::WITH, 'COALESCE(IDENTITY(locationHistory.addressLocation), IDENTITY(personAddress.address)) = acp_address.id'); From cc0e832cc97167105ea096be185b8334806c2047 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Thu, 19 Jan 2023 12:47:04 +0100 Subject: [PATCH 224/321] FEATURE [voter][confidential] added right to see confidential periods --- .../Security/Authorization/AccompanyingPeriodVoter.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php b/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php index 709624b54..9b4976847 100644 --- a/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php +++ b/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php @@ -107,6 +107,11 @@ class AccompanyingPeriodVoter extends AbstractChillVoter implements ProvideRoleH */ public const TOGGLE_INTENSITY = 'CHILL_PERSON_ACCOMPANYING_PERIOD_TOGGLE_INTENSITY'; + /** + * Right to see confidential period even if not referrer + */ + public const SEE_CONFIDENTIAL = 'CHILL_PERSON_ACCOMPANYING_PERIOD_SEE_CONFIDENTIAL'; + private Security $security; private VoterHelperInterface $voterHelper; From 9ccc57bbcb394bed6b1fe1f13ff07fa9d9f27ba7 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Thu, 19 Jan 2023 12:48:00 +0100 Subject: [PATCH 225/321] FEATURE [config][voter] config set for relation between bulk_assign and see_confidential --- .../DependencyInjection/ChillPersonExtension.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php b/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php index 569dd1502..576e563bd 100644 --- a/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php +++ b/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php @@ -985,6 +985,7 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac ], AccompanyingPeriodVoter::REASSIGN_BULK => [ AccompanyingPeriodVoter::CONFIDENTIAL_CRUD, + AccompanyingPeriodVoter::SEE_CONFIDENTIAL, ], AccompanyingPeriodVoter::TOGGLE_CONFIDENTIAL => [ AccompanyingPeriodVoter::CONFIDENTIAL_CRUD, From b3d993165d27a3354adbe2c3a65b4e59ebd0ddfd Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Wed, 25 Jan 2023 15:10:33 +0100 Subject: [PATCH 226/321] FEATURE: [confidential][voter] bulk assign right should also give right to access confidential parcours --- .../Security/Authorization/AccompanyingPeriodVoter.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php b/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php index 9b4976847..436f51792 100644 --- a/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php +++ b/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php @@ -225,6 +225,10 @@ class AccompanyingPeriodVoter extends AbstractChillVoter implements ProvideRoleH return true; } +/* if ($this->voterHelper->voteOnAttribute(self::REASSIGN_BULK, null, $token)) { + return true; + }*/ + return $token->getUser() === $subject->getUser(); } } From a7dbdc2b9d9bb2a6d7dd8f12ddacb2fd145735aa Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Fri, 10 Feb 2023 19:15:09 +0100 Subject: [PATCH 227/321] FEATURE [voter][confidential] voter adapted. repository changes left to do --- .../ReassignAccompanyingPeriodController.php | 6 ++++-- .../DependencyInjection/ChillPersonExtension.php | 8 ++++---- .../Authorization/AccompanyingPeriodVoter.php | 16 +++------------- 3 files changed, 11 insertions(+), 19 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Controller/ReassignAccompanyingPeriodController.php b/src/Bundle/ChillPersonBundle/Controller/ReassignAccompanyingPeriodController.php index bafc4b1cb..fde9746d3 100644 --- a/src/Bundle/ChillPersonBundle/Controller/ReassignAccompanyingPeriodController.php +++ b/src/Bundle/ChillPersonBundle/Controller/ReassignAccompanyingPeriodController.php @@ -20,6 +20,7 @@ use Chill\MainBundle\Repository\UserRepository; use Chill\MainBundle\Templating\Entity\UserRender; use Chill\PersonBundle\Repository\AccompanyingPeriodACLAwareRepositoryInterface; use Chill\PersonBundle\Repository\AccompanyingPeriodRepository; +use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter; use Doctrine\ORM\EntityManagerInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\Form\CallbackTransformer; @@ -30,6 +31,7 @@ use Symfony\Component\Form\FormFactoryInterface; use Symfony\Component\Form\FormInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Security\Core\Exception\AccessDeniedException; use Symfony\Component\Security\Core\Security; @@ -85,8 +87,8 @@ class ReassignAccompanyingPeriodController extends AbstractController */ public function listAction(Request $request): Response { - if (!$this->security->isGranted('ROLE_USER') || !$this->security->getUser() instanceof User) { - throw new AccessDeniedException(); + if (!$this->security->isGranted(AccompanyingPeriodVoter::REASSIGN_BULK)) { + throw new AccessDeniedHttpException('no right to reassign bulk'); } $form = $this->buildFilterForm(); diff --git a/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php b/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php index 576e563bd..6fd434635 100644 --- a/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php +++ b/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php @@ -984,11 +984,11 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac AccompanyingPeriodVoter::DELETE, ], AccompanyingPeriodVoter::REASSIGN_BULK => [ - AccompanyingPeriodVoter::CONFIDENTIAL_CRUD, - AccompanyingPeriodVoter::SEE_CONFIDENTIAL, + AccompanyingPeriodVoter::SEE_CONFIDENTIAL_ALL, + AccompanyingPeriodVoter::TOGGLE_CONFIDENTIAL_ALL, ], - AccompanyingPeriodVoter::TOGGLE_CONFIDENTIAL => [ - AccompanyingPeriodVoter::CONFIDENTIAL_CRUD, + AccompanyingPeriodVoter::TOGGLE_CONFIDENTIAL_ALL => [ + AccompanyingPeriodVoter::SEE_CONFIDENTIAL_ALL, ], ], ]); diff --git a/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php b/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php index 436f51792..3dd991501 100644 --- a/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php +++ b/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php @@ -42,11 +42,6 @@ class AccompanyingPeriodVoter extends AbstractChillVoter implements ProvideRoleH self::RE_OPEN_COURSE, ]; - /** - * Give the ability to see all confidential courses. - */ - public const CONFIDENTIAL_CRUD = 'CHILL_PERSON_ACCOMPANYING_PERIOD_CRUD_CONFIDENTIAL'; - public const CREATE = 'CHILL_PERSON_ACCOMPANYING_PERIOD_CREATE'; /** @@ -110,7 +105,7 @@ class AccompanyingPeriodVoter extends AbstractChillVoter implements ProvideRoleH /** * Right to see confidential period even if not referrer */ - public const SEE_CONFIDENTIAL = 'CHILL_PERSON_ACCOMPANYING_PERIOD_SEE_CONFIDENTIAL'; + public const SEE_CONFIDENTIAL_ALL = 'CHILL_PERSON_ACCOMPANYING_PERIOD_SEE_CONFIDENTIAL'; private Security $security; @@ -136,7 +131,6 @@ class AccompanyingPeriodVoter extends AbstractChillVoter implements ProvideRoleH return [ self::SEE, self::SEE_DETAILS, - self::CONFIDENTIAL_CRUD, self::CREATE, self::EDIT, self::DELETE, @@ -154,7 +148,7 @@ class AccompanyingPeriodVoter extends AbstractChillVoter implements ProvideRoleH public function getRolesWithoutScope(): array { - return [self::REASSIGN_BULK]; + return []; } protected function supports($attribute, $subject) @@ -221,14 +215,10 @@ class AccompanyingPeriodVoter extends AbstractChillVoter implements ProvideRoleH // if confidential, only the referent can see it if ($subject->isConfidential()) { - if ($this->voterHelper->voteOnAttribute(self::CONFIDENTIAL_CRUD, $subject, $token)) { + if ($this->voterHelper->voteOnAttribute(self::SEE_CONFIDENTIAL_ALL, $subject, $token)) { return true; } -/* if ($this->voterHelper->voteOnAttribute(self::REASSIGN_BULK, null, $token)) { - return true; - }*/ - return $token->getUser() === $subject->getUser(); } } From dd344aed527df6718ebed27fe089991b4862693e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 4 Jul 2023 15:59:39 +0200 Subject: [PATCH 228/321] Implements right "see confidential course" on method findByPerson Add unit tests for that --- .../Authorization/AuthorizationHelper.php | 4 - ...orizationHelperForCurrentUserInterface.php | 5 +- .../AuthorizationHelperInterface.php | 3 +- .../AccompanyingPeriodController.php | 8 +- .../AccompanyingPeriodACLAwareRepository.php | 119 ++++++---- ...nyingPeriodACLAwareRepositoryInterface.php | 10 +- ...companyingPeriodACLAwareRepositoryTest.php | 206 ++++++++++++++++++ 7 files changed, 306 insertions(+), 49 deletions(-) create mode 100644 src/Bundle/ChillPersonBundle/Tests/Repository/AccompanyingPeriodACLAwareRepositoryTest.php diff --git a/src/Bundle/ChillMainBundle/Security/Authorization/AuthorizationHelper.php b/src/Bundle/ChillMainBundle/Security/Authorization/AuthorizationHelper.php index 1105c9d8a..be884de94 100644 --- a/src/Bundle/ChillMainBundle/Security/Authorization/AuthorizationHelper.php +++ b/src/Bundle/ChillMainBundle/Security/Authorization/AuthorizationHelper.php @@ -195,10 +195,6 @@ class AuthorizationHelper implements AuthorizationHelperInterface /** * Return all reachable scope for a given user, center and role. - * - * @param Center|Center[] $center - * - * @return array|Scope[] */ public function getReachableScopes(UserInterface $user, string $role, Center|array $center): array { diff --git a/src/Bundle/ChillMainBundle/Security/Authorization/AuthorizationHelperForCurrentUserInterface.php b/src/Bundle/ChillMainBundle/Security/Authorization/AuthorizationHelperForCurrentUserInterface.php index f0d3f9fba..54e30c244 100644 --- a/src/Bundle/ChillMainBundle/Security/Authorization/AuthorizationHelperForCurrentUserInterface.php +++ b/src/Bundle/ChillMainBundle/Security/Authorization/AuthorizationHelperForCurrentUserInterface.php @@ -25,7 +25,8 @@ interface AuthorizationHelperForCurrentUserInterface public function getReachableCenters(string $role, ?Scope $scope = null): array; /** - * @param array|Center|Center[] $center + * @param list
      |Center $center + * @return list */ - public function getReachableScopes(string $role, $center): array; + public function getReachableScopes(string $role, array|Center $center): array; } diff --git a/src/Bundle/ChillMainBundle/Security/Authorization/AuthorizationHelperInterface.php b/src/Bundle/ChillMainBundle/Security/Authorization/AuthorizationHelperInterface.php index 1176cf1fa..1dc9668ec 100644 --- a/src/Bundle/ChillMainBundle/Security/Authorization/AuthorizationHelperInterface.php +++ b/src/Bundle/ChillMainBundle/Security/Authorization/AuthorizationHelperInterface.php @@ -26,7 +26,8 @@ interface AuthorizationHelperInterface public function getReachableCenters(UserInterface $user, string $role, ?Scope $scope = null): array; /** - * @param Center|list
      $center + * @param Center|array
      $center + * @return list */ public function getReachableScopes(UserInterface $user, string $role, Center|array $center): array; } diff --git a/src/Bundle/ChillPersonBundle/Controller/AccompanyingPeriodController.php b/src/Bundle/ChillPersonBundle/Controller/AccompanyingPeriodController.php index b32454387..8b4c0b27a 100644 --- a/src/Bundle/ChillPersonBundle/Controller/AccompanyingPeriodController.php +++ b/src/Bundle/ChillPersonBundle/Controller/AccompanyingPeriodController.php @@ -219,13 +219,13 @@ class AccompanyingPeriodController extends AbstractController ]); $this->eventDispatcher->dispatch(PrivacyEvent::PERSON_PRIVACY_EVENT, $event); - $accompanyingPeriodsRaw = $this->accompanyingPeriodACLAwareRepository - ->findByPerson($person, AccompanyingPeriodVoter::SEE); + $accompanyingPeriods = $this->accompanyingPeriodACLAwareRepository + ->findByPerson($person, AccompanyingPeriodVoter::SEE, ["openingDate" => "DESC", "id" => "DESC"]); - usort($accompanyingPeriodsRaw, static fn ($a, $b) => $b->getOpeningDate() > $a->getOpeningDate()); + //usort($accompanyingPeriodsRaw, static fn ($a, $b) => $b->getOpeningDate() <=> $a->getOpeningDate()); // filter visible or not visible - $accompanyingPeriods = array_filter($accompanyingPeriodsRaw, fn (AccompanyingPeriod $ap) => $this->isGranted(AccompanyingPeriodVoter::SEE, $ap)); + //$accompanyingPeriods = array_filter($accompanyingPeriodsRaw, fn (AccompanyingPeriod $ap) => $this->isGranted(AccompanyingPeriodVoter::SEE, $ap)); return $this->render('@ChillPerson/AccompanyingPeriod/list.html.twig', [ 'accompanying_periods' => $accompanyingPeriods, diff --git a/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodACLAwareRepository.php b/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodACLAwareRepository.php index 0aaabd05f..104f49ec7 100644 --- a/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodACLAwareRepository.php +++ b/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodACLAwareRepository.php @@ -13,54 +13,51 @@ namespace Chill\PersonBundle\Repository; use Chill\MainBundle\Entity\Address; use Chill\MainBundle\Entity\Location; -use Chill\MainBundle\Entity\PostalCode; use Chill\MainBundle\Entity\Scope; use Chill\MainBundle\Entity\User; use Chill\MainBundle\Entity\UserJob; -use Chill\MainBundle\Security\Authorization\AuthorizationHelper; -use Chill\MainBundle\Security\Resolver\CenterResolverDispatcherInterface; +use Chill\MainBundle\Security\Authorization\AuthorizationHelperForCurrentUserInterface; +use Chill\MainBundle\Security\Resolver\CenterResolverManagerInterface; use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\AccompanyingPeriodParticipation; use Chill\PersonBundle\Entity\Household\PersonHouseholdAddress; use Chill\PersonBundle\Entity\Person; use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter; use DateTime; - use DateTimeImmutable; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Query\Expr\Join; use Doctrine\ORM\QueryBuilder; +use Repository\AccompanyingPeriodACLAwareRepositoryTest; use Symfony\Component\Security\Core\Security; use function count; -final class AccompanyingPeriodACLAwareRepository implements AccompanyingPeriodACLAwareRepositoryInterface +/** + * @see AccompanyingPeriodACLAwareRepositoryTest + */ +final readonly class AccompanyingPeriodACLAwareRepository implements AccompanyingPeriodACLAwareRepositoryInterface { private AccompanyingPeriodRepository $accompanyingPeriodRepository; - private AuthorizationHelper $authorizationHelper; + private AuthorizationHelperForCurrentUserInterface $authorizationHelper; - private CenterResolverDispatcherInterface $centerResolverDispatcher; + private CenterResolverManagerInterface $centerResolver; private Security $security; public function __construct( AccompanyingPeriodRepository $accompanyingPeriodRepository, Security $security, - AuthorizationHelper $authorizationHelper, - CenterResolverDispatcherInterface $centerResolverDispatcher + AuthorizationHelperForCurrentUserInterface $authorizationHelper, + CenterResolverManagerInterface $centerResolverDispatcher ) { $this->accompanyingPeriodRepository = $accompanyingPeriodRepository; $this->security = $security; $this->authorizationHelper = $authorizationHelper; - $this->centerResolverDispatcher = $centerResolverDispatcher; + $this->centerResolver = $centerResolverDispatcher; } - /** - * @param array|PostalCode[] - * - * @return QueryBuilder - */ - public function buildQueryOpenedAccompanyingCourseByUser(?User $user, array $postalCodes = []) + public function buildQueryOpenedAccompanyingCourseByUser(?User $user, array $postalCodes = []): QueryBuilder { $qb = $this->accompanyingPeriodRepository->createQueryBuilder('ap'); @@ -152,10 +149,14 @@ final class AccompanyingPeriodACLAwareRepository implements AccompanyingPeriodAC ): array { $qb = $this->accompanyingPeriodRepository->createQueryBuilder('ap'); $scopes = $this->authorizationHelper - ->getReachableCircles( - $this->security->getUser(), + ->getReachableScopes( $role, - $this->centerResolverDispatcher->resolveCenter($person) + $this->centerResolver->resolveCenters($person) + ); + $scopesCanSeeConfidential = $this->authorizationHelper + ->getReachableScopes( + AccompanyingPeriodVoter::SEE_CONFIDENTIAL_ALL, + $this->centerResolver->resolveCenters($person) ); if (0 === count($scopes)) { @@ -165,12 +166,42 @@ final class AccompanyingPeriodACLAwareRepository implements AccompanyingPeriodAC $qb ->join('ap.participations', 'participation') ->where($qb->expr()->eq('participation.person', ':person')) - ->andWhere( - $qb->expr()->orX( - 'ap.confidential = FALSE', - $qb->expr()->eq('ap.user', ':user') - ) - ) + ->setParameter('person', $person); + + $qb = $this->addACLClauses($qb, $scopes, $scopesCanSeeConfidential); + $qb = $this->addOrderLimitClauses($qb, $orderBy, $limit, $offset); + + return $qb->getQuery()->getResult(); + } + + public function addOrderLimitClauses(QueryBuilder $qb, ?array $orderBy = null, ?int $limit = null, ?int $offset = null): QueryBuilder + { + if (null !== $orderBy) { + foreach ($orderBy as $field => $order) { + $qb->addOrderBy('ap.' . $field, $order); + } + } + + if (null !== $limit) { + $qb->setMaxResults($limit); + } + + if (null !== $offset) { + $qb->setFirstResult($offset); + } + + return $qb; + } + + /** + * @param QueryBuilder $qb where the accompanying period have the `ap` alias + * @param array $scopesCanSee + * @param array $scopesCanSeeConfidential + * @return QueryBuilder + */ + public function addACLClauses(QueryBuilder $qb, array $scopesCanSee, array $scopesCanSeeConfidential): QueryBuilder + { + $qb ->andWhere( $qb->expr()->orX( $qb->expr()->neq('ap.step', ':draft'), @@ -181,25 +212,44 @@ final class AccompanyingPeriodACLAwareRepository implements AccompanyingPeriodAC ) ) ->setParameter('draft', AccompanyingPeriod::STEP_DRAFT) - ->setParameter('person', $person) ->setParameter('user', $this->security->getUser()) ->setParameter('creator', $this->security->getUser()); + // add join condition for scopes $orx = $qb->expr()->orX( + // even if the scope is not in one authorized, the user can see the course if it is in DRAFT state $qb->expr()->eq('ap.step', ':draft') ); - foreach ($scopes as $key => $scope) { - $orx->add($qb->expr()->orX( + foreach ($scopesCanSee as $key => $scope) { + // for each scope: + // - either the user is the referrer of the course + // - or the accompanying course is one of the reachable scopes + // - and the parcours is not confidential OR the user is the referrer OR the user can see the confidential course + + $orOnScope = $qb->expr()->orX( $qb->expr()->isMemberOf(':scope_' . $key, 'ap.scopes'), $qb->expr()->eq('ap.user', ':user') - )); + ); + + if (in_array($scope, $scopesCanSeeConfidential, true)) { + $orx->add($orOnScope); + } else { + // we must add a condition: the course is not confidential or the user is the referrer + $andXOnScope = $qb->expr()->andX( + $orOnScope, + $qb->expr()->orX( + 'ap.confidential = FALSE', + $qb->expr()->eq('ap.user', ':user') + ) + ); + $orx->add($andXOnScope); + } $qb->setParameter('scope_' . $key, $scope); - $qb->setParameter('user', $this->security->getUser()); } $qb->andWhere($orx); - return $qb->getQuery()->getResult(); + return $qb; } public function findByUnDispatched(array $jobs, array $services, array $administrativeLocations, ?int $limit = null, ?int $offset = null): array @@ -237,9 +287,6 @@ final class AccompanyingPeriodACLAwareRepository implements AccompanyingPeriodAC return $qb->getQuery()->getResult(); } - /** - * @return array|AccompanyingPeriod[] - */ public function findByUserOpenedAccompanyingPeriod(?User $user, array $orderBy = [], int $limit = 0, int $offset = 50): array { if (null === $user) { @@ -261,7 +308,6 @@ final class AccompanyingPeriodACLAwareRepository implements AccompanyingPeriodAC private function addACLByUnDispatched(QueryBuilder $qb): QueryBuilder { $centers = $this->authorizationHelper->getReachableCenters( - $this->security->getUser(), AccompanyingPeriodVoter::SEE ); @@ -273,8 +319,7 @@ final class AccompanyingPeriodACLAwareRepository implements AccompanyingPeriodAC foreach ($centers as $key => $center) { $scopes = $this->authorizationHelper - ->getReachableCircles( - $this->security->getUser(), + ->getReachableScopes( AccompanyingPeriodVoter::SEE, $center ); diff --git a/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodACLAwareRepositoryInterface.php b/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodACLAwareRepositoryInterface.php index 0cca1a5f4..ff3d89783 100644 --- a/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodACLAwareRepositoryInterface.php +++ b/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodACLAwareRepositoryInterface.php @@ -33,6 +33,9 @@ interface AccompanyingPeriodACLAwareRepositoryInterface public function countByUserOpenedAccompanyingPeriod(?User $user): int; + /** + * @return array + */ public function findByPerson( Person $person, string $role, @@ -45,14 +48,19 @@ interface AccompanyingPeriodACLAwareRepositoryInterface * @param array|UserJob[] $jobs if empty, does not take this argument into account * @param array|Scope[] $services if empty, does not take this argument into account * - * @return array|AccompanyingPeriod[] + * @return list */ public function findByUnDispatched(array $jobs, array $services, array $administrativeLocations, ?int $limit = null, ?int $offset = null): array; /** * @param array|PostalCode[] $postalCodes + * @return list */ public function findByUserAndPostalCodesOpenedAccompanyingPeriod(?User $user, array $postalCodes, array $orderBy = [], int $limit = 0, int $offset = 50): array; + /** + * @deprecated + * @return list + */ public function findByUserOpenedAccompanyingPeriod(?User $user, array $orderBy = [], int $limit = 0, int $offset = 50): array; } diff --git a/src/Bundle/ChillPersonBundle/Tests/Repository/AccompanyingPeriodACLAwareRepositoryTest.php b/src/Bundle/ChillPersonBundle/Tests/Repository/AccompanyingPeriodACLAwareRepositoryTest.php new file mode 100644 index 000000000..17c12fea5 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Repository/AccompanyingPeriodACLAwareRepositoryTest.php @@ -0,0 +1,206 @@ +accompanyingPeriodRepository = self::$container->get(AccompanyingPeriodRepository::class); + $this->centerResolverManager = self::$container->get(CenterResolverManagerInterface::class); + $this->entityManager = self::$container->get(EntityManagerInterface::class); + $this->scopeRepository = self::$container->get(ScopeRepositoryInterface::class); + $this->registry = self::$container->get(Registry::class); + + } + + public static function tearDownAfterClass(): void + { + self::bootKernel(); + $em = self::$container->get(EntityManagerInterface::class); + $repository = self::$container->get(AccompanyingPeriodRepository::class); + + foreach (self::$periodsIdsToDelete as $id) { + if (null === $period = $repository->find($id)) { + throw new \RuntimeException("period not found while trying to delete it"); + } + + foreach ($period->getParticipations() as $participation) { + $em->remove($participation); + } + $em->remove($period); + } + + $em->flush(); + } + + + /** + * For testing this method, we mock the authorization helper to return different Scope that a user + * can see, or that a user can see confidential periods. + * + * @param array $scopeUserCanSee + * @param array $scopeUserCanSeeConfidential + * @param array $expectedPeriod + * @dataProvider provideDataForFindByPerson + */ + public function testFindByPersonTestUser(User $user, Person $person, array $scopeUserCanSee, array $scopeUserCanSeeConfidential, array $expectedPeriod, string $message): void + { + $security = $this->prophesize(Security::class); + $security->getUser()->willReturn($user); + + $authorizationHelper = $this->prophesize(AuthorizationHelperForCurrentUserInterface::class); + $authorizationHelper->getReachableScopes(AccompanyingPeriodVoter::SEE, Argument::any()) + ->willReturn($scopeUserCanSee); + $authorizationHelper->getReachableScopes(AccompanyingPeriodVoter::SEE_CONFIDENTIAL_ALL, Argument::any()) + ->willReturn($scopeUserCanSeeConfidential); + + $repository = new AccompanyingPeriodACLAwareRepository( + $this->accompanyingPeriodRepository, + $security->reveal(), + $authorizationHelper->reveal(), + $this->centerResolverManager + ); + + $actuals = $repository->findByPerson($person, AccompanyingPeriodVoter::SEE); + $expectedIds = array_map(fn (AccompanyingPeriod $period) => $period->getId(), $expectedPeriod); + + self::assertCount(count($expectedPeriod), $actuals, $message); + foreach ($actuals as $actual) { + self::assertContains($actual->getId(), $expectedIds); + } + } + + public function provideDataForFindByPerson(): iterable + { + $this->setUp(); + + if (null === $user = $this->entityManager->createQuery("SELECT u FROM " . User::class . " u")->setMaxResults(1)->getSingleResult()) { + throw new \RuntimeException("no user found"); + } + + if (null === $anotherUser = $this->entityManager->createQuery("SELECT u FROM " . User::class . " u WHERE u.id != :uid")->setParameter('uid', $user->getId()) + ->setMaxResults(1)->getSingleResult()) { + throw new \RuntimeException("no user found"); + } + + [$person, $anotherPerson, $person2, $person3] = $this->entityManager + ->createQuery("SELECT p FROM " . Person::class . " p WHERE SIZE(p.accompanyingPeriodParticipations) = 0") + ->setMaxResults(4) + ->getResult(); + + if (null === $person || null === $anotherPerson || null === $person2 || null === $person3) { + throw new \RuntimeException("no person found"); + } + + $scopes = $this->scopeRepository->findAll(); + + if (3 > count($scopes)) { + throw new \RuntimeException("not enough scopes for this test"); + } + $scopesCanSee = [ $scopes[0] ]; + $scopesGroup2 = [ $scopes[1] ]; + + // case: a period is in draft state + $period = $this->buildPeriod($person, $scopesCanSee, $user, false); + + yield [$user, $person, $scopesCanSee, [], [$period], "a user can see his period during draft state"]; + + // another user is not allowed to see this period, because it is in DRAFT state + yield [$anotherUser, $person, $scopesCanSee, [], [], "another user is not allowed to see the period of someone else in draft state"]; + + // the period is confirmed + $period = $this->buildPeriod($anotherPerson, $scopesCanSee, $user, true); + + // the other user can now see it + yield [$user, $anotherPerson, $scopesCanSee, [], [$period], "a user see his period when confirmed"]; + yield [$anotherUser, $anotherPerson, $scopesCanSee, [], [$period], "another user with required scopes is allowed to see the period when not draft"]; + yield [$anotherUser, $anotherPerson, $scopesGroup2, [], [], "another user without the required scopes is not allowed to see the period when not draft"]; + + // this period will be confidential + $period = $this->buildPeriod($person2, $scopesCanSee, $user, true); + $period->setConfidential(true)->setUser($user, true); + + yield [$user, $person2, $scopesCanSee, [], [$period], "a user see his period when confirmed and confidential with required scopes"]; + yield [$user, $person2, $scopesGroup2, [], [$period], "a user see his period when confirmed and confidential without required scopes"]; + yield [$anotherUser, $person2, $scopesCanSee, [], [], "a user don't see a confidential period, even if he has required scopes"]; + yield [$anotherUser, $person2, $scopesCanSee, $scopesCanSee, [$period], "a user see the period when confirmed and confidential if he has required scope to see the period"]; + + // period draft with creator = null + $period = $this->buildPeriod($person3, $scopesCanSee, null, false); + yield [$user, $person3, $scopesCanSee, [], [$period], "a user see a period when draft if no creator on the period"]; + $this->entityManager->flush(); + } + + /** + * @param Person $person + * @param array $scopes + * @return AccompanyingPeriod + */ + private function buildPeriod(Person $person, array $scopes, User|null $creator, bool $confirm): AccompanyingPeriod + { + $period = new AccompanyingPeriod(); + $period->addPerson($person); + if (null !== $creator) { + $period->setCreatedBy($creator); + } + + foreach ($scopes as $scope) { + $period->addScope($scope); + } + + $this->entityManager->persist($period); + self::$periodsIdsToDelete[] = $period->getId(); + + if ($confirm) { + $workflow = $this->registry->get($period, 'accompanying_period_lifecycle'); + $workflow->apply($period, 'confirm'); + } + + return $period; + } +} From 3e63b4abf30736c41afccb7af97fd259f3bfb6cb Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Tue, 4 Jul 2023 16:42:56 +0200 Subject: [PATCH 229/321] UX: improve FilterOrder box design --- .../translations/messages.fr.yml | 2 + .../Form/Type/Listing/FilterOrderType.php | 3 + .../Resources/public/chill/scss/forms.scss | 12 +++ .../views/FilterOrder/base.html.twig | 81 ++++++++----------- 4 files changed, 50 insertions(+), 48 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/translations/messages.fr.yml b/src/Bundle/ChillActivityBundle/translations/messages.fr.yml index c53a04f31..d37b3488f 100644 --- a/src/Bundle/ChillActivityBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillActivityBundle/translations/messages.fr.yml @@ -96,6 +96,8 @@ activity_filter: My activities: Mes échanges (où j'interviens) Types: Par type d'échange Jobs: Par métier impliqué + By: Filtrer par + Search: Chercher dans la liste #timeline '%user% has done an %activity_type%': '%user% a effectué un échange de type "%activity_type%"' diff --git a/src/Bundle/ChillMainBundle/Form/Type/Listing/FilterOrderType.php b/src/Bundle/ChillMainBundle/Form/Type/Listing/FilterOrderType.php index 16038515d..1f373400c 100644 --- a/src/Bundle/ChillMainBundle/Form/Type/Listing/FilterOrderType.php +++ b/src/Bundle/ChillMainBundle/Form/Type/Listing/FilterOrderType.php @@ -38,6 +38,9 @@ final class FilterOrderType extends \Symfony\Component\Form\AbstractType $builder->add('q', SearchType::class, [ 'label' => false, 'required' => false, + 'attr' => [ + 'placeholder' => 'activity_filter.Search', + ] ]); } diff --git a/src/Bundle/ChillMainBundle/Resources/public/chill/scss/forms.scss b/src/Bundle/ChillMainBundle/Resources/public/chill/scss/forms.scss index 0ae568244..cd81f36dc 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/chill/scss/forms.scss +++ b/src/Bundle/ChillMainBundle/Resources/public/chill/scss/forms.scss @@ -42,3 +42,15 @@ form { font-weight: 700; margin-bottom: .375em; } + +.chill_filter_order { + background: $gray-100; /* + border: 3px dashed $white; + background: repeating-linear-gradient( + -45deg, + $gray-100, + $gray-100 2px, + $white 2px, + $white 6px + ); */ +} \ No newline at end of file diff --git a/src/Bundle/ChillMainBundle/Resources/views/FilterOrder/base.html.twig b/src/Bundle/ChillMainBundle/Resources/views/FilterOrder/base.html.twig index d4a6bbdd4..8faef5d14 100644 --- a/src/Bundle/ChillMainBundle/Resources/views/FilterOrder/base.html.twig +++ b/src/Bundle/ChillMainBundle/Resources/views/FilterOrder/base.html.twig @@ -1,102 +1,87 @@ {{ form_start(form) }} -
      -
      + {% set btnSubmit = 0 %} +
      +
      {% if form.vars.has_search_box %} -
      -
      - {{ form_widget(form.q)}} - +
      +
      + {{ form_widget(form.q) }} +
      {% endif %}
      {% if form.dateRanges is defined %} + {% set btnSubmit = 1 %} {% if form.dateRanges|length > 0 %} {% for dateRangeName, _o in form.dateRanges %} -
      +
      {% if form.dateRanges[dateRangeName].vars.label is not same as(false) %} -
      {{ form_label(form.dateRanges[dateRangeName])}} -
      {% endif %} -
      -
      +
      +
      {{ 'chill_calendar.From'|trans }} {{ form_widget(form.dateRanges[dateRangeName]['from']) }} {{ 'chill_calendar.To'|trans }} {{ form_widget(form.dateRanges[dateRangeName]['to']) }}
      -
      - -
      {% endfor %} {% endif %} {% endif %} {% if form.checkboxes is defined %} + {% set btnSubmit = 1 %} {% if form.checkboxes|length > 0 %} {% for checkbox_name, options in form.checkboxes %} -
      -
      +
      +
      {{ 'activity_filter.By'|trans }}
      +
      {% for c in form['checkboxes'][checkbox_name].children %} -
      - {{ form_widget(c) }} - {{ form_label(c) }} -
      + {{ form_widget(c) }} + {{ form_label(c) }} {% endfor %}
      - {% if loop.last %} -
      -
      -
        -
      • - -
      • -
      -
      -
      - {% endif %} {% endfor %} {% endif %} {% endif %} {% if form.entity_choices is defined %} + {% set btnSubmit = 1 %} {% if form.entity_choices |length > 0 %} {% for checkbox_name, options in form.entity_choices %} -
      +
      {% if form.entity_choices[checkbox_name].vars.label is not same as(false) %} -
      - {{ form_label(form.entity_choices[checkbox_name])}} -
      + {{ form_label(form.entity_choices[checkbox_name])}} {% endif %} -
      +
      {% for c in form['entity_choices'][checkbox_name].children %} -
      - {{ form_widget(c) }} - {{ form_label(c) }} -
      + {{ form_widget(c) }} + {{ form_label(c) }} {% endfor %}
      -
      - -
      {% endfor %} {% endif %} {% endif %} {% if form.single_checkboxes is defined %} + {% set btnSubmit = 1 %} {% for name, _o in form.single_checkboxes %} -
      -
      +
      +
      {{ 'activity_filter.By'|trans }}
      +
      {{ form_widget(form.single_checkboxes[name]) }}
      -
      - -
      {% endfor %} {% endif %} + + {% if btnSubmit == 1 %} +
      + +
      + {% endif %}
      {% for k,v in otherParameters %} From a56370d8519af48dc217ee48d789ceab136cacb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 4 Jul 2023 16:00:09 +0200 Subject: [PATCH 230/321] DX: fix phpstan issues with more strict type hinting in AuthorizationHelperInterface --- .../Timeline/TimelineActivityProvider.php | 1 + .../Service/DocGenerator/PersonContext.php | 10 ++++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Timeline/TimelineActivityProvider.php b/src/Bundle/ChillActivityBundle/Timeline/TimelineActivityProvider.php index dad597676..2c9272b08 100644 --- a/src/Bundle/ChillActivityBundle/Timeline/TimelineActivityProvider.php +++ b/src/Bundle/ChillActivityBundle/Timeline/TimelineActivityProvider.php @@ -161,6 +161,7 @@ class TimelineActivityProvider implements TimelineProviderInterface // loop on reachable scopes foreach ($reachableScopes as $scope) { + /** @phpstan-ignore-next-line */ if (in_array($scope->getId(), $scopes_ids, true)) { continue; } diff --git a/src/Bundle/ChillPersonBundle/Service/DocGenerator/PersonContext.php b/src/Bundle/ChillPersonBundle/Service/DocGenerator/PersonContext.php index 9d7f1cdd5..5b5773922 100644 --- a/src/Bundle/ChillPersonBundle/Service/DocGenerator/PersonContext.php +++ b/src/Bundle/ChillPersonBundle/Service/DocGenerator/PersonContext.php @@ -360,10 +360,12 @@ final class PersonContext implements PersonContextInterface private function isScopeNecessary(Person $person): bool { - if ($this->showScopes && 1 < $this->authorizationHelper->getReachableScopes( - $this->security->getUser(), - PersonDocumentVoter::CREATE, - $this->centerResolverManager->resolveCenters($person) + if ($this->showScopes && 1 < count( + $this->authorizationHelper->getReachableScopes( + $this->security->getUser(), + PersonDocumentVoter::CREATE, + $this->centerResolverManager->resolveCenters($person) + ) )) { return true; } From 7f9738975cd6690b20ea7c886562342994c9c5f3 Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Tue, 4 Jul 2023 17:53:08 +0200 Subject: [PATCH 231/321] UX: improve FilterOrder box design --- src/Bundle/ChillActivityBundle/translations/messages.fr.yml | 1 + .../Resources/views/FilterOrder/base.html.twig | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Bundle/ChillActivityBundle/translations/messages.fr.yml b/src/Bundle/ChillActivityBundle/translations/messages.fr.yml index d37b3488f..3099e99b0 100644 --- a/src/Bundle/ChillActivityBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillActivityBundle/translations/messages.fr.yml @@ -98,6 +98,7 @@ activity_filter: Jobs: Par métier impliqué By: Filtrer par Search: Chercher dans la liste + By date: Filtrer par date #timeline '%user% has done an %activity_type%': '%user% a effectué un échange de type "%activity_type%"' diff --git a/src/Bundle/ChillMainBundle/Resources/views/FilterOrder/base.html.twig b/src/Bundle/ChillMainBundle/Resources/views/FilterOrder/base.html.twig index 8faef5d14..b2673b60c 100644 --- a/src/Bundle/ChillMainBundle/Resources/views/FilterOrder/base.html.twig +++ b/src/Bundle/ChillMainBundle/Resources/views/FilterOrder/base.html.twig @@ -18,8 +18,10 @@
      {% if form.dateRanges[dateRangeName].vars.label is not same as(false) %} {{ form_label(form.dateRanges[dateRangeName])}} + {% else %} +
      {{ 'activity_filter.By date'|trans }}
      {% endif %} -
      +
      {{ 'chill_calendar.From'|trans }} {{ form_widget(form.dateRanges[dateRangeName]['from']) }} From 145c1df313e0328830fe406c12b1afcf03b070dd Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Wed, 5 Jul 2023 09:43:13 +0200 Subject: [PATCH 232/321] cleaning --- .../Resources/public/chill/scss/forms.scss | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Resources/public/chill/scss/forms.scss b/src/Bundle/ChillMainBundle/Resources/public/chill/scss/forms.scss index cd81f36dc..a517a5516 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/chill/scss/forms.scss +++ b/src/Bundle/ChillMainBundle/Resources/public/chill/scss/forms.scss @@ -44,13 +44,5 @@ form { } .chill_filter_order { - background: $gray-100; /* - border: 3px dashed $white; - background: repeating-linear-gradient( - -45deg, - $gray-100, - $gray-100 2px, - $white 2px, - $white 6px - ); */ + background: $gray-100; } \ No newline at end of file From 25d4b6acbb2b5d547abb38072f69da7f764e4141 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Wed, 5 Jul 2023 10:54:37 +0200 Subject: [PATCH 233/321] [FEATURE] allow adding of user filters in filter order - template still to be done --- .../Form/Type/Listing/FilterOrderType.php | 30 ++++++++++++++++++ .../Templating/Listing/FilterOrderHelper.php | 31 ++++++++++++++++++- .../Listing/FilterOrderHelperBuilder.php | 23 ++++++++++++++ 3 files changed, 83 insertions(+), 1 deletion(-) diff --git a/src/Bundle/ChillMainBundle/Form/Type/Listing/FilterOrderType.php b/src/Bundle/ChillMainBundle/Form/Type/Listing/FilterOrderType.php index 16038515d..9aebab144 100644 --- a/src/Bundle/ChillMainBundle/Form/Type/Listing/FilterOrderType.php +++ b/src/Bundle/ChillMainBundle/Form/Type/Listing/FilterOrderType.php @@ -12,6 +12,7 @@ declare(strict_types=1); namespace Chill\MainBundle\Form\Type\Listing; use Chill\MainBundle\Form\Type\ChillDateType; +use Chill\MainBundle\Form\Type\PickUserDynamicType; use Chill\MainBundle\Templating\Listing\FilterOrderHelper; use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\Extension\Core\Type\CheckboxType; @@ -120,6 +121,35 @@ final class FilterOrderType extends \Symfony\Component\Form\AbstractType $builder->add($singleCheckBoxBuilder); } + + if ([] !== $helper->getUserPickers()) { + $userPickersBuilder = $builder->create('userPicker', null, ['compound' => true]); + + foreach ($helper->getUserPickers() as $name => [ + 'label' => $label, 'options' => $options + ]) { + $userPicker = $userPickersBuilder->create($name, null, [ + 'compound' => true, + 'label' => $label, + ]); + + $userPicker->add( + $name, + PickUserDynamicType::class, + [ + 'multiple' => true, + 'label' => $label, + ...$options, + ] + ); + + + $userPickersBuilder->add($userPicker); + } + + $builder->add($userPickersBuilder); + } + } public function buildView(FormView $view, FormInterface $form, array $options) diff --git a/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelper.php b/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelper.php index 28cc8e331..f12c23299 100644 --- a/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelper.php +++ b/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelper.php @@ -52,6 +52,11 @@ class FilterOrderHelper */ private array $entityChoices = []; + /** + * @var array + */ + private array $userPickers = []; + public function __construct( FormFactoryInterface $formFactory, RequestStack $requestStack @@ -82,6 +87,14 @@ class FilterOrderHelper return $this->entityChoices; } + public function addUserPickers(string $name, ?string $label = null, array $options = []): self + { + $this->userPickers[$name] = ['label' => $label, 'options' => $options]; + + return $this; + } + + public function addCheckbox(string $name, array $choices, ?array $default = [], ?array $trans = [], array $options = []): self { $missing = count($choices) - count($trans) - 1; @@ -116,6 +129,16 @@ class FilterOrderHelper ->handleRequest($this->requestStack->getCurrentRequest()); } + public function getUserPickers(): array + { + return $this->userPickers; + } + + public function getUserPickerData(string $name): array + { + return $this->getFormData()['userPickers'][$name]; + } + public function getCheckboxData(string $name): array { return $this->getFormData()['checkboxes'][$name]; @@ -180,7 +203,8 @@ class FilterOrderHelper 'checkboxes' => [], 'dateRanges' => [], 'single_checkboxes' => [], - 'entity_choices' => [] + 'entity_choices' => [], + 'user_pickers' => [] ]; if ($this->hasSearchBox()) { @@ -204,7 +228,12 @@ class FilterOrderHelper $r['entity_choices'][$name] = ($c['options']['multiple'] ?? true) ? [] : null; } + foreach ($this->userPickers as $name => $u) { + $r['user_pickers'][$name] = ($u['options']['multiple'] ?? true) ? [] : null; + } + return $r; + } private function getFormData(): array diff --git a/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelperBuilder.php b/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelperBuilder.php index e176e27c6..6fd0eeb42 100644 --- a/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelperBuilder.php +++ b/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelperBuilder.php @@ -37,6 +37,11 @@ class FilterOrderHelperBuilder */ private array $entityChoices = []; + /** + * @var array + */ + private array $userPickers = []; + public function __construct( FormFactoryInterface $formFactory, RequestStack $requestStack @@ -83,6 +88,13 @@ class FilterOrderHelperBuilder return $this; } + public function addUserPickers(string $name, ?string $label = null, ?array $options = []): self + { + $this->userPickers[$name] = ['label' => $label, 'options' => $options]; + + return $this; + } + public function build(): FilterOrderHelper { $helper = new FilterOrderHelper( @@ -124,6 +136,17 @@ class FilterOrderHelperBuilder $helper->addDateRange($name, $label, $from, $to); } + + foreach ( + $this->userPickers as $name => [ + 'label' => $label, + 'options' => $options + ] + ) { + $helper->addUserPickers($name, $label, $options); + } + + return $helper; } } From 0d626fb3459a0b30e847b315618851e203db68ef Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Wed, 5 Jul 2023 10:55:30 +0200 Subject: [PATCH 234/321] [FEATURE] implement user filter in orderFilterHelper for tasks --- src/Bundle/ChillTaskBundle/Controller/SingleTaskController.php | 2 ++ .../Resources/views/SingleTask/List/index.html.twig | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/Bundle/ChillTaskBundle/Controller/SingleTaskController.php b/src/Bundle/ChillTaskBundle/Controller/SingleTaskController.php index 2ba9488b6..58d2a406e 100644 --- a/src/Bundle/ChillTaskBundle/Controller/SingleTaskController.php +++ b/src/Bundle/ChillTaskBundle/Controller/SingleTaskController.php @@ -299,6 +299,7 @@ final class SingleTaskController extends AbstractController $this->denyAccessUnlessGranted(TaskVoter::SHOW, null); $filterOrder = $this->buildFilterOrder(); + $flags = array_merge( $filterOrder->getCheckboxData('status'), array_map(static fn ($i) => 'state_' . $i, $filterOrder->getCheckboxData('states')) @@ -680,6 +681,7 @@ final class SingleTaskController extends AbstractController ->addSearchBox() ->addCheckbox('status', $statuses, $statuses, $statusTrans) ->addCheckbox('states', $states, ['new', 'in_progress']) + ->addUserPickers('userPicker', 'userPicker', ['multiple' => True]) ->build(); } diff --git a/src/Bundle/ChillTaskBundle/Resources/views/SingleTask/List/index.html.twig b/src/Bundle/ChillTaskBundle/Resources/views/SingleTask/List/index.html.twig index 8fe45959e..b479eb948 100644 --- a/src/Bundle/ChillTaskBundle/Resources/views/SingleTask/List/index.html.twig +++ b/src/Bundle/ChillTaskBundle/Resources/views/SingleTask/List/index.html.twig @@ -27,8 +27,10 @@ {% block css %} {{ parent() }} {{ encore_entry_link_tags('page_task_list') }} + {{ encore_entry_link_tags('mod_pickentity_type') }} {% endblock %} {% block js %} {{ parent() }} {{ encore_entry_script_tags('page_task_list') }} + {{ encore_entry_script_tags('mod_pickentity_type') }} {% endblock %} From 4da7040a49b4a05af0e37434052cc1d457806629 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Wed, 5 Jul 2023 12:38:42 +0200 Subject: [PATCH 235/321] FEATURE [user filter] implement query. Selecting multiple users doesn't work --- .../Form/Type/Listing/FilterOrderType.php | 2 +- .../views/FilterOrder/base.html.twig | 18 +++++++++++- .../Templating/Listing/FilterOrderHelper.php | 5 ++-- .../Listing/FilterOrderHelperBuilder.php | 4 +-- .../Controller/SingleTaskController.php | 8 +++-- .../SingleTaskAclAwareRepository.php | 29 ++++++++++++++++--- .../SingleTaskAclAwareRepositoryInterface.php | 4 ++- .../translations/messages.fr.yml | 1 + 8 files changed, 58 insertions(+), 13 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Form/Type/Listing/FilterOrderType.php b/src/Bundle/ChillMainBundle/Form/Type/Listing/FilterOrderType.php index a5166e322..c6744f852 100644 --- a/src/Bundle/ChillMainBundle/Form/Type/Listing/FilterOrderType.php +++ b/src/Bundle/ChillMainBundle/Form/Type/Listing/FilterOrderType.php @@ -126,7 +126,7 @@ final class FilterOrderType extends \Symfony\Component\Form\AbstractType } if ([] !== $helper->getUserPickers()) { - $userPickersBuilder = $builder->create('userPicker', null, ['compound' => true]); + $userPickersBuilder = $builder->create('user_pickers', null, ['compound' => true]); foreach ($helper->getUserPickers() as $name => [ 'label' => $label, 'options' => $options diff --git a/src/Bundle/ChillMainBundle/Resources/views/FilterOrder/base.html.twig b/src/Bundle/ChillMainBundle/Resources/views/FilterOrder/base.html.twig index b2673b60c..fa35cdbf3 100644 --- a/src/Bundle/ChillMainBundle/Resources/views/FilterOrder/base.html.twig +++ b/src/Bundle/ChillMainBundle/Resources/views/FilterOrder/base.html.twig @@ -67,6 +67,22 @@ {% endfor %} {% endif %} {% endif %} + {% if form.user_pickers is defined %} + {% set btnSubmit = 1 %} + {% if form.user_pickers|length > 0 %} + {% for name, options in form.user_pickers %} +
      +
      + {% for p in form['user_pickers'][name].children %} + {{ form_widget(p) }} + {{ form_label(p) }} + {% endfor %} +
      +
      + {% endfor %} + {% endif %} + {% endif %} + {% if form.single_checkboxes is defined %} {% set btnSubmit = 1 %} {% for name, _o in form.single_checkboxes %} @@ -78,7 +94,7 @@
      {% endfor %} {% endif %} - + {% if btnSubmit == 1 %}
      diff --git a/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelper.php b/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelper.php index bdec463bd..026c55ef6 100644 --- a/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelper.php +++ b/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelper.php @@ -87,7 +87,7 @@ class FilterOrderHelper return $this->entityChoices; } - public function addUserPickers(string $name, ?string $label = null, array $options = []): self + public function addUserPicker(string $name, ?string $label = null, array $options = []): self { $this->userPickers[$name] = ['label' => $label, 'options' => $options]; @@ -136,7 +136,8 @@ class FilterOrderHelper public function getUserPickerData(string $name): array { - return $this->getFormData()['userPickers'][$name]; + dump($this->getFormData()['user_pickers']); + return $this->getFormData()['user_pickers'][$name]; } public function getCheckboxData(string $name): array diff --git a/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelperBuilder.php b/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelperBuilder.php index 6fd0eeb42..86180d06e 100644 --- a/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelperBuilder.php +++ b/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelperBuilder.php @@ -88,7 +88,7 @@ class FilterOrderHelperBuilder return $this; } - public function addUserPickers(string $name, ?string $label = null, ?array $options = []): self + public function addUserPicker(string $name, ?string $label = null, ?array $options = []): self { $this->userPickers[$name] = ['label' => $label, 'options' => $options]; @@ -143,7 +143,7 @@ class FilterOrderHelperBuilder 'options' => $options ] ) { - $helper->addUserPickers($name, $label, $options); + $helper->addUserPicker($name, $label, $options); } diff --git a/src/Bundle/ChillTaskBundle/Controller/SingleTaskController.php b/src/Bundle/ChillTaskBundle/Controller/SingleTaskController.php index 58d2a406e..e60a58145 100644 --- a/src/Bundle/ChillTaskBundle/Controller/SingleTaskController.php +++ b/src/Bundle/ChillTaskBundle/Controller/SingleTaskController.php @@ -300,13 +300,16 @@ final class SingleTaskController extends AbstractController $filterOrder = $this->buildFilterOrder(); + $filteredUsers = $filterOrder->getUserPickerData('userPicker'); + $flags = array_merge( $filterOrder->getCheckboxData('status'), array_map(static fn ($i) => 'state_' . $i, $filterOrder->getCheckboxData('states')) ); $nb = $this->singleTaskAclAwareRepository->countByAllViewable( $filterOrder->getQueryString(), - $flags + $flags, + $filteredUsers ); $paginator = $this->paginatorFactory->create($nb); @@ -314,6 +317,7 @@ final class SingleTaskController extends AbstractController $tasks = $this->singleTaskAclAwareRepository->findByAllViewable( $filterOrder->getQueryString(), $flags, + $filteredUsers, $paginator->getCurrentPageFirstItemNumber(), $paginator->getItemsPerPage(), [ @@ -681,7 +685,7 @@ final class SingleTaskController extends AbstractController ->addSearchBox() ->addCheckbox('status', $statuses, $statuses, $statusTrans) ->addCheckbox('states', $states, ['new', 'in_progress']) - ->addUserPickers('userPicker', 'userPicker', ['multiple' => True]) + ->addUserPicker('userPicker', 'Filter by user', ['multiple' => True, 'required' => False]) ->build(); } diff --git a/src/Bundle/ChillTaskBundle/Repository/SingleTaskAclAwareRepository.php b/src/Bundle/ChillTaskBundle/Repository/SingleTaskAclAwareRepository.php index 0efc16085..ef30a7783 100644 --- a/src/Bundle/ChillTaskBundle/Repository/SingleTaskAclAwareRepository.php +++ b/src/Bundle/ChillTaskBundle/Repository/SingleTaskAclAwareRepository.php @@ -51,7 +51,8 @@ final class SingleTaskAclAwareRepository implements SingleTaskAclAwareRepository public function buildBaseQuery( ?string $pattern = null, - ?array $flags = [] + ?array $flags = [], + ?array $users = [] ): QueryBuilder { $qb = $this->em->createQueryBuilder(); $qb @@ -62,6 +63,24 @@ final class SingleTaskAclAwareRepository implements SingleTaskAclAwareRepository ->setParameter('pattern', '%' . $pattern . '%'); } + if (count($users) > 0) { + $orXUser = $qb->expr()->orX(); + + foreach ($users as $key => $user) { + $orXUser->add( + $qb->expr()->eq('t.assignee', ':user') + ); + + $qb->setParameter('user', $user); + } + + if ($orXUser->count() > 0) { + $qb->andWhere($orXUser); + } + + return $qb; + } + if (count($flags) > 0) { $orXDate = $qb->expr()->orX(); $orXState = $qb->expr()->orX(); @@ -183,9 +202,10 @@ final class SingleTaskAclAwareRepository implements SingleTaskAclAwareRepository public function countByAllViewable( ?string $pattern = null, - ?array $flags = [] + ?array $flags = [], + ?array $users = [] ): int { - $qb = $this->buildBaseQuery($pattern, $flags); + $qb = $this->buildBaseQuery($pattern, $flags, $users); return $this ->addACLGlobal($qb) @@ -231,11 +251,12 @@ final class SingleTaskAclAwareRepository implements SingleTaskAclAwareRepository public function findByAllViewable( ?string $pattern = null, ?array $flags = [], + ?array $users = [], ?int $start = 0, ?int $limit = 50, ?array $orderBy = [] ): array { - $qb = $this->buildBaseQuery($pattern, $flags); + $qb = $this->buildBaseQuery($pattern, $flags, $users); $qb = $this->addACLGlobal($qb); return $this->getResult($qb, $start, $limit, $orderBy); diff --git a/src/Bundle/ChillTaskBundle/Repository/SingleTaskAclAwareRepositoryInterface.php b/src/Bundle/ChillTaskBundle/Repository/SingleTaskAclAwareRepositoryInterface.php index 57c57e592..7d2870c67 100644 --- a/src/Bundle/ChillTaskBundle/Repository/SingleTaskAclAwareRepositoryInterface.php +++ b/src/Bundle/ChillTaskBundle/Repository/SingleTaskAclAwareRepositoryInterface.php @@ -18,7 +18,8 @@ interface SingleTaskAclAwareRepositoryInterface { public function countByAllViewable( ?string $pattern = null, - ?array $flags = [] + ?array $flags = [], + ?array $users = [] ): int; public function countByCourse( @@ -38,6 +39,7 @@ interface SingleTaskAclAwareRepositoryInterface public function findByAllViewable( ?string $pattern = null, ?array $flags = [], + ?array $users = [], ?int $start = 0, ?int $limit = 50, ?array $orderBy = [] diff --git a/src/Bundle/ChillTaskBundle/translations/messages.fr.yml b/src/Bundle/ChillTaskBundle/translations/messages.fr.yml index d437baac2..599ca8640 100644 --- a/src/Bundle/ChillTaskBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillTaskBundle/translations/messages.fr.yml @@ -65,6 +65,7 @@ Not assigned: Aucun utilisateur assigné For person: Pour By: Par Any tasks: Aucune tâche +Filter by user: Filtrer par utilisateur(s) # transitions - default task definition "new": "nouvelle" From 1ee0e8e350381e039f04171019f2a9584394412e Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Wed, 5 Jul 2023 13:35:06 +0200 Subject: [PATCH 236/321] DX phpstan and csfixer --- .../Form/Type/Listing/FilterOrderType.php | 13 +++---------- .../Resources/views/FilterOrder/base.html.twig | 12 +++++++----- .../Templating/Listing/FilterOrderHelper.php | 1 - .../Templating/Listing/FilterOrderHelperBuilder.php | 6 +++--- .../Controller/SingleTaskController.php | 2 +- 5 files changed, 14 insertions(+), 20 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Form/Type/Listing/FilterOrderType.php b/src/Bundle/ChillMainBundle/Form/Type/Listing/FilterOrderType.php index c6744f852..4e41a1740 100644 --- a/src/Bundle/ChillMainBundle/Form/Type/Listing/FilterOrderType.php +++ b/src/Bundle/ChillMainBundle/Form/Type/Listing/FilterOrderType.php @@ -129,25 +129,18 @@ final class FilterOrderType extends \Symfony\Component\Form\AbstractType $userPickersBuilder = $builder->create('user_pickers', null, ['compound' => true]); foreach ($helper->getUserPickers() as $name => [ - 'label' => $label, 'options' => $options + 'label' => $label, 'options' => $opts ]) { - $userPicker = $userPickersBuilder->create($name, null, [ - 'compound' => true, - 'label' => $label, - ]); - $userPicker->add( + $userPickersBuilder->add( $name, PickUserDynamicType::class, [ 'multiple' => true, 'label' => $label, - ...$options, + ...$opts, ] ); - - - $userPickersBuilder->add($userPicker); } $builder->add($userPickersBuilder); diff --git a/src/Bundle/ChillMainBundle/Resources/views/FilterOrder/base.html.twig b/src/Bundle/ChillMainBundle/Resources/views/FilterOrder/base.html.twig index fa35cdbf3..9a9a11fbd 100644 --- a/src/Bundle/ChillMainBundle/Resources/views/FilterOrder/base.html.twig +++ b/src/Bundle/ChillMainBundle/Resources/views/FilterOrder/base.html.twig @@ -69,14 +69,16 @@ {% endif %} {% if form.user_pickers is defined %} {% set btnSubmit = 1 %} - {% if form.user_pickers|length > 0 %} + {% if form.user_pickers.children|length > 0 %} {% for name, options in form.user_pickers %}
      + {% if form.user_pickers[name].vars.label is not same as(false) %} + {{ form_label(form.user_pickers[name]) }} + {% else %} + {{ form_label(form.user_pickers[name].vars.label) }} + {% endif %}
      - {% for p in form['user_pickers'][name].children %} - {{ form_widget(p) }} - {{ form_label(p) }} - {% endfor %} + {{ form_widget(form.user_pickers[name]) }}
      {% endfor %} diff --git a/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelper.php b/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelper.php index 026c55ef6..8554b4431 100644 --- a/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelper.php +++ b/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelper.php @@ -136,7 +136,6 @@ class FilterOrderHelper public function getUserPickerData(string $name): array { - dump($this->getFormData()['user_pickers']); return $this->getFormData()['user_pickers'][$name]; } diff --git a/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelperBuilder.php b/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelperBuilder.php index 86180d06e..d9a505dee 100644 --- a/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelperBuilder.php +++ b/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelperBuilder.php @@ -139,9 +139,9 @@ class FilterOrderHelperBuilder foreach ( $this->userPickers as $name => [ - 'label' => $label, - 'options' => $options - ] + 'label' => $label, + 'options' => $options + ] ) { $helper->addUserPicker($name, $label, $options); } diff --git a/src/Bundle/ChillTaskBundle/Controller/SingleTaskController.php b/src/Bundle/ChillTaskBundle/Controller/SingleTaskController.php index e60a58145..22e49704f 100644 --- a/src/Bundle/ChillTaskBundle/Controller/SingleTaskController.php +++ b/src/Bundle/ChillTaskBundle/Controller/SingleTaskController.php @@ -685,7 +685,7 @@ final class SingleTaskController extends AbstractController ->addSearchBox() ->addCheckbox('status', $statuses, $statuses, $statusTrans) ->addCheckbox('states', $states, ['new', 'in_progress']) - ->addUserPicker('userPicker', 'Filter by user', ['multiple' => True, 'required' => False]) + ->addUserPicker('userPicker', 'Filter by user', ['multiple' => true, 'required' => false]) ->build(); } From 4e934653be7641605ac52070e3529663c78e00f7 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Wed, 5 Jul 2023 14:12:43 +0200 Subject: [PATCH 237/321] DX changie added --- .changes/unreleased/Feature-20230705-140336.yaml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changes/unreleased/Feature-20230705-140336.yaml diff --git a/.changes/unreleased/Feature-20230705-140336.yaml b/.changes/unreleased/Feature-20230705-140336.yaml new file mode 100644 index 000000000..3ce7f3c0f --- /dev/null +++ b/.changes/unreleased/Feature-20230705-140336.yaml @@ -0,0 +1,5 @@ +kind: Feature +body: Allow filtering on the basis of a user within general tasks list +time: 2023-07-05T14:03:36.664880092+02:00 +custom: + Issue: "" From 52d51264bab3a096be592a8df31f83e3f0b4dca4 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Wed, 5 Jul 2023 14:57:28 +0200 Subject: [PATCH 238/321] FIX [query][user filter] avoid replacement of user parameter in query --- .../Repository/SingleTaskAclAwareRepository.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Bundle/ChillTaskBundle/Repository/SingleTaskAclAwareRepository.php b/src/Bundle/ChillTaskBundle/Repository/SingleTaskAclAwareRepository.php index ef30a7783..d1652cc89 100644 --- a/src/Bundle/ChillTaskBundle/Repository/SingleTaskAclAwareRepository.php +++ b/src/Bundle/ChillTaskBundle/Repository/SingleTaskAclAwareRepository.php @@ -68,10 +68,10 @@ final class SingleTaskAclAwareRepository implements SingleTaskAclAwareRepository foreach ($users as $key => $user) { $orXUser->add( - $qb->expr()->eq('t.assignee', ':user') + $qb->expr()->eq('t.assignee', ':user_' . $key) ); - $qb->setParameter('user', $user); + $qb->setParameter('user_' . $key, $user); } if ($orXUser->count() > 0) { From 4b25970ce0a43e82531280940c6507da8f071b41 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Wed, 5 Jul 2023 15:35:13 +0200 Subject: [PATCH 239/321] FEATURE [filter] start implementation of social action filter --- .../AccompanyingCourseWorkController.php | 38 ++++++++++++++++++- .../AccompanyingPeriodWorkRepository.php | 2 +- .../translations/messages.fr.yml | 3 ++ 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseWorkController.php b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseWorkController.php index 8d15ca30f..75d0bae7c 100644 --- a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseWorkController.php +++ b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseWorkController.php @@ -11,9 +11,14 @@ declare(strict_types=1); namespace Chill\PersonBundle\Controller; +use Chill\MainBundle\Entity\UserJob; use Chill\MainBundle\Pagination\PaginatorFactory; +use Chill\MainBundle\Templating\Listing\FilterOrderHelper; +use Chill\MainBundle\Templating\TranslatableStringHelperInterface; use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork; +use Chill\PersonBundle\Entity\Person; +use Chill\PersonBundle\Entity\SocialWork\SocialAction; use Chill\PersonBundle\Repository\AccompanyingPeriod\AccompanyingPeriodWorkRepository; use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodWorkVoter; use Psr\Log\LoggerInterface; @@ -38,18 +43,22 @@ class AccompanyingCourseWorkController extends AbstractController private AccompanyingPeriodWorkRepository $workRepository; + private TranslatableStringHelperInterface $translatableStringHelper; + public function __construct( TranslatorInterface $trans, SerializerInterface $serializer, AccompanyingPeriodWorkRepository $workRepository, PaginatorFactory $paginator, - LoggerInterface $chillLogger + LoggerInterface $chillLogger, + TranslatableStringHelperInterface $translatableStringHelper ) { $this->trans = $trans; $this->serializer = $serializer; $this->workRepository = $workRepository; $this->paginator = $paginator; $this->chillLogger = $chillLogger; + $this->translatableStringHelper = $translatableStringHelper; } /** @@ -162,11 +171,21 @@ class AccompanyingCourseWorkController extends AbstractController { $this->denyAccessUnlessGranted(AccompanyingPeriodWorkVoter::SEE, $period); + $filter = $this->buildFilterOrder($period); + + $filterData = [ + 'types' => $filter->getEntityChoiceData('typesFilter'), + 'before' => $filter->getDateRangeData('dateFilter')['to'], + 'after' => $filter->getDateRangeData('dateFilter')['from'], + 'user' => $filter->getUserPickerData('userFilter') + ]; + $totalItems = $this->workRepository->countByAccompanyingPeriod($period); $paginator = $this->paginator->create($totalItems); $works = $this->workRepository->findByAccompanyingPeriodOpenFirst( $period, + $filterData, $paginator->getItemsPerPage(), $paginator->getCurrentPageFirstItemNumber() ); @@ -210,4 +229,21 @@ class AccompanyingCourseWorkController extends AbstractController ->add('submit', SubmitType::class, ['label' => 'Delete']) ->getForm(); } + + private function buildFilterOrder($associatedPeriod): FilterOrderHelper + { + + $filterBuilder = $this->filterOrderHelperFactory->create(self::class); + $types = $this->workRepository->findByAccompanyingPeriod($associatedPeriod); + + $filterBuilder + ->addDateRange('dateFilter', 'accompanying_course_work.date_filter') + ->addEntityChoice('typesFilter', 'accompanying_course_work.types_filter', \Chill\PersonBundle\Entity\SocialAction::class, $types, [ + 'choice_label' => fn (SocialAction $sa) => $this->translatableStringHelper->localize($sa->getTitle()) + ]) + ->addUserPicker('userFilter', 'accompanying_course_work.user_filter') + ; + + return $filterBuilder->build(); + } } diff --git a/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/AccompanyingPeriodWorkRepository.php b/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/AccompanyingPeriodWorkRepository.php index bf2d34aae..1bd9b0f4e 100644 --- a/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/AccompanyingPeriodWorkRepository.php +++ b/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/AccompanyingPeriodWorkRepository.php @@ -96,7 +96,7 @@ final class AccompanyingPeriodWorkRepository implements ObjectRepository * * @return AccompanyingPeriodWork[] */ - public function findByAccompanyingPeriodOpenFirst(AccompanyingPeriod $period, int $limit = 10, int $offset = 0): array + public function findByAccompanyingPeriodOpenFirst(AccompanyingPeriod $period, $filters, int $limit = 10, int $offset = 0): array { $rsm = new ResultSetMappingBuilder($this->em); $rsm->addRootEntityFromClassMetadata(AccompanyingPeriodWork::class, 'w'); diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index 01383c050..f783c403e 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -912,6 +912,9 @@ accompanying_course_work: social_evaluation: Évaluation private_comment: Commentaire privé timeSpent: Temps de rédaction + date_filter: Filtrer par date + types_filter: Filtrer par type d'action + user_filter: Filtrer par intervenant # From 6c58e7eb3e13a3421250263f69043740787e0c8d Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Wed, 5 Jul 2023 15:49:50 +0200 Subject: [PATCH 240/321] DX phpstan and cs-fixer --- .../AccompanyingCourseWorkController.php | 34 +++++-------------- .../AccompanyingPeriodWorkRepository.php | 1 + 2 files changed, 10 insertions(+), 25 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseWorkController.php b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseWorkController.php index 75d0bae7c..9abf1677d 100644 --- a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseWorkController.php +++ b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseWorkController.php @@ -14,6 +14,7 @@ namespace Chill\PersonBundle\Controller; use Chill\MainBundle\Entity\UserJob; use Chill\MainBundle\Pagination\PaginatorFactory; use Chill\MainBundle\Templating\Listing\FilterOrderHelper; +use Chill\MainBundle\Templating\Listing\FilterOrderHelperFactoryInterface; use Chill\MainBundle\Templating\TranslatableStringHelperInterface; use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork; @@ -33,32 +34,15 @@ use Symfony\Contracts\Translation\TranslatorInterface; class AccompanyingCourseWorkController extends AbstractController { - private LoggerInterface $chillLogger; - - private PaginatorFactory $paginator; - - private SerializerInterface $serializer; - - private TranslatorInterface $trans; - - private AccompanyingPeriodWorkRepository $workRepository; - - private TranslatableStringHelperInterface $translatableStringHelper; - public function __construct( - TranslatorInterface $trans, - SerializerInterface $serializer, - AccompanyingPeriodWorkRepository $workRepository, - PaginatorFactory $paginator, - LoggerInterface $chillLogger, - TranslatableStringHelperInterface $translatableStringHelper + private readonly TranslatorInterface $trans, + private readonly SerializerInterface $serializer, + private readonly AccompanyingPeriodWorkRepository $workRepository, + private readonly PaginatorFactory $paginator, + private readonly LoggerInterface $chillLogger, + private readonly TranslatableStringHelperInterface $translatableStringHelper, + private readonly FilterOrderHelperFactoryInterface $filterOrderHelperFactory ) { - $this->trans = $trans; - $this->serializer = $serializer; - $this->workRepository = $workRepository; - $this->paginator = $paginator; - $this->chillLogger = $chillLogger; - $this->translatableStringHelper = $translatableStringHelper; } /** @@ -238,7 +222,7 @@ class AccompanyingCourseWorkController extends AbstractController $filterBuilder ->addDateRange('dateFilter', 'accompanying_course_work.date_filter') - ->addEntityChoice('typesFilter', 'accompanying_course_work.types_filter', \Chill\PersonBundle\Entity\SocialAction::class, $types, [ + ->addEntityChoice('typesFilter', 'accompanying_course_work.types_filter', \Chill\PersonBundle\Entity\SocialWork\SocialAction::class, $types, [ 'choice_label' => fn (SocialAction $sa) => $this->translatableStringHelper->localize($sa->getTitle()) ]) ->addUserPicker('userFilter', 'accompanying_course_work.user_filter') diff --git a/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/AccompanyingPeriodWorkRepository.php b/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/AccompanyingPeriodWorkRepository.php index 1bd9b0f4e..60a00e12a 100644 --- a/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/AccompanyingPeriodWorkRepository.php +++ b/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/AccompanyingPeriodWorkRepository.php @@ -95,6 +95,7 @@ final class AccompanyingPeriodWorkRepository implements ObjectRepository * * then, closed works * * @return AccompanyingPeriodWork[] + * @param mixed $filters */ public function findByAccompanyingPeriodOpenFirst(AccompanyingPeriod $period, $filters, int $limit = 10, int $offset = 0): array { From 61982634a6203875f6bcaf0fd30fd454db204729 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Wed, 5 Jul 2023 16:05:51 +0200 Subject: [PATCH 241/321] FEATURE add filter to the template --- .../Controller/AccompanyingCourseWorkController.php | 3 ++- .../Resources/views/AccompanyingCourseWork/index.html.twig | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseWorkController.php b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseWorkController.php index 9abf1677d..1f2680f9e 100644 --- a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseWorkController.php +++ b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseWorkController.php @@ -178,6 +178,7 @@ class AccompanyingCourseWorkController extends AbstractController 'accompanyingCourse' => $period, 'works' => $works, 'paginator' => $paginator, + 'filter' => $filter ]); } @@ -225,7 +226,7 @@ class AccompanyingCourseWorkController extends AbstractController ->addEntityChoice('typesFilter', 'accompanying_course_work.types_filter', \Chill\PersonBundle\Entity\SocialWork\SocialAction::class, $types, [ 'choice_label' => fn (SocialAction $sa) => $this->translatableStringHelper->localize($sa->getTitle()) ]) - ->addUserPicker('userFilter', 'accompanying_course_work.user_filter') + ->addUserPicker('userFilter', 'accompanying_course_work.user_filter', ['required' => false]) ; return $filterBuilder->build(); diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/index.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/index.html.twig index ab1989f63..1cedfa694 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/index.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourseWork/index.html.twig @@ -5,18 +5,23 @@ {% block js %} {{ parent() }} {{ encore_entry_script_tags('mod_entity_workflow_pick') }} + {{ encore_entry_script_tags('mod_pickentity_type') }} {% endblock %} {% block css %} {{ parent() }} {{ encore_entry_link_tags('mod_entity_workflow_pick') }} + {{ encore_entry_link_tags('mod_pickentity_type') }} {% endblock %} + {% block content %}

      {{ block('title') }}

      + {{ filter|chill_render_filter_order_helper }} + {% if works|length == 0 %}

      {{ 'accompanying_course_work.Any work'|trans }}

      {% else %} From a990591e0cadcb5d2f70b61ab9c60df5c8a88036 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 5 Jul 2023 16:23:14 +0200 Subject: [PATCH 242/321] handle right to see confidential course on regulation list --- ...mpanyingPeriodRegulationListController.php | 1 + .../AccompanyingPeriodACLAwareRepository.php | 122 ++++++++++----- ...nyingPeriodACLAwareRepositoryInterface.php | 2 +- ...companyingPeriodACLAwareRepositoryTest.php | 141 +++++++++++++++++- 4 files changed, 229 insertions(+), 37 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Controller/AccompanyingPeriodRegulationListController.php b/src/Bundle/ChillPersonBundle/Controller/AccompanyingPeriodRegulationListController.php index 6bbb6c368..cd550ef59 100644 --- a/src/Bundle/ChillPersonBundle/Controller/AccompanyingPeriodRegulationListController.php +++ b/src/Bundle/ChillPersonBundle/Controller/AccompanyingPeriodRegulationListController.php @@ -78,6 +78,7 @@ class AccompanyingPeriodRegulationListController $form['jobs']->getData(), $form['services']->getData(), $form['locations']->getData(), + ['openingDate' => 'DESC', 'id' => 'DESC'], $paginator->getItemsPerPage(), $paginator->getCurrentPageFirstItemNumber() ); diff --git a/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodACLAwareRepository.php b/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodACLAwareRepository.php index 104f49ec7..e62e2b3ac 100644 --- a/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodACLAwareRepository.php +++ b/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodACLAwareRepository.php @@ -12,6 +12,7 @@ declare(strict_types=1); namespace Chill\PersonBundle\Repository; use Chill\MainBundle\Entity\Address; +use Chill\MainBundle\Entity\Center; use Chill\MainBundle\Entity\Location; use Chill\MainBundle\Entity\Scope; use Chill\MainBundle\Entity\User; @@ -26,6 +27,8 @@ use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter; use DateTime; use DateTimeImmutable; use Doctrine\DBAL\Types\Types; +use Doctrine\ORM\NonUniqueResultException; +use Doctrine\ORM\NoResultException; use Doctrine\ORM\Query\Expr\Join; use Doctrine\ORM\QueryBuilder; use Repository\AccompanyingPeriodACLAwareRepositoryTest; @@ -107,9 +110,16 @@ final readonly class AccompanyingPeriodACLAwareRepository implements Accompanyin return $qb; } + /** + * @throws NonUniqueResultException + * @throws NoResultException + */ public function countByUnDispatched(array $jobs, array $services, array $administrativeLocations): int { - $qb = $this->addACLByUnDispatched($this->buildQueryUnDispatched($jobs, $services, $administrativeLocations)); + $qb = $this->addACLByUnDispatched( + $this->buildQueryUnDispatched($jobs, $services, $administrativeLocations), + $this->buildCenterOnScope() + ); $qb->select('COUNT(ap)'); @@ -194,6 +204,8 @@ final readonly class AccompanyingPeriodACLAwareRepository implements Accompanyin } /** + * Add clause for scope on a query, based on no + * * @param QueryBuilder $qb where the accompanying period have the `ap` alias * @param array $scopesCanSee * @param array $scopesCanSeeConfidential @@ -252,19 +264,27 @@ final readonly class AccompanyingPeriodACLAwareRepository implements Accompanyin return $qb; } - public function findByUnDispatched(array $jobs, array $services, array $administrativeLocations, ?int $limit = null, ?int $offset = null): array + public function buildCenterOnScope(): array { - $qb = $this->addACLByUnDispatched($this->buildQueryUnDispatched($jobs, $services, $administrativeLocations)); + $centerOnScopes = []; + foreach ($this->authorizationHelper->getReachableCenters(AccompanyingPeriodVoter::SEE) as $center) { + $centerOnScopes[] = [ + 'center' => $center, + 'scopeOnRole' => $this->authorizationHelper->getReachableScopes(AccompanyingPeriodVoter::SEE, $center), + 'scopeCanSeeConfidential' => $this->authorizationHelper->getReachableScopes(AccompanyingPeriodVoter::SEE_CONFIDENTIAL_ALL, $center), + ]; + } + return $centerOnScopes; + } + + public function findByUnDispatched(array $jobs, array $services, array $administrativeAdministrativeLocations, ?array $orderBy = null, ?int $limit = null, ?int $offset = null): array + { + $qb = $this->buildQueryUnDispatched($jobs, $services, $administrativeAdministrativeLocations); $qb->select('ap'); - if (null !== $limit) { - $qb->setMaxResults($limit); - } - - if (null !== $offset) { - $qb->setFirstResult($offset); - } + $qb = $this->addACLByUnDispatched($qb, $this->buildCenterOnScope(), false); + $qb = $this->addOrderLimitClauses($qb, $orderBy, $limit, $offset); return $qb->getQuery()->getResult(); } @@ -305,41 +325,73 @@ final readonly class AccompanyingPeriodACLAwareRepository implements Accompanyin return $qb->getQuery()->getResult(); } - private function addACLByUnDispatched(QueryBuilder $qb): QueryBuilder + /** + * @param QueryBuilder $qb + * @param list, scopeCanSeeConfidential: list}> $centerScopes + * @param bool $allowNoCenter if true, will allow to see the periods linked to person which does not have any center. Very few edge case when some Person are not associated to a center. + * @return QueryBuilder + */ + public function addACLByUnDispatched(QueryBuilder $qb, array $centerScopes, bool $allowNoCenter = false): QueryBuilder { - $centers = $this->authorizationHelper->getReachableCenters( - AccompanyingPeriodVoter::SEE - ); + $user = $this->security->getUser(); - $orX = $qb->expr()->orX(); - - if (0 === count($centers)) { + if (0 === count($centerScopes) || !$user instanceof User) { return $qb->andWhere("'FALSE' = 'TRUE'"); } - foreach ($centers as $key => $center) { - $scopes = $this->authorizationHelper - ->getReachableScopes( - AccompanyingPeriodVoter::SEE, - $center - ); + $orX = $qb->expr()->orX(); + $idx = 0; + foreach ($centerScopes as ['center' => $center, 'scopeOnRole' => $scopes, 'scopeCanSeeConfidential' => $scopesCanSeeConfidential]) { $and = $qb->expr()->andX( - $qb->expr()->exists('SELECT part FROM ' . AccompanyingPeriodParticipation::class . ' part ' . - "JOIN part.person p WHERE part.accompanyingPeriod = ap.id AND p.center = :center_{$key}") + $qb->expr()->exists( + 'SELECT 1 FROM ' . AccompanyingPeriodParticipation::class . " part_{$idx} " . + "JOIN part_{$idx}.person p{$idx} LEFT JOIN p{$idx}.centerCurrent centerCurrent_{$idx} " . + "WHERE part_{$idx}.accompanyingPeriod = ap.id AND (centerCurrent_{$idx}.center = :center_{$idx}" + . ($allowNoCenter ? " OR centerCurrent_{$idx}.id IS NULL)" : ")") + ) ); - $qb->setParameter('center_' . $key, $center); - $orScope = $qb->expr()->orX(); + $qb->setParameter('center_' . $idx, $center); - foreach ($scopes as $skey => $scope) { - $orScope->add( - $qb->expr()->isMemberOf(':scope_' . $key . '_' . $skey, 'ap.scopes') + $orScopeInsideCenter = $qb->expr()->orX( + // even if the scope is not in one authorized, the user can see the course if it is in DRAFT state + $qb->expr()->eq('ap.step', ':draft') + ); + + $idx++; + foreach ($scopes as $scope) { + // for each scope: + // - either the user is the referrer of the course + // - or the accompanying course is one of the reachable scopes + // - and the parcours is not confidential OR the user is the referrer OR the user can see the confidential course + $orOnScope = $qb->expr()->orX( + $qb->expr()->isMemberOf(':scope_' . $idx, 'ap.scopes'), + $qb->expr()->eq('ap.user', ':user') ); - $qb->setParameter('scope_' . $key . '_' . $skey, $scope); + $qb->setParameter('user', $user); + + if (in_array($scope, $scopesCanSeeConfidential, true)) { + $orScopeInsideCenter->add($orOnScope); + } else { + // we must add a condition: the course is not confidential or the user is the referrer + $andXOnScope = $qb->expr()->andX( + $orOnScope, + $qb->expr()->orX( + 'ap.confidential = FALSE', + $qb->expr()->eq('ap.user', ':user') + ) + ); + $orScopeInsideCenter->add($andXOnScope); + } + $qb->setParameter('scope_' . $idx, $scope); + + $idx++; } - $and->add($orScope); + $and->add($orScopeInsideCenter); $orX->add($and); + + $idx++; } return $qb->andWhere($orX); @@ -350,7 +402,7 @@ final readonly class AccompanyingPeriodACLAwareRepository implements Accompanyin * @param array|Scope[] $services * @param array|Location[] $locations */ - private function buildQueryUnDispatched(array $jobs, array $services, array $locations): QueryBuilder + public function buildQueryUnDispatched(array $jobs, array $services, array $locations): QueryBuilder { $qb = $this->accompanyingPeriodRepository->createQueryBuilder('ap'); @@ -378,8 +430,8 @@ final readonly class AccompanyingPeriodACLAwareRepository implements Accompanyin $or = $qb->expr()->orX(); foreach ($services as $key => $service) { - $or->add($qb->expr()->isMemberOf(':scope_' . $key, 'ap.scopes')); - $qb->setParameter('scope_' . $key, $service); + $or->add($qb->expr()->isMemberOf(':scopef_' . $key, 'ap.scopes')); + $qb->setParameter('scopef_' . $key, $service); } $qb->andWhere($or); } diff --git a/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodACLAwareRepositoryInterface.php b/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodACLAwareRepositoryInterface.php index ff3d89783..61b631904 100644 --- a/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodACLAwareRepositoryInterface.php +++ b/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodACLAwareRepositoryInterface.php @@ -50,7 +50,7 @@ interface AccompanyingPeriodACLAwareRepositoryInterface * * @return list */ - public function findByUnDispatched(array $jobs, array $services, array $administrativeLocations, ?int $limit = null, ?int $offset = null): array; + public function findByUnDispatched(array $jobs, array $services, array $administrativeAdministrativeLocations, ?array $orderBy = null, ?int $limit = null, ?int $offset = null): array; /** * @param array|PostalCode[] $postalCodes diff --git a/src/Bundle/ChillPersonBundle/Tests/Repository/AccompanyingPeriodACLAwareRepositoryTest.php b/src/Bundle/ChillPersonBundle/Tests/Repository/AccompanyingPeriodACLAwareRepositoryTest.php index 17c12fea5..90e0d2384 100644 --- a/src/Bundle/ChillPersonBundle/Tests/Repository/AccompanyingPeriodACLAwareRepositoryTest.php +++ b/src/Bundle/ChillPersonBundle/Tests/Repository/AccompanyingPeriodACLAwareRepositoryTest.php @@ -11,8 +11,10 @@ declare(strict_types=1); namespace Repository; +use Chill\MainBundle\Entity\Center; use Chill\MainBundle\Entity\Scope; use Chill\MainBundle\Entity\User; +use Chill\MainBundle\Repository\CenterRepositoryInterface; use Chill\MainBundle\Repository\ScopeRepositoryInterface; use Chill\MainBundle\Security\Authorization\AuthorizationHelperForCurrentUserInterface; use Chill\MainBundle\Security\Resolver\CenterResolverManagerInterface; @@ -35,10 +37,13 @@ use Symfony\Component\Workflow\Registry; class AccompanyingPeriodACLAwareRepositoryTest extends KernelTestCase { use ProphecyTrait; + private AccompanyingPeriodRepository $accompanyingPeriodRepository; private CenterResolverManagerInterface $centerResolverManager; + private CenterRepositoryInterface $centerRepository; + private EntityManagerInterface $entityManager; private ScopeRepositoryInterface $scopeRepository; @@ -51,11 +56,11 @@ class AccompanyingPeriodACLAwareRepositoryTest extends KernelTestCase { self::bootKernel(); $this->accompanyingPeriodRepository = self::$container->get(AccompanyingPeriodRepository::class); + $this->centerRepository = self::$container->get(CenterRepositoryInterface::class); $this->centerResolverManager = self::$container->get(CenterResolverManagerInterface::class); $this->entityManager = self::$container->get(EntityManagerInterface::class); $this->scopeRepository = self::$container->get(ScopeRepositoryInterface::class); $this->registry = self::$container->get(Registry::class); - } public static function tearDownAfterClass(): void @@ -78,6 +83,140 @@ class AccompanyingPeriodACLAwareRepositoryTest extends KernelTestCase $em->flush(); } + /** + * @dataProvider provideDataFindByUndispatched + * @param list, scopeCanSeeConfidential: list}> $centerScopes + * @param list $expectedContains + * @param list $expectedNotContains + */ + public function testFindByUndispatched(User $user, array $centerScopes, array $expectedContains, array $expectedNotContains, string $message): void + { + $security = $this->prophesize(Security::class); + $security->getUser()->willReturn($user); + + $authorizationHelper = $this->prophesize(AuthorizationHelperForCurrentUserInterface::class); + $centers = []; + + foreach ($centerScopes as ['center' => $center, 'scopeOnRole' => $scopes, 'scopeCanSeeConfidential' => $scopesCanSeeConfidential]) { + $centers[spl_object_hash($center)] = $center; + $authorizationHelper->getReachableScopes(AccompanyingPeriodVoter::SEE, $center) + ->willReturn($scopes); + $authorizationHelper->getReachableScopes(AccompanyingPeriodVoter::SEE_CONFIDENTIAL_ALL, $center) + ->willReturn($scopesCanSeeConfidential); + } + $authorizationHelper->getReachableCenters(AccompanyingPeriodVoter::SEE)->willReturn(array_values($centers)); + + $repository = new AccompanyingPeriodACLAwareRepository( + $this->accompanyingPeriodRepository, + $security->reveal(), + $authorizationHelper->reveal(), + $this->centerResolverManager + ); + + $actual = array_map( + fn (AccompanyingPeriod $period) => $period->getId(), + $repository->findByUnDispatched([], [], [], ['id' => 'DESC'], 20, 0) + ); + + foreach ($expectedContains as $expected) { + self::assertContains($expected->getId(), $actual, $message); + } + foreach ($expectedNotContains as $expected) { + self::assertNotContains($expected->getId(), $actual, $message); + } + } + + public function provideDataFindByUndispatched(): iterable + { + $this->setUp(); + + if (null === $user = $this->entityManager->createQuery("SELECT u FROM " . User::class . " u")->setMaxResults(1)->getSingleResult()) { + throw new \RuntimeException("no user found"); + } + + if (null === $anotherUser = $this->entityManager->createQuery("SELECT u FROM " . User::class . " u WHERE u.id != :uid")->setParameter('uid', $user->getId()) + ->setMaxResults(1)->getSingleResult()) { + throw new \RuntimeException("no user found"); + } + + /** @var Person $person */ + [$person, $anotherPerson, $person2, $person3] = $this->entityManager + ->createQuery("SELECT p FROM " . Person::class . " p ") + ->setMaxResults(4) + ->getResult(); + + if (null === $person || null === $anotherPerson || null === $person2 || null === $person3) { + throw new \RuntimeException("no person found"); + } + + $scopes = $this->scopeRepository->findAll(); + + if (3 > count($scopes)) { + throw new \RuntimeException("not enough scopes for this test"); + } + $scopesCanSee = [ $scopes[0] ]; + $scopesGroup2 = [ $scopes[1] ]; + + $centers = $this->centerRepository->findActive(); + + if (2 > count($centers)) { + throw new \RuntimeException("not enough centers for this test"); + } + + $period = $this->buildPeriod($person, $scopesCanSee, $user, true); + + // expected scope: can see the period + yield [ + $anotherUser, + [ + [ + 'center' => $person->getCenter(), + 'scopeOnRole' => $scopesCanSee, + 'scopeCanSeeConfidential' => [], + ], + ], + [$period], + [], + "period should be visible with expected scopes", + ]; + + // no scope visible + yield [ + $anotherUser, + [ + [ + 'center' => $person->getCenter(), + 'scopeOnRole' => $scopesGroup2, + 'scopeCanSeeConfidential' => [], + ], + ], + [], + [$period], + "period should not be visible without expected scopes", + ]; + + // another center + yield [ + $anotherUser, + [ + [ + 'center' => $person->getCenter(), + 'scopeOnRole' => $scopesGroup2, + 'scopeCanSeeConfidential' => [], + ], + [ + 'center' => array_values(array_filter($centers, fn (Center $c) => $c !== $person->getCenter()))[0], + 'scopeOnRole' => $scopesCanSee, + 'scopeCanSeeConfidential' => [], + ], + ], + [], + [$period], + "period should not be visible for user having right in another scope (with multiple centers)" + ]; + + $this->entityManager->flush(); + } /** * For testing this method, we mock the authorization helper to return different Scope that a user From 779eb812b0f542a5c2ccb64dc92fc1aa18c6317c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 5 Jul 2023 21:56:50 +0200 Subject: [PATCH 243/321] Add new role to see confidential right on method AccompanyingPeriodACLAwareRepositoryInterface::findByUserAndPostalCodeOpenedAccompanyingPeriod --- .../ReassignAccompanyingPeriodController.php | 2 +- .../AccompanyingPeriodACLAwareRepository.php | 102 +++------- ...nyingPeriodACLAwareRepositoryInterface.php | 12 +- ...companyingPeriodACLAwareRepositoryTest.php | 174 +++++++++++++++++- 4 files changed, 200 insertions(+), 90 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Controller/ReassignAccompanyingPeriodController.php b/src/Bundle/ChillPersonBundle/Controller/ReassignAccompanyingPeriodController.php index fde9746d3..3e5b59c2a 100644 --- a/src/Bundle/ChillPersonBundle/Controller/ReassignAccompanyingPeriodController.php +++ b/src/Bundle/ChillPersonBundle/Controller/ReassignAccompanyingPeriodController.php @@ -98,7 +98,7 @@ class ReassignAccompanyingPeriodController extends AbstractController $userFrom = $form['user']->getData(); $postalCodes = $form['postal_code']->getData() instanceof PostalCode ? [$form['postal_code']->getData()] : []; - $total = $this->accompanyingPeriodACLAwareRepository->countByUserOpenedAccompanyingPeriod($userFrom); + $total = $this->accompanyingPeriodACLAwareRepository->countByUserAndPostalCodesOpenedAccompanyingPeriod($userFrom, $postalCodes); $paginator = $this->paginatorFactory->create($total); $paginator->setItemsPerPage(50); $periods = $this->accompanyingPeriodACLAwareRepository diff --git a/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodACLAwareRepository.php b/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodACLAwareRepository.php index e62e2b3ac..79a7710ff 100644 --- a/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodACLAwareRepository.php +++ b/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodACLAwareRepository.php @@ -14,6 +14,7 @@ namespace Chill\PersonBundle\Repository; use Chill\MainBundle\Entity\Address; use Chill\MainBundle\Entity\Center; use Chill\MainBundle\Entity\Location; +use Chill\MainBundle\Entity\PostalCode; use Chill\MainBundle\Entity\Scope; use Chill\MainBundle\Entity\User; use Chill\MainBundle\Entity\UserJob; @@ -21,12 +22,8 @@ use Chill\MainBundle\Security\Authorization\AuthorizationHelperForCurrentUserInt use Chill\MainBundle\Security\Resolver\CenterResolverManagerInterface; use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\AccompanyingPeriodParticipation; -use Chill\PersonBundle\Entity\Household\PersonHouseholdAddress; use Chill\PersonBundle\Entity\Person; use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter; -use DateTime; -use DateTimeImmutable; -use Doctrine\DBAL\Types\Types; use Doctrine\ORM\NonUniqueResultException; use Doctrine\ORM\NoResultException; use Doctrine\ORM\Query\Expr\Join; @@ -60,51 +57,33 @@ final readonly class AccompanyingPeriodACLAwareRepository implements Accompanyin $this->centerResolver = $centerResolverDispatcher; } - public function buildQueryOpenedAccompanyingCourseByUser(?User $user, array $postalCodes = []): QueryBuilder + public function buildQueryOpenedAccompanyingCourseByUserAndPostalCodes(?User $user, array $postalCodes = []): QueryBuilder { $qb = $this->accompanyingPeriodRepository->createQueryBuilder('ap'); $qb->where($qb->expr()->eq('ap.user', ':user')) ->andWhere( $qb->expr()->neq('ap.step', ':draft'), - $qb->expr()->orX( - $qb->expr()->isNull('ap.closingDate'), - $qb->expr()->gt('ap.closingDate', ':now') - ) + $qb->expr()->neq('ap.step', ':closed'), ) ->setParameter('user', $user) - ->setParameter('now', new DateTime('now')) - ->setParameter('draft', AccompanyingPeriod::STEP_DRAFT); + ->setParameter('draft', AccompanyingPeriod::STEP_DRAFT) + ->setParameter('closed', AccompanyingPeriod::STEP_CLOSED); if ([] !== $postalCodes) { - $qb->join('ap.locationHistories', 'location_history') - ->leftJoin(PersonHouseholdAddress::class, 'person_address', Join::WITH, 'IDENTITY(location_history.personLocation) = IDENTITY(person_address.person)') + $qb->join('ap.locationHistories', 'location_history', Join::WITH, 'location_history.endDate IS NULL') + ->leftJoin(Person\PersonCurrentAddress::class, 'person_address', Join::WITH, 'IDENTITY(location_history.personLocation) = IDENTITY(person_address.person)') ->join( Address::class, 'address', Join::WITH, - 'COALESCE(IDENTITY(location_history.addressLocation), IDENTITY(person_address.address)) = address.id' + 'COALESCE(IDENTITY(person_address.address), IDENTITY(location_history.addressLocation)) = address.id' ) + ->join('address.postcode', 'postcode') ->andWhere( - $qb->expr()->orX( - $qb->expr()->isNull('person_address'), - $qb->expr()->andX( - $qb->expr()->lte('person_address.validFrom', ':now'), - $qb->expr()->orX( - $qb->expr()->isNull('person_address.validTo'), - $qb->expr()->lt('person_address.validTo', ':now') - ) - ) - ) + $qb->expr()->in('postcode.code', ':postal_codes') ) - ->andWhere( - $qb->expr()->isNull('location_history.endDate') - ) - ->andWhere( - $qb->expr()->in('address.postcode', ':postal_codes') - ) - ->setParameter('now', new DateTimeImmutable('now'), Types::DATE_IMMUTABLE) - ->setParameter('postal_codes', $postalCodes); + ->setParameter('postal_codes', array_map(fn (PostalCode $postalCode) => $postalCode->getCode(), $postalCodes)); } return $qb; @@ -116,7 +95,7 @@ final readonly class AccompanyingPeriodACLAwareRepository implements Accompanyin */ public function countByUnDispatched(array $jobs, array $services, array $administrativeLocations): int { - $qb = $this->addACLByUnDispatched( + $qb = $this->addACLMultiCenterOnQuery( $this->buildQueryUnDispatched($jobs, $services, $administrativeLocations), $this->buildCenterOnScope() ); @@ -132,22 +111,12 @@ final readonly class AccompanyingPeriodACLAwareRepository implements Accompanyin return 0; } - return $this->buildQueryOpenedAccompanyingCourseByUser($user, $postalCodes) - ->select('COUNT(ap)') - ->getQuery() - ->getSingleScalarResult(); - } + $qb = $this->buildQueryOpenedAccompanyingCourseByUserAndPostalCodes($user, $postalCodes); + $qb = $this->addACLMultiCenterOnQuery($qb, $this->buildCenterOnScope(), false); - public function countByUserOpenedAccompanyingPeriod(?User $user): int - { - if (null === $user) { - return 0; - } + $qb->select('COUNT(DISTINCT ap)'); - return $this->buildQueryOpenedAccompanyingCourseByUser($user) - ->select('COUNT(ap)') - ->getQuery() - ->getSingleScalarResult(); + return $qb->getQuery()->getSingleScalarResult(); } public function findByPerson( @@ -283,7 +252,7 @@ final readonly class AccompanyingPeriodACLAwareRepository implements Accompanyin $qb = $this->buildQueryUnDispatched($jobs, $services, $administrativeAdministrativeLocations); $qb->select('ap'); - $qb = $this->addACLByUnDispatched($qb, $this->buildCenterOnScope(), false); + $qb = $this->addACLMultiCenterOnQuery($qb, $this->buildCenterOnScope(), false); $qb = $this->addOrderLimitClauses($qb, $orderBy, $limit, $offset); return $qb->getQuery()->getResult(); @@ -295,32 +264,9 @@ final readonly class AccompanyingPeriodACLAwareRepository implements Accompanyin return []; } - $qb = $this->buildQueryOpenedAccompanyingCourseByUser($user); - - $qb->setFirstResult($offset) - ->setMaxResults($limit); - - foreach ($orderBy as $field => $direction) { - $qb->addOrderBy('ap.' . $field, $direction); - } - - return $qb->getQuery()->getResult(); - } - - public function findByUserOpenedAccompanyingPeriod(?User $user, array $orderBy = [], int $limit = 0, int $offset = 50): array - { - if (null === $user) { - return []; - } - - $qb = $this->buildQueryOpenedAccompanyingCourseByUser($user); - - $qb->setFirstResult($offset) - ->setMaxResults($limit); - - foreach ($orderBy as $field => $direction) { - $qb->addOrderBy('ap.' . $field, $direction); - } + $qb = $this->buildQueryOpenedAccompanyingCourseByUserAndPostalCodes($user, $postalCodes); + $qb = $this->addACLMultiCenterOnQuery($qb, $this->buildCenterOnScope(), false); + $qb = $this->addOrderLimitClauses($qb, $orderBy, $limit, $offset); return $qb->getQuery()->getResult(); } @@ -331,7 +277,7 @@ final readonly class AccompanyingPeriodACLAwareRepository implements Accompanyin * @param bool $allowNoCenter if true, will allow to see the periods linked to person which does not have any center. Very few edge case when some Person are not associated to a center. * @return QueryBuilder */ - public function addACLByUnDispatched(QueryBuilder $qb, array $centerScopes, bool $allowNoCenter = false): QueryBuilder + public function addACLMultiCenterOnQuery(QueryBuilder $qb, array $centerScopes, bool $allowNoCenter = false): QueryBuilder { $user = $this->security->getUser(); @@ -366,9 +312,9 @@ final readonly class AccompanyingPeriodACLAwareRepository implements Accompanyin // - and the parcours is not confidential OR the user is the referrer OR the user can see the confidential course $orOnScope = $qb->expr()->orX( $qb->expr()->isMemberOf(':scope_' . $idx, 'ap.scopes'), - $qb->expr()->eq('ap.user', ':user') + $qb->expr()->eq('ap.user', ':user_executing') ); - $qb->setParameter('user', $user); + $qb->setParameter('user_executing', $user); if (in_array($scope, $scopesCanSeeConfidential, true)) { $orScopeInsideCenter->add($orOnScope); @@ -378,7 +324,7 @@ final readonly class AccompanyingPeriodACLAwareRepository implements Accompanyin $orOnScope, $qb->expr()->orX( 'ap.confidential = FALSE', - $qb->expr()->eq('ap.user', ':user') + $qb->expr()->eq('ap.user', ':user_executing') ) ); $orScopeInsideCenter->add($andXOnScope); diff --git a/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodACLAwareRepositoryInterface.php b/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodACLAwareRepositoryInterface.php index 61b631904..7b31887b9 100644 --- a/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodACLAwareRepositoryInterface.php +++ b/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodACLAwareRepositoryInterface.php @@ -31,8 +31,6 @@ interface AccompanyingPeriodACLAwareRepositoryInterface */ public function countByUserAndPostalCodesOpenedAccompanyingPeriod(?User $user, array $postalCodes): int; - public function countByUserOpenedAccompanyingPeriod(?User $user): int; - /** * @return array */ @@ -40,8 +38,8 @@ interface AccompanyingPeriodACLAwareRepositoryInterface Person $person, string $role, ?array $orderBy = [], - ?int $limit = null, - ?int $offset = null + ?int $limit = null, + ?int $offset = null ): array; /** @@ -57,10 +55,4 @@ interface AccompanyingPeriodACLAwareRepositoryInterface * @return list */ public function findByUserAndPostalCodesOpenedAccompanyingPeriod(?User $user, array $postalCodes, array $orderBy = [], int $limit = 0, int $offset = 50): array; - - /** - * @deprecated - * @return list - */ - public function findByUserOpenedAccompanyingPeriod(?User $user, array $orderBy = [], int $limit = 0, int $offset = 50): array; } diff --git a/src/Bundle/ChillPersonBundle/Tests/Repository/AccompanyingPeriodACLAwareRepositoryTest.php b/src/Bundle/ChillPersonBundle/Tests/Repository/AccompanyingPeriodACLAwareRepositoryTest.php index 90e0d2384..cb8d56ba3 100644 --- a/src/Bundle/ChillPersonBundle/Tests/Repository/AccompanyingPeriodACLAwareRepositoryTest.php +++ b/src/Bundle/ChillPersonBundle/Tests/Repository/AccompanyingPeriodACLAwareRepositoryTest.php @@ -80,7 +80,178 @@ class AccompanyingPeriodACLAwareRepositoryTest extends KernelTestCase $em->remove($period); } - $em->flush(); + //$em->flush(); + } + + /** + * @dataProvider provideDataFindByUserAndPostalCodesOpenedAccompanyingPeriod + * @param list, scopeCanSeeConfidential: list}> $centerScopes + * @param list $expectedContains + * @param list $expectedNotContains + */ + public function testFindByUserAndPostalCodesOpenedAccompanyingPeriod(User $user, User $searched, array $centerScopes, array $expectedContains, array $expectedNotContains, string $message): void + { + $security = $this->prophesize(Security::class); + $security->getUser()->willReturn($user); + + $authorizationHelper = $this->prophesize(AuthorizationHelperForCurrentUserInterface::class); + $centers = []; + + foreach ($centerScopes as ['center' => $center, 'scopeOnRole' => $scopes, 'scopeCanSeeConfidential' => $scopesCanSeeConfidential]) { + $centers[spl_object_hash($center)] = $center; + $authorizationHelper->getReachableScopes(AccompanyingPeriodVoter::SEE, $center) + ->willReturn($scopes); + $authorizationHelper->getReachableScopes(AccompanyingPeriodVoter::SEE_CONFIDENTIAL_ALL, $center) + ->willReturn($scopesCanSeeConfidential); + } + $authorizationHelper->getReachableCenters(AccompanyingPeriodVoter::SEE)->willReturn(array_values($centers)); + + $repository = new AccompanyingPeriodACLAwareRepository( + $this->accompanyingPeriodRepository, + $security->reveal(), + $authorizationHelper->reveal(), + $this->centerResolverManager + ); + + $actual = array_map( + fn (AccompanyingPeriod $period) => $period->getId(), + $repository->findByUserAndPostalCodesOpenedAccompanyingPeriod($searched, [], ['id' => 'DESC'], 20, 0) + ); + + foreach ($expectedContains as $expected) { + self::assertContains($expected->getId(), $actual, $message); + } + foreach ($expectedNotContains as $expected) { + self::assertNotContains($expected->getId(), $actual, $message); + } + } + + public function provideDataFindByUserAndPostalCodesOpenedAccompanyingPeriod(): iterable + { + $this->setUp(); + + if (null === $user = $this->entityManager->createQuery("SELECT u FROM " . User::class . " u")->setMaxResults(1)->getSingleResult()) { + throw new \RuntimeException("no user found"); + } + + if (null === $anotherUser = $this->entityManager->createQuery("SELECT u FROM " . User::class . " u WHERE u.id != :uid")->setParameter('uid', $user->getId()) + ->setMaxResults(1)->getSingleResult()) { + throw new \RuntimeException("no user found"); + } + + /** @var Person $person */ + [$person, $anotherPerson, $person2, $person3] = $this->entityManager + ->createQuery("SELECT p FROM " . Person::class . " p JOIN p.centerCurrent current_center") + ->setMaxResults(4) + ->getResult(); + + if (null === $person || null === $anotherPerson || null === $person2 || null === $person3) { + throw new \RuntimeException("no person found"); + } + + $scopes = $this->scopeRepository->findAll(); + + if (3 > count($scopes)) { + throw new \RuntimeException("not enough scopes for this test"); + } + $scopesCanSee = [ $scopes[0] ]; + $scopesGroup2 = [ $scopes[1] ]; + + $centers = $this->centerRepository->findActive(); + $aCenterNotAssociatedToPerson = array_values(array_filter($centers, fn (Center $c) => $c !== $person->getCenter()))[0]; + + if (2 > count($centers)) { + throw new \RuntimeException("not enough centers for this test"); + } + + $period = $this->buildPeriod($person, $scopesCanSee, $user, true); + $period->setUser($user); + + yield [ + $anotherUser, + $user, + [ + [ + 'center' => $person->getCenter(), + 'scopeOnRole' => $scopesCanSee, + 'scopeCanSeeConfidential' => [], + ], + ], + [$period], + [], + "period should be visible with expected scopes", + ]; + + yield [ + $anotherUser, + $user, + [ + [ + 'center' => $person->getCenter(), + 'scopeOnRole' => $scopesGroup2, + 'scopeCanSeeConfidential' => [], + ], + ], + [], + [$period], + "period should not be visible without expected scopes", + ]; + + yield [ + $anotherUser, + $user, + [ + [ + 'center' => $person->getCenter(), + 'scopeOnRole' => $scopesGroup2, + 'scopeCanSeeConfidential' => [], + ], + [ + 'center' => $aCenterNotAssociatedToPerson, + 'scopeOnRole' => $scopesCanSee, + 'scopeCanSeeConfidential' => [], + ], + ], + [], + [$period], + "period should not be visible for user having right in another scope (with multiple centers)" + ]; + + $period = $this->buildPeriod($person, $scopesCanSee, $user, true); + $period->setUser($user); + $period->setConfidential(true); + + yield [ + $anotherUser, + $user, + [ + [ + 'center' => $person->getCenter(), + 'scopeOnRole' => $scopesCanSee, + 'scopeCanSeeConfidential' => [], + ], + ], + [], + [$period], + "period confidential should not be visible", + ]; + + yield [ + $anotherUser, + $user, + [ + [ + 'center' => $person->getCenter(), + 'scopeOnRole' => $scopesCanSee, + 'scopeCanSeeConfidential' => $scopesCanSee, + ], + ], + [$period], + [], + "period confidential be visible if user has required scopes", + ]; + + $this->entityManager->flush(); } /** @@ -165,6 +336,7 @@ class AccompanyingPeriodACLAwareRepositoryTest extends KernelTestCase $period = $this->buildPeriod($person, $scopesCanSee, $user, true); + // expected scope: can see the period yield [ $anotherUser, From ff1629cbb7d6719c381d86cea6bb54d658534202 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 5 Jul 2023 22:06:21 +0200 Subject: [PATCH 244/321] Separate role "see confidential course" from "reassign bulk" --- .../DependencyInjection/ChillPersonExtension.php | 4 ---- .../Security/Authorization/AccompanyingPeriodVoter.php | 1 + src/Bundle/ChillPersonBundle/translations/messages.fr.yml | 3 ++- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php b/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php index 6fd434635..121bbba14 100644 --- a/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php +++ b/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php @@ -983,10 +983,6 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac AccompanyingPeriodVoter::EDIT, AccompanyingPeriodVoter::DELETE, ], - AccompanyingPeriodVoter::REASSIGN_BULK => [ - AccompanyingPeriodVoter::SEE_CONFIDENTIAL_ALL, - AccompanyingPeriodVoter::TOGGLE_CONFIDENTIAL_ALL, - ], AccompanyingPeriodVoter::TOGGLE_CONFIDENTIAL_ALL => [ AccompanyingPeriodVoter::SEE_CONFIDENTIAL_ALL, ], diff --git a/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php b/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php index 3dd991501..795a921e7 100644 --- a/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php +++ b/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php @@ -138,6 +138,7 @@ class AccompanyingPeriodVoter extends AbstractChillVoter implements ProvideRoleH self::TOGGLE_CONFIDENTIAL_ALL, self::REASSIGN_BULK, self::STATS, + self::SEE_CONFIDENTIAL_ALL, ]; } diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index 01383c050..635f86c99 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -329,8 +329,9 @@ CHILL_PERSON_ACCOMPANYING_PERIOD_CREATE: Créer un parcours d'accompagnement CHILL_PERSON_ACCOMPANYING_PERIOD_UPDATE: Modifier un parcours d'accompagnement CHILL_PERSON_ACCOMPANYING_PERIOD_FULL: Voir les détails, créer, supprimer et mettre à jour un parcours d'accompagnement CHILL_PERSON_ACCOMPANYING_COURSE_REASSIGN_BULK: Réassigner les parcours en lot -CHILL_PERSON_ACCOMPANYING_PERIOD_SEE_DETAILS: Voir les détails d'un parcours d'accompagnement +CHILL_PERSON_ACCOMPANYING_PERIOD_SEE_DETAILS: Voir les détails d'un parcours d'accompagnement CHILL_PERSON_ACCOMPANYING_PERIOD_STATS: Statistiques sur les parcours d'accompagnement +CHILL_PERSON_ACCOMPANYING_PERIOD_SEE_CONFIDENTIAL: Voir les parcours confidentiels CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_CREATE: Créer une action d'accompagnement CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_DELETE: Supprimer une action d'accompagnement From af4e7f1226bad8fb4e5327ddf515f7dc11a0369f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 5 Jul 2023 22:06:36 +0200 Subject: [PATCH 245/321] Add changie entry --- .changes/unreleased/Feature-20230705-220544.yaml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changes/unreleased/Feature-20230705-220544.yaml diff --git a/.changes/unreleased/Feature-20230705-220544.yaml b/.changes/unreleased/Feature-20230705-220544.yaml new file mode 100644 index 000000000..4212f7646 --- /dev/null +++ b/.changes/unreleased/Feature-20230705-220544.yaml @@ -0,0 +1,6 @@ +kind: Feature +body: Create a role "See Confidential Periods", separated from the "Reassign courses" + role +time: 2023-07-05T22:05:44.435112463+02:00 +custom: + Issue: "121" From c04fd66163f2014ac54362f56bafebca9f38e1ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 5 Jul 2023 22:20:27 +0200 Subject: [PATCH 246/321] do not show filter on job or activity type if less than 2 possibilities --- .../Controller/ActivityController.php | 39 +++++++++++-------- .../Templating/Listing/FilterOrderHelper.php | 20 ++++++++++ 2 files changed, 43 insertions(+), 16 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Controller/ActivityController.php b/src/Bundle/ChillActivityBundle/Controller/ActivityController.php index 63639c149..9b6e69bf0 100644 --- a/src/Bundle/ChillActivityBundle/Controller/ActivityController.php +++ b/src/Bundle/ChillActivityBundle/Controller/ActivityController.php @@ -259,8 +259,8 @@ final class ActivityController extends AbstractController $filterArgs = [ 'my_activities' => $filter->getSingleCheckboxData('my_activities'), - 'types' => $filter->getEntityChoiceData('activity_types'), - 'jobs' => $filter->getEntityChoiceData('jobs'), + 'types' => $filter->hasEntityChoice('activity_type') ? $filter->getEntityChoiceData('activity_types') : [], + 'jobs' => $filter->hasEntityChoice('jobs') ? $filter->getEntityChoiceData('jobs') : [], 'before' => $filter->getDateRangeData('activity_date')['to'], 'after' => $filter->getDateRangeData('activity_date')['from'], ]; @@ -327,21 +327,28 @@ final class ActivityController extends AbstractController $filterBuilder ->addDateRange('activity_date', 'activity.date') - ->addSingleCheckbox('my_activities', 'activity_filter.My activities') - ->addEntityChoice('activity_types', 'activity_filter.Types', \Chill\ActivityBundle\Entity\ActivityType::class, $types, [ - 'choice_label' => function (\Chill\ActivityBundle\Entity\ActivityType $activityType) { - $text = match ($activityType->hasCategory()) { - true => $this->translatableStringHelper->localize($activityType->getCategory()->getName()) . ' > ', - false => '', - }; + ->addSingleCheckbox('my_activities', 'activity_filter.My activities'); - return $text . $this->translatableStringHelper->localize($activityType->getName()); - } - ]) - ->addEntityChoice('jobs', 'activity_filter.Jobs', UserJob::class, $jobs, [ - 'choice_label' => fn (UserJob $u) => $this->translatableStringHelper->localize($u->getLabel()) - ]) - ; + if (1 < count($types)) { + $filterBuilder + ->addEntityChoice('activity_types', 'activity_filter.Types', \Chill\ActivityBundle\Entity\ActivityType::class, $types, [ + 'choice_label' => function (\Chill\ActivityBundle\Entity\ActivityType $activityType) { + $text = match ($activityType->hasCategory()) { + true => $this->translatableStringHelper->localize($activityType->getCategory()->getName()) . ' > ', + false => '', + }; + + return $text . $this->translatableStringHelper->localize($activityType->getName()); + } + ]); + } + + if (1 < count($jobs)) { + $filterBuilder + ->addEntityChoice('jobs', 'activity_filter.Jobs', UserJob::class, $jobs, [ + 'choice_label' => fn (UserJob $u) => $this->translatableStringHelper->localize($u->getLabel()) + ]); + } return $filterBuilder->build(); } diff --git a/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelper.php b/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelper.php index 28cc8e331..5c9971890 100644 --- a/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelper.php +++ b/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelper.php @@ -116,16 +116,31 @@ class FilterOrderHelper ->handleRequest($this->requestStack->getCurrentRequest()); } + public function hasCheckboxData(string $name): bool + { + return array_key_exists($name, $this->checkboxes); + } + public function getCheckboxData(string $name): array { return $this->getFormData()['checkboxes'][$name]; } + public function hasSingleCheckboxData(string $name): bool + { + return array_key_exists($name, $this->singleCheckbox); + } + public function getSingleCheckboxData(string $name): ?bool { return $this->getFormData()['single_checkboxes'][$name]; } + public function hasEntityChoice(string $name): bool + { + return array_key_exists($name, $this->entityChoices); + } + public function getEntityChoiceData($name): mixed { return $this->getFormData()['entity_choices'][$name]; @@ -144,6 +159,11 @@ class FilterOrderHelper return $this->singleCheckbox; } + public function hasDateRangeData(string $name): bool + { + return array_key_exists($name, $this->dateRanges); + } + /** * @return array{to: ?DateTimeImmutable, from: ?DateTimeImmutable} */ From c19232de35e72cadf0bc5978af2e8d6d79b50e8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 5 Jul 2023 22:37:51 +0200 Subject: [PATCH 247/321] DX: fix phpstan issues --- .../ChillEventBundle/Controller/ParticipationController.php | 5 ++++- src/Bundle/ChillEventBundle/Entity/Event.php | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Bundle/ChillEventBundle/Controller/ParticipationController.php b/src/Bundle/ChillEventBundle/Controller/ParticipationController.php index 1929beac1..a2a82c88f 100644 --- a/src/Bundle/ChillEventBundle/Controller/ParticipationController.php +++ b/src/Bundle/ChillEventBundle/Controller/ParticipationController.php @@ -16,6 +16,8 @@ use Chill\EventBundle\Entity\Event; use Chill\EventBundle\Entity\Participation; use Chill\EventBundle\Form\ParticipationType; use Chill\EventBundle\Security\Authorization\ParticipationVoter; +use Doctrine\Common\Collections\Collection; +use Doctrine\Common\Collections\ReadableCollection; use LogicException; use Psr\Log\LoggerInterface; use RuntimeException; @@ -509,7 +511,7 @@ class ParticipationController extends AbstractController /** * @return \Symfony\Component\Form\FormInterface */ - protected function createEditFormMultiple(ArrayIterator $participations, Event $event) + protected function createEditFormMultiple(Collection $participations, Event $event) { $form = $this->createForm( \Symfony\Component\Form\Extension\Core\Type\FormType::class, @@ -638,6 +640,7 @@ class ParticipationController extends AbstractController $ignoredParticipations = $newParticipations = []; foreach ($participations as $participation) { + /** @var Participation $participation */ // check for authorization $this->denyAccessUnlessGranted( ParticipationVoter::CREATE, diff --git a/src/Bundle/ChillEventBundle/Entity/Event.php b/src/Bundle/ChillEventBundle/Entity/Event.php index d55a7b8a8..cc762e979 100644 --- a/src/Bundle/ChillEventBundle/Entity/Event.php +++ b/src/Bundle/ChillEventBundle/Entity/Event.php @@ -160,11 +160,11 @@ class Event implements HasCenterInterface, HasScopeInterface } /** - * @return ArrayIterator|Collection|Traversable + * @return Collection */ public function getParticipations() { - return $this->getParticipationsOrdered(); + return new ArrayCollection(iterator_to_array($this->getParticipationsOrdered())); } /** From 20d5fabc1876e65ca07ffb18b1cfa477ae1fc2c4 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Thu, 6 Jul 2023 13:39:08 +0200 Subject: [PATCH 248/321] [repository][action filter] integrating filters in repository --- .../AccompanyingCourseWorkController.php | 4 +- .../AccompanyingPeriodWorkRepository.php | 58 ++++++++++++++++++- 2 files changed, 58 insertions(+), 4 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseWorkController.php b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseWorkController.php index 1f2680f9e..c56489afd 100644 --- a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseWorkController.php +++ b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseWorkController.php @@ -161,7 +161,7 @@ class AccompanyingCourseWorkController extends AbstractController 'types' => $filter->getEntityChoiceData('typesFilter'), 'before' => $filter->getDateRangeData('dateFilter')['to'], 'after' => $filter->getDateRangeData('dateFilter')['from'], - 'user' => $filter->getUserPickerData('userFilter') + 'users' => $filter->getUserPickerData('userFilter') ]; $totalItems = $this->workRepository->countByAccompanyingPeriod($period); @@ -219,7 +219,7 @@ class AccompanyingCourseWorkController extends AbstractController { $filterBuilder = $this->filterOrderHelperFactory->create(self::class); - $types = $this->workRepository->findByAccompanyingPeriod($associatedPeriod); + $types = $this->workRepository->findActionTypeByPeriod($associatedPeriod); $filterBuilder ->addDateRange('dateFilter', 'accompanying_course_work.date_filter') diff --git a/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/AccompanyingPeriodWorkRepository.php b/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/AccompanyingPeriodWorkRepository.php index 60a00e12a..a5e27afd5 100644 --- a/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/AccompanyingPeriodWorkRepository.php +++ b/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/AccompanyingPeriodWorkRepository.php @@ -108,8 +108,32 @@ final class AccompanyingPeriodWorkRepository implements ObjectRepository CASE WHEN enddate IS NULL THEN '-infinity'::timestamp ELSE 'infinity'::timestamp END ASC, startdate DESC, enddate DESC, - id DESC - LIMIT :limit OFFSET :offset"; + id DESC"; + + // implement filters + + if([] !== ($filters['types'] ?? [])) + { + $sql .= "AND WHERE w.socialAction IN (:types)"; + } + + if([] !== ($filters['users'] ?? [])) + { + $sql .= "AND WHERE w.createdBy IN (:users)"; + + foreach ($filters['users'] as $key => $user) { + $sql .= "OR :user_" . $key . " IN w.referrers)"; + + $nq = $this->em->createNativeQuery($sql, $rsm) + ->setParameter(':user_' . $key); + } + + // ... to be continued + } + + // set limit and offset + + $sql .= " LIMIT :limit OFFSET :offset"; $nq = $this->em->createNativeQuery($sql, $rsm) ->setParameter('periodId', $period->getId(), Types::INTEGER) @@ -119,6 +143,36 @@ final class AccompanyingPeriodWorkRepository implements ObjectRepository return $nq->getResult(); } + /** + * Return a list of types of social actions associated to the accompanying period + * + * @return array + */ + public function findActionTypeByPeriod(AccompanyingPeriod $period): array + { + $in = $this->em->createQueryBuilder(); + $in + ->select('1') + ->from(AccompanyingPeriodWork::class, 'apw'); + + + $in->andWhere('apw.accompanyingPeriod = :period')->setParameter('period', $period); + + + // join between the embedded exist query and the main query + $in->andWhere('apw.socialAction = sa'); + + $qb = $this->em->createQueryBuilder()->setParameters($in->getParameters()); + $qb + ->select('sa') + ->from(SocialAction::class, 'sa') + ->where( + $qb->expr()->exists($in->getDQL()) + ); + + return $qb->getQuery()->getResult(); + } + public function findNearEndDateByUser(User $user, DateTimeImmutable $since, DateTimeImmutable $until, int $limit = 20, int $offset = 0): array { return $this->buildQueryNearEndDateByUser($user, $since, $until) From cc97199c5deceb7c98bca0af26c659a9b5ea149d Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Thu, 6 Jul 2023 13:40:25 +0200 Subject: [PATCH 249/321] DX added changie --- .changes/unreleased/Feature-20230706-134010.yaml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changes/unreleased/Feature-20230706-134010.yaml diff --git a/.changes/unreleased/Feature-20230706-134010.yaml b/.changes/unreleased/Feature-20230706-134010.yaml new file mode 100644 index 000000000..73a0727fc --- /dev/null +++ b/.changes/unreleased/Feature-20230706-134010.yaml @@ -0,0 +1,5 @@ +kind: Feature +body: Adding OrderFilter to the list of social actions. +time: 2023-07-06T13:40:10.339001208+02:00 +custom: + Issue: "120" From 5b42b85b503c23eda24d5c774d05f4524fc70a72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 6 Jul 2023 16:58:24 +0200 Subject: [PATCH 250/321] Read absence from MS graph api --- .../Exception/UserAbsenceSyncException.php | 20 ++ .../Connector/MSGraph/MSUserAbsenceReader.php | 68 +++++++ .../MSGraph/MSUserAbsenceReaderTest.php | 176 ++++++++++++++++++ 3 files changed, 264 insertions(+) create mode 100644 src/Bundle/ChillCalendarBundle/Exception/UserAbsenceSyncException.php create mode 100644 src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MSUserAbsenceReader.php create mode 100644 src/Bundle/ChillCalendarBundle/Tests/RemoteCalendar/Connector/MSGraph/MSUserAbsenceReaderTest.php diff --git a/src/Bundle/ChillCalendarBundle/Exception/UserAbsenceSyncException.php b/src/Bundle/ChillCalendarBundle/Exception/UserAbsenceSyncException.php new file mode 100644 index 000000000..b46c93976 --- /dev/null +++ b/src/Bundle/ChillCalendarBundle/Exception/UserAbsenceSyncException.php @@ -0,0 +1,20 @@ +mapCalendarToUser->getUserId($user); + + if (null === $id) { + return null; + } + + try { + $automaticRepliesSettings = $this->machineHttpClient + ->request('GET', '/users/' . $id . '/mailboxSettings/automaticRepliesSetting') + ->toArray(true); + } catch (ClientExceptionInterface|DecodingExceptionInterface|RedirectionExceptionInterface|TransportExceptionInterface $e) { + throw new UserAbsenceSyncException("Error receiving response for mailboxSettings", 0, $e); + } catch (ServerExceptionInterface $e) { + throw new UserAbsenceSyncException("Server error receiving response for mailboxSettings", 0, $e); + } + + if (!array_key_exists("status", $automaticRepliesSettings)) { + throw new \LogicException("no key \"status\" on automatic replies settings: " . json_encode($automaticRepliesSettings)); + } + + return match ($automaticRepliesSettings['status']) { + 'disabled' => false, + 'alwaysEnabled' => true, + 'scheduled' => + RemoteEventConverter::convertStringDateWithoutTimezone($automaticRepliesSettings['scheduledStartDateTime']['dateTime']) < $this->clock->now() + && RemoteEventConverter::convertStringDateWithoutTimezone($automaticRepliesSettings['scheduledEndDateTime']['dateTime']) > $this->clock->now(), + default => throw new UserAbsenceSyncException("this status is not documented by Microsoft") + }; + } + +} diff --git a/src/Bundle/ChillCalendarBundle/Tests/RemoteCalendar/Connector/MSGraph/MSUserAbsenceReaderTest.php b/src/Bundle/ChillCalendarBundle/Tests/RemoteCalendar/Connector/MSGraph/MSUserAbsenceReaderTest.php new file mode 100644 index 000000000..089477fda --- /dev/null +++ b/src/Bundle/ChillCalendarBundle/Tests/RemoteCalendar/Connector/MSGraph/MSUserAbsenceReaderTest.php @@ -0,0 +1,176 @@ +prophesize(MapCalendarToUser::class); + $mapUser->getUserId($user)->willReturn('1234'); + $clock = new MockClock(new \DateTimeImmutable('2023-07-07T12:00:00')); + + $absenceReader = new MSUserAbsenceReader($client, $mapUser->reveal(), $clock); + + self::assertEquals($expected, $absenceReader->isUserAbsent($user), $message); + } + + public function testIsUserAbsentWithoutRemoteId(): void + { + $user = new User(); + $client = new MockHttpClient(); + + $mapUser = $this->prophesize(MapCalendarToUser::class); + $mapUser->getUserId($user)->willReturn(null); + $clock = new MockClock(new \DateTimeImmutable('2023-07-07T12:00:00')); + + $absenceReader = new MSUserAbsenceReader($client, $mapUser->reveal(), $clock); + + self::assertNull($absenceReader->isUserAbsent($user), "when no user found, absence should be null"); + } + + public function provideDataTestUserAbsence(): iterable + { + // contains data that was retrieved from microsoft graph api on 2023-07-06 + + yield [ + <<<'JSON' + { + "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users('4feb0ae3-7ffb-48dd-891e-c86b2cdeefd4')/mailboxSettings/automaticRepliesSetting", + "status": "disabled", + "externalAudience": "none", + "internalReplyMessage": "Je suis en congé.", + "externalReplyMessage": "", + "scheduledStartDateTime": { + "dateTime": "2023-07-06T12:00:00.0000000", + "timeZone": "UTC" + }, + "scheduledEndDateTime": { + "dateTime": "2023-07-07T12:00:00.0000000", + "timeZone": "UTC" + } + } + JSON, + false, + "User is present" + ]; + + yield [ + <<<'JSON' + { + "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users('4feb0ae3-7ffb-48dd-891e-c86b2cdeefd4')/mailboxSettings/automaticRepliesSetting", + "status": "scheduled", + "externalAudience": "none", + "internalReplyMessage": "Je suis en congé.", + "externalReplyMessage": "", + "scheduledStartDateTime": { + "dateTime": "2023-07-06T11:00:00.0000000", + "timeZone": "UTC" + }, + "scheduledEndDateTime": { + "dateTime": "2023-07-21T11:00:00.0000000", + "timeZone": "UTC" + } + } + JSON, + true, + 'User is absent with absence scheduled, we are within this period' + ]; + + yield [ + <<<'JSON' + { + "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users('4feb0ae3-7ffb-48dd-891e-c86b2cdeefd4')/mailboxSettings/automaticRepliesSetting", + "status": "scheduled", + "externalAudience": "none", + "internalReplyMessage": "Je suis en congé.", + "externalReplyMessage": "", + "scheduledStartDateTime": { + "dateTime": "2023-07-08T11:00:00.0000000", + "timeZone": "UTC" + }, + "scheduledEndDateTime": { + "dateTime": "2023-07-21T11:00:00.0000000", + "timeZone": "UTC" + } + } + JSON, + false, + 'User is present: absence is scheduled for later' + ]; + + yield [ + <<<'JSON' + { + "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users('4feb0ae3-7ffb-48dd-891e-c86b2cdeefd4')/mailboxSettings/automaticRepliesSetting", + "status": "scheduled", + "externalAudience": "none", + "internalReplyMessage": "Je suis en congé.", + "externalReplyMessage": "", + "scheduledStartDateTime": { + "dateTime": "2023-07-05T11:00:00.0000000", + "timeZone": "UTC" + }, + "scheduledEndDateTime": { + "dateTime": "2023-07-06T11:00:00.0000000", + "timeZone": "UTC" + } + } + JSON, + false, + 'User is present: absence is past' + ]; + + yield [ + <<<'JSON' + { + "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users('4feb0ae3-7ffb-48dd-891e-c86b2cdeefd4')/mailboxSettings/automaticRepliesSetting", + "status": "alwaysEnabled", + "externalAudience": "none", + "internalReplyMessage": "Je suis en congé.", + "externalReplyMessage": "", + "scheduledStartDateTime": { + "dateTime": "2023-07-06T12:00:00.0000000", + "timeZone": "UTC" + }, + "scheduledEndDateTime": { + "dateTime": "2023-07-07T12:00:00.0000000", + "timeZone": "UTC" + } + } + JSON, + true, + "User is absent: absence is always enabled" + ]; + } + +} From 2861945a5251ed77d50bfe5a8e1fc6083234ba6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 6 Jul 2023 17:29:10 +0200 Subject: [PATCH 251/321] Syncer for user absence, from the msgraph reader --- .../Exception/UserAbsenceSyncException.php | 4 +- .../Connector/MSGraph/MSUserAbsenceReader.php | 2 +- .../MSGraph/MSUserAbsenceReaderInterface.php | 22 ++++++ .../Connector/MSGraph/MSUserAbsenceSync.php | 44 ++++++++++++ .../MSGraph/MSUserAbsenceSyncTest.php | 67 +++++++++++++++++++ 5 files changed, 136 insertions(+), 3 deletions(-) create mode 100644 src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MSUserAbsenceReaderInterface.php create mode 100644 src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MSUserAbsenceSync.php create mode 100644 src/Bundle/ChillCalendarBundle/Tests/RemoteCalendar/Connector/MSGraph/MSUserAbsenceSyncTest.php diff --git a/src/Bundle/ChillCalendarBundle/Exception/UserAbsenceSyncException.php b/src/Bundle/ChillCalendarBundle/Exception/UserAbsenceSyncException.php index b46c93976..558774fc5 100644 --- a/src/Bundle/ChillCalendarBundle/Exception/UserAbsenceSyncException.php +++ b/src/Bundle/ChillCalendarBundle/Exception/UserAbsenceSyncException.php @@ -13,8 +13,8 @@ namespace Chill\CalendarBundle\Exception; class UserAbsenceSyncException extends \LogicException { - public function __construct(string $message = "", int $code = 20230706) + public function __construct(string $message = "", int $code = 20230706, ?\Throwable $previous = null) { - parent::__construct($message, $code); + parent::__construct($message, $code, $previous); } } diff --git a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MSUserAbsenceReader.php b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MSUserAbsenceReader.php index b79a55052..83376528f 100644 --- a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MSUserAbsenceReader.php +++ b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MSUserAbsenceReader.php @@ -21,7 +21,7 @@ use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface; use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; use Symfony\Contracts\HttpClient\HttpClientInterface; -readonly class MSUserAbsenceReader +final readonly class MSUserAbsenceReader implements MSUserAbsenceReaderInterface { public function __construct( private HttpClientInterface $machineHttpClient, diff --git a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MSUserAbsenceReaderInterface.php b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MSUserAbsenceReaderInterface.php new file mode 100644 index 000000000..a918bb7ea --- /dev/null +++ b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MSUserAbsenceReaderInterface.php @@ -0,0 +1,22 @@ +absenceReader->isUserAbsent($user); + + if (null === $absence) { + return; + } + + if ($absence === $user->isAbsent()) { + // nothing to do + return; + } + + if ($absence) { + $user->setAbsenceStart($this->clock->now()); + } else { + $user->setAbsenceStart(null); + } + } +} diff --git a/src/Bundle/ChillCalendarBundle/Tests/RemoteCalendar/Connector/MSGraph/MSUserAbsenceSyncTest.php b/src/Bundle/ChillCalendarBundle/Tests/RemoteCalendar/Connector/MSGraph/MSUserAbsenceSyncTest.php new file mode 100644 index 000000000..ddd92086d --- /dev/null +++ b/src/Bundle/ChillCalendarBundle/Tests/RemoteCalendar/Connector/MSGraph/MSUserAbsenceSyncTest.php @@ -0,0 +1,67 @@ +prophesize(MSUserAbsenceReaderInterface::class); + $userAbsenceReader->isUserAbsent($user)->willReturn($absenceFromMicrosoft); + + $clock = new MockClock(new \DateTimeImmutable('2023-07-01T12:00:00')); + + $syncer = new MSUserAbsenceSync($userAbsenceReader->reveal(), $clock); + + $syncer->syncUserAbsence($user); + + self::assertEquals($expectedAbsence, $user->isAbsent(), $message); + self::assertEquals($expectedAbsenceStart, $user->getAbsenceStart(), $message); + } + + public function provideDataTestSyncUserAbsence(): iterable + { + yield [new User(), false, false, null, "user present remains present"]; + yield [new User(), true, true, new \DateTimeImmutable('2023-07-01T12:00:00'), "user present becomes absent"]; + + $user = new User(); + $user->setAbsenceStart($abs = new \DateTimeImmutable("2023-07-01T12:00:00")); + yield [$user, true, true, $abs, "user absent remains absent"]; + + $user = new User(); + $user->setAbsenceStart($abs = new \DateTimeImmutable("2023-07-01T12:00:00")); + yield [$user, false, false, null, "user absent becomes present"]; + + yield [new User(), null, false, null, "user not syncable: presence do not change"]; + + $user = new User(); + $user->setAbsenceStart($abs = new \DateTimeImmutable("2023-07-01T12:00:00")); + yield [$user, null, true, $abs, "user not syncable: absence do not change"]; + } +} From 77d4b13c1bab2624a9b28c016f522486f859abb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 6 Jul 2023 21:33:01 +0200 Subject: [PATCH 252/321] Sync user absence / presence within MapAndSubscribeUserCalendarCommand --- .../MapAndSubscribeUserCalendarCommand.php | 182 ++++++++++-------- .../MSGraph/MSGraphUserRepository.php | 2 +- .../Connector/MSGraph/MSUserAbsenceReader.php | 3 +- .../Connector/MSGraph/MSUserAbsenceSync.php | 6 + .../MSGraph/MSUserAbsenceSyncTest.php | 3 +- 5 files changed, 109 insertions(+), 87 deletions(-) diff --git a/src/Bundle/ChillCalendarBundle/Command/MapAndSubscribeUserCalendarCommand.php b/src/Bundle/ChillCalendarBundle/Command/MapAndSubscribeUserCalendarCommand.php index b90fb83d4..193b04934 100644 --- a/src/Bundle/ChillCalendarBundle/Command/MapAndSubscribeUserCalendarCommand.php +++ b/src/Bundle/ChillCalendarBundle/Command/MapAndSubscribeUserCalendarCommand.php @@ -18,9 +18,12 @@ declare(strict_types=1); namespace Chill\CalendarBundle\Command; +use Chill\CalendarBundle\Exception\UserAbsenceSyncException; use Chill\CalendarBundle\RemoteCalendar\Connector\MSGraph\EventsOnUserSubscriptionCreator; use Chill\CalendarBundle\RemoteCalendar\Connector\MSGraph\MapCalendarToUser; use Chill\CalendarBundle\RemoteCalendar\Connector\MSGraph\MSGraphUserRepository; +use Chill\CalendarBundle\RemoteCalendar\Connector\MSGraph\MSUserAbsenceSync; +use Chill\MainBundle\Repository\UserRepositoryInterface; use DateInterval; use DateTimeImmutable; use Doctrine\ORM\EntityManagerInterface; @@ -30,32 +33,17 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; -class MapAndSubscribeUserCalendarCommand extends Command +final class MapAndSubscribeUserCalendarCommand extends Command { - private EntityManagerInterface $em; - - private EventsOnUserSubscriptionCreator $eventsOnUserSubscriptionCreator; - - private LoggerInterface $logger; - - private MapCalendarToUser $mapCalendarToUser; - - private MSGraphUserRepository $userRepository; - public function __construct( - EntityManagerInterface $em, - EventsOnUserSubscriptionCreator $eventsOnUserSubscriptionCreator, - LoggerInterface $logger, - MapCalendarToUser $mapCalendarToUser, - MSGraphUserRepository $userRepository + private readonly EntityManagerInterface $em, + private readonly EventsOnUserSubscriptionCreator $eventsOnUserSubscriptionCreator, + private readonly LoggerInterface $logger, + private readonly MapCalendarToUser $mapCalendarToUser, + private readonly UserRepositoryInterface $userRepository, + private readonly MSUserAbsenceSync $userAbsenceSync, ) { parent::__construct('chill:calendar:msgraph-user-map-subscribe'); - - $this->em = $em; - $this->eventsOnUserSubscriptionCreator = $eventsOnUserSubscriptionCreator; - $this->logger = $logger; - $this->mapCalendarToUser = $mapCalendarToUser; - $this->userRepository = $userRepository; } public function execute(InputInterface $input, OutputInterface $output): int @@ -67,83 +55,109 @@ class MapAndSubscribeUserCalendarCommand extends Command /** @var DateInterval $interval the interval before the end of the expiration */ $interval = new DateInterval('P1D'); $expiration = (new DateTimeImmutable('now'))->add(new DateInterval($input->getOption('subscription-duration'))); - $total = $this->userRepository->countByMostOldSubscriptionOrWithoutSubscriptionOrData($interval); + $users = $this->userRepository->findAllAsArray('fr'); $created = 0; $renewed = 0; - $this->logger->info(self::class . ' the number of user to get - renew', [ - 'total' => $total, + $this->logger->info(self::class . ' start user to get - renew', [ 'expiration' => $expiration->format(DateTimeImmutable::ATOM), ]); - while ($offset < $total) { - $users = $this->userRepository->findByMostOldSubscriptionOrWithoutSubscriptionOrData( - $interval, - $limit, - $offset - ); + foreach ($users as $u) { + ++$offset; - foreach ($users as $user) { - if (!$this->mapCalendarToUser->hasUserId($user)) { - $this->mapCalendarToUser->writeMetadata($user); - } - - if ($this->mapCalendarToUser->hasUserId($user)) { - // we first try to renew an existing subscription, if any. - // if not, or if it fails, we try to create a new one - if ($this->mapCalendarToUser->hasActiveSubscription($user)) { - $this->logger->debug(self::class . ' renew a subscription for', [ - 'userId' => $user->getId(), - 'username' => $user->getUsernameCanonical(), - ]); - - ['secret' => $secret, 'id' => $id, 'expiration' => $expirationTs] - = $this->eventsOnUserSubscriptionCreator->renewSubscriptionForUser($user, $expiration); - $this->mapCalendarToUser->writeSubscriptionMetadata($user, $expirationTs, $id, $secret); - - if (0 !== $expirationTs) { - ++$renewed; - } else { - $this->logger->warning(self::class . ' could not renew subscription for a user', [ - 'userId' => $user->getId(), - 'username' => $user->getUsernameCanonical(), - ]); - } - } - - if (!$this->mapCalendarToUser->hasActiveSubscription($user)) { - $this->logger->debug(self::class . ' create a subscription for', [ - 'userId' => $user->getId(), - 'username' => $user->getUsernameCanonical(), - ]); - - ['secret' => $secret, 'id' => $id, 'expiration' => $expirationTs] - = $this->eventsOnUserSubscriptionCreator->createSubscriptionForUser($user, $expiration); - $this->mapCalendarToUser->writeSubscriptionMetadata($user, $expirationTs, $id, $secret); - - if (0 !== $expirationTs) { - ++$created; - } else { - $this->logger->warning(self::class . ' could not create subscription for a user', [ - 'userId' => $user->getId(), - 'username' => $user->getUsernameCanonical(), - ]); - } - } - } - - ++$offset; + if (false === $u['enabled']) { + continue; } - $this->em->flush(); - $this->em->clear(); + $user = $this->userRepository->find($u['id']); + + if (null === $user) { + $this->logger->error("could not find user by id", ['uid' => $u['id']]); + $output->writeln("could not find user by id : " . $u['id']); + continue; + } + + if (!$this->mapCalendarToUser->hasUserId($user)) { + $user = $this->mapCalendarToUser->writeMetadata($user); + + // if user still does not have userid, continue + if (!$this->mapCalendarToUser->hasUserId($user)) { + $this->logger->warning("user does not have a counterpart on ms api", ['userId' => $user->getId(), 'email' => $user->getEmail()]); + $output->writeln(sprintf("giving up for user with email %s and id %s", $user->getEmail(), $user->getId())); + + continue; + } + } + + // sync user absence + try { + $this->userAbsenceSync->syncUserAbsence($user); + } catch (UserAbsenceSyncException $e) { + $this->logger->error("could not sync user absence", ['userId' => $user->getId(), 'email' => $user->getEmail(), 'exception' => $e->getTraceAsString(), "message" => $e->getMessage()]); + $output->writeln(sprintf("Could not sync user absence: id: %s and email: %s", $user->getId(), $user->getEmail())); + throw $e; + } + + // we first try to renew an existing subscription, if any. + // if not, or if it fails, we try to create a new one + if ($this->mapCalendarToUser->hasActiveSubscription($user)) { + $this->logger->debug(self::class . ' renew a subscription for', [ + 'userId' => $user->getId(), + 'username' => $user->getUsernameCanonical(), + ]); + + ['secret' => $secret, 'id' => $id, 'expiration' => $expirationTs] + = $this->eventsOnUserSubscriptionCreator->renewSubscriptionForUser($user, $expiration); + $this->mapCalendarToUser->writeSubscriptionMetadata($user, $expirationTs, $id, $secret); + + if (0 !== $expirationTs) { + ++$renewed; + } else { + $this->logger->warning(self::class . ' could not renew subscription for a user', [ + 'userId' => $user->getId(), + 'username' => $user->getUsernameCanonical(), + ]); + } + } + + if (!$this->mapCalendarToUser->hasActiveSubscription($user)) { + $this->logger->debug(self::class . ' create a subscription for', [ + 'userId' => $user->getId(), + 'username' => $user->getUsernameCanonical(), + ]); + + ['secret' => $secret, 'id' => $id, 'expiration' => $expirationTs] + = $this->eventsOnUserSubscriptionCreator->createSubscriptionForUser($user, $expiration); + $this->mapCalendarToUser->writeSubscriptionMetadata($user, $expirationTs, $id, $secret); + + if (0 !== $expirationTs) { + ++$created; + } else { + $this->logger->warning(self::class . ' could not create subscription for a user', [ + 'userId' => $user->getId(), + 'username' => $user->getUsernameCanonical(), + ]); + } + } + + + if (0 === $offset % $limit) { + $this->em->flush(); + $this->em->clear(); + } } + $this->em->flush(); + $this->em->clear(); + $this->logger->warning(self::class . ' process executed', [ 'created' => $created, 'renewed' => $renewed, ]); + $output->writeln("users synchronized"); + return 0; } @@ -152,7 +166,7 @@ class MapAndSubscribeUserCalendarCommand extends Command parent::configure(); $this - ->setDescription('MSGraph: collect user metadata and create subscription on events for users') + ->setDescription('MSGraph: collect user metadata and create subscription on events for users, and sync the user absence-presence') ->addOption( 'renew-before-end-interval', 'r', diff --git a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MSGraphUserRepository.php b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MSGraphUserRepository.php index c523a1e92..ae822669c 100644 --- a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MSGraphUserRepository.php +++ b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MSGraphUserRepository.php @@ -65,7 +65,7 @@ class MSGraphUserRepository } /** - * @return array|User[] + * @return array */ public function findByMostOldSubscriptionOrWithoutSubscriptionOrData(DateInterval $interval, int $limit = 50, int $offset = 0): array { diff --git a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MSUserAbsenceReader.php b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MSUserAbsenceReader.php index 83376528f..0e756c194 100644 --- a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MSUserAbsenceReader.php +++ b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MSUserAbsenceReader.php @@ -13,6 +13,7 @@ namespace Chill\CalendarBundle\RemoteCalendar\Connector\MSGraph; use Chill\CalendarBundle\Exception\UserAbsenceSyncException; use Chill\MainBundle\Entity\User; +use Psr\Log\LoggerInterface; use Symfony\Component\Clock\ClockInterface; use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface; use Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface; @@ -43,7 +44,7 @@ final readonly class MSUserAbsenceReader implements MSUserAbsenceReaderInterface try { $automaticRepliesSettings = $this->machineHttpClient - ->request('GET', '/users/' . $id . '/mailboxSettings/automaticRepliesSetting') + ->request('GET', 'users/' . $id . '/mailboxSettings/automaticRepliesSetting') ->toArray(true); } catch (ClientExceptionInterface|DecodingExceptionInterface|RedirectionExceptionInterface|TransportExceptionInterface $e) { throw new UserAbsenceSyncException("Error receiving response for mailboxSettings", 0, $e); diff --git a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MSUserAbsenceSync.php b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MSUserAbsenceSync.php index aaa06a64b..10bf21b9b 100644 --- a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MSUserAbsenceSync.php +++ b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MSUserAbsenceSync.php @@ -12,6 +12,7 @@ declare(strict_types=1); namespace Chill\CalendarBundle\RemoteCalendar\Connector\MSGraph; use Chill\MainBundle\Entity\User; +use Psr\Log\LoggerInterface; use Symfony\Component\Clock\ClockInterface; readonly class MSUserAbsenceSync @@ -19,6 +20,7 @@ readonly class MSUserAbsenceSync public function __construct( private MSUserAbsenceReaderInterface $absenceReader, private ClockInterface $clock, + private LoggerInterface $logger, ) { } @@ -35,9 +37,13 @@ readonly class MSUserAbsenceSync return; } + $this->logger->info("will change user absence", ['userId' => $user->getId()]); + if ($absence) { + $this->logger->debug("make user absent", ['userId' => $user->getId()]); $user->setAbsenceStart($this->clock->now()); } else { + $this->logger->debug("make user present", ['userId' => $user->getId()]); $user->setAbsenceStart(null); } } diff --git a/src/Bundle/ChillCalendarBundle/Tests/RemoteCalendar/Connector/MSGraph/MSUserAbsenceSyncTest.php b/src/Bundle/ChillCalendarBundle/Tests/RemoteCalendar/Connector/MSGraph/MSUserAbsenceSyncTest.php index ddd92086d..1b0f1e416 100644 --- a/src/Bundle/ChillCalendarBundle/Tests/RemoteCalendar/Connector/MSGraph/MSUserAbsenceSyncTest.php +++ b/src/Bundle/ChillCalendarBundle/Tests/RemoteCalendar/Connector/MSGraph/MSUserAbsenceSyncTest.php @@ -17,6 +17,7 @@ use Chill\CalendarBundle\RemoteCalendar\Connector\MSGraph\MSUserAbsenceSync; use Chill\MainBundle\Entity\User; use PHPUnit\Framework\TestCase; use Prophecy\PhpUnit\ProphecyTrait; +use Psr\Log\NullLogger; use Symfony\Component\Clock\MockClock; /** @@ -37,7 +38,7 @@ class MSUserAbsenceSyncTest extends TestCase $clock = new MockClock(new \DateTimeImmutable('2023-07-01T12:00:00')); - $syncer = new MSUserAbsenceSync($userAbsenceReader->reveal(), $clock); + $syncer = new MSUserAbsenceSync($userAbsenceReader->reveal(), $clock, new NullLogger()); $syncer->syncUserAbsence($user); From 9b6e6ec20f6bf425245de6f1f08a21e46b7d4eae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 6 Jul 2023 21:34:43 +0200 Subject: [PATCH 253/321] add a changie --- .changes/unreleased/Feature-20230706-213428.yaml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changes/unreleased/Feature-20230706-213428.yaml diff --git a/.changes/unreleased/Feature-20230706-213428.yaml b/.changes/unreleased/Feature-20230706-213428.yaml new file mode 100644 index 000000000..092e5a2e0 --- /dev/null +++ b/.changes/unreleased/Feature-20230706-213428.yaml @@ -0,0 +1,5 @@ +kind: Feature +body: 'Sync user absence / presence through microsoft outlook / graph api. ' +time: 2023-07-06T21:34:28.973144334+02:00 +custom: + Issue: "124" From 93a598b5497339590a4936b5dae4036082d04de6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 6 Jul 2023 21:45:29 +0200 Subject: [PATCH 254/321] improve php applying rector rules --- .../ChillCalendarBundle/Exception/UserAbsenceSyncException.php | 2 +- .../RemoteCalendar/Connector/MSGraph/MSUserAbsenceReader.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Bundle/ChillCalendarBundle/Exception/UserAbsenceSyncException.php b/src/Bundle/ChillCalendarBundle/Exception/UserAbsenceSyncException.php index 558774fc5..a5e5a679a 100644 --- a/src/Bundle/ChillCalendarBundle/Exception/UserAbsenceSyncException.php +++ b/src/Bundle/ChillCalendarBundle/Exception/UserAbsenceSyncException.php @@ -13,7 +13,7 @@ namespace Chill\CalendarBundle\Exception; class UserAbsenceSyncException extends \LogicException { - public function __construct(string $message = "", int $code = 20230706, ?\Throwable $previous = null) + public function __construct(string $message = "", int $code = 20_230_706, ?\Throwable $previous = null) { parent::__construct($message, $code, $previous); } diff --git a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MSUserAbsenceReader.php b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MSUserAbsenceReader.php index 0e756c194..c70072a47 100644 --- a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MSUserAbsenceReader.php +++ b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MSUserAbsenceReader.php @@ -53,7 +53,7 @@ final readonly class MSUserAbsenceReader implements MSUserAbsenceReaderInterface } if (!array_key_exists("status", $automaticRepliesSettings)) { - throw new \LogicException("no key \"status\" on automatic replies settings: " . json_encode($automaticRepliesSettings)); + throw new \LogicException("no key \"status\" on automatic replies settings: " . json_encode($automaticRepliesSettings, JSON_THROW_ON_ERROR)); } return match ($automaticRepliesSettings['status']) { From d3251075e978331ed9b003d223e83bd95f2f8fc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 6 Jul 2023 21:55:29 +0200 Subject: [PATCH 255/321] fix loading of kernel if ms calendar is not created --- .../MSGraph/MSGraphUserRepository.php | 84 ------------------- .../RemoteCalendarCompilerPass.php | 16 ++-- 2 files changed, 6 insertions(+), 94 deletions(-) delete mode 100644 src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MSGraphUserRepository.php diff --git a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MSGraphUserRepository.php b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MSGraphUserRepository.php deleted file mode 100644 index ae822669c..000000000 --- a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MSGraphUserRepository.php +++ /dev/null @@ -1,84 +0,0 @@ -'msgraph' ?? 'subscription_events_expiration' - OR (attributes->'msgraph' ?? 'subscription_events_expiration' AND (attributes->'msgraph'->>'subscription_events_expiration')::int < EXTRACT(EPOCH FROM (NOW() + :interval::interval))) - LIMIT :limit OFFSET :offset - ; - SQL; - - private EntityManagerInterface $entityManager; - - public function __construct(EntityManagerInterface $entityManager) - { - $this->entityManager = $entityManager; - } - - public function countByMostOldSubscriptionOrWithoutSubscriptionOrData(DateInterval $interval): int - { - $rsm = new ResultSetMapping(); - $rsm->addScalarResult('c', 'c'); - - $sql = strtr(self::MOST_OLD_SUBSCRIPTION_OR_ANY_MS_GRAPH, [ - '{select}' => 'COUNT(u) AS c', - 'LIMIT :limit OFFSET :offset' => '', - ]); - - return $this->entityManager->createNativeQuery($sql, $rsm)->setParameters([ - 'interval' => $interval, - ])->getSingleScalarResult(); - } - - /** - * @return array - */ - public function findByMostOldSubscriptionOrWithoutSubscriptionOrData(DateInterval $interval, int $limit = 50, int $offset = 0): array - { - $rsm = new ResultSetMappingBuilder($this->entityManager); - $rsm->addRootEntityFromClassMetadata(User::class, 'u'); - - return $this->entityManager->createNativeQuery( - strtr(self::MOST_OLD_SUBSCRIPTION_OR_ANY_MS_GRAPH, ['{select}' => $rsm->generateSelectClause()]), - $rsm - )->setParameters([ - 'interval' => $interval, - 'limit' => $limit, - 'offset' => $offset, - ])->getResult(); - } -} diff --git a/src/Bundle/ChillCalendarBundle/RemoteCalendar/DependencyInjection/RemoteCalendarCompilerPass.php b/src/Bundle/ChillCalendarBundle/RemoteCalendar/DependencyInjection/RemoteCalendarCompilerPass.php index f56735de7..6a986c9db 100644 --- a/src/Bundle/ChillCalendarBundle/RemoteCalendar/DependencyInjection/RemoteCalendarCompilerPass.php +++ b/src/Bundle/ChillCalendarBundle/RemoteCalendar/DependencyInjection/RemoteCalendarCompilerPass.php @@ -23,6 +23,8 @@ use Chill\CalendarBundle\Command\MapAndSubscribeUserCalendarCommand; use Chill\CalendarBundle\Controller\RemoteCalendarConnectAzureController; use Chill\CalendarBundle\RemoteCalendar\Connector\MSGraph\MachineHttpClient; use Chill\CalendarBundle\RemoteCalendar\Connector\MSGraph\MachineTokenStorage; +use Chill\CalendarBundle\RemoteCalendar\Connector\MSGraph\MSUserAbsenceReaderInterface; +use Chill\CalendarBundle\RemoteCalendar\Connector\MSGraph\MSUserAbsenceSync; use Chill\CalendarBundle\RemoteCalendar\Connector\MSGraphRemoteCalendarConnector; use Chill\CalendarBundle\RemoteCalendar\Connector\NullRemoteCalendarConnector; use Chill\CalendarBundle\RemoteCalendar\Connector\RemoteCalendarConnectorInterface; @@ -37,17 +39,13 @@ class RemoteCalendarCompilerPass implements CompilerPassInterface public function process(ContainerBuilder $container) { $config = $container->getParameter('chill_calendar'); - $connector = null; - if (!$config['remote_calendars_sync']['enabled']) { - $connector = NullRemoteCalendarConnector::class; - } - - if ($config['remote_calendars_sync']['microsoft_graph']['enabled']) { + if (true === $config['remote_calendars_sync']['microsoft_graph']['enabled']) { $connector = MSGraphRemoteCalendarConnector::class; $container->setAlias(HttpClientInterface::class . ' $machineHttpClient', MachineHttpClient::class); } else { + $connector = NullRemoteCalendarConnector::class; // remove services which cannot be loaded $container->removeDefinition(MapAndSubscribeUserCalendarCommand::class); $container->removeDefinition(AzureGrantAdminConsentAndAcquireToken::class); @@ -55,16 +53,14 @@ class RemoteCalendarCompilerPass implements CompilerPassInterface $container->removeDefinition(MachineTokenStorage::class); $container->removeDefinition(MachineHttpClient::class); $container->removeDefinition(MSGraphRemoteCalendarConnector::class); + $container->removeDefinition(MSUserAbsenceReaderInterface::class); + $container->removeDefinition(MSUserAbsenceSync::class); } if (!$container->hasAlias(Azure::class) && $container->hasDefinition('knpu.oauth2.client.azure')) { $container->setAlias(Azure::class, 'knpu.oauth2.provider.azure'); } - if (null === $connector) { - throw new RuntimeException('Could not configure remote calendar'); - } - foreach ([ NullRemoteCalendarConnector::class, MSGraphRemoteCalendarConnector::class, ] as $serviceId) { From 43b7139488dd0f3b99286b421ba5c1594b709d18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 6 Jul 2023 22:01:45 +0200 Subject: [PATCH 256/321] One more changie [ci-skip] --- .changes/unreleased/Fixed-20230706-220125.yaml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changes/unreleased/Fixed-20230706-220125.yaml diff --git a/.changes/unreleased/Fixed-20230706-220125.yaml b/.changes/unreleased/Fixed-20230706-220125.yaml new file mode 100644 index 000000000..b9449d514 --- /dev/null +++ b/.changes/unreleased/Fixed-20230706-220125.yaml @@ -0,0 +1,6 @@ +kind: Fixed +body: 'Command to subscribe on MS Graph users calendars: improve the loop to be more + efficient' +time: 2023-07-06T22:01:25.847374805+02:00 +custom: + Issue: "" From 7ccff61c254cea360b68bf33d74ea0988ee1a5e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Fri, 7 Jul 2023 09:17:36 +0200 Subject: [PATCH 257/321] Refactor ListAccompanyingPeriod to use a helper for most of the work --- .../Export/Export/ListAccompanyingPeriod.php | 313 +----------------- .../Helper/ListAccompanyingPeriodHelper.php | 306 +++++++++++++++++ .../translations/messages.fr.yml | 2 +- 3 files changed, 315 insertions(+), 306 deletions(-) create mode 100644 src/Bundle/ChillPersonBundle/Export/Helper/ListAccompanyingPeriodHelper.php diff --git a/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriod.php b/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriod.php index af66ab312..3f7821bbc 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriod.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriod.php @@ -29,6 +29,7 @@ use Chill\PersonBundle\Entity\Household\PersonHouseholdAddress; use Chill\PersonBundle\Entity\Person\PersonCenterHistory; use Chill\PersonBundle\Entity\SocialWork\SocialIssue; use Chill\PersonBundle\Export\Declarations; +use Chill\PersonBundle\Export\Helper\ListAccompanyingPeriodHelper; use Chill\PersonBundle\Repository\PersonRepository; use Chill\PersonBundle\Repository\SocialWork\SocialIssueRepository; use Chill\PersonBundle\Security\Authorization\PersonVoter; @@ -45,95 +46,13 @@ use Symfony\Component\Form\FormBuilderInterface; use Symfony\Contracts\Translation\TranslatorInterface; use function strlen; -class ListAccompanyingPeriod implements ListInterface, GroupedExportInterface +final readonly class ListAccompanyingPeriod implements ListInterface, GroupedExportInterface { - private const FIELDS = [ - 'id', - 'step', - 'stepSince', - 'openingDate', - 'closingDate', - 'referrer', - 'referrerSince', - 'administrativeLocation', - 'locationIsPerson', - 'locationIsTemp', - 'locationPersonName', - 'locationPersonId', - 'origin', - 'closingMotive', - 'confidential', - 'emergency', - 'intensity', - 'job', - 'isRequestorPerson', - 'isRequestorThirdParty', - 'requestorPerson', - 'requestorPersonId', - 'requestorThirdParty', - 'requestorThirdPartyId', - 'scopes', - 'socialIssues', - 'createdAt', - 'createdBy', - 'updatedAt', - 'updatedBy', - ]; - - private ExportAddressHelper $addressHelper; - - private DateTimeHelper $dateTimeHelper; - - private EntityManagerInterface $entityManager; - - private PersonRenderInterface $personRender; - - private PersonRepository $personRepository; - - private RollingDateConverterInterface $rollingDateConverter; - - private SocialIssueRender $socialIssueRender; - - private SocialIssueRepository $socialIssueRepository; - - private ThirdPartyRender $thirdPartyRender; - - private ThirdPartyRepository $thirdPartyRepository; - - private TranslatableStringHelperInterface $translatableStringHelper; - - private TranslatorInterface $translator; - - private UserHelper $userHelper; - public function __construct( - ExportAddressHelper $addressHelper, - DateTimeHelper $dateTimeHelper, - EntityManagerInterface $entityManager, - PersonRenderInterface $personRender, - PersonRepository $personRepository, - ThirdPartyRepository $thirdPartyRepository, - ThirdPartyRender $thirdPartyRender, - SocialIssueRepository $socialIssueRepository, - SocialIssueRender $socialIssueRender, - TranslatableStringHelperInterface $translatableStringHelper, - TranslatorInterface $translator, - RollingDateConverterInterface $rollingDateConverter, - UserHelper $userHelper + private EntityManagerInterface $entityManager, + private RollingDateConverterInterface $rollingDateConverter, + private ListAccompanyingPeriodHelper $listAccompanyingPeriodHelper, ) { - $this->addressHelper = $addressHelper; - $this->dateTimeHelper = $dateTimeHelper; - $this->entityManager = $entityManager; - $this->personRender = $personRender; - $this->personRepository = $personRepository; - $this->socialIssueRender = $socialIssueRender; - $this->socialIssueRepository = $socialIssueRepository; - $this->thirdPartyRender = $thirdPartyRender; - $this->thirdPartyRepository = $thirdPartyRepository; - $this->translatableStringHelper = $translatableStringHelper; - $this->translator = $translator; - $this->rollingDateConverter = $rollingDateConverter; - $this->userHelper = $userHelper; } public function buildForm(FormBuilderInterface $builder) @@ -169,141 +88,12 @@ class ListAccompanyingPeriod implements ListInterface, GroupedExportInterface public function getLabels($key, array $values, $data) { - if (substr($key, 0, strlen('address_fields')) === 'address_fields') { - return $this->addressHelper->getLabel($key, $values, $data, 'address_fields'); - } - - switch ($key) { - case 'stepSince': - case 'openingDate': - case 'closingDate': - case 'referrerSince': - case 'createdAt': - case 'updatedAt': - return $this->dateTimeHelper->getLabel('export.list.acp.' . $key); - - case 'origin': - case 'closingMotive': - case 'job': - return function ($value) use ($key) { - if ('_header' === $value) { - return 'export.list.acp.' . $key; - } - - if (null === $value) { - return ''; - } - - return $this->translatableStringHelper->localize(json_decode($value, true, 512, JSON_THROW_ON_ERROR)); - }; - - case 'locationPersonName': - case 'requestorPerson': - return function ($value) use ($key) { - if ('_header' === $value) { - return 'export.list.acp.' . $key; - } - - if (null === $value || null === $person = $this->personRepository->find($value)) { - return ''; - } - - return $this->personRender->renderString($person, []); - }; - - case 'requestorThirdParty': - return function ($value) use ($key) { - if ('_header' === $value) { - return 'export.list.acp.' . $key; - } - - if (null === $value || null === $thirdparty = $this->thirdPartyRepository->find($value)) { - return ''; - } - - return $this->thirdPartyRender->renderString($thirdparty, []); - }; - - case 'scopes': - return function ($value) use ($key) { - if ('_header' === $value) { - return 'export.list.acp.' . $key; - } - - if (null === $value) { - return ''; - } - - return implode( - '|', - array_map( - fn ($s) => $this->translatableStringHelper->localize($s), - json_decode($value, true, 512, JSON_THROW_ON_ERROR) - ) - ); - }; - - case 'socialIssues': - return function ($value) use ($key) { - if ('_header' === $value) { - return 'export.list.acp.' . $key; - } - - if (null === $value) { - return ''; - } - - return implode( - '|', - array_map( - fn ($s) => $this->socialIssueRender->renderString($this->socialIssueRepository->find($s), []), - json_decode($value, true, 512, JSON_THROW_ON_ERROR) - ) - ); - }; - - case 'step': - return fn ($value) => match ($value) { - '_header' => 'export.list.acp.step', - null => '', - AccompanyingPeriod::STEP_DRAFT => $this->translator->trans('course.draft'), - AccompanyingPeriod::STEP_CONFIRMED => $this->translator->trans('course.confirmed'), - AccompanyingPeriod::STEP_CLOSED => $this->translator->trans('course.closed'), - AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_SHORT => $this->translator->trans('course.inactive_short'), - AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_LONG => $this->translator->trans('course.inactive_long'), - default => $value, - }; - - case 'intensity': - return fn ($value) => match ($value) { - '_header' => 'export.list.acp.intensity', - null => '', - AccompanyingPeriod::INTENSITY_OCCASIONAL => $this->translator->trans('occasional'), - AccompanyingPeriod::INTENSITY_REGULAR => $this->translator->trans('regular'), - default => $value, - }; - - default: - return static function ($value) use ($key) { - if ('_header' === $value) { - return 'export.list.acp.' . $key; - } - - if (null === $value) { - return ''; - } - - return $value; - }; - } + return $this->listAccompanyingPeriodHelper->getLabels($key, $values, $data); } public function getQueryKeys($data) { - return array_merge( - self::FIELDS, - $this->addressHelper->getKeys(ExportAddressHelper::F_ALL, 'address_fields') - ); + return $this->listAccompanyingPeriodHelper->getQueryKeys($data); } public function getResult($query, $data) @@ -341,7 +131,7 @@ class ListAccompanyingPeriod implements ListInterface, GroupedExportInterface ->setParameter('list_acp_step', AccompanyingPeriod::STEP_DRAFT) ->setParameter('authorized_centers', $centers); - $this->addSelectClauses($qb, $this->rollingDateConverter->convert($data['calc_date'])); + $this->listAccompanyingPeriodHelper->addSelectClauses($qb, $this->rollingDateConverter->convert($data['calc_date'])); return $qb; } @@ -357,91 +147,4 @@ class ListAccompanyingPeriod implements ListInterface, GroupedExportInterface Declarations::ACP_TYPE, ]; } - - private function addSelectClauses(QueryBuilder $qb, DateTimeImmutable $calcDate): void - { - // add the regular fields - foreach (['id', 'openingDate', 'closingDate', 'confidential', 'emergency', 'intensity', 'createdAt', 'updatedAt'] as $field) { - $qb->addSelect(sprintf('acp.%s AS %s', $field, $field)); - } - - // add the field which are simple association - foreach (['origin' => 'label', 'closingMotive' => 'name', 'job' => 'label', 'createdBy' => 'label', 'updatedBy' => 'label', 'administrativeLocation' => 'name'] as $entity => $field) { - $qb - ->leftJoin(sprintf('acp.%s', $entity), "{$entity}_t") - ->addSelect(sprintf('%s_t.%s AS %s', $entity, $field, $entity)); - } - - // step at date - $qb - ->addSelect('stepHistory.step AS step') - ->addSelect('stepHistory.startDate AS stepSince') - ->leftJoin('acp.stepHistories', 'stepHistory') - ->andWhere( - $qb->expr()->andX( - $qb->expr()->lte('stepHistory.startDate', ':calcDate'), - $qb->expr()->orX($qb->expr()->isNull('stepHistory.endDate'), $qb->expr()->gt('stepHistory.endDate', ':calcDate')) - ) - ); - - // referree at date - $qb - ->addSelect('referrer_t.label AS referrer') - ->addSelect('userHistory.startDate AS referrerSince') - ->leftJoin('acp.userHistories', 'userHistory') - ->leftJoin('userHistory.user', 'referrer_t') - ->andWhere( - $qb->expr()->orX( - $qb->expr()->isNull('userHistory'), - $qb->expr()->andX( - $qb->expr()->lte('userHistory.startDate', ':calcDate'), - $qb->expr()->orX($qb->expr()->isNull('userHistory.endDate'), $qb->expr()->gt('userHistory.endDate', ':calcDate')) - ) - ) - ); - - // location of the acp - $qb - ->addSelect('CASE WHEN locationHistory.personLocation IS NOT NULL THEN 1 ELSE 0 END AS locationIsPerson') - ->addSelect('CASE WHEN locationHistory.personLocation IS NOT NULL THEN 0 ELSE 1 END AS locationIsTemp') - ->addSelect('IDENTITY(locationHistory.personLocation) AS locationPersonName') - ->addSelect('IDENTITY(locationHistory.personLocation) AS locationPersonId') - ->leftJoin('acp.locationHistories', 'locationHistory') - ->andWhere( - $qb->expr()->orX( - $qb->expr()->isNull('locationHistory'), - $qb->expr()->andX( - $qb->expr()->lte('locationHistory.startDate', ':calcDate'), - $qb->expr()->orX($qb->expr()->isNull('locationHistory.endDate'), $qb->expr()->gt('locationHistory.endDate', ':calcDate')) - ) - ) - ) - ->leftJoin( - PersonHouseholdAddress::class, - 'personAddress', - Join::WITH, - 'locationHistory.personLocation = personAddress.person AND (personAddress.validFrom <= :calcDate AND (personAddress.validTo IS NULL OR personAddress.validTo > :calcDate))' - ) - ->leftJoin(Address::class, 'acp_address', Join::WITH, 'COALESCE(IDENTITY(locationHistory.addressLocation), IDENTITY(personAddress.address)) = acp_address.id'); - - $this->addressHelper->addSelectClauses(ExportAddressHelper::F_ALL, $qb, 'acp_address', 'address_fields'); - - // requestor - $qb - ->addSelect('CASE WHEN acp.requestorPerson IS NULL THEN 1 ELSE 0 END AS isRequestorPerson') - ->addSelect('CASE WHEN acp.requestorPerson IS NULL THEN 0 ELSE 1 END AS isRequestorThirdParty') - ->addSelect('IDENTITY(acp.requestorPerson) AS requestorPersonId') - ->addSelect('IDENTITY(acp.requestorThirdParty) AS requestorThirdPartyId') - ->addSelect('IDENTITY(acp.requestorPerson) AS requestorPerson') - ->addSelect('IDENTITY(acp.requestorThirdParty) AS requestorThirdParty'); - - $qb - // scopes - ->addSelect('(SELECT AGGREGATE(scope.name) FROM ' . Scope::class . ' scope WHERE scope MEMBER OF acp.scopes) AS scopes') - // social issues - ->addSelect('(SELECT AGGREGATE(socialIssue.id) FROM ' . SocialIssue::class . ' socialIssue WHERE socialIssue MEMBER OF acp.socialIssues) AS socialIssues'); - - // add parameter - $qb->setParameter('calcDate', $calcDate); - } } diff --git a/src/Bundle/ChillPersonBundle/Export/Helper/ListAccompanyingPeriodHelper.php b/src/Bundle/ChillPersonBundle/Export/Helper/ListAccompanyingPeriodHelper.php new file mode 100644 index 000000000..8671b4977 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Export/Helper/ListAccompanyingPeriodHelper.php @@ -0,0 +1,306 @@ +addressHelper->getKeys(ExportAddressHelper::F_ALL, 'address_fields') + ); + } + + public function getLabels($key, array $values, $data) + { + if (substr($key, 0, strlen('address_fields')) === 'address_fields') { + return $this->addressHelper->getLabel($key, $values, $data, 'address_fields'); + } + + switch ($key) { + case 'stepSince': + case 'openingDate': + case 'closingDate': + case 'referrerSince': + case 'createdAt': + case 'updatedAt': + return $this->dateTimeHelper->getLabel('export.list.acp.' . $key); + + case 'origin': + case 'closingMotive': + case 'job': + return function ($value) use ($key) { + if ('_header' === $value) { + return 'export.list.acp.' . $key; + } + + if (null === $value) { + return ''; + } + + return $this->translatableStringHelper->localize(json_decode($value, true, 512, JSON_THROW_ON_ERROR)); + }; + + case 'locationPersonName': + case 'requestorPerson': + return function ($value) use ($key) { + if ('_header' === $value) { + return 'export.list.acp.' . $key; + } + + if (null === $value || null === $person = $this->personRepository->find($value)) { + return ''; + } + + return $this->personRender->renderString($person, []); + }; + + case 'requestorThirdParty': + return function ($value) use ($key) { + if ('_header' === $value) { + return 'export.list.acp.' . $key; + } + + if (null === $value || null === $thirdparty = $this->thirdPartyRepository->find($value)) { + return ''; + } + + return $this->thirdPartyRender->renderString($thirdparty, []); + }; + + case 'scopes': + return function ($value) use ($key) { + if ('_header' === $value) { + return 'export.list.acp.' . $key; + } + + if (null === $value) { + return ''; + } + + return implode( + '|', + array_map( + fn ($s) => $this->translatableStringHelper->localize($s), + json_decode($value, true, 512, JSON_THROW_ON_ERROR) + ) + ); + }; + + case 'socialIssues': + return function ($value) use ($key) { + if ('_header' === $value) { + return 'export.list.acp.' . $key; + } + + if (null === $value) { + return ''; + } + + return implode( + '|', + array_map( + fn ($s) => $this->socialIssueRender->renderString($this->socialIssueRepository->find($s), []), + json_decode($value, true, 512, JSON_THROW_ON_ERROR) + ) + ); + }; + + case 'step': + return fn ($value) => match ($value) { + '_header' => 'export.list.acp.step', + null => '', + AccompanyingPeriod::STEP_DRAFT => $this->translator->trans('course.draft'), + AccompanyingPeriod::STEP_CONFIRMED => $this->translator->trans('course.confirmed'), + AccompanyingPeriod::STEP_CLOSED => $this->translator->trans('course.closed'), + AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_SHORT => $this->translator->trans('course.inactive_short'), + AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_LONG => $this->translator->trans('course.inactive_long'), + default => $value, + }; + + case 'intensity': + return fn ($value) => match ($value) { + '_header' => 'export.list.acp.intensity', + null => '', + AccompanyingPeriod::INTENSITY_OCCASIONAL => $this->translator->trans('occasional'), + AccompanyingPeriod::INTENSITY_REGULAR => $this->translator->trans('regular'), + default => $value, + }; + + default: + return static function ($value) use ($key) { + if ('_header' === $value) { + return 'export.list.acp.' . $key; + } + + if (null === $value) { + return ''; + } + + return $value; + }; + } + } + + public function addSelectClauses(QueryBuilder $qb, \DateTimeImmutable $calcDate): void + { + // add the regular fields + foreach (['id', 'openingDate', 'closingDate', 'confidential', 'emergency', 'intensity', 'createdAt', 'updatedAt'] as $field) { + $qb->addSelect(sprintf('acp.%s AS %s', $field, $field)); + } + + // add the field which are simple association + foreach (['origin' => 'label', 'closingMotive' => 'name', 'job' => 'label', 'createdBy' => 'label', 'updatedBy' => 'label', 'administrativeLocation' => 'name'] as $entity => $field) { + $qb + ->leftJoin(sprintf('acp.%s', $entity), "{$entity}_t") + ->addSelect(sprintf('%s_t.%s AS %s', $entity, $field, $entity)); + } + + // step at date + $qb + ->addSelect('stepHistory.step AS step') + ->addSelect('stepHistory.startDate AS stepSince') + ->leftJoin('acp.stepHistories', 'stepHistory') + ->andWhere( + $qb->expr()->andX( + $qb->expr()->lte('stepHistory.startDate', ':calcDate'), + $qb->expr()->orX($qb->expr()->isNull('stepHistory.endDate'), $qb->expr()->gt('stepHistory.endDate', ':calcDate')) + ) + ); + + // referree at date + $qb + ->addSelect('referrer_t.label AS referrer') + ->addSelect('userHistory.startDate AS referrerSince') + ->leftJoin('acp.userHistories', 'userHistory') + ->leftJoin('userHistory.user', 'referrer_t') + ->andWhere( + $qb->expr()->orX( + $qb->expr()->isNull('userHistory'), + $qb->expr()->andX( + $qb->expr()->lte('userHistory.startDate', ':calcDate'), + $qb->expr()->orX($qb->expr()->isNull('userHistory.endDate'), $qb->expr()->gt('userHistory.endDate', ':calcDate')) + ) + ) + ); + + // location of the acp + $qb + ->addSelect('CASE WHEN locationHistory.personLocation IS NOT NULL THEN 1 ELSE 0 END AS locationIsPerson') + ->addSelect('CASE WHEN locationHistory.personLocation IS NOT NULL THEN 0 ELSE 1 END AS locationIsTemp') + ->addSelect('IDENTITY(locationHistory.personLocation) AS locationPersonName') + ->addSelect('IDENTITY(locationHistory.personLocation) AS locationPersonId') + ->leftJoin('acp.locationHistories', 'locationHistory') + ->andWhere( + $qb->expr()->orX( + $qb->expr()->isNull('locationHistory'), + $qb->expr()->andX( + $qb->expr()->lte('locationHistory.startDate', ':calcDate'), + $qb->expr()->orX($qb->expr()->isNull('locationHistory.endDate'), $qb->expr()->gt('locationHistory.endDate', ':calcDate')) + ) + ) + ) + ->leftJoin( + PersonHouseholdAddress::class, + 'personAddress', + Join::WITH, + 'locationHistory.personLocation = personAddress.person AND (personAddress.validFrom <= :calcDate AND (personAddress.validTo IS NULL OR personAddress.validTo > :calcDate))' + ) + ->leftJoin(Address::class, 'acp_address', Join::WITH, 'COALESCE(IDENTITY(locationHistory.addressLocation), IDENTITY(personAddress.address)) = acp_address.id'); + + $this->addressHelper->addSelectClauses(ExportAddressHelper::F_ALL, $qb, 'acp_address', 'address_fields'); + + // requestor + $qb + ->addSelect('CASE WHEN acp.requestorPerson IS NULL THEN 1 ELSE 0 END AS isRequestorPerson') + ->addSelect('CASE WHEN acp.requestorPerson IS NULL THEN 0 ELSE 1 END AS isRequestorThirdParty') + ->addSelect('IDENTITY(acp.requestorPerson) AS requestorPersonId') + ->addSelect('IDENTITY(acp.requestorThirdParty) AS requestorThirdPartyId') + ->addSelect('IDENTITY(acp.requestorPerson) AS requestorPerson') + ->addSelect('IDENTITY(acp.requestorThirdParty) AS requestorThirdParty'); + + $qb + // scopes + ->addSelect('(SELECT AGGREGATE(scope.name) FROM ' . Scope::class . ' scope WHERE scope MEMBER OF acp.scopes) AS scopes') + // social issues + ->addSelect('(SELECT AGGREGATE(socialIssue.id) FROM ' . SocialIssue::class . ' socialIssue WHERE socialIssue MEMBER OF acp.socialIssues) AS socialIssues'); + + // add parameter + $qb->setParameter('calcDate', $calcDate); + } +} diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index 2f7800e2b..08e51aeab 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -1175,7 +1175,7 @@ export: referrerSince: Référent depuis le locationIsPerson: Parcours localisé auprès d'un usager concerné locationIsTemp: Parcours avec une localisation temporaire - acpLocationPersonName: Usager auprès duquel le parcours est localisé + locationPersonName: Usager auprès duquel le parcours est localisé locationPersonId: Identifiant de l'usager auprès duquel le parcours est localisé acpaddress_fieldscountry: Pays de l'adresse isRequestorPerson: Le demandeur est-il un usager ? From 56d9072abe971cf69f07a55a931e8becabe8fb68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Fri, 7 Jul 2023 09:33:03 +0200 Subject: [PATCH 258/321] change id, to avoid collision between ListPersonHelper and ListAccompanyingPeriodHelper --- .../Export/Helper/ListAccompanyingPeriodHelper.php | 6 ++++-- .../ChillPersonBundle/Export/Helper/ListPersonHelper.php | 7 ++++++- src/Bundle/ChillPersonBundle/translations/messages.fr.yml | 4 +++- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Export/Helper/ListAccompanyingPeriodHelper.php b/src/Bundle/ChillPersonBundle/Export/Helper/ListAccompanyingPeriodHelper.php index 8671b4977..a32d78904 100644 --- a/src/Bundle/ChillPersonBundle/Export/Helper/ListAccompanyingPeriodHelper.php +++ b/src/Bundle/ChillPersonBundle/Export/Helper/ListAccompanyingPeriodHelper.php @@ -32,7 +32,7 @@ use Symfony\Contracts\Translation\TranslatorInterface; final readonly class ListAccompanyingPeriodHelper { public const FIELDS = [ - 'id', + 'acpId', 'step', 'stepSince', 'openingDate', @@ -219,8 +219,10 @@ final readonly class ListAccompanyingPeriodHelper public function addSelectClauses(QueryBuilder $qb, \DateTimeImmutable $calcDate): void { + $qb->addSelect('acp.id AS acpId'); + // add the regular fields - foreach (['id', 'openingDate', 'closingDate', 'confidential', 'emergency', 'intensity', 'createdAt', 'updatedAt'] as $field) { + foreach (['openingDate', 'closingDate', 'confidential', 'emergency', 'intensity', 'createdAt', 'updatedAt'] as $field) { $qb->addSelect(sprintf('acp.%s AS %s', $field, $field)); } diff --git a/src/Bundle/ChillPersonBundle/Export/Helper/ListPersonHelper.php b/src/Bundle/ChillPersonBundle/Export/Helper/ListPersonHelper.php index 77a1d9c86..697019ca3 100644 --- a/src/Bundle/ChillPersonBundle/Export/Helper/ListPersonHelper.php +++ b/src/Bundle/ChillPersonBundle/Export/Helper/ListPersonHelper.php @@ -42,7 +42,7 @@ use function strlen; class ListPersonHelper { public const FIELDS = [ - 'id', + 'personId', 'civility', 'firstName', 'lastName', @@ -124,6 +124,11 @@ class ListPersonHelper } switch ($f) { + case 'personId': + $qb->addSelect('person.id AS personId'); + + break; + case 'countryOfBirth': case 'nationality': $qb->addSelect(sprintf('IDENTITY(person.%s) as %s', $f, $f)); diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index 08e51aeab..0a82fc330 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -997,6 +997,8 @@ notification: Notify referrer: Notifier le référent Notify any: Notifier d'autres utilisateurs +personId: Identifiant de l'usager + export: export: acp_stats: @@ -1152,7 +1154,7 @@ export: Generate a list of accompanying periods, filtered on different parameters.: Génère une liste des parcours d'accompagnement, filtrée sur différents paramètres. Date of calculation for associated elements: Date de calcul des éléments associés The associated referree, localisation, and other elements will be valid at this date: Les éléments associés, comme la localisation, le référent et d'autres éléments seront valides à cette date - id: Identifiant du parcours + acpId: Identifiant du parcours openingDate: Date d'ouverture du parcours closingDate: Date de fermeture du parcours closingMotive: Motif de cloture From 7f30742fc3615311500931f9d22563f228e3c752 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Fri, 7 Jul 2023 09:36:39 +0200 Subject: [PATCH 259/321] Rename ListPersonWithAccompanyingPeriod to ListPersonHavingAccompanyingPeriod --- ...ngPeriod.php => ListPersonHavingAccompanyingPeriod.php} | 7 ++++++- .../ChillPersonBundle/config/services/exports_person.yaml | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) rename src/Bundle/ChillPersonBundle/Export/Export/{ListPersonWithAccompanyingPeriod.php => ListPersonHavingAccompanyingPeriod.php} (96%) diff --git a/src/Bundle/ChillPersonBundle/Export/Export/ListPersonWithAccompanyingPeriod.php b/src/Bundle/ChillPersonBundle/Export/Export/ListPersonHavingAccompanyingPeriod.php similarity index 96% rename from src/Bundle/ChillPersonBundle/Export/Export/ListPersonWithAccompanyingPeriod.php rename to src/Bundle/ChillPersonBundle/Export/Export/ListPersonHavingAccompanyingPeriod.php index 370046232..f2e4de4e3 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/ListPersonWithAccompanyingPeriod.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/ListPersonHavingAccompanyingPeriod.php @@ -35,7 +35,12 @@ use function count; use function in_array; use function strlen; -class ListPersonWithAccompanyingPeriod implements ExportElementValidatedInterface, ListInterface, GroupedExportInterface +/** + * List the persons, having an accompanying period. + * + * Details of the accompanying period are not included + */ +class ListPersonHavingAccompanyingPeriod implements ExportElementValidatedInterface, ListInterface, GroupedExportInterface { private ExportAddressHelper $addressHelper; diff --git a/src/Bundle/ChillPersonBundle/config/services/exports_person.yaml b/src/Bundle/ChillPersonBundle/config/services/exports_person.yaml index 64360aee9..81875fafb 100644 --- a/src/Bundle/ChillPersonBundle/config/services/exports_person.yaml +++ b/src/Bundle/ChillPersonBundle/config/services/exports_person.yaml @@ -24,7 +24,7 @@ services: tags: - { name: chill.export, alias: list_person } - Chill\PersonBundle\Export\Export\ListPersonWithAccompanyingPeriod: + Chill\PersonBundle\Export\Export\ListPersonHavingAccompanyingPeriod: autowire: true autoconfigure: true tags: From 17d2b795b41d9aee8457ad9ade199e07d1c5be60 Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Fri, 7 Jul 2023 11:38:00 +0200 Subject: [PATCH 260/321] update changelog --- .changes/unreleased/DX-20230623-122408.yaml | 5 --- .../unreleased/Feature-20230623-122530.yaml | 5 --- .../unreleased/Feature-20230623-122702.yaml | 6 --- .../unreleased/Feature-20230623-124438.yaml | 5 --- .../unreleased/Fixed-20230628-170055.yaml | 6 --- .../unreleased/Fixed-20230629-124412.yaml | 6 --- .../unreleased/Fixed-20230629-231503.yaml | 5 --- .../unreleased/Fixed-20230630-171119.yaml | 5 --- .../unreleased/Fixed-20230630-171153.yaml | 5 --- .changie.yaml | 2 + CHANGELOG.md | 37 +++++++++++++++++++ .../Resources/public/chill/scss/forms.scss | 2 +- 12 files changed, 40 insertions(+), 49 deletions(-) delete mode 100644 .changes/unreleased/DX-20230623-122408.yaml delete mode 100644 .changes/unreleased/Feature-20230623-122530.yaml delete mode 100644 .changes/unreleased/Feature-20230623-122702.yaml delete mode 100644 .changes/unreleased/Feature-20230623-124438.yaml delete mode 100644 .changes/unreleased/Fixed-20230628-170055.yaml delete mode 100644 .changes/unreleased/Fixed-20230629-124412.yaml delete mode 100644 .changes/unreleased/Fixed-20230629-231503.yaml delete mode 100644 .changes/unreleased/Fixed-20230630-171119.yaml delete mode 100644 .changes/unreleased/Fixed-20230630-171153.yaml diff --git a/.changes/unreleased/DX-20230623-122408.yaml b/.changes/unreleased/DX-20230623-122408.yaml deleted file mode 100644 index 58dd96180..000000000 --- a/.changes/unreleased/DX-20230623-122408.yaml +++ /dev/null @@ -1,5 +0,0 @@ -kind: DX -body: '[FilterOrderHelper] add entity choice and singleCheckbox' -time: 2023-06-23T12:24:08.133491895+02:00 -custom: - Issue: "" diff --git a/.changes/unreleased/Feature-20230623-122530.yaml b/.changes/unreleased/Feature-20230623-122530.yaml deleted file mode 100644 index 922750ea8..000000000 --- a/.changes/unreleased/Feature-20230623-122530.yaml +++ /dev/null @@ -1,5 +0,0 @@ -kind: Feature -body: '[activity list] add filtering for activities list' -time: 2023-06-23T12:25:30.49643551+02:00 -custom: - Issue: "" diff --git a/.changes/unreleased/Feature-20230623-122702.yaml b/.changes/unreleased/Feature-20230623-122702.yaml deleted file mode 100644 index e1d1b0e1f..000000000 --- a/.changes/unreleased/Feature-20230623-122702.yaml +++ /dev/null @@ -1,6 +0,0 @@ -kind: Feature -body: '[activity list] in person context, show also the activities from the accompanying - periods where the person participates' -time: 2023-06-23T12:27:02.159041095+02:00 -custom: - Issue: "" diff --git a/.changes/unreleased/Feature-20230623-124438.yaml b/.changes/unreleased/Feature-20230623-124438.yaml deleted file mode 100644 index bc199d3bb..000000000 --- a/.changes/unreleased/Feature-20230623-124438.yaml +++ /dev/null @@ -1,5 +0,0 @@ -kind: Feature -body: '[activity list] add pagination to the list of activities' -time: 2023-06-23T12:44:38.879098862+02:00 -custom: - Issue: "" diff --git a/.changes/unreleased/Fixed-20230628-170055.yaml b/.changes/unreleased/Fixed-20230628-170055.yaml deleted file mode 100644 index 7f9ec3028..000000000 --- a/.changes/unreleased/Fixed-20230628-170055.yaml +++ /dev/null @@ -1,6 +0,0 @@ -kind: Fixed -body: '[export] Rename label for CurrentActionFilter (on accompanying period work) - to make precision between "ouvert" and "sans date de fin"' -time: 2023-06-28T17:00:55.206937751+02:00 -custom: - Issue: "" diff --git a/.changes/unreleased/Fixed-20230629-124412.yaml b/.changes/unreleased/Fixed-20230629-124412.yaml deleted file mode 100644 index 7fc3d3eb0..000000000 --- a/.changes/unreleased/Fixed-20230629-124412.yaml +++ /dev/null @@ -1,6 +0,0 @@ -kind: Fixed -body: Force the db to have either a person_location or a address_location, and avoid - to have both also internally in the entity -time: 2023-06-29T12:44:12.019663991+02:00 -custom: - Issue: "" diff --git a/.changes/unreleased/Fixed-20230629-231503.yaml b/.changes/unreleased/Fixed-20230629-231503.yaml deleted file mode 100644 index e021d1fda..000000000 --- a/.changes/unreleased/Fixed-20230629-231503.yaml +++ /dev/null @@ -1,5 +0,0 @@ -kind: Fixed -body: '[export] set rolling date on person age aggregator' -time: 2023-06-29T23:15:03.20841309+02:00 -custom: - Issue: "" diff --git a/.changes/unreleased/Fixed-20230630-171119.yaml b/.changes/unreleased/Fixed-20230630-171119.yaml deleted file mode 100644 index f3185ace2..000000000 --- a/.changes/unreleased/Fixed-20230630-171119.yaml +++ /dev/null @@ -1,5 +0,0 @@ -kind: Fixed -body: '[export] fix list when a person locating a course is without address' -time: 2023-06-30T17:11:19.454081914+02:00 -custom: - Issue: "" diff --git a/.changes/unreleased/Fixed-20230630-171153.yaml b/.changes/unreleased/Fixed-20230630-171153.yaml deleted file mode 100644 index c09bd93d0..000000000 --- a/.changes/unreleased/Fixed-20230630-171153.yaml +++ /dev/null @@ -1,5 +0,0 @@ -kind: Fixed -body: '[export] remove unused condition on course about duration participation' -time: 2023-06-30T17:11:53.076615549+02:00 -custom: - Issue: "" diff --git a/.changie.yaml b/.changie.yaml index 8a25ed695..cda69de65 100644 --- a/.changie.yaml +++ b/.changie.yaml @@ -30,6 +30,8 @@ kinds: auto: patch - label: DX auto: patch + - label: UX + auto: patch newlines: afterChangelogHeader: 1 beforeChangelogVersion: 1 diff --git a/CHANGELOG.md b/CHANGELOG.md index 93ff93556..1f51bf06e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,43 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), and is generated by [Changie](https://github.com/miniscruff/changie). +## v2.4.0 - 2023-07-07 +### Feature +* [activity list] add filtering for activities list + + +* [activity list] in person context, show also the activities from the accompanying periods where the person participates + + +* [activity list] add pagination to the list of activities + + +* ([#118](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/118)) improve UX design for filterOrder box + + + + +### Fixed +* [export] Rename label for CurrentActionFilter (on accompanying period work) to make precision between "ouvert" and "sans date de fin" + + +* Force the db to have either a person_location or a address_location, and avoid to have both also internally in the entity + + +* [export] set rolling date on person age aggregator + + +* [export] fix list when a person locating a course is without address + + +* [export] remove unused condition on course about duration participation + + +### DX +* [FilterOrderHelper] add entity choice and singleCheckbox + + + ## v2.3.0 - 2023-06-27 ### Feature * ([#110](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/110)) Edit saved exports options: the saved exports options (forms, filters, aggregators) are now editable. diff --git a/src/Bundle/ChillMainBundle/Resources/public/chill/scss/forms.scss b/src/Bundle/ChillMainBundle/Resources/public/chill/scss/forms.scss index a517a5516..28c597bc0 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/chill/scss/forms.scss +++ b/src/Bundle/ChillMainBundle/Resources/public/chill/scss/forms.scss @@ -44,5 +44,5 @@ form { } .chill_filter_order { - background: $gray-100; + background: $gray-100; } \ No newline at end of file From c8146ded17b332a3566b58b7c824840259b7f7ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Fri, 7 Jul 2023 12:36:24 +0200 Subject: [PATCH 261/321] Feature: add a list for people with their associated accompanying course --- .../unreleased/Feature-20230707-123609.yaml | 5 + .../Export/ExportInterface.php | 2 +- ...istPersonWithAccompanyingPeriodDetails.php | 149 ++++++++++++++++++ .../Helper/ListAccompanyingPeriodHelper.php | 39 +++-- .../Export/Helper/ListPersonHelper.php | 42 ++--- .../config/services/exports_person.yaml | 20 +-- .../translations/messages.fr.yml | 10 +- 7 files changed, 213 insertions(+), 54 deletions(-) create mode 100644 .changes/unreleased/Feature-20230707-123609.yaml create mode 100644 src/Bundle/ChillPersonBundle/Export/Export/ListPersonWithAccompanyingPeriodDetails.php diff --git a/.changes/unreleased/Feature-20230707-123609.yaml b/.changes/unreleased/Feature-20230707-123609.yaml new file mode 100644 index 000000000..51ff94d4c --- /dev/null +++ b/.changes/unreleased/Feature-20230707-123609.yaml @@ -0,0 +1,5 @@ +kind: Feature +body: '[export] Add a list for people with their associated course' +time: 2023-07-07T12:36:09.596469063+02:00 +custom: + Issue: "125" diff --git a/src/Bundle/ChillMainBundle/Export/ExportInterface.php b/src/Bundle/ChillMainBundle/Export/ExportInterface.php index f357a9fdb..a11a51746 100644 --- a/src/Bundle/ChillMainBundle/Export/ExportInterface.php +++ b/src/Bundle/ChillMainBundle/Export/ExportInterface.php @@ -97,7 +97,7 @@ interface ExportInterface extends ExportElementInterface * @param mixed[] $values The values from the result. if there are duplicates, those might be given twice. Example: array('FR', 'BE', 'CZ', 'FR', 'BE', 'FR') * @param mixed $data The data from the export's form (as defined in `buildForm`) * - * @return callable(null|string|int|float|'_header' $value): string|int|\DateTimeInterface where the first argument is the value, and the function should return the label to show in the formatted file. Example : `function($countryCode) use ($countries) { return $countries[$countryCode]->getName(); }` + * @return (callable(null|string|int|float|'_header' $value): string|int|\DateTimeInterface) where the first argument is the value, and the function should return the label to show in the formatted file. Example : `function($countryCode) use ($countries) { return $countries[$countryCode]->getName(); }` */ public function getLabels($key, array $values, $data); diff --git a/src/Bundle/ChillPersonBundle/Export/Export/ListPersonWithAccompanyingPeriodDetails.php b/src/Bundle/ChillPersonBundle/Export/Export/ListPersonWithAccompanyingPeriodDetails.php new file mode 100644 index 000000000..295d87842 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Export/Export/ListPersonWithAccompanyingPeriodDetails.php @@ -0,0 +1,149 @@ +add('address_date', PickRollingDateType::class, [ + 'label' => 'Data valid at this date', + 'help' => 'Data regarding center, addresses, and so on will be computed at this date', + ]); + } + public function getFormDefaultData(): array + { + return ['address_date' => new RollingDate(RollingDate::T_TODAY)]; + } + + public function getAllowedFormattersTypes() + { + return [FormatterInterface::TYPE_LIST]; + } + + public function getDescription() + { + return 'export.list.person_with_acp.Create a list of people having an accompaying periods with details of period, according to various filters.'; + } + + public function getGroup(): string + { + return 'Exports of persons'; + } + + public function getLabels($key, array $values, $data) + { + if (in_array($key, $this->listPersonHelper->getAllKeys(), true)) { + return $this->listPersonHelper->getLabels($key, $values, $data); + } + + return $this->listAccompanyingPeriodHelper->getLabels($key, $values, $data); + } + + public function getQueryKeys($data) + { + return array_merge( + $this->listPersonHelper->getAllKeys(), + $this->listAccompanyingPeriodHelper->getQueryKeys($data), + ); + } + + public function getResult($query, $data) + { + return $query->getQuery()->getResult(AbstractQuery::HYDRATE_SCALAR); + } + + public function getTitle() + { + return 'export.list.person_with_acp.List peoples having an accompanying period with period details'; + } + + public function getType() + { + return Declarations::PERSON_TYPE; + } + + /** + * param array{fields: string[], address_date: DateTimeImmutable} $data. + */ + public function initiateQuery(array $requiredModifiers, array $acl, array $data = []) + { + $centers = array_map(static fn ($el) => $el['center'], $acl); + + $qb = $this->entityManager->createQueryBuilder(); + + $qb->from(Person::class, 'person') + ->join('person.accompanyingPeriodParticipations', 'acppart') + ->join('acppart.accompanyingPeriod', 'acp') + ->andWhere($qb->expr()->neq('acp.step', "'" . AccompanyingPeriod::STEP_DRAFT . "'")) + ->andWhere( + $qb->expr()->exists( + 'SELECT 1 FROM ' . PersonCenterHistory::class . ' pch WHERE pch.person = person.id AND pch.center IN (:authorized_centers)' + ) + )->setParameter('authorized_centers', $centers); + + $this->listPersonHelper->addSelect($qb, ListPersonHelper::FIELDS, $this->rollingDateConverter->convert($data['address_date'])); + $this->listAccompanyingPeriodHelper->addSelectClauses($qb, $this->rollingDateConverter->convert($data['address_date'])); + + return $qb; + } + + public function requiredRole(): string + { + return PersonVoter::LISTS; + } + + public function supportsModifiers() + { + return [Declarations::PERSON_TYPE, Declarations::PERSON_IMPLIED_IN, Declarations::ACP_TYPE]; + } +} diff --git a/src/Bundle/ChillPersonBundle/Export/Helper/ListAccompanyingPeriodHelper.php b/src/Bundle/ChillPersonBundle/Export/Helper/ListAccompanyingPeriodHelper.php index a32d78904..5fa2252cd 100644 --- a/src/Bundle/ChillPersonBundle/Export/Helper/ListAccompanyingPeriodHelper.php +++ b/src/Bundle/ChillPersonBundle/Export/Helper/ListAccompanyingPeriodHelper.php @@ -58,10 +58,10 @@ final readonly class ListAccompanyingPeriodHelper 'requestorThirdPartyId', 'scopes', 'socialIssues', - 'createdAt', - 'createdBy', - 'updatedAt', - 'updatedBy', + 'acpCreatedAt', + 'acpCreatedBy', + 'acpUpdatedAt', + 'acpUpdatedBy', ]; public function __construct( @@ -82,14 +82,14 @@ final readonly class ListAccompanyingPeriodHelper { return array_merge( ListAccompanyingPeriodHelper::FIELDS, - $this->addressHelper->getKeys(ExportAddressHelper::F_ALL, 'address_fields') + $this->addressHelper->getKeys(ExportAddressHelper::F_ALL, 'acp_address_fields') ); } public function getLabels($key, array $values, $data) { - if (substr($key, 0, strlen('address_fields')) === 'address_fields') { - return $this->addressHelper->getLabel($key, $values, $data, 'address_fields'); + if (str_starts_with($key, 'acp_address_fields')) { + return $this->addressHelper->getLabel($key, $values, $data, 'acp_address_fields'); } switch ($key) { @@ -97,8 +97,8 @@ final readonly class ListAccompanyingPeriodHelper case 'openingDate': case 'closingDate': case 'referrerSince': - case 'createdAt': - case 'updatedAt': + case 'acpCreatedAt': + case 'acpUpdatedAt': return $this->dateTimeHelper->getLabel('export.list.acp.' . $key); case 'origin': @@ -220,14 +220,23 @@ final readonly class ListAccompanyingPeriodHelper public function addSelectClauses(QueryBuilder $qb, \DateTimeImmutable $calcDate): void { $qb->addSelect('acp.id AS acpId'); + $qb->addSelect('acp.createdAt AS acpCreatedAt'); + $qb->addSelect('acp.updatedAt AS acpUpdatedAt'); // add the regular fields - foreach (['openingDate', 'closingDate', 'confidential', 'emergency', 'intensity', 'createdAt', 'updatedAt'] as $field) { + foreach (['openingDate', 'closingDate', 'confidential', 'emergency', 'intensity'] as $field) { $qb->addSelect(sprintf('acp.%s AS %s', $field, $field)); } // add the field which are simple association - foreach (['origin' => 'label', 'closingMotive' => 'name', 'job' => 'label', 'createdBy' => 'label', 'updatedBy' => 'label', 'administrativeLocation' => 'name'] as $entity => $field) { + $qb + ->leftJoin('acp.createdBy', "acp_created_by_t") + ->addSelect('acp_created_by_t.label AS acpCreatedBy'); + $qb + ->leftJoin('acp.updatedBy', "acp_updated_by_t") + ->addSelect('acp_updated_by_t.label AS acpUpdatedBy'); + + foreach (['origin' => 'label', 'closingMotive' => 'name', 'job' => 'label', 'administrativeLocation' => 'name'] as $entity => $field) { $qb ->leftJoin(sprintf('acp.%s', $entity), "{$entity}_t") ->addSelect(sprintf('%s_t.%s AS %s', $entity, $field, $entity)); @@ -279,13 +288,13 @@ final readonly class ListAccompanyingPeriodHelper ) ->leftJoin( PersonHouseholdAddress::class, - 'personAddress', + 'acpPersonAddress', Join::WITH, - 'locationHistory.personLocation = personAddress.person AND (personAddress.validFrom <= :calcDate AND (personAddress.validTo IS NULL OR personAddress.validTo > :calcDate))' + 'locationHistory.personLocation = acpPersonAddress.person AND (acpPersonAddress.validFrom <= :calcDate AND (acpPersonAddress.validTo IS NULL OR acpPersonAddress.validTo > :calcDate))' ) - ->leftJoin(Address::class, 'acp_address', Join::WITH, 'COALESCE(IDENTITY(locationHistory.addressLocation), IDENTITY(personAddress.address)) = acp_address.id'); + ->leftJoin(Address::class, 'acp_address', Join::WITH, 'COALESCE(IDENTITY(locationHistory.addressLocation), IDENTITY(acpPersonAddress.address)) = acp_address.id'); - $this->addressHelper->addSelectClauses(ExportAddressHelper::F_ALL, $qb, 'acp_address', 'address_fields'); + $this->addressHelper->addSelectClauses(ExportAddressHelper::F_ALL, $qb, 'acp_address', 'acp_address_fields'); // requestor $qb diff --git a/src/Bundle/ChillPersonBundle/Export/Helper/ListPersonHelper.php b/src/Bundle/ChillPersonBundle/Export/Helper/ListPersonHelper.php index 697019ca3..198794326 100644 --- a/src/Bundle/ChillPersonBundle/Export/Helper/ListPersonHelper.php +++ b/src/Bundle/ChillPersonBundle/Export/Helper/ListPersonHelper.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Chill\PersonBundle\Export\Helper; +use Chill\MainBundle\Entity\Language; use Chill\MainBundle\Export\Helper\ExportAddressHelper; use Chill\MainBundle\Repository\CenterRepositoryInterface; use Chill\MainBundle\Repository\CivilityRepositoryInterface; @@ -114,7 +115,26 @@ class ListPersonHelper } /** - * @param array|value-of[] $fields + * Those keys are the "direct" keys, which are created when we decide to use to list all the keys. + * + * This method must be used in `getKeys` instead of the `self::FIELDS` + * + * @return array + */ + public function getAllKeys(): array + { + return [ + ...array_filter( + ListPersonHelper::FIELDS, + fn (string $key) => !in_array($key, ['address_fields', 'lifecycleUpdate'], true) + ), + ...$this->addressHelper->getKeys(ExportAddressHelper::F_ALL, 'address_fields'), + ...['createdAt', 'createdBy', 'updatedAt', 'updatedBy'], + ]; + } + + /** + * @param array> $fields */ public function addSelect(QueryBuilder $qb, array $fields, DateTimeImmutable $computedDate): void { @@ -143,25 +163,7 @@ class ListPersonHelper break; case 'spokenLanguages': - $qb - ->leftJoin('person.spokenLanguages', 'spokenLanguage') - ->addSelect('AGGREGATE(spokenLanguage.id) AS spokenLanguages') - ->addGroupBy('person'); - - if (in_array('center', $fields, true)) { - $qb->addGroupBy('center'); - } - - if (in_array('address_fields', $fields, true)) { - $qb - ->addGroupBy('address_fieldsid') - ->addGroupBy('address_fieldscountry_t.id') - ->addGroupBy('address_fieldspostcode_t.id'); - } - - if (in_array('household_id', $fields, true)) { - $qb->addGroupBy('household_id'); - } + $qb->addSelect('(SELECT AGGREGATE(language.id) FROM ' . Language::class . ' language WHERE language MEMBER OF person.spokenLanguages) AS spokenLanguages'); break; diff --git a/src/Bundle/ChillPersonBundle/config/services/exports_person.yaml b/src/Bundle/ChillPersonBundle/config/services/exports_person.yaml index 81875fafb..43f5556cf 100644 --- a/src/Bundle/ChillPersonBundle/config/services/exports_person.yaml +++ b/src/Bundle/ChillPersonBundle/config/services/exports_person.yaml @@ -4,35 +4,27 @@ services: autowire: true ## Indicators - chill.person.export.count_person: - class: Chill\PersonBundle\Export\Export\CountPerson - autowire: true - autoconfigure: true + Chill\PersonBundle\Export\Export\CountPerson: tags: - { name: chill.export, alias: count_person } - chill.person.export.count_person_with_accompanying_course: - class: Chill\PersonBundle\Export\Export\CountPersonWithAccompanyingCourse - autowire: true - autoconfigure: true + Chill\PersonBundle\Export\Export\CountPersonWithAccompanyingCourse: tags: - { name: chill.export, alias: count_person_with_accompanying_course } Chill\PersonBundle\Export\Export\ListPerson: - autowire: true - autoconfigure: true tags: - { name: chill.export, alias: list_person } Chill\PersonBundle\Export\Export\ListPersonHavingAccompanyingPeriod: - autowire: true - autoconfigure: true tags: - { name: chill.export, alias: list_person_with_acp } + Chill\PersonBundle\Export\Export\ListPersonWithAccompanyingPeriodDetails: + tags: + - { name: chill.export, alias: list_person_with_acp_details } + Chill\PersonBundle\Export\Export\ListAccompanyingPeriod: - autowire: true - autoconfigure: true tags: - { name: chill.export, alias: list_acp } diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index 0a82fc330..1159b2c49 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -1148,7 +1148,9 @@ export: list: person_with_acp: List peoples having an accompanying period: Liste des usagers ayant un parcours d'accompagnement + List peoples having an accompanying period with period details: Liste des usagers concernés avec détail de chaque parcours Create a list of people having an accompaying periods, according to various filters.: Génère une liste des usagers ayant un parcours d'accompagnement, selon différents critères liés au parcours ou à l'usager + Create a list of people having an accompaying periods with details of period, according to various filters.: Génère une liste des usagers ayant un parcours d'accompagnement, selon différents critères liés au parcours ou à l'usager. Ajoute les détails du parcours à la liste. acp: List of accompanying periods: Liste des parcours d'accompagnements Generate a list of accompanying periods, filtered on different parameters.: Génère une liste des parcours d'accompagnement, filtrée sur différents paramètres. @@ -1162,14 +1164,14 @@ export: confidential: Confidentiel emergency: Urgent intensity: Intensité - createdAt: Créé le - updatedAt: Dernière mise à jour le + acpCreatedAt: Créé le + acpUpdatedAt: Dernière mise à jour le acpOrigin: Origine du parcours origin: Origine du parcours acpClosingMotive: Motif de fermeture acpJob: Métier du parcours - createdBy: Créé par - updatedBy: Dernière modification par + acpCreatedBy: Créé par + acpUpdatedBy: Dernière modification par administrativeLocation: Location administrative step: Etape stepSince: Dernière modification de l'étape From 63f9bd554897e1363d0b321c9e80c28e2b7745bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Fri, 7 Jul 2023 12:42:32 +0200 Subject: [PATCH 262/321] [export] Add ordering by person''s lastname or course opening date in list which concerns accompanying course or people --- .changes/unreleased/Feature-20230707-124132.yaml | 6 ++++++ .../Export/Export/ListAccompanyingPeriod.php | 5 +++++ .../Export/Export/ListPersonHavingAccompanyingPeriod.php | 5 +++++ .../Export/ListPersonWithAccompanyingPeriodDetails.php | 6 ++++++ 4 files changed, 22 insertions(+) create mode 100644 .changes/unreleased/Feature-20230707-124132.yaml diff --git a/.changes/unreleased/Feature-20230707-124132.yaml b/.changes/unreleased/Feature-20230707-124132.yaml new file mode 100644 index 000000000..4ad93ad22 --- /dev/null +++ b/.changes/unreleased/Feature-20230707-124132.yaml @@ -0,0 +1,6 @@ +kind: Feature +body: '[export] Add ordering by person''s lastname or course opening date in list + which concerns accompanying course or peoples' +time: 2023-07-07T12:41:32.112725962+02:00 +custom: + Issue: "" diff --git a/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriod.php b/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriod.php index 3f7821bbc..ab9c0db2f 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriod.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriod.php @@ -133,6 +133,11 @@ final readonly class ListAccompanyingPeriod implements ListInterface, GroupedExp $this->listAccompanyingPeriodHelper->addSelectClauses($qb, $this->rollingDateConverter->convert($data['calc_date'])); + $qb + ->addOrderBy('acp.openingDate') + ->addOrderBy('acp.closingDate') + ->addOrderBy('acp.id'); + return $qb; } diff --git a/src/Bundle/ChillPersonBundle/Export/Export/ListPersonHavingAccompanyingPeriod.php b/src/Bundle/ChillPersonBundle/Export/Export/ListPersonHavingAccompanyingPeriod.php index f2e4de4e3..408d0b3af 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/ListPersonHavingAccompanyingPeriod.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/ListPersonHavingAccompanyingPeriod.php @@ -190,6 +190,11 @@ class ListPersonHavingAccompanyingPeriod implements ExportElementValidatedInterf $this->listPersonHelper->addSelect($qb, $fields, $data['address_date']); + $qb + ->addOrderBy('person.lastName') + ->addOrderBy('person.firstName') + ->addOrderBy('person.id'); + return $qb; } diff --git a/src/Bundle/ChillPersonBundle/Export/Export/ListPersonWithAccompanyingPeriodDetails.php b/src/Bundle/ChillPersonBundle/Export/Export/ListPersonWithAccompanyingPeriodDetails.php index 295d87842..ddb16bb2d 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/ListPersonWithAccompanyingPeriodDetails.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/ListPersonWithAccompanyingPeriodDetails.php @@ -134,6 +134,12 @@ final readonly class ListPersonWithAccompanyingPeriodDetails implements ListInte $this->listPersonHelper->addSelect($qb, ListPersonHelper::FIELDS, $this->rollingDateConverter->convert($data['address_date'])); $this->listAccompanyingPeriodHelper->addSelectClauses($qb, $this->rollingDateConverter->convert($data['address_date'])); + $qb + ->addOrderBy('person.lastName') + ->addOrderBy('person.firstName') + ->addOrderBy('person.id') + ->addOrderBy('acp.id'); + return $qb; } From 197d69ef4a09fffd359305b8e1ad0a6f03f466b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Fri, 7 Jul 2023 13:21:22 +0200 Subject: [PATCH 263/321] release v2.4.0 --- .changes/unreleased/DX-20230629-160029.yaml | 5 --- .../unreleased/Feature-20230629-131558.yaml | 6 --- .../unreleased/Feature-20230629-173445.yaml | 5 --- .../unreleased/Feature-20230629-173509.yaml | 5 --- .../unreleased/Feature-20230629-173544.yaml | 5 --- .../unreleased/Feature-20230629-173617.yaml | 5 --- .../unreleased/Feature-20230629-173822.yaml | 5 --- .../unreleased/Feature-20230629-173844.yaml | 5 --- .../unreleased/Feature-20230705-220544.yaml | 6 --- .../unreleased/Feature-20230706-213428.yaml | 5 --- .../unreleased/Fixed-20230627-110233.yaml | 6 --- .../unreleased/Fixed-20230628-170055.yaml | 6 --- .../unreleased/Fixed-20230629-124412.yaml | 6 --- .../unreleased/Fixed-20230629-231503.yaml | 5 --- .../unreleased/Fixed-20230630-171119.yaml | 5 --- .../unreleased/Fixed-20230630-171153.yaml | 5 --- .../unreleased/Fixed-20230706-220125.yaml | 6 --- .changes/v2.4.0.md | 36 ++++++++++++++++++ CHANGELOG.md | 37 +++++++++++++++++++ 19 files changed, 73 insertions(+), 91 deletions(-) delete mode 100644 .changes/unreleased/DX-20230629-160029.yaml delete mode 100644 .changes/unreleased/Feature-20230629-131558.yaml delete mode 100644 .changes/unreleased/Feature-20230629-173445.yaml delete mode 100644 .changes/unreleased/Feature-20230629-173509.yaml delete mode 100644 .changes/unreleased/Feature-20230629-173544.yaml delete mode 100644 .changes/unreleased/Feature-20230629-173617.yaml delete mode 100644 .changes/unreleased/Feature-20230629-173822.yaml delete mode 100644 .changes/unreleased/Feature-20230629-173844.yaml delete mode 100644 .changes/unreleased/Feature-20230705-220544.yaml delete mode 100644 .changes/unreleased/Feature-20230706-213428.yaml delete mode 100644 .changes/unreleased/Fixed-20230627-110233.yaml delete mode 100644 .changes/unreleased/Fixed-20230628-170055.yaml delete mode 100644 .changes/unreleased/Fixed-20230629-124412.yaml delete mode 100644 .changes/unreleased/Fixed-20230629-231503.yaml delete mode 100644 .changes/unreleased/Fixed-20230630-171119.yaml delete mode 100644 .changes/unreleased/Fixed-20230630-171153.yaml delete mode 100644 .changes/unreleased/Fixed-20230706-220125.yaml create mode 100644 .changes/v2.4.0.md diff --git a/.changes/unreleased/DX-20230629-160029.yaml b/.changes/unreleased/DX-20230629-160029.yaml deleted file mode 100644 index b83befec6..000000000 --- a/.changes/unreleased/DX-20230629-160029.yaml +++ /dev/null @@ -1,5 +0,0 @@ -kind: DX -body: 'Rolling Date: can receive a null parameter' -time: 2023-06-29T16:00:29.664814895+02:00 -custom: - Issue: "" diff --git a/.changes/unreleased/Feature-20230629-131558.yaml b/.changes/unreleased/Feature-20230629-131558.yaml deleted file mode 100644 index 42d731c4f..000000000 --- a/.changes/unreleased/Feature-20230629-131558.yaml +++ /dev/null @@ -1,6 +0,0 @@ -kind: Feature -body: '[export] on "filter by user working" on accompanying period, add two dates - to filters intervention within a period' -time: 2023-06-29T13:15:58.070316708+02:00 -custom: - Issue: "113" diff --git a/.changes/unreleased/Feature-20230629-173445.yaml b/.changes/unreleased/Feature-20230629-173445.yaml deleted file mode 100644 index 2d3642a85..000000000 --- a/.changes/unreleased/Feature-20230629-173445.yaml +++ /dev/null @@ -1,5 +0,0 @@ -kind: Feature -body: '[export] Add an aggregator by user''s job working on a course' -time: 2023-06-29T17:34:45.278993433+02:00 -custom: - Issue: "113" diff --git a/.changes/unreleased/Feature-20230629-173509.yaml b/.changes/unreleased/Feature-20230629-173509.yaml deleted file mode 100644 index 95fd23458..000000000 --- a/.changes/unreleased/Feature-20230629-173509.yaml +++ /dev/null @@ -1,5 +0,0 @@ -kind: Feature -body: '[export] add an aggregator by user''s scope working on a course' -time: 2023-06-29T17:35:09.548758741+02:00 -custom: - Issue: "113" diff --git a/.changes/unreleased/Feature-20230629-173544.yaml b/.changes/unreleased/Feature-20230629-173544.yaml deleted file mode 100644 index 94e79bc6d..000000000 --- a/.changes/unreleased/Feature-20230629-173544.yaml +++ /dev/null @@ -1,5 +0,0 @@ -kind: Feature -body: '[export] on aggregator "user working on a course"' -time: 2023-06-29T17:35:44.998468724+02:00 -custom: - Issue: "" diff --git a/.changes/unreleased/Feature-20230629-173617.yaml b/.changes/unreleased/Feature-20230629-173617.yaml deleted file mode 100644 index 445b85cff..000000000 --- a/.changes/unreleased/Feature-20230629-173617.yaml +++ /dev/null @@ -1,5 +0,0 @@ -kind: Feature -body: '[export] add a center aggregator for Person' -time: 2023-06-29T17:36:17.635876613+02:00 -custom: - Issue: "113" diff --git a/.changes/unreleased/Feature-20230629-173822.yaml b/.changes/unreleased/Feature-20230629-173822.yaml deleted file mode 100644 index 6a1569d00..000000000 --- a/.changes/unreleased/Feature-20230629-173822.yaml +++ /dev/null @@ -1,5 +0,0 @@ -kind: Feature -body: '[export] add a filter on "job working on a course"' -time: 2023-06-29T17:38:22.682951416+02:00 -custom: - Issue: "113" diff --git a/.changes/unreleased/Feature-20230629-173844.yaml b/.changes/unreleased/Feature-20230629-173844.yaml deleted file mode 100644 index f307ebf57..000000000 --- a/.changes/unreleased/Feature-20230629-173844.yaml +++ /dev/null @@ -1,5 +0,0 @@ -kind: Feature -body: '[export] Add a filter on "scope working on a course"' -time: 2023-06-29T17:38:44.238287822+02:00 -custom: - Issue: "113" diff --git a/.changes/unreleased/Feature-20230705-220544.yaml b/.changes/unreleased/Feature-20230705-220544.yaml deleted file mode 100644 index 4212f7646..000000000 --- a/.changes/unreleased/Feature-20230705-220544.yaml +++ /dev/null @@ -1,6 +0,0 @@ -kind: Feature -body: Create a role "See Confidential Periods", separated from the "Reassign courses" - role -time: 2023-07-05T22:05:44.435112463+02:00 -custom: - Issue: "121" diff --git a/.changes/unreleased/Feature-20230706-213428.yaml b/.changes/unreleased/Feature-20230706-213428.yaml deleted file mode 100644 index 092e5a2e0..000000000 --- a/.changes/unreleased/Feature-20230706-213428.yaml +++ /dev/null @@ -1,5 +0,0 @@ -kind: Feature -body: 'Sync user absence / presence through microsoft outlook / graph api. ' -time: 2023-07-06T21:34:28.973144334+02:00 -custom: - Issue: "124" diff --git a/.changes/unreleased/Fixed-20230627-110233.yaml b/.changes/unreleased/Fixed-20230627-110233.yaml deleted file mode 100644 index 58bb23933..000000000 --- a/.changes/unreleased/Fixed-20230627-110233.yaml +++ /dev/null @@ -1,6 +0,0 @@ -kind: Fixed -body: On the accompanying course page, open the action on view mode if the user does - not have right to update them (i.e. if the accompanying period is closed) -time: 2023-06-27T11:02:33.027807027+02:00 -custom: - Issue: "116" diff --git a/.changes/unreleased/Fixed-20230628-170055.yaml b/.changes/unreleased/Fixed-20230628-170055.yaml deleted file mode 100644 index 7f9ec3028..000000000 --- a/.changes/unreleased/Fixed-20230628-170055.yaml +++ /dev/null @@ -1,6 +0,0 @@ -kind: Fixed -body: '[export] Rename label for CurrentActionFilter (on accompanying period work) - to make precision between "ouvert" and "sans date de fin"' -time: 2023-06-28T17:00:55.206937751+02:00 -custom: - Issue: "" diff --git a/.changes/unreleased/Fixed-20230629-124412.yaml b/.changes/unreleased/Fixed-20230629-124412.yaml deleted file mode 100644 index 7fc3d3eb0..000000000 --- a/.changes/unreleased/Fixed-20230629-124412.yaml +++ /dev/null @@ -1,6 +0,0 @@ -kind: Fixed -body: Force the db to have either a person_location or a address_location, and avoid - to have both also internally in the entity -time: 2023-06-29T12:44:12.019663991+02:00 -custom: - Issue: "" diff --git a/.changes/unreleased/Fixed-20230629-231503.yaml b/.changes/unreleased/Fixed-20230629-231503.yaml deleted file mode 100644 index e021d1fda..000000000 --- a/.changes/unreleased/Fixed-20230629-231503.yaml +++ /dev/null @@ -1,5 +0,0 @@ -kind: Fixed -body: '[export] set rolling date on person age aggregator' -time: 2023-06-29T23:15:03.20841309+02:00 -custom: - Issue: "" diff --git a/.changes/unreleased/Fixed-20230630-171119.yaml b/.changes/unreleased/Fixed-20230630-171119.yaml deleted file mode 100644 index f3185ace2..000000000 --- a/.changes/unreleased/Fixed-20230630-171119.yaml +++ /dev/null @@ -1,5 +0,0 @@ -kind: Fixed -body: '[export] fix list when a person locating a course is without address' -time: 2023-06-30T17:11:19.454081914+02:00 -custom: - Issue: "" diff --git a/.changes/unreleased/Fixed-20230630-171153.yaml b/.changes/unreleased/Fixed-20230630-171153.yaml deleted file mode 100644 index c09bd93d0..000000000 --- a/.changes/unreleased/Fixed-20230630-171153.yaml +++ /dev/null @@ -1,5 +0,0 @@ -kind: Fixed -body: '[export] remove unused condition on course about duration participation' -time: 2023-06-30T17:11:53.076615549+02:00 -custom: - Issue: "" diff --git a/.changes/unreleased/Fixed-20230706-220125.yaml b/.changes/unreleased/Fixed-20230706-220125.yaml deleted file mode 100644 index b9449d514..000000000 --- a/.changes/unreleased/Fixed-20230706-220125.yaml +++ /dev/null @@ -1,6 +0,0 @@ -kind: Fixed -body: 'Command to subscribe on MS Graph users calendars: improve the loop to be more - efficient' -time: 2023-07-06T22:01:25.847374805+02:00 -custom: - Issue: "" diff --git a/.changes/v2.4.0.md b/.changes/v2.4.0.md new file mode 100644 index 000000000..522957300 --- /dev/null +++ b/.changes/v2.4.0.md @@ -0,0 +1,36 @@ +## v2.4.0 - 2023-07-07 + +### Feature +* ([#113](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/113)) [export] on "filter by user working" on accompanying period, add two dates to filters intervention within a period +* ([#113](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/113)) [export] Add an aggregator by user's job working on a course +* ([#113](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/113)) [export] add an aggregator by user's scope working on a course +* [export] on aggregator "user working on a course" +* ([#113](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/113)) [export] add a center aggregator for Person +* ([#113](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/113)) [export] add a filter on "job working on a course" +* ([#113](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/113)) [export] Add a filter on "scope working on a course" +* ([#121](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/121)) Create a role "See Confidential Periods", separated from the "Reassign courses" role +* ([#124](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/124)) Sync user absence / presence through microsoft outlook / graph api. + +### Fixed +* ([#116](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/116)) On the accompanying course page, open the action on view mode if the user does not have right to update them (i.e. if the accompanying period is closed) +* [export] Rename label for CurrentActionFilter (on accompanying period work) to make precision between "ouvert" and "sans date de fin" +* Force the db to have either a person_location or a address_location, and avoid to have both also internally in the entity +* [export] set rolling date on person age aggregator +* [export] fix list when a person locating a course is without address +* [export] remove unused condition on course about duration participation +* Command to subscribe on MS Graph users calendars: improve the loop to be more efficient + +### DX +* Rolling Date: can receive a null parameter + +### Traduction francophone des principaux changements + +- sur le "filtre par intervenant", ajoute deux dates pour limiter la période d'intervention; +- ajout d'un regroupement par métier des intervenants sur un parcours; +- ajout d'un regroupement par service des intervenants sur un parcours; +- ajout d'un regroupement par utilisateur intervenant sur un parcours +- ajout d'un regroupement "par centre de l'usager"; +- ajout d'un filtre "par métier intervenant sur un parcours"; +- ajout d'un filtre "par service intervenant sur un parcours"; +- création d'un rôle spécifique pour voir les parcours confidentiels (et séparer de celui de la liste qui permet de ré-assigner les parcours en lot); +- synchronisation de l'absence des utilisateurs par microsoft graph api diff --git a/CHANGELOG.md b/CHANGELOG.md index 93ff93556..b74eea58d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,43 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), and is generated by [Changie](https://github.com/miniscruff/changie). +## v2.4.0 - 2023-07-07 + +### Feature +* ([#113](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/113)) [export] on "filter by user working" on accompanying period, add two dates to filters intervention within a period +* ([#113](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/113)) [export] Add an aggregator by user's job working on a course +* ([#113](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/113)) [export] add an aggregator by user's scope working on a course +* [export] on aggregator "user working on a course" +* ([#113](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/113)) [export] add a center aggregator for Person +* ([#113](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/113)) [export] add a filter on "job working on a course" +* ([#113](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/113)) [export] Add a filter on "scope working on a course" +* ([#121](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/121)) Create a role "See Confidential Periods", separated from the "Reassign courses" role +* ([#124](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/124)) Sync user absence / presence through microsoft outlook / graph api. + +### Fixed +* ([#116](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/116)) On the accompanying course page, open the action on view mode if the user does not have right to update them (i.e. if the accompanying period is closed) +* [export] Rename label for CurrentActionFilter (on accompanying period work) to make precision between "ouvert" and "sans date de fin" +* Force the db to have either a person_location or a address_location, and avoid to have both also internally in the entity +* [export] set rolling date on person age aggregator +* [export] fix list when a person locating a course is without address +* [export] remove unused condition on course about duration participation +* Command to subscribe on MS Graph users calendars: improve the loop to be more efficient + +### DX +* Rolling Date: can receive a null parameter + +### Traduction francophone des principaux changements + +- sur le "filtre par intervenant", ajoute deux dates pour limiter la période d'intervention; +- ajout d'un regroupement par métier des intervenants sur un parcours; +- ajout d'un regroupement par service des intervenants sur un parcours; +- ajout d'un regroupement par utilisateur intervenant sur un parcours +- ajout d'un regroupement "par centre de l'usager"; +- ajout d'un filtre "par métier intervenant sur un parcours"; +- ajout d'un filtre "par service intervenant sur un parcours"; +- création d'un rôle spécifique pour voir les parcours confidentiels (et séparer de celui de la liste qui permet de ré-assigner les parcours en lot); +- synchronisation de l'absence des utilisateurs par microsoft graph api + ## v2.3.0 - 2023-06-27 ### Feature * ([#110](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/110)) Edit saved exports options: the saved exports options (forms, filters, aggregators) are now editable. From 20e64e87680d102c686000f1c35d0139d00eecdf Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Fri, 7 Jul 2023 15:41:29 +0200 Subject: [PATCH 264/321] test filterOrder in an accordion --- .../views/FilterOrder/base.html.twig | 162 ++++++++++-------- 1 file changed, 86 insertions(+), 76 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Resources/views/FilterOrder/base.html.twig b/src/Bundle/ChillMainBundle/Resources/views/FilterOrder/base.html.twig index b2673b60c..f642c82aa 100644 --- a/src/Bundle/ChillMainBundle/Resources/views/FilterOrder/base.html.twig +++ b/src/Bundle/ChillMainBundle/Resources/views/FilterOrder/base.html.twig @@ -1,92 +1,102 @@ {{ form_start(form) }} - {% set btnSubmit = 0 %} -
      -
      - {% if form.vars.has_search_box %} -
      -
      - {{ form_widget(form.q) }} - -
      -
      - {% endif %} -
      - {% if form.dateRanges is defined %} - {% set btnSubmit = 1 %} - {% if form.dateRanges|length > 0 %} - {% for dateRangeName, _o in form.dateRanges %} -
      - {% if form.dateRanges[dateRangeName].vars.label is not same as(false) %} - {{ form_label(form.dateRanges[dateRangeName])}} - {% else %} -
      {{ 'activity_filter.By date'|trans }}
      - {% endif %} -
      -
      - {{ 'chill_calendar.From'|trans }} - {{ form_widget(form.dateRanges[dateRangeName]['from']) }} - {{ 'chill_calendar.To'|trans }} - {{ form_widget(form.dateRanges[dateRangeName]['to']) }} -
      +
      +

      + +

      +
      + {% set btnSubmit = 0 %} +
      +
      + {% if form.vars.has_search_box %} +
      +
      + {{ form_widget(form.q) }} +
      - {% endfor %} + {% endif %} +
      + {% if form.dateRanges is defined %} + {% set btnSubmit = 1 %} + {% if form.dateRanges|length > 0 %} + {% for dateRangeName, _o in form.dateRanges %} +
      + {% if form.dateRanges[dateRangeName].vars.label is not same as(false) %} + {{ form_label(form.dateRanges[dateRangeName])}} + {% else %} +
      {{ 'activity_filter.By date'|trans }}
      + {% endif %} +
      +
      + {{ 'chill_calendar.From'|trans }} + {{ form_widget(form.dateRanges[dateRangeName]['from']) }} + {{ 'chill_calendar.To'|trans }} + {{ form_widget(form.dateRanges[dateRangeName]['to']) }} +
      +
      +
      + {% endfor %} + {% endif %} {% endif %} - {% endif %} - {% if form.checkboxes is defined %} - {% set btnSubmit = 1 %} - {% if form.checkboxes|length > 0 %} - {% for checkbox_name, options in form.checkboxes %} + {% if form.checkboxes is defined %} + {% set btnSubmit = 1 %} + {% if form.checkboxes|length > 0 %} + {% for checkbox_name, options in form.checkboxes %} +
      +
      {{ 'activity_filter.By'|trans }}
      +
      + {% for c in form['checkboxes'][checkbox_name].children %} + {{ form_widget(c) }} + {{ form_label(c) }} + {% endfor %} +
      +
      + {% endfor %} + {% endif %} + {% endif %} + {% if form.entity_choices is defined %} + {% set btnSubmit = 1 %} + {% if form.entity_choices |length > 0 %} + {% for checkbox_name, options in form.entity_choices %} +
      + {% if form.entity_choices[checkbox_name].vars.label is not same as(false) %} + {{ form_label(form.entity_choices[checkbox_name])}} + {% endif %} +
      + {% for c in form['entity_choices'][checkbox_name].children %} + {{ form_widget(c) }} + {{ form_label(c) }} + {% endfor %} +
      +
      + {% endfor %} + {% endif %} + {% endif %} + {% if form.single_checkboxes is defined %} + {% set btnSubmit = 1 %} + {% for name, _o in form.single_checkboxes %}
      {{ 'activity_filter.By'|trans }}
      - {% for c in form['checkboxes'][checkbox_name].children %} - {{ form_widget(c) }} - {{ form_label(c) }} - {% endfor %} + {{ form_widget(form.single_checkboxes[name]) }}
      {% endfor %} {% endif %} - {% endif %} - {% if form.entity_choices is defined %} - {% set btnSubmit = 1 %} - {% if form.entity_choices |length > 0 %} - {% for checkbox_name, options in form.entity_choices %} -
      - {% if form.entity_choices[checkbox_name].vars.label is not same as(false) %} - {{ form_label(form.entity_choices[checkbox_name])}} - {% endif %} -
      - {% for c in form['entity_choices'][checkbox_name].children %} - {{ form_widget(c) }} - {{ form_label(c) }} - {% endfor %} -
      -
      - {% endfor %} - {% endif %} - {% endif %} - {% if form.single_checkboxes is defined %} - {% set btnSubmit = 1 %} - {% for name, _o in form.single_checkboxes %} + + {% if btnSubmit == 1 %}
      -
      {{ 'activity_filter.By'|trans }}
      -
      - {{ form_widget(form.single_checkboxes[name]) }} -
      +
      - {% endfor %} - {% endif %} - - {% if btnSubmit == 1 %} -
      - -
      - {% endif %} + {% endif %} +
      +
      - {% for k,v in otherParameters %} - - {% endfor %} +{% for k,v in otherParameters %} + +{% endfor %} {{ form_end(form) }} + From 6bdb3e969538bc3cf0ad3458d5015d3ab180626e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Fri, 7 Jul 2023 21:49:36 +0200 Subject: [PATCH 265/321] fix typo which prevent to apply a filter on activity types --- .../ChillActivityBundle/Controller/ActivityController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Bundle/ChillActivityBundle/Controller/ActivityController.php b/src/Bundle/ChillActivityBundle/Controller/ActivityController.php index 9b6e69bf0..1e911ff08 100644 --- a/src/Bundle/ChillActivityBundle/Controller/ActivityController.php +++ b/src/Bundle/ChillActivityBundle/Controller/ActivityController.php @@ -259,7 +259,7 @@ final class ActivityController extends AbstractController $filterArgs = [ 'my_activities' => $filter->getSingleCheckboxData('my_activities'), - 'types' => $filter->hasEntityChoice('activity_type') ? $filter->getEntityChoiceData('activity_types') : [], + 'types' => $filter->hasEntityChoice('activity_types') ? $filter->getEntityChoiceData('activity_types') : [], 'jobs' => $filter->hasEntityChoice('jobs') ? $filter->getEntityChoiceData('jobs') : [], 'before' => $filter->getDateRangeData('activity_date')['to'], 'after' => $filter->getDateRangeData('activity_date')['from'], From 39896ea6e26e3cb2392830b2e18c9bb8f396cefe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Mon, 10 Jul 2023 15:26:54 +0200 Subject: [PATCH 266/321] [FilterOrder] add a method to get all the active filters --- .../Form/Type/Listing/FilterOrderType.php | 25 +++--- .../views/FilterOrder/base.html.twig | 13 ++- .../Templating/Listing/FilterOrderHelper.php | 79 ++++++++++++++++--- .../Listing/FilterOrderHelperBuilder.php | 10 ++- .../Listing/FilterOrderHelperFactory.php | 8 +- .../Listing/FilterOrderPositionEnum.php | 12 +++ .../translations/messages+intl-icu.fr.yaml | 5 ++ 7 files changed, 126 insertions(+), 26 deletions(-) create mode 100644 src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderPositionEnum.php diff --git a/src/Bundle/ChillMainBundle/Form/Type/Listing/FilterOrderType.php b/src/Bundle/ChillMainBundle/Form/Type/Listing/FilterOrderType.php index 1f373400c..d16ce3813 100644 --- a/src/Bundle/ChillMainBundle/Form/Type/Listing/FilterOrderType.php +++ b/src/Bundle/ChillMainBundle/Form/Type/Listing/FilterOrderType.php @@ -47,16 +47,7 @@ final class FilterOrderType extends \Symfony\Component\Form\AbstractType $checkboxesBuilder = $builder->create('checkboxes', null, ['compound' => true]); foreach ($helper->getCheckboxes() as $name => $c) { - $choices = array_combine( - array_map(static function ($c, $t) { - if (null !== $t) { - return $t; - } - - return $c; - }, $c['choices'], $c['trans']), - $c['choices'] - ); + $choices = self::buildCheckboxChoices($c['choices'], $c['trans']); $checkboxesBuilder->add($name, ChoiceType::class, [ 'choices' => $choices, @@ -125,6 +116,20 @@ final class FilterOrderType extends \Symfony\Component\Form\AbstractType } } + public static function buildCheckboxChoices(array $choices, array $trans = []): array + { + return array_combine( + array_map(static function ($c, $t) { + if (null !== $t) { + return $t; + } + + return $c; + }, $choices, $trans), + $choices + ); + } + public function buildView(FormView $view, FormInterface $form, array $options) { /** @var FilterOrderHelper $helper */ diff --git a/src/Bundle/ChillMainBundle/Resources/views/FilterOrder/base.html.twig b/src/Bundle/ChillMainBundle/Resources/views/FilterOrder/base.html.twig index f642c82aa..4de7604cf 100644 --- a/src/Bundle/ChillMainBundle/Resources/views/FilterOrder/base.html.twig +++ b/src/Bundle/ChillMainBundle/Resources/views/FilterOrder/base.html.twig @@ -85,7 +85,7 @@
      {% endfor %} {% endif %} - + {% if btnSubmit == 1 %}
      @@ -93,6 +93,17 @@ {% endif %}
      + {% set active = helper.getActiveFilters() %} + {% if active|length > 0 %} +
      + {% for f in active %} + {% if f.label != '' %}{{ f.label|trans }} : {% endif %}{{ f.value }} + {% endfor %} +
      + {% endif %} +
      + +
      {% for k,v in otherParameters %} diff --git a/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelper.php b/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelper.php index c0ef1cd89..a038dfd71 100644 --- a/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelper.php +++ b/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelper.php @@ -13,16 +13,19 @@ namespace Chill\MainBundle\Templating\Listing; use Chill\MainBundle\Form\Type\Listing\FilterOrderType; use DateTimeImmutable; -use Symfony\Component\Form\Extension\Core\Type\FormType; -use Symfony\Component\Form\Extension\Core\Type\HiddenType; use Symfony\Component\Form\FormFactoryInterface; use Symfony\Component\Form\FormInterface; use Symfony\Component\HttpFoundation\RequestStack; +use Symfony\Component\PropertyAccess\PropertyAccessor; +use Symfony\Component\PropertyAccess\PropertyAccessorInterface; +use Symfony\Component\PropertyAccess\PropertyPath; +use Symfony\Component\PropertyAccess\PropertyPathInterface; +use Symfony\Contracts\Translation\TranslatorInterface; use function array_merge; use function count; -class FilterOrderHelper +final class FilterOrderHelper { private array $checkboxes = []; @@ -33,16 +36,12 @@ class FilterOrderHelper private array $dateRanges = []; - private FormFactoryInterface $formFactory; - public const FORM_NAME = 'f'; private array $formOptions = []; private string $formType = FilterOrderType::class; - private RequestStack $requestStack; - private ?array $searchBoxFields = null; private ?array $submitted = null; @@ -52,12 +51,13 @@ class FilterOrderHelper */ private array $entityChoices = []; + public function __construct( - FormFactoryInterface $formFactory, - RequestStack $requestStack + private readonly FormFactoryInterface $formFactory, + private readonly RequestStack $requestStack, + private readonly TranslatorInterface $translator, + private readonly PropertyAccessorInterface $propertyAccessor, ) { - $this->formFactory = $formFactory; - $this->requestStack = $requestStack; } public function addSingleCheckbox(string $name, string $label): self @@ -199,6 +199,63 @@ class FilterOrderHelper return $this; } + /** + * Return all the data required to display the active filters + * + * @return array + */ + public function getActiveFilters(): array + { + $result = []; + + if ($this->hasSearchBox() && '' !== $this->getQueryString()) { + $result[] = ['label' => '', 'value' => $this->getQueryString(), 'position' => FilterOrderPositionEnum::SearchBox->value, 'name' => 'q']; + } + + foreach ($this->dateRanges as $name => ['label' => $label]) { + $base = ['position' => FilterOrderPositionEnum::DateRange->value, 'name' => $name, 'label' => (string) $label]; + + if (null !== ($from = $this->getDateRangeData($name)['from'] ?? null)) { + $result[] = ['value' => $this->translator->trans('filter_order.by_date.From', ['from_date' => $from]), ...$base]; + } + if (null !== ($to = $this->getDateRangeData($name)['to'] ?? null)) { + $result[] = ['value' => $this->translator->trans('filter_order.by_date.To', ['to_date' => $to]), ...$base]; + } + } + + foreach ($this->checkboxes as $name => ['choices' => $choices, 'trans' => $trans, 'options' => $options]) { + foreach ($this->getCheckboxData($name) as $keyChoice) { + $result[] = ['value' => $choices['keyChoice'], 'label' => $options['label'], 'position' => FilterOrderPositionEnum::Checkboxes->value, 'name' => $name]; + } + } + + foreach ($this->entityChoices as $name => ['label' => $label, 'class' => $class, 'choices' => $choices, 'options' => $options]) { + foreach ($this->getEntityChoiceData($name) as $selected) { + if (is_callable($options['choice_label'])) { + $value = call_user_func($options['choice_label'], $selected); + } elseif ($options['choice_label'] instanceof PropertyPathInterface || is_string($options['choice_label'])) { + $value = $this->propertyAccessor->getValue($selected, $options['choice_label']); + } else { + if (!$selected instanceof \Stringable) { + throw new \UnexpectedValueException(sprintf("we are not able to transform the value of %s to a string. Implements \Stringable or add a 'choice_label' option to the filterFormBuilder", get_class($selected))); + } + + $value = (string) $selected; + } + + $result[] = ['value' => $value, 'label' => $label, 'position' => FilterOrderPositionEnum::EntityChoice->value, 'name' => $name]; + } + } + + foreach ($this->singleCheckbox as $name => ['label' => $label]) { + if (true === $this->getSingleCheckboxData($name)) { + $result[] = ['label' => '', 'value' => $this->translator->trans($label), 'position' => FilterOrderPositionEnum::SingleCheckbox->value, 'name' => $name]; + } + } + + return $result; + } + private function getDefaultData(): array { $r = [ diff --git a/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelperBuilder.php b/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelperBuilder.php index e176e27c6..dfa361f6e 100644 --- a/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelperBuilder.php +++ b/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelperBuilder.php @@ -14,6 +14,8 @@ namespace Chill\MainBundle\Templating\Listing; use DateTimeImmutable; use Symfony\Component\Form\FormFactoryInterface; use Symfony\Component\HttpFoundation\RequestStack; +use Symfony\Component\PropertyAccess\PropertyAccessorInterface; +use Symfony\Contracts\Translation\TranslatorInterface; class FilterOrderHelperBuilder { @@ -39,7 +41,9 @@ class FilterOrderHelperBuilder public function __construct( FormFactoryInterface $formFactory, - RequestStack $requestStack + RequestStack $requestStack, + private readonly TranslatorInterface $translator, + private readonly PropertyAccessorInterface $propertyAccessor, ) { $this->formFactory = $formFactory; $this->requestStack = $requestStack; @@ -87,7 +91,9 @@ class FilterOrderHelperBuilder { $helper = new FilterOrderHelper( $this->formFactory, - $this->requestStack + $this->requestStack, + $this->translator, + $this->propertyAccessor ); $helper->setSearchBox($this->searchBoxFields); diff --git a/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelperFactory.php b/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelperFactory.php index c88c71af5..3fbb2864d 100644 --- a/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelperFactory.php +++ b/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelperFactory.php @@ -13,6 +13,8 @@ namespace Chill\MainBundle\Templating\Listing; use Symfony\Component\Form\FormFactoryInterface; use Symfony\Component\HttpFoundation\RequestStack; +use Symfony\Component\PropertyAccess\PropertyAccessorInterface; +use Symfony\Contracts\Translation\TranslatorInterface; class FilterOrderHelperFactory implements FilterOrderHelperFactoryInterface { @@ -22,7 +24,9 @@ class FilterOrderHelperFactory implements FilterOrderHelperFactoryInterface public function __construct( FormFactoryInterface $formFactory, - RequestStack $requestStack + RequestStack $requestStack, + private readonly TranslatorInterface $translator, + private readonly PropertyAccessorInterface $propertyAccessor, ) { $this->formFactory = $formFactory; $this->requestStack = $requestStack; @@ -30,6 +34,6 @@ class FilterOrderHelperFactory implements FilterOrderHelperFactoryInterface public function create(string $context, ?array $options = []): FilterOrderHelperBuilder { - return new FilterOrderHelperBuilder($this->formFactory, $this->requestStack); + return new FilterOrderHelperBuilder($this->formFactory, $this->requestStack, $this->translator, $this->propertyAccessor); } } diff --git a/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderPositionEnum.php b/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderPositionEnum.php new file mode 100644 index 000000000..cda8119f5 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderPositionEnum.php @@ -0,0 +1,12 @@ + Date: Mon, 10 Jul 2023 15:39:00 +0200 Subject: [PATCH 267/321] [filterOrder] fix error in method getActiveFilters when dealing with entityChoice with incorrect number of translation --- .../Templating/Listing/FilterOrderHelper.php | 13 ++++++++----- .../Templating/Listing/FilterOrderPositionEnum.php | 9 +++++++++ 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelper.php b/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelper.php index a038dfd71..701238208 100644 --- a/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelper.php +++ b/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelper.php @@ -84,9 +84,11 @@ final class FilterOrderHelper public function addCheckbox(string $name, array $choices, ?array $default = [], ?array $trans = [], array $options = []): self { - $missing = count($choices) - count($trans) - 1; + $missing = count($choices) - count($trans); + $this->checkboxes[$name] = [ - 'choices' => $choices, 'default' => $default, + 'choices' => $choices, + 'default' => $default, 'trans' => array_merge( $trans, 0 < $missing ? @@ -223,9 +225,10 @@ final class FilterOrderHelper } } - foreach ($this->checkboxes as $name => ['choices' => $choices, 'trans' => $trans, 'options' => $options]) { + foreach ($this->checkboxes as $name => ['choices' => $choices, 'trans' => $trans]) { + $translatedChoice = array_combine($choices, [...$trans]); foreach ($this->getCheckboxData($name) as $keyChoice) { - $result[] = ['value' => $choices['keyChoice'], 'label' => $options['label'], 'position' => FilterOrderPositionEnum::Checkboxes->value, 'name' => $name]; + $result[] = ['value' => $translatedChoice[$keyChoice], 'label' => '', 'position' => FilterOrderPositionEnum::Checkboxes->value, 'name' => $name]; } } @@ -237,7 +240,7 @@ final class FilterOrderHelper $value = $this->propertyAccessor->getValue($selected, $options['choice_label']); } else { if (!$selected instanceof \Stringable) { - throw new \UnexpectedValueException(sprintf("we are not able to transform the value of %s to a string. Implements \Stringable or add a 'choice_label' option to the filterFormBuilder", get_class($selected))); + throw new \UnexpectedValueException(sprintf("we are not able to transform the value of %s to a string. Implements \\Stringable or add a 'choice_label' option to the filterFormBuilder", get_class($selected))); } $value = (string) $selected; diff --git a/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderPositionEnum.php b/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderPositionEnum.php index cda8119f5..09e8d39aa 100644 --- a/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderPositionEnum.php +++ b/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderPositionEnum.php @@ -1,5 +1,14 @@ Date: Mon, 10 Jul 2023 15:55:05 +0200 Subject: [PATCH 268/321] render active filters like pills --- .../Resources/views/FilterOrder/base.html.twig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Resources/views/FilterOrder/base.html.twig b/src/Bundle/ChillMainBundle/Resources/views/FilterOrder/base.html.twig index 4de7604cf..7a05a2f80 100644 --- a/src/Bundle/ChillMainBundle/Resources/views/FilterOrder/base.html.twig +++ b/src/Bundle/ChillMainBundle/Resources/views/FilterOrder/base.html.twig @@ -95,9 +95,9 @@
      {% set active = helper.getActiveFilters() %} {% if active|length > 0 %} -
      +
      {% for f in active %} - {% if f.label != '' %}{{ f.label|trans }} : {% endif %}{{ f.value }} + {% if f.label != '' %}{{ f.label|trans }} : {% endif %}{{ f.value }} {% endfor %}
      {% endif %} From 0d365e16e58df1614b132fc4b1fa2dc655458e3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Mon, 10 Jul 2023 15:59:17 +0200 Subject: [PATCH 269/321] add missing translations --- .../ChillMainBundle/Templating/Listing/FilterOrderHelper.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelper.php b/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelper.php index 701238208..2b24ffa0d 100644 --- a/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelper.php +++ b/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelper.php @@ -228,7 +228,7 @@ final class FilterOrderHelper foreach ($this->checkboxes as $name => ['choices' => $choices, 'trans' => $trans]) { $translatedChoice = array_combine($choices, [...$trans]); foreach ($this->getCheckboxData($name) as $keyChoice) { - $result[] = ['value' => $translatedChoice[$keyChoice], 'label' => '', 'position' => FilterOrderPositionEnum::Checkboxes->value, 'name' => $name]; + $result[] = ['value' => $this->translator->trans($translatedChoice[$keyChoice]), 'label' => '', 'position' => FilterOrderPositionEnum::Checkboxes->value, 'name' => $name]; } } @@ -246,7 +246,7 @@ final class FilterOrderHelper $value = (string) $selected; } - $result[] = ['value' => $value, 'label' => $label, 'position' => FilterOrderPositionEnum::EntityChoice->value, 'name' => $name]; + $result[] = ['value' => $this->translator->trans($value), 'label' => $label, 'position' => FilterOrderPositionEnum::EntityChoice->value, 'name' => $name]; } } From bf93c1ddb21f2bcbb28d42094b4f0d7c4cc78ef5 Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Tue, 11 Jul 2023 14:06:10 +0200 Subject: [PATCH 270/321] fix label color in active filters pills --- .../translations/messages.fr.yml | 3 --- .../Form/Type/Listing/FilterOrderType.php | 2 +- .../Resources/views/FilterOrder/base.html.twig | 16 ++++++++++++---- .../translations/messages+intl-icu.fr.yaml | 4 ++++ 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/translations/messages.fr.yml b/src/Bundle/ChillActivityBundle/translations/messages.fr.yml index 3099e99b0..c53a04f31 100644 --- a/src/Bundle/ChillActivityBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillActivityBundle/translations/messages.fr.yml @@ -96,9 +96,6 @@ activity_filter: My activities: Mes échanges (où j'interviens) Types: Par type d'échange Jobs: Par métier impliqué - By: Filtrer par - Search: Chercher dans la liste - By date: Filtrer par date #timeline '%user% has done an %activity_type%': '%user% a effectué un échange de type "%activity_type%"' diff --git a/src/Bundle/ChillMainBundle/Form/Type/Listing/FilterOrderType.php b/src/Bundle/ChillMainBundle/Form/Type/Listing/FilterOrderType.php index d16ce3813..f22b6bfba 100644 --- a/src/Bundle/ChillMainBundle/Form/Type/Listing/FilterOrderType.php +++ b/src/Bundle/ChillMainBundle/Form/Type/Listing/FilterOrderType.php @@ -39,7 +39,7 @@ final class FilterOrderType extends \Symfony\Component\Form\AbstractType 'label' => false, 'required' => false, 'attr' => [ - 'placeholder' => 'activity_filter.Search', + 'placeholder' => 'filter_order.Search', ] ]); } diff --git a/src/Bundle/ChillMainBundle/Resources/views/FilterOrder/base.html.twig b/src/Bundle/ChillMainBundle/Resources/views/FilterOrder/base.html.twig index 7a05a2f80..0dcc4ce3f 100644 --- a/src/Bundle/ChillMainBundle/Resources/views/FilterOrder/base.html.twig +++ b/src/Bundle/ChillMainBundle/Resources/views/FilterOrder/base.html.twig @@ -26,7 +26,7 @@ {% if form.dateRanges[dateRangeName].vars.label is not same as(false) %} {{ form_label(form.dateRanges[dateRangeName])}} {% else %} -
      {{ 'activity_filter.By date'|trans }}
      +
      {{ 'filter_order.By date'|trans }}
      {% endif %}
      @@ -45,7 +45,7 @@ {% if form.checkboxes|length > 0 %} {% for checkbox_name, options in form.checkboxes %}
      -
      {{ 'activity_filter.By'|trans }}
      +
      {{ 'filter_order.By'|trans }}
      {% for c in form['checkboxes'][checkbox_name].children %} {{ form_widget(c) }} @@ -78,7 +78,7 @@ {% set btnSubmit = 1 %} {% for name, _o in form.single_checkboxes %}
      -
      {{ 'activity_filter.By'|trans }}
      +
      {{ 'filter_order.By'|trans }}
      {{ form_widget(form.single_checkboxes[name]) }}
      @@ -97,7 +97,15 @@ {% if active|length > 0 %}
      {% for f in active %} - {% if f.label != '' %}{{ f.label|trans }} : {% endif %}{{ f.value }} + + {%- if f.label != '' %} + {{ f.label|trans }} : + {% endif -%} + {%- if f.position == 'search_box' and f.value is not null %} + {{ 'filter_order.search_box'|trans ~ ' :' }} + {% endif -%} + {{ f.value}}{# + #} {% endfor %}
      {% endif %} diff --git a/src/Bundle/ChillMainBundle/translations/messages+intl-icu.fr.yaml b/src/Bundle/ChillMainBundle/translations/messages+intl-icu.fr.yaml index e1dc89dc2..96b2edd98 100644 --- a/src/Bundle/ChillMainBundle/translations/messages+intl-icu.fr.yaml +++ b/src/Bundle/ChillMainBundle/translations/messages+intl-icu.fr.yaml @@ -59,3 +59,7 @@ filter_order: by_date: From: Depuis le {from_date, date, long} To: Jusqu'au {to_date, date, long} + By: Filtrer par + Search: Chercher dans la liste + By date: Filtrer par date + search_box: Filtrer par contenu From 88114e3ba69fbd97a27eb850600acc78e27f526a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 11 Jul 2023 14:17:02 +0200 Subject: [PATCH 271/321] Fixed: [filterOrder] refactor active filter helper to a dedicated class and fix loading of multiple entity choices --- .../views/FilterOrder/base.html.twig | 1 - .../FilterOrderGetActiveFilterHelper.php | 84 +++++++++++++++++++ .../Templating/Listing/FilterOrderHelper.php | 70 +--------------- .../Listing/FilterOrderHelperBuilder.php | 4 - .../Listing/FilterOrderHelperFactory.php | 4 +- .../Templating/Listing/Templating.php | 2 + 6 files changed, 91 insertions(+), 74 deletions(-) create mode 100644 src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderGetActiveFilterHelper.php diff --git a/src/Bundle/ChillMainBundle/Resources/views/FilterOrder/base.html.twig b/src/Bundle/ChillMainBundle/Resources/views/FilterOrder/base.html.twig index 0dcc4ce3f..b517eb154 100644 --- a/src/Bundle/ChillMainBundle/Resources/views/FilterOrder/base.html.twig +++ b/src/Bundle/ChillMainBundle/Resources/views/FilterOrder/base.html.twig @@ -93,7 +93,6 @@ {% endif %}
      - {% set active = helper.getActiveFilters() %} {% if active|length > 0 %}
      {% for f in active %} diff --git a/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderGetActiveFilterHelper.php b/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderGetActiveFilterHelper.php new file mode 100644 index 000000000..6b204e552 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderGetActiveFilterHelper.php @@ -0,0 +1,84 @@ + + */ + public function getActiveFilters(FilterOrderHelper $filterOrderHelper): array + { + $result = []; + + if ($filterOrderHelper->hasSearchBox() && '' !== $filterOrderHelper->getQueryString()) { + $result[] = ['label' => '', 'value' => $filterOrderHelper->getQueryString(), 'position' => FilterOrderPositionEnum::SearchBox->value, 'name' => 'q']; + } + + foreach ($filterOrderHelper->getDateRanges() as $name => ['label' => $label]) { + $base = ['position' => FilterOrderPositionEnum::DateRange->value, 'name' => $name, 'label' => (string)$label]; + + if (null !== ($from = $filterOrderHelper->getDateRangeData($name)['from'] ?? null)) { + $result[] = ['value' => $this->translator->trans('filter_order.by_date.From', ['from_date' => $from]), ...$base]; + } + if (null !== ($to = $filterOrderHelper->getDateRangeData($name)['to'] ?? null)) { + $result[] = ['value' => $this->translator->trans('filter_order.by_date.To', ['to_date' => $to]), ...$base]; + } + } + + foreach ($filterOrderHelper->getCheckboxes() as $name => ['choices' => $choices, 'trans' => $trans]) { + $translatedChoice = array_combine($choices, [...$trans]); + foreach ($filterOrderHelper->getCheckboxData($name) as $keyChoice) { + $result[] = ['value' => $this->translator->trans($translatedChoice[$keyChoice]), 'label' => '', 'position' => FilterOrderPositionEnum::Checkboxes->value, 'name' => $name]; + } + } + + foreach ($filterOrderHelper->getEntityChoices() as $name => ['label' => $label, 'class' => $class, 'choices' => $choices, 'options' => $options]) { + foreach ($filterOrderHelper->getEntityChoiceData($name) as $selected) { + if (is_callable($options['choice_label'])) { + $value = call_user_func($options['choice_label'], $selected); + } elseif ($options['choice_label'] instanceof PropertyPathInterface || is_string($options['choice_label'])) { + $value = $this->propertyAccessor->getValue($selected, $options['choice_label']); + } else { + if (!$selected instanceof \Stringable) { + throw new \UnexpectedValueException(sprintf("we are not able to transform the value of %s to a string. Implements \\Stringable or add a 'choice_label' option to the filterFormBuilder", get_class($selected))); + } + + $value = (string)$selected; + } + + $result[] = ['value' => $this->translator->trans($value), 'label' => $label, 'position' => FilterOrderPositionEnum::EntityChoice->value, 'name' => $name]; + } + } + + foreach ($filterOrderHelper->getSingleCheckbox() as $name => ['label' => $label]) { + if (true === $filterOrderHelper->getSingleCheckboxData($name)) { + $result[] = ['label' => '', 'value' => $this->translator->trans($label), 'position' => FilterOrderPositionEnum::SingleCheckbox->value, 'name' => $name]; + } + } + + return $result; + } +} diff --git a/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelper.php b/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelper.php index 2b24ffa0d..84939a052 100644 --- a/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelper.php +++ b/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelper.php @@ -55,8 +55,6 @@ final class FilterOrderHelper public function __construct( private readonly FormFactoryInterface $formFactory, private readonly RequestStack $requestStack, - private readonly TranslatorInterface $translator, - private readonly PropertyAccessorInterface $propertyAccessor, ) { } @@ -84,16 +82,14 @@ final class FilterOrderHelper public function addCheckbox(string $name, array $choices, ?array $default = [], ?array $trans = [], array $options = []): self { - $missing = count($choices) - count($trans); + if ([] === $trans) { + $trans = $choices; + } $this->checkboxes[$name] = [ 'choices' => $choices, 'default' => $default, - 'trans' => array_merge( - $trans, - 0 < $missing ? - array_fill(0, $missing, null) : [] - ), + 'trans' => $trans, ...$options, ]; @@ -201,64 +197,6 @@ final class FilterOrderHelper return $this; } - /** - * Return all the data required to display the active filters - * - * @return array - */ - public function getActiveFilters(): array - { - $result = []; - - if ($this->hasSearchBox() && '' !== $this->getQueryString()) { - $result[] = ['label' => '', 'value' => $this->getQueryString(), 'position' => FilterOrderPositionEnum::SearchBox->value, 'name' => 'q']; - } - - foreach ($this->dateRanges as $name => ['label' => $label]) { - $base = ['position' => FilterOrderPositionEnum::DateRange->value, 'name' => $name, 'label' => (string) $label]; - - if (null !== ($from = $this->getDateRangeData($name)['from'] ?? null)) { - $result[] = ['value' => $this->translator->trans('filter_order.by_date.From', ['from_date' => $from]), ...$base]; - } - if (null !== ($to = $this->getDateRangeData($name)['to'] ?? null)) { - $result[] = ['value' => $this->translator->trans('filter_order.by_date.To', ['to_date' => $to]), ...$base]; - } - } - - foreach ($this->checkboxes as $name => ['choices' => $choices, 'trans' => $trans]) { - $translatedChoice = array_combine($choices, [...$trans]); - foreach ($this->getCheckboxData($name) as $keyChoice) { - $result[] = ['value' => $this->translator->trans($translatedChoice[$keyChoice]), 'label' => '', 'position' => FilterOrderPositionEnum::Checkboxes->value, 'name' => $name]; - } - } - - foreach ($this->entityChoices as $name => ['label' => $label, 'class' => $class, 'choices' => $choices, 'options' => $options]) { - foreach ($this->getEntityChoiceData($name) as $selected) { - if (is_callable($options['choice_label'])) { - $value = call_user_func($options['choice_label'], $selected); - } elseif ($options['choice_label'] instanceof PropertyPathInterface || is_string($options['choice_label'])) { - $value = $this->propertyAccessor->getValue($selected, $options['choice_label']); - } else { - if (!$selected instanceof \Stringable) { - throw new \UnexpectedValueException(sprintf("we are not able to transform the value of %s to a string. Implements \\Stringable or add a 'choice_label' option to the filterFormBuilder", get_class($selected))); - } - - $value = (string) $selected; - } - - $result[] = ['value' => $this->translator->trans($value), 'label' => $label, 'position' => FilterOrderPositionEnum::EntityChoice->value, 'name' => $name]; - } - } - - foreach ($this->singleCheckbox as $name => ['label' => $label]) { - if (true === $this->getSingleCheckboxData($name)) { - $result[] = ['label' => '', 'value' => $this->translator->trans($label), 'position' => FilterOrderPositionEnum::SingleCheckbox->value, 'name' => $name]; - } - } - - return $result; - } - private function getDefaultData(): array { $r = [ diff --git a/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelperBuilder.php b/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelperBuilder.php index dfa361f6e..f2bded220 100644 --- a/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelperBuilder.php +++ b/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelperBuilder.php @@ -42,8 +42,6 @@ class FilterOrderHelperBuilder public function __construct( FormFactoryInterface $formFactory, RequestStack $requestStack, - private readonly TranslatorInterface $translator, - private readonly PropertyAccessorInterface $propertyAccessor, ) { $this->formFactory = $formFactory; $this->requestStack = $requestStack; @@ -92,8 +90,6 @@ class FilterOrderHelperBuilder $helper = new FilterOrderHelper( $this->formFactory, $this->requestStack, - $this->translator, - $this->propertyAccessor ); $helper->setSearchBox($this->searchBoxFields); diff --git a/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelperFactory.php b/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelperFactory.php index 3fbb2864d..6665750dd 100644 --- a/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelperFactory.php +++ b/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelperFactory.php @@ -25,8 +25,6 @@ class FilterOrderHelperFactory implements FilterOrderHelperFactoryInterface public function __construct( FormFactoryInterface $formFactory, RequestStack $requestStack, - private readonly TranslatorInterface $translator, - private readonly PropertyAccessorInterface $propertyAccessor, ) { $this->formFactory = $formFactory; $this->requestStack = $requestStack; @@ -34,6 +32,6 @@ class FilterOrderHelperFactory implements FilterOrderHelperFactoryInterface public function create(string $context, ?array $options = []): FilterOrderHelperBuilder { - return new FilterOrderHelperBuilder($this->formFactory, $this->requestStack, $this->translator, $this->propertyAccessor); + return new FilterOrderHelperBuilder($this->formFactory, $this->requestStack); } } diff --git a/src/Bundle/ChillMainBundle/Templating/Listing/Templating.php b/src/Bundle/ChillMainBundle/Templating/Listing/Templating.php index b91cd86e8..2d32813cb 100644 --- a/src/Bundle/ChillMainBundle/Templating/Listing/Templating.php +++ b/src/Bundle/ChillMainBundle/Templating/Listing/Templating.php @@ -24,6 +24,7 @@ class Templating extends AbstractExtension { public function __construct( private readonly RequestStack $requestStack, + private readonly FilterOrderGetActiveFilterHelper $filterOrderGetActiveFilterHelper, ) { } @@ -68,6 +69,7 @@ class Templating extends AbstractExtension return $environment->render($template, [ 'helper' => $helper, + 'active' => $this->filterOrderGetActiveFilterHelper->getActiveFilters($helper), 'form' => $helper->buildForm()->createView(), 'options' => $options, 'otherParameters' => $otherParameters, From 6065680e1e0bc71c19dd05ef158d301324f61805 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 11 Jul 2023 15:01:32 +0200 Subject: [PATCH 272/321] Feature: [export] allow to group activities by location --- .../unreleased/Feature-20230711-150055.yaml | 5 ++ .../Aggregator/ActivityLocationAggregator.php | 80 +++++++++++++++++++ .../config/services/export.yaml | 4 + .../translations/messages.fr.yml | 3 + 4 files changed, 92 insertions(+) create mode 100644 .changes/unreleased/Feature-20230711-150055.yaml create mode 100644 src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityLocationAggregator.php diff --git a/.changes/unreleased/Feature-20230711-150055.yaml b/.changes/unreleased/Feature-20230711-150055.yaml new file mode 100644 index 000000000..ecee61b49 --- /dev/null +++ b/.changes/unreleased/Feature-20230711-150055.yaml @@ -0,0 +1,5 @@ +kind: Feature +body: '[Export] allow to group activities by localisation' +time: 2023-07-11T15:00:55.770070399+02:00 +custom: + Issue: "128" diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityLocationAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityLocationAggregator.php new file mode 100644 index 000000000..9103943e4 --- /dev/null +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityLocationAggregator.php @@ -0,0 +1,80 @@ +getAllAliases(), true)) { + $qb->leftJoin('activity.location', 'actloc'); + } + $qb->addSelect(sprintf('actloc.name AS %s', self::KEY)); + $qb->addGroupBy(self::KEY); + } + + public function applyOn(): string + { + return Declarations::ACTIVITY; + } + + public function buildForm(FormBuilderInterface $builder) + { + // no form required for this aggregator + } + public function getFormDefaultData(): array + { + return []; + } + + public function getLabels($key, array $values, $data): Closure + { + return function ($value): string { + if ('_header' === $value) { + return 'export.aggregator.activity.by_location.Activity Location'; + } + + if (null === $value || '' === $value) { + return ''; + } + + return $value; + }; + } + + public function getQueryKeys($data): array + { + return [self::KEY]; + } + + public function getTitle() + { + return 'export.aggregator.activity.by_location.Title'; + } +} diff --git a/src/Bundle/ChillActivityBundle/config/services/export.yaml b/src/Bundle/ChillActivityBundle/config/services/export.yaml index 09817d80e..03285c416 100644 --- a/src/Bundle/ChillActivityBundle/config/services/export.yaml +++ b/src/Bundle/ChillActivityBundle/config/services/export.yaml @@ -144,6 +144,10 @@ services: tags: - { name: chill.export_aggregator, alias: activity_common_type_aggregator } + Chill\ActivityBundle\Export\Aggregator\ActivityLocationAggregator: + tags: + - { name: chill.export_aggregator, alias: activity_common_location_aggregator } + chill.activity.export.user_aggregator: class: Chill\ActivityBundle\Export\Aggregator\ActivityUserAggregator tags: diff --git a/src/Bundle/ChillActivityBundle/translations/messages.fr.yml b/src/Bundle/ChillActivityBundle/translations/messages.fr.yml index abef160d3..037c24f3f 100644 --- a/src/Bundle/ChillActivityBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillActivityBundle/translations/messages.fr.yml @@ -372,6 +372,9 @@ export: is sent: envoyé is received: reçu Group activity by sentreceived: Grouper les échanges par envoyé / reçu + by_location: + Activity Location: Localisation de l'échange + Title: Grouper les échanges par localisation de l'échange generic_doc: filter: From 2882038efcd4be2b65db67df7cb4f2498fcb0f57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 11 Jul 2023 16:00:40 +0200 Subject: [PATCH 273/321] [export] Add a filter "filter course having an activity between two dates" --- .../unreleased/Feature-20230711-155929.yaml | 5 ++ ...PeriodHavingActivityBetweenDatesFilter.php | 90 +++++++++++++++++++ .../config/services/export.yaml | 4 + .../translations/messages+intl-icu.fr.yml | 5 ++ .../translations/messages.fr.yml | 6 ++ 5 files changed, 110 insertions(+) create mode 100644 .changes/unreleased/Feature-20230711-155929.yaml create mode 100644 src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/PeriodHavingActivityBetweenDatesFilter.php create mode 100644 src/Bundle/ChillActivityBundle/translations/messages+intl-icu.fr.yml diff --git a/.changes/unreleased/Feature-20230711-155929.yaml b/.changes/unreleased/Feature-20230711-155929.yaml new file mode 100644 index 000000000..329bbb677 --- /dev/null +++ b/.changes/unreleased/Feature-20230711-155929.yaml @@ -0,0 +1,5 @@ +kind: Feature +body: '[export] Add a filter "filter course having an activity between two dates"' +time: 2023-07-11T15:59:29.065329834+02:00 +custom: + Issue: "129" diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/PeriodHavingActivityBetweenDatesFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/PeriodHavingActivityBetweenDatesFilter.php new file mode 100644 index 000000000..27e012d0b --- /dev/null +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/PeriodHavingActivityBetweenDatesFilter.php @@ -0,0 +1,90 @@ +add('start_date', PickRollingDateType::class, [ + 'label' => 'export.filter.activity.course_having_activity_between_date.Receiving an activity after' + ]) + ->add('end_date', PickRollingDateType::class, [ + 'label' => 'export.filter.activity.course_having_activity_between_date.Receiving an activity before' + ]); + } + + public function getFormDefaultData(): array + { + return [ + 'start_date' => new RollingDate(RollingDate::T_YEAR_CURRENT_START), + 'end_date' => new RollingDate(RollingDate::T_TODAY) + ]; + } + + public function describeAction($data, $format = 'string') + { + return [ + 'export.filter.activity.course_having_activity_between_date.Only course having an activity between from and to', + [ + 'from' => $this->rollingDateConverter->convert($data['start_date']), + 'to' => $this->rollingDateConverter->convert($data['end_date']), + ] + ]; + } + + public function addRole(): ?string + { + return null; + } + + public function alterQuery(QueryBuilder $qb, $data) + { + $alias = 'act_period_having_act_betw_date_alias'; + $from = 'act_period_having_act_betw_date_start'; + $to = 'act_period_having_act_betw_date_end'; + + $qb->andWhere( + $qb->expr()->exists( + 'SELECT 1 FROM ' . Activity::class . " {$alias} WHERE {$alias}.date >= :{$from} AND {$alias}.date < :{$to} AND {$alias}.accompanyingPeriod = acp" + ) + ); + + $qb + ->setParameter($from, $this->rollingDateConverter->convert($data['start_date'])) + ->setParameter($to, $this->rollingDateConverter->convert($data['end_date'])); + } + + public function applyOn() + { + return \Chill\PersonBundle\Export\Declarations::ACP_TYPE; + } +} diff --git a/src/Bundle/ChillActivityBundle/config/services/export.yaml b/src/Bundle/ChillActivityBundle/config/services/export.yaml index 09817d80e..932985083 100644 --- a/src/Bundle/ChillActivityBundle/config/services/export.yaml +++ b/src/Bundle/ChillActivityBundle/config/services/export.yaml @@ -135,6 +135,10 @@ services: tags: - { name: chill.export_filter, alias: 'accompanyingcourse_has_no_activity_filter' } + Chill\ActivityBundle\Export\Filter\ACPFilters\PeriodHavingActivityBetweenDatesFilter: + tags: + - { name: chill.export_filter, alias: 'period_having_activity_betw_dates_filter' } + ## Aggregators Chill\ActivityBundle\Export\Aggregator\PersonAggregators\ActivityReasonAggregator: tags: diff --git a/src/Bundle/ChillActivityBundle/translations/messages+intl-icu.fr.yml b/src/Bundle/ChillActivityBundle/translations/messages+intl-icu.fr.yml new file mode 100644 index 000000000..ab3b963ab --- /dev/null +++ b/src/Bundle/ChillActivityBundle/translations/messages+intl-icu.fr.yml @@ -0,0 +1,5 @@ +export: + filter: + activity: + course_having_activity_between_date: + Only course having an activity between from and to: Seulement les parcours ayant reçu au moins un échange entre le {from, date, short} et le {to, date, short} diff --git a/src/Bundle/ChillActivityBundle/translations/messages.fr.yml b/src/Bundle/ChillActivityBundle/translations/messages.fr.yml index abef160d3..551a63d27 100644 --- a/src/Bundle/ChillActivityBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillActivityBundle/translations/messages.fr.yml @@ -365,6 +365,12 @@ export: by_usersscope: Filter by users scope: Filtrer les échanges par services d'au moins un utilisateur participant 'Filtered activity by users scope: only %scopes%': 'Filtré par service d''au moins un utilisateur participant: seulement %scopes%' + course_having_activity_between_date: + Title: Filtre les parcours ayant reçu un échange entre deux dates + Receiving an activity after: Ayant reçu un échange après le + Receiving an activity before: Ayant reçu un échange avant le + + aggregator: activity: by_sent_received: From edd66f6a6cf3622dd82a8535a9f4a6272cc9bb1d Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Wed, 12 Jul 2023 09:04:15 +0200 Subject: [PATCH 274/321] FIX [budget][templates] reimplement display of all calculator results --- .../Resources/views/Budget/_macros.html.twig | 33 ++++++++++++++----- .../Resources/views/Person/index.html.twig | 2 +- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_macros.html.twig b/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_macros.html.twig index dfa286af4..a1fee19ce 100644 --- a/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_macros.html.twig +++ b/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_macros.html.twig @@ -1,11 +1,12 @@ -{% macro table_elements(elements, family) %} +{% macro table_elements(elements, type) %} + - - - - + + + + @@ -38,17 +39,17 @@
        {% if is_granted('CHILL_BUDGET_ELEMENT_SEE', f) %}
      • - +
      • {% endif %} {% if is_granted('CHILL_BUDGET_ELEMENT_UPDATE', f) %}
      • - +
      • {% endif %} {% if is_granted('CHILL_BUDGET_ELEMENT_DELETE', f) %}
      • - +
      • {% endif %}
      @@ -69,7 +70,7 @@
      {{ 'Budget element type'|trans }}{{ 'Amount'|trans }}{{ 'Validity period'|trans }} {{ 'Budget element type'|trans }}{{ 'Amount'|trans }}{{ 'Validity period'|trans }} 
      {% endmacro %} -{% macro table_results(actualCharges, actualResources) %} +{% macro table_results(actualCharges, actualResources, results) %} {% set totalCharges = 0 %} {% for c in actualCharges %} @@ -97,6 +98,20 @@ {{ result|format_currency('EUR') }} + {% for result in results %} + + {{ result.label }} + + {% if result.type == 'currency' %} + {{ result.result|format_currency('EUR') }} + {% elseif result.type == 'percentage' %} + {{ result.result|round(2, 'ceil') ~ '%' }} + {% else %} + {{ result.result|round(2, 'common') }} + {% endif %} + + + {% endfor %} {% endmacro %} diff --git a/src/Bundle/ChillBudgetBundle/Resources/views/Person/index.html.twig b/src/Bundle/ChillBudgetBundle/Resources/views/Person/index.html.twig index 18d04b889..aba564206 100644 --- a/src/Bundle/ChillBudgetBundle/Resources/views/Person/index.html.twig +++ b/src/Bundle/ChillBudgetBundle/Resources/views/Person/index.html.twig @@ -25,7 +25,7 @@

      {{ 'Budget calculator'|trans }}

      - {{ table_results(charges, resources) }} + {{ table_results(charges, resources, results) }}
      {% if is_granted('CHILL_BUDGET_ELEMENT_CREATE', person) %} From f7d385eba1877756c34ed64857d0e847aedccf9d Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Wed, 12 Jul 2023 09:06:08 +0200 Subject: [PATCH 275/321] DX add changie --- .changes/unreleased/Fixed-20230712-090514.yaml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changes/unreleased/Fixed-20230712-090514.yaml diff --git a/.changes/unreleased/Fixed-20230712-090514.yaml b/.changes/unreleased/Fixed-20230712-090514.yaml new file mode 100644 index 000000000..51a8b9317 --- /dev/null +++ b/.changes/unreleased/Fixed-20230712-090514.yaml @@ -0,0 +1,5 @@ +kind: Fixed +body: reimplement the visualization of all calculator results (specific to AMLI) +time: 2023-07-12T09:05:14.416268226+02:00 +custom: + Issue: "" From e38b369149dc92c6db0a36963c562c2976088540 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 12 Jul 2023 10:26:22 +0200 Subject: [PATCH 276/321] [cron-job] add a new "lastExecution" data on CronJobExecution entity This column will store the results of the last execution --- .../Entity/CronJobExecution.php | 18 +++++++++- .../migrations/Version20230711152947.php | 33 +++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 src/Bundle/ChillMainBundle/migrations/Version20230711152947.php diff --git a/src/Bundle/ChillMainBundle/Entity/CronJobExecution.php b/src/Bundle/ChillMainBundle/Entity/CronJobExecution.php index 0cacffac9..2883055fc 100644 --- a/src/Bundle/ChillMainBundle/Entity/CronJobExecution.php +++ b/src/Bundle/ChillMainBundle/Entity/CronJobExecution.php @@ -31,7 +31,6 @@ class CronJobExecution private string $key; /** - * @var DateTimeImmutable * @ORM\Column(type="datetime_immutable", nullable=true, options={"default": null}) */ private ?DateTimeImmutable $lastEnd = null; @@ -46,6 +45,11 @@ class CronJobExecution */ private ?int $lastStatus = null; + /** + * @ORM\Column(type="json", options={"default": "'{}'::jsonb", "jsonb": true}) + */ + private array $lastExecutionData = []; + public function __construct(string $key) { $this->key = $key; @@ -92,4 +96,16 @@ class CronJobExecution return $this; } + + public function getLastExecutionData(): array + { + return $this->lastExecutionData; + } + + public function setLastExecutionData(array $lastExecutionData): CronJobExecution + { + $this->lastExecutionData = $lastExecutionData; + + return $this; + } } diff --git a/src/Bundle/ChillMainBundle/migrations/Version20230711152947.php b/src/Bundle/ChillMainBundle/migrations/Version20230711152947.php new file mode 100644 index 000000000..ed804473e --- /dev/null +++ b/src/Bundle/ChillMainBundle/migrations/Version20230711152947.php @@ -0,0 +1,33 @@ +addSql('ALTER TABLE chill_main_cronjob_execution ADD lastExecutionData JSONB DEFAULT \'{}\'::jsonb NOT NULL'); + } + + public function down(Schema $schema): void + { + $this->addSql('ALTER TABLE chill_main_cronjob_execution DROP COLUMN lastExecutionData'); + } +} From a2e705bd92e085007fb0313b163f194497bcb5bf Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Wed, 12 Jul 2023 10:38:11 +0200 Subject: [PATCH 277/321] fixed: error with parent joins in thirdparty api search query --- .../Controller/resquery.bad.sql | 21 +++++++++++++++++++ .../Controller/resquery.fixed.sql | 21 +++++++++++++++++++ .../Search/ThirdPartyApiSearch.php | 2 +- 3 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 src/Bundle/ChillMainBundle/Controller/resquery.bad.sql create mode 100644 src/Bundle/ChillMainBundle/Controller/resquery.fixed.sql diff --git a/src/Bundle/ChillMainBundle/Controller/resquery.bad.sql b/src/Bundle/ChillMainBundle/Controller/resquery.bad.sql new file mode 100644 index 000000000..1033ec28c --- /dev/null +++ b/src/Bundle/ChillMainBundle/Controller/resquery.bad.sql @@ -0,0 +1,21 @@ +SELECT +'tparty' AS key, jsonb_build_object('id', tparty.id) AS metadata, GREATEST( +STRICT_WORD_SIMILARITY(LOWER(UNACCENT('areams')), tparty.canonicalized), +STRICT_WORD_SIMILARITY(LOWER(UNACCENT('areams')), parent.canonicalized) +) + GREATEST( +(tparty.canonicalized LIKE '%s' || LOWER(UNACCENT('areams')) || '%')::int, +(parent.canonicalized LIKE '%s' || LOWER(UNACCENT('areams')) || '%')::int +) + COALESCE((LOWER(UNACCENT(cmpc.label)) LIKE '%' || LOWER(UNACCENT('areams')) || '%')::int * 0.3, 0) + COALESCE((LOWER(UNACCENT(cmpc_p.label)) LIKE '%' || LOWER(UNACCENT('areams')) || '%')::int * 0.3, 0) + 1 AS pertinence +FROM chill_3party.third_party AS tparty +LEFT JOIN chill_main_address cma ON cma.id = tparty.address_id +LEFT JOIN chill_main_postal_code cmpc ON cma.postcode_id = cmpc.id +LEFT JOIN chill_3party.third_party AS parent ON tparty.parent_id = parent.id +LEFT JOIN chill_main_address cma_p ON parent.address_id = cma_p.id +LEFT JOIN chill_main_postal_code cmpc_p ON cma_p.postcode_id = cmpc.id +WHERE (tparty.active IS TRUE) AND (((LOWER(UNACCENT('areams')) <<% tparty.canonicalized OR +tparty.canonicalized LIKE '%' || LOWER(UNACCENT('areams')) || '%') +OR +(LOWER(UNACCENT('areams')) <<% parent.canonicalized OR +parent.canonicalized LIKE '%' || LOWER(UNACCENT('areams')) || '%')) +AND tparty.active IS TRUE and (parent.active IS TRUE OR parent IS NULL)) +ORDER BY pertinence DESC LIMIT 50 OFFSET 0; diff --git a/src/Bundle/ChillMainBundle/Controller/resquery.fixed.sql b/src/Bundle/ChillMainBundle/Controller/resquery.fixed.sql new file mode 100644 index 000000000..dbb55f187 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Controller/resquery.fixed.sql @@ -0,0 +1,21 @@ +SELECT +'tparty' AS key, jsonb_build_object('id', tparty.id) AS metadata, GREATEST( +STRICT_WORD_SIMILARITY(LOWER(UNACCENT('areams')), tparty.canonicalized), +STRICT_WORD_SIMILARITY(LOWER(UNACCENT('areams')), parent.canonicalized) +) + GREATEST( +(tparty.canonicalized LIKE '%s' || LOWER(UNACCENT('areams')) || '%')::int, +(parent.canonicalized LIKE '%s' || LOWER(UNACCENT('areams')) || '%')::int +) + COALESCE((LOWER(UNACCENT(cmpc.label)) LIKE '%' || LOWER(UNACCENT('areams')) || '%')::int * 0.3, 0) + COALESCE((LOWER(UNACCENT(cmpc_p.label)) LIKE '%' || LOWER(UNACCENT('areams')) || '%')::int * 0.3, 0) + 1 AS pertinence +FROM chill_3party.third_party AS tparty +LEFT JOIN chill_main_address cma ON cma.id = tparty.address_id +LEFT JOIN chill_main_postal_code cmpc ON cma.postcode_id = cmpc.id +LEFT JOIN chill_3party.third_party AS parent ON tparty.parent_id = parent.id +LEFT JOIN chill_main_address cma_p ON parent.address_id = cma_p.id +LEFT JOIN chill_main_postal_code cmpc_p ON cma_p.postcode_id = cmpc_p.id +WHERE (tparty.active IS TRUE) AND (((LOWER(UNACCENT('areams')) <<% tparty.canonicalized OR +tparty.canonicalized LIKE '%' || LOWER(UNACCENT('areams')) || '%') +OR +(LOWER(UNACCENT('areams')) <<% parent.canonicalized OR +parent.canonicalized LIKE '%' || LOWER(UNACCENT('areams')) || '%')) +AND tparty.active IS TRUE and (parent.active IS TRUE OR parent IS NULL)) +ORDER BY pertinence DESC LIMIT 50 OFFSET 0; diff --git a/src/Bundle/ChillThirdPartyBundle/Search/ThirdPartyApiSearch.php b/src/Bundle/ChillThirdPartyBundle/Search/ThirdPartyApiSearch.php index 86c0fa9db..42b98622f 100644 --- a/src/Bundle/ChillThirdPartyBundle/Search/ThirdPartyApiSearch.php +++ b/src/Bundle/ChillThirdPartyBundle/Search/ThirdPartyApiSearch.php @@ -75,7 +75,7 @@ class ThirdPartyApiSearch implements SearchApiInterface LEFT JOIN chill_main_postal_code cmpc ON cma.postcode_id = cmpc.id LEFT JOIN chill_3party.third_party AS parent ON tparty.parent_id = parent.id LEFT JOIN chill_main_address cma_p ON parent.address_id = cma_p.id - LEFT JOIN chill_main_postal_code cmpc_p ON cma_p.postcode_id = cmpc.id') + LEFT JOIN chill_main_postal_code cmpc_p ON cma_p.postcode_id = cmpc_p.id') ->andWhereClause('tparty.active IS TRUE'); $strs = explode(' ', $pattern); From f3829d3390ae7e22939f02a6bb71db305ebe060e Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Wed, 12 Jul 2023 10:50:17 +0200 Subject: [PATCH 278/321] adapt query to simplify join clauses (lightly improve perfs) --- .../Controller/resquery.good.sql | 19 +++++++++++++++++++ .../Search/ThirdPartyApiSearch.php | 10 +++------- 2 files changed, 22 insertions(+), 7 deletions(-) create mode 100644 src/Bundle/ChillMainBundle/Controller/resquery.good.sql diff --git a/src/Bundle/ChillMainBundle/Controller/resquery.good.sql b/src/Bundle/ChillMainBundle/Controller/resquery.good.sql new file mode 100644 index 000000000..5877b04f8 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Controller/resquery.good.sql @@ -0,0 +1,19 @@ +SELECT +'tparty' AS key, jsonb_build_object('id', tparty.id) AS metadata, GREATEST( +STRICT_WORD_SIMILARITY(LOWER(UNACCENT('areams')), tparty.canonicalized), +STRICT_WORD_SIMILARITY(LOWER(UNACCENT('areams')), parent.canonicalized) +) + GREATEST( +(tparty.canonicalized LIKE '%s' || LOWER(UNACCENT('areams')) || '%')::int, +(parent.canonicalized LIKE '%s' || LOWER(UNACCENT('areams')) || '%')::int +) + COALESCE((LOWER(UNACCENT(cmpc.label)) LIKE '%' || LOWER(UNACCENT('areams')) || '%')::int * 0.3, 0) + 1 AS pertinence +FROM chill_3party.third_party AS tparty +LEFT JOIN chill_3party.third_party AS parent ON tparty.parent_id = parent.id +LEFT JOIN chill_main_address cma ON cma.id = COALESCE(parent.address_id, tparty.address_id) +LEFT JOIN chill_main_postal_code cmpc ON cma.postcode_id = cmpc.id +WHERE (((LOWER(UNACCENT('areams')) <<% tparty.canonicalized OR +tparty.canonicalized LIKE '%' || LOWER(UNACCENT('areams')) || '%') +OR +(LOWER(UNACCENT('areams')) <<% parent.canonicalized OR +parent.canonicalized LIKE '%' || LOWER(UNACCENT('areams')) || '%')) +AND tparty.active IS TRUE and (parent.active IS TRUE OR parent IS NULL)) +ORDER BY pertinence DESC, tparty.id ASC LIMIT 500 OFFSET 0; diff --git a/src/Bundle/ChillThirdPartyBundle/Search/ThirdPartyApiSearch.php b/src/Bundle/ChillThirdPartyBundle/Search/ThirdPartyApiSearch.php index 42b98622f..bb5303143 100644 --- a/src/Bundle/ChillThirdPartyBundle/Search/ThirdPartyApiSearch.php +++ b/src/Bundle/ChillThirdPartyBundle/Search/ThirdPartyApiSearch.php @@ -71,12 +71,9 @@ class ThirdPartyApiSearch implements SearchApiInterface ->setSelectKey('tparty') ->setSelectJsonbMetadata("jsonb_build_object('id', tparty.id)") ->setFromClause('chill_3party.third_party AS tparty - LEFT JOIN chill_main_address cma ON cma.id = tparty.address_id - LEFT JOIN chill_main_postal_code cmpc ON cma.postcode_id = cmpc.id LEFT JOIN chill_3party.third_party AS parent ON tparty.parent_id = parent.id - LEFT JOIN chill_main_address cma_p ON parent.address_id = cma_p.id - LEFT JOIN chill_main_postal_code cmpc_p ON cma_p.postcode_id = cmpc_p.id') - ->andWhereClause('tparty.active IS TRUE'); + LEFT JOIN chill_main_address cma ON cma.id = COALESCE(parent.address_id, tparty.address_id) + LEFT JOIN chill_main_postal_code cmpc ON cma.postcode_id = cmpc.id'); $strs = explode(' ', $pattern); $wheres = []; @@ -102,8 +99,7 @@ class ThirdPartyApiSearch implements SearchApiInterface (parent.canonicalized LIKE '%s' || LOWER(UNACCENT(?)) || '%')::int ) + " . // take postcode label into account, but lower than the canonicalized field - "COALESCE((LOWER(UNACCENT(cmpc.label)) LIKE '%' || LOWER(UNACCENT(?)) || '%')::int * 0.3, 0) + " . - "COALESCE((LOWER(UNACCENT(cmpc_p.label)) LIKE '%' || LOWER(UNACCENT(?)) || '%')::int * 0.3, 0)"; + "COALESCE((LOWER(UNACCENT(cmpc.label)) LIKE '%' || LOWER(UNACCENT(?)) || '%')::int * 0.3, 0)"; $pertinenceArgs[] = [$str, $str, $str, $str, $str, $str]; } } From efee2d8b44369e6546d13afa19d58b8a43d086db Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Wed, 12 Jul 2023 10:53:12 +0200 Subject: [PATCH 279/321] cleaning --- .../Controller/resquery.bad.sql | 21 ------------------- .../Controller/resquery.fixed.sql | 21 ------------------- .../Controller/resquery.good.sql | 19 ----------------- 3 files changed, 61 deletions(-) delete mode 100644 src/Bundle/ChillMainBundle/Controller/resquery.bad.sql delete mode 100644 src/Bundle/ChillMainBundle/Controller/resquery.fixed.sql delete mode 100644 src/Bundle/ChillMainBundle/Controller/resquery.good.sql diff --git a/src/Bundle/ChillMainBundle/Controller/resquery.bad.sql b/src/Bundle/ChillMainBundle/Controller/resquery.bad.sql deleted file mode 100644 index 1033ec28c..000000000 --- a/src/Bundle/ChillMainBundle/Controller/resquery.bad.sql +++ /dev/null @@ -1,21 +0,0 @@ -SELECT -'tparty' AS key, jsonb_build_object('id', tparty.id) AS metadata, GREATEST( -STRICT_WORD_SIMILARITY(LOWER(UNACCENT('areams')), tparty.canonicalized), -STRICT_WORD_SIMILARITY(LOWER(UNACCENT('areams')), parent.canonicalized) -) + GREATEST( -(tparty.canonicalized LIKE '%s' || LOWER(UNACCENT('areams')) || '%')::int, -(parent.canonicalized LIKE '%s' || LOWER(UNACCENT('areams')) || '%')::int -) + COALESCE((LOWER(UNACCENT(cmpc.label)) LIKE '%' || LOWER(UNACCENT('areams')) || '%')::int * 0.3, 0) + COALESCE((LOWER(UNACCENT(cmpc_p.label)) LIKE '%' || LOWER(UNACCENT('areams')) || '%')::int * 0.3, 0) + 1 AS pertinence -FROM chill_3party.third_party AS tparty -LEFT JOIN chill_main_address cma ON cma.id = tparty.address_id -LEFT JOIN chill_main_postal_code cmpc ON cma.postcode_id = cmpc.id -LEFT JOIN chill_3party.third_party AS parent ON tparty.parent_id = parent.id -LEFT JOIN chill_main_address cma_p ON parent.address_id = cma_p.id -LEFT JOIN chill_main_postal_code cmpc_p ON cma_p.postcode_id = cmpc.id -WHERE (tparty.active IS TRUE) AND (((LOWER(UNACCENT('areams')) <<% tparty.canonicalized OR -tparty.canonicalized LIKE '%' || LOWER(UNACCENT('areams')) || '%') -OR -(LOWER(UNACCENT('areams')) <<% parent.canonicalized OR -parent.canonicalized LIKE '%' || LOWER(UNACCENT('areams')) || '%')) -AND tparty.active IS TRUE and (parent.active IS TRUE OR parent IS NULL)) -ORDER BY pertinence DESC LIMIT 50 OFFSET 0; diff --git a/src/Bundle/ChillMainBundle/Controller/resquery.fixed.sql b/src/Bundle/ChillMainBundle/Controller/resquery.fixed.sql deleted file mode 100644 index dbb55f187..000000000 --- a/src/Bundle/ChillMainBundle/Controller/resquery.fixed.sql +++ /dev/null @@ -1,21 +0,0 @@ -SELECT -'tparty' AS key, jsonb_build_object('id', tparty.id) AS metadata, GREATEST( -STRICT_WORD_SIMILARITY(LOWER(UNACCENT('areams')), tparty.canonicalized), -STRICT_WORD_SIMILARITY(LOWER(UNACCENT('areams')), parent.canonicalized) -) + GREATEST( -(tparty.canonicalized LIKE '%s' || LOWER(UNACCENT('areams')) || '%')::int, -(parent.canonicalized LIKE '%s' || LOWER(UNACCENT('areams')) || '%')::int -) + COALESCE((LOWER(UNACCENT(cmpc.label)) LIKE '%' || LOWER(UNACCENT('areams')) || '%')::int * 0.3, 0) + COALESCE((LOWER(UNACCENT(cmpc_p.label)) LIKE '%' || LOWER(UNACCENT('areams')) || '%')::int * 0.3, 0) + 1 AS pertinence -FROM chill_3party.third_party AS tparty -LEFT JOIN chill_main_address cma ON cma.id = tparty.address_id -LEFT JOIN chill_main_postal_code cmpc ON cma.postcode_id = cmpc.id -LEFT JOIN chill_3party.third_party AS parent ON tparty.parent_id = parent.id -LEFT JOIN chill_main_address cma_p ON parent.address_id = cma_p.id -LEFT JOIN chill_main_postal_code cmpc_p ON cma_p.postcode_id = cmpc_p.id -WHERE (tparty.active IS TRUE) AND (((LOWER(UNACCENT('areams')) <<% tparty.canonicalized OR -tparty.canonicalized LIKE '%' || LOWER(UNACCENT('areams')) || '%') -OR -(LOWER(UNACCENT('areams')) <<% parent.canonicalized OR -parent.canonicalized LIKE '%' || LOWER(UNACCENT('areams')) || '%')) -AND tparty.active IS TRUE and (parent.active IS TRUE OR parent IS NULL)) -ORDER BY pertinence DESC LIMIT 50 OFFSET 0; diff --git a/src/Bundle/ChillMainBundle/Controller/resquery.good.sql b/src/Bundle/ChillMainBundle/Controller/resquery.good.sql deleted file mode 100644 index 5877b04f8..000000000 --- a/src/Bundle/ChillMainBundle/Controller/resquery.good.sql +++ /dev/null @@ -1,19 +0,0 @@ -SELECT -'tparty' AS key, jsonb_build_object('id', tparty.id) AS metadata, GREATEST( -STRICT_WORD_SIMILARITY(LOWER(UNACCENT('areams')), tparty.canonicalized), -STRICT_WORD_SIMILARITY(LOWER(UNACCENT('areams')), parent.canonicalized) -) + GREATEST( -(tparty.canonicalized LIKE '%s' || LOWER(UNACCENT('areams')) || '%')::int, -(parent.canonicalized LIKE '%s' || LOWER(UNACCENT('areams')) || '%')::int -) + COALESCE((LOWER(UNACCENT(cmpc.label)) LIKE '%' || LOWER(UNACCENT('areams')) || '%')::int * 0.3, 0) + 1 AS pertinence -FROM chill_3party.third_party AS tparty -LEFT JOIN chill_3party.third_party AS parent ON tparty.parent_id = parent.id -LEFT JOIN chill_main_address cma ON cma.id = COALESCE(parent.address_id, tparty.address_id) -LEFT JOIN chill_main_postal_code cmpc ON cma.postcode_id = cmpc.id -WHERE (((LOWER(UNACCENT('areams')) <<% tparty.canonicalized OR -tparty.canonicalized LIKE '%' || LOWER(UNACCENT('areams')) || '%') -OR -(LOWER(UNACCENT('areams')) <<% parent.canonicalized OR -parent.canonicalized LIKE '%' || LOWER(UNACCENT('areams')) || '%')) -AND tparty.active IS TRUE and (parent.active IS TRUE OR parent IS NULL)) -ORDER BY pertinence DESC, tparty.id ASC LIMIT 500 OFFSET 0; From 3f66e1a862416658a3afce675dbc1cb29440fb24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 12 Jul 2023 11:36:26 +0200 Subject: [PATCH 280/321] [cron-job] allow a cronjob to pass data from one execution to another When a cronjob is executed, it may return an array of data. This data will be passed as parameter on the next execution --- .changes/unreleased/DX-20230712-113603.yaml | 6 ++ .../ChillMainBundle/Cron/CronJobInterface.php | 10 ++- .../ChillMainBundle/Cron/CronManager.php | 25 +++++- ...eographicalUnitMaterializedViewCronJob.php | 4 +- .../Cron/CronJobDatabaseInteractionTest.php | 87 +++++++++++++++++++ .../Tests/Cron/CronManagerTest.php | 12 +-- .../AccompanyingPeriodStepChangeCronjob.php | 4 +- 7 files changed, 137 insertions(+), 11 deletions(-) create mode 100644 .changes/unreleased/DX-20230712-113603.yaml create mode 100644 src/Bundle/ChillMainBundle/Tests/Cron/CronJobDatabaseInteractionTest.php diff --git a/.changes/unreleased/DX-20230712-113603.yaml b/.changes/unreleased/DX-20230712-113603.yaml new file mode 100644 index 000000000..518ac3ca9 --- /dev/null +++ b/.changes/unreleased/DX-20230712-113603.yaml @@ -0,0 +1,6 @@ +kind: DX +body: '[cronjob] when a cronjob is executed, it may return an array of data that will + be passed as argument on the next execution' +time: 2023-07-12T11:36:03.813179067+02:00 +custom: + Issue: "" diff --git a/src/Bundle/ChillMainBundle/Cron/CronJobInterface.php b/src/Bundle/ChillMainBundle/Cron/CronJobInterface.php index 4e1ca9ff6..69edf8464 100644 --- a/src/Bundle/ChillMainBundle/Cron/CronJobInterface.php +++ b/src/Bundle/ChillMainBundle/Cron/CronJobInterface.php @@ -19,5 +19,13 @@ interface CronJobInterface public function getKey(): string; - public function run(): void; + /** + * Execute the cronjob + * + * If data is returned, this data is passed as argument on the next execution + * + * @param array $lastExecutionData the data which was returned from the previous execution + * @return array|null optionally return an array with the same data than the previous execution + */ + public function run(array $lastExecutionData): null|array; } diff --git a/src/Bundle/ChillMainBundle/Cron/CronManager.php b/src/Bundle/ChillMainBundle/Cron/CronManager.php index f69dcba76..a3e82a170 100644 --- a/src/Bundle/ChillMainBundle/Cron/CronManager.php +++ b/src/Bundle/ChillMainBundle/Cron/CronManager.php @@ -14,6 +14,7 @@ namespace Chill\MainBundle\Cron; use Chill\MainBundle\Entity\CronJobExecution; use Chill\MainBundle\Repository\CronJobExecutionRepositoryInterface; use DateTimeImmutable; +use Doctrine\DBAL\Types\Types; use Doctrine\ORM\EntityManagerInterface; use Exception; use Psr\Log\LoggerInterface; @@ -46,6 +47,8 @@ class CronManager implements CronManagerInterface private const UPDATE_BEFORE_EXEC = 'UPDATE ' . CronJobExecution::class . ' cr SET cr.lastStart = :now WHERE cr.key = :key'; + private const UPDATE_LAST_EXECUTION_DATA = 'UPDATE ' . CronJobExecution::class . ' cr SET cr.lastExecutionData = :data WHERE cr.key = :key'; + private CronJobExecutionRepositoryInterface $cronJobExecutionRepository; private EntityManagerInterface $entityManager; @@ -85,6 +88,9 @@ class CronManager implements CronManagerInterface foreach ($orderedJobs as $job) { if ($job->canRun($lasts[$job->getKey()] ?? null)) { if (array_key_exists($job->getKey(), $lasts)) { + + $executionData = $lasts[$job->getKey()]->getLastExecutionData(); + $this->entityManager ->createQuery(self::UPDATE_BEFORE_EXEC) ->setParameters([ @@ -96,12 +102,17 @@ class CronManager implements CronManagerInterface $execution = new CronJobExecution($job->getKey()); $this->entityManager->persist($execution); $this->entityManager->flush(); + + $executionData = $execution->getLastExecutionData(); } $this->entityManager->clear(); + // note: at this step, the entity manager does not have any entity CronJobExecution + // into his internal memory + try { $this->logger->info(sprintf('%sWill run job', self::LOG_PREFIX), ['job' => $job->getKey()]); - $job->run(); + $result = $job->run($executionData); $this->entityManager ->createQuery(self::UPDATE_AFTER_EXEC) @@ -112,6 +123,14 @@ class CronManager implements CronManagerInterface ]) ->execute(); + if (null !== $result) { + $this->entityManager + ->createQuery(self::UPDATE_LAST_EXECUTION_DATA) + ->setParameter('data', $result, Types::JSON) + ->setParameter('key', $job->getKey(), Types::STRING) + ->execute(); + } + $this->logger->info(sprintf('%sSuccessfully run job', self::LOG_PREFIX), ['job' => $job->getKey()]); return; @@ -133,7 +152,7 @@ class CronManager implements CronManagerInterface } /** - * @return array<0: CronJobInterface[], 1: array> + * @return array{0: array, 1: array} */ private function getOrderedJobs(): array { @@ -174,7 +193,7 @@ class CronManager implements CronManagerInterface { foreach ($this->jobs as $job) { if ($job->getKey() === $forceJob) { - $job->run(); + $job->run([]); } } } diff --git a/src/Bundle/ChillMainBundle/Service/AddressGeographicalUnit/RefreshAddressToGeographicalUnitMaterializedViewCronJob.php b/src/Bundle/ChillMainBundle/Service/AddressGeographicalUnit/RefreshAddressToGeographicalUnitMaterializedViewCronJob.php index 9dbb38a3f..3a6ff8fb9 100644 --- a/src/Bundle/ChillMainBundle/Service/AddressGeographicalUnit/RefreshAddressToGeographicalUnitMaterializedViewCronJob.php +++ b/src/Bundle/ChillMainBundle/Service/AddressGeographicalUnit/RefreshAddressToGeographicalUnitMaterializedViewCronJob.php @@ -49,8 +49,10 @@ class RefreshAddressToGeographicalUnitMaterializedViewCronJob implements CronJob return 'refresh-materialized-view-address-to-geog-units'; } - public function run(): void + public function run(array $lastExecutionData): null|array { $this->connection->executeQuery('REFRESH MATERIALIZED VIEW view_chill_main_address_geographical_unit'); + + return null; } } diff --git a/src/Bundle/ChillMainBundle/Tests/Cron/CronJobDatabaseInteractionTest.php b/src/Bundle/ChillMainBundle/Tests/Cron/CronJobDatabaseInteractionTest.php new file mode 100644 index 000000000..0b80730fe --- /dev/null +++ b/src/Bundle/ChillMainBundle/Tests/Cron/CronJobDatabaseInteractionTest.php @@ -0,0 +1,87 @@ +entityManager = self::$container->get(EntityManagerInterface::class); + $this->cronJobExecutionRepository = self::$container->get(CronJobExecutionRepository::class); + } + + public function testCompleteLifeCycle(): void + { + $cronjob = $this->prophesize(CronJobInterface::class); + $cronjob->canRun(null)->willReturn(true); + $cronjob->canRun(Argument::type(CronJobExecution::class))->willReturn(true); + $cronjob->getKey()->willReturn('test-with-data'); + $cronjob->run([])->willReturn(['test' => 'execution-0']); + $cronjob->run(['test' => 'execution-0'])->willReturn(['test' => 'execution-1']); + + $cronjob->run([])->shouldBeCalledOnce(); + $cronjob->run(['test' => 'execution-0'])->shouldBeCalledOnce(); + + $manager = new CronManager( + $this->cronJobExecutionRepository, + $this->entityManager, + [$cronjob->reveal()], + new NullLogger() + ); + + // run a first time + $manager->run(); + + // run a second time + $manager->run(); + } + +} + +class JobWithReturn implements CronJobInterface +{ + public function canRun(?CronJobExecution $cronJobExecution): bool + { + return true; + } + + public function getKey(): string + { + return 'with-data'; + } + + public function run(array $lastExecutionData): null|array + { + return ['data' => 'test']; + } +} diff --git a/src/Bundle/ChillMainBundle/Tests/Cron/CronManagerTest.php b/src/Bundle/ChillMainBundle/Tests/Cron/CronManagerTest.php index 4b812ce2b..47c929a52 100644 --- a/src/Bundle/ChillMainBundle/Tests/Cron/CronManagerTest.php +++ b/src/Bundle/ChillMainBundle/Tests/Cron/CronManagerTest.php @@ -40,7 +40,7 @@ final class CronManagerTest extends TestCase $jobToExecute = $this->prophesize(CronJobInterface::class); $jobToExecute->getKey()->willReturn('to-exec'); $jobToExecute->canRun(Argument::type(CronJobExecution::class))->willReturn(true); - $jobToExecute->run()->shouldBeCalled(); + $jobToExecute->run([])->shouldBeCalled(); $executions = [ ['key' => $jobOld1->getKey(), 'lastStart' => new DateTimeImmutable('yesterday'), 'lastEnd' => new DateTimeImmutable('1 hours ago'), 'lastStatus' => CronJobExecution::SUCCESS], @@ -64,7 +64,7 @@ final class CronManagerTest extends TestCase $jobAlreadyExecuted = new JobCanRun('k'); $jobNeverExecuted = $this->prophesize(CronJobInterface::class); $jobNeverExecuted->getKey()->willReturn('never-executed'); - $jobNeverExecuted->run()->shouldBeCalled(); + $jobNeverExecuted->run([])->shouldBeCalled(); $jobNeverExecuted->canRun(null)->willReturn(true); $executions = [ @@ -86,7 +86,7 @@ final class CronManagerTest extends TestCase $jobAlreadyExecuted = new JobCanRun('k'); $jobNeverExecuted = $this->prophesize(CronJobInterface::class); $jobNeverExecuted->getKey()->willReturn('never-executed'); - $jobNeverExecuted->run()->shouldBeCalled(); + $jobNeverExecuted->run([])->shouldBeCalled(); $jobNeverExecuted->canRun(null)->willReturn(true); $executions = [ @@ -178,8 +178,9 @@ class JobCanRun implements CronJobInterface return $this->key; } - public function run(): void + public function run(array $lastExecutionData): null|array { + return null; } } @@ -195,7 +196,8 @@ class JobCannotRun implements CronJobInterface return 'job-b'; } - public function run(): void + public function run(array $lastExecutionData): null|array { + return null; } } diff --git a/src/Bundle/ChillPersonBundle/AccompanyingPeriod/Lifecycle/AccompanyingPeriodStepChangeCronjob.php b/src/Bundle/ChillPersonBundle/AccompanyingPeriod/Lifecycle/AccompanyingPeriodStepChangeCronjob.php index f637e70b9..2ddf3415c 100644 --- a/src/Bundle/ChillPersonBundle/AccompanyingPeriod/Lifecycle/AccompanyingPeriodStepChangeCronjob.php +++ b/src/Bundle/ChillPersonBundle/AccompanyingPeriod/Lifecycle/AccompanyingPeriodStepChangeCronjob.php @@ -39,8 +39,10 @@ readonly class AccompanyingPeriodStepChangeCronjob implements CronJobInterface return 'accompanying-period-step-change'; } - public function run(): void + public function run(array $lastExecutionData): null|array { ($this->requestor)(); + + return null; } } From e82c7cdc6c174c6873775a43d20446668af3eb43 Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Wed, 12 Jul 2023 13:24:23 +0200 Subject: [PATCH 281/321] Fixed: [homepage widget] repair my unread notification list with actions and evaluations documents --- .../public/vuejs/HomepageWidget/MyNotifications.vue | 8 ++++++++ .../Resources/public/vuejs/HomepageWidget/js/i18n.js | 1 + 2 files changed, 9 insertions(+) diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/HomepageWidget/MyNotifications.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/HomepageWidget/MyNotifications.vue index 06683f8fc..bfde741ac 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/HomepageWidget/MyNotifications.vue +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/HomepageWidget/MyNotifications.vue @@ -66,6 +66,10 @@ export default { return appMessages.fr.the_activity; case 'Chill\\PersonBundle\\Entity\\AccompanyingPeriod': return appMessages.fr.the_course; + case 'Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWork': + return appMessages.fr.the_action; + case 'Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluationDocument': + return appMessages.fr.the_evaluation_document; case 'Chill\\MainBundle\\Entity\\Workflow\\EntityWorkflow': return appMessages.fr.the_workflow; default: @@ -78,6 +82,10 @@ export default { return `/fr/activity/${n.relatedEntityId}/show` case 'Chill\\PersonBundle\\Entity\\AccompanyingPeriod': return `/fr/parcours/${n.relatedEntityId}` + case 'Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWork': + return `/fr/person/accompanying-period/work/${n.relatedEntityId}/show` + case 'Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluationDocument': + return `/fr/notification/${n.id}/show` // to the notification case 'Chill\\MainBundle\\Entity\\Workflow\\EntityWorkflow': return `/fr/main/workflow/${n.relatedEntityId}/show` default: diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/HomepageWidget/js/i18n.js b/src/Bundle/ChillMainBundle/Resources/public/vuejs/HomepageWidget/js/i18n.js index 697074671..587f06fa9 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/HomepageWidget/js/i18n.js +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/HomepageWidget/js/i18n.js @@ -46,6 +46,7 @@ const appMessages = { the_course: "le parcours", the_action: "l'action", the_evaluation: "l'évaluation", + the_evaluation_document: "le document de l'évaluation", the_task: "la tâche", the_workflow: "le workflow", StartDate: "Date d'ouverture", From e0758215ba3c557fc26065591663be2389e1fe50 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Wed, 12 Jul 2023 15:17:03 +0200 Subject: [PATCH 282/321] FEATURE [repository] implement filter logic --- src/Bundle/ChillMainBundle/Entity/Address.php | 1 + .../Templating/Listing/FilterOrderHelper.php | 3 +- .../AccompanyingCourseWorkController.php | 4 +- .../AccompanyingPeriodWorkRepository.php | 42 ++++++++++++------- 4 files changed, 32 insertions(+), 18 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Entity/Address.php b/src/Bundle/ChillMainBundle/Entity/Address.php index 1bd1a453a..9fcb07fe5 100644 --- a/src/Bundle/ChillMainBundle/Entity/Address.php +++ b/src/Bundle/ChillMainBundle/Entity/Address.php @@ -255,6 +255,7 @@ class Address implements TrackCreationInterface, TrackUpdateInterface public function syncWithReference(AddressReference $addressReference): Address { + dump($addressReference); $this ->setPoint($addressReference->getPoint()) ->setPostcode($addressReference->getPostcode()) diff --git a/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelper.php b/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelper.php index 8554b4431..6a4d07167 100644 --- a/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelper.php +++ b/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelper.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Chill\MainBundle\Templating\Listing; +use Chill\MainBundle\Entity\User; use Chill\MainBundle\Form\Type\Listing\FilterOrderType; use DateTimeImmutable; use Symfony\Component\Form\Extension\Core\Type\FormType; @@ -134,7 +135,7 @@ class FilterOrderHelper return $this->userPickers; } - public function getUserPickerData(string $name): array + public function getUserPickerData(string $name) { return $this->getFormData()['user_pickers'][$name]; } diff --git a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseWorkController.php b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseWorkController.php index c56489afd..3eb6e67f5 100644 --- a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseWorkController.php +++ b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseWorkController.php @@ -161,7 +161,7 @@ class AccompanyingCourseWorkController extends AbstractController 'types' => $filter->getEntityChoiceData('typesFilter'), 'before' => $filter->getDateRangeData('dateFilter')['to'], 'after' => $filter->getDateRangeData('dateFilter')['from'], - 'users' => $filter->getUserPickerData('userFilter') + 'user' => $filter->getUserPickerData('userFilter') ]; $totalItems = $this->workRepository->countByAccompanyingPeriod($period); @@ -226,7 +226,7 @@ class AccompanyingCourseWorkController extends AbstractController ->addEntityChoice('typesFilter', 'accompanying_course_work.types_filter', \Chill\PersonBundle\Entity\SocialWork\SocialAction::class, $types, [ 'choice_label' => fn (SocialAction $sa) => $this->translatableStringHelper->localize($sa->getTitle()) ]) - ->addUserPicker('userFilter', 'accompanying_course_work.user_filter', ['required' => false]) + ->addUserPicker('userFilter', 'accompanying_course_work.user_filter', ['required' => false, 'multiple' => false]) ; return $filterBuilder->build(); diff --git a/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/AccompanyingPeriodWorkRepository.php b/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/AccompanyingPeriodWorkRepository.php index a5e27afd5..6fc8ff86e 100644 --- a/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/AccompanyingPeriodWorkRepository.php +++ b/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/AccompanyingPeriodWorkRepository.php @@ -103,40 +103,52 @@ final class AccompanyingPeriodWorkRepository implements ObjectRepository $rsm->addRootEntityFromClassMetadata(AccompanyingPeriodWork::class, 'w'); $sql = "SELECT {$rsm} FROM chill_person_accompanying_period_work w - WHERE accompanyingPeriod_id = :periodId - ORDER BY - CASE WHEN enddate IS NULL THEN '-infinity'::timestamp ELSE 'infinity'::timestamp END ASC, - startdate DESC, - enddate DESC, - id DESC"; + WHERE accompanyingPeriod_id = :periodId"; // implement filters if([] !== ($filters['types'] ?? [])) { - $sql .= "AND WHERE w.socialAction IN (:types)"; + $sql .= " AND w.socialaction_id IN (:types)"; } if([] !== ($filters['users'] ?? [])) { - $sql .= "AND WHERE w.createdBy IN (:users)"; + $sql .= " AND w.createdBy = (:userCreated)"; - foreach ($filters['users'] as $key => $user) { - $sql .= "OR :user_" . $key . " IN w.referrers)"; + $sql .= " OR :userReferrer IN (w.referrers)"; + } - $nq = $this->em->createNativeQuery($sql, $rsm) - ->setParameter(':user_' . $key); - } - - // ... to be continued + if (null !== ($after = $filters['after'] ?? null) && null === $filters['before']) { + $sql .= " AND w.startdate::date >= :after"; + } elseif (null !== ($before = $filters['before'] ?? null) && null === $filters['after']) { + $sql .= " AND COALESCE(w.enddate::date, 'infinity'::date) <= :before"; + } elseif (null !== ($after = $filters['after'] ?? null) && null !== ($before = $filters['before'] ?? null)) { + $sql .= " AND w.startdate::date >= :after AND COALESCE(w.enddate::date, 'now'::date) <= :before"; } // set limit and offset + $sql .= " ORDER BY + CASE WHEN enddate IS NULL THEN '-infinity'::timestamp ELSE 'infinity'::timestamp END ASC, + startdate DESC, + enddate DESC, + id DESC"; + $sql .= " LIMIT :limit OFFSET :offset"; + $typeIds = []; + foreach ($filters['types'] as $type) { + $typeIds[] = $type->getId(); + } + $nq = $this->em->createNativeQuery($sql, $rsm) ->setParameter('periodId', $period->getId(), Types::INTEGER) + ->setParameter('types', $typeIds) + ->setParameter('userCreated', $filters['user']) + ->setParameter('userReferrer', $filters['user']) + ->setParameter('after', $filters['after']) + ->setParameter('before', $filters['before']) ->setParameter('limit', $limit, Types::INTEGER) ->setParameter('offset', $offset, Types::INTEGER); From 29306d2b66bcd6a1e3882391ed22c863140bbbc6 Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Wed, 24 May 2023 19:55:17 +0200 Subject: [PATCH 283/321] UX: [vue][onTheFly] improve residential address position in modale --- .../_components/Entity/AddressRenderBox.vue | 2 +- .../_components/Entity/PersonRenderBox.vue | 93 +++++++------------ 2 files changed, 33 insertions(+), 62 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/Entity/AddressRenderBox.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/Entity/AddressRenderBox.vue index 14a376856..00fb2b996 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/Entity/AddressRenderBox.vue +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/Entity/AddressRenderBox.vue @@ -1,6 +1,6 @@