mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-08-20 14:43:49 +00:00
Merge remote-tracking branch 'origin/master' into 709-notification-eval-action
This commit is contained in:
@@ -650,8 +650,8 @@ final class ActivityController extends AbstractController
|
||||
throw $this->createNotFoundException('Accompanying Period not found');
|
||||
}
|
||||
|
||||
// TODO Add permission
|
||||
// $this->denyAccessUnlessGranted('CHILL_PERSON_SEE', $person);
|
||||
// TODO Add permission
|
||||
// $this->denyAccessUnlessGranted('CHILL_PERSON_SEE', $person);
|
||||
} else {
|
||||
throw $this->createNotFoundException('Person or Accompanying Period not found');
|
||||
}
|
||||
|
@@ -26,12 +26,12 @@ final class PersonMenuBuilder implements LocalMenuBuilderInterface
|
||||
/**
|
||||
* @var AuthorizationCheckerInterface
|
||||
*/
|
||||
protected $authorizationChecker;
|
||||
private $authorizationChecker;
|
||||
|
||||
/**
|
||||
* @var TranslatorInterface
|
||||
*/
|
||||
protected $translator;
|
||||
private $translator;
|
||||
|
||||
public function __construct(
|
||||
AuthorizationCheckerInterface $authorizationChecker,
|
||||
|
@@ -24,6 +24,9 @@ use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\PersonBundle\Repository\PersonRepository;
|
||||
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 Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
||||
@@ -55,6 +58,10 @@ class ActivityContext implements
|
||||
|
||||
private TranslatorInterface $translator;
|
||||
|
||||
private ThirdPartyRender $thirdPartyRender;
|
||||
|
||||
private ThirdPartyRepository $thirdPartyRepository;
|
||||
|
||||
public function __construct(
|
||||
DocumentCategoryRepository $documentCategoryRepository,
|
||||
NormalizerInterface $normalizer,
|
||||
@@ -63,7 +70,9 @@ class ActivityContext implements
|
||||
PersonRenderInterface $personRender,
|
||||
PersonRepository $personRepository,
|
||||
TranslatorInterface $translator,
|
||||
BaseContextData $baseContextData
|
||||
BaseContextData $baseContextData,
|
||||
ThirdPartyRender $thirdPartyRender,
|
||||
ThirdPartyRepository $thirdPartyRepository
|
||||
) {
|
||||
$this->documentCategoryRepository = $documentCategoryRepository;
|
||||
$this->normalizer = $normalizer;
|
||||
@@ -73,6 +82,8 @@ class ActivityContext implements
|
||||
$this->personRepository = $personRepository;
|
||||
$this->translator = $translator;
|
||||
$this->baseContextData = $baseContextData;
|
||||
$this->thirdPartyRender = $thirdPartyRender;
|
||||
$this->thirdPartyRepository = $thirdPartyRepository;
|
||||
}
|
||||
|
||||
public function adminFormReverseTransform(array $data): array
|
||||
@@ -89,6 +100,8 @@ class ActivityContext implements
|
||||
'person1Label' => $data['person1Label'] ?? $this->translator->trans('docgen.person 1'),
|
||||
'person2' => $data['person2'] ?? false,
|
||||
'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, [
|
||||
'label' => 'person 2 label',
|
||||
'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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -165,9 +206,11 @@ class ActivityContext implements
|
||||
$normalized = [];
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -235,7 +285,7 @@ class ActivityContext implements
|
||||
{
|
||||
$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
|
||||
|
@@ -140,26 +140,36 @@ class ListActivitiesByAccompanyingPeriodContext implements
|
||||
return $normalized;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list
|
||||
*/
|
||||
private function filterActivitiesByUser(array $activities, User $user): array
|
||||
{
|
||||
return array_filter(
|
||||
$activities,
|
||||
function ($activity) use ($user) {
|
||||
$activityUsernames = array_map(static fn ($user) => $user['username'], $activity['users'] ?? []);
|
||||
return in_array($user->getUsername(), $activityUsernames, true);
|
||||
}
|
||||
return array_values(
|
||||
array_filter(
|
||||
$activities,
|
||||
function ($activity) use ($user) {
|
||||
$activityUsernames = array_map(static fn ($user) => $user['username'], $activity['users'] ?? []);
|
||||
return in_array($user->getUsername(), $activityUsernames, true);
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list
|
||||
*/
|
||||
private function filterWorksByUser(array $works, User $user): array
|
||||
{
|
||||
return array_filter(
|
||||
$works,
|
||||
function ($work) use ($user) {
|
||||
$workUsernames = array_map(static fn ($user) => $user['username'], $work['referrers'] ?? []);
|
||||
return array_values(
|
||||
array_filter(
|
||||
$works,
|
||||
function ($work) use ($user) {
|
||||
$workUsernames = array_map(static fn ($user) => $user['username'], $work['referrers'] ?? []);
|
||||
|
||||
return in_array($user->getUsername(), $workUsernames, true);
|
||||
}
|
||||
return in_array($user->getUsername(), $workUsernames, true);
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
@@ -21,7 +21,7 @@ class CalculatorResult
|
||||
|
||||
public $label;
|
||||
|
||||
public $result;
|
||||
public float $result;
|
||||
|
||||
public $type;
|
||||
}
|
||||
|
@@ -1,55 +1,91 @@
|
||||
<template>
|
||||
<a :class="props.classes" @click="download_and_open($event)">
|
||||
<i class="fa fa-download"></i>
|
||||
Télécharger
|
||||
</a>
|
||||
<a v-if="!state.is_ready" :class="props.classes" @click="download_and_open($event)">
|
||||
<i class="fa fa-download"></i>
|
||||
Télécharger
|
||||
</a>
|
||||
<a v-else :class="props.classes" target="_blank" :type="props.storedObject.type" :download="buildDocumentName()" :href="state.href_url" ref="open_button">
|
||||
<i class="fa fa-external-link"></i>
|
||||
Ouvrir
|
||||
</a>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {reactive} from "vue";
|
||||
import {reactive, ref, nextTick, onMounted} from "vue";
|
||||
import {build_download_info_link, download_and_decrypt_doc} from "./helpers";
|
||||
import mime from "mime";
|
||||
import {StoredObject} from "../../types";
|
||||
|
||||
interface DownloadButtonConfig {
|
||||
storedObject: StoredObject,
|
||||
classes: {[k: string]: boolean},
|
||||
filename?: string,
|
||||
storedObject: StoredObject,
|
||||
classes: { [k: string]: boolean },
|
||||
filename?: string,
|
||||
}
|
||||
|
||||
interface DownloadButtonState {
|
||||
is_ready: boolean
|
||||
is_ready: boolean,
|
||||
is_running: boolean,
|
||||
href_url: string,
|
||||
}
|
||||
|
||||
const props = defineProps<DownloadButtonConfig>();
|
||||
const state: DownloadButtonState = reactive({is_ready: false});
|
||||
const state: DownloadButtonState = reactive({is_ready: false, is_running: false, href_url: "#"});
|
||||
|
||||
async function download_and_open(event: Event): Promise<void> {
|
||||
const button = event.target as HTMLAnchorElement;
|
||||
|
||||
if (!state.is_ready) {
|
||||
event.preventDefault();
|
||||
const urlInfo = build_download_info_link(props.storedObject.filename);
|
||||
|
||||
const raw = await download_and_decrypt_doc(urlInfo, props.storedObject.keyInfos, new Uint8Array(props.storedObject.iv));
|
||||
|
||||
button.href = window.URL.createObjectURL(raw);
|
||||
button.type = props.storedObject.type;
|
||||
|
||||
button.download = props.filename || 'document';
|
||||
const open_button = ref<HTMLAnchorElement | null>(null);
|
||||
|
||||
function buildDocumentName(): string {
|
||||
const document_name = props.filename || 'document';
|
||||
const ext = mime.getExtension(props.storedObject.type);
|
||||
|
||||
if (null !== ext) {
|
||||
button.download = button.download + '.' + ext;
|
||||
return document_name + '.' + ext;
|
||||
}
|
||||
|
||||
state.is_ready = true;
|
||||
return document_name;
|
||||
}
|
||||
|
||||
// for fixing https://gitlab.com/Chill-Projet/chill-bundles/-/issues/98
|
||||
window.setTimeout(() => {
|
||||
button.click()
|
||||
}, 750);
|
||||
}
|
||||
async function download_and_open(event: Event): Promise<void> {
|
||||
const button = event.target as HTMLAnchorElement;
|
||||
|
||||
if (state.is_running) {
|
||||
console.log('state is running, aborting');
|
||||
return;
|
||||
}
|
||||
|
||||
state.is_running = true;
|
||||
|
||||
if (state.is_ready) {
|
||||
console.log('state is ready. This should not happens');
|
||||
return;
|
||||
}
|
||||
|
||||
const urlInfo = build_download_info_link(props.storedObject.filename);
|
||||
let raw;
|
||||
|
||||
try {
|
||||
raw = await download_and_decrypt_doc(urlInfo, props.storedObject.keyInfos, new Uint8Array(props.storedObject.iv));
|
||||
} catch (e) {
|
||||
console.error("error while downloading and decrypting document");
|
||||
console.error(e);
|
||||
throw e;
|
||||
}
|
||||
|
||||
console.log('document downloading (and decrypting) successfully');
|
||||
|
||||
console.log('creating the url')
|
||||
state.href_url = window.URL.createObjectURL(raw);
|
||||
console.log('url created', state.href_url);
|
||||
state.is_running = false;
|
||||
state.is_ready = true;
|
||||
console.log('new button marked as ready');
|
||||
console.log('will click on button');
|
||||
|
||||
console.log('openbutton is now', open_button.value);
|
||||
|
||||
await nextTick();
|
||||
console.log('next tick actions');
|
||||
console.log('openbutton after next tick', open_button.value);
|
||||
open_button.value?.click();
|
||||
console.log('open button should have been clicked');
|
||||
}
|
||||
</script>
|
||||
|
||||
|
@@ -149,16 +149,21 @@ async function download_and_decrypt_doc(urlGenerator: string, keyData: JsonWebKe
|
||||
}
|
||||
|
||||
if (iv.length === 0) {
|
||||
console.log('returning document immediatly');
|
||||
return rawResponse.blob();
|
||||
}
|
||||
|
||||
console.log('start decrypting doc');
|
||||
|
||||
const rawBuffer = await rawResponse.arrayBuffer();
|
||||
|
||||
try {
|
||||
const key = await window.crypto.subtle
|
||||
.importKey('jwk', keyData, { name: algo }, false, ['decrypt']);
|
||||
console.log('key created');
|
||||
const decrypted = await window.crypto.subtle
|
||||
.decrypt({ name: algo, iv: iv }, key, rawBuffer);
|
||||
console.log('doc decrypted');
|
||||
|
||||
return Promise.resolve(new Blob([decrypted]));
|
||||
} catch (e) {
|
||||
|
@@ -36,5 +36,4 @@ class SynchronizeEntityInfoViewsCommand extends Command
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -163,7 +163,6 @@ final class PermissionsGroupController extends AbstractController
|
||||
*/
|
||||
public function deleteLinkRoleScopeAction(int $pgid, int $rsid): Response
|
||||
{
|
||||
|
||||
$permissionsGroup = $this->permissionsGroupRepository->find($pgid);
|
||||
$roleScope = $this->roleScopeRepository->find($rsid);
|
||||
|
||||
|
@@ -141,5 +141,4 @@ final readonly class UserExportController
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -48,12 +48,19 @@ class Center implements HasCenterInterface
|
||||
*/
|
||||
private string $name = '';
|
||||
|
||||
/**
|
||||
* @var Collection<Regroupment>
|
||||
* @ORM\ManyToMany(targetEntity=Regroupment::class, mappedBy="centers")
|
||||
*/
|
||||
private Collection $regroupments;
|
||||
|
||||
/**
|
||||
* Center constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->groupCenters = new \Doctrine\Common\Collections\ArrayCollection();
|
||||
$this->groupCenters = new ArrayCollection();
|
||||
$this->regroupments = new ArrayCollection();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -106,6 +113,14 @@ class Center implements HasCenterInterface
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection<Regroupment>
|
||||
*/
|
||||
public function getRegroupments(): Collection
|
||||
{
|
||||
return $this->regroupments;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
*
|
||||
|
@@ -22,11 +22,12 @@ use Doctrine\ORM\Mapping as ORM;
|
||||
class Regroupment
|
||||
{
|
||||
/**
|
||||
* @var Center
|
||||
* @ORM\ManyToMany(
|
||||
* targetEntity=Center::class
|
||||
* targetEntity=Center::class,
|
||||
* inversedBy="regroupments"
|
||||
* )
|
||||
* @ORM\Id
|
||||
* @var Collection<Center>
|
||||
*/
|
||||
private Collection $centers;
|
||||
|
||||
@@ -52,6 +53,26 @@ class Regroupment
|
||||
$this->centers = new ArrayCollection();
|
||||
}
|
||||
|
||||
public function addCenter(Center $center): self
|
||||
{
|
||||
if (!$this->centers->contains($center)) {
|
||||
$this->centers->add($center);
|
||||
$center->getRegroupments()->add($this);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function removeCenter(Center $center): self
|
||||
{
|
||||
if ($this->centers->contains($center)) {
|
||||
$this->centers->removeElement($center);
|
||||
$center->getRegroupments()->removeElement($this);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getCenters(): Collection
|
||||
{
|
||||
return $this->centers;
|
||||
|
@@ -31,7 +31,7 @@ class RegroupmentType extends AbstractType
|
||||
->add('centers', EntityType::class, [
|
||||
'class' => Center::class,
|
||||
'multiple' => true,
|
||||
'attr' => ['class' => 'select2'],
|
||||
'expanded' => true,
|
||||
])
|
||||
->add('isActive', CheckboxType::class, [
|
||||
'label' => 'Actif ?',
|
||||
|
@@ -14,6 +14,8 @@ namespace Chill\MainBundle\Repository;
|
||||
use Chill\MainBundle\Entity\Regroupment;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use Doctrine\ORM\NonUniqueResultException;
|
||||
use Doctrine\ORM\NoResultException;
|
||||
use Doctrine\Persistence\ObjectRepository;
|
||||
|
||||
final class RegroupmentRepository implements ObjectRepository
|
||||
@@ -59,6 +61,30 @@ final class RegroupmentRepository implements ObjectRepository
|
||||
return $this->repository->findOneBy($criteria, $orderBy);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NonUniqueResultException
|
||||
* @throws NoResultException
|
||||
*/
|
||||
public function findOneByName(string $name): ?Regroupment
|
||||
{
|
||||
return $this->repository->createQueryBuilder('r')
|
||||
->where('LOWER(r.name) = LOWER(:searched)')
|
||||
->setParameter('searched', $name)
|
||||
->getQuery()
|
||||
->getSingleResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<Regroupment>
|
||||
*/
|
||||
public function findRegroupmentAssociatedToNoCenter(): array
|
||||
{
|
||||
return $this->repository->createQueryBuilder('r')
|
||||
->where('SIZE(r.centers) = 0')
|
||||
->getQuery()
|
||||
->getResult();
|
||||
}
|
||||
|
||||
public function getClassName()
|
||||
{
|
||||
return Regroupment::class;
|
||||
|
@@ -39,8 +39,13 @@
|
||||
{{ 'This will eventually restrict your possibilities in filtering the data.'|trans }}</p>
|
||||
|
||||
<h3 class="m-3">{{ 'Center'|trans }}</h3>
|
||||
|
||||
{{ form_widget(form.centers.center) }}
|
||||
|
||||
<div class="mb-3 mt-3">
|
||||
<input id="toggle-check-all" class="btn btn-misc" type= "button" onclick='uncheckAll(this)' value="{{ 'uncheck all centers'|trans|e('html_attr') }}"/>
|
||||
</div>
|
||||
|
||||
{% if form.centers.regroupment is defined %}
|
||||
<h3 class="m-3">{{ 'Pick aggregated centers'|trans }}</h3>
|
||||
{{ form_widget(form.centers.regroupment) }}
|
||||
@@ -53,3 +58,15 @@
|
||||
|
||||
</div>
|
||||
{% endblock content %}
|
||||
|
||||
{% block js %}
|
||||
|
||||
<script>
|
||||
const uncheckAll = () => {
|
||||
const allCenters = document.getElementsByName('centers[center][]');
|
||||
|
||||
allCenters.forEach(checkbox => checkbox.checked = false)
|
||||
}
|
||||
</script>
|
||||
|
||||
{% endblock js %}
|
||||
|
@@ -285,6 +285,8 @@ The export will contains only data from the picked centers.: L'export ne contien
|
||||
This will eventually restrict your possibilities in filtering the data.: Les possibilités de filtrages seront adaptées aux droits de consultation pour les centres choisis.
|
||||
Go to export options: Vers la préparation de l'export
|
||||
Pick aggregated centers: Regroupement de centres
|
||||
uncheck all centers: Désélectionner tous les centres
|
||||
check all centers: Sélectionner tous les centres
|
||||
# export creation step 'export' : choose aggregators, filtering and formatter
|
||||
Formatter: Mise en forme
|
||||
Choose the formatter: Choisissez le format d'export voulu.
|
||||
|
@@ -51,7 +51,10 @@ class UserRefEventSubscriber implements EventSubscriberInterface
|
||||
|
||||
public function onStateEntered(EnteredEvent $enteredEvent): void
|
||||
{
|
||||
if ($enteredEvent->getMarking()->has(AccompanyingPeriod::STEP_CONFIRMED)) {
|
||||
if (
|
||||
$enteredEvent->getMarking()->has(AccompanyingPeriod::STEP_CONFIRMED)
|
||||
and $enteredEvent->getTransition()->getName() === 'confirm'
|
||||
) {
|
||||
$this->onPeriodConfirmed($enteredEvent->getSubject());
|
||||
}
|
||||
}
|
||||
|
@@ -34,5 +34,4 @@ class AccompanyingPeriodStepChangeMessageHandler implements MessageHandlerInterf
|
||||
|
||||
($this->changer)($period, $message->getTransition());
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -84,5 +84,4 @@ class AccompanyingPeriodStepChangeRequestor
|
||||
$this->messageBus->dispatch(new AccompanyingPeriodStepChangeRequestMessage($accompanyingPeriodId, 'mark_active'));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -13,7 +13,11 @@ namespace Chill\PersonBundle\Actions\Remove;
|
||||
|
||||
use Chill\PersonBundle\Actions\ActionEvent;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriodParticipation;
|
||||
use Chill\PersonBundle\Entity\Household\HouseholdMember;
|
||||
use Chill\PersonBundle\Entity\Household\PersonHouseholdAddress;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\PersonBundle\Entity\Relationships\Relationship;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
@@ -42,7 +46,7 @@ class PersonMove
|
||||
protected $eventDispatcher;
|
||||
|
||||
public function __construct(
|
||||
EntityManagerInterface $em,
|
||||
EntityManagerInterface $em,
|
||||
EventDispatcherInterface $eventDispatcher
|
||||
) {
|
||||
$this->em = $em;
|
||||
@@ -84,8 +88,11 @@ class PersonMove
|
||||
}
|
||||
|
||||
foreach ($metadata->getAssociationMappings() as $field => $mapping) {
|
||||
if (Person::class === $mapping['targetEntity']) {
|
||||
if (in_array($metadata->getName(), $toDelete, true)) {
|
||||
if (in_array($mapping['sourceEntity'], $this->getIgnoredEntities(), true)) {
|
||||
continue;
|
||||
}
|
||||
if (Person::class === $mapping['targetEntity'] and true === $mapping['isOwningSide']) {
|
||||
if (in_array($mapping['sourceEntity'], $toDelete, true)) {
|
||||
$sql = $this->createDeleteSQL($metadata, $from, $field);
|
||||
$event = new ActionEvent(
|
||||
$from->getId(),
|
||||
@@ -120,7 +127,7 @@ class PersonMove
|
||||
return $sqls;
|
||||
}
|
||||
|
||||
protected function createDeleteSQL(ClassMetadata $metadata, Person $from, $field): string
|
||||
private function createDeleteSQL(ClassMetadata $metadata, Person $from, $field): string
|
||||
{
|
||||
$mapping = $metadata->getAssociationMapping($field);
|
||||
|
||||
@@ -137,26 +144,41 @@ class PersonMove
|
||||
);
|
||||
}
|
||||
|
||||
protected function createMoveSQL(ClassMetadata $metadata, Person $from, Person $to, $field): string
|
||||
private function createMoveSQL(ClassMetadata $metadata, Person $from, Person $to, $field): string
|
||||
{
|
||||
$mapping = $metadata->getAssociationMapping($field);
|
||||
|
||||
// Set part of the query, aka <here> in "UPDATE table SET <here> "
|
||||
$sets = [];
|
||||
|
||||
foreach ($mapping['joinColumns'] as $columns) {
|
||||
$sets[] = sprintf('%s = %d', $columns['name'], $to->getId());
|
||||
}
|
||||
|
||||
$conditions = [];
|
||||
$tableName = '';
|
||||
|
||||
foreach ($mapping['joinColumns'] as $columns) {
|
||||
$conditions[] = sprintf('%s = %d', $columns['name'], $from->getId());
|
||||
if (array_key_exists('joinTable', $mapping)) {
|
||||
$tableName = (null !== ($mapping['joinTable']['schema'] ?? null) ? $mapping['joinTable']['schema'] . '.' : '')
|
||||
. $mapping['joinTable']['name'];
|
||||
|
||||
foreach ($mapping['joinTable']['inverseJoinColumns'] as $columns) {
|
||||
$sets[] = sprintf('%s = %d', $columns['name'], $to->getId());
|
||||
}
|
||||
|
||||
foreach ($mapping['joinTable']['inverseJoinColumns'] as $columns) {
|
||||
$conditions[] = sprintf('%s = %d', $columns['name'], $from->getId());
|
||||
}
|
||||
} elseif (array_key_exists('joinColumns', $mapping)) {
|
||||
$tableName = $this->getTableName($metadata);
|
||||
foreach ($mapping['joinColumns'] as $columns) {
|
||||
$sets[] = sprintf('%s = %d', $columns['name'], $to->getId());
|
||||
}
|
||||
|
||||
|
||||
foreach ($mapping['joinColumns'] as $columns) {
|
||||
$conditions[] = sprintf('%s = %d', $columns['name'], $from->getId());
|
||||
}
|
||||
}
|
||||
|
||||
return sprintf(
|
||||
'UPDATE %s SET %s WHERE %s',
|
||||
$this->getTableName($metadata),
|
||||
$tableName,
|
||||
implode(' ', $sets),
|
||||
implode(' AND ', $conditions)
|
||||
);
|
||||
@@ -166,10 +188,23 @@ class PersonMove
|
||||
* return an array of classes where entities should be deleted
|
||||
* instead of moved.
|
||||
*/
|
||||
protected function getDeleteEntities(): array
|
||||
private function getDeleteEntities(): array
|
||||
{
|
||||
return [
|
||||
AccompanyingPeriod::class,
|
||||
Person\PersonCenterHistory::class,
|
||||
HouseholdMember::class,
|
||||
AccompanyingPeriodParticipation::class,
|
||||
AccompanyingPeriod\AccompanyingPeriodWork::class,
|
||||
Relationship::class
|
||||
];
|
||||
}
|
||||
|
||||
private function getIgnoredEntities(): array
|
||||
{
|
||||
return [
|
||||
Person\PersonCurrentAddress::class,
|
||||
PersonHouseholdAddress::class,
|
||||
Person\PersonCenterCurrent::class,
|
||||
];
|
||||
}
|
||||
|
||||
|
@@ -247,7 +247,7 @@ class PersonDuplicateController extends Controller
|
||||
);
|
||||
|
||||
$duplicatePersons = $this->similarPersonMatcher->
|
||||
matchPerson($person, $personNotDuplicateRepository, 0.5, SimilarPersonMatcher::SIMILAR_SEARCH_ORDER_BY_ALPHABETICAL);
|
||||
matchPerson($person, 0.5, SimilarPersonMatcher::SIMILAR_SEARCH_ORDER_BY_ALPHABETICAL, false);
|
||||
|
||||
$notDuplicatePersons = $personNotDuplicateRepository->findNotDuplicatePerson($person);
|
||||
|
||||
@@ -264,14 +264,14 @@ class PersonDuplicateController extends Controller
|
||||
|
||||
$nb_activity = $em->getRepository(Activity::class)->findBy(['person' => $id]);
|
||||
$nb_document = $em->getRepository(PersonDocument::class)->findBy(['person' => $id]);
|
||||
$nb_event = $em->getRepository(Participation::class)->findBy(['person' => $id]);
|
||||
// $nb_event = $em->getRepository(Participation::class)->findBy(['person' => $id]);
|
||||
$nb_task = $em->getRepository(SingleTask::class)->countByParameters(['person' => $id]);
|
||||
$person = $em->getRepository(Person::class)->findOneBy(['id' => $id]);
|
||||
|
||||
return [
|
||||
'nb_activity' => count($nb_activity),
|
||||
'nb_document' => count($nb_document),
|
||||
'nb_event' => count($nb_event),
|
||||
// 'nb_event' => count($nb_event),
|
||||
'nb_task' => $nb_task,
|
||||
'nb_addresses' => count($person->getAddresses()),
|
||||
];
|
||||
|
@@ -12,9 +12,11 @@ declare(strict_types=1);
|
||||
namespace Chill\PersonBundle\Controller;
|
||||
|
||||
use Chill\MainBundle\Pagination\PaginatorFactory;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
use Chill\PersonBundle\Repository\AccompanyingPeriodRepository;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
class UserAccompanyingPeriodController extends AbstractController
|
||||
@@ -32,12 +34,24 @@ class UserAccompanyingPeriodController extends AbstractController
|
||||
/**
|
||||
* @Route("/{_locale}/person/accompanying-periods/my", name="chill_person_accompanying_period_user")
|
||||
*/
|
||||
public function listAction(Request $request)
|
||||
public function listAction(Request $request): Response
|
||||
{
|
||||
$total = $this->accompanyingPeriodRepository->countBy(['user' => $this->getUser(), 'step' => ['CONFIRMED', 'CLOSED']]);
|
||||
$active = $request->query->getBoolean('active', true);
|
||||
$steps = match ($active) {
|
||||
true => [
|
||||
AccompanyingPeriod::STEP_CONFIRMED,
|
||||
AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_LONG,
|
||||
AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_SHORT,
|
||||
],
|
||||
false => [
|
||||
AccompanyingPeriod::STEP_CLOSED,
|
||||
]
|
||||
};
|
||||
|
||||
$total = $this->accompanyingPeriodRepository->countBy(['user' => $this->getUser(), 'step' => $steps]);
|
||||
$pagination = $this->paginatorFactory->create($total);
|
||||
$accompanyingPeriods = $this->accompanyingPeriodRepository->findBy(
|
||||
['user' => $this->getUser(), 'step' => ['CONFIRMED', 'CLOSED']],
|
||||
['user' => $this->getUser(), 'step' => $steps],
|
||||
['openingDate' => 'DESC'],
|
||||
$pagination->getItemsPerPage(),
|
||||
$pagination->getCurrentPageFirstItemNumber()
|
||||
@@ -46,13 +60,14 @@ class UserAccompanyingPeriodController extends AbstractController
|
||||
return $this->render('@ChillPerson/AccompanyingPeriod/user_periods_list.html.twig', [
|
||||
'accompanyingPeriods' => $accompanyingPeriods,
|
||||
'pagination' => $pagination,
|
||||
'active' => $active,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/{_locale}/person/accompanying-periods/my/drafts", name="chill_person_accompanying_period_draft_user")
|
||||
*/
|
||||
public function listDraftsAction(Request $request)
|
||||
public function listDraftsAction(): Response
|
||||
{
|
||||
$total = $this->accompanyingPeriodRepository->countBy(['user' => $this->getUser(), 'step' => 'DRAFT']);
|
||||
$pagination = $this->paginatorFactory->create($total);
|
||||
|
@@ -45,7 +45,7 @@ class PersonCenterCurrent
|
||||
private ?int $id = null;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity=Person::class, inversedBy="centerCurrent")
|
||||
* @ORM\OneToOne(targetEntity=Person::class, inversedBy="centerCurrent")
|
||||
*/
|
||||
private Person $person;
|
||||
|
||||
|
@@ -107,7 +107,6 @@ class ListHouseholdInPeriod implements ListInterface, GroupedExportInterface
|
||||
return $this->aggregateStringHelper->getLabelMulti($key, $values, 'export.list.household.' . $key);
|
||||
|
||||
case 'compositionType':
|
||||
//dump($values);
|
||||
return $this->translatableStringHelper->getLabel($key, $values, 'export.list.household.' . $key);
|
||||
|
||||
default:
|
||||
|
@@ -12,7 +12,9 @@ declare(strict_types=1);
|
||||
namespace Chill\PersonBundle\Menu;
|
||||
|
||||
use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
|
||||
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
|
||||
use Knp\Menu\MenuItem;
|
||||
use Symfony\Component\Security\Core\Security;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
class HouseholdMenuBuilder implements LocalMenuBuilderInterface
|
||||
@@ -22,9 +24,12 @@ class HouseholdMenuBuilder implements LocalMenuBuilderInterface
|
||||
*/
|
||||
protected $translator;
|
||||
|
||||
public function __construct(TranslatorInterface $translator)
|
||||
private Security $security;
|
||||
|
||||
public function __construct(TranslatorInterface $translator, Security $security)
|
||||
{
|
||||
$this->translator = $translator;
|
||||
$this->security = $security;
|
||||
}
|
||||
|
||||
public function buildMenu($menuId, MenuItem $menu, array $parameters): void
|
||||
@@ -53,12 +58,14 @@ class HouseholdMenuBuilder implements LocalMenuBuilderInterface
|
||||
], ])
|
||||
->setExtras(['order' => 17]);
|
||||
|
||||
$menu->addChild($this->translator->trans('household.Accompanying period'), [
|
||||
'route' => 'chill_person_household_accompanying_period',
|
||||
'routeParameters' => [
|
||||
'household_id' => $household->getId(),
|
||||
], ])
|
||||
->setExtras(['order' => 20]);
|
||||
if ($this->security->isGranted(AccompanyingPeriodVoter::SEE, $parameters['household'])) {
|
||||
$menu->addChild($this->translator->trans('household.Accompanying period'), [
|
||||
'route' => 'chill_person_household_accompanying_period',
|
||||
'routeParameters' => [
|
||||
'household_id' => $household->getId(),
|
||||
],])
|
||||
->setExtras(['order' => 20]);
|
||||
}
|
||||
|
||||
$menu->addChild($this->translator->trans('household.Addresses'), [
|
||||
'route' => 'chill_person_household_addresses',
|
||||
|
@@ -15,6 +15,7 @@ use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\PersonBundle\Repository\ResidentialAddressRepository;
|
||||
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
|
||||
use Chill\PersonBundle\Security\Authorization\PersonVoter;
|
||||
use Knp\Menu\MenuItem;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
||||
use Symfony\Component\Security\Core\Security;
|
||||
@@ -106,17 +107,19 @@ class PersonMenuBuilder implements LocalMenuBuilderInterface
|
||||
->setExtras([
|
||||
'order' => 99999,
|
||||
]);
|
||||
/*
|
||||
$menu->addChild($this->translator->trans('Person duplicate'), [
|
||||
'route' => 'chill_person_duplicate_view',
|
||||
'routeParameters' => [
|
||||
'person_id' => $parameters['person']->getId(),
|
||||
],
|
||||
])
|
||||
->setExtras([
|
||||
'order' => 99999,
|
||||
]);
|
||||
*/
|
||||
|
||||
if ($this->security->isGranted(PersonVoter::DUPLICATE, $parameters['person'])) {
|
||||
$menu->addChild($this->translator->trans('Person duplicate'), [
|
||||
'route' => 'chill_person_duplicate_view',
|
||||
'routeParameters' => [
|
||||
'person_id' => $parameters['person']->getId(),
|
||||
],
|
||||
])
|
||||
->setExtras([
|
||||
'order' => 99999,
|
||||
]);
|
||||
}
|
||||
|
||||
if (
|
||||
'visible' === $this->showAccompanyingPeriod
|
||||
&& $this->security->isGranted(AccompanyingPeriodVoter::SEE, $parameters['person'])
|
||||
|
@@ -89,5 +89,4 @@ readonly class AccompanyingPeriodInfoRepository implements AccompanyingPeriodInf
|
||||
{
|
||||
return AccompanyingPeriodInfo::class;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -122,7 +122,8 @@
|
||||
<add-evaluation
|
||||
v-for="e in pickedEvaluations"
|
||||
v-bind:key="e.key"
|
||||
v-bind:evaluation="e">
|
||||
v-bind:evaluation="e"
|
||||
v-bind:docAnchorId="this.docAnchorId">
|
||||
</add-evaluation>
|
||||
|
||||
<!-- box to add new evaluation -->
|
||||
@@ -406,6 +407,7 @@ export default {
|
||||
i18n,
|
||||
data() {
|
||||
return {
|
||||
docAnchorId: null,
|
||||
isExpanded: false,
|
||||
editor: ClassicEditor,
|
||||
showAddObjective: false,
|
||||
@@ -445,7 +447,14 @@ export default {
|
||||
},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
beforeMount() {
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
this.docAnchorId = urlParams.get('doc_id');
|
||||
},
|
||||
mounted() {
|
||||
this.scrollToElement(this.docAnchorId);
|
||||
},
|
||||
computed: {
|
||||
...mapState([
|
||||
'work',
|
||||
'resultsForAction',
|
||||
@@ -594,7 +603,7 @@ export default {
|
||||
});
|
||||
},
|
||||
saveFormOnTheFly(payload) {
|
||||
console.log('saveFormOnTheFly: type', payload.type, ', data', payload.data);
|
||||
// console.log('saveFormOnTheFly: type', payload.type, ', data', payload.data);
|
||||
|
||||
let body = { type: payload.type };
|
||||
body.name = payload.data.text;
|
||||
@@ -616,6 +625,12 @@ export default {
|
||||
this.$toast.open({message: 'An error occurred'});
|
||||
}
|
||||
})
|
||||
},
|
||||
scrollToElement(docAnchorId) {
|
||||
const documentEl = document.getElementById(`document_${docAnchorId}`);
|
||||
if (documentEl) {
|
||||
documentEl.scrollIntoView({behavior: 'smooth'});
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@@ -11,7 +11,7 @@
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<form-evaluation ref="FormEvaluation" :key="evaluation.key" :evaluation="evaluation"></form-evaluation>
|
||||
<form-evaluation ref="FormEvaluation" :key="evaluation.key" :evaluation="evaluation" :docAnchorId="docAnchorId"></form-evaluation>
|
||||
|
||||
<ul class="record_actions">
|
||||
<li v-if="evaluation.workflows_availables.length > 0">
|
||||
@@ -85,7 +85,7 @@ export default {
|
||||
Modal,
|
||||
ListWorkflowModal,
|
||||
},
|
||||
props: ['evaluation'],
|
||||
props: ['evaluation', 'docAnchorId'],
|
||||
i18n,
|
||||
data() {
|
||||
return {
|
||||
|
@@ -79,8 +79,8 @@
|
||||
<h5>{{ $t('Documents') }} :</h5>
|
||||
|
||||
<div class="flex-table">
|
||||
<div class="item-bloc" v-for="(d, i) in evaluation.documents" :key="d.id">
|
||||
<div class="item-row">
|
||||
<div class="item-bloc" v-for="(d, i) in evaluation.documents" :key="d.id" :class="[parseInt(this.docAnchorId) === d.id ? 'bg-blink' : 'nothing']">
|
||||
<div :id="`document_${d.id}`" class="item-row">
|
||||
<div class="input-group input-group-lg mb-3 row">
|
||||
<label class="col-sm-3 col-form-label">Titre du document:</label>
|
||||
<div class="col-sm-9">
|
||||
@@ -92,7 +92,7 @@
|
||||
:data-key="i"
|
||||
@input="onInputDocumentTitle"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item-row">
|
||||
<div class="item-col item-meta">
|
||||
@@ -238,7 +238,7 @@ const i18n = {
|
||||
|
||||
export default {
|
||||
name: "FormEvaluation",
|
||||
props: ['evaluation'],
|
||||
props: ['evaluation', 'docAnchorId'],
|
||||
components: {
|
||||
ckeditor: CKEditor.component,
|
||||
PickTemplate,
|
||||
@@ -437,4 +437,19 @@ export default {
|
||||
ul.document-upload {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.bg-blink{
|
||||
color: #050000;
|
||||
padding: 10px;
|
||||
display: inline-block;
|
||||
border-radius: 5px;
|
||||
animation: blinkingBackground 2.2s infinite;
|
||||
animation-iteration-count: 2;
|
||||
}
|
||||
|
||||
@keyframes blinkingBackground{
|
||||
0% { background-color: #ed776d;}
|
||||
50% { background-color: #ffffff;}
|
||||
100% { background-color: #ed776d;}
|
||||
}
|
||||
</style>
|
||||
|
@@ -207,7 +207,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {dateToISO} from 'ChillMainAssets/chill/js/date';
|
||||
import {dateToISO, ISOToDate} from 'ChillMainAssets/chill/js/date';
|
||||
import AddressRenderBox from 'ChillMainAssets/vuejs/_components/Entity/AddressRenderBox.vue';
|
||||
import Confidential from 'ChillMainAssets/vuejs/_components/Confidential.vue';
|
||||
import BadgeEntity from 'ChillMainAssets/vuejs/_components/BadgeEntity.vue';
|
||||
@@ -262,7 +262,7 @@ export default {
|
||||
},
|
||||
birthdate: function () {
|
||||
if (this.person.birthdate !== null || this.person.birthdate === "undefined") {
|
||||
return new Date(this.person.birthdate.datetime);
|
||||
return ISOToDate(this.person.birthdate.datetime);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
|
@@ -16,11 +16,13 @@
|
||||
</div>
|
||||
<div class="wh-col">
|
||||
{% if period.step == 'DRAFT' %}
|
||||
<span class="badge bg-secondary">{{- 'Draft'|trans|upper -}}</span>
|
||||
{% elseif period.step == 'CONFIRMED' %}
|
||||
<span class="badge bg-primary">{{- 'Confirmed'|trans|upper -}}</span>
|
||||
{% else %}
|
||||
<span class="badge bg-danger">{{- 'Closed'|trans|upper -}}</span>
|
||||
<span class="badge bg-secondary" style="font-size: 85%;" title="{{ 'course.draft'|trans|e('html_attr') }}">{{ 'course.draft'|trans }}</span>
|
||||
{% elseif period.step == 'CLOSED' %}
|
||||
<span class="badge bg-danger" style="font-size: 85%;" title="{{ 'course.closed'|trans|e('html_attr') }}">{{ 'course.closed'|trans }}</span>
|
||||
{% elseif period.step == 'CONFIRMED_INACTIVE_SHORT' %}
|
||||
<span class="badge bg-chill-yellow text-primary" style="font-size: 85%;" title="{{ 'course.inactive_short'|trans|e('html_attr') }}">{{ 'course.inactive_short'|trans }}</span>
|
||||
{% elseif period.step == 'CONFIRMED_INACTIVE_LONG' %}
|
||||
<span class="badge bg-danger" style="font-size: 85%;" title="{{ 'course.inactive_long'|trans|e('html_attr') }}">{{ 'course.inactive_long'|trans }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -17,6 +17,15 @@
|
||||
<div class="col-md-10">
|
||||
<h1>{{ 'My accompanying periods'|trans }}</h1>
|
||||
|
||||
<ul class="nav nav-pills justify-content-center">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link {% if active == true %}active{% endif %}" aria-current="page" href="{{ chill_path_forward_return_path('chill_person_accompanying_period_user', {'active': true}) }}">{{ ['Confirmed'|trans, 'course.inactive_short'|trans, 'course.inactive_long'|trans]|join(', ') }}</a>
|
||||
</li>
|
||||
<li class="nav-item ">
|
||||
<a class="nav-link {% if active == false %}active{% endif %}" href="{{ chill_path_forward_return_path('chill_person_accompanying_period_user', {'active': false}) }}">{{ 'course.closed'|trans }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>{{ 'Number of periods'|trans }}: <span class="badge rounded-pill bg-primary">{{ pagination.totalItems }}</span></p>
|
||||
|
||||
<div class="flex-table accompanyingcourse-list">
|
||||
|
@@ -40,13 +40,14 @@
|
||||
{{ 'Household summary'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
{# TODO: add ACL to check if user is allowed to edit household? #}
|
||||
<li>
|
||||
<a class="btn btn-create"
|
||||
href="{{ path ('chill_household_accompanying_course_new', {'household_id' : household.id } ) }}" role="button">
|
||||
{{ 'Create an accompanying period'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
{% if is_granted('CHILL_PERSON_HOUSEHOLD_EDIT', household) %}
|
||||
<li>
|
||||
<a class="btn btn-create"
|
||||
href="{{ path ('chill_household_accompanying_course_new', {'household_id' : household.id } ) }}" role="button">
|
||||
{{ 'Create an accompanying period'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
@@ -39,7 +39,7 @@
|
||||
<li><b>{{ person.counters.nb_activity }}</b> {{ (person.counters.nb_activity > 1)? 'échanges' : 'échange' }}</li>
|
||||
<li><b>{{ person.counters.nb_task }}</b> {{ (person.counters.nb_task > 1)? 'tâches' : 'tâche' }}</li>
|
||||
<li><b>{{ person.counters.nb_document }}</b> {{ (person.counters.nb_document > 1)? 'documents' : 'document' }}</li>
|
||||
<li><b>{{ person.counters.nb_event }}</b> {{ (person.counters.nb_event > 1)? 'événements' : 'événement' }}</li>
|
||||
{# <li><b>{{ person.counters.nb_event }}</b> {{ (person.counters.nb_event > 1)? 'événements' : 'événement' }}</li>#}
|
||||
<li><b>{{ person.counters.nb_addresses }}</b> {{ (person.counters.nb_addresses > 1)? 'adresses' : 'adresse' }}</li>
|
||||
|
||||
</ul>
|
||||
|
@@ -25,7 +25,7 @@
|
||||
|
||||
<h1>{{ 'Merge duplicate persons folders'|trans }}</h1>
|
||||
|
||||
<div class="col-md-6">
|
||||
<div class="col-md-11">
|
||||
<p><b>{{ 'Old person'|trans }}</b>:
|
||||
{{ 'Old person explain'|trans }}
|
||||
</p>
|
||||
@@ -43,7 +43,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<div class="col-md-11">
|
||||
<p><b>{{ 'New person'|trans }}</b>:
|
||||
{{ 'New person explain'|trans }}
|
||||
</p>
|
||||
@@ -63,10 +63,10 @@
|
||||
|
||||
{{ form_start(form) }}
|
||||
|
||||
<div class="col-md-4 centered">
|
||||
<div class="col-md-12 centered">
|
||||
|
||||
<div class="container-fluid" style="padding-top: 1em;">
|
||||
<div class="col-1 clear" style="padding-top: 10px;">
|
||||
<div class="clear" style="padding-top: 10px;">
|
||||
{{ form_widget(form.confirm) }}
|
||||
</div>
|
||||
<div class="col-11">
|
||||
|
@@ -123,7 +123,7 @@
|
||||
<ul class="record_actions">
|
||||
<li>{{ doc.storedObject|chill_document_button_group(doc.title, is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_UPDATE', evaluation.accompanyingPeriodWork)) }}</li>
|
||||
<li>
|
||||
<a class="btn btn-show" href="{{ path('chill_person_accompanying_period_work_edit', {'id': evaluation.accompanyingPeriodWork.id}) }}">
|
||||
<a class="btn btn-show" href="{{ path('chill_person_accompanying_period_work_edit', {'id': evaluation.accompanyingPeriodWork.id, 'doc_id': doc.id}) }}">
|
||||
{{ 'Show'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
|
@@ -18,6 +18,7 @@ use Chill\MainBundle\Security\Authorization\VoterHelperFactoryInterface;
|
||||
use Chill\MainBundle\Security\Authorization\VoterHelperInterface;
|
||||
use Chill\MainBundle\Security\ProvideRoleHierarchyInterface;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
use Chill\PersonBundle\Entity\Household\Household;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
use Symfony\Component\Security\Core\Security;
|
||||
@@ -119,6 +120,7 @@ class AccompanyingPeriodVoter extends AbstractChillVoter implements ProvideRoleH
|
||||
->generate(self::class)
|
||||
->addCheckFor(null, [self::CREATE, self::REASSIGN_BULK])
|
||||
->addCheckFor(AccompanyingPeriod::class, [self::TOGGLE_CONFIDENTIAL, ...self::ALL])
|
||||
->addCheckFor(Household::class, [self::SEE])
|
||||
->addCheckFor(Person::class, [self::SEE, self::CREATE])
|
||||
->addCheckFor(Center::class, [self::STATS])
|
||||
->build();
|
||||
|
@@ -22,10 +22,14 @@ use Chill\DocStoreBundle\Entity\StoredObject;
|
||||
use Chill\DocStoreBundle\Repository\DocumentCategoryRepository;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\Resource;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriodParticipation;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\PersonBundle\Repository\PersonRepository;
|
||||
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 Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
@@ -40,6 +44,7 @@ use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
use function array_key_exists;
|
||||
|
||||
/**
|
||||
* @see AccompanyingPeriodContextTest
|
||||
* @template-implements DocGeneratorContextWithPublicFormInterface<AccompanyingPeriod>
|
||||
*/
|
||||
class AccompanyingPeriodContext implements
|
||||
@@ -62,6 +67,10 @@ class AccompanyingPeriodContext implements
|
||||
|
||||
private TranslatorInterface $translator;
|
||||
|
||||
private ThirdPartyRender $thirdPartyRender;
|
||||
|
||||
private ThirdPartyRepository $thirdPartyRepository;
|
||||
|
||||
public function __construct(
|
||||
DocumentCategoryRepository $documentCategoryRepository,
|
||||
NormalizerInterface $normalizer,
|
||||
@@ -70,7 +79,9 @@ class AccompanyingPeriodContext implements
|
||||
PersonRenderInterface $personRender,
|
||||
PersonRepository $personRepository,
|
||||
TranslatorInterface $translator,
|
||||
BaseContextData $baseContextData
|
||||
BaseContextData $baseContextData,
|
||||
ThirdPartyRender $thirdPartyRender,
|
||||
ThirdPartyRepository $thirdPartyRepository
|
||||
) {
|
||||
$this->documentCategoryRepository = $documentCategoryRepository;
|
||||
$this->normalizer = $normalizer;
|
||||
@@ -80,6 +91,8 @@ class AccompanyingPeriodContext implements
|
||||
$this->personRepository = $personRepository;
|
||||
$this->translator = $translator;
|
||||
$this->baseContextData = $baseContextData;
|
||||
$this->thirdPartyRender = $thirdPartyRender;
|
||||
$this->thirdPartyRepository = $thirdPartyRepository;
|
||||
}
|
||||
|
||||
public function adminFormReverseTransform(array $data): array
|
||||
@@ -103,11 +116,12 @@ class AccompanyingPeriodContext implements
|
||||
'person1Label' => $data['person1Label'] ?? $this->translator->trans('docgen.person 1'),
|
||||
'person2' => $data['person2'] ?? false,
|
||||
'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)) {
|
||||
$r['category'] = array_key_exists('category', $data) ?
|
||||
$this->documentCategoryRepository->find($data['category']) : null;
|
||||
$r['category'] = $this->documentCategoryRepository->find($data['category']);
|
||||
}
|
||||
|
||||
return $r;
|
||||
@@ -140,6 +154,14 @@ class AccompanyingPeriodContext implements
|
||||
'label' => 'person 2 label',
|
||||
'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, [
|
||||
'placeholder' => 'Choose a document category',
|
||||
'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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -254,7 +305,7 @@ class AccompanyingPeriodContext implements
|
||||
{
|
||||
$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
|
||||
@@ -264,6 +315,8 @@ class AccompanyingPeriodContext implements
|
||||
$normalized[$k] = null !== ($data[$k] ?? null) ? $data[$k]->getId() : null;
|
||||
}
|
||||
|
||||
$normalized['thirdParty'] = ($data['thirdParty'] ?? null)?->getId();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@@ -18,13 +18,18 @@ use Chill\DocStoreBundle\Entity\StoredObject;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluation;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluationDocument;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\Resource;
|
||||
use Chill\PersonBundle\Entity\SocialWork\Evaluation;
|
||||
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 Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
|
||||
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
/**
|
||||
* @implements DocGeneratorContextWithPublicFormInterface<AccompanyingPeriodWorkEvaluation>
|
||||
@@ -43,18 +48,26 @@ class AccompanyingPeriodWorkEvaluationContext implements
|
||||
|
||||
private TranslatableStringHelperInterface $translatableStringHelper;
|
||||
|
||||
private ThirdPartyRender $thirdPartyRender;
|
||||
|
||||
private TranslatorInterface $translator;
|
||||
|
||||
public function __construct(
|
||||
AccompanyingPeriodWorkContext $accompanyingPeriodWorkContext,
|
||||
EntityManagerInterface $em,
|
||||
EvaluationRepository $evaluationRepository,
|
||||
NormalizerInterface $normalizer,
|
||||
TranslatableStringHelperInterface $translatableStringHelper
|
||||
TranslatableStringHelperInterface $translatableStringHelper,
|
||||
ThirdPartyRender $thirdPartyRender,
|
||||
TranslatorInterface $translator
|
||||
) {
|
||||
$this->accompanyingPeriodWorkContext = $accompanyingPeriodWorkContext;
|
||||
$this->em = $em;
|
||||
$this->evaluationRepository = $evaluationRepository;
|
||||
$this->normalizer = $normalizer;
|
||||
$this->translatableStringHelper = $translatableStringHelper;
|
||||
$this->thirdPartyRender = $thirdPartyRender;
|
||||
$this->translator = $translator;
|
||||
}
|
||||
|
||||
public function adminFormReverseTransform(array $data): array
|
||||
@@ -102,6 +115,31 @@ class AccompanyingPeriodWorkEvaluationContext implements
|
||||
public function buildPublicForm(FormBuilderInterface $builder, DocGeneratorTemplate $template, $entity): void
|
||||
{
|
||||
$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
|
||||
@@ -116,7 +154,6 @@ class AccompanyingPeriodWorkEvaluationContext implements
|
||||
AbstractNormalizer::GROUPS => ['docgen:read'],
|
||||
]
|
||||
);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
@@ -26,14 +26,22 @@ use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
|
||||
use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface;
|
||||
use Chill\MainBundle\Security\Resolver\CenterResolverManagerInterface;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||
use Chill\PersonBundle\Entity\Person\PersonResource;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\PersonBundle\Entity\Person\ResidentialAddress;
|
||||
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 Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use LogicException;
|
||||
use Service\DocGenerator\PersonContextTest;
|
||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||
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\FormBuilderInterface;
|
||||
use Symfony\Component\Security\Core\Security;
|
||||
@@ -43,6 +51,9 @@ use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
use function array_key_exists;
|
||||
use function count;
|
||||
|
||||
/**
|
||||
* @see PersonContextTest
|
||||
*/
|
||||
final class PersonContext implements PersonContextInterface
|
||||
{
|
||||
private AuthorizationHelperInterface $authorizationHelper;
|
||||
@@ -67,6 +78,12 @@ final class PersonContext implements PersonContextInterface
|
||||
|
||||
private TranslatorInterface $translator;
|
||||
|
||||
private ThirdPartyRender $thirdPartyRender;
|
||||
|
||||
private ThirdPartyRepository $thirdPartyRepository;
|
||||
|
||||
private ResidentialAddressRepository $residentialAddressRepository;
|
||||
|
||||
public function __construct(
|
||||
AuthorizationHelperInterface $authorizationHelper,
|
||||
BaseContextData $baseContextData,
|
||||
@@ -78,7 +95,10 @@ final class PersonContext implements PersonContextInterface
|
||||
ScopeRepositoryInterface $scopeRepository,
|
||||
Security $security,
|
||||
TranslatorInterface $translator,
|
||||
TranslatableStringHelperInterface $translatableStringHelper
|
||||
TranslatableStringHelperInterface $translatableStringHelper,
|
||||
ThirdPartyRender $thirdPartyRender,
|
||||
ThirdPartyRepository $thirdPartyRepository,
|
||||
ResidentialAddressRepository $residentialAddressRepository
|
||||
) {
|
||||
$this->authorizationHelper = $authorizationHelper;
|
||||
$this->centerResolverManager = $centerResolverManager;
|
||||
@@ -91,6 +111,9 @@ final class PersonContext implements PersonContextInterface
|
||||
$this->showScopes = $parameterBag->get('chill_main')['acl']['form_show_scopes'];
|
||||
$this->translator = $translator;
|
||||
$this->translatableStringHelper = $translatableStringHelper;
|
||||
$this->thirdPartyRender = $thirdPartyRender;
|
||||
$this->thirdPartyRepository = $thirdPartyRepository;
|
||||
$this->residentialAddressRepository = $residentialAddressRepository;
|
||||
}
|
||||
|
||||
public function adminFormReverseTransform(array $data): array
|
||||
@@ -110,11 +133,12 @@ final class PersonContext implements PersonContextInterface
|
||||
$r = [
|
||||
'mainPerson' => $data['mainPerson'] ?? false,
|
||||
'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)) {
|
||||
$r['category'] = array_key_exists('category', $data) ?
|
||||
$this->documentCategoryRepository->find($data['category']) : null;
|
||||
$r['category'] = $this->documentCategoryRepository->find($data['category']);
|
||||
}
|
||||
|
||||
return $r;
|
||||
@@ -131,6 +155,14 @@ final class PersonContext implements PersonContextInterface
|
||||
->setParameter('docClass', PersonDocument::class),
|
||||
'choice_label' => fn ($entity = null) => $entity ? $this->translatableStringHelper->localize($entity->getName()) : '',
|
||||
'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
|
||||
{
|
||||
$options = $template->getOptions();
|
||||
|
||||
$builder->add('title', TextType::class, [
|
||||
'required' => true,
|
||||
'label' => 'docgen.Document title',
|
||||
'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)) {
|
||||
$builder->add('scope', ScopePickerType::class, [
|
||||
'center' => $this->centerResolverManager->resolveCenters($entity),
|
||||
@@ -156,10 +223,6 @@ final class PersonContext implements PersonContextInterface
|
||||
|
||||
public function getData(DocGeneratorTemplate $template, $entity, array $contextGenerationData = []): array
|
||||
{
|
||||
if (!$entity instanceof Person) {
|
||||
throw new UnexpectedTypeException($entity, Person::class);
|
||||
}
|
||||
|
||||
$data = [];
|
||||
$data = array_merge($data, $this->baseContextData->getData($contextGenerationData['creator'] ?? null));
|
||||
$data['person'] = $this->normalizer->normalize($entity, 'docgen', [
|
||||
@@ -170,6 +233,13 @@ final class PersonContext implements PersonContextInterface
|
||||
'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;
|
||||
}
|
||||
|
||||
@@ -223,6 +293,7 @@ final class PersonContext implements PersonContextInterface
|
||||
return [
|
||||
'title' => $data['title'] ?? '',
|
||||
'scope_id' => $scope instanceof Scope ? $scope->getId() : null,
|
||||
'thirdParty' => ($data['thirdParty'] ?? null)?->getId(),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -242,6 +313,7 @@ final class PersonContext implements PersonContextInterface
|
||||
return [
|
||||
'title' => $data['title'] ?? '',
|
||||
'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;
|
||||
|
||||
/**
|
||||
* @template-extends DocGeneratorContextWithPublicFormInterface<Person>
|
||||
* @template-extends DocGeneratorContextWithPublicFormInterface<Person>
|
||||
* @template-extends DocGeneratorContextWithAdminFormInterface<Person>
|
||||
*/
|
||||
interface PersonContextInterface extends DocGeneratorContextWithAdminFormInterface, DocGeneratorContextWithPublicFormInterface
|
||||
{
|
||||
|
@@ -51,5 +51,4 @@ class AccompanyingPeriodStepChangeCronjobTest extends TestCase
|
||||
// can not run: not enough elapsed time
|
||||
yield ['2023-01-15T01:00:00+02:00', new \DateTimeImmutable('2023-01-15T00:30:00+02:00'), false];
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -78,17 +78,13 @@ final class SocialWorkTypeFilterTest extends AbstractFilterTest
|
||||
$goals = array_unique($goals);
|
||||
$results = array_unique($results);
|
||||
|
||||
$data = [
|
||||
return [
|
||||
[
|
||||
'actionType' => implode(',', $actions),
|
||||
'goal' => implode(',', $goals),
|
||||
'result' => implode(',', $results),
|
||||
],
|
||||
];
|
||||
/// TODO ne fonctionne pas
|
||||
var_dump($data);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function getQueryBuilders(): array
|
||||
|
@@ -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\Repository\DocumentCategoryRepository;
|
||||
use Chill\DocStoreBundle\Security\Authorization\PersonDocumentVoter;
|
||||
use Chill\MainBundle\Entity\Address;
|
||||
use Chill\MainBundle\Entity\Center;
|
||||
use Chill\MainBundle\Entity\PostalCode;
|
||||
use Chill\MainBundle\Entity\Scope;
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Chill\MainBundle\Form\Type\ScopePickerType;
|
||||
use Chill\MainBundle\Repository\ScopeRepositoryInterface;
|
||||
use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface;
|
||||
use Chill\MainBundle\Security\Resolver\CenterResolverManagerInterface;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\PersonBundle\Repository\ResidentialAddressRepository;
|
||||
use Chill\PersonBundle\Service\DocGenerator\AccompanyingPeriodContext;
|
||||
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 PHPUnit\Framework\TestCase;
|
||||
use Prophecy\Argument;
|
||||
use Prophecy\Exception\Prediction\FailedPredictionException;
|
||||
use Prophecy\PhpUnit\ProphecyTrait;
|
||||
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
@@ -46,10 +56,142 @@ use function count;
|
||||
* @internal
|
||||
* @coversNothing
|
||||
*/
|
||||
final class PersonContextTest extends TestCase
|
||||
final class PersonContextTest extends KernelTestCase
|
||||
{
|
||||
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.
|
||||
*/
|
||||
@@ -208,9 +350,13 @@ final class PersonContextTest extends TestCase
|
||||
?EntityManagerInterface $em = null,
|
||||
?NormalizerInterface $normalizer = null,
|
||||
?ParameterBagInterface $parameterBag = null,
|
||||
?ScopeRepositoryInterface $scopeRepository = null,
|
||||
?Security $security = null,
|
||||
?TranslatorInterface $translator = null,
|
||||
?TranslatableStringHelperInterface $translatableStringHelper = null
|
||||
?TranslatableStringHelperInterface $translatableStringHelper = null,
|
||||
?ThirdPartyRender $thirdPartyRender = null,
|
||||
?ThirdPartyRepository $thirdPartyRepository = null,
|
||||
?ResidentialAddressRepository $residentialAddressRepository = null
|
||||
): PersonContext {
|
||||
if (null === $authorizationHelper) {
|
||||
$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]]]);
|
||||
}
|
||||
|
||||
if (null === $scopeRepository) {
|
||||
$scopeRepository = $this->prophesize(ScopeRepositoryInterface::class);
|
||||
$scopeRepository = $scopeRepository->reveal();
|
||||
}
|
||||
|
||||
if (null === $security) {
|
||||
$security = $this->prophesize(Security::class);
|
||||
$security->getUser()->willReturn(new User());
|
||||
@@ -267,6 +418,28 @@ final class PersonContextTest extends TestCase
|
||||
$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(
|
||||
$authorizationHelper,
|
||||
$baseContextData,
|
||||
@@ -275,9 +448,13 @@ final class PersonContextTest extends TestCase
|
||||
$em,
|
||||
$normalizer,
|
||||
$parameterBag,
|
||||
$scopeRepository,
|
||||
$security,
|
||||
$translator,
|
||||
$translatableStringHelper
|
||||
$translatableStringHelper,
|
||||
$thirdPartyRender,
|
||||
$thirdPartyRepository,
|
||||
$residentialAddressRepository
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -927,10 +927,10 @@ docgen:
|
||||
Accompanying period work: "Action d'accompagnement"
|
||||
Accompanying period work context: "Evaluation des actions d'accompagnement"
|
||||
Main person: Usager principal
|
||||
person 1: Premièr usager
|
||||
person 1: Premier usager
|
||||
person 2: Second usager
|
||||
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
|
||||
A basic context for accompanying period: Contexte pour les parcours
|
||||
A context for accompanying period work: Contexte pour les actions d'accompagnement
|
||||
|
@@ -166,7 +166,7 @@ class LoadReports extends AbstractFixture implements ContainerAwareInterface, Or
|
||||
/**
|
||||
* pick a random choice.
|
||||
*
|
||||
* @return string|string[] the array of slug if multiple, a single slug otherwise
|
||||
* @return string|string[]
|
||||
*/
|
||||
private function getRandomChoice(CustomField $field)
|
||||
{
|
||||
@@ -211,6 +211,8 @@ class LoadReports extends AbstractFixture implements ContainerAwareInterface, Or
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
return $picked;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -226,7 +228,7 @@ class LoadReports extends AbstractFixture implements ContainerAwareInterface, Or
|
||||
/**
|
||||
* pick a choice within a 'choices' options (for choice type).
|
||||
*
|
||||
* @return the slug of the selected choice
|
||||
* @return string the slug of the selected choice
|
||||
*/
|
||||
private function pickChoice(array $choices)
|
||||
{
|
||||
|
@@ -117,7 +117,7 @@ class ThirdPartyType extends AbstractType
|
||||
'label' => 'thirdparty.Contact data are confidential',
|
||||
]);
|
||||
|
||||
// Institutional ThirdParty (parent)
|
||||
// Institutional ThirdParty (parent)
|
||||
} else {
|
||||
$builder
|
||||
->add('nameCompany', TextType::class, [
|
||||
|
@@ -21,7 +21,7 @@ use DomainException;
|
||||
|
||||
use function array_key_exists;
|
||||
|
||||
final class ThirdPartyRepository implements ObjectRepository
|
||||
class ThirdPartyRepository implements ObjectRepository
|
||||
{
|
||||
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 not visible in any center: Le tiers n'est associé à aucun centre
|
||||
No third parties: Aucun tiers
|
||||
Any third party selected: Aucun tiers sélectionné
|
||||
|
||||
Thirdparty handling: Tiers traitant
|
||||
Thirdparty workers: Tiers intervenants
|
||||
@@ -112,6 +113,8 @@ crud:
|
||||
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)
|
||||
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
|
||||
export:
|
||||
|
Reference in New Issue
Block a user