From a798f737f16bfd96fcf3d7b117ae30878c617cfe Mon Sep 17 00:00:00 2001 From: Vitor Mattos <1079143+vitormattos@users.noreply.github.com> Date: Tue, 30 Dec 2025 14:10:38 -0300 Subject: [PATCH] fix: refactor envelope signing flow and envelope status propagation - Remove unnecessary state saving/restoration in sign() method - Extract buildEnvelopeSignRequests() for envelope-specific logic - Create getEnvelopeContext() to resolve envelope and its sign request - Fix envelope status not updating when all children are signed - Ensure envelope sign_request is marked as SIGNED with timestamp - Improve envelope resolution via parent lookup and identify method matching - Simplify sign() to use envelope context from getEnvelopeContext() - Separate concerns: getSignRequestsToSign() handles requests only - Eliminate code duplication in envelope resolution logic Fixes: Envelope remains unsigned when all child files are signed Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com> --- lib/Service/SignFileService.php | 114 +++++++++++++++++++++----------- 1 file changed, 75 insertions(+), 39 deletions(-) diff --git a/lib/Service/SignFileService.php b/lib/Service/SignFileService.php index 94b767337e..8e7e6f5c43 100644 --- a/lib/Service/SignFileService.php +++ b/lib/Service/SignFileService.php @@ -325,17 +325,14 @@ public function getVisibleElements(): array { } public function sign(): void { - $originalLibreSignFile = $this->libreSignFile; - $originalSignRequest = $this->signRequest; - $envelopeLastSignedDate = null; - $lastSignedFile = null; - $signRequests = $this->getSignRequestsToSign(); if (empty($signRequests)) { throw new LibresignException('No sign requests found to process'); } + $envelopeLastSignedDate = null; + foreach ($signRequests as $signRequestData) { $this->libreSignFile = $signRequestData['file']; $this->signRequest = $signRequestData['signRequest']; @@ -345,7 +342,6 @@ public function sign(): void { $this->validateDocMdpAllowsSignatures(); $signedFile = $this->getEngine()->sign(); - $lastSignedFile = $signedFile; $hash = $this->computeHash($signedFile); $envelopeLastSignedDate = $this->getEngine()->getLastSignedDate(); @@ -356,36 +352,20 @@ public function sign(): void { $this->dispatchSignedEvent(); } - $this->libreSignFile = $originalLibreSignFile; - $this->signRequest = $originalSignRequest; - - if ($originalLibreSignFile->isEnvelope()) { - if ($envelopeLastSignedDate) { - $this->signRequest->setSigned($envelopeLastSignedDate); - $this->signRequest->setStatusEnum(\OCA\Libresign\Enum\SignRequestStatus::SIGNED); - $this->signRequestMapper->update($this->signRequest); - $this->sequentialSigningService - ->setFile($this->libreSignFile) - ->releaseNextOrder( - $this->signRequest->getFileId(), - $this->signRequest->getSigningOrder() - ); - } - $this->updateEnvelopeStatus(); - - if ($lastSignedFile instanceof File) { - $event = $this->signedEventFactory->make( - $this->signRequest, - $this->libreSignFile, - $lastSignedFile, - ); - $this->eventDispatcher->dispatchTyped($event); - } + $envelopeContext = $this->getEnvelopeContext(); + if ($envelopeContext['envelope'] instanceof FileEntity) { + $this->updateEnvelopeStatus( + $envelopeContext['envelope'], + $envelopeContext['envelopeSignRequest'] ?? null, + $envelopeLastSignedDate + ); } } /** - * @return array Array of ['file' => FileEntity, 'signRequest' => SignRequestEntity] + * Get sign requests to process. + * + * @return array Array of sign request data with 'file' => FileEntity, 'signRequest' => SignRequestEntity */ private function getSignRequestsToSign(): array { if (!$this->libreSignFile->isEnvelope() @@ -397,6 +377,13 @@ private function getSignRequestsToSign(): array { ]]; } + return $this->buildEnvelopeSignRequests(); + } + + /** + * @return array Array of sign request data with 'file' => FileEntity, 'signRequest' => SignRequestEntity + */ + private function buildEnvelopeSignRequests(): array { $envelopeId = $this->libreSignFile->isEnvelope() ? $this->libreSignFile->getId() : $this->libreSignFile->getParentFileId(); @@ -433,8 +420,46 @@ private function getSignRequestsToSign(): array { return $signRequestsData; } - private function updateEnvelopeStatus(): void { - $childFiles = $this->fileMapper->getChildrenFiles($this->libreSignFile->getId()); + /** + * Get envelope context if the current file is or belongs to an envelope. + * + * @return array Array with 'envelope' => FileEntity or null, 'envelopeSignRequest' => SignRequestEntity or null + */ + private function getEnvelopeContext(): array { + $result = [ + 'envelope' => null, + 'envelopeSignRequest' => null, + ]; + + if (!$this->libreSignFile->isEnvelope() && !$this->libreSignFile->hasParent()) { + return $result; + } + + if ($this->libreSignFile->isEnvelope()) { + $result['envelope'] = $this->libreSignFile; + $result['envelopeSignRequest'] = $this->signRequest; + return $result; + } + + try { + $envelopeId = $this->libreSignFile->isEnvelope() + ? $this->libreSignFile->getId() + : $this->libreSignFile->getParentFileId(); + $result['envelope'] = $this->fileMapper->getById($envelopeId); + $identifyMethod = $this->identifyMethodService->getIdentifiedMethod($this->signRequest->getId()); + $result['envelopeSignRequest'] = $this->signRequestMapper->getByIdentifyMethodAndFileId( + $identifyMethod, + $result['envelope']->getId() + ); + } catch (DoesNotExistException $e) { + // Envelope not found or sign request not found, leave as null + } + + return $result; + } + + private function updateEnvelopeStatus(FileEntity $envelope, ?SignRequestEntity $envelopeSignRequest = null, ?DateTimeInterface $signedDate = null): void { + $childFiles = $this->fileMapper->getChildrenFiles($envelope->getId()); $totalSignRequests = 0; $signedSignRequests = 0; @@ -451,16 +476,27 @@ private function updateEnvelopeStatus(): void { } if ($totalSignRequests === 0) { - $this->libreSignFile->setStatus(FileEntity::STATUS_DRAFT); + $envelope->setStatus(FileEntity::STATUS_DRAFT); } elseif ($signedSignRequests === 0) { - $this->libreSignFile->setStatus(FileEntity::STATUS_ABLE_TO_SIGN); + $envelope->setStatus(FileEntity::STATUS_ABLE_TO_SIGN); } elseif ($signedSignRequests === $totalSignRequests) { - $this->libreSignFile->setStatus(FileEntity::STATUS_SIGNED); + $envelope->setStatus(FileEntity::STATUS_SIGNED); + if ($envelopeSignRequest instanceof SignRequestEntity) { + $envelopeSignRequest->setSigned($signedDate ?: new DateTime()); + $envelopeSignRequest->setStatusEnum(\OCA\Libresign\Enum\SignRequestStatus::SIGNED); + $this->signRequestMapper->update($envelopeSignRequest); + $this->sequentialSigningService + ->setFile($envelope) + ->releaseNextOrder( + $envelopeSignRequest->getFileId(), + $envelopeSignRequest->getSigningOrder() + ); + } } else { - $this->libreSignFile->setStatus(FileEntity::STATUS_PARTIAL_SIGNED); + $envelope->setStatus(FileEntity::STATUS_PARTIAL_SIGNED); } - $this->fileMapper->update($this->libreSignFile); + $this->fileMapper->update($envelope); } /**