From db94af0958b3989bfa3c4b930dc63e9bbd6468a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 10 Jul 2024 12:47:02 +0200 Subject: [PATCH] Add support for user signatures in workflow transitions This update introduces the ability to specify user signatures in workflow transitions. It allows a nullable user to be declared that may be requested to apply a signature. The code now handles the use-case of signing a transition by a user in addition to previous functionality of having it signed by a "Person" entity. Corresponding tests are also updated to validate this new feature. --- .../Entity/Workflow/EntityWorkflow.php | 17 +++++++--- .../Entity/Workflow/EntityWorkflowTest.php | 33 +++++++++++++++++++ .../Workflow/WorkflowTransitionContextDTO.php | 10 +++++- 3 files changed, 55 insertions(+), 5 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Entity/Workflow/EntityWorkflow.php b/src/Bundle/ChillMainBundle/Entity/Workflow/EntityWorkflow.php index 4b5da09db..eb187cd39 100644 --- a/src/Bundle/ChillMainBundle/Entity/Workflow/EntityWorkflow.php +++ b/src/Bundle/ChillMainBundle/Entity/Workflow/EntityWorkflow.php @@ -413,8 +413,13 @@ class EntityWorkflow implements TrackCreationInterface, TrackUpdateInterface * * @return $this */ - public function setStep(string $step, WorkflowTransitionContextDTO $transitionContextDTO, string $transition, \DateTimeImmutable $transitionAt, ?User $byUser = null): self - { + public function setStep( + string $step, + WorkflowTransitionContextDTO $transitionContextDTO, + string $transition, + \DateTimeImmutable $transitionAt, + ?User $byUser = null + ): self { $previousStep = $this->getCurrentStep(); $previousStep @@ -437,8 +442,12 @@ class EntityWorkflow implements TrackCreationInterface, TrackUpdateInterface $newStep->addDestEmail($email); } - foreach ($transitionContextDTO->futurePersonSignatures as $personSignature) { - new EntityWorkflowStepSignature($newStep, $personSignature); + if (null !== $transitionContextDTO->futureUserSignature) { + new EntityWorkflowStepSignature($newStep, $transitionContextDTO->futureUserSignature); + } else { + foreach ($transitionContextDTO->futurePersonSignatures as $personSignature) { + new EntityWorkflowStepSignature($newStep, $personSignature); + } } // copy the freeze diff --git a/src/Bundle/ChillMainBundle/Tests/Entity/Workflow/EntityWorkflowTest.php b/src/Bundle/ChillMainBundle/Tests/Entity/Workflow/EntityWorkflowTest.php index 30003144f..4eb56f995 100644 --- a/src/Bundle/ChillMainBundle/Tests/Entity/Workflow/EntityWorkflowTest.php +++ b/src/Bundle/ChillMainBundle/Tests/Entity/Workflow/EntityWorkflowTest.php @@ -13,7 +13,9 @@ namespace Chill\MainBundle\Tests\Entity\Workflow; use Chill\MainBundle\Entity\User; use Chill\MainBundle\Entity\Workflow\EntityWorkflow; +use Chill\MainBundle\Entity\Workflow\EntityWorkflowStepSignature; use Chill\MainBundle\Workflow\WorkflowTransitionContextDTO; +use Chill\PersonBundle\Entity\Person; use PHPUnit\Framework\TestCase; /** @@ -105,4 +107,35 @@ final class EntityWorkflowTest extends TestCase self::assertEquals('2024-01-02', $previous->getTransitionAt()?->format('Y-m-d')); self::assertEquals('to_step_two', $previous->getTransitionAfter()); } + + public function testSetStepSignatureForUserIsCreated() + { + $entityWorkflow = new EntityWorkflow(); + $dto = new WorkflowTransitionContextDTO($entityWorkflow); + $dto->futureUserSignature = $user = new User(); + + $entityWorkflow->setStep('new', $dto, 'to_new', new \DateTimeImmutable()); + + $actual = $entityWorkflow->getCurrentStep(); + + self::assertCount(1, $actual->getSignatures()); + self::assertSame($user, $actual->getSignatures()->first()->getSigner()); + } + + public function testSetStepSignatureForPersonIsCreated() + { + $entityWorkflow = new EntityWorkflow(); + $dto = new WorkflowTransitionContextDTO($entityWorkflow); + $dto->futurePersonSignatures[] = $person1 = new Person(); + $dto->futurePersonSignatures[] = $person2 = new Person(); + + $entityWorkflow->setStep('new', $dto, 'to_new', new \DateTimeImmutable()); + + $actual = $entityWorkflow->getCurrentStep(); + $persons = $actual->getSignatures()->map(fn (EntityWorkflowStepSignature $signature) => $signature->getSigner()); + + self::assertCount(2, $actual->getSignatures()); + self::assertContains($person1, $persons); + self::assertContains($person2, $persons); + } } diff --git a/src/Bundle/ChillMainBundle/Workflow/WorkflowTransitionContextDTO.php b/src/Bundle/ChillMainBundle/Workflow/WorkflowTransitionContextDTO.php index ba4cde51e..88bb0fa76 100644 --- a/src/Bundle/ChillMainBundle/Workflow/WorkflowTransitionContextDTO.php +++ b/src/Bundle/ChillMainBundle/Workflow/WorkflowTransitionContextDTO.php @@ -13,6 +13,7 @@ namespace Chill\MainBundle\Workflow; use Chill\MainBundle\Entity\User; use Chill\MainBundle\Entity\Workflow\EntityWorkflow; +use Chill\PersonBundle\Entity\Person; use Symfony\Component\Validator\Constraints as Assert; use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Workflow\Transition; @@ -52,10 +53,17 @@ class WorkflowTransitionContextDTO public array $futureDestEmails = []; /** - * a list of future @see{Person} with will sign the next step. + * A list of future @see{Person} with will sign the next step. + * + * @var list */ public array $futurePersonSignatures = []; + /** + * An eventual user which is requested to apply a signature. + */ + public ?User $futureUserSignature = null; + public ?Transition $transition = null; public string $comment = '';