feat(PDFBurner): support unstructured annotations and simplify processing

- Added `UnstructuredAnnotations` property to handle annotations without structured IDs
- Changed default `hasStructuredID` to `False`, set to `True` only after successful parsing
- Updated `AddInstantJSONAnnotationToPDF` to process annotations directly instead of grouping by receiver
- Simplified logic for reversing annotations and applying seal positioning
This commit is contained in:
tekh 2025-10-08 16:27:28 +02:00
parent e96523b786
commit 57422a481c
4 changed files with 51 additions and 36 deletions

View File

@ -34,7 +34,7 @@ public class RemoveHistoryHandler : INotificationHandler<RemoveSignatureNotifica
await _repo.DeleteAsync(hists await _repo.DeleteAsync(hists
=> hists => hists
.Where(hist => hist.Envelope!.Uuid == notification.EnvelopeUuid) .Where(hist => hist.Envelope!.Uuid == notification.EnvelopeUuid)
.Where(hist => hist.Status == EnvelopeStatus.DocumentSigned) .Where(hist => hist.Status == EnvelopeStatus.DocumentSigned),
, cancel); cancel);
} }
} }

View File

@ -8,6 +8,7 @@ Imports Newtonsoft.Json.Linq
Imports DigitalData.Core.Abstraction.Application Imports DigitalData.Core.Abstraction.Application
Imports EnvelopeGenerator.Infrastructure Imports EnvelopeGenerator.Infrastructure
Imports Microsoft.EntityFrameworkCore Imports Microsoft.EntityFrameworkCore
Imports System.Text
Public Class frmFinalizePDF Public Class frmFinalizePDF
Private Const CONNECTIONSTRING = "Server=sDD-VMP04-SQL17\DD_DEVELOP01;Database=DD_ECM;User Id=sa;Password=+bk8oAbbQP1AzoHtvZUbd+Mbok2f8Fl4miEx1qssJ5yEaEWoQJ9prg4L14fURpPnqi1WMNs9fE4=;" Private Const CONNECTIONSTRING = "Server=sDD-VMP04-SQL17\DD_DEVELOP01;Database=DD_ECM;User Id=sa;Password=+bk8oAbbQP1AzoHtvZUbd+Mbok2f8Fl4miEx1qssJ5yEaEWoQJ9prg4L14fURpPnqi1WMNs9fE4=;"
@ -104,7 +105,15 @@ Public Class frmFinalizePDF
Process.Start(oNewPath) Process.Start(oNewPath)
Catch ex As Exception Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.Critical) Dim exMsg As StringBuilder = New StringBuilder(ex.Message).AppendLine()
Dim innerEx = ex.InnerException
While (innerEx IsNot Nothing)
exMsg.AppendLine(innerEx.Message)
innerEx = innerEx.InnerException
End While
MsgBox(exMsg.ToString(), MsgBoxStyle.Critical)
End Try End Try
End Sub End Sub

View File

@ -71,42 +71,39 @@ Namespace Jobs.FinalizeDocument
Private Sub AddInstantJSONAnnotationToPDF(pInstantJSON As String) Private Sub AddInstantJSONAnnotationToPDF(pInstantJSON As String)
Dim oAnnotationData = JsonConvert.DeserializeObject(Of AnnotationData)(pInstantJSON) Dim oAnnotationData = JsonConvert.DeserializeObject(Of AnnotationData)(pInstantJSON)
For Each annots In oAnnotationData.AnnotationsByReceiver oAnnotationData.annotations.Reverse()
annots.Reverse() Dim yPosOfSigAnnot = oAnnotationData.annotations.ElementAt(2).bbox.ElementAt(1) - 71.84002685546875 + 7
Dim isSeal = True 'First element is signature seal
Dim yPosOfSigAnnot = annots.ElementAt(2).bbox.ElementAt(1) - 71.84002685546875 + 7 Dim formFieldIndex = 0
Dim isSeal = True 'First element is signature seal For Each oAnnotation In oAnnotationData.annotations
Logger.Debug("Adding AnnotationID: " + oAnnotation.id)
Dim formFieldIndex = 0 Select Case oAnnotation.type
For Each oAnnotation In annots Case ANNOTATION_TYPE_IMAGE
Logger.Debug("Adding AnnotationID: " + oAnnotation.id)
Select Case oAnnotation.type If (isSeal) Then
Case ANNOTATION_TYPE_IMAGE oAnnotation.bbox.Item(1) = yPosOfSigAnnot
End If
If (isSeal) Then AddImageAnnotation(oAnnotation, oAnnotationData.attachments)
oAnnotation.bbox.Item(1) = yPosOfSigAnnot Exit Select
End If
AddImageAnnotation(oAnnotation, oAnnotationData.attachments) Case ANNOTATION_TYPE_INK
Exit Select AddInkAnnotation(oAnnotation)
Exit Select
Case ANNOTATION_TYPE_INK Case ANNOTATION_TYPE_WIDGET
AddInkAnnotation(oAnnotation) 'Add form field values
Exit Select Dim formFieldValue = oAnnotationData.formFieldValues.FirstOrDefault(Function(fv) fv.name = oAnnotation.id)
If formFieldValue IsNot Nothing AndAlso Not _pdfBurnerParams.IgnoredLabels.Contains(formFieldValue.value) Then
AddFormFieldValue(oAnnotation, formFieldValue, formFieldIndex)
formFieldIndex += 1
End If
Exit Select
End Select
Case ANNOTATION_TYPE_WIDGET isSeal = False
'Add form field values
Dim formFieldValue = oAnnotationData.formFieldValues.FirstOrDefault(Function(fv) fv.name = oAnnotation.id)
If formFieldValue IsNot Nothing AndAlso Not _pdfBurnerParams.IgnoredLabels.Contains(formFieldValue.value) Then
AddFormFieldValue(oAnnotation, formFieldValue, formFieldIndex)
formFieldIndex += 1
End If
Exit Select
End Select
isSeal = False
Next
Next Next
End Sub End Sub
@ -186,6 +183,15 @@ Namespace Jobs.FinalizeDocument
End Get End Get
End Property End Property
Public ReadOnly Property UnstructuredAnnotations As IEnumerable(Of List(Of Annotation))
Get
Return annotations _
.Where(Function(annot) Not annot.hasStructuredID).ToList() _
.GroupBy(Function(a) a.receiverId) _
.Select(Function(g) g.ToList())
End Get
End Property
Public Property attachments As Dictionary(Of String, Attachment) Public Property attachments As Dictionary(Of String, Attachment)
Public Property formFieldValues As List(Of FormFieldValue) Public Property formFieldValues As List(Of FormFieldValue)
End Class End Class
@ -202,7 +208,7 @@ Namespace Jobs.FinalizeDocument
Public internalType As String = Nothing Public internalType As String = Nothing
Public hasStructuredID As Boolean = True Public hasStructuredID As Boolean = False
Public Property id As String Public Property id As String
Get Get
@ -211,14 +217,13 @@ Namespace Jobs.FinalizeDocument
Set(value As String) Set(value As String)
_id = value _id = value
If String.IsNullOrWhiteSpace(id) Then If String.IsNullOrWhiteSpace(_id) Then
Throw New BurnAnnotationException("The identifier of annotation is null or empty.") Throw New BurnAnnotationException("The identifier of annotation is null or empty.")
End If End If
Dim parts As String() = value.Split("#"c) Dim parts As String() = value.Split("#"c)
If (parts.Length <> 4) Then If (parts.Length <> 4) Then
hasStructuredID = False
Return Return
'Throw New BurnAnnotationException($"The identifier of annotation has more or less than 4 sub-part. Id: {_id}") 'Throw New BurnAnnotationException($"The identifier of annotation has more or less than 4 sub-part. Id: {_id}")
End If End If
@ -236,6 +241,8 @@ Namespace Jobs.FinalizeDocument
End If End If
internalType = parts(3) internalType = parts(3)
hasStructuredID = True
End Set End Set
End Property End Property

View File

@ -275,7 +275,6 @@ class App {
}); });
} }
async validateAnnotations(totalSignatures) { async validateAnnotations(totalSignatures) {
const annotations = await getAnnotations(this.pdfKit) const annotations = await getAnnotations(this.pdfKit)
const filtered = annotations const filtered = annotations