diff --git a/src/Bundle/ChillMainBundle/Resources/public/lib/api/apiMethods.js b/src/Bundle/ChillMainBundle/Resources/public/lib/api/apiMethods.js index 5ad119858..7a4a81248 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/lib/api/apiMethods.js +++ b/src/Bundle/ChillMainBundle/Resources/public/lib/api/apiMethods.js @@ -1,7 +1,7 @@ /** * Generic api method that can be adapted to any fetch request */ - const makeFetch = (method, url, body) => { +const makeFetch = (method, url, body) => { return fetch(url, { method: method, headers: { diff --git a/src/Bundle/ChillPersonBundle/AccompanyingPeriod/Events/UserRefEventSubscriber.php b/src/Bundle/ChillPersonBundle/AccompanyingPeriod/Events/UserRefEventSubscriber.php index 590874ab4..13fcb5e79 100644 --- a/src/Bundle/ChillPersonBundle/AccompanyingPeriod/Events/UserRefEventSubscriber.php +++ b/src/Bundle/ChillPersonBundle/AccompanyingPeriod/Events/UserRefEventSubscriber.php @@ -60,6 +60,7 @@ class UserRefEventSubscriber implements EventSubscriberInterface { if ($period->hasPreviousUser() && $period->getUser() !== $this->security->getUser() + && $period->getUser() !== null && $period->getStep() !== AccompanyingPeriod::STEP_DRAFT ) { $this->generateNotificationToUser($period); diff --git a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseApiController.php b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseApiController.php index 83d6c26cd..9a984f237 100644 --- a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseApiController.php +++ b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseApiController.php @@ -31,6 +31,7 @@ use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter; use Chill\ThirdPartyBundle\Entity\ThirdParty; use DateInterval; use DateTimeImmutable; +use JsonSchema\Exception\ValidationException; use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\HttpFoundation\Exception\BadRequestException; @@ -323,13 +324,21 @@ final class AccompanyingCourseApiController extends ApiController * @Route("/api/1.0/person/accompanying-course/{id}/confidential.json", name="chill_api_person_accompanying_period_confidential") * @ParamConverter("accompanyingCourse", options={"id": "id"}) */ - public function toggleConfidentialApi(AccompanyingPeriod $accompanyingCourse, Request $request) + public function toggleConfidentialApi(AccompanyingPeriod $accompanyingCourse, $id, Request $request) { - if ($request->getMethod() === 'POST') { + if ($request->getMethod() == 'POST') { $this->denyAccessUnlessGranted(AccompanyingPeriodVoter::TOGGLE_CONFIDENTIAL, $accompanyingCourse); - $accompanyingCourse->setConfidential(!$accompanyingCourse->isConfidential()); - $this->getDoctrine()->getManager()->flush(); + if (null != $accompanyingCourse->getUser() && $this->getUser() == $accompanyingCourse->getUser()) { + $accompanyingCourse->setConfidential(!$accompanyingCourse->isConfidential()); + $this->getDoctrine()->getManager()->flush(); + } else { + if ($accompanyingCourse->getUser() == null) { + throw new ValidationException("The parcours must have a referrer to be set to confidential"); + } + throw new ValidationException("Only the referrer can set a parcours to confidential"); + } + } return $this->json($accompanyingCourse->isConfidential(), Response::HTTP_OK, [], ['groups' => ['read']]); diff --git a/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php b/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php index b7fdd4836..30fcc43ad 100644 --- a/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php +++ b/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php @@ -395,26 +395,16 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac Request::METHOD_POST => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE, ], ], - 'confidential' => [ - 'methods' => [ - Request::METHOD_POST => true, - Request::METHOD_GET => true, - ], - 'controller_action' => 'toggleConfidentialApi', - 'roles' => [ - Request::METHOD_POST => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::TOGGLE_CONFIDENTIAL, - ], - ], - 'intensity' => [ - 'methods' => [ - Request::METHOD_POST => true, - Request::METHOD_GET => true, - ], - 'controller_action' => 'toggleIntensityApi', - 'roles' => [ - Request::METHOD_POST => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::TOGGLE_INTENSITY, - ], - ], + // 'confidential' => [ + // 'methods' => [ + // Request::METHOD_POST => true, + // Request::METHOD_GET => true, + // ], + // 'controller_action' => 'toggleConfidentialApi', + // 'roles' => [ + // Request::METHOD_POST => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::TOGGLE_CONFIDENTIAL, + // ], + // ], 'findAccompanyingPeriodsByPerson' => [ 'path' => '/by-person/{person_id}.{_format}', 'controller_action' => 'getAccompanyingPeriodsByPerson', diff --git a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php index b5df81ce3..0eac2a34c 100644 --- a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php +++ b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php @@ -38,6 +38,7 @@ use DateTimeInterface; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; +use JsonSchema\Exception\ValidationException; use LogicException; use Symfony\Component\Serializer\Annotation\DiscriminatorMap; use Symfony\Component\Serializer\Annotation\Groups; @@ -59,11 +60,6 @@ use const SORT_REGULAR; * "accompanying_period": AccompanyingPeriod::class * }) * @Assert\GroupSequenceProvider - * @Assert\Expression( - * "this.isConfidential and this.getUser === NULL", - * message="If the accompanying course is confirmed and confidential, a referrer must remain assigned." - * ) - * * @AccompanyingPeriodValidity(groups={AccompanyingPeriod::STEP_DRAFT, AccompanyingPeriod::STEP_CONFIRMED}) */ class AccompanyingPeriod implements @@ -340,6 +336,9 @@ class AccompanyingPeriod implements * @ORM\ManyToOne(targetEntity=User::class) * @ORM\JoinColumn(nullable=true) * @Groups({"read", "write", "docgen:read"}) + * @Assert\Expression("!this.isConfidential() or (this.isConfidential() and value != null)", + * groups={AccompanyingPeriod::STEP_CONFIRMED}, + * message="Referrer cannot be null for a confidential parcours") */ private ?User $user = null; @@ -500,20 +499,6 @@ class AccompanyingPeriod implements return end($periods) === $this; } - /** - * @Assert\Callback - */ - public function canUserBeNull(ExecutionContextInterface $context) - { - if ($this->getStep() === self::STEP_CONFIRMED && $this->isConfidential() === true) { - if (!$this->getUser()) { - $context->buildViolation('User cannot be null for an accompanying period that is confirmed and confidential') - ->atPath('user') - ->addViolation(); - } - } - } - /** * Close a participation for a person. * diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/index.js b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/index.js index 8440e50d5..4cf073eb4 100644 --- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/index.js +++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/index.js @@ -46,6 +46,12 @@ if (root === 'banner') { }) .use(store) .use(i18n) + .use(VueToast, { + position: "bottom-right", + type: "error", + duration: 5000, + dismissible: true + }) .component('banner', Banner) .mount('#banner-accompanying-course'); }); diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/store/index.js b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/store/index.js index 63c94f37a..1cc4fd481 100644 --- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/store/index.js +++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/store/index.js @@ -444,11 +444,11 @@ let initPromise = (root) => Promise.all([getScopesPromise(root), accompanyingCou body.gender = payload.data.gender; console.log('id', payload.data.id, 'and body', body); patchPerson(payload.data.id, body) - .then(person => new Promise((resolve, reject) => { - console.log('patch person', person); - commit('updatePerson', { target: payload.target, person: person }); - resolve(); - })); + .then(person => new Promise((resolve, reject) => { + console.log('patch person', person); + commit('updatePerson', { target: payload.target, person: person }); + resolve(); + })); } else if (payload.type === 'thirdparty') { body.name = payload.data.text; @@ -457,10 +457,10 @@ let initPromise = (root) => Promise.all([getScopesPromise(root), accompanyingCou body.address = { id: payload.data.address.address_id }; console.log('id', payload.data.id, 'and body', body); patchThirdparty(payload.data.id, body) - .then(thirdparty => new Promise((resolve, reject) => { - console.log('patch thirdparty', thirdparty); - commit('updateThirdparty', { target: payload.target, thirdparty: thirdparty }); - resolve(); + .then(thirdparty => new Promise((resolve, reject) => { + console.log('patch thirdparty', thirdparty); + commit('updateThirdparty', { target: payload.target, thirdparty: thirdparty }); + resolve(); })); } }, @@ -495,14 +495,18 @@ let initPromise = (root) => Promise.all([getScopesPromise(root), accompanyingCou }) }, toggleConfidential({ commit }, payload) { - const url = `/api/1.0/person/accompanying-course/${id}.json` + const url = `/api/1.0/person/accompanying-course/${id}/confidential.json` const body = { type: "accompanying_period", confidential: payload } - return makeFetch('PATCH', url, body) + console.log('url', url, 'body', body); + + return makeFetch('POST', url, body) .then((response) => { + console.log('response', response); commit('toggleConfidential', response); }) .catch((error) => { + console.log('error', error) commit('catchError', error); throw error; }) @@ -773,10 +777,10 @@ let initPromise = (root) => Promise.all([getScopesPromise(root), accompanyingCou "object": { "type": "accompanying_period", "id": id - }, - "class": "Chill\\PersonBundle\\Entity\\AccompanyingPeriod", - "roles": [ - "CHILL_PERSON_ACCOMPANYING_PERIOD_TOGGLE_CONFIDENTIAL" + }, + "class": "Chill\\PersonBundle\\Entity\\AccompanyingPeriod", + "roles": [ + "CHILL_PERSON_ACCOMPANYING_PERIOD_TOGGLE_CONFIDENTIAL" ] } diff --git a/src/Bundle/ChillPersonBundle/translations/validators.fr.yml b/src/Bundle/ChillPersonBundle/translations/validators.fr.yml index c47aee1c5..fa23f0c8e 100644 --- a/src/Bundle/ChillPersonBundle/translations/validators.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/validators.fr.yml @@ -51,6 +51,8 @@ household_membership: A course must contains at least one social issue: 'Un parcours doit être associé à au moins une problématique sociale' A course must be associated to at least one scope: 'Un parcours doit être associé à au moins un service' The social %name% issue cannot be deleted because it is associated with an activity or an action: 'La problématique sociale "%name%" ne peut pas être supprimée car elle est associée à une activité ou une action' +Referrer cannot be null for a confidential parcours: 'Un parcours confidentiel doit avoir un référent' +Only the referrer can set a parcours to confidential: 'Seul le référent peut modifier la confidentialité' # resource You must associate at least one entity: Associez un usager, un tiers ou indiquez une description libre