Refactor ListPersonHelper and ListPerson to simplify process and allow to add customization of fields

This commit is contained in:
Julien Fastré 2024-03-15 15:02:12 +01:00
parent dfe780f0f5
commit ccf3324bc2
Signed by: julienfastre
GPG Key ID: BDE2190974723FCB
10 changed files with 134 additions and 251 deletions

View File

@ -0,0 +1,5 @@
kind: Feature
body: Allow to customize list person with new fields
time: 2024-03-19T17:21:00.873293991+01:00
custom:
Issue: "238"

View File

@ -13,6 +13,7 @@ namespace Chill\PersonBundle;
use Chill\PersonBundle\Actions\Remove\PersonMoveSqlHandlerInterface; use Chill\PersonBundle\Actions\Remove\PersonMoveSqlHandlerInterface;
use Chill\PersonBundle\DependencyInjection\CompilerPass\AccompanyingPeriodTimelineCompilerPass; use Chill\PersonBundle\DependencyInjection\CompilerPass\AccompanyingPeriodTimelineCompilerPass;
use Chill\PersonBundle\Export\Helper\CustomizeListPersonHelperInterface;
use Chill\PersonBundle\Service\EntityInfo\AccompanyingPeriodInfoUnionQueryPartInterface; use Chill\PersonBundle\Service\EntityInfo\AccompanyingPeriodInfoUnionQueryPartInterface;
use Chill\PersonBundle\Widget\PersonListWidgetFactory; use Chill\PersonBundle\Widget\PersonListWidgetFactory;
use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\ContainerBuilder;
@ -32,5 +33,7 @@ class ChillPersonBundle extends Bundle
->addTag('chill_person.accompanying_period_info_part'); ->addTag('chill_person.accompanying_period_info_part');
$container->registerForAutoconfiguration(PersonMoveSqlHandlerInterface::class) $container->registerForAutoconfiguration(PersonMoveSqlHandlerInterface::class)
->addTag('chill_person.person_move_handler'); ->addTag('chill_person.person_move_handler');
$container->registerForAutoconfiguration(CustomizeListPersonHelperInterface::class)
->addTag('chill_person.list_person_customizer');
} }
} }

View File

@ -14,10 +14,8 @@ namespace Chill\PersonBundle\Export\Export;
use Chill\CustomFieldsBundle\CustomFields\CustomFieldChoice; use Chill\CustomFieldsBundle\CustomFields\CustomFieldChoice;
use Chill\CustomFieldsBundle\Entity\CustomField; use Chill\CustomFieldsBundle\Entity\CustomField;
use Chill\CustomFieldsBundle\Service\CustomFieldProvider; use Chill\CustomFieldsBundle\Service\CustomFieldProvider;
use Chill\MainBundle\Export\ExportElementValidatedInterface;
use Chill\MainBundle\Export\FormatterInterface; use Chill\MainBundle\Export\FormatterInterface;
use Chill\MainBundle\Export\GroupedExportInterface; use Chill\MainBundle\Export\GroupedExportInterface;
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\Templating\TranslatableStringHelper; use Chill\MainBundle\Templating\TranslatableStringHelper;
@ -30,21 +28,17 @@ use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Query; use Doctrine\ORM\Query;
use PhpOffice\PhpSpreadsheet\Shared\Date; use PhpOffice\PhpSpreadsheet\Shared\Date;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
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\Context\ExecutionContextInterface;
/** /**
* Render a list of people. * Render a list of people.
*/ */
class ListPerson implements ExportElementValidatedInterface, ListInterface, GroupedExportInterface class ListPerson implements ListInterface, GroupedExportInterface
{ {
private array $slugs = []; private array $slugs = [];
private readonly bool $filterStatsByCenters; private readonly bool $filterStatsByCenters;
public function __construct( public function __construct(
private readonly ExportAddressHelper $addressHelper,
private readonly CustomFieldProvider $customFieldProvider, private readonly CustomFieldProvider $customFieldProvider,
private readonly ListPersonHelper $listPersonHelper, private readonly ListPersonHelper $listPersonHelper,
private readonly EntityManagerInterface $entityManager, private readonly EntityManagerInterface $entityManager,
@ -56,39 +50,6 @@ class ListPerson implements ExportElementValidatedInterface, ListInterface, Grou
public function buildForm(FormBuilderInterface $builder) public function buildForm(FormBuilderInterface $builder)
{ {
$choices = array_combine(ListPersonHelper::FIELDS, ListPersonHelper::FIELDS);
foreach ($this->getCustomFields() as $cf) {
$choices[$this->translatableStringHelper->localize($cf->getName())]
=
$cf->getSlug();
}
// Add a checkbox to select fields
$builder->add('fields', ChoiceType::class, [
'multiple' => true,
'expanded' => true,
'choices' => $choices,
'label' => 'Fields to include in export',
'choice_attr' => static function (string $val): array {
// add a 'data-display-target' for address fields
if (str_starts_with($val, 'address') || 'center' === $val || 'household' === $val) {
return ['data-display-target' => 'address_date'];
}
return [];
},
'constraints' => [new Callback([
'callback' => static function ($selected, ExecutionContextInterface $context) {
if (0 === \count($selected)) {
$context->buildViolation('You must select at least one element')
->atPath('fields')
->addViolation();
}
},
])],
]);
// 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' => 'Data valid at this date', 'label' => 'Data valid at this date',
@ -99,15 +60,7 @@ class ListPerson implements ExportElementValidatedInterface, ListInterface, Grou
public function getFormDefaultData(): array public function getFormDefaultData(): array
{ {
$choices = array_combine(ListPersonHelper::FIELDS, ListPersonHelper::FIELDS); return ['address_date' => new \DateTimeImmutable()];
foreach ($this->getCustomFields() as $cf) {
$choices[$this->translatableStringHelper->localize($cf->getName())]
=
$cf->getSlug();
}
return ['fields' => array_values($choices), 'address_date' => new \DateTimeImmutable()];
} }
public function getAllowedFormattersTypes() public function getAllowedFormattersTypes()
@ -127,7 +80,7 @@ class ListPerson implements ExportElementValidatedInterface, ListInterface, Grou
public function getLabels($key, array $values, $data) public function getLabels($key, array $values, $data)
{ {
if (\in_array($key, $this->listPersonHelper->getAllPossibleFields(), true)) { if (\in_array($key, $this->listPersonHelper->getAllKeys(), true)) {
return $this->listPersonHelper->getLabels($key, $values, $data); return $this->listPersonHelper->getLabels($key, $values, $data);
} }
@ -138,28 +91,12 @@ class ListPerson implements ExportElementValidatedInterface, ListInterface, Grou
{ {
$fields = []; $fields = [];
foreach (ListPersonHelper::FIELDS as $key) { foreach ($this->listPersonHelper->getAllKeys() as $key) {
if (!\in_array($key, $data['fields'], true)) {
continue;
}
if (str_starts_with($key, 'address_fields')) {
$fields = \array_merge($fields, $this->addressHelper->getKeys(ExportAddressHelper::F_ALL, 'address_fields'));
continue;
}
if ('lifecycleUpdate' === $key) {
$fields = \array_merge($fields, ['createdAt', 'createdBy', 'updatedAt', 'updatedBy']);
continue;
}
$fields[] = $key; $fields[] = $key;
} }
// add the key from slugs and return // add the key from slugs and return
return \array_merge($fields, \array_keys($this->slugs)); return [...$fields, ...\array_keys($this->slugs)];
} }
public function getResult($query, $data) public function getResult($query, $data)
@ -184,11 +121,6 @@ class ListPerson implements ExportElementValidatedInterface, ListInterface, Grou
{ {
$centers = array_map(static fn ($el) => $el['center'], $acl); $centers = array_map(static fn ($el) => $el['center'], $acl);
// throw an error if any fields are present
if (!\array_key_exists('fields', $data)) {
throw new \Doctrine\DBAL\Exception\InvalidArgumentException('any fields have been checked');
}
$qb = $this->entityManager->createQueryBuilder() $qb = $this->entityManager->createQueryBuilder()
->from(Person::class, 'person'); ->from(Person::class, 'person');
@ -202,15 +134,9 @@ class ListPerson implements ExportElementValidatedInterface, ListInterface, Grou
->setParameter('authorized_centers', $centers); ->setParameter('authorized_centers', $centers);
} }
$fields = $data['fields']; $this->listPersonHelper->addSelect($qb, $data['address_date']);
$this->listPersonHelper->addSelect($qb, $fields, $data['address_date']);
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)) {
@ -251,26 +177,6 @@ class ListPerson implements ExportElementValidatedInterface, ListInterface, Grou
return [Declarations::PERSON_TYPE]; return [Declarations::PERSON_TYPE];
} }
public function validateForm($data, ExecutionContextInterface $context)
{
// get the field starting with address_
$addressFields = array_filter(
ListPersonHelper::FIELDS,
static fn (string $el): bool => str_starts_with($el, 'address_')
);
// check if there is one field starting with address in data
if (\count(array_intersect($data['fields'], $addressFields)) > 0) {
// if a field address is checked, the date must not be empty
if (!$data['address_date'] instanceof \DateTimeImmutable) {
$context
->buildViolation('You must set this date if an address is checked')
->atPath('address_date')
->addViolation();
}
}
}
private function DQLToSlug($cleanedSlug) private function DQLToSlug($cleanedSlug)
{ {
return $this->slugs[$cleanedSlug]['slug']; return $this->slugs[$cleanedSlug]['slug'];
@ -293,9 +199,9 @@ class ListPerson implements ExportElementValidatedInterface, ListInterface, Grou
{ {
return $this->entityManager return $this->entityManager
->createQuery('SELECT cf ' ->createQuery('SELECT cf '
.'FROM ChillCustomFieldsBundle:CustomField cf ' .'FROM '.CustomField::class.' cf '
.'JOIN cf.customFieldGroup g ' .'JOIN cf.customFieldGroup g '
.'WHERE cf.type != :title AND g.entity LIKE :entity') .'WHERE cf.type != :title AND g.entity LIKE :entity AND cf.active = TRUE')
->setParameters([ ->setParameters([
'title' => 'title', 'title' => 'title',
'entity' => \addcslashes(Person::class, '\\'), 'entity' => \addcslashes(Person::class, '\\'),

View File

@ -12,10 +12,8 @@ declare(strict_types=1);
namespace Chill\PersonBundle\Export\Export; namespace Chill\PersonBundle\Export\Export;
use Chill\MainBundle\Export\AccompanyingCourseExportHelper; use Chill\MainBundle\Export\AccompanyingCourseExportHelper;
use Chill\MainBundle\Export\ExportElementValidatedInterface;
use Chill\MainBundle\Export\FormatterInterface; use Chill\MainBundle\Export\FormatterInterface;
use Chill\MainBundle\Export\GroupedExportInterface; use Chill\MainBundle\Export\GroupedExportInterface;
use Chill\MainBundle\Export\Helper\ExportAddressHelper;
use Chill\MainBundle\Export\ListInterface; use Chill\MainBundle\Export\ListInterface;
use Chill\MainBundle\Form\Type\PickRollingDateType; use Chill\MainBundle\Form\Type\PickRollingDateType;
use Chill\MainBundle\Service\RollingDate\RollingDate; use Chill\MainBundle\Service\RollingDate\RollingDate;
@ -30,22 +28,18 @@ use DateTimeImmutable;
use Doctrine\ORM\AbstractQuery; use Doctrine\ORM\AbstractQuery;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
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\Context\ExecutionContextInterface;
/** /**
* List the persons, having an accompanying period. * List the persons, having an accompanying period.
* *
* Details of the accompanying period are not included * Details of the accompanying period are not included
*/ */
final readonly class ListPersonHavingAccompanyingPeriod implements ExportElementValidatedInterface, ListInterface, GroupedExportInterface final readonly class ListPersonHavingAccompanyingPeriod implements ListInterface, GroupedExportInterface
{ {
private bool $filterStatsByCenters; private bool $filterStatsByCenters;
public function __construct( public function __construct(
private ExportAddressHelper $addressHelper,
private ListPersonHelper $listPersonHelper, private ListPersonHelper $listPersonHelper,
private EntityManagerInterface $entityManager, private EntityManagerInterface $entityManager,
private RollingDateConverterInterface $rollingDateConverter, private RollingDateConverterInterface $rollingDateConverter,
@ -56,32 +50,6 @@ final readonly class ListPersonHavingAccompanyingPeriod implements ExportElement
public function buildForm(FormBuilderInterface $builder) public function buildForm(FormBuilderInterface $builder)
{ {
$choices = array_combine(ListPersonHelper::FIELDS, ListPersonHelper::FIELDS);
$builder->add('fields', ChoiceType::class, [
'multiple' => true,
'expanded' => true,
'choices' => $choices,
'label' => 'Fields to include in export',
'choice_attr' => static function (string $val): array {
// add a 'data-display-target' for address fields
if (str_starts_with($val, 'address') || 'center' === $val || 'household' === $val) {
return ['data-display-target' => 'address_date'];
}
return [];
},
'constraints' => [new Callback([
'callback' => static function ($selected, ExecutionContextInterface $context) {
if (0 === \count($selected)) {
$context->buildViolation('You must select at least one element')
->atPath('fields')
->addViolation();
}
},
])],
]);
$builder->add('address_date_rolling', PickRollingDateType::class, [ $builder->add('address_date_rolling', PickRollingDateType::class, [
'label' => 'Data valid at this date', 'label' => 'Data valid at this date',
'help' => 'Data regarding center, addresses, and so on will be computed at this date', 'help' => 'Data regarding center, addresses, and so on will be computed at this date',
@ -90,9 +58,7 @@ final readonly class ListPersonHavingAccompanyingPeriod implements ExportElement
public function getFormDefaultData(): array public function getFormDefaultData(): array
{ {
$choices = array_combine(ListPersonHelper::FIELDS, ListPersonHelper::FIELDS); return ['address_date_rolling' => new RollingDate(RollingDate::T_TODAY)];
return ['fields' => array_values($choices), 'address_date_rolling' => new RollingDate(RollingDate::T_TODAY)];
} }
public function getAllowedFormattersTypes() public function getAllowedFormattersTypes()
@ -117,29 +83,7 @@ final readonly class ListPersonHavingAccompanyingPeriod implements ExportElement
public function getQueryKeys($data) public function getQueryKeys($data)
{ {
$fields = []; return $this->listPersonHelper->getAllKeys();
foreach (ListPersonHelper::FIELDS as $key) {
if (!\in_array($key, $data['fields'], true)) {
continue;
}
if (str_starts_with($key, 'address_fields')) {
$fields = array_merge($fields, $this->addressHelper->getKeys(ExportAddressHelper::F_ALL, 'address_fields'));
continue;
}
if ('lifecycleUpdate' === $key) {
$fields = array_merge($fields, ['createdAt', 'createdBy', 'updatedAt', 'updatedBy']);
continue;
}
$fields[] = $key;
}
return $fields;
} }
public function getResult($query, $data) public function getResult($query, $data)
@ -164,11 +108,6 @@ final readonly class ListPersonHavingAccompanyingPeriod implements ExportElement
{ {
$centers = array_map(static fn ($el) => $el['center'], $acl); $centers = array_map(static fn ($el) => $el['center'], $acl);
// throw an error if any fields are present
if (!\array_key_exists('fields', $data)) {
throw new \Doctrine\DBAL\Exception\InvalidArgumentException('any fields have been checked');
}
$qb = $this->entityManager->createQueryBuilder(); $qb = $this->entityManager->createQueryBuilder();
$qb->from(Person::class, 'person') $qb->from(Person::class, 'person')
@ -185,9 +124,7 @@ final readonly class ListPersonHavingAccompanyingPeriod implements ExportElement
)->setParameter('authorized_centers', $centers); )->setParameter('authorized_centers', $centers);
} }
$fields = $data['fields']; $this->listPersonHelper->addSelect($qb, $this->rollingDateConverter->convert($data['address_date_rolling']));
$this->listPersonHelper->addSelect($qb, $fields, $this->rollingDateConverter->convert($data['address_date_rolling']));
AccompanyingCourseExportHelper::addClosingMotiveExclusionClause($qb); AccompanyingCourseExportHelper::addClosingMotiveExclusionClause($qb);
@ -208,24 +145,4 @@ final readonly class ListPersonHavingAccompanyingPeriod implements ExportElement
{ {
return [Declarations::PERSON_TYPE, Declarations::ACP_TYPE]; return [Declarations::PERSON_TYPE, Declarations::ACP_TYPE];
} }
public function validateForm($data, ExecutionContextInterface $context)
{
// get the field starting with address_
$addressFields = array_filter(
ListPersonHelper::FIELDS,
static fn (string $el): bool => str_starts_with($el, 'address_')
);
// check if there is one field starting with address in data
if (\count(array_intersect($data['fields'], $addressFields)) > 0) {
// if a field address is checked, the date must not be empty
if (!$data['address_date'] instanceof \DateTimeImmutable) {
$context
->buildViolation('You must set this date if an address is checked')
->atPath('address_date')
->addViolation();
}
}
}
} }

View File

@ -120,7 +120,7 @@ final readonly class ListPersonWithAccompanyingPeriodDetails implements ListInte
$this->filterListAccompanyingPeriodHelper->addFilterAccompanyingPeriods($qb, $requiredModifiers, $acl, $data); $this->filterListAccompanyingPeriodHelper->addFilterAccompanyingPeriods($qb, $requiredModifiers, $acl, $data);
$this->listPersonHelper->addSelect($qb, ListPersonHelper::FIELDS, $this->rollingDateConverter->convert($data['address_date'])); $this->listPersonHelper->addSelect($qb, $this->rollingDateConverter->convert($data['address_date']));
$this->listAccompanyingPeriodHelper->addSelectClauses($qb, $this->rollingDateConverter->convert($data['address_date'])); $this->listAccompanyingPeriodHelper->addSelectClauses($qb, $this->rollingDateConverter->convert($data['address_date']));
AccompanyingCourseExportHelper::addClosingMotiveExclusionClause($qb); AccompanyingCourseExportHelper::addClosingMotiveExclusionClause($qb);

View File

@ -0,0 +1,36 @@
<?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 Doctrine\ORM\QueryBuilder;
/**
* This interface provides methods for customizing the list of person.
*/
interface CustomizeListPersonHelperInterface
{
/**
* Alter the keys possibles (column header) for the list.
*/
public function alterKeys(array $existing): array;
public function alterSelect(QueryBuilder $qb, \DateTimeImmutable $computedDate): void;
/**
* Return the callable which transform the doctrine result representation.
*
* If the key is not managed by the current implementation, this method must return null.
*
* @return callable|null return null if the key is not managed by the current implementation
*/
public function getLabels(string $key, array $values, array $data): ?callable;
}

View File

@ -35,9 +35,9 @@ use Symfony\Contracts\Translation\TranslatorInterface;
* *
* for some fields * for some fields
*/ */
class ListPersonHelper final readonly class ListPersonHelper
{ {
final public const FIELDS = [ private const FIELDS = [
'personId', 'personId',
'civility', 'civility',
'firstName', 'firstName',
@ -60,17 +60,31 @@ class ListPersonHelper
'countryOfBirth', 'countryOfBirth',
'nationality', 'nationality',
// add full addresses // add full addresses
'address_fields', // 'address_fields',
// add a list of spoken languages // add a list of spoken languages
'spokenLanguages', 'spokenLanguages',
// add household id // add household id
'household_id', 'household_id',
// add created at, created by, updated at, and updated by // add created at, created by, updated at, and updated by
'lifecycleUpdate', // 'lifecycleUpdate',
'createdAt', 'createdBy', 'updatedAt', 'updatedBy',
]; ];
public function __construct(private readonly ExportAddressHelper $addressHelper, private readonly CenterRepositoryInterface $centerRepository, private readonly CivilityRepositoryInterface $civilityRepository, private readonly CountryRepository $countryRepository, private readonly LanguageRepositoryInterface $languageRepository, private readonly MaritalStatusRepositoryInterface $maritalStatusRepository, private readonly TranslatableStringHelper $translatableStringHelper, private readonly TranslatorInterface $translator, private readonly UserRepositoryInterface $userRepository) public function __construct(
{ private ExportAddressHelper $addressHelper,
private CenterRepositoryInterface $centerRepository,
private CivilityRepositoryInterface $civilityRepository,
private CountryRepository $countryRepository,
private LanguageRepositoryInterface $languageRepository,
private MaritalStatusRepositoryInterface $maritalStatusRepository,
private TranslatableStringHelper $translatableStringHelper,
private TranslatorInterface $translator,
private UserRepositoryInterface $userRepository,
/**
* @var iterable<CustomizeListPersonHelperInterface>
*/
private iterable $customPersonHelpers,
) {
} }
/** /**
@ -82,26 +96,34 @@ class ListPersonHelper
*/ */
public function getAllKeys(): array public function getAllKeys(): array
{ {
return [ $keys = [
...array_filter( ...ListPersonHelper::FIELDS,
ListPersonHelper::FIELDS,
fn (string $key) => !\in_array($key, ['address_fields', 'lifecycleUpdate'], true)
),
...$this->addressHelper->getKeys(ExportAddressHelper::F_ALL, 'address_fields'), ...$this->addressHelper->getKeys(ExportAddressHelper::F_ALL, 'address_fields'),
...['createdAt', 'createdBy', 'updatedAt', 'updatedBy'],
]; ];
foreach ($this->customPersonHelpers as $customize) {
$keys = $customize->alterKeys($keys);
}
return $keys;
} }
/** public function addSelect(QueryBuilder $qb, \DateTimeImmutable $computedDate): void
* @param array<value-of<self::FIELDS>> $fields
*/
public function addSelect(QueryBuilder $qb, array $fields, \DateTimeImmutable $computedDate): void
{ {
foreach (ListPersonHelper::FIELDS as $f) { // we first add all the fields which are handled by the
if (!\in_array($f, $fields, true)) { $focusedFieldKeys = [
continue; 'personId', 'countryOfBirth', 'nationality', // 'address_fields',
} 'spokenLanguages', 'household_id', 'center', // 'lifecycleUpdate',
'genderComment', 'maritalStatus', 'maritalStatusComment', 'civility',
'createdAt', 'createdBy', 'updatedAt', 'updatedBy',
];
$filteredFields = array_filter(
ListPersonHelper::FIELDS,
fn ($field) => !in_array($field, $focusedFieldKeys, true)
);
foreach ($this->getAllKeys() as $f) {
switch ($f) { switch ($f) {
case 'personId': case 'personId':
$qb->addSelect('person.id AS personId'); $qb->addSelect('person.id AS personId');
@ -114,13 +136,6 @@ class ListPersonHelper
break; break;
case 'address_fields':
$this->addCurrentAddressAt($qb, $computedDate);
$qb->leftJoin('personHouseholdAddress.address', 'personAddress');
$this->addressHelper->addSelectClauses(ExportAddressHelper::F_ALL, $qb, 'personAddress', 'address_fields');
break;
case 'spokenLanguages': case 'spokenLanguages':
$qb->addSelect('(SELECT AGGREGATE(language.id) FROM '.Language::class.' language WHERE language MEMBER OF person.spokenLanguages) AS spokenLanguages'); $qb->addSelect('(SELECT AGGREGATE(language.id) FROM '.Language::class.' language WHERE language MEMBER OF person.spokenLanguages) AS spokenLanguages');
@ -154,15 +169,6 @@ class ListPersonHelper
break; 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': case 'genderComment':
$qb->addSelect('person.genderComment.comment AS genderComment'); $qb->addSelect('person.genderComment.comment AS genderComment');
@ -184,25 +190,47 @@ class ListPersonHelper
break; break;
default: default:
$qb->addSelect(sprintf('person.%s as %s', $f, $f)); if (in_array($f, $filteredFields, true)) {
$qb->addSelect(sprintf('person.%s as %s', $f, $f));
}
} }
} }
// address
$this->addCurrentAddressAt($qb, $computedDate);
$qb->leftJoin('personHouseholdAddress.address', 'personAddress');
$this->addressHelper->addSelectClauses(ExportAddressHelper::F_ALL, $qb, 'personAddress', 'address_fields');
// lifecycle update
$qb
->addSelect('person.createdAt AS createdAt')
->addSelect('IDENTITY(person.createdBy) AS createdBy')
->addSelect('person.updatedAt AS updatedAt')
->addSelect('IDENTITY(person.updatedBy) AS updatedBy');
foreach ($this->customPersonHelpers as $customPersonHelper) {
$customPersonHelper->alterSelect($qb, $computedDate);
}
} }
/** /**
* @return array|string[] * @return array|string[]
*
* @deprecated
*/ */
public function getAllPossibleFields(): array public function getAllPossibleFields(): array
{ {
return array_merge( return $this->getAllKeys();
self::FIELDS,
['createdAt', 'createdBy', 'updatedAt', 'updatedBy'],
$this->addressHelper->getKeys(ExportAddressHelper::F_ALL, 'address_fields')
);
} }
public function getLabels($key, array $values, $data): callable public function getLabels($key, array $values, $data): callable
{ {
foreach ($this->customPersonHelpers as $customPersonHelper) {
if (null !== $callable = $customPersonHelper->getLabels($key, $values, $data)) {
return $callable;
}
}
if (str_starts_with((string) $key, 'address_fields')) { if (str_starts_with((string) $key, 'address_fields')) {
return $this->addressHelper->getLabel($key, $values, $data, 'address_fields'); return $this->addressHelper->getLabel($key, $values, $data, 'address_fields');
} }
@ -366,7 +394,7 @@ class ListPersonHelper
}; };
default: default:
if (!\in_array($key, self::getAllPossibleFields(), true)) { if (!\in_array($key, self::getAllKeys(), true)) {
throw new \RuntimeException("this key is not supported by this helper: {$key}"); throw new \RuntimeException("this key is not supported by this helper: {$key}");
} }

View File

@ -11,7 +11,6 @@ declare(strict_types=1);
namespace Chill\PersonBundle\Tests\Export\Export; namespace Chill\PersonBundle\Tests\Export\Export;
use Chill\MainBundle\Export\Helper\ExportAddressHelper;
use Chill\MainBundle\Service\RollingDate\RollingDate; use Chill\MainBundle\Service\RollingDate\RollingDate;
use Chill\MainBundle\Service\RollingDate\RollingDateConverterInterface; use Chill\MainBundle\Service\RollingDate\RollingDateConverterInterface;
use Chill\MainBundle\Test\Export\AbstractExportTest; use Chill\MainBundle\Test\Export\AbstractExportTest;
@ -35,13 +34,11 @@ class ListPersonHavingAccompanyingPeriodTest extends AbstractExportTest
public function getExport() public function getExport()
{ {
$addressHelper = self::$container->get(ExportAddressHelper::class);
$listPersonHelper = self::$container->get(ListPersonHelper::class); $listPersonHelper = self::$container->get(ListPersonHelper::class);
$entityManager = self::$container->get(EntityManagerInterface::class); $entityManager = self::$container->get(EntityManagerInterface::class);
$rollingDateconverter = self::$container->get(RollingDateConverterInterface::class); $rollingDateconverter = self::$container->get(RollingDateConverterInterface::class);
yield new ListPersonHavingAccompanyingPeriod( yield new ListPersonHavingAccompanyingPeriod(
$addressHelper,
$listPersonHelper, $listPersonHelper,
$entityManager, $entityManager,
$rollingDateconverter, $rollingDateconverter,
@ -49,7 +46,6 @@ class ListPersonHavingAccompanyingPeriodTest extends AbstractExportTest
); );
yield new ListPersonHavingAccompanyingPeriod( yield new ListPersonHavingAccompanyingPeriod(
$addressHelper,
$listPersonHelper, $listPersonHelper,
$entityManager, $entityManager,
$rollingDateconverter, $rollingDateconverter,
@ -59,7 +55,7 @@ class ListPersonHavingAccompanyingPeriodTest extends AbstractExportTest
public function getFormData() public function getFormData()
{ {
return [['address_date_rolling' => new RollingDate(RollingDate::T_TODAY), 'fields' => ListPersonHelper::FIELDS]]; return [['address_date_rolling' => new RollingDate(RollingDate::T_TODAY)]];
} }
public function getModifiersCombination() public function getModifiersCombination()

View File

@ -12,7 +12,6 @@ declare(strict_types=1);
namespace Chill\PersonBundle\Tests\Export\Export; namespace Chill\PersonBundle\Tests\Export\Export;
use Chill\CustomFieldsBundle\Service\CustomFieldProvider; use Chill\CustomFieldsBundle\Service\CustomFieldProvider;
use Chill\MainBundle\Export\Helper\ExportAddressHelper;
use Chill\MainBundle\Templating\TranslatableStringHelper; use Chill\MainBundle\Templating\TranslatableStringHelper;
use Chill\MainBundle\Test\Export\AbstractExportTest; use Chill\MainBundle\Test\Export\AbstractExportTest;
use Chill\PersonBundle\Export\Export\ListPerson; use Chill\PersonBundle\Export\Export\ListPerson;
@ -50,14 +49,12 @@ final class ListPersonTest extends AbstractExportTest
public function getExport() public function getExport()
{ {
$addressHelper = self::$container->get(ExportAddressHelper::class);
$customFieldProvider = self::$container->get(CustomFieldProvider::class); $customFieldProvider = self::$container->get(CustomFieldProvider::class);
$listPersonHelper = self::$container->get(ListPersonHelper::class); $listPersonHelper = self::$container->get(ListPersonHelper::class);
$entityManager = self::$container->get(EntityManagerInterface::class); $entityManager = self::$container->get(EntityManagerInterface::class);
$translatableStringHelper = self::$container->get(TranslatableStringHelper::class); $translatableStringHelper = self::$container->get(TranslatableStringHelper::class);
yield new ListPerson( yield new ListPerson(
$addressHelper,
$customFieldProvider, $customFieldProvider,
$listPersonHelper, $listPersonHelper,
$entityManager, $entityManager,
@ -66,7 +63,6 @@ final class ListPersonTest extends AbstractExportTest
); );
yield new ListPerson( yield new ListPerson(
$addressHelper,
$customFieldProvider, $customFieldProvider,
$listPersonHelper, $listPersonHelper,
$entityManager, $entityManager,
@ -77,15 +73,7 @@ final class ListPersonTest extends AbstractExportTest
public function getFormData(): iterable public function getFormData(): iterable
{ {
foreach ([ yield ['address_date' => new \DateTimeImmutable('today')];
['fields' => ['id', 'firstName', 'lastName']],
['fields' => ['id', 'birthdate', 'gender', 'memo', 'email', 'phonenumber']],
['fields' => ['firstName', 'lastName', 'phonenumber']],
['fields' => ['id', 'nationality']],
['fields' => ['id', 'countryOfBirth']],
] as $base) {
yield [...$base, 'address_date' => new \DateTimeImmutable('today')];
}
} }
public function getModifiersCombination(): array public function getModifiersCombination(): array

View File

@ -16,6 +16,10 @@ services:
tags: tags:
- { name: chill.export, alias: list_person } - { name: chill.export, alias: list_person }
Chill\PersonBundle\Export\Helper\ListPersonHelper:
arguments:
$customPersonHelpers: !tagged_iterator chill_person.list_person_customizer
Chill\PersonBundle\Export\Export\ListPersonHavingAccompanyingPeriod: Chill\PersonBundle\Export\Export\ListPersonHavingAccompanyingPeriod:
tags: tags:
- { name: chill.export, alias: list_person_with_acp } - { name: chill.export, alias: list_person_with_acp }