mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-12 13:24:25 +00:00
DX: Refactor ListPerson to extract methods linked to label and select
This commit is contained in:
parent
f434cc5c02
commit
f4c3997e55
@ -20,28 +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\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\Export\Helper\ListPersonHelper;
|
||||||
use Chill\PersonBundle\Security\Authorization\PersonVoter;
|
use Chill\PersonBundle\Security\Authorization\PersonVoter;
|
||||||
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 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;
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
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 Symfony\Contracts\Translation\TranslatorInterface;
|
|
||||||
use function addcslashes;
|
use function addcslashes;
|
||||||
use function array_key_exists;
|
use function array_key_exists;
|
||||||
use function array_keys;
|
use function array_keys;
|
||||||
@ -56,96 +48,35 @@ use function uniqid;
|
|||||||
*/
|
*/
|
||||||
class ListPerson implements ExportElementValidatedInterface, ListInterface, GroupedExportInterface
|
class ListPerson implements ExportElementValidatedInterface, ListInterface, GroupedExportInterface
|
||||||
{
|
{
|
||||||
public const FIELDS = [
|
|
||||||
'id',
|
|
||||||
'civility',
|
|
||||||
'firstName',
|
|
||||||
'lastName',
|
|
||||||
'birthdate',
|
|
||||||
'center',
|
|
||||||
'deathdate',
|
|
||||||
'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 CustomFieldProvider $customFieldProvider;
|
private CustomFieldProvider $customFieldProvider;
|
||||||
|
|
||||||
private EntityManagerInterface $entityManager;
|
private EntityManagerInterface $entityManager;
|
||||||
|
|
||||||
private LanguageRepositoryInterface $languageRepository;
|
private ListPersonHelper $listPersonHelper;
|
||||||
|
|
||||||
private MaritalStatusRepositoryInterface $maritalStatusRepository;
|
|
||||||
|
|
||||||
private $slugs = [];
|
private $slugs = [];
|
||||||
|
|
||||||
private TranslatableStringHelper $translatableStringHelper;
|
private TranslatableStringHelper $translatableStringHelper;
|
||||||
|
|
||||||
private TranslatorInterface $translator;
|
|
||||||
|
|
||||||
private UserRepositoryInterface $userRepository;
|
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
ExportAddressHelper $addressHelper,
|
ExportAddressHelper $addressHelper,
|
||||||
CivilityRepositoryInterface $civilityRepository,
|
|
||||||
CountryRepository $countryRepository,
|
|
||||||
CustomFieldProvider $customFieldProvider,
|
CustomFieldProvider $customFieldProvider,
|
||||||
|
ListPersonHelper $listPersonHelper,
|
||||||
EntityManagerInterface $em,
|
EntityManagerInterface $em,
|
||||||
LanguageRepositoryInterface $languageRepository,
|
TranslatableStringHelper $translatableStringHelper
|
||||||
MaritalStatusRepositoryInterface $maritalStatusRepository,
|
|
||||||
TranslatableStringHelper $translatableStringHelper,
|
|
||||||
TranslatorInterface $translator,
|
|
||||||
UserRepositoryInterface $userRepository
|
|
||||||
) {
|
) {
|
||||||
$this->addressHelper = $addressHelper;
|
$this->addressHelper = $addressHelper;
|
||||||
$this->civilityRepository = $civilityRepository;
|
|
||||||
$this->countryRepository = $countryRepository;
|
|
||||||
$this->entityManager = $em;
|
|
||||||
$this->languageRepository = $languageRepository;
|
|
||||||
$this->maritalStatusRepository = $maritalStatusRepository;
|
|
||||||
$this->translator = $translator;
|
|
||||||
$this->translatableStringHelper = $translatableStringHelper;
|
|
||||||
$this->customFieldProvider = $customFieldProvider;
|
$this->customFieldProvider = $customFieldProvider;
|
||||||
$this->userRepository = $userRepository;
|
$this->listPersonHelper = $listPersonHelper;
|
||||||
|
$this->entityManager = $em;
|
||||||
|
$this->translatableStringHelper = $translatableStringHelper;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function buildForm(FormBuilderInterface $builder)
|
public function buildForm(FormBuilderInterface $builder)
|
||||||
{
|
{
|
||||||
$choices = array_combine(self::FIELDS, self::FIELDS);
|
$choices = array_combine(ListPersonHelper::FIELDS, ListPersonHelper::FIELDS);
|
||||||
|
|
||||||
foreach ($this->getCustomFields() as $cf) {
|
foreach ($this->getCustomFields() as $cf) {
|
||||||
$choices[$this->translatableStringHelper->localize($cf->getName())]
|
$choices[$this->translatableStringHelper->localize($cf->getName())]
|
||||||
@ -205,183 +136,24 @@ 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_fields')) === 'address_fields') {
|
if (in_array($key, $this->listPersonHelper->getAllPossibleFields(), true)) {
|
||||||
return $this->addressHelper->getLabel($key, $values, $data, 'address_fields');
|
return $this->listPersonHelper->getLabels($key, $values, $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ($key) {
|
return $this->getLabelForCustomField($key, $values, $data);
|
||||||
case 'birthdate':
|
|
||||||
case 'deathdate':
|
|
||||||
case 'maritalStatusDate':
|
|
||||||
case 'createdAt':
|
|
||||||
case 'updatedAt':
|
|
||||||
// for birthdate, we have to transform the string into a date
|
|
||||||
// to format the date correctly.
|
|
||||||
return function ($value) use ($key) {
|
|
||||||
if ('_header' === $value) {
|
|
||||||
return $this->translator->trans($key);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (null === $value) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
// warning: won't work with DateTimeImmutable as we reset time a few lines later
|
|
||||||
$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.
|
|
||||||
if (false === $date) {
|
|
||||||
throw new Exception(sprintf('The value %s could '
|
|
||||||
. 'not be converted to %s', $value, DateTime::class));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$hasTime) {
|
|
||||||
$date->setTime(0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
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':
|
|
||||||
// for gender, we have to translate men/women statement
|
|
||||||
return function ($value) use ($key) {
|
|
||||||
if ('_header' === $value) {
|
|
||||||
return $this->translator->trans($key);
|
|
||||||
}
|
|
||||||
|
|
||||||
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 'nationality':
|
|
||||||
return function ($value) use ($key) {
|
|
||||||
if ('_header' === $value) {
|
|
||||||
return $this->translator->trans($key);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (null === $value) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
$country = $this->countryRepository->find($value);
|
|
||||||
|
|
||||||
return $this->translatableStringHelper->localize(
|
|
||||||
$country->getName()
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
default:
|
|
||||||
// for fields which are associated with person
|
|
||||||
if (in_array($key, self::FIELDS, true)) {
|
|
||||||
return function ($value) use ($key) {
|
|
||||||
if ('_header' === $value) {
|
|
||||||
return $this->translator->trans($key);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $value;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->getLabelForCustomField($key, $values, $data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getQueryKeys($data)
|
public function getQueryKeys($data)
|
||||||
{
|
{
|
||||||
$fields = [];
|
$fields = [];
|
||||||
|
|
||||||
foreach (self::FIELDS as $key) {
|
foreach (ListPersonHelper::FIELDS as $key) {
|
||||||
if (!in_array($key, $data['fields'], true)) {
|
if (!in_array($key, $data['fields'], true)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (substr($key, 0, strlen('address_fields')) === 'address_fields') {
|
if (substr($key, 0, strlen('address_fields')) === 'address_fields') {
|
||||||
$fields = array_merge($fields, $this->addressHelper->getKeys(self::HELPER_ATTRIBUTES, 'address_fields'));
|
$fields = array_merge($fields, $this->addressHelper->getKeys(ListPersonHelper::HELPER_ATTRIBUTES, 'address_fields'));
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -442,109 +214,7 @@ class ListPerson implements ExportElementValidatedInterface, ListInterface, Grou
|
|||||||
|
|
||||||
$fields = $data['fields'];
|
$fields = $data['fields'];
|
||||||
|
|
||||||
foreach (self::FIELDS as $f) {
|
$this->listPersonHelper->addSelect($qb, $fields, $data['address_date']);
|
||||||
if (!in_array($f, $fields, true)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch ($f) {
|
|
||||||
case 'countryOfBirth':
|
|
||||||
case 'nationality':
|
|
||||||
$qb->addSelect(sprintf('IDENTITY(person.%s) as %s', $f, $f));
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'address_fields':
|
|
||||||
foreach ($this->addressHelper->getKeys(self::HELPER_ATTRIBUTES, 'address_fields') as $key) {
|
|
||||||
$qb
|
|
||||||
->addSelect(sprintf('IDENTITY(personHouseholdAddress.address) AS %s', $key));
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->addCurrentAddressAt($qb, $data['address_date']);
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'spokenLanguages':
|
|
||||||
$qb
|
|
||||||
->leftJoin('person.spokenLanguages', 'spokenLanguage')
|
|
||||||
->addSelect('AGGREGATE(spokenLanguage.id) AS spokenLanguages')
|
|
||||||
->addGroupBy('person');
|
|
||||||
|
|
||||||
if (in_array('center', $fields, true)) {
|
|
||||||
$qb->addGroupBy('center');
|
|
||||||
}
|
|
||||||
|
|
||||||
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']);
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
default:
|
|
||||||
$qb->addSelect(sprintf('person.%s as %s', $f, $f));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($this->getCustomFields() as $cf) {
|
foreach ($this->getCustomFields() as $cf) {
|
||||||
if (!in_array($cf->getSlug(), $fields, true)) {
|
if (!in_array($cf->getSlug(), $fields, true)) {
|
||||||
@ -595,7 +265,7 @@ class ListPerson implements ExportElementValidatedInterface, ListInterface, Grou
|
|||||||
{
|
{
|
||||||
// get the field starting with address_
|
// get the field starting with address_
|
||||||
$addressFields = array_filter(
|
$addressFields = array_filter(
|
||||||
self::FIELDS,
|
ListPersonHelper::FIELDS,
|
||||||
static fn (string $el): bool => substr($el, 0, 8) === 'address_'
|
static fn (string $el): bool => substr($el, 0, 8) === 'address_'
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -611,29 +281,6 @@ 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'];
|
||||||
|
428
src/Bundle/ChillPersonBundle/Export/Helper/ListPersonHelper.php
Normal file
428
src/Bundle/ChillPersonBundle/Export/Helper/ListPersonHelper.php
Normal file
@ -0,0 +1,428 @@
|
|||||||
|
<?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\Export\Helper;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Export\Helper\ExportAddressHelper;
|
||||||
|
use Chill\MainBundle\Repository\CivilityRepositoryInterface;
|
||||||
|
use Chill\MainBundle\Repository\CountryRepository;
|
||||||
|
use Chill\MainBundle\Repository\LanguageRepositoryInterface;
|
||||||
|
use Chill\MainBundle\Repository\UserRepositoryInterface;
|
||||||
|
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||||
|
use Chill\PersonBundle\Entity\Person;
|
||||||
|
use Chill\PersonBundle\Repository\MaritalStatusRepositoryInterface;
|
||||||
|
use DateTime;
|
||||||
|
use DateTimeImmutable;
|
||||||
|
use Doctrine\ORM\Query;
|
||||||
|
use Doctrine\ORM\QueryBuilder;
|
||||||
|
use Exception;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Shared\Date;
|
||||||
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
|
use function in_array;
|
||||||
|
use function strlen;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper for list person: provide:.
|
||||||
|
*
|
||||||
|
* * the labels;
|
||||||
|
* * add select statement in query
|
||||||
|
*
|
||||||
|
* for some fields
|
||||||
|
*/
|
||||||
|
class ListPersonHelper
|
||||||
|
{
|
||||||
|
public const FIELDS = [
|
||||||
|
'id',
|
||||||
|
'civility',
|
||||||
|
'firstName',
|
||||||
|
'lastName',
|
||||||
|
'birthdate',
|
||||||
|
'center',
|
||||||
|
'deathdate',
|
||||||
|
'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',
|
||||||
|
];
|
||||||
|
|
||||||
|
public 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 CivilityRepositoryInterface $civilityRepository;
|
||||||
|
|
||||||
|
private CountryRepository $countryRepository;
|
||||||
|
|
||||||
|
private LanguageRepositoryInterface $languageRepository;
|
||||||
|
|
||||||
|
private MaritalStatusRepositoryInterface $maritalStatusRepository;
|
||||||
|
|
||||||
|
private TranslatableStringHelper $translatableStringHelper;
|
||||||
|
|
||||||
|
private TranslatorInterface $translator;
|
||||||
|
|
||||||
|
private UserRepositoryInterface $userRepository;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
ExportAddressHelper $addressHelper,
|
||||||
|
CivilityRepositoryInterface $civilityRepository,
|
||||||
|
CountryRepository $countryRepository,
|
||||||
|
LanguageRepositoryInterface $languageRepository,
|
||||||
|
MaritalStatusRepositoryInterface $maritalStatusRepository,
|
||||||
|
TranslatableStringHelper $translatableStringHelper,
|
||||||
|
TranslatorInterface $translator,
|
||||||
|
UserRepositoryInterface $userRepository
|
||||||
|
) {
|
||||||
|
$this->addressHelper = $addressHelper;
|
||||||
|
$this->civilityRepository = $civilityRepository;
|
||||||
|
$this->countryRepository = $countryRepository;
|
||||||
|
$this->languageRepository = $languageRepository;
|
||||||
|
$this->maritalStatusRepository = $maritalStatusRepository;
|
||||||
|
$this->translatableStringHelper = $translatableStringHelper;
|
||||||
|
$this->translator = $translator;
|
||||||
|
$this->userRepository = $userRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array|value-of<self::FIELDS>[] $fields
|
||||||
|
*/
|
||||||
|
public function addSelect(QueryBuilder $qb, array $fields, DateTimeImmutable $computedDate): void
|
||||||
|
{
|
||||||
|
foreach (ListPersonHelper::FIELDS as $f) {
|
||||||
|
if (!in_array($f, $fields, true)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ($f) {
|
||||||
|
case 'countryOfBirth':
|
||||||
|
case 'nationality':
|
||||||
|
$qb->addSelect(sprintf('IDENTITY(person.%s) as %s', $f, $f));
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'address_fields':
|
||||||
|
foreach ($this->addressHelper->getKeys(ListPersonHelper::HELPER_ATTRIBUTES, 'address_fields') as $key) {
|
||||||
|
$qb
|
||||||
|
->addSelect(sprintf('IDENTITY(personHouseholdAddress.address) AS %s', $key));
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->addCurrentAddressAt($qb, $computedDate);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'spokenLanguages':
|
||||||
|
$qb
|
||||||
|
->leftJoin('person.spokenLanguages', 'spokenLanguage')
|
||||||
|
->addSelect('AGGREGATE(spokenLanguage.id) AS spokenLanguages')
|
||||||
|
->addGroupBy('person');
|
||||||
|
|
||||||
|
if (in_array('center', $fields, true)) {
|
||||||
|
$qb->addGroupBy('center');
|
||||||
|
}
|
||||||
|
|
||||||
|
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, $computedDate);
|
||||||
|
|
||||||
|
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', $computedDate);
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
default:
|
||||||
|
$qb->addSelect(sprintf('person.%s as %s', $f, $f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array|string[]
|
||||||
|
*/
|
||||||
|
public function getAllPossibleFields(): array
|
||||||
|
{
|
||||||
|
return array_merge(
|
||||||
|
self::FIELDS,
|
||||||
|
['createdAt', 'createdBy', 'updatedAt', 'updatedBy'],
|
||||||
|
$this->addressHelper->getKeys(self::HELPER_ATTRIBUTES, 'address_fields')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLabels($key, array $values, $data): callable
|
||||||
|
{
|
||||||
|
if (substr($key, 0, strlen('address_fields')) === 'address_fields') {
|
||||||
|
return $this->addressHelper->getLabel($key, $values, $data, 'address_fields');
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ($key) {
|
||||||
|
case 'birthdate':
|
||||||
|
case 'deathdate':
|
||||||
|
case 'maritalStatusDate':
|
||||||
|
case 'createdAt':
|
||||||
|
case 'updatedAt':
|
||||||
|
// for birthdate, we have to transform the string into a date
|
||||||
|
// to format the date correctly.
|
||||||
|
return function ($value) use ($key) {
|
||||||
|
if ('_header' === $value) {
|
||||||
|
return $this->translator->trans($key);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null === $value) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
// warning: won't work with DateTimeImmutable as we reset time a few lines later
|
||||||
|
$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.
|
||||||
|
if (false === $date) {
|
||||||
|
throw new Exception(sprintf('The value %s could '
|
||||||
|
. 'not be converted to %s', $value, DateTime::class));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$hasTime) {
|
||||||
|
$date->setTime(0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
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':
|
||||||
|
// for gender, we have to translate men/women statement
|
||||||
|
return function ($value) use ($key) {
|
||||||
|
if ('_header' === $value) {
|
||||||
|
return $this->translator->trans($key);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 'nationality':
|
||||||
|
return function ($value) use ($key) {
|
||||||
|
if ('_header' === $value) {
|
||||||
|
return $this->translator->trans($key);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null === $value) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$country = $this->countryRepository->find($value);
|
||||||
|
|
||||||
|
return $this->translatableStringHelper->localize(
|
||||||
|
$country->getName()
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
default:
|
||||||
|
// for fields which are associated with person
|
||||||
|
if (in_array($key, ListPersonHelper::FIELDS, true)) {
|
||||||
|
return function ($value) use ($key) {
|
||||||
|
if ('_header' === $value) {
|
||||||
|
return $this->translator->trans($key);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $value;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user