mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-08-29 19:13:49 +00:00
Merge branch 'signature-app-master' into 'master'
Signature app master Closes #307 See merge request Chill-Projet/chill-bundles!743
This commit is contained in:
@@ -11,7 +11,6 @@ declare(strict_types=1);
|
||||
|
||||
namespace Chill\PersonBundle\Controller;
|
||||
|
||||
use Chill\DocStoreBundle\Serializer\Normalizer\StoredObjectNormalizer;
|
||||
use Chill\MainBundle\Pagination\PaginatorFactory;
|
||||
use Chill\MainBundle\Templating\Listing\FilterOrderHelper;
|
||||
use Chill\MainBundle\Templating\Listing\FilterOrderHelperFactoryInterface;
|
||||
@@ -116,7 +115,7 @@ final class AccompanyingCourseWorkController extends AbstractController
|
||||
{
|
||||
$this->denyAccessUnlessGranted(AccompanyingPeriodWorkVoter::UPDATE, $work);
|
||||
|
||||
$json = $this->serializer->normalize($work, 'json', ['groups' => ['read', StoredObjectNormalizer::ADD_DAV_EDIT_LINK_CONTEXT]]);
|
||||
$json = $this->serializer->normalize($work, 'json', ['groups' => ['read']]);
|
||||
|
||||
return $this->render('@ChillPerson/AccompanyingCourseWork/edit.html.twig', [
|
||||
'accompanyingCourse' => $work->getAccompanyingPeriod(),
|
||||
|
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\PersonBundle\Controller;
|
||||
|
||||
use Chill\MainBundle\Routing\ChillUrlGeneratorInterface;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluationDocument;
|
||||
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodWorkVoter;
|
||||
use Chill\PersonBundle\Service\AccompanyingPeriodWorkEvaluationDocument\AccompanyingPeriodWorkEvaluationDocumentDuplicator;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Component\Security\Core\Security;
|
||||
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
|
||||
use Symfony\Component\Serializer\SerializerInterface;
|
||||
|
||||
class AccompanyingPeriodWorkEvaluationDocumentDuplicateController
|
||||
{
|
||||
public function __construct(
|
||||
private readonly AccompanyingPeriodWorkEvaluationDocumentDuplicator $duplicator,
|
||||
private readonly Security $security,
|
||||
private readonly SerializerInterface $serializer,
|
||||
private readonly EntityManagerInterface $entityManager,
|
||||
private readonly ChillUrlGeneratorInterface $urlGenerator,
|
||||
) {}
|
||||
|
||||
#[Route('/api/1.0/person/accompanying-course-work-evaluation-document/{id}/duplicate', methods: ['POST'])]
|
||||
public function duplicateApi(AccompanyingPeriodWorkEvaluationDocument $document): Response
|
||||
{
|
||||
$work = $document->getAccompanyingPeriodWorkEvaluation()->getAccompanyingPeriodWork();
|
||||
|
||||
if (!$this->security->isGranted(AccompanyingPeriodWorkVoter::UPDATE, $work)) {
|
||||
throw new AccessDeniedHttpException('not allowed to edit this accompanying period work');
|
||||
}
|
||||
|
||||
$duplicatedDocument = $this->duplicator->duplicate($document);
|
||||
|
||||
$this->entityManager->persist($duplicatedDocument);
|
||||
$this->entityManager->persist($duplicatedDocument->getStoredObject());
|
||||
$this->entityManager->flush();
|
||||
|
||||
return new JsonResponse(
|
||||
$this->serializer->serialize($duplicatedDocument, 'json', [AbstractNormalizer::GROUPS => ['read']]),
|
||||
json: true
|
||||
);
|
||||
}
|
||||
|
||||
#[Route('/{_locale}/person/accompanying-course-work-evaluation-document/{id}/duplicate', name: 'chill_person_accompanying_period_work_evaluation_document_duplicate', methods: ['POST'])]
|
||||
public function duplicate(AccompanyingPeriodWorkEvaluationDocument $document): Response
|
||||
{
|
||||
$work = $document->getAccompanyingPeriodWorkEvaluation()->getAccompanyingPeriodWork();
|
||||
|
||||
if (!$this->security->isGranted(AccompanyingPeriodWorkVoter::UPDATE, $work)) {
|
||||
throw new AccessDeniedHttpException('not allowed to edit this accompanying period work');
|
||||
}
|
||||
|
||||
$duplicatedDocument = $this->duplicator->duplicate($document);
|
||||
|
||||
$this->entityManager->persist($duplicatedDocument);
|
||||
$this->entityManager->persist($duplicatedDocument->getStoredObject());
|
||||
$this->entityManager->flush();
|
||||
|
||||
return new RedirectResponse(
|
||||
$this->urlGenerator->forwardReturnPath(
|
||||
'chill_person_accompanying_period_work_edit',
|
||||
['id' => $work->getId(), 'doc_id' => $duplicatedDocument->getId()]
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\PersonBundle\Controller;
|
||||
|
||||
use Chill\MainBundle\Repository\Workflow\EntityWorkflowStepSignatureACLAwareRepository;
|
||||
use Chill\MainBundle\Workflow\EntityWorkflowManager;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\PersonBundle\Security\Authorization\PersonVoter;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
class PersonSignatureController extends AbstractController
|
||||
{
|
||||
public function __construct(
|
||||
private readonly EntityWorkflowStepSignatureACLAwareRepository $signatureRepository,
|
||||
private readonly EntityWorkflowManager $entityWorkflowManager,
|
||||
) {}
|
||||
|
||||
#[Route(path: '/{_locale}/signatures/by-person/{id}', name: 'chill_person_signature_list')]
|
||||
public function listSignatures(Person $person): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted(PersonVoter::SEE, $person);
|
||||
|
||||
$signatures = $this->signatureRepository->findByPersonAndPendingState($person);
|
||||
$signatureData = [];
|
||||
|
||||
foreach ($signatures as $signature) {
|
||||
$entityWorkflow = $signature->getStep()->getEntityWorkflow();
|
||||
$handler = $this->entityWorkflowManager->getHandler($entityWorkflow);
|
||||
|
||||
$workflow = [
|
||||
'handler_template' => $handler->getTemplate($entityWorkflow),
|
||||
'handler_template_data' => $handler->getTemplateData($entityWorkflow),
|
||||
'entity_workflow' => $entityWorkflow,
|
||||
];
|
||||
|
||||
$storedObject = $this->entityWorkflowManager->getAssociatedStoredObject($entityWorkflow);
|
||||
$signatureData[] = [
|
||||
'signature' => $signature,
|
||||
'document' => $storedObject,
|
||||
'workflow' => $workflow,
|
||||
];
|
||||
}
|
||||
|
||||
return $this->render('@ChillPerson/Person/signature_list.html.twig', [
|
||||
'signatures' => $signatureData,
|
||||
'person' => $person,
|
||||
]);
|
||||
}
|
||||
}
|
@@ -25,6 +25,8 @@ use Chill\MainBundle\Entity\Gender;
|
||||
use Chill\MainBundle\Entity\HasCenterInterface;
|
||||
use Chill\MainBundle\Entity\Language;
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Chill\MainBundle\Entity\Workflow\EntityWorkflowSignatureStateEnum;
|
||||
use Chill\MainBundle\Entity\Workflow\EntityWorkflowStepSignature;
|
||||
use Chill\MainBundle\Validation\Constraint\PhonenumberConstraint;
|
||||
use Chill\PersonBundle\Entity\Household\Household;
|
||||
use Chill\PersonBundle\Entity\Household\HouseholdMember;
|
||||
@@ -40,6 +42,7 @@ use DateTime;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\Common\Collections\Criteria;
|
||||
use Doctrine\Common\Collections\ReadableCollection;
|
||||
use Doctrine\Common\Collections\Selectable;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use libphonenumber\PhoneNumber;
|
||||
@@ -375,6 +378,12 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
#[ORM\ManyToOne(targetEntity: User::class)]
|
||||
private ?User $updatedBy = null;
|
||||
|
||||
/**
|
||||
* @var Collection<int, EntityWorkflowStepSignature>
|
||||
*/
|
||||
#[ORM\OneToMany(targetEntity: EntityWorkflowStepSignature::class, mappedBy: 'personSigner', orphanRemoval: true)]
|
||||
private Collection $signatures;
|
||||
|
||||
/**
|
||||
* Person constructor.
|
||||
*/
|
||||
@@ -396,6 +405,7 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
$this->budgetCharges = new ArrayCollection();
|
||||
$this->resources = new ArrayCollection();
|
||||
$this->centerHistory = new ArrayCollection();
|
||||
$this->signatures = new ArrayCollection();
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
@@ -467,6 +477,35 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addSignature(EntityWorkflowStepSignature $signature): self
|
||||
{
|
||||
if (!$this->signatures->contains($signature)) {
|
||||
$this->signatures->add($signature);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function removeSignature(EntityWorkflowStepSignature $signature): self
|
||||
{
|
||||
$this->signatures->removeElement($signature);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ReadableCollection<int, EntityWorkflowStepSignature>
|
||||
*/
|
||||
public function getSignatures(): ReadableCollection
|
||||
{
|
||||
return $this->signatures;
|
||||
}
|
||||
|
||||
public function getSignaturesPending(): ReadableCollection
|
||||
{
|
||||
return $this->signatures->filter(fn (EntityWorkflowStepSignature $signature) => EntityWorkflowSignatureStateEnum::PENDING === $signature->getState());
|
||||
}
|
||||
|
||||
/**
|
||||
* Function used for validation that check if the accompanying periods of
|
||||
* the person are not collapsing (i.e. have not shared days) or having
|
||||
|
@@ -11,6 +11,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace Chill\PersonBundle\Menu;
|
||||
|
||||
use Chill\MainBundle\Repository\Workflow\EntityWorkflowStepSignatureACLAwareRepository;
|
||||
use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\PersonBundle\Repository\ResidentialAddressRepository;
|
||||
@@ -43,6 +44,7 @@ class PersonMenuBuilder implements LocalMenuBuilderInterface
|
||||
private readonly Security $security,
|
||||
protected TranslatorInterface $translator,
|
||||
private readonly ResidentialAddressRepository $residentialAddressRepo,
|
||||
private readonly EntityWorkflowStepSignatureACLAwareRepository $entityWorkflowStepSignatureRepository,
|
||||
) {
|
||||
$this->showAccompanyingPeriod = $parameterBag->get('chill_person.accompanying_period');
|
||||
}
|
||||
@@ -125,6 +127,21 @@ class PersonMenuBuilder implements LocalMenuBuilderInterface
|
||||
? $nbAccompanyingPeriod : null,
|
||||
]);
|
||||
}
|
||||
|
||||
$nbSignatures = count($this->entityWorkflowStepSignatureRepository->findByPersonAndPendingState($parameters['person']));
|
||||
|
||||
if ($nbSignatures > 0) {
|
||||
$menu->addChild($this->translator->trans('workflow.signature_list.menu'), [
|
||||
'route' => 'chill_person_signature_list',
|
||||
'routeParameters' => [
|
||||
'id' => $parameters['person']->getId(),
|
||||
],
|
||||
])
|
||||
->setExtras([
|
||||
'order' => 110,
|
||||
'counter' => $nbSignatures,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public static function getMenuIds(): array
|
||||
|
@@ -11,12 +11,15 @@ declare(strict_types=1);
|
||||
|
||||
namespace Chill\PersonBundle\Repository\AccompanyingPeriod;
|
||||
|
||||
use Chill\DocStoreBundle\Entity\StoredObject;
|
||||
use Chill\DocStoreBundle\Repository\AssociatedEntityToStoredObjectInterface;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluationDocument;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use Doctrine\ORM\NonUniqueResultException;
|
||||
use Doctrine\Persistence\ObjectRepository;
|
||||
|
||||
class AccompanyingPeriodWorkEvaluationDocumentRepository implements ObjectRepository
|
||||
class AccompanyingPeriodWorkEvaluationDocumentRepository implements ObjectRepository, AssociatedEntityToStoredObjectInterface
|
||||
{
|
||||
private readonly EntityRepository $repository;
|
||||
|
||||
@@ -58,4 +61,18 @@ class AccompanyingPeriodWorkEvaluationDocumentRepository implements ObjectReposi
|
||||
{
|
||||
return AccompanyingPeriodWorkEvaluationDocument::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NonUniqueResultException
|
||||
*/
|
||||
public function findAssociatedEntityToStoredObject(StoredObject $storedObject): ?AccompanyingPeriodWorkEvaluationDocument
|
||||
{
|
||||
$qb = $this->repository->createQueryBuilder('acpwed');
|
||||
$query = $qb
|
||||
->where('acpwed.storedObject = :storedObject')
|
||||
->setParameter('storedObject', $storedObject)
|
||||
->getQuery();
|
||||
|
||||
return $query->getOneOrNullResult();
|
||||
}
|
||||
}
|
||||
|
@@ -22,11 +22,11 @@ use Doctrine\ORM\Query\ResultSetMappingBuilder;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Doctrine\Persistence\ObjectRepository;
|
||||
|
||||
final readonly class AccompanyingPeriodWorkRepository implements ObjectRepository
|
||||
class AccompanyingPeriodWorkRepository implements ObjectRepository
|
||||
{
|
||||
private EntityRepository $repository;
|
||||
private readonly EntityRepository $repository;
|
||||
|
||||
public function __construct(private EntityManagerInterface $em)
|
||||
public function __construct(private readonly EntityManagerInterface $em)
|
||||
{
|
||||
$this->repository = $em->getRepository(AccompanyingPeriodWork::class);
|
||||
}
|
||||
|
@@ -3,8 +3,10 @@
|
||||
*/
|
||||
|
||||
span.badge-user,
|
||||
span.badge-user-group,
|
||||
span.badge-person,
|
||||
span.badge-thirdparty {
|
||||
margin: 0.2rem 0.1rem;
|
||||
display: inline-block;
|
||||
padding: 0 0.5em !important;
|
||||
background-color: $white;
|
||||
@@ -18,6 +20,11 @@ span.badge-thirdparty {
|
||||
}
|
||||
}
|
||||
|
||||
span.badge-user-group {
|
||||
font-weight: 600;
|
||||
border-width: 0px;
|
||||
}
|
||||
|
||||
span.badge-user {
|
||||
border-bottom-width: 1px;
|
||||
&.system {
|
||||
@@ -231,6 +238,10 @@ div[class*='budget-'] {
|
||||
background-color: $chill-ll-gray;
|
||||
color: $chill-blue;
|
||||
}
|
||||
&.bg-user-group {
|
||||
background-color: $chill-l-gray;
|
||||
color: $chill-blue;
|
||||
}
|
||||
&.bg-confidential {
|
||||
background-color: $chill-ll-gray;
|
||||
color: $chill-red;
|
||||
|
@@ -1,4 +1,12 @@
|
||||
import {Address, Center, Civility, DateTime} from "../../../ChillMainBundle/Resources/public/types";
|
||||
import {
|
||||
Address,
|
||||
Center,
|
||||
Civility,
|
||||
DateTime,
|
||||
User,
|
||||
WorkflowAvailable
|
||||
} from "../../../ChillMainBundle/Resources/public/types";
|
||||
import {StoredObject} from "../../../ChillDocStoreBundle/Resources/public/types";
|
||||
|
||||
export interface Person {
|
||||
id: number;
|
||||
@@ -20,3 +28,16 @@ export interface Person {
|
||||
current_household_id: number;
|
||||
current_residential_addresses: Address[];
|
||||
}
|
||||
|
||||
export interface AccompanyingPeriodWorkEvaluationDocument {
|
||||
id: number;
|
||||
type: "accompanying_period_work_evaluation_document"
|
||||
storedObject: StoredObject;
|
||||
title: string;
|
||||
createdAt: DateTime | null;
|
||||
createdBy: User | null;
|
||||
updatedAt: DateTime | null;
|
||||
updatedBy: User | null;
|
||||
workflows_availables: WorkflowAvailable[];
|
||||
workflows: object[];
|
||||
}
|
||||
|
@@ -340,9 +340,8 @@ import ThirdPartyRenderBox from 'ChillThirdPartyAssets/vuejs/_components/Entity/
|
||||
import PickTemplate from 'ChillDocGeneratorAssets/vuejs/_components/PickTemplate.vue';
|
||||
import OnTheFly from 'ChillMainAssets/vuejs/OnTheFly/components/OnTheFly.vue';
|
||||
import ListWorkflowModal from 'ChillMainAssets/vuejs/_components/EntityWorkflow/ListWorkflowModal.vue';
|
||||
import PickWorkflow from 'ChillMainAssets/vuejs/_components/EntityWorkflow/PickWorkflow.vue';
|
||||
import PersonText from 'ChillPersonAssets/vuejs/_components/Entity/PersonText.vue';
|
||||
import {buildLinkCreate} from 'ChillMainAssets/lib/entity-workflow/api.js';
|
||||
import {buildLinkCreate} from 'ChillMainAssets/lib/entity-workflow/api';
|
||||
import { makeFetch } from 'ChillMainAssets/lib/api/apiMethods';
|
||||
|
||||
const i18n = {
|
||||
@@ -406,7 +405,6 @@ export default {
|
||||
PickTemplate,
|
||||
ListWorkflowModal,
|
||||
OnTheFly,
|
||||
PickWorkflow,
|
||||
PersonText,
|
||||
},
|
||||
i18n,
|
||||
|
@@ -54,7 +54,7 @@
|
||||
import FormEvaluation from './FormEvaluation.vue';
|
||||
import Modal from 'ChillMainAssets/vuejs/_components/Modal';
|
||||
import ListWorkflowModal from 'ChillMainAssets/vuejs/_components/EntityWorkflow/ListWorkflowModal.vue';
|
||||
import {buildLinkCreate} from 'ChillMainAssets/lib/entity-workflow/api.js';
|
||||
import {buildLinkCreate} from 'ChillMainAssets/lib/entity-workflow/api';
|
||||
|
||||
const i18n = {
|
||||
messages: {
|
||||
|
@@ -103,7 +103,7 @@
|
||||
<div class="item-row">
|
||||
<div class="item-col">
|
||||
<ul class="record_actions">
|
||||
<li v-if="d.workflows_availables.length > 0">
|
||||
<li v-if="d.workflows_availables.length > 0 || d.workflows.length > 0">
|
||||
<list-workflow-modal
|
||||
:workflows="d.workflows"
|
||||
:allowCreate="true"
|
||||
@@ -140,19 +140,16 @@
|
||||
@on-stored-object-status-change="onStatusDocumentChanged"
|
||||
></document-action-buttons-group>
|
||||
</li>
|
||||
<li>
|
||||
<add-async-upload
|
||||
:buttonTitle="$t('replace')"
|
||||
:options="asyncUploadOptions"
|
||||
:btnClasses="{'btn': true, 'btn-edit': true}"
|
||||
@addDocument="(arg) => replaceDocument(d, arg)"
|
||||
>
|
||||
</add-async-upload>
|
||||
<li v-if="d.storedObject._permissions.canEdit">
|
||||
<drop-file-modal :existing-doc="d.storedObject" :allow-remove="false" @add-document="(arg) => replaceDocument(d, arg.stored_object, arg.stored_object_version)"></drop-file-modal>
|
||||
</li>
|
||||
<li v-if="d.workflows.length === 0">
|
||||
<a class="btn btn-delete" @click="removeDocument(d)">
|
||||
</a>
|
||||
</li>
|
||||
<li v-if="Number.isInteger(d.id)">
|
||||
<button type="button" @click="duplicateDocument(d)" class="btn btn-duplicate" title="Dupliquer"></button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@@ -177,12 +174,7 @@
|
||||
<label class="col-form-label">{{ $t('document_upload') }}</label>
|
||||
<ul class="record_actions document-upload">
|
||||
<li>
|
||||
<add-async-upload
|
||||
:buttonTitle="$t('browse')"
|
||||
:options="asyncUploadOptions"
|
||||
@addDocument="addDocument"
|
||||
>
|
||||
</add-async-upload>
|
||||
<drop-file-modal :allow-remove="false" @add-document="addDocument"></drop-file-modal>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -199,12 +191,11 @@ import ClassicEditor from 'ChillMainAssets/module/ckeditor5/editor_config';
|
||||
import { mapGetters, mapState } from 'vuex';
|
||||
import PickTemplate from 'ChillDocGeneratorAssets/vuejs/_components/PickTemplate.vue';
|
||||
import {buildLink} from 'ChillDocGeneratorAssets/lib/document-generator';
|
||||
import AddAsyncUpload from 'ChillDocStoreAssets/vuejs/_components/AddAsyncUpload.vue';
|
||||
import AddAsyncUploadDownloader from 'ChillDocStoreAssets/vuejs/_components/AddAsyncUploadDownloader.vue';
|
||||
import ListWorkflowModal from 'ChillMainAssets/vuejs/_components/EntityWorkflow/ListWorkflowModal.vue';
|
||||
import {buildLinkCreate} from 'ChillMainAssets/lib/entity-workflow/api.js';
|
||||
import {buildLinkCreate} from 'ChillMainAssets/lib/entity-workflow/api';
|
||||
import {buildLinkCreate as buildLinkCreateNotification} from 'ChillMainAssets/lib/entity-notification/api';
|
||||
import DocumentActionButtonsGroup from "ChillDocStoreAssets/vuejs/DocumentActionButtonsGroup.vue";
|
||||
import DropFileModal from "ChillDocStoreAssets/vuejs/DropFileWidget/DropFileModal.vue";
|
||||
|
||||
const i18n = {
|
||||
messages: {
|
||||
@@ -243,10 +234,9 @@ export default {
|
||||
name: "FormEvaluation",
|
||||
props: ['evaluation', 'docAnchorId'],
|
||||
components: {
|
||||
DropFileModal,
|
||||
ckeditor: CKEditor.component,
|
||||
PickTemplate,
|
||||
AddAsyncUpload,
|
||||
AddAsyncUploadDownloader,
|
||||
ListWorkflowModal,
|
||||
DocumentActionButtonsGroup,
|
||||
},
|
||||
@@ -380,27 +370,38 @@ export default {
|
||||
const title = event.target.value;
|
||||
this.$store.commit('updateDocumentTitle', {id: id, key: key, evaluationKey: this.evaluation.key, title: title});
|
||||
},
|
||||
addDocument(storedObject) {
|
||||
addDocument({stored_object, stored_object_version}) {
|
||||
let document = {
|
||||
type: 'accompanying_period_work_evaluation_document',
|
||||
storedObject: storedObject,
|
||||
storedObject: stored_object,
|
||||
title: 'Nouveau document',
|
||||
};
|
||||
this.$store.commit('addDocument', {key: this.evaluation.key, document: document});
|
||||
this.$store.commit('addDocument', {key: this.evaluation.key, document, stored_object_version});
|
||||
},
|
||||
replaceDocument(oldDocument, storedObject) {
|
||||
/**
|
||||
* Replaces a document in the store with a new document.
|
||||
*
|
||||
* @param {Object} oldDocument - The document to be replaced.
|
||||
* @param {StoredObject} storedObject - The stored object of the new document.
|
||||
* @param {StoredObjectVersion} storedObjectVersion - The new version of the document
|
||||
* @return {void}
|
||||
*/
|
||||
replaceDocument(oldDocument, storedObject, storedObjectVersion) {
|
||||
let document = {
|
||||
type: 'accompanying_period_work_evaluation_document',
|
||||
storedObject: storedObject,
|
||||
title: oldDocument.title
|
||||
};
|
||||
this.$store.commit('replaceDocument', {key: this.evaluation.key, document: document, oldDocument: oldDocument});
|
||||
this.$store.commit('replaceDocument', {key: this.evaluation.key, document, oldDocument: oldDocument, stored_object_version: storedObjectVersion});
|
||||
},
|
||||
removeDocument(document) {
|
||||
if (window.confirm("Êtes-vous sûr·e de vouloir supprimer le document qui a pour titre \"" + document.title +"\" ?")) {
|
||||
this.$store.commit('removeDocument', {key: this.evaluation.key, document: document});
|
||||
}
|
||||
},
|
||||
duplicateDocument(document) {
|
||||
this.$store.dispatch('duplicateDocument', {evaluation_key: this.evaluation.key, document: document});
|
||||
},
|
||||
onStatusDocumentChanged(newStatus) {
|
||||
console.log('onStatusDocumentChanged', newStatus);
|
||||
this.$store.commit('statusDocumentChanged', {key: this.evaluation.key, newStatus: newStatus});
|
||||
|
@@ -4,6 +4,7 @@ import { findSocialActionsBySocialIssue } from 'ChillPersonAssets/vuejs/_api/Soc
|
||||
import { create } from 'ChillPersonAssets/vuejs/_api/AccompanyingCourseWork.js';
|
||||
import { fetchResults, makeFetch } from 'ChillMainAssets/lib/api/apiMethods.ts';
|
||||
import { fetchTemplates } from 'ChillDocGeneratorAssets/api/pickTemplate.js';
|
||||
import { duplicate } from '../_api/accompanyingCourseWorkEvaluationDocument';
|
||||
|
||||
const debug = process.env.NODE_ENV !== 'production';
|
||||
const evalFQDN = encodeURIComponent("Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluation");
|
||||
@@ -219,7 +220,11 @@ const store = createStore({
|
||||
found.results = found.results.filter(r => r.id !== result.id);
|
||||
},
|
||||
addDocument(state, payload) {
|
||||
// associate version to stored object
|
||||
payload.document.storedObject.currentVersion = payload.stored_object_version;
|
||||
|
||||
let evaluation = state.evaluationsPicked.find(e => e.key === payload.key);
|
||||
|
||||
evaluation.documents.push(Object.assign(
|
||||
payload.document, {
|
||||
key: evaluation.documents.length + 1,
|
||||
@@ -234,6 +239,21 @@ const store = createStore({
|
||||
}
|
||||
evaluation.documents = evaluation.documents.filter(d => d.key !== document.key);
|
||||
},
|
||||
addDuplicatedDocument(state, {document, evaluation_key}) {
|
||||
console.log('add duplicated document', document);
|
||||
console.log('add duplicated dcuemnt - evaluation key', evaluation_key);
|
||||
|
||||
let evaluation = state.evaluationsPicked.find(e => e.key === evaluation_key);
|
||||
document.key = evaluation.documents.length + 1;
|
||||
evaluation.documents.splice(0, 0, document);
|
||||
},
|
||||
/**
|
||||
* Replaces a document in the state with a new document.
|
||||
*
|
||||
* @param {object} state - The current state of the application.
|
||||
* @param {{key: number, oldDocument: {key: number}, stored_object_version: StoredObjectVersion}} payload - The object containing the information about the document to be replaced.
|
||||
* @return {void} - returns nothing.
|
||||
*/
|
||||
replaceDocument(state, payload) {
|
||||
let evaluation = state.evaluationsPicked.find(e => e.key === payload.key);
|
||||
if (evaluation === undefined) {
|
||||
@@ -244,9 +264,10 @@ const store = createStore({
|
||||
|
||||
if (typeof doc === 'undefined') {
|
||||
console.error('doc not found');
|
||||
return;
|
||||
}
|
||||
|
||||
doc.storedObject = payload.document.storedObject;
|
||||
doc.storedObject.currentVersion = payload.stored_object_version;
|
||||
return;
|
||||
let newDocument = Object.assign(
|
||||
payload.document, {
|
||||
@@ -494,6 +515,10 @@ const store = createStore({
|
||||
addDocument({commit}, payload) {
|
||||
commit('addDocument', payload);
|
||||
},
|
||||
async duplicateDocument({commit}, {document, evaluation_key}) {
|
||||
const newDoc = await duplicate(document.id);
|
||||
commit('addDuplicatedDocument', {document: newDoc, evaluation_key});
|
||||
},
|
||||
removeDocument({commit}, payload) {
|
||||
commit('removeDocument', payload);
|
||||
},
|
||||
|
@@ -0,0 +1,6 @@
|
||||
import {AccompanyingPeriodWorkEvaluationDocument} from "../../types";
|
||||
import {makeFetch} from "../../../../../ChillMainBundle/Resources/public/lib/api/apiMethods";
|
||||
|
||||
export const duplicate = async (id: number): Promise<AccompanyingPeriodWorkEvaluationDocument> => {
|
||||
return makeFetch<null, AccompanyingPeriodWorkEvaluationDocument>("POST", `/api/1.0/person/accompanying-course-work-evaluation-document/${id}/duplicate`);
|
||||
}
|
@@ -27,6 +27,11 @@
|
||||
v-bind:item="item">
|
||||
</suggestion-user>
|
||||
|
||||
<suggestion-user-group
|
||||
v-if="item.result.type === 'user_group'"
|
||||
v-bind:item="item">
|
||||
></suggestion-user-group>
|
||||
|
||||
<suggestion-household
|
||||
v-if="item.result.type === 'household'"
|
||||
v-bind:item="item">
|
||||
@@ -41,6 +46,7 @@ import SuggestionPerson from './TypePerson';
|
||||
import SuggestionThirdParty from './TypeThirdParty';
|
||||
import SuggestionUser from './TypeUser';
|
||||
import SuggestionHousehold from './TypeHousehold';
|
||||
import SuggestionUserGroup from './TypeUserGroup';
|
||||
|
||||
export default {
|
||||
name: 'PersonSuggestion',
|
||||
@@ -49,6 +55,7 @@ export default {
|
||||
SuggestionThirdParty,
|
||||
SuggestionUser,
|
||||
SuggestionHousehold,
|
||||
SuggestionUserGroup,
|
||||
},
|
||||
props: [
|
||||
'item',
|
||||
|
@@ -0,0 +1,30 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
import {ResultItem, UserGroup} from "../../../../../../ChillMainBundle/Resources/public/types";
|
||||
import BadgeEntity from "ChillMainAssets/vuejs/_components/BadgeEntity.vue";
|
||||
import UserRenderBoxBadge from "ChillMainAssets/vuejs/_components/Entity/UserRenderBoxBadge.vue";
|
||||
import UserGroupRenderBox from "ChillMainAssets/vuejs/_components/Entity/UserGroupRenderBox.vue";
|
||||
|
||||
interface TypeUserGroupProps {
|
||||
item: ResultItem<UserGroup>;
|
||||
}
|
||||
|
||||
const props = defineProps<TypeUserGroupProps>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="container user-group-container">
|
||||
<div class="user-group-identification">
|
||||
<user-group-render-box :user-group="props.item.result"></user-group-render-box>
|
||||
</div>
|
||||
</div>
|
||||
<div class="right_actions">
|
||||
<span class="badge rounded-pill bg-user-group">
|
||||
Groupe d'utilisateur
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
</style>
|
@@ -211,7 +211,7 @@
|
||||
<h3 class="chill-beige">Public</h3>
|
||||
{% if w.note is not empty %}
|
||||
<blockquote class="chill-user-quote">
|
||||
{{ w.note|chill_entity_render_box({'metadata': true }) }}
|
||||
{{ w.note }}
|
||||
</blockquote>
|
||||
{% else %}
|
||||
<span class="chill-no-data-statement">{{ 'No comment associated'|trans }}</span>
|
||||
|
@@ -237,8 +237,7 @@
|
||||
{% if displayContent is defined and displayContent == 'long' %}
|
||||
|
||||
{% if e.comment is not empty %}
|
||||
<blockquote
|
||||
class="chill-user-quote">{{ e.comment|chill_entity_render_box }}</blockquote>
|
||||
<blockquote class="chill-user-quote">{{ e.comment }}</blockquote>
|
||||
{% endif %}
|
||||
|
||||
{% import "@ChillDocStore/Macro/macro.html.twig" as m %}
|
||||
|
@@ -60,9 +60,11 @@
|
||||
{{ document.storedObject|chill_document_button_group(document.title, is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_UPDATE', document.accompanyingPeriodWorkEvaluation.accompanyingPeriodWork)) }}
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_SEE', w)%}
|
||||
{% if is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_UPDATE', w) %}
|
||||
<li>
|
||||
<a href="{{ chill_path_add_return_path('chill_person_accompanying_period_work_show', {'id': w.id, 'docId': document.id}) }}" class="btn btn-show"></a>
|
||||
<form method="post" action="{{ chill_path_add_return_path('chill_person_accompanying_period_work_evaluation_document_duplicate', {id: document.id}) }}">
|
||||
<button type="submit" class="btn btn-duplicate" title="{{ 'crud.view.link_duplicate'|trans }}"></button>
|
||||
</form>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_UPDATE', w) %}
|
||||
@@ -70,6 +72,11 @@
|
||||
<a href="{{ chill_path_add_return_path('chill_person_accompanying_period_work_edit', {'id': w.id, 'docId': document.id}) }}" class="btn btn-edit"></a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_SEE', w)%}
|
||||
<li>
|
||||
<a href="{{ chill_path_add_return_path('chill_person_accompanying_period_work_show', {'id': w.id, 'docId': document.id}) }}" class="btn btn-show"></a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
@@ -328,8 +328,33 @@
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% if person.signaturesPending|length > 0 %}
|
||||
<div class="item-row separator">
|
||||
<div class="wrap-list periods-list">
|
||||
<div class="wl-row">
|
||||
<div class="wl-col title">
|
||||
<h3>{{ 'workflow.pending_signatures'|trans({nb_signatures: person.signaturesPending|length}) }}</h3>
|
||||
</div>
|
||||
<div class="wl-col list">
|
||||
{% for signature in person.signaturesPending %}
|
||||
{% set entityWorkflow = signature.step.entityWorkflow %}
|
||||
{{ entityWorkflow|chill_entity_render_string }}
|
||||
<ul class="record_actions small slim">
|
||||
<li>
|
||||
<a href="{{ chill_path_force_return_path(path('chill_main_workflow_show', {id: entityWorkflow.id}), 'chill_main_workflow_signature_metadata', {signature_id: signature.id}) }}" class="btn btn-misc">
|
||||
<i class="fa fa-pencil"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ chill_path_add_return_path('chill_main_workflow_show', {id: entityWorkflow.id}) }}" class="btn btn-show"></a>
|
||||
</li>
|
||||
</ul>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
@@ -0,0 +1,44 @@
|
||||
{% extends "@ChillPerson/Person/layout.html.twig" %}
|
||||
{% set activeRouteKey = 'chill_person_signature_list' %}
|
||||
|
||||
{% block title %}{{ 'Person signatures'|trans ~ ' ' ~ person|chill_entity_render_string }}{% endblock %}
|
||||
|
||||
{% block dam %}
|
||||
<a class="btn btn-misc" href="{{ chill_path_add_return_path('chill_main_workflow_signature_metadata', { 'signature_id': s.signature.id}) }}"><i class="fa fa-pencil-square-o"></i> {{ 'workflow.signature_zone.button_sign'|trans }}</a>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<h1>{{ 'workflow.signature_list.title'|trans }}</h1>
|
||||
|
||||
<div class="container">
|
||||
<div class="row align-items-center">
|
||||
{% for s in signatures %}
|
||||
{% set signature = s.signature %}
|
||||
{% set workflow = s.workflow %}
|
||||
{% set document = s.document %}
|
||||
|
||||
<div class="item-bloc">
|
||||
<div class="item-row">
|
||||
<div class="item-col flex-grow-1">
|
||||
{% include workflow.handler_template with workflow.handler_template_data|merge({'display_action': true, 'display_action_more': [block('dam')|raw] }) %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block css %}
|
||||
{{ parent() }}
|
||||
{{ encore_entry_link_tags('mod_async_upload') }}
|
||||
{{ encore_entry_script_tags('mod_document_action_buttons_group') }}
|
||||
{% endblock css %}
|
||||
|
||||
{% block js %}
|
||||
{{ parent() }}
|
||||
{{ encore_entry_script_tags('mod_async_upload') }}
|
||||
{{ encore_entry_link_tags('mod_document_action_buttons_group') }}
|
||||
{% endblock js %}
|
@@ -13,6 +13,11 @@
|
||||
</div>
|
||||
{% if display_action is defined and display_action == true %}
|
||||
<ul class="record_actions">
|
||||
{% for dam in display_action_more|default([]) %}
|
||||
<li>
|
||||
{{ dam|raw }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
<li>
|
||||
<a class="btn btn-update"
|
||||
href="{{ chill_path_add_return_path('chill_person_accompanying_period_work_edit', { 'id': work.id }) }}">
|
||||
|
@@ -94,6 +94,11 @@
|
||||
{% if display_action is defined and display_action == true %}
|
||||
{# TODO add acl #}
|
||||
<ul class="record_actions">
|
||||
{% for dam in display_action_more|default([]) %}
|
||||
<li>
|
||||
{{ dam|raw }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
<li>
|
||||
<a class="btn btn-show" href="{{ path('chill_person_accompanying_period_work_edit', {'id': evaluation.accompanyingPeriodWork.id}) }}">
|
||||
{{ 'Show'|trans }}
|
||||
|
@@ -121,6 +121,11 @@
|
||||
|
||||
{% if display_action is defined and display_action == true %}
|
||||
<ul class="record_actions">
|
||||
{% for dam in display_action_more|default([]) %}
|
||||
<li>
|
||||
{{ dam|raw }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
<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, 'doc_id': doc.id}) }}">
|
||||
|
@@ -24,13 +24,14 @@ use Symfony\Component\Security\Core\Authorization\Voter\Voter;
|
||||
class AccompanyingPeriodWorkEvaluationDocumentVoter extends Voter
|
||||
{
|
||||
final public const SEE = 'CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_EVALUATION_DOCUMENT_SHOW';
|
||||
final public const SEE_AND_EDIT = 'CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_EVALUATION_DOCUMENT_EDIT';
|
||||
|
||||
public function __construct(private readonly AccessDecisionManagerInterface $accessDecisionManager) {}
|
||||
|
||||
protected function supports($attribute, $subject)
|
||||
public function supports($attribute, $subject): bool
|
||||
{
|
||||
return $subject instanceof AccompanyingPeriodWorkEvaluationDocument
|
||||
&& self::SEE === $attribute;
|
||||
&& (self::SEE === $attribute || self::SEE_AND_EDIT === $attribute);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -39,7 +40,7 @@ class AccompanyingPeriodWorkEvaluationDocumentVoter extends Voter
|
||||
*
|
||||
* @return bool|void
|
||||
*/
|
||||
protected function voteOnAttribute($attribute, $subject, TokenInterface $token): bool
|
||||
public function voteOnAttribute($attribute, $subject, TokenInterface $token): bool
|
||||
{
|
||||
return match ($attribute) {
|
||||
self::SEE => $this->accessDecisionManager->decide(
|
||||
@@ -47,6 +48,11 @@ class AccompanyingPeriodWorkEvaluationDocumentVoter extends Voter
|
||||
[AccompanyingPeriodWorkEvaluationVoter::SEE],
|
||||
$subject->getAccompanyingPeriodWorkEvaluation()
|
||||
),
|
||||
self::SEE_AND_EDIT => $this->accessDecisionManager->decide(
|
||||
$token,
|
||||
[AccompanyingPeriodWorkEvaluationVoter::SEE_AND_EDIT],
|
||||
$subject->getAccompanyingPeriodWorkEvaluation()
|
||||
),
|
||||
default => throw new \UnexpectedValueException("The attribute {$attribute} is not supported"),
|
||||
};
|
||||
}
|
||||
|
@@ -21,11 +21,14 @@ class AccompanyingPeriodWorkEvaluationVoter extends Voter implements ChillVoterI
|
||||
{
|
||||
final public const ALL = [
|
||||
self::SEE,
|
||||
self::SEE_AND_EDIT,
|
||||
self::STATS,
|
||||
];
|
||||
|
||||
final public const SEE = 'CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_EVALUATION_SHOW';
|
||||
|
||||
final public const SEE_AND_EDIT = 'CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_EVALUATION_EDIT';
|
||||
|
||||
final public const STATS = 'CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_EVALUATION_STATS';
|
||||
|
||||
public function __construct(private readonly Security $security) {}
|
||||
@@ -45,6 +48,7 @@ class AccompanyingPeriodWorkEvaluationVoter extends Voter implements ChillVoterI
|
||||
return match ($attribute) {
|
||||
self::STATS => $this->security->isGranted(AccompanyingPeriodVoter::STATS, $subject),
|
||||
self::SEE => $this->security->isGranted(AccompanyingPeriodWorkVoter::SEE, $subject->getAccompanyingPeriodWork()),
|
||||
self::SEE_AND_EDIT => $this->security->isGranted(AccompanyingPeriodWorkVoter::UPDATE, $subject->getAccompanyingPeriodWork()),
|
||||
default => throw new \UnexpectedValueException("attribute {$attribute} is not supported"),
|
||||
};
|
||||
}
|
||||
|
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\PersonBundle\Security\Authorization\StoredObjectVoter;
|
||||
|
||||
use Chill\DocStoreBundle\Repository\AssociatedEntityToStoredObjectInterface;
|
||||
use Chill\DocStoreBundle\Security\Authorization\StoredObjectRoleEnum;
|
||||
use Chill\DocStoreBundle\Security\Authorization\StoredObjectVoter\AbstractStoredObjectVoter;
|
||||
use Chill\DocStoreBundle\Service\WorkflowStoredObjectPermissionHelper;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluationDocument;
|
||||
use Chill\PersonBundle\Repository\AccompanyingPeriod\AccompanyingPeriodWorkEvaluationDocumentRepository;
|
||||
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodWorkEvaluationDocumentVoter;
|
||||
use Symfony\Component\Security\Core\Security;
|
||||
|
||||
class AccompanyingPeriodWorkEvaluationDocumentStoredObjectVoter extends AbstractStoredObjectVoter
|
||||
{
|
||||
public function __construct(
|
||||
private readonly AccompanyingPeriodWorkEvaluationDocumentRepository $repository,
|
||||
Security $security,
|
||||
WorkflowStoredObjectPermissionHelper $workflowDocumentService,
|
||||
) {
|
||||
parent::__construct($security, $workflowDocumentService);
|
||||
}
|
||||
|
||||
protected function getRepository(): AssociatedEntityToStoredObjectInterface
|
||||
{
|
||||
return $this->repository;
|
||||
}
|
||||
|
||||
protected function getClass(): string
|
||||
{
|
||||
return AccompanyingPeriodWorkEvaluationDocument::class;
|
||||
}
|
||||
|
||||
protected function attributeToRole(StoredObjectRoleEnum $attribute): string
|
||||
{
|
||||
return match ($attribute) {
|
||||
StoredObjectRoleEnum::SEE => AccompanyingPeriodWorkEvaluationDocumentVoter::SEE,
|
||||
StoredObjectRoleEnum::EDIT => AccompanyingPeriodWorkEvaluationDocumentVoter::SEE_AND_EDIT,
|
||||
};
|
||||
}
|
||||
|
||||
protected function canBeAssociatedWithWorkflow(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\PersonBundle\Security\CenterResolver;
|
||||
|
||||
use Chill\MainBundle\Entity\Center;
|
||||
use Chill\MainBundle\Security\Resolver\CenterResolverInterface;
|
||||
use Chill\MainBundle\Security\Resolver\ManagerAwareCenterResolverInterface;
|
||||
use Chill\MainBundle\Security\Resolver\ManagerAwareCenterResolverTrait;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluationDocument;
|
||||
|
||||
final class AccompanyingPeriodWorkEvaluationDocumentCenterResolver implements CenterResolverInterface, ManagerAwareCenterResolverInterface
|
||||
{
|
||||
use ManagerAwareCenterResolverTrait;
|
||||
|
||||
public static function getDefaultPriority(): int
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function resolveCenter($entity, ?array $options = []): Center|array
|
||||
{
|
||||
/* @var $entity AccompanyingPeriodWorkEvaluationDocument */
|
||||
return $this->centerResolverManager->resolveCenters($entity->getAccompanyingPeriodWorkEvaluation()
|
||||
->getAccompanyingPeriodWork()->getAccompanyingPeriod(), $options);
|
||||
}
|
||||
|
||||
public function supports($entity, ?array $options = []): bool
|
||||
{
|
||||
return $entity instanceof AccompanyingPeriodWorkEvaluationDocument;
|
||||
}
|
||||
}
|
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\PersonBundle\Service\AccompanyingPeriod;
|
||||
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriodParticipation;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
|
||||
/**
|
||||
* Provide persons associated with an accompanying period.
|
||||
*/
|
||||
class ProvidePersonsAssociated
|
||||
{
|
||||
/**
|
||||
* @return list<Person>
|
||||
*/
|
||||
public function getPersonsAssociated(AccompanyingPeriod $period): array
|
||||
{
|
||||
return array_values(
|
||||
$period->getCurrentParticipations()
|
||||
->map(fn (AccompanyingPeriodParticipation $participation) => $participation->getPerson())
|
||||
->toArray()
|
||||
);
|
||||
}
|
||||
}
|
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\PersonBundle\Service\AccompanyingPeriod;
|
||||
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\Resource;
|
||||
use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
||||
|
||||
/**
|
||||
* Provide third parties participating to an AccompanyingPeriod.
|
||||
*/
|
||||
class ProvideThirdPartiesAssociated
|
||||
{
|
||||
/**
|
||||
* @return list<ThirdParty>
|
||||
*/
|
||||
public function getThirdPartiesAssociated(AccompanyingPeriod $period): array
|
||||
{
|
||||
$thirdParties = [];
|
||||
|
||||
foreach (
|
||||
$period
|
||||
->getResources()->filter(fn (Resource $resource) => null !== $resource->getThirdParty())
|
||||
->map(fn (Resource $resource) => $resource->getThirdParty()) as $thirdParty) {
|
||||
$thirdParties[] = $thirdParty;
|
||||
}
|
||||
|
||||
if (null !== $requestor = $period->getRequestorThirdParty()) {
|
||||
$thirdParties[] = $requestor;
|
||||
}
|
||||
|
||||
return array_values(
|
||||
// filter objects to remove duplicates
|
||||
array_filter(
|
||||
$thirdParties,
|
||||
fn ($o, $k) => array_search($o, $thirdParties, true) === $k,
|
||||
ARRAY_FILTER_USE_BOTH
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\PersonBundle\Service\AccompanyingPeriodWork;
|
||||
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\PersonBundle\Service\AccompanyingPeriod\ProvidePersonsAssociated as ProvidePersonsAssociatedAccompanyingPeriod;
|
||||
|
||||
/**
|
||||
* Provide persons associated with an accompanying period work.
|
||||
*/
|
||||
class ProvidePersonsAssociated
|
||||
{
|
||||
public function __construct(private readonly ProvidePersonsAssociatedAccompanyingPeriod $providePersonsAssociated) {}
|
||||
|
||||
/**
|
||||
* @return list<Person>
|
||||
*/
|
||||
public function getPersonsAssociated(AccompanyingPeriod\AccompanyingPeriodWork $work): array
|
||||
{
|
||||
return $this->providePersonsAssociated->getPersonsAssociated($work->getAccompanyingPeriod());
|
||||
}
|
||||
}
|
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\PersonBundle\Service\AccompanyingPeriodWork;
|
||||
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork;
|
||||
use Chill\PersonBundle\Service\AccompanyingPeriod\ProvideThirdPartiesAssociated as ProvideThirdPartiesAssociatedAccompanyingPeriod;
|
||||
use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
||||
|
||||
/**
|
||||
* Provide third parties associated with an accompanying period work.
|
||||
*/
|
||||
class ProvideThirdPartiesAssociated
|
||||
{
|
||||
public function __construct(private readonly ProvideThirdPartiesAssociatedAccompanyingPeriod $thirdPartiesAssociated) {}
|
||||
|
||||
/**
|
||||
* @return list<ThirdParty>
|
||||
*/
|
||||
public function getThirdPartiesAssociated(AccompanyingPeriodWork $accompanyingPeriodWork): array
|
||||
{
|
||||
$thirdParties = $this->thirdPartiesAssociated->getThirdPartiesAssociated($accompanyingPeriodWork->getAccompanyingPeriod());
|
||||
|
||||
if (null !== $tp = $accompanyingPeriodWork->getHandlingThierParty()) {
|
||||
$thirdParties[] = $tp;
|
||||
}
|
||||
|
||||
foreach ($accompanyingPeriodWork->getThirdParties() as $thirdParty) {
|
||||
$thirdParties[] = $thirdParty;
|
||||
}
|
||||
|
||||
return array_values(
|
||||
// filter objects to remove duplicates
|
||||
array_filter(
|
||||
$thirdParties,
|
||||
fn ($o, $k) => array_search($o, $thirdParties, true) === $k,
|
||||
ARRAY_FILTER_USE_BOTH
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\PersonBundle\Service\AccompanyingPeriodWorkEvaluationDocument;
|
||||
|
||||
use Chill\DocStoreBundle\Service\StoredObjectDuplicate;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluationDocument;
|
||||
use Symfony\Component\Clock\ClockInterface;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
class AccompanyingPeriodWorkEvaluationDocumentDuplicator
|
||||
{
|
||||
public function __construct(
|
||||
private readonly StoredObjectDuplicate $storedObjectDuplicate,
|
||||
private readonly TranslatorInterface $translator,
|
||||
private readonly ClockInterface $clock,
|
||||
) {}
|
||||
|
||||
public function duplicate(AccompanyingPeriodWorkEvaluationDocument $document): AccompanyingPeriodWorkEvaluationDocument
|
||||
{
|
||||
$newDocument = new AccompanyingPeriodWorkEvaluationDocument();
|
||||
$newDocument
|
||||
->setTitle($document->getTitle().' ('.$this->translator->trans('accompanying_course_evaluation_document.duplicated_at', ['at' => $this->clock->now()]).')')
|
||||
->setStoredObject($this->storedObjectDuplicate->duplicate($document->getStoredObject()))
|
||||
;
|
||||
|
||||
$document->getAccompanyingPeriodWorkEvaluation()->addDocument($newDocument);
|
||||
|
||||
return $newDocument;
|
||||
}
|
||||
}
|
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\PersonBundle\Tests\Controller;
|
||||
|
||||
use Chill\MainBundle\Controller\WorkflowSignatureCancelController;
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Chill\MainBundle\Entity\Workflow\EntityWorkflow;
|
||||
use Chill\MainBundle\Routing\ChillUrlGeneratorInterface;
|
||||
use Chill\MainBundle\Security\Authorization\EntityWorkflowStepSignatureVoter;
|
||||
use Chill\MainBundle\Workflow\SignatureStepStateChanger;
|
||||
use Chill\MainBundle\Workflow\WorkflowTransitionContextDTO;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
|
||||
use Symfony\Component\Form\FormFactoryInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
use Symfony\Component\Routing\RequestContext;
|
||||
use Symfony\Component\Security\Core\Security;
|
||||
use Twig\Environment;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @coversNothing
|
||||
*/
|
||||
class WorkflowSignatureCancelControllerStepTest extends WebTestCase
|
||||
{
|
||||
private FormFactoryInterface $formFactory;
|
||||
private SignatureStepStateChanger $signatureStepStateChanger;
|
||||
private ChillUrlGeneratorInterface $chillUrlGenerator;
|
||||
private RequestStack $requestStack;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
self::bootKernel();
|
||||
|
||||
$this->formFactory = self::getContainer()->get('form.factory');
|
||||
$this->signatureStepStateChanger = self::getContainer()->get(SignatureStepStateChanger::class);
|
||||
$this->chillUrlGenerator = self::getContainer()->get(ChillUrlGeneratorInterface::class);
|
||||
|
||||
$requestContext = self::getContainer()->get(RequestContext::class);
|
||||
$requestContext->setParameter('_locale', 'fr');
|
||||
|
||||
$this->requestStack = self::getContainer()->get(RequestStack::class);
|
||||
|
||||
}
|
||||
|
||||
public function testCancelSignatureGet(): void
|
||||
{
|
||||
$entityWorkflow = new EntityWorkflow();
|
||||
$dto = new WorkflowTransitionContextDTO($entityWorkflow);
|
||||
$dto->futureUserSignature = new User();
|
||||
$entityWorkflow->setStep('signature', $dto, 'to_signature', new \DateTimeImmutable(), new User());
|
||||
$signature = $entityWorkflow->getCurrentStep()->getSignatures()->first();
|
||||
|
||||
$security = $this->createMock(Security::class);
|
||||
$security->expects($this->once())->method('isGranted')
|
||||
->with(EntityWorkflowStepSignatureVoter::CANCEL, $signature)->willReturn(true);
|
||||
|
||||
$entityManager = $this->createMock(EntityManager::class);
|
||||
|
||||
$twig = $this->createMock(Environment::class);
|
||||
$twig->expects($this->once())->method('render')->withAnyParameters()
|
||||
->willReturn('template');
|
||||
|
||||
$controller = new WorkflowSignatureCancelController($entityManager, $security, $this->formFactory, $twig, $this->signatureStepStateChanger, $this->chillUrlGenerator);
|
||||
|
||||
$request = new Request();
|
||||
$request->setMethod('GET');
|
||||
|
||||
$this->requestStack->push($request);
|
||||
|
||||
$response = $controller->cancelSignature($signature, $request);
|
||||
|
||||
self::assertEquals(200, $response->getStatusCode());
|
||||
}
|
||||
}
|
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\PersonBundle\Tests\Service\AccompanyingPeriod;
|
||||
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\PersonBundle\Service\AccompanyingPeriod\ProvideThirdPartiesAssociated;
|
||||
use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @coversNothing
|
||||
*/
|
||||
class ProvideThirdPartiesAssociatedTest extends TestCase
|
||||
{
|
||||
public function testGetThirdPartiesAssociated()
|
||||
{
|
||||
$period = new AccompanyingPeriod();
|
||||
$period->setRequestor($tp1 = new ThirdParty());
|
||||
$period->addResource((new AccompanyingPeriod\Resource())->setResource($tp1));
|
||||
$period->addResource((new AccompanyingPeriod\Resource())->setResource($tp2 = new ThirdParty()));
|
||||
$period->addResource((new AccompanyingPeriod\Resource())->setResource($p1 = new Person()));
|
||||
|
||||
$provider = new ProvideThirdPartiesAssociated();
|
||||
|
||||
$thirdParties = $provider->getThirdPartiesAssociated($period);
|
||||
|
||||
self::assertCount(2, $thirdParties);
|
||||
self::assertContains($tp1, $thirdParties);
|
||||
self::assertContains($tp2, $thirdParties);
|
||||
self::assertNotContains($p1, $thirdParties);
|
||||
self::assertNotContains(null, $thirdParties);
|
||||
}
|
||||
}
|
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\PersonBundle\Tests\Service\AccompanyingPeriodWork;
|
||||
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\PersonBundle\Service\AccompanyingPeriodWork\ProvideThirdPartiesAssociated;
|
||||
use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @coversNothing
|
||||
*/
|
||||
class ProvideThirdPartiesAssociatedTest extends TestCase
|
||||
{
|
||||
public function testGetThirdPartiesAssociated()
|
||||
{
|
||||
$period = new AccompanyingPeriod();
|
||||
$period->setRequestor($tp1 = new ThirdParty());
|
||||
$period->addResource((new AccompanyingPeriod\Resource())->setResource($tp1));
|
||||
$period->addResource((new AccompanyingPeriod\Resource())->setResource($tp2 = new ThirdParty()));
|
||||
$period->addResource((new AccompanyingPeriod\Resource())->setResource($p1 = new Person()));
|
||||
$period->addWork($work = new AccompanyingPeriod\AccompanyingPeriodWork());
|
||||
$work->addThirdParty($tp3 = new ThirdParty());
|
||||
$work->addThirdParty($tp1);
|
||||
$work->setHandlingThierParty($tp4 = new ThirdParty());
|
||||
|
||||
$providerAccPeriod = new \Chill\PersonBundle\Service\AccompanyingPeriod\ProvideThirdPartiesAssociated();
|
||||
$provider = new ProvideThirdPartiesAssociated($providerAccPeriod);
|
||||
|
||||
|
||||
$thirdParties = $provider->getThirdPartiesAssociated($work);
|
||||
|
||||
self::assertContains($tp1, $thirdParties);
|
||||
self::assertContains($tp2, $thirdParties);
|
||||
self::assertContains($tp3, $thirdParties);
|
||||
self::assertContains($tp4, $thirdParties);
|
||||
self::assertNotContains($p1, $thirdParties);
|
||||
self::assertCount(4, $thirdParties);
|
||||
}
|
||||
}
|
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\PersonBundle\Tests\Service\AccompanyingPeriodWorkEvaluationDocument;
|
||||
|
||||
use Chill\DocStoreBundle\Entity\StoredObject;
|
||||
use Chill\DocStoreBundle\Service\StoredObjectDuplicate;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluation;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluationDocument;
|
||||
use Chill\PersonBundle\Service\AccompanyingPeriodWorkEvaluationDocument\AccompanyingPeriodWorkEvaluationDocumentDuplicator;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Clock\MockClock;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @coversNothing
|
||||
*/
|
||||
class AccompanyingPeriodWorkEvaluationDocumentDuplicatorTest extends TestCase
|
||||
{
|
||||
public function testDuplicate()
|
||||
{
|
||||
$storedObject = new StoredObject();
|
||||
$evaluation = new AccompanyingPeriodWorkEvaluation();
|
||||
$document = new AccompanyingPeriodWorkEvaluationDocument();
|
||||
$document
|
||||
->setStoredObject($storedObject)
|
||||
->setTitle('test title')
|
||||
->setAccompanyingPeriodWorkEvaluation($evaluation);
|
||||
|
||||
$storedObjectDuplicator = $this->createMock(StoredObjectDuplicate::class);
|
||||
$storedObjectDuplicator->expects($this->once())->method('duplicate')->with($storedObject)->willReturn($newStoredObject = new StoredObject());
|
||||
|
||||
$translator = $this->createMock(TranslatorInterface::class);
|
||||
$translator->method('trans')->willReturn('test translated');
|
||||
|
||||
$clock = new MockClock();
|
||||
|
||||
$duplicator = new AccompanyingPeriodWorkEvaluationDocumentDuplicator($storedObjectDuplicator, $translator, $clock);
|
||||
|
||||
$actual = $duplicator->duplicate($document);
|
||||
|
||||
self::assertNotSame($document, $actual);
|
||||
self::assertStringStartsWith('test title', $actual->getTitle());
|
||||
self::assertSame($newStoredObject, $actual->getStoredObject());
|
||||
self::assertSame($evaluation, $actual->getAccompanyingPeriodWorkEvaluation());
|
||||
}
|
||||
}
|
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\PersonBundle\Tests\Workflow;
|
||||
|
||||
use Chill\DocStoreBundle\Workflow\WorkflowWithPublicViewDocumentHelper;
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Chill\MainBundle\Entity\Workflow\EntityWorkflow;
|
||||
use Chill\MainBundle\Repository\Workflow\EntityWorkflowRepository;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluationDocument;
|
||||
use Chill\PersonBundle\Repository\AccompanyingPeriod\AccompanyingPeriodWorkEvaluationDocumentRepository;
|
||||
use Chill\PersonBundle\Service\AccompanyingPeriodWork\ProvidePersonsAssociated;
|
||||
use Chill\PersonBundle\Service\AccompanyingPeriodWork\ProvideThirdPartiesAssociated;
|
||||
use Chill\PersonBundle\Workflow\AccompanyingPeriodWorkEvaluationDocumentWorkflowHandler;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Prophecy\PhpUnit\ProphecyTrait;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
use Twig\Environment;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @coversNothing
|
||||
*/
|
||||
class AccompanyingPeriodWorkEvaluationDocumentWorkflowHandlerTest extends TestCase
|
||||
{
|
||||
use ProphecyTrait;
|
||||
|
||||
public function testGetSuggestedUsers()
|
||||
{
|
||||
$accompanyingCourse = new AccompanyingPeriod();
|
||||
$accompanyingCourse->setUser($referrer = new User());
|
||||
$accompanyingCourse->addWork($work = new AccompanyingPeriod\AccompanyingPeriodWork());
|
||||
$work->addReferrer($workReferrer1 = new User());
|
||||
$work->addReferrer($workReferrer2 = new User());
|
||||
$work->addReferrer($referrer);
|
||||
$work->addAccompanyingPeriodWorkEvaluation($eval = new AccompanyingPeriod\AccompanyingPeriodWorkEvaluation());
|
||||
$eval->addDocument($doc = new AccompanyingPeriodWorkEvaluationDocument());
|
||||
$entityWorkflow = new EntityWorkflow();
|
||||
|
||||
// Prophesize each dependency
|
||||
$workflowRepositoryProphecy = $this->prophesize(EntityWorkflowRepository::class);
|
||||
$translatableStringHelperProphecy = $this->prophesize(TranslatableStringHelperInterface::class);
|
||||
$translatorProphecy = $this->prophesize(TranslatorInterface::class);
|
||||
$twig = $this->prophesize(Environment::class);
|
||||
|
||||
// Create an instance of the class under test using revealed prophecies directly
|
||||
$handler = new AccompanyingPeriodWorkEvaluationDocumentWorkflowHandler(
|
||||
$this->buildRepository($doc, 1),
|
||||
$workflowRepositoryProphecy->reveal(),
|
||||
$translatableStringHelperProphecy->reveal(),
|
||||
$translatorProphecy->reveal(),
|
||||
new WorkflowWithPublicViewDocumentHelper($twig->reveal()),
|
||||
$this->prophesize(ProvideThirdPartiesAssociated::class)->reveal(),
|
||||
$this->prophesize(ProvidePersonsAssociated::class)->reveal(),
|
||||
);
|
||||
|
||||
$entityWorkflow->setRelatedEntityId(1);
|
||||
$entityWorkflow->setRelatedEntityClass(AccompanyingPeriodWorkEvaluationDocument::class);
|
||||
|
||||
$users = $handler->getSuggestedUsers($entityWorkflow);
|
||||
|
||||
self::assertContains($referrer, $users);
|
||||
self::assertContains($workReferrer1, $users);
|
||||
self::assertContains($workReferrer2, $users);
|
||||
}
|
||||
|
||||
private function buildRepository(AccompanyingPeriodWorkEvaluationDocument $document, int $id): AccompanyingPeriodWorkEvaluationDocumentRepository
|
||||
{
|
||||
$repository = $this->prophesize(AccompanyingPeriodWorkEvaluationDocumentRepository::class);
|
||||
|
||||
$repository->find($id)->willReturn($document);
|
||||
|
||||
return $repository->reveal();
|
||||
}
|
||||
}
|
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\PersonBundle\Tests\Workflow;
|
||||
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Chill\MainBundle\Entity\Workflow\EntityWorkflow;
|
||||
use Chill\MainBundle\Repository\Workflow\EntityWorkflowRepository;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
use Chill\PersonBundle\Repository\AccompanyingPeriod\AccompanyingPeriodWorkEvaluationRepository;
|
||||
use Chill\PersonBundle\Service\AccompanyingPeriodWork\ProvidePersonsAssociated;
|
||||
use Chill\PersonBundle\Service\AccompanyingPeriodWork\ProvideThirdPartiesAssociated;
|
||||
use Chill\PersonBundle\Workflow\AccompanyingPeriodWorkEvaluationWorkflowHandler;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Prophecy\PhpUnit\ProphecyTrait;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @coversNothing
|
||||
*/
|
||||
class AccompanyingPeriodWorkEvaluationWorkflowHandlerTest extends TestCase
|
||||
{
|
||||
use ProphecyTrait;
|
||||
|
||||
public function testGetSuggestedUsers()
|
||||
{
|
||||
$accompanyingCourse = new AccompanyingPeriod();
|
||||
$accompanyingCourse->setUser($referrer = new User());
|
||||
$accompanyingCourse->addWork($work = new AccompanyingPeriod\AccompanyingPeriodWork());
|
||||
$work->addReferrer($workReferrer1 = new User());
|
||||
$work->addReferrer($workReferrer2 = new User());
|
||||
$work->addReferrer($referrer);
|
||||
$work->addAccompanyingPeriodWorkEvaluation($eval = new AccompanyingPeriod\AccompanyingPeriodWorkEvaluation());
|
||||
$entityWorkflow = new EntityWorkflow();
|
||||
$entityWorkflow->setRelatedEntityId(1);
|
||||
|
||||
// Prophesize each dependency
|
||||
$workflowRepositoryProphecy = $this->prophesize(EntityWorkflowRepository::class);
|
||||
$translatableStringHelperProphecy = $this->prophesize(TranslatableStringHelperInterface::class);
|
||||
$translatorProphecy = $this->prophesize(TranslatorInterface::class);
|
||||
|
||||
// Create an instance of the class under test using revealed prophecies directly
|
||||
$handler = new AccompanyingPeriodWorkEvaluationWorkflowHandler(
|
||||
$this->buildRepository($eval, 1),
|
||||
$workflowRepositoryProphecy->reveal(),
|
||||
$translatableStringHelperProphecy->reveal(),
|
||||
$translatorProphecy->reveal(),
|
||||
$this->prophesize(ProvideThirdPartiesAssociated::class)->reveal(),
|
||||
$this->prophesize(ProvidePersonsAssociated::class)->reveal(),
|
||||
);
|
||||
|
||||
$users = $handler->getSuggestedUsers($entityWorkflow);
|
||||
|
||||
self::assertContains($referrer, $users);
|
||||
self::assertContains($workReferrer1, $users);
|
||||
self::assertContains($workReferrer2, $users);
|
||||
}
|
||||
|
||||
private function buildRepository(AccompanyingPeriod\AccompanyingPeriodWorkEvaluation $evaluation, int $id): AccompanyingPeriodWorkEvaluationRepository
|
||||
{
|
||||
$evaluationRepositoryProphecy = $this->prophesize(AccompanyingPeriodWorkEvaluationRepository::class);
|
||||
$evaluationRepositoryProphecy->find($id)->willReturn($evaluation);
|
||||
|
||||
return $evaluationRepositoryProphecy->reveal();
|
||||
}
|
||||
}
|
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\PersonBundle\Tests\Workflow;
|
||||
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Chill\MainBundle\Entity\Workflow\EntityWorkflow;
|
||||
use Chill\MainBundle\Repository\Workflow\EntityWorkflowRepository;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
use Chill\PersonBundle\Repository\AccompanyingPeriod\AccompanyingPeriodWorkRepository;
|
||||
use Chill\PersonBundle\Service\AccompanyingPeriodWork\ProvidePersonsAssociated;
|
||||
use Chill\PersonBundle\Service\AccompanyingPeriodWork\ProvideThirdPartiesAssociated;
|
||||
use Chill\PersonBundle\Workflow\AccompanyingPeriodWorkWorkflowHandler;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Prophecy\PhpUnit\ProphecyTrait;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @coversNothing
|
||||
*/
|
||||
class AccompanyingPeriodWorkWorkflowHandlerTest extends TestCase
|
||||
{
|
||||
use ProphecyTrait;
|
||||
|
||||
public function testGetSuggestedUsers()
|
||||
{
|
||||
$accompanyingCourse = new AccompanyingPeriod();
|
||||
$accompanyingCourse->setUser($referrer = new User());
|
||||
$accompanyingCourse->addWork($work = new AccompanyingPeriod\AccompanyingPeriodWork());
|
||||
$work->addReferrer($workReferrer1 = new User());
|
||||
$work->addReferrer($workReferrer2 = new User());
|
||||
$work->addReferrer($referrer);
|
||||
$entityWorkflow = new EntityWorkflow();
|
||||
$entityWorkflow->setRelatedEntityId(1);
|
||||
|
||||
// Prophesize each dependency
|
||||
$workflowRepositoryProphecy = $this->prophesize(EntityWorkflowRepository::class);
|
||||
$translatableStringHelperProphecy = $this->prophesize(TranslatableStringHelperInterface::class);
|
||||
$translatorProphecy = $this->prophesize(TranslatorInterface::class);
|
||||
|
||||
// Create an instance of the class under test using revealed prophecies directly
|
||||
$handler = new AccompanyingPeriodWorkWorkflowHandler(
|
||||
$this->buildRepository($work, 1),
|
||||
$workflowRepositoryProphecy->reveal(),
|
||||
$translatableStringHelperProphecy->reveal(),
|
||||
$translatorProphecy->reveal(),
|
||||
$this->prophesize(ProvideThirdPartiesAssociated::class)->reveal(),
|
||||
$this->prophesize(ProvidePersonsAssociated::class)->reveal(),
|
||||
);
|
||||
|
||||
$users = $handler->getSuggestedUsers($entityWorkflow);
|
||||
|
||||
self::assertContains($referrer, $users);
|
||||
self::assertContains($workReferrer1, $users);
|
||||
self::assertContains($workReferrer2, $users);
|
||||
}
|
||||
|
||||
private function buildRepository(AccompanyingPeriod\AccompanyingPeriodWork $work, int $int): AccompanyingPeriodWorkRepository
|
||||
{
|
||||
$accompanyingPeriodWorkRepositoryProphecy = $this->prophesize(AccompanyingPeriodWorkRepository::class);
|
||||
$accompanyingPeriodWorkRepositoryProphecy
|
||||
->find($int)
|
||||
->willReturn($work);
|
||||
|
||||
return $accompanyingPeriodWorkRepositoryProphecy->reveal();
|
||||
}
|
||||
}
|
@@ -11,17 +11,36 @@ declare(strict_types=1);
|
||||
|
||||
namespace Chill\PersonBundle\Workflow;
|
||||
|
||||
use Chill\DocStoreBundle\Entity\StoredObject;
|
||||
use Chill\DocStoreBundle\Workflow\WorkflowWithPublicViewDocumentHelper;
|
||||
use Chill\MainBundle\Entity\Workflow\EntityWorkflow;
|
||||
use Chill\MainBundle\Entity\Workflow\EntityWorkflowSend;
|
||||
use Chill\MainBundle\Repository\Workflow\EntityWorkflowRepository;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||
use Chill\MainBundle\Workflow\EntityWorkflowHandlerInterface;
|
||||
use Chill\MainBundle\Workflow\EntityWorkflowWithPublicViewInterface;
|
||||
use Chill\MainBundle\Workflow\EntityWorkflowWithStoredObjectHandlerInterface;
|
||||
use Chill\MainBundle\Workflow\Templating\EntityWorkflowViewMetadataDTO;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluationDocument;
|
||||
use Chill\PersonBundle\Repository\AccompanyingPeriod\AccompanyingPeriodWorkEvaluationDocumentRepository;
|
||||
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodWorkEvaluationDocumentVoter;
|
||||
use Chill\PersonBundle\Service\AccompanyingPeriodWork\ProvidePersonsAssociated;
|
||||
use Chill\PersonBundle\Service\AccompanyingPeriodWork\ProvideThirdPartiesAssociated;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
class AccompanyingPeriodWorkEvaluationDocumentWorkflowHandler implements EntityWorkflowHandlerInterface
|
||||
/**
|
||||
* @implements EntityWorkflowWithStoredObjectHandlerInterface<AccompanyingPeriodWorkEvaluationDocument>
|
||||
*/
|
||||
class AccompanyingPeriodWorkEvaluationDocumentWorkflowHandler implements EntityWorkflowWithStoredObjectHandlerInterface, EntityWorkflowWithPublicViewInterface
|
||||
{
|
||||
public function __construct(private readonly AccompanyingPeriodWorkEvaluationDocumentRepository $repository, private readonly TranslatableStringHelperInterface $translatableStringHelper, private readonly TranslatorInterface $translator) {}
|
||||
public function __construct(
|
||||
private readonly AccompanyingPeriodWorkEvaluationDocumentRepository $repository,
|
||||
private readonly EntityWorkflowRepository $workflowRepository,
|
||||
private readonly TranslatableStringHelperInterface $translatableStringHelper,
|
||||
private readonly TranslatorInterface $translator,
|
||||
private readonly WorkflowWithPublicViewDocumentHelper $publicViewDocumentHelper,
|
||||
private readonly ProvideThirdPartiesAssociated $provideThirdPartiesAssociated,
|
||||
private readonly ProvidePersonsAssociated $providePersonsAssociated,
|
||||
) {}
|
||||
|
||||
public function getDeletionRoles(): array
|
||||
{
|
||||
@@ -67,8 +86,6 @@ class AccompanyingPeriodWorkEvaluationDocumentWorkflowHandler implements EntityW
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AccompanyingPeriodWorkEvaluationDocument $object
|
||||
*
|
||||
* @return array[]
|
||||
*/
|
||||
public function getRelatedObjects(object $object): array
|
||||
@@ -85,17 +102,36 @@ class AccompanyingPeriodWorkEvaluationDocumentWorkflowHandler implements EntityW
|
||||
|
||||
public function getSuggestedUsers(EntityWorkflow $entityWorkflow): array
|
||||
{
|
||||
$suggestedUsers = $entityWorkflow->getUsersInvolved();
|
||||
$related = $this->getRelatedEntity($entityWorkflow);
|
||||
|
||||
$referrer = $this->getRelatedEntity($entityWorkflow)
|
||||
->getAccompanyingPeriodWorkEvaluation()
|
||||
if (null === $related) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$users = [];
|
||||
if (null !== $referrer = $related->getAccompanyingPeriodWorkEvaluation()
|
||||
->getAccompanyingPeriodWork()
|
||||
->getAccompanyingPeriod()
|
||||
->getUser();
|
||||
->getUser()
|
||||
) {
|
||||
$users[] = $referrer;
|
||||
}
|
||||
|
||||
$suggestedUsers[spl_object_hash($referrer)] = $referrer;
|
||||
foreach ($related->getAccompanyingPeriodWorkEvaluation()
|
||||
->getAccompanyingPeriodWork()
|
||||
->getReferrersHistoryCurrent() as $referrerHistory
|
||||
) {
|
||||
$users[] = $referrerHistory->getUser();
|
||||
}
|
||||
|
||||
return $suggestedUsers;
|
||||
return array_values(
|
||||
// filter objects to remove duplicates
|
||||
array_filter(
|
||||
$users,
|
||||
fn ($o, $k) => array_search($o, $users, true) === $k,
|
||||
ARRAY_FILTER_USE_BOTH
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function getTemplate(EntityWorkflow $entityWorkflow, array $options = []): string
|
||||
@@ -124,8 +160,49 @@ class AccompanyingPeriodWorkEvaluationDocumentWorkflowHandler implements EntityW
|
||||
return AccompanyingPeriodWorkEvaluationDocument::class === $entityWorkflow->getRelatedEntityClass();
|
||||
}
|
||||
|
||||
public function getAssociatedStoredObject(EntityWorkflow $entityWorkflow): ?StoredObject
|
||||
{
|
||||
return $this->getRelatedEntity($entityWorkflow)?->getStoredObject();
|
||||
}
|
||||
|
||||
public function supportsFreeze(EntityWorkflow $entityWorkflow, array $options = []): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function findByRelatedEntity(object $object): array
|
||||
{
|
||||
if (!$object instanceof AccompanyingPeriodWorkEvaluationDocument) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $this->workflowRepository->findByRelatedEntity(AccompanyingPeriodWorkEvaluationDocument::class, $object->getId());
|
||||
}
|
||||
|
||||
public function renderPublicView(EntityWorkflowSend $entityWorkflowSend, EntityWorkflowViewMetadataDTO $metadata): string
|
||||
{
|
||||
return $this->publicViewDocumentHelper->render($entityWorkflowSend, $metadata, $this);
|
||||
}
|
||||
|
||||
public function getSuggestedPersons(EntityWorkflow $entityWorkflow): array
|
||||
{
|
||||
$related = $this->getRelatedEntity($entityWorkflow);
|
||||
|
||||
if (null === $related) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $this->providePersonsAssociated->getPersonsAssociated($related->getAccompanyingPeriodWorkEvaluation()->getAccompanyingPeriodWork());
|
||||
}
|
||||
|
||||
public function getSuggestedThirdParties(EntityWorkflow $entityWorkflow): array
|
||||
{
|
||||
$related = $this->getRelatedEntity($entityWorkflow);
|
||||
|
||||
if (null === $related) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $this->provideThirdPartiesAssociated->getThirdPartiesAssociated($related->getAccompanyingPeriodWorkEvaluation()->getAccompanyingPeriodWork());
|
||||
}
|
||||
}
|
||||
|
@@ -12,17 +12,30 @@ declare(strict_types=1);
|
||||
namespace Chill\PersonBundle\Workflow;
|
||||
|
||||
use Chill\MainBundle\Entity\Workflow\EntityWorkflow;
|
||||
use Chill\MainBundle\Repository\Workflow\EntityWorkflowRepository;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||
use Chill\MainBundle\Workflow\EntityWorkflowHandlerInterface;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluation;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluationDocument;
|
||||
use Chill\PersonBundle\Repository\AccompanyingPeriod\AccompanyingPeriodWorkEvaluationRepository;
|
||||
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodWorkEvaluationVoter;
|
||||
use Chill\PersonBundle\Service\AccompanyingPeriodWork\ProvidePersonsAssociated;
|
||||
use Chill\PersonBundle\Service\AccompanyingPeriodWork\ProvideThirdPartiesAssociated;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
class AccompanyingPeriodWorkEvaluationWorkflowHandler implements EntityWorkflowHandlerInterface
|
||||
/**
|
||||
* @implements EntityWorkflowHandlerInterface<AccompanyingPeriodWorkEvaluation>
|
||||
*/
|
||||
readonly class AccompanyingPeriodWorkEvaluationWorkflowHandler implements EntityWorkflowHandlerInterface
|
||||
{
|
||||
public function __construct(private readonly AccompanyingPeriodWorkEvaluationRepository $repository, private readonly TranslatableStringHelperInterface $translatableStringHelper, private readonly TranslatorInterface $translator) {}
|
||||
public function __construct(
|
||||
private AccompanyingPeriodWorkEvaluationRepository $repository,
|
||||
private EntityWorkflowRepository $workflowRepository,
|
||||
private TranslatableStringHelperInterface $translatableStringHelper,
|
||||
private TranslatorInterface $translator,
|
||||
private ProvideThirdPartiesAssociated $provideThirdPartiesAssociated,
|
||||
private ProvidePersonsAssociated $providePersonsAssociated,
|
||||
) {}
|
||||
|
||||
public function getDeletionRoles(): array
|
||||
{
|
||||
@@ -53,9 +66,6 @@ class AccompanyingPeriodWorkEvaluationWorkflowHandler implements EntityWorkflowH
|
||||
return $this->repository->find($entityWorkflow->getRelatedEntityId());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AccompanyingPeriodWorkEvaluation $object
|
||||
*/
|
||||
public function getRelatedObjects(object $object): array
|
||||
{
|
||||
$relateds = [];
|
||||
@@ -75,16 +85,34 @@ class AccompanyingPeriodWorkEvaluationWorkflowHandler implements EntityWorkflowH
|
||||
|
||||
public function getSuggestedUsers(EntityWorkflow $entityWorkflow): array
|
||||
{
|
||||
$suggestedUsers = $entityWorkflow->getUsersInvolved();
|
||||
$related = $this->getRelatedEntity($entityWorkflow);
|
||||
|
||||
$referrer = $this->getRelatedEntity($entityWorkflow)
|
||||
->getAccompanyingPeriodWork()
|
||||
if (null === $related) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$users = [];
|
||||
if (null !== $referrer = $related->getAccompanyingPeriodWork()
|
||||
->getAccompanyingPeriod()
|
||||
->getUser();
|
||||
->getUser()
|
||||
) {
|
||||
$users[] = $referrer;
|
||||
}
|
||||
|
||||
$suggestedUsers[spl_object_hash($referrer)] = $referrer;
|
||||
foreach ($related->getAccompanyingPeriodWork()
|
||||
->getReferrersHistoryCurrent() as $referrerHistory
|
||||
) {
|
||||
$users[] = $referrerHistory->getUser();
|
||||
}
|
||||
|
||||
return $suggestedUsers;
|
||||
return array_values(
|
||||
// filter objects to remove duplicates
|
||||
array_filter(
|
||||
$users,
|
||||
fn ($o, $k) => array_search($o, $users, true) === $k,
|
||||
ARRAY_FILTER_USE_BOTH
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function getTemplate(EntityWorkflow $entityWorkflow, array $options = []): string
|
||||
@@ -114,4 +142,35 @@ class AccompanyingPeriodWorkEvaluationWorkflowHandler implements EntityWorkflowH
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function findByRelatedEntity(object $object): array
|
||||
{
|
||||
if (!$object instanceof AccompanyingPeriodWorkEvaluation) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $this->workflowRepository->findByRelatedEntity(AccompanyingPeriodWorkEvaluation::class, $object->getId());
|
||||
}
|
||||
|
||||
public function getSuggestedPersons(EntityWorkflow $entityWorkflow): array
|
||||
{
|
||||
$related = $this->getRelatedEntity($entityWorkflow);
|
||||
|
||||
if (null === $related) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $this->providePersonsAssociated->getPersonsAssociated($related->getAccompanyingPeriodWork());
|
||||
}
|
||||
|
||||
public function getSuggestedThirdParties(EntityWorkflow $entityWorkflow): array
|
||||
{
|
||||
$related = $this->getRelatedEntity($entityWorkflow);
|
||||
|
||||
if (null === $related) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $this->provideThirdPartiesAssociated->getThirdPartiesAssociated($related->getAccompanyingPeriodWork());
|
||||
}
|
||||
}
|
||||
|
@@ -12,6 +12,7 @@ declare(strict_types=1);
|
||||
namespace Chill\PersonBundle\Workflow;
|
||||
|
||||
use Chill\MainBundle\Entity\Workflow\EntityWorkflow;
|
||||
use Chill\MainBundle\Repository\Workflow\EntityWorkflowRepository;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||
use Chill\MainBundle\Workflow\EntityWorkflowHandlerInterface;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork;
|
||||
@@ -19,11 +20,23 @@ use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluatio
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluationDocument;
|
||||
use Chill\PersonBundle\Repository\AccompanyingPeriod\AccompanyingPeriodWorkRepository;
|
||||
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodWorkVoter;
|
||||
use Chill\PersonBundle\Service\AccompanyingPeriodWork\ProvidePersonsAssociated;
|
||||
use Chill\PersonBundle\Service\AccompanyingPeriodWork\ProvideThirdPartiesAssociated;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
class AccompanyingPeriodWorkWorkflowHandler implements EntityWorkflowHandlerInterface
|
||||
/**
|
||||
* @implements EntityWorkflowHandlerInterface<AccompanyingPeriodWork>
|
||||
*/
|
||||
readonly class AccompanyingPeriodWorkWorkflowHandler implements EntityWorkflowHandlerInterface
|
||||
{
|
||||
public function __construct(private readonly AccompanyingPeriodWorkRepository $repository, private readonly TranslatableStringHelperInterface $translatableStringHelper, private readonly TranslatorInterface $translator) {}
|
||||
public function __construct(
|
||||
private AccompanyingPeriodWorkRepository $repository,
|
||||
private EntityWorkflowRepository $workflowRepository,
|
||||
private TranslatableStringHelperInterface $translatableStringHelper,
|
||||
private TranslatorInterface $translator,
|
||||
private ProvideThirdPartiesAssociated $thirdPartiesAssociated,
|
||||
private ProvidePersonsAssociated $providePersonsAssociated,
|
||||
) {}
|
||||
|
||||
public function getDeletionRoles(): array
|
||||
{
|
||||
@@ -55,9 +68,6 @@ class AccompanyingPeriodWorkWorkflowHandler implements EntityWorkflowHandlerInte
|
||||
return $this->repository->find($entityWorkflow->getRelatedEntityId());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AccompanyingPeriodWork $object
|
||||
*/
|
||||
public function getRelatedObjects(object $object): array
|
||||
{
|
||||
$relateds = [];
|
||||
@@ -81,17 +91,32 @@ class AccompanyingPeriodWorkWorkflowHandler implements EntityWorkflowHandlerInte
|
||||
|
||||
public function getSuggestedUsers(EntityWorkflow $entityWorkflow): array
|
||||
{
|
||||
$suggestedUsers = $entityWorkflow->getUsersInvolved();
|
||||
$related = $this->getRelatedEntity($entityWorkflow);
|
||||
|
||||
$referrer = $this->getRelatedEntity($entityWorkflow)
|
||||
->getAccompanyingPeriod()
|
||||
->getUser();
|
||||
|
||||
if (null !== $referrer) {
|
||||
$suggestedUsers[spl_object_hash($referrer)] = $referrer;
|
||||
if (null === $related) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $suggestedUsers;
|
||||
$users = [];
|
||||
if (null !== $referrer = $related->getAccompanyingPeriod()
|
||||
->getUser()
|
||||
) {
|
||||
$users[] = $referrer;
|
||||
}
|
||||
|
||||
foreach ($related->getReferrersHistoryCurrent() as $referrerHistory
|
||||
) {
|
||||
$users[] = $referrerHistory->getUser();
|
||||
}
|
||||
|
||||
return array_values(
|
||||
// filter objects to remove duplicates
|
||||
array_filter(
|
||||
$users,
|
||||
fn ($o, $k) => array_search($o, $users, true) === $k,
|
||||
ARRAY_FILTER_USE_BOTH
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function getTemplate(EntityWorkflow $entityWorkflow, array $options = []): string
|
||||
@@ -121,4 +146,35 @@ class AccompanyingPeriodWorkWorkflowHandler implements EntityWorkflowHandlerInte
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function findByRelatedEntity(object $object): array
|
||||
{
|
||||
if (!$object instanceof AccompanyingPeriodWork) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $this->workflowRepository->findByRelatedEntity(AccompanyingPeriodWork::class, $object->getId());
|
||||
}
|
||||
|
||||
public function getSuggestedPersons(EntityWorkflow $entityWorkflow): array
|
||||
{
|
||||
$related = $this->getRelatedEntity($entityWorkflow);
|
||||
|
||||
if (null === $related) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $this->providePersonsAssociated->getPersonsAssociated($related);
|
||||
}
|
||||
|
||||
public function getSuggestedThirdParties(EntityWorkflow $entityWorkflow): array
|
||||
{
|
||||
$related = $this->getRelatedEntity($entityWorkflow);
|
||||
|
||||
if (null === $related) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $this->thirdPartiesAssociated->getThirdPartiesAssociated($related);
|
||||
}
|
||||
}
|
||||
|
@@ -1948,3 +1948,25 @@ paths:
|
||||
responses:
|
||||
200:
|
||||
description: "OK"
|
||||
|
||||
/1.0/person/accompanying-course-work-evaluation-document/{id}/duplicate:
|
||||
post:
|
||||
tags:
|
||||
- accompanying-course-work-evaluation-document
|
||||
summary: Dupliate an an accompanying period work evaluation document
|
||||
parameters:
|
||||
- in: path
|
||||
name: id
|
||||
required: true
|
||||
description: The document's id
|
||||
schema:
|
||||
type: integer
|
||||
format: integer
|
||||
minimum: 1
|
||||
responses:
|
||||
200:
|
||||
description: "OK"
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
|
@@ -68,3 +68,6 @@ services:
|
||||
autowire: true
|
||||
tags: ['controller.service_arguments']
|
||||
|
||||
Chill\PersonBundle\Controller\PersonSignatureController:
|
||||
tags: [ 'controller.service_arguments' ]
|
||||
|
||||
|
@@ -165,8 +165,8 @@ exports:
|
||||
{ total, plural,
|
||||
=0 {Aucun usager ne correspond aux termes de recherche}
|
||||
one {Un usager correspond aux termes de recherche}
|
||||
many {# usagers correspondent aux terms de recherche}
|
||||
other {# usagers correspondent aux terms de recherche}
|
||||
many {# usagers correspondent aux termes de recherche}
|
||||
other {# usagers correspondent aux termes de recherche}
|
||||
}
|
||||
|
||||
'nb person with similar name. Please verify that this is a new person': >-
|
||||
@@ -175,3 +175,7 @@ exports:
|
||||
one {Un usager a un nom similaire. Vérifiez qu'il ne s'agit pas de lui.}
|
||||
other {# usagers ont un nom similaire. Vérifiez qu'il ne s'agit pas de l'un d'eux}
|
||||
}
|
||||
|
||||
accompanying_course_evaluation_document:
|
||||
duplicated_at: >-
|
||||
Dupliqué le {at, date, long} à {at, time, short}
|
||||
|
@@ -958,6 +958,10 @@ workflow:
|
||||
Doc for evaluation (n°%eval%): Document de l'évaluation n°%eval%
|
||||
doc for evaluation deleted: Document supprimé dans une évaluation
|
||||
SocialAction deleted: Action sociale supprimée
|
||||
signature_list:
|
||||
title: Signature en attente
|
||||
menu: Signature en attente
|
||||
no_signatures: Aucune signature demandée
|
||||
|
||||
period_by_user_list:
|
||||
Period by user: Parcours d'accompagnement par utilisateur
|
||||
|
Reference in New Issue
Block a user