606 lines
31 KiB
VB.net
606 lines
31 KiB
VB.net
Imports System.Collections.Generic
|
|
Imports System.Data
|
|
Imports System.IO
|
|
Imports System.Linq
|
|
Imports System.Security.Cryptography
|
|
Imports DigitalData.Modules.Database
|
|
Imports DigitalData.Modules.Interfaces
|
|
Imports DigitalData.Modules.Interfaces.Exceptions
|
|
Imports DigitalData.Modules.Jobs.Exceptions
|
|
Imports DigitalData.Modules.Logging
|
|
Imports FirebirdSql.Data.FirebirdClient
|
|
Imports System.Data.SqlClient
|
|
|
|
Public Class ImportZUGFeRDFiles
|
|
Implements IJob
|
|
|
|
Public Const ZUGFERD_IN = "ZUGFeRD in"
|
|
Public Const ZUGFERD_ERROR = "ZUGFeRD Error"
|
|
Public Const ZUGFERD_SUCCESS = "ZUGFeRD Success"
|
|
Public Const ZUGFERD_EML = "ZUGFeRD Eml"
|
|
Public Const ZUGFERD_REJECTED_EML = "ZUGFeRD Eml Rejected"
|
|
Public Const ZUGFERD_ATTACHMENTS = "ZUGFeRD Attachments"
|
|
Public HISTORY_ID As Integer
|
|
|
|
Private Const DIRECTORY_DONT_MOVE = "DIRECTORY_DONT_MOVE"
|
|
|
|
' List of allowed extensions for PDF/A Attachments
|
|
' This list should not contain xml so the zugferd xml file will be filtered out
|
|
Private ReadOnly AllowedExtensions As List(Of String) = New List(Of String) From {"docx", "doc", "pdf", "xls", "xlsx", "ppt", "pptx", "txt"}
|
|
|
|
Private ReadOnly _logger As Logger
|
|
Private ReadOnly _logConfig As LogConfig
|
|
Private ReadOnly _zugferd As ZUGFeRDInterface
|
|
Private ReadOnly _firebird As Firebird
|
|
Private ReadOnly _filesystem As Filesystem.File
|
|
Private ReadOnly _EmailOutAccountId As Integer
|
|
Private ReadOnly _mssql As MSSQLServer
|
|
Private ReadOnly _email As EmailFunctions
|
|
|
|
|
|
Public Sub New(LogConfig As LogConfig, Firebird As Firebird, pEmailOutAccount As Integer, Optional MSSQL As MSSQLServer = Nothing)
|
|
_logConfig = LogConfig
|
|
_logger = LogConfig.GetLogger()
|
|
_firebird = Firebird
|
|
_filesystem = New Filesystem.File(_logConfig)
|
|
_mssql = MSSQL
|
|
_EmailOutAccountId = pEmailOutAccount
|
|
_email = New EmailFunctions(LogConfig, _mssql, _firebird)
|
|
|
|
_logger.Debug("Registering GDPicture License")
|
|
If _mssql IsNot Nothing Then
|
|
Dim oSQL = "SELECT LICENSE FROM TBDD_3RD_PARTY_MODULES WHERE NAME = 'GDPICTURE'"
|
|
Dim oLicenseKey As String = _mssql.GetScalarValue(oSQL)
|
|
_zugferd = New ZUGFeRDInterface(_logConfig, oLicenseKey)
|
|
Else
|
|
_logger.Warn("GDPicture License could not be registered! MSSQL is not enabled!")
|
|
Throw New ArgumentNullException("MSSQL")
|
|
End If
|
|
End Sub
|
|
|
|
Private Function MoveAndRenameEmailToRejected(Args As WorkerArgs, MessageId As String) As EmailData
|
|
Dim oEmailData = _email.GetEmailDataForMessageId(MessageId)
|
|
Dim oSource = _email.GetOriginalEmailPath(Args.OriginalEmailDirectory, MessageId)
|
|
Dim oDateSubDirectoryName As String = Now.ToString("yyyy-MM-dd")
|
|
Dim oDestination As String
|
|
|
|
Dim oRejectedDirectory As String = Path.Combine(Args.RejectedEmailDirectory, oDateSubDirectoryName)
|
|
|
|
' Create the destination directory if it does not exist
|
|
If Not Directory.Exists(oRejectedDirectory) Then
|
|
Try
|
|
Directory.CreateDirectory(oRejectedDirectory)
|
|
Catch ex As Exception
|
|
_logger.Error(ex)
|
|
End Try
|
|
End If
|
|
|
|
' If oEmailData is Nothing, TBEDM_EMAIL_PROFILER_HISTORY for MessageId was not found.
|
|
' This only should happen when testing and db-tables are deleted frequently
|
|
If oEmailData Is Nothing Then
|
|
oDestination = _email.GetEmailPathWithSubjectAsName(oRejectedDirectory, MessageId)
|
|
Else
|
|
oDestination = _email.GetEmailPathWithSubjectAsName(oRejectedDirectory, oEmailData.Subject)
|
|
End If
|
|
|
|
_logger.Debug("Destination for eml file is {0}", oDestination)
|
|
|
|
Dim oFinalFileName = _filesystem.GetVersionedFilename(oDestination)
|
|
|
|
_logger.Debug("Versioned filename for eml file is {0}", oFinalFileName)
|
|
|
|
If oEmailData Is Nothing Then
|
|
_logger.Warn("Could not get Email Data from database. File {0} will not be moved!", oSource)
|
|
Return Nothing
|
|
End If
|
|
|
|
Try
|
|
_logger.Info("Moving email from {0} to {1}", oSource, oFinalFileName)
|
|
IO.File.Move(oSource, oFinalFileName)
|
|
oEmailData.Attachment = oFinalFileName
|
|
Catch ex As Exception
|
|
_logger.Warn("File {0} could not be moved! Original Filename will be used!", oSource)
|
|
_logger.Error(ex)
|
|
oEmailData.Attachment = oSource
|
|
End Try
|
|
|
|
Return oEmailData
|
|
End Function
|
|
|
|
Private Sub AddRejectedState(oMessageID As String, oTitle As String, oTitle1 As String, oComment As String, Transaction As SqlTransaction)
|
|
Try
|
|
'PRCUST_ADD_HISTORY_STATE: @MessageID VARCHAR(250), @TITLE1 VARCHAR(250), @TITLE2 VARCHAR(250)
|
|
Dim oSQL = $"EXEC PRCUST_ADD_HISTORY_STATE '{oMessageID}','{oTitle}','{oTitle1}','{oComment.Replace("'", "''")}'"
|
|
_mssql.ExecuteNonQuery(oSQL, Transaction)
|
|
Catch ex As Exception
|
|
_logger.Error(ex)
|
|
End Try
|
|
End Sub
|
|
|
|
Public Sub Start(Arguments As Object) Implements IJob.Start
|
|
Dim oArgs As WorkerArgs = Arguments
|
|
Dim oPropertyExtractor = New PropertyValues(_logConfig)
|
|
Dim oAttachmentExtractor = New PDFEmbeds(_logConfig)
|
|
|
|
_logger.Debug("Starting Job {0}", [GetType].Name)
|
|
|
|
Try
|
|
For Each oPath As String In oArgs.WatchDirectories
|
|
Dim oDirInfo As New DirectoryInfo(oPath)
|
|
|
|
_logger.Debug($"Start processing directory {oDirInfo.FullName}")
|
|
|
|
If oDirInfo.Exists Then
|
|
' Filter out *.lock files
|
|
Dim oFiles As List(Of FileInfo) = oDirInfo.
|
|
GetFiles().
|
|
Where(Function(f) Not f.Name.EndsWith(".lock")).
|
|
ToList()
|
|
Dim oFileCount = oFiles.Count
|
|
Dim oCurrentFileCount = 0
|
|
|
|
If oFileCount = 0 Then
|
|
_logger.Debug("No files to process.")
|
|
Continue For
|
|
Else
|
|
_logger.Info("Found {0} files", oFileCount)
|
|
End If
|
|
|
|
' Group files by messageId
|
|
Dim oGrouped As Dictionary(Of String, List(Of FileInfo)) = _zugferd.FileGroup.GroupFiles(oFiles)
|
|
|
|
_logger.Info("Found {0} file groups", oGrouped.Count)
|
|
|
|
' Process each file group together
|
|
For Each oFileGroup In oGrouped
|
|
' Start a new transaction for each file group.
|
|
' This way we can rollback database changes for the whole filegroup in case something goes wrong.
|
|
Dim oFBConnection As FbConnection = _firebird.GetConnection()
|
|
Dim oFBTransaction As FbTransaction = oFBConnection.BeginTransaction()
|
|
|
|
Dim oSQLConnection As SqlConnection = _mssql.GetConnection()
|
|
Dim oSQLTransaction As SqlTransaction = oSQLConnection.BeginTransaction()
|
|
|
|
' Count the amount of ZUGFeRD files
|
|
Dim oZUGFeRDCount As Integer = 0
|
|
|
|
' Set the default Move Directory
|
|
Dim oMoveDirectory As String = oArgs.ErrorDirectory
|
|
|
|
' Flag to save if the whole process was a success.
|
|
' Will be set only at the end of the function if no error occurred.
|
|
Dim oIsSuccess As Boolean = False
|
|
|
|
' Create file lists
|
|
Dim oFileGroupFiles As List(Of FileInfo) = oFileGroup.Value
|
|
Dim oEmailAttachmentFiles As New List(Of FileInfo)
|
|
Dim oEmbeddedAttachmentFiles As New List(Of PDFEmbeds.EmbeddedFile)
|
|
|
|
Dim oMessageId As String = oFileGroup.Key
|
|
Dim oMissingProperties As New List(Of String)
|
|
Dim oMD5CheckSum As String = String.Empty
|
|
|
|
_logger.NewBlock($"Message Id {oMessageId}")
|
|
_logger.Info("Start processing file group {0}", oMessageId)
|
|
|
|
Try
|
|
For Each oFile In oFileGroupFiles
|
|
Dim oDocument As CrossIndustryDocumentType
|
|
' Start a global group counter for each file
|
|
Dim oGlobalGroupCounter = 0
|
|
' Clear missing properties for the new file
|
|
oMissingProperties = New List(Of String)
|
|
oCurrentFileCount += 1
|
|
|
|
' Only pdf files are allowed from here on
|
|
If Not oFile.Name.EndsWith(".pdf") Then
|
|
_logger.Debug("Skipping non-pdf file {0}", oFile.Name)
|
|
oEmailAttachmentFiles.Add(oFile)
|
|
Continue For
|
|
End If
|
|
|
|
_logger.Info("Start processing file {0}", oFile.Name)
|
|
|
|
Try
|
|
oDocument = _zugferd.ExtractZUGFeRDFileWithGDPicture(oFile.FullName)
|
|
Catch ex As ZUGFeRDExecption
|
|
Select Case ex.ErrorType
|
|
Case ZUGFeRDInterface.ErrorType.NoZugferd
|
|
_logger.Info("File [{0}] is not a valid ZUGFeRD document. Skipping.", oFile.Name)
|
|
oEmailAttachmentFiles.Add(oFile)
|
|
Continue For
|
|
|
|
Case ZUGFeRDInterface.ErrorType.NoValidZugferd
|
|
_logger.Warn("File [{0}] is an Incorrectly formatted ZUGFeRD document!", oFile.Name)
|
|
Throw New InvalidFerdException()
|
|
|
|
Case Else
|
|
_logger.Warn("Unexpected Error occurred while extracting ZUGFeRD Information from file {0}", oFile.Name)
|
|
Throw ex
|
|
End Select
|
|
End Try
|
|
|
|
' Extract all attachments with the extensions specified in `AllowedExtensions`.
|
|
' If you need to extract and use embedded xml files, you need to filter out the zugferd-invoice.xml yourself.
|
|
' Right now the zugferd-invoice.xml is filtered out because `AllowedExtensions` does not contain `xml`.
|
|
Dim oAttachments = oAttachmentExtractor.Extract(oFile.FullName, AllowedExtensions)
|
|
If oAttachments Is Nothing Then
|
|
_logger.Warn("Attachments for file [{0}] could not be extracted", oFile.FullName)
|
|
Else
|
|
oEmbeddedAttachmentFiles.AddRange(oAttachments)
|
|
End If
|
|
|
|
oMD5CheckSum = CreateMD5(oFile.FullName)
|
|
If oMD5CheckSum <> String.Empty Then
|
|
Dim oCheckCommand = $"SELECT * FROM TBEDM_ZUGFERD_HISTORY_IN WHERE GUID = (SELECT MAX(GUID) FROM TBEDM_ZUGFERD_HISTORY_IN WHERE UPPER(MD5HASH) = UPPER('{oMD5CheckSum}'))"
|
|
Dim oMD5DT As DataTable = _firebird.GetDatatable(oCheckCommand, Firebird.TransactionMode.NoTransaction)
|
|
If Not IsNothing(oMD5DT) Then
|
|
If oMD5DT.Rows.Count = 1 Then
|
|
Dim oRejected As Boolean
|
|
Try
|
|
oRejected = CBool(oMD5DT.Rows(0).Item("REJECTED"))
|
|
Catch ex As Exception
|
|
_logger.Warn("Error while converting REJECTED: " & ex.Message)
|
|
oRejected = False
|
|
End Try
|
|
If oRejected = False Then
|
|
HISTORY_ID = oMD5DT.Rows(0).Item("GUID")
|
|
Throw New MD5HashException($"There is already an identical invoice! - HistoryID [{HISTORY_ID}]")
|
|
Else
|
|
_logger.Info("ZuGFeRDFile already has been worked, but formerly obviously was rejected!")
|
|
End If
|
|
End If
|
|
Else
|
|
_logger.Warn("Be careful: oExistsDT is nothing!")
|
|
End If
|
|
Else
|
|
_logger.Warn("Be careful: oMD5CheckSum is nothing!")
|
|
End If
|
|
|
|
' Check if there are more than one ZUGFeRD files
|
|
If oZUGFeRDCount = 1 Then
|
|
Throw New TooMuchFerdsException()
|
|
End If
|
|
|
|
' Since extraction went well, increase the amount of ZUGFeRD files
|
|
oZUGFeRDCount += 1
|
|
|
|
' Check the document against the configured property map and return:
|
|
' - a List of valid properties
|
|
' - a List of missing properties
|
|
Dim oCheckResult = _zugferd.PropertyValues.CheckPropertyValues(oDocument, oArgs.PropertyMap, oMessageId)
|
|
|
|
If oCheckResult.MissingProperties.Count > 0 Then
|
|
oMissingProperties = oCheckResult.MissingProperties
|
|
Throw New MissingValueException(oFile)
|
|
End If
|
|
Dim oDelSQL = $"DELETE FROM TBEDMI_ITEM_VALUE where REFERENCE_GUID = '{oMessageId}'"
|
|
Dim oStep As String
|
|
|
|
oStep = "Firebird TBEDMI_ITEM_VALUE Delete messageID Items"
|
|
Try
|
|
_firebird.ExecuteNonQueryWithConnection(oDelSQL, oFBConnection)
|
|
Catch ex As Exception
|
|
_logger.Error(ex)
|
|
_logger.Warn("Step [{0}] with SQL [{1}] was not successful.", oStep, oDelSQL)
|
|
End Try
|
|
|
|
If oArgs.InsertIntoSQLServer = True Then
|
|
oStep = "MSSQL TBEDMI_ITEM_VALUE Delete messageID Items"
|
|
Try
|
|
_mssql.ExecuteNonQueryWithConnectionObject(oDelSQL, oSQLConnection)
|
|
Catch ex As Exception
|
|
_logger.Warn("Step [{0}] with SQL [{1}] was not successful.", oStep, oDelSQL)
|
|
End Try
|
|
End If
|
|
|
|
For Each oProperty In oCheckResult.ValidProperties
|
|
Dim oGroupCounterValue = oProperty.GroupCounter
|
|
|
|
' If GroupCounter is -1, it means this is a default property that can only occur once.
|
|
' Set the actual inserted value to 0
|
|
If oGroupCounterValue = -1 Then
|
|
oGroupCounterValue = 0
|
|
End If
|
|
|
|
Dim oCommand = $"INSERT INTO {oProperty.TableName} (REFERENCE_GUID, ITEM_DESCRIPTION, ITEM_VALUE, GROUP_COUNTER,SPEC_NAME,IS_REQUIRED) VALUES
|
|
('{oMessageId}', '{oProperty.Description}', '{oProperty.Value.Replace("'", "''")}', {oGroupCounterValue},'{oProperty.TableColumn}','{oProperty.ISRequired}')"
|
|
_logger.Debug("Mapping Property [{0}] with value [{1}], Will be inserted into table [{2}]", oProperty.TableColumn, oProperty.Value.Replace("'", "''"), oProperty.TableName)
|
|
' Insert into SQL Server
|
|
If oArgs.InsertIntoSQLServer = True Then
|
|
Dim oResult = _mssql.ExecuteNonQueryWithConnectionObject(oCommand, oSQLConnection, MSSQLServer.TransactionMode.ExternalTransaction, oSQLTransaction)
|
|
If oResult = False Then
|
|
_logger.Warn($"SQL Command [{oCommand}] was not successful. Check the log.")
|
|
End If
|
|
End If
|
|
' Insert into Firebird
|
|
_firebird.ExecuteNonQueryWithConnection(oCommand, oFBConnection, Firebird.TransactionMode.ExternalTransaction, oFBTransaction)
|
|
Next
|
|
Next
|
|
|
|
'Check if there are no ZUGFeRD files
|
|
If oZUGFeRDCount = 0 Then
|
|
Throw New NoFerdsException()
|
|
End If
|
|
|
|
'If no errors occurred...
|
|
'Log the History
|
|
If oMD5CheckSum <> String.Empty Then
|
|
Dim oInsertCommand = $"INSERT INTO TBEDM_ZUGFERD_HISTORY_IN (MESSAGE_ID, MD5HASH) VALUES ('{oMessageId}', '{oMD5CheckSum}')"
|
|
_firebird.ExecuteNonQueryWithConnection(oInsertCommand, oFBConnection, Firebird.TransactionMode.ExternalTransaction, oFBTransaction)
|
|
|
|
' History ID is only need in case of an error
|
|
oFBTransaction.Commit()
|
|
|
|
Try
|
|
Dim oSQL = $"SELECT MAX(GUID) FROM TBEDM_ZUGFERD_HISTORY_IN WHERE MESSAGE_ID = '{oMessageId}'"
|
|
HISTORY_ID = _firebird.GetScalarValue(oSQL)
|
|
Catch ex As Exception
|
|
HISTORY_ID = 0
|
|
End Try
|
|
End If
|
|
|
|
oIsSuccess = True
|
|
oMoveDirectory = oArgs.SuccessDirectory
|
|
|
|
Catch ex As MD5HashException
|
|
_logger.Error(ex)
|
|
'oFBTransaction.Rollback()
|
|
|
|
Dim oSQL = $"UPDATE TBEDM_ZUGFERD_HISTORY_IN SET COMMENT = 'REJECTED - Already processed (MD5Hash)' WHERE GUID = '{HISTORY_ID}'"
|
|
_firebird.ExecuteNonQuery(oSQL)
|
|
|
|
Dim oBody = EmailStrings.EMAIL_MD5_ERROR
|
|
Dim oEmailData = MoveAndRenameEmailToRejected(oArgs, oMessageId)
|
|
_email.AddToEmailQueueMSSQL(oMessageId, oBody, oEmailData, "MD5HashException", _EmailOutAccountId, oSQLTransaction)
|
|
AddRejectedState(oMessageId, "MD5HashException", "Die gesendete Rechnung wurde bereits verarbeitet!", "", oSQLTransaction)
|
|
|
|
Catch ex As InvalidFerdException
|
|
_logger.Error(ex)
|
|
'oFBTransaction.Rollback()
|
|
|
|
Dim oSQL = $"UPDATE TBEDM_ZUGFERD_HISTORY_IN SET COMMENT = 'REJECTED - ZUGFeRD yes but incorrect format' WHERE GUID = '{HISTORY_ID}'"
|
|
_firebird.ExecuteNonQuery(oSQL)
|
|
|
|
Dim oBody = EmailStrings.EMAIL_INVALID_DOCUMENT
|
|
Dim oEmailData = MoveAndRenameEmailToRejected(oArgs, oMessageId)
|
|
_email.AddToEmailQueueMSSQL(oMessageId, oBody, oEmailData, "InvalidFerdException", _EmailOutAccountId, oSQLTransaction)
|
|
AddRejectedState(oMessageId, "InvalidFerdException", "Inkorrekte Formate", "", oSQLTransaction)
|
|
|
|
Catch ex As TooMuchFerdsException
|
|
_logger.Error(ex)
|
|
'oFBTransaction.Rollback()
|
|
|
|
Dim oSQL = $"UPDATE TBEDM_ZUGFERD_HISTORY_IN SET COMMENT = 'REJECTED - More than one ZUGFeRD-document in email' WHERE GUID = '{HISTORY_ID}'"
|
|
_firebird.ExecuteNonQuery(oSQL)
|
|
|
|
Dim oBody = EmailStrings.EMAIL_TOO_MUCH_FERDS
|
|
Dim oEmailData = MoveAndRenameEmailToRejected(oArgs, oMessageId)
|
|
_email.AddToEmailQueueMSSQL(oMessageId, oBody, oEmailData, "TooMuchFerdsException", _EmailOutAccountId, oSQLTransaction)
|
|
AddRejectedState(oMessageId, "TooMuchFerdsException", "Email enthielt mehr als ein ZUGFeRD-Dokument", "", oSQLTransaction)
|
|
|
|
Catch ex As NoFerdsException
|
|
_logger.Error(ex)
|
|
'oFBTransaction.Rollback()
|
|
|
|
Dim oSQL = $"UPDATE TBEDM_ZUGFERD_HISTORY_IN SET COMMENT = 'REJECTED - no ZUGFeRD-Document in email' WHERE GUID = '{HISTORY_ID}'"
|
|
_firebird.ExecuteNonQuery(oSQL)
|
|
|
|
Dim oBody = EmailStrings.EMAIL_NO_FERDS
|
|
Dim oEmailData = MoveAndRenameEmailToRejected(oArgs, oMessageId)
|
|
_email.AddToEmailQueueMSSQL(oMessageId, oBody, oEmailData, "NoFerdsException", _EmailOutAccountId, oSQLTransaction)
|
|
AddRejectedState(oMessageId, "NoFerdsException", " Email enthielt keine ZUGFeRD-Dokumente", "", oSQLTransaction)
|
|
|
|
Catch ex As MissingValueException
|
|
_logger.Error(ex)
|
|
'oFBTransaction.Rollback()
|
|
|
|
Dim oMessage As String = ""
|
|
For Each prop In oMissingProperties
|
|
oMessage &= $"- {prop}"
|
|
Next
|
|
Dim oSQL = $"UPDATE TBEDM_ZUGFERD_HISTORY_IN SET COMMENT = 'REJECTED - Missing Required Properties: [{oMessage}]' WHERE GUID = '{HISTORY_ID}'"
|
|
_firebird.ExecuteNonQuery(oSQL)
|
|
|
|
Dim oBody = CreateBodyForMissingProperties(ex.File.Name, oMissingProperties)
|
|
Dim oEmailData = MoveAndRenameEmailToRejected(oArgs, oMessageId)
|
|
_email.AddToEmailQueueMSSQL(oMessageId, oBody, oEmailData, "MissingValueException", _EmailOutAccountId, oSQLTransaction)
|
|
AddRejectedState(oMessageId, "MissingValueException", "Es fehlten ZugferdSpezifikationen", oMessage, oSQLTransaction)
|
|
|
|
Catch ex As OutOfMemoryException
|
|
_logger.Warn("OutOfMemory Error occurred: {0}", ex.Message)
|
|
_logger.Error(ex)
|
|
|
|
' Rollback Firebird
|
|
oFBTransaction.Rollback()
|
|
|
|
' Rollback MSSQL
|
|
oSQLTransaction.Rollback()
|
|
|
|
oMoveDirectory = DIRECTORY_DONT_MOVE
|
|
|
|
Catch ex As Exception
|
|
_logger.Warn("Unknown Error occurred: {0}", ex.Message)
|
|
_logger.Error(ex)
|
|
|
|
' Rollback Firebird
|
|
oFBTransaction.Rollback()
|
|
|
|
' Rollback MSSQL
|
|
oSQLTransaction.Rollback()
|
|
|
|
oMoveDirectory = DIRECTORY_DONT_MOVE
|
|
|
|
Finally
|
|
Try
|
|
' If everything went OK, finally commit all changes to the Database
|
|
' ==================================================================
|
|
If oIsSuccess Then
|
|
' Commit SQL Transaction
|
|
oSQLTransaction.Commit()
|
|
|
|
' Commit Firebird Transaction
|
|
oFBTransaction.Commit()
|
|
End If
|
|
Catch ex As Exception
|
|
_logger.Error(ex)
|
|
_logger.Warn("Database Transactions were not committed successfully.")
|
|
End Try
|
|
|
|
Try
|
|
oFBConnection.Close()
|
|
oSQLConnection.Close()
|
|
Catch ex As Exception
|
|
_logger.Error(ex)
|
|
_logger.Warn("Database Connections were not closed successfully.")
|
|
End Try
|
|
|
|
Try
|
|
' If an application error occurred, dont move files so they will be processed again later
|
|
If oMoveDirectory = DIRECTORY_DONT_MOVE Then
|
|
_logger.Info("Application Error occurred. Files for message Id {0} will not be moved.", oMessageId)
|
|
Else
|
|
' Move all files of the current group
|
|
MoveFiles(oArgs, oMessageId, oFileGroupFiles, oEmailAttachmentFiles, oEmbeddedAttachmentFiles, oMoveDirectory, oIsSuccess)
|
|
End If
|
|
_logger.Info("Finished processing file group {0}", oMessageId)
|
|
Catch ex As Exception
|
|
_logger.Warn("Could not move files!")
|
|
_logger.Error(ex)
|
|
Throw ex
|
|
Finally
|
|
_logger.EndBlock()
|
|
End Try
|
|
End Try
|
|
Next
|
|
End If
|
|
Next
|
|
|
|
_logger.Debug("Finishing Job {0}", Me.GetType.Name)
|
|
Catch ex As Exception
|
|
_logger.Error(ex)
|
|
_logger.Info("Job Failed! See error log for details")
|
|
End Try
|
|
End Sub
|
|
|
|
Private Sub MoveFiles(
|
|
Args As WorkerArgs,
|
|
MessageId As String,
|
|
Files As List(Of FileInfo),
|
|
AttachmentFiles As List(Of FileInfo),
|
|
EmbeddedAttachments As List(Of PDFEmbeds.EmbeddedFile),
|
|
MoveDirectory As String,
|
|
IsSuccess As Boolean)
|
|
|
|
Dim oFinalMoveDirectory As String = MoveDirectory
|
|
Dim oDateSubDirectoryName As String = Now.ToString("yyyy\\MM\\dd")
|
|
Dim oAttachmentDirectory As String = Path.Combine(oFinalMoveDirectory, Args.AttachmentsSubDirectory, oDateSubDirectoryName)
|
|
|
|
' Files will be moved to a subfolder for the current day if they are rejected
|
|
If Not IsSuccess Then
|
|
oFinalMoveDirectory = Path.Combine(oFinalMoveDirectory, oDateSubDirectoryName)
|
|
End If
|
|
|
|
' Create directories if they don't exist
|
|
If Not Directory.Exists(oFinalMoveDirectory) Then
|
|
Try
|
|
Directory.CreateDirectory(oFinalMoveDirectory)
|
|
Catch ex As Exception
|
|
_logger.Error(ex)
|
|
End Try
|
|
End If
|
|
|
|
If Not Directory.Exists(oAttachmentDirectory) And AttachmentFiles.Count > 0 Then
|
|
Try
|
|
Directory.CreateDirectory(oAttachmentDirectory)
|
|
Catch ex As Exception
|
|
_logger.Error(ex)
|
|
End Try
|
|
End If
|
|
|
|
' Filter out Attachments from `Files`
|
|
Dim oInvoiceFiles As List(Of FileInfo) = Files.Except(AttachmentFiles).ToList()
|
|
|
|
' Move PDF/A Files
|
|
For Each oFile In oInvoiceFiles
|
|
Try
|
|
Dim oFileName = _filesystem.GetVersionedFilename(Path.Combine(oFinalMoveDirectory, oFile.Name))
|
|
|
|
_filesystem.MoveTo(oFile.FullName, oFileName, oFinalMoveDirectory)
|
|
|
|
_logger.Info("Finished processing file {0}", oFile.Name)
|
|
_logger.Info("File moved to {0}", oFileName)
|
|
Catch ex As Exception
|
|
_logger.Warn("Could not move file {0}", oFile.FullName)
|
|
_logger.Error(ex)
|
|
End Try
|
|
Next
|
|
|
|
' Move non-PDF/A Email Attachments/Files
|
|
For Each oFile In AttachmentFiles
|
|
Try
|
|
Dim oFileName = _filesystem.GetVersionedFilename(Path.Combine(oAttachmentDirectory, oFile.Name))
|
|
|
|
_filesystem.MoveTo(oFile.FullName, oFileName, oAttachmentDirectory)
|
|
|
|
_logger.Info("Finished processing file {0}", oFile.Name)
|
|
_logger.Info("Attachment moved to {0}", oFileName)
|
|
Catch ex As Exception
|
|
_logger.Warn("Could not move attachment {0}", oFile.FullName)
|
|
_logger.Error(ex)
|
|
End Try
|
|
Next
|
|
|
|
' Write Embedded Files to disk
|
|
For Each oResult In EmbeddedAttachments
|
|
Try
|
|
Dim oFileName As String = $"{MessageId}~{oResult.FileName}"
|
|
Dim oFilePath As String = Path.Combine(oAttachmentDirectory, oFileName)
|
|
|
|
Using oWriter As New FileStream(oFilePath, FileMode.Create)
|
|
oWriter.Write(oResult.FileContents, 0, oResult.FileContents.Length)
|
|
End Using
|
|
Catch ex As Exception
|
|
_logger.Warn("Could not save embedded attachment {0}", oResult.FileName)
|
|
_logger.Error(ex)
|
|
End Try
|
|
Next
|
|
End Sub
|
|
|
|
|
|
Private Function CreateBodyForMissingProperties(OriginalFilename As String, MissingProperties As List(Of String))
|
|
Dim oBody = String.Format(EmailStrings.EMAIL_MISSINGPROPERTIES_1, OriginalFilename)
|
|
|
|
If MissingProperties.Count > 0 Then
|
|
oBody &= $"{vbNewLine}{vbNewLine}"
|
|
oBody &= EmailStrings.EMAIL_MISSINGPROPERTIES_2
|
|
oBody &= $"{vbNewLine}{vbNewLine}"
|
|
|
|
For Each prop In MissingProperties
|
|
oBody &= $"- {prop}"
|
|
Next
|
|
End If
|
|
|
|
Return oBody
|
|
End Function
|
|
Private Function CreateMD5(ByVal Filename As String) As String
|
|
Try
|
|
Dim oMD5 As New MD5CryptoServiceProvider
|
|
Dim oHash As Byte()
|
|
Dim oHashString As String
|
|
Dim oResult As String = ""
|
|
|
|
Using oFileStream As New FileStream(Filename, FileMode.Open, FileAccess.Read, FileShare.Read, 8192)
|
|
oHash = oMD5.ComputeHash(oFileStream)
|
|
oHashString = BitConverter.ToString(oHash)
|
|
End Using
|
|
|
|
oResult = oHashString.Replace("-", "")
|
|
Return oResult
|
|
Catch ex As Exception
|
|
_logger.Error(ex)
|
|
Return ""
|
|
End Try
|
|
End Function
|
|
End Class
|