mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
add ListPerson
Add / complete list of person. Some SQL function are added to allow to get the last address at a given date.
This commit is contained in:
parent
045119d61f
commit
25cad2f11d
@ -130,36 +130,6 @@ class PersonController extends Controller
|
|||||||
return $this->redirect($url);
|
return $this->redirect($url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a csv file with all the persons
|
|
||||||
*
|
|
||||||
* @return A csv file with all the persons
|
|
||||||
*/
|
|
||||||
public function exportAction()
|
|
||||||
{
|
|
||||||
$em = $this->getDoctrine()->getManager();
|
|
||||||
$chillSecurityHelper = $this->get('chill.main.security.authorization.helper');
|
|
||||||
$user = $this->get('security.context')->getToken()->getUser();
|
|
||||||
|
|
||||||
$reachableCenters = $chillSecurityHelper->getReachableCenters($user,
|
|
||||||
new Role('CHILL_PERSON_SEE'));
|
|
||||||
|
|
||||||
$personRepository = $em->getRepository('ChillPersonBundle:Person');
|
|
||||||
$qb = $personRepository->createQueryBuilder('p');
|
|
||||||
$qb->where($qb->expr()->in('p.center', ':centers'))
|
|
||||||
->setParameter('centers', $reachableCenters);
|
|
||||||
$persons = $qb->getQuery()->getResult();
|
|
||||||
|
|
||||||
$response = $this->render('ChillPersonBundle:Person:export.csv.twig',
|
|
||||||
array(
|
|
||||||
'persons' => $persons,
|
|
||||||
'cf_group' => $this->getCFGroup()));
|
|
||||||
$response->headers->set('Content-Type', 'text/csv; charset=utf-8');
|
|
||||||
$response->headers->set('Content-Disposition', 'attachment; filename="export_person.csv"');
|
|
||||||
|
|
||||||
return $response;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function newAction()
|
public function newAction()
|
||||||
{
|
{
|
||||||
|
@ -26,6 +26,7 @@ use Symfony\Component\DependencyInjection\Loader;
|
|||||||
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
|
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
|
||||||
use Chill\MainBundle\DependencyInjection\MissingBundleException;
|
use Chill\MainBundle\DependencyInjection\MissingBundleException;
|
||||||
use Chill\PersonBundle\Security\Authorization\PersonVoter;
|
use Chill\PersonBundle\Security\Authorization\PersonVoter;
|
||||||
|
use Chill\PersonBundle\Doctrine\DQL\AddressPart;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the class that loads and manages your bundle configuration
|
* This is the class that loads and manages your bundle configuration
|
||||||
@ -91,6 +92,7 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
|
|||||||
{
|
{
|
||||||
$this->prependRoleHierarchy($container);
|
$this->prependRoleHierarchy($container);
|
||||||
$this->prependHomepageWidget($container);
|
$this->prependHomepageWidget($container);
|
||||||
|
$this->prependDoctrineDQL($container);
|
||||||
|
|
||||||
$bundles = $container->getParameter('kernel.bundles');
|
$bundles = $container->getParameter('kernel.bundles');
|
||||||
//add ChillMain to assetic-enabled bundles
|
//add ChillMain to assetic-enabled bundles
|
||||||
@ -162,4 +164,33 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
|
|||||||
)
|
)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add DQL function linked with person
|
||||||
|
*
|
||||||
|
* @param ContainerBuilder $container
|
||||||
|
*/
|
||||||
|
protected function prependDoctrineDQL(ContainerBuilder $container)
|
||||||
|
{
|
||||||
|
//add DQL function to ORM (default entity_manager)
|
||||||
|
|
||||||
|
$container->prependExtensionConfig('doctrine', array(
|
||||||
|
'orm' => array(
|
||||||
|
'dql' => array(
|
||||||
|
'string_functions' => array(
|
||||||
|
'GET_PERSON_ADDRESS_ADDRESS_ID' => AddressPart\AddressPartAddressId::class,
|
||||||
|
'GET_PERSON_ADDRESS_STREET_ADDRESS_1' => AddressPart\AddressPartStreetAddress1::class,
|
||||||
|
'GET_PERSON_ADDRESS_STREET_ADDRESS_2' => AddressPart\AddressPartStreetAddress2::class,
|
||||||
|
'GET_PERSON_ADDRESS_VALID_FROM' => AddressPart\AddressPartValidFrom::class,
|
||||||
|
'GET_PERSON_ADDRESS_POSTCODE_LABEL' => AddressPart\AddressPartPostCodeLabel::class,
|
||||||
|
'GET_PERSON_ADDRESS_POSTCODE_CODE' => AddressPart\AddressPartPostCodeCode::class,
|
||||||
|
'GET_PERSON_ADDRESS_POSTCODE_ID' => AddressPart\AddressPartPostCodeId::class,
|
||||||
|
'GET_PERSON_ADDRESS_COUNTRY_NAME' => AddressPart\AddressPartCountryName::class,
|
||||||
|
'GET_PERSON_ADDRESS_COUNTRY_CODE' => AddressPart\AddressPartCountryCode::class,
|
||||||
|
'GET_PERSON_ADDRESS_COUNTRY_ID' => AddressPart\AddressPartCountryId::class
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
103
Doctrine/DQL/AddressPart.php
Normal file
103
Doctrine/DQL/AddressPart.php
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2017 Champs Libres Cooperative <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\Doctrine\DQL;
|
||||||
|
|
||||||
|
use Doctrine\ORM\Query\AST\Functions\FunctionNode;
|
||||||
|
use Doctrine\ORM\Query\Lexer;
|
||||||
|
use Doctrine\ORM\Query\Parser;
|
||||||
|
use Doctrine\ORM\Query\SqlWalker;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* USAGE GET_ADDRESS_<part>(person.id, :date, 'postcode') where part
|
||||||
|
* should be replace by the part of the address.
|
||||||
|
*
|
||||||
|
* This function return the current address part at the given date, for the
|
||||||
|
* given person (identified by his id)
|
||||||
|
*
|
||||||
|
* The aim of this function is to be used within reports
|
||||||
|
*
|
||||||
|
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||||
|
*/
|
||||||
|
abstract class AddressPart extends FunctionNode
|
||||||
|
{
|
||||||
|
public $fields = array(
|
||||||
|
'address_id',
|
||||||
|
'streetaddress1',
|
||||||
|
'streetaddress2',
|
||||||
|
'validfrom',
|
||||||
|
'postcode_label',
|
||||||
|
'postcode_code',
|
||||||
|
'postcode_id',
|
||||||
|
'country_name',
|
||||||
|
'country_code',
|
||||||
|
'country_id'
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @var \Doctrine\ORM\Query\AST\Node
|
||||||
|
*/
|
||||||
|
private $pid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @var \Doctrine\ORM\Query\AST\Node
|
||||||
|
*/
|
||||||
|
private $date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @var \Doctrine\ORM\Query\AST\Node
|
||||||
|
*/
|
||||||
|
private $part;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return the part of the address
|
||||||
|
*
|
||||||
|
* Should be one value of the "public" amongst
|
||||||
|
* 'address_id', 'streetaddress1',
|
||||||
|
* 'streetaddress2', 'validfrom', 'postcode_label', 'postcode_code',
|
||||||
|
* 'postcode_id', 'country_name', 'country_code', 'country_id'
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
abstract public function getPart();
|
||||||
|
|
||||||
|
public function getSql(SqlWalker $sqlWalker)
|
||||||
|
{
|
||||||
|
return sprintf(
|
||||||
|
'get_last_address_%s(%s, %s)',
|
||||||
|
$this->getPart(),
|
||||||
|
$this->pid->dispatch($sqlWalker),
|
||||||
|
$this->date->dispatch($sqlWalker)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function parse(Parser $parser)
|
||||||
|
{
|
||||||
|
$a = $parser->match(Lexer::T_IDENTIFIER);
|
||||||
|
$parser->match(Lexer::T_OPEN_PARENTHESIS);
|
||||||
|
// person id
|
||||||
|
$this->pid = $parser->SingleValuedPathExpression();
|
||||||
|
$parser->match(Lexer::T_COMMA);
|
||||||
|
// date
|
||||||
|
$this->date = $parser->ArithmeticPrimary();
|
||||||
|
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
|
||||||
|
}
|
||||||
|
}
|
33
Doctrine/DQL/AddressPart/AddressPartAddressId.php
Normal file
33
Doctrine/DQL/AddressPart/AddressPartAddressId.php
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2017 Champs Libres Cooperative <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\Doctrine\DQL\AddressPart;
|
||||||
|
|
||||||
|
use Chill\PersonBundle\Doctrine\DQL\AddressPart;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||||
|
*/
|
||||||
|
class AddressPartAddressId extends AddressPart
|
||||||
|
{
|
||||||
|
public function getPart()
|
||||||
|
{
|
||||||
|
return 'address_id';
|
||||||
|
}
|
||||||
|
}
|
33
Doctrine/DQL/AddressPart/AddressPartCountryCode.php
Normal file
33
Doctrine/DQL/AddressPart/AddressPartCountryCode.php
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2017 Champs Libres Cooperative <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\Doctrine\DQL\AddressPart;
|
||||||
|
|
||||||
|
use Chill\PersonBundle\Doctrine\DQL\AddressPart;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||||
|
*/
|
||||||
|
class AddressPartCountryCode extends AddressPart
|
||||||
|
{
|
||||||
|
public function getPart()
|
||||||
|
{
|
||||||
|
return 'country_code';
|
||||||
|
}
|
||||||
|
}
|
33
Doctrine/DQL/AddressPart/AddressPartCountryId.php
Normal file
33
Doctrine/DQL/AddressPart/AddressPartCountryId.php
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2017 Champs Libres Cooperative <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\Doctrine\DQL\AddressPart;
|
||||||
|
|
||||||
|
use Chill\PersonBundle\Doctrine\DQL\AddressPart;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||||
|
*/
|
||||||
|
class AddressPartCountryId extends AddressPart
|
||||||
|
{
|
||||||
|
public function getPart()
|
||||||
|
{
|
||||||
|
return 'country_id';
|
||||||
|
}
|
||||||
|
}
|
33
Doctrine/DQL/AddressPart/AddressPartCountryName.php
Normal file
33
Doctrine/DQL/AddressPart/AddressPartCountryName.php
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2017 Champs Libres Cooperative <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\Doctrine\DQL\AddressPart;
|
||||||
|
|
||||||
|
use Chill\PersonBundle\Doctrine\DQL\AddressPart;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||||
|
*/
|
||||||
|
class AddressPartCountryName extends AddressPart
|
||||||
|
{
|
||||||
|
public function getPart()
|
||||||
|
{
|
||||||
|
return 'country_name';
|
||||||
|
}
|
||||||
|
}
|
33
Doctrine/DQL/AddressPart/AddressPartPostCodeCode.php
Normal file
33
Doctrine/DQL/AddressPart/AddressPartPostCodeCode.php
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2017 Champs Libres Cooperative <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\Doctrine\DQL\AddressPart;
|
||||||
|
|
||||||
|
use Chill\PersonBundle\Doctrine\DQL\AddressPart;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||||
|
*/
|
||||||
|
class AddressPartPostCodeCode extends AddressPart
|
||||||
|
{
|
||||||
|
public function getPart()
|
||||||
|
{
|
||||||
|
return 'postcode_code';
|
||||||
|
}
|
||||||
|
}
|
33
Doctrine/DQL/AddressPart/AddressPartPostCodeId.php
Normal file
33
Doctrine/DQL/AddressPart/AddressPartPostCodeId.php
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2017 Champs Libres Cooperative <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\Doctrine\DQL\AddressPart;
|
||||||
|
|
||||||
|
use Chill\PersonBundle\Doctrine\DQL\AddressPart;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||||
|
*/
|
||||||
|
class AddressPartPostCodeId extends AddressPart
|
||||||
|
{
|
||||||
|
public function getPart()
|
||||||
|
{
|
||||||
|
return 'postcode_id';
|
||||||
|
}
|
||||||
|
}
|
33
Doctrine/DQL/AddressPart/AddressPartPostCodeLabel.php
Normal file
33
Doctrine/DQL/AddressPart/AddressPartPostCodeLabel.php
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2017 Champs Libres Cooperative <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\Doctrine\DQL\AddressPart;
|
||||||
|
|
||||||
|
use Chill\PersonBundle\Doctrine\DQL\AddressPart;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||||
|
*/
|
||||||
|
class AddressPartPostCodeLabel extends AddressPart
|
||||||
|
{
|
||||||
|
public function getPart()
|
||||||
|
{
|
||||||
|
return 'postcode_label';
|
||||||
|
}
|
||||||
|
}
|
33
Doctrine/DQL/AddressPart/AddressPartStreetAddress1.php
Normal file
33
Doctrine/DQL/AddressPart/AddressPartStreetAddress1.php
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2017 Champs Libres Cooperative <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\Doctrine\DQL\AddressPart;
|
||||||
|
|
||||||
|
use Chill\PersonBundle\Doctrine\DQL\AddressPart;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||||
|
*/
|
||||||
|
class AddressPartStreetAddress1 extends AddressPart
|
||||||
|
{
|
||||||
|
public function getPart()
|
||||||
|
{
|
||||||
|
return 'streetaddress1';
|
||||||
|
}
|
||||||
|
}
|
33
Doctrine/DQL/AddressPart/AddressPartStreetAddress2.php
Normal file
33
Doctrine/DQL/AddressPart/AddressPartStreetAddress2.php
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2017 Champs Libres Cooperative <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\Doctrine\DQL\AddressPart;
|
||||||
|
|
||||||
|
use Chill\PersonBundle\Doctrine\DQL\AddressPart;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||||
|
*/
|
||||||
|
class AddressPartStreetAddress2 extends AddressPart
|
||||||
|
{
|
||||||
|
public function getPart()
|
||||||
|
{
|
||||||
|
return 'streetaddress2';
|
||||||
|
}
|
||||||
|
}
|
33
Doctrine/DQL/AddressPart/AddressPartValidFrom.php
Normal file
33
Doctrine/DQL/AddressPart/AddressPartValidFrom.php
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2017 Champs Libres Cooperative <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\Doctrine\DQL\AddressPart;
|
||||||
|
|
||||||
|
use Chill\PersonBundle\Doctrine\DQL\AddressPart;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||||
|
*/
|
||||||
|
class AddressPartValidFrom extends AddressPart
|
||||||
|
{
|
||||||
|
public function getPart()
|
||||||
|
{
|
||||||
|
return 'validfrom';
|
||||||
|
}
|
||||||
|
}
|
@ -15,7 +15,10 @@ use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
|||||||
use Symfony\Component\Translation\TranslatorInterface;
|
use Symfony\Component\Translation\TranslatorInterface;
|
||||||
use Symfony\Component\Validator\Constraints\Callback;
|
use Symfony\Component\Validator\Constraints\Callback;
|
||||||
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
||||||
|
use Chill\PersonBundle\Entity\Person;
|
||||||
|
use Chill\CustomFieldsBundle\Entity\CustomField;
|
||||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||||
|
use Chill\CustomFieldsBundle\Service\CustomFieldProvider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render a list of peoples
|
* Render a list of peoples
|
||||||
@ -37,26 +40,35 @@ class ListPerson implements ListInterface
|
|||||||
protected $translator;
|
protected $translator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @var TranslatableStringHelper
|
* @var TranslatableStringHelper
|
||||||
*/
|
*/
|
||||||
protected $translatableStringHelper;
|
protected $translatableStringHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @var CustomFieldProvider
|
||||||
|
*/
|
||||||
|
protected $customFieldProvider;
|
||||||
|
|
||||||
protected $fields = array(
|
protected $fields = array(
|
||||||
'id', 'firstName', 'lastName', 'birthdate',
|
'id', 'firstName', 'lastName', 'birthdate',
|
||||||
'placeOfBirth', 'gender', 'memo', 'email', 'phonenumber',
|
'placeOfBirth', 'gender', 'memo', 'email', 'phonenumber',
|
||||||
'countryOfBirth', 'nationality'
|
'countryOfBirth', 'nationality', 'address_street_address_1',
|
||||||
|
'address_street_address_2', 'address_valid_from', 'address_postcode_label',
|
||||||
|
'address_postcode_code', 'address_country_name', 'address_country_code'
|
||||||
);
|
);
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
EntityManagerInterface $em,
|
EntityManagerInterface $em,
|
||||||
TranslatorInterface $translator,
|
TranslatorInterface $translator,
|
||||||
TranslatableStringHelper $translatableStringHelper
|
TranslatableStringHelper $translatableStringHelper,
|
||||||
)
|
CustomFieldProvider $customFieldProvider
|
||||||
{
|
) {
|
||||||
$this->entityManager = $em;
|
$this->entityManager = $em;
|
||||||
$this->translator = $translator;
|
$this->translator = $translator;
|
||||||
$this->translatableStringHelper = $translatableStringHelper;
|
$this->translatableStringHelper = $translatableStringHelper;
|
||||||
|
$this->customFieldProvider = $customFieldProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -66,11 +78,21 @@ class ListPerson implements ListInterface
|
|||||||
*/
|
*/
|
||||||
public function buildForm(FormBuilderInterface $builder)
|
public function buildForm(FormBuilderInterface $builder)
|
||||||
{
|
{
|
||||||
|
$choices = array_combine($this->fields, $this->fields);
|
||||||
|
|
||||||
|
foreach ($this->getCustomFields() as $cf) {
|
||||||
|
$choices
|
||||||
|
[$this->translatableStringHelper->localize($cf->getName())]
|
||||||
|
=
|
||||||
|
$cf->getSlug();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
$builder->add('fields', ChoiceType::class, array(
|
$builder->add('fields', ChoiceType::class, array(
|
||||||
'multiple' => true,
|
'multiple' => true,
|
||||||
'expanded' => true,
|
'expanded' => true,
|
||||||
'choices' => array_combine($this->fields, $this->fields),
|
'choices' => $choices,
|
||||||
|
'choices_as_values' => true,
|
||||||
'label' => 'Fields to include in export',
|
'label' => 'Fields to include in export',
|
||||||
'constraints' => [new Callback(array(
|
'constraints' => [new Callback(array(
|
||||||
'callback' => function($selected, ExecutionContextInterface $context) {
|
'callback' => function($selected, ExecutionContextInterface $context) {
|
||||||
@ -84,6 +106,25 @@ class ListPerson implements ListInterface
|
|||||||
));
|
));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get custom fields associated with person
|
||||||
|
*
|
||||||
|
* @return CustomField[]
|
||||||
|
*/
|
||||||
|
private function getCustomFields()
|
||||||
|
{
|
||||||
|
return $this->entityManager
|
||||||
|
->createQuery("SELECT cf "
|
||||||
|
. "FROM ChillCustomFieldsBundle:CustomField cf "
|
||||||
|
. "JOIN cf.customFieldGroup g "
|
||||||
|
. "WHERE cf.type != :title AND g.entity LIKE :entity")
|
||||||
|
->setParameters(array(
|
||||||
|
'title' => 'title',
|
||||||
|
'entity' => \addcslashes(Person::class, "\\")
|
||||||
|
))
|
||||||
|
->getResult();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
@ -163,13 +204,42 @@ class ListPerson implements ListInterface
|
|||||||
return $this->translatableStringHelper->localize(
|
return $this->translatableStringHelper->localize(
|
||||||
$country->getName());
|
$country->getName());
|
||||||
};
|
};
|
||||||
default:
|
case 'address_country_name':
|
||||||
return function($value) use ($key) {
|
return function($value) use ($key) {
|
||||||
if ($value === '_header') { return \strtolower($key); }
|
if ($value === '_header') { return \strtolower($key); }
|
||||||
|
|
||||||
return $value;
|
if ($value === NULL) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->translatableStringHelper->localize(json_decode($value, true));
|
||||||
|
};
|
||||||
|
default:
|
||||||
|
// for fields which are associated with person
|
||||||
|
if (in_array($key, $this->fields)) {
|
||||||
|
return function($value) use ($key) {
|
||||||
|
if ($value === '_header') { return \strtolower($key); }
|
||||||
|
|
||||||
|
return $value;
|
||||||
|
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
// for fields which are custom fields
|
||||||
|
/* @var $cf CustomField */
|
||||||
|
$cf = $this->entityManager
|
||||||
|
->getRepository(CustomField::class)
|
||||||
|
->findOneBy(array('slug' => $this->DQLToSlug($key)));
|
||||||
|
|
||||||
|
return function($value) use ($cf) {
|
||||||
|
if ($value === '_header') {
|
||||||
|
return $this->translatableStringHelper->localize($cf->getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->customFieldProvider
|
||||||
|
->getCustomFieldByType($cf->getType())
|
||||||
|
->render(json_decode($value, true), $cf, 'csv');
|
||||||
};
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -182,7 +252,34 @@ class ListPerson implements ListInterface
|
|||||||
*/
|
*/
|
||||||
public function getQueryKeys($data)
|
public function getQueryKeys($data)
|
||||||
{
|
{
|
||||||
return $data['fields'];
|
$fields = array();
|
||||||
|
|
||||||
|
foreach ($data['fields'] as $key) {
|
||||||
|
if (in_array($key, $this->fields)) {
|
||||||
|
$fields[] = $key;
|
||||||
|
} else {
|
||||||
|
// this should be a slug from custom field, we have to clean it
|
||||||
|
$fields[] = $this->slugToDQL($key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clean a slug to be usable by DQL
|
||||||
|
*
|
||||||
|
* @param string $slugsanitize
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function slugToDQL($slug)
|
||||||
|
{
|
||||||
|
return "cf____".\str_replace("-", "____", $slug);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function DQLToSlug($cleanedSlug)
|
||||||
|
{
|
||||||
|
return \str_replace("____", "-", \substr($cleanedSlug, 6));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -236,12 +333,38 @@ class ListPerson implements ListInterface
|
|||||||
case 'nationality':
|
case 'nationality':
|
||||||
$qb->addSelect(sprintf('IDENTITY(person.%s) as %s', $f, $f));
|
$qb->addSelect(sprintf('IDENTITY(person.%s) as %s', $f, $f));
|
||||||
break;
|
break;
|
||||||
|
case 'address_street_address_1':
|
||||||
|
case 'address_street_address_2':
|
||||||
|
case 'address_valid_from':
|
||||||
|
case 'address_postcode_label':
|
||||||
|
case 'address_postcode_code':
|
||||||
|
case 'address_country_name':
|
||||||
|
case 'address_country_code':
|
||||||
|
|
||||||
|
$qb->addSelect(sprintf(
|
||||||
|
'GET_PERSON_ADDRESS_%s(person.id, :address_date) AS %s',
|
||||||
|
// get the part after address_
|
||||||
|
strtoupper(substr($f, 8)),
|
||||||
|
$f));
|
||||||
|
$qb->setParameter('address_date', new \DateTime());
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
$qb->addSelect(sprintf('person.%s as %s', $f, $f));
|
$qb->addSelect(sprintf('person.%s as %s', $f, $f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach ($this->getCustomFields() as $cf) {
|
||||||
|
if (in_array($cf->getSlug(), $data['fields'])) {
|
||||||
|
$slug = $this->slugToDQL($cf->getSlug());
|
||||||
|
$qb->addSelect(
|
||||||
|
sprintf('GET_JSON_FIELD_BY_KEY(person.cFData, :slug%s) AS %s',
|
||||||
|
$slug, $slug));
|
||||||
|
$qb->setParameter(sprintf('slug%s', $slug), $cf->getSlug());
|
||||||
|
//$qb->setParameter(sprintf('name%s', $slug), $cf->getSlug());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$qb
|
$qb
|
||||||
->from('ChillPersonBundle:Person', 'person')
|
->from('ChillPersonBundle:Person', 'person')
|
||||||
->join('person.center', 'center')
|
->join('person.center', 'center')
|
||||||
|
@ -92,15 +92,6 @@ chill_person_address_update:
|
|||||||
path: /{_locale}/person/{person_id}/address/{address_id}/update
|
path: /{_locale}/person/{person_id}/address/{address_id}/update
|
||||||
defaults: { _controller: ChillPersonBundle:PersonAddress:update }
|
defaults: { _controller: ChillPersonBundle:PersonAddress:update }
|
||||||
|
|
||||||
chill_person_export:
|
|
||||||
path: /{_locale}/person/export/
|
|
||||||
defaults: { _controller: ChillPersonBundle:Person:export }
|
|
||||||
options:
|
|
||||||
menus:
|
|
||||||
export:
|
|
||||||
order: 200
|
|
||||||
label: Export persons
|
|
||||||
|
|
||||||
chill_person_timeline:
|
chill_person_timeline:
|
||||||
path: /{_locale}/person/{person_id}/timeline
|
path: /{_locale}/person/{person_id}/timeline
|
||||||
defaults: { _controller: ChillPersonBundle:TimelinePerson:person }
|
defaults: { _controller: ChillPersonBundle:TimelinePerson:person }
|
||||||
|
@ -12,6 +12,7 @@ services:
|
|||||||
- "@doctrine.orm.entity_manager"
|
- "@doctrine.orm.entity_manager"
|
||||||
- "@translator"
|
- "@translator"
|
||||||
- "@chill.main.helper.translatable_string"
|
- "@chill.main.helper.translatable_string"
|
||||||
|
- "@chill.custom_field.provider"
|
||||||
tags:
|
tags:
|
||||||
- { name: chill.export, alias: list_person }
|
- { name: chill.export, alias: list_person }
|
||||||
|
|
||||||
|
123
Resources/migrations/Version20170117131924.php
Normal file
123
Resources/migrations/Version20170117131924.php
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Application\Migrations;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Migrations\AbstractMigration;
|
||||||
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add postgresql functions to compute last address on person.
|
||||||
|
*/
|
||||||
|
class Version20170117131924 extends AbstractMigration
|
||||||
|
{
|
||||||
|
|
||||||
|
public $fields = array(
|
||||||
|
'address_id' => 'integer',
|
||||||
|
'streetaddress1' => 'varchar(255)',
|
||||||
|
'streetaddress2' => 'varchar(255)',
|
||||||
|
'validfrom' => 'date',
|
||||||
|
'postcode_label' => 'varchar(255)',
|
||||||
|
'postcode_code' => 'varchar(100)',
|
||||||
|
'postcode_id' => 'integer',
|
||||||
|
'country_name' => 'json',
|
||||||
|
'country_code' => 'varchar(3)',
|
||||||
|
'country_id' => 'integer'
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Schema $schema
|
||||||
|
*/
|
||||||
|
public function up(Schema $schema)
|
||||||
|
{
|
||||||
|
$this->addSql(<<<'SQL'
|
||||||
|
CREATE OR REPLACE FUNCTION public.get_last_address (
|
||||||
|
pid integer,
|
||||||
|
before_date date)
|
||||||
|
RETURNS TABLE(
|
||||||
|
person_id integer,
|
||||||
|
address_id integer,
|
||||||
|
streetaddress1 varchar(255),
|
||||||
|
streetaddress2 varchar(255),
|
||||||
|
validfrom date,
|
||||||
|
postcode_label varchar(255),
|
||||||
|
postcode_code varchar(100),
|
||||||
|
postcode_id integer,
|
||||||
|
country_name json,
|
||||||
|
country_code varchar(3),
|
||||||
|
country_id integer)
|
||||||
|
AS
|
||||||
|
$BODY$
|
||||||
|
SELECT
|
||||||
|
pid AS person_id,
|
||||||
|
chill_main_address.id AS address_id,
|
||||||
|
chill_main_address.streetaddress1,
|
||||||
|
chill_main_address.streetaddress2,
|
||||||
|
chill_main_address.validfrom,
|
||||||
|
chill_main_postal_code.label,
|
||||||
|
chill_main_postal_code.code,
|
||||||
|
chill_main_postal_code.id AS postal_code_id,
|
||||||
|
country.name,
|
||||||
|
country.countrycode,
|
||||||
|
country.id AS country_id
|
||||||
|
FROM chill_main_address
|
||||||
|
JOIN (
|
||||||
|
SELECT
|
||||||
|
chill_main_address.id AS address_id,
|
||||||
|
validfrom,
|
||||||
|
rank() OVER (PARTITION BY person_id ORDER BY validfrom DESC) as pos
|
||||||
|
FROM chill_person_persons_to_addresses
|
||||||
|
JOIN chill_main_address ON chill_person_persons_to_addresses.address_id = chill_main_address.id
|
||||||
|
WHERE person_id = pid
|
||||||
|
AND chill_main_address.validfrom <= before_date
|
||||||
|
) AS ranking ON ranking.address_id = chill_main_address.id
|
||||||
|
JOIN chill_main_postal_code ON chill_main_address.postcode_id = chill_main_postal_code.id
|
||||||
|
JOIN country ON chill_main_postal_code.country_id = country.id
|
||||||
|
WHERE ranking.pos = 1
|
||||||
|
$BODY$
|
||||||
|
LANGUAGE sql VOLATILE
|
||||||
|
COST 100;
|
||||||
|
SQL
|
||||||
|
);
|
||||||
|
|
||||||
|
// create function to get part of address
|
||||||
|
foreach ($this->fields as $var => $type) {
|
||||||
|
$this->addSql(sprintf(<<<'SQL'
|
||||||
|
CREATE OR REPLACE FUNCTION get_last_address_%s (
|
||||||
|
pid integer,
|
||||||
|
before_date date)
|
||||||
|
RETURNS %s AS
|
||||||
|
$BODY$
|
||||||
|
SELECT %s FROM get_last_address(pid, before_date)
|
||||||
|
$BODY$
|
||||||
|
LANGUAGE sql volatile
|
||||||
|
COST 100;
|
||||||
|
SQL
|
||||||
|
, $var, $type, $var));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Schema $schema
|
||||||
|
*/
|
||||||
|
public function down(Schema $schema)
|
||||||
|
{
|
||||||
|
// drop function to get parts of address
|
||||||
|
foreach ($this->fields as $var => $type) {
|
||||||
|
$this->addSql(<<<SQL
|
||||||
|
|
||||||
|
DROP FUNCTION get_last_address_$var (
|
||||||
|
pid integer,
|
||||||
|
before_date date)
|
||||||
|
SQL
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->addSQL(<<<SQL
|
||||||
|
DROP FUNCTION public.get_last_address (
|
||||||
|
pid integer,
|
||||||
|
before_date date)
|
||||||
|
SQL
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -14,6 +14,7 @@ dateOfBirth: date de naissance
|
|||||||
dateofbirth: date de naissance
|
dateofbirth: date de naissance
|
||||||
'Unknown date of birth': 'Date de naissance inconnue'
|
'Unknown date of birth': 'Date de naissance inconnue'
|
||||||
Nationality: Nationalité
|
Nationality: Nationalité
|
||||||
|
nationality: nationalité
|
||||||
'Without nationality': 'Sans nationalité'
|
'Without nationality': 'Sans nationalité'
|
||||||
Gender: Genre
|
Gender: Genre
|
||||||
gender: genre
|
gender: genre
|
||||||
@ -22,6 +23,7 @@ gender: genre
|
|||||||
'Place of birth': 'Lieu de naissance'
|
'Place of birth': 'Lieu de naissance'
|
||||||
placeOfBirth: lieu de naissance
|
placeOfBirth: lieu de naissance
|
||||||
'Country of birth': 'Pays de naissance'
|
'Country of birth': 'Pays de naissance'
|
||||||
|
countryOfBirth: 'Pays de naissance'
|
||||||
'Unknown country of birth': 'Pays inconnu'
|
'Unknown country of birth': 'Pays inconnu'
|
||||||
'Marital status': 'État civil'
|
'Marital status': 'État civil'
|
||||||
'Number of children': 'Nombre d''enfants'
|
'Number of children': 'Nombre d''enfants'
|
||||||
@ -53,6 +55,17 @@ Married: Marié(e)
|
|||||||
'Family information': Famille
|
'Family information': Famille
|
||||||
'Contact information': 'Informations de contact'
|
'Contact information': 'Informations de contact'
|
||||||
'Administrative information': Administratif
|
'Administrative information': Administratif
|
||||||
|
|
||||||
|
# addresses part
|
||||||
|
address_street_address_1: Adresse ligne 1
|
||||||
|
address_street_address_2: Adresse ligne 2
|
||||||
|
address_valid_from: Date de début de validité de l'adresse
|
||||||
|
address_postcode_label: Commune
|
||||||
|
address_postcode_code: Code postal
|
||||||
|
address_country_name: Pays
|
||||||
|
address_country_code: Code pays
|
||||||
|
|
||||||
|
|
||||||
'Alreay existing person': 'Dossiers déjà encodés'
|
'Alreay existing person': 'Dossiers déjà encodés'
|
||||||
'Add the person': 'Ajouter la personne'
|
'Add the person': 'Ajouter la personne'
|
||||||
'Confirm the creation': 'Confirmer la création'
|
'Confirm the creation': 'Confirmer la création'
|
||||||
|
@ -1,71 +0,0 @@
|
|||||||
"{{ 'Person id'|trans }}",{#
|
|
||||||
#}"{{ 'First name'|trans }}",{#
|
|
||||||
#}"{{ 'Last name'|trans }}",{#
|
|
||||||
#}"{{ 'Gender'|trans }}",{#
|
|
||||||
#}"{{ 'Date of birth'|trans }}",{#
|
|
||||||
#}"{{ 'Place of birth'|trans }}",{#
|
|
||||||
#}"{{ 'Nationality'|trans }}",{#
|
|
||||||
#}"{{ 'Spoken languages'|trans }}",{#
|
|
||||||
#}"{{ 'Email'|trans }}",{#
|
|
||||||
#}"{{ 'Phonenumber'|trans }}",{#
|
|
||||||
#}"{{ 'Marital Status'|trans }}",{#
|
|
||||||
#}"{{ 'Center'|trans }}",{#
|
|
||||||
#}{% if cf_group %}{#
|
|
||||||
#}{% for customField in cf_group.customFields %}{#
|
|
||||||
#}"{{ chill_custom_field_label(customField) }}"{% if not loop.last %},{% endif %}{#
|
|
||||||
#}{% endfor %}{#
|
|
||||||
#}{% endif %}{#
|
|
||||||
|
|
||||||
#}{{ '\r\n'|raw }}{#
|
|
||||||
#}{% for person in persons %}{#
|
|
||||||
#}{{ person.id }},{#
|
|
||||||
#}"{{ person.firstName|csv_cell }}",{#
|
|
||||||
#}"{{ person.lastName|csv_cell }}",{#
|
|
||||||
#}"{{ person.gender|csv_cell }}",{#
|
|
||||||
#}"{{ person.birthdate|localizeddate('short', 'none') }}",{#
|
|
||||||
#}"{# countryOfBirth
|
|
||||||
#}{% if person.countryOfBirth is not null %}{#
|
|
||||||
#}{{ person.countryOfBirth.name|localize_translatable_string }}{#
|
|
||||||
#}{% else %}{#
|
|
||||||
#}{{ 'Unknown country of birth'|trans }}{#
|
|
||||||
#}{% endif %}{#
|
|
||||||
#}",{#
|
|
||||||
#}"{# nationality
|
|
||||||
#}{% if person.nationality is not null %}{#
|
|
||||||
#}{{ person.nationality.name|localize_translatable_string }}{#
|
|
||||||
#}{% else %}{#
|
|
||||||
#}{{ 'Without nationality'|trans }}{#
|
|
||||||
#}{% endif %}{#
|
|
||||||
#}",{#
|
|
||||||
#}"{# spokenLanguages
|
|
||||||
#}{% if person.spokenLanguages|length == 0 %}{#
|
|
||||||
#}{{ 'Unknown spoken languages'|trans }}{#
|
|
||||||
#}{% else %}{#
|
|
||||||
#}{% for lang in person.spokenLanguages %}{#
|
|
||||||
#}{{ lang.name|localize_translatable_string }}{% if not loop.last %},{% endif %}{#
|
|
||||||
#}{% endfor %}{#
|
|
||||||
#}{% endif %}{#
|
|
||||||
#}",{#
|
|
||||||
#}"{{ person.email|csv_cell }}",{#
|
|
||||||
#}"{{ person.phonenumber|csv_cell }}",{#
|
|
||||||
#}"{# maritalStatus
|
|
||||||
#}{% if person.maritalStatus is not null %}{#
|
|
||||||
#}{{ person.maritalStatus.name|localize_translatable_string}}{#
|
|
||||||
#}{% else %}{#
|
|
||||||
#}{{ 'Unknown marital status'|trans }}{#
|
|
||||||
#}{% endif %}{#
|
|
||||||
#}",{#
|
|
||||||
#}"{{ person.center|csv_cell }}",{#
|
|
||||||
#}{% if cf_group %}{#
|
|
||||||
#}{% for customField in cf_group.customFields %}{#
|
|
||||||
#}{% if customField.type == 'title' %}{#
|
|
||||||
#}""{#
|
|
||||||
#}{% else %}{#
|
|
||||||
#}"{{ chill_custom_field_widget(person.cFData , customField, 'csv') }}"{#
|
|
||||||
#}{% endif %}{#
|
|
||||||
#}{% if not loop.last %},{% endif %}{#
|
|
||||||
#}{% endfor %}{#
|
|
||||||
#}{% endif %}{#
|
|
||||||
#}{{ '\r\n'|raw }}{#
|
|
||||||
|
|
||||||
#}{% endfor %}
|
|
@ -1,149 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Chill is a software for social workers
|
|
||||||
*
|
|
||||||
* Copyright (C) 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\Tests\Controller;
|
|
||||||
|
|
||||||
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
|
|
||||||
use Symfony\Component\Security\Core\Role\Role;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests for the export of a person
|
|
||||||
*/
|
|
||||||
|
|
||||||
class PersonControllerExportTest extends WebTestCase
|
|
||||||
{
|
|
||||||
/** @var \Doctrine\ORM\EntityManagerInterface The entity manager */
|
|
||||||
private $em;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prepare the client and the entity manager. The client send a Gest requestion
|
|
||||||
* on the route chill_person_export.
|
|
||||||
*/
|
|
||||||
protected function setUp()
|
|
||||||
{
|
|
||||||
$this->client = static::createClient(array(), array(
|
|
||||||
'PHP_AUTH_USER' => 'center a_social',
|
|
||||||
'PHP_AUTH_PW' => 'password',
|
|
||||||
));
|
|
||||||
|
|
||||||
$exportUrl = $this->client->getContainer()->get('router')->generate('chill_person_export',
|
|
||||||
array('_locale' => 'fr'));
|
|
||||||
|
|
||||||
$this->client->request('GET', $exportUrl);
|
|
||||||
|
|
||||||
$this->em = $this->client->getContainer()->get('doctrine.orm.entity_manager');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test the format of the exportAction :
|
|
||||||
* - check if the file has the csv format
|
|
||||||
* - check if each row as the same number of cell than the first row
|
|
||||||
* - check if the number of row of the csv file is the same than the number of persons
|
|
||||||
*
|
|
||||||
* @return The content of the export
|
|
||||||
*/
|
|
||||||
public function testExportActionFormat()
|
|
||||||
{
|
|
||||||
$response = $this->client->getResponse();
|
|
||||||
|
|
||||||
$this->assertTrue(
|
|
||||||
strpos($response->headers->get('Content-Type'),'text/csv') !== false,
|
|
||||||
'The csv file is well received');
|
|
||||||
|
|
||||||
$content = $response->getContent();
|
|
||||||
$rows = str_getcsv($content, "\n");
|
|
||||||
$headerRow = array_pop($rows);
|
|
||||||
$header = str_getcsv($headerRow);
|
|
||||||
$headerSize = sizeof($header);
|
|
||||||
$numberOfRows = 0;
|
|
||||||
|
|
||||||
foreach ($rows as $row) {
|
|
||||||
$rowContent = str_getcsv($row);
|
|
||||||
|
|
||||||
$this->assertTrue(
|
|
||||||
sizeof($rowContent) == $headerSize,
|
|
||||||
'Each row of the csv contains the good number of elements ('
|
|
||||||
. 'regarding to the first row');
|
|
||||||
|
|
||||||
$numberOfRows ++;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
$chillSecurityHelper = $this->client->getContainer()->get('chill.main.security.authorization.helper');
|
|
||||||
$user = $this->client->getContainer()->get('security.context')->getToken()->getUser();
|
|
||||||
|
|
||||||
$reachableCenters = $chillSecurityHelper->getReachableCenters($user,
|
|
||||||
new Role('CHILL_PERSON_SEE'));
|
|
||||||
|
|
||||||
$personRepository = $this->em->getRepository('ChillPersonBundle:Person');
|
|
||||||
$qb = $personRepository->createQueryBuilder('p');
|
|
||||||
$qb->where($qb->expr()->in('p.center', ':centers'))
|
|
||||||
->setParameter('centers', $reachableCenters);
|
|
||||||
$persons = $qb->getQuery()->getResult();
|
|
||||||
|
|
||||||
|
|
||||||
$this->assertTrue(
|
|
||||||
$numberOfRows == (sizeof($persons)),
|
|
||||||
'The csv file has a number of row equivalent than the number of '
|
|
||||||
. 'person in the db'
|
|
||||||
);
|
|
||||||
|
|
||||||
return $content;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check that the export file do not contain a person form center B
|
|
||||||
*
|
|
||||||
* @depends testExportActionFormat
|
|
||||||
*/
|
|
||||||
public function testExportActionNotContainingPersonFromCenterB($content)
|
|
||||||
{
|
|
||||||
$centerB = $this->em->getRepository('ChillMainBundle:Center')
|
|
||||||
->findOneBy(array('name' => 'Center B'));
|
|
||||||
|
|
||||||
$person = $this->em->getRepository('ChillPersonBundle:Person')
|
|
||||||
->findOneBy(array('center' => $centerB));
|
|
||||||
|
|
||||||
$this->assertFalse(strpos($person->getFirstName(), $content));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check that the export file contains information about a random person
|
|
||||||
* of center A
|
|
||||||
* @depends testExportActionFormat
|
|
||||||
*/
|
|
||||||
public function testExportActionContainsARandomPersonFromCenterA($content)
|
|
||||||
{
|
|
||||||
$centerA = $this->em->getRepository('ChillMainBundle:Center')
|
|
||||||
->findOneBy(array('name' => 'Center A'));
|
|
||||||
|
|
||||||
$person = $this->em->getRepository('ChillPersonBundle:Person')
|
|
||||||
->findOneBy(array('center' => $centerA));
|
|
||||||
|
|
||||||
$this->assertContains($person->getFirstName(), $content);
|
|
||||||
$this->assertContains($person->getLastName(), $content);
|
|
||||||
$this->assertContains($person->getGender(), $content);
|
|
||||||
|
|
||||||
$this->markTestIncomplete('Test other information of the person');
|
|
||||||
}
|
|
||||||
}
|
|
@ -44,6 +44,15 @@ class ListPersonTest extends AbstractExportTest
|
|||||||
$container = self::$kernel->getContainer();
|
$container = self::$kernel->getContainer();
|
||||||
|
|
||||||
$this->export = $container->get('chill.person.export.list_person');
|
$this->export = $container->get('chill.person.export.list_person');
|
||||||
|
|
||||||
|
// add a fake request with a default locale (used in translatable string)
|
||||||
|
$prophet = new \Prophecy\Prophet;
|
||||||
|
$request = $prophet->prophesize();
|
||||||
|
$request->willExtend(\Symfony\Component\HttpFoundation\Request::class);
|
||||||
|
$request->getLocale()->willReturn('fr');
|
||||||
|
|
||||||
|
$container->get('request_stack')
|
||||||
|
->push($request->reveal());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -62,7 +71,10 @@ class ListPersonTest extends AbstractExportTest
|
|||||||
array('fields' => ['id', 'birthdate', 'gender', 'memo', 'email', 'phonenumber']),
|
array('fields' => ['id', 'birthdate', 'gender', 'memo', 'email', 'phonenumber']),
|
||||||
array('fields' => ['firstName', 'lastName', 'phonenumber']),
|
array('fields' => ['firstName', 'lastName', 'phonenumber']),
|
||||||
array('fields' => ['id', 'nationality']),
|
array('fields' => ['id', 'nationality']),
|
||||||
array('fields' => ['id', 'countryOfBirth'])
|
array('fields' => ['id', 'countryOfBirth']),
|
||||||
|
array('fields' => ['id', 'address_street_address_1',
|
||||||
|
'address_street_address_2', 'address_valid_from', 'address_postcode_label',
|
||||||
|
'address_postcode_code', 'address_country_name', 'address_country_code'])
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user