diff --git a/CHANGELOG.md b/CHANGELOG.md index e26c866f8..312c86971 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,10 +12,8 @@ and this project adheres to * [main] avoid address reference search on undefined post code (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/561) +* [person] prevent duplicate relationship in filiation/household graph (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/560) * [Documents] Validate storedObject and allow for null data (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/565) -* [Activity form] invert 'incoming' and 'receiving' in Activity form -* [Activity form] keep the same order for 'attendee' field in new and edit form -* [list with period] use "sameas" test operator to introduce requestor in list ## Test releases diff --git a/phpstan-critical.neon b/phpstan-critical.neon index 262d3012f..1dc516834 100644 --- a/phpstan-critical.neon +++ b/phpstan-critical.neon @@ -5,11 +5,6 @@ parameters: count: 1 path: src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php - - - message: "#^Access to an undefined property Chill\\\\PersonBundle\\\\Entity\\\\Person\\:\\:\\$currentHouseholdParticipationAt\\.$#" - count: 3 - path: src/Bundle/ChillPersonBundle/Entity/Person.php - - message: "#^Access to an undefined property Chill\\\\PersonBundle\\\\Entity\\\\Household\\\\PersonHouseholdAddress\\:\\:\\$relation\\.$#" count: 1 diff --git a/phpstan.neon.dist b/phpstan.neon.dist index edec00554..3322f9539 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -3,6 +3,7 @@ parameters: paths: - src/ excludePaths: + - .php_cs* - docs/ - src/Bundle/*/Tests/* - src/Bundle/*/tests/* diff --git a/src/Bundle/ChillMainBundle/CRUD/Controller/ApiController.php b/src/Bundle/ChillMainBundle/CRUD/Controller/ApiController.php index a780af78a..9bf43b37e 100644 --- a/src/Bundle/ChillMainBundle/CRUD/Controller/ApiController.php +++ b/src/Bundle/ChillMainBundle/CRUD/Controller/ApiController.php @@ -16,9 +16,9 @@ use Chill\MainBundle\Serializer\Model\Collection; use Exception; use LogicException; use RuntimeException; -use Symfony\Component\HttpFoundation\Exception\BadRequestException; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\Serializer\Exception\NotEncodableValueException; use Symfony\Component\Serializer\Normalizer\AbstractNormalizer; use Symfony\Component\Serializer\SerializerInterface; @@ -55,7 +55,7 @@ class ApiController extends AbstractCRUDController return $this->entityDelete('_entity', $request, $id, $_format); default: - throw new \Symfony\Component\HttpFoundation\Exception\BadRequestException('This method is not implemented'); + throw new BadRequestHttpException('This method is not implemented'); } } @@ -120,7 +120,7 @@ class ApiController extends AbstractCRUDController return $this->entityPostAction('_entity', $request, $_format); default: - throw new \Symfony\Component\HttpFoundation\Exception\BadRequestException('This method is not implemented'); + throw new BadRequestHttpException('This method is not implemented'); } } @@ -160,7 +160,7 @@ class ApiController extends AbstractCRUDController try { $entity = $this->deserialize($action, $request, $_format, $entity); } catch (NotEncodableValueException $e) { - throw new BadRequestException('invalid json', 400, $e); + throw new BadRequestHttpException('invalid json', 400, $e); } $errors = $this->validate($action, $request, $_format, $entity); @@ -273,7 +273,7 @@ class ApiController extends AbstractCRUDController try { $postedData = $this->getSerializer()->deserialize($request->getContent(), $postedDataType, $_format, $postedDataContext); } catch (\Symfony\Component\Serializer\Exception\UnexpectedValueException $e) { - throw new BadRequestException(sprintf('Unable to deserialize posted ' . + throw new BadRequestHttpException(sprintf('Unable to deserialize posted ' . 'data: %s', $e->getMessage()), 0, $e); } @@ -290,7 +290,7 @@ class ApiController extends AbstractCRUDController break; default: - throw new BadRequestException('this method is not supported'); + throw new BadRequestHttpException('this method is not supported'); } $errors = $this->validate($action, $request, $_format, $entity, [$postedData]); @@ -408,7 +408,7 @@ class ApiController extends AbstractCRUDController return $this->json($entity, Response::HTTP_OK, [], $context); } - throw new \Symfony\Component\HttpFoundation\Exception\BadRequestException('This format is not implemented'); + throw new BadRequestHttpException('This format is not implemented'); } protected function entityPostAction($action, Request $request, string $_format): Response @@ -418,7 +418,7 @@ class ApiController extends AbstractCRUDController try { $entity = $this->deserialize($action, $request, $_format, $entity); } catch (NotEncodableValueException $e) { - throw new BadRequestException('invalid json', 400, $e); + throw new BadRequestHttpException('invalid json', 400, $e); } $errors = $this->validate($action, $request, $_format, $entity); diff --git a/src/Bundle/ChillMainBundle/CRUD/Controller/CRUDController.php b/src/Bundle/ChillMainBundle/CRUD/Controller/CRUDController.php index 62d587ab3..edca07b41 100644 --- a/src/Bundle/ChillMainBundle/CRUD/Controller/CRUDController.php +++ b/src/Bundle/ChillMainBundle/CRUD/Controller/CRUDController.php @@ -25,6 +25,7 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\Form\FormInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\Security\Core\Role\Role; use Symfony\Component\Serializer\SerializerInterface; use Symfony\Contracts\Translation\TranslatorInterface; @@ -1140,6 +1141,6 @@ class CRUDController extends AbstractController return $this->json($entity, Response::HTTP_OK, [], $context); } - throw new \Symfony\Component\HttpFoundation\Exception\BadRequestException('This format is not implemented'); + throw new BadRequestHttpException('This format is not implemented'); } } diff --git a/src/Bundle/ChillMainBundle/Controller/SearchController.php b/src/Bundle/ChillMainBundle/Controller/SearchController.php index 41349336a..496538665 100644 --- a/src/Bundle/ChillMainBundle/Controller/SearchController.php +++ b/src/Bundle/ChillMainBundle/Controller/SearchController.php @@ -22,7 +22,6 @@ use Chill\MainBundle\Search\UnknowSearchNameException; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\Form\Extension\Core\Type\FormType; use Symfony\Component\Form\Extension\Core\Type\SubmitType; -use Symfony\Component\HttpFoundation\Exception\BadRequestException; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; @@ -216,7 +215,7 @@ class SearchController extends AbstractController $types = $request->query->get('type', []); if (count($types) === 0) { - throw new BadRequestException('The request must contains at ' + throw new BadRequestHttpException('The request must contains at ' . ' one type'); } diff --git a/src/Bundle/ChillMainBundle/Controller/WorkflowController.php b/src/Bundle/ChillMainBundle/Controller/WorkflowController.php index 103de6d84..2803ff254 100644 --- a/src/Bundle/ChillMainBundle/Controller/WorkflowController.php +++ b/src/Bundle/ChillMainBundle/Controller/WorkflowController.php @@ -25,7 +25,6 @@ use Doctrine\ORM\EntityManagerInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\Form\Extension\Core\Type\FormType; use Symfony\Component\Form\Extension\Core\Type\SubmitType; -use Symfony\Component\HttpFoundation\Exception\BadRequestException; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; @@ -144,7 +143,7 @@ class WorkflowController extends AbstractController public function getAccessByAccessKey(EntityWorkflowStep $entityWorkflowStep, Request $request): Response { if (null === $accessKey = $request->query->get('accessKey', null)) { - throw new BadRequestException('accessKey is missing'); + throw new BadRequestHttpException('accessKey is missing'); } if (!$this->getUser() instanceof User) { diff --git a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseApiController.php b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseApiController.php index f1306640b..21db6b00c 100644 --- a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseApiController.php +++ b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseApiController.php @@ -33,10 +33,10 @@ use DateInterval; use DateTimeImmutable; use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; use Symfony\Component\EventDispatcher\EventDispatcherInterface; -use Symfony\Component\HttpFoundation\Exception\BadRequestException; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Security\Core\Exception\AccessDeniedException; use Symfony\Component\Serializer\Exception\RuntimeException; @@ -185,7 +185,7 @@ final class AccompanyingCourseApiController extends ApiController ->deserialize($request->getContent(), Person::class, $_format, []); if (null === $person) { - throw new BadRequestException('person id not found'); + throw new BadRequestHttpException('person id not found'); } // TODO add acl @@ -204,7 +204,7 @@ final class AccompanyingCourseApiController extends ApiController break; default: - throw new BadRequestException('This method is not supported'); + throw new BadRequestHttpException('This method is not supported'); } $errors = $this->validator->validate($accompanyingPeriod); @@ -247,12 +247,12 @@ final class AccompanyingCourseApiController extends ApiController } if (null === $requestor) { - throw new BadRequestException('Could not find any person or thirdparty', 0, null); + throw new BadRequestHttpException('Could not find any person or thirdparty', 0, null); } $accompanyingPeriod->setRequestor($requestor); } else { - throw new BadRequestException('method not supported'); + throw new BadRequestHttpException('method not supported'); } $errors = $this->validator->validate($accompanyingPeriod); diff --git a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php index b15f8adb9..4d78bb42b 100644 --- a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php +++ b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php @@ -21,9 +21,9 @@ use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter; use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Symfony\Component\Form\Extension\Core\Type\SubmitType; -use Symfony\Component\HttpFoundation\Exception\BadRequestException; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Serializer\SerializerInterface; use Symfony\Component\Validator\ConstraintViolationInterface; @@ -255,7 +255,7 @@ class AccompanyingCourseController extends Controller $personIds = $request->query->get('person_id'); if (false === is_array($personIds)) { - throw new BadRequestException('person_id parameter should be an array'); + throw new BadRequestHttpException('person_id parameter should be an array'); } foreach ($personIds as $personId) { diff --git a/src/Bundle/ChillPersonBundle/Controller/HouseholdController.php b/src/Bundle/ChillPersonBundle/Controller/HouseholdController.php index 7b6dc201e..503867a3e 100644 --- a/src/Bundle/ChillPersonBundle/Controller/HouseholdController.php +++ b/src/Bundle/ChillPersonBundle/Controller/HouseholdController.php @@ -21,8 +21,8 @@ use Chill\PersonBundle\Security\Authorization\HouseholdVoter; use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\Form\FormInterface; -use Symfony\Component\HttpFoundation\Exception\BadRequestException; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Security\Core\Security; use Symfony\Component\Serializer\Normalizer\AbstractNormalizer; @@ -202,7 +202,7 @@ class HouseholdController extends AbstractController $this->denyAccessUnlessGranted(HouseholdVoter::EDIT, $household); if (!$request->query->has('address_id')) { - throw new BadRequestException('parameter address_id is missing'); + throw new BadRequestHttpException('parameter address_id is missing'); } $address_id = $request->query->getInt('address_id'); @@ -218,7 +218,7 @@ class HouseholdController extends AbstractController } if (null === $address) { - throw new BadRequestException('The edited address does not belongs to the household'); + throw new BadRequestHttpException('The edited address does not belongs to the household'); } $form = $this->createForm(AddressDateType::class, $address, []); diff --git a/src/Bundle/ChillPersonBundle/Controller/HouseholdMemberController.php b/src/Bundle/ChillPersonBundle/Controller/HouseholdMemberController.php index 2ec72a786..cacba0630 100644 --- a/src/Bundle/ChillPersonBundle/Controller/HouseholdMemberController.php +++ b/src/Bundle/ChillPersonBundle/Controller/HouseholdMemberController.php @@ -20,9 +20,9 @@ use Chill\PersonBundle\Form\HouseholdMemberType; use Chill\PersonBundle\Household\MembersEditor; use Chill\PersonBundle\Repository\AccompanyingPeriodRepository; use Chill\PersonBundle\Security\Authorization\PersonVoter; -use Symfony\Component\HttpFoundation\Exception\BadRequestException; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Symfony\Component\Serializer\Exception; @@ -105,7 +105,7 @@ class HouseholdMemberController extends ApiController $ids = $request->query->get('persons', []); if (0 === count($ids)) { - throw new BadRequestException('parameters persons in query ' . + throw new BadRequestHttpException('parameters persons in query ' . 'is not an array or empty'); } @@ -121,7 +121,8 @@ class HouseholdMemberController extends ApiController } } - if ($householdId = $request->query->get('household', false)) { + if ($request->query->has('household')) { + $householdId = $request->query->get('household', false); $household = $em->getRepository(Household::class) ->find($householdId); $allowHouseholdCreate = false; @@ -189,7 +190,7 @@ class HouseholdMemberController extends ApiController ['groups' => ['read']] ); } catch (Exception\InvalidArgumentException|Exception\UnexpectedValueException $e) { - throw new BadRequestException("Deserialization error: {$e->getMessage()}", 45896, $e); + throw new BadRequestHttpException("Deserialization error: {$e->getMessage()}", 45896, $e); } // TODO ACL diff --git a/src/Bundle/ChillPersonBundle/Entity/Person.php b/src/Bundle/ChillPersonBundle/Entity/Person.php index ef522f068..7f2630a1e 100644 --- a/src/Bundle/ChillPersonBundle/Entity/Person.php +++ b/src/Bundle/ChillPersonBundle/Entity/Person.php @@ -240,6 +240,11 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI */ private array $currentHouseholdAt = []; + /** + * Cache for the computation of current household participation. + */ + private array $currentHouseholdParticipationAt = []; + /** * The current person address. * diff --git a/src/Bundle/ChillPersonBundle/Entity/Relationships/Relationship.php b/src/Bundle/ChillPersonBundle/Entity/Relationships/Relationship.php index d51881bb2..62fbb63a9 100644 --- a/src/Bundle/ChillPersonBundle/Entity/Relationships/Relationship.php +++ b/src/Bundle/ChillPersonBundle/Entity/Relationships/Relationship.php @@ -15,6 +15,7 @@ use Chill\MainBundle\Doctrine\Model\TrackCreationInterface; use Chill\MainBundle\Doctrine\Model\TrackUpdateInterface; use Chill\MainBundle\Entity\User; use Chill\PersonBundle\Entity\Person; +use Chill\PersonBundle\Validator\Constraints\Relationship\RelationshipNoDuplicate; use DateTimeImmutable; use DateTimeInterface; use Doctrine\ORM\Mapping as ORM; @@ -31,6 +32,7 @@ use Symfony\Component\Validator\Constraints as Assert; * @DiscriminatorMap(typeProperty="type", mapping={ * "relationship": Relationship::class * }) + * @RelationshipNoDuplicate */ class Relationship implements TrackCreationInterface, TrackUpdateInterface { diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/VisGraph/App.vue b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/VisGraph/App.vue index f5db187b9..f86c68576 100644 --- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/VisGraph/App.vue +++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/VisGraph/App.vue @@ -472,15 +472,25 @@ export default { case 'create': return postRelationship(this.modal.data) - .then(relationship => new Promise(resolve => { - //console.log('post relationship response', relationship) - this.$store.dispatch('addLinkFromRelationship', relationship) - this.modal.showModal = false - this.resetForm() - this.forceUpdateComponent() - resolve() - })) - .catch() + .then(relationship => new Promise(resolve => { + //console.log('post relationship response', relationship) + this.$store.dispatch('addLinkFromRelationship', relationship) + this.modal.showModal = false + this.resetForm() + this.forceUpdateComponent() + resolve() + })) + .catch( error => { + if (error.name === 'ValidationException') { + for (let v of error.violations) { + this.$toast.open({message: v }); + console.log(v) + } + } else { + this.$toast.open({message: 'An error occurred'}); + } + } + ) case 'edit': return patchRelationship(this.modal.data) diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/VisGraph/api.js b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/VisGraph/api.js index 448ff6633..01c335436 100644 --- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/VisGraph/api.js +++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/VisGraph/api.js @@ -1,50 +1,5 @@ -import { splitId } from './vis-network' - -/** - * @function makeFetch - * @param method - * @param url - * @param body - * @returns {Promise} - */ -const makeFetch = (method, url, body) => { - return fetch(url, { - method: method, - headers: { - 'Content-Type': 'application/json;charset=utf-8' - }, - body: (body !== null) ? JSON.stringify(body) : null - }) - .then(response => { - - if (response.ok) { - return response.json(); - } - - if (response.status === 422) { - return response.json().then(violations => { - throw ValidationException(violations) - }); - } - - throw { - msg: 'Error while updating AccompanyingPeriod Course.', - sta: response.status, - txt: response.statusText, - err: new Error(), - body: response.body - }; - }); -} - -/** - * @param violations - * @constructor - */ -const ValidationException = (violations) => { - this.violations = violations - this.name = 'ValidationException' -} +import { splitId } from './vis-network'; +import {makeFetch} from 'ChillMainAssets/lib/api/apiMethods.js'; /** * @function getFetch @@ -136,7 +91,7 @@ const getRelationsList = () => { * @returns {Promise} */ const postRelationship = (relationship) => { - //console.log(relationship) + //console.log(relationship); return postFetch( `/api/1.0/relations/relationship.json`, { diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/VisGraph/index.js b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/VisGraph/index.js index 5e8989e49..a64afd4a1 100644 --- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/VisGraph/index.js +++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/VisGraph/index.js @@ -3,8 +3,10 @@ import { store } from "./store.js" import { _createI18n } from 'ChillMainAssets/vuejs/_js/i18n' import { visMessages } from './i18n' import App from './App.vue' +import VueToast from 'vue-toast-notification'; +import 'vue-toast-notification/dist/theme-sugar.css'; -import './vis-network' +import './vis-network'; const i18n = _createI18n(visMessages) const container = document.getElementById('relationship-graph') @@ -25,5 +27,11 @@ const app = createApp({ }) .use(store) .use(i18n) +.use(VueToast, { + position: "bottom-right", + type: "error", + duration: 5000, + dismissible: true + }) .component('app', App) .mount('#relationship-graph') diff --git a/src/Bundle/ChillPersonBundle/Validator/Constraints/Relationship/RelationshipNoDuplicate.php b/src/Bundle/ChillPersonBundle/Validator/Constraints/Relationship/RelationshipNoDuplicate.php new file mode 100644 index 000000000..db4d7c0d6 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Validator/Constraints/Relationship/RelationshipNoDuplicate.php @@ -0,0 +1,27 @@ +relationshipRepository = $relationshipRepository; + } + + public function validate($relationship, Constraint $constraint) + { + if (!$constraint instanceof RelationshipNoDuplicate) { + throw new UnexpectedTypeException($constraint, RelationshipNoDuplicate::class); + } + + $fromPerson = $relationship->getFromPerson(); + $toPerson = $relationship->getToPerson(); + + $relationships = $this->relationshipRepository->findBy([ + 'fromPerson' => [$fromPerson, $toPerson], + 'toPerson' => [$fromPerson, $toPerson], + ]); + + foreach ($relationships as $r) { + if ( + $r->getFromPerson() === $fromPerson + || $r->getFromPerson() === $toPerson + || $r->getToPerson() === $fromPerson + || $r->getToPerson() === $toPerson + ) { + $this->context->buildViolation($constraint->message) + ->addViolation(); + } + } + } +} diff --git a/src/Bundle/ChillPersonBundle/migrations/Version20220425000000.php b/src/Bundle/ChillPersonBundle/migrations/Version20220425000000.php new file mode 100644 index 000000000..1dd50d224 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/migrations/Version20220425000000.php @@ -0,0 +1,36 @@ +addSql('DROP INDEX IDX_RELATIONSHIPS000'); + } + + public function getDescription(): string + { + return 'Add constraint with a index on chill_person_relationships.'; + } + + public function up(Schema $schema): void + { + $this->addSql('CREATE UNIQUE INDEX IDX_RELATIONSHIPS000 ON chill_person_relationships (least(fromperson_id, toperson_id), greatest(fromperson_id, toperson_id))'); + } +} diff --git a/src/Bundle/ChillPersonBundle/translations/validators.fr.yml b/src/Bundle/ChillPersonBundle/translations/validators.fr.yml index 13fcb54fb..b2bc549d7 100644 --- a/src/Bundle/ChillPersonBundle/translations/validators.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/validators.fr.yml @@ -62,3 +62,7 @@ You cannot associate a resource with the same person: Vous ne pouvez pas ajouter #location The period must remain located: 'Un parcours doit être localisé' The person where the course is located must be associated to the course. Change course's location before removing the person.: "Le parcours est localisé auprès cet usager. Veuillez changer la localisation du parcours avant de suprimer l'usager" + +#relationship +relationship: + duplicate: Une relation de filiation existe déjà entre ces 2 personnes \ No newline at end of file diff --git a/src/Bundle/ChillReportBundle/Controller/ReportController.php b/src/Bundle/ChillReportBundle/Controller/ReportController.php index bca915090..33ddd3a39 100644 --- a/src/Bundle/ChillReportBundle/Controller/ReportController.php +++ b/src/Bundle/ChillReportBundle/Controller/ReportController.php @@ -334,7 +334,7 @@ class ReportController extends AbstractController $cFGroupId = $request->query->get('cFGroup'); - if ($cFGroupId) { + if ($request->query->has('cFGroup')) { return $this->redirect( $this->generateUrl( 'report_new', @@ -391,7 +391,7 @@ class ReportController extends AbstractController { $cFGroupId = $request->query->get('cFGroup'); - if ($cFGroupId) { + if ($request->query->has('cFGroup')) { return $this->redirect( $this->generateUrl( 'report_export_list', diff --git a/src/Bundle/ChillTaskBundle/Controller/SingleTaskController.php b/src/Bundle/ChillTaskBundle/Controller/SingleTaskController.php index b4b6727b2..355015215 100644 --- a/src/Bundle/ChillTaskBundle/Controller/SingleTaskController.php +++ b/src/Bundle/ChillTaskBundle/Controller/SingleTaskController.php @@ -33,7 +33,6 @@ use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\FormFactoryInterface; -use Symfony\Component\HttpFoundation\Exception\BadRequestException; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -494,7 +493,7 @@ final class SingleTaskController extends AbstractController ); default: - throw new BadRequestException("format not supported: {$_format}"); + throw new BadRequestHttpException("format not supported: {$_format}"); } }