diff --git a/CHANGELOG.md b/CHANGELOG.md index d1d184e46..e4b2368b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to ## Unreleased +* [parcours] Toggle emergency/intensity only by referrer (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/442) * [docstore] Add an API entrypoint for StoredObject (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/466) * [person] Add the possibility of uploading existing documents to AccPeriodWorkEvaluationDocument (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/466) * [person] Add title to AccPeriodWorkEvaluationDocument (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/466) @@ -48,10 +49,9 @@ and this project adheres to * [thirdparty_contact]: in search results the 'qualité' is displayed (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/465) * [bug]: fix confidential toggle of address in thirdpartyrenderbox (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/460) + ## Test releases * Creation of PickCivilityType, and implementation in PersonType and ThirdpartyType -* [renderbox]: Fix display of address (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/462) -* [renderbox]: Add email in personRenderBox, this was not yet displayed. ### test release 2022-02-14 @@ -68,6 +68,7 @@ and this project adheres to * [parcours]: Mes parcours brouillon added to user menu (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/440) * [Documents]: List view adapted to display more information (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/414) * [person]: style fix in parcours listing per person. (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/432) +* [parcours]: Only the referrer can toggle the intensity of the parcours (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/442) * [household]: display address of current household (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/415) * ajoute un ordre dans les localisation (api) * [pick entity]: fix translations in modal (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/419) @@ -316,6 +317,7 @@ and this project adheres to * add an endpoint for checking permissions. See https://gitlab.com/Chill-Projet/chill-bundles/-/merge_requests/232 * [activity] for a new activity: suggest and create on-the-fly locations based on the accompanying course location + location of the suggested parties * [calendar] for a new rdv: suggest and create on-the-fly locations based on the accompanying course location + location of the suggested parties +* [period] Validation added when period is confidential and confirmed -> user cannot be null. ## Test releases diff --git a/composer b/composer new file mode 100755 index 000000000..0e7ab8212 Binary files /dev/null and b/composer differ diff --git a/src/Bundle/ChillMainBundle/Resources/public/chill/scss/render_box.scss b/src/Bundle/ChillMainBundle/Resources/public/chill/scss/render_box.scss index c42c592a9..37d4f97c4 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/chill/scss/render_box.scss +++ b/src/Bundle/ChillMainBundle/Resources/public/chill/scss/render_box.scss @@ -72,7 +72,7 @@ section.chill-entity { } } p { - // display: inline-block; + display: inline-block; margin: 0 0 0 1.5em; text-indent: -1.5em; diff --git a/src/Bundle/ChillMainBundle/Resources/public/lib/api/apiMethods.js b/src/Bundle/ChillMainBundle/Resources/public/lib/api/apiMethods.js index 5ad119858..67f3e2f42 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: { @@ -11,19 +11,20 @@ }) .then(response => { if (response.ok) { + console.log('200 error') return response.json(); } if (response.status === 422) { + console.log('422 error') return response.json().then(response => { throw ValidationException(response) }); } if (response.status === 403) { - return response.json().then(() => { - throw AccessException(); - }); + console.log('403 error') + throw AccessException(response); } throw { @@ -88,14 +89,13 @@ const ValidationException = (response) => { error.violations = response.violations.map((violation) => `${violation.title}: ${violation.propertyPath}`); error.titles = response.violations.map((violation) => violation.title); error.propertyPaths = response.violations.map((violation) => violation.propertyPath); - return error; } -const AccessException = () => { +const AccessException = (response) => { const error = {}; error.name = 'AccessException'; - error.violations = ['You are no longer permitted to perform this action']; + error.violations = ['You are not allowed to perform this action']; return error; } diff --git a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseApiController.php b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseApiController.php index 3da40db4c..f1306640b 100644 --- a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseApiController.php +++ b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseApiController.php @@ -322,19 +322,39 @@ 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"}) + * + * @param mixed $id */ - public function toggleConfidentialApi(AccompanyingPeriod $accompanyingCourse, Request $request) + public function toggleConfidentialApi(AccompanyingPeriod $accompanyingCourse, $id, Request $request) { if ($request->getMethod() === 'POST') { $this->denyAccessUnlessGranted(AccompanyingPeriodVoter::TOGGLE_CONFIDENTIAL, $accompanyingCourse); $accompanyingCourse->setConfidential(!$accompanyingCourse->isConfidential()); + $this->getDoctrine()->getManager()->flush(); } return $this->json($accompanyingCourse->isConfidential(), Response::HTTP_OK, [], ['groups' => ['read']]); } + /** + * @Route("/api/1.0/person/accompanying-course/{id}/intensity.json", name="chill_api_person_accompanying_period_intensity") + * @ParamConverter("accompanyingCourse", options={"id": "id"}) + */ + public function toggleIntensityApi(AccompanyingPeriod $accompanyingCourse, Request $request) + { + if ($request->getMethod() === 'POST') { + $this->denyAccessUnlessGranted(AccompanyingPeriodVoter::TOGGLE_INTENSITY, $accompanyingCourse); + + $status = $accompanyingCourse->getIntensity() === 'regular' ? 'occasional' : 'regular'; + $accompanyingCourse->setIntensity($status); + $this->getDoctrine()->getManager()->flush(); + } + + return $this->json($accompanyingCourse->getIntensity(), Response::HTTP_OK, [], ['groups' => ['read']]); + } + public function workApi($id, Request $request, string $_format): Response { return $this->addRemoveSomething( diff --git a/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php b/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php index 716ef9ee8..b05da5626 100644 --- a/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php +++ b/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php @@ -395,16 +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, - ], - ], + // '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 0012f341d..d75ade12b 100644 --- a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php +++ b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php @@ -30,6 +30,8 @@ use Chill\PersonBundle\Entity\AccompanyingPeriod\Resource; use Chill\PersonBundle\Entity\AccompanyingPeriod\UserHistory; use Chill\PersonBundle\Entity\SocialWork\SocialIssue; use Chill\PersonBundle\Validator\Constraints\AccompanyingPeriod\AccompanyingPeriodValidity; +use Chill\PersonBundle\Validator\Constraints\AccompanyingPeriod\ConfidentialCourseMustHaveReferrer; +use Chill\PersonBundle\Validator\Constraints\AccompanyingPeriod\LocationValidity; use Chill\PersonBundle\Validator\Constraints\AccompanyingPeriod\ParticipationOverlap; use Chill\PersonBundle\Validator\Constraints\AccompanyingPeriod\ResourceDuplicateCheck; use Chill\ThirdPartyBundle\Entity\ThirdParty; @@ -62,12 +64,9 @@ 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}) + * @LocationValidity(groups={AccompanyingPeriod::STEP_DRAFT, AccompanyingPeriod::STEP_CONFIRMED}) + * @ConfidentialCourseMustHaveReferrer(groups={AccompanyingPeriod::STEP_DRAFT, AccompanyingPeriod::STEP_CONFIRMED}) */ class AccompanyingPeriod implements GroupSequenceProviderInterface, @@ -201,7 +200,7 @@ class AccompanyingPeriod implements /** * @var string * @ORM\Column(type="string", nullable=true) - * @Groups({"read", "write"}) + * @Groups({"read"}) * @Assert\NotBlank(groups={AccompanyingPeriod::STEP_CONFIRMED}) */ private $intensity = self::INTENSITY_OCCASIONAL; @@ -1000,7 +999,7 @@ class AccompanyingPeriod implements } /** - * Validation function. + * Validation functions. */ public function isDateConsistent(ExecutionContextInterface $context) { diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/components/Banner/ToggleFlags.vue b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/components/Banner/ToggleFlags.vue index 39fe50acc..a24277fa0 100644 --- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/components/Banner/ToggleFlags.vue +++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/components/Banner/ToggleFlags.vue @@ -58,7 +58,7 @@ export default { this.$store.dispatch('toggleIntensity', value) .catch(({name, violations}) => { if (name === 'ValidationException' || name === 'AccessException') { - violations.forEach((violation) => this.$toast.open({message: violation})); + this.$toast.open({message: this.$t('Only the referrer can toggle the intensity of an accompanying course')}) } else { this.$toast.open({message: 'An error occurred'}) } @@ -75,20 +75,15 @@ export default { }); }, toggleConfidential() { - this.$store.dispatch('fetchPermissions').then(() => { - if (!this.$store.getters.canTogglePermission) { - this.$toast.open({message: "Seul le référent peut modifier la confidentialité"}); - return Promise.resolve(); - } else { - return this.$store.dispatch('toggleConfidential', (!this.isConfidential)); - } - }).catch(({name, violations}) => { - if (name === 'ValidationException' || name === 'AccessException') { - violations.forEach((violation) => this.$toast.open({message: violation})); - } else { - this.$toast.open({message: 'An error occurred'}) - } - }); + this.$store.dispatch('toggleConfidential') + .catch(({name, violations}) => { + console.log(name); + if (name === 'ValidationException' || name === 'AccessException') { + this.$toast.open({message: this.$t('Only the referrer can toggle the confidentiality of an accompanying course')}) + } else { + this.$toast.open({message: 'An error occurred'}) + } + }); }, }, } 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/js/i18n.js b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/js/i18n.js index 49253eab8..5f0321c70 100644 --- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/js/i18n.js +++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/js/i18n.js @@ -167,6 +167,8 @@ const appMessages = { 'Error while retriving users.': "Erreur du serveur lors du chargement de la liste des travailleurs.", 'Error while getting whoami.': "Erreur du serveur lors de la requête 'qui suis-je ?'", 'Error while retriving origin\'s list.': "Erreur du serveur lors du chargement de la liste des origines de la demande.", + 'Only the referrer can toggle the intensity of an accompanying course': "Seul le référent peut modifier l'intensité d'un parcours.", + 'Only the referrer can toggle the confidentiality of an accompanying course': "Seul le référent peut modifier la confidentialité d'un parcours." } }; 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 05960aaea..f7fd59b32 100644 --- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/store/index.js +++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/store/index.js @@ -420,24 +420,24 @@ let initPromise = (root) => Promise.all([getScopesPromise(root), accompanyingCou const url = `/api/1.0/person/accompanying-course/resource/${id}.json`; return makeFetch('PATCH', url, body) - .then((response) => { - commit('patchResource', response); - }) - .catch((error) => { - commit('catchError', error); - throw error; - }) + .then((response) => { + commit('patchResource', response); + }) + .catch((error) => { + commit('catchError', error); + throw error; + }) }, /** * Update accompanying course intensity/emergency/confidentiality */ toggleIntensity({ commit }, payload) { - const url = `/api/1.0/person/accompanying-course/${id}.json` + const url = `/api/1.0/person/accompanying-course/${id}/intensity.json` const body = { type: "accompanying_period", 'intensity': payload } - return makeFetch('PATCH', url, body) + return makeFetch('POST', url, body) .then((response) => { - commit('toggleIntensity', response.intensity); + commit('toggleIntensity', response); }) .catch((error) => { @@ -459,14 +459,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) => { - commit('toggleConfidential', response.confidential); + console.log('response', response); + commit('toggleConfidential', response); }) .catch((error) => { + console.log('error', error) commit('catchError', error); throw error; }) @@ -737,10 +741,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/Resources/public/vuejs/_components/Entity/PersonRenderBox.vue b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/_components/Entity/PersonRenderBox.vue index d87e0f50c..f77f006db 100644 --- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/_components/Entity/PersonRenderBox.vue +++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/_components/Entity/PersonRenderBox.vue @@ -113,15 +113,6 @@

{{ $t('renderbox.no_data') }}

-
  • - - {{ person.email }} -
  • -
  • - -

    {{ $t('renderbox.no_data') }}

    -
  • -
  • diff --git a/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php b/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php index 3915c764a..bf6e6c287 100644 --- a/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php +++ b/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php @@ -33,6 +33,7 @@ class AccompanyingPeriodVoter extends AbstractChillVoter implements ProvideRoleH self::DELETE, self::FULL, self::TOGGLE_CONFIDENTIAL_ALL, + self::TOGGLE_INTENSITY, ]; public const CREATE = 'CHILL_PERSON_ACCOMPANYING_PERIOD_CREATE'; @@ -62,6 +63,11 @@ class AccompanyingPeriodVoter extends AbstractChillVoter implements ProvideRoleH */ public const TOGGLE_CONFIDENTIAL_ALL = 'CHILL_PERSON_ACCOMPANYING_PERIOD_TOGGLE_CONFIDENTIAL_ALL'; + /** + * Right to toggle urgency of parcours. + */ + public const TOGGLE_INTENSITY = 'CHILL_PERSON_ACCOMPANYING_PERIOD_TOGGLE_INTENSITY'; + private Security $security; private VoterHelperInterface $voterHelper; @@ -125,11 +131,20 @@ class AccompanyingPeriodVoter extends AbstractChillVoter implements ProvideRoleH } if (self::TOGGLE_CONFIDENTIAL === $attribute) { - if ($subject->getUser() === $token->getUser()) { + if (null !== $subject->getUser() && ($subject->getUser() === $token->getUser())) { return true; } - return $this->voterHelper->voteOnAttribute(self::TOGGLE_CONFIDENTIAL_ALL, $subject, $token); + return false; + // return $this->voterHelper->voteOnAttribute(self::TOGGLE_CONFIDENTIAL_ALL, $subject, $token); + } + + if (self::TOGGLE_INTENSITY === $attribute) { + if (null !== $subject->getUser() && ($subject->getUser() === $token->getUser())) { + return true; + } + + return false; } // if confidential, only the referent can see it diff --git a/src/Bundle/ChillPersonBundle/Tests/AccompanyingPeriod/AccompanyingPeriodConfidentialTest.php b/src/Bundle/ChillPersonBundle/Tests/AccompanyingPeriod/AccompanyingPeriodConfidentialTest.php index 2dc51335c..37c4ba788 100644 --- a/src/Bundle/ChillPersonBundle/Tests/AccompanyingPeriod/AccompanyingPeriodConfidentialTest.php +++ b/src/Bundle/ChillPersonBundle/Tests/AccompanyingPeriod/AccompanyingPeriodConfidentialTest.php @@ -13,9 +13,7 @@ namespace Chill\PersonBundle\Tests\AccompanyingPeriod; use Chill\MainBundle\Entity\User; use Chill\PersonBundle\Entity\AccompanyingPeriod; -use Chill\PersonBundle\Entity\Person; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; -use Symfony\Component\HttpFoundation\Request; /** * @internal @@ -42,7 +40,7 @@ final class AccompanyingPeriodConfidentialTest extends WebTestCase ]); } - public function dataGenerateRandomAccompanyingCourse() + public function testConfidentialInvalid() { // Disabling this dataprovider to avoid having errors while running the test. return yield from []; @@ -88,10 +86,7 @@ final class AccompanyingPeriodConfidentialTest extends WebTestCase } } - /** - * @dataProvider dataGenerateRandomAccompanyingCourse - */ - public function testRemoveUserWhenConfidential(int $periodId) + public function testConfidentialValid() { $this->markTestIncomplete( 'Marked as incomplete because of a problem in the dataprovider, at line 81.' @@ -101,8 +96,7 @@ final class AccompanyingPeriodConfidentialTest extends WebTestCase ->find($periodId); $em = self::$kernel->getContainer()->get('doctrine.orm.entity_manager'); - $isConfidential = $period->isConfidential(); - $step = $period->getStep(); + $violations = self::$validator->validate($period, null, ['confirmed']); $initialUser = $period->getUser(); diff --git a/src/Bundle/ChillPersonBundle/Validator/Constraints/AccompanyingPeriod/AccompanyingPeriodValidityValidator.php b/src/Bundle/ChillPersonBundle/Validator/Constraints/AccompanyingPeriod/AccompanyingPeriodValidityValidator.php index 0cf75397b..940290315 100644 --- a/src/Bundle/ChillPersonBundle/Validator/Constraints/AccompanyingPeriod/AccompanyingPeriodValidityValidator.php +++ b/src/Bundle/ChillPersonBundle/Validator/Constraints/AccompanyingPeriod/AccompanyingPeriodValidityValidator.php @@ -15,6 +15,7 @@ use Chill\ActivityBundle\Repository\ActivityRepository; use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\SocialWork\SocialIssue; use Chill\PersonBundle\Templating\Entity\SocialIssueRender; +use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; use Symfony\Component\Validator\Exception\UnexpectedTypeException; @@ -28,10 +29,13 @@ class AccompanyingPeriodValidityValidator extends ConstraintValidator private SocialIssueRender $socialIssueRender; - public function __construct(ActivityRepository $activityRepository, SocialIssueRender $socialIssueRender) + private TokenStorageInterface $token; + + public function __construct(ActivityRepository $activityRepository, SocialIssueRender $socialIssueRender, TokenStorageInterface $token) { $this->activityRepository = $activityRepository; $this->socialIssueRender = $socialIssueRender; + $this->token = $token; } public function validate($period, Constraint $constraint) @@ -44,6 +48,7 @@ class AccompanyingPeriodValidityValidator extends ConstraintValidator throw new UnexpectedValueException($period, AccompanyingPeriod::class); } + /** Check if a social issue can be deleted (is not linked to an action or activity within the parcours) */ $socialIssues = []; $activities = $this->activityRepository->findBy(['accompanyingPeriod' => $period]); diff --git a/src/Bundle/ChillPersonBundle/Validator/Constraints/AccompanyingPeriod/ConfidentialCourseMustHaveReferrer.php b/src/Bundle/ChillPersonBundle/Validator/Constraints/AccompanyingPeriod/ConfidentialCourseMustHaveReferrer.php new file mode 100644 index 000000000..c85130f9b --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Validator/Constraints/AccompanyingPeriod/ConfidentialCourseMustHaveReferrer.php @@ -0,0 +1,27 @@ +isConfidential() && null === $value->getUser()) { + $this->context + ->buildViolation($constraint->message) + ->atPath('user') + ->addViolation(); + } + } +} diff --git a/src/Bundle/ChillPersonBundle/chill.api.specs.yaml b/src/Bundle/ChillPersonBundle/chill.api.specs.yaml index cd242e1c0..e6fefa5df 100644 --- a/src/Bundle/ChillPersonBundle/chill.api.specs.yaml +++ b/src/Bundle/ChillPersonBundle/chill.api.specs.yaml @@ -1177,6 +1177,44 @@ paths: 422: description: "object with validation errors" + /1.0/person/accompanying-course/{id}/intensity.json: + post: + tags: + - person + summary: "Toggle intensity status of accompanying course" + parameters: + - name: id + in: path + required: true + description: The accompanying period's id + schema: + type: integer + format: integer + minimum: 1 + requestBody: + description: "Intensity toggle" + required: true + content: + application/json: + schema: + type: object + properties: + type: + type: string + enum: + - "accompanying_period" + intensity: + type: string + responses: + 401: + description: "Unauthorized" + 404: + description: "Not found" + 200: + description: "OK" + 422: + description: "object with validation errors" + /1.0/person/accompanying-course/by-person/{person_id}.json: get: tags: diff --git a/src/Bundle/ChillPersonBundle/translations/validators.fr.yml b/src/Bundle/ChillPersonBundle/translations/validators.fr.yml index c47aee1c5..452365c4c 100644 --- a/src/Bundle/ChillPersonBundle/translations/validators.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/validators.fr.yml @@ -20,6 +20,7 @@ Two addresses has the same validFrom date: La date de validité est identique à The firstname cannot be empty: Le prénom ne peut pas être vide The lastname cannot be empty: Le nom de famille ne peut pas être vide The gender must be set: Le genre doit être renseigné +You are not allowed to perform this action: Vous n'avez pas le droit de changer cette valeur. #export list You must select at least one element: Vous devez sélectionner au moins un élément @@ -51,6 +52,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' +A confidential parcours must have a referrer: 'Un parcours confidentiel doit avoir un référent' +Only the referrer can change the confidentiality of a parcours: '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