Add PDF signature zone availability checks

Introduce `PDFSignatureZoneAvailable` service to check available PDF signature zones. Updated `WorkflowAddSignatureController` to use the new service. Added unit tests to verify the correctness of the functionality.
This commit is contained in:
2024-09-04 13:48:46 +02:00
parent c6a6d76790
commit e17203ca3a
5 changed files with 236 additions and 25 deletions

View File

@@ -0,0 +1,69 @@
<?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\Service\Signature;
use Chill\DocStoreBundle\Service\StoredObjectManagerInterface;
use Chill\MainBundle\Entity\Workflow\EntityWorkflow;
use Chill\MainBundle\Entity\Workflow\EntityWorkflowSignatureStateEnum;
use Chill\MainBundle\Entity\Workflow\EntityWorkflowStep;
use Chill\MainBundle\Entity\Workflow\EntityWorkflowStepSignature;
use Chill\MainBundle\Workflow\EntityWorkflowManager;
class PDFSignatureZoneAvailable
{
public function __construct(
private readonly EntityWorkflowManager $entityWorkflowManager,
private readonly PDFSignatureZoneParser $pdfSignatureZoneParser,
private readonly StoredObjectManagerInterface $storedObjectManager,
) {}
/**
* @return list<PDFSignatureZone>
*/
public function getAvailableSignatureZones(EntityWorkflow $entityWorkflow): array
{
$storedObject = $this->entityWorkflowManager->getAssociatedStoredObject($entityWorkflow);
if (null === $storedObject) {
throw new \RuntimeException('No stored object found');
}
if ('application/pdf' !== $storedObject->getType()) {
throw new \RuntimeException('Only PDF documents are supported');
}
$zones = $this->pdfSignatureZoneParser->findSignatureZones($this->storedObjectManager->read($storedObject));
$signatureZonesIndexes = array_map(
fn (EntityWorkflowStepSignature $step) => $step->getZoneSignatureIndex(),
$this->collectSignaturesInUse($entityWorkflow)
);
return array_filter($zones, fn (PDFSignatureZone $zone) => !in_array($zone->index, $signatureZonesIndexes, true));
}
/**
* @return list<EntityWorkflowStepSignature>
*/
private function collectSignaturesInUse(EntityWorkflow $entityWorkflow): array
{
return array_reduce($entityWorkflow->getSteps()->toArray(), function (array $result, EntityWorkflowStep $step) {
$current = [...$result];
foreach ($step->getSignatures() as $signature) {
if (EntityWorkflowSignatureStateEnum::SIGNED === $signature->getState()) {
$current[] = $signature;
}
}
return $current;
}, []);
}
}