This commit is contained in:
Julie Lenaerts 2022-02-14 18:00:09 +01:00
parent df61fbff12
commit 8ee451c6e0
8 changed files with 56 additions and 59 deletions

View File

@ -1,7 +1,7 @@
/** /**
* Generic api method that can be adapted to any fetch request * Generic api method that can be adapted to any fetch request
*/ */
const makeFetch = (method, url, body) => { const makeFetch = (method, url, body) => {
return fetch(url, { return fetch(url, {
method: method, method: method,
headers: { headers: {

View File

@ -60,6 +60,7 @@ class UserRefEventSubscriber implements EventSubscriberInterface
{ {
if ($period->hasPreviousUser() if ($period->hasPreviousUser()
&& $period->getUser() !== $this->security->getUser() && $period->getUser() !== $this->security->getUser()
&& $period->getUser() !== null
&& $period->getStep() !== AccompanyingPeriod::STEP_DRAFT && $period->getStep() !== AccompanyingPeriod::STEP_DRAFT
) { ) {
$this->generateNotificationToUser($period); $this->generateNotificationToUser($period);

View File

@ -31,6 +31,7 @@ use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
use Chill\ThirdPartyBundle\Entity\ThirdParty; use Chill\ThirdPartyBundle\Entity\ThirdParty;
use DateInterval; use DateInterval;
use DateTimeImmutable; use DateTimeImmutable;
use JsonSchema\Exception\ValidationException;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Exception\BadRequestException; 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") * @Route("/api/1.0/person/accompanying-course/{id}/confidential.json", name="chill_api_person_accompanying_period_confidential")
* @ParamConverter("accompanyingCourse", options={"id": "id"}) * @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); $this->denyAccessUnlessGranted(AccompanyingPeriodVoter::TOGGLE_CONFIDENTIAL, $accompanyingCourse);
if (null != $accompanyingCourse->getUser() && $this->getUser() == $accompanyingCourse->getUser()) {
$accompanyingCourse->setConfidential(!$accompanyingCourse->isConfidential()); $accompanyingCourse->setConfidential(!$accompanyingCourse->isConfidential());
$this->getDoctrine()->getManager()->flush(); $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']]); return $this->json($accompanyingCourse->isConfidential(), Response::HTTP_OK, [], ['groups' => ['read']]);

View File

@ -395,26 +395,16 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
Request::METHOD_POST => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE, Request::METHOD_POST => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE,
], ],
], ],
'confidential' => [ // 'confidential' => [
'methods' => [ // 'methods' => [
Request::METHOD_POST => true, // Request::METHOD_POST => true,
Request::METHOD_GET => true, // Request::METHOD_GET => true,
], // ],
'controller_action' => 'toggleConfidentialApi', // 'controller_action' => 'toggleConfidentialApi',
'roles' => [ // 'roles' => [
Request::METHOD_POST => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::TOGGLE_CONFIDENTIAL, // 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,
],
],
'findAccompanyingPeriodsByPerson' => [ 'findAccompanyingPeriodsByPerson' => [
'path' => '/by-person/{person_id}.{_format}', 'path' => '/by-person/{person_id}.{_format}',
'controller_action' => 'getAccompanyingPeriodsByPerson', 'controller_action' => 'getAccompanyingPeriodsByPerson',

View File

@ -38,6 +38,7 @@ use DateTimeInterface;
use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection; use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
use JsonSchema\Exception\ValidationException;
use LogicException; use LogicException;
use Symfony\Component\Serializer\Annotation\DiscriminatorMap; use Symfony\Component\Serializer\Annotation\DiscriminatorMap;
use Symfony\Component\Serializer\Annotation\Groups; use Symfony\Component\Serializer\Annotation\Groups;
@ -59,11 +60,6 @@ use const SORT_REGULAR;
* "accompanying_period": AccompanyingPeriod::class * "accompanying_period": AccompanyingPeriod::class
* }) * })
* @Assert\GroupSequenceProvider * @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}) * @AccompanyingPeriodValidity(groups={AccompanyingPeriod::STEP_DRAFT, AccompanyingPeriod::STEP_CONFIRMED})
*/ */
class AccompanyingPeriod implements class AccompanyingPeriod implements
@ -340,6 +336,9 @@ class AccompanyingPeriod implements
* @ORM\ManyToOne(targetEntity=User::class) * @ORM\ManyToOne(targetEntity=User::class)
* @ORM\JoinColumn(nullable=true) * @ORM\JoinColumn(nullable=true)
* @Groups({"read", "write", "docgen:read"}) * @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; private ?User $user = null;
@ -500,20 +499,6 @@ class AccompanyingPeriod implements
return end($periods) === $this; 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. * Close a participation for a person.
* *

View File

@ -46,6 +46,12 @@ if (root === 'banner') {
}) })
.use(store) .use(store)
.use(i18n) .use(i18n)
.use(VueToast, {
position: "bottom-right",
type: "error",
duration: 5000,
dismissible: true
})
.component('banner', Banner) .component('banner', Banner)
.mount('#banner-accompanying-course'); .mount('#banner-accompanying-course');
}); });

View File

@ -495,14 +495,18 @@ let initPromise = (root) => Promise.all([getScopesPromise(root), accompanyingCou
}) })
}, },
toggleConfidential({ commit }, payload) { 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 } 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) => { .then((response) => {
console.log('response', response);
commit('toggleConfidential', response); commit('toggleConfidential', response);
}) })
.catch((error) => { .catch((error) => {
console.log('error', error)
commit('catchError', error); commit('catchError', error);
throw error; throw error;
}) })

View File

@ -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 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' 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' 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 # resource
You must associate at least one entity: Associez un usager, un tiers ou indiquez une description libre You must associate at least one entity: Associez un usager, un tiers ou indiquez une description libre