MergeCommit
This commit is contained in:
commit
6a051f7a92
@ -1,7 +1,9 @@
|
||||
Imports System.IO
|
||||
Imports System.Reflection
|
||||
Imports System.Xml
|
||||
Imports System.Xml.Serialization
|
||||
Imports DigitalData.Modules.Interfaces.Exceptions
|
||||
Imports DigitalData.Modules.Interfaces.PDFEmbeds
|
||||
Imports DigitalData.Modules.Interfaces.Peppol
|
||||
Imports DigitalData.Modules.Interfaces.ZUGFeRD
|
||||
Imports DigitalData.Modules.Logging
|
||||
@ -138,6 +140,44 @@ Public Class ZUGFeRDInterface
|
||||
End If
|
||||
End Function
|
||||
|
||||
Public Function GetSerializedXMLContentFromFile(oFileInfo As FileInfo) As ZugferdResult
|
||||
Dim oResult = New ZugferdResult()
|
||||
|
||||
Try
|
||||
Dim oFileSize As Integer = oFileInfo.Length
|
||||
Dim oFileData As Byte() = File.ReadAllBytes(oFileInfo.FullName)
|
||||
|
||||
Dim oXmlFile As EmbeddedFile = New EmbeddedFile() With {
|
||||
.FileName = oFileInfo.Name,
|
||||
.FileContents = oFileData
|
||||
}
|
||||
|
||||
Using oStream As New MemoryStream(oXmlFile.FileContents)
|
||||
oResult = New ZugferdResult With {
|
||||
.DataFileName = oXmlFile.FileName,
|
||||
.XElementObject = XElement.Load(oStream)
|
||||
}
|
||||
End Using
|
||||
|
||||
Catch ex As ZUGFeRDExecption
|
||||
' Don't log ZUGFeRD Exceptions here, they should be handled by the calling code.
|
||||
' It also produces misleading error messages when checking if an attachment is a zugferd file.
|
||||
Throw ex
|
||||
|
||||
Catch ex As Exception
|
||||
_logger.Error(ex)
|
||||
Throw New ZUGFeRDExecption(ErrorType.NoValidZugferd, "Datei ist eine ungültige XML Datei.")
|
||||
End Try
|
||||
|
||||
If oResult.ValidationErrors.Any() Then
|
||||
Throw New ValidationException() With {
|
||||
.ValidationErrors = oResult.ValidationErrors
|
||||
}
|
||||
End If
|
||||
|
||||
Return SerializeZUGFeRDDocument(oResult)
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' Validates a ZUGFeRD File and extracts the XML Document from it
|
||||
''' </summary>
|
||||
|
||||
@ -30,6 +30,8 @@ Public Class PropertyValues
|
||||
Public Description As String
|
||||
Public Value As String
|
||||
Public XMLPath As String
|
||||
|
||||
Public ItemType As Integer = 0
|
||||
End Class
|
||||
|
||||
Public Class MissingProperty
|
||||
@ -109,6 +111,7 @@ Public Class PropertyValues
|
||||
Dim oIsRequired As Boolean = oColumn.Key.IsRequired
|
||||
Dim oPropertyDescription As String = oColumn.Key.Description
|
||||
Dim oPropertyPath As String = oColumn.Key.XMLPath
|
||||
Dim oItemType As Integer = oColumn.Key.ItemType
|
||||
|
||||
Dim oRowCounter = oRowIndex + oGlobalGroupCounter + 1
|
||||
|
||||
@ -144,7 +147,8 @@ Public Class PropertyValues
|
||||
.TableName = oTableName,
|
||||
.TableColumn = oTableColumn,
|
||||
.IsRequired = oIsRequired,
|
||||
.XMLPath = oPropertyPath
|
||||
.XMLPath = oPropertyPath,
|
||||
.ItemType = oItemType
|
||||
})
|
||||
Next
|
||||
Next
|
||||
@ -162,6 +166,7 @@ Public Class PropertyValues
|
||||
Dim oTableName = oItem.Value.TableName
|
||||
Dim oIsRequired = oItem.Value.IsRequired
|
||||
Dim oDescription = oItem.Value.Description
|
||||
Dim oItemType = oItem.Value.ItemType
|
||||
|
||||
Try
|
||||
oPropertyValueList = GetPropValue(pDocument, oItem.Key)
|
||||
@ -225,7 +230,8 @@ Public Class PropertyValues
|
||||
.TableName = oTableName,
|
||||
.TableColumn = oTableColumn,
|
||||
.IsRequired = oIsRequired,
|
||||
.XMLPath = oPropertyPath
|
||||
.XMLPath = oPropertyPath,
|
||||
.ItemType = oItemType
|
||||
})
|
||||
Next
|
||||
|
||||
@ -304,7 +310,6 @@ Public Class PropertyValues
|
||||
Return oResults
|
||||
End If
|
||||
|
||||
|
||||
Next
|
||||
|
||||
Return New List(Of Object) From {Obj}
|
||||
|
||||
@ -16,4 +16,13 @@
|
||||
''' XML Pfad, für Anzeige in Ablehnungsmail
|
||||
''' </summary>
|
||||
Public XMLPath As String
|
||||
|
||||
''' <summary>
|
||||
''' (Daten-)Typ des Knoten
|
||||
''' 0 = Default / Text
|
||||
''' 1 = Datum
|
||||
''' 2 = Gleitkomma
|
||||
''' 3 = Memo-Feld
|
||||
''' </summary>
|
||||
Public ItemType As Integer
|
||||
End Class
|
||||
@ -116,6 +116,7 @@
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="ZUGFeRD\XRechnungViewDocument.vb" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="FirebirdSql.Data.FirebirdClient, Version=7.5.0.0, Culture=neutral, PublicKeyToken=3750abcc3150b00c, processorArchitecture=MSIL">
|
||||
|
||||
@ -166,14 +166,18 @@ Public Class ImportZUGFeRDFiles
|
||||
End If
|
||||
|
||||
Dim oEmailDataBase = _email.GetEmailDataForMessageId(oMessageId)
|
||||
Dim oFileCounter As Integer = 0
|
||||
|
||||
Try
|
||||
Dim oInNdex = 0
|
||||
For Each oFile In oFileGroupFiles
|
||||
'----------------------------
|
||||
'----------------------------
|
||||
'Hier Logik für xml/xRechnungs-Handling - paralleler Zweig zu ProcessFile
|
||||
Dim oResult As ProcessFileResult = ProcessFile(oMessageId, oEmailDataBase, oZUGFeRDCount, oFile, oConnections, oArgs)
|
||||
oFileCounter += 1
|
||||
Dim oResult As ProcessFileResult
|
||||
|
||||
If oFileCounter = 1 AndAlso oFile.Name.ToUpper.EndsWith(".XML") Then
|
||||
oResult = ProcessXMLFile(oMessageId, oZUGFeRDCount, oFile, oConnections, oArgs)
|
||||
Else
|
||||
oResult = ProcessFile(oMessageId, oZUGFeRDCount, oFile, oConnections, oArgs)
|
||||
End If
|
||||
|
||||
If oResult.ZugferdFileFound = True Then
|
||||
_logger.Debug("Zugferd File found")
|
||||
@ -394,6 +398,9 @@ Public Class ImportZUGFeRDFiles
|
||||
' 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)
|
||||
|
||||
ElseIf (1 = 0) Then
|
||||
' Hier das neue PDF erzeugen
|
||||
Else
|
||||
' Move all files of the current group
|
||||
_file.MoveFiles(oArgs, oMessageId, oFileGroupFiles, oEmailAttachmentFiles, oEmbeddedAttachmentFiles, oMoveDirectory, oIsSuccess)
|
||||
@ -459,34 +466,25 @@ Public Class ImportZUGFeRDFiles
|
||||
Return oRejectionCodeString
|
||||
End Function
|
||||
|
||||
Private Function ProcessFile(pMessageId As String, pEmailData As EmailData, pZugferdFiles As Integer, oFile As FileInfo, oConnections As DatabaseConnections, pArgs As WorkerArgs) As ProcessFileResult
|
||||
Private Function ProcessXMLFile(pMessageId As String, pZugferdFileCounter As Integer, pFile As FileInfo, pConnections As DatabaseConnections, pArgs As WorkerArgs) As ProcessFileResult
|
||||
Dim oDocument As ZUGFeRDInterface.ZugferdResult
|
||||
Dim oResult As New ProcessFileResult()
|
||||
|
||||
' Only pdf files are allowed from here on
|
||||
If Not oFile.Name.ToUpper.EndsWith(".PDF") Then
|
||||
_logger.Debug("Skipping non-pdf file {0}", oFile.Name)
|
||||
oResult.EmailAttachmentFiles.Add(oFile)
|
||||
|
||||
' Checking filesize for attachment files
|
||||
If _filesystem.TestFileSizeIsLessThanMaxFileSize(oFile.FullName, pArgs.MaxAttachmentSizeInMegaBytes) = False Then
|
||||
_logger.Warn("Filesize for File [{0}] exceeded limit of {1} MB", oFile.Name, pArgs.MaxAttachmentSizeInMegaBytes)
|
||||
Throw New FileSizeLimitReachedException(oFile.Name, pArgs.MaxAttachmentSizeInMegaBytes)
|
||||
End If
|
||||
|
||||
If pFile.Extension.Equals(".xml", StringComparison.OrdinalIgnoreCase) = False Then
|
||||
' Diese Methode ist nur für den xml-Beleg gedacht
|
||||
Return oResult
|
||||
End If
|
||||
|
||||
_logger.Info("Start processing file {0}", oFile.Name)
|
||||
_logger.Info("Start xml processing file {0}", pFile.Name)
|
||||
|
||||
' Checking filesize for pdf files
|
||||
If _filesystem.TestFileSizeIsLessThanMaxFileSize(oFile.FullName, pArgs.MaxAttachmentSizeInMegaBytes) = False Then
|
||||
_logger.Warn("Filesize for File [{0}] exceeded limit of {1} MB", oFile.Name, pArgs.MaxAttachmentSizeInMegaBytes)
|
||||
Throw New FileSizeLimitReachedException(oFile.Name, pArgs.MaxAttachmentSizeInMegaBytes)
|
||||
' Checking filesize
|
||||
If _filesystem.TestFileSizeIsLessThanMaxFileSize(pFile.FullName, pArgs.MaxAttachmentSizeInMegaBytes) = False Then
|
||||
_logger.Warn("Filesize for File [{0}] exceeded limit of {1} MB", pFile.Name, pArgs.MaxAttachmentSizeInMegaBytes)
|
||||
Throw New FileSizeLimitReachedException(pFile.Name, pArgs.MaxAttachmentSizeInMegaBytes)
|
||||
End If
|
||||
|
||||
Try
|
||||
oDocument = _zugferd.ExtractZUGFeRDFileWithGDPicture(oFile.FullName)
|
||||
oDocument = _zugferd.GetSerializedXMLContentFromFile(pFile)
|
||||
|
||||
Catch ex As ValidationException
|
||||
Throw ex
|
||||
@ -494,70 +492,156 @@ Public Class ImportZUGFeRDFiles
|
||||
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)
|
||||
_logger.Info("File [{0}] is not a valid ZUGFeRD document. Skipping.", pFile.Name)
|
||||
|
||||
oResult.EmailAttachmentFiles.Add(oFile)
|
||||
oResult.EmailAttachmentFiles.Add(pFile)
|
||||
Return oResult
|
||||
|
||||
Case ZUGFeRDInterface.ErrorType.UnsupportedFormat
|
||||
_logger.Info("File [{0}/{1}] is an unsupported ZUFeRD document format!", oFile.Name, ex.XmlFile)
|
||||
_logger.Info("File [{0}/{1}] is an unsupported ZUFeRD document format!", pFile.Name, ex.XmlFile)
|
||||
Throw New UnsupportedFerdException(ex.XmlFile)
|
||||
|
||||
Case ZUGFeRDInterface.ErrorType.NoValidZugferd
|
||||
_logger.Info("File [{0}] is an Incorrectly formatted ZUGFeRD document!", oFile.Name)
|
||||
_logger.Info("File [{0}] is an Incorrectly formatted ZUGFeRD document!", pFile.Name)
|
||||
Throw New InvalidFerdException()
|
||||
|
||||
Case Else
|
||||
_logger.Warn("Unexpected Error occurred while extracting ZUGFeRD Information from file {0}", oFile.Name)
|
||||
_logger.Warn("Unexpected Error occurred while extracting ZUGFeRD Information from file {0}", pFile.Name)
|
||||
Throw ex
|
||||
End Select
|
||||
|
||||
End Try
|
||||
|
||||
Try
|
||||
Dim sqlResult As Boolean = StoreXMLItemsInDatabase(pMessageId, oDocument, pFile, pConnections, pArgs)
|
||||
Catch ex As Exception
|
||||
Throw ex
|
||||
End Try
|
||||
|
||||
_logger.Debug("File processed.")
|
||||
|
||||
Dim oMD5Checksum = _hash.GenerateAndCheck_MD5Sum(pFile, pMessageId, pArgs.IgnoreRejectionStatus)
|
||||
oResult.ZugferdFileFound = True
|
||||
oResult.MD5Checksum = oMD5Checksum
|
||||
oResult.ZugferdFileCount = 1 ' Es kann hier nur genau einen Treffer geben!
|
||||
|
||||
Return oResult
|
||||
End Function
|
||||
|
||||
Private Function ProcessFile(pMessageId As String, pZugferdFileCounter As Integer, pFile As FileInfo, pConnections As DatabaseConnections, pArgs As WorkerArgs) As ProcessFileResult
|
||||
Dim oDocument As ZUGFeRDInterface.ZugferdResult
|
||||
Dim oResult As New ProcessFileResult()
|
||||
|
||||
' Only pdf files are allowed from here on
|
||||
If Not pFile.Name.ToUpper.EndsWith(".PDF") Then
|
||||
_logger.Debug("Skipping non-pdf file {0}", pFile.Name)
|
||||
oResult.EmailAttachmentFiles.Add(pFile)
|
||||
|
||||
' Checking filesize for attachment files
|
||||
If _filesystem.TestFileSizeIsLessThanMaxFileSize(pFile.FullName, pArgs.MaxAttachmentSizeInMegaBytes) = False Then
|
||||
_logger.Warn("Filesize for File [{0}] exceeded limit of {1} MB", pFile.Name, pArgs.MaxAttachmentSizeInMegaBytes)
|
||||
Throw New FileSizeLimitReachedException(pFile.Name, pArgs.MaxAttachmentSizeInMegaBytes)
|
||||
End If
|
||||
|
||||
Return oResult
|
||||
End If
|
||||
|
||||
_logger.Info("Start processing file {0}", pFile.Name)
|
||||
|
||||
' Checking filesize for pdf files
|
||||
If _filesystem.TestFileSizeIsLessThanMaxFileSize(pFile.FullName, pArgs.MaxAttachmentSizeInMegaBytes) = False Then
|
||||
_logger.Warn("Filesize for File [{0}] exceeded limit of {1} MB", pFile.Name, pArgs.MaxAttachmentSizeInMegaBytes)
|
||||
Throw New FileSizeLimitReachedException(pFile.Name, pArgs.MaxAttachmentSizeInMegaBytes)
|
||||
End If
|
||||
|
||||
Try
|
||||
oDocument = _zugferd.ExtractZUGFeRDFileWithGDPicture(pFile.FullName)
|
||||
|
||||
Catch ex As ValidationException
|
||||
Throw ex
|
||||
|
||||
Catch ex As ZUGFeRDExecption
|
||||
Select Case ex.ErrorType
|
||||
Case ZUGFeRDInterface.ErrorType.NoZugferd
|
||||
_logger.Info("File [{0}] is not a valid ZUGFeRD document. Skipping.", pFile.Name)
|
||||
|
||||
oResult.EmailAttachmentFiles.Add(pFile)
|
||||
Return oResult
|
||||
|
||||
Case ZUGFeRDInterface.ErrorType.UnsupportedFormat
|
||||
_logger.Info("File [{0}/{1}] is an unsupported ZUFeRD document format!", pFile.Name, ex.XmlFile)
|
||||
Throw New UnsupportedFerdException(ex.XmlFile)
|
||||
|
||||
Case ZUGFeRDInterface.ErrorType.NoValidZugferd
|
||||
_logger.Info("File [{0}] is an Incorrectly formatted ZUGFeRD document!", pFile.Name)
|
||||
Throw New InvalidFerdException()
|
||||
|
||||
Case Else
|
||||
_logger.Warn("Unexpected Error occurred while extracting ZUGFeRD Information from file {0}", pFile.Name)
|
||||
Throw ex
|
||||
End Select
|
||||
End Try
|
||||
|
||||
' Check if there are more than one ZUGFeRD files
|
||||
If pZugferdFiles = 1 Then
|
||||
If pZugferdFileCounter = 1 Then
|
||||
Throw New TooMuchFerdsException()
|
||||
End If
|
||||
|
||||
' Since extraction went well, increase the amount of ZUGFeRD files
|
||||
pZugferdFiles += 1
|
||||
pZugferdFileCounter += 1
|
||||
_logger.Info("Zugferd file found. Increasing counter.")
|
||||
|
||||
' 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 = _embeds.Extract(oFile.FullName, AllowedExtensions)
|
||||
Dim oAttachments = _embeds.Extract(pFile.FullName, AllowedExtensions)
|
||||
If oAttachments Is Nothing Then
|
||||
_logger.Warn("Attachments for file [{0}] could not be extracted", oFile.FullName)
|
||||
_logger.Warn("Attachments for file [{0}] could not be extracted", pFile.FullName)
|
||||
Else
|
||||
oResult.EmbeddedAttachmentFiles.AddRange(oAttachments)
|
||||
End If
|
||||
|
||||
' Check the Checksum and rejection status
|
||||
Dim oMD5Checksum = _hash.GenerateAndCheck_MD5Sum(oFile, pMessageId, pArgs.IgnoreRejectionStatus)
|
||||
Try
|
||||
Dim sqlResult As Boolean = StoreXMLItemsInDatabase(pMessageId, oDocument, pFile, pConnections, pArgs)
|
||||
Catch ex As Exception
|
||||
Throw ex
|
||||
End Try
|
||||
|
||||
_logger.Debug("File processed.")
|
||||
|
||||
' Check the Checksum and rejection status
|
||||
Dim oMD5Checksum = _hash.GenerateAndCheck_MD5Sum(pFile, pMessageId, pArgs.IgnoreRejectionStatus)
|
||||
oResult.ZugferdFileFound = True
|
||||
oResult.MD5Checksum = oMD5Checksum
|
||||
oResult.ZugferdFileCount = pZugferdFileCounter
|
||||
|
||||
Return oResult
|
||||
|
||||
End Function
|
||||
|
||||
Private Function StoreXMLItemsInDatabase(pMessageId As String, pDocument As ZUGFeRDInterface.ZugferdResult, pFile As FileInfo, pConnections As DatabaseConnections, pArgs As WorkerArgs) As Boolean
|
||||
' Check the document against the configured property map and return:
|
||||
' - a List of valid properties
|
||||
' - a List of missing properties
|
||||
|
||||
Dim oPropertyMap = _zugferd.FilterPropertyMap(pArgs.PropertyMap, oDocument.Specification)
|
||||
Dim oCheckResult = _zugferd.PropertyValues.CheckPropertyValues(oDocument.SchemaObject, oPropertyMap, pMessageId)
|
||||
Dim oPropertyMap = _zugferd.FilterPropertyMap(pArgs.PropertyMap, pDocument.Specification)
|
||||
Dim oCheckResult = _zugferd.PropertyValues.CheckPropertyValues(pDocument.SchemaObject, oPropertyMap, pMessageId)
|
||||
|
||||
_logger.Info("Properties checked: [{0}] missing properties / [{1}] valid properties found.", oCheckResult.MissingProperties.Count, oCheckResult.ValidProperties.Count)
|
||||
|
||||
If oCheckResult.MissingProperties.Count > 0 Then
|
||||
_logger.Warn("[{0}] missing properties found. Exiting.", oCheckResult.MissingProperties.Count)
|
||||
Throw New MissingValueException(oFile, oCheckResult.MissingProperties)
|
||||
Throw New MissingValueException(pFile, oCheckResult.MissingProperties)
|
||||
Else
|
||||
_logger.Debug("No missing properties found. Continuing.")
|
||||
|
||||
End If
|
||||
|
||||
If DeleteExistingPropertyValues(pMessageId, oConnections) = False Then
|
||||
If DeleteExistingPropertyValues(pMessageId, pConnections) = False Then
|
||||
Throw New Exception("Could not cleanup data. Exiting.")
|
||||
End If
|
||||
|
||||
' DataTable vorbereiten
|
||||
Dim oDataTable As DataTable = FillDataTable(pMessageId, oCheckResult, oDocument.Specification, oDocument.UsedXMLSchema)
|
||||
Dim oDataTable As DataTable = FillDataTable(pMessageId, oCheckResult, pDocument.Specification, pDocument.UsedXMLSchema)
|
||||
|
||||
' ColumnList initialisieren
|
||||
Dim oColumnNames As List(Of String) = New List(Of String) From {
|
||||
@ -569,7 +653,7 @@ Public Class ImportZUGFeRDFiles
|
||||
"IS_REQUIRED"
|
||||
}
|
||||
|
||||
Dim oBulkResult = BulkInsert(oConnections, oDataTable, "TBEDMI_ITEM_VALUE", oColumnNames)
|
||||
Dim oBulkResult = BulkInsert(pConnections, oDataTable, "TBEDMI_ITEM_VALUE", oColumnNames)
|
||||
|
||||
If oBulkResult = False Then
|
||||
_logger.Error("Bulk Insert for MessageId [{0}] failed!", pMessageId)
|
||||
@ -577,15 +661,7 @@ Public Class ImportZUGFeRDFiles
|
||||
End If
|
||||
|
||||
_logger.Info("Bulk Insert finished. [{0}] rows inserted for MessageId [{1}].", oDataTable.Rows.Count, pMessageId)
|
||||
|
||||
_logger.Debug("File processed.")
|
||||
|
||||
oResult.ZugferdFileFound = True
|
||||
oResult.MD5Checksum = oMD5Checksum
|
||||
oResult.ZugferdFileCount = pZugferdFiles
|
||||
|
||||
Return oResult
|
||||
|
||||
Return True
|
||||
End Function
|
||||
|
||||
Private Function FillDataTable(pMessageId As String, pCheckResult As PropertyValues.CheckPropertyValuesResult, pSpecification As String, pUsedXMLSchema As String) As DataTable
|
||||
@ -660,6 +736,8 @@ Public Class ImportZUGFeRDFiles
|
||||
Catch ex As Exception
|
||||
_logger.Warn("Step [{0}] with SQL [{1}] was not successful.", oStep, oDelSQL)
|
||||
End Try
|
||||
|
||||
Return False
|
||||
End Function
|
||||
|
||||
Private Function BulkInsert(pConnections As DatabaseConnections, pTable As DataTable, pDestinationTable As String, pColumns As List(Of String)) As Boolean
|
||||
|
||||
3
Jobs/ZUGFeRD/XRechnungViewDocument.vb
Normal file
3
Jobs/ZUGFeRD/XRechnungViewDocument.vb
Normal file
@ -0,0 +1,3 @@
|
||||
Public Class XRechnungViewDocument
|
||||
|
||||
End Class
|
||||
Loading…
x
Reference in New Issue
Block a user