mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-08-29 11:03:50 +00:00
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:
@@ -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;
|
||||
}, []);
|
||||
}
|
||||
}
|
@@ -0,0 +1,76 @@
|
||||
<?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 Tests\Service\Signature;
|
||||
|
||||
use Chill\DocStoreBundle\Entity\StoredObject;
|
||||
use Chill\DocStoreBundle\Service\Signature\PDFPage;
|
||||
use Chill\DocStoreBundle\Service\Signature\PDFSignatureZone;
|
||||
use Chill\DocStoreBundle\Service\Signature\PDFSignatureZoneAvailable;
|
||||
use Chill\DocStoreBundle\Service\Signature\PDFSignatureZoneParser;
|
||||
use Chill\DocStoreBundle\Service\StoredObjectManagerInterface;
|
||||
use Chill\MainBundle\Entity\Workflow\EntityWorkflow;
|
||||
use Chill\MainBundle\Entity\Workflow\EntityWorkflowSignatureStateEnum;
|
||||
use Chill\MainBundle\Workflow\EntityWorkflowManager;
|
||||
use Chill\MainBundle\Workflow\WorkflowTransitionContextDTO;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Prophecy\PhpUnit\ProphecyTrait;
|
||||
use Symfony\Component\Clock\MockClock;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @coversNothing
|
||||
*/
|
||||
class PDFSignatureZoneAvailableTest extends TestCase
|
||||
{
|
||||
use ProphecyTrait;
|
||||
|
||||
public function testGetAvailableSignatureZones(): void
|
||||
{
|
||||
$clock = new MockClock();
|
||||
|
||||
$storedObject = new StoredObject();
|
||||
$storedObject->registerVersion(type: 'application/pdf');
|
||||
|
||||
$entityWorkflow = new EntityWorkflow();
|
||||
$dto1 = new WorkflowTransitionContextDTO($entityWorkflow);
|
||||
$dto1->futurePersonSignatures[] = new Person();
|
||||
$entityWorkflow->setStep('step1', $dto1, 'transition1', $clock->now());
|
||||
$signature = $entityWorkflow->getCurrentStep()->getSignatures()->first();
|
||||
$signature->setZoneSignatureIndex(1)->setState(EntityWorkflowSignatureStateEnum::SIGNED);
|
||||
|
||||
$entityWorkflowManager = $this->prophesize(EntityWorkflowManager::class);
|
||||
$entityWorkflowManager->getAssociatedStoredObject($entityWorkflow)->willReturn($storedObject);
|
||||
|
||||
$storedObjectManager = $this->prophesize(StoredObjectManagerInterface::class);
|
||||
$storedObjectManager->read($storedObject)->willReturn('fake-content');
|
||||
|
||||
$parser = $this->prophesize(PDFSignatureZoneParser::class);
|
||||
$parser->findSignatureZones('fake-content')->willReturn([
|
||||
$zone1 = new PDFSignatureZone(1, 0.0, 10.0, 20.0, 20.0, new PDFPage(1, 500, 500)),
|
||||
$zone2 = new PDFSignatureZone(2, 0.0, 10.0, 20.0, 20.0, new PDFPage(1, 500, 500)),
|
||||
]);
|
||||
|
||||
$filter = new PDFSignatureZoneAvailable(
|
||||
$entityWorkflowManager->reveal(),
|
||||
$parser->reveal(),
|
||||
$storedObjectManager->reveal(),
|
||||
);
|
||||
|
||||
$actual = $filter->getAvailableSignatureZones($entityWorkflow);
|
||||
|
||||
self::assertNotContains($zone1, $actual);
|
||||
self::assertContains($zone2, $actual);
|
||||
self::assertCount(1, $actual, 'there should be only one remaining zone');
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user