mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
Merge branch 'signature-app/get-stored-object-from-workflow' into 'signature-app-master'
Allow to retrieve an eventual stored object associated with an EntityWorkflow + handle more effectively transition See merge request Chill-Projet/chill-bundles!711
This commit is contained in:
commit
3e8805bdda
@ -11,6 +11,9 @@ declare(strict_types=1);
|
||||
|
||||
namespace Chill\DocStoreBundle\Service\Signature\Driver\BaseSigner;
|
||||
|
||||
use Chill\DocStoreBundle\Service\StoredObjectManagerInterface;
|
||||
use Chill\MainBundle\Repository\Workflow\EntityWorkflowStepSignatureRepository;
|
||||
use Chill\MainBundle\Workflow\EntityWorkflowManager;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;
|
||||
|
||||
@ -23,10 +26,27 @@ final readonly class PdfSignedMessageHandler implements MessageHandlerInterface
|
||||
|
||||
public function __construct(
|
||||
private LoggerInterface $logger,
|
||||
private EntityWorkflowManager $entityWorkflowManager,
|
||||
private StoredObjectManagerInterface $storedObjectManager,
|
||||
private EntityWorkflowStepSignatureRepository $entityWorkflowStepSignatureRepository,
|
||||
) {}
|
||||
|
||||
public function __invoke(PdfSignedMessage $message): void
|
||||
{
|
||||
$this->logger->info(self::P.'a message is received', ['signaturedId' => $message->signatureId]);
|
||||
|
||||
$signature = $this->entityWorkflowStepSignatureRepository->find($message->signatureId);
|
||||
|
||||
if (null === $signature) {
|
||||
throw new \RuntimeException('no signature found');
|
||||
}
|
||||
|
||||
$storedObject = $this->entityWorkflowManager->getAssociatedStoredObject($signature->getStep()->getEntityWorkflow());
|
||||
|
||||
if (null === $storedObject) {
|
||||
throw new \RuntimeException('no stored object found');
|
||||
}
|
||||
|
||||
$this->storedObjectManager->write($storedObject, $message->content);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,84 @@
|
||||
<?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\DocStoreBundle\Tests\Service\Signature\Driver\BaseSigner;
|
||||
|
||||
use Chill\DocStoreBundle\Entity\StoredObject;
|
||||
use Chill\DocStoreBundle\Service\Signature\Driver\BaseSigner\PdfSignedMessage;
|
||||
use Chill\DocStoreBundle\Service\Signature\Driver\BaseSigner\PdfSignedMessageHandler;
|
||||
use Chill\DocStoreBundle\Service\StoredObjectManagerInterface;
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Chill\MainBundle\Entity\Workflow\EntityWorkflow;
|
||||
use Chill\MainBundle\Entity\Workflow\EntityWorkflowStepSignature;
|
||||
use Chill\MainBundle\Repository\Workflow\EntityWorkflowStepSignatureRepository;
|
||||
use Chill\MainBundle\Workflow\EntityWorkflowManager;
|
||||
use Chill\MainBundle\Workflow\WorkflowTransitionContextDTO;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psr\Log\NullLogger;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @coversNothing
|
||||
*/
|
||||
class PdfSignedMessageHandlerTest extends TestCase
|
||||
{
|
||||
public function testThatObjectIsWrittenInStoredObjectManagerHappyScenario(): void
|
||||
{
|
||||
// a dummy stored object
|
||||
$storedObject = new StoredObject();
|
||||
// build the associated EntityWorkflow, with one step with a person signature
|
||||
$entityWorkflow = new EntityWorkflow();
|
||||
$dto = new WorkflowTransitionContextDTO($entityWorkflow);
|
||||
$dto->futurePersonSignatures[] = new Person();
|
||||
$entityWorkflow->setStep('new_step', $dto, 'new_transition', new \DateTimeImmutable(), new User());
|
||||
$step = $entityWorkflow->getCurrentStep();
|
||||
$signature = $step->getSignatures()->first();
|
||||
|
||||
$handler = new PdfSignedMessageHandler(
|
||||
new NullLogger(),
|
||||
$this->buildEntityWorkflowManager($storedObject),
|
||||
$this->buildStoredObjectManager($storedObject, $expectedContent = '1234'),
|
||||
$this->buildSignatureRepository($signature)
|
||||
);
|
||||
|
||||
// we simply call the handler. The mocked StoredObjectManager will check that the "write" method is invoked once
|
||||
// with the content "1234"
|
||||
$handler(new PdfSignedMessage(10, $expectedContent));
|
||||
}
|
||||
|
||||
private function buildSignatureRepository(EntityWorkflowStepSignature $signature): EntityWorkflowStepSignatureRepository
|
||||
{
|
||||
$entityWorkflowStepSignatureRepository = $this->createMock(EntityWorkflowStepSignatureRepository::class);
|
||||
$entityWorkflowStepSignatureRepository->method('find')->with($this->isType('int'))->willReturn($signature);
|
||||
|
||||
return $entityWorkflowStepSignatureRepository;
|
||||
}
|
||||
|
||||
private function buildEntityWorkflowManager(?StoredObject $associatedStoredObject): EntityWorkflowManager
|
||||
{
|
||||
$entityWorkflowManager = $this->createMock(EntityWorkflowManager::class);
|
||||
$entityWorkflowManager->method('getAssociatedStoredObject')->willReturn($associatedStoredObject);
|
||||
|
||||
return $entityWorkflowManager;
|
||||
}
|
||||
|
||||
private function buildStoredObjectManager(StoredObject $expectedStoredObject, string $expectedContent): StoredObjectManagerInterface
|
||||
{
|
||||
$storedObjectManager = $this->createMock(StoredObjectManagerInterface::class);
|
||||
$storedObjectManager->expects($this->once())
|
||||
->method('write')
|
||||
->with($this->identicalTo($expectedStoredObject), $expectedContent);
|
||||
|
||||
return $storedObjectManager;
|
||||
}
|
||||
}
|
@ -12,15 +12,19 @@ declare(strict_types=1);
|
||||
namespace Chill\DocStoreBundle\Workflow;
|
||||
|
||||
use Chill\DocStoreBundle\Entity\AccompanyingCourseDocument;
|
||||
use Chill\DocStoreBundle\Entity\StoredObject;
|
||||
use Chill\DocStoreBundle\Security\Authorization\AccompanyingCourseDocumentVoter;
|
||||
use Chill\MainBundle\Entity\Workflow\EntityWorkflow;
|
||||
use Chill\MainBundle\Workflow\EntityWorkflowHandlerInterface;
|
||||
use Chill\MainBundle\Workflow\EntityWorkflowWithStoredObjectHandlerInterface;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriodParticipation;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
class AccompanyingCourseDocumentWorkflowHandler implements EntityWorkflowHandlerInterface
|
||||
/**
|
||||
* @implements EntityWorkflowWithStoredObjectHandlerInterface<AccompanyingCourseDocument>
|
||||
*/
|
||||
class AccompanyingCourseDocumentWorkflowHandler implements EntityWorkflowWithStoredObjectHandlerInterface
|
||||
{
|
||||
private readonly EntityRepository $repository;
|
||||
|
||||
@ -73,8 +77,6 @@ class AccompanyingCourseDocumentWorkflowHandler implements EntityWorkflowHandler
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AccompanyingCourseDocument $object
|
||||
*
|
||||
* @return array[]
|
||||
*/
|
||||
public function getRelatedObjects(object $object): array
|
||||
@ -121,4 +123,9 @@ class AccompanyingCourseDocumentWorkflowHandler implements EntityWorkflowHandler
|
||||
{
|
||||
return AccompanyingCourseDocument::class === $entityWorkflow->getRelatedEntityClass();
|
||||
}
|
||||
|
||||
public function getAssociatedStoredObject(EntityWorkflow $entityWorkflow): ?StoredObject
|
||||
{
|
||||
return $this->getRelatedEntity($entityWorkflow)?->getObject();
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ use Chill\MainBundle\Workflow\EntityWorkflowManager;
|
||||
use Chill\MainBundle\Workflow\WorkflowTransitionContextDTO;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\Clock\ClockInterface;
|
||||
use Symfony\Component\Form\Extension\Core\Type\FormType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
@ -39,7 +40,18 @@ use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
class WorkflowController extends AbstractController
|
||||
{
|
||||
public function __construct(private readonly EntityWorkflowManager $entityWorkflowManager, private readonly EntityWorkflowRepository $entityWorkflowRepository, private readonly ValidatorInterface $validator, private readonly PaginatorFactory $paginatorFactory, private readonly Registry $registry, private readonly EntityManagerInterface $entityManager, private readonly TranslatorInterface $translator, private readonly ChillSecurity $security, private readonly \Doctrine\Persistence\ManagerRegistry $managerRegistry) {}
|
||||
public function __construct(
|
||||
private readonly EntityWorkflowManager $entityWorkflowManager,
|
||||
private readonly EntityWorkflowRepository $entityWorkflowRepository,
|
||||
private readonly ValidatorInterface $validator,
|
||||
private readonly PaginatorFactory $paginatorFactory,
|
||||
private readonly Registry $registry,
|
||||
private readonly EntityManagerInterface $entityManager,
|
||||
private readonly TranslatorInterface $translator,
|
||||
private readonly ChillSecurity $security,
|
||||
private readonly \Doctrine\Persistence\ManagerRegistry $managerRegistry,
|
||||
private readonly ClockInterface $clock,
|
||||
) {}
|
||||
|
||||
#[Route(path: '/{_locale}/main/workflow/create', name: 'chill_main_workflow_create')]
|
||||
public function create(Request $request): Response
|
||||
@ -310,7 +322,14 @@ class WorkflowController extends AbstractController
|
||||
throw $this->createAccessDeniedException(sprintf("not allowed to apply transition {$transition}: %s", implode(', ', $msgs)));
|
||||
}
|
||||
|
||||
$workflow->apply($entityWorkflow, $transition, ['context' => $stepDTO]);
|
||||
$byUser = $this->security->getUser();
|
||||
|
||||
$workflow->apply($entityWorkflow, $transition, [
|
||||
'context' => $stepDTO,
|
||||
'byUser' => $byUser,
|
||||
'transition' => $transition,
|
||||
'transitionAt' => $this->clock->now(),
|
||||
]);
|
||||
|
||||
$this->entityManager->flush();
|
||||
|
||||
|
@ -413,8 +413,15 @@ class EntityWorkflow implements TrackCreationInterface, TrackUpdateInterface
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setStep(string $step, WorkflowTransitionContextDTO $transitionContextDTO): self
|
||||
public function setStep(string $step, WorkflowTransitionContextDTO $transitionContextDTO, string $transition, \DateTimeImmutable $transitionAt, ?User $byUser = null): self
|
||||
{
|
||||
$previousStep = $this->getCurrentStep();
|
||||
|
||||
$previousStep
|
||||
->setTransitionAfter($transition)
|
||||
->setTransitionAt($transitionAt)
|
||||
->setTransitionBy($byUser);
|
||||
|
||||
$newStep = new EntityWorkflowStep();
|
||||
$newStep->setCurrentStep($step);
|
||||
|
||||
@ -430,6 +437,10 @@ class EntityWorkflow implements TrackCreationInterface, TrackUpdateInterface
|
||||
$newStep->addDestEmail($email);
|
||||
}
|
||||
|
||||
foreach ($transitionContextDTO->futurePersonSignatures as $personSignature) {
|
||||
new EntityWorkflowStepSignature($newStep, $personSignature);
|
||||
}
|
||||
|
||||
// copy the freeze
|
||||
if ($this->isFreeze()) {
|
||||
$newStep->setFreezeAfter(true);
|
||||
|
@ -12,13 +12,14 @@ declare(strict_types=1);
|
||||
namespace Chill\MainBundle\Security\Authorization;
|
||||
|
||||
use Chill\MainBundle\Repository\Workflow\EntityWorkflowRepository;
|
||||
use Chill\MainBundle\Workflow\EntityWorkflowHandlerInterface;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
|
||||
|
||||
class WorkflowEntityDeletionVoter extends Voter
|
||||
{
|
||||
/**
|
||||
* @param \Chill\MainBundle\Workflow\EntityWorkflowHandlerInterface[] $handlers
|
||||
* @param EntityWorkflowHandlerInterface[] $handlers
|
||||
*/
|
||||
public function __construct(private $handlers, private readonly EntityWorkflowRepository $entityWorkflowRepository) {}
|
||||
|
||||
@ -30,7 +31,7 @@ class WorkflowEntityDeletionVoter extends Voter
|
||||
|
||||
foreach ($this->handlers as $handler) {
|
||||
if ($handler->isObjectSupported($subject)
|
||||
&& \in_array($attribute, $handler->getDeletionRoles($subject), true)) {
|
||||
&& \in_array($attribute, $handler->getDeletionRoles(), true)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace Chill\MainBundle\Tests\Entity\Workflow;
|
||||
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Chill\MainBundle\Entity\Workflow\EntityWorkflow;
|
||||
use Chill\MainBundle\Workflow\WorkflowTransitionContextDTO;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
@ -26,7 +27,7 @@ final class EntityWorkflowTest extends TestCase
|
||||
{
|
||||
$entityWorkflow = new EntityWorkflow();
|
||||
|
||||
$entityWorkflow->setStep('final', new WorkflowTransitionContextDTO($entityWorkflow));
|
||||
$entityWorkflow->setStep('final', new WorkflowTransitionContextDTO($entityWorkflow), 'finalize', new \DateTimeImmutable());
|
||||
$entityWorkflow->getCurrentStep()->setIsFinal(true);
|
||||
|
||||
$this->assertTrue($entityWorkflow->isFinal());
|
||||
@ -38,16 +39,16 @@ final class EntityWorkflowTest extends TestCase
|
||||
|
||||
$this->assertFalse($entityWorkflow->isFinal());
|
||||
|
||||
$entityWorkflow->setStep('two', new WorkflowTransitionContextDTO($entityWorkflow));
|
||||
$entityWorkflow->setStep('two', new WorkflowTransitionContextDTO($entityWorkflow), 'two', new \DateTimeImmutable());
|
||||
|
||||
$this->assertFalse($entityWorkflow->isFinal());
|
||||
|
||||
$entityWorkflow->setStep('previous_final', new WorkflowTransitionContextDTO($entityWorkflow));
|
||||
$entityWorkflow->setStep('previous_final', new WorkflowTransitionContextDTO($entityWorkflow), 'three', new \DateTimeImmutable());
|
||||
|
||||
$this->assertFalse($entityWorkflow->isFinal());
|
||||
|
||||
$entityWorkflow->getCurrentStep()->setIsFinal(true);
|
||||
$entityWorkflow->setStep('final', new WorkflowTransitionContextDTO($entityWorkflow));
|
||||
$entityWorkflow->setStep('final', new WorkflowTransitionContextDTO($entityWorkflow), 'four', new \DateTimeImmutable());
|
||||
|
||||
$this->assertTrue($entityWorkflow->isFinal());
|
||||
}
|
||||
@ -58,23 +59,50 @@ final class EntityWorkflowTest extends TestCase
|
||||
|
||||
$this->assertFalse($entityWorkflow->isFreeze());
|
||||
|
||||
$entityWorkflow->setStep('step_one', new WorkflowTransitionContextDTO($entityWorkflow));
|
||||
$entityWorkflow->setStep('step_one', new WorkflowTransitionContextDTO($entityWorkflow), 'to_step_one', new \DateTimeImmutable());
|
||||
|
||||
$this->assertFalse($entityWorkflow->isFreeze());
|
||||
|
||||
$entityWorkflow->setStep('step_three', new WorkflowTransitionContextDTO($entityWorkflow));
|
||||
$entityWorkflow->setStep('step_three', new WorkflowTransitionContextDTO($entityWorkflow), 'to_step_three', new \DateTimeImmutable());
|
||||
|
||||
$this->assertFalse($entityWorkflow->isFreeze());
|
||||
|
||||
$entityWorkflow->setStep('freezed', new WorkflowTransitionContextDTO($entityWorkflow));
|
||||
$entityWorkflow->setStep('freezed', new WorkflowTransitionContextDTO($entityWorkflow), 'to_freezed', new \DateTimeImmutable());
|
||||
$entityWorkflow->getCurrentStep()->setFreezeAfter(true);
|
||||
|
||||
$this->assertTrue($entityWorkflow->isFreeze());
|
||||
|
||||
$entityWorkflow->setStep('after_freeze', new WorkflowTransitionContextDTO($entityWorkflow));
|
||||
$entityWorkflow->setStep('after_freeze', new WorkflowTransitionContextDTO($entityWorkflow), 'to_after_freeze', new \DateTimeImmutable());
|
||||
|
||||
$this->assertTrue($entityWorkflow->isFreeze());
|
||||
|
||||
$this->assertTrue($entityWorkflow->getCurrentStep()->isFreezeAfter());
|
||||
}
|
||||
|
||||
public function testPreviousStepMetadataAreFilled()
|
||||
{
|
||||
$entityWorkflow = new EntityWorkflow();
|
||||
$initialStep = $entityWorkflow->getCurrentStep();
|
||||
|
||||
$entityWorkflow->setStep('step_one', new WorkflowTransitionContextDTO($entityWorkflow), 'to_step_one', new \DateTimeImmutable('2024-01-01'), $user1 = new User());
|
||||
|
||||
$previous = $entityWorkflow->getCurrentStep();
|
||||
|
||||
$entityWorkflow->setStep('step_one', new WorkflowTransitionContextDTO($entityWorkflow), 'to_step_two', new \DateTimeImmutable('2024-01-02'), $user2 = new User());
|
||||
|
||||
$final = $entityWorkflow->getCurrentStep();
|
||||
|
||||
$stepsChained = $entityWorkflow->getStepsChained();
|
||||
|
||||
self::assertCount(3, $stepsChained);
|
||||
self::assertSame($initialStep, $stepsChained[0]);
|
||||
self::assertSame($previous, $stepsChained[1]);
|
||||
self::assertSame($final, $stepsChained[2]);
|
||||
self::assertEquals($user1, $initialStep->getTransitionBy());
|
||||
self::assertEquals('2024-01-01', $initialStep->getTransitionAt()?->format('Y-m-d'));
|
||||
self::assertEquals('to_step_one', $initialStep->getTransitionAfter());
|
||||
self::assertEquals($user2, $previous->getTransitionBy());
|
||||
self::assertEquals('2024-01-02', $previous->getTransitionAt()?->format('Y-m-d'));
|
||||
self::assertEquals('to_step_two', $previous->getTransitionAfter());
|
||||
}
|
||||
}
|
||||
|
@ -39,19 +39,29 @@ class EntityWorkflowMarkingStoreTest extends TestCase
|
||||
{
|
||||
$markingStore = $this->buildMarkingStore();
|
||||
$workflow = new EntityWorkflow();
|
||||
$previousStep = $workflow->getCurrentStep();
|
||||
|
||||
$dto = new WorkflowTransitionContextDTO($workflow);
|
||||
$dto->futureCcUsers[] = $user1 = new User();
|
||||
$dto->futureDestUsers[] = $user2 = new User();
|
||||
$dto->futureDestEmails[] = $email = 'test@example.com';
|
||||
|
||||
$markingStore->setMarking($workflow, new Marking(['foo' => 1]), ['context' => $dto]);
|
||||
$markingStore->setMarking($workflow, new Marking(['foo' => 1]), [
|
||||
'context' => $dto,
|
||||
'transition' => 'bar_transition',
|
||||
'byUser' => $user3 = new User(),
|
||||
'transitionAt' => $at = new \DateTimeImmutable(),
|
||||
]);
|
||||
|
||||
$currentStep = $workflow->getCurrentStep();
|
||||
self::assertEquals('foo', $currentStep->getCurrentStep());
|
||||
self::assertContains($email, $currentStep->getDestEmail());
|
||||
self::assertContains($user1, $currentStep->getCcUser());
|
||||
self::assertContains($user2, $currentStep->getDestUser());
|
||||
|
||||
self::assertSame($user3, $previousStep->getTransitionBy());
|
||||
self::assertSame($at, $previousStep->getTransitionAt());
|
||||
self::assertEquals('bar_transition', $previousStep->getTransitionAfter());
|
||||
}
|
||||
|
||||
private function buildMarkingStore(): EntityWorkflowMarkingStore
|
||||
|
@ -14,6 +14,9 @@ namespace Chill\MainBundle\Workflow;
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Chill\MainBundle\Entity\Workflow\EntityWorkflow;
|
||||
|
||||
/**
|
||||
* @template T of object
|
||||
*/
|
||||
interface EntityWorkflowHandlerInterface
|
||||
{
|
||||
/**
|
||||
@ -25,6 +28,9 @@ interface EntityWorkflowHandlerInterface
|
||||
|
||||
public function getEntityTitle(EntityWorkflow $entityWorkflow, array $options = []): string;
|
||||
|
||||
/**
|
||||
* @return T|null
|
||||
*/
|
||||
public function getRelatedEntity(EntityWorkflow $entityWorkflow): ?object;
|
||||
|
||||
public function getRelatedObjects(object $object): array;
|
||||
|
@ -11,6 +11,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace Chill\MainBundle\Workflow;
|
||||
|
||||
use Chill\DocStoreBundle\Entity\StoredObject;
|
||||
use Chill\MainBundle\Entity\Workflow\EntityWorkflow;
|
||||
use Chill\MainBundle\Workflow\Exception\HandlerNotFoundException;
|
||||
use Symfony\Component\Workflow\Registry;
|
||||
@ -37,4 +38,15 @@ class EntityWorkflowManager
|
||||
{
|
||||
return $this->registry->all($entityWorkflow);
|
||||
}
|
||||
|
||||
public function getAssociatedStoredObject(EntityWorkflow $entityWorkflow): ?StoredObject
|
||||
{
|
||||
foreach ($this->handlers as $handler) {
|
||||
if ($handler instanceof EntityWorkflowWithStoredObjectHandlerInterface && $handler->supports($entityWorkflow)) {
|
||||
return $handler->getAssociatedStoredObject($entityWorkflow);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -40,10 +40,14 @@ final readonly class EntityWorkflowMarkingStore implements MarkingStoreInterface
|
||||
$next = array_keys($places)[0];
|
||||
|
||||
$transitionDTO = $context['context'] ?? null;
|
||||
$transition = $context['transition'];
|
||||
$byUser = $context['byUser'] ?? null;
|
||||
$at = $context['transitionAt'];
|
||||
|
||||
if (!$transitionDTO instanceof WorkflowTransitionContextDTO) {
|
||||
throw new \UnexpectedValueException(sprintf('Expected instance of %s', WorkflowTransitionContextDTO::class));
|
||||
}
|
||||
|
||||
$subject->setStep($next, $transitionDTO);
|
||||
$subject->setStep($next, $transitionDTO, $transition, $at, $byUser);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,27 @@
|
||||
<?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\MainBundle\Workflow;
|
||||
|
||||
use Chill\DocStoreBundle\Entity\StoredObject;
|
||||
use Chill\MainBundle\Entity\Workflow\EntityWorkflow;
|
||||
|
||||
/**
|
||||
* Add methods to handle workflows associated with @see{StoredObject}.
|
||||
*
|
||||
* @template T of object
|
||||
*
|
||||
* @template-extends EntityWorkflowHandlerInterface<T>
|
||||
*/
|
||||
interface EntityWorkflowWithStoredObjectHandlerInterface extends EntityWorkflowHandlerInterface
|
||||
{
|
||||
public function getAssociatedStoredObject(EntityWorkflow $entityWorkflow): ?StoredObject;
|
||||
}
|
@ -108,12 +108,6 @@ final readonly class EntityWorkflowTransitionEventSubscriber implements EventSub
|
||||
|
||||
/** @var EntityWorkflow $entityWorkflow */
|
||||
$entityWorkflow = $event->getSubject();
|
||||
$step = $entityWorkflow->getCurrentStep();
|
||||
|
||||
$step
|
||||
->setTransitionAfter($event->getTransition()->getName())
|
||||
->setTransitionAt(new \DateTimeImmutable('now'))
|
||||
->setTransitionBy($this->security->getUser());
|
||||
|
||||
$this->chillLogger->info('[workflow] apply transition on entityWorkflow', [
|
||||
'relatedEntityClass' => $entityWorkflow->getRelatedEntityClass(),
|
||||
|
@ -51,6 +51,11 @@ class WorkflowTransitionContextDTO
|
||||
*/
|
||||
public array $futureDestEmails = [];
|
||||
|
||||
/**
|
||||
* a list of future @see{Person} with will sign the next step.
|
||||
*/
|
||||
public array $futurePersonSignatures = [];
|
||||
|
||||
public ?Transition $transition = null;
|
||||
|
||||
public string $comment = '';
|
||||
|
@ -11,15 +11,19 @@ declare(strict_types=1);
|
||||
|
||||
namespace Chill\PersonBundle\Workflow;
|
||||
|
||||
use Chill\DocStoreBundle\Entity\StoredObject;
|
||||
use Chill\MainBundle\Entity\Workflow\EntityWorkflow;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||
use Chill\MainBundle\Workflow\EntityWorkflowHandlerInterface;
|
||||
use Chill\MainBundle\Workflow\EntityWorkflowWithStoredObjectHandlerInterface;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluationDocument;
|
||||
use Chill\PersonBundle\Repository\AccompanyingPeriod\AccompanyingPeriodWorkEvaluationDocumentRepository;
|
||||
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodWorkEvaluationDocumentVoter;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
class AccompanyingPeriodWorkEvaluationDocumentWorkflowHandler implements EntityWorkflowHandlerInterface
|
||||
/**
|
||||
* @implements EntityWorkflowWithStoredObjectHandlerInterface<AccompanyingPeriodWorkEvaluationDocument>
|
||||
*/
|
||||
class AccompanyingPeriodWorkEvaluationDocumentWorkflowHandler implements EntityWorkflowWithStoredObjectHandlerInterface
|
||||
{
|
||||
public function __construct(private readonly AccompanyingPeriodWorkEvaluationDocumentRepository $repository, private readonly TranslatableStringHelperInterface $translatableStringHelper, private readonly TranslatorInterface $translator) {}
|
||||
|
||||
@ -67,8 +71,6 @@ class AccompanyingPeriodWorkEvaluationDocumentWorkflowHandler implements EntityW
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AccompanyingPeriodWorkEvaluationDocument $object
|
||||
*
|
||||
* @return array[]
|
||||
*/
|
||||
public function getRelatedObjects(object $object): array
|
||||
@ -123,4 +125,9 @@ class AccompanyingPeriodWorkEvaluationDocumentWorkflowHandler implements EntityW
|
||||
{
|
||||
return AccompanyingPeriodWorkEvaluationDocument::class === $entityWorkflow->getRelatedEntityClass();
|
||||
}
|
||||
|
||||
public function getAssociatedStoredObject(EntityWorkflow $entityWorkflow): ?StoredObject
|
||||
{
|
||||
return $this->getRelatedEntity($entityWorkflow)?->getStoredObject();
|
||||
}
|
||||
}
|
||||
|
@ -20,9 +20,16 @@ use Chill\PersonBundle\Repository\AccompanyingPeriod\AccompanyingPeriodWorkEvalu
|
||||
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodWorkEvaluationVoter;
|
||||
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 TranslatableStringHelperInterface $translatableStringHelper,
|
||||
private TranslatorInterface $translator
|
||||
) {}
|
||||
|
||||
public function getDeletionRoles(): array
|
||||
{
|
||||
@ -53,9 +60,6 @@ class AccompanyingPeriodWorkEvaluationWorkflowHandler implements EntityWorkflowH
|
||||
return $this->repository->find($entityWorkflow->getRelatedEntityId());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AccompanyingPeriodWorkEvaluation $object
|
||||
*/
|
||||
public function getRelatedObjects(object $object): array
|
||||
{
|
||||
$relateds = [];
|
||||
|
@ -21,9 +21,16 @@ use Chill\PersonBundle\Repository\AccompanyingPeriod\AccompanyingPeriodWorkRepos
|
||||
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodWorkVoter;
|
||||
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 TranslatableStringHelperInterface $translatableStringHelper,
|
||||
private TranslatorInterface $translator
|
||||
) {}
|
||||
|
||||
public function getDeletionRoles(): array
|
||||
{
|
||||
@ -55,9 +62,6 @@ class AccompanyingPeriodWorkWorkflowHandler implements EntityWorkflowHandlerInte
|
||||
return $this->repository->find($entityWorkflow->getRelatedEntityId());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AccompanyingPeriodWork $object
|
||||
*/
|
||||
public function getRelatedObjects(object $object): array
|
||||
{
|
||||
$relateds = [];
|
||||
|
Loading…
x
Reference in New Issue
Block a user