Improve person accompanyingPeriod validation - close #410

This commit is contained in:
Marc Ducobu 2015-03-06 20:36:21 +01:00
parent c80326d0ed
commit 5634a19174
5 changed files with 110 additions and 158 deletions

View File

@ -4,7 +4,7 @@
* Chill is a software for social workers
*
* Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS,
* <http://www.champs-libres.coop>
* <http://www.champs-libres.coop>, <info@champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
@ -40,7 +40,6 @@ class AccompanyingPeriodController extends Controller
return $this->render('ChillPersonBundle:AccompanyingPeriod:list.html.twig',
array('accompanying_periods' => $person->getAccompanyingPeriodsOrdered(),
'person' => $person));
}
public function createAction($person_id) {
@ -51,10 +50,10 @@ class AccompanyingPeriodController extends Controller
}
$accompanyingPeriod = new AccompanyingPeriod(new \DateTime());
$accompanyingPeriod->setPerson($person)
->setDateOpening(new \DateTime())
->setDateClosing(new \DateTime());
$accompanyingPeriod->setDateClosing(new \DateTime());
$person->addAccompanyingPeriod(
$accompanyingPeriod);
$form = $this->createForm(new AccompanyingPeriodType(),
$accompanyingPeriod, array('period_action' => 'update'));
@ -62,21 +61,16 @@ class AccompanyingPeriodController extends Controller
$request = $this->getRequest();
if ($request->getMethod() === 'POST') {
$form->handleRequest($request);
$errors = $this->_validatePerson($person);
$flashBag = $this->get('session')->getFlashBag();
if ($form->isValid(array('Default', 'closed'))
&& count($errors) === 0) {
$em = $this->getDoctrine()->getManager();
$em->persist($accompanyingPeriod);
$em->flush();
$flashBag->add('success',
$this->get('translator')->trans(
'Period created!'));
@ -84,7 +78,6 @@ class AccompanyingPeriodController extends Controller
return $this->redirect($this->generateUrl('chill_person_accompanying_period_list',
array('person_id' => $person->getId())));
} else {
$flashBag->add('danger', $this->get('translator')
->trans('Error! Period not created!'));
@ -94,8 +87,6 @@ class AccompanyingPeriodController extends Controller
}
}
return $this->render('ChillPersonBundle:AccompanyingPeriod:form.html.twig',
array(
'form' => $form->createView(),
@ -117,18 +108,13 @@ class AccompanyingPeriodController extends Controller
}
$person = $accompanyingPeriod->getPerson();
$form = $this->createForm(new AccompanyingPeriodType(),
$accompanyingPeriod, array('period_action' => 'update'));
$request = $this->getRequest();
if ($request->getMethod() === 'POST') {
$form->handleRequest($request);
$errors = $this->_validatePerson($person);
$flashBag = $this->get('session')->getFlashBag();
if ($form->isValid(array('Default', 'closed'))
@ -142,7 +128,6 @@ class AccompanyingPeriodController extends Controller
return $this->redirect($this->generateUrl('chill_person_accompanying_period_list',
array('person_id' => $person->getId())));
} else {
$flashBag->add('danger', $this->get('translator')
->trans('Error when updating the period'));
@ -152,8 +137,6 @@ class AccompanyingPeriodController extends Controller
}
}
return $this->render('ChillPersonBundle:AccompanyingPeriod:form.html.twig',
array(
'form' => $form->createView(),
@ -182,7 +165,6 @@ class AccompanyingPeriodController extends Controller
}
$current = $person->getCurrentAccompanyingPeriod();
$form = $this->createForm(new AccompanyingPeriodType(), $current, array(
'period_action' => 'close'
));
@ -270,7 +252,7 @@ class AccompanyingPeriodController extends Controller
$request = $this->getRequest();
//in case the person is already open
if ($person->isOpen() === true) {
if ($person->isOpen()) {
$this->get('session')->getFlashBag()
->add('danger', $this->get('translator')
->trans('Error! Period %name% is not closed ; it can be open',
@ -306,8 +288,7 @@ class AccompanyingPeriodController extends Controller
return $this->redirect(
$this->generateUrl('chill_person_accompanying_period_list', array(
'person_id' => $person->getId()
))
);
)));
} else {
$this->get('session')->getFlashBag()
->add('danger', $this->get('translator')
@ -318,7 +299,6 @@ class AccompanyingPeriodController extends Controller
->add('info', $error->getMessage());
}
}
} else { // if errors in forms
$this->get('session')->getFlashBag()
->add('danger', $this->get('translator')
@ -327,11 +307,9 @@ class AccompanyingPeriodController extends Controller
}
return $this->render('ChillPersonBundle:AccompanyingPeriod:form.html.twig',
array(
'form' => $form->createView(),
array('form' => $form->createView(),
'person' => $person,
'accompanying_period' => $accompanyingPeriod
));
'accompanying_period' => $accompanyingPeriod));
}
private function _getPerson($id) {
@ -339,5 +317,4 @@ class AccompanyingPeriodController extends Controller
->getRepository('ChillPersonBundle:Person')
->find($id);
}
}

View File

@ -4,7 +4,7 @@
* Chill is a software for social workers
*
* Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS,
* <http://www.champs-libres.coop>
* <http://www.champs-libres.coop>, <info@champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
@ -206,8 +206,6 @@ class AccompanyingPeriod
return $this;
}
/// VALIDATION function
public function isDateConsistent(ExecutionContextInterface $context) {
if ($this->isOpen()) {

View File

@ -6,7 +6,7 @@ namespace Chill\PersonBundle\Entity;
* Chill is a software for social workers
*
* Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS,
* <http://www.champs-libres.coop>
* <http://www.champs-libres.coop>, <info@champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
@ -567,93 +567,67 @@ class Person {
*
* This method add violation errors.
*/
public function isAccompanyingPeriodValid(ExecutionContextInterface $context) {
$r = $this->checkAccompanyingPeriodIsNotCovering();
public function isAccompanyingPeriodValid(ExecutionContextInterface $context)
{
$r = $this->checkAccompanyingPeriodsAreNotCollapsing();
if ($r !== true) {
if ($r['result'] === self::ERROR_OPENING_NOT_CLOSED_IS_BEFORE_NEW_LINE) {
$context->addViolationAt('history',
'Accompanying period not closed is before the new line',
if ($r['result'] === self::ERROR_PERIODS_ARE_COLLAPSING) {
$context->addViolationAt('accompanyingPeriods',
'Two accompanying periods have days in commun',
array());
return;
}
$context->addViolationAt('history', 'Periods are collapsing',
array(
'%dateOpening%' => $r['dateOpening']->format('d-m-Y'),
'%dateClosing%' => $r['dateClosing']->format('d-m-Y'),
'%date%' => $r['date']->format('d-m-Y')
)
);
if ($r['result'] === self::ERROR_ADDIND_PERIOD_AFTER_AN_OPEN_PERIOD) {
$context->addViolationAt('accompanyingPeriods',
'A period is opened and a period is added after it',
array());
}
}
}
const ERROR_OPENING_IS_INSIDE_CLOSING = 1;
const ERROR_OPENING_NOT_CLOSED_IS_BEFORE_NEW_LINE = 2;
const ERROR_OPENING_NOT_CLOSE_IS_INSIDE_CLOSED_ACCOMPANYING_PERIOD_LINE = 3;
const ERROR_OPENING_IS_BEFORE_OTHER_LINE_AND_CLOSED_IS_AFTER_THIS_LINE = 4;
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
// a period opened and another one after it
public function checkAccompanyingPeriodIsNotCovering()
/**
* Function used for validation that check if the accompanying periods of
* the person are not collapsing (i.e. have not shared days) or having
* a period after an open period.
*
* @return true | array True if the accompanying periods are not collapsing,
* an array with data for displaying the error
*/
public function checkAccompanyingPeriodsAreNotCollapsing()
{
$periods = $this->getAccompanyingPeriodsOrdered();
$periodsNbr = sizeof($periods);
$i = 0;
foreach ($periods as $key => $period) {
//accompanying period is open : we must check the arent any period after
if ($period->isOpen()) {
foreach ($periods as $subKey => $against) {
//if we are checking the same, continue
if ($key === $subKey) {
continue;
}
while($i < $periodsNbr - 1) {
$periodI = $periods[$i];
$periodAfterI = $periods[$i + 1];
if ($period->getDateOpening() > $against->getDateOpening()
&& $period->getDateOpening() < $against->getDateOpening()) {
// the period date opening is inside another opening line
if($periodI->isOpen()) {
return array(
'result' => self::ERROR_OPENING_NOT_CLOSE_IS_INSIDE_CLOSED_ACCOMPANYING_PERIOD_LINE,
'dateOpening' => $against->getDateOpening(),
'dateClosing' => $against->getDateClosing(),
'date' => $period->getDateOpening()
'result' => self::ERROR_ADDIND_PERIOD_AFTER_AN_OPEN_PERIOD,
'dateOpening' => $periodAfterI->getDateOpening(),
'dateClosing' => $periodAfterI->getDateClosing(),
'date' => $periodI->getDateOpening()
);
}
if ($period->getDateOpening() < $against->getDateOpening()
&& $period->getDateClosing() > $against->getDateClosing()) {
// the period date opening is inside another opening line
} elseif ($periodI->getDateClosing() >= $periodAfterI->getDateOpening()) {
return array(
'result' => self::ERROR_OPENING_IS_BEFORE_OTHER_LINE_AND_CLOSED_IS_AFTER_THIS_LINE,
'dateOpening' => $against->getDateOpening(),
'dateClosing' => $against->getDateClosing(),
'date' => $period->getDateOpening()
'result' => self::ERROR_PERIODS_ARE_COLLAPSING,
'dateOpening' => $periodI->getDateOpening(),
'dateClosing' => $periodI->getDateClosing(),
'date' => $periodAfterI->getDateOpening()
);
}
$i++;
}
//if we have an aopening later...
if ($period->getDateOpening() < $against->getDateClosing()) {
return array( 'result' => self::ERROR_OPENING_NOT_CLOSED_IS_BEFORE_NEW_LINE,
'dateOpening' => $against->getDateOpening(),
'dateClosing' => $against->getDateClosing(),
'date' => $period->getDateOpening()
);
}
}
} else {
//we must check there is not covering lines
foreach ($periods as $subKey => $against) {
//check if dateOpening is inside an `against` line
if ($period->getDateOpening() > $against->getDateOpening()
&& $period->getDateOpening() < $against->getDateClosing()) {
return array(
'result' => self::ERROR_OPENING_IS_INSIDE_CLOSING,
'dateOpening' => $against->getDateOpening(),
'dateClosing' => $against->getDateClosing(),
'date' => $period->getDateOpening()
);
}
}
}
}
return true;
}
}

View File

@ -30,7 +30,8 @@ use Chill\PersonBundle\Entity\AccompanyingPeriod\ClosingMotive;
/**
* Test the creation or deletion of accompanying periods
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
* The person on which the test is done has a (current) period opened (and not
* closed) starting the 2015-01-05.
*/
class AccompanyingPeriodControllerTest extends WebTestCase
{
@ -56,14 +57,19 @@ class AccompanyingPeriodControllerTest extends WebTestCase
const CLOSING_INPUT = 'chill_personbundle_accompanyingperiod[date_closing]';
const CLOSING_MOTIVE_INPUT = 'chill_personbundle_accompanyingperiod[closingMotive]';
/**
* Setup before the first test of this class (see phpunit doc)
*/
public static function setUpBeforeClass()
{
static::bootKernel();
static::$em = static::$kernel->getContainer()
->get('doctrine.orm.entity_manager');
}
/**
* Setup before each test method (see phpunit doc)
*/
public function setUp()
{
$this->client = static::createClient(array(), array(
@ -74,13 +80,15 @@ class AccompanyingPeriodControllerTest extends WebTestCase
$this->person = (new Person(new \DateTime('2015-01-05')))
->setFirstName('Roland')
->setLastName('Gallorime')
->setGenre(Person::GENRE_MAN)
;
->setGenre(Person::GENRE_MAN);
static::$em->persist($this->person);
static::$em->flush();
}
/**
* TearDown after each test method (see phpunit doc)
*/
public function tearDown()
{
static::$em->refresh($this->person);
@ -207,7 +215,6 @@ class AccompanyingPeriodControllerTest extends WebTestCase
*/
public function testAddNewPeriodBeforeActual()
{
$crawler = $this->client->request('GET', '/en/person/'
.$this->person->getId().'/accompanying-period/create');
@ -244,8 +251,6 @@ class AccompanyingPeriodControllerTest extends WebTestCase
*/
public function testCreatePeriodWithClosingAfterCurrentFails()
{
$this->markTestSkipped('this feature is not yet implemented');
$crawler = $this->client->request('GET', '/en/person/'
.$this->person->getId().'/accompanying-period/create');
@ -280,8 +285,6 @@ class AccompanyingPeriodControllerTest extends WebTestCase
*/
public function testCreatePeriodWithOpeningAndClosingAfterCurrentFails()
{
$this->markTestSkipped('this feature is not yet implemented');
$crawler = $this->client->request('GET', '/en/person/'
.$this->person->getId().'/accompanying-period/create');

View File

@ -126,9 +126,9 @@ class PersonTest extends \PHPUnit_Framework_TestCase
$period = $p->getCurrentAccompanyingPeriod()->setDateClosing($g);
$p->close($period);
$r = $p->checkAccompanyingPeriodIsNotCovering();
$r = $p->checkAccompanyingPeriodsAreNotCollapsing();
$this->assertEquals($r['result'], Person::ERROR_OPENING_IS_INSIDE_CLOSING);
$this->assertEquals($r['result'], Person::ERROR_PERIODS_ARE_COLLAPSING);
}
/**
@ -147,8 +147,8 @@ class PersonTest extends \PHPUnit_Framework_TestCase
$f = new \DateTime("2013/1/1");
$p->open(new AccompanyingPeriod($f));
$r = $p->checkAccompanyingPeriodIsNotCovering();
$r = $p->checkAccompanyingPeriodsAreNotCollapsing();
$this->assertEquals($r['result'], Person::ERROR_OPENING_NOT_CLOSED_IS_BEFORE_NEW_LINE);
$this->assertEquals($r['result'], Person::ERROR_ADDIND_PERIOD_AFTER_AN_OPEN_PERIOD);
}
}