From 387b7c2fbd04d26a49f4143586928accebc4094d Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Wed, 16 Mar 2022 11:36:46 +0100 Subject: [PATCH 1/8] first commit --- .../UserAccompanyingPeriodController.php | 65 ++++++++++++++++++- .../AccompanyingPeriodRepository.php | 10 +++ 2 files changed, 74 insertions(+), 1 deletion(-) diff --git a/src/Bundle/ChillPersonBundle/Controller/UserAccompanyingPeriodController.php b/src/Bundle/ChillPersonBundle/Controller/UserAccompanyingPeriodController.php index 321f212d5..774b272c5 100644 --- a/src/Bundle/ChillPersonBundle/Controller/UserAccompanyingPeriodController.php +++ b/src/Bundle/ChillPersonBundle/Controller/UserAccompanyingPeriodController.php @@ -11,11 +11,17 @@ declare(strict_types=1); namespace Chill\PersonBundle\Controller; +use Chill\MainBundle\Entity\User; use Chill\MainBundle\Pagination\PaginatorFactory; +use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Repository\AccompanyingPeriodRepository; +use Doctrine\ORM\EntityRepository; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; +use Symfony\Component\Form\FormInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\Annotation\Route; +use Symfony\Component\Security\Core\Exception\AccessDeniedException; +use Symfony\Component\Security\Core\Security; class UserAccompanyingPeriodController extends AbstractController { @@ -23,10 +29,13 @@ class UserAccompanyingPeriodController extends AbstractController private PaginatorFactory $paginatorFactory; - public function __construct(AccompanyingPeriodRepository $accompanyingPeriodRepository, PaginatorFactory $paginatorFactory) + private Security $security; + + public function __construct(AccompanyingPeriodRepository $accompanyingPeriodRepository, PaginatorFactory $paginatorFactory, Security $security) { $this->accompanyingPeriodRepository = $accompanyingPeriodRepository; $this->paginatorFactory = $paginatorFactory; + $this->security = $security; } /** @@ -68,4 +77,58 @@ class UserAccompanyingPeriodController extends AbstractController 'pagination' => $pagination, ]); } + + /** + * @Route("/{_locale}/person/accompanying-periods/my/drafts", name="chill_person_accompanying_period_draft_user") + */ + public function listConfirmedAction(Request $request) + { + if (!$this->security->isGranted('ROLE_USER') || !$this->security->getUser() instanceof User) { + throw new AccessDeniedException(); + } + + $form = $this->buildUserSelectionForm(); + + $form->handleRequest($request); + if ($form->isSubmitted() && $form->isValid()) { + $user = $_POST['user']; + + $periods = $this->getDoctrine()->getRepository(AccompanyingPeriod::class)->findConfirmedByUser($user); + + return $this->render('@ChillPerson/AccompanyingPeriod/user_reassign_periods_list.html.twig', [ + 'accompanyingPeriods' => $periods, + ]); + } + + return $this->render('@ChillPerson/AccompanyingPeriod/user_reassign_periods_list.html.twig', [ + 'form' => $form + ]); + } + + private function buildUserSelectionForm(): FormInterface + { + $data = [ + 'users' => [], + ]; + + $builder = $this->formFactory->createBuilder(FormType::class, $data, [ + 'method' => 'get', 'csrf_protection' => false]); + + $builder + ->add('users', EntityType::class, [ + 'class' => User::class, + 'query_builder' => function (EntityRepository $er) { + $qb = $er->createQueryBuilder('u'); + return $qb; + }, + 'choice_label' => function(User $u) { + return $u->getUsername(); + }, + 'multiple' => false, + 'label' => 'User', + 'required' => false, + ]); + + return $builder->getForm(); + } } diff --git a/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodRepository.php b/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodRepository.php index 122b658bd..ab7006fd8 100644 --- a/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodRepository.php +++ b/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodRepository.php @@ -78,6 +78,16 @@ final class AccompanyingPeriodRepository implements ObjectRepository ->getResult(); } + public function findConfirmedByUser(User $user) + { + $qb = $this->createQueryBuilder('ap'); + $qb->where($qb->expr()->eq('ap.user', ':user')) + ->andWhere('ap.step', 'CONFIRMED') + ->setParameter('user', $user); + + return $qb; + } + public function findOneBy(array $criteria): ?AccompanyingPeriod { return $this->findOneBy($criteria); From 97731b0a9b6a1b926fdbb963e4bea993eb5d7bf8 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Thu, 17 Mar 2022 12:28:00 +0100 Subject: [PATCH 2/8] controller + template made to list confirmed parcours for a specific user --- .../Repository/UserRepository.php | 5 + .../ReassignAccompanyingPeriodController.php | 108 ++++++++++++++++++ .../UserAccompanyingPeriodController.php | 65 +---------- .../AccompanyingPeriodACLAwareRepository.php | 23 ++++ .../reassign_list.html.twig | 80 +++++++++++++ .../config/services/controller.yaml | 5 + 6 files changed, 222 insertions(+), 64 deletions(-) create mode 100644 src/Bundle/ChillPersonBundle/Controller/ReassignAccompanyingPeriodController.php create mode 100644 src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/reassign_list.html.twig diff --git a/src/Bundle/ChillMainBundle/Repository/UserRepository.php b/src/Bundle/ChillMainBundle/Repository/UserRepository.php index fc3a6e187..56a82de3d 100644 --- a/src/Bundle/ChillMainBundle/Repository/UserRepository.php +++ b/src/Bundle/ChillMainBundle/Repository/UserRepository.php @@ -32,6 +32,11 @@ final class UserRepository implements ObjectRepository $this->repository = $entityManager->getRepository(User::class); } + public function createQueryBuilder(string $alias, ?string $indexBy = null): QueryBuilder + { + return $this->repository->createQueryBuilder($alias, $indexBy); + } + public function countBy(array $criteria): int { return $this->repository->count($criteria); diff --git a/src/Bundle/ChillPersonBundle/Controller/ReassignAccompanyingPeriodController.php b/src/Bundle/ChillPersonBundle/Controller/ReassignAccompanyingPeriodController.php new file mode 100644 index 000000000..66a460199 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Controller/ReassignAccompanyingPeriodController.php @@ -0,0 +1,108 @@ +accompanyingPeriodACLAwareRepository = $accompanyingPeriodACLAwareRepository; + $this->engine = $engine; + $this->formFactory = $formFactory; + $this->paginatorFactory = $paginatorFactory; + $this->security = $security; + $this->userRepository = $userRepository; + } + + /** + * @Route("/{_locale}/person/accompanying-periods/reassign", name="chill_course_list_reassign") + */ + public function listAction(Request $request): Response + { + if (!$this->security->isGranted('ROLE_USER') || !$this->security->getUser() instanceof User) { + throw new AccessDeniedException(); + } + + $form = $this->buildFilterForm(); + + $form->handleRequest($request); + + // $total = $this->accompanyingPeriodACLAwareRepository->countByUserConfirmed( + // $form['jobs']->getData(), + // $form['services']->getData(), + // $form['locations']->getData(), + // ); + // $paginator = $this->paginatorFactory->create($total); + $periods = $this->accompanyingPeriodACLAwareRepository + ->findByUserConfirmed( + $form['user']->getData(), + 1, + 1 + ); + + return new Response( + $this->engine->render('@ChillPerson/AccompanyingPeriod/reassign_list.html.twig', [ + // 'paginator' => $paginator, + 'periods' => $periods, + 'form' => $form->createView() + ]) + ); + } + + private function buildFilterForm(): FormInterface + { + $builder = $this->formFactory->createBuilder(FormType::class, [ + 'method' => 'get', 'csrf_protection' => false]); + + $builder + ->add('user', EntityType::class, [ + 'class' => User::class, + 'query_builder' => function () { + $qb = $this->userRepository->createQueryBuilder('u'); + + $qb->where('u.enabled = true') + ->orderBy('u.username', 'ASC'); + + return $qb; + }, + 'choice_label' => function (User $u) { + return $u->getUsername(); + }, + 'multiple' => false, + 'label' => 'User', + 'required' => false, + ]); + + return $builder->getForm(); + } + +} \ No newline at end of file diff --git a/src/Bundle/ChillPersonBundle/Controller/UserAccompanyingPeriodController.php b/src/Bundle/ChillPersonBundle/Controller/UserAccompanyingPeriodController.php index 774b272c5..321f212d5 100644 --- a/src/Bundle/ChillPersonBundle/Controller/UserAccompanyingPeriodController.php +++ b/src/Bundle/ChillPersonBundle/Controller/UserAccompanyingPeriodController.php @@ -11,17 +11,11 @@ declare(strict_types=1); namespace Chill\PersonBundle\Controller; -use Chill\MainBundle\Entity\User; use Chill\MainBundle\Pagination\PaginatorFactory; -use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Repository\AccompanyingPeriodRepository; -use Doctrine\ORM\EntityRepository; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; -use Symfony\Component\Form\FormInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\Annotation\Route; -use Symfony\Component\Security\Core\Exception\AccessDeniedException; -use Symfony\Component\Security\Core\Security; class UserAccompanyingPeriodController extends AbstractController { @@ -29,13 +23,10 @@ class UserAccompanyingPeriodController extends AbstractController private PaginatorFactory $paginatorFactory; - private Security $security; - - public function __construct(AccompanyingPeriodRepository $accompanyingPeriodRepository, PaginatorFactory $paginatorFactory, Security $security) + public function __construct(AccompanyingPeriodRepository $accompanyingPeriodRepository, PaginatorFactory $paginatorFactory) { $this->accompanyingPeriodRepository = $accompanyingPeriodRepository; $this->paginatorFactory = $paginatorFactory; - $this->security = $security; } /** @@ -77,58 +68,4 @@ class UserAccompanyingPeriodController extends AbstractController 'pagination' => $pagination, ]); } - - /** - * @Route("/{_locale}/person/accompanying-periods/my/drafts", name="chill_person_accompanying_period_draft_user") - */ - public function listConfirmedAction(Request $request) - { - if (!$this->security->isGranted('ROLE_USER') || !$this->security->getUser() instanceof User) { - throw new AccessDeniedException(); - } - - $form = $this->buildUserSelectionForm(); - - $form->handleRequest($request); - if ($form->isSubmitted() && $form->isValid()) { - $user = $_POST['user']; - - $periods = $this->getDoctrine()->getRepository(AccompanyingPeriod::class)->findConfirmedByUser($user); - - return $this->render('@ChillPerson/AccompanyingPeriod/user_reassign_periods_list.html.twig', [ - 'accompanyingPeriods' => $periods, - ]); - } - - return $this->render('@ChillPerson/AccompanyingPeriod/user_reassign_periods_list.html.twig', [ - 'form' => $form - ]); - } - - private function buildUserSelectionForm(): FormInterface - { - $data = [ - 'users' => [], - ]; - - $builder = $this->formFactory->createBuilder(FormType::class, $data, [ - 'method' => 'get', 'csrf_protection' => false]); - - $builder - ->add('users', EntityType::class, [ - 'class' => User::class, - 'query_builder' => function (EntityRepository $er) { - $qb = $er->createQueryBuilder('u'); - return $qb; - }, - 'choice_label' => function(User $u) { - return $u->getUsername(); - }, - 'multiple' => false, - 'label' => 'User', - 'required' => false, - ]); - - return $builder->getForm(); - } } diff --git a/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodACLAwareRepository.php b/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodACLAwareRepository.php index 6e6c3ca44..735227ced 100644 --- a/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodACLAwareRepository.php +++ b/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodACLAwareRepository.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Chill\PersonBundle\Repository; +use Chill\MainBundle\Entity\User; use Chill\MainBundle\Security\Authorization\AuthorizationHelper; use Chill\MainBundle\Security\Resolver\CenterResolverDispatcherInterface; use Chill\PersonBundle\Entity\AccompanyingPeriod; @@ -92,4 +93,26 @@ final class AccompanyingPeriodACLAwareRepository implements AccompanyingPeriodAC return $qb->getQuery()->getResult(); } + + /** + * @return array|AccompanyingPeriod[] + */ + public function findByUserConfirmed(?User $user, int $limit, int $offset): array + { + if (null === $user) { + return []; + } + + $qb = $this->accompanyingPeriodRepository->createQueryBuilder('ap'); + + $qb->where($qb->expr()->eq('ap.user', ':user')) + ->andWhere( + $qb->expr()->eq('ap.step', ':confirmed') + ) + ->setParameter('user', $user) + ->setParameter('confirmed', AccompanyingPeriod::STEP_CONFIRMED); + + return $qb->getQuery()->getResult(); + + } } diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/reassign_list.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/reassign_list.html.twig new file mode 100644 index 000000000..673b8a36d --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/reassign_list.html.twig @@ -0,0 +1,80 @@ +{% extends 'ChillMainBundle::layout.html.twig' %} + +{% block title "Liste de parcours à réassigner" %} + +{% block js %} + {{ encore_entry_script_tags('mod_set_referrer') }} +{% endblock %} + +{% block css %} + {{ encore_entry_link_tags('mod_set_referrer') }} +{% endblock %} + +{# {% macro period_meta(period) %} + {% if is_granted('CHILL_PERSON_ACCOMPANYING_PERIOD_UPDATE', period) %} +
+ {% set job_id = null %} + {% if period.job is defined %} + {% set job_id = period.job.id %} + {% endif %} + +
+ {% endif %} +{% endmacro %} #} + +{% macro period_actions(period) %} + {% if is_granted('CHILL_PERSON_ACCOMPANYING_PERIOD_SEE', period) %} +
  • + +
  • + {% endif %} +{% endmacro %} + +{% import _self as m %} + +{% block content %} +
    +

    {{ block('title') }}

    + + {{ form_start(form) }} +
    +
    + {{ form_label(form.user ) }} + {{ form_widget(form.user, {'attr': {'class': 'select2'}}) }} +
    +
    + +
      +
    • + +
    • +
    + + {{ form_end(form) }} + + {% if form.user.vars.value is empty %} +

    Choisissez un référent pour afficher ses parcours.

    + {% elseif periods|length == 0 and form.user.vars.value is not empty %} +

    Aucun parcour à réassigner pour cet utilisateur.

    + {% else %} +

    Amount of parcours à réassigner (calculé ce jour à {{ null|format_time('medium') }})

    + +
    + {% for period in periods %} + {% include '@ChillPerson/AccompanyingPeriod/_list_item.html.twig' with {'period': period, + 'recordAction': m.period_actions(period) } %} + {% endfor %} +
    + {% endif %} + + {# {{ chill_pagination(paginator) }} #} + +
    +{% endblock %} + diff --git a/src/Bundle/ChillPersonBundle/config/services/controller.yaml b/src/Bundle/ChillPersonBundle/config/services/controller.yaml index 22d58ccbe..67c724093 100644 --- a/src/Bundle/ChillPersonBundle/config/services/controller.yaml +++ b/src/Bundle/ChillPersonBundle/config/services/controller.yaml @@ -41,6 +41,11 @@ services: autowire: true tags: ['controller.service_arguments'] + Chill\PersonBundle\Controller\ReassignAccompanyingPeriodController: + autoconfigure: true + autowire: true + tags: ['controller.service_arguments'] + Chill\PersonBundle\Controller\PersonApiController: arguments: $authorizationHelper: '@Chill\MainBundle\Security\Authorization\AuthorizationHelper' From 6adb647ccc1cd9d760e7b714d3642e6eb313ed2d Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Thu, 17 Mar 2022 12:31:44 +0100 Subject: [PATCH 3/8] changelog updated --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 96685b5f0..e0f20e6b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -45,6 +45,7 @@ and this project adheres to * [contact] add contact button color changed plus the pipe at the side removed (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/506) * [household] create-edit household composition placed in separate page to avoid confusion (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/505) * [blur] Improved positioning of toggle icon (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/486) +* [parcours] List of parcours for a specific user so they can be reassigned in case of absence (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/509) ## Test releases From 72ba2c6bca7ade11464bb4f03abca9429efc0e16 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Thu, 17 Mar 2022 14:13:21 +0100 Subject: [PATCH 4/8] paginator added + phpcsfixes --- .../Repository/UserRepository.php | 10 ++--- .../ReassignAccompanyingPeriodController.php | 35 ++++++++++-------- .../AccompanyingPeriodACLAwareRepository.php | 37 ++++++++++++++----- .../reassign_list.html.twig | 15 ++++---- 4 files changed, 61 insertions(+), 36 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Repository/UserRepository.php b/src/Bundle/ChillMainBundle/Repository/UserRepository.php index 56a82de3d..0616878ff 100644 --- a/src/Bundle/ChillMainBundle/Repository/UserRepository.php +++ b/src/Bundle/ChillMainBundle/Repository/UserRepository.php @@ -32,11 +32,6 @@ final class UserRepository implements ObjectRepository $this->repository = $entityManager->getRepository(User::class); } - public function createQueryBuilder(string $alias, ?string $indexBy = null): QueryBuilder - { - return $this->repository->createQueryBuilder($alias, $indexBy); - } - public function countBy(array $criteria): int { return $this->repository->count($criteria); @@ -56,6 +51,11 @@ final class UserRepository implements ObjectRepository return (int) $qb->getQuery()->getSingleScalarResult(); } + public function createQueryBuilder(string $alias, ?string $indexBy = null): QueryBuilder + { + return $this->repository->createQueryBuilder($alias, $indexBy); + } + public function find($id, $lockMode = null, $lockVersion = null): ?User { return $this->repository->find($id, $lockMode, $lockVersion); diff --git a/src/Bundle/ChillPersonBundle/Controller/ReassignAccompanyingPeriodController.php b/src/Bundle/ChillPersonBundle/Controller/ReassignAccompanyingPeriodController.php index 66a460199..04e38da13 100644 --- a/src/Bundle/ChillPersonBundle/Controller/ReassignAccompanyingPeriodController.php +++ b/src/Bundle/ChillPersonBundle/Controller/ReassignAccompanyingPeriodController.php @@ -1,11 +1,19 @@ handleRequest($request); - // $total = $this->accompanyingPeriodACLAwareRepository->countByUserConfirmed( - // $form['jobs']->getData(), - // $form['services']->getData(), - // $form['locations']->getData(), - // ); - // $paginator = $this->paginatorFactory->create($total); + $total = $this->accompanyingPeriodACLAwareRepository->countByUserConfirmed( + $form['user']->getData() + ); + $paginator = $this->paginatorFactory->create($total); $periods = $this->accompanyingPeriodACLAwareRepository ->findByUserConfirmed( $form['user']->getData(), - 1, - 1 + $paginator->getItemsPerPage(), + $paginator->getCurrentPageFirstItemNumber() ); return new Response( $this->engine->render('@ChillPerson/AccompanyingPeriod/reassign_list.html.twig', [ - // 'paginator' => $paginator, + 'paginator' => $paginator, 'periods' => $periods, - 'form' => $form->createView() + 'form' => $form->createView(), ]) ); } @@ -81,7 +87,7 @@ class ReassignAccompanyingPeriodController extends AbstractController private function buildFilterForm(): FormInterface { $builder = $this->formFactory->createBuilder(FormType::class, [ - 'method' => 'get', 'csrf_protection' => false]); + 'method' => 'get', 'csrf_protection' => false, ]); $builder ->add('user', EntityType::class, [ @@ -94,7 +100,7 @@ class ReassignAccompanyingPeriodController extends AbstractController return $qb; }, - 'choice_label' => function (User $u) { + 'choice_label' => static function (User $u) { return $u->getUsername(); }, 'multiple' => false, @@ -104,5 +110,4 @@ class ReassignAccompanyingPeriodController extends AbstractController return $builder->getForm(); } - -} \ No newline at end of file +} diff --git a/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodACLAwareRepository.php b/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodACLAwareRepository.php index 735227ced..47e1ee441 100644 --- a/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodACLAwareRepository.php +++ b/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodACLAwareRepository.php @@ -42,6 +42,33 @@ final class AccompanyingPeriodACLAwareRepository implements AccompanyingPeriodAC $this->centerResolverDispatcher = $centerResolverDispatcher; } + public function buildQueryByUser(?User $user) + { + $qb = $this->accompanyingPeriodRepository->createQueryBuilder('ap'); + + $qb->where($qb->expr()->eq('ap.user', ':user')) + ->andWhere( + $qb->expr()->eq('ap.step', ':confirmed'), + $qb->expr()->eq('ap.confidential', 'false') + ) + ->setParameter('user', $user) + ->setParameter('confirmed', AccompanyingPeriod::STEP_CONFIRMED); + + return $qb; + } + + public function countByUserConfirmed(?User $user) + { + if (null === $user) { + return 0; + } + + return $this->buildQueryByUser($user) + ->select('COUNT(ap)') + ->getQuery() + ->getSingleScalarResult(); + } + public function findByPerson( Person $person, string $role, @@ -103,16 +130,8 @@ final class AccompanyingPeriodACLAwareRepository implements AccompanyingPeriodAC return []; } - $qb = $this->accompanyingPeriodRepository->createQueryBuilder('ap'); - - $qb->where($qb->expr()->eq('ap.user', ':user')) - ->andWhere( - $qb->expr()->eq('ap.step', ':confirmed') - ) - ->setParameter('user', $user) - ->setParameter('confirmed', AccompanyingPeriod::STEP_CONFIRMED); + $qb = $this->buildQueryByUser($user); return $qb->getQuery()->getResult(); - } } diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/reassign_list.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/reassign_list.html.twig index 673b8a36d..d7e11f6ee 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/reassign_list.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/reassign_list.html.twig @@ -1,6 +1,6 @@ {% extends 'ChillMainBundle::layout.html.twig' %} -{% block title "Liste de parcours à réassigner" %} +{% block title "Liste de parcours à réassigner pour un utilisateur" %} {% block js %} {{ encore_entry_script_tags('mod_set_referrer') }} @@ -10,7 +10,7 @@ {{ encore_entry_link_tags('mod_set_referrer') }} {% endblock %} -{# {% macro period_meta(period) %} +{% macro period_meta(period) %} {% if is_granted('CHILL_PERSON_ACCOMPANYING_PERIOD_UPDATE', period) %}
    {% set job_id = null %} @@ -24,7 +24,8 @@ >
    {% endif %} -{% endmacro %} #} +{% endmacro %} + {% macro period_actions(period) %} {% if is_granted('CHILL_PERSON_ACCOMPANYING_PERIOD_SEE', period) %} @@ -61,19 +62,19 @@ {% if form.user.vars.value is empty %}

    Choisissez un référent pour afficher ses parcours.

    {% elseif periods|length == 0 and form.user.vars.value is not empty %} -

    Aucun parcour à réassigner pour cet utilisateur.

    +

    Aucun parcours actifs pour ce référent.

    {% else %} -

    Amount of parcours à réassigner (calculé ce jour à {{ null|format_time('medium') }})

    +

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

    {% for period in periods %} {% include '@ChillPerson/AccompanyingPeriod/_list_item.html.twig' with {'period': period, - 'recordAction': m.period_actions(period) } %} + 'recordAction': m.period_actions(period), 'itemMeta': m.period_meta(period) } %} {% endfor %}
    {% endif %} - {# {{ chill_pagination(paginator) }} #} + {{ chill_pagination(paginator) }} {% endblock %} From 15af0203fff262f1c0fc8bc100ad5cc4f1657433 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Mon, 21 Mar 2022 10:21:12 +0100 Subject: [PATCH 5/8] add menu entry in section menu --- .../Menu/SectionMenuBuilder.php | 18 ++++++++++-------- .../translations/messages.fr.yml | 1 + 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Menu/SectionMenuBuilder.php b/src/Bundle/ChillPersonBundle/Menu/SectionMenuBuilder.php index 04f989d84..4635eb4fc 100644 --- a/src/Bundle/ChillPersonBundle/Menu/SectionMenuBuilder.php +++ b/src/Bundle/ChillPersonBundle/Menu/SectionMenuBuilder.php @@ -22,15 +22,9 @@ use Symfony\Contracts\Translation\TranslatorInterface; */ class SectionMenuBuilder implements LocalMenuBuilderInterface { - /** - * @var AuthorizationCheckerInterface - */ - protected $authorizationChecker; + protected AuthorizationCheckerInterface $authorizationChecker; - /** - * @var TranslatorInterface - */ - protected $translator; + protected TranslatorInterface $translator; /** * SectionMenuBuilder constructor. @@ -63,6 +57,14 @@ class SectionMenuBuilder implements LocalMenuBuilderInterface 'order' => 11, 'icons' => ['plus'], ]); + + $menu->addChild($this->translator->trans('Accompanying courses of users'), [ + 'route' => 'chill_course_list_reassign', + ]) + ->setExtras([ + 'order' => 12, + 'icons' => ['task'], + ]); } public static function getMenuIds(): array diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index bc238570d..57fc039b8 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -194,6 +194,7 @@ No accompanying user: Aucun accompagnant No data given: Pas d'information Participants: Personnes impliquées Create an accompanying course: Créer un parcours +Accompanying courses of users: Parcours des utilisateurs This accompanying course is still a draft: Ce parcours est encore à l'état brouillon. Associated peoples: Usagers concernés Resources: Interlocuteurs privilégiés From a06a0788c146b69d9d1e67f86eceea0548c0564b Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Mon, 21 Mar 2022 10:22:28 +0100 Subject: [PATCH 6/8] csfixes --- .../ChillMainBundle/Command/LoadPostalCodesCommand.php | 5 +++-- .../Serializer/Normalizer/PhonenumberNormalizer.php | 9 ++++----- .../Menu/AccompanyingCourseMenuBuilder.php | 2 +- ...anyingPeriodWorkEvaluationDocumentWorkflowHandler.php | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Command/LoadPostalCodesCommand.php b/src/Bundle/ChillMainBundle/Command/LoadPostalCodesCommand.php index 5d577a0b4..bc4616b7b 100644 --- a/src/Bundle/ChillMainBundle/Command/LoadPostalCodesCommand.php +++ b/src/Bundle/ChillMainBundle/Command/LoadPostalCodesCommand.php @@ -26,6 +26,7 @@ use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\Validator\Validator\ValidatorInterface; use function count; +use function strlen; class LoadPostalCodesCommand extends Command { @@ -118,11 +119,11 @@ class LoadPostalCodesCommand extends Command private function addPostalCode($row, OutputInterface $output) { - if($row[2] == 'FR' && strlen($row[0]) == 4) { + if ('FR' === $row[2] && strlen($row[0]) === 4) { // CP in FRANCE are on 5 digit // For CP starting with a zero, the starting zero can be remove if stored as number in a csv // add a zero if CP from FR and on 4 digit - $row[0] = '0'.$row[0]; + $row[0] = '0' . $row[0]; } if ($output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE) { diff --git a/src/Bundle/ChillMainBundle/Serializer/Normalizer/PhonenumberNormalizer.php b/src/Bundle/ChillMainBundle/Serializer/Normalizer/PhonenumberNormalizer.php index 677199ad4..7eb323754 100644 --- a/src/Bundle/ChillMainBundle/Serializer/Normalizer/PhonenumberNormalizer.php +++ b/src/Bundle/ChillMainBundle/Serializer/Normalizer/PhonenumberNormalizer.php @@ -18,7 +18,6 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; use Symfony\Component\Serializer\Exception\UnexpectedValueException; use Symfony\Component\Serializer\Normalizer\ContextAwareNormalizerInterface; use Symfony\Component\Serializer\Normalizer\DenormalizerInterface; -use Symfony\Component\Serializer\Normalizer\NormalizerInterface; class PhonenumberNormalizer implements ContextAwareNormalizerInterface, DenormalizerInterface { @@ -54,7 +53,7 @@ class PhonenumberNormalizer implements ContextAwareNormalizerInterface, Denormal public function normalize($object, ?string $format = null, array $context = []): string { - if ($format === 'docgen' && null === $object) { + if ('docgen' === $format && null === $object) { return ''; } @@ -68,13 +67,13 @@ class PhonenumberNormalizer implements ContextAwareNormalizerInterface, Denormal public function supportsNormalization($data, ?string $format = null, array $context = []): bool { - if ($data instanceof PhoneNumber && $format === 'json') { + if ($data instanceof PhoneNumber && 'json' === $format) { return true; } - if ($format === 'docgen' && ( + if ('docgen' === $format && ( $data instanceof PhoneNumber || PhoneNumber::class === ($context['docgen:expects'] ?? null) - )) { + )) { return true; } diff --git a/src/Bundle/ChillPersonBundle/Menu/AccompanyingCourseMenuBuilder.php b/src/Bundle/ChillPersonBundle/Menu/AccompanyingCourseMenuBuilder.php index 8f1ecb0d1..929fb2ae0 100644 --- a/src/Bundle/ChillPersonBundle/Menu/AccompanyingCourseMenuBuilder.php +++ b/src/Bundle/ChillPersonBundle/Menu/AccompanyingCourseMenuBuilder.php @@ -75,7 +75,7 @@ class AccompanyingCourseMenuBuilder implements LocalMenuBuilderInterface 'accompanying_period_id' => $period->getId(), ], ]) ->setExtras(['order' => 30]); - */ + */ $menu->addChild($this->translator->trans('Accompanying Course Comment'), [ 'route' => 'chill_person_accompanying_period_comment_list', diff --git a/src/Bundle/ChillPersonBundle/Workflow/AccompanyingPeriodWorkEvaluationDocumentWorkflowHandler.php b/src/Bundle/ChillPersonBundle/Workflow/AccompanyingPeriodWorkEvaluationDocumentWorkflowHandler.php index d7a196a6c..d7ce1ed4b 100644 --- a/src/Bundle/ChillPersonBundle/Workflow/AccompanyingPeriodWorkEvaluationDocumentWorkflowHandler.php +++ b/src/Bundle/ChillPersonBundle/Workflow/AccompanyingPeriodWorkEvaluationDocumentWorkflowHandler.php @@ -62,7 +62,7 @@ class AccompanyingPeriodWorkEvaluationDocumentWorkflowHandler implements EntityW 'workflow.Doc for evaluation (n°%eval%)', ['%eval%' => $entityWorkflow->getRelatedEntityId()] ) . ' (' . $this->translatableStringHelper->localize($doc->getAccompanyingPeriodWorkEvaluation() - ->getEvaluation()->getTitle()).') '.$doc->getTitle(); + ->getEvaluation()->getTitle()) . ') ' . $doc->getTitle(); } public function getRelatedEntity(EntityWorkflow $entityWorkflow): ?AccompanyingPeriodWorkEvaluationDocument From 293efc03b41dafdf006f8ba99513ce4256c94cd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Mon, 21 Mar 2022 13:35:14 +0100 Subject: [PATCH 7/8] fixes for reasign list * use existing method in UserRepository and use a method instead of building a query outside of the repository; * use renderString to render users * fix building of filter form (add $data). This make the use of the method "get" instead of post --- .../Repository/UserRepository.php | 5 ---- .../ReassignAccompanyingPeriodController.php | 24 +++++++++---------- .../reassign_list.html.twig | 4 ++-- 3 files changed, 14 insertions(+), 19 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Repository/UserRepository.php b/src/Bundle/ChillMainBundle/Repository/UserRepository.php index 0616878ff..fc3a6e187 100644 --- a/src/Bundle/ChillMainBundle/Repository/UserRepository.php +++ b/src/Bundle/ChillMainBundle/Repository/UserRepository.php @@ -51,11 +51,6 @@ final class UserRepository implements ObjectRepository return (int) $qb->getQuery()->getSingleScalarResult(); } - public function createQueryBuilder(string $alias, ?string $indexBy = null): QueryBuilder - { - return $this->repository->createQueryBuilder($alias, $indexBy); - } - public function find($id, $lockMode = null, $lockVersion = null): ?User { return $this->repository->find($id, $lockMode, $lockVersion); diff --git a/src/Bundle/ChillPersonBundle/Controller/ReassignAccompanyingPeriodController.php b/src/Bundle/ChillPersonBundle/Controller/ReassignAccompanyingPeriodController.php index 04e38da13..24de2d7db 100644 --- a/src/Bundle/ChillPersonBundle/Controller/ReassignAccompanyingPeriodController.php +++ b/src/Bundle/ChillPersonBundle/Controller/ReassignAccompanyingPeriodController.php @@ -14,6 +14,7 @@ namespace Chill\PersonBundle\Controller; use Chill\MainBundle\Entity\User; use Chill\MainBundle\Pagination\PaginatorFactory; use Chill\MainBundle\Repository\UserRepository; +use Chill\MainBundle\Templating\Entity\UserRender; use Chill\PersonBundle\Repository\AccompanyingPeriodACLAwareRepository; use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; @@ -39,9 +40,11 @@ class ReassignAccompanyingPeriodController extends AbstractController private Security $security; + private UserRender $userRender; + private UserRepository $userRepository; - public function __construct(AccompanyingPeriodACLAwareRepository $accompanyingPeriodACLAwareRepository, UserRepository $userRepository, EngineInterface $engine, FormFactoryInterface $formFactory, PaginatorFactory $paginatorFactory, Security $security) + public function __construct(AccompanyingPeriodACLAwareRepository $accompanyingPeriodACLAwareRepository, UserRepository $userRepository, EngineInterface $engine, FormFactoryInterface $formFactory, PaginatorFactory $paginatorFactory, Security $security, UserRender $userRender) { $this->accompanyingPeriodACLAwareRepository = $accompanyingPeriodACLAwareRepository; $this->engine = $engine; @@ -49,6 +52,7 @@ class ReassignAccompanyingPeriodController extends AbstractController $this->paginatorFactory = $paginatorFactory; $this->security = $security; $this->userRepository = $userRepository; + $this->userRender = $userRender; } /** @@ -86,22 +90,18 @@ class ReassignAccompanyingPeriodController extends AbstractController private function buildFilterForm(): FormInterface { - $builder = $this->formFactory->createBuilder(FormType::class, [ + $data = [ + 'user' => null, + ]; + $builder = $this->formFactory->createBuilder(FormType::class, $data, [ 'method' => 'get', 'csrf_protection' => false, ]); $builder ->add('user', EntityType::class, [ 'class' => User::class, - 'query_builder' => function () { - $qb = $this->userRepository->createQueryBuilder('u'); - - $qb->where('u.enabled = true') - ->orderBy('u.username', 'ASC'); - - return $qb; - }, - 'choice_label' => static function (User $u) { - return $u->getUsername(); + 'choices' => $this->userRepository->findByActive(['username' => 'ASC']), + 'choice_label' => function (User $u) { + return $this->userRender->renderString($u, []); }, 'multiple' => false, 'label' => 'User', diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/reassign_list.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/reassign_list.html.twig index d7e11f6ee..55b932751 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/reassign_list.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/reassign_list.html.twig @@ -42,8 +42,8 @@

    {{ block('title') }}

    {{ form_start(form) }} -
    -
    +
    +
    {{ form_label(form.user ) }} {{ form_widget(form.user, {'attr': {'class': 'select2'}}) }}
    From ac9e55e2fc47c10c3413f5d90b49139f0e304cc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Mon, 21 Mar 2022 14:54:01 +0100 Subject: [PATCH 8/8] fix methods for accompanying period repository acl aware * add method to interface * delegate ACL to another method --- .../ReassignAccompanyingPeriodController.php | 10 ++++--- .../AccompanyingPeriodACLAwareRepository.php | 27 +++++++++++++------ ...nyingPeriodACLAwareRepositoryInterface.php | 5 ++++ .../reassign_list.html.twig | 7 ++--- .../translations/messages.fr.yml | 5 ++++ 5 files changed, 39 insertions(+), 15 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Controller/ReassignAccompanyingPeriodController.php b/src/Bundle/ChillPersonBundle/Controller/ReassignAccompanyingPeriodController.php index 24de2d7db..ac5b6dfab 100644 --- a/src/Bundle/ChillPersonBundle/Controller/ReassignAccompanyingPeriodController.php +++ b/src/Bundle/ChillPersonBundle/Controller/ReassignAccompanyingPeriodController.php @@ -16,6 +16,7 @@ use Chill\MainBundle\Pagination\PaginatorFactory; use Chill\MainBundle\Repository\UserRepository; use Chill\MainBundle\Templating\Entity\UserRender; use Chill\PersonBundle\Repository\AccompanyingPeriodACLAwareRepository; +use Chill\PersonBundle\Repository\AccompanyingPeriodACLAwareRepositoryInterface; use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\Form\Extension\Core\Type\FormType; @@ -30,7 +31,7 @@ use Symfony\Component\Templating\EngineInterface; class ReassignAccompanyingPeriodController extends AbstractController { - private AccompanyingPeriodACLAwareRepository $accompanyingPeriodACLAwareRepository; + private AccompanyingPeriodACLAwareRepositoryInterface $accompanyingPeriodACLAwareRepository; private EngineInterface $engine; @@ -44,7 +45,7 @@ class ReassignAccompanyingPeriodController extends AbstractController private UserRepository $userRepository; - public function __construct(AccompanyingPeriodACLAwareRepository $accompanyingPeriodACLAwareRepository, UserRepository $userRepository, EngineInterface $engine, FormFactoryInterface $formFactory, PaginatorFactory $paginatorFactory, Security $security, UserRender $userRender) + public function __construct(AccompanyingPeriodACLAwareRepositoryInterface $accompanyingPeriodACLAwareRepository, UserRepository $userRepository, EngineInterface $engine, FormFactoryInterface $formFactory, PaginatorFactory $paginatorFactory, Security $security, UserRender $userRender) { $this->accompanyingPeriodACLAwareRepository = $accompanyingPeriodACLAwareRepository; $this->engine = $engine; @@ -68,13 +69,14 @@ class ReassignAccompanyingPeriodController extends AbstractController $form->handleRequest($request); - $total = $this->accompanyingPeriodACLAwareRepository->countByUserConfirmed( + $total = $this->accompanyingPeriodACLAwareRepository->countByUserOpenedAccompanyingPeriod( $form['user']->getData() ); $paginator = $this->paginatorFactory->create($total); $periods = $this->accompanyingPeriodACLAwareRepository - ->findByUserConfirmed( + ->findByUserOpenedAccompanyingPeriod( $form['user']->getData(), + ['openingDate' => 'ASC'], $paginator->getItemsPerPage(), $paginator->getCurrentPageFirstItemNumber() ); diff --git a/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodACLAwareRepository.php b/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodACLAwareRepository.php index 47e1ee441..f4c9a52a3 100644 --- a/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodACLAwareRepository.php +++ b/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodACLAwareRepository.php @@ -42,28 +42,32 @@ final class AccompanyingPeriodACLAwareRepository implements AccompanyingPeriodAC $this->centerResolverDispatcher = $centerResolverDispatcher; } - public function buildQueryByUser(?User $user) + public function buildQueryOpenedAccompanyingCourseByUser(?User $user) { $qb = $this->accompanyingPeriodRepository->createQueryBuilder('ap'); $qb->where($qb->expr()->eq('ap.user', ':user')) ->andWhere( - $qb->expr()->eq('ap.step', ':confirmed'), - $qb->expr()->eq('ap.confidential', 'false') + $qb->expr()->neq('ap.step', ':draft'), + $qb->expr()->orX( + $qb->expr()->isNull('ap.closingDate'), + $qb->expr()->gt('ap.closingDate', ':now') + ) ) ->setParameter('user', $user) - ->setParameter('confirmed', AccompanyingPeriod::STEP_CONFIRMED); + ->setParameter('now', new \DateTime('now')) + ->setParameter('draft', AccompanyingPeriod::STEP_DRAFT); return $qb; } - public function countByUserConfirmed(?User $user) + public function countByUserOpenedAccompanyingPeriod(?User $user): int { if (null === $user) { return 0; } - return $this->buildQueryByUser($user) + return $this->buildQueryOpenedAccompanyingCourseByUser($user) ->select('COUNT(ap)') ->getQuery() ->getSingleScalarResult(); @@ -124,13 +128,20 @@ final class AccompanyingPeriodACLAwareRepository implements AccompanyingPeriodAC /** * @return array|AccompanyingPeriod[] */ - public function findByUserConfirmed(?User $user, int $limit, int $offset): array + public function findByUserOpenedAccompanyingPeriod(?User $user, array $orderBy = [], int $limit = 0, int $offset = 50): array { if (null === $user) { return []; } - $qb = $this->buildQueryByUser($user); + $qb = $this->buildQueryOpenedAccompanyingCourseByUser($user); + + $qb->setFirstResult($offset) + ->setMaxResults($limit); + + foreach ($orderBy as $field => $direction) { + $qb->addOrderBy('ap.'.$field, $direction); + } return $qb->getQuery()->getResult(); } diff --git a/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodACLAwareRepositoryInterface.php b/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodACLAwareRepositoryInterface.php index 778e8d8fe..0c5af217f 100644 --- a/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodACLAwareRepositoryInterface.php +++ b/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodACLAwareRepositoryInterface.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Chill\PersonBundle\Repository; +use Chill\MainBundle\Entity\User; use Chill\PersonBundle\Entity\Person; interface AccompanyingPeriodACLAwareRepositoryInterface @@ -22,4 +23,8 @@ interface AccompanyingPeriodACLAwareRepositoryInterface ?int $limit = null, ?int $offset = null ): array; + + public function findByUserOpenedAccompanyingPeriod(?User $user, array $orderBy = [], int $limit = 0, int $offset = 50): array; + + public function countByUserOpenedAccompanyingPeriod(?User $user): int; } diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/reassign_list.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/reassign_list.html.twig index 55b932751..87166d990 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/reassign_list.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/reassign_list.html.twig @@ -1,6 +1,6 @@ {% extends 'ChillMainBundle::layout.html.twig' %} -{% block title "Liste de parcours à réassigner pour un utilisateur" %} +{% block title 'period_by_user_list.Period by user'|trans %} {% block js %} {{ encore_entry_script_tags('mod_set_referrer') }} @@ -60,9 +60,10 @@ {{ form_end(form) }} {% if form.user.vars.value is empty %} -

    Choisissez un référent pour afficher ses parcours.

    +

    {{ 'period_by_user_list.Pick a user'|trans }}

    {% elseif periods|length == 0 and form.user.vars.value is not empty %} -

    Aucun parcours actifs pour ce référent.

    +

    {{ 'period_by_user_list.Any course or no authorization to see them'|trans }}

    + {% else %}

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

    diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index bb5e5e846..d6e739632 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -579,3 +579,8 @@ My accompanying periods in draft: Mes parcours brouillons workflow: Doc for evaluation (n°%eval%): Document de l'évaluation n°%eval% + +period_by_user_list: + Period by user: Parcours d'accompagnement par utilisateur + Pick a user: Choisissez un utilisateur pour obtenir la liste de ses parcours + Any course or no authorization to see them: Aucun parcours pour ce référent, ou aucun droit pour visualiser les parcours de ce référent.