mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
Duplicate and accompanying course evaluation document
- create a service which duplicate the accompanying course work evaluation document - create a controller to duplicate this document - update the vuejs component to use this duplicate action
This commit is contained in:
parent
ce80207d98
commit
611a968162
@ -19,8 +19,6 @@ use Chill\DocStoreBundle\Workflow\AccompanyingCourseDocumentDuplicator;
|
|||||||
use Chill\MainBundle\Entity\User;
|
use Chill\MainBundle\Entity\User;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use Symfony\Component\Clock\MockClock;
|
use Symfony\Component\Clock\MockClock;
|
||||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
|
||||||
use Symfony\Component\Security\Core\Security;
|
|
||||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -12,11 +12,8 @@ declare(strict_types=1);
|
|||||||
namespace Chill\DocStoreBundle\Workflow;
|
namespace Chill\DocStoreBundle\Workflow;
|
||||||
|
|
||||||
use Chill\DocStoreBundle\Entity\AccompanyingCourseDocument;
|
use Chill\DocStoreBundle\Entity\AccompanyingCourseDocument;
|
||||||
use Chill\DocStoreBundle\Security\Authorization\AccompanyingCourseDocumentVoter;
|
|
||||||
use Chill\DocStoreBundle\Service\StoredObjectDuplicate;
|
use Chill\DocStoreBundle\Service\StoredObjectDuplicate;
|
||||||
use Symfony\Component\Clock\ClockInterface;
|
use Symfony\Component\Clock\ClockInterface;
|
||||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
|
||||||
use Symfony\Component\Security\Core\Security;
|
|
||||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -17,7 +17,6 @@ use Chill\DocStoreBundle\Entity\StoredObject;
|
|||||||
use Chill\DocStoreBundle\Security\Authorization\AccompanyingCourseDocumentVoter;
|
use Chill\DocStoreBundle\Security\Authorization\AccompanyingCourseDocumentVoter;
|
||||||
use Chill\MainBundle\Entity\Workflow\EntityWorkflow;
|
use Chill\MainBundle\Entity\Workflow\EntityWorkflow;
|
||||||
use Chill\MainBundle\Repository\Workflow\EntityWorkflowRepository;
|
use Chill\MainBundle\Repository\Workflow\EntityWorkflowRepository;
|
||||||
use Chill\MainBundle\Workflow\EntityWorkflowWithDuplicableRelatedEntityInterface;
|
|
||||||
use Chill\MainBundle\Workflow\EntityWorkflowWithStoredObjectHandlerInterface;
|
use Chill\MainBundle\Workflow\EntityWorkflowWithStoredObjectHandlerInterface;
|
||||||
use Chill\PersonBundle\Entity\AccompanyingPeriodParticipation;
|
use Chill\PersonBundle\Entity\AccompanyingPeriodParticipation;
|
||||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
@ -28,8 +27,8 @@ use Symfony\Contracts\Translation\TranslatorInterface;
|
|||||||
readonly class AccompanyingCourseDocumentWorkflowHandler implements EntityWorkflowWithStoredObjectHandlerInterface
|
readonly class AccompanyingCourseDocumentWorkflowHandler implements EntityWorkflowWithStoredObjectHandlerInterface
|
||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private TranslatorInterface $translator,
|
private TranslatorInterface $translator,
|
||||||
private EntityWorkflowRepository $workflowRepository,
|
private EntityWorkflowRepository $workflowRepository,
|
||||||
private AccompanyingCourseDocumentRepository $repository,
|
private AccompanyingCourseDocumentRepository $repository,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
|
@ -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\Controller;
|
||||||
|
|
||||||
|
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\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,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
#[Route('/api/1.0/person/accompanying-course-work-evaluation-document/{id}/duplicate', methods: ['POST'])]
|
||||||
|
public function __invoke(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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -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 {
|
export interface Person {
|
||||||
id: number;
|
id: number;
|
||||||
@ -20,3 +28,16 @@ export interface Person {
|
|||||||
current_household_id: number;
|
current_household_id: number;
|
||||||
current_residential_addresses: Address[];
|
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[];
|
||||||
|
}
|
||||||
|
@ -147,6 +147,9 @@
|
|||||||
<a class="btn btn-delete" @click="removeDocument(d)">
|
<a class="btn btn-delete" @click="removeDocument(d)">
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li v-if="Number.isInteger(d.id)">
|
||||||
|
<button type="button" @click="duplicateDocument(d)" class="btn btn-duplicate" title="Dupliquer"></button>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -396,6 +399,9 @@ export default {
|
|||||||
this.$store.commit('removeDocument', {key: this.evaluation.key, document: document});
|
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) {
|
onStatusDocumentChanged(newStatus) {
|
||||||
console.log('onStatusDocumentChanged', newStatus);
|
console.log('onStatusDocumentChanged', newStatus);
|
||||||
this.$store.commit('statusDocumentChanged', {key: this.evaluation.key, newStatus: 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 { create } from 'ChillPersonAssets/vuejs/_api/AccompanyingCourseWork.js';
|
||||||
import { fetchResults, makeFetch } from 'ChillMainAssets/lib/api/apiMethods.ts';
|
import { fetchResults, makeFetch } from 'ChillMainAssets/lib/api/apiMethods.ts';
|
||||||
import { fetchTemplates } from 'ChillDocGeneratorAssets/api/pickTemplate.js';
|
import { fetchTemplates } from 'ChillDocGeneratorAssets/api/pickTemplate.js';
|
||||||
|
import { duplicate } from '../_api/accompanyingCourseWorkEvaluationDocument';
|
||||||
|
|
||||||
const debug = process.env.NODE_ENV !== 'production';
|
const debug = process.env.NODE_ENV !== 'production';
|
||||||
const evalFQDN = encodeURIComponent("Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluation");
|
const evalFQDN = encodeURIComponent("Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluation");
|
||||||
@ -238,6 +239,14 @@ const store = createStore({
|
|||||||
}
|
}
|
||||||
evaluation.documents = evaluation.documents.filter(d => d.key !== document.key);
|
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.
|
* Replaces a document in the state with a new document.
|
||||||
*
|
*
|
||||||
@ -506,6 +515,10 @@ const store = createStore({
|
|||||||
addDocument({commit}, payload) {
|
addDocument({commit}, payload) {
|
||||||
commit('addDocument', 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) {
|
removeDocument({commit}, payload) {
|
||||||
commit('removeDocument', 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`);
|
||||||
|
}
|
@ -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,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());
|
||||||
|
}
|
||||||
|
}
|
@ -1948,3 +1948,25 @@ paths:
|
|||||||
responses:
|
responses:
|
||||||
200:
|
200:
|
||||||
description: "OK"
|
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
|
||||||
|
@ -163,8 +163,8 @@ exports:
|
|||||||
{ total, plural,
|
{ total, plural,
|
||||||
=0 {Aucun usager ne correspond aux termes de recherche}
|
=0 {Aucun usager ne correspond aux termes de recherche}
|
||||||
one {Un usager correspond aux termes de recherche}
|
one {Un usager correspond aux termes de recherche}
|
||||||
many {# usagers correspondent aux terms de recherche}
|
many {# usagers correspondent aux termes de recherche}
|
||||||
other {# usagers correspondent aux terms de recherche}
|
other {# usagers correspondent aux termes de recherche}
|
||||||
}
|
}
|
||||||
|
|
||||||
'nb person with similar name. Please verify that this is a new person': >-
|
'nb person with similar name. Please verify that this is a new person': >-
|
||||||
@ -173,3 +173,7 @@ exports:
|
|||||||
one {Un usager a un nom similaire. Vérifiez qu'il ne s'agit pas de lui.}
|
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}
|
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}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user