From 02f6a1d1101ca1cd78d11b970dec669f085f13c1 Mon Sep 17 00:00:00 2001 From: nobohan Date: Tue, 16 Nov 2021 17:35:58 +0100 Subject: [PATCH 01/68] user: add location to user entity --- src/Bundle/ChillMainBundle/Entity/User.php | 25 ++++++++++++++ .../migrations/Version20211116162847.php | 33 +++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 src/Bundle/ChillMainBundle/migrations/Version20211116162847.php diff --git a/src/Bundle/ChillMainBundle/Entity/User.php b/src/Bundle/ChillMainBundle/Entity/User.php index 2048667e1..2d87bcaf1 100644 --- a/src/Bundle/ChillMainBundle/Entity/User.php +++ b/src/Bundle/ChillMainBundle/Entity/User.php @@ -6,6 +6,7 @@ use Doctrine\ORM\Mapping as ORM; use Doctrine\Common\Collections\Collection; use Doctrine\Common\Collections\ArrayCollection; use Chill\MainBundle\Entity\UserJob; +use Chill\MainBundle\Entity\Location; use Symfony\Component\Security\Core\User\AdvancedUserInterface; use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Serializer\Annotation\DiscriminatorMap; @@ -138,6 +139,12 @@ class User implements AdvancedUserInterface { */ private ?UserJob $userJob = null; + /** + * @var Location|null + * @ORM\ManyToOne(targetEntity=Location::class) + */ + private ?Location $location = null; + /** * User constructor. */ @@ -485,4 +492,22 @@ class User implements AdvancedUserInterface { $this->userJob = $userJob; return $this; } + + /** + * @return Location|null + */ + public function getLocation(): ?Location + { + return $this->location; + } + + /** + * @param Location|null $location + * @return User + */ + public function setLocation(?Location $location): User + { + $this->location = $location; + return $this; + } } diff --git a/src/Bundle/ChillMainBundle/migrations/Version20211116162847.php b/src/Bundle/ChillMainBundle/migrations/Version20211116162847.php new file mode 100644 index 000000000..3971841c7 --- /dev/null +++ b/src/Bundle/ChillMainBundle/migrations/Version20211116162847.php @@ -0,0 +1,33 @@ +addSql('ALTER TABLE users ADD location_id INT DEFAULT NULL'); + $this->addSql('ALTER TABLE users ADD CONSTRAINT FK_1483A5E964D218E FOREIGN KEY (location_id) REFERENCES chill_main_location (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('CREATE INDEX IDX_1483A5E964D218E ON users (location_id)'); + } + + public function down(Schema $schema): void + { + $this->addSql('ALTER TABLE users DROP CONSTRAINT FK_1483A5E964D218E'); + $this->addSql('DROP INDEX IDX_1483A5E964D218E'); + $this->addSql('ALTER TABLE users DROP location_id'); + } +} From 32c7695d80bdee6c6c0a14638fc8bf26a1a98001 Mon Sep 17 00:00:00 2001 From: nobohan Date: Tue, 16 Nov 2021 17:51:05 +0100 Subject: [PATCH 02/68] user: correct property name --- src/Bundle/ChillMainBundle/Entity/User.php | 10 +++++----- .../migrations/Version20211116162847.php | 16 ++++++++-------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Entity/User.php b/src/Bundle/ChillMainBundle/Entity/User.php index 2d87bcaf1..c6fd42859 100644 --- a/src/Bundle/ChillMainBundle/Entity/User.php +++ b/src/Bundle/ChillMainBundle/Entity/User.php @@ -143,7 +143,7 @@ class User implements AdvancedUserInterface { * @var Location|null * @ORM\ManyToOne(targetEntity=Location::class) */ - private ?Location $location = null; + private ?Location $currentLocation = null; /** * User constructor. @@ -496,18 +496,18 @@ class User implements AdvancedUserInterface { /** * @return Location|null */ - public function getLocation(): ?Location + public function getCurrentLocation(): ?Location { - return $this->location; + return $this->currentLocation; } /** * @param Location|null $location * @return User */ - public function setLocation(?Location $location): User + public function setCurrentLocation(?Location $currentLocation): User { - $this->location = $location; + $this->currentLocation = $currentLocation; return $this; } } diff --git a/src/Bundle/ChillMainBundle/migrations/Version20211116162847.php b/src/Bundle/ChillMainBundle/migrations/Version20211116162847.php index 3971841c7..04680b381 100644 --- a/src/Bundle/ChillMainBundle/migrations/Version20211116162847.php +++ b/src/Bundle/ChillMainBundle/migrations/Version20211116162847.php @@ -8,26 +8,26 @@ use Doctrine\DBAL\Schema\Schema; use Doctrine\Migrations\AbstractMigration; /** - * Add location to User entity + * Add current location to User entity */ final class Version20211116162847 extends AbstractMigration { public function getDescription(): string { - return 'Add location to User entity'; + return 'Add current location to User entity'; } public function up(Schema $schema): void { - $this->addSql('ALTER TABLE users ADD location_id INT DEFAULT NULL'); - $this->addSql('ALTER TABLE users ADD CONSTRAINT FK_1483A5E964D218E FOREIGN KEY (location_id) REFERENCES chill_main_location (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); - $this->addSql('CREATE INDEX IDX_1483A5E964D218E ON users (location_id)'); + $this->addSql('ALTER TABLE users ADD currentLocation_id INT DEFAULT NULL'); + $this->addSql('ALTER TABLE users ADD CONSTRAINT FK_1483A5E93C219753 FOREIGN KEY (currentLocation_id) REFERENCES chill_main_location (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('CREATE INDEX IDX_1483A5E93C219753 ON users (currentLocation_id)'); } public function down(Schema $schema): void { - $this->addSql('ALTER TABLE users DROP CONSTRAINT FK_1483A5E964D218E'); - $this->addSql('DROP INDEX IDX_1483A5E964D218E'); - $this->addSql('ALTER TABLE users DROP location_id'); + $this->addSql('ALTER TABLE users DROP CONSTRAINT FK_1483A5E93C219753'); + $this->addSql('DROP INDEX IDX_1483A5E93C219753'); + $this->addSql('ALTER TABLE users DROP currentLocation_id'); } } From 59050384257220e251cea4bcb38e2ed1b476e2c4 Mon Sep 17 00:00:00 2001 From: nobohan Date: Wed, 17 Nov 2021 11:35:54 +0100 Subject: [PATCH 03/68] user: current location edit form and page --- .../Controller/UserController.php | 96 ++++++++++++++----- .../Form/UserCurrentLocationType.php | 23 +++++ .../User/edit_current_location.html.twig | 23 +++++ .../translations/messages.fr.yml | 4 + 4 files changed, 121 insertions(+), 25 deletions(-) create mode 100644 src/Bundle/ChillMainBundle/Form/UserCurrentLocationType.php create mode 100644 src/Bundle/ChillMainBundle/Resources/views/User/edit_current_location.html.twig diff --git a/src/Bundle/ChillMainBundle/Controller/UserController.php b/src/Bundle/ChillMainBundle/Controller/UserController.php index bb8203011..3e6bade41 100644 --- a/src/Bundle/ChillMainBundle/Controller/UserController.php +++ b/src/Bundle/ChillMainBundle/Controller/UserController.php @@ -18,6 +18,7 @@ use Chill\MainBundle\Entity\User; use Chill\MainBundle\Form\UserType; use Chill\MainBundle\Entity\GroupCenter; use Chill\MainBundle\Form\Type\ComposedGroupCenterType; +use Chill\MainBundle\Form\UserCurrentLocationType; use Chill\MainBundle\Form\UserPasswordType; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface; @@ -87,7 +88,7 @@ class UserController extends CRUDController [ 'add_groupcenter_form' => $this->createAddLinkGroupCenterForm($entity, $request)->createView(), 'delete_groupcenter_form' => array_map( - function(\Symfony\Component\Form\Form $form) { + function (\Symfony\Component\Form\Form $form) { return $form->createView(); }, iterator_to_array($this->getDeleteLinkGroupCenterByUser($entity, $request), true) @@ -145,11 +146,10 @@ class UserController extends CRUDController private function createEditPasswordForm(User $user) { return $this->createForm(UserPasswordType::class, null, array( - 'user' => $user - )) + 'user' => $user + )) ->add('submit', SubmitType::class, array('label' => 'Change password')) - ->remove('actual_password') - ; + ->remove('actual_password'); } /** @@ -167,7 +167,7 @@ class UserController extends CRUDController } $groupCenter = $em->getRepository('ChillMainBundle:GroupCenter') - ->find($gcid); + ->find($gcid); if (!$groupCenter) { throw $this->createNotFoundException('Unable to find groupCenter entity'); @@ -184,10 +184,9 @@ class UserController extends CRUDController $em->flush(); $this->addFlash('success', $this->get('translator') - ->trans('The permissions where removed.')); + ->trans('The permissions where removed.')); return $this->redirect($this->generateUrl('chill_crud_admin_user_edit', array('id' => $uid))); - } /** @@ -209,24 +208,26 @@ class UserController extends CRUDController if ($form->isValid()) { $groupCenter = $this->getPersistedGroupCenter( - $form[self::FORM_GROUP_CENTER_COMPOSED]->getData()); + $form[self::FORM_GROUP_CENTER_COMPOSED]->getData() + ); $user->addGroupCenter($groupCenter); if ($this->validator->validate($user)->count() === 0) { $em->flush(); - $this->addFlash('success', $this->get('translator')->trans('The ' + $this->addFlash('success', $this->get('translator')->trans('The ' . 'permissions have been successfully added to the user')); - $returnPathParams = $request->query->has('returnPath') ? - ['returnPath' => $request->query->get('returnPath')] : []; - - return $this->redirect($this->generateUrl('chill_crud_admin_user_edit', - \array_merge(['id' => $uid], $returnPathParams))); + $returnPathParams = $request->query->has('returnPath') ? + ['returnPath' => $request->query->get('returnPath')] : []; + return $this->redirect($this->generateUrl( + 'chill_crud_admin_user_edit', + \array_merge(['id' => $uid], $returnPathParams) + )); } - foreach($this->validator->validate($user) as $error) { + foreach ($this->validator->validate($user) as $error) { $this->addFlash('error', $error->getMessage()); } } @@ -236,7 +237,7 @@ class UserController extends CRUDController 'edit_form' => $this->createEditForm($user)->createView(), 'add_groupcenter_form' => $this->createAddLinkGroupCenterForm($user, $request)->createView(), 'delete_groupcenter_form' => array_map( - static fn(Form $form) => $form->createView(), + static fn (Form $form) => $form->createView(), iterator_to_array($this->getDeleteLinkGroupCenterByUser($user, $request), true) ) ]); @@ -247,10 +248,10 @@ class UserController extends CRUDController $em = $this->getDoctrine()->getManager(); $groupCenterManaged = $em->getRepository('ChillMainBundle:GroupCenter') - ->findOneBy(array( - 'center' => $groupCenter->getCenter(), - 'permissionsGroup' => $groupCenter->getPermissionsGroup() - )); + ->findOneBy(array( + 'center' => $groupCenter->getCenter(), + 'permissionsGroup' => $groupCenter->getPermissionsGroup() + )); if (!$groupCenterManaged) { $em->persist($groupCenter); @@ -270,8 +271,10 @@ class UserController extends CRUDController $returnPathParams = $request->query->has('returnPath') ? ['returnPath' => $request->query->get('returnPath')] : []; return $this->createFormBuilder() - ->setAction($this->generateUrl('admin_user_delete_groupcenter', - array_merge($returnPathParams, ['uid' => $user->getId(), 'gcid' => $groupCenter->getId()]))) + ->setAction($this->generateUrl( + 'admin_user_delete_groupcenter', + array_merge($returnPathParams, ['uid' => $user->getId(), 'gcid' => $groupCenter->getId()]) + )) ->setMethod('DELETE') ->add('submit', SubmitType::class, array('label' => 'Delete')) ->getForm(); @@ -285,8 +288,10 @@ class UserController extends CRUDController $returnPathParams = $request->query->has('returnPath') ? ['returnPath' => $request->query->get('returnPath')] : []; return $this->createFormBuilder() - ->setAction($this->generateUrl('admin_user_add_groupcenter', - array_merge($returnPathParams, ['uid' => $user->getId()]))) + ->setAction($this->generateUrl( + 'admin_user_add_groupcenter', + array_merge($returnPathParams, ['uid' => $user->getId()]) + )) ->setMethod('POST') ->add(self::FORM_GROUP_CENTER_COMPOSED, ComposedGroupCenterType::class) ->add('submit', SubmitType::class, array('label' => 'Add a new groupCenter')) @@ -299,4 +304,45 @@ class UserController extends CRUDController yield $groupCenter->getId() => $this->createDeleteLinkGroupCenterForm($user, $groupCenter, $request); } } + + + /** + * @param User $user + * @return \Symfony\Component\Form\Form + */ + private function createEditLocationForm() + { + return $this->createForm(UserCurrentLocationType::class) + ->add('submit', SubmitType::class, ['label' => 'Change current location']); + } + + /** + * Displays a form to edit the user current location. + * + * @Route("/{_locale}/main/user/{id}/current-location/edit", name="chill_main_user_currentlocation_edit") + */ + public function editCurrentLocationAction(User $user, Request $request) + { + $editForm = $this->createEditLocationForm(); + $editForm->handleRequest($request); + + if ($editForm->isSubmitted() && $editForm->isValid()) { + $currentLocation = $editForm->get('location')->getData(); + + $user->setCurrentLocation($currentLocation); + + $this->getDoctrine()->getManager()->flush(); + $this->addFlash('success', $this->get('translator')->trans('Current location successfully updated')); + + return $this->redirect( + $request->query->has('returnPath') ? $request->query->get('returnPath') : + $this->generateUrl('chill_main_homepage') + ); + } + + return $this->render('@ChillMain/User/edit_current_location.html.twig', [ + 'entity' => $user, + 'edit_form' => $editForm->createView() + ]); + } } diff --git a/src/Bundle/ChillMainBundle/Form/UserCurrentLocationType.php b/src/Bundle/ChillMainBundle/Form/UserCurrentLocationType.php new file mode 100644 index 000000000..fa24d987e --- /dev/null +++ b/src/Bundle/ChillMainBundle/Form/UserCurrentLocationType.php @@ -0,0 +1,23 @@ +add('location', EntityType::class, [ + 'class' => Location::class, + 'choice_label' => function (Location $entity) { + return $entity->getName(); + }, + ]); + } +} diff --git a/src/Bundle/ChillMainBundle/Resources/views/User/edit_current_location.html.twig b/src/Bundle/ChillMainBundle/Resources/views/User/edit_current_location.html.twig new file mode 100644 index 000000000..aa1f248ef --- /dev/null +++ b/src/Bundle/ChillMainBundle/Resources/views/User/edit_current_location.html.twig @@ -0,0 +1,23 @@ +{% extends 'ChillMainBundle::layout.html.twig' %} + +{% block title %}{{ 'Edit my current location'|trans }}{% endblock %} + +{% block content -%} +

{{ 'Edit my current location'|trans }}

+ + {{ form_start(edit_form) }} + {{ form_row(edit_form.location) }} + + + + {{ form_end(edit_form) }} +{% endblock %} diff --git a/src/Bundle/ChillMainBundle/translations/messages.fr.yml b/src/Bundle/ChillMainBundle/translations/messages.fr.yml index 598edaec6..c3078938d 100644 --- a/src/Bundle/ChillMainBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillMainBundle/translations/messages.fr.yml @@ -176,6 +176,10 @@ Flags: Drapeaux # admin section for users jobs User jobs: Métiers +# user page for current location +Edit my current location: Éditer ma localisation actuelle +Change current location: Changer ma localisation actuelle +Current location successfully updated: Localisation actuelle mise à jour #admin section for circles (old: scopes) List circles: Cercles From 480e02af01182a5384add71d236d771b07f85f37 Mon Sep 17 00:00:00 2001 From: nobohan Date: Wed, 17 Nov 2021 13:54:32 +0100 Subject: [PATCH 04/68] user: add change location for user in user menu --- .../Controller/UserController.php | 27 +++++++------------ .../Form/UserCurrentLocationType.php | 2 +- .../User/edit_current_location.html.twig | 2 +- .../Routing/MenuBuilder/UserMenuBuilder.php | 21 ++++++++++----- .../translations/messages.fr.yml | 2 ++ 5 files changed, 28 insertions(+), 26 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Controller/UserController.php b/src/Bundle/ChillMainBundle/Controller/UserController.php index 3e6bade41..722a1d04f 100644 --- a/src/Bundle/ChillMainBundle/Controller/UserController.php +++ b/src/Bundle/ChillMainBundle/Controller/UserController.php @@ -305,29 +305,20 @@ class UserController extends CRUDController } } - - /** - * @param User $user - * @return \Symfony\Component\Form\Form - */ - private function createEditLocationForm() - { - return $this->createForm(UserCurrentLocationType::class) - ->add('submit', SubmitType::class, ['label' => 'Change current location']); - } - /** * Displays a form to edit the user current location. * - * @Route("/{_locale}/main/user/{id}/current-location/edit", name="chill_main_user_currentlocation_edit") + * @Route("/{_locale}/main/user/current-location/edit", name="chill_main_user_currentlocation_edit") */ - public function editCurrentLocationAction(User $user, Request $request) + public function editCurrentLocationAction(Request $request) { - $editForm = $this->createEditLocationForm(); - $editForm->handleRequest($request); + $user = $this->getUser(); + $form = $this->createForm(UserCurrentLocationType::class, $user) + ->add('submit', SubmitType::class, ['label' => 'Change current location']) + ->handleRequest($request); - if ($editForm->isSubmitted() && $editForm->isValid()) { - $currentLocation = $editForm->get('location')->getData(); + if ($form->isSubmitted() && $form->isValid()) { + $currentLocation = $form->get('currentLocation')->getData(); $user->setCurrentLocation($currentLocation); @@ -342,7 +333,7 @@ class UserController extends CRUDController return $this->render('@ChillMain/User/edit_current_location.html.twig', [ 'entity' => $user, - 'edit_form' => $editForm->createView() + 'edit_form' => $form->createView() ]); } } diff --git a/src/Bundle/ChillMainBundle/Form/UserCurrentLocationType.php b/src/Bundle/ChillMainBundle/Form/UserCurrentLocationType.php index fa24d987e..23dc99696 100644 --- a/src/Bundle/ChillMainBundle/Form/UserCurrentLocationType.php +++ b/src/Bundle/ChillMainBundle/Form/UserCurrentLocationType.php @@ -13,7 +13,7 @@ class UserCurrentLocationType extends AbstractType public function buildForm(FormBuilderInterface $builder, array $options) { $builder - ->add('location', EntityType::class, [ + ->add('currentLocation', EntityType::class, [ 'class' => Location::class, 'choice_label' => function (Location $entity) { return $entity->getName(); diff --git a/src/Bundle/ChillMainBundle/Resources/views/User/edit_current_location.html.twig b/src/Bundle/ChillMainBundle/Resources/views/User/edit_current_location.html.twig index aa1f248ef..206c96642 100644 --- a/src/Bundle/ChillMainBundle/Resources/views/User/edit_current_location.html.twig +++ b/src/Bundle/ChillMainBundle/Resources/views/User/edit_current_location.html.twig @@ -6,7 +6,7 @@

{{ 'Edit my current location'|trans }}

{{ form_start(edit_form) }} - {{ form_row(edit_form.location) }} + {{ form_row(edit_form.currentLocation) }}
  • diff --git a/src/Bundle/ChillMainBundle/Routing/MenuBuilder/UserMenuBuilder.php b/src/Bundle/ChillMainBundle/Routing/MenuBuilder/UserMenuBuilder.php index 010f5609d..bbe160371 100644 --- a/src/Bundle/ChillMainBundle/Routing/MenuBuilder/UserMenuBuilder.php +++ b/src/Bundle/ChillMainBundle/Routing/MenuBuilder/UserMenuBuilder.php @@ -38,28 +38,37 @@ class UserMenuBuilder implements LocalMenuBuilderInterface { $this->tokenStorage = $tokenStorage; } - + public function buildMenu($menuId, \Knp\Menu\MenuItem $menu, array $parameters) { if ($this->tokenStorage->getToken()->getUser() instanceof User) { + $menu + ->addChild( + 'Change location', + ['route' => 'chill_main_user_currentlocation_edit'] + ) + ->setExtras([ + 'order' => 99999999997 + ]); $menu ->addChild( 'Change password', - [ 'route' => 'change_my_password'] + ['route' => 'change_my_password'] ) ->setExtras([ 'order' => 99999999998 ]); } - + $menu ->addChild( - 'Logout', + 'Logout', [ 'route' => 'logout' - ]) + ] + ) ->setExtras([ - 'order'=> 99999999999, + 'order' => 99999999999, 'icon' => 'power-off' ]); } diff --git a/src/Bundle/ChillMainBundle/translations/messages.fr.yml b/src/Bundle/ChillMainBundle/translations/messages.fr.yml index c3078938d..340cb0e29 100644 --- a/src/Bundle/ChillMainBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillMainBundle/translations/messages.fr.yml @@ -177,8 +177,10 @@ Flags: Drapeaux User jobs: Métiers # user page for current location +Current location: Localisation actuelle Edit my current location: Éditer ma localisation actuelle Change current location: Changer ma localisation actuelle +Change location: Changer ma localisation Current location successfully updated: Localisation actuelle mise à jour #admin section for circles (old: scopes) From 593817f12e15c27eaa1c4b76b0aaeeb9ff631226 Mon Sep 17 00:00:00 2001 From: nobohan Date: Wed, 17 Nov 2021 14:12:22 +0100 Subject: [PATCH 05/68] user: refine display of location name (as usual, service injection does not work) --- .../Form/UserCurrentLocationType.php | 17 ++++++++++++++++- .../ChillMainBundle/config/services/form.yaml | 4 ++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/Bundle/ChillMainBundle/Form/UserCurrentLocationType.php b/src/Bundle/ChillMainBundle/Form/UserCurrentLocationType.php index 23dc99696..607b9c31e 100644 --- a/src/Bundle/ChillMainBundle/Form/UserCurrentLocationType.php +++ b/src/Bundle/ChillMainBundle/Form/UserCurrentLocationType.php @@ -3,6 +3,7 @@ namespace Chill\MainBundle\Form; use Chill\MainBundle\Entity\Location; +// use Chill\MainBundle\Templating\TranslatableStringHelper; use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; @@ -10,13 +11,27 @@ use Symfony\Component\Form\FormBuilderInterface; class UserCurrentLocationType extends AbstractType { + + // private TranslatableStringHelper $translatableStringHelper; + + // /** + // * @param TranslatableStringHelper $translatableStringHelper + // */ + // public function __construct(TranslatableStringHelper $translatableStringHelper) + // { + // $this->translatableStringHelper = $translatableStringHelper; + // } + public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('currentLocation', EntityType::class, [ 'class' => Location::class, 'choice_label' => function (Location $entity) { - return $entity->getName(); + return $entity->getName() ? + $entity->getName() : + //$this->translatableStringHelper->localize($entity->getLocationType()->getTitle()); //TODO does not work + $entity->getLocationType()->getTitle()['fr']; }, ]); } diff --git a/src/Bundle/ChillMainBundle/config/services/form.yaml b/src/Bundle/ChillMainBundle/config/services/form.yaml index 27d018229..b20f9e226 100644 --- a/src/Bundle/ChillMainBundle/config/services/form.yaml +++ b/src/Bundle/ChillMainBundle/config/services/form.yaml @@ -141,5 +141,9 @@ services: autowire: true Chill\MainBundle\Form\Type\LocationFormType: + autowire: true + autoconfigure: true + + Chill\MainBundle\Form\Type\UserCurrentLocationType: autowire: true autoconfigure: true \ No newline at end of file From f0ff4c18afed77b9e809174676302e205b730726 Mon Sep 17 00:00:00 2001 From: nobohan Date: Wed, 17 Nov 2021 14:20:18 +0100 Subject: [PATCH 06/68] upd CHANGELOG --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6dc54473f..7487fe9d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,9 @@ and this project adheres to +* [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] + * [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) From cd4de2e2443772d0104a83b08309377688e621b9 Mon Sep 17 00:00:00 2001 From: nobohan Date: Wed, 17 Nov 2021 15:19:24 +0100 Subject: [PATCH 07/68] activity: fix type error + add new property for new form --- .../Controller/ActivityController.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Controller/ActivityController.php b/src/Bundle/ChillActivityBundle/Controller/ActivityController.php index 9b1f3f48a..36dd609f3 100644 --- a/src/Bundle/ChillActivityBundle/Controller/ActivityController.php +++ b/src/Bundle/ChillActivityBundle/Controller/ActivityController.php @@ -266,16 +266,19 @@ final class ActivityController extends AbstractController $activity_array = $this->serializer->normalize($entity, 'json', ['groups' => 'read']); + $defaultLocationId = $this->getUser()->getCurrentLocation()->getId(); + return $this->render($view, [ 'person' => $person, 'accompanyingCourse' => $accompanyingPeriod, 'entity' => $entity, 'form' => $form->createView(), - 'activity_json' => $activity_array + 'activity_json' => $activity_array, + 'default_location_id' => $defaultLocationId ]); } - public function showAction(Request $request, $id): Response + public function showAction(Request $request, int $id): Response { $view = null; $em = $this->getDoctrine()->getManager(); @@ -330,7 +333,7 @@ final class ActivityController extends AbstractController * Displays a form to edit an existing Activity entity. * */ - public function editAction($id, Request $request): Response + public function editAction(int $id, Request $request): Response { $view = null; $em = $this->getDoctrine()->getManager(); From 63e5220084da6bdac54c6dff1d3d031e1188e20d Mon Sep 17 00:00:00 2001 From: nobohan Date: Wed, 17 Nov 2021 15:21:53 +0100 Subject: [PATCH 08/68] activity: add user current location as default for a new activity --- .../vuejs/Activity/components/Location.vue | 17 +++++++++-------- .../Activity/newAccompanyingCourse.html.twig | 1 + .../Form/UserCurrentLocationType.php | 2 +- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location.vue b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location.vue index c8d1472bd..5fa3360b7 100644 --- a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location.vue +++ b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location.vue @@ -55,16 +55,17 @@ export default { } }, mounted() { - this.getLocationsList(); + getLocations().then(response => new Promise(resolve => { + console.log('getLocations', response); + this.locations = response.results; + if (window.default_location_id) { + let location = this.locations.filter(l => l.id === window.default_location_id); + this.$store.dispatch('updateLocation', location); + } + resolve(); + })) }, methods: { - getLocationsList() { - getLocations().then(response => new Promise(resolve => { - console.log('getLocations', response); - this.locations = response.results; - resolve(); - })) - }, customLabel(value) { return `${value.locationType.title.fr} ${value.name ? value.name : ''}`; } diff --git a/src/Bundle/ChillActivityBundle/Resources/views/Activity/newAccompanyingCourse.html.twig b/src/Bundle/ChillActivityBundle/Resources/views/Activity/newAccompanyingCourse.html.twig index 101ad5502..d8f02a37d 100644 --- a/src/Bundle/ChillActivityBundle/Resources/views/Activity/newAccompanyingCourse.html.twig +++ b/src/Bundle/ChillActivityBundle/Resources/views/Activity/newAccompanyingCourse.html.twig @@ -22,6 +22,7 @@ '{{ "You are going to leave a page with unsubmitted data. Are you sure you want to leave ?"|trans }}'); }); window.activity = {{ activity_json|json_encode|raw }}; + window.default_location_id = {{ default_location_id }}; {{ encore_entry_script_tags('vue_activity') }} {% endblock %} diff --git a/src/Bundle/ChillMainBundle/Form/UserCurrentLocationType.php b/src/Bundle/ChillMainBundle/Form/UserCurrentLocationType.php index 607b9c31e..6d3d5f6df 100644 --- a/src/Bundle/ChillMainBundle/Form/UserCurrentLocationType.php +++ b/src/Bundle/ChillMainBundle/Form/UserCurrentLocationType.php @@ -29,7 +29,7 @@ class UserCurrentLocationType extends AbstractType 'class' => Location::class, 'choice_label' => function (Location $entity) { return $entity->getName() ? - $entity->getName() : + $entity->getLocationType()->getTitle()['fr'] . ' ' . $entity->getName() : //$this->translatableStringHelper->localize($entity->getLocationType()->getTitle()); //TODO does not work $entity->getLocationType()->getTitle()['fr']; }, From 11b82f746830f3cc84335563682a14bfea241431 Mon Sep 17 00:00:00 2001 From: nobohan Date: Wed, 17 Nov 2021 15:22:55 +0100 Subject: [PATCH 09/68] upd CHANGELOG --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7487fe9d1..840b8e4f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,7 +13,7 @@ and this project adheres to * [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] +* [activity] add user current location as default location for a new activity (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/133) * [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) From be92ac4a083cbf6183dcf1ebd68616665b33908b Mon Sep 17 00:00:00 2001 From: nobohan Date: Thu, 18 Nov 2021 11:26:14 +0100 Subject: [PATCH 10/68] user: correct dependency injection for form for locationType and userCurrentLocation --- .../ChillMainBundle/Form/LocationFormType.php | 19 ++++++++------- .../Form/UserCurrentLocationType.php | 23 +++++++++---------- .../ChillMainBundle/config/services/form.yaml | 6 ++--- .../translations/messages.fr.yml | 3 +-- 4 files changed, 24 insertions(+), 27 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Form/LocationFormType.php b/src/Bundle/ChillMainBundle/Form/LocationFormType.php index 83d1c4242..e7f2c1d5e 100644 --- a/src/Bundle/ChillMainBundle/Form/LocationFormType.php +++ b/src/Bundle/ChillMainBundle/Form/LocationFormType.php @@ -15,15 +15,15 @@ use Symfony\Component\OptionsResolver\OptionsResolver; final class LocationFormType extends AbstractType { - // private TranslatableStringHelper $translatableStringHelper; + private TranslatableStringHelper $translatableStringHelper; - // /** - // * @param TranslatableStringHelper $translatableStringHelper - // */ - // public function __construct(TranslatableStringHelper $translatableStringHelper) - // { - // $this->translatableStringHelper = $translatableStringHelper; - // } + /** + * @param TranslatableStringHelper $translatableStringHelper + */ + public function __construct(TranslatableStringHelper $translatableStringHelper) + { + $this->translatableStringHelper = $translatableStringHelper; + } public function buildForm(FormBuilderInterface $builder, array $options) { @@ -38,8 +38,7 @@ final class LocationFormType extends AbstractType ]; }, 'choice_label' => function (EntityLocationType $entity) { - //return $this->translatableStringHelper->localize($entity->getTitle()); //TODO not working. Cannot pass smthg in the constructor - return $entity->getTitle()['fr']; + return $this->translatableStringHelper->localize($entity->getTitle()); }, ]) ->add('name', TextType::class) diff --git a/src/Bundle/ChillMainBundle/Form/UserCurrentLocationType.php b/src/Bundle/ChillMainBundle/Form/UserCurrentLocationType.php index 6d3d5f6df..97097c079 100644 --- a/src/Bundle/ChillMainBundle/Form/UserCurrentLocationType.php +++ b/src/Bundle/ChillMainBundle/Form/UserCurrentLocationType.php @@ -3,7 +3,7 @@ namespace Chill\MainBundle\Form; use Chill\MainBundle\Entity\Location; -// use Chill\MainBundle\Templating\TranslatableStringHelper; +use Chill\MainBundle\Templating\TranslatableStringHelper; use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; @@ -12,15 +12,15 @@ use Symfony\Component\Form\FormBuilderInterface; class UserCurrentLocationType extends AbstractType { - // private TranslatableStringHelper $translatableStringHelper; + private TranslatableStringHelper $translatableStringHelper; - // /** - // * @param TranslatableStringHelper $translatableStringHelper - // */ - // public function __construct(TranslatableStringHelper $translatableStringHelper) - // { - // $this->translatableStringHelper = $translatableStringHelper; - // } + /** + * @param TranslatableStringHelper $translatableStringHelper + */ + public function __construct(TranslatableStringHelper $translatableStringHelper) + { + $this->translatableStringHelper = $translatableStringHelper; + } public function buildForm(FormBuilderInterface $builder, array $options) { @@ -29,9 +29,8 @@ class UserCurrentLocationType extends AbstractType 'class' => Location::class, 'choice_label' => function (Location $entity) { return $entity->getName() ? - $entity->getLocationType()->getTitle()['fr'] . ' ' . $entity->getName() : - //$this->translatableStringHelper->localize($entity->getLocationType()->getTitle()); //TODO does not work - $entity->getLocationType()->getTitle()['fr']; + $this->translatableStringHelper->localize($entity->getLocationType()->getTitle()) . ' ' . $entity->getName() : + $this->translatableStringHelper->localize($entity->getLocationType()->getTitle()); }, ]); } diff --git a/src/Bundle/ChillMainBundle/config/services/form.yaml b/src/Bundle/ChillMainBundle/config/services/form.yaml index b20f9e226..8c741ed36 100644 --- a/src/Bundle/ChillMainBundle/config/services/form.yaml +++ b/src/Bundle/ChillMainBundle/config/services/form.yaml @@ -140,10 +140,10 @@ services: autoconfigure: true autowire: true - Chill\MainBundle\Form\Type\LocationFormType: + Chill\MainBundle\Form\LocationFormType: autowire: true autoconfigure: true - Chill\MainBundle\Form\Type\UserCurrentLocationType: + Chill\MainBundle\Form\UserCurrentLocationType: autowire: true - autoconfigure: true \ No newline at end of file + autoconfigure: true diff --git a/src/Bundle/ChillMainBundle/translations/messages.fr.yml b/src/Bundle/ChillMainBundle/translations/messages.fr.yml index 340cb0e29..a4d49403d 100644 --- a/src/Bundle/ChillMainBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillMainBundle/translations/messages.fr.yml @@ -206,8 +206,7 @@ Location list: Liste des localisations Location type: Type de localisation Phonenumber1: Numéro de téléphone Phonenumber2: Autre numéro de téléphone -Configure location: Configuration des localisations -Configure location type: Configuration des types de localisations +Configure location and location type: Configuration des localisations # circles / scopes Choose the circle: Choisir le cercle From ce5af04df7359c449c7e8374e62fc0b69ca19cad Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Thu, 18 Nov 2021 14:46:33 +0100 Subject: [PATCH 11/68] closed step added + form/controller/template basic start --- .../AccompanyingCourseController.php | 25 +++++++++++++++++ .../ChillPersonExtension.php | 5 ++++ .../Entity/AccompanyingPeriod.php | 11 ++++++++ .../Form/AccompanyingCourseType.php | 22 +++++++++++++++ .../views/AccompanyingCourse/close.html.twig | 28 +++++++++++++++++++ 5 files changed, 91 insertions(+) create mode 100644 src/Bundle/ChillPersonBundle/Form/AccompanyingCourseType.php create mode 100644 src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourse/close.html.twig diff --git a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php index 5c11f4802..3b6698875 100644 --- a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php +++ b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php @@ -158,4 +158,29 @@ class AccompanyingCourseController extends Controller ]); } + /** + * @Route("/{_locale}/parcours/{accompanying_period_id}/close", name="chill_person_accompanying_course_close") + * @ParamConverter("accompanyingCourse", options={"id": "accompanying_period_id"}) + */ + + public function closeAction(AccompanyingPeriod $accompanyingCourse, Request $request): Response + { + $this->denyAccessUnlessGranted(AccompanyingPeriodVoter::EDIT, $accompanyingCourse); + + $form = $this->createForm(AccompanyingCourseType::class, $accompanyingCourse); + + $form->handleRequest($request); + + if ($form->isSubmitted() && $form->isValid()) { + + $this->getDoctrine()->getManager()->flush(); + + } + + return $this->render('@ChillPerson/AccompanyingCourse/close.html.twig', [ + 'form' => $form->createView(), + 'accompanyingCourse' => $accompanyingCourse + ]); + } + } diff --git a/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php b/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php index 211765330..996215082 100644 --- a/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php +++ b/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php @@ -221,12 +221,17 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac 'places' => [ 'DRAFT', 'CONFIRMED', + 'CLOSED', ], 'transitions' => [ 'confirm' => [ 'from' => 'DRAFT', 'to' => 'CONFIRMED' ], + 'close' => [ + 'from' => 'CONFIRMED', + 'to' => 'CLOSED' + ], ], ], ] diff --git a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php index 15f33abe7..0fdbe35fd 100644 --- a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php +++ b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php @@ -94,6 +94,14 @@ class AccompanyingPeriod implements TrackCreationInterface, TrackUpdateInterface */ public const STEP_CONFIRMED = 'CONFIRMED'; + /** + * Mark an accompanying period as "closed". + * + * This means that the accompanying period **is** + * closed by the creator + */ + public const STEP_CLOSED = 'CLOSED'; + /** * @var integer * @@ -117,6 +125,8 @@ class AccompanyingPeriod implements TrackCreationInterface, TrackUpdateInterface * * @ORM\Column(type="date", nullable=true) * @Groups({"read", "write"}) + * @Assert\NotBlank(groups={AccompanyingPeriod::STEP_CLOSED}) + * @Assert\GreaterThan(propertyPath="openingDate", groups={AccompanyingPeriod::STEP_CLOSED}) */ private $closingDate = null; @@ -166,6 +176,7 @@ class AccompanyingPeriod implements TrackCreationInterface, TrackUpdateInterface * targetEntity="Chill\PersonBundle\Entity\AccompanyingPeriod\ClosingMotive") * @ORM\JoinColumn(nullable=true) * @Groups({"read", "write"}) + * @Assert\NotBlank(groups={AccompanyingPeriod::STEP_CLOSED}) */ private $closingMotive = null; diff --git a/src/Bundle/ChillPersonBundle/Form/AccompanyingCourseType.php b/src/Bundle/ChillPersonBundle/Form/AccompanyingCourseType.php new file mode 100644 index 000000000..a1bdd5c2e --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Form/AccompanyingCourseType.php @@ -0,0 +1,22 @@ +add('closingDate', ChillDateType::class, + [ + 'required' => true, + ]); + + $builder->add('closingMotive', ClosingMotivePickerType::class); + } +} \ No newline at end of file diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourse/close.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourse/close.html.twig new file mode 100644 index 000000000..f0c819b35 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourse/close.html.twig @@ -0,0 +1,28 @@ +{% extends "@ChillPerson/AccompanyingCourse/layout.html.twig" %} + +{% block content %} +

    {{ "Close accompanying course"|trans }}

    + + {{ form_start(form) }} + + {{ form_row(form.closingDate) }} + {{ form_row(form.closingMotive) }} + + {% set accompanying_course_id = null %} + {% if accompanyingCourse %} + {% set accompanying_course_id = accompanyingCourse.id %} + {% endif %} + + + + {{ form_end(form) }} +{% endblock %} \ No newline at end of file From 6db180e7ca766dabc69c596493e9feb0ef47e318 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Thu, 18 Nov 2021 14:56:59 +0100 Subject: [PATCH 12/68] use statement fix --- .../Controller/AccompanyingCourseController.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php index 3b6698875..1f4262034 100644 --- a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php +++ b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php @@ -7,6 +7,7 @@ use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\AccompanyingPeriodParticipation; use Chill\PersonBundle\Privacy\AccompanyingPeriodPrivacyEvent; use Chill\PersonBundle\Entity\Person; +use Chill\PersonBundle\Form\AccompanyingCourseType; use Chill\PersonBundle\Repository\AccompanyingPeriod\AccompanyingPeriodWorkRepository; use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter; use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; From dcbed94050d63814af495b74bf72bb641b102cd8 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Thu, 18 Nov 2021 15:01:03 +0100 Subject: [PATCH 13/68] changelog updated --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 31c3e1b5d..a7e354584 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ and this project adheres to * [person] do not ask for center any more on person creation * [3party] do not ask for center any more on 3party creation * [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) +* [accompanyingCourse] Ability to close accompanying course (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/296) ## Test releases From 6c48a22f8673e19c2b0fcdb7b5cb6f2a4809d85e Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Fri, 19 Nov 2021 08:37:56 +0100 Subject: [PATCH 14/68] transition added + attempt voter --- .../Controller/AccompanyingCourseController.php | 12 +++++++++++- .../Authorization/AccompanyingPeriodVoter.php | 6 ++++++ .../config/services/controller.yaml | 7 ++----- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php index 1f4262034..c9b9cee35 100644 --- a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php +++ b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php @@ -23,6 +23,7 @@ use Symfony\Component\Serializer\SerializerInterface; use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Validator\Validator\ValidatorInterface; +use Symfony\Component\Workflow\Registry; /** * Class AccompanyingCourseController @@ -39,16 +40,20 @@ class AccompanyingCourseController extends Controller private AccompanyingPeriodWorkRepository $workRepository; + private Registry $registry; + public function __construct( SerializerInterface $serializer, EventDispatcherInterface $dispatcher, ValidatorInterface $validator, - AccompanyingPeriodWorkRepository $workRepository + AccompanyingPeriodWorkRepository $workRepository, + Registry $registry ) { $this->serializer = $serializer; $this->dispatcher = $dispatcher; $this->validator = $validator; $this->workRepository = $workRepository; + $this->registry = $registry; } /** @@ -175,6 +180,11 @@ class AccompanyingCourseController extends Controller if ($form->isSubmitted() && $form->isValid()) { $this->getDoctrine()->getManager()->flush(); + $workflow = $this->registry->get($accompanyingCourse); + + if ($workflow->can($accompanyingCourse, 'close')) { + $workflow->apply($accompanyingCourse, 'close'); + } } diff --git a/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php b/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php index 5247df505..49847d114 100644 --- a/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php +++ b/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php @@ -78,6 +78,12 @@ class AccompanyingPeriodVoter extends AbstractChillVoter implements ProvideRole return false; } + if (AccompanyingPeriod::STEP_CLOSED === $subject->getStep()) { + if($this->security->isGranted(self::EDIT, $subject)) { + return false; + } + } + // if confidential, only the referent can see it if ($subject->isConfidential()) { return $token->getUser() === $subject->getUser(); diff --git a/src/Bundle/ChillPersonBundle/config/services/controller.yaml b/src/Bundle/ChillPersonBundle/config/services/controller.yaml index 369fe63bb..fb31e8ee9 100644 --- a/src/Bundle/ChillPersonBundle/config/services/controller.yaml +++ b/src/Bundle/ChillPersonBundle/config/services/controller.yaml @@ -32,11 +32,8 @@ services: tags: ['controller.service_arguments'] Chill\PersonBundle\Controller\AccompanyingCourseController: - arguments: - $serializer: '@Symfony\Component\Serializer\SerializerInterface' - $dispatcher: '@Symfony\Contracts\EventDispatcher\EventDispatcherInterface' - $validator: '@Symfony\Component\Validator\Validator\ValidatorInterface' - $workRepository: '@Chill\PersonBundle\Repository\AccompanyingPeriod\AccompanyingPeriodWorkRepository' + autoconfigure: true + autowire: true tags: ['controller.service_arguments'] Chill\PersonBundle\Controller\AccompanyingCourseApiController: From f2bf88ec908008ad0374a4c14bf9afd42211321c Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Fri, 19 Nov 2021 08:45:28 +0100 Subject: [PATCH 15/68] adjustment to apply validation --- .../Controller/AccompanyingCourseController.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php index c9b9cee35..43c516ca9 100644 --- a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php +++ b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php @@ -183,6 +183,11 @@ class AccompanyingCourseController extends Controller $workflow = $this->registry->get($accompanyingCourse); if ($workflow->can($accompanyingCourse, 'close')) { + $errors = $this->validator->validate($accompanyingCourse, null, [$accompanyingCourse::STEP_CLOSED]); + if( count($errors) > 0 ){ + return $this->json($errors, 422); + } + $workflow->apply($accompanyingCourse, 'close'); } From 26a13ae6dfa0ca7768736f969757e202262d6ad8 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Fri, 19 Nov 2021 09:46:24 +0100 Subject: [PATCH 16/68] badge adapted+ menu entry + persistance of object fixed --- .../Controller/AccompanyingCourseController.php | 14 +++++++++++--- .../Menu/AccompanyingCourseMenuBuilder.php | 8 ++++++++ .../vuejs/AccompanyingCourse/components/Banner.vue | 7 ++++++- .../public/vuejs/AccompanyingCourse/js/i18n.js | 3 ++- .../views/AccompanyingPeriod/_list.html.twig | 4 +++- .../Authorization/AccompanyingPeriodVoter.php | 10 +++++----- .../ChillPersonBundle/translations/messages.fr.yml | 2 ++ 7 files changed, 37 insertions(+), 11 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php index 43c516ca9..8eab36d03 100644 --- a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php +++ b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php @@ -99,7 +99,7 @@ class AccompanyingCourseController extends Controller public function indexAction(AccompanyingPeriod $accompanyingCourse): Response { $this->denyAccessUnlessGranted(AccompanyingPeriodVoter::SEE, $accompanyingCourse); - + // compute some warnings // get persons without household $withoutHousehold = []; @@ -179,7 +179,9 @@ class AccompanyingCourseController extends Controller if ($form->isSubmitted() && $form->isValid()) { - $this->getDoctrine()->getManager()->flush(); + $em = $this->getDoctrine()->getManager(); + $em->persist($accompanyingCourse); + $workflow = $this->registry->get($accompanyingCourse); if ($workflow->can($accompanyingCourse, 'close')) { @@ -187,10 +189,16 @@ class AccompanyingCourseController extends Controller if( count($errors) > 0 ){ return $this->json($errors, 422); } - $workflow->apply($accompanyingCourse, 'close'); + $em->persist($accompanyingCourse); } + $em->flush(); + + return $this->redirectToRoute('chill_person_accompanying_course_index', [ + 'accompanying_period_id' => $accompanyingCourse->getId() + ]); + } return $this->render('@ChillPerson/AccompanyingCourse/close.html.twig', [ diff --git a/src/Bundle/ChillPersonBundle/Menu/AccompanyingCourseMenuBuilder.php b/src/Bundle/ChillPersonBundle/Menu/AccompanyingCourseMenuBuilder.php index df70b9e64..599bfb309 100644 --- a/src/Bundle/ChillPersonBundle/Menu/AccompanyingCourseMenuBuilder.php +++ b/src/Bundle/ChillPersonBundle/Menu/AccompanyingCourseMenuBuilder.php @@ -67,6 +67,14 @@ class AccompanyingCourseMenuBuilder implements LocalMenuBuilderInterface 'id' => $period->getId() ]]) ->setExtras(['order' => 40]); + + $menu->addChild($this->translator->trans('Close Accompanying Course'), [ + 'route' => 'chill_person_accompanying_course_close', + 'routeParameters' => [ + 'accompanying_period_id' => $period->getId() + ]]) + ->setExtras(['order' => 50]); + } 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 84e7fb2c6..d83196286 100644 --- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/components/Banner.vue +++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/components/Banner.vue @@ -11,7 +11,7 @@ {{ $t('course.step.draft') }} - + {{ $t('course.step.active') }} @@ -26,6 +26,11 @@ + + + {{ $t('course.step.closed') }} + + 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 10b656e4a..6cd255f8d 100644 --- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/js/i18n.js +++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/js/i18n.js @@ -20,7 +20,8 @@ const appMessages = { status: "État", step: { draft: "Brouillon", - active: "En file active" + active: "En file active", + closed: "Cloturé" }, open_at: "ouvert le ", by: "par ", diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/_list.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/_list.html.twig index c5797a4b2..af8657e28 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/_list.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/_list.html.twig @@ -21,8 +21,10 @@
    {% if accompanying_period.step == 'DRAFT' %} {{- 'Draft'|trans|upper -}} - {% else %} + {% elseif accompanying_period.step == 'CONFIRMED' %} {{- 'Confirmed'|trans|upper -}} + {% else %} + {{- 'Closed'|trans|upper -}} {% endif %}
    diff --git a/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php b/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php index 49847d114..9daa9ad2e 100644 --- a/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php +++ b/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php @@ -78,11 +78,11 @@ class AccompanyingPeriodVoter extends AbstractChillVoter implements ProvideRole return false; } - if (AccompanyingPeriod::STEP_CLOSED === $subject->getStep()) { - if($this->security->isGranted(self::EDIT, $subject)) { - return false; - } - } + // if (AccompanyingPeriod::STEP_CLOSED === $subject->getStep()) { + // if($this->security->isGranted(self::EDIT, $subject)) { + // return false; + // } + // } // if confidential, only the referent can see it if ($subject->isConfidential()) { diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index 7f9527b91..77f988fa1 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -374,6 +374,7 @@ regular: régulier Confidential: confidentiel Draft: brouillon Confirmed: en file active +Closed: Cloturé # Accompanying Course Accompanying Course: Parcours d'accompagnement @@ -381,6 +382,7 @@ Accompanying Course History: Historique du parcours Resume Accompanying Course: Résumé du parcours Show Accompanying Course: Voir le parcours Edit Accompanying Course: Modifier le parcours +Close Accompanying Course: Clôturer le parcours Create Accompanying Course: Créer un nouveau parcours Drop Accompanying Course: Supprimer le parcours This course is located at a temporarily address. You should locate this course to an user: Le parcours est localisé à une adresse temporaire. Il devrait être localisé auprès d'une personne concernée. From 210c8b8b971bc53ae649f167af69059e5093f849 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Fri, 19 Nov 2021 11:29:29 +0100 Subject: [PATCH 17/68] voters adjusted --- .../Security/Authorization/ActivityVoter.php | 5 +++++ .../AccompanyingCourseDocumentVoter.php | 8 ++++++++ .../Authorization/AccompanyingPeriodVoter.php | 15 ++++++++------- .../Security/Authorization/TaskVoter.php | 6 ++++++ 4 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Security/Authorization/ActivityVoter.php b/src/Bundle/ChillActivityBundle/Security/Authorization/ActivityVoter.php index cc9cecf52..2e6f01c6e 100644 --- a/src/Bundle/ChillActivityBundle/Security/Authorization/ActivityVoter.php +++ b/src/Bundle/ChillActivityBundle/Security/Authorization/ActivityVoter.php @@ -91,6 +91,11 @@ class ActivityVoter extends AbstractChillVoter implements ProvideRoleHierarchyIn return false; } } elseif ($subject->getAccompanyingPeriod() instanceof AccompanyingPeriod) { + if (AccompanyingPeriod::STEP_CLOSED === $subject->getAccompanyingPeriod->getStep()) { + if (\in_array($attribute, [self::UPDATE, self::CREATE, self::DELETE])) { + return false; + } + } if (!$this->security->isGranted(AccompanyingPeriodVoter::SEE, $subject->getAccompanyingPeriod())) { return false; } diff --git a/src/Bundle/ChillDocStoreBundle/Security/Authorization/AccompanyingCourseDocumentVoter.php b/src/Bundle/ChillDocStoreBundle/Security/Authorization/AccompanyingCourseDocumentVoter.php index 53507d573..d93b786e2 100644 --- a/src/Bundle/ChillDocStoreBundle/Security/Authorization/AccompanyingCourseDocumentVoter.php +++ b/src/Bundle/ChillDocStoreBundle/Security/Authorization/AccompanyingCourseDocumentVoter.php @@ -76,6 +76,14 @@ class AccompanyingCourseDocumentVoter extends AbstractChillVoter implements Prov return false; } + if ($subject instanceof AccompanyingCourseDocument) { + if (AccompanyingPeriod::STEP_CLOSED === $subject->getCourse()->getStep()) { + if (\in_array($attribute, [self::UPDATE, self::CREATE, self::DELETE])) { + return false; + } + } + } + return $this->voterHelper->voteOnAttribute($attribute, $subject, $token); } diff --git a/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php b/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php index 9daa9ad2e..4f170b2b0 100644 --- a/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php +++ b/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php @@ -68,6 +68,13 @@ class AccompanyingPeriodVoter extends AbstractChillVoter implements ProvideRole } if ($subject instanceof AccompanyingPeriod) { + + if (AccompanyingPeriod::STEP_CLOSED === $subject->getStep()) { + if (\in_array($attribute, [self::EDIT, self::DELETE])) { + return false; + } + } + if (AccompanyingPeriod::STEP_DRAFT === $subject->getStep()) { // only creator can see, edit, delete, etc. if ($subject->getCreatedBy() === $token->getUser() @@ -77,13 +84,7 @@ class AccompanyingPeriodVoter extends AbstractChillVoter implements ProvideRole return false; } - - // if (AccompanyingPeriod::STEP_CLOSED === $subject->getStep()) { - // if($this->security->isGranted(self::EDIT, $subject)) { - // return false; - // } - // } - + // if confidential, only the referent can see it if ($subject->isConfidential()) { return $token->getUser() === $subject->getUser(); diff --git a/src/Bundle/ChillTaskBundle/Security/Authorization/TaskVoter.php b/src/Bundle/ChillTaskBundle/Security/Authorization/TaskVoter.php index a3f1fff92..9e5a59c01 100644 --- a/src/Bundle/ChillTaskBundle/Security/Authorization/TaskVoter.php +++ b/src/Bundle/ChillTaskBundle/Security/Authorization/TaskVoter.php @@ -112,6 +112,12 @@ final class TaskVoter extends AbstractChillVoter implements ProvideRoleHierarchy if (!$this->accessDecisionManager->decide($token, [AccompanyingPeriodVoter::SEE], $period)) { return false; } + + if (AccompanyingPeriod::STEP_CLOSED === $subject->getCourse()->getStep()) { + if (\in_array($attribute, [self::UPDATE, self::CREATE_COURSE, self::DELETE])) { + return false; + } + } } } From 7fe316b49aef7533ffe6c00843af02b74f4f169b Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Fri, 19 Nov 2021 11:35:31 +0100 Subject: [PATCH 18/68] change menu entry order --- .../ChillPersonBundle/Menu/AccompanyingCourseMenuBuilder.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Bundle/ChillPersonBundle/Menu/AccompanyingCourseMenuBuilder.php b/src/Bundle/ChillPersonBundle/Menu/AccompanyingCourseMenuBuilder.php index 599bfb309..2c978e212 100644 --- a/src/Bundle/ChillPersonBundle/Menu/AccompanyingCourseMenuBuilder.php +++ b/src/Bundle/ChillPersonBundle/Menu/AccompanyingCourseMenuBuilder.php @@ -73,7 +73,7 @@ class AccompanyingCourseMenuBuilder implements LocalMenuBuilderInterface 'routeParameters' => [ 'accompanying_period_id' => $period->getId() ]]) - ->setExtras(['order' => 50]); + ->setExtras(['order' => 500]); } From 5928215c0d722b16649adf6df4d775509bfa2a34 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Thu, 18 Nov 2021 14:46:33 +0100 Subject: [PATCH 19/68] closed step added + form/controller/template basic start --- .../AccompanyingCourseController.php | 25 +++++++++++++++++ .../ChillPersonExtension.php | 5 ++++ .../Entity/AccompanyingPeriod.php | 11 ++++++++ .../Form/AccompanyingCourseType.php | 22 +++++++++++++++ .../views/AccompanyingCourse/close.html.twig | 28 +++++++++++++++++++ 5 files changed, 91 insertions(+) create mode 100644 src/Bundle/ChillPersonBundle/Form/AccompanyingCourseType.php create mode 100644 src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourse/close.html.twig diff --git a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php index 5c11f4802..3b6698875 100644 --- a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php +++ b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php @@ -158,4 +158,29 @@ class AccompanyingCourseController extends Controller ]); } + /** + * @Route("/{_locale}/parcours/{accompanying_period_id}/close", name="chill_person_accompanying_course_close") + * @ParamConverter("accompanyingCourse", options={"id": "accompanying_period_id"}) + */ + + public function closeAction(AccompanyingPeriod $accompanyingCourse, Request $request): Response + { + $this->denyAccessUnlessGranted(AccompanyingPeriodVoter::EDIT, $accompanyingCourse); + + $form = $this->createForm(AccompanyingCourseType::class, $accompanyingCourse); + + $form->handleRequest($request); + + if ($form->isSubmitted() && $form->isValid()) { + + $this->getDoctrine()->getManager()->flush(); + + } + + return $this->render('@ChillPerson/AccompanyingCourse/close.html.twig', [ + 'form' => $form->createView(), + 'accompanyingCourse' => $accompanyingCourse + ]); + } + } diff --git a/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php b/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php index 211765330..996215082 100644 --- a/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php +++ b/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php @@ -221,12 +221,17 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac 'places' => [ 'DRAFT', 'CONFIRMED', + 'CLOSED', ], 'transitions' => [ 'confirm' => [ 'from' => 'DRAFT', 'to' => 'CONFIRMED' ], + 'close' => [ + 'from' => 'CONFIRMED', + 'to' => 'CLOSED' + ], ], ], ] diff --git a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php index 15f33abe7..0fdbe35fd 100644 --- a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php +++ b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php @@ -94,6 +94,14 @@ class AccompanyingPeriod implements TrackCreationInterface, TrackUpdateInterface */ public const STEP_CONFIRMED = 'CONFIRMED'; + /** + * Mark an accompanying period as "closed". + * + * This means that the accompanying period **is** + * closed by the creator + */ + public const STEP_CLOSED = 'CLOSED'; + /** * @var integer * @@ -117,6 +125,8 @@ class AccompanyingPeriod implements TrackCreationInterface, TrackUpdateInterface * * @ORM\Column(type="date", nullable=true) * @Groups({"read", "write"}) + * @Assert\NotBlank(groups={AccompanyingPeriod::STEP_CLOSED}) + * @Assert\GreaterThan(propertyPath="openingDate", groups={AccompanyingPeriod::STEP_CLOSED}) */ private $closingDate = null; @@ -166,6 +176,7 @@ class AccompanyingPeriod implements TrackCreationInterface, TrackUpdateInterface * targetEntity="Chill\PersonBundle\Entity\AccompanyingPeriod\ClosingMotive") * @ORM\JoinColumn(nullable=true) * @Groups({"read", "write"}) + * @Assert\NotBlank(groups={AccompanyingPeriod::STEP_CLOSED}) */ private $closingMotive = null; diff --git a/src/Bundle/ChillPersonBundle/Form/AccompanyingCourseType.php b/src/Bundle/ChillPersonBundle/Form/AccompanyingCourseType.php new file mode 100644 index 000000000..a1bdd5c2e --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Form/AccompanyingCourseType.php @@ -0,0 +1,22 @@ +add('closingDate', ChillDateType::class, + [ + 'required' => true, + ]); + + $builder->add('closingMotive', ClosingMotivePickerType::class); + } +} \ No newline at end of file diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourse/close.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourse/close.html.twig new file mode 100644 index 000000000..f0c819b35 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourse/close.html.twig @@ -0,0 +1,28 @@ +{% extends "@ChillPerson/AccompanyingCourse/layout.html.twig" %} + +{% block content %} +

    {{ "Close accompanying course"|trans }}

    + + {{ form_start(form) }} + + {{ form_row(form.closingDate) }} + {{ form_row(form.closingMotive) }} + + {% set accompanying_course_id = null %} + {% if accompanyingCourse %} + {% set accompanying_course_id = accompanyingCourse.id %} + {% endif %} + + + + {{ form_end(form) }} +{% endblock %} \ No newline at end of file From e38729aa6591a15d901680a39ae8c04b283c1f85 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Thu, 18 Nov 2021 14:56:59 +0100 Subject: [PATCH 20/68] use statement fix --- .../Controller/AccompanyingCourseController.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php index 3b6698875..1f4262034 100644 --- a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php +++ b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php @@ -7,6 +7,7 @@ use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\AccompanyingPeriodParticipation; use Chill\PersonBundle\Privacy\AccompanyingPeriodPrivacyEvent; use Chill\PersonBundle\Entity\Person; +use Chill\PersonBundle\Form\AccompanyingCourseType; use Chill\PersonBundle\Repository\AccompanyingPeriod\AccompanyingPeriodWorkRepository; use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter; use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; From e9e3b85518449341daeff662bed6ef06d42c1d96 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Thu, 18 Nov 2021 15:01:03 +0100 Subject: [PATCH 21/68] changelog updated --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 31c3e1b5d..a7e354584 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ and this project adheres to * [person] do not ask for center any more on person creation * [3party] do not ask for center any more on 3party creation * [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) +* [accompanyingCourse] Ability to close accompanying course (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/296) ## Test releases From a20d7222a857adcd7a359c9a452b17f5b535c4fa Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Fri, 19 Nov 2021 08:37:56 +0100 Subject: [PATCH 22/68] transition added + attempt voter --- .../Controller/AccompanyingCourseController.php | 12 +++++++++++- .../Authorization/AccompanyingPeriodVoter.php | 6 ++++++ .../config/services/controller.yaml | 7 ++----- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php index 1f4262034..c9b9cee35 100644 --- a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php +++ b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php @@ -23,6 +23,7 @@ use Symfony\Component\Serializer\SerializerInterface; use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Validator\Validator\ValidatorInterface; +use Symfony\Component\Workflow\Registry; /** * Class AccompanyingCourseController @@ -39,16 +40,20 @@ class AccompanyingCourseController extends Controller private AccompanyingPeriodWorkRepository $workRepository; + private Registry $registry; + public function __construct( SerializerInterface $serializer, EventDispatcherInterface $dispatcher, ValidatorInterface $validator, - AccompanyingPeriodWorkRepository $workRepository + AccompanyingPeriodWorkRepository $workRepository, + Registry $registry ) { $this->serializer = $serializer; $this->dispatcher = $dispatcher; $this->validator = $validator; $this->workRepository = $workRepository; + $this->registry = $registry; } /** @@ -175,6 +180,11 @@ class AccompanyingCourseController extends Controller if ($form->isSubmitted() && $form->isValid()) { $this->getDoctrine()->getManager()->flush(); + $workflow = $this->registry->get($accompanyingCourse); + + if ($workflow->can($accompanyingCourse, 'close')) { + $workflow->apply($accompanyingCourse, 'close'); + } } diff --git a/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php b/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php index 5247df505..49847d114 100644 --- a/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php +++ b/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php @@ -78,6 +78,12 @@ class AccompanyingPeriodVoter extends AbstractChillVoter implements ProvideRole return false; } + if (AccompanyingPeriod::STEP_CLOSED === $subject->getStep()) { + if($this->security->isGranted(self::EDIT, $subject)) { + return false; + } + } + // if confidential, only the referent can see it if ($subject->isConfidential()) { return $token->getUser() === $subject->getUser(); diff --git a/src/Bundle/ChillPersonBundle/config/services/controller.yaml b/src/Bundle/ChillPersonBundle/config/services/controller.yaml index 369fe63bb..fb31e8ee9 100644 --- a/src/Bundle/ChillPersonBundle/config/services/controller.yaml +++ b/src/Bundle/ChillPersonBundle/config/services/controller.yaml @@ -32,11 +32,8 @@ services: tags: ['controller.service_arguments'] Chill\PersonBundle\Controller\AccompanyingCourseController: - arguments: - $serializer: '@Symfony\Component\Serializer\SerializerInterface' - $dispatcher: '@Symfony\Contracts\EventDispatcher\EventDispatcherInterface' - $validator: '@Symfony\Component\Validator\Validator\ValidatorInterface' - $workRepository: '@Chill\PersonBundle\Repository\AccompanyingPeriod\AccompanyingPeriodWorkRepository' + autoconfigure: true + autowire: true tags: ['controller.service_arguments'] Chill\PersonBundle\Controller\AccompanyingCourseApiController: From 57cf46a0af78d588760b59037434379f2779b7e9 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Fri, 19 Nov 2021 08:45:28 +0100 Subject: [PATCH 23/68] adjustment to apply validation --- .../Controller/AccompanyingCourseController.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php index c9b9cee35..43c516ca9 100644 --- a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php +++ b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php @@ -183,6 +183,11 @@ class AccompanyingCourseController extends Controller $workflow = $this->registry->get($accompanyingCourse); if ($workflow->can($accompanyingCourse, 'close')) { + $errors = $this->validator->validate($accompanyingCourse, null, [$accompanyingCourse::STEP_CLOSED]); + if( count($errors) > 0 ){ + return $this->json($errors, 422); + } + $workflow->apply($accompanyingCourse, 'close'); } From fc8a766c25cc829e55693134357c28030d71cbb8 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Fri, 19 Nov 2021 09:46:24 +0100 Subject: [PATCH 24/68] badge adapted+ menu entry + persistance of object fixed --- .../Controller/AccompanyingCourseController.php | 14 +++++++++++--- .../Menu/AccompanyingCourseMenuBuilder.php | 8 ++++++++ .../vuejs/AccompanyingCourse/components/Banner.vue | 7 ++++++- .../public/vuejs/AccompanyingCourse/js/i18n.js | 3 ++- .../views/AccompanyingPeriod/_list.html.twig | 4 +++- .../Authorization/AccompanyingPeriodVoter.php | 10 +++++----- .../ChillPersonBundle/translations/messages.fr.yml | 2 ++ 7 files changed, 37 insertions(+), 11 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php index 43c516ca9..8eab36d03 100644 --- a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php +++ b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php @@ -99,7 +99,7 @@ class AccompanyingCourseController extends Controller public function indexAction(AccompanyingPeriod $accompanyingCourse): Response { $this->denyAccessUnlessGranted(AccompanyingPeriodVoter::SEE, $accompanyingCourse); - + // compute some warnings // get persons without household $withoutHousehold = []; @@ -179,7 +179,9 @@ class AccompanyingCourseController extends Controller if ($form->isSubmitted() && $form->isValid()) { - $this->getDoctrine()->getManager()->flush(); + $em = $this->getDoctrine()->getManager(); + $em->persist($accompanyingCourse); + $workflow = $this->registry->get($accompanyingCourse); if ($workflow->can($accompanyingCourse, 'close')) { @@ -187,10 +189,16 @@ class AccompanyingCourseController extends Controller if( count($errors) > 0 ){ return $this->json($errors, 422); } - $workflow->apply($accompanyingCourse, 'close'); + $em->persist($accompanyingCourse); } + $em->flush(); + + return $this->redirectToRoute('chill_person_accompanying_course_index', [ + 'accompanying_period_id' => $accompanyingCourse->getId() + ]); + } return $this->render('@ChillPerson/AccompanyingCourse/close.html.twig', [ diff --git a/src/Bundle/ChillPersonBundle/Menu/AccompanyingCourseMenuBuilder.php b/src/Bundle/ChillPersonBundle/Menu/AccompanyingCourseMenuBuilder.php index df70b9e64..599bfb309 100644 --- a/src/Bundle/ChillPersonBundle/Menu/AccompanyingCourseMenuBuilder.php +++ b/src/Bundle/ChillPersonBundle/Menu/AccompanyingCourseMenuBuilder.php @@ -67,6 +67,14 @@ class AccompanyingCourseMenuBuilder implements LocalMenuBuilderInterface 'id' => $period->getId() ]]) ->setExtras(['order' => 40]); + + $menu->addChild($this->translator->trans('Close Accompanying Course'), [ + 'route' => 'chill_person_accompanying_course_close', + 'routeParameters' => [ + 'accompanying_period_id' => $period->getId() + ]]) + ->setExtras(['order' => 50]); + } 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 84e7fb2c6..d83196286 100644 --- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/components/Banner.vue +++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/components/Banner.vue @@ -11,7 +11,7 @@ {{ $t('course.step.draft') }}
    - + {{ $t('course.step.active') }} @@ -26,6 +26,11 @@ + + + {{ $t('course.step.closed') }} + + 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 10b656e4a..6cd255f8d 100644 --- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/js/i18n.js +++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/js/i18n.js @@ -20,7 +20,8 @@ const appMessages = { status: "État", step: { draft: "Brouillon", - active: "En file active" + active: "En file active", + closed: "Cloturé" }, open_at: "ouvert le ", by: "par ", diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/_list.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/_list.html.twig index c5797a4b2..af8657e28 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/_list.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/_list.html.twig @@ -21,8 +21,10 @@
    {% if accompanying_period.step == 'DRAFT' %} {{- 'Draft'|trans|upper -}} - {% else %} + {% elseif accompanying_period.step == 'CONFIRMED' %} {{- 'Confirmed'|trans|upper -}} + {% else %} + {{- 'Closed'|trans|upper -}} {% endif %}
    diff --git a/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php b/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php index 49847d114..9daa9ad2e 100644 --- a/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php +++ b/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php @@ -78,11 +78,11 @@ class AccompanyingPeriodVoter extends AbstractChillVoter implements ProvideRole return false; } - if (AccompanyingPeriod::STEP_CLOSED === $subject->getStep()) { - if($this->security->isGranted(self::EDIT, $subject)) { - return false; - } - } + // if (AccompanyingPeriod::STEP_CLOSED === $subject->getStep()) { + // if($this->security->isGranted(self::EDIT, $subject)) { + // return false; + // } + // } // if confidential, only the referent can see it if ($subject->isConfidential()) { diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index 7f9527b91..77f988fa1 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -374,6 +374,7 @@ regular: régulier Confidential: confidentiel Draft: brouillon Confirmed: en file active +Closed: Cloturé # Accompanying Course Accompanying Course: Parcours d'accompagnement @@ -381,6 +382,7 @@ Accompanying Course History: Historique du parcours Resume Accompanying Course: Résumé du parcours Show Accompanying Course: Voir le parcours Edit Accompanying Course: Modifier le parcours +Close Accompanying Course: Clôturer le parcours Create Accompanying Course: Créer un nouveau parcours Drop Accompanying Course: Supprimer le parcours This course is located at a temporarily address. You should locate this course to an user: Le parcours est localisé à une adresse temporaire. Il devrait être localisé auprès d'une personne concernée. From f145d6c921c874c08edbaa132dff561573d06c7f Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Fri, 19 Nov 2021 11:29:29 +0100 Subject: [PATCH 25/68] voters adjusted --- .../Security/Authorization/ActivityVoter.php | 5 +++++ .../AccompanyingCourseDocumentVoter.php | 8 ++++++++ .../Authorization/AccompanyingPeriodVoter.php | 15 ++++++++------- .../Security/Authorization/TaskVoter.php | 6 ++++++ 4 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Security/Authorization/ActivityVoter.php b/src/Bundle/ChillActivityBundle/Security/Authorization/ActivityVoter.php index cc9cecf52..2e6f01c6e 100644 --- a/src/Bundle/ChillActivityBundle/Security/Authorization/ActivityVoter.php +++ b/src/Bundle/ChillActivityBundle/Security/Authorization/ActivityVoter.php @@ -91,6 +91,11 @@ class ActivityVoter extends AbstractChillVoter implements ProvideRoleHierarchyIn return false; } } elseif ($subject->getAccompanyingPeriod() instanceof AccompanyingPeriod) { + if (AccompanyingPeriod::STEP_CLOSED === $subject->getAccompanyingPeriod->getStep()) { + if (\in_array($attribute, [self::UPDATE, self::CREATE, self::DELETE])) { + return false; + } + } if (!$this->security->isGranted(AccompanyingPeriodVoter::SEE, $subject->getAccompanyingPeriod())) { return false; } diff --git a/src/Bundle/ChillDocStoreBundle/Security/Authorization/AccompanyingCourseDocumentVoter.php b/src/Bundle/ChillDocStoreBundle/Security/Authorization/AccompanyingCourseDocumentVoter.php index 53507d573..d93b786e2 100644 --- a/src/Bundle/ChillDocStoreBundle/Security/Authorization/AccompanyingCourseDocumentVoter.php +++ b/src/Bundle/ChillDocStoreBundle/Security/Authorization/AccompanyingCourseDocumentVoter.php @@ -76,6 +76,14 @@ class AccompanyingCourseDocumentVoter extends AbstractChillVoter implements Prov return false; } + if ($subject instanceof AccompanyingCourseDocument) { + if (AccompanyingPeriod::STEP_CLOSED === $subject->getCourse()->getStep()) { + if (\in_array($attribute, [self::UPDATE, self::CREATE, self::DELETE])) { + return false; + } + } + } + return $this->voterHelper->voteOnAttribute($attribute, $subject, $token); } diff --git a/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php b/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php index 9daa9ad2e..4f170b2b0 100644 --- a/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php +++ b/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php @@ -68,6 +68,13 @@ class AccompanyingPeriodVoter extends AbstractChillVoter implements ProvideRole } if ($subject instanceof AccompanyingPeriod) { + + if (AccompanyingPeriod::STEP_CLOSED === $subject->getStep()) { + if (\in_array($attribute, [self::EDIT, self::DELETE])) { + return false; + } + } + if (AccompanyingPeriod::STEP_DRAFT === $subject->getStep()) { // only creator can see, edit, delete, etc. if ($subject->getCreatedBy() === $token->getUser() @@ -77,13 +84,7 @@ class AccompanyingPeriodVoter extends AbstractChillVoter implements ProvideRole return false; } - - // if (AccompanyingPeriod::STEP_CLOSED === $subject->getStep()) { - // if($this->security->isGranted(self::EDIT, $subject)) { - // return false; - // } - // } - + // if confidential, only the referent can see it if ($subject->isConfidential()) { return $token->getUser() === $subject->getUser(); diff --git a/src/Bundle/ChillTaskBundle/Security/Authorization/TaskVoter.php b/src/Bundle/ChillTaskBundle/Security/Authorization/TaskVoter.php index a3f1fff92..9e5a59c01 100644 --- a/src/Bundle/ChillTaskBundle/Security/Authorization/TaskVoter.php +++ b/src/Bundle/ChillTaskBundle/Security/Authorization/TaskVoter.php @@ -112,6 +112,12 @@ final class TaskVoter extends AbstractChillVoter implements ProvideRoleHierarchy if (!$this->accessDecisionManager->decide($token, [AccompanyingPeriodVoter::SEE], $period)) { return false; } + + if (AccompanyingPeriod::STEP_CLOSED === $subject->getCourse()->getStep()) { + if (\in_array($attribute, [self::UPDATE, self::CREATE_COURSE, self::DELETE])) { + return false; + } + } } } From 167b7b20d1806794519b0791a0f42e73f2e61926 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Fri, 19 Nov 2021 11:35:31 +0100 Subject: [PATCH 26/68] change menu entry order --- .../ChillPersonBundle/Menu/AccompanyingCourseMenuBuilder.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Bundle/ChillPersonBundle/Menu/AccompanyingCourseMenuBuilder.php b/src/Bundle/ChillPersonBundle/Menu/AccompanyingCourseMenuBuilder.php index 599bfb309..2c978e212 100644 --- a/src/Bundle/ChillPersonBundle/Menu/AccompanyingCourseMenuBuilder.php +++ b/src/Bundle/ChillPersonBundle/Menu/AccompanyingCourseMenuBuilder.php @@ -73,7 +73,7 @@ class AccompanyingCourseMenuBuilder implements LocalMenuBuilderInterface 'routeParameters' => [ 'accompanying_period_id' => $period->getId() ]]) - ->setExtras(['order' => 50]); + ->setExtras(['order' => 500]); } From 909e2ca07031312005c0bf76a793e770ebf7f31b Mon Sep 17 00:00:00 2001 From: nobohan Date: Wed, 17 Nov 2021 17:17:35 +0100 Subject: [PATCH 27/68] activity: delete admin_user_show in twig template because this route is not defined and should not be defined --- .../Resources/views/Activity/concernedGroups.html.twig | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Bundle/ChillActivityBundle/Resources/views/Activity/concernedGroups.html.twig b/src/Bundle/ChillActivityBundle/Resources/views/Activity/concernedGroups.html.twig index 9e36f14f6..124798e27 100644 --- a/src/Bundle/ChillActivityBundle/Resources/views/Activity/concernedGroups.html.twig +++ b/src/Bundle/ChillActivityBundle/Resources/views/Activity/concernedGroups.html.twig @@ -17,7 +17,6 @@ }, { 'title': 'Users concerned'|trans, 'items': entity.users, - 'path' : 'admin_user_show', 'key' : 'id' }, ] %} From b3cd7c5cdb7168c9acf2eb48b1319bf5917ac830 Mon Sep 17 00:00:00 2001 From: nobohan Date: Thu, 18 Nov 2021 14:50:56 +0100 Subject: [PATCH 28/68] activity: suggest requestor, user and ressources for adding persons|user|3rdparty --- .../Activity/components/ConcernedGroups.vue | 6 +-- .../Resources/public/vuejs/Activity/store.js | 44 +++++++++++++++++-- 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/ConcernedGroups.vue b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/ConcernedGroups.vue index 108e1e493..dad898126 100644 --- a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/ConcernedGroups.vue +++ b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/ConcernedGroups.vue @@ -10,9 +10,9 @@ -
    +
      -
    • +
    • {{ p.text }}
    @@ -91,7 +91,7 @@ export default { accompanyingCourse: state => state.activity.accompanyingPeriod }), ...mapGetters([ - 'filterSuggestedPersons' + 'suggestedEntities' ]), getContext() { return (this.accompanyingCourse) ? "accompanyingCourse" : "person"; diff --git a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/store.js b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/store.js index 415c5a359..230a3cb73 100644 --- a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/store.js +++ b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/store.js @@ -26,14 +26,52 @@ const store = createStore({ socialActionsList: [], }, getters: { - filterSuggestedPersons(state) { + suggestedEntities(state) { if (typeof(state.activity.accompanyingPeriod) === 'undefined') { return []; } - let existingPersonIds = state.activity.persons.map(p => p.id); - return state.activity.accompanyingPeriod.participations.filter(p => p.endDate === null) + const allEntities = [ + ...store.getters.suggestedPersons, + ...store.getters.suggestedRequestor, + ...store.getters.suggestedUser, + ...store.getters.suggestedResources + ]; + const uniqueIds = [...new Set(allEntities.map(i => `${i.type}-${i.id}`))]; + return Array.from(uniqueIds, id => allEntities.filter(r => `${r.type}-${r.id}` === id)[0]); + }, + suggestedPersons(state) { + const existingPersonIds = state.activity.persons.map(p => p.id); + return state.activity.accompanyingPeriod.participations + .filter(p => p.endDate === null) .map(p => p.person) .filter(p => !existingPersonIds.includes(p.id)) + }, + suggestedRequestor(state) { + const existingPersonIds = state.activity.persons.map(p => p.id); + const existingThirdPartyIds = state.activity.thirdParties.map(p => p.id); + return [state.activity.accompanyingPeriod.requestor] + .filter(r => + (r.type === 'person' && !existingPersonIds.includes(r.id)) || + (r.type === 'thirdparty' && !existingThirdPartyIds.includes(r.id)) + ); + }, + suggestedUser(state) { + const existingUserIds = state.activity.users.map(p => p.id); + return [state.activity.accompanyingPeriod.user] + .filter( + u => !existingUserIds.includes(u.id) + ); + }, + suggestedResources(state) { + const resources = state.activity.accompanyingPeriod.resources; + const existingPersonIds = state.activity.persons.map(p => p.id); + const existingThirdPartyIds = state.activity.thirdParties.map(p => p.id); + return state.activity.accompanyingPeriod.resources + .map(r => r.resource) + .filter(r => + (r.type === 'person' && !existingPersonIds.includes(r.id)) || + (r.type === 'thirdparty' && !existingThirdPartyIds.includes(r.id)) + ); } }, mutations: { From aae7d2fb2a971a91289a31484b04a330e339871b Mon Sep 17 00:00:00 2001 From: nobohan Date: Thu, 18 Nov 2021 15:17:07 +0100 Subject: [PATCH 29/68] activity: naming of addSuggestedEntities --- .../public/vuejs/Activity/components/ConcernedGroups.vue | 6 +++--- .../Resources/public/vuejs/Activity/store.js | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/ConcernedGroups.vue b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/ConcernedGroups.vue index dad898126..fb9d67c9a 100644 --- a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/ConcernedGroups.vue +++ b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/ConcernedGroups.vue @@ -12,7 +12,7 @@
      -
    • +
    • {{ p.text }}
    @@ -168,7 +168,7 @@ export default { }, addNewPersons({ selected, modal }) { console.log('@@@ CLICK button addNewPersons', selected); - selected.forEach(function(item) { + selected.forEach((item) => { this.$store.dispatch('addPersonsInvolved', item); }, this ); @@ -176,7 +176,7 @@ export default { modal.showModal = false; this.setPersonsInBloc(); }, - addNewPerson(person) { + addSuggestedEntity(person) { this.$store.dispatch('addPersonsInvolved', { result: person, type: 'person' }); this.setPersonsInBloc(); }, diff --git a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/store.js b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/store.js index 230a3cb73..947a54a9b 100644 --- a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/store.js +++ b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/store.js @@ -126,7 +126,7 @@ const store = createStore({ // ConcernedGroups addPersonsInvolved(state, payload) { - //console.log('### mutation addPersonsInvolved', payload.result.type); + console.log('### mutation addPersonsInvolved', payload); switch (payload.result.type) { case 'person': state.activity.persons.push(payload.result); From e40ea6902c5e03478cc218f377b52afe60946d89 Mon Sep 17 00:00:00 2001 From: nobohan Date: Thu, 18 Nov 2021 16:16:28 +0100 Subject: [PATCH 30/68] calendar: fix type hinting in Calendar controller --- .../ChillCalendarBundle/Controller/CalendarController.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Bundle/ChillCalendarBundle/Controller/CalendarController.php b/src/Bundle/ChillCalendarBundle/Controller/CalendarController.php index c6f435ea6..8ebd30868 100644 --- a/src/Bundle/ChillCalendarBundle/Controller/CalendarController.php +++ b/src/Bundle/ChillCalendarBundle/Controller/CalendarController.php @@ -168,7 +168,7 @@ class CalendarController extends AbstractController * Show a calendar item * @Route("/{_locale}/calendar/calendar/{id}/show", name="chill_calendar_calendar_show") */ - public function showAction(Request $request, $id): Response + public function showAction(Request $request, int $id): Response { $view = null; $em = $this->getDoctrine()->getManager(); @@ -241,7 +241,7 @@ class CalendarController extends AbstractController * Edit a calendar item * @Route("/{_locale}/calendar/calendar/{id}/edit", name="chill_calendar_calendar_edit") */ - public function editAction($id, Request $request): Response + public function editAction(int $id, Request $request): Response { $view = null; $em = $this->getDoctrine()->getManager(); @@ -302,7 +302,7 @@ class CalendarController extends AbstractController * Delete a calendar item * @Route("/{_locale}/calendar/{id}/delete", name="chill_calendar_calendar_delete") */ - public function deleteAction(Request $request, $id) + public function deleteAction(Request $request, int $id) { $view = null; $em = $this->getDoctrine()->getManager(); From d0e9829a3c89bc3af4b926169d47ff6d1cf4530d Mon Sep 17 00:00:00 2001 From: nobohan Date: Thu, 18 Nov 2021 16:46:25 +0100 Subject: [PATCH 31/68] activity: fix links to third party view page --- .../Resources/views/Activity/concernedGroups.html.twig | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Resources/views/Activity/concernedGroups.html.twig b/src/Bundle/ChillActivityBundle/Resources/views/Activity/concernedGroups.html.twig index 124798e27..39c993dd3 100644 --- a/src/Bundle/ChillActivityBundle/Resources/views/Activity/concernedGroups.html.twig +++ b/src/Bundle/ChillActivityBundle/Resources/views/Activity/concernedGroups.html.twig @@ -12,8 +12,8 @@ }, { 'title': 'Third parties'|trans, 'items': entity.thirdParties, - 'path' : 'chill_3party_3party_show', - 'key' : 'thirdparty_id' + 'path' : 'chill_crud_3party_3party_view', + 'key' : 'id' }, { 'title': 'Users concerned'|trans, 'items': entity.users, @@ -34,8 +34,8 @@ }, { 'title': 'Third parties'|trans, 'items': entity.thirdParties, - 'path' : 'chill_3party_3party_show', - 'key' : 'thirdparty_id' + 'path' : 'chill_crud_3party_3party_view', + 'key' : 'id' }, { 'title': 'Users concerned'|trans, 'items': entity.users, From 631ffa02f793e99ade40f7df9062411334b34138 Mon Sep 17 00:00:00 2001 From: nobohan Date: Thu, 18 Nov 2021 17:37:39 +0100 Subject: [PATCH 32/68] calendar: add suggestion for concernedGroups --- .../Activity/components/ConcernedGroups.vue | 1 - .../Resources/public/vuejs/Activity/store.js | 1 + .../ChillCalendarBundle/Entity/Calendar.php | 1 + .../Resources/public/vuejs/Calendar/store.js | 52 ++++++++++++++++++- 4 files changed, 53 insertions(+), 2 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/ConcernedGroups.vue b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/ConcernedGroups.vue index fb9d67c9a..42c6ee79e 100644 --- a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/ConcernedGroups.vue +++ b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/ConcernedGroups.vue @@ -9,7 +9,6 @@ v-bind:setPersonsInBloc="setPersonsInBloc">
    -
    • diff --git a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/store.js b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/store.js index 947a54a9b..a152de510 100644 --- a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/store.js +++ b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/store.js @@ -27,6 +27,7 @@ const store = createStore({ }, getters: { suggestedEntities(state) { + console.log(state.activity) if (typeof(state.activity.accompanyingPeriod) === 'undefined') { return []; } diff --git a/src/Bundle/ChillCalendarBundle/Entity/Calendar.php b/src/Bundle/ChillCalendarBundle/Entity/Calendar.php index b5314f02b..225c760da 100644 --- a/src/Bundle/ChillCalendarBundle/Entity/Calendar.php +++ b/src/Bundle/ChillCalendarBundle/Entity/Calendar.php @@ -51,6 +51,7 @@ class Calendar /** * @ORM\ManyToOne(targetEntity="Chill\PersonBundle\Entity\AccompanyingPeriod") + * @Groups({"read"}) */ private AccompanyingPeriod $accompanyingPeriod; diff --git a/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/store.js b/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/store.js index b4578ea2b..457d31799 100644 --- a/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/store.js +++ b/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/store.js @@ -28,9 +28,59 @@ const mapEntity = (entity) => { const store = createStore({ strict: debug, state: { - activity: mapEntity(window.entity), + activity: mapEntity(window.entity), // activity is the calendar entity actually currentEvent: null }, + getters: { + suggestedEntities(state) { + console.log(state.activity) + if (typeof(state.activity.accompanyingPeriod) === 'undefined') { + return []; + } + const allEntities = [ + ...store.getters.suggestedPersons, + ...store.getters.suggestedRequestor, + ...store.getters.suggestedUser, + ...store.getters.suggestedResources + ]; + const uniqueIds = [...new Set(allEntities.map(i => `${i.type}-${i.id}`))]; + return Array.from(uniqueIds, id => allEntities.filter(r => `${r.type}-${r.id}` === id)[0]); + }, + suggestedPersons(state) { + const existingPersonIds = state.activity.persons.map(p => p.id); + return state.activity.accompanyingPeriod.participations + .filter(p => p.endDate === null) + .map(p => p.person) + .filter(p => !existingPersonIds.includes(p.id)) + }, + suggestedRequestor(state) { + const existingPersonIds = state.activity.persons.map(p => p.id); + const existingThirdPartyIds = state.activity.thirdParties.map(p => p.id); + return [state.activity.accompanyingPeriod.requestor] + .filter(r => + (r.type === 'person' && !existingPersonIds.includes(r.id)) || + (r.type === 'thirdparty' && !existingThirdPartyIds.includes(r.id)) + ); + }, + suggestedUser(state) { + const existingUserIds = state.activity.users.map(p => p.id); + return [state.activity.accompanyingPeriod.user] + .filter( + u => !existingUserIds.includes(u.id) + ); + }, + suggestedResources(state) { + const resources = state.activity.accompanyingPeriod.resources; + const existingPersonIds = state.activity.persons.map(p => p.id); + const existingThirdPartyIds = state.activity.thirdParties.map(p => p.id); + return state.activity.accompanyingPeriod.resources + .map(r => r.resource) + .filter(r => + (r.type === 'person' && !existingPersonIds.includes(r.id)) || + (r.type === 'thirdparty' && !existingThirdPartyIds.includes(r.id)) + ); + } + }, mutations: { // ConcernedGroups From bdb24750ab320324461d5617bc7b671544325542 Mon Sep 17 00:00:00 2001 From: nobohan Date: Thu, 18 Nov 2021 19:17:03 +0100 Subject: [PATCH 33/68] calendar: remove done TODO --- src/Bundle/ChillCalendarBundle/Entity/Calendar.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Bundle/ChillCalendarBundle/Entity/Calendar.php b/src/Bundle/ChillCalendarBundle/Entity/Calendar.php index 225c760da..e024b000b 100644 --- a/src/Bundle/ChillCalendarBundle/Entity/Calendar.php +++ b/src/Bundle/ChillCalendarBundle/Entity/Calendar.php @@ -111,8 +111,6 @@ class Calendar */ private ?\DateTimeImmutable $endDate = null; - //TODO Lieu - /** * @ORM\Column(type="string", length=255) */ From f5a6314ca2b793ab798b776a8cdc9fa25ae6e3ab Mon Sep 17 00:00:00 2001 From: nobohan Date: Thu, 18 Nov 2021 19:22:44 +0100 Subject: [PATCH 34/68] calendar: can add User from suggested entities --- .../ChillCalendarBundle/Form/CalendarType.php | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/Bundle/ChillCalendarBundle/Form/CalendarType.php b/src/Bundle/ChillCalendarBundle/Form/CalendarType.php index 753eb3728..dc2b3589e 100644 --- a/src/Bundle/ChillCalendarBundle/Form/CalendarType.php +++ b/src/Bundle/ChillCalendarBundle/Form/CalendarType.php @@ -194,24 +194,24 @@ class CalendarType extends AbstractType )) ; - // $builder->add('invites', HiddenType::class); - // $builder->get('invites') - // ->addModelTransformer(new CallbackTransformer( - // function (iterable $usersAsIterable): string { - // $userIds = []; - // foreach ($usersAsIterable as $value) { - // $userIds[] = $value->getId(); - // } - // return implode(',', $userIds); - // }, - // function (?string $usersAsString): array { - // return array_map( - // fn(string $id): ?Invite => $this->om->getRepository(Invite::class)->findOneBy(['id' => (int) $id]), - // explode(',', $usersAsString) - // ); - // } - // )) - // ; + $builder->add('invites', HiddenType::class); + $builder->get('invites') + ->addModelTransformer(new CallbackTransformer( + function (iterable $usersAsIterable): string { + $userIds = []; + foreach ($usersAsIterable as $value) { + $userIds[] = $value->getId(); + } + return implode(',', $userIds); + }, + function (?string $usersAsString): array { + return array_map( + fn(string $id): ?Invite => $this->om->getRepository(Invite::class)->findOneBy(['id' => (int) $id]), + explode(',', $usersAsString) + ); + } + )) + ; }/** From aa53df8bb0be7f7625c96c94805f5380b0745009 Mon Sep 17 00:00:00 2001 From: nobohan Date: Fri, 19 Nov 2021 11:45:23 +0100 Subject: [PATCH 35/68] activity: avoid adding persons|Users|Thirdparty if not allowed --- .../ChillActivityBundle/Entity/Activity.php | 5 +- .../Entity/ActivityType.php | 6 + .../Activity/components/ConcernedGroups.vue | 49 +- .../Resources/public/vuejs/Activity/store.js | 479 ++++++++++-------- .../Resources/views/Activity/edit.html.twig | 20 +- 5 files changed, 332 insertions(+), 227 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Entity/Activity.php b/src/Bundle/ChillActivityBundle/Entity/Activity.php index 4ed654c85..995cf450d 100644 --- a/src/Bundle/ChillActivityBundle/Entity/Activity.php +++ b/src/Bundle/ChillActivityBundle/Entity/Activity.php @@ -22,6 +22,7 @@ use Doctrine\Common\Collections\ArrayCollection; use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Serializer\Annotation\Groups; use Symfony\Component\Serializer\Annotation\DiscriminatorMap; +use Symfony\Component\Serializer\Annotation\SerializedName; /** * Class Activity @@ -30,7 +31,7 @@ use Symfony\Component\Serializer\Annotation\DiscriminatorMap; * @ORM\Entity(repositoryClass="Chill\ActivityBundle\Repository\ActivityRepository") * @ORM\Table(name="activity") * @ORM\HasLifecycleCallbacks() - * @DiscriminatorMap(typeProperty="type", mapping={ + * @DiscriminatorMap(typeProperty="_type", mapping={ * "activity"=Activity::class * }) */ @@ -102,6 +103,8 @@ class Activity implements HasCenterInterface, HasScopeInterface, AccompanyingPer /** * @ORM\ManyToOne(targetEntity="Chill\ActivityBundle\Entity\ActivityType") + * @Groups({"read"}) + * @SerializedName("activityType") */ private ActivityType $type; diff --git a/src/Bundle/ChillActivityBundle/Entity/ActivityType.php b/src/Bundle/ChillActivityBundle/Entity/ActivityType.php index c8ae6ca07..835af284e 100644 --- a/src/Bundle/ChillActivityBundle/Entity/ActivityType.php +++ b/src/Bundle/ChillActivityBundle/Entity/ActivityType.php @@ -21,6 +21,7 @@ namespace Chill\ActivityBundle\Entity; use Doctrine\ORM\Mapping as ORM; +use Symfony\Component\Serializer\Annotation\Groups; /** * Class ActivityType @@ -45,11 +46,13 @@ class ActivityType /** * @ORM\Column(type="json") + * @Groups({"read"}) */ private array $name = []; /** * @ORM\Column(type="boolean") + * @Groups({"read"}) */ private bool $active = true; @@ -100,6 +103,7 @@ class ActivityType /** * @ORM\Column(type="smallint", nullable=false, options={"default"=1}) + * @Groups({"read"}) */ private int $personsVisible = self::FIELD_OPTIONAL; @@ -110,6 +114,7 @@ class ActivityType /** * @ORM\Column(type="smallint", nullable=false, options={"default"=1}) + * @Groups({"read"}) */ private int $thirdPartiesVisible = self::FIELD_INVISIBLE; @@ -190,6 +195,7 @@ class ActivityType /** * @ORM\Column(type="smallint", nullable=false, options={"default"=1}) + * @Groups({"read"}) */ private int $usersVisible = self::FIELD_OPTIONAL; diff --git a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/ConcernedGroups.vue b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/ConcernedGroups.vue index 42c6ee79e..9eaeef697 100644 --- a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/ConcernedGroups.vue +++ b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/ConcernedGroups.vue @@ -1,5 +1,5 @@