mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
Merge branch 'issue712_add_thirdparty_docgen_context' into 'master'
Issue712 add thirdparty docgen context See merge request Chill-Projet/chill-bundles!540
This commit is contained in:
commit
c77dd011b8
@ -24,6 +24,9 @@ use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
|||||||
use Chill\PersonBundle\Entity\Person;
|
use Chill\PersonBundle\Entity\Person;
|
||||||
use Chill\PersonBundle\Repository\PersonRepository;
|
use Chill\PersonBundle\Repository\PersonRepository;
|
||||||
use Chill\PersonBundle\Templating\Entity\PersonRenderInterface;
|
use Chill\PersonBundle\Templating\Entity\PersonRenderInterface;
|
||||||
|
use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
||||||
|
use Chill\ThirdPartyBundle\Templating\Entity\ThirdPartyRender;
|
||||||
|
use Chill\ThirdPartyBundle\Repository\ThirdPartyRepository;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
||||||
@ -55,6 +58,10 @@ class ActivityContext implements
|
|||||||
|
|
||||||
private TranslatorInterface $translator;
|
private TranslatorInterface $translator;
|
||||||
|
|
||||||
|
private ThirdPartyRender $thirdPartyRender;
|
||||||
|
|
||||||
|
private ThirdPartyRepository $thirdPartyRepository;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
DocumentCategoryRepository $documentCategoryRepository,
|
DocumentCategoryRepository $documentCategoryRepository,
|
||||||
NormalizerInterface $normalizer,
|
NormalizerInterface $normalizer,
|
||||||
@ -63,7 +70,9 @@ class ActivityContext implements
|
|||||||
PersonRenderInterface $personRender,
|
PersonRenderInterface $personRender,
|
||||||
PersonRepository $personRepository,
|
PersonRepository $personRepository,
|
||||||
TranslatorInterface $translator,
|
TranslatorInterface $translator,
|
||||||
BaseContextData $baseContextData
|
BaseContextData $baseContextData,
|
||||||
|
ThirdPartyRender $thirdPartyRender,
|
||||||
|
ThirdPartyRepository $thirdPartyRepository
|
||||||
) {
|
) {
|
||||||
$this->documentCategoryRepository = $documentCategoryRepository;
|
$this->documentCategoryRepository = $documentCategoryRepository;
|
||||||
$this->normalizer = $normalizer;
|
$this->normalizer = $normalizer;
|
||||||
@ -73,6 +82,8 @@ class ActivityContext implements
|
|||||||
$this->personRepository = $personRepository;
|
$this->personRepository = $personRepository;
|
||||||
$this->translator = $translator;
|
$this->translator = $translator;
|
||||||
$this->baseContextData = $baseContextData;
|
$this->baseContextData = $baseContextData;
|
||||||
|
$this->thirdPartyRender = $thirdPartyRender;
|
||||||
|
$this->thirdPartyRepository = $thirdPartyRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function adminFormReverseTransform(array $data): array
|
public function adminFormReverseTransform(array $data): array
|
||||||
@ -89,6 +100,8 @@ class ActivityContext implements
|
|||||||
'person1Label' => $data['person1Label'] ?? $this->translator->trans('docgen.person 1'),
|
'person1Label' => $data['person1Label'] ?? $this->translator->trans('docgen.person 1'),
|
||||||
'person2' => $data['person2'] ?? false,
|
'person2' => $data['person2'] ?? false,
|
||||||
'person2Label' => $data['person2Label'] ?? $this->translator->trans('docgen.person 2'),
|
'person2Label' => $data['person2Label'] ?? $this->translator->trans('docgen.person 2'),
|
||||||
|
'thirdParty' => $data['thirdParty'] ?? false,
|
||||||
|
'thirdPartyLabel' => $data['thirdPartyLabel'] ?? $this->translator->trans('thirdParty'),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,6 +131,14 @@ class ActivityContext implements
|
|||||||
->add('person2Label', TextType::class, [
|
->add('person2Label', TextType::class, [
|
||||||
'label' => 'person 2 label',
|
'label' => 'person 2 label',
|
||||||
'required' => true,
|
'required' => true,
|
||||||
|
])
|
||||||
|
->add('thirdParty', CheckboxType::class, [
|
||||||
|
'required' => false,
|
||||||
|
'label' => 'docgen.Ask for thirdParty',
|
||||||
|
])
|
||||||
|
->add('thirdPartyLabel', TextType::class, [
|
||||||
|
'label' => 'docgen.thirdParty label',
|
||||||
|
'required' => true,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,6 +164,20 @@ class ActivityContext implements
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$thirdParties = $entity->getThirdParties();
|
||||||
|
if ($options['thirdParty'] ?? false) {
|
||||||
|
$builder->add('thirdParty', EntityType::class, [
|
||||||
|
'class' => ThirdParty::class,
|
||||||
|
'choices' => $thirdParties,
|
||||||
|
'choice_label' => fn (ThirdParty $p) => $this->thirdPartyRender->renderString($p, []),
|
||||||
|
'multiple' => false,
|
||||||
|
'required' => false,
|
||||||
|
'expanded' => true,
|
||||||
|
'label' => $options['thirdPartyLabel'],
|
||||||
|
'placeholder' => $this->translator->trans('Any third party selected'),
|
||||||
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function contextGenerationDataDenormalize(DocGeneratorTemplate $template, $entity, array $data): array
|
public function contextGenerationDataDenormalize(DocGeneratorTemplate $template, $entity, array $data): array
|
||||||
@ -157,6 +192,12 @@ class ActivityContext implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (null !== ($id = ($data['thirdParty'] ?? null))) {
|
||||||
|
$denormalized['thirdParty'] = $this->thirdPartyRepository->find($id);
|
||||||
|
} else {
|
||||||
|
$denormalized['thirdParty'] = null;
|
||||||
|
}
|
||||||
|
|
||||||
return $denormalized;
|
return $denormalized;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,9 +206,11 @@ class ActivityContext implements
|
|||||||
$normalized = [];
|
$normalized = [];
|
||||||
|
|
||||||
foreach (['mainPerson', 'person1', 'person2'] as $k) {
|
foreach (['mainPerson', 'person1', 'person2'] as $k) {
|
||||||
$normalized[$k] = null === $data[$k] ? null : $data[$k]->getId();
|
$normalized[$k] = ($data[$k] ?? null)?->getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$normalized['thirdParty'] = ($data['thirdParty'] ?? null)?->getId();
|
||||||
|
|
||||||
return $normalized;
|
return $normalized;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,6 +239,13 @@ class ActivityContext implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($options['thirdParty']) {
|
||||||
|
$data['thirdParty'] = $this->normalizer->normalize($contextGenerationData['thirdParty'], 'docgen', [
|
||||||
|
'docgen:expects' => ThirdParty::class,
|
||||||
|
'groups' => 'docgen:read'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,7 +285,7 @@ class ActivityContext implements
|
|||||||
{
|
{
|
||||||
$options = $template->getOptions();
|
$options = $template->getOptions();
|
||||||
|
|
||||||
return $options['mainPerson'] || $options['person1'] || $options['person2'];
|
return $options['mainPerson'] || $options['person1'] || $options['person2'] || $options ['thirdParty'];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function storeGenerated(DocGeneratorTemplate $template, StoredObject $storedObject, object $entity, array $contextGenerationData): void
|
public function storeGenerated(DocGeneratorTemplate $template, StoredObject $storedObject, object $entity, array $contextGenerationData): void
|
||||||
|
@ -22,10 +22,14 @@ use Chill\DocStoreBundle\Entity\StoredObject;
|
|||||||
use Chill\DocStoreBundle\Repository\DocumentCategoryRepository;
|
use Chill\DocStoreBundle\Repository\DocumentCategoryRepository;
|
||||||
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||||
|
use Chill\PersonBundle\Entity\AccompanyingPeriod\Resource;
|
||||||
use Chill\PersonBundle\Entity\AccompanyingPeriodParticipation;
|
use Chill\PersonBundle\Entity\AccompanyingPeriodParticipation;
|
||||||
use Chill\PersonBundle\Entity\Person;
|
use Chill\PersonBundle\Entity\Person;
|
||||||
use Chill\PersonBundle\Repository\PersonRepository;
|
use Chill\PersonBundle\Repository\PersonRepository;
|
||||||
use Chill\PersonBundle\Templating\Entity\PersonRenderInterface;
|
use Chill\PersonBundle\Templating\Entity\PersonRenderInterface;
|
||||||
|
use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
||||||
|
use Chill\ThirdPartyBundle\Templating\Entity\ThirdPartyRender;
|
||||||
|
use Chill\ThirdPartyBundle\Repository\ThirdPartyRepository;
|
||||||
use DateTime;
|
use DateTime;
|
||||||
use Doctrine\Common\Collections\ArrayCollection;
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
@ -40,6 +44,7 @@ use Symfony\Contracts\Translation\TranslatorInterface;
|
|||||||
use function array_key_exists;
|
use function array_key_exists;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @see AccompanyingPeriodContextTest
|
||||||
* @template-implements DocGeneratorContextWithPublicFormInterface<AccompanyingPeriod>
|
* @template-implements DocGeneratorContextWithPublicFormInterface<AccompanyingPeriod>
|
||||||
*/
|
*/
|
||||||
class AccompanyingPeriodContext implements
|
class AccompanyingPeriodContext implements
|
||||||
@ -62,6 +67,10 @@ class AccompanyingPeriodContext implements
|
|||||||
|
|
||||||
private TranslatorInterface $translator;
|
private TranslatorInterface $translator;
|
||||||
|
|
||||||
|
private ThirdPartyRender $thirdPartyRender;
|
||||||
|
|
||||||
|
private ThirdPartyRepository $thirdPartyRepository;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
DocumentCategoryRepository $documentCategoryRepository,
|
DocumentCategoryRepository $documentCategoryRepository,
|
||||||
NormalizerInterface $normalizer,
|
NormalizerInterface $normalizer,
|
||||||
@ -70,7 +79,9 @@ class AccompanyingPeriodContext implements
|
|||||||
PersonRenderInterface $personRender,
|
PersonRenderInterface $personRender,
|
||||||
PersonRepository $personRepository,
|
PersonRepository $personRepository,
|
||||||
TranslatorInterface $translator,
|
TranslatorInterface $translator,
|
||||||
BaseContextData $baseContextData
|
BaseContextData $baseContextData,
|
||||||
|
ThirdPartyRender $thirdPartyRender,
|
||||||
|
ThirdPartyRepository $thirdPartyRepository
|
||||||
) {
|
) {
|
||||||
$this->documentCategoryRepository = $documentCategoryRepository;
|
$this->documentCategoryRepository = $documentCategoryRepository;
|
||||||
$this->normalizer = $normalizer;
|
$this->normalizer = $normalizer;
|
||||||
@ -80,6 +91,8 @@ class AccompanyingPeriodContext implements
|
|||||||
$this->personRepository = $personRepository;
|
$this->personRepository = $personRepository;
|
||||||
$this->translator = $translator;
|
$this->translator = $translator;
|
||||||
$this->baseContextData = $baseContextData;
|
$this->baseContextData = $baseContextData;
|
||||||
|
$this->thirdPartyRender = $thirdPartyRender;
|
||||||
|
$this->thirdPartyRepository = $thirdPartyRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function adminFormReverseTransform(array $data): array
|
public function adminFormReverseTransform(array $data): array
|
||||||
@ -103,11 +116,12 @@ class AccompanyingPeriodContext implements
|
|||||||
'person1Label' => $data['person1Label'] ?? $this->translator->trans('docgen.person 1'),
|
'person1Label' => $data['person1Label'] ?? $this->translator->trans('docgen.person 1'),
|
||||||
'person2' => $data['person2'] ?? false,
|
'person2' => $data['person2'] ?? false,
|
||||||
'person2Label' => $data['person2Label'] ?? $this->translator->trans('docgen.person 2'),
|
'person2Label' => $data['person2Label'] ?? $this->translator->trans('docgen.person 2'),
|
||||||
|
'thirdParty' => $data['thirdParty'] ?? false,
|
||||||
|
'thirdPartyLabel' => $data['thirdPartyLabel'] ?? $this->translator->trans('Third party'),
|
||||||
];
|
];
|
||||||
|
|
||||||
if (array_key_exists('category', $data)) {
|
if (array_key_exists('category', $data)) {
|
||||||
$r['category'] = array_key_exists('category', $data) ?
|
$r['category'] = $this->documentCategoryRepository->find($data['category']);
|
||||||
$this->documentCategoryRepository->find($data['category']) : null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $r;
|
return $r;
|
||||||
@ -140,6 +154,14 @@ class AccompanyingPeriodContext implements
|
|||||||
'label' => 'person 2 label',
|
'label' => 'person 2 label',
|
||||||
'required' => true,
|
'required' => true,
|
||||||
])
|
])
|
||||||
|
->add('thirdParty', CheckboxType::class, [
|
||||||
|
'required' => false,
|
||||||
|
'label' => 'docgen.Ask for thirdParty',
|
||||||
|
])
|
||||||
|
->add('thirdPartyLabel', TextType::class, [
|
||||||
|
'label' => 'docgen.thirdParty label',
|
||||||
|
'required' => true,
|
||||||
|
])
|
||||||
->add('category', EntityType::class, [
|
->add('category', EntityType::class, [
|
||||||
'placeholder' => 'Choose a document category',
|
'placeholder' => 'Choose a document category',
|
||||||
'class' => DocumentCategory::class,
|
'class' => DocumentCategory::class,
|
||||||
@ -190,6 +212,28 @@ class AccompanyingPeriodContext implements
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$thirdParties = [...array_values(array_filter([$entity->getRequestorThirdParty()])), ...array_values(array_filter(
|
||||||
|
array_map(
|
||||||
|
fn (Resource $r): ?ThirdParty => $r->getThirdParty(),
|
||||||
|
$entity->getResources()->filter(
|
||||||
|
static fn (Resource $r): bool => null !== $r->getThirdParty()
|
||||||
|
)->toArray()
|
||||||
|
)
|
||||||
|
))];
|
||||||
|
|
||||||
|
if ($options['thirdParty'] ?? false) {
|
||||||
|
$builder->add('thirdParty', EntityType::class, [
|
||||||
|
'class' => ThirdParty::class,
|
||||||
|
'choices' => $thirdParties,
|
||||||
|
'choice_label' => fn (ThirdParty $p) => $this->thirdPartyRender->renderString($p, []),
|
||||||
|
'multiple' => false,
|
||||||
|
'required' => false,
|
||||||
|
'expanded' => true,
|
||||||
|
'label' => $options['thirdPartyLabel'],
|
||||||
|
'placeholder' => $this->translator->trans('Any third party selected'),
|
||||||
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getData(DocGeneratorTemplate $template, $entity, array $contextGenerationData = []): array
|
public function getData(DocGeneratorTemplate $template, $entity, array $contextGenerationData = []): array
|
||||||
@ -215,6 +259,13 @@ class AccompanyingPeriodContext implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($options['thirdParty']) {
|
||||||
|
$data['thirdParty'] = $this->normalizer->normalize($contextGenerationData['thirdParty'], 'docgen', [
|
||||||
|
'docgen:expects' => ThirdParty::class,
|
||||||
|
'groups' => 'docgen:read'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -254,7 +305,7 @@ class AccompanyingPeriodContext implements
|
|||||||
{
|
{
|
||||||
$options = $template->getOptions();
|
$options = $template->getOptions();
|
||||||
|
|
||||||
return $options['mainPerson'] || $options['person1'] || $options['person2'];
|
return $options['mainPerson'] || $options['person1'] || $options['person2'] || $options ['thirdParty'];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function contextGenerationDataNormalize(DocGeneratorTemplate $template, $entity, array $data): array
|
public function contextGenerationDataNormalize(DocGeneratorTemplate $template, $entity, array $data): array
|
||||||
@ -264,6 +315,8 @@ class AccompanyingPeriodContext implements
|
|||||||
$normalized[$k] = null !== ($data[$k] ?? null) ? $data[$k]->getId() : null;
|
$normalized[$k] = null !== ($data[$k] ?? null) ? $data[$k]->getId() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$normalized['thirdParty'] = ($data['thirdParty'] ?? null)?->getId();
|
||||||
|
|
||||||
return $normalized;
|
return $normalized;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,6 +332,12 @@ class AccompanyingPeriodContext implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (null !== ($id = ($data['thirdParty'] ?? null))) {
|
||||||
|
$denormalized['thirdParty'] = $this->thirdPartyRepository->find($id);
|
||||||
|
} else {
|
||||||
|
$denormalized['thirdParty'] = null;
|
||||||
|
}
|
||||||
|
|
||||||
return $denormalized;
|
return $denormalized;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,13 +18,18 @@ use Chill\DocStoreBundle\Entity\StoredObject;
|
|||||||
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluation;
|
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluation;
|
||||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluationDocument;
|
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluationDocument;
|
||||||
|
use Chill\PersonBundle\Entity\AccompanyingPeriod\Resource;
|
||||||
use Chill\PersonBundle\Entity\SocialWork\Evaluation;
|
use Chill\PersonBundle\Entity\SocialWork\Evaluation;
|
||||||
use Chill\PersonBundle\Repository\SocialWork\EvaluationRepository;
|
use Chill\PersonBundle\Repository\SocialWork\EvaluationRepository;
|
||||||
|
use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
||||||
|
use Chill\ThirdPartyBundle\Templating\Entity\ThirdPartyRender;
|
||||||
|
use Chill\ThirdPartyBundle\Repository\ThirdPartyRepository;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
|
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
|
||||||
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
||||||
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @implements DocGeneratorContextWithPublicFormInterface<AccompanyingPeriodWorkEvaluation>
|
* @implements DocGeneratorContextWithPublicFormInterface<AccompanyingPeriodWorkEvaluation>
|
||||||
@ -43,18 +48,26 @@ class AccompanyingPeriodWorkEvaluationContext implements
|
|||||||
|
|
||||||
private TranslatableStringHelperInterface $translatableStringHelper;
|
private TranslatableStringHelperInterface $translatableStringHelper;
|
||||||
|
|
||||||
|
private ThirdPartyRender $thirdPartyRender;
|
||||||
|
|
||||||
|
private TranslatorInterface $translator;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
AccompanyingPeriodWorkContext $accompanyingPeriodWorkContext,
|
AccompanyingPeriodWorkContext $accompanyingPeriodWorkContext,
|
||||||
EntityManagerInterface $em,
|
EntityManagerInterface $em,
|
||||||
EvaluationRepository $evaluationRepository,
|
EvaluationRepository $evaluationRepository,
|
||||||
NormalizerInterface $normalizer,
|
NormalizerInterface $normalizer,
|
||||||
TranslatableStringHelperInterface $translatableStringHelper
|
TranslatableStringHelperInterface $translatableStringHelper,
|
||||||
|
ThirdPartyRender $thirdPartyRender,
|
||||||
|
TranslatorInterface $translator
|
||||||
) {
|
) {
|
||||||
$this->accompanyingPeriodWorkContext = $accompanyingPeriodWorkContext;
|
$this->accompanyingPeriodWorkContext = $accompanyingPeriodWorkContext;
|
||||||
$this->em = $em;
|
$this->em = $em;
|
||||||
$this->evaluationRepository = $evaluationRepository;
|
$this->evaluationRepository = $evaluationRepository;
|
||||||
$this->normalizer = $normalizer;
|
$this->normalizer = $normalizer;
|
||||||
$this->translatableStringHelper = $translatableStringHelper;
|
$this->translatableStringHelper = $translatableStringHelper;
|
||||||
|
$this->thirdPartyRender = $thirdPartyRender;
|
||||||
|
$this->translator = $translator;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function adminFormReverseTransform(array $data): array
|
public function adminFormReverseTransform(array $data): array
|
||||||
@ -102,6 +115,31 @@ class AccompanyingPeriodWorkEvaluationContext implements
|
|||||||
public function buildPublicForm(FormBuilderInterface $builder, DocGeneratorTemplate $template, $entity): void
|
public function buildPublicForm(FormBuilderInterface $builder, DocGeneratorTemplate $template, $entity): void
|
||||||
{
|
{
|
||||||
$this->accompanyingPeriodWorkContext->buildPublicForm($builder, $template, $entity->getAccompanyingPeriodWork());
|
$this->accompanyingPeriodWorkContext->buildPublicForm($builder, $template, $entity->getAccompanyingPeriodWork());
|
||||||
|
|
||||||
|
$thirdParties = [...array_values(array_filter($entity->getAccompanyingPeriodWork()->getThirdParties()->toArray())), ...array_values(array_filter([$entity->getAccompanyingPeriodWork()->getHandlingThierParty()])), ...array_values(
|
||||||
|
array_filter(
|
||||||
|
array_map(
|
||||||
|
fn (Resource $r): ?ThirdParty => $r->getThirdParty(),
|
||||||
|
$entity->getAccompanyingPeriodWork()->getAccompanyingPeriod()->getResources()->filter(
|
||||||
|
static fn (Resource $r): bool => null !== $r->getThirdParty()
|
||||||
|
)->toArray()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)];
|
||||||
|
|
||||||
|
$options = $template->getOptions();
|
||||||
|
if ($options['thirdParty'] ?? false) {
|
||||||
|
$builder->add('thirdParty', EntityType::class, [
|
||||||
|
'class' => ThirdParty::class,
|
||||||
|
'choices' => $thirdParties,
|
||||||
|
'choice_label' => fn (ThirdParty $p) => $this->thirdPartyRender->renderString($p, []),
|
||||||
|
'multiple' => false,
|
||||||
|
'required' => false,
|
||||||
|
'expanded' => true,
|
||||||
|
'label' => $options['thirdPartyLabel'],
|
||||||
|
'placeholder' => $this->translator->trans('Any third party selected'),
|
||||||
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getData(DocGeneratorTemplate $template, $entity, array $contextGenerationData = []): array
|
public function getData(DocGeneratorTemplate $template, $entity, array $contextGenerationData = []): array
|
||||||
@ -116,7 +154,6 @@ class AccompanyingPeriodWorkEvaluationContext implements
|
|||||||
AbstractNormalizer::GROUPS => ['docgen:read'],
|
AbstractNormalizer::GROUPS => ['docgen:read'],
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,14 +26,22 @@ use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
|
|||||||
use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface;
|
use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface;
|
||||||
use Chill\MainBundle\Security\Resolver\CenterResolverManagerInterface;
|
use Chill\MainBundle\Security\Resolver\CenterResolverManagerInterface;
|
||||||
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||||
|
use Chill\PersonBundle\Entity\Person\PersonResource;
|
||||||
use Chill\PersonBundle\Entity\Person;
|
use Chill\PersonBundle\Entity\Person;
|
||||||
|
use Chill\PersonBundle\Entity\Person\ResidentialAddress;
|
||||||
use Chill\PersonBundle\Repository\PersonRepository;
|
use Chill\PersonBundle\Repository\PersonRepository;
|
||||||
|
use Chill\PersonBundle\Repository\ResidentialAddressRepository;
|
||||||
|
use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
||||||
|
use Chill\ThirdPartyBundle\Templating\Entity\ThirdPartyRender;
|
||||||
|
use Chill\ThirdPartyBundle\Repository\ThirdPartyRepository;
|
||||||
use DateTime;
|
use DateTime;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Doctrine\ORM\EntityRepository;
|
use Doctrine\ORM\EntityRepository;
|
||||||
use LogicException;
|
use LogicException;
|
||||||
|
use Service\DocGenerator\PersonContextTest;
|
||||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
use Symfony\Component\Security\Core\Security;
|
use Symfony\Component\Security\Core\Security;
|
||||||
@ -43,6 +51,9 @@ use Symfony\Contracts\Translation\TranslatorInterface;
|
|||||||
use function array_key_exists;
|
use function array_key_exists;
|
||||||
use function count;
|
use function count;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see PersonContextTest
|
||||||
|
*/
|
||||||
final class PersonContext implements PersonContextInterface
|
final class PersonContext implements PersonContextInterface
|
||||||
{
|
{
|
||||||
private AuthorizationHelperInterface $authorizationHelper;
|
private AuthorizationHelperInterface $authorizationHelper;
|
||||||
@ -67,6 +78,12 @@ final class PersonContext implements PersonContextInterface
|
|||||||
|
|
||||||
private TranslatorInterface $translator;
|
private TranslatorInterface $translator;
|
||||||
|
|
||||||
|
private ThirdPartyRender $thirdPartyRender;
|
||||||
|
|
||||||
|
private ThirdPartyRepository $thirdPartyRepository;
|
||||||
|
|
||||||
|
private ResidentialAddressRepository $residentialAddressRepository;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
AuthorizationHelperInterface $authorizationHelper,
|
AuthorizationHelperInterface $authorizationHelper,
|
||||||
BaseContextData $baseContextData,
|
BaseContextData $baseContextData,
|
||||||
@ -78,7 +95,10 @@ final class PersonContext implements PersonContextInterface
|
|||||||
ScopeRepositoryInterface $scopeRepository,
|
ScopeRepositoryInterface $scopeRepository,
|
||||||
Security $security,
|
Security $security,
|
||||||
TranslatorInterface $translator,
|
TranslatorInterface $translator,
|
||||||
TranslatableStringHelperInterface $translatableStringHelper
|
TranslatableStringHelperInterface $translatableStringHelper,
|
||||||
|
ThirdPartyRender $thirdPartyRender,
|
||||||
|
ThirdPartyRepository $thirdPartyRepository,
|
||||||
|
ResidentialAddressRepository $residentialAddressRepository
|
||||||
) {
|
) {
|
||||||
$this->authorizationHelper = $authorizationHelper;
|
$this->authorizationHelper = $authorizationHelper;
|
||||||
$this->centerResolverManager = $centerResolverManager;
|
$this->centerResolverManager = $centerResolverManager;
|
||||||
@ -91,6 +111,9 @@ final class PersonContext implements PersonContextInterface
|
|||||||
$this->showScopes = $parameterBag->get('chill_main')['acl']['form_show_scopes'];
|
$this->showScopes = $parameterBag->get('chill_main')['acl']['form_show_scopes'];
|
||||||
$this->translator = $translator;
|
$this->translator = $translator;
|
||||||
$this->translatableStringHelper = $translatableStringHelper;
|
$this->translatableStringHelper = $translatableStringHelper;
|
||||||
|
$this->thirdPartyRender = $thirdPartyRender;
|
||||||
|
$this->thirdPartyRepository = $thirdPartyRepository;
|
||||||
|
$this->residentialAddressRepository = $residentialAddressRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function adminFormReverseTransform(array $data): array
|
public function adminFormReverseTransform(array $data): array
|
||||||
@ -110,11 +133,12 @@ final class PersonContext implements PersonContextInterface
|
|||||||
$r = [
|
$r = [
|
||||||
'mainPerson' => $data['mainPerson'] ?? false,
|
'mainPerson' => $data['mainPerson'] ?? false,
|
||||||
'mainPersonLabel' => $data['mainPersonLabel'] ?? $this->translator->trans('docgen.Main person'),
|
'mainPersonLabel' => $data['mainPersonLabel'] ?? $this->translator->trans('docgen.Main person'),
|
||||||
|
'thirdParty' => $data['thirdParty'] ?? false,
|
||||||
|
'thirdPartyLabel' => $data['thirdPartyLabel'] ?? $this->translator->trans('Third party'),
|
||||||
];
|
];
|
||||||
|
|
||||||
if (array_key_exists('category', $data)) {
|
if (array_key_exists('category', $data)) {
|
||||||
$r['category'] = array_key_exists('category', $data) ?
|
$r['category'] = $this->documentCategoryRepository->find($data['category']);
|
||||||
$this->documentCategoryRepository->find($data['category']) : null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $r;
|
return $r;
|
||||||
@ -131,6 +155,14 @@ final class PersonContext implements PersonContextInterface
|
|||||||
->setParameter('docClass', PersonDocument::class),
|
->setParameter('docClass', PersonDocument::class),
|
||||||
'choice_label' => fn ($entity = null) => $entity ? $this->translatableStringHelper->localize($entity->getName()) : '',
|
'choice_label' => fn ($entity = null) => $entity ? $this->translatableStringHelper->localize($entity->getName()) : '',
|
||||||
'required' => true,
|
'required' => true,
|
||||||
|
])
|
||||||
|
->add('thirdParty', CheckboxType::class, [
|
||||||
|
'required' => false,
|
||||||
|
'label' => 'docgen.Ask for thirdParty',
|
||||||
|
])
|
||||||
|
->add('thirdPartyLabel', TextType::class, [
|
||||||
|
'label' => 'docgen.thirdParty label',
|
||||||
|
'required' => true,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,12 +171,47 @@ final class PersonContext implements PersonContextInterface
|
|||||||
*/
|
*/
|
||||||
public function buildPublicForm(FormBuilderInterface $builder, DocGeneratorTemplate $template, $entity): void
|
public function buildPublicForm(FormBuilderInterface $builder, DocGeneratorTemplate $template, $entity): void
|
||||||
{
|
{
|
||||||
|
$options = $template->getOptions();
|
||||||
|
|
||||||
$builder->add('title', TextType::class, [
|
$builder->add('title', TextType::class, [
|
||||||
'required' => true,
|
'required' => true,
|
||||||
'label' => 'docgen.Document title',
|
'label' => 'docgen.Document title',
|
||||||
'data' => $this->translatableStringHelper->localize($template->getName()),
|
'data' => $this->translatableStringHelper->localize($template->getName()),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
$thirdParties = [...array_values(
|
||||||
|
array_filter(
|
||||||
|
array_map(
|
||||||
|
fn (ResidentialAddress $r): ?ThirdParty => $r->getHostThirdParty(),
|
||||||
|
$this
|
||||||
|
->residentialAddressRepository
|
||||||
|
->findCurrentResidentialAddressByPerson($entity)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
), ...array_values(
|
||||||
|
array_filter(
|
||||||
|
array_map(
|
||||||
|
fn (PersonResource $r): ?ThirdParty => $r->getThirdParty(),
|
||||||
|
$entity->getResources()->filter(
|
||||||
|
static fn (PersonResource $r): bool => null !== $r->getThirdParty()
|
||||||
|
)->toArray()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)];
|
||||||
|
|
||||||
|
if ($options['thirdParty'] ?? false) {
|
||||||
|
$builder->add('thirdParty', EntityType::class, [
|
||||||
|
'class' => ThirdParty::class,
|
||||||
|
'choices' => $thirdParties,
|
||||||
|
'choice_label' => fn (ThirdParty $p) => $this->thirdPartyRender->renderString($p, []),
|
||||||
|
'multiple' => false,
|
||||||
|
'required' => false,
|
||||||
|
'expanded' => true,
|
||||||
|
'label' => $options['thirdPartyLabel'],
|
||||||
|
'placeholder' => $this->translator->trans('Any third party selected'),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->isScopeNecessary($entity)) {
|
if ($this->isScopeNecessary($entity)) {
|
||||||
$builder->add('scope', ScopePickerType::class, [
|
$builder->add('scope', ScopePickerType::class, [
|
||||||
'center' => $this->centerResolverManager->resolveCenters($entity),
|
'center' => $this->centerResolverManager->resolveCenters($entity),
|
||||||
@ -156,10 +223,6 @@ final class PersonContext implements PersonContextInterface
|
|||||||
|
|
||||||
public function getData(DocGeneratorTemplate $template, $entity, array $contextGenerationData = []): array
|
public function getData(DocGeneratorTemplate $template, $entity, array $contextGenerationData = []): array
|
||||||
{
|
{
|
||||||
if (!$entity instanceof Person) {
|
|
||||||
throw new UnexpectedTypeException($entity, Person::class);
|
|
||||||
}
|
|
||||||
|
|
||||||
$data = [];
|
$data = [];
|
||||||
$data = array_merge($data, $this->baseContextData->getData($contextGenerationData['creator'] ?? null));
|
$data = array_merge($data, $this->baseContextData->getData($contextGenerationData['creator'] ?? null));
|
||||||
$data['person'] = $this->normalizer->normalize($entity, 'docgen', [
|
$data['person'] = $this->normalizer->normalize($entity, 'docgen', [
|
||||||
@ -170,6 +233,13 @@ final class PersonContext implements PersonContextInterface
|
|||||||
'docgen:person:with-budget' => true,
|
'docgen:person:with-budget' => true,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
if ($template->getOptions()['thirdParty']) {
|
||||||
|
$data['thirdParty'] = $this->normalizer->normalize($contextGenerationData['thirdParty'], 'docgen', [
|
||||||
|
'docgen:expects' => ThirdParty::class,
|
||||||
|
'groups' => 'docgen:read'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -223,6 +293,7 @@ final class PersonContext implements PersonContextInterface
|
|||||||
return [
|
return [
|
||||||
'title' => $data['title'] ?? '',
|
'title' => $data['title'] ?? '',
|
||||||
'scope_id' => $scope instanceof Scope ? $scope->getId() : null,
|
'scope_id' => $scope instanceof Scope ? $scope->getId() : null,
|
||||||
|
'thirdParty' => ($data['thirdParty'] ?? null)?->getId(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,6 +313,7 @@ final class PersonContext implements PersonContextInterface
|
|||||||
return [
|
return [
|
||||||
'title' => $data['title'] ?? '',
|
'title' => $data['title'] ?? '',
|
||||||
'scope' => $scope,
|
'scope' => $scope,
|
||||||
|
'thirdParty' => null !== ($id = ($data['thirdParty'] ?? null)) ? $this->thirdPartyRepository->find($id) : null,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +19,8 @@ use Chill\PersonBundle\Entity\Person;
|
|||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @template-extends DocGeneratorContextWithPublicFormInterface<Person>
|
* @template-extends DocGeneratorContextWithPublicFormInterface<Person>
|
||||||
|
* @template-extends DocGeneratorContextWithAdminFormInterface<Person>
|
||||||
*/
|
*/
|
||||||
interface PersonContextInterface extends DocGeneratorContextWithAdminFormInterface, DocGeneratorContextWithPublicFormInterface
|
interface PersonContextInterface extends DocGeneratorContextWithAdminFormInterface, DocGeneratorContextWithPublicFormInterface
|
||||||
{
|
{
|
||||||
|
@ -0,0 +1,291 @@
|
|||||||
|
<?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 Service\DocGenerator;
|
||||||
|
|
||||||
|
use Chill\DocGeneratorBundle\Entity\DocGeneratorTemplate;
|
||||||
|
use Chill\DocGeneratorBundle\Service\Context\BaseContextData;
|
||||||
|
use Chill\DocStoreBundle\Repository\DocumentCategoryRepository;
|
||||||
|
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||||
|
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||||
|
use Chill\PersonBundle\Entity\Person;
|
||||||
|
use Chill\PersonBundle\Repository\PersonRepository;
|
||||||
|
use Chill\PersonBundle\Service\DocGenerator\AccompanyingPeriodContext;
|
||||||
|
use Chill\PersonBundle\Templating\Entity\PersonRenderInterface;
|
||||||
|
use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
||||||
|
use Chill\ThirdPartyBundle\Repository\ThirdPartyRepository;
|
||||||
|
use Chill\ThirdPartyBundle\Templating\Entity\ThirdPartyRender;
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
|
||||||
|
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
||||||
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
* @coversNothing
|
||||||
|
*/
|
||||||
|
class AccompanyingPeriodContextTest extends KernelTestCase
|
||||||
|
{
|
||||||
|
private BaseContextData $baseContextData;
|
||||||
|
|
||||||
|
private DocumentCategoryRepository $documentCategoryRepository;
|
||||||
|
|
||||||
|
private EntityManagerInterface $em;
|
||||||
|
|
||||||
|
private NormalizerInterface $normalizer;
|
||||||
|
|
||||||
|
private PersonRenderInterface $personRender;
|
||||||
|
|
||||||
|
private PersonRepository $personRepository;
|
||||||
|
|
||||||
|
private TranslatableStringHelperInterface $translatableStringHelper;
|
||||||
|
|
||||||
|
private TranslatorInterface $translator;
|
||||||
|
|
||||||
|
private ThirdPartyRender $thirdPartyRender;
|
||||||
|
|
||||||
|
private ThirdPartyRepository $thirdPartyRepository;
|
||||||
|
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
self::bootKernel();
|
||||||
|
$this->baseContextData = self::$container->get(BaseContextData::class);
|
||||||
|
$this->documentCategoryRepository = self::$container->get(DocumentCategoryRepository::class);
|
||||||
|
$this->em = self::$container->get(EntityManagerInterface::class);
|
||||||
|
$this->normalizer = self::$container->get(NormalizerInterface::class);
|
||||||
|
$this->personRender = self::$container->get(PersonRenderInterface::class);
|
||||||
|
$this->personRepository = self::$container->get(PersonRepository::class);
|
||||||
|
$this->translatableStringHelper = self::$container->get(TranslatableStringHelperInterface::class);
|
||||||
|
$this->translator = self::$container->get(TranslatorInterface::class);
|
||||||
|
$this->thirdPartyRender = self::$container->get(ThirdPartyRender::class);
|
||||||
|
$this->thirdPartyRepository = self::$container->get(ThirdPartyRepository::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function buildContext(): AccompanyingPeriodContext
|
||||||
|
{
|
||||||
|
return new AccompanyingPeriodContext(
|
||||||
|
$this->documentCategoryRepository,
|
||||||
|
$this->normalizer,
|
||||||
|
$this->translatableStringHelper,
|
||||||
|
$this->em,
|
||||||
|
$this->personRender,
|
||||||
|
$this->personRepository,
|
||||||
|
$this->translator,
|
||||||
|
$this->baseContextData,
|
||||||
|
$this->thirdPartyRender,
|
||||||
|
$this->thirdPartyRepository,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This test run the methods executed when a document is generated:
|
||||||
|
*
|
||||||
|
* - normalized data from the form in a way that they are stored in message queue;
|
||||||
|
* - denormalize the data from the message queue,
|
||||||
|
* - and get the data, as they will be transmitted to the GeneratorDriver
|
||||||
|
*
|
||||||
|
* @param array $options the options, as they are stored in the DocGeneratorTemplate (the admin form data)
|
||||||
|
* @param AccompanyingPeriod $entity The entity from which the data will be extracted
|
||||||
|
* @param array $data The data, from the public form
|
||||||
|
* @param array $expectedNormalized, how the normalized data are expected (allow to check that this data will be compliant with the storage in messenger queue)
|
||||||
|
* @param callable $assertionsOnData some test that will be executed on the normalized data
|
||||||
|
* @dataProvider provideNormalizedData
|
||||||
|
*/
|
||||||
|
public function testContextGenerationDataNormalizeDenormalizeGetData(
|
||||||
|
array $options,
|
||||||
|
AccompanyingPeriod $entity,
|
||||||
|
array $data,
|
||||||
|
array $expectedNormalized,
|
||||||
|
callable $assertionsOnData
|
||||||
|
): void {
|
||||||
|
$context = $this->buildContext();
|
||||||
|
$template = new DocGeneratorTemplate();
|
||||||
|
$template->setName(["fr" =>"test"])->setContext(AccompanyingPeriodContext::class)
|
||||||
|
->setDescription("description")->setActive(true)
|
||||||
|
->setOptions($options);
|
||||||
|
|
||||||
|
$normalized = $context->contextGenerationDataNormalize($template, $entity, $data);
|
||||||
|
|
||||||
|
self::assertEquals($expectedNormalized, $normalized);
|
||||||
|
|
||||||
|
$denormalized = $context->contextGenerationDataDenormalize($template, $entity, $normalized);
|
||||||
|
|
||||||
|
$data = $context->getData($template, $entity, $denormalized);
|
||||||
|
|
||||||
|
call_user_func($assertionsOnData, $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function provideNormalizedData(): iterable
|
||||||
|
{
|
||||||
|
self::bootKernel();
|
||||||
|
$em = self::$container->get(EntityManagerInterface::class);
|
||||||
|
|
||||||
|
$thirdParty = $em->createQuery("SELECT t FROM " . ThirdParty::class . " t")
|
||||||
|
->setMaxResults(1)
|
||||||
|
->getSingleResult();
|
||||||
|
|
||||||
|
if (null === $thirdParty) {
|
||||||
|
throw new \RuntimeException("No thirdparty in database");
|
||||||
|
}
|
||||||
|
|
||||||
|
$period = $em->createQuery("SELECT a FROM " . AccompanyingPeriod::class . " a WHERE a.step = 'CONFIRMED'")
|
||||||
|
->setMaxResults(1)
|
||||||
|
->getSingleResult();
|
||||||
|
|
||||||
|
if (null === $period) {
|
||||||
|
throw new \RuntimeException("No confirmed period in database");
|
||||||
|
}
|
||||||
|
|
||||||
|
$person = $em->createQuery("SELECT p FROM " . Person::class . " p")
|
||||||
|
->setMaxResults(1)
|
||||||
|
->getSingleResult();
|
||||||
|
|
||||||
|
if (null === $person) {
|
||||||
|
throw new \RuntimeException("No confirmed period in database");
|
||||||
|
}
|
||||||
|
|
||||||
|
yield [
|
||||||
|
// test with only thirdParty
|
||||||
|
[
|
||||||
|
'mainPerson' => false,
|
||||||
|
'mainPersonLabel' => 'person',
|
||||||
|
'person1' => false,
|
||||||
|
'person1Label' => 'person2',
|
||||||
|
'person2' => false,
|
||||||
|
'person2Label' => 'person2',
|
||||||
|
'thirdParty' => true,
|
||||||
|
'thirdPartyLabel' => '3party'
|
||||||
|
],
|
||||||
|
$period,
|
||||||
|
[
|
||||||
|
'thirdParty' => $thirdParty
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'thirdParty' => $thirdParty->getId(),
|
||||||
|
'mainPerson' => null,
|
||||||
|
'person1' => null,
|
||||||
|
'person2' => null,
|
||||||
|
],
|
||||||
|
function (array $data) use ($thirdParty, $period) {
|
||||||
|
self::assertArrayHasKey('thirdParty', $data);
|
||||||
|
self::assertEquals($thirdParty->getId(), $data['thirdParty']['id']);
|
||||||
|
|
||||||
|
self::assertArrayHasKey('course', $data);
|
||||||
|
self::assertEquals($period->getId(), $data['course']['id']);
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
yield [
|
||||||
|
// test with only mainPerson
|
||||||
|
[
|
||||||
|
'mainPerson' => true,
|
||||||
|
'mainPersonLabel' => 'person',
|
||||||
|
'person1' => false,
|
||||||
|
'person1Label' => 'person2',
|
||||||
|
'person2' => false,
|
||||||
|
'person2Label' => 'person2',
|
||||||
|
'thirdParty' => false,
|
||||||
|
'thirdPartyLabel' => '3party'
|
||||||
|
],
|
||||||
|
$period,
|
||||||
|
[
|
||||||
|
'mainPerson' => $person,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'thirdParty' => null,
|
||||||
|
'mainPerson' => $person->getId(),
|
||||||
|
'person1' => null,
|
||||||
|
'person2' => null,
|
||||||
|
],
|
||||||
|
function (array $data) use ($person, $period) {
|
||||||
|
self::assertArrayHasKey('mainPerson', $data);
|
||||||
|
self::assertEquals($person->getId(), $data['mainPerson']['id']);
|
||||||
|
|
||||||
|
self::assertArrayHasKey('course', $data);
|
||||||
|
self::assertEquals($period->getId(), $data['course']['id']);
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
yield [
|
||||||
|
// test with every options activated
|
||||||
|
[
|
||||||
|
'mainPerson' => true,
|
||||||
|
'mainPersonLabel' => 'person',
|
||||||
|
'person1' => true,
|
||||||
|
'person1Label' => 'person2',
|
||||||
|
'person2' => true,
|
||||||
|
'person2Label' => 'person2',
|
||||||
|
'thirdParty' => true,
|
||||||
|
'thirdPartyLabel' => '3party'
|
||||||
|
],
|
||||||
|
$period,
|
||||||
|
[
|
||||||
|
'mainPerson' => $person,
|
||||||
|
'person1' => $person,
|
||||||
|
'person2' => $person,
|
||||||
|
'thirdParty' => $thirdParty,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'thirdParty' => $thirdParty->getId(),
|
||||||
|
'mainPerson' => $person->getId(),
|
||||||
|
'person1' => $person->getId(),
|
||||||
|
'person2' => $person->getId(),
|
||||||
|
],
|
||||||
|
function (array $data) use ($person, $thirdParty, $period) {
|
||||||
|
self::assertArrayHasKey('mainPerson', $data);
|
||||||
|
self::assertEquals($person->getId(), $data['mainPerson']['id']);
|
||||||
|
|
||||||
|
self::assertArrayHasKey('person1', $data);
|
||||||
|
self::assertEquals($person->getId(), $data['person1']['id']);
|
||||||
|
|
||||||
|
self::assertArrayHasKey('person2', $data);
|
||||||
|
self::assertEquals($person->getId(), $data['person2']['id']);
|
||||||
|
|
||||||
|
self::assertArrayHasKey('thirdParty', $data);
|
||||||
|
self::assertEquals($thirdParty->getId(), $data['thirdParty']['id']);
|
||||||
|
|
||||||
|
self::assertArrayHasKey('course', $data);
|
||||||
|
self::assertEquals($period->getId(), $data['course']['id']);
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
yield [
|
||||||
|
// test with any option activated
|
||||||
|
[
|
||||||
|
'mainPerson' => false,
|
||||||
|
'mainPersonLabel' => 'person',
|
||||||
|
'person1' => false,
|
||||||
|
'person1Label' => 'person2',
|
||||||
|
'person2' => false,
|
||||||
|
'person2Label' => 'person2',
|
||||||
|
'thirdParty' => false,
|
||||||
|
'thirdPartyLabel' => '3party'
|
||||||
|
],
|
||||||
|
$period,
|
||||||
|
[
|
||||||
|
'mainPerson' => null,
|
||||||
|
'person1' => null,
|
||||||
|
'person2' => null,
|
||||||
|
'thirdParty' => null,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'thirdParty' => null,
|
||||||
|
'mainPerson' => null,
|
||||||
|
'person1' => null,
|
||||||
|
'person2' => null,
|
||||||
|
],
|
||||||
|
function (array $data) use ($period) {
|
||||||
|
self::assertArrayHasKey('course', $data);
|
||||||
|
self::assertEquals($period->getId(), $data['course']['id']);
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
@ -18,20 +18,30 @@ use Chill\DocStoreBundle\Entity\PersonDocument;
|
|||||||
use Chill\DocStoreBundle\Entity\StoredObject;
|
use Chill\DocStoreBundle\Entity\StoredObject;
|
||||||
use Chill\DocStoreBundle\Repository\DocumentCategoryRepository;
|
use Chill\DocStoreBundle\Repository\DocumentCategoryRepository;
|
||||||
use Chill\DocStoreBundle\Security\Authorization\PersonDocumentVoter;
|
use Chill\DocStoreBundle\Security\Authorization\PersonDocumentVoter;
|
||||||
|
use Chill\MainBundle\Entity\Address;
|
||||||
use Chill\MainBundle\Entity\Center;
|
use Chill\MainBundle\Entity\Center;
|
||||||
|
use Chill\MainBundle\Entity\PostalCode;
|
||||||
use Chill\MainBundle\Entity\Scope;
|
use Chill\MainBundle\Entity\Scope;
|
||||||
use Chill\MainBundle\Entity\User;
|
use Chill\MainBundle\Entity\User;
|
||||||
use Chill\MainBundle\Form\Type\ScopePickerType;
|
use Chill\MainBundle\Form\Type\ScopePickerType;
|
||||||
|
use Chill\MainBundle\Repository\ScopeRepositoryInterface;
|
||||||
use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface;
|
use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface;
|
||||||
use Chill\MainBundle\Security\Resolver\CenterResolverManagerInterface;
|
use Chill\MainBundle\Security\Resolver\CenterResolverManagerInterface;
|
||||||
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||||
|
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||||
use Chill\PersonBundle\Entity\Person;
|
use Chill\PersonBundle\Entity\Person;
|
||||||
|
use Chill\PersonBundle\Repository\ResidentialAddressRepository;
|
||||||
|
use Chill\PersonBundle\Service\DocGenerator\AccompanyingPeriodContext;
|
||||||
use Chill\PersonBundle\Service\DocGenerator\PersonContext;
|
use Chill\PersonBundle\Service\DocGenerator\PersonContext;
|
||||||
|
use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
||||||
|
use Chill\ThirdPartyBundle\Repository\ThirdPartyRepository;
|
||||||
|
use Chill\ThirdPartyBundle\Templating\Entity\ThirdPartyRender;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use Prophecy\Argument;
|
use Prophecy\Argument;
|
||||||
use Prophecy\Exception\Prediction\FailedPredictionException;
|
use Prophecy\Exception\Prediction\FailedPredictionException;
|
||||||
use Prophecy\PhpUnit\ProphecyTrait;
|
use Prophecy\PhpUnit\ProphecyTrait;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
|
||||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
|
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
|
||||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||||
@ -46,10 +56,142 @@ use function count;
|
|||||||
* @internal
|
* @internal
|
||||||
* @coversNothing
|
* @coversNothing
|
||||||
*/
|
*/
|
||||||
final class PersonContextTest extends TestCase
|
final class PersonContextTest extends KernelTestCase
|
||||||
{
|
{
|
||||||
use ProphecyTrait;
|
use ProphecyTrait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This test run the methods executed when a document is generated:
|
||||||
|
*
|
||||||
|
* - normalized data from the form in a way that they are stored in message queue;
|
||||||
|
* - denormalize the data from the message queue,
|
||||||
|
* - and get the data, as they will be transmitted to the GeneratorDriver
|
||||||
|
*
|
||||||
|
* @param array $options the options, as they are stored in the DocGeneratorTemplate (the admin form data)
|
||||||
|
* @param Person $entity The entity from which the data will be extracted
|
||||||
|
* @param array $data The data, from the public form
|
||||||
|
* @param array $expectedNormalized, how the normalized data are expected (allow to check that this data will be compliant with the storage in messenger queue)
|
||||||
|
* @param callable $assertionsOnData some test that will be executed on the normalized data
|
||||||
|
* @dataProvider provideNormalizedData
|
||||||
|
*/
|
||||||
|
public function testContextGenerationDataNormalizeDenormalizeGetData(
|
||||||
|
array $options,
|
||||||
|
Person $entity,
|
||||||
|
array $data,
|
||||||
|
array $expectedNormalized,
|
||||||
|
callable $assertionsOnData
|
||||||
|
): void {
|
||||||
|
// we boot kernel only for this test
|
||||||
|
self::bootKernel();
|
||||||
|
|
||||||
|
// we create a PersonContext with the minimal dependency injection needed (relying on
|
||||||
|
// prophecy for other dependencies)
|
||||||
|
$context = $this->buildPersonContext(
|
||||||
|
null,
|
||||||
|
self::$container->get(BaseContextData::class),
|
||||||
|
self::$container->get(CenterResolverManagerInterface::class),
|
||||||
|
self::$container->get(DocumentCategoryRepository::class),
|
||||||
|
self::$container->get(EntityManagerInterface::class),
|
||||||
|
self::$container->get(NormalizerInterface::class),
|
||||||
|
(new ParameterBag(['chill_main' => ['acl' => ['form_show_scopes' => false]]])),
|
||||||
|
null,
|
||||||
|
self::$container->get(Security::class),
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
self::$container->get(ThirdPartyRepository::class)
|
||||||
|
);
|
||||||
|
$template = new DocGeneratorTemplate();
|
||||||
|
$template->setName(["fr" =>"test"])->setContext(AccompanyingPeriodContext::class)
|
||||||
|
->setDescription("description")->setActive(true)
|
||||||
|
->setOptions($options);
|
||||||
|
|
||||||
|
$normalized = $context->contextGenerationDataNormalize($template, $entity, $data);
|
||||||
|
|
||||||
|
self::assertEquals($expectedNormalized, $normalized);
|
||||||
|
|
||||||
|
$denormalized = $context->contextGenerationDataDenormalize($template, $entity, $normalized);
|
||||||
|
|
||||||
|
$data = $context->getData($template, $entity, $denormalized);
|
||||||
|
|
||||||
|
call_user_func($assertionsOnData, $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function provideNormalizedData(): iterable
|
||||||
|
{
|
||||||
|
self::bootKernel();
|
||||||
|
$em = self::$container->get(EntityManagerInterface::class);
|
||||||
|
|
||||||
|
$thirdParty = $em->createQuery("SELECT t FROM " . ThirdParty::class . " t")
|
||||||
|
->setMaxResults(1)
|
||||||
|
->getSingleResult();
|
||||||
|
|
||||||
|
if (null === $thirdParty) {
|
||||||
|
throw new \RuntimeException("No thirdparty in database");
|
||||||
|
}
|
||||||
|
|
||||||
|
$person = $em->createQuery("SELECT p FROM " . Person::class . " p")
|
||||||
|
->setMaxResults(1)
|
||||||
|
->getSingleResult();
|
||||||
|
|
||||||
|
if (null === $person) {
|
||||||
|
throw new \RuntimeException("No confirmed period in database");
|
||||||
|
}
|
||||||
|
|
||||||
|
$category = self::$container->get(DocumentCategoryRepository::class)
|
||||||
|
->findAll()[0];
|
||||||
|
|
||||||
|
if (null === $category) {
|
||||||
|
throw new \RuntimeException("no document category in database");
|
||||||
|
}
|
||||||
|
|
||||||
|
yield [
|
||||||
|
[
|
||||||
|
'thirdParty' => true,
|
||||||
|
'thirdPartyLabel' => '3party',
|
||||||
|
'category' => $category,
|
||||||
|
],
|
||||||
|
$person,
|
||||||
|
[
|
||||||
|
'title' => 'test',
|
||||||
|
'thirdParty' => $thirdParty,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'thirdParty' => $thirdParty->getId(),
|
||||||
|
'title' => 'test',
|
||||||
|
'scope_id' => null,
|
||||||
|
],
|
||||||
|
function ($data) use ($person, $thirdParty) {
|
||||||
|
self::assertArrayHasKey('person', $data);
|
||||||
|
self::assertEquals($person->getId(), $data['person']['id']);
|
||||||
|
|
||||||
|
self::assertArrayHasKey('thirdParty', $data);
|
||||||
|
self::assertEquals($thirdParty->getId(), $data['thirdParty']['id']);
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
yield [
|
||||||
|
[
|
||||||
|
'thirdParty' => false,
|
||||||
|
'thirdPartyLabel' => '3party',
|
||||||
|
'category' => $category,
|
||||||
|
],
|
||||||
|
$person,
|
||||||
|
[
|
||||||
|
'title' => 'test',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'title' => 'test',
|
||||||
|
'scope_id' => null,
|
||||||
|
'thirdParty' => null,
|
||||||
|
],
|
||||||
|
function ($data) use ($person, $thirdParty) {
|
||||||
|
self::assertArrayHasKey('person', $data);
|
||||||
|
self::assertEquals($person->getId(), $data['person']['id']);
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test that the build person context works in the case when 'form_show_scope' is false.
|
* Test that the build person context works in the case when 'form_show_scope' is false.
|
||||||
*/
|
*/
|
||||||
@ -208,9 +350,13 @@ final class PersonContextTest extends TestCase
|
|||||||
?EntityManagerInterface $em = null,
|
?EntityManagerInterface $em = null,
|
||||||
?NormalizerInterface $normalizer = null,
|
?NormalizerInterface $normalizer = null,
|
||||||
?ParameterBagInterface $parameterBag = null,
|
?ParameterBagInterface $parameterBag = null,
|
||||||
|
?ScopeRepositoryInterface $scopeRepository = null,
|
||||||
?Security $security = null,
|
?Security $security = null,
|
||||||
?TranslatorInterface $translator = null,
|
?TranslatorInterface $translator = null,
|
||||||
?TranslatableStringHelperInterface $translatableStringHelper = null
|
?TranslatableStringHelperInterface $translatableStringHelper = null,
|
||||||
|
?ThirdPartyRender $thirdPartyRender = null,
|
||||||
|
?ThirdPartyRepository $thirdPartyRepository = null,
|
||||||
|
?ResidentialAddressRepository $residentialAddressRepository = null
|
||||||
): PersonContext {
|
): PersonContext {
|
||||||
if (null === $authorizationHelper) {
|
if (null === $authorizationHelper) {
|
||||||
$authorizationHelper = $this->prophesize(AuthorizationHelperInterface::class)->reveal();
|
$authorizationHelper = $this->prophesize(AuthorizationHelperInterface::class)->reveal();
|
||||||
@ -250,6 +396,11 @@ final class PersonContextTest extends TestCase
|
|||||||
$parameterBag = new ParameterBag(['chill_main' => ['acl' => ['form_show_scopes' => true]]]);
|
$parameterBag = new ParameterBag(['chill_main' => ['acl' => ['form_show_scopes' => true]]]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (null === $scopeRepository) {
|
||||||
|
$scopeRepository = $this->prophesize(ScopeRepositoryInterface::class);
|
||||||
|
$scopeRepository = $scopeRepository->reveal();
|
||||||
|
}
|
||||||
|
|
||||||
if (null === $security) {
|
if (null === $security) {
|
||||||
$security = $this->prophesize(Security::class);
|
$security = $this->prophesize(Security::class);
|
||||||
$security->getUser()->willReturn(new User());
|
$security->getUser()->willReturn(new User());
|
||||||
@ -267,6 +418,28 @@ final class PersonContextTest extends TestCase
|
|||||||
$translatableStringHelper = $translatableStringHelper->reveal();
|
$translatableStringHelper = $translatableStringHelper->reveal();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (null === $thirdPartyRender) {
|
||||||
|
$thirdPartyRender = $this->prophesize(ThirdPartyRender::class);
|
||||||
|
$thirdPartyRender = $thirdPartyRender->reveal();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null === $thirdPartyRepository) {
|
||||||
|
$thirdPartyRepository = $this->prophesize(ThirdPartyRepository::class);
|
||||||
|
$thirdPartyRepository = $thirdPartyRepository->reveal();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null === $residentialAddressRepository) {
|
||||||
|
$residentialAddressRepository = $this->prophesize(ResidentialAddressRepository::class);
|
||||||
|
$residentialAddressRepository->findCurrentResidentialAddressByPerson(Argument::type(Person::class), Argument::any())
|
||||||
|
->willReturn([
|
||||||
|
(new Person\ResidentialAddress())
|
||||||
|
->setAddress((new Address())
|
||||||
|
->setStreet('test street')
|
||||||
|
->setPostcode(new PostalCode()))
|
||||||
|
]);
|
||||||
|
$residentialAddressRepository = $residentialAddressRepository->reveal();
|
||||||
|
}
|
||||||
|
|
||||||
return new PersonContext(
|
return new PersonContext(
|
||||||
$authorizationHelper,
|
$authorizationHelper,
|
||||||
$baseContextData,
|
$baseContextData,
|
||||||
@ -275,9 +448,13 @@ final class PersonContextTest extends TestCase
|
|||||||
$em,
|
$em,
|
||||||
$normalizer,
|
$normalizer,
|
||||||
$parameterBag,
|
$parameterBag,
|
||||||
|
$scopeRepository,
|
||||||
$security,
|
$security,
|
||||||
$translator,
|
$translator,
|
||||||
$translatableStringHelper
|
$translatableStringHelper,
|
||||||
|
$thirdPartyRender,
|
||||||
|
$thirdPartyRepository,
|
||||||
|
$residentialAddressRepository
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -927,10 +927,10 @@ docgen:
|
|||||||
Accompanying period work: "Action d'accompagnement"
|
Accompanying period work: "Action d'accompagnement"
|
||||||
Accompanying period work context: "Evaluation des actions d'accompagnement"
|
Accompanying period work context: "Evaluation des actions d'accompagnement"
|
||||||
Main person: Usager principal
|
Main person: Usager principal
|
||||||
person 1: Premièr usager
|
person 1: Premier usager
|
||||||
person 2: Second usager
|
person 2: Second usager
|
||||||
Ask for main person: Demander à l'utilisateur de préciser l'usager principal
|
Ask for main person: Demander à l'utilisateur de préciser l'usager principal
|
||||||
Ask for person 1: Demander à l'utilisateur de préciser le premièr usager
|
Ask for person 1: Demander à l'utilisateur de préciser le premier usager
|
||||||
Ask for person 2: Demander à l'utilisateur de préciser le second usager
|
Ask for person 2: Demander à l'utilisateur de préciser le second usager
|
||||||
A basic context for accompanying period: Contexte pour les parcours
|
A basic context for accompanying period: Contexte pour les parcours
|
||||||
A context for accompanying period work: Contexte pour les actions d'accompagnement
|
A context for accompanying period work: Contexte pour les actions d'accompagnement
|
||||||
|
@ -21,7 +21,7 @@ use DomainException;
|
|||||||
|
|
||||||
use function array_key_exists;
|
use function array_key_exists;
|
||||||
|
|
||||||
final class ThirdPartyRepository implements ObjectRepository
|
class ThirdPartyRepository implements ObjectRepository
|
||||||
{
|
{
|
||||||
private EntityRepository $repository;
|
private EntityRepository $repository;
|
||||||
|
|
||||||
|
@ -75,6 +75,7 @@ No email given: Aucune adresse courriel renseignée
|
|||||||
The party is visible in those centers: Le tiers est visible dans ces centres
|
The party is visible in those centers: Le tiers est visible dans ces centres
|
||||||
The party is not visible in any center: Le tiers n'est associé à aucun centre
|
The party is not visible in any center: Le tiers n'est associé à aucun centre
|
||||||
No third parties: Aucun tiers
|
No third parties: Aucun tiers
|
||||||
|
Any third party selected: Aucun tiers sélectionné
|
||||||
|
|
||||||
Thirdparty handling: Tiers traitant
|
Thirdparty handling: Tiers traitant
|
||||||
Thirdparty workers: Tiers intervenants
|
Thirdparty workers: Tiers intervenants
|
||||||
@ -112,6 +113,8 @@ crud:
|
|||||||
docgen:
|
docgen:
|
||||||
A context for person with a third party (for sending mail): Un contexte d'une personne avec un tiers (pour envoyer un courrier à ce tiers, par exemple)
|
A context for person with a third party (for sending mail): Un contexte d'une personne avec un tiers (pour envoyer un courrier à ce tiers, par exemple)
|
||||||
Person with third party: Personne avec choix d'un tiers
|
Person with third party: Personne avec choix d'un tiers
|
||||||
|
Ask for thirdParty: Demander à l'utilisateur de préciser un tiers
|
||||||
|
thirdParty label: Libellé du tiers
|
||||||
|
|
||||||
# exports
|
# exports
|
||||||
export:
|
export:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user