diff --git a/src/Bundle/ChillMainBundle/Controller/WorkflowSignatureCancelController.php b/src/Bundle/ChillMainBundle/Controller/WorkflowSignatureCancelController.php new file mode 100644 index 000000000..20fce559a --- /dev/null +++ b/src/Bundle/ChillMainBundle/Controller/WorkflowSignatureCancelController.php @@ -0,0 +1,69 @@ +security->isGranted(EntityWorkflowStepSignatureVoter::CANCEL, $signature)) { + throw new AccessDeniedHttpException('not allowed to cancel this signature'); + } + + $form = $this->formFactory->create(); + $form->add('confirm', SubmitType::class, ['label' => 'Confirm']); + + $form->handleRequest($request); + + if ($form->isSubmitted() && $form->isValid()) { + $this->signatureStepStateChanger->markSignatureAsCanceled($signature); + $this->entityManager->flush(); + + return new RedirectResponse( + $this->chillUrlGenerator->returnPathOr('chill_main_workflow_show', ['id' => $signature->getStep()->getEntityWorkflow()->getId()]) + ); + } + + return + new Response( + $this->twig->render( + '@ChillMain/WorkflowSignature/cancel.html.twig', + ['form' => $form->createView(), 'signature' => $signature] + ) + ); + } +} diff --git a/src/Bundle/ChillMainBundle/Entity/Workflow/EntityWorkflowStepSignature.php b/src/Bundle/ChillMainBundle/Entity/Workflow/EntityWorkflowStepSignature.php index 5b659d844..945e0d024 100644 --- a/src/Bundle/ChillMainBundle/Entity/Workflow/EntityWorkflowStepSignature.php +++ b/src/Bundle/ChillMainBundle/Entity/Workflow/EntityWorkflowStepSignature.php @@ -161,6 +161,16 @@ class EntityWorkflowStepSignature implements TrackCreationInterface, TrackUpdate return EntityWorkflowSignatureStateEnum::PENDING == $this->getState(); } + public function isCanceled(): bool + { + return EntityWorkflowSignatureStateEnum::CANCELED === $this->getState(); + } + + public function isRejected(): bool + { + return EntityWorkflowSignatureStateEnum::REJECTED === $this->getState(); + } + /** * Checks whether all signatures associated with a given workflow step are not pending. * diff --git a/src/Bundle/ChillMainBundle/Resources/views/Workflow/_signature.html.twig b/src/Bundle/ChillMainBundle/Resources/views/Workflow/_signature.html.twig index b0e401645..3cefd2a41 100644 --- a/src/Bundle/ChillMainBundle/Resources/views/Workflow/_signature.html.twig +++ b/src/Bundle/ChillMainBundle/Resources/views/Workflow/_signature.html.twig @@ -3,7 +3,7 @@
{{ s.stateDate }}
- {% endif %} -{{ 'workflow.signature.are_you_sure'|trans({'%signer%': signature.signer|chill_entity_render_string}) }}
+ + {{ form_start(form) }} + + {{ form_end(form) }} +{% endblock %} diff --git a/src/Bundle/ChillMainBundle/Security/Authorization/EntityWorkflowStepSignatureVoter.php b/src/Bundle/ChillMainBundle/Security/Authorization/EntityWorkflowStepSignatureVoter.php index 683f1352f..35a640a07 100644 --- a/src/Bundle/ChillMainBundle/Security/Authorization/EntityWorkflowStepSignatureVoter.php +++ b/src/Bundle/ChillMainBundle/Security/Authorization/EntityWorkflowStepSignatureVoter.php @@ -20,9 +20,12 @@ final class EntityWorkflowStepSignatureVoter extends Voter { public const SIGN = 'CHILL_MAIN_ENTITY_WORKFLOW_SIGNATURE_SIGN'; + public const CANCEL = 'CHILL_MAIN_ENTITY_WORKFLOW_SIGNATURE_CANCEL'; + protected function supports(string $attribute, $subject) { - return $subject instanceof EntityWorkflowStepSignature && self::SIGN === $attribute; + return $subject instanceof EntityWorkflowStepSignature + && in_array($attribute, [self::SIGN, self::CANCEL], true); } protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token) diff --git a/src/Bundle/ChillMainBundle/Workflow/SignatureStepStateChanger.php b/src/Bundle/ChillMainBundle/Workflow/SignatureStepStateChanger.php index 3e2871810..06046d111 100644 --- a/src/Bundle/ChillMainBundle/Workflow/SignatureStepStateChanger.php +++ b/src/Bundle/ChillMainBundle/Workflow/SignatureStepStateChanger.php @@ -89,6 +89,13 @@ class SignatureStepStateChanger $this->logger->info(self::LOG_PREFIX.'Transition automatically applied', ['signatureId' => $signature->getId()]); } + public function markSignatureAsCanceled(EntityWorkflowStepSignature $signature): void + { + $signature + ->setState(EntityWorkflowSignatureStateEnum::CANCELED) + ->setStateDate($this->clock->now()); + } + private function getPreviousSender(EntityWorkflowStep $entityWorkflowStep): ?User { $stepsChained = $entityWorkflowStep->getEntityWorkflow()->getStepsChained(); diff --git a/src/Bundle/ChillMainBundle/translations/messages+intl-icu.fr.yaml b/src/Bundle/ChillMainBundle/translations/messages+intl-icu.fr.yaml index a0753f7a6..7f941b13a 100644 --- a/src/Bundle/ChillMainBundle/translations/messages+intl-icu.fr.yaml +++ b/src/Bundle/ChillMainBundle/translations/messages+intl-icu.fr.yaml @@ -45,8 +45,10 @@ workflow: few {# workflows} other {# workflows} } - signature_zone: - has_signed_statement: 'A signé le {datetime, date, short} à {datetime, time, short}' + signature: + signed_statement: 'Signature appliquée le {datetime, date, short} à {datetime, time, short}' + rejected_statement: 'Signature rejectée le {datetime, date, short} à {datetime, time, short}' + canceled_statement: 'Signature annulée le {datetime, date, short} à {datetime, time, short}' duration: diff --git a/src/Bundle/ChillMainBundle/translations/messages.fr.yml b/src/Bundle/ChillMainBundle/translations/messages.fr.yml index 495b9a3bd..12ecb09a7 100644 --- a/src/Bundle/ChillMainBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillMainBundle/translations/messages.fr.yml @@ -538,6 +538,7 @@ workflow: signature_zone: title: Signatures électroniques button_sign: Signer + button_cancel: Annuler metadata: sign_by: 'Signature pour %name%' docType: Type de document @@ -550,6 +551,10 @@ workflow: user: Utilisateur already_signed_alert: La signature a déjà été appliquée + signature: + cancel_signature_of: Annulation de la signature de %signer% + are_you_sure: Êtes-vous sûr de vouloir annuler la signature de %signer% + Subscribe final: Recevoir une notification à l'étape finale Subscribe all steps: Recevoir une notification à chaque étape diff --git a/src/Bundle/ChillPersonBundle/Tests/Controller/WorkflowSignatureCancelControllerStepTest.php b/src/Bundle/ChillPersonBundle/Tests/Controller/WorkflowSignatureCancelControllerStepTest.php new file mode 100644 index 000000000..727f525d3 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Controller/WorkflowSignatureCancelControllerStepTest.php @@ -0,0 +1,86 @@ +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()); + } +}