3 Commits

4 changed files with 73 additions and 47 deletions

View File

@@ -13,7 +13,7 @@ Imports System.Runtime.InteropServices
<Assembly: AssemblyCompany("Digital Data")> <Assembly: AssemblyCompany("Digital Data")>
<Assembly: AssemblyProduct("Modules.Jobs")> <Assembly: AssemblyProduct("Modules.Jobs")>
<Assembly: AssemblyCopyright("Copyright © 2024")> <Assembly: AssemblyCopyright("Copyright © 2024")>
<Assembly: AssemblyTrademark("2.5.9.0")> <Assembly: AssemblyTrademark("2.6.0.0")>
<Assembly: ComVisible(False)> <Assembly: ComVisible(False)>
@@ -30,5 +30,5 @@ Imports System.Runtime.InteropServices
' Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern ' Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern
' übernehmen, indem Sie "*" eingeben: ' übernehmen, indem Sie "*" eingeben:
<Assembly: AssemblyVersion("2.5.9.0")> <Assembly: AssemblyVersion("2.6.0.0")>
<Assembly: AssemblyFileVersion("2.5.9.0")> <Assembly: AssemblyFileVersion("2.6.0.0")>

View File

@@ -72,12 +72,7 @@ Public Class HashFunctions
End Try End Try
' Try to get the original filename from Attachment table Dim oOriginalName As Object = GetOriginalFilename(pFile.Name)
' If this fails, falls back to the new filename (<msgid>~Attm<i>.ext)
Dim oSQL = $"SELECT EMAIL_ATTMT FROM TBEMLP_HISTORY_ATTACHMENT WHERE EMAIL_ATTMT_INDEX = '{pFile.Name}'"
Dim oEmailAttachment = Database.GetScalarValue(oSQL, MSSQLServer.TransactionMode.NoTransaction)
Dim oOriginalName = ObjectEx.NotNull(oEmailAttachment, pFile.Name)
Logger.Info("File with MessageId [{0}] and Filename [{1}] has already been processed.", pMessageId, oOriginalName) Logger.Info("File with MessageId [{0}] and Filename [{1}] has already been processed.", pMessageId, oOriginalName)
' If the file was already rejected, it is allowed to be processed again, ' If the file was already rejected, it is allowed to be processed again,
@@ -101,6 +96,15 @@ Public Class HashFunctions
Return oMD5CheckSum Return oMD5CheckSum
End Function End Function
Public Function GetOriginalFilename(pFilename As String) As String
' Try to get the original filename from Attachment table
' If this fails, falls back to the new filename (<msgid>~Attm<i>.ext)
Dim oSQL = $"SELECT EMAIL_ATTMT FROM TBEMLP_HISTORY_ATTACHMENT WHERE EMAIL_ATTMT_INDEX = '{pFilename}'"
Dim oEmailAttachment = Database.GetScalarValue(oSQL, MSSQLServer.TransactionMode.NoTransaction)
Dim oOriginalName = ObjectEx.NotNull(oEmailAttachment, pFilename)
Return oOriginalName
End Function
Private Function CreateMD5(pFilename As String) As String Private Function CreateMD5(pFilename As String) As String
Try Try
Dim oMD5 As New MD5CryptoServiceProvider Dim oMD5 As New MD5CryptoServiceProvider

View File

@@ -1,8 +1,5 @@
Imports System.Data.SqlClient Imports DigitalData.Modules.Database
Imports System.ServiceModel.Channels
Imports DigitalData.Modules.Database
Imports DigitalData.Modules.Logging Imports DigitalData.Modules.Logging
Imports Microsoft.VisualBasic.FileIO
Namespace ZUGFeRD Namespace ZUGFeRD
Public Class HistoryFunctions Public Class HistoryFunctions
@@ -30,7 +27,8 @@ Namespace ZUGFeRD
MD5HASH = '{pMD5Checksum}' MD5HASH = '{pMD5Checksum}'
WHERE EMAIL_MSGID = '{pMessageId}'" WHERE EMAIL_MSGID = '{pMessageId}'"
If pMessage.Contains("REJECTED") Then 'If pMessage.Contains("REJECTED") Then
If pMessage.Contains(EmailStrings.ErrorCodePraefix) Then
oSQL = $"UPDATE TBEMLP_HISTORY SET oSQL = $"UPDATE TBEMLP_HISTORY SET
COMMENT = '{pMessage}', COMMENT = '{pMessage}',
MD5HASH = '{pMD5Checksum}', MD5HASH = '{pMD5Checksum}',

View File

@@ -1,17 +1,14 @@
Imports System.Collections.Generic Imports System.Collections.Generic
Imports System.Data Imports System.Data
Imports System.Data.SqlClient
Imports System.IO Imports System.IO
Imports System.Linq Imports System.Linq
Imports System.Security.Cryptography
Imports DigitalData.Modules.Base Imports DigitalData.Modules.Base
Imports DigitalData.Modules.Database Imports DigitalData.Modules.Database
Imports DigitalData.Modules.Interfaces Imports DigitalData.Modules.Interfaces
Imports DigitalData.Modules.Interfaces.Exceptions Imports DigitalData.Modules.Interfaces.Exceptions
Imports DigitalData.Modules.Jobs.Exceptions Imports DigitalData.Modules.Jobs.Exceptions
Imports DigitalData.Modules.Logging Imports DigitalData.Modules.Logging
Imports System.Data.SqlClient
Imports Newtonsoft.Json.Linq
Imports System.Xml.Linq
Public Class ImportZUGFeRDFiles Public Class ImportZUGFeRDFiles
Implements IJob Implements IJob
@@ -219,10 +216,14 @@ Public Class ImportZUGFeRDFiles
Catch ex As ValidationException Catch ex As ValidationException
_logger.Error(ex) _logger.Error(ex)
Dim oErrors = ex.ValidationErrors Dim oErrorCodeString = $"{EmailStrings.ErrorCodePraefix}{ErrorCode.ValidationException}"
Dim oMessage = "REJECTED - ZUGFeRD yes but formal validation failed!" Dim oErrorMessage = $"Error {oErrorCodeString} occured for '{oMessageId}'"
_history.Update_HistoryEntry(oMessageId, oMD5CheckSum, oMessage) _logger.Error(oErrorMessage)
'Dim oMessage = "REJECTED - ZUGFeRD yes but formal validation failed!"
_history.Update_HistoryEntry(oMessageId, oMD5CheckSum, oErrorCodeString)
Dim oErrors = ex.ValidationErrors
Dim oErrorList As String = "" Dim oErrorList As String = ""
Dim oErrorListDE As String = "" Dim oErrorListDE As String = ""
For Each oError In oErrors For Each oError In oErrors
@@ -233,106 +234,129 @@ Public Class ImportZUGFeRDFiles
Dim oBody = String.Format(EmailStrings.EMAIL_VALIDATION_ERROR, oErrorList) Dim oBody = String.Format(EmailStrings.EMAIL_VALIDATION_ERROR, oErrorList)
Dim oEmailData = _file.MoveAndRenameEmailToRejected(oArgs, oMessageId) Dim oEmailData = _file.MoveAndRenameEmailToRejected(oArgs, oMessageId)
_email.AddToEmailQueueMSSQL(oMessageId, oSQLTransaction, oBody, oEmailData, "ValidationException", _EmailOutAccountId, oArgs.NamePortal, oArgs.RejectionTemplateId, ErrorCode.ValidationException, oErrorListDE, oErrorList) _email.AddToEmailQueueMSSQL(oMessageId, oSQLTransaction, oBody, oEmailData, "ValidationException", _EmailOutAccountId, oArgs.NamePortal, oArgs.RejectionTemplateId, ErrorCode.ValidationException, oErrorListDE, oErrorList)
AddRejectedState(oMessageId, "ValidationException", "Die Rechnungsvalidierung ist fehlgeschlagen!", "", oSQLTransaction) AddRejectedState(oMessageId, oErrorCodeString, "Die Rechnungsvalidierung ist fehlgeschlagen!", "", oSQLTransaction)
Catch ex As MD5HashException Catch ex As MD5HashException
_logger.Error(ex) _logger.Error(ex)
Dim oErrorCodeString = $"{EmailStrings.ErrorCodePraefix}{ErrorCode.MD5HashException}"
Dim oErrorMessage = $"Error {oErrorCodeString} occured for '{oMessageId}'"
_logger.Error(oErrorMessage)
' When MD5HashException is thrown, we don't have a MD5Hash yet. ' When MD5HashException is thrown, we don't have a MD5Hash yet.
' That 's why we set it to String.Empty here. ' That 's why we set it to String.Empty here.
Dim oMessage = "REJECTED - Already processed (MD5Hash)" 'Dim oMessage = "REJECTED - Already processed (MD5Hash)"
_history.Update_HistoryEntry(oMessageId, String.Empty, oMessage) _history.Update_HistoryEntry(oMessageId, String.Empty, oErrorCodeString)
Dim oBody = String.Format(EmailStrings.EMAIL_MD5_ERROR, ex.FileName) Dim oBody = String.Format(EmailStrings.EMAIL_MD5_ERROR, ex.FileName)
Dim oEmailData = _file.MoveAndRenameEmailToRejected(oArgs, oMessageId) Dim oEmailData = _file.MoveAndRenameEmailToRejected(oArgs, oMessageId)
_email.AddToEmailQueueMSSQL(oMessageId, oSQLTransaction, oBody, oEmailData, "MD5HashException", _EmailOutAccountId, oArgs.NamePortal, oArgs.RejectionTemplateId, ErrorCode.MD5HashException, ex.FileName, "") _email.AddToEmailQueueMSSQL(oMessageId, oSQLTransaction, oBody, oEmailData, "MD5HashException", _EmailOutAccountId, oArgs.NamePortal, oArgs.RejectionTemplateId, ErrorCode.MD5HashException, ex.FileName, "")
AddRejectedState(oMessageId, "MD5HashException", "Die gesendete Rechnung wurde bereits verarbeitet!", "", oSQLTransaction) AddRejectedState(oMessageId, oErrorCodeString, "Die gesendete Rechnung wurde bereits verarbeitet!", "", oSQLTransaction)
Catch ex As UnsupportedFerdException Catch ex As UnsupportedFerdException
_logger.Error(ex) _logger.Error(ex)
Dim oErrorCodeString = $"{EmailStrings.ErrorCodePraefix}{ErrorCode.UnsupportedFerdException}"
Dim oErrorMessage = $"Error {oErrorCodeString} occured for '{oMessageId}'"
_logger.Error(oErrorMessage)
' When UnsupportedFerdException is thrown, we don't have a MD5Hash yet. ' When UnsupportedFerdException is thrown, we don't have a MD5Hash yet.
' That 's why we set it to String.Empty here. ' That 's why we set it to String.Empty here.
_history.Update_HistoryEntry(oMessageId, String.Empty, "REJECTED - ZUGFeRD yes but unsupported format") _history.Update_HistoryEntry(oMessageId, String.Empty, oErrorCodeString)
Dim oEmailData = _file.MoveAndRenameEmailToRejected(oArgs, oMessageId) Dim oEmailData = _file.MoveAndRenameEmailToRejected(oArgs, oMessageId)
Dim oBody As String = String.Format(EmailStrings.EMAIL_UNSUPPORTED_DOCUMENT, oEmailData.Subject, ex.XmlFile) Dim oBody As String = String.Format(EmailStrings.EMAIL_UNSUPPORTED_DOCUMENT, oEmailData.Subject, ex.XmlFile)
_email.AddToEmailQueueMSSQL(oMessageId, oSQLTransaction, oBody, oEmailData, "UnsupportedFerdException", _EmailOutAccountId, oArgs.NamePortal, oArgs.RejectionTemplateId, ErrorCode.UnsupportedFerdException, ex.XmlFile, "") _email.AddToEmailQueueMSSQL(oMessageId, oSQLTransaction, oBody, oEmailData, "UnsupportedFerdException", _EmailOutAccountId, oArgs.NamePortal, oArgs.RejectionTemplateId, ErrorCode.UnsupportedFerdException, ex.XmlFile, "")
AddRejectedState(oMessageId, "UnsupportedFerdException", "Nicht unterstütztes Datenformat", "", oSQLTransaction) AddRejectedState(oMessageId, oErrorCodeString, "Nicht unterstütztes Datenformat", "", oSQLTransaction)
Catch ex As InvalidFerdException Catch ex As InvalidFerdException
_logger.Error(ex) _logger.Error(ex)
Dim oErrorCodeString = $"{EmailStrings.ErrorCodePraefix}{ErrorCode.InvalidFerdException}"
Dim oErrorMessage = $"Error {oErrorCodeString} occured for '{oMessageId}'"
_logger.Error(oErrorMessage)
' When InvalidFerdException is thrown, we don't have a MD5Hash yet. ' When InvalidFerdException is thrown, we don't have a MD5Hash yet.
' That 's why we set it to String.Empty here. ' That 's why we set it to String.Empty here.
_history.Update_HistoryEntry(oMessageId, String.Empty, "REJECTED - ZUGFeRD yes but incorrect format") _history.Update_HistoryEntry(oMessageId, String.Empty, oErrorCodeString)
Dim oEmailData = _file.MoveAndRenameEmailToRejected(oArgs, oMessageId) Dim oEmailData = _file.MoveAndRenameEmailToRejected(oArgs, oMessageId)
Dim oBody = String.Format(EmailStrings.EMAIL_INVALID_DOCUMENT, oEmailData.Subject) Dim oBody = String.Format(EmailStrings.EMAIL_INVALID_DOCUMENT, oEmailData.Subject)
_email.AddToEmailQueueMSSQL(oMessageId, oSQLTransaction, oBody, oEmailData, "InvalidFerdException", _EmailOutAccountId, oArgs.NamePortal, oArgs.RejectionTemplateId, ErrorCode.InvalidFerdException, "", "") _email.AddToEmailQueueMSSQL(oMessageId, oSQLTransaction, oBody, oEmailData, "InvalidFerdException", _EmailOutAccountId, oArgs.NamePortal, oArgs.RejectionTemplateId, ErrorCode.InvalidFerdException, "", "")
AddRejectedState(oMessageId, "InvalidFerdException", "Inkorrekte Formate", "", oSQLTransaction) AddRejectedState(oMessageId, oErrorCodeString, "Inkorrektes Format", "", oSQLTransaction)
Catch ex As TooMuchFerdsException Catch ex As TooMuchFerdsException
_logger.Error(ex) _logger.Error(ex)
_history.Update_HistoryEntry(oMessageId, oMD5CheckSum, "REJECTED - More than one ZUGFeRD-document in email") Dim oErrorCodeString = $"{EmailStrings.ErrorCodePraefix}{ErrorCode.TooMuchFerdsException}"
Dim oErrorMessage = $"Error {oErrorCodeString} occured for '{oMessageId}'"
_logger.Error(oErrorMessage)
_history.Update_HistoryEntry(oMessageId, oMD5CheckSum, oErrorCodeString)
Dim oEmailData = _file.MoveAndRenameEmailToRejected(oArgs, oMessageId) Dim oEmailData = _file.MoveAndRenameEmailToRejected(oArgs, oMessageId)
Dim oBody = String.Format(EmailStrings.EMAIL_TOO_MUCH_FERDS, oEmailData.Subject) Dim oBody = String.Format(EmailStrings.EMAIL_TOO_MUCH_FERDS, oEmailData.Subject)
_email.AddToEmailQueueMSSQL(oMessageId, oSQLTransaction, oBody, oEmailData, "TooMuchFerdsException", _EmailOutAccountId, oArgs.NamePortal, oArgs.RejectionTemplateId, ErrorCode.TooMuchFerdsException, "", "") _email.AddToEmailQueueMSSQL(oMessageId, oSQLTransaction, oBody, oEmailData, "TooMuchFerdsException", _EmailOutAccountId, oArgs.NamePortal, oArgs.RejectionTemplateId, ErrorCode.TooMuchFerdsException, "", "")
AddRejectedState(oMessageId, "TooMuchFerdsException", "Email enthielt mehr als ein ZUGFeRD-Dokument", "", oSQLTransaction) AddRejectedState(oMessageId, oErrorCodeString, "Email enthielt mehr als ein ZUGFeRD-Dokument", "", oSQLTransaction)
Catch ex As NoFerdsException Catch ex As NoFerdsException
_logger.Error(ex) _logger.Error(ex)
_history.Update_HistoryEntry(oMessageId, oMD5CheckSum, "REJECTED - no ZUGFeRD-Document in email") Dim oErrorCodeString = $"{EmailStrings.ErrorCodePraefix}{ErrorCode.NoFerdsException}"
Dim oErrorMessage = $"Error {oErrorCodeString} occured for '{oMessageId}'"
_logger.Error(oErrorMessage)
_history.Update_HistoryEntry(oMessageId, oMD5CheckSum, oErrorCodeString)
Dim oEmailData = _file.MoveAndRenameEmailToRejected(oArgs, oMessageId) Dim oEmailData = _file.MoveAndRenameEmailToRejected(oArgs, oMessageId)
Dim oBody = String.Format(EmailStrings.EMAIL_NO_FERDS, oEmailData.Subject) Dim oBody = String.Format(EmailStrings.EMAIL_NO_FERDS, oEmailData.Subject)
_email.AddToEmailQueueMSSQL(oMessageId, oSQLTransaction, oBody, oEmailData, "NoFerdsException", _EmailOutAccountId, oArgs.NamePortal, oArgs.RejectionTemplateId, ErrorCode.NoFerdsException, "", "") _email.AddToEmailQueueMSSQL(oMessageId, oSQLTransaction, oBody, oEmailData, "NoFerdsException", _EmailOutAccountId, oArgs.NamePortal, oArgs.RejectionTemplateId, ErrorCode.NoFerdsException, "", "")
AddRejectedState(oMessageId, "NoFerdsException", " Email enthielt keine ZUGFeRD-Dokumente", "", oSQLTransaction) AddRejectedState(oMessageId, oErrorCodeString, "Email enthielt keine ZUGFeRD-Dokumente", "", oSQLTransaction)
Catch ex As MissingValueException Catch ex As MissingValueException
_logger.Error(ex) _logger.Error(ex)
Dim oMessage As String = "" Dim oErrorCodeString = $"{EmailStrings.ErrorCodePraefix}{ErrorCode.MissingValueException}"
For Each prop In ex.MissingProperties Dim oErrorMessage = $"Error {oErrorCodeString} occured for '{oMessageId}'"
oMessage &= $"- {prop}" _logger.Error(oErrorMessage)
Next
_history.Update_HistoryEntry(oMessageId, oMD5CheckSum, $"REJECTED - Missing Required Properties: [{oMessage}]") _history.Update_HistoryEntry(oMessageId, oMD5CheckSum, oErrorCodeString)
Dim oMissingFieldList As String = "" Dim oMissingFieldList As String = ""
For Each oMissingFieldDescription In ex.MissingProperties For Each oMissingFieldDescription In ex.MissingProperties
oMissingFieldList += $"<li>{oMissingFieldDescription}</li>" oMissingFieldList += $"<li>{oMissingFieldDescription}</li>"
Next Next
Dim oOrgFilename = _hash.GetOriginalFilename(ex.File.Name)
Dim oBody = _email.CreateBodyForMissingProperties(ex.File.Name, ex.MissingProperties) Dim oBody = _email.CreateBodyForMissingProperties(ex.File.Name, ex.MissingProperties)
Dim oEmailData = _file.MoveAndRenameEmailToRejected(oArgs, oMessageId) Dim oEmailData = _file.MoveAndRenameEmailToRejected(oArgs, oMessageId)
_email.AddToEmailQueueMSSQL(oMessageId, oSQLTransaction, oBody, oEmailData, "MissingValueException", _EmailOutAccountId, oArgs.NamePortal, oArgs.RejectionTemplateId, ErrorCode.MissingValueException, ex.File.Name, oMissingFieldList)
AddRejectedState(oMessageId, "MissingValueException", "Es fehlten ZugferdSpezifikationen", oMessage, oSQLTransaction) _email.AddToEmailQueueMSSQL(oMessageId, oSQLTransaction, oBody, oEmailData, "MissingValueException", _EmailOutAccountId, oArgs.NamePortal, oArgs.RejectionTemplateId, ErrorCode.MissingValueException, oOrgFilename, oMissingFieldList)
AddRejectedState(oMessageId, oErrorCodeString, "Es fehlten ZugferdSpezifikationen", "", oSQLTransaction)
Catch ex As FileSizeLimitReachedException Catch ex As FileSizeLimitReachedException
_logger.Error(ex) _logger.Error(ex)
_history.Update_HistoryEntry(oMessageId, oMD5CheckSum, "REJECTED - File size limit reached") Dim oErrorCodeString = $"{EmailStrings.ErrorCodePraefix}{ErrorCode.FileSizeLimitReachedException}"
Dim oErrorMessage = $"Error {oErrorCodeString} occured for '{oMessageId}'"
_logger.Error(oErrorMessage)
_history.Update_HistoryEntry(oMessageId, oMD5CheckSum, oErrorCodeString)
Dim oEmailData = _file.MoveAndRenameEmailToRejected(oArgs, oMessageId) Dim oEmailData = _file.MoveAndRenameEmailToRejected(oArgs, oMessageId)
Dim oKey = FileSizeLimitReachedException.KEY_FILENAME Dim oKey = FileSizeLimitReachedException.KEY_FILENAME
Dim oFileExceedingThreshold As String = IIf(ex.Data.Contains(oKey), ex.Data.Item(oKey), "") Dim oFileExceedingThreshold As String = IIf(ex.Data.Contains(oKey), ex.Data.Item(oKey), "")
Dim oFileWithoutMessageId = oFileExceedingThreshold. Dim oOrgFilename = _hash.GetOriginalFilename(oFileExceedingThreshold)
Replace(oMessageId, "").
Replace("~", "")
Dim oBody = String.Format(EmailStrings.EMAIL_FILE_SIZE_REACHED, oArgs.MaxAttachmentSizeInMegaBytes, oFileWithoutMessageId) Dim oBody = String.Format(EmailStrings.EMAIL_FILE_SIZE_REACHED, oArgs.MaxAttachmentSizeInMegaBytes, oOrgFilename)
_email.AddToEmailQueueMSSQL(oMessageId, oSQLTransaction, oBody, oEmailData, "FileSizeLimitReachedException", _EmailOutAccountId, oArgs.NamePortal, oArgs.RejectionTemplateId, ErrorCode.FileSizeLimitReachedException, oArgs.MaxAttachmentSizeInMegaBytes, oFileWithoutMessageId) _email.AddToEmailQueueMSSQL(oMessageId, oSQLTransaction, oBody, oEmailData, "FileSizeLimitReachedException", _EmailOutAccountId, oArgs.NamePortal, oArgs.RejectionTemplateId, ErrorCode.FileSizeLimitReachedException, oArgs.MaxAttachmentSizeInMegaBytes, oOrgFilename)
AddRejectedState(oMessageId, "FileSizeLimitReachedException", "Erlaubte Dateigröße überschritten", "", oSQLTransaction) AddRejectedState(oMessageId, oErrorCodeString, "Erlaubte Dateigröße überschritten", "", oSQLTransaction)
Catch ex As NoFerdsAlternateException Catch ex As NoFerdsAlternateException