From 04a408ab97e1df03aed9c5836d1dee330579ece3 Mon Sep 17 00:00:00 2001 From: pitzm Date: Tue, 3 Jun 2025 15:23:22 +0200 Subject: [PATCH] Jobs: MIME-Types + File-Extension + xlsx-Dateien --- Jobs/ZUGFeRD/ImportZUGFeRDFiles.vb | 123 +++++++++++++++++++++++------ 1 file changed, 99 insertions(+), 24 deletions(-) diff --git a/Jobs/ZUGFeRD/ImportZUGFeRDFiles.vb b/Jobs/ZUGFeRD/ImportZUGFeRDFiles.vb index 8f4b4d19..2c55899b 100644 --- a/Jobs/ZUGFeRD/ImportZUGFeRDFiles.vb +++ b/Jobs/ZUGFeRD/ImportZUGFeRDFiles.vb @@ -37,6 +37,20 @@ Public Class ImportZUGFeRDFiles "ATTACHMENT_FILE_FILENAME", "ATTACHMENT_FILE_VALUE", "ATTACHMENT_FILE_MIMECODE" } + ' List of the allowed MIME-Codes + ' Allowed Values are: + '- application/pdf + '- application/vnd.openxmlformats-officedocument.spreadsheetml.sheet (xlsx) + '- application/vnd.oasis.opendocument.spreadsheet + '- image/jpeg + '- image/png + '- image/tiff (UBL) + '- text/csv + '- text/xml (UBL) + Private ReadOnly AllowedMimeTypesInEmbeddedFiles As List(Of String) = New List(Of String) From { + "application/pdf", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" + } + Private ReadOnly _logger As Logger Private ReadOnly _logConfig As LogConfig Private ReadOnly _filesystem As FilesystemEx @@ -708,13 +722,13 @@ Public Class ImportZUGFeRDFiles End Function ''' - ''' Hier werden die Dateianhänge behandelt, die im XML als base64 gespeichert wurden - ''' Die Knotendefinition muss ITEM_TYPE = 3 für den Dateiinhalt haben! + ''' Hier werden die Dateianhänge behandelt, die im XML als base64 eingetragen wurden. ''' Die zusammengehörigen Knoten müssen über "FILES" gruppiert werden! + ''' + ''' Die erwarteten Knoten-Namen sind in der List EmbeddedFilesColumnNames enthalten! ''' - Private Function HandleEmbeddedAttachments(pMessageId As String, pDocument As ZUGFeRDInterface.ZugferdResult, pConnections As DatabaseConnections, pCheckResult As CheckPropertyValuesResult, pArgs As WorkerArgs, pProcessFileResult As ProcessFileResult) As Boolean - - ' TODO: klären!!! - Fehlerhandling? Ab wann liegt ein Fehler und damit eine Ablehnung vor? + Private Function HandleEmbeddedAttachments(pMessageId As String, pDocument As ZUGFeRDInterface.ZugferdResult, pConnections As DatabaseConnections, + pCheckResult As CheckPropertyValuesResult, pArgs As WorkerArgs, pProcessFileResult As ProcessFileResult) As Boolean If (pCheckResult Is Nothing) Then _logger.Debug("pCheckResult is empty!") @@ -737,6 +751,7 @@ Public Class ImportZUGFeRDFiles Return True End If + ' GroupCounter Werte in Hashset eintragen, um distinct Werte zu erhalten Dim oIndexList As HashSet(Of Integer) = New HashSet(Of Integer) For Each resultItem In embAttachmentList oIndexList.Add(resultItem.GroupCounter) @@ -758,17 +773,12 @@ Public Class ImportZUGFeRDFiles Dim oMimeTypeProperty As ValidProperty = GetIndexProperty(embAttachmentList, groupIndex, "ATTACHMENT_FILE_MIMECODE") If oMimeTypeProperty IsNot Nothing AndAlso oMimeTypeProperty.Value IsNot Nothing Then - oMimeCodeString = oMimeTypeProperty.Value + oMimeCodeString = oMimeTypeProperty.Value.ToLower() Else _logger.Info("Empty MIME-Code! File can not be stored!") Continue For End If - If Not oMimeCodeString.Equals("application/pdf", StringComparison.InvariantCultureIgnoreCase) = True Then - _logger.Info("Not allowed MIME-Code! File will not be stored!") - Continue For - End If - Dim oFilenameProperty As ValidProperty = GetIndexProperty(embAttachmentList, groupIndex, "ATTACHMENT_FILE_FILENAME") If oFilenameProperty IsNot Nothing Then oOrgFilename = oFilenameProperty.Value @@ -782,8 +792,15 @@ Public Class ImportZUGFeRDFiles Continue For End If - Dim newAttachmentFilename = pMessageId + "~attm" + nextAttachmentIndex.ToString + ".pdf" + Dim newAttachmentFilename = pMessageId + "~attm" + nextAttachmentIndex.ToString + + Dim oFileExtension = GetEmbeddedFileExtension(oMimeTypeProperty.Value) + If oFileExtension.IsNotNullOrEmpty() Then + newAttachmentFilename += "." + oFileExtension + End If + Dim embeddedFilePath = Path.Combine(oOutputPath, newAttachmentFilename) + _logger.Debug("Next Attachment File is [{0}]", embeddedFilePath) If SaveBase64ToDisk(embeddedFilePath, oBase64String) = True Then _logger.Debug("Saved file [{0}] to disk", embeddedFilePath) pProcessFileResult.EmailAttachmentFiles.Add(New FileInfo(embeddedFilePath)) @@ -792,12 +809,17 @@ Public Class ImportZUGFeRDFiles Return False End If + If TestFileOnDisk(embeddedFilePath, oMimeCodeString) = False Then + _logger.Error("Could not save File to Disk!") + Return False + End If + If InsertAttachmentHistoryEntry(pMessageId, oOrgFilename, embeddedFilePath) = False Then _logger.Error("Could not save attachment Data to DB!") Return False End If - If InsertEmbeddedFileData(pMessageId, oBase64String, oOrgFilename, oMimeCodeString, groupIndex) = False Then + If InsertEmbeddedFileDataToDB(pMessageId, oBase64String, oOrgFilename, oMimeCodeString, groupIndex) = False Then _logger.Error("Could not save attachment Data to DB!") Return False End If @@ -808,6 +830,62 @@ Public Class ImportZUGFeRDFiles Return True End Function + Private Function TestFileOnDisk(pEmbeddedFilePath As String, pMimeCodeString As String) As Boolean + Try + If pMimeCodeString = "application/pdf" Then + Dim oGdPicturePDF As New GdPicturePDF + Dim oStatus As GdPictureStatus = oGdPicturePDF.LoadFromFile(pEmbeddedFilePath, True) + If oStatus <> GdPictureStatus.OK Then + _logger.Error("File [{0}] has no proper state!", pEmbeddedFilePath) + Return False + End If + + Else + ' Test other files + Dim fileInfo As FileInfo = New FileInfo(pEmbeddedFilePath) + If fileInfo.Exists = False Then + _logger.Error("Could not find File [{0}] on Disk!", pEmbeddedFilePath) + Return False + End If + End If + + Return True + Catch ex As Exception + _logger.Error(ex) + Return False + End Try + End Function + + Private Function GetEmbeddedFileExtension(pMimeTypeValue As String) As String + + If pMimeTypeValue.IsNullOrEmpty() Then + _logger.Warn("Empty MimeCode is not allowed!") + Return String.Empty + End If + + Select Case pMimeTypeValue.ToLower() + Case "application/pdf" + Return "pdf" + Case "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" + Return "xlsx" + Case "application/vnd.oasis.opendocument.spreadsheet" + Return "odt" + Case "image/jpeg" + Return "jpg" + Case "image/png" + Return "png" + Case "image/tiff" + Return "tif" + Case "text/csv" + Return "csv" + Case "text/xml" + Return "xml" + Case Else + Return String.Empty + End Select + + End Function + Private Shared Function GetIndexProperty(pListResult As List(Of ValidProperty), pGroupIndex As Integer, pTableColumn As String) As ValidProperty Return pListResult.Where( Function(z) @@ -819,7 +897,7 @@ Public Class ImportZUGFeRDFiles ''' ''' Speichert die Daten inkl. base64-String in die Datenbank ''' - Private Function InsertEmbeddedFileData(pMessageId As String, pItemValue As String, pOrgFilename As String, pMimeType As String, pGroupIndex As Integer) As Boolean + Private Function InsertEmbeddedFileDataToDB(pMessageId As String, pItemValue As String, pOrgFilename As String, pMimeType As String, pGroupIndex As Integer) As Boolean Try Dim oCommand = New SqlCommand( "INSERT INTO TBEDMI_ITEM_FILES ( @@ -863,15 +941,17 @@ Public Class ImportZUGFeRDFiles End Function ''' - ''' Prüft, ob Embedded Attachments in den XML-Ergebnissen enthalten sind + ''' Prüft, ob Embedded Attachments in den XML-Ergebnissen enthalten sind, + ''' in dem geprüft wird, ob bestimmte MIME-Codes vorhanden sind. ''' ''' ''' Private Function CheckEmbeddedAttachmentEntries(pCheckResult As CheckPropertyValuesResult) As Boolean + Try Dim resultList = pCheckResult.ValidProperties.Where( Function(z) - Return z.TableColumn = "ATTACHMENT_FILE_VALUE" + Return (z.TableColumn = "ATTACHMENT_FILE_MIMECODE" AndAlso AllowedMimeTypesInEmbeddedFiles.Contains(z.Value.ToLower())) End Function ).ToList() @@ -889,12 +969,13 @@ Public Class ImportZUGFeRDFiles End Function + ''' ''' Speichere base64 als Datei auf der Platte ab ''' Private Function SaveBase64ToDisk(pExportFilePath As String, pBase64String As String) As Boolean - Try + Try Dim base64BinaryDataString As String = pBase64String ' Hier Base64-String einfügen Dim binaryDataString As Byte() = Convert.FromBase64String(base64BinaryDataString) Dim oFilename As String = pExportFilePath @@ -904,19 +985,13 @@ Public Class ImportZUGFeRDFiles Stream.Close() End Using - Dim oGdPicturePDF As New GdPicturePDF - Dim oStatus As GdPictureStatus = oGdPicturePDF.LoadFromFile(pExportFilePath, True) - If oStatus <> GdPictureStatus.OK Then - _logger.Error("File [{0}] has no proper state!", pExportFilePath) - Return False - End If + Return True Catch ex As Exception _logger.Error("Could NOT save File [{0}] to Disk! Exception: [{1}]", pExportFilePath, ex.Message) Return False End Try - Return True End Function '''