Merge branch 'docgen/improve-context-courses' into 'master'

docgen: some fixes and improvements

See merge request Chill-Projet/chill-bundles!408
This commit is contained in:
Julien Fastré 2022-04-13 07:53:43 +00:00
commit e6169ddffa
8 changed files with 178 additions and 96 deletions

View File

@ -11,6 +11,9 @@ and this project adheres to
## Unreleased ## Unreleased
<!-- write down unreleased development here --> <!-- write down unreleased development here -->
* [docgen] add more persons choices in docgen for course: amongst requestor (if person), resources of course (if person), and PersonResource (if person);
* [docgen] add a new context with a list of activities in course
* [docgen] add a comment in budget lines
## Test releases ## Test releases

View File

@ -15,7 +15,6 @@ use Chill\ActivityBundle\Entity\Activity;
use Chill\ActivityBundle\Entity\ActivityPresence; use Chill\ActivityBundle\Entity\ActivityPresence;
use Chill\ActivityBundle\Entity\ActivityType; use Chill\ActivityBundle\Entity\ActivityType;
use Chill\ActivityBundle\Security\Authorization\ActivityVoter; use Chill\ActivityBundle\Security\Authorization\ActivityVoter;
use Chill\MainBundle\Entity\Embeddable\CommentEmbeddable;
use Chill\MainBundle\Entity\Location; use Chill\MainBundle\Entity\Location;
use Chill\MainBundle\Entity\LocationType; use Chill\MainBundle\Entity\LocationType;
use Chill\MainBundle\Entity\Scope; use Chill\MainBundle\Entity\Scope;
@ -84,7 +83,7 @@ final class ActivityACLAwareRepository implements ActivityACLAwareRepositoryInte
{ {
$rsm = new ResultSetMappingBuilder($this->em); $rsm = new ResultSetMappingBuilder($this->em);
$sql = " $sql = '
SELECT SELECT
a.id AS activity_id, a.id AS activity_id,
date, date,
@ -112,13 +111,13 @@ final class ActivityACLAwareRepository implements ActivityACLAwareRepositoryInte
LEFT JOIN LATERAL (SELECT jsonb_agg(user_id) userids, activity_id FROM activity_user AS au WHERE a.id = au.activity_id GROUP BY activity_id) AS users ON TRUE LEFT JOIN LATERAL (SELECT jsonb_agg(user_id) userids, activity_id FROM activity_user AS au WHERE a.id = au.activity_id GROUP BY activity_id) AS users ON TRUE
LEFT JOIN LATERAL (SELECT jsonb_agg(thirdparty_id) thirdpartyids, activity_id FROM activity_thirdparty AS au WHERE a.id = au.activity_id GROUP BY activity_id) AS thirdparties ON TRUE LEFT JOIN LATERAL (SELECT jsonb_agg(thirdparty_id) thirdpartyids, activity_id FROM activity_thirdparty AS au WHERE a.id = au.activity_id GROUP BY activity_id) AS thirdparties ON TRUE
LEFT JOIN LATERAL (SELECT jsonb_agg(person_id) personids, activity_id FROM activity_person AS au WHERE a.id = au.activity_id GROUP BY activity_id) AS persons ON TRUE LEFT JOIN LATERAL (SELECT jsonb_agg(person_id) personids, activity_id FROM activity_person AS au WHERE a.id = au.activity_id GROUP BY activity_id) AS persons ON TRUE
LEFT JOIN LATERAL (SELECT jsonb_agg(socialaction_id) socialactionids, activity_id FROM postgres.public.chill_activity_activity_chill_person_socialaction AS au WHERE a.id = au.activity_id GROUP BY activity_id) AS actions ON TRUE LEFT JOIN LATERAL (SELECT jsonb_agg(socialaction_id) socialactionids, activity_id FROM chill_activity_activity_chill_person_socialaction AS au WHERE a.id = au.activity_id GROUP BY activity_id) AS actions ON TRUE
LEFT JOIN LATERAL (SELECT jsonb_agg(socialissue_id) socialissueids, activity_id FROM postgres.public.chill_activity_activity_chill_person_socialissue AS au WHERE a.id = au.activity_id GROUP BY activity_id) AS issues ON TRUE LEFT JOIN LATERAL (SELECT jsonb_agg(socialissue_id) socialissueids, activity_id FROM chill_activity_activity_chill_person_socialissue AS au WHERE a.id = au.activity_id GROUP BY activity_id) AS issues ON TRUE
WHERE accompanyingperiod_id = ? WHERE accompanyingperiod_id = ?
ORDER BY a.date DESC, a.id DESC ORDER BY a.date DESC, a.id DESC
LIMIT ? LIMIT ?
"; ';
$rsm $rsm
->addEntityResult(Activity::class, 'a') ->addEntityResult(Activity::class, 'a')
@ -133,7 +132,7 @@ final class ActivityACLAwareRepository implements ActivityACLAwareRepositoryInte
->addFieldResult('location', 'phonenumber1', 'phonenumber1') ->addFieldResult('location', 'phonenumber1', 'phonenumber1')
->addFieldResult('location', 'phonenumber2', 'phonenumber2') ->addFieldResult('location', 'phonenumber2', 'phonenumber2')
->addFieldResult('location', 'email', 'email') ->addFieldResult('location', 'email', 'email')
->addJoinedEntityResult(LocationType::class,'locationType', 'location', 'locationType' ) ->addJoinedEntityResult(LocationType::class, 'locationType', 'location', 'locationType')
->addFieldResult('locationType', 'locationtype_id', 'id') ->addFieldResult('locationType', 'locationtype_id', 'id')
->addFieldResult('locationType', 'locationtype_title', 'title') ->addFieldResult('locationType', 'locationtype_title', 'title')
->addJoinedEntityResult(ActivityType::class, 'activityType', 'a', 'activityType') ->addJoinedEntityResult(ActivityType::class, 'activityType', 'a', 'activityType')
@ -151,8 +150,7 @@ final class ActivityACLAwareRepository implements ActivityACLAwareRepositoryInte
->addScalarResult('socialactionids', 'socialActionIds', Types::JSON) ->addScalarResult('socialactionids', 'socialActionIds', Types::JSON)
->addScalarResult('socialissueids', 'socialIssueIds', Types::JSON) ->addScalarResult('socialissueids', 'socialIssueIds', Types::JSON)
->addScalarResult('durationtimeminute', 'durationTimeMinute', Types::INTEGER) ->addScalarResult('durationtimeminute', 'durationTimeMinute', Types::INTEGER)
->addScalarResult('traveltimeminute', 'travelTimeMinute', Types::INTEGER) ->addScalarResult('traveltimeminute', 'travelTimeMinute', Types::INTEGER);
;
$nq = $this->em->createNativeQuery($sql, $rsm); $nq = $this->em->createNativeQuery($sql, $rsm);

View File

@ -26,10 +26,6 @@ interface ActivityACLAwareRepositoryInterface
* *
* The aim of this method is to get a long list of activities and keep performance. * The aim of this method is to get a long list of activities and keep performance.
* *
* @param AccompanyingPeriod $period
* @param string $role
* @param int|null $limit
* @param array|null $orderBy
* @return array an array of array, each item representing an activity * @return array an array of array, each item representing an activity
*/ */
public function findByAccompanyingPeriodSimplified(AccompanyingPeriod $period, ?int $limit = 1000): array; public function findByAccompanyingPeriodSimplified(AccompanyingPeriod $period, ?int $limit = 1000): array;

View File

@ -1,5 +1,14 @@
<?php <?php
/**
* 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.
*/
declare(strict_types=1);
namespace Chill\ActivityBundle\Service\DocGenerator; namespace Chill\ActivityBundle\Service\DocGenerator;
use Chill\ActivityBundle\Entity\ActivityPresence; use Chill\ActivityBundle\Entity\ActivityPresence;
@ -23,6 +32,7 @@ use Chill\PersonBundle\Repository\SocialWork\SocialIssueRepository;
use Chill\PersonBundle\Service\DocGenerator\AccompanyingPeriodContext; use Chill\PersonBundle\Service\DocGenerator\AccompanyingPeriodContext;
use Chill\ThirdPartyBundle\Entity\ThirdParty; use Chill\ThirdPartyBundle\Entity\ThirdParty;
use Chill\ThirdPartyBundle\Repository\ThirdPartyRepository; use Chill\ThirdPartyBundle\Repository\ThirdPartyRepository;
use DateTime;
use libphonenumber\PhoneNumber; use libphonenumber\PhoneNumber;
use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer; use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
@ -38,18 +48,18 @@ class ListActivitiesByAccompanyingPeriodContext implements
private NormalizerInterface $normalizer; private NormalizerInterface $normalizer;
private TranslatableStringHelperInterface $translatableStringHelper;
private PersonRepository $personRepository; private PersonRepository $personRepository;
private SocialActionRepository $socialActionRepository; private SocialActionRepository $socialActionRepository;
private SocialIssueRepository $socialIssueRepository; private SocialIssueRepository $socialIssueRepository;
private UserRepository $userRepository;
private ThirdPartyRepository $thirdPartyRepository; private ThirdPartyRepository $thirdPartyRepository;
private TranslatableStringHelperInterface $translatableStringHelper;
private UserRepository $userRepository;
public function __construct( public function __construct(
AccompanyingPeriodContext $accompanyingPeriodContext, AccompanyingPeriodContext $accompanyingPeriodContext,
ActivityACLAwareRepositoryInterface $activityACLAwareRepository, ActivityACLAwareRepositoryInterface $activityACLAwareRepository,
@ -72,6 +82,26 @@ class ListActivitiesByAccompanyingPeriodContext implements
$this->userRepository = $userRepository; $this->userRepository = $userRepository;
} }
public function adminFormReverseTransform(array $data): array
{
return $this->accompanyingPeriodContext->adminFormReverseTransform($data);
}
public function adminFormTransform(array $data): array
{
return $this->accompanyingPeriodContext->adminFormTransform($data);
}
public function buildAdminForm(FormBuilderInterface $builder): void
{
$this->accompanyingPeriodContext->buildAdminForm($builder);
}
public function buildPublicForm(FormBuilderInterface $builder, DocGeneratorTemplate $template, $entity): void
{
$this->accompanyingPeriodContext->buildPublicForm($builder, $template, $entity);
}
public function getData(DocGeneratorTemplate $template, $entity, array $contextGenerationData = []): array public function getData(DocGeneratorTemplate $template, $entity, array $contextGenerationData = []): array
{ {
$data = $this->accompanyingPeriodContext->getData($template, $entity, $contextGenerationData); $data = $this->accompanyingPeriodContext->getData($template, $entity, $contextGenerationData);
@ -81,6 +111,46 @@ class ListActivitiesByAccompanyingPeriodContext implements
return $data; return $data;
} }
public function getDescription(): string
{
return 'docgen.Accompanying period with a list of activities description';
}
public function getEntityClass(): string
{
return AccompanyingPeriod::class;
}
public function getFormData(DocGeneratorTemplate $template, $entity): array
{
return $this->accompanyingPeriodContext->getFormData($template, $entity);
}
public static function getKey(): string
{
return self::class;
}
public function getName(): string
{
return 'docgen.Accompanying period with a list of activities';
}
public function hasAdminForm(): bool
{
return $this->accompanyingPeriodContext->hasAdminForm();
}
public function hasPublicForm(DocGeneratorTemplate $template, $entity): bool
{
return $this->accompanyingPeriodContext->hasPublicForm($template, $entity);
}
public function storeGenerated(DocGeneratorTemplate $template, StoredObject $storedObject, object $entity, array $contextGenerationData): void
{
$this->accompanyingPeriodContext->storeGenerated($template, $storedObject, $entity, $contextGenerationData);
}
private function getActivitiesSimplified(AccompanyingPeriod $period) private function getActivitiesSimplified(AccompanyingPeriod $period)
{ {
$activities = $activities =
@ -91,20 +161,21 @@ class ListActivitiesByAccompanyingPeriodContext implements
$activity = $row[0]; $activity = $row[0];
$activity['date'] = $this->normalizer->normalize($activity['date'], 'docgen', [ $activity['date'] = $this->normalizer->normalize($activity['date'], 'docgen', [
AbstractNormalizer::GROUPS => ['docgen:read'], 'docgen:expects' => \DateTime::class AbstractNormalizer::GROUPS => ['docgen:read'], 'docgen:expects' => DateTime::class,
]); ]);
if (null === $activity['location']) { if (null === $activity['location']) {
$activity['location'] = $this->normalizer->normalize(null, 'docgen', [ $activity['location'] = $this->normalizer->normalize(null, 'docgen', [
AbstractNormalizer::GROUPS => ['docgen:read'], 'docgen:expects' => Location::class AbstractNormalizer::GROUPS => ['docgen:read'], 'docgen:expects' => Location::class,
]); ]);
$activity['location']['type'] = 'location'; $activity['location']['type'] = 'location';
} else { } else {
$activity['location']['isNull'] = false; $activity['location']['isNull'] = false;
$activity['location']['type'] = 'location'; $activity['location']['type'] = 'location';
foreach (['1', '2'] as $key) { foreach (['1', '2'] as $key) {
$activity['location']['phonenumber'.$key] = $this->normalizer->normalize( $activity['location']['phonenumber' . $key] = $this->normalizer->normalize(
$activity['location']['phonenumber'.$key], $activity['location']['phonenumber' . $key],
'docgen', 'docgen',
[AbstractNormalizer::GROUPS => ['docgen:read'], 'docgen:expects' => PhoneNumber::class] [AbstractNormalizer::GROUPS => ['docgen:read'], 'docgen:expects' => PhoneNumber::class]
); );
@ -127,7 +198,7 @@ class ListActivitiesByAccompanyingPeriodContext implements
$activity['activityType']['type'] = 'activityType'; $activity['activityType']['type'] = 'activityType';
} else { } else {
$activity['activityType'] = $this->normalizer->normalize(null, 'docgen', [ $activity['activityType'] = $this->normalizer->normalize(null, 'docgen', [
AbstractNormalizer::GROUPS => ['docgen:read'], 'docgen:expects' => ActivityType::class AbstractNormalizer::GROUPS => ['docgen:read'], 'docgen:expects' => ActivityType::class,
]); ]);
} }
@ -139,7 +210,7 @@ class ListActivitiesByAccompanyingPeriodContext implements
$activity['attendee']['type'] = 'activityPresence'; $activity['attendee']['type'] = 'activityPresence';
} else { } else {
$activity['attendee'] = $this->normalizer->normalize(null, 'docgen', [ $activity['attendee'] = $this->normalizer->normalize(null, 'docgen', [
AbstractNormalizer::GROUPS => ['docgen:read'], 'docgen:expects' => ActivityPresence::class AbstractNormalizer::GROUPS => ['docgen:read'], 'docgen:expects' => ActivityPresence::class,
]); ]);
} }
@ -212,65 +283,4 @@ class ListActivitiesByAccompanyingPeriodContext implements
return $results; return $results;
} }
public function getDescription(): string
{
return 'docgen.Accompanying period with a list of activities description';
}
public function getEntityClass(): string
{
return AccompanyingPeriod::class;
}
public static function getKey(): string
{
return self::class;
}
public function getName(): string
{
return 'docgen.Accompanying period with a list of activities';
}
public function storeGenerated(DocGeneratorTemplate $template, StoredObject $storedObject, object $entity, array $contextGenerationData): void
{
$this->accompanyingPeriodContext->storeGenerated($template, $storedObject, $entity, $contextGenerationData);
}
public function adminFormReverseTransform(array $data): array
{
return $this->accompanyingPeriodContext->adminFormReverseTransform($data);
}
public function adminFormTransform(array $data): array
{
return $this->accompanyingPeriodContext->adminFormTransform($data);
}
public function buildAdminForm(FormBuilderInterface $builder): void
{
$this->accompanyingPeriodContext->buildAdminForm($builder);
}
public function hasAdminForm(): bool
{
return $this->accompanyingPeriodContext->hasAdminForm();
}
public function buildPublicForm(FormBuilderInterface $builder, DocGeneratorTemplate $template, $entity): void
{
$this->accompanyingPeriodContext->buildPublicForm($builder, $template, $entity);
}
public function getFormData(DocGeneratorTemplate $template, $entity): array
{
return $this->accompanyingPeriodContext->getFormData($template, $entity);
}
public function hasPublicForm(DocGeneratorTemplate $template, $entity): bool
{
return $this->accompanyingPeriodContext->hasPublicForm($template, $entity);
}
} }

View File

@ -25,13 +25,13 @@ use function count;
*/ */
class SummaryBudget implements SummaryBudgetInterface class SummaryBudget implements SummaryBudgetInterface
{ {
private const QUERY_CHARGE_BY_HOUSEHOLD = 'select SUM(amount) AS sum, type FROM chill_budget.charge WHERE (person_id IN (_ids_) OR household_id = ?) AND NOW() BETWEEN startdate AND COALESCE(enddate, \'infinity\'::timestamp) GROUP BY type'; private const QUERY_CHARGE_BY_HOUSEHOLD = 'select SUM(amount) AS sum, string_agg(comment, \'|\') AS comment, type FROM chill_budget.charge WHERE (person_id IN (_ids_) OR household_id = ?) AND NOW() BETWEEN startdate AND COALESCE(enddate, \'infinity\'::timestamp) GROUP BY type';
private const QUERY_CHARGE_BY_PERSON = 'select SUM(amount) AS sum, type FROM chill_budget.charge WHERE person_id = ? AND NOW() BETWEEN startdate AND COALESCE(enddate, \'infinity\'::timestamp) GROUP BY type'; private const QUERY_CHARGE_BY_PERSON = 'select SUM(amount) AS sum, string_agg(comment, \'|\') AS comment, type FROM chill_budget.charge WHERE person_id = ? AND NOW() BETWEEN startdate AND COALESCE(enddate, \'infinity\'::timestamp) GROUP BY type';
private const QUERY_RESOURCE_BY_HOUSEHOLD = 'select SUM(amount) AS sum, type FROM chill_budget.resource WHERE (person_id IN (_ids_) OR household_id = ?) AND NOW() BETWEEN startdate AND COALESCE(enddate, \'infinity\'::timestamp) GROUP BY type'; private const QUERY_RESOURCE_BY_HOUSEHOLD = 'select SUM(amount) AS sum, string_agg(comment, \'|\') AS comment, type FROM chill_budget.resource WHERE (person_id IN (_ids_) OR household_id = ?) AND NOW() BETWEEN startdate AND COALESCE(enddate, \'infinity\'::timestamp) GROUP BY type';
private const QUERY_RESOURCE_BY_PERSON = 'select SUM(amount) AS sum, type FROM chill_budget.resource WHERE person_id = ? AND NOW() BETWEEN startdate AND COALESCE(enddate, \'infinity\'::timestamp) GROUP BY type'; private const QUERY_RESOURCE_BY_PERSON = 'select SUM(amount) AS sum, string_agg(comment, \'|\') AS comment, type FROM chill_budget.resource WHERE person_id = ? AND NOW() BETWEEN startdate AND COALESCE(enddate, \'infinity\'::timestamp) GROUP BY type';
private array $chargeLabels; private array $chargeLabels;
@ -110,7 +110,8 @@ class SummaryBudget implements SummaryBudgetInterface
$rsm = new ResultSetMapping(); $rsm = new ResultSetMapping();
$rsm $rsm
->addScalarResult('sum', 'sum') ->addScalarResult('sum', 'sum')
->addScalarResult('type', 'type'); ->addScalarResult('type', 'type')
->addScalarResult('comment', 'comment');
return $rsm; return $rsm;
} }
@ -121,7 +122,7 @@ class SummaryBudget implements SummaryBudgetInterface
$labels = $this->chargeLabels; $labels = $this->chargeLabels;
return array_combine($keys, array_map(function ($i) use ($labels) { return array_combine($keys, array_map(function ($i) use ($labels) {
return ['sum' => 0.0, 'label' => $this->translatableStringHelper->localize($labels[$i])]; return ['sum' => 0.0, 'label' => $this->translatableStringHelper->localize($labels[$i]), 'comment' => ''];
}, $keys)); }, $keys));
} }
@ -131,7 +132,7 @@ class SummaryBudget implements SummaryBudgetInterface
$labels = $this->resourcesLabels; $labels = $this->resourcesLabels;
return array_combine($keys, array_map(function ($i) use ($labels) { return array_combine($keys, array_map(function ($i) use ($labels) {
return ['sum' => 0.0, 'label' => $this->translatableStringHelper->localize($labels[$i])]; return ['sum' => 0.0, 'label' => $this->translatableStringHelper->localize($labels[$i]), 'comment' => ''];
}, $keys)); }, $keys));
} }
@ -158,6 +159,7 @@ class SummaryBudget implements SummaryBudgetInterface
$result[$row['type']] = [ $result[$row['type']] = [
'sum' => (float) $row['sum'], 'sum' => (float) $row['sum'],
'label' => $this->translatableStringHelper->localize($label[$row['type']]), 'label' => $this->translatableStringHelper->localize($label[$row['type']]),
'comment' => (string) $row['comment'],
]; ];
} }

View File

@ -0,0 +1,54 @@
<?php
/**
* 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.
*/
declare(strict_types=1);
namespace Serializer\Normalizer;
use Chill\MainBundle\Serializer\Normalizer\PhonenumberNormalizer;
use libphonenumber\PhoneNumber;
use libphonenumber\PhoneNumberUtil;
use PHPUnit\Framework\TestCase;
use Prophecy\Argument;
use Prophecy\PhpUnit\ProphecyTrait;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
/**
* @internal
* @coversNothing
*/
final class PhonenumberNormalizerTest extends TestCase
{
use ProphecyTrait;
public function dataProviderNormalizePhonenumber()
{
$phonenumberUtil = PhoneNumberUtil::getInstance();
yield [$phonenumberUtil->parse('+32486123465'), 'docgen', ['docgen:expects' => PhoneNumber::class], '0486 12 34 65'];
yield [null, 'docgen', ['docgen:expects' => PhoneNumber::class], ''];
}
/**
* @dataProvider dataProviderNormalizePhonenumber
*
* @param mixed $format
* @param mixed $context
* @param mixed $expected
*/
public function testNormalize(?Phonenumber $phonenumber, $format, $context, $expected)
{
$parameterBag = $this->prophesize(ParameterBagInterface::class);
$parameterBag->get(Argument::exact('chill_main'))->willReturn(['phone_helper' => ['default_carrier_code' => 'BE']]);
$normalizer = new PhonenumberNormalizer($parameterBag->reveal());
$this->assertEquals($expected, $normalizer->normalize($phonenumber, $format, $context));
}
}

View File

@ -23,6 +23,7 @@ use Chill\PersonBundle\Repository\Relationships\RelationshipRepository;
use Chill\PersonBundle\Templating\Entity\PersonRenderInterface; use Chill\PersonBundle\Templating\Entity\PersonRenderInterface;
use DateTimeInterface; use DateTimeInterface;
use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\ArrayCollection;
use libphonenumber\PhoneNumber;
use Symfony\Component\Serializer\Exception\UnexpectedValueException; use Symfony\Component\Serializer\Exception\UnexpectedValueException;
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer; use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
use Symfony\Component\Serializer\Normalizer\ContextAwareNormalizerInterface; use Symfony\Component\Serializer\Normalizer\ContextAwareNormalizerInterface;
@ -71,6 +72,7 @@ class PersonDocGenNormalizer implements
$dateContext = $context; $dateContext = $context;
$dateContext['docgen:expects'] = DateTimeInterface::class; $dateContext['docgen:expects'] = DateTimeInterface::class;
$addressContext = array_merge($context, ['docgen:expects' => Address::class]); $addressContext = array_merge($context, ['docgen:expects' => Address::class]);
$phonenumberContext = array_merge($context, ['docgen:expects' => PhoneNumber::class]);
$personResourceContext = array_merge($context, [ $personResourceContext = array_merge($context, [
'docgen:expects' => Person\PersonResource::class, 'docgen:expects' => Person\PersonResource::class,
// we simplify the list of attributes for the embedded persons // we simplify the list of attributes for the embedded persons
@ -113,9 +115,9 @@ class PersonDocGenNormalizer implements
'maritalStatus' => null !== ($ms = $person->getMaritalStatus()) ? $this->translatableStringHelper->localize($ms->getName()) : '', 'maritalStatus' => null !== ($ms = $person->getMaritalStatus()) ? $this->translatableStringHelper->localize($ms->getName()) : '',
'maritalStatusDate' => $this->normalizer->normalize($person->getMaritalStatusDate(), $format, $dateContext), 'maritalStatusDate' => $this->normalizer->normalize($person->getMaritalStatusDate(), $format, $dateContext),
'email' => $person->getEmail(), 'email' => $person->getEmail(),
'firstPhoneNumber' => $this->normalizer->normalize($person->getPhonenumber() ?? $person->getMobilenumber(), $format, $context), 'firstPhoneNumber' => $this->normalizer->normalize($person->getPhonenumber() ?? $person->getMobilenumber(), $format, $phonenumberContext),
'fixPhoneNumber' => $this->normalizer->normalize($person->getPhonenumber(), $format, $context), 'fixPhoneNumber' => $this->normalizer->normalize($person->getPhonenumber(), $format, $phonenumberContext),
'mobilePhoneNumber' => $this->normalizer->normalize($person->getMobilenumber(), $format, $context), 'mobilePhoneNumber' => $this->normalizer->normalize($person->getMobilenumber(), $format, $phonenumberContext),
'nationality' => null !== ($c = $person->getNationality()) ? $this->translatableStringHelper->localize($c->getName()) : '', 'nationality' => null !== ($c = $person->getNationality()) ? $this->translatableStringHelper->localize($c->getName()) : '',
'placeOfBirth' => $person->getPlaceOfBirth(), 'placeOfBirth' => $person->getPlaceOfBirth(),
'memo' => $person->getMemo(), 'memo' => $person->getMemo(),

View File

@ -152,8 +152,25 @@ class AccompanyingPeriodContext implements
$options = $template->getOptions(); $options = $template->getOptions();
$persons = $entity->getCurrentParticipations()->map(static function (AccompanyingPeriodParticipation $p) { $persons = $entity->getCurrentParticipations()->map(static function (AccompanyingPeriodParticipation $p) {
return $p->getPerson(); return $p->getPerson();
}) });
->toArray();
foreach ($entity->getCurrentParticipations() as $p) {
foreach ($p->getPerson()->getResources() as $r) {
if (null !== $r->getPerson() && !$persons->contains($r->getPerson())) {
$persons->add($r->getPerson());
}
}
}
if (null !== $entity->getRequestorPerson() && !$persons->contains($entity->getRequestorPerson())) {
$persons->add($entity->getRequestorPerson());
}
foreach ($entity->getResources() as $r) {
if (null !== $r->getPerson() && !$persons->contains($r->getPerson())) {
$persons->add($r->getPerson());
}
}
foreach (['mainPerson', 'person1', 'person2'] as $key) { foreach (['mainPerson', 'person1', 'person2'] as $key) {
if ($options[$key] ?? false) { if ($options[$key] ?? false) {