From e283c32984fabee263ca9a5bc3ac3bc94876452e Mon Sep 17 00:00:00 2001 From: Marc Ducobu Date: Fri, 22 Apr 2016 16:28:00 +0200 Subject: [PATCH] Adding validation on address validFrom date (unique by person) --- Controller/PersonAddressController.php | 142 ++++++++++++------ Entity/Person.php | 40 ++++- Resources/config/validation.yml | 5 +- .../migrations/Version20160422000000.php | 42 ++++++ 4 files changed, 182 insertions(+), 47 deletions(-) create mode 100644 Resources/migrations/Version20160422000000.php diff --git a/Controller/PersonAddressController.php b/Controller/PersonAddressController.php index f76719344..39e4cd4c7 100644 --- a/Controller/PersonAddressController.php +++ b/Controller/PersonAddressController.php @@ -44,13 +44,16 @@ class PersonAddressController extends Controller ->getRepository('ChillPersonBundle:Person') ->find($person_id); - if ($person === NULL) { + if ($person === null) { throw $this->createNotFoundException("Person with id $person_id not" . " found "); } - $this->denyAccessUnlessGranted('CHILL_PERSON_SEE', $person, - "You are not allowed to edit this person."); + $this->denyAccessUnlessGranted( + 'CHILL_PERSON_SEE', + $person, + "You are not allowed to edit this person." + ); return $this->render('ChillPersonBundle:Address:list.html.twig', array( 'person' => $person @@ -63,13 +66,16 @@ class PersonAddressController extends Controller ->getRepository('ChillPersonBundle:Person') ->find($person_id); - if ($person === NULL) { + if ($person === null) { throw $this->createNotFoundException("Person with id $person_id not" . " found "); } - $this->denyAccessUnlessGranted('CHILL_PERSON_UPDATE', $person, - "You are not allowed to edit this person."); + $this->denyAccessUnlessGranted( + 'CHILL_PERSON_UPDATE', + $person, + "You are not allowed to edit this person." + ); $address = new Address(); @@ -87,34 +93,48 @@ class PersonAddressController extends Controller ->getRepository('ChillPersonBundle:Person') ->find($person_id); - if ($person === NULL) { + if ($person === null) { throw $this->createNotFoundException("Person with id $person_id not" . " found "); } - $this->denyAccessUnlessGranted('CHILL_PERSON_UPDATE', $person, - "You are not allowed to edit this person."); + $this->denyAccessUnlessGranted( + 'CHILL_PERSON_UPDATE', + $person, + "You are not allowed to edit this person." + ); $address = new Address(); $form = $this->createCreateForm($person, $address); - $form->handleRequest($request); - if ($form->isSubmitted() && $form->isValid()) { - $address = $form->getData(); - $person->addAddress($address); + $person->addAddress($address); + + if ($form->isSubmitted()) { + $validatePersonErrors = $this->validatePerson($person); - $em = $this->getDoctrine()->getManager(); - $em->flush(); - - $this->addFlash('success', + if (count($validatePersonErrors) !== 0) { + foreach ($validatePersonErrors as $error) { + $this->addFlash('error', $error->getMessage()); + } + } elseif ($form->isValid()) { + + $em = $this->getDoctrine()->getManager(); + $em->flush(); + + $this->addFlash( + 'success', $this->get('translator')->trans('The new address was created successfully') - ); - - return $this->redirectToRoute('chill_person_address_list', array( - 'person_id' => $person->getId() - )); + ); + + return $this->redirectToRoute('chill_person_address_list', array( + 'person_id' => $person->getId() + )); + } else { + $this->addFlash('error', $this->get('translator') + ->trans('Error! Address not created!')); + } } return $this->render('ChillPersonBundle:Address:new.html.twig', array( @@ -129,13 +149,16 @@ class PersonAddressController extends Controller ->getRepository('ChillPersonBundle:Person') ->find($person_id); - if ($person === NULL) { + if ($person === null) { throw $this->createNotFoundException("Person with id $person_id not" . " found "); } - $this->denyAccessUnlessGranted('CHILL_PERSON_UPDATE', $person, - "You are not allowed to edit this person."); + $this->denyAccessUnlessGranted( + 'CHILL_PERSON_UPDATE', + $person, + "You are not allowed to edit this person." + ); $address = $this->findAddressById($person, $address_id); @@ -146,40 +169,52 @@ class PersonAddressController extends Controller 'address' => $address, 'form' => $form->createView() )); - - } public function updateAction($person_id, $address_id, Request $request) { $person = $this->getDoctrine()->getManager() - ->getRepository('ChillPersonBundle:Person') - ->find($person_id); + ->getRepository('ChillPersonBundle:Person') + ->find($person_id); - if ($person === NULL) { + if ($person === null) { throw $this->createNotFoundException("Person with id $person_id not" - . " found "); + . " found "); } - $this->denyAccessUnlessGranted('CHILL_PERSON_UPDATE', $person, - "You are not allowed to edit this person."); + $this->denyAccessUnlessGranted( + 'CHILL_PERSON_UPDATE', + $person, + "You are not allowed to edit this person." + ); $address = $this->findAddressById($person, $address_id); $form = $this->createEditForm($person, $address); - $form->handleRequest($request); - - if ($form->isSubmitted() && $form->isValid()) { - $this->getDoctrine()->getManager() - ->flush(); + + if ($request->getMethod() === 'POST') { + $validatePersonErrors = $this->validatePerson($person); - $this->addFlash('success', $this->get('translator')->trans( - "The address has been successfully updated")); - - return $this->redirectToRoute('chill_person_address_list', array( - 'person_id' => $person->getId() - )); + if (count($validatePersonErrors) !== 0) { + foreach ($validatePersonErrors as $error) { + $this->addFlash('error', $error->getMessage()); + } + } elseif ($form->isValid()) { + $this->getDoctrine()->getManager() + ->flush(); + + $this->addFlash('success', $this->get('translator')->trans( + "The address has been successfully updated" + )); + + return $this->redirectToRoute('chill_person_address_list', array( + 'person_id' => $person->getId() + )); + } else { + $this->addFlash('error', $this->get('translator') + ->trans('Error when updating the period')); + } } return $this->render('ChillPersonBundle:Address:edit.html.twig', array( @@ -190,7 +225,6 @@ class PersonAddressController extends Controller } /** - * * @param Person $person * @param Address $address * @return \Symfony\Component\Form\Form @@ -256,4 +290,22 @@ class PersonAddressController extends Controller return $addresses->first(); } + + /** + * @param Chill\PersonBundle\Entity\Person $person + * @return \Symfony\Component\Validator\ConstraintViolationListInterface + */ + private function validatePerson(Person $person) + { + $errors = $this->get('validator') + ->validate($person, array('Default')); + $errors_addresses_consistent = $this->get('validator') + ->validate($person, array('addresses_consistent')); + + foreach($errors_addresses_consistent as $error) { + $errors->add($error); + } + + return $errors; + } } diff --git a/Entity/Person.php b/Entity/Person.php index 2fa1b287d..ef8b4c989 100644 --- a/Entity/Person.php +++ b/Entity/Person.php @@ -669,6 +669,44 @@ class Person implements HasCenterInterface { } } + /** + * Return true if the person has two addresses with the + * same validFrom date (in format 'Y-m-d') + */ + public function hasTwoAdressWithSameValidFromDate() + { + $validYMDDates = array(); + + foreach ($this->addresses as $ad) { + $validDate = $ad->getValidFrom()->format('Y-m-d'); + + if (in_array($validDate, $validYMDDates)) { + return true; + } + $validYMDDates[] = $validDate; + } + + return false; + } + + /** + * Validation callback that checks if the addresses are valid (do not have + * two addresses with the same validFrom date) + * + * This method add violation errors. + */ + public function isAddressesValid(ExecutionContextInterface $context) + { + if ($this->hasTwoAdressWithSameValidFromDate()) { + $context->addViolationAt( + 'addresses', + 'Two addresses has the same validFrom date', + array() + ); + } + } + + const ERROR_PERIODS_ARE_COLLAPSING = 1; // when two different periods // have days in commun const ERROR_ADDIND_PERIOD_AFTER_AN_OPEN_PERIOD = 2; // where there exist @@ -713,4 +751,4 @@ class Person implements HasCenterInterface { return true; } -} \ No newline at end of file +} diff --git a/Resources/config/validation.yml b/Resources/config/validation.yml index f6e683d3e..c80bae183 100644 --- a/Resources/config/validation.yml +++ b/Resources/config/validation.yml @@ -34,6 +34,9 @@ Chill\PersonBundle\Entity\Person: - Callback: methods: [isAccompanyingPeriodValid] groups: [accompanying_period_consistent] + - Callback: + methods: [isAddressesValid] + groups: [addresses_consistent] Chill\PersonBundle\Entity\AccompanyingPeriod: properties: @@ -50,4 +53,4 @@ Chill\PersonBundle\Entity\AccompanyingPeriod: groups: [closed] constraints: - Callback: - methods: [isDateConsistent] \ No newline at end of file + methods: [isDateConsistent] diff --git a/Resources/migrations/Version20160422000000.php b/Resources/migrations/Version20160422000000.php new file mode 100644 index 000000000..20cd6700f --- /dev/null +++ b/Resources/migrations/Version20160422000000.php @@ -0,0 +1,42 @@ +connection->query('SELECT COUNT(*), pe.id, ad.validfrom FROM person AS pe + INNER JOIN chill_person_persons_to_addresses AS pe_ad ON pe.id = pe_ad.person_id + INNER JOIN chill_main_address AS ad ON ad.id = pe_ad.address_id + GROUP BY pe.id, ad.validfrom + HAVING COUNT(*) > 1'); + + $personWithTwoAddressWithSameValidFrom = $stmt->fetchAll(); + + foreach ($personWithTwoAddressWithSameValidFrom as $p) { + $this->warnIf(true, 'The person with id '.$p['id'].' has two adresses with the same validFrom date'); + } + + $this->abortIf( + sizeof($personWithTwoAddressWithSameValidFrom) != 0, + 'There exists some person with multiple adress with the same validFrom' + ); + } + + /** + * @param Schema $schema + */ + public function down(Schema $schema) + { + } +}