refactor(EnvelopeGenerator.Common): umbenennen in EnvelopeGenerator.CommonService
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
Namespace Jobs.FinalizeDocument
|
||||
Public Class FinalizeDocumentExceptions
|
||||
|
||||
Public Class MergeDocumentException
|
||||
Inherits ApplicationException
|
||||
|
||||
Public Sub New(message As String)
|
||||
MyBase.New(message)
|
||||
End Sub
|
||||
|
||||
Public Sub New(message As String, innerException As Exception)
|
||||
MyBase.New(message, innerException)
|
||||
End Sub
|
||||
End Class
|
||||
|
||||
Public Class BurnAnnotationException
|
||||
Inherits ApplicationException
|
||||
|
||||
Public Sub New(message As String)
|
||||
MyBase.New(message)
|
||||
End Sub
|
||||
|
||||
Public Sub New(message As String, innerException As Exception)
|
||||
MyBase.New(message, innerException)
|
||||
End Sub
|
||||
End Class
|
||||
|
||||
Public Class CreateReportException
|
||||
Inherits ApplicationException
|
||||
|
||||
Public Sub New(message As String)
|
||||
MyBase.New(message)
|
||||
End Sub
|
||||
|
||||
Public Sub New(message As String, innerException As Exception)
|
||||
MyBase.New(message, innerException)
|
||||
End Sub
|
||||
End Class
|
||||
Public Class ExportDocumentException
|
||||
Inherits ApplicationException
|
||||
|
||||
Public Sub New(message As String)
|
||||
MyBase.New(message)
|
||||
End Sub
|
||||
|
||||
Public Sub New(message As String, innerException As Exception)
|
||||
MyBase.New(message, innerException)
|
||||
End Sub
|
||||
End Class
|
||||
|
||||
End Class
|
||||
End Namespace
|
||||
@@ -0,0 +1,456 @@
|
||||
Imports DigitalData.Modules.Database
|
||||
Imports DigitalData.Modules.Logging
|
||||
Imports DigitalData.Modules.Base
|
||||
Imports GdPicture14
|
||||
Imports Quartz
|
||||
Imports System.Security.Cryptography
|
||||
Imports System.IO
|
||||
Imports EnvelopeGenerator.CommonServices.Jobs.FinalizeDocument.FinalizeDocumentExceptions
|
||||
Imports EnvelopeGenerator.CommonServices.Jobs.FinalizeDocument
|
||||
Imports EnvelopeGenerator.Domain.Constants
|
||||
Imports DevExpress.DataProcessing
|
||||
Imports System.Data.SqlClient
|
||||
Imports EnvelopeGenerator.Domain.Entities
|
||||
|
||||
Namespace Jobs
|
||||
Public Class FinalizeDocumentJob
|
||||
Implements IJob
|
||||
|
||||
Private ReadOnly LicenseManager As New LicenseManager()
|
||||
Private GdViewer As GdViewer
|
||||
|
||||
Private LogConfig As LogConfig
|
||||
Private Logger As Logger
|
||||
Private Database As MSSQLServer
|
||||
Private Config As DbConfig
|
||||
|
||||
Private ConfigModel As ConfigModel
|
||||
Private EnvelopeModel As EnvelopeModel
|
||||
Private ReportModel As ReportModel
|
||||
|
||||
Private ActionService As ActionService
|
||||
|
||||
Private PDFBurner As PDFBurner
|
||||
Private PDFMerger As PDFMerger
|
||||
Private ReportCreator As ReportCreator
|
||||
|
||||
Private ReadOnly CompleteWaitTime As Integer = 1
|
||||
Private ParentFolderUID As String = ""
|
||||
Private myTempFiles As TempFiles
|
||||
|
||||
Private Class EnvelopeData
|
||||
Public EnvelopeId As Integer
|
||||
Public EnvelopeUUID As String
|
||||
Public DocumentPath As String
|
||||
Public AnnotationData As List(Of String)
|
||||
Public DocAsByte As Byte()
|
||||
|
||||
End Class
|
||||
|
||||
Public Function Execute(pContext As IJobExecutionContext) As Task Implements IJob.Execute
|
||||
Dim oGdPictureKey As String = pContext.MergedJobDataMap.Item(Domain.Constants.GDPICTURE)
|
||||
LogConfig = pContext.MergedJobDataMap.Item(Domain.Constants.LOGCONFIG)
|
||||
Logger = LogConfig.GetLogger()
|
||||
myTempFiles = New TempFiles(LogConfig)
|
||||
myTempFiles.Create()
|
||||
Dim JobId = pContext.JobDetail.Key
|
||||
Logger.Debug("Starting job {0}", JobId)
|
||||
|
||||
Try
|
||||
Logger.Debug("Loading GdViewer..")
|
||||
GdViewer = New GdViewer()
|
||||
LicenseManager.RegisterKEY(oGdPictureKey)
|
||||
|
||||
Logger.Debug("Loading Database..")
|
||||
Database = GetDatabase(pContext, LogConfig)
|
||||
|
||||
Logger.Debug("Loading Models & Services")
|
||||
Dim oState = GetState()
|
||||
InitializeModels(oState)
|
||||
|
||||
Logger.Debug("Loading Configuration..")
|
||||
Config = ConfigModel.LoadConfiguration()
|
||||
oState.DbConfig = Config
|
||||
|
||||
InitializeServices(oState)
|
||||
|
||||
Logger.Debug("Loading PDFBurner..")
|
||||
Dim pdfBurnerParams As PDFBurnerParams = pContext.MergedJobDataMap.Item(PDF_BURNER_PARAMS)
|
||||
PDFBurner = New PDFBurner(LogConfig, oGdPictureKey, pdfBurnerParams)
|
||||
|
||||
Logger.Debug("Loading PDFMerger..")
|
||||
PDFMerger = New PDFMerger(LogConfig, oGdPictureKey)
|
||||
|
||||
Logger.Debug("Loading ReportCreator..")
|
||||
ReportCreator = New ReportCreator(LogConfig, oState)
|
||||
|
||||
Config.DocumentPath = Config.DocumentPath
|
||||
|
||||
Logger.Debug("DocumentPath: [{0}]", Config.DocumentPath)
|
||||
|
||||
|
||||
Logger.Debug("ExportPath: [{0}]", Config.ExportPath)
|
||||
|
||||
Dim oCompleteStatus As Integer = EnvelopeStatus.EnvelopeCompletelySigned
|
||||
Dim oSql = $"SELECT * FROM TBSIG_ENVELOPE WHERE STATUS = {oCompleteStatus} AND DATEDIFF(minute, CHANGED_WHEN, GETDATE()) >= {CompleteWaitTime} ORDER BY GUID"
|
||||
Dim oTable = Database.GetDatatable(oSql)
|
||||
|
||||
Dim oEnvelopeIds As List(Of Integer) = oTable.Rows.Cast(Of DataRow).
|
||||
Select(Function(r) r.Item("GUID")).
|
||||
Cast(Of Integer).
|
||||
ToList()
|
||||
|
||||
If oEnvelopeIds.Count > 0 Then
|
||||
Logger.Info("Found [{0}] completed envelopes.", oEnvelopeIds.Count)
|
||||
End If
|
||||
|
||||
Dim oTotal As Integer = oEnvelopeIds.Count
|
||||
Dim oCurrent As Integer = 1
|
||||
|
||||
For Each oId In oEnvelopeIds
|
||||
Logger.Info("Finalizing Envelope [{0}] ({1}/{2})", oId, oCurrent, oTotal)
|
||||
Try
|
||||
Dim oEnvelope = EnvelopeModel.GetById(oId)
|
||||
If oEnvelope Is Nothing Then
|
||||
Logger.Warn("Envelope could not be loaded for Id [{0}]!", oId)
|
||||
Throw New ArgumentNullException("EnvelopeData")
|
||||
End If
|
||||
Logger.Debug("Loading Envelope Data..")
|
||||
Dim oEnvelopeData = GetEnvelopeData(oId)
|
||||
|
||||
If oEnvelopeData Is Nothing Then
|
||||
Logger.Warn("EnvelopeData could not be loaded for Id [{0}]!", oId)
|
||||
Throw New ArgumentNullException("EnvelopeData")
|
||||
End If
|
||||
Logger.Debug("Burning Annotations to pdf ...")
|
||||
Dim oBurnedDocument As Byte() = BurnAnnotationsToPdf(oEnvelopeData)
|
||||
If oBurnedDocument Is Nothing Then
|
||||
Logger.Warn("Document could not be finalized!")
|
||||
Throw New ApplicationException("Document could not be finalized")
|
||||
End If
|
||||
|
||||
If ActionService.CreateReport(oEnvelope) = False Then
|
||||
Logger.Warn("Document Report could not be created!")
|
||||
Throw New ApplicationException("Document Report could not be created")
|
||||
End If
|
||||
|
||||
Logger.Debug("Creating report..")
|
||||
Dim oReport As Byte() = ReportCreator.CreateReport(oEnvelope)
|
||||
Logger.Debug("Report created!")
|
||||
|
||||
Logger.Debug("Merging documents ...")
|
||||
Dim oMergedDocument As Byte() = PDFMerger.MergeDocuments(oBurnedDocument, oReport)
|
||||
Logger.Debug("Documents merged!")
|
||||
|
||||
Dim oOutputDirectoryPath = Path.Combine(Config.ExportPath, ParentFolderUID)
|
||||
If Not Directory.Exists(oOutputDirectoryPath) Then
|
||||
Directory.CreateDirectory(oOutputDirectoryPath)
|
||||
End If
|
||||
Dim oOutputFilePath = Path.Combine(oOutputDirectoryPath, $"{oEnvelope.Uuid}.pdf")
|
||||
Logger.Debug("Writing finalized Pdf to disk..")
|
||||
Logger.Info("Output path is [{0}]", oOutputFilePath)
|
||||
|
||||
Try
|
||||
File.WriteAllBytes(oOutputFilePath, oMergedDocument)
|
||||
Catch ex As Exception
|
||||
Logger.Warn("Could not export final document to disk!")
|
||||
Throw New ExportDocumentException("Could not export final document to disk!", ex)
|
||||
End Try
|
||||
|
||||
Logger.Debug("Writing EB-bytes to database...")
|
||||
Update_File_DB(oOutputFilePath, oEnvelope.Id)
|
||||
|
||||
|
||||
If SendFinalEmails(oEnvelope) = False Then ', oOutputFilePath
|
||||
Throw New ApplicationException("Final emails could not be sent!")
|
||||
Else
|
||||
Logger.Info("Report-mails successfully sent!")
|
||||
End If
|
||||
Logger.Debug("Setting envelope status..")
|
||||
If ActionService.FinalizeEnvelope(oEnvelope) = False Then
|
||||
Logger.Warn("Envelope could not be finalized!")
|
||||
Throw New ApplicationException("Envelope could not be finalized")
|
||||
End If
|
||||
Catch ex As Exception
|
||||
Logger.Warn(ex, $"Unhandled exception while working envelope [{oId}]")
|
||||
End Try
|
||||
|
||||
|
||||
oCurrent += 1
|
||||
Logger.Info($"Envelope [{oId}] finalized!")
|
||||
|
||||
Next
|
||||
|
||||
Logger.Debug("Completed job {0} successfully!", JobId)
|
||||
Catch ex As MergeDocumentException
|
||||
Logger.Warn("Certificate Document job failed at step: Merging documents!")
|
||||
Logger.Error(ex)
|
||||
|
||||
Catch ex As ExportDocumentException
|
||||
Logger.Warn("Certificate Document job failed at step: Exporting document!")
|
||||
Logger.Error(ex)
|
||||
|
||||
Catch ex As Exception
|
||||
Logger.Warn("Certificate Document job failed!")
|
||||
Logger.Error(ex)
|
||||
Finally
|
||||
Logger.Debug("Job execution for [{0}] ended", JobId)
|
||||
End Try
|
||||
|
||||
Return Task.FromResult(True)
|
||||
End Function
|
||||
Private Sub Update_File_DB(pFilePath As String, pEnvelopeID As Long)
|
||||
Dim SqlCom As SqlCommand
|
||||
Dim imageData As Byte()
|
||||
Dim sFileName As String
|
||||
Dim qry As String
|
||||
|
||||
Try
|
||||
'Read Image Bytes into a byte array
|
||||
'Initialize SQL Server Connection
|
||||
|
||||
'Convert File to bytes Array
|
||||
imageData = ReadFile(pFilePath)
|
||||
If Not IsNothing(imageData) Then
|
||||
sFileName = System.IO.Path.GetFileName(pFilePath)
|
||||
'Set insert query
|
||||
qry = $"UPDATE TBSIG_ENVELOPE SET DOC_RESULT = @ImageData WHERE GUID = {pEnvelopeID}"
|
||||
'Initialize SqlCommand object for insert.
|
||||
SqlCom = New SqlCommand(qry, Database.GetConnection)
|
||||
'We are passing File Name and Image byte data as sql parameters.
|
||||
SqlCom.Parameters.Add(New SqlParameter("@ImageData", DirectCast(imageData, Object)))
|
||||
'Execute the Query
|
||||
SqlCom.ExecuteNonQuery()
|
||||
End If
|
||||
|
||||
Catch ex As Exception
|
||||
Logger.Error(ex)
|
||||
End Try
|
||||
End Sub
|
||||
'Open file in to a filestream and read data in a byte array.
|
||||
Private Function ReadFile(ByVal sPath As String) As Byte()
|
||||
'Initialize byte array with a null value initially.
|
||||
Dim data As Byte() = Nothing
|
||||
'Use FileInfo object to get file size.
|
||||
Dim fInfo As New FileInfo(sPath)
|
||||
Dim numBytes As Long = fInfo.Length
|
||||
'Open FileStream to read file
|
||||
Dim fStream As New FileStream(sPath, FileMode.Open, FileAccess.Read)
|
||||
'Use BinaryReader to read file stream into byte array.
|
||||
Dim br As New BinaryReader(fStream)
|
||||
'When you use BinaryReader, you need to supply number of bytes to read from file.
|
||||
'In this case we want to read entire file. So supplying total number of bytes.
|
||||
data = br.ReadBytes(CInt(numBytes))
|
||||
Return data
|
||||
End Function
|
||||
'Private Function NetUse_Command(pDestinationPath As String, pUsername As String, pPassword As String)
|
||||
' Dim oDectryptedPW = Helpers.Decrypt(My.Settings.NetUse_PW)
|
||||
' Dim netUseCommand As String = $"net use {pDestinationPath} /user:{pUsername} {oDectryptedPW}"
|
||||
' Logger.Debug("EXECUTING NetUse_Command for " & pDestinationPath)
|
||||
' Dim processInfo As New ProcessStartInfo("cmd.exe", $"/C {netUseCommand}")
|
||||
' processInfo.RedirectStandardOutput = True
|
||||
' processInfo.UseShellExecute = False
|
||||
' processInfo.CreateNoWindow = True
|
||||
|
||||
' Using process As Process = Process.Start(processInfo)
|
||||
' process.WaitForExit()
|
||||
|
||||
' ' Prüfe den Rückgabewert des net use Befehls
|
||||
' If process.ExitCode = 0 Then
|
||||
' Return True
|
||||
' Else
|
||||
' Return False
|
||||
' End If
|
||||
' End Using
|
||||
'End Function
|
||||
|
||||
'Private Function Clean_DNZ_PAth(pSourcePath As String) As Boolean
|
||||
' Dim oFilename = System.IO.Path.GetFileName(pSourcePath)
|
||||
|
||||
' Logger.Debug("## Starting Clean_DNZ_PAth ...")
|
||||
' Logger.Debug("## pSourcePath {0}", pSourcePath)
|
||||
|
||||
' Dim oDirectorySource = Path.Combine(pSourcePath, ParentFolderUID)
|
||||
|
||||
' Try
|
||||
' Logger.Debug($"Deleting oDirectorySource {oDirectorySource} ...")
|
||||
' Directory.Delete(oDirectorySource, True)
|
||||
' Console.WriteLine($"Folder successfully deleted!")
|
||||
' Logger.Debug($"...Deleted!")
|
||||
' Return True
|
||||
' Catch ex As Exception
|
||||
' Logger.Error(ex)
|
||||
' Return False
|
||||
' End Try
|
||||
|
||||
|
||||
'End Function
|
||||
Private Function SendFinalEmails(pEnvelope As Envelope) As Boolean ', pAttachment As String
|
||||
Dim oMailToCreator = pEnvelope.FinalEmailToCreator
|
||||
Dim oMailToReceivers = pEnvelope.FinalEmailToReceivers
|
||||
|
||||
If oMailToCreator <> FinalEmailType.No Then
|
||||
Logger.Debug("Sending email to creator ...")
|
||||
SendFinalEmailToCreator(pEnvelope) ', pAttachment
|
||||
Else
|
||||
Logger.Warn($"No SendFinalEmailToCreator - oMailToCreator [{oMailToCreator}] <> [{FinalEmailType.No}] ")
|
||||
End If
|
||||
|
||||
If oMailToReceivers <> FinalEmailType.No Then
|
||||
Logger.Debug("Sending emails to receivers..")
|
||||
SendFinalEmailToReceivers(pEnvelope) ', pAttachment
|
||||
Else
|
||||
Logger.Warn($"No SendFinalEmailToReceivers - oMailToCreator [{oMailToReceivers}] <> [{FinalEmailType.No}] ")
|
||||
End If
|
||||
|
||||
Return True
|
||||
End Function
|
||||
|
||||
Private Function SendFinalEmailToCreator(pEnvelope As Envelope) As Boolean ', pAttachment As String
|
||||
Dim oIncludeAttachment = SendFinalEmailWithAttachment(pEnvelope.FinalEmailToCreator)
|
||||
' Dim oAttachment = String.Empty
|
||||
|
||||
Logger.Debug("Attachment included: [{0}]", oIncludeAttachment)
|
||||
If oIncludeAttachment Then
|
||||
'oAttachment = pAttachment
|
||||
End If
|
||||
|
||||
If ActionService.CompleteEnvelope(pEnvelope) = False Then ', oAttachment
|
||||
Logger.Error("Envelope could not be completed for receiver [{0}]", pEnvelope.User.Email)
|
||||
Return False
|
||||
End If
|
||||
|
||||
Return True
|
||||
End Function
|
||||
|
||||
Private Function SendFinalEmailToReceivers(pEnvelope As Envelope) As Boolean ', pAttachment As String
|
||||
Dim oIncludeAttachment = SendFinalEmailWithAttachment(pEnvelope.FinalEmailToReceivers)
|
||||
'Dim oAttachment = String.Empty
|
||||
|
||||
Logger.Debug("Attachment included: [{0}]", oIncludeAttachment)
|
||||
If oIncludeAttachment Then
|
||||
|
||||
' oAttachment = pAttachment
|
||||
End If
|
||||
|
||||
For Each oReceiver In pEnvelope.Receivers
|
||||
If ActionService.CompleteEnvelope(pEnvelope, oReceiver) = False Then ', oAttachment
|
||||
Logger.Error("Envelope could not be completed for receiver [{0}]", oReceiver.EmailAddress)
|
||||
Return False
|
||||
End If
|
||||
Next
|
||||
|
||||
Return True
|
||||
End Function
|
||||
|
||||
Private Function SendFinalEmailWithAttachment(pType As FinalEmailType)
|
||||
If pType = FinalEmailType.YesWithAttachment Then
|
||||
Return True
|
||||
Else
|
||||
Return False
|
||||
End If
|
||||
End Function
|
||||
|
||||
Private Function BurnAnnotationsToPdf(pEnvelopeData As EnvelopeData) As Byte()
|
||||
Dim pEnvelopeId = pEnvelopeData.EnvelopeId
|
||||
|
||||
Logger.Info($"Burning [{pEnvelopeData.AnnotationData.Count}] signatures")
|
||||
Dim oAnnotations = pEnvelopeData.AnnotationData
|
||||
Dim oInputPath = ""
|
||||
If IsNothing(pEnvelopeData.DocAsByte) Then
|
||||
oInputPath = pEnvelopeData.DocumentPath
|
||||
Logger.Info($"Input path: [{oInputPath}]")
|
||||
Else
|
||||
Logger.Debug($"we got bytes..")
|
||||
oInputPath = Config.DocumentPathOrigin
|
||||
Logger.Debug($"oInputPath: {Config.DocumentPathOrigin}")
|
||||
End If
|
||||
|
||||
|
||||
If IsNothing(pEnvelopeData.DocAsByte) Then
|
||||
Dim oDirectorySource As String = Path.GetDirectoryName(oInputPath)
|
||||
Dim split As String() = oDirectorySource.Split("\")
|
||||
ParentFolderUID = split(split.Length - 1)
|
||||
Else
|
||||
ParentFolderUID = pEnvelopeData.EnvelopeUUID
|
||||
End If
|
||||
|
||||
|
||||
Logger.Info("ParentFolderUID: [{0}]", ParentFolderUID)
|
||||
Dim oInputDocumentBuffer As Byte()
|
||||
If Not IsNothing(pEnvelopeData.DocAsByte) Then
|
||||
oInputDocumentBuffer = pEnvelopeData.DocAsByte
|
||||
Else
|
||||
Try
|
||||
oInputDocumentBuffer = File.ReadAllBytes(oInputPath)
|
||||
Catch ex As Exception
|
||||
Throw New BurnAnnotationException("Source document could not be read from disk!", ex)
|
||||
End Try
|
||||
End If
|
||||
|
||||
Return PDFBurner.BurnInstantJSONAnnotationsToPDF(oInputDocumentBuffer, oAnnotations)
|
||||
End Function
|
||||
|
||||
Private Function GetEnvelopeData(pEnvelopeId As Integer) As EnvelopeData
|
||||
Dim oSql = $"SELECT T.GUID, T.ENVELOPE_UUID,T2.FILEPATH, T2.BYTE_DATA FROM [dbo].[TBSIG_ENVELOPE] T
|
||||
JOIN TBSIG_ENVELOPE_DOCUMENT T2 ON T.GUID = T2.ENVELOPE_ID
|
||||
WHERE T.GUID = {pEnvelopeId}"
|
||||
Dim oTable As DataTable = Database.GetDatatable(oSql)
|
||||
Dim oRow As DataRow = oTable.Rows.Cast(Of DataRow).SingleOrDefault()
|
||||
If oRow Is Nothing Then
|
||||
Return Nothing
|
||||
End If
|
||||
|
||||
Dim oAnnotationData = GetAnnotationData(pEnvelopeId)
|
||||
Dim oData As New EnvelopeData With {
|
||||
.EnvelopeId = pEnvelopeId,
|
||||
.DocumentPath = oRow.ItemEx("FILEPATH", ""),
|
||||
.AnnotationData = oAnnotationData,
|
||||
.DocAsByte = DirectCast(oRow.Item("BYTE_DATA"), Byte()),
|
||||
.EnvelopeUUID = oRow.ItemEx("ENVELOPE_UUID", "")
|
||||
}
|
||||
|
||||
Logger.Debug("Document path: [{0}]", oData.DocumentPath)
|
||||
|
||||
Return oData
|
||||
End Function
|
||||
|
||||
Private Function GetAnnotationData(pEnvelopeId As Integer) As List(Of String)
|
||||
Dim oSql = $"SELECT VALUE FROM TBSIG_DOCUMENT_STATUS WHERE ENVELOPE_ID = {pEnvelopeId}"
|
||||
Dim oTable As DataTable = Database.GetDatatable(oSql)
|
||||
|
||||
Return oTable.Rows.Cast(Of DataRow).
|
||||
Select(Function(r) r.ItemEx("VALUE", String.Empty)).
|
||||
Cast(Of String).
|
||||
ToList()
|
||||
|
||||
End Function
|
||||
|
||||
Private Sub InitializeServices(pState As State)
|
||||
ActionService = New ActionService(pState, Database)
|
||||
End Sub
|
||||
|
||||
Private Sub InitializeModels(pState As State)
|
||||
ConfigModel = New ConfigModel(pState)
|
||||
EnvelopeModel = New EnvelopeModel(pState)
|
||||
ReportModel = New ReportModel(pState)
|
||||
End Sub
|
||||
|
||||
Private Function GetDatabase(pContext As IJobExecutionContext, pLogConfig As LogConfig) As MSSQLServer
|
||||
Dim oConnectionString As String = pContext.MergedJobDataMap.Item(Domain.Constants.DATABASE)
|
||||
Dim Database = New MSSQLServer(pLogConfig, MSSQLServer.DecryptConnectionString(oConnectionString))
|
||||
|
||||
Return Database
|
||||
End Function
|
||||
|
||||
Private Function GetState() As State
|
||||
Return New State With {
|
||||
.LogConfig = LogConfig,
|
||||
.Database = Database,
|
||||
.UserId = 0,
|
||||
.Config = Nothing,
|
||||
.DbConfig = Nothing
|
||||
}
|
||||
End Function
|
||||
End Class
|
||||
End Namespace
|
||||
@@ -0,0 +1,221 @@
|
||||
Imports System.Drawing
|
||||
Imports System.IO
|
||||
Imports DigitalData.Modules.Base
|
||||
Imports DigitalData.Modules.Logging
|
||||
Imports GdPicture14
|
||||
Imports Newtonsoft.Json
|
||||
Imports EnvelopeGenerator.CommonServices.Jobs.FinalizeDocument.FinalizeDocumentExceptions
|
||||
|
||||
Namespace Jobs.FinalizeDocument
|
||||
Public Class PDFBurner
|
||||
Inherits BaseClass
|
||||
|
||||
Private ReadOnly Manager As AnnotationManager
|
||||
Private ReadOnly LicenseManager As LicenseManager
|
||||
|
||||
Private Const ANNOTATION_TYPE_IMAGE = "pspdfkit/image"
|
||||
Private Const ANNOTATION_TYPE_INK = "pspdfkit/ink"
|
||||
Private Const ANNOTATION_TYPE_WIDGET = "pspdfkit/widget"
|
||||
Private Property _pdfBurnerParams As PDFBurnerParams
|
||||
|
||||
Public Sub New(pLogConfig As LogConfig, pGDPictureLicenseKey As String, pdfBurnerParams As PDFBurnerParams)
|
||||
MyBase.New(pLogConfig)
|
||||
|
||||
LicenseManager = New LicenseManager()
|
||||
LicenseManager.RegisterKEY(pGDPictureLicenseKey)
|
||||
|
||||
Manager = New AnnotationManager()
|
||||
|
||||
_pdfBurnerParams = pdfBurnerParams
|
||||
End Sub
|
||||
|
||||
Public Function BurnInstantJSONAnnotationsToPDF(pSourceBuffer As Byte(), pInstantJSONList As List(Of String)) As Byte()
|
||||
Dim oResult As GdPictureStatus
|
||||
Using oSourceStream As New MemoryStream(pSourceBuffer)
|
||||
' Open PDF
|
||||
oResult = Manager.InitFromStream(oSourceStream)
|
||||
If oResult <> GdPictureStatus.OK Then
|
||||
Throw New BurnAnnotationException($"Could not open document for burning: [{oResult}]")
|
||||
End If
|
||||
|
||||
' Add annotation to PDF
|
||||
For Each oJSON In pInstantJSONList
|
||||
If AddInstantJSONAnnotationToPDF(oJSON) = False Then
|
||||
Logger.Warn($"Error in AddInstantJSONAnnotationToPDF - oJson: ")
|
||||
Logger.Warn(oJSON)
|
||||
Throw New BurnAnnotationException($"Adding Annotation failed")
|
||||
End If
|
||||
Next
|
||||
oResult = Manager.BurnAnnotationsToPage(RemoveInitialAnnots:=True, VectorMode:=True)
|
||||
If oResult <> GdPictureStatus.OK Then
|
||||
Throw New BurnAnnotationException($"Could not burn annotations to file: [{oResult}]")
|
||||
End If
|
||||
|
||||
'Save PDF
|
||||
Using oNewStream As New MemoryStream()
|
||||
oResult = Manager.SaveDocumentToPDF(oNewStream)
|
||||
If oResult <> GdPictureStatus.OK Then
|
||||
Throw New BurnAnnotationException($"Could not save document to stream: [{oResult}]")
|
||||
End If
|
||||
|
||||
Manager.Close()
|
||||
|
||||
Return oNewStream.ToArray()
|
||||
End Using
|
||||
End Using
|
||||
End Function
|
||||
|
||||
Private Function AddInstantJSONAnnotationToPDF(pInstantJSON As String) As Boolean
|
||||
Try
|
||||
Dim oAnnotationData = JsonConvert.DeserializeObject(Of AnnotationData)(pInstantJSON)
|
||||
oAnnotationData.annotations.Reverse()
|
||||
Dim formFieldIndex = 0
|
||||
For Each oAnnotation In oAnnotationData.annotations
|
||||
Logger.Debug("Adding AnnotationID: " + oAnnotation.id)
|
||||
Select Case oAnnotation.type
|
||||
Case ANNOTATION_TYPE_IMAGE
|
||||
AddImageAnnotation(oAnnotation, oAnnotationData.attachments)
|
||||
|
||||
Case ANNOTATION_TYPE_INK
|
||||
AddInkAnnotation(oAnnotation)
|
||||
|
||||
Case ANNOTATION_TYPE_WIDGET
|
||||
'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
|
||||
End Select
|
||||
|
||||
Next
|
||||
|
||||
Return True
|
||||
Catch ex As Exception
|
||||
Logger.Warn("Could not create annotation from InstantJSON")
|
||||
Logger.Error(ex)
|
||||
Return False
|
||||
End Try
|
||||
End Function
|
||||
|
||||
Private Function AddImageAnnotation(pAnnotation As Annotation, pAttachments As Dictionary(Of String, Attachment)) As Boolean
|
||||
Try
|
||||
Dim oAttachment = pAttachments.Where(Function(a) a.Key = pAnnotation.imageAttachmentId).
|
||||
SingleOrDefault()
|
||||
|
||||
' Convert pixels to Inches
|
||||
Dim oBounds = pAnnotation.bbox.Select(AddressOf ToInches).ToList()
|
||||
|
||||
Dim oX = oBounds.Item(0)
|
||||
Dim oY = oBounds.Item(1)
|
||||
Dim oWidth = oBounds.Item(2)
|
||||
Dim oHeight = oBounds.Item(3)
|
||||
|
||||
Manager.SelectPage(pAnnotation.pageIndex + 1)
|
||||
Manager.AddEmbeddedImageAnnotFromBase64(oAttachment.Value.binary, oX, oY, oWidth, oHeight)
|
||||
|
||||
Return True
|
||||
Catch ex As Exception
|
||||
Logger.Warn("Could not add image annotation!")
|
||||
Logger.Error(ex)
|
||||
|
||||
Return False
|
||||
End Try
|
||||
End Function
|
||||
|
||||
Private Function AddInkAnnotation(pAnnotation As Annotation) As Boolean
|
||||
Try
|
||||
Dim oSegments = pAnnotation.lines.points
|
||||
Dim oColor = ColorTranslator.FromHtml(pAnnotation.strokeColor)
|
||||
Manager.SelectPage(pAnnotation.pageIndex + 1)
|
||||
|
||||
For Each oSegment As List(Of List(Of Single)) In oSegments
|
||||
Dim oPoints = oSegment.
|
||||
Select(AddressOf ToPointF).
|
||||
ToArray()
|
||||
|
||||
Manager.AddFreeHandAnnot(oColor, oPoints)
|
||||
Next
|
||||
|
||||
Return True
|
||||
Catch ex As Exception
|
||||
Logger.Warn("Could not add image annotation!")
|
||||
Logger.Error(ex)
|
||||
|
||||
Return False
|
||||
End Try
|
||||
|
||||
End Function
|
||||
|
||||
Private Function AddFormFieldValue(pAnnotation As Annotation, formFieldValue As FormFieldValue, index As Integer) As Boolean
|
||||
Try
|
||||
' Convert pixels to Inches
|
||||
Dim oBounds = pAnnotation.bbox.Select(AddressOf ToInches).ToList()
|
||||
|
||||
Dim oX = oBounds.Item(0)
|
||||
Dim oY = oBounds.Item(1) + _pdfBurnerParams.YOffset * index + _pdfBurnerParams.TopMargin
|
||||
Dim oWidth = oBounds.Item(2)
|
||||
Dim oHeight = oBounds.Item(3)
|
||||
|
||||
Manager.SelectPage(pAnnotation.pageIndex + 1)
|
||||
' Add the text annotation
|
||||
Dim ant = Manager.AddTextAnnot(oX, oY, oWidth, oHeight, formFieldValue.value)
|
||||
|
||||
' Set the font properties
|
||||
ant.FontName = _pdfBurnerParams.FontName
|
||||
ant.FontSize = _pdfBurnerParams.FontSize
|
||||
ant.FontStyle = _pdfBurnerParams.FontStyle
|
||||
Manager.SaveAnnotationsToPage()
|
||||
Return True
|
||||
Catch ex As Exception
|
||||
Logger.Warn("Could not add image annotation!")
|
||||
Logger.Error(ex)
|
||||
Return False
|
||||
End Try
|
||||
End Function
|
||||
|
||||
Private Function ToPointF(pPoints As List(Of Single)) As PointF
|
||||
Dim oPoints = pPoints.Select(AddressOf ToInches).ToList()
|
||||
Return New PointF(oPoints.Item(0), oPoints.Item(1))
|
||||
End Function
|
||||
|
||||
Private Function ToInches(pValue As Double) As Double
|
||||
Return pValue / 72
|
||||
End Function
|
||||
|
||||
Private Function ToInches(pValue As Single) As Single
|
||||
Return pValue / 72
|
||||
End Function
|
||||
|
||||
Friend Class AnnotationData
|
||||
Public Property annotations As List(Of Annotation)
|
||||
Public Property attachments As Dictionary(Of String, Attachment)
|
||||
Public Property formFieldValues As List(Of FormFieldValue)
|
||||
End Class
|
||||
|
||||
Friend Class Annotation
|
||||
Public Property id As String
|
||||
Public Property bbox As List(Of Double)
|
||||
Public Property type As String
|
||||
Public Property isSignature As Boolean
|
||||
Public Property imageAttachmentId As String
|
||||
Public Property lines As Lines
|
||||
Public Property pageIndex As Integer
|
||||
Public Property strokeColor As String
|
||||
End Class
|
||||
|
||||
Friend Class Lines
|
||||
Public Property points As List(Of List(Of List(Of Single)))
|
||||
End Class
|
||||
|
||||
Friend Class Attachment
|
||||
Public Property binary As String
|
||||
Public Property contentType As String
|
||||
End Class
|
||||
|
||||
Friend Class FormFieldValue
|
||||
Public Property name As String
|
||||
Public Property value As String
|
||||
End Class
|
||||
End Class
|
||||
End Namespace
|
||||
@@ -0,0 +1,16 @@
|
||||
Imports System.Drawing
|
||||
Namespace Jobs.FinalizeDocument
|
||||
Public Class PDFBurnerParams
|
||||
Public Property IgnoredLabels As New List(Of String) From {"Date", "Datum", "ZIP", "PLZ", "Place", "Ort", "Position", "Stellung"}
|
||||
|
||||
Public Property TopMargin As Double = 0.1
|
||||
|
||||
Public Property YOffset As Double = -0.3
|
||||
|
||||
Public Property FontName As String = "Arial"
|
||||
|
||||
Public Property FontSize As Integer = 8
|
||||
|
||||
Public Property FontStyle As FontStyle = FontStyle.Italic
|
||||
End Class
|
||||
End Namespace
|
||||
@@ -0,0 +1,71 @@
|
||||
Imports DigitalData.Modules.Base
|
||||
Imports DigitalData.Modules.Logging
|
||||
Imports EnvelopeGenerator.CommonServices.Jobs.FinalizeDocument.FinalizeDocumentExceptions
|
||||
Imports GdPicture14
|
||||
Imports System.IO
|
||||
|
||||
Public Class PDFMerger
|
||||
Inherits BaseClass
|
||||
|
||||
Private ReadOnly Manager As AnnotationManager
|
||||
Private ReadOnly LicenseManager As LicenseManager
|
||||
|
||||
Private Const ALLOW_RASTERIZATION = True
|
||||
Private Const ALLOW_VECTORIZATION = True
|
||||
|
||||
Private ReadOnly PDFAConformanceLevel As PdfConversionConformance = PdfConversionConformance.PDF_A_1b
|
||||
|
||||
Public Sub New(pLogConfig As LogConfig, pGDPictureLicenseKey As String)
|
||||
MyBase.New(pLogConfig)
|
||||
|
||||
LicenseManager = New LicenseManager()
|
||||
LicenseManager.RegisterKEY(pGDPictureLicenseKey)
|
||||
|
||||
Manager = New AnnotationManager()
|
||||
End Sub
|
||||
|
||||
Public Function MergeDocuments(pDocument As Byte(), pReport As Byte()) As Byte()
|
||||
Using oDocumentStream As New MemoryStream(pDocument)
|
||||
Using oReportStream As New MemoryStream(pReport)
|
||||
Using oFinalStream As New MemoryStream()
|
||||
Using oDocumentPDF As New GdPicturePDF()
|
||||
Using oReportPDF As New GdPicturePDF()
|
||||
Dim oStatus As GdPictureStatus = GdPictureStatus.OK
|
||||
|
||||
' Load the source file into memory
|
||||
oDocumentPDF.LoadFromStream(oDocumentStream, True)
|
||||
|
||||
oStatus = oDocumentPDF.GetStat()
|
||||
If oStatus <> GdPictureStatus.OK Then
|
||||
Throw New MergeDocumentException($"Document could not be loaded: {oStatus}")
|
||||
End If
|
||||
|
||||
' Load the report file into memory
|
||||
oReportPDF.LoadFromStream(oReportStream, True)
|
||||
oStatus = oReportPDF.GetStat()
|
||||
If oStatus <> GdPictureStatus.OK Then
|
||||
Throw New MergeDocumentException($"Report could not be loaded: {oStatus}")
|
||||
End If
|
||||
|
||||
' Merge the documents
|
||||
Dim oMergedPDF = oDocumentPDF.Merge2Documents(oDocumentPDF, oReportPDF)
|
||||
oStatus = oMergedPDF.GetStat()
|
||||
If oStatus <> GdPictureStatus.OK Then
|
||||
Throw New MergeDocumentException($"Documents could not be merged: {oStatus}")
|
||||
End If
|
||||
|
||||
' Convert to PDF/A
|
||||
oMergedPDF.ConvertToPDFA(oFinalStream, PDFAConformanceLevel, ALLOW_VECTORIZATION, ALLOW_RASTERIZATION)
|
||||
oStatus = oDocumentPDF.GetStat()
|
||||
If oStatus <> GdPictureStatus.OK Then
|
||||
Throw New MergeDocumentException($"Document could not be converted to PDF/A: {oStatus}")
|
||||
End If
|
||||
|
||||
Return oFinalStream.ToArray()
|
||||
End Using
|
||||
End Using
|
||||
End Using
|
||||
End Using
|
||||
End Using
|
||||
End Function
|
||||
End Class
|
||||
@@ -0,0 +1,92 @@
|
||||
Imports System.IO
|
||||
Imports DigitalData.Modules.Logging
|
||||
Imports DigitalData.Modules.Base
|
||||
Imports EnvelopeGenerator.CommonServices.Jobs.FinalizeDocument.FinalizeDocumentExceptions
|
||||
Imports EnvelopeGenerator.Domain.Entities
|
||||
|
||||
Public Class ReportCreator
|
||||
Inherits BaseClass
|
||||
|
||||
Private Envelope As Envelope
|
||||
Private ReadOnly ReportModel As ReportModel
|
||||
Private ReadOnly EnvelopeModel As EnvelopeModel
|
||||
|
||||
Public Sub New(pLogConfig As LogConfig, pState As State)
|
||||
MyBase.New(pLogConfig)
|
||||
|
||||
ReportModel = New ReportModel(pState)
|
||||
EnvelopeModel = New EnvelopeModel(pState)
|
||||
End Sub
|
||||
|
||||
Public Function CreateReport(pEnvelope As Domain.Entities.Envelope) As Byte()
|
||||
Try
|
||||
Logger.Debug("Loading report data..")
|
||||
Dim oTable = ReportModel.List(pEnvelope.Id)
|
||||
Dim oItems = GetReportSource(oTable)
|
||||
|
||||
Envelope = pEnvelope
|
||||
|
||||
If oItems.Count = 0 Then
|
||||
Throw New CreateReportException("No report data found!")
|
||||
End If
|
||||
|
||||
Logger.Debug("Creating report with [{0}] items..", oItems.Count)
|
||||
Dim oBuffer = DoCreateReport(oItems)
|
||||
Logger.Debug("Report created!")
|
||||
|
||||
Return oBuffer
|
||||
Catch ex As Exception
|
||||
Logger.Error(ex)
|
||||
Throw New CreateReportException("Could not prepare report data!", ex)
|
||||
End Try
|
||||
End Function
|
||||
|
||||
Private Function GetReportSource(pDataTable As DataTable) As List(Of ReportItem)
|
||||
Logger.Debug("Preparing report data")
|
||||
Return pDataTable.Rows.
|
||||
Cast(Of DataRow).
|
||||
Select(AddressOf ToReportItem).
|
||||
OrderByDescending(Function(r) r.ItemDate).
|
||||
ToList()
|
||||
End Function
|
||||
|
||||
Private Function DoCreateReport(pReportItems As List(Of ReportItem)) As Byte()
|
||||
Dim oItems = pReportItems.Select(AddressOf MergeEnvelope).ToList()
|
||||
Dim oSource As New ReportSource With {.Items = oItems}
|
||||
Dim oReport As New rptEnvelopeHistory() With {.DataSource = oSource, .DataMember = "Items"}
|
||||
|
||||
Logger.Debug("Creating report in memory..")
|
||||
oReport.CreateDocument()
|
||||
|
||||
Logger.Debug("Exporting report to stream..")
|
||||
Using oStream As New MemoryStream()
|
||||
oReport.ExportToPdf(oStream)
|
||||
|
||||
Logger.Debug("Writing report to buffer..")
|
||||
Return oStream.ToArray()
|
||||
End Using
|
||||
End Function
|
||||
|
||||
Private Function MergeEnvelope(pItem As ReportItem) As ReportItem
|
||||
If pItem.Envelope Is Nothing Then
|
||||
pItem.Envelope = Envelope
|
||||
End If
|
||||
Return pItem
|
||||
End Function
|
||||
|
||||
Private Function ToReportItem(pRow As DataRow) As ReportItem
|
||||
Try
|
||||
Return New ReportItem() With {
|
||||
.EnvelopeId = pRow.Item("ENVELOPE_ID"),
|
||||
.EnvelopeTitle = pRow.ItemEx("HEAD_TITLE", String.Empty),
|
||||
.EnvelopeSubject = pRow.ItemEx("HEAD_SUBJECT", String.Empty),
|
||||
.ItemDate = pRow.ItemEx(Of Date)("POS_WHEN", Nothing),
|
||||
.ItemStatus = pRow.ItemEx("POS_STATUS", 0),
|
||||
.ItemUserReference = pRow.ItemEx("POS_WHO", "")
|
||||
}
|
||||
Catch ex As Exception
|
||||
Logger.Error(ex)
|
||||
Throw New CreateReportException("Could not read data from database!", ex)
|
||||
End Try
|
||||
End Function
|
||||
End Class
|
||||
@@ -0,0 +1,22 @@
|
||||
Imports EnvelopeGenerator.Domain
|
||||
Imports EnvelopeGenerator.Domain.Entities
|
||||
|
||||
Public Class ReportItem
|
||||
|
||||
Public Property Envelope As Envelope
|
||||
Public Property EnvelopeId As Integer
|
||||
Public Property EnvelopeTitle As String
|
||||
Public Property EnvelopeSubject As String
|
||||
|
||||
Public Property ItemStatus As Constants.EnvelopeStatus
|
||||
Public ReadOnly Property ItemStatusTranslated As String
|
||||
Get
|
||||
Dim oStatus = ItemStatus.ToString()
|
||||
Return My.Resources.Model.ResourceManager.GetString(oStatus)
|
||||
End Get
|
||||
End Property
|
||||
|
||||
Public Property ItemUserReference As String
|
||||
Public Property ItemDate As Date
|
||||
|
||||
End Class
|
||||
@@ -0,0 +1,3 @@
|
||||
Public Class ReportSource
|
||||
Public Property Items As List(Of ReportItem)
|
||||
End Class
|
||||
Reference in New Issue
Block a user