Imports DigitalData.Modules.Database Imports DigitalData.Modules.Logging Imports DigitalData.Modules.Base Imports GdPicture14 Imports Quartz Imports Quartz.Util Imports DevExpress.XtraRichEdit.Keyboard Imports DevExpress.Pdf Imports System.Security.Cryptography Imports DevExpress Imports System.IO Imports System.Runtime.Remoting.Messaging Namespace Jobs Public Class CertificateDocumentJob Implements IJob Private LicenseManager As New LicenseManager() Private GdViewer As GdViewer Private ConfigModel As ConfigModel Private EnvelopeModel As EnvelopeModel Private LogConfig As LogConfig Private Logger As Logger Private Database As MSSQLServer Private Config As DbConfig Private PDFBurner As PDFBurner Private Class EnvelopeData Public EnvelopeId As Integer Public DocumentPath As String Public AnnotationData As List(Of String) End Class Public Async Function Execute(pContext As IJobExecutionContext) As Task Implements IJob.Execute Dim oGdPictureKey As String = pContext.MergedJobDataMap.Item(Constants.GDPICTURE) LogConfig = pContext.MergedJobDataMap.Item(Constants.LOGCONFIG) Logger = LogConfig.GetLogger() Try Logger.Debug("Loading GdViewer..") GdViewer = New GdViewer() LicenseManager.RegisterKEY(oGdPictureKey) Logger.Debug("Loading PDFBurner..") PDFBurner = New PDFBurner(LogConfig, oGdPictureKey) Logger.Debug("Loading Database..") Database = GetDatabase(pContext, LogConfig) Logger.Debug("Loading Configuration..") Config = ConfigModel.LoadConfiguration() Dim JobId = pContext.JobDetail.Key Logger.Debug("Starting job {0}", JobId) Dim oCompleteStatus As Integer = Constants.EnvelopeStatus.EnvelopeCompletelySigned Dim oSql = $"SELECT * FROM TBSIG_ENVELOPE WHERE STATUS = {oCompleteStatus}" 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() Logger.Info("Found [{0}] completed envelopes.", oEnvelopeIds.Count) For Each oId In oEnvelopeIds Logger.Info("Finalizing Envelope [{0}]", oId) Dim oEnvelopeData = GetEnvelopeData(oId) If oEnvelopeData Is Nothing Then Logger.Warn("EnvelopeData could not be loaded for Envelope [{0}]!", oId) End If 'GenerateFinalPDF(oEnvelopeData) 'Dim oReport As Byte() = Await GenerateReportPdf(oId) 'MergeDocuments() Logger.Info("Envelope finialized!") Next Logger.Debug("Completed job {0}", JobId) Catch ex As Exception Logger.Warn("Certificate Document job failed!") Logger.Error(ex) End Try End Function Private Function MergeDocuments(pDocumentPath As String, pReport As Byte()) Using oGdPicturePDF As New GdPicturePDF() Using oGdPicturePDFReport As New GdPicturePDF() Using oStream As New MemoryStream(pReport) ' Load the source file into memory If oGdPicturePDF.LoadFromFile(pDocumentPath, True) <> GdPictureStatus.OK Then Throw New ApplicationException("Document could not be loaded!") End If ' Load the report file into memory If oGdPicturePDFReport.LoadFromStream(oStream, True) <> GdPictureStatus.OK Then Throw New ApplicationException("Report could not be loaded!") End If If oGdPicturePDF.ClonePages(oGdPicturePDFReport, "*") = GdPictureStatus.OK Then Throw New ApplicationException("Report could not be loaded!") End If End Using End Using End Using End Function Private Function GenerateFinalPDF(pData As EnvelopeData) As Boolean Dim pEnvelopeId = pData.EnvelopeId Logger.Info("Burning [{0}] signatures", pData.AnnotationData.Count) Dim oAnnotations = pData.AnnotationData Dim oInputPath = pData.DocumentPath Dim oOutputPath = Config.ExportPath Logger.Info("Input path: [{0}]", oInputPath) Logger.Info("Output path: [{0}]", oOutputPath) Dim oBurnResult = PDFBurner.BurnInstantJSONAnnotationsToPDF(oInputPath, oAnnotations, oOutputPath) If oBurnResult = False Then Logger.Warn("PDF Could not be burned for Envelope [{0}]!", pEnvelopeId) Return False End If Return True End Function Private Async Function GenerateReportPdf(pEnvelopeId As Integer) As Task(Of Byte()) Dim oSql As String = $"SELECT * FROM VWSIG_ENVELOPE_REPORT WHERE ENVELOPE_ID = {pEnvelopeId}" Dim oTable As DataTable = Database.GetDatatable(oSql) Dim oItems = GetReportSource(oTable) If oItems.Count = 0 Then Return Nothing End If Dim oState As New State() With { .Database = Database, .LogConfig = LogConfig } EnvelopeModel = New EnvelopeModel(oState) Dim oEnvelope = EnvelopeModel.GetById(pEnvelopeId) Dim oCreator As New ReportCreator(oEnvelope) Dim oBuffer = Await oCreator.CreateReport(oItems) Return oBuffer End Function Private Function GetReportSource(pDataTable As DataTable) As List(Of ReportItem) Return pDataTable.Rows. Cast(Of DataRow). Select(AddressOf ToReportItem). OrderByDescending(Function(r) r.ItemDate). ToList() End Function Private Function GetEnvelopeData(pEnvelopeId As Integer) As EnvelopeData Dim oSql = $"SELECT T.GUID, T2.FILEPATH 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 } 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 Function ToReportItem(pRow As DataRow) As ReportItem 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", "") } End Function Private Sub InitializeModels() Dim oState = GetState() ConfigModel = New ConfigModel(oState) EnvelopeModel = New EnvelopeModel(oState) End Sub Private Function GetDatabase(pContext As IJobExecutionContext, pLogConfig As LogConfig) As MSSQLServer Dim oConnectionString As String = pContext.MergedJobDataMap.Item(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 } End Function End Class End Namespace