mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
Merge branch 'master' of gitlab.com:Chill-Projet/chill-bundles
This commit is contained in:
commit
7b17dc692e
@ -11,6 +11,7 @@ and this project adheres to
|
|||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
<!-- write down unreleased development here -->
|
<!-- write down unreleased development here -->
|
||||||
|
* [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)
|
* [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 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)
|
* [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)
|
* [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)
|
* [bug]: fix confidential toggle of address in thirdpartyrenderbox (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/460)
|
||||||
|
|
||||||
|
|
||||||
## Test releases
|
## Test releases
|
||||||
* Creation of PickCivilityType, and implementation in PersonType and ThirdpartyType
|
* 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
|
### 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)
|
* [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)
|
* [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)
|
* [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)
|
* [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)
|
* 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)
|
* [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
|
* 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
|
* [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
|
* [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
|
## Test releases
|
||||||
|
@ -72,7 +72,7 @@ section.chill-entity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
p {
|
p {
|
||||||
// display: inline-block;
|
display: inline-block;
|
||||||
margin: 0 0 0 1.5em;
|
margin: 0 0 0 1.5em;
|
||||||
text-indent: -1.5em;
|
text-indent: -1.5em;
|
||||||
|
|
||||||
|
@ -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: {
|
||||||
@ -11,19 +11,20 @@
|
|||||||
})
|
})
|
||||||
.then(response => {
|
.then(response => {
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
|
console.log('200 error')
|
||||||
return response.json();
|
return response.json();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response.status === 422) {
|
if (response.status === 422) {
|
||||||
|
console.log('422 error')
|
||||||
return response.json().then(response => {
|
return response.json().then(response => {
|
||||||
throw ValidationException(response)
|
throw ValidationException(response)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response.status === 403) {
|
if (response.status === 403) {
|
||||||
return response.json().then(() => {
|
console.log('403 error')
|
||||||
throw AccessException();
|
throw AccessException(response);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
throw {
|
throw {
|
||||||
@ -88,14 +89,13 @@ const ValidationException = (response) => {
|
|||||||
error.violations = response.violations.map((violation) => `${violation.title}: ${violation.propertyPath}`);
|
error.violations = response.violations.map((violation) => `${violation.title}: ${violation.propertyPath}`);
|
||||||
error.titles = response.violations.map((violation) => violation.title);
|
error.titles = response.violations.map((violation) => violation.title);
|
||||||
error.propertyPaths = response.violations.map((violation) => violation.propertyPath);
|
error.propertyPaths = response.violations.map((violation) => violation.propertyPath);
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
const AccessException = () => {
|
const AccessException = (response) => {
|
||||||
const error = {};
|
const error = {};
|
||||||
error.name = 'AccessException';
|
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;
|
return error;
|
||||||
}
|
}
|
||||||
|
@ -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")
|
* @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"})
|
||||||
|
*
|
||||||
|
* @param mixed $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);
|
||||||
|
|
||||||
$accompanyingCourse->setConfidential(!$accompanyingCourse->isConfidential());
|
$accompanyingCourse->setConfidential(!$accompanyingCourse->isConfidential());
|
||||||
|
|
||||||
$this->getDoctrine()->getManager()->flush();
|
$this->getDoctrine()->getManager()->flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->json($accompanyingCourse->isConfidential(), Response::HTTP_OK, [], ['groups' => ['read']]);
|
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
|
public function workApi($id, Request $request, string $_format): Response
|
||||||
{
|
{
|
||||||
return $this->addRemoveSomething(
|
return $this->addRemoveSomething(
|
||||||
|
@ -395,16 +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,
|
||||||
],
|
// ],
|
||||||
],
|
// ],
|
||||||
'findAccompanyingPeriodsByPerson' => [
|
'findAccompanyingPeriodsByPerson' => [
|
||||||
'path' => '/by-person/{person_id}.{_format}',
|
'path' => '/by-person/{person_id}.{_format}',
|
||||||
'controller_action' => 'getAccompanyingPeriodsByPerson',
|
'controller_action' => 'getAccompanyingPeriodsByPerson',
|
||||||
|
@ -30,6 +30,8 @@ use Chill\PersonBundle\Entity\AccompanyingPeriod\Resource;
|
|||||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\UserHistory;
|
use Chill\PersonBundle\Entity\AccompanyingPeriod\UserHistory;
|
||||||
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
|
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
|
||||||
use Chill\PersonBundle\Validator\Constraints\AccompanyingPeriod\AccompanyingPeriodValidity;
|
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\ParticipationOverlap;
|
||||||
use Chill\PersonBundle\Validator\Constraints\AccompanyingPeriod\ResourceDuplicateCheck;
|
use Chill\PersonBundle\Validator\Constraints\AccompanyingPeriod\ResourceDuplicateCheck;
|
||||||
use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
||||||
@ -62,12 +64,9 @@ 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})
|
||||||
|
* @LocationValidity(groups={AccompanyingPeriod::STEP_DRAFT, AccompanyingPeriod::STEP_CONFIRMED})
|
||||||
|
* @ConfidentialCourseMustHaveReferrer(groups={AccompanyingPeriod::STEP_DRAFT, AccompanyingPeriod::STEP_CONFIRMED})
|
||||||
*/
|
*/
|
||||||
class AccompanyingPeriod implements
|
class AccompanyingPeriod implements
|
||||||
GroupSequenceProviderInterface,
|
GroupSequenceProviderInterface,
|
||||||
@ -201,7 +200,7 @@ class AccompanyingPeriod implements
|
|||||||
/**
|
/**
|
||||||
* @var string
|
* @var string
|
||||||
* @ORM\Column(type="string", nullable=true)
|
* @ORM\Column(type="string", nullable=true)
|
||||||
* @Groups({"read", "write"})
|
* @Groups({"read"})
|
||||||
* @Assert\NotBlank(groups={AccompanyingPeriod::STEP_CONFIRMED})
|
* @Assert\NotBlank(groups={AccompanyingPeriod::STEP_CONFIRMED})
|
||||||
*/
|
*/
|
||||||
private $intensity = self::INTENSITY_OCCASIONAL;
|
private $intensity = self::INTENSITY_OCCASIONAL;
|
||||||
@ -1000,7 +999,7 @@ class AccompanyingPeriod implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validation function.
|
* Validation functions.
|
||||||
*/
|
*/
|
||||||
public function isDateConsistent(ExecutionContextInterface $context)
|
public function isDateConsistent(ExecutionContextInterface $context)
|
||||||
{
|
{
|
||||||
|
@ -58,7 +58,7 @@ export default {
|
|||||||
this.$store.dispatch('toggleIntensity', value)
|
this.$store.dispatch('toggleIntensity', value)
|
||||||
.catch(({name, violations}) => {
|
.catch(({name, violations}) => {
|
||||||
if (name === 'ValidationException' || name === 'AccessException') {
|
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 {
|
} else {
|
||||||
this.$toast.open({message: 'An error occurred'})
|
this.$toast.open({message: 'An error occurred'})
|
||||||
}
|
}
|
||||||
@ -75,16 +75,11 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
toggleConfidential() {
|
toggleConfidential() {
|
||||||
this.$store.dispatch('fetchPermissions').then(() => {
|
this.$store.dispatch('toggleConfidential')
|
||||||
if (!this.$store.getters.canTogglePermission) {
|
.catch(({name, violations}) => {
|
||||||
this.$toast.open({message: "Seul le référent peut modifier la confidentialité"});
|
console.log(name);
|
||||||
return Promise.resolve();
|
|
||||||
} else {
|
|
||||||
return this.$store.dispatch('toggleConfidential', (!this.isConfidential));
|
|
||||||
}
|
|
||||||
}).catch(({name, violations}) => {
|
|
||||||
if (name === 'ValidationException' || name === 'AccessException') {
|
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 confidentiality of an accompanying course')})
|
||||||
} else {
|
} else {
|
||||||
this.$toast.open({message: 'An error occurred'})
|
this.$toast.open({message: 'An error occurred'})
|
||||||
}
|
}
|
||||||
|
@ -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');
|
||||||
});
|
});
|
||||||
|
@ -167,6 +167,8 @@ const appMessages = {
|
|||||||
'Error while retriving users.': "Erreur du serveur lors du chargement de la liste des travailleurs.",
|
'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 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.",
|
'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."
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -432,12 +432,12 @@ let initPromise = (root) => Promise.all([getScopesPromise(root), accompanyingCou
|
|||||||
* Update accompanying course intensity/emergency/confidentiality
|
* Update accompanying course intensity/emergency/confidentiality
|
||||||
*/
|
*/
|
||||||
toggleIntensity({ commit }, payload) {
|
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 }
|
const body = { type: "accompanying_period", 'intensity': payload }
|
||||||
|
|
||||||
return makeFetch('PATCH', url, body)
|
return makeFetch('POST', url, body)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
commit('toggleIntensity', response.intensity);
|
commit('toggleIntensity', response);
|
||||||
|
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
@ -459,14 +459,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) => {
|
||||||
commit('toggleConfidential', response.confidential);
|
console.log('response', response);
|
||||||
|
commit('toggleConfidential', response);
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
|
console.log('error', error)
|
||||||
commit('catchError', error);
|
commit('catchError', error);
|
||||||
throw error;
|
throw error;
|
||||||
})
|
})
|
||||||
|
@ -113,15 +113,6 @@
|
|||||||
<p class="chill-no-data-statement">{{ $t('renderbox.no_data') }}</p>
|
<p class="chill-no-data-statement">{{ $t('renderbox.no_data') }}</p>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li v-if="person.email">
|
|
||||||
<i class="fa fa-li fa-envelope-o"></i>
|
|
||||||
<a :href="'mailto: ' + person.email">{{ person.email }}</a>
|
|
||||||
</li>
|
|
||||||
<li v-else-if="options.addNoData">
|
|
||||||
<i class="fa fa-li fa-envelope-o"></i>
|
|
||||||
<p class="chill-no-data-statement">{{ $t('renderbox.no_data') }}</p>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li v-if="person.centers !== undefined && person.centers.length > 0 && options.addCenter">
|
<li v-if="person.centers !== undefined && person.centers.length > 0 && options.addCenter">
|
||||||
<i class="fa fa-li fa-long-arrow-right"></i>
|
<i class="fa fa-li fa-long-arrow-right"></i>
|
||||||
<template v-for="c in person.centers">{{ c.name }}</template>
|
<template v-for="c in person.centers">{{ c.name }}</template>
|
||||||
|
@ -33,6 +33,7 @@ class AccompanyingPeriodVoter extends AbstractChillVoter implements ProvideRoleH
|
|||||||
self::DELETE,
|
self::DELETE,
|
||||||
self::FULL,
|
self::FULL,
|
||||||
self::TOGGLE_CONFIDENTIAL_ALL,
|
self::TOGGLE_CONFIDENTIAL_ALL,
|
||||||
|
self::TOGGLE_INTENSITY,
|
||||||
];
|
];
|
||||||
|
|
||||||
public const CREATE = 'CHILL_PERSON_ACCOMPANYING_PERIOD_CREATE';
|
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';
|
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 Security $security;
|
||||||
|
|
||||||
private VoterHelperInterface $voterHelper;
|
private VoterHelperInterface $voterHelper;
|
||||||
@ -125,11 +131,20 @@ class AccompanyingPeriodVoter extends AbstractChillVoter implements ProvideRoleH
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (self::TOGGLE_CONFIDENTIAL === $attribute) {
|
if (self::TOGGLE_CONFIDENTIAL === $attribute) {
|
||||||
if ($subject->getUser() === $token->getUser()) {
|
if (null !== $subject->getUser() && ($subject->getUser() === $token->getUser())) {
|
||||||
return true;
|
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
|
// if confidential, only the referent can see it
|
||||||
|
@ -13,9 +13,7 @@ namespace Chill\PersonBundle\Tests\AccompanyingPeriod;
|
|||||||
|
|
||||||
use Chill\MainBundle\Entity\User;
|
use Chill\MainBundle\Entity\User;
|
||||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||||
use Chill\PersonBundle\Entity\Person;
|
|
||||||
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
|
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @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.
|
// Disabling this dataprovider to avoid having errors while running the test.
|
||||||
return yield from [];
|
return yield from [];
|
||||||
@ -88,10 +86,7 @@ final class AccompanyingPeriodConfidentialTest extends WebTestCase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function testConfidentialValid()
|
||||||
* @dataProvider dataGenerateRandomAccompanyingCourse
|
|
||||||
*/
|
|
||||||
public function testRemoveUserWhenConfidential(int $periodId)
|
|
||||||
{
|
{
|
||||||
$this->markTestIncomplete(
|
$this->markTestIncomplete(
|
||||||
'Marked as incomplete because of a problem in the dataprovider, at line 81.'
|
'Marked as incomplete because of a problem in the dataprovider, at line 81.'
|
||||||
@ -101,8 +96,7 @@ final class AccompanyingPeriodConfidentialTest extends WebTestCase
|
|||||||
->find($periodId);
|
->find($periodId);
|
||||||
$em = self::$kernel->getContainer()->get('doctrine.orm.entity_manager');
|
$em = self::$kernel->getContainer()->get('doctrine.orm.entity_manager');
|
||||||
|
|
||||||
$isConfidential = $period->isConfidential();
|
$violations = self::$validator->validate($period, null, ['confirmed']);
|
||||||
$step = $period->getStep();
|
|
||||||
|
|
||||||
$initialUser = $period->getUser();
|
$initialUser = $period->getUser();
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ use Chill\ActivityBundle\Repository\ActivityRepository;
|
|||||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||||
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
|
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
|
||||||
use Chill\PersonBundle\Templating\Entity\SocialIssueRender;
|
use Chill\PersonBundle\Templating\Entity\SocialIssueRender;
|
||||||
|
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
|
||||||
use Symfony\Component\Validator\Constraint;
|
use Symfony\Component\Validator\Constraint;
|
||||||
use Symfony\Component\Validator\ConstraintValidator;
|
use Symfony\Component\Validator\ConstraintValidator;
|
||||||
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
|
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
|
||||||
@ -28,10 +29,13 @@ class AccompanyingPeriodValidityValidator extends ConstraintValidator
|
|||||||
|
|
||||||
private SocialIssueRender $socialIssueRender;
|
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->activityRepository = $activityRepository;
|
||||||
$this->socialIssueRender = $socialIssueRender;
|
$this->socialIssueRender = $socialIssueRender;
|
||||||
|
$this->token = $token;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function validate($period, Constraint $constraint)
|
public function validate($period, Constraint $constraint)
|
||||||
@ -44,6 +48,7 @@ class AccompanyingPeriodValidityValidator extends ConstraintValidator
|
|||||||
throw new UnexpectedValueException($period, AccompanyingPeriod::class);
|
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 = [];
|
$socialIssues = [];
|
||||||
|
|
||||||
$activities = $this->activityRepository->findBy(['accompanyingPeriod' => $period]);
|
$activities = $this->activityRepository->findBy(['accompanyingPeriod' => $period]);
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Chill is a software for social workers
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view
|
||||||
|
* the LICENSE file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Chill\PersonBundle\Validator\Constraints\AccompanyingPeriod;
|
||||||
|
|
||||||
|
use Symfony\Component\Validator\Constraint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Annotation
|
||||||
|
*/
|
||||||
|
class ConfidentialCourseMustHaveReferrer extends Constraint
|
||||||
|
{
|
||||||
|
public string $message = 'A confidential parcours must have a referrer';
|
||||||
|
|
||||||
|
public function getTargets()
|
||||||
|
{
|
||||||
|
return [self::CLASS_CONSTRAINT];
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Chill\PersonBundle\Validator\Constraints\AccompanyingPeriod;
|
||||||
|
|
||||||
|
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||||
|
use Symfony\Component\Validator\Constraint;
|
||||||
|
use Symfony\Component\Validator\ConstraintValidator;
|
||||||
|
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
|
||||||
|
|
||||||
|
class ConfidentialCourseMustHaveReferrerValidator extends ConstraintValidator
|
||||||
|
{
|
||||||
|
public function validate($value, Constraint $constraint)
|
||||||
|
{
|
||||||
|
if (!$value instanceof AccompanyingPeriod) {
|
||||||
|
throw new UnexpectedTypeException($value, AccompanyingPeriod::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$constraint instanceof ConfidentialCourseMustHaveReferrer) {
|
||||||
|
throw new UnexpectedTypeException($constraint, ConfidentialCourseMustHaveReferrer::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($value->isConfidential() && null === $value->getUser()) {
|
||||||
|
$this->context
|
||||||
|
->buildViolation($constraint->message)
|
||||||
|
->atPath('user')
|
||||||
|
->addViolation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1177,6 +1177,44 @@ paths:
|
|||||||
422:
|
422:
|
||||||
description: "object with validation errors"
|
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:
|
/1.0/person/accompanying-course/by-person/{person_id}.json:
|
||||||
get:
|
get:
|
||||||
tags:
|
tags:
|
||||||
|
@ -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 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 lastname cannot be empty: Le nom de famille ne peut pas être vide
|
||||||
The gender must be set: Le genre doit être renseigné
|
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
|
#export list
|
||||||
You must select at least one element: Vous devez sélectionner au moins un élément
|
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 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'
|
||||||
|
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
|
# 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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user