Refactor PDF signature handling and add signature state changer

Simplified PdfSignedMessageHandler by delegating signature state changes to a new SignatureStepStateChanger class. Added utility method to EntityWorkflowStepSignature for checking pending signatures and created new test cases for the SignatureStepStateChanger.
This commit is contained in:
nobohan
2024-07-18 17:13:47 +02:00
committed by Julien Fastré
parent 00e878892e
commit 1197a46f5f
5 changed files with 276 additions and 10 deletions

View File

@@ -0,0 +1,96 @@
<?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\MainBundle\Entity\User;
use Chill\MainBundle\Entity\Workflow\EntityWorkflowSignatureStateEnum;
use Chill\MainBundle\Entity\Workflow\EntityWorkflowStep;
use Chill\MainBundle\Entity\Workflow\EntityWorkflowStepSignature;
use Symfony\Component\Clock\ClockInterface;
use Symfony\Component\Workflow\Registry;
class SignatureStepStateChanger
{
public function __construct(
private readonly Registry $registry,
private readonly ClockInterface $clock,
) {}
public function markSignatureAsSigned(EntityWorkflowStepSignature $signature, ?int $atIndex): void
{
$signature
->setState(EntityWorkflowSignatureStateEnum::SIGNED)
->setZoneSignatureIndex($atIndex)
->setStateDate($this->clock->now())
;
if (!EntityWorkflowStepSignature::isAllSignatureNotPendingForStep($signature->getStep())) {
return;
}
$entityWorkflow = $signature->getStep()->getEntityWorkflow();
$workflow = $this->registry->get($entityWorkflow, $entityWorkflow->getWorkflowName());
$metadataStore = $workflow->getMetadataStore();
// find a transition
$marking = $workflow->getMarking($entityWorkflow);
$places = $marking->getPlaces();
$transition = null;
foreach ($places as $place => $int) {
$metadata = $metadataStore->getPlaceMetadata($place);
if (array_key_exists('onSignatureCompleted', $metadata)) {
$transition = $metadata['onSignatureCompleted']['transitionName'];
}
}
if (null === $transition) {
return;
}
$previousUser = $this->getPreviousSender($signature->getStep());
if (null === $previousUser) {
return;
}
$transitionDto = new WorkflowTransitionContextDTO($entityWorkflow);
$transitionDto->futureDestUsers[] = $previousUser;
$workflow->apply($entityWorkflow, $transition, [
'context' => $transitionDto,
'transitionAt' => $this->clock->now(),
'transition' => $transition,
]);
}
private function getPreviousSender(EntityWorkflowStep $entityWorkflowStep): ?User
{
$stepsChained = $entityWorkflowStep->getEntityWorkflow()->getStepsChained();
foreach ($stepsChained as $stepChained) {
if ($stepChained === $entityWorkflowStep) {
if (null === $previous = $stepChained->getPrevious()) {
return null;
}
if (null !== $previousUser = $previous->getTransitionBy()) {
return $previousUser;
}
return $this->getPreviousSender($previous);
}
}
throw new \LogicException('no same step found');
}
}