From 679d19e2a13a2b66155273a6cfa7eaf4b673096d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Mon, 30 May 2022 10:01:27 +0200 Subject: [PATCH 01/33] allow null values for private comment --- .../Entity/Embeddable/PrivateCommentEmbeddable.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Entity/Embeddable/PrivateCommentEmbeddable.php b/src/Bundle/ChillMainBundle/Entity/Embeddable/PrivateCommentEmbeddable.php index 09a35324e..00e0f29d7 100644 --- a/src/Bundle/ChillMainBundle/Entity/Embeddable/PrivateCommentEmbeddable.php +++ b/src/Bundle/ChillMainBundle/Entity/Embeddable/PrivateCommentEmbeddable.php @@ -54,9 +54,9 @@ class PrivateCommentEmbeddable return $this; } - public function setCommentForUser(User $user, string $content): self + public function setCommentForUser(User $user, ?string $content): self { - $this->comments[$user->getId()] = trim($content); + $this->comments[$user->getId()] = trim((string) $content); return $this; } From 0849b2d5f401d75de119f4691ee442f457e15153 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Mon, 30 May 2022 21:16:40 +0200 Subject: [PATCH 02/33] docgen: fix title of origin --- src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php | 4 ++++ .../ChillPersonBundle/Entity/AccompanyingPeriod/Origin.php | 7 +++---- .../Normalizer/AccompanyingPeriodDocGenNormalizer.php | 1 + .../Normalizer/AccompanyingPeriodOriginNormalizer.php | 2 +- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php index da1709f48..ab51bbf85 100644 --- a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php +++ b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php @@ -692,6 +692,10 @@ class AccompanyingPeriod implements return [[self::STEP_DRAFT, self::STEP_CONFIRMED]]; } + if ($this->getStep() === self::STEP_CLOSED) { + return [[self::STEP_DRAFT, self::STEP_CONFIRMED, self::STEP_CLOSED]]; + } + throw new LogicException('no validation group permitted with this step: ' . $this->getStep()); } diff --git a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/Origin.php b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/Origin.php index 7a1114b3e..492d7d995 100644 --- a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/Origin.php +++ b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/Origin.php @@ -14,7 +14,6 @@ namespace Chill\PersonBundle\Entity\AccompanyingPeriod; use DateTimeImmutable; use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Serializer\Annotation as Serializer; -use Symfony\Component\Serializer\Annotation\Groups; /** * @ORM\Entity @@ -31,20 +30,20 @@ class Origin * @ORM\Id * @ORM\GeneratedValue * @ORM\Column(type="integer") - * @Groups({"read", "docgen:read"}) + * @Serializer\Groups({"read", "docgen:read"}) */ private ?int $id = null; /** * @ORM\Column(type="json") - * @Groups({"read", "docgen:read"}) + * @Serializer\Groups({"read", "docgen:read"}) * @Serializer\Context({"is-translatable": true}, groups={"docgen:read"}) */ private array $label = []; /** * @ORM\Column(type="date_immutable", nullable=true) - * @Groups({"read"}) + * @Serializer\Groups({"read"}) */ private ?DateTimeImmutable $noActiveAfter = null; diff --git a/src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodDocGenNormalizer.php b/src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodDocGenNormalizer.php index fab2a022d..79adc560c 100644 --- a/src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodDocGenNormalizer.php +++ b/src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodDocGenNormalizer.php @@ -121,6 +121,7 @@ class AccompanyingPeriodDocGenNormalizer implements ContextAwareNormalizerInterf 'type' => 'accompanying_period', 'isNull' => false, 'closingDate' => $this->normalizer->normalize($period->getClosingDate(), $format, $dateContext), + 'closingMotive' => $this->normalizer->normalize($period->getClosingMotive(), $format, array_merge($context, ['docgen:expects' => AccompanyingPeriod\ClosingMotive::class])), 'confidential' => $period->isConfidential(), 'createdAt' => $this->normalizer->normalize($period->getCreatedAt(), $format, $dateContext), 'createdBy' => $this->normalizer->normalize($period->getCreatedBy(), $format, $userContext), diff --git a/src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodOriginNormalizer.php b/src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodOriginNormalizer.php index 66f65b67b..6cc3d446b 100644 --- a/src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodOriginNormalizer.php +++ b/src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodOriginNormalizer.php @@ -35,6 +35,6 @@ final class AccompanyingPeriodOriginNormalizer implements NormalizerInterface public function supportsNormalization($data, $format = null): bool { - return $data instanceof Origin; + return $data instanceof Origin && $format === 'json'; } } From a4e3ffbe27f85a92de4ef2630be71617da8f0856 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Mon, 30 May 2022 22:41:47 +0200 Subject: [PATCH 03/33] fix cs --- .../migrations/Version20220527234046.php | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/Bundle/ChillCalendarBundle/migrations/Version20220527234046.php b/src/Bundle/ChillCalendarBundle/migrations/Version20220527234046.php index c53f82661..9cb68932e 100644 --- a/src/Bundle/ChillCalendarBundle/migrations/Version20220527234046.php +++ b/src/Bundle/ChillCalendarBundle/migrations/Version20220527234046.php @@ -1,5 +1,12 @@ addSql('ALTER TABLE chill_calendar.calendar ALTER COLUMN privateComment_comments DROP NOT NULL'); + $this->addSql('ALTER TABLE chill_calendar.calendar ALTER COLUMN privateComment_comments SET DEFAULT NULL'); + } + public function getDescription(): string { return ''; @@ -19,12 +32,5 @@ final class Version20220527234046 extends AbstractMigration $this->addSql('UPDATE chill_calendar.calendar SET privateComment_comments=\'{}\' WHERE privateComment_comments IS NULL'); $this->addSql('ALTER TABLE chill_calendar.calendar ALTER COLUMN privateComment_comments SET NOT NULL'); $this->addSql('ALTER TABLE chill_calendar.calendar ALTER COLUMN privateComment_comments SET DEFAULT \'{}\''); - - } - - public function down(Schema $schema): void - { - $this->addSql('ALTER TABLE chill_calendar.calendar ALTER COLUMN privateComment_comments DROP NOT NULL'); - $this->addSql('ALTER TABLE chill_calendar.calendar ALTER COLUMN privateComment_comments SET DEFAULT NULL'); } } From f92cef02cff90455bf0a67e4c51c898406478bc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Mon, 30 May 2022 22:43:50 +0200 Subject: [PATCH 04/33] fix creating a new AccompanyingPeriodWorkEvaluationDocument when replacing the document (the workflow was lost) --- CHANGELOG.md | 11 +- .../vuejs/AccompanyingCourseWorkEdit/store.js | 8 + .../AccompanyingPeriodOriginNormalizer.php | 2 +- ...anyingPeriodWorkEvaluationDenormalizer.php | 14 -- ...ngPeriodWorkEvaluationDenormalizerTest.php | 140 ++++++++++++++++++ 5 files changed, 158 insertions(+), 17 deletions(-) create mode 100644 src/Bundle/ChillPersonBundle/Tests/Serializer/Normalizer/AccompanyingPeriodWorkEvaluationDenormalizerTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f61f05de..f6b15672e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,15 @@ and this project adheres to ## Unreleased + +## 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) @@ -28,8 +37,6 @@ and this project adheres to * [address] can add extra address info even if noAddress (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/576) -## Test releases - ### 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) diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/store.js b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/store.js index caec4fd05..4b997d002 100644 --- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/store.js +++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/store.js @@ -232,6 +232,14 @@ const store = createStore({ return; } + let doc = evaluation.documents.find(d => d.key === payload.oldDocument.key); + + if (typeof doc === 'undefined') { + console.error('doc not found'); + } + + doc.storedObject = payload.document.storedObject; + return; let newDocument = Object.assign( payload.document, { key: evaluation.documents.length + 1, diff --git a/src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodOriginNormalizer.php b/src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodOriginNormalizer.php index 6cc3d446b..ca7589e79 100644 --- a/src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodOriginNormalizer.php +++ b/src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodOriginNormalizer.php @@ -35,6 +35,6 @@ final class AccompanyingPeriodOriginNormalizer implements NormalizerInterface public function supportsNormalization($data, $format = null): bool { - return $data instanceof Origin && $format === 'json'; + return $data instanceof Origin && 'json' === $format; } } diff --git a/src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodWorkEvaluationDenormalizer.php b/src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodWorkEvaluationDenormalizer.php index 4680d9fa7..77e289e6a 100644 --- a/src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodWorkEvaluationDenormalizer.php +++ b/src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodWorkEvaluationDenormalizer.php @@ -13,8 +13,6 @@ namespace Chill\PersonBundle\Serializer\Normalizer; use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluation; use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluationDocument; -use Chill\PersonBundle\Repository\AccompanyingPeriod\AccompanyingPeriodWorkRepository; -use Doctrine\ORM\EntityManagerInterface; use Symfony\Component\Serializer\Normalizer\AbstractNormalizer; use Symfony\Component\Serializer\Normalizer\ContextAwareDenormalizerInterface; use Symfony\Component\Serializer\Normalizer\DenormalizerAwareInterface; @@ -35,18 +33,6 @@ class AccompanyingPeriodWorkEvaluationDenormalizer implements ContextAwareDenorm use ObjectToPopulateTrait; - private EntityManagerInterface $em; - - private AccompanyingPeriodWorkRepository $workRepository; - - public function __construct( - AccompanyingPeriodWorkRepository $workRepository, - EntityManagerInterface $em - ) { - $this->workRepository = $workRepository; - $this->em = $em; - } - public function denormalize($data, $type, $format = null, array $context = []) { $evaluation = $this->denormalizer->denormalize($data, $type, $format, array_merge( diff --git a/src/Bundle/ChillPersonBundle/Tests/Serializer/Normalizer/AccompanyingPeriodWorkEvaluationDenormalizerTest.php b/src/Bundle/ChillPersonBundle/Tests/Serializer/Normalizer/AccompanyingPeriodWorkEvaluationDenormalizerTest.php new file mode 100644 index 000000000..f46e76932 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Serializer/Normalizer/AccompanyingPeriodWorkEvaluationDenormalizerTest.php @@ -0,0 +1,140 @@ +markTestIncomplete('not yet finished'); + $evaluation = new AccompanyingPeriodWorkEvaluation(); + $doc = new AccompanyingPeriodWorkEvaluationDocument(); + $doc->setStoredObject($storedObject = new StoredObject()); + $reflectionProperty = new ReflectionProperty(AccompanyingPeriodWorkEvaluationDocument::class, 'id'); + $reflectionProperty->setAccessible(true); + $reflectionProperty->setValue($doc, 1); + + $evaluation->addDocument($doc); + + $data = json_decode(self::ENCODED_DATA); + $context = + [AbstractNormalizer::OBJECT_TO_POPULATE => $evaluation, 'groups' => ['write']]; + + $denormalizer = new AccompanyingPeriodWorkEvaluationDenormalizer(); + + /* + $this->assertTrue( + $denormalizer->supportsDenormalization( + $data, + AccompanyingPeriodWorkEvaluation::class, + 'json', + $context + ) + ); + */ + + $denormalizedEvaluation = $denormalizer->denormalize( + $data, + AccompanyingPeriodWorkEvaluation::class, + 'json', + $context + ); + + $this->assertSame($evaluation, $denormalizedEvaluation); + $this->assertCount(1, $evaluation->getDocuments()); + $this->assertSame($doc, $evaluation->getDocuments()->first()); + $this->assertNotSame($storedObject, $evaluation->getDocuments()->first()->getStoredObject()); + } +} From 75490306a2ba3b23fc24b8591072ac6ef38bd414 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Wed, 1 Jun 2022 11:04:23 +0200 Subject: [PATCH 05/33] add pagination on workflow list page --- .../ChillMainBundle/Resources/views/Workflow/list.html.twig | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Bundle/ChillMainBundle/Resources/views/Workflow/list.html.twig b/src/Bundle/ChillMainBundle/Resources/views/Workflow/list.html.twig index 562413bc2..85a521d2a 100644 --- a/src/Bundle/ChillMainBundle/Resources/views/Workflow/list.html.twig +++ b/src/Bundle/ChillMainBundle/Resources/views/Workflow/list.html.twig @@ -115,5 +115,6 @@ {% endfor %} {% endif %} + {{ chill_pagination(paginator) }} {% endblock %} From 83de518b451b53c5ccafe3ab4db4da049978d770 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Wed, 1 Jun 2022 11:08:20 +0200 Subject: [PATCH 06/33] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f6b15672e..8fa527749 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to ## Unreleased +* [workflow]: added pagination to workflow list page ## Test releases From 8d70562132fc96f8e0ab3830e803fb271d34ca0f Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Wed, 1 Jun 2022 11:37:29 +0200 Subject: [PATCH 07/33] null error in task widget on homepage fixed --- CHANGELOG.md | 1 + .../Resources/public/vuejs/HomepageWidget/MyTasks.vue | 9 +++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8fa527749..8c479fe6b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to * [workflow]: added pagination to workflow list page +* [homepage_widget]: null error on tasks widget fixed ## Test releases diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/HomepageWidget/MyTasks.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/HomepageWidget/MyTasks.vue index 572b8f83a..77a2bd34c 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/HomepageWidget/MyTasks.vue +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/HomepageWidget/MyTasks.vue @@ -1,5 +1,5 @@ - +
{{ $t('my_tasks.description_alert') }}
{{ $t('no_data') }} @@ -49,7 +50,7 @@ - + + + From f0187536c173da203cdef839e3242e52b125ecaf Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Mon, 13 Jun 2022 15:35:35 +0200 Subject: [PATCH 13/33] visual changes when option 'create household' is checked in user create form --- .../vuejs/Address/components/ShowPane.vue | 81 +++++++++++++------ 1 file changed, 58 insertions(+), 23 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/ShowPane.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/ShowPane.vue index 4be073991..4197079d4 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/ShowPane.vue +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/ShowPane.vue @@ -15,27 +15,46 @@ {{ $t('wait_redirection') }} -
-

- {{ $t('not_yet_address') }} -

+
+
+ +

+ {{ $t('not_yet_address') }} +

+ + + + +
+
+ +
+ + +
- - - - + + From 4719a743078d73d224d1c06f982517fced5192fb Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Mon, 13 Jun 2022 17:35:21 +0200 Subject: [PATCH 14/33] constraint added to workflow transtion - cannot be null --- CHANGELOG.md | 1 + .../ChillMainBundle/Form/WorkflowStepType.php | 39 +++++++++++-------- .../translations/messages.fr.yml | 1 + 3 files changed, 24 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ea0e2c0a..2ed9cdebf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ and this project adheres to * [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) ## Test releases diff --git a/src/Bundle/ChillMainBundle/Form/WorkflowStepType.php b/src/Bundle/ChillMainBundle/Form/WorkflowStepType.php index 9a2fd1b6c..3eba23b37 100644 --- a/src/Bundle/ChillMainBundle/Form/WorkflowStepType.php +++ b/src/Bundle/ChillMainBundle/Form/WorkflowStepType.php @@ -109,6 +109,7 @@ class WorkflowStepType extends AbstractType 'multiple' => false, 'expanded' => true, 'choices' => $choices, + 'constraints' => [new NotNull()], 'choice_label' => function (Transition $transition) use ($workflow) { $meta = $workflow->getMetadataStore()->getTransitionMetadata($transition); @@ -208,24 +209,28 @@ class WorkflowStepType extends AbstractType $transition = $form['transition']->getData(); $toFinal = true; - foreach ($transition->getTos() as $to) { - $meta = $workflow->getMetadataStore()->getPlaceMetadata($to); - - if ( - !array_key_exists('isFinal', $meta) || false === $meta['isFinal'] - ) { - $toFinal = false; - } - } - - $destUsers = $form['future_dest_users']->getData(); - $destEmails = $form['future_dest_emails']->getData(); - - if (!$toFinal && [] === $destUsers && [] === $destEmails) { + if (null === $transition) { $context - ->buildViolation('workflow.You must add at least one dest user or email') - ->atPath('future_dest_users') - ->addViolation(); + ->buildViolation('workflow.You must select a next step, pick another decision if no next steps are available'); + } else { + foreach ($transition->getTos() as $to) { + $meta = $workflow->getMetadataStore()->getPlaceMetadata($to); + + if ( + !array_key_exists('isFinal', $meta) || false === $meta['isFinal'] + ) { + $toFinal = false; + } + } + $destUsers = $form['future_dest_users']->getData(); + $destEmails = $form['future_dest_emails']->getData(); + + if (!$toFinal && [] === $destUsers && [] === $destEmails) { + $context + ->buildViolation('workflow.You must add at least one dest user or email') + ->atPath('future_dest_users') + ->addViolation(); + } } } ), diff --git a/src/Bundle/ChillMainBundle/translations/messages.fr.yml b/src/Bundle/ChillMainBundle/translations/messages.fr.yml index c5ab02d6b..376806292 100644 --- a/src/Bundle/ChillMainBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillMainBundle/translations/messages.fr.yml @@ -463,6 +463,7 @@ workflow: Previous transitionned: Anciens workflows Previous workflow transitionned help: Workflows où vous avez exécuté une action. For: Pour + You must select a next step, pick another decision if no next steps are available: Il faut une prochaine étape. Choissisez une autre décision si nécessaire. Subscribe final: Recevoir une notification à l'étape finale From 0943366d39cac376b6f928eeace55d2495ecbdde Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Mon, 13 Jun 2022 17:59:29 +0200 Subject: [PATCH 15/33] only prefill agents traitants of action if parcours has a referrer, otherwise null --- CHANGELOG.md | 1 + .../EventListener/AccompanyingPeriodWorkEventListener.php | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ed9cdebf..9d9a0da1c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ and this project adheres to * [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) +* [action]: Agents traitants should be prefilled with referrer of the parcours or left empty if there is no referrer (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/696) ## Test releases diff --git a/src/Bundle/ChillPersonBundle/EventListener/AccompanyingPeriodWorkEventListener.php b/src/Bundle/ChillPersonBundle/EventListener/AccompanyingPeriodWorkEventListener.php index 83f9ca460..ba7a2bbc8 100644 --- a/src/Bundle/ChillPersonBundle/EventListener/AccompanyingPeriodWorkEventListener.php +++ b/src/Bundle/ChillPersonBundle/EventListener/AccompanyingPeriodWorkEventListener.php @@ -26,8 +26,9 @@ class AccompanyingPeriodWorkEventListener public function prePersistAccompanyingPeriodWork(AccompanyingPeriodWork $work): void { - if ($this->security->getUser() instanceof User) { - $work->addReferrer($this->security->getUser()); + $referrer = $work->getAccompanyingPeriod()->getUser(); + if (null !== $referrer) { + $work->addReferrer($referrer); } } } From a48b990c736786d36e83f26ae9f3fc63fed4619e Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Tue, 14 Jun 2022 17:15:33 +0200 Subject: [PATCH 16/33] condition correction to fix display of addAddress btn in parcours and household tunnel --- .../public/vuejs/Address/components/ShowPane.vue | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/ShowPane.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/ShowPane.vue index 4197079d4..0b2047a2a 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/ShowPane.vue +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/ShowPane.vue @@ -55,6 +55,21 @@ +
+ + + +
+ From 86afe2f7026b3fb49fe137c50e4ae13388e1035d Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Wed, 15 Jun 2022 15:58:53 +0200 Subject: [PATCH 24/33] fix condition --- .../Resources/public/vuejs/Address/components/ShowPane.vue | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/ShowPane.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/ShowPane.vue index 9a1d5cdb3..35b502f25 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/ShowPane.vue +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/ShowPane.vue @@ -37,14 +37,14 @@ -
+
-
+
@@ -158,12 +158,13 @@ export default { text-align: center; box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px; padding:1.5rem; + margin-bottom:2rem; i { font-size:2rem; margin-bottom:2rem; } .add-address-btn { - // display: block + display: block } } From 72ce5c716daf75e5b06b775a7808242e58ade4cf Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Wed, 15 Jun 2022 16:02:37 +0200 Subject: [PATCH 25/33] remove border from address --- .../Resources/public/vuejs/Address/components/ShowPane.vue | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/ShowPane.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/ShowPane.vue index 35b502f25..a2731a9ac 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/ShowPane.vue +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/ShowPane.vue @@ -148,11 +148,7 @@ export default { .address-container { display:flex; justify-content:flex-end; - // padding-right: 1rem; border-radius: 5px; - border: 1px dotted; - border-left: 1px dotted; - border-right: 1px dotted; } .no-address-yet { text-align: center; From ccaf430b378dc7436f84a8951ff9f2e0e689bf61 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Wed, 15 Jun 2022 16:02:37 +0200 Subject: [PATCH 26/33] remove border from address --- .../public/vuejs/Address/components/ShowPane.vue | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/ShowPane.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/ShowPane.vue index 35b502f25..7f7b1b529 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/ShowPane.vue +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/ShowPane.vue @@ -58,6 +58,10 @@
+
+ +
+
@@ -148,11 +152,7 @@ export default { .address-container { display:flex; justify-content:flex-end; - // padding-right: 1rem; border-radius: 5px; - border: 1px dotted; - border-left: 1px dotted; - border-right: 1px dotted; } .no-address-yet { text-align: center; From 1bd00c3f4c0653ede1b677dd27fb6b88c09a19ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 15 Jun 2022 14:18:59 +0200 Subject: [PATCH 27/33] fix editing thirdparty without date --- src/Bundle/ChillThirdPartyBundle/Entity/ThirdParty.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Bundle/ChillThirdPartyBundle/Entity/ThirdParty.php b/src/Bundle/ChillThirdPartyBundle/Entity/ThirdParty.php index f060c4bfb..a1df7ca55 100644 --- a/src/Bundle/ChillThirdPartyBundle/Entity/ThirdParty.php +++ b/src/Bundle/ChillThirdPartyBundle/Entity/ThirdParty.php @@ -767,9 +767,9 @@ class ThirdParty implements TrackCreationInterface, TrackUpdateInterface return $this; } - public function setFirstname(string $firstname): self + public function setFirstname(?string $firstname): self { - $this->firstname = $firstname; + $this->firstname = trim((string) $firstname); return $this; } @@ -781,9 +781,9 @@ class ThirdParty implements TrackCreationInterface, TrackUpdateInterface return $this; } - public function setName($name): self + public function setName(?string $name): self { - $this->name = $name; + $this->name = (string) $name; return $this; } From 8982697a73178ffef5a6b688f2eb9dc7981ef507 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 15 Jun 2022 15:04:07 +0200 Subject: [PATCH 28/33] add missing translation message --- src/Bundle/ChillPersonBundle/translations/messages.fr.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index a93c51296..266970698 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -88,6 +88,7 @@ All genders: tous les genres Any person selected: Aucune personne sélectionnée Create a household and add an address: Ajouter une adresse pour un usager non suivi et seul dans un ménage A new household will be created. The person will be member of this household.: Un nouveau ménage va être créé. L'usager sera membre de ce ménage. +Comment on the gender: Commentaire sur le genre # dédoublonnage Old person: Doublon From da9eba2618f679523259c508b9f7d6696553202b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 16 Jun 2022 15:37:51 +0200 Subject: [PATCH 29/33] add regulation list and basic regulation list query --- ...mpanyingPeriodRegulationListController.php | 167 ++++++++++++++++++ .../Menu/SectionMenuBuilder.php | 27 ++- .../AccompanyingPeriodACLAwareRepository.php | 116 ++++++++++++ ...nyingPeriodACLAwareRepositoryInterface.php | 17 ++ .../dispatch_list.html.twig | 88 +++++++++ ...yingPeriodRegulationListControllerTest.php | 39 ++++ 6 files changed, 446 insertions(+), 8 deletions(-) create mode 100644 src/Bundle/ChillPersonBundle/Controller/AccompanyingPeriodRegulationListController.php create mode 100644 src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourse/dispatch_list.html.twig create mode 100644 src/Bundle/ChillPersonBundle/Tests/Controller/AccompanyingPeriodRegulationListControllerTest.php diff --git a/src/Bundle/ChillPersonBundle/Controller/AccompanyingPeriodRegulationListController.php b/src/Bundle/ChillPersonBundle/Controller/AccompanyingPeriodRegulationListController.php new file mode 100644 index 000000000..ef38b7335 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Controller/AccompanyingPeriodRegulationListController.php @@ -0,0 +1,167 @@ +accompanyingPeriodACLAwareRepository = $accompanyingPeriodACLAwareRepository; + $this->engine = $engine; + $this->formFactory = $formFactory; + $this->paginatorFactory = $paginatorFactory; + $this->security = $security; + $this->translatableStringHelper = $translatableStringHelper; + } + + /** + * @Route("/{_locale}/person/periods/undispatched", name="chill_person_course_list_regulation") + */ + public function listRegul(Request $request): Response + { + if (!$this->security->isGranted('ROLE_USER') || !$this->security->getUser() instanceof User) { + throw new AccessDeniedHttpException(); + } + + $form = $this->buildFilterForm(); + + $form->handleRequest($request); + + $total = $this->accompanyingPeriodACLAwareRepository->countByUnDispatched( + $form['jobs']->getData(), + $form['services']->getData(), + $form['locations']->getData(), + ); + $paginator = $this->paginatorFactory->create($total); + $periods = $this->accompanyingPeriodACLAwareRepository + ->findByUnDispatched( + $form['jobs']->getData(), + $form['services']->getData(), + $form['locations']->getData(), + $paginator->getItemsPerPage(), + $paginator->getCurrentPageFirstItemNumber() + ); + + return new Response( + $this->engine->render('@ChillPerson/AccompanyingCourse/dispatch_list.html.twig', [ + 'paginator' => $paginator, + 'periods' => $periods, + 'form' => $form->createView(), + ]) + ); + } + + private function buildFilterForm(): FormInterface + { + $data = [ + 'services' => [], + 'jobs' => [], + 'locations' => [], + ]; + + $builder = $this->formFactory->createBuilder(FormType::class, $data, [ + 'method' => 'get', 'csrf_protection' => false, ]); + + $builder + ->add('services', EntityType::class, [ + 'class' => Scope::class, + 'query_builder' => static function (EntityRepository $er) { + return $er->createQueryBuilder('s'); + }, + 'choice_label' => function (Scope $s) { + return $this->translatableStringHelper->localize($s->getName()); + }, + 'multiple' => true, + 'label' => 'Service', + 'required' => false, + ]) + ->add('jobs', EntityType::class, [ + 'class' => UserJob::class, + 'query_builder' => static function (EntityRepository $er) { + $qb = $er->createQueryBuilder('j'); + $qb->andWhere($qb->expr()->eq('j.active', "'TRUE'")); + + return $qb; + }, + 'choice_label' => function (UserJob $j) { + return $this->translatableStringHelper->localize($j->getLabel()); + }, + 'multiple' => true, + 'label' => 'Métier', + 'required' => false, + ]) + ->add('locations', EntityType::class, [ + 'class' => Location::class, + 'query_builder' => static function (EntityRepository $er) { + $qb = $er->createQueryBuilder('l'); + $qb + ->join('l.locationType', 't') + ->where( + $qb->expr()->andX( + $qb->expr()->eq('t.availableForUsers', "'TRUE'"), + $qb->expr()->eq('t.active', "'TRUE'"), + $qb->expr()->eq('l.active', "'TRUE'"), + $qb->expr()->eq('l.availableForUsers', "'TRUE'") + ) + ); + + return $qb; + }, + 'choice_label' => static function (Location $l) { + return $l->getName(); + }, + 'multiple' => true, + 'group_by' => function (Location $l) { + if (null === $type = $l->getLocationType()) { + return null; + } + + return $this->translatableStringHelper->localize($type->getTitle()); + }, + 'label' => 'Localisation administrative', + 'required' => false, + ]); + + return $builder->getForm(); + } +} diff --git a/src/Bundle/ChillPersonBundle/Menu/SectionMenuBuilder.php b/src/Bundle/ChillPersonBundle/Menu/SectionMenuBuilder.php index 722598ef7..183d2353e 100644 --- a/src/Bundle/ChillPersonBundle/Menu/SectionMenuBuilder.php +++ b/src/Bundle/ChillPersonBundle/Menu/SectionMenuBuilder.php @@ -11,12 +11,13 @@ declare(strict_types=1); namespace Chill\PersonBundle\Menu; +use Chill\MainBundle\Entity\User; use Chill\MainBundle\Routing\LocalMenuBuilderInterface; 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\Authorization\AuthorizationCheckerInterface; +use Symfony\Component\Security\Core\Security; use Symfony\Contracts\Translation\TranslatorInterface; /** @@ -24,20 +25,20 @@ use Symfony\Contracts\Translation\TranslatorInterface; */ class SectionMenuBuilder implements LocalMenuBuilderInterface { - protected AuthorizationCheckerInterface $authorizationChecker; - protected ParameterBagInterface $parameterBag; protected TranslatorInterface $translator; + private Security $security; + /** * SectionMenuBuilder constructor. */ - public function __construct(AuthorizationCheckerInterface $authorizationChecker, TranslatorInterface $translator, ParameterBagInterface $parameterBag) + public function __construct(ParameterBagInterface $parameterBag, Security $security, TranslatorInterface $translator) { - $this->authorizationChecker = $authorizationChecker; - $this->translator = $translator; $this->parameterBag = $parameterBag; + $this->security = $security; + $this->translator = $translator; } /** @@ -45,7 +46,7 @@ class SectionMenuBuilder implements LocalMenuBuilderInterface */ public function buildMenu($menuId, MenuItem $menu, array $parameters) { - if ($this->authorizationChecker->isGranted(PersonVoter::CREATE) && $this->parameterBag->get('chill_person.create_person_allowed')) { + if ($this->security->isGranted(PersonVoter::CREATE) && $this->parameterBag->get('chill_person.create_person_allowed')) { $menu->addChild($this->translator->trans('Add a person'), [ 'route' => 'chill_person_new', ]) @@ -65,7 +66,7 @@ class SectionMenuBuilder implements LocalMenuBuilderInterface ]); } - if ($this->authorizationChecker->isGranted(AccompanyingPeriodVoter::REASSIGN_BULK, null)) { + if ($this->security->isGranted(AccompanyingPeriodVoter::REASSIGN_BULK, null)) { $menu->addChild($this->translator->trans('reassign.Bulk reassign'), [ 'route' => 'chill_course_list_reassign', ]) @@ -74,6 +75,16 @@ class SectionMenuBuilder implements LocalMenuBuilderInterface 'icons' => [], ]); } + + if ($this->security->getUser() instanceof User && $this->security->isGranted('ROLE_USER')) { + $menu + ->addChild('Régulation', [ + 'route' => 'chill_person_course_list_regulation', + ]) + ->setExtras([ + 'order' => 150, + ]); + } } public static function getMenuIds(): array diff --git a/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodACLAwareRepository.php b/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodACLAwareRepository.php index 8efd60e58..653fed9c2 100644 --- a/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodACLAwareRepository.php +++ b/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodACLAwareRepository.php @@ -11,13 +11,19 @@ declare(strict_types=1); namespace Chill\PersonBundle\Repository; +use Chill\MainBundle\Entity\Location; +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\PersonBundle\Entity\AccompanyingPeriod; +use Chill\PersonBundle\Entity\AccompanyingPeriodParticipation; use Chill\PersonBundle\Entity\Person; +use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter; use DateTime; +use Doctrine\ORM\QueryBuilder; use Symfony\Component\Security\Core\Security; use function count; @@ -62,6 +68,15 @@ final class AccompanyingPeriodACLAwareRepository implements AccompanyingPeriodAC return $qb; } + public function countByUnDispatched(array $jobs, array $services, array $administrativeLocations): int + { + $qb = $this->addACLByUnDispatched($this->buildQueryUnDispatched($jobs, $services, $administrativeLocations)); + + $qb->select('COUNT(ap)'); + + return $qb->getQuery()->getSingleScalarResult(); + } + public function countByUserOpenedAccompanyingPeriod(?User $user): int { if (null === $user) { @@ -126,6 +141,23 @@ final class AccompanyingPeriodACLAwareRepository implements AccompanyingPeriodAC return $qb->getQuery()->getResult(); } + public function findByUnDispatched(array $jobs, array $services, array $administrativeLocations, ?int $limit = null, ?int $offset = null): array + { + $qb = $this->addACLByUnDispatched($this->buildQueryUnDispatched($jobs, $services, $administrativeLocations)); + + $qb->select('ap'); + + if (null !== $limit) { + $qb->setMaxResults($limit); + } + + if (null !== $offset) { + $qb->setFirstResult($offset); + } + + return $qb->getQuery()->getResult(); + } + /** * @return array|AccompanyingPeriod[] */ @@ -146,4 +178,88 @@ final class AccompanyingPeriodACLAwareRepository implements AccompanyingPeriodAC return $qb->getQuery()->getResult(); } + + private function addACLByUnDispatched(QueryBuilder $qb): QueryBuilder + { + $centers = $this->authorizationHelper->getReachableCenters( + $this->security->getUser(), + AccompanyingPeriodVoter::SEE + ); + + $orX = $qb->expr()->orX(); + + if (0 === count($centers)) { + return $qb->andWhere("'FALSE' = 'TRUE'"); + } + + foreach ($centers as $key => $center) { + $scopes = $this->authorizationHelper + ->getReachableCircles( + $this->security->getUser(), + AccompanyingPeriodVoter::SEE, + $center + ); + + $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->setParameter('center_' . $key, $center); + $orScope = $qb->expr()->orX(); + + foreach ($scopes as $skey => $scope) { + $orScope->add( + $qb->expr()->isMemberOf(':scope_' . $key . '_' . $skey, 'ap.scopes') + ); + $qb->setParameter('scope_' . $key . '_' . $skey, $scope); + } + + $and->add($orScope); + $orX->add($and); + } + + return $qb->andWhere($orX); + } + + /** + * @param array|UserJob[] $jobs + * @param array|Scope[] $services + * @param array|Location[] $locations + */ + private function buildQueryUnDispatched(array $jobs, array $services, array $locations): QueryBuilder + { + $qb = $this->accompanyingPeriodRepository->createQueryBuilder('ap'); + + $qb->where( + $qb->expr()->andX( + $qb->expr()->isNull('ap.user'), + $qb->expr()->neq('ap.step', ':draft'), + $qb->expr()->neq('ap.step', ':closed') + ) + ) + ->setParameter('draft', AccompanyingPeriod::STEP_DRAFT) + ->setParameter('closed', AccompanyingPeriod::STEP_CLOSED); + + if (0 < count($jobs)) { + $qb->andWhere($qb->expr()->in('ap.job', ':jobs')) + ->setParameter('jobs', $jobs); + } + + if (0 < count($locations)) { + $qb->andWhere($qb->expr()->in('ap.administrativeLocation', ':locations')) + ->setParameter('locations', $locations); + } + + if (0 < count($services)) { + $or = $qb->expr()->orX(); + + foreach ($services as $key => $service) { + $or->add($qb->expr()->isMemberOf('ap.scopes', ':scope_' . $key)); + $qb->setParameter('scope_' . $key, $service); + } + $qb->andWhere($or); + } + + return $qb; + } } diff --git a/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodACLAwareRepositoryInterface.php b/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodACLAwareRepositoryInterface.php index a02ec27c6..e8d0bd856 100644 --- a/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodACLAwareRepositoryInterface.php +++ b/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodACLAwareRepositoryInterface.php @@ -11,11 +11,20 @@ declare(strict_types=1); namespace Chill\PersonBundle\Repository; +use Chill\MainBundle\Entity\Scope; use Chill\MainBundle\Entity\User; +use Chill\MainBundle\Entity\UserJob; +use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\Person; interface AccompanyingPeriodACLAwareRepositoryInterface { + /** + * @param array|UserJob[] $jobs + * @param array|Scope[] $services + */ + public function countByUnDispatched(array $jobs, array $services, array $administrativeLocations): int; + public function countByUserOpenedAccompanyingPeriod(?User $user): int; public function findByPerson( @@ -26,5 +35,13 @@ interface AccompanyingPeriodACLAwareRepositoryInterface ?int $offset = null ): array; + /** + * @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[] + */ + public function findByUnDispatched(array $jobs, array $services, array $administrativeLocations, ?int $limit = null, ?int $offset = null): array; + public function findByUserOpenedAccompanyingPeriod(?User $user, array $orderBy = [], int $limit = 0, int $offset = 50): array; } diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourse/dispatch_list.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourse/dispatch_list.html.twig new file mode 100644 index 000000000..9b48883ef --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourse/dispatch_list.html.twig @@ -0,0 +1,88 @@ +{% extends 'ChillMainBundle::layout.html.twig' %} + +{% block title "Liste de parcours à répartir" %} + +{% block js %} + {{ encore_entry_script_tags('mod_set_referrer') }} +{% endblock %} + +{% block css %} + {{ encore_entry_link_tags('mod_set_referrer') }} +{% endblock %} + +{% macro period_meta(period) %} + {% if is_granted('CHILL_PERSON_ACCOMPANYING_PERIOD_UPDATE', period) %} +
+ {% set job_id = null %} + {% if period.job is defined %} + {% set job_id = period.job.id %} + {% endif %} + +
+ {% endif %} +{% endmacro %} + +{% macro period_actions(period) %} + {% if is_granted('CHILL_PERSON_ACCOMPANYING_PERIOD_SEE', period) %} +
  • + +
  • + {% endif %} +{% endmacro %} + +{% import _self as m %} + +{% block content %} +
    +

    {{ block('title') }}

    + + {{ form_start(form) }} +
    +
    + {{ form_label(form.locations ) }} + {{ form_widget(form.locations, {'attr': {'class': 'select2'}}) }} +
    +
    + {{ form_label(form.jobs) }} + {{ form_widget(form.jobs, {'attr': {'class': 'select2'}}) }} +
    +
    + {{ form_label(form.services) }} + {{ form_widget(form.services, {'attr': {'class': 'select2'}}) }} +
    +
    + +
      +
    • + +
    • +
    + + {{ form_end(form) }} + + + {% if periods|length == 0 %} +

    Aucun parcours à désigner, ou droits insuffisants pour les afficher

    + {% else %} + +

    {{ paginator.totalItems }} parcours à attribuer (calculé ce jour à {{ null|format_time('medium') }})

    + +
    + {% for period in periods %} + {% include '@ChillPerson/AccompanyingPeriod/_list_item.html.twig' with {'period': period, + 'recordAction': m.period_actions(period), 'itemMeta': m.period_meta(period) } %} + {% endfor %} +
    + {% endif %} + + {{ chill_pagination(paginator) }} + +
    +{% endblock %} + diff --git a/src/Bundle/ChillPersonBundle/Tests/Controller/AccompanyingPeriodRegulationListControllerTest.php b/src/Bundle/ChillPersonBundle/Tests/Controller/AccompanyingPeriodRegulationListControllerTest.php new file mode 100644 index 000000000..32f3a598c --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Controller/AccompanyingPeriodRegulationListControllerTest.php @@ -0,0 +1,39 @@ +getClientAuthenticated(); + + $client->request('GET', '/fr/person/periods/undispatched'); + + $this->assertResponseIsSuccessful(); + } +} From dfb583fa8b0662cd40c150081da1b6d60622e910 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 16 Jun 2022 15:37:59 +0200 Subject: [PATCH 30/33] fix cs --- src/Bundle/ChillMainBundle/Form/WorkflowStepType.php | 4 ++-- .../EventListener/AccompanyingPeriodWorkEventListener.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Form/WorkflowStepType.php b/src/Bundle/ChillMainBundle/Form/WorkflowStepType.php index 3eba23b37..b70e7a55b 100644 --- a/src/Bundle/ChillMainBundle/Form/WorkflowStepType.php +++ b/src/Bundle/ChillMainBundle/Form/WorkflowStepType.php @@ -215,7 +215,7 @@ class WorkflowStepType extends AbstractType } else { foreach ($transition->getTos() as $to) { $meta = $workflow->getMetadataStore()->getPlaceMetadata($to); - + if ( !array_key_exists('isFinal', $meta) || false === $meta['isFinal'] ) { @@ -224,7 +224,7 @@ class WorkflowStepType extends AbstractType } $destUsers = $form['future_dest_users']->getData(); $destEmails = $form['future_dest_emails']->getData(); - + if (!$toFinal && [] === $destUsers && [] === $destEmails) { $context ->buildViolation('workflow.You must add at least one dest user or email') diff --git a/src/Bundle/ChillPersonBundle/EventListener/AccompanyingPeriodWorkEventListener.php b/src/Bundle/ChillPersonBundle/EventListener/AccompanyingPeriodWorkEventListener.php index ba7a2bbc8..5fbf4b9ee 100644 --- a/src/Bundle/ChillPersonBundle/EventListener/AccompanyingPeriodWorkEventListener.php +++ b/src/Bundle/ChillPersonBundle/EventListener/AccompanyingPeriodWorkEventListener.php @@ -11,7 +11,6 @@ declare(strict_types=1); namespace Chill\PersonBundle\EventListener; -use Chill\MainBundle\Entity\User; use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork; use Symfony\Component\Security\Core\Security; @@ -27,6 +26,7 @@ class AccompanyingPeriodWorkEventListener public function prePersistAccompanyingPeriodWork(AccompanyingPeriodWork $work): void { $referrer = $work->getAccompanyingPeriod()->getUser(); + if (null !== $referrer) { $work->addReferrer($referrer); } From 0cfad13720cdea6857bf87c96fdddc03531be37b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 16 Jun 2022 21:30:46 +0200 Subject: [PATCH 31/33] fix normalization for null accompanying period docgen --- .../AccompanyingPeriodDocGenNormalizer.php | 1 + ...AccompanyingPeriodDocGenNormalizerTest.php | 53 +------------------ 2 files changed, 2 insertions(+), 52 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodDocGenNormalizer.php b/src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodDocGenNormalizer.php index 79adc560c..86deda604 100644 --- a/src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodDocGenNormalizer.php +++ b/src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodDocGenNormalizer.php @@ -44,6 +44,7 @@ class AccompanyingPeriodDocGenNormalizer implements ContextAwareNormalizerInterf private const PERIOD_NULL = [ 'id', 'closingDate' => DateTime::class, + 'closingMotive' => AccompanyingPeriod\ClosingMotive::class, 'confidential', 'confidentialText', 'createdAt' => DateTime::class, diff --git a/src/Bundle/ChillPersonBundle/Tests/Serializer/Normalizer/AccompanyingPeriodDocGenNormalizerTest.php b/src/Bundle/ChillPersonBundle/Tests/Serializer/Normalizer/AccompanyingPeriodDocGenNormalizerTest.php index 58ca55262..c42dc9a5a 100644 --- a/src/Bundle/ChillPersonBundle/Tests/Serializer/Normalizer/AccompanyingPeriodDocGenNormalizerTest.php +++ b/src/Bundle/ChillPersonBundle/Tests/Serializer/Normalizer/AccompanyingPeriodDocGenNormalizerTest.php @@ -65,6 +65,7 @@ final class AccompanyingPeriodDocGenNormalizerTest extends KernelTestCase 'type' => 'accompanying_period', 'isNull' => false, 'closingDate' => '@ignored', + 'closingMotive' => '@ignored', 'confidential' => true, 'confidentialText' => 'confidentiel', 'createdAt' => '@ignored', @@ -121,59 +122,7 @@ final class AccompanyingPeriodDocGenNormalizerTest extends KernelTestCase { $data = $this->normalizer->normalize(null, 'docgen', ['docgen:expects' => AccompanyingPeriod::class]); - $expected = [ - 'id' => '', - 'type' => 'accompanying_period', - 'closingDate' => '@ignored', - 'confidential' => false, - 'confidentialText' => '', - 'createdAt' => '@ignored', - 'createdBy' => '@ignored', - 'emergency' => false, - 'emergencyText' => '', - 'openingDate' => '@ignored', - 'originText' => '', - 'origin' => '@ignored', - 'requestorAnonymous' => false, - 'resources' => [], - 'socialIssues' => '@ignored', - 'intensity' => '', - 'step' => '', - 'closingMotiveText' => '', - 'socialIssuesText' => '', - 'scopes' => '@ignored', - 'scopesText' => '', - 'ref' => '@ignored', - 'participations' => '@ignored', - 'currentParticipations' => '@ignored', - 'isClosed' => false, - 'hasRef' => false, - 'hasRequestor' => false, - 'requestorKind' => 'none', - 'hasRequestorPerson' => false, - 'hasRequestorThirdParty' => false, - 'requestorPerson' => '@ignored', - 'requestorThirdParty' => '@ignored', - 'isNull' => true, - 'administrativeLocation' => '@ignored', - 'hasAdministrativeLocation' => false, - 'hasLocation' => false, - 'hasLocationPerson' => false, - 'location' => '@ignored', - 'locationPerson' => '@ignored', - 'works' => [], - ]; - $this->assertIsArray($data); - $this->assertEqualsCanonicalizing(array_keys($expected), array_keys($data)); - - foreach ($expected as $key => $item) { - if ('@ignored' === $item) { - continue; - } - - $this->assertEquals($item, $data[$key], "test the key {$key}"); - } } public function testNormalizeParticipations() From 832da83b277caa903251f9d05b6c6698477fac4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 16 Jun 2022 21:35:05 +0200 Subject: [PATCH 32/33] fix tests for person controller update --- .../Tests/Controller/PersonControllerUpdateTest.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Tests/Controller/PersonControllerUpdateTest.php b/src/Bundle/ChillPersonBundle/Tests/Controller/PersonControllerUpdateTest.php index 608a5bef5..c034e7a03 100644 --- a/src/Bundle/ChillPersonBundle/Tests/Controller/PersonControllerUpdateTest.php +++ b/src/Bundle/ChillPersonBundle/Tests/Controller/PersonControllerUpdateTest.php @@ -11,9 +11,11 @@ declare(strict_types=1); namespace Chill\PersonBundle\Tests\Controller; +use Chill\MainBundle\Entity\Center; use Chill\MainBundle\Test\PrepareClientTrait; use Chill\PersonBundle\Entity\Person; use Closure; +use Doctrine\ORM\EntityManagerInterface; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; /** @@ -55,10 +57,10 @@ final class PersonControllerUpdateTest extends WebTestCase { self::bootKernel(); - $this->em = self::$kernel->getContainer() - ->get('doctrine.orm.entity_manager'); + $this->em = self::$container + ->get(EntityManagerInterface::class); - $center = $this->em->getRepository(\Chill\MainBundle\Entity\Center::class) + $center = $this->em->getRepository(Center::class) ->findOneBy(['name' => 'Center A']); $this->person = (new Person()) From 1742dd4951e5a1697df58699f06741af15c83007 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Fri, 17 Jun 2022 13:34:05 +0200 Subject: [PATCH 33/33] add return path after changing location, and select2 on picking user location --- .../Form/UserCurrentLocationType.php | 1 + .../Routing/MenuBuilder/UserMenuBuilder.php | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Form/UserCurrentLocationType.php b/src/Bundle/ChillMainBundle/Form/UserCurrentLocationType.php index 4bdf61604..e7ae27b3a 100644 --- a/src/Bundle/ChillMainBundle/Form/UserCurrentLocationType.php +++ b/src/Bundle/ChillMainBundle/Form/UserCurrentLocationType.php @@ -43,6 +43,7 @@ class UserCurrentLocationType extends AbstractType }, 'placeholder' => 'Pick a location', 'required' => false, + 'attr' => ['class' => 'select2'], ]); } } diff --git a/src/Bundle/ChillMainBundle/Routing/MenuBuilder/UserMenuBuilder.php b/src/Bundle/ChillMainBundle/Routing/MenuBuilder/UserMenuBuilder.php index 6b6f9cceb..cacf9c073 100644 --- a/src/Bundle/ChillMainBundle/Routing/MenuBuilder/UserMenuBuilder.php +++ b/src/Bundle/ChillMainBundle/Routing/MenuBuilder/UserMenuBuilder.php @@ -16,6 +16,7 @@ use Chill\MainBundle\Notification\Counter\NotificationByUserCounter; use Chill\MainBundle\Routing\LocalMenuBuilderInterface; use Chill\MainBundle\Workflow\Counter\WorkflowByUserCounter; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; +use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\Security\Core\Security; use Symfony\Contracts\Translation\TranslatorInterface; @@ -25,6 +26,8 @@ class UserMenuBuilder implements LocalMenuBuilderInterface private NotificationByUserCounter $notificationByUserCounter; + private RequestStack $requestStack; + private Security $security; private TranslatorInterface $translator; @@ -36,13 +39,15 @@ class UserMenuBuilder implements LocalMenuBuilderInterface WorkflowByUserCounter $workflowByUserCounter, Security $security, TranslatorInterface $translator, - ParameterBagInterface $parameterBag + ParameterBagInterface $parameterBag, + RequestStack $requestStack ) { $this->notificationByUserCounter = $notificationByUserCounter; $this->workflowByUserCounter = $workflowByUserCounter; $this->security = $security; $this->translator = $translator; $this->parameterBag = $parameterBag; + $this->requestStack = $requestStack; } public function buildMenu($menuId, \Knp\Menu\MenuItem $menu, array $parameters) @@ -59,7 +64,12 @@ class UserMenuBuilder implements LocalMenuBuilderInterface $menu ->addChild( $locationTextMenu, - ['route' => 'chill_main_user_currentlocation_edit'] + [ + 'route' => 'chill_main_user_currentlocation_edit', + 'routeParameters' => [ + 'returnPath' => $this->requestStack->getCurrentRequest()->getRequestUri(), + ], + ] ) ->setExtras([ 'order' => -9999999,