Merge branch 110_extend_thirdparty into 'master'

This commit is contained in:
Mathieu Jaumotte 2021-08-19 12:19:00 +02:00
commit 227d627ad5
29 changed files with 657 additions and 518 deletions

View File

@ -5,11 +5,13 @@ image: registry.gitlab.com/chill-projet/chill-app/php-base-image:7.4
cache: cache:
paths: paths:
- tests/app/vendor/ - tests/app/vendor/
- .composer
before_script: before_script:
# add extensions to postgres # add extensions to postgres
- PGPASSWORD=$POSTGRES_PASSWORD psql -U $POSTGRES_USER -h db -c "CREATE EXTENSION IF NOT EXISTS unaccent; CREATE EXTENSION IF NOT EXISTS pg_trgm;" - PGPASSWORD=$POSTGRES_PASSWORD psql -U $POSTGRES_USER -h db -c "CREATE EXTENSION IF NOT EXISTS unaccent; CREATE EXTENSION IF NOT EXISTS pg_trgm;"
# Install and run Composer # Install and run Composer
- mkdir -p $COMPOSER_HOME
- curl -sS https://getcomposer.org/installer | php - curl -sS https://getcomposer.org/installer | php
- php -d memory_limit=2G composer.phar install - php -d memory_limit=2G composer.phar install
- php tests/app/bin/console doctrine:migrations:migrate -n - php tests/app/bin/console doctrine:migrations:migrate -n
@ -34,6 +36,10 @@ variables:
REDIS_HOST: redis REDIS_HOST: redis
REDIS_PORT: 6379 REDIS_PORT: 6379
REDIS_URL: redis://redis:6379 REDIS_URL: redis://redis:6379
# change vendor dir to make the app install into tests/apps
COMPOSER_VENDOR_DIR: tests/app/vendor
# cache some composer data
COMPOSER_HOME: .composer
# Run our tests # Run our tests

View File

@ -15,6 +15,7 @@ trait LoadAbstractNotificationsTrait
{ {
public function load(ObjectManager $manager) public function load(ObjectManager $manager)
{ {
return;
foreach ($this->notifs as $notif) { foreach ($this->notifs as $notif) {
$entityId = $this->getReference($notif['entityRef'])->getId(); $entityId = $this->getReference($notif['entityRef'])->getId();

View File

@ -111,3 +111,8 @@ $chill-theme-buttons: (
} }
} }
} }
// fix min-width on small pictos buttons
.btn-sm, .btn-group-sm > .btn {
min-width: 36px;
}

View File

@ -51,6 +51,7 @@ div.flex-bloc {
flex-grow: 0; flex-shrink: 1; flex-basis: auto; flex-grow: 0; flex-shrink: 1; flex-basis: auto;
flex-direction: column; flex-direction: column;
margin: 0; margin: 0;
hyphens: auto;
div.item-row { div.item-row {
flex-grow: 1; flex-shrink: 1; flex-basis: auto; flex-grow: 1; flex-shrink: 1; flex-basis: auto;

View File

@ -1,88 +0,0 @@
<?php
/*
* Chill is a software for social workers
*
* Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS,
* <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
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Chill\PersonBundle\DataFixtures\ORM;
use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Doctrine\Persistence\ObjectManager;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Entity\Person;
/**
* Description of LoadAccompanyingPeriod
*
* @author Champs-Libres Coop
*/
class LoadAccompanyingPeriod extends AbstractFixture implements OrderedFixtureInterface, ContainerAwareInterface
{
use \Symfony\Component\DependencyInjection\ContainerAwareTrait;
public const ACCOMPANYING_PERIOD = 'parcours 1';
public function getOrder()
{
return 10004;
}
public static $references = array();
public function load(ObjectManager $manager)
{
$centerA = $this->getReference('centerA');
$centerAId = $centerA->getId();
$personIds = $this->container->get('doctrine.orm.entity_manager')
->createQueryBuilder()
->select('p.id')
->from('ChillPersonBundle:Person', 'p')
->where('p.center = :centerAId')
->orderBy('p.id', 'ASC')
->setParameter('centerAId', $centerAId)
->getQuery()
->getScalarResult();
$openingDate = new \DateTime('2020-04-01');
$person1 = $manager->getRepository(Person::class)->find($personIds[0]);
$person2 = $manager->getRepository(Person::class)->find($personIds[1]);
$socialScope = $this->getReference('scope_social');
$a = new AccompanyingPeriod($openingDate);
$a->addPerson($person1);
$a->addPerson($person2);
$a->addScope($socialScope);
$a->setStep(AccompanyingPeriod::STEP_CONFIRMED);
$manager->persist($a);
$this->addReference(self::ACCOMPANYING_PERIOD, $a);
echo "Adding one AccompanyingPeriod\n";
$manager->flush();
}
}

View File

@ -6,7 +6,6 @@ use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\DependentFixtureInterface; use Doctrine\Common\DataFixtures\DependentFixtureInterface;
use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\MainBundle\DataFixtures\ORM\LoadAbstractNotificationsTrait; use Chill\MainBundle\DataFixtures\ORM\LoadAbstractNotificationsTrait;
use Chill\PersonBundle\DataFixtures\ORM\LoadAccompanyingPeriod;
/** /**
* Load notififications into database * Load notififications into database
@ -19,7 +18,7 @@ class LoadAccompanyingPeriodNotifications extends AbstractFixture implements Dep
[ [
'message' => 'Hello !', 'message' => 'Hello !',
'entityClass' => AccompanyingPeriod::class, 'entityClass' => AccompanyingPeriod::class,
'entityRef' => LoadAccompanyingPeriod::ACCOMPANYING_PERIOD, 'entityRef' => null,
'sender' => 'center a_social', 'sender' => 'center a_social',
'addressees' => [ 'addressees' => [
'center a_social', 'center a_social',
@ -30,10 +29,15 @@ class LoadAccompanyingPeriodNotifications extends AbstractFixture implements Dep
] ]
]; ];
protected function getEntityRef()
{
return null;
}
public function getDependencies() public function getDependencies()
{ {
return [ return [
LoadAccompanyingPeriod::class, LoadPeople::class,
]; ];
} }
} }

View File

@ -33,7 +33,7 @@ class LoadHousehold extends Fixture implements DependentFixtureInterface
public function load(ObjectManager $manager) public function load(ObjectManager $manager)
{ {
// generate two times the participation. This will lead to // generate two times the participation. This will lead to
// some movement in participation (same people in two differents // some movement in participation (same people in two differents
// households) // households)
@ -110,7 +110,7 @@ class LoadHousehold extends Fixture implements DependentFixtureInterface
$i = 0; $i = 0;
while ($i < $nb) { while ($i < $nb) {
$address = $this->createAddress(); $address = $this->createAddress();
$address->setValidFrom(\DateTime::createFromImmutable($date)); $address->setValidFrom(\DateTime::createFromImmutable($date));
if (\random_int(0, 20) < 1) { if (\random_int(0, 20) < 1) {
$date = $date->add(new \DateInterval('P'.\random_int(8, 52).'W')); $date = $date->add(new \DateInterval('P'.\random_int(8, 52).'W'));
@ -157,6 +157,7 @@ class LoadHousehold extends Fixture implements DependentFixtureInterface
->setParameter('center', 'Center A') ->setParameter('center', 'Center A')
->getScalarResult() ->getScalarResult()
; ;
\shuffle($this->personIds); \shuffle($this->personIds);
} }

View File

@ -21,9 +21,15 @@
namespace Chill\PersonBundle\DataFixtures\ORM; namespace Chill\PersonBundle\DataFixtures\ORM;
use Chill\MainBundle\Entity\Center;
use Chill\MainBundle\Entity\Country;
use Chill\MainBundle\Entity\PostalCode; use Chill\MainBundle\Entity\PostalCode;
use Chill\MainBundle\Repository\CenterRepository;
use Chill\MainBundle\Repository\CountryRepository;
use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Entity\MaritalStatus;
use Chill\PersonBundle\Entity\SocialWork\SocialIssue; use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
use Chill\PersonBundle\Repository\MaritalStatusRepository;
use Chill\ThirdPartyBundle\Entity\ThirdParty; use Chill\ThirdPartyBundle\Entity\ThirdParty;
use Doctrine\Common\DataFixtures\AbstractFixture; use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface; use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
@ -31,6 +37,7 @@ use Doctrine\Persistence\ObjectManager;
use Chill\PersonBundle\Entity\Person; use Chill\PersonBundle\Entity\Person;
use Faker\Factory; use Faker\Factory;
use Faker\Generator; use Faker\Generator;
use Nelmio\Alice\Faker\GeneratorFactory;
use Nelmio\Alice\Loader\NativeLoader; use Nelmio\Alice\Loader\NativeLoader;
use Nelmio\Alice\ObjectSet; use Nelmio\Alice\ObjectSet;
use Symfony\Component\DependencyInjection\ContainerAwareInterface; use Symfony\Component\DependencyInjection\ContainerAwareInterface;
@ -44,8 +51,6 @@ use Chill\PersonBundle\Repository\SocialWork\SocialIssueRepository;
/** /**
* Load people into database * Load people into database
* *
* @author Julien Fastré <julien arobase fastre point info>
* @author Marc Ducobu <marc@champs-libres.coop>
*/ */
class LoadPeople extends AbstractFixture implements OrderedFixtureInterface, ContainerAwareInterface class LoadPeople extends AbstractFixture implements OrderedFixtureInterface, ContainerAwareInterface
{ {
@ -57,35 +62,50 @@ class LoadPeople extends AbstractFixture implements OrderedFixtureInterface, Con
protected SocialIssueRepository $socialIssueRepository; protected SocialIssueRepository $socialIssueRepository;
protected array $cacheSocialIssues = array(); protected CountryRepository $countryRepository;
public function __construct(Registry $workflowRegistry, SocialIssueRepository $socialIssueRepository) protected NativeLoader $loader;
{
/**
* @var array|SocialIssue[]
*/
protected array $cacheSocialIssues = [];
/**
* @var array|Country[]
*/
protected array $cacheCountries = [];
/**
* @var array|Center[]
*/
protected array $cacheCenters = [];
protected CenterRepository $centerRepository;
/**
* @var array|MaritalStatus[]
*/
protected array $cacheMaritalStatuses = [];
protected MaritalStatusRepository $maritalStatusRepository;
public function __construct(
Registry $workflowRegistry,
SocialIssueRepository $socialIssueRepository,
CenterRepository $centerRepository,
CountryRepository $countryRepository,
MaritalStatusRepository $maritalStatusRepository
) {
$this->faker = Factory::create('fr_FR'); $this->faker = Factory::create('fr_FR');
$this->faker->addProvider($this);
$this->workflowRegistry = $workflowRegistry; $this->workflowRegistry = $workflowRegistry;
$this->socialIssueRepository = $socialIssueRepository; $this->socialIssueRepository = $socialIssueRepository;
} $this->centerRepository = $centerRepository;
$this->countryRepository = $countryRepository;
$this->maritalStatusRepository = $maritalStatusRepository;
$this->loader = new NativeLoader($this->faker);
public function prepare()
{
//prepare days, month, years
$y = 1950;
do {
$this->years[] = $y;
$y = $y +1;
} while ($y >= 1990);
$m = 1;
do {
$this->month[] = $m;
$m = $m +1;
} while ($m >= 12);
$d = 1;
do {
$this->day[] = $d;
$d = $d + 1;
} while ($d <= 28);
} }
public function getOrder() public function getOrder()
@ -95,8 +115,8 @@ class LoadPeople extends AbstractFixture implements OrderedFixtureInterface, Con
public function load(ObjectManager $manager) public function load(ObjectManager $manager)
{ {
$this->loadRandPeople($manager);
$this->loadExpectedPeople($manager); $this->loadExpectedPeople($manager);
$this->loadRandPeople($manager);
$manager->flush(); $manager->flush();
} }
@ -105,117 +125,102 @@ class LoadPeople extends AbstractFixture implements OrderedFixtureInterface, Con
{ {
echo "loading expected people...\n"; echo "loading expected people...\n";
foreach ($this->peoples as $person) {
$this->addAPerson($this->fillWithDefault($person), $manager); foreach ($this->peoples as $personDef) {
$person = $this->createExpectedPerson($personDef);
$this->addAPerson($person, $manager);
} }
} }
public function loadRandPeople(ObjectManager $manager) protected function loadRandPeople(ObjectManager $manager)
{ {
echo "loading rand people...\n"; echo "loading rand people...\n";
$persons = $this->createRandPerson()->getObjects();
$this->prepare(); foreach ($persons as $person) {
$this->addAPerson($person, $manager);
$chooseLastNameOrTri = array('tri', 'tri', 'name', 'tri'); }
$i = 0;
do {
$i++;
$sex = $this->genders[array_rand($this->genders)];
if ($chooseLastNameOrTri[array_rand($chooseLastNameOrTri)] === 'tri' ) {
$length = rand(2, 3);
$lastName = '';
for ($j = 0; $j <= $length; $j++) {
$lastName .= $this->lastNamesTrigrams[array_rand($this->lastNamesTrigrams)];
}
$lastName = ucfirst($lastName);
} else {
$lastName = $this->lastNames[array_rand($this->lastNames)];
}
if ($sex === Person::MALE_GENDER) {
$firstName = $this->firstNamesMale[array_rand($this->firstNamesMale)];
} else {
$firstName = $this->firstNamesFemale[array_rand($this->firstNamesFemale)];
}
// add an address on 80% of the created people
if (rand(0,100) < 80) {
$address = $this->getRandomAddress();
// on 30% of those person, add multiple addresses
if (rand(0,10) < 4) {
$address = array(
$address,
$this->getRandomAddress()
);
}
} else {
$address = null;
}
$person = array(
'FirstName' => $firstName,
'LastName' => $lastName,
'Gender' => $sex,
'Nationality' => (rand(0,100) > 50) ? NULL: 'BE',
'center' => (rand(0,1) == 0) ? 'centerA': 'centerB',
'Address' => $address,
'maritalStatus' => $this->maritalStatusRef[array_rand($this->maritalStatusRef)]
);
$this->addAPerson($this->fillWithDefault($person), $manager);
} while ($i <= 100);
} }
/** private function createRandPerson(): ObjectSet
* fill a person array with default value
*
* @param string[] $specific
*/
private function fillWithDefault(array $specific)
{ {
return array_merge(array( return $this->loader->loadData([
'Birthdate' => "1960-10-12", Person::class => [
'PlaceOfBirth' => "Ottignies Louvain-La-Neuve", 'persons{1..300}' => [
'Gender' => Person::MALE_GENDER, 'firstName' => '<firstname()>',
'Email' => "roger@yopmail.com", 'lastName' => '<lastname()>',
'CountryOfBirth' => 'BE', 'gender' => '<getRandomGender()>',
'Nationality' => 'BE', 'nationality' => '<getRandomCountry()>',
'CFData' => array(), 'center' => '<getRandomCenter()>',
'Address' => null 'maritalStatus' => '<getRandomMaritalStatus()>',
), $specific); 'birthdate' => '<dateTimeBetween("-75 years", "-1 tears")>',
'placeOfBirth' => '<city()>',
'email' => '<freeEmail()>',
'countryOfBirth' => '<getRandomCountry(80)>',
]
]
]);
} }
private function getRandomSocialIssue(): SocialIssue private function createExpectedPerson($default): Person
{ {
if (0 === count($this->cacheSocialIssues)) { $person = $this->loader->loadData([
$this->cacheSocialIssues = $this->socialIssueRepository->findAll(); Person::class => [
"person" => [
'firstName' => $default['firstName'] ?? '<firstname()>',
'lastName' => $default['lastName'] ?? '<lastname()>',
'gender' => '<getRandomGender()>',
'nationality' => '<getRandomCountry()>',
'center' => '<getRandomCenter()>',
'maritalStatus' => '<getRandomMaritalStatus()>',
'birthdate' => '<dateTimeBetween("-75 years", "-1 tears")>',
'placeOfBirth' => '<city()>',
'email' => '<freeEmail()>',
'countryOfBirth' => '<getRandomCountry(80)>',
],
]
])->getObjects()['person'];
// force some values
foreach ($default as $key => $value) {
switch ($key) {
case 'birthdate':
$person->setBirthdate(new \DateTime($value));
break;
case 'center':
$person->setCenter($this->centerRepository
->findOneBy(['name' => $value]));
break;
case 'countryOfBirth':
case 'nationality':
$country = $this->countryRepository
->findOneBy(['countryCode' => $value]);
$person->{'set'.\ucfirst($key)}($country);
break;
case 'maritalStatus':
$person->setMaritalStatus($this->maritalStatusRepository
->find($value));
break;
}
} }
return $this->cacheSocialIssues[\array_rand($this->cacheSocialIssues)]; return $person;
} }
/** /**
* create a new person from array data * create a new person from array data
* *
* @param array $person
* @param ObjectManager $manager
* @throws \Exception * @throws \Exception
*/ */
private function addAPerson(array $person, ObjectManager $manager) private function addAPerson(Person $person, ObjectManager $manager)
{ {
$p = new Person();
$accompanyingPeriod = new AccompanyingPeriod( $accompanyingPeriod = new AccompanyingPeriod(
(new \DateTime()) (new \DateTime())
->sub( ->sub(
new \DateInterval('P' . \random_int(0, 180) . 'D') new \DateInterval('P' . \random_int(0, 180) . 'D')
) )
); );
$p->addAccompanyingPeriod($accompanyingPeriod); $person->addAccompanyingPeriod($accompanyingPeriod);
$accompanyingPeriod->addSocialIssue($this->getRandomSocialIssue()); $accompanyingPeriod->addSocialIssue($this->getRandomSocialIssue());
if (\random_int(0, 10) > 3) { if (\random_int(0, 10) > 3) {
@ -225,53 +230,13 @@ class LoadPeople extends AbstractFixture implements OrderedFixtureInterface, Con
$workflow->apply($accompanyingPeriod, 'confirm'); $workflow->apply($accompanyingPeriod, 'confirm');
} }
foreach ($person as $key => $value) { $manager->persist($person);
switch ($key) { echo "add person'".$person->__toString()."'\n";
case 'CountryOfBirth':
case 'Nationality':
$value = $this->getCountry($value);
break;
case 'Birthdate':
$value = new \DateTime($value);
break;
case 'center':
case 'maritalStatus':
$value = $this->getReference($value);
break;
case 'accompanyingPeriods':
$this->addAccompanyingPeriods($p, $value, $manager);
break;
}
//try to add the data using the setSomething function,
// if not possible, fallback to addSomething function
if (method_exists($p, 'set'.$key)) {
call_user_func(array($p, 'set'.$key), $value);
} elseif (method_exists($p, 'add'.$key)) {
// if we have a "addSomething", we may have multiple items to add
// so, we set the value in an array if it is not an array, and
// will call the function addSomething multiple times
if (!is_array($value)) {
$value = array($value);
}
foreach($value as $v) {
if ($v !== NULL) {
call_user_func(array($p, 'add'.$key), $v);
}
}
}
}
$manager->persist($p);
echo "add person'".$p->__toString()."'\n";
} }
private function createAddress(): Address private function createAddress(): Address
{ {
$loader = new NativeLoader(); $objectSet = $this->loader->loadData([
$objectSet = $loader->loadData([
Address::class => [ Address::class => [
'address' => [ 'address' => [
'street' => '<fr_FR:streetName()>', 'street' => '<fr_FR:streetName()>',
@ -285,6 +250,17 @@ class LoadPeople extends AbstractFixture implements OrderedFixtureInterface, Con
return $objectSet->getObjects()['address']; return $objectSet->getObjects()['address'];
} }
private function getRandomSocialIssue(): SocialIssue
{
if (0 === count($this->cacheSocialIssues)) {
$this->cacheSocialIssues = $this->socialIssueRepository->findAll();
}
return $this->cacheSocialIssues[\array_rand($this->cacheSocialIssues)];
}
private function getPostalCode(): PostalCode private function getPostalCode(): PostalCode
{ {
$ref = LoadPostalCodes::$refs[\array_rand(LoadPostalCodes::$refs)]; $ref = LoadPostalCodes::$refs[\array_rand(LoadPostalCodes::$refs)];
@ -306,7 +282,6 @@ class LoadPeople extends AbstractFixture implements OrderedFixtureInterface, Con
return Point::fromLonLat($lon, $lat); return Point::fromLonLat($lon, $lat);
} }
/** /**
* Create a random address * Create a random address
* *
@ -329,53 +304,77 @@ class LoadPeople extends AbstractFixture implements OrderedFixtureInterface, Con
; ;
} }
private function getCountry($countryCode) /**
* @internal This method is public and called by faker as a custom generator
* @return Center
*/
public function getRandomCenter(): Center
{ {
if ($countryCode === NULL) { if (0 === count($this->cacheCenters)) {
return NULL; $this->cacheCenters = $this->centerRepository->findAll();
} }
return $this->container->get('doctrine.orm.entity_manager')
->getRepository('ChillMainBundle:Country') return $this->cacheCenters[\array_rand($this->cacheCenters)];
->findOneByCountryCode($countryCode);
} }
private $maritalStatusRef = ['ms_single', 'ms_married', 'ms_widow', 'ms_separat', /**
'ms_divorce', 'ms_legalco', 'ms_unknown']; * @internal This method is public and called by faker as a custom generator
* @param int $nullPercentage
* @return Country|null
* @throws \Exception
*/
public function getRandomCountry(int $nullPercentage = 20): ?Country
{
if (0 === count($this->cacheCountries)) {
$this->cacheCountries = $this->countryRepository->findAll();
}
private $firstNamesMale = array("Jean", "Mohamed", "Alfred", "Robert", "Justin", "Brian", if ($nullPercentage < \random_int(0, 100)) {
"Compère", "Jean-de-Dieu", "Charles", "Pierre", "Luc", "Mathieu", "Alain", "Etienne", "Eric", return NULL;
"Corentin", "Gaston", "Spirou", "Fantasio", "Mahmadou", "Mohamidou", "Vursuv", "Youssef" ); }
private $firstNamesFemale = array("Svedana", "Sevlatina", "Irène", "Marcelle", return $this->cacheCountries [\array_rand($this->cacheCountries)];
"Corentine", "Alfonsine", "Caroline", "Solange", "Gostine", "Fatoumata", "Nicole", }
"Groseille", "Chana", "Oxana", "Ivana", "Julie", "Tina", "Adèle" );
private $lastNames = array("Diallo", "Bah", "Gaillot", "Martin"); /**
* @internal This method is public and called by faker as a custom generator
* @return string
*/
public function getRandomGender(): string
{
return $this->genders[array_rand($this->genders)];
}
private $lastNamesTrigrams = array("fas", "tré", "hu", 'blart', 'van', 'der', 'lin', 'den', /**
'ta', 'mi', 'net', 'gna', 'bol', 'sac', 'ré', 'jo', 'du', 'pont', 'cas', 'tor', 'rob', 'al', * @internal This method is public and called by faker as a custom generator
'ma', 'gone', 'car',"fu", "ka", "lot", "no", "va", "du", "bu", "su", "jau", "tte", 'sir', * @param int $nullPercentage
"lo", 'to', "cho", "car", 'mo','zu', 'qi', 'mu'); * @return MaritalStatus|null
* @throws \Exception
*/
public function getRandomMaritalStatus(int $nullPercentage = 50): ?MaritalStatus
{
if (0 === count($this->cacheMaritalStatuses)) {
$this->cacheMaritalStatuses = $this->maritalStatusRepository->findAll();
}
private $genders = array(Person::MALE_GENDER, Person::FEMALE_GENDER); if ($nullPercentage < \random_int(0, 100)) {
return NULL;
}
private $years = array(); return $this->cacheMaritalStatuses[array_rand($this->cacheMaritalStatuses)];
}
private $month = array(); private $genders = array(Person::MALE_GENDER, Person::FEMALE_GENDER, Person::BOTH_GENDER);
private $day = array();
private $peoples = array( private $peoples = array(
array( array(
'LastName' => "Depardieu", 'lastName' => "Depardieu",
'FirstName' => "Gérard", 'firstName' => "Gérard",
'Birthdate' => "1948-12-27", 'birthdate' => "1948-12-27",
'PlaceOfBirth' => "Châteauroux", 'placeOfBirth' => "Châteauroux",
'Gender' => Person::MALE_GENDER, 'nationality' => 'RU',
'CountryOfBirth' => 'FR', 'gender' => Person::MALE_GENDER,
'Nationality' => 'RU', 'center' => 'Center A',
'center' => 'centerA',
'maritalStatus' => 'ms_divorce',
'accompanyingPeriods' => [ 'accompanyingPeriods' => [
[ [
'from' => '2015-02-01', 'from' => '2015-02-01',
@ -394,67 +393,123 @@ class LoadPeople extends AbstractFixture implements OrderedFixtureInterface, Con
), ),
array( array(
//to have a person with same firstname as Gérard Depardieu //to have a person with same firstname as Gérard Depardieu
'LastName' => "Depardieu", 'lastName' => "Depardieu",
'FirstName' => "Jean", 'firstName' => "Jean",
'Birthdate' => "1960-10-12", 'birthdate' => "1960-10-12",
'CountryOfBirth' => 'FR', 'countryOfBirth' => 'FR',
'Nationality' => 'FR', 'nationality' => 'FR',
'center' => 'centerA', 'center' => 'Center A',
'maritalStatus' => 'ms_divorce' 'maritalStatus' => 'ms_divorce'
), ),
array( array(
//to have a person with same birthdate of Gérard Depardieu //to have a person with same birthdate of Gérard Depardieu
'LastName' => 'Van Snick', 'lastName' => 'Van Snick',
'FirstName' => 'Bart', 'firstName' => 'Bart',
'Birthdate' => '1948-12-27', 'birthdate' => '1948-12-27',
'center' => 'centerA', 'center' => 'Center A',
'maritalStatus' => 'ms_legalco' 'maritalStatus' => 'ms_legalco'
), ),
array( array(
//to have a woman with Depardieu as FirstName //to have a woman with Depardieu as FirstName
'LastName' => 'Depardieu', 'lastName' => 'Depardieu',
'FirstName' => 'Charline', 'firstName' => 'Charline',
'Gender' => Person::FEMALE_GENDER, 'gender' => Person::FEMALE_GENDER,
'center' => 'centerA', 'center' => 'Center A',
'maritalStatus' => 'ms_legalco' 'maritalStatus' => 'ms_legalco'
), ),
array( array(
//to have a special character in lastName //to have a special character in lastName
'LastName' => 'Manço', 'lastName' => 'Manço',
'FirstName' => 'Étienne', 'firstName' => 'Étienne',
'center' => 'centerA', 'center' => 'Center A',
'maritalStatus' => 'ms_unknown' 'maritalStatus' => 'ms_unknown'
), ),
array( array(
//to have true duplicate person //to have true duplicate person
'LastName' => "Depardieu", 'lastName' => "Depardieu",
'FirstName' => "Jean", 'firstName' => "Jean",
'Birthdate' => "1960-10-12", 'birthdate' => "1960-10-12",
'CountryOfBirth' => 'FR', 'countryOfBirth' => 'FR',
'Nationality' => 'FR', 'nationality' => 'FR',
'center' => 'centerA', 'center' => 'Center A',
'maritalStatus' => 'ms_divorce' 'maritalStatus' => 'ms_divorce'
), ),
array( array(
//to have false duplicate person //to have false duplicate person
'LastName' => "Depardieu", 'lastName' => "Depardieu",
'FirstName' => "Jeanne", 'firstName' => "Jeanne",
'Birthdate' => "1966-11-13", 'birthdate' => "1966-11-13",
'CountryOfBirth' => 'FR', 'countryOfBirth' => 'FR',
'Nationality' => 'FR', 'nationality' => 'FR',
'center' => 'centerA', 'center' => 'Center A',
'maritalStatus' => 'ms_legalco' 'maritalStatus' => 'ms_legalco'
), ),
[
'lastName' => 'Diallo',
'firstName' => "Fatoumata Binta"
],
[
'lastName' => 'Diallo',
'firstName' => 'Abdoulaye',
],
[
'lastName' => 'Diallo',
'firstName' => 'Diakite',
],
[
'lastName' => 'Diallo',
'firstName' => 'Mohamed',
],
[
'lastName' => 'Diallo',
'firstName' => 'Fatou',
],
[
'lastName' => 'Diallo',
'firstName' => 'Fanta',
],
[
'lastName' => 'Bah',
'firstName' => "Fatoumata Binta"
],
[
'lastName' => 'Bah',
'firstName' => 'Abdoulaye',
],
[
'lastName' => 'Bah',
'firstName' => 'Diakite',
],
[
'lastName' => 'Bah',
'firstName' => 'Mohamed',
],
[
'lastName' => 'Bah',
'firstName' => 'Fatou',
],
[
'lastName' => 'Bah',
'firstName' => 'Fanta',
],
[
'lastName' => 'Bah',
'firstName' => 'Gaston',
],
[
'lastName' => 'Gaillot',
'firstName' => 'Adèle',
],
); );
/*
private function addAccompanyingPeriods(Person $person, array $periods, ObjectManager $manager) private function addAccompanyingPeriods(Person $person, array $periods, ObjectManager $manager)
{ {
foreach ($periods as $period) { foreach ($periods as $period) {
echo "adding new past Accompanying Period..\n"; echo "adding new past Accompanying Period..\n";
/** @var AccompanyingPeriod $accompanyingPeriod */ /** @var AccompanyingPeriod $accompanyingPeriod
$accompanyingPeriod = new AccompanyingPeriod(new \DateTime($period['from'])); $accompanyingPeriod = new AccompanyingPeriod(new \DateTime($period['from']));
$accompanyingPeriod $accompanyingPeriod
->setClosingDate(new \DateTime($period['to'])) ->setClosingDate(new \DateTime($period['to']))
@ -464,4 +519,5 @@ class LoadPeople extends AbstractFixture implements OrderedFixtureInterface, Con
$person->addAccompanyingPeriod($accompanyingPeriod); $person->addAccompanyingPeriod($accompanyingPeriod);
} }
} }
*/
} }

View File

@ -167,7 +167,7 @@ class AccompanyingPeriodWorkEvaluationDocument implements \Chill\MainBundle\Doct
/** /**
* @return DateTimeImmutable|null * @return DateTimeImmutable|null
*/ */
public function getUpdatedAt(): ?DateTimeInterface public function getUpdatedAt(): ?\DateTimeInterface
{ {
return $this->updatedAt; return $this->updatedAt;
} }

View File

@ -0,0 +1,43 @@
<?php
namespace Chill\PersonBundle\Repository;
use Chill\PersonBundle\Entity\MaritalStatus;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use Doctrine\Persistence\ObjectRepository;
use UnexpectedValueException;
class MaritalStatusRepository implements ObjectRepository
{
private EntityRepository $repository;
public function __construct(EntityManagerInterface $entityManager)
{
$this->repository = $entityManager->getRepository(MaritalStatus::class);
}
public function find($id): ?MaritalStatus
{
return $this->repository->find($id);
}
public function findAll(): array
{
return $this->repository->findAll();
}
public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $offset = null): array
{
return $this->repository->findBy($criteria, $orderBy, $limit, $offset);
}
public function findOneBy(array $criteria): ?MaritalStatus
{
return $this->findOneBy($criteria);
}
public function getClassName(): string
{
return MaritalStatus::class;
}
}

View File

@ -6,15 +6,21 @@
<h1 v-else>{{ $t('course.title.active') }}</h1> <h1 v-else>{{ $t('course.title.active') }}</h1>
<persons-associated></persons-associated> <persons-associated></persons-associated>
<course-location></course-location>
<origin-demand></origin-demand> <origin-demand></origin-demand>
<requestor></requestor> <requestor></requestor>
<social-issue></social-issue> <social-issue></social-issue>
<course-location></course-location>
<referrer></referrer> <referrer></referrer>
<resources></resources> <resources></resources>
<comment v-if="accompanyingCourse.step === 'DRAFT'"></comment> <comment v-if="accompanyingCourse.step === 'DRAFT'"></comment>
<confirm v-if="accompanyingCourse.step === 'DRAFT'"></confirm> <confirm v-if="accompanyingCourse.step === 'DRAFT'"></confirm>
<div v-for="error in errorMsg" class="vue-component errors alert alert-danger">
<p>
<span>{{ error.sta }} {{ error.txt }}</span><br>
<span>{{ $t(error.msg) }}</span>
</p>
</div>
</template> </template>
<script> <script>
@ -48,7 +54,8 @@ export default {
}, },
computed: mapState([ computed: mapState([
'accompanyingCourse', 'accompanyingCourse',
'addressContext' 'addressContext',
'errorMsg'
]) ])
}; };
</script> </script>
@ -89,6 +96,16 @@ export default {
} }
table { table {
} }
&.errors {
//display: flex;
//position: sticky;
//bottom: 0.3em;
//z-index: 1000;
margin: 1em 0;
padding: 1em;
border-radius: 0;
}
} }
} }
</style> </style>

View File

@ -9,7 +9,7 @@ const getAccompanyingCourse = (id) => {
return fetch(url) return fetch(url)
.then(response => { .then(response => {
if (response.ok) { return response.json(); } if (response.ok) { return response.json(); }
throw Error('Error with request resource response'); throw { msg: 'Error while retriving AccompanyingPeriod Course.', sta: response.status, txt: response.statusText, err: new Error(), body: response.body };
}); });
}; };
@ -32,7 +32,8 @@ const patchAccompanyingCourse = (id, body) => {
}) })
.then(response => { .then(response => {
if (response.ok) { return response.json(); } if (response.ok) { return response.json(); }
throw Error('Error with request resource response'); console.log(response);
throw { msg: 'Error while updating AccompanyingPeriod Course.', sta: response.status, txt: response.statusText, err: new Error(), body: response.body };
}); });
}; };
@ -47,7 +48,7 @@ const confirmAccompanyingCourse = (id) => {
}) })
.then(response => { .then(response => {
if (response.ok) { return response.json(); } if (response.ok) { return response.json(); }
throw Error('Error with request resource response'); throw { msg: 'Error while confirming AccompanyingPeriod Course.', sta: response.status, txt: response.statusText, err: new Error(), body: response.body };
}); });
}; };
@ -59,7 +60,7 @@ const getSocialIssues = () => {
return fetch(url) return fetch(url)
.then(response => { .then(response => {
if (response.ok) { return response.json(); } if (response.ok) { return response.json(); }
throw Error('Error with request resource response'); throw { msg: 'Error while retriving Social Issues.', sta: response.status, txt: response.statusText, err: new Error(), body: response.body };
}); });
}; };
@ -83,7 +84,7 @@ const postParticipation = (id, payload, method) => {
}) })
.then(response => { .then(response => {
if (response.ok) { return response.json(); } if (response.ok) { return response.json(); }
throw Error('Error with request resource response'); throw { msg: 'Error while sending AccompanyingPeriod Course participation.', sta: response.status, txt: response.statusText, err: new Error(), body: response.body };
}); });
}; };
@ -109,7 +110,7 @@ const postRequestor = (id, payload, method) => {
}) })
.then(response => { .then(response => {
if (response.ok) { return response.json(); } if (response.ok) { return response.json(); }
throw Error('Error with request resource response'); throw { msg: 'Error while sending AccompanyingPeriod Course requestor', sta: response.status, txt: response.statusText, err: new Error(), body: response.body };
}); });
}; };
@ -142,7 +143,7 @@ const postResource = (id, payload, method) => {
}) })
.then(response => { .then(response => {
if (response.ok) { return response.json(); } if (response.ok) { return response.json(); }
throw Error('Error with request resource response'); throw { msg: 'Error while sending AccompanyingPeriod Course resource.', sta: response.status, txt: response.statusText, err: new Error(), body: response.body };
}); });
}; };
@ -161,7 +162,7 @@ const postSocialIssue = (id, body, method) => {
}) })
.then(response => { .then(response => {
if (response.ok) { return response.json(); } if (response.ok) { return response.json(); }
throw Error('Error with request resource response'); throw { msg: 'Error while updating SocialIssue.', sta: response.status, txt: response.statusText, err: new Error(), body: response.body };
}); });
}; };
@ -170,7 +171,7 @@ const getUsers = () => {
return fetch(url) return fetch(url)
.then(response => { .then(response => {
if (response.ok) { return response.json(); } if (response.ok) { return response.json(); }
throw Error('Error with request resource response'); throw { msg: 'Error while retriving users.', sta: response.status, txt: response.statusText, err: new Error(), body: response.body };
}); });
}; };
@ -179,7 +180,7 @@ const whoami = () => {
return fetch(url) return fetch(url)
.then(response => { .then(response => {
if (response.ok) { return response.json(); } if (response.ok) { return response.json(); }
throw Error('Error with request resource response'); throw { msg: 'Error while getting whoami.', sta: response.status, txt: response.statusText, err: new Error(), body: response.body };
}); });
}; };
@ -188,7 +189,7 @@ const getListOrigins = () => {
return fetch(url) return fetch(url)
.then(response => { .then(response => {
if (response.ok) { return response.json(); } if (response.ok) { return response.json(); }
throw Error('Error with request resource response'); throw { msg: 'Error while retriving origin\'s list.', sta: response.status, txt: response.statusText, err: new Error(), body: response.body };
}); });
} }

View File

@ -60,7 +60,7 @@ export default {
personId: this.person.id personId: this.person.id
}; };
this.$store.dispatch('updateLocation', payload); this.$store.dispatch('updateLocation', payload);
window.location.assign('#section-50'); window.location.assign('#section-20');
this.modal.showModal = false; this.modal.showModal = false;
} }
} }

View File

@ -27,17 +27,19 @@
]) }} ]) }}
</div> </div>
<ul class="record_actions"> <div>
<li> <ul class="record_actions">
<button type="submit" class="btn btn-save">{{ $t('action.save') }}</button> <li>
</li> <button type="submit" class="btn btn-save">{{ $t('action.save') }}</button>
<li v-if="initialComment !== null"> </li>
<a class="btn btn-delete" <li v-if="initialComment !== null">
@click="removeComment"> <a class="btn btn-delete"
{{ $t('action.delete') }} @click="removeComment">
</a> {{ $t('action.delete') }}
</li> </a>
</ul> </li>
</ul>
</div>
</form> </form>
</div> </div>

View File

@ -3,24 +3,43 @@
<h2><a name="section-90"></a> <h2><a name="section-90"></a>
{{ $t('confirm.title') }} {{ $t('confirm.title') }}
</h2> </h2>
<div> <div>
<p> <p v-html="$t('confirm.text_draft', [$t('course.step.draft')])"></p>
{{ $t('confirm.text_draft') }}
<span class="badge bg-secondary">{{ $t('course.step.draft') }}</span> <div v-if="!isValidToBeConfirmed">
</p> <div class="alert alert-warning">
<p> {{ $t('confirm.alert_validation') }}
{{ $t('confirm.text_active') }} <ul class="mt-2">
<span class="badge bg-primary">{{ $t('course.step.active') }}</span> <li v-for="k in validationKeys">
</p> {{ $t(notValidMessages[k].msg) }}
<a :href="notValidMessages[k].anchor">
<i class="fa fa-level-up fa-fw"></i>
</a>
</li>
</ul>
</div>
<ul class="record_actions">
<li>
<button class="btn btn-save" disabled>
{{ $t('confirm.ok') }}
</button>
</li>
</ul>
</div>
<div v-else>
<p v-html="$t('confirm.text_active', [$t('course.step.active')])"></p>
<ul class="record_actions">
<li>
<button
class="btn btn-save"
@click="modal.showModal = true">
{{ $t('confirm.ok') }}
</button>
</li>
</ul>
</div>
<ul class="record_actions">
<li>
<button class="btn btn-save" @click="modal.showModal = true">
{{ $t('confirm.ok') }}
</button>
</li>
</ul>
</div> </div>
<teleport to="body"> <teleport to="body">
@ -43,6 +62,7 @@
</template> </template>
<script> <script>
import {mapGetters, mapState} from "vuex";
import Modal from 'ChillMainAssets/vuejs/_components/Modal'; import Modal from 'ChillMainAssets/vuejs/_components/Modal';
export default { export default {
@ -55,13 +75,34 @@ export default {
modal: { modal: {
showModal: false, showModal: false,
modalDialogClass: "modal-dialog-centered modal-md" modalDialogClass: "modal-dialog-centered modal-md"
},
notValidMessages: {
participation: {
msg: 'confirm.participation_not_valid',
anchor: '#section-10'
},
location: {
msg: 'confirm.location_not_valid',
anchor: '#section-20' //
},
socialIssue: {
msg: 'confirm.socialIssue_not_valid',
anchor: '#section-50'
}
} }
} }
}, },
computed: { computed: {
accompanyingCourse() { ...mapState([
return this.$store.state.accompanyingCourse 'accompanyingCourse'
} ]),
...mapGetters([
'isParticipationValid',
'isSocialIssueValid',
'isLocationValid',
'validationKeys',
'isValidToBeConfirmed'
])
}, },
methods: { methods: {
confirmCourse() { confirmCourse() {
@ -72,9 +113,3 @@ export default {
} }
} }
</script> </script>
<style lang="scss" scoped>
div.vue-component > div {
//margin: 1em;
}
</style>

View File

@ -1,28 +1,36 @@
<template> <template>
<div class="vue-component"> <div class="vue-component">
<h2><a name="section-50"></a> <h2><a name="section-20"></a>
{{ $t('courselocation.title') }} {{ $t('courselocation.title') }}
</h2> </h2>
<div class="my-4">
<!-- {# include vue_address component #} --> <!-- {# include vue_address component #} -->
<div v-for="error in displayErrors" class="alert alert-danger my-2"> <div v-for="error in displayErrors" class="alert alert-danger my-2">
{{ error }} {{ error }}
</div> </div>
<show-address <div v-if="hasNoLocation">
v-if="accompanyingCourse.location" <label class="chill-no-data-statement">
:address="accompanyingCourse.location"> {{ $t('courselocation.no_address') }}
</show-address> </label>
</div>
<div v-if="isPersonLocation" class="alert alert-success"> <div v-if="isPersonLocation">
<label class="col-form-label">
{{ $t('courselocation.person_locator', [ accompanyingCourse.personLocation.text ]) }} {{ $t('courselocation.person_locator', [ accompanyingCourse.personLocation.text ]) }}
</div> </label>
</div>
<div v-if="isTemporaryAddress" class="alert alert-warning"> <show-address
<p>{{ $t('courselocation.temporary_address_must_be_changed') }}</p> v-if="accompanyingCourse.location"
</div> :address="accompanyingCourse.location">
</show-address>
<div v-if="isTemporaryAddress" class="alert alert-warning">
<p>{{ $t('courselocation.temporary_address_must_be_changed') }}</p>
</div>
<div>
<ul class="record_actions"> <ul class="record_actions">
<li> <li>
<add-address <add-address
@ -43,8 +51,8 @@
</button> </button>
</li> </li>
</ul> </ul>
</div> </div>
</div> </div>
</template> </template>
@ -96,6 +104,9 @@ export default {
isPersonLocation() { isPersonLocation() {
return this.accompanyingCourse.locationStatus === 'person'; return this.accompanyingCourse.locationStatus === 'person';
}, },
hasNoLocation() {
return this.accompanyingCourse.locationStatus === 'none';
},
isContextEdit() { isContextEdit() {
return this.context.edit; return this.context.edit;
} }

View File

@ -1,8 +1,8 @@
<template> <template>
<div class="vue-component"> <div class="vue-component">
<h2><a name="section-20"></a>{{ $t('origin.title') }}</h2> <h2><a name="section-30"></a>{{ $t('origin.title') }}</h2>
<div class="my-4"> <div class="mb-4">
<label for="selectOrigin"> <label for="selectOrigin">
{{ $t('origin.label') }} {{ $t('origin.label') }}
</label> </label>

View File

@ -2,9 +2,12 @@
<div class="vue-component"> <div class="vue-component">
<h2><a name="section-10"></a>{{ $t('persons_associated.title')}}</h2> <h2><a name="section-10"></a>{{ $t('persons_associated.title')}}</h2>
<div> <div v-if="participations.length > 0">
<label class="col-form-label">{{ $tc('persons_associated.counter', counter) }}</label> <label class="col-form-label">{{ $tc('persons_associated.counter', counter) }}</label>
</div> </div>
<div v-else>
<label class="chill-no-data-statement">{{ $tc('persons_associated.counter', counter) }}</label>
</div>
<table class="table table-bordered table-striped border-dark align-middle" v-if="participations.length > 0"> <table class="table table-bordered table-striped border-dark align-middle" v-if="participations.length > 0">
<thead> <thead>

View File

@ -2,7 +2,7 @@
<div class="vue-component"> <div class="vue-component">
<h2><a name="section-60"></a>{{ $t('referrer.title') }}</h2> <h2><a name="section-60"></a>{{ $t('referrer.title') }}</h2>
<div class="my-4"> <div>
<label class="col-form-label" for="selectReferrer"> <label class="col-form-label" for="selectReferrer">
{{ $t('referrer.label') }} {{ $t('referrer.label') }}
</label> </label>
@ -18,7 +18,9 @@
v-bind:options="options" v-bind:options="options"
@select="updateReferrer"> @select="updateReferrer">
</VueMultiselect> </VueMultiselect>
</div>
<div>
<ul class="record_actions"> <ul class="record_actions">
<li> <li>
<button <button
@ -30,8 +32,8 @@
</button> </button>
</li> </li>
</ul> </ul>
</div> </div>
</div> </div>
</template> </template>

View File

@ -1,12 +1,12 @@
<template> <template>
<div class="vue-component"> <div class="vue-component">
<h2><a name="section-30"></a>{{ $t('requestor.title') }}</h2> <h2><a name="section-40"></a>{{ $t('requestor.title') }}</h2>
<div v-if="accompanyingCourse.requestor" class="flex-table"> <div v-if="accompanyingCourse.requestor" class="flex-table">
<label> <label>
<input type="checkbox" v-model="isAnonymous" class="me-2" /><!-- :value="value" --> <input type="checkbox" v-model="isAnonymous" class="me-2" />
{{ $t('requestor.is_anonymous') }} {{ $t('requestor.is_anonymous') }}
</label> </label>
@ -67,7 +67,7 @@
</ul> </ul>
</div> </div>
<div v-else> <div v-else>
<label>{{ $t('requestor.counter') }}</label> <label class="chill-no-data-statement">{{ $t('requestor.counter') }}</label>
</div> </div>
<div> <div>

View File

@ -3,9 +3,12 @@
<h2><a name="section-70"></a>{{ $t('resources.title')}}</h2> <h2><a name="section-70"></a>{{ $t('resources.title')}}</h2>
<div> <div v-if="resources.length > 0">
<label class="col-form-label">{{ $tc('resources.counter', counter) }}</label> <label class="col-form-label">{{ $tc('resources.counter', counter) }}</label>
</div> </div>
<div v-else>
<label class="chill-no-data-statement">{{ $tc('resources.counter', counter) }}</label>
</div>
<table class="table table-bordered table-striped border-dark align-middle" v-if="resources.length > 0"> <table class="table table-bordered table-striped border-dark align-middle" v-if="resources.length > 0">
<thead> <thead>

View File

@ -64,7 +64,7 @@ export default {
emits: ['remove'], emits: ['remove'],
computed: { computed: {
hasCurrentHouseholdAddress() { hasCurrentHouseholdAddress() {
if ( !this.resource.resource.type === 'person' if ( this.resource.resource.type === 'person'
&& this.resource.resource.current_household_address !== null ) { && this.resource.resource.current_household_address !== null ) {
return true; return true;
} }

View File

@ -1,6 +1,6 @@
<template> <template>
<div class="vue-component"> <div class="vue-component">
<h2><a name="section-40"></a>{{ $t('social_issue.title') }}</h2> <h2><a name="section-50"></a>{{ $t('social_issue.title') }}</h2>
<div class="my-4"> <div class="my-4">
<!--label for="field">{{ $t('social_issue.label') }}</label <!--label for="field">{{ $t('social_issue.label') }}</label

View File

@ -34,7 +34,7 @@ const appMessages = {
}, },
persons_associated: { persons_associated: {
title: "Usagers concernés", title: "Usagers concernés",
counter: "Il n'y a pas encore d'usager | 1 usager | {count} usagers", counter: "Il n'y a pas encore d'usagers | 1 usager | {count} usagers",
firstname: "Prénom", firstname: "Prénom",
lastname: "Nom", lastname: "Nom",
name: "Nom", name: "Nom",
@ -70,11 +70,12 @@ const appMessages = {
edit_temporary_address: "Modifier l'adresse temporaire", edit_temporary_address: "Modifier l'adresse temporaire",
assign_course_address: "Désigner comme l'adresse du parcours", assign_course_address: "Désigner comme l'adresse du parcours",
remove_button: "Enlever l'adresse", remove_button: "Enlever l'adresse",
temporary_address_must_be_changed: "Cette addresse est temporaire et doit être remplacée par celle d'un usager de référence.", temporary_address_must_be_changed: "Cette addresse est temporaire et devrait être remplacée par celle d'un usager de référence.",
sure: "Êtes-vous sûr ?", sure: "Êtes-vous sûr ?",
sure_description: "Voulez-vous faire de cette adresse l'adresse du parcours ?", sure_description: "Voulez-vous faire de cette adresse l'adresse du parcours ?",
ok: "Désigner comme adresse du parcours", ok: "Désigner comme adresse du parcours",
person_locator: "Parcours localisé auprès de {0}", person_locator: "Parcours localisé auprès de {0}",
no_address: "Il n'y a pas d'adresse associée au parcours"
}, },
referrer: { referrer: {
title: "Référent du parcours", title: "Référent du parcours",
@ -97,13 +98,28 @@ const appMessages = {
}, },
confirm: { confirm: {
title: "Confirmation", title: "Confirmation",
text_draft: "Le parcours est actuellement à l'état de ", text_draft: "Le parcours est actuellement à l'état de <b>{0}</b>.",
text_active: "En validant cette étape, vous lui donnez le statut ", text_active: "En validant cette étape, vous lui donnez le statut <b>{0}</b>.",
alert_validation: "Certaines conditions ne sont pas remplies pour pouvoir confirmer le parcours :",
participation_not_valid: "sélectionnez au minimum 1 usager",
socialIssue_not_valid: "sélectionnez au minimum une problématique sociale",
location_not_valid: "indiquez au minimum une localisation temporaire du parcours",
sure: "Êtes-vous sûr ?", sure: "Êtes-vous sûr ?",
sure_description: "Une fois le changement confirmé, il n'est plus possible de le remettre à l'état de brouillon !", sure_description: "Une fois le changement confirmé, il ne sera plus possible de le remettre à l'état de brouillon !",
ok: "Confirmer le parcours" ok: "Confirmer le parcours"
}, },
// catch errors
'Error while updating AccompanyingPeriod Course.': "Erreur du serveur lors de la mise à jour du parcours d'accompagnement.",
'Error while retriving AccompanyingPeriod Course.': "Erreur du serveur lors du chargement du parcours d'accompagnement.",
'Error while confirming AccompanyingPeriod Course.': "Erreur du serveur lors de la confirmation du parcours d'accompagnement.",
'Error while retriving Social Issues.': "Erreur du serveur lors du chargement des problématique sociales.",
'Error while sending AccompanyingPeriod Course participation.': "Erreur du serveur lors de l'envoi des infos d'un usager.",
'Error while sending AccompanyingPeriod Course requestor': "Erreur du serveur lors de l'envoi des infos du demandeur.",
'Error while sending AccompanyingPeriod Course resource.': "Erreur du serveur lors de l'envoi des infos d'un interlocuteur privilégié.",
'Error while updating SocialIssue.': "Erreur du serveur lors de la mise à jour d'une problématique sociale.",
'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 retriving origin\'s list.': "Erreur du serveur lors du chargement de la liste des origines de la demande.",
} }
}; };

View File

@ -25,9 +25,33 @@ let initPromise = getAccompanyingCourse(id)
errorMsg: [] errorMsg: []
}, },
getters: { getters: {
isParticipationValid(state) {
return state.accompanyingCourse.participations.length > 0;
},
isSocialIssueValid(state) {
return state.accompanyingCourse.socialIssues.length > 0;
},
isLocationValid(state) {
return state.accompanyingCourse.location !== null;
},
validationKeys(state, getters) {
let keys = [];
if (!getters.isParticipationValid) { keys.push('participation'); }
if (!getters.isLocationValid) { keys.push('location'); }
if (!getters.isSocialIssueValid) { keys.push('socialIssue'); }
//console.log('getter keys', keys);
return keys;
},
isValidToBeConfirmed(state, getters) {
if (getters.validationKeys.length === 0) {
return true;
}
return false;
}
}, },
mutations: { mutations: {
catchError(state, error) { catchError(state, error) {
console.log('### mutation: a new error have been catched and pushed in store !', error);
state.errorMsg.push(error); state.errorMsg.push(error);
}, },
removeParticipation(state, participation) { removeParticipation(state, participation) {

View File

@ -3,7 +3,7 @@
/* /*
* Chill is a software for social workers * Chill is a software for social workers
* *
* Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS, * Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS,
* <http://www.champs-libres.coop>, <info@champs-libres.coop> * <http://www.champs-libres.coop>, <info@champs-libres.coop>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
@ -42,7 +42,7 @@ class PersonControllerCreateTest extends WebTestCase
const BIRTHDATE_INPUT = "chill_personbundle_person_creation[birthdate]"; const BIRTHDATE_INPUT = "chill_personbundle_person_creation[birthdate]";
const CREATEDATE_INPUT = "chill_personbundle_person_creation[creation_date]"; const CREATEDATE_INPUT = "chill_personbundle_person_creation[creation_date]";
const CENTER_INPUT = "chill_personbundle_person_creation[center]"; const CENTER_INPUT = "chill_personbundle_person_creation[center]";
const LONG_TEXT = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta. Mauris massa. Vestibulum lacinia arcu eget nulla. Class aptent taciti sociosq. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta.Mauris massa. Vestibulum lacinia arcu eget nulla. Class aptent taciti sociosq."; const LONG_TEXT = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta. Mauris massa. Vestibulum lacinia arcu eget nulla. Class aptent taciti sociosq. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta.Mauris massa. Vestibulum lacinia arcu eget nulla. Class aptent taciti sociosq.";
public function setUp(): void public function setUp(): void
@ -51,7 +51,7 @@ class PersonControllerCreateTest extends WebTestCase
} }
/** /**
* *
* @param Form $creationForm * @param Form $creationForm
*/ */
private function fillAValidCreationForm( private function fillAValidCreationForm(
@ -64,26 +64,26 @@ class PersonControllerCreateTest extends WebTestCase
$creationForm->get(self::GENDER_INPUT)->select("man"); $creationForm->get(self::GENDER_INPUT)->select("man");
$date = new \DateTime('1947-02-01'); $date = new \DateTime('1947-02-01');
$creationForm->get(self::BIRTHDATE_INPUT)->setValue($date->format('d-m-Y')); $creationForm->get(self::BIRTHDATE_INPUT)->setValue($date->format('d-m-Y'));
return $creationForm; return $creationForm;
} }
/** /**
* Test the "add a person" page : test that required elements are present * Test the "add a person" page : test that required elements are present
* *
* see https://redmine.champs-libres.coop/projects/chillperson/wiki/Test_plan_for_page_%22add_a_person%22 * see https://redmine.champs-libres.coop/projects/chillperson/wiki/Test_plan_for_page_%22add_a_person%22
*/ */
public function testAddAPersonPage() public function testAddAPersonPage()
{ {
$client = $this->client; $client = $this->client;
$crawler = $client->request('GET', '/fr/person/new'); $crawler = $client->request('GET', '/fr/person/new');
$this->assertTrue($client->getResponse()->isSuccessful(), $this->assertTrue($client->getResponse()->isSuccessful(),
"The page is accessible at the URL /{_locale}/person/new"); "The page is accessible at the URL /{_locale}/person/new");
$form = $crawler->selectButton("Ajouter la personne")->form(); $form = $crawler->selectButton("Ajouter la personne")->form();
$this->assertInstanceOf('Symfony\Component\DomCrawler\Form', $form, $this->assertInstanceOf('Symfony\Component\DomCrawler\Form', $form,
'The page contains a butto '); 'The page contains a butto ');
$this->assertTrue($form->has(self::FIRSTNAME_INPUT), $this->assertTrue($form->has(self::FIRSTNAME_INPUT),
'The page contains a "firstname" input'); 'The page contains a "firstname" input');
@ -91,27 +91,27 @@ class PersonControllerCreateTest extends WebTestCase
'The page contains a "lastname" input'); 'The page contains a "lastname" input');
$this->assertTrue($form->has(self::GENDER_INPUT), $this->assertTrue($form->has(self::GENDER_INPUT),
'The page contains a "gender" input'); 'The page contains a "gender" input');
$this->assertTrue($form->has(self::BIRTHDATE_INPUT), $this->assertTrue($form->has(self::BIRTHDATE_INPUT),
'The page has a "date of birth" input'); 'The page has a "date of birth" input');
$genderType = $form->get(self::GENDER_INPUT); $genderType = $form->get(self::GENDER_INPUT);
$this->assertEquals('radio', $genderType->getType(), $this->assertEquals('radio', $genderType->getType(),
'The gender input has radio buttons'); 'The gender input has radio buttons');
$this->assertEquals(3, count($genderType->availableOptionValues()), $this->assertEquals(3, count($genderType->availableOptionValues()),
'The gender input has three options: man, women and undefined'); 'The gender input has three options: man, women and undefined');
$this->assertTrue(in_array('man', $genderType->availableOptionValues()), $this->assertTrue(in_array('man', $genderType->availableOptionValues()),
'gender has "homme" option'); 'gender has "homme" option');
$this->assertTrue(in_array('woman', $genderType->availableOptionValues()), $this->assertTrue(in_array('woman', $genderType->availableOptionValues()),
'gender has "femme" option'); 'gender has "femme" option');
$this->assertFalse($genderType->hasValue(), 'The gender input is not checked'); $this->assertFalse($genderType->hasValue(), 'The gender input is not checked');
return $form; return $form;
} }
/** /**
* Test the creation of a valid person. * Test the creation of a valid person.
* *
* @param Form $form * @param Form $form
* @return string The id of the created person * @return string The id of the created person
* @depends testAddAPersonPage * @depends testAddAPersonPage
@ -125,9 +125,9 @@ class PersonControllerCreateTest extends WebTestCase
$this->assertTrue((bool)$client->getResponse()->isRedirect(), $this->assertTrue((bool)$client->getResponse()->isRedirect(),
"a valid form redirect to url /{_locale}/person/{personId}/general/edit"); "a valid form redirect to url /{_locale}/person/{personId}/general/edit");
$client->followRedirect(); $client->followRedirect();
// visualize regexp here : http://jex.im/regulex/#!embed=false&flags=&re=%2Ffr%2Fperson%2F[1-9][0-9]*%2Fgeneral%2Fedit%24 // visualize regexp here : http://jex.im/regulex/#!embed=false&flags=&re=%2Ffr%2Fperson%2F[1-9][0-9]*%2Fgeneral%2Fedit%24
$this->assertRegExp('|/fr/person/[1-9][0-9]*/general/edit$|', $this->assertRegExp('|/fr/person/[1-9][0-9]*/general/edit$|',
$client->getHistory()->current()->getUri(), $client->getHistory()->current()->getUri(),
"a valid form redirect to url /{_locale}/person/{personId}/general/edit"); "a valid form redirect to url /{_locale}/person/{personId}/general/edit");
@ -149,11 +149,11 @@ class PersonControllerCreateTest extends WebTestCase
$client = $this->client; $client = $this->client;
$client->request('GET', '/fr/person/'.$personId.'/general'); $client->request('GET', '/fr/person/'.$personId.'/general');
$this->assertTrue($client->getResponse()->isSuccessful(), $this->assertTrue($client->getResponse()->isSuccessful(),
"The person view page is accessible at the URL" "The person view page is accessible at the URL"
. "/{_locale}/person/{personID}/general"); . "/{_locale}/person/{personID}/general");
} }
/** /**
* test adding a person with a user with multi center * test adding a person with a user with multi center
* is valid * is valid
@ -161,70 +161,71 @@ class PersonControllerCreateTest extends WebTestCase
public function testValidFormWithMultiCenterUser() public function testValidFormWithMultiCenterUser()
{ {
$client = $this->getClientAuthenticated('multi_center'); $client = $this->getClientAuthenticated('multi_center');
$crawler = $client->request('GET', '/fr/person/new'); $crawler = $client->request('GET', '/fr/person/new');
$this->assertTrue($client->getResponse()->isSuccessful(), $this->assertTrue($client->getResponse()->isSuccessful(),
"The page is accessible at the URL /{_locale}/person/new"); "The page is accessible at the URL /{_locale}/person/new");
$form = $crawler->selectButton("Ajouter la personne")->form(); $form = $crawler->selectButton("Ajouter la personne")->form();
$this->fillAValidCreationForm($form, 'roger', 'rabbit'); // create a very long name to avoid collision
$this->fillAValidCreationForm($form, 'Carmela Girdana Assuntamente Castalle', 'rabbit');
$this->assertTrue($form->has(self::CENTER_INPUT), $this->assertTrue($form->has(self::CENTER_INPUT),
'The page contains a "center" input'); 'The page contains a "center" input');
$centerInput = $form->get(self::CENTER_INPUT); $centerInput = $form->get(self::CENTER_INPUT);
$availableValues = $centerInput->availableOptionValues(); $availableValues = $centerInput->availableOptionValues();
$lastCenterInputValue = end($availableValues); $lastCenterInputValue = end($availableValues);
$centerInput->setValue($lastCenterInputValue); $centerInput->setValue($lastCenterInputValue);
$client->submit($form); $client->submit($form);
$this->assertTrue($client->getResponse()->isRedirect(), $this->assertTrue($client->getResponse()->isRedirect(),
"a valid form redirect to url /{_locale}/person/{personId}/general/edit"); "a valid form redirect to url /{_locale}/person/{personId}/general/edit");
$client->followRedirect(); $client->followRedirect();
$this->assertRegExp('|/fr/person/[1-9][0-9]*/general/edit$|', $this->assertRegExp('|/fr/person/[1-9][0-9]*/general/edit$|',
$client->getHistory()->current()->getUri(), $client->getHistory()->current()->getUri(),
"a valid form redirect to url /{_locale}/person/{personId}/general/edit"); "a valid form redirect to url /{_locale}/person/{personId}/general/edit");
} }
public function testReviewExistingDetectionInversedLastNameWithFirstName() public function testReviewExistingDetectionInversedLastNameWithFirstName()
{ {
$client = $this->client; $client = $this->client;
$crawler = $client->request('GET', '/fr/person/new'); $crawler = $client->request('GET', '/fr/person/new');
//test the page is loaded before continuing //test the page is loaded before continuing
$this->assertTrue($client->getResponse()->isSuccessful()); $this->assertTrue($client->getResponse()->isSuccessful());
$form = $crawler->selectButton("Ajouter la personne")->form(); $form = $crawler->selectButton("Ajouter la personne")->form();
$form = $this->fillAValidCreationForm($form, 'Charline', 'dd'); $form = $this->fillAValidCreationForm($form, 'Charline', 'dd');
$client->submit($form); $client->submit($form);
$this->assertContains('Depardieu', $client->getCrawler()->text(), $this->assertContains('Depardieu', $client->getCrawler()->text(),
"check that the page has detected the lastname of a person existing in database"); "check that the page has detected the lastname of a person existing in database");
//inversion //inversion
$form = $crawler->selectButton("Ajouter la personne")->form(); $form = $crawler->selectButton("Ajouter la personne")->form();
$form = $this->fillAValidCreationForm($form, 'dd', 'Charline'); $form = $this->fillAValidCreationForm($form, 'dd', 'Charline');
$client->submit($form); $client->submit($form);
$this->assertContains('Depardieu', $client->getCrawler()->text(), $this->assertContains('Depardieu', $client->getCrawler()->text(),
"check that the page has detected the lastname of a person existing in database"); "check that the page has detected the lastname of a person existing in database");
} }
public static function tearDownAfterClass() public static function tearDownAfterClass()
{ {
static::bootKernel(); static::bootKernel();
$em = static::$kernel->getContainer()->get('doctrine.orm.entity_manager'); $em = static::$kernel->getContainer()->get('doctrine.orm.entity_manager');
//remove two people created during test //remove two people created during test
$jesus = $em->getRepository('ChillPersonBundle:Person') $jesus = $em->getRepository('ChillPersonBundle:Person')
->findOneBy(array('firstName' => 'God')); ->findOneBy(array('firstName' => 'God'));
if ($jesus !== NULL) { if ($jesus !== NULL) {
$em->remove($jesus); $em->remove($jesus);
} }
$jesus2 = $em->getRepository('ChillPersonBundle:Person') $jesus2 = $em->getRepository('ChillPersonBundle:Person')
->findOneBy(array('firstName' => 'roger')); ->findOneBy(array('firstName' => 'roger'));
if ($jesus2 !== NULL) { if ($jesus2 !== NULL) {

View File

@ -33,165 +33,165 @@ class PersonSearchTest extends WebTestCase
public function testExpected() public function testExpected()
{ {
$client = $this->getAuthenticatedClient(); $client = $this->getAuthenticatedClient();
$crawler = $client->request('GET', '/fr/search', array( $crawler = $client->request('GET', '/fr/search', array(
'q' => '@person Depardieu' 'q' => '@person Depardieu'
)); ));
$this->assertRegExp('/Depardieu/', $crawler->filter('.list-with-period')->text()); $this->assertRegExp('/Depardieu/', $crawler->filter('.list-with-period')->text());
} }
public function testExpectedNamed() public function testExpectedNamed()
{ {
$client = $this->getAuthenticatedClient(); $client = $this->getAuthenticatedClient();
$crawler = $client->request('GET', '/fr/search', array( $crawler = $client->request('GET', '/fr/search', array(
'q' => '@person Depardieu', 'name' => 'person_regular' 'q' => '@person Depardieu', 'name' => 'person_regular'
)); ));
$this->assertRegExp('/Depardieu/', $crawler->filter('.list-with-period')->text()); $this->assertRegExp('/Depardieu/', $crawler->filter('.list-with-period')->text());
} }
public function testSearchByLastName() public function testSearchByLastName()
{ {
$crawler = $this->generateCrawlerForSearch('@person lastname:Depardieu'); $crawler = $this->generateCrawlerForSearch('@person lastname:Depardieu');
$this->assertRegExp('/Depardieu/', $crawler->filter('.list-with-period')->text()); $this->assertRegExp('/Depardieu/', $crawler->filter('.list-with-period')->text());
} }
public function testSearchByFirstNameLower() public function testSearchByFirstNameLower()
{ {
$crawler = $this->generateCrawlerForSearch('@person firstname:Gérard'); $crawler = $this->generateCrawlerForSearch('@person firstname:Gérard');
$this->assertRegExp('/Depardieu/', $crawler->filter('.list-with-period')->text()); $this->assertRegExp('/Depardieu/', $crawler->filter('.list-with-period')->text());
} }
public function testSearchByFirstNamePartim() public function testSearchByFirstNamePartim()
{ {
$crawler = $this->generateCrawlerForSearch('@person firstname:Ger'); $crawler = $this->generateCrawlerForSearch('@person firstname:Ger');
$this->assertRegExp('/Depardieu/', $crawler->filter('.list-with-period')->text()); $this->assertRegExp('/Depardieu/', $crawler->filter('.list-with-period')->text());
} }
public function testLastNameAccentued() public function testLastNameAccentued()
{ {
$crawlerSpecial = $this->generateCrawlerForSearch('@person lastname:manço'); $crawlerSpecial = $this->generateCrawlerForSearch('@person lastname:manço');
$this->assertRegExp('/Manço/', $crawlerSpecial->filter('.list-with-period')->text()); $this->assertRegExp('/Manço/', $crawlerSpecial->filter('.list-with-period')->text());
$crawlerNoSpecial = $this->generateCrawlerForSearch('@person lastname:manco'); $crawlerNoSpecial = $this->generateCrawlerForSearch('@person lastname:manco');
$this->assertRegExp('/Manço/', $crawlerNoSpecial->filter('.list-with-period')->text()); $this->assertRegExp('/Manço/', $crawlerNoSpecial->filter('.list-with-period')->text());
} }
public function testSearchByFirstName() public function testSearchByFirstName()
{ {
$crawler = $this->generateCrawlerForSearch('@person firstname:Jean'); $crawler = $this->generateCrawlerForSearch('@person firstname:Jean');
$this->assertRegExp('/Depardieu/', $crawler->filter('.list-with-period')->text()); $this->assertRegExp('/Depardieu/', $crawler->filter('.list-with-period')->text());
} }
public function testSearchByFirstNameLower2() public function testSearchByFirstNameLower2()
{ {
$crawler = $this->generateCrawlerForSearch('@person firstname:jean'); $crawler = $this->generateCrawlerForSearch('@person firstname:jean');
$this->assertRegExp('/Depardieu/', $crawler->filter('.list-with-period')->text()); $this->assertRegExp('/Depardieu/', $crawler->filter('.list-with-period')->text());
} }
public function testSearchByFirstNamePartim2() public function testSearchByFirstNamePartim2()
{ {
$crawler = $this->generateCrawlerForSearch('@person firstname:ean'); $crawler = $this->generateCrawlerForSearch('@person firstname:ean');
$this->assertRegExp('/Depardieu/', $crawler->filter('.list-with-period')->text()); $this->assertRegExp('/Depardieu/', $crawler->filter('.list-with-period')->text());
} }
public function testSearchByFirstNameAccented() public function testSearchByFirstNameAccented()
{ {
$crawlerSpecial = $this->generateCrawlerForSearch('@person firstname:Gérard'); $crawlerSpecial = $this->generateCrawlerForSearch('@person firstname:Gérard');
$this->assertRegExp('/Gérard/', $crawlerSpecial->filter('.list-with-period')->text()); $this->assertRegExp('/Gérard/', $crawlerSpecial->filter('.list-with-period')->text());
$crawlerNoSpecial = $this->generateCrawlerForSearch('@person firstname:Gerard'); $crawlerNoSpecial = $this->generateCrawlerForSearch('@person firstname:Gerard');
$this->assertRegExp('/Gérard/', $crawlerNoSpecial->filter('.list-with-period')->text()); $this->assertRegExp('/Gérard/', $crawlerNoSpecial->filter('.list-with-period')->text());
} }
public function testSearchCombineLastnameAndNationality() public function testSearchCombineLastnameAndNationality()
{ {
$crawler = $this->generateCrawlerForSearch('@person lastname:Depardieu nationality:RU'); $crawler = $this->generateCrawlerForSearch('@person lastname:Depardieu nationality:RU');
$this->assertRegExp('/Gérard/', $crawler->filter('.list-with-period')->text()); $this->assertRegExp('/Gérard/', $crawler->filter('.list-with-period')->text());
//if this is a AND clause, Jean Depardieu should not appears //if this is a AND clause, Jean Depardieu should not appears
$this->assertNotRegExp('/Jean/', $crawler->filter('.list-with-period')->text(), $this->assertNotRegExp('/Jean/', $crawler->filter('.list-with-period')->text(),
"assert clause firstname and nationality are AND"); "assert clause firstname and nationality are AND");
} }
public function testSearchCombineLastnameAndFirstName() public function testSearchCombineLastnameAndFirstName()
{ {
$crawler = $this->generateCrawlerForSearch('@person lastname:Depardieu firstname:Jean'); $crawler = $this->generateCrawlerForSearch('@person lastname:Depardieu firstname:Jean');
$this->assertRegExp('/Depardieu/', $crawler->filter('.list-with-period')->text()); $this->assertRegExp('/Depardieu/', $crawler->filter('.list-with-period')->text());
//if this is a AND clause, Jean Depardieu should not appears //if this is a AND clause, Jean Depardieu should not appears
$this->assertNotRegExp('/Gérard/', $crawler->filter('.list-with-period')->text(), $this->assertNotRegExp('/Gérard/', $crawler->filter('.list-with-period')->text(),
"assert clause firstname and nationality are AND"); "assert clause firstname and nationality are AND");
} }
public function testSearchBirthdate() public function testSearchBirthdate()
{ {
$crawler = $this->generateCrawlerForSearch('@person birthdate:1948-12-27'); $crawler = $this->generateCrawlerForSearch('@person birthdate:1948-12-27');
$this->assertRegExp('/Gérard/', $crawler->filter('.list-with-period')->text()); $this->assertRegExp('/Gérard/', $crawler->filter('.list-with-period')->text());
$this->assertRegExp('/Bart/', $crawler->filter('.list-with-period')->text()); $this->assertRegExp('/Bart/', $crawler->filter('.list-with-period')->text());
} }
public function testSearchCombineBirthdateAndLastName() public function testSearchCombineBirthdateAndLastName()
{ {
$crawler = $this->generateCrawlerForSearch('@person birthdate:1948-12-27 lastname:(Van Snick)'); $crawler = $this->generateCrawlerForSearch('@person birthdate:1948-12-27 lastname:(Van Snick)');
$this->assertRegExp('/Bart/', $crawler->filter('.list-with-period')->text()); $this->assertRegExp('/Bart/', $crawler->filter('.list-with-period')->text());
$this->assertNotRegExp('/Depardieu/', $crawler->filter('.list-with-period')->text()); $this->assertNotRegExp('/Depardieu/', $crawler->filter('.list-with-period')->text());
} }
public function testSearchCombineGenderAndLastName() public function testSearchCombineGenderAndLastName()
{ {
$crawler = $this->generateCrawlerForSearch('@person gender:woman lastname:(Depardieu)'); $crawler = $this->generateCrawlerForSearch('@person gender:woman lastname:(Depardieu)');
$this->assertRegExp('/Charline/', $crawler->filter('.list-with-period')->text()); $this->assertRegExp('/Charline/', $crawler->filter('.list-with-period')->text());
$this->assertNotRegExp('/Gérard/', $crawler->filter('.list-with-period')->text()); $this->assertNotRegExp('/Gérard/', $crawler->filter('.list-with-period')->text());
} }
public function testSearchMultipleTrigramUseAndClauseInDefault() public function testSearchMultipleTrigramUseAndClauseInDefault()
{ {
$crawler = $this->generateCrawlerForSearch('@person cha dep'); $crawler = $this->generateCrawlerForSearch('@person cha dep');
$this->assertRegExp('/Charline/', $crawler->filter('.list-with-period')->text()); $this->assertRegExp('/Charline/', $crawler->filter('.list-with-period')->text());
$this->assertNotRegExp('/Gérard/', $crawler->filter('.list-with-period')->text()); $this->assertNotRegExp('/Gérard/', $crawler->filter('.list-with-period')->text());
$this->assertNotRegExp('/Jean/', $crawler->filter('.list-with-period')->text()); $this->assertNotRegExp('/Jean/', $crawler->filter('.list-with-period')->text());
} }
public function testDefaultAccented() public function testDefaultAccented()
{ {
$crawlerSpecial = $this->generateCrawlerForSearch('@person manço'); $crawlerSpecial = $this->generateCrawlerForSearch('@person manço');
$this->assertRegExp('/Manço/', $crawlerSpecial->filter('.list-with-period')->text()); $this->assertRegExp('/Manço/', $crawlerSpecial->filter('.list-with-period')->text());
$crawlerNoSpecial = $this->generateCrawlerForSearch('@person manco'); $crawlerNoSpecial = $this->generateCrawlerForSearch('@person manco');
$this->assertRegExp('/Manço/', $crawlerNoSpecial->filter('.list-with-period')->text()); $this->assertRegExp('/Manço/', $crawlerNoSpecial->filter('.list-with-period')->text());
$crawlerSpecial = $this->generateCrawlerForSearch('@person Étienne'); $crawlerSpecial = $this->generateCrawlerForSearch('@person Étienne');
$this->assertRegExp('/Étienne/', $crawlerSpecial->filter('.list-with-period')->text()); $this->assertRegExp('/Étienne/', $crawlerSpecial->filter('.list-with-period')->text());
$crawlerNoSpecial = $this->generateCrawlerForSearch('@person etienne'); $crawlerNoSpecial = $this->generateCrawlerForSearch('@person etienne');
$this->assertRegExp('/Étienne/', $crawlerNoSpecial->filter('.list-with-period')->text()); $this->assertRegExp('/Étienne/', $crawlerNoSpecial->filter('.list-with-period')->text());
} }
/** /**
* test that person which a user cannot see are not displayed in results * test that person which a user cannot see are not displayed in results
*/ */
@ -199,30 +199,29 @@ class PersonSearchTest extends WebTestCase
{ {
$crawlerCanSee = $this->generateCrawlerForSearch('Gérard', 'center a_social'); $crawlerCanSee = $this->generateCrawlerForSearch('Gérard', 'center a_social');
$crawlerCannotSee = $this->generateCrawlerForSearch('Gérard', 'center b_social'); $crawlerCannotSee = $this->generateCrawlerForSearch('Gérard', 'center b_social');
$this->assertRegExp('/Gérard/', $crawlerCanSee->text(), $this->assertRegExp('/Depardieu/', $crawlerCanSee->text(),
'center a_social may see "Gérard" in center a'); 'center a_social may see "Depardieu" in center a');
$this->assertRegExp('/Aucune personne ne correspond aux termes de recherche/', $this->assertNotRegExp('/Depardieu/', $crawlerCannotSee->text(),
$crawlerCannotSee->text(), 'center b_social may see "Depardieu" in center b');
'center b_social may not see any "Gérard" associated to center b');
} }
private function generateCrawlerForSearch($pattern, $username = 'center a_social') private function generateCrawlerForSearch($pattern, $username = 'center a_social')
{ {
$client = $this->getAuthenticatedClient($username); $client = $this->getAuthenticatedClient($username);
$crawler = $client->request('GET', '/fr/search', array( $crawler = $client->request('GET', '/fr/search', array(
'q' => $pattern, 'q' => $pattern,
)); ));
$this->assertTrue($client->getResponse()->isSuccessful()); $this->assertTrue($client->getResponse()->isSuccessful());
return $crawler; return $crawler;
} }
/** /**
* *
* @return \Symfony\Component\BrowserKit\Client * @return \Symfony\Component\BrowserKit\Client
*/ */
private function getAuthenticatedClient($username = 'center a_social') private function getAuthenticatedClient($username = 'center a_social')

View File

@ -27,7 +27,7 @@ use Doctrine\ORM\EntityManagerInterface;
use Chill\MainBundle\Test\PrepareClientTrait; use Chill\MainBundle\Test\PrepareClientTrait;
/** /**
* This class tests entries are shown for closing and opening * This class tests entries are shown for closing and opening
* periods in timeline. * periods in timeline.
* *
* @author Julien Fastré <julien.fastre@champs-libres.coop> * @author Julien Fastré <julien.fastre@champs-libres.coop>
@ -40,22 +40,19 @@ class TimelineAccompanyingPeriodTest extends WebTestCase
/** /**
* @dataProvider provideDataPersonWithAccompanyingPeriod * @dataProvider provideDataPersonWithAccompanyingPeriod
*/ */
public function testEntriesAreShown($personId) public function testEntriesAreShown($personId)
{ {
$client = $this->getClientAuthenticated(); $client = $this->getClientAuthenticated();
$crawler = $client->request('GET', "/en/person/{$personId}/timeline"); $crawler = $client->request('GET', "/en/person/{$personId}/timeline");
$this->assertTrue($client->getResponse()->isSuccessful(), $this->assertTrue($client->getResponse()->isSuccessful(),
"the timeline page loads sucessfully"); "the timeline page loads sucessfully");
$this->assertGreaterThan(0, $crawler->filter('.timeline div')->count(), $this->assertGreaterThan(0, $crawler->filter('.timeline div')->count(),
"the timeline page contains multiple div inside a .timeline element"); "the timeline page contains multiple div inside a .timeline element");
$this->assertContains(" Une période d'accompagnement est ouverte", $this->assertContains("est ouvert",
$crawler->filter('.timeline')->text(), $crawler->filter('.timeline')->text(),
"the text 'une période d'accompagnement a été ouverte' is present"); "the text 'est ouvert' is present");
$this->assertContains("Une periode d'accompagnement se clôture",
$crawler->Filter('.timeline')->text(),
"the text 'Une période d'accompagnement a été fermée' is present");
} }
public function provideDataPersonWithAccompanyingPeriod() public function provideDataPersonWithAccompanyingPeriod()
@ -71,8 +68,7 @@ class TimelineAccompanyingPeriodTest extends WebTestCase
->join('part.accompanyingPeriod', 'period') ->join('part.accompanyingPeriod', 'period')
->join('p.center', 'center') ->join('p.center', 'center')
->select('p.id') ->select('p.id')
->where($qb->expr()->isNotNull('period.closingDate')) ->where($qb->expr()->eq('center.name', ':center'))
->andWhere($qb->expr()->eq('center.name', ':center'))
->setParameter('center', 'Center A') ->setParameter('center', 'Center A')
->setMaxResults(1000) ->setMaxResults(1000)
->getQuery() ->getQuery()
@ -86,5 +82,5 @@ class TimelineAccompanyingPeriodTest extends WebTestCase
yield [ \array_pop($personIds)['id'] ]; yield [ \array_pop($personIds)['id'] ];
} }
} }

@ -1 +1 @@
Subproject commit 614c9de4c7e606e1f89f02b6236f605767f110cb Subproject commit 8839b431f296733b792c788f2ef58e5ecd6419d3