Fixed: [list person] fix list person and add new fields

This commit is contained in:
Julien Fastré 2022-10-26 12:47:32 +02:00
parent 333c305eef
commit f434cc5c02
13 changed files with 457 additions and 92 deletions

View File

@ -5,11 +5,6 @@ parameters:
count: 1 count: 1
path: src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php path: src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php
-
message: "#^Access to an undefined property Chill\\\\PersonBundle\\\\Entity\\\\Household\\\\PersonHouseholdAddress\\:\\:\\$relation\\.$#"
count: 1
path: src/Bundle/ChillPersonBundle/Entity/Household/PersonHouseholdAddress.php
- -
message: "#^Access to an undefined property Chill\\\\PersonBundle\\\\Entity\\\\AccompanyingPeriod\\:\\:\\$work\\.$#" message: "#^Access to an undefined property Chill\\\\PersonBundle\\\\Entity\\\\AccompanyingPeriod\\:\\:\\$work\\.$#"
count: 1 count: 1
@ -30,11 +25,6 @@ parameters:
count: 1 count: 1
path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/MembersEditorNormalizer.php path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/MembersEditorNormalizer.php
-
message: "#^Undefined variable\\: \\$choiceSlug$#"
count: 1
path: src/Bundle/ChillPersonBundle/Export/Export/ListPerson.php
- -
message: "#^Undefined variable\\: \\$choiceSlug$#" message: "#^Undefined variable\\: \\$choiceSlug$#"
count: 1 count: 1

View File

@ -340,11 +340,6 @@ parameters:
count: 1 count: 1
path: src/Bundle/ChillPersonBundle/Export/Aggregator/NationalityAggregator.php path: src/Bundle/ChillPersonBundle/Export/Aggregator/NationalityAggregator.php
-
message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#"
count: 2
path: src/Bundle/ChillPersonBundle/Export/Export/ListPerson.php
- -
message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#" message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#"
count: 1 count: 1

View File

@ -20,32 +20,32 @@ use Symfony\Component\PropertyAccess\PropertyAccessor;
use function strlen; use function strlen;
/** /**
* Helps to load addresses and format them in list * Helps to load addresses and format them in list.
*/ */
class ExportAddressHelper class ExportAddressHelper
{ {
public const ATTRIBUTES = 0b01000000; public const F_AS_STRING = 0b00010000;
public const BUILDING = 0b00001000; public const F_ATTRIBUTES = 0b01000000;
public const COUNTRY = 0b00000001; public const F_BUILDING = 0b00001000;
public const GEOM = 0b00100000; public const F_COUNTRY = 0b00000001;
public const POSTAL_CODE = 0b00000010; public const F_GEOM = 0b00100000;
public const STREET = 0b00000100; public const F_POSTAL_CODE = 0b00000010;
public const STRING = 0b00010000; public const F_STREET = 0b00000100;
private const ALL = [ private const ALL = [
'country' => self::COUNTRY, 'country' => self::F_COUNTRY,
'postal_code' => self::POSTAL_CODE, 'postal_code' => self::F_POSTAL_CODE,
'street' => self::STREET, 'street' => self::F_STREET,
'building' => self::BUILDING, 'building' => self::F_BUILDING,
'string' => self::STRING, 'string' => self::F_AS_STRING,
'geom' => self::GEOM, 'geom' => self::F_GEOM,
'attributes' => self::ATTRIBUTES, 'attributes' => self::F_ATTRIBUTES,
]; ];
private const COLUMN_MAPPING = [ private const COLUMN_MAPPING = [
@ -78,6 +78,8 @@ class ExportAddressHelper
} }
/** /**
* @param self::F_* $params
*
* @return array|string[] * @return array|string[]
*/ */
public function getKeys(int $params, string $prefix = ''): array public function getKeys(int $params, string $prefix = ''): array

View File

@ -12,19 +12,40 @@ declare(strict_types=1);
namespace Chill\MainBundle\Repository; namespace Chill\MainBundle\Repository;
use Chill\MainBundle\Entity\Civility; use Chill\MainBundle\Entity\Civility;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\ORM\EntityManagerInterface;
use Doctrine\Persistence\ManagerRegistry; use Doctrine\ORM\EntityRepository;
/** class CivilityRepository implements CivilityRepositoryInterface
* @method Civility|null find($id, $lockMode = null, $lockVersion = null)
* @method Civility|null findOneBy(array $criteria, array $orderBy = null)
* @method Civility[] findAll()
* @method Civility[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class CivilityRepository extends ServiceEntityRepository
{ {
public function __construct(ManagerRegistry $registry) private EntityRepository $repository;
public function __construct(EntityManagerInterface $entityManager)
{ {
parent::__construct($registry, Civility::class); $this->repository = $entityManager->getRepository($this->getClassName());
}
public function find($id): ?Civility
{
return $this->repository->find($id);
}
public function findAll(): array
{
return $this->repository->findAll();
}
public function findBy(array $criteria, ?array $orderBy = null, ?int $limit = null, ?int $offset = null): array
{
return $this->repository->findBy($criteria, $orderBy, $limit, $offset);
}
public function findOneBy(array $criteria): ?Civility
{
return $this->repository->findOneBy($criteria);
}
public function getClassName(): string
{
return Civility::class;
} }
} }

View File

@ -0,0 +1,34 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\MainBundle\Repository;
use Chill\MainBundle\Entity\Civility;
use Doctrine\Persistence\ObjectRepository;
interface CivilityRepositoryInterface extends ObjectRepository
{
public function find($id): ?Civility;
/**
* @return array|Civility[]
*/
public function findAll(): array;
/**
* @return array|Civility[]
*/
public function findBy(array $criteria, ?array $orderBy = null, ?int $limit = null, ?int $offset = null): array;
public function findOneBy(array $criteria): ?Civility;
public function getClassName(): string;
}

View File

@ -14,15 +14,14 @@ namespace Chill\MainBundle\Repository;
use Chill\MainBundle\Entity\Language; use Chill\MainBundle\Entity\Language;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository; use Doctrine\ORM\EntityRepository;
use Doctrine\Persistence\ObjectRepository;
final class LanguageRepository implements ObjectRepository final class LanguageRepository implements LanguageRepositoryInterface
{ {
private EntityRepository $repository; private EntityRepository $repository;
public function __construct(EntityManagerInterface $entityManager) public function __construct(EntityManagerInterface $entityManager)
{ {
$this->repository = $entityManager->getRepository(Language::class); $this->repository = $entityManager->getRepository($this->getClassName());
} }
public function find($id, $lockMode = null, $lockVersion = null): ?Language public function find($id, $lockMode = null, $lockVersion = null): ?Language
@ -54,7 +53,7 @@ final class LanguageRepository implements ObjectRepository
return $this->repository->findOneBy($criteria, $orderBy); return $this->repository->findOneBy($criteria, $orderBy);
} }
public function getClassName() public function getClassName(): string
{ {
return Language::class; return Language::class;
} }

View File

@ -0,0 +1,37 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\MainBundle\Repository;
use Chill\MainBundle\Entity\Language;
use Doctrine\Persistence\ObjectRepository;
interface LanguageRepositoryInterface extends ObjectRepository
{
public function find($id, $lockMode = null, $lockVersion = null): ?Language;
/**
* @return Language[]
*/
public function findAll(): array;
/**
* @param mixed|null $limit
* @param mixed|null $offset
*
* @return Language[]
*/
public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $offset = null): array;
public function findOneBy(array $criteria, ?array $orderBy = null): ?Language;
public function getClassName(): string;
}

View File

@ -39,6 +39,8 @@ Last updated by: Dernière mise à jour par
on: "le " on: "le "
Last updated on: Dernière mise à jour le Last updated on: Dernière mise à jour le
by_user: "par " by_user: "par "
lifecycleUpdate: Evenements de création et mise à jour
address_fields: Données liées à l'adresse
Edit: Modifier Edit: Modifier
Update: Mettre à jour Update: Mettre à jour
@ -57,6 +59,7 @@ Until: Jusqu'au
#elements used in software #elements used in software
centers: centres centers: centres
Centers: Centres Centers: Centres
center: centre
comment: commentaire comment: commentaire
Comment: Commentaire Comment: Commentaire
Pinned comment: Commentaire épinglé Pinned comment: Commentaire épinglé
@ -236,6 +239,7 @@ Default for: Type de localisation par défaut pour
none: aucun none: aucun
person: usager person: usager
thirdparty: tiers thirdparty: tiers
civility: civilité
#admin section for civility #admin section for civility
abbreviation: abbréviation abbreviation: abbréviation

View File

@ -84,7 +84,7 @@ class PersonHouseholdAddress
public function getHousehold(): ?Household public function getHousehold(): ?Household
{ {
return $this->relation; return $this->household;
} }
public function getPerson(): ?Person public function getPerson(): ?Person

View File

@ -20,15 +20,20 @@ use Chill\MainBundle\Export\GroupedExportInterface;
use Chill\MainBundle\Export\Helper\ExportAddressHelper; use Chill\MainBundle\Export\Helper\ExportAddressHelper;
use Chill\MainBundle\Export\ListInterface; use Chill\MainBundle\Export\ListInterface;
use Chill\MainBundle\Form\Type\ChillDateType; use Chill\MainBundle\Form\Type\ChillDateType;
use Chill\MainBundle\Repository\CivilityRepositoryInterface;
use Chill\MainBundle\Repository\CountryRepository; use Chill\MainBundle\Repository\CountryRepository;
use Chill\MainBundle\Repository\LanguageRepositoryInterface;
use Chill\MainBundle\Repository\UserRepositoryInterface;
use Chill\MainBundle\Templating\TranslatableStringHelper; use Chill\MainBundle\Templating\TranslatableStringHelper;
use Chill\PersonBundle\Entity\Person; use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Export\Declarations; use Chill\PersonBundle\Export\Declarations;
use Chill\PersonBundle\Repository\MaritalStatusRepositoryInterface;
use Chill\PersonBundle\Security\Authorization\PersonVoter; use Chill\PersonBundle\Security\Authorization\PersonVoter;
use DateTime; use DateTime;
use DateTimeImmutable; use DateTimeImmutable;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Query; use Doctrine\ORM\Query;
use Doctrine\ORM\QueryBuilder;
use Exception; use Exception;
use PhpOffice\PhpSpreadsheet\Shared\Date; use PhpOffice\PhpSpreadsheet\Shared\Date;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
@ -44,7 +49,6 @@ use function array_merge;
use function count; use function count;
use function in_array; use function in_array;
use function strlen; use function strlen;
use function strtolower;
use function uniqid; use function uniqid;
/** /**
@ -54,42 +58,89 @@ class ListPerson implements ExportElementValidatedInterface, ListInterface, Grou
{ {
public const FIELDS = [ public const FIELDS = [
'id', 'id',
'civility',
'firstName', 'firstName',
'lastName', 'lastName',
'birthdate', 'birthdate',
'placeOfBirth', 'gender', 'memo', 'email', 'phonenumber', 'center',
'mobilenumber', 'contactInfo', 'countryOfBirth', 'nationality', 'deathdate',
'address', 'placeOfBirth',
'gender',
'genderComment',
'maritalStatus',
'maritalStatusComment',
'maritalStatusDate',
'memo',
'email',
'phonenumber',
'mobilenumber',
'numberOfChildren',
'contactInfo',
'countryOfBirth',
'nationality',
// add full addresses
'address_fields',
// add a list of spoken languages
'spokenLanguages',
// add household id
'household_id',
// add created at, created by, updated at, and updated by
'lifecycleUpdate',
]; ];
private const HELPER_ATTRIBUTES =
ExportAddressHelper::F_ATTRIBUTES |
ExportAddressHelper::F_BUILDING |
ExportAddressHelper::F_COUNTRY |
ExportAddressHelper::F_GEOM |
ExportAddressHelper::F_POSTAL_CODE |
ExportAddressHelper::F_STREET |
ExportAddressHelper::F_AS_STRING;
private ExportAddressHelper $addressHelper; private ExportAddressHelper $addressHelper;
private CivilityRepositoryInterface $civilityRepository;
private CountryRepository $countryRepository; private CountryRepository $countryRepository;
private CustomFieldProvider $customFieldProvider; private CustomFieldProvider $customFieldProvider;
private EntityManagerInterface $entityManager; private EntityManagerInterface $entityManager;
private LanguageRepositoryInterface $languageRepository;
private MaritalStatusRepositoryInterface $maritalStatusRepository;
private $slugs = []; private $slugs = [];
private TranslatableStringHelper $translatableStringHelper; private TranslatableStringHelper $translatableStringHelper;
private TranslatorInterface $translator; private TranslatorInterface $translator;
private UserRepositoryInterface $userRepository;
public function __construct( public function __construct(
CountryRepository $countryRepository,
ExportAddressHelper $addressHelper, ExportAddressHelper $addressHelper,
CivilityRepositoryInterface $civilityRepository,
CountryRepository $countryRepository,
CustomFieldProvider $customFieldProvider,
EntityManagerInterface $em, EntityManagerInterface $em,
TranslatorInterface $translator, LanguageRepositoryInterface $languageRepository,
MaritalStatusRepositoryInterface $maritalStatusRepository,
TranslatableStringHelper $translatableStringHelper, TranslatableStringHelper $translatableStringHelper,
CustomFieldProvider $customFieldProvider TranslatorInterface $translator,
UserRepositoryInterface $userRepository
) { ) {
$this->addressHelper = $addressHelper; $this->addressHelper = $addressHelper;
$this->civilityRepository = $civilityRepository;
$this->countryRepository = $countryRepository; $this->countryRepository = $countryRepository;
$this->entityManager = $em; $this->entityManager = $em;
$this->languageRepository = $languageRepository;
$this->maritalStatusRepository = $maritalStatusRepository;
$this->translator = $translator; $this->translator = $translator;
$this->translatableStringHelper = $translatableStringHelper; $this->translatableStringHelper = $translatableStringHelper;
$this->customFieldProvider = $customFieldProvider; $this->customFieldProvider = $customFieldProvider;
$this->userRepository = $userRepository;
} }
public function buildForm(FormBuilderInterface $builder) public function buildForm(FormBuilderInterface $builder)
@ -110,7 +161,7 @@ class ListPerson implements ExportElementValidatedInterface, ListInterface, Grou
'label' => 'Fields to include in export', 'label' => 'Fields to include in export',
'choice_attr' => static function (string $val): array { 'choice_attr' => static function (string $val): array {
// add a 'data-display-target' for address fields // add a 'data-display-target' for address fields
if (substr($val, 0, 7) === 'address') { if (substr($val, 0, 7) === 'address' || 'center' === $val || 'household' === $val) {
return ['data-display-target' => 'address_date']; return ['data-display-target' => 'address_date'];
} }
@ -130,7 +181,8 @@ class ListPerson implements ExportElementValidatedInterface, ListInterface, Grou
// add a date field for addresses // add a date field for addresses
$builder->add('address_date', ChillDateType::class, [ $builder->add('address_date', ChillDateType::class, [
'label' => 'Address valid at this date', 'label' => 'Data valid at this date',
'help' => 'Data regarding center, addresses, and so on will be computed at this date',
'data' => new DateTimeImmutable(), 'data' => new DateTimeImmutable(),
'input' => 'datetime_immutable', 'input' => 'datetime_immutable',
]); ]);
@ -153,17 +205,21 @@ class ListPerson implements ExportElementValidatedInterface, ListInterface, Grou
public function getLabels($key, array $values, $data) public function getLabels($key, array $values, $data)
{ {
if (substr($key, 0, strlen('address')) === 'address') { if (substr($key, 0, strlen('address_fields')) === 'address_fields') {
return $this->addressHelper->getLabel($key, $values, $data, 'address_'); return $this->addressHelper->getLabel($key, $values, $data, 'address_fields');
} }
switch ($key) { switch ($key) {
case 'birthdate': case 'birthdate':
case 'deathdate':
case 'maritalStatusDate':
case 'createdAt':
case 'updatedAt':
// for birthdate, we have to transform the string into a date // for birthdate, we have to transform the string into a date
// to format the date correctly. // to format the date correctly.
return static function ($value) { return function ($value) use ($key) {
if ('_header' === $value) { if ('_header' === $value) {
return 'birthdate'; return $this->translator->trans($key);
} }
if (null === $value) { if (null === $value) {
@ -172,32 +228,120 @@ class ListPerson implements ExportElementValidatedInterface, ListInterface, Grou
// warning: won't work with DateTimeImmutable as we reset time a few lines later // warning: won't work with DateTimeImmutable as we reset time a few lines later
$date = DateTime::createFromFormat('Y-m-d', $value); $date = DateTime::createFromFormat('Y-m-d', $value);
$hasTime = false;
if (false === $date) {
$date = DateTime::createFromFormat('Y-m-d H:i:s', $value);
$hasTime = true;
}
// check that the creation could occurs. // check that the creation could occurs.
if (false === $date) { if (false === $date) {
throw new Exception(sprintf('The value %s could ' throw new Exception(sprintf('The value %s could '
. 'not be converted to %s', $value, DateTime::class)); . 'not be converted to %s', $value, DateTime::class));
} }
$date->setTime(0, 0, 0); if (!$hasTime) {
$date->setTime(0, 0, 0);
}
return $date; return $date;
}; };
case 'createdBy':
case 'updatedBy':
return function ($value) use ($key) {
if ('_header' === $value) {
return $this->translator->trans($key);
}
if (null === $value) {
return '';
}
return $this->userRepository->find($value)->getLabel();
};
case 'civility':
return function ($value) use ($key) {
if ('_header' === $value) {
return $this->translator->trans($key);
}
if (null === $value) {
return '';
}
$civility = $this->civilityRepository->find($value);
if (null === $civility) {
return '';
}
return $this->translatableStringHelper->localize($civility->getName());
};
case 'gender': case 'gender':
// for gender, we have to translate men/women statement // for gender, we have to translate men/women statement
return function ($value) { return function ($value) use ($key) {
if ('_header' === $value) { if ('_header' === $value) {
return 'gender'; return $this->translator->trans($key);
} }
return $this->translator->trans($value); return $this->translator->trans($value);
}; };
case 'maritalStatus':
return function ($value) use ($key) {
if ('_header' === $value) {
return $this->translator->trans($key);
}
if (null === $value) {
return '';
}
$maritalStatus = $this->maritalStatusRepository->find($value);
return $this->translatableStringHelper->localize($maritalStatus->getName());
};
case 'spokenLanguages':
return function ($value) use ($key) {
if ('_header' === $value) {
return $this->translator->trans($key);
}
if (null === $value) {
return '';
}
$ids = json_decode($value);
return
implode(
'|',
array_map(function ($id) {
if (null === $id) {
return '';
}
$lang = $this->languageRepository->find($id);
if (null === $lang) {
return null;
}
return $this->translatableStringHelper->localize($lang->getName());
}, $ids)
);
};
case 'countryOfBirth': case 'countryOfBirth':
case 'nationality': case 'nationality':
return function ($value) use ($key) { return function ($value) use ($key) {
if ('_header' === $value) { if ('_header' === $value) {
return strtolower($key); return $this->translator->trans($key);
} }
if (null === $value) { if (null === $value) {
@ -214,9 +358,9 @@ class ListPerson implements ExportElementValidatedInterface, ListInterface, Grou
default: default:
// for fields which are associated with person // for fields which are associated with person
if (in_array($key, self::FIELDS, true)) { if (in_array($key, self::FIELDS, true)) {
return static function ($value) use ($key) { return function ($value) use ($key) {
if ('_header' === $value) { if ('_header' === $value) {
return strtolower($key); return $this->translator->trans($key);
} }
return $value; return $value;
@ -231,9 +375,19 @@ class ListPerson implements ExportElementValidatedInterface, ListInterface, Grou
{ {
$fields = []; $fields = [];
foreach ($data['fields'] as $key) { foreach (self::FIELDS as $key) {
if (substr($key, 0, strlen('address')) === 'address') { if (!in_array($key, $data['fields'], true)) {
$fields = array_merge($fields, $this->addressHelper->getKeys(0b01111111, 'address_')); continue;
}
if (substr($key, 0, strlen('address_fields')) === 'address_fields') {
$fields = array_merge($fields, $this->addressHelper->getKeys(self::HELPER_ATTRIBUTES, 'address_fields'));
continue;
}
if ('lifecycleUpdate' === $key) {
$fields = array_merge($fields, ['createdAt', 'createdBy', 'updatedAt', 'updatedBy']);
continue; continue;
} }
@ -286,8 +440,10 @@ class ListPerson implements ExportElementValidatedInterface, ListInterface, Grou
) )
->setParameter('authorized_centers', $centers); ->setParameter('authorized_centers', $centers);
$fields = $data['fields'];
foreach (self::FIELDS as $f) { foreach (self::FIELDS as $f) {
if (!in_array($f, $data['fields'], true)) { if (!in_array($f, $fields, true)) {
continue; continue;
} }
@ -298,31 +454,90 @@ class ListPerson implements ExportElementValidatedInterface, ListInterface, Grou
break; break;
case 'address': case 'address_fields':
foreach ($this->addressHelper->getKeys(0b01111111, 'address_') as $key) { foreach ($this->addressHelper->getKeys(self::HELPER_ATTRIBUTES, 'address_fields') as $key) {
$qb $qb
->addSelect(sprintf('IDENTITY(currentPersonAddress.address) AS %s', $key)); ->addSelect(sprintf('IDENTITY(personHouseholdAddress.address) AS %s', $key));
} }
if (!(in_array('currentPersonAddress', $qb->getAllAliases(), true))) { $this->addCurrentAddressAt($qb, $data['address_date']);
$qb
->leftJoin('person.currentPersonAddress', 'currentPersonAddress') break;
->andWhere(
$qb->expr()->orX( case 'spokenLanguages':
// no address at this time $qb
$qb->expr()->isNull('currentPersonAddress'), ->leftJoin('person.spokenLanguages', 'spokenLanguage')
// there is one address... ->addSelect('AGGREGATE(spokenLanguage.id) AS spokenLanguages')
$qb->expr()->andX( ->addGroupBy('person');
$qb->expr()->lte('currentPersonAddress.validFrom', ':address_date'),
$qb->expr()->orX( if (in_array('center', $fields, true)) {
$qb->expr()->isNull('currentPersonAddress.validTo'), $qb->addGroupBy('center');
$qb->expr()->gt('currentPersonAddress.validTo', ':address_date') }
)
if (in_array('address_fields', $fields, true)) {
$qb->addGroupBy('address_fieldsid');
}
if (in_array('household_id', $fields, true)) {
$qb->addGroupBy('household_id');
}
break;
case 'household_id':
$qb
->addSelect('IDENTITY(personHouseholdAddress.household) AS household_id');
$this->addCurrentAddressAt($qb, $data['address_date']);
break;
case 'center':
$qb
->addSelect('IDENTITY(centerHistory.center) AS center')
->leftJoin('person.centerHistory', 'centerHistory')
->andWhere(
$qb->expr()->orX(
$qb->expr()->isNull('centerHistory'),
$qb->expr()->andX(
$qb->expr()->lte('centerHistory.startDate', ':address_date'),
$qb->expr()->orX(
$qb->expr()->isNull('centerHistory.endDate'),
$qb->expr()->gte('centerHistory.endDate', ':address_date')
) )
) )
) )
->setParameter('address_date', $data['address_date']); )
} ->setParameter('address_date', $data['address_date']);
break;
case 'lifecycleUpdate':
$qb
->addSelect('person.createdAt AS createdAt')
->addSelect('IDENTITY(person.createdBy) AS createdBy')
->addSelect('person.updatedAt AS updatedAt')
->addSelect('IDENTITY(person.updatedBy) AS updatedBy');
break;
case 'genderComment':
$qb->addSelect('person.genderComment.comment AS genderComment');
break;
case 'maritalStatus':
$qb->addSelect('IDENTITY(person.maritalStatus) AS maritalStatus');
break;
case 'maritalStatusComment':
$qb->addSelect('person.maritalStatusComment.comment AS maritalStatusComment');
break;
case 'civility':
$qb->addSelect('IDENTITY(person.civility) AS civility');
break; break;
@ -332,6 +547,10 @@ class ListPerson implements ExportElementValidatedInterface, ListInterface, Grou
} }
foreach ($this->getCustomFields() as $cf) { foreach ($this->getCustomFields() as $cf) {
if (!in_array($cf->getSlug(), $fields, true)) {
continue;
}
$cfType = $this->customFieldProvider->getCustomFieldByType($cf->getType()); $cfType = $this->customFieldProvider->getCustomFieldByType($cf->getType());
if ($cfType instanceof CustomFieldChoice && $cfType->isMultiple($cf)) { if ($cfType instanceof CustomFieldChoice && $cfType->isMultiple($cf)) {
@ -383,7 +602,7 @@ class ListPerson implements ExportElementValidatedInterface, ListInterface, Grou
// check if there is one field starting with address in data // check if there is one field starting with address in data
if (count(array_intersect($data['fields'], $addressFields)) > 0) { if (count(array_intersect($data['fields'], $addressFields)) > 0) {
// if a field address is checked, the date must not be empty // if a field address is checked, the date must not be empty
if (empty($data['address_date'])) { if (!$data['address_date'] instanceof DateTimeImmutable) {
$context $context
->buildViolation('You must set this date if an address is checked') ->buildViolation('You must set this date if an address is checked')
->atPath('address_date') ->atPath('address_date')
@ -392,6 +611,29 @@ class ListPerson implements ExportElementValidatedInterface, ListInterface, Grou
} }
} }
private function addCurrentAddressAt(QueryBuilder $qb, DateTimeImmutable $date): void
{
if (!(in_array('personHouseholdAddress', $qb->getAllAliases(), true))) {
$qb
->leftJoin('person.householdAddresses', 'personHouseholdAddress')
->andWhere(
$qb->expr()->orX(
// no address at this time
$qb->expr()->isNull('personHouseholdAddress'),
// there is one address...
$qb->expr()->andX(
$qb->expr()->lte('personHouseholdAddress.validFrom', ':address_date'),
$qb->expr()->orX(
$qb->expr()->isNull('personHouseholdAddress.validTo'),
$qb->expr()->gt('personHouseholdAddress.validTo', ':address_date')
)
)
)
)
->setParameter('address_date', $date);
}
}
private function DQLToSlug($cleanedSlug) private function DQLToSlug($cleanedSlug)
{ {
return $this->slugs[$cleanedSlug]['slug']; return $this->slugs[$cleanedSlug]['slug'];
@ -464,7 +706,7 @@ class ListPerson implements ExportElementValidatedInterface, ListInterface, Grou
. ' | ' . $label; . ' | ' . $label;
} }
if ('_other' === $slugChoice && $cfType->isChecked($cf, $choiceSlug, $decoded)) { if ('_other' === $slugChoice && $cfType->isChecked($cf, $slugChoice, $decoded)) {
return $cfType->extractOtherValue($cf, $decoded); return $cfType->extractOtherValue($cf, $decoded);
} }

View File

@ -14,9 +14,8 @@ namespace Chill\PersonBundle\Repository;
use Chill\PersonBundle\Entity\MaritalStatus; use Chill\PersonBundle\Entity\MaritalStatus;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository; use Doctrine\ORM\EntityRepository;
use Doctrine\Persistence\ObjectRepository;
class MaritalStatusRepository implements ObjectRepository class MaritalStatusRepository implements MaritalStatusRepositoryInterface
{ {
private EntityRepository $repository; private EntityRepository $repository;

View File

@ -0,0 +1,27 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\Repository;
use Chill\PersonBundle\Entity\MaritalStatus;
interface MaritalStatusRepositoryInterface
{
public function find($id): ?MaritalStatus;
public function findAll(): array;
public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $offset = null): array;
public function findOneBy(array $criteria): ?MaritalStatus;
public function getClassName(): string;
}

View File

@ -89,6 +89,16 @@ Any person selected: Aucune personne sélectionnée
Create a household and add an address: Ajouter une adresse pour une personne non suivie et seule dans un ménage Create a household and add an address: Ajouter une adresse pour une personne non suivie et seule dans un ménage
A new household will be created. The person will be member of this household.: Un nouveau ménage va être créé. La personne sera membre de ce ménage. A new household will be created. The person will be member of this household.: Un nouveau ménage va être créé. La personne sera membre de ce ménage.
Comment on the gender: Commentaire sur le genre Comment on the gender: Commentaire sur le genre
genderComment: Commentaire sur le genre
maritalStatus: État civil
maritalStatusComment: Commentaire sur l'état civil
maritalStatusDate: Date de l'état civil
memo: Commentaire
numberOfChildren: Nombre d'enfants
contactInfo: Commentaire des contacts
spokenLanguages: Langues parlées
# dédoublonnage # dédoublonnage
Old person: Doublon Old person: Doublon
@ -339,6 +349,8 @@ List peoples: Liste des personnes
Create a list of people according to various filters.: Crée une liste des personnes selon différents filtres. Create a list of people according to various filters.: Crée une liste des personnes selon différents filtres.
Fields to include in export: Champs à inclure dans l'export Fields to include in export: Champs à inclure dans l'export
Address valid at this date: Addresse valide à cette date Address valid at this date: Addresse valide à cette date
Data valid at this date: Données valides à cette date
Data regarding center, addresses, and so on will be computed at this date: Les données concernant le centre, l'adresse, le ménage, sera calculé à cette date.
List duplicates: Liste des doublons List duplicates: Liste des doublons
Create a list of duplicate people: Créer la liste des personnes détectées comme doublons. Create a list of duplicate people: Créer la liste des personnes détectées comme doublons.
Count people participating in an accompanying course: Nombre de personnes concernées par un parcours Count people participating in an accompanying course: Nombre de personnes concernées par un parcours
@ -748,6 +760,7 @@ socialAction:
defaultNotificationDelay: Délai de notification par défaut defaultNotificationDelay: Délai de notification par défaut
socialIssue: Problématique sociale socialIssue: Problématique sociale
household_id: Identifiant du ménage
household: household:
allowHolder: Peut être titulaire allowHolder: Peut être titulaire
shareHousehold: Membre du ménage shareHousehold: Membre du ménage
@ -1006,6 +1019,8 @@ export:
Computation date for referrer: Date à laquelle le référent était actif Computation date for referrer: Date à laquelle le référent était actif
by_referrer: by_referrer:
Computation date for referrer: Date à laquelle le référent était actif Computation date for referrer: Date à laquelle le référent était actif
lists:
social_action: social_action:
and children: et dérivés and children: et dérivés