From c129b3586202748cd140da6b008f193463b95cd1 Mon Sep 17 00:00:00 2001 From: pitzm Date: Thu, 20 Aug 2026 12:34:58 +0200 Subject: [PATCH 1/3] =?UTF-8?q?-=20Modules.Jobs:=20Version=203.8.1.0=20-?= =?UTF-8?q?=20WITH=20(NOLOCK)=20in=20allen=20Abfragen=20erg=C3=A4nzt=20-?= =?UTF-8?q?=20Deteinamen=20der=20PDF-Attachments=20enthalten=20nur=20noch?= =?UTF-8?q?=20ASCII-Zeichen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Jobs/My Project/AssemblyInfo.vb | 6 ++--- Jobs/ZUGFeRD/EmailFunctions.vb | 8 +++---- Jobs/ZUGFeRD/ErrorCode.vb | 2 +- Jobs/ZUGFeRD/FileFunctions.vb | 41 ++++++++++++++++++++++++++++++++- Jobs/ZUGFeRD/HashFunctions.vb | 4 ++-- 5 files changed, 50 insertions(+), 11 deletions(-) diff --git a/Jobs/My Project/AssemblyInfo.vb b/Jobs/My Project/AssemblyInfo.vb index d49b4213..4db508fe 100644 --- a/Jobs/My Project/AssemblyInfo.vb +++ b/Jobs/My Project/AssemblyInfo.vb @@ -13,7 +13,7 @@ Imports System.Runtime.InteropServices - + @@ -30,5 +30,5 @@ Imports System.Runtime.InteropServices ' Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern ' übernehmen, indem Sie "*" eingeben: - - + + diff --git a/Jobs/ZUGFeRD/EmailFunctions.vb b/Jobs/ZUGFeRD/EmailFunctions.vb index 1871bd5e..20c6a24d 100644 --- a/Jobs/ZUGFeRD/EmailFunctions.vb +++ b/Jobs/ZUGFeRD/EmailFunctions.vb @@ -48,7 +48,7 @@ Namespace ZUGFeRD Dim intCode As Integer = DirectCast(pErrorCode, Integer) oErrorCode = $"{EmailStrings.ErrorCodePraefix}{intCode}" - Dim oSQL = $"SELECT COUNT(*) FROM TBDD_GUI_LANGUAGE_PHRASE WHERE TITLE = '{oErrorCode}'" + Dim oSQL = $"SELECT COUNT(*) FROM TBDD_GUI_LANGUAGE_PHRASE WITH (NOLOCK) WHERE TITLE = '{oErrorCode}'" If _mssql.GetScalarValue(oSQL) > 0 Then useLegacyMethod = False Else @@ -59,7 +59,7 @@ Namespace ZUGFeRD ' Gibt es das Template in TBDD_EMAIL_TEMPLATE? If useLegacyMethod = False AndAlso pTemplateId > 0 Then Try - Dim oSQL = $"SELECT COUNT(*) FROM TBDD_EMAIL_TEMPLATE WHERE GUID = {pTemplateId}" + Dim oSQL = $"SELECT COUNT(*) FROM TBDD_EMAIL_TEMPLATE WITH (NOLOCK) WHERE GUID = {pTemplateId}" If _mssql.GetScalarValue(oSQL) <= 0 Then _logger.Warn($"EMAIL_TEMPLATE [{pTemplateId}] not found in TBDD_EMAIL_TEMPLATE!") useLegacyMethod = True @@ -185,7 +185,7 @@ Namespace ZUGFeRD _logger.Debug("To: {0}", oEmailTo) _logger.Debug("Subject: {0}", oSubject) _logger.Debug("Body {0}", oFinalBodyText) - Dim osql = $"Select MAX(GUID) FROM TBEMLP_HISTORY WHERE EMAIL_MSGID = '{MessageId}'" + Dim osql = $"Select MAX(GUID) FROM TBEMLP_HISTORY WITH (NOLOCK) WHERE EMAIL_MSGID = '{MessageId}'" Dim oHistoryID = _mssql.GetScalarValue(osql) If IsNumeric(oHistoryID) Then @@ -223,7 +223,7 @@ Namespace ZUGFeRD End Sub Public Function GetEmailDataForMessageId(MessageId As String) As EmailData - Dim oSQL = $"SELECT EMAIL_FROM, EMAIL_SUBJECT FROM TBEMLP_HISTORY WHERE EMAIL_MSGID = '{MessageId}'" + Dim oSQL = $"SELECT EMAIL_FROM, EMAIL_SUBJECT FROM TBEMLP_HISTORY WITH (NOLOCK) WHERE EMAIL_MSGID = '{MessageId}'" Try Dim oDatatable = _mssql.GetDatatable(oSQL) Dim oRow As DataRow diff --git a/Jobs/ZUGFeRD/ErrorCode.vb b/Jobs/ZUGFeRD/ErrorCode.vb index 0d8f41e9..beadd5a2 100644 --- a/Jobs/ZUGFeRD/ErrorCode.vb +++ b/Jobs/ZUGFeRD/ErrorCode.vb @@ -10,5 +10,5 @@ FileSizeLimitReachedException = 20008 OutOfMemoryException = 20009 UnhandledException = 20010 - FileMoveException = 200011 + FileMoveException = 20011 End Enum diff --git a/Jobs/ZUGFeRD/FileFunctions.vb b/Jobs/ZUGFeRD/FileFunctions.vb index 5638575f..395c9966 100644 --- a/Jobs/ZUGFeRD/FileFunctions.vb +++ b/Jobs/ZUGFeRD/FileFunctions.vb @@ -1,6 +1,8 @@ Imports System.Collections.Generic +Imports System.Globalization Imports System.IO Imports System.Linq +Imports System.Text Imports DigitalData.Modules.Base Imports DigitalData.Modules.Database Imports DigitalData.Modules.Interfaces @@ -91,7 +93,8 @@ Namespace ZUGFeRD ' Write Embedded Files to disk For Each oResult In pEmbeddedAttachments Try - Dim oFileName As String = $"{pMessageId}~{oResult.FileName}" + Dim oCleanedFilename As String = BereinigeDateinamenAscii(oResult.FileName) + Dim oFileName As String = $"{pMessageId}~{oCleanedFilename}" Dim oFilePath As String = Path.Combine(oAttachmentDirectory, oFileName) If Not File.Exists(oAttachmentDirectory) Then @@ -208,6 +211,7 @@ Namespace ZUGFeRD Return False ' Andere Fehler End Try End Function + Public Function GetEmailPathWithSubjectAsName(RejectedEmailDirectory As String, UncleanedSubject As String) As String Dim oCleanSubject = String.Join("", UncleanedSubject.Split(Path.GetInvalidPathChars())) Dim oAttachmentDirectory = RejectedEmailDirectory @@ -218,6 +222,41 @@ Namespace ZUGFeRD Return oAttachmentPath End Function + + ''' + ''' 20.8.2026 - In den Dateinamen der Anhänge in einem PDF können Unicode-Zeichen vorkommen + ''' die später nicht mehr verarbeitet werden können. sie werden hier rausgefiltert + ''' + ''' + ''' + Function BereinigeDateinamenAscii(pFilename As String) As String + If pFilename.IsNullOrEmpty() Then + Return String.Empty + End If + + ' Restliche Diakritika entfernen (é, à, ñ, etc.) + Dim normalisiert As String = pFilename.Normalize(NormalizationForm.FormD) + Dim sb As New StringBuilder() + + For Each c As Char In normalisiert + If CharUnicodeInfo.GetUnicodeCategory(c) = UnicodeCategory.NonSpacingMark Then + Continue For + End If + + Dim code As Integer = AscW(c) + + If code >= 32 AndAlso code <= 126 Then + If "\/:*?""<>|".Contains(c) Then + sb.Append("_") + Else + sb.Append(c) + End If + End If + ' Alles andere (z.B. 你好) wird komplett verworfen + Next + + Return sb.ToString() + End Function End Class End Namespace diff --git a/Jobs/ZUGFeRD/HashFunctions.vb b/Jobs/ZUGFeRD/HashFunctions.vb index af9a3ccd..d327caf9 100644 --- a/Jobs/ZUGFeRD/HashFunctions.vb +++ b/Jobs/ZUGFeRD/HashFunctions.vb @@ -33,7 +33,7 @@ Public Class HashFunctions End If ' Check if Checksum exists in History Table - Dim oCheckCommand = $"SELECT * FROM TBEMLP_HISTORY WHERE GUID = (SELECT MAX(GUID) FROM TBEMLP_HISTORY WHERE UPPER(MD5HASH) = UPPER('{oMD5CheckSum}'))" + Dim oCheckCommand = $"SELECT * FROM TBEMLP_HISTORY WITH (NOLOCK) WHERE GUID = (SELECT MAX(GUID) FROM TBEMLP_HISTORY WITH (NOLOCK) WHERE UPPER(MD5HASH) = UPPER('{oMD5CheckSum}'))" Dim oTable As DataTable = Database.GetDatatable(oCheckCommand, MSSQLServer.TransactionMode.NoTransaction) ' If History entries could not be fetched, just return the MD5 Checksum @@ -94,7 +94,7 @@ Public Class HashFunctions 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 (~Attm.ext) - Dim oSQL = $"SELECT EMAIL_ATTMT FROM TBEMLP_HISTORY_ATTACHMENT WHERE EMAIL_ATTMT_INDEX = '{pFilename}'" + Dim oSQL = $"SELECT EMAIL_ATTMT FROM TBEMLP_HISTORY_ATTACHMENT WITH (NOLOCK) WHERE EMAIL_ATTMT_INDEX = '{pFilename}'" Dim oEmailAttachment = Database.GetScalarValue(oSQL, MSSQLServer.TransactionMode.NoTransaction) Dim oOriginalName = ObjectEx.NotNull(oEmailAttachment, pFilename) Return oOriginalName From 5b83e5d2652a61ce785d689829f323de3cda225c Mon Sep 17 00:00:00 2001 From: pitzm Date: Thu, 3 Sep 2026 14:08:32 +0200 Subject: [PATCH 2/3] =?UTF-8?q?Modules.Interface:=20Version=202.4.6.0=20F?= =?UTF-8?q?=C3=BCr=20XML-Dateien=20wird=20jetzt=20der=20Validator=20durchl?= =?UTF-8?q?aufen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Interfaces/My Project/AssemblyInfo.vb | 6 +++--- Interfaces/ZUGFeRDInterface.vb | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Interfaces/My Project/AssemblyInfo.vb b/Interfaces/My Project/AssemblyInfo.vb index a9aeb3ff..2900e333 100644 --- a/Interfaces/My Project/AssemblyInfo.vb +++ b/Interfaces/My Project/AssemblyInfo.vb @@ -13,7 +13,7 @@ Imports System.Runtime.InteropServices - + @@ -31,5 +31,5 @@ Imports System.Runtime.InteropServices ' übernehmen, indem Sie "*" eingeben: ' - - + + diff --git a/Interfaces/ZUGFeRDInterface.vb b/Interfaces/ZUGFeRDInterface.vb index c14b459a..603cf7e4 100644 --- a/Interfaces/ZUGFeRDInterface.vb +++ b/Interfaces/ZUGFeRDInterface.vb @@ -194,6 +194,8 @@ Public Class ZUGFeRDInterface } End Using + oResult = _Validator.ValidateZUGFeRDDocument(oResult) + 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. From 4dc454403b640d8bb1cf259ca8791881117d7f5a Mon Sep 17 00:00:00 2001 From: pitzm Date: Thu, 3 Sep 2026 15:04:44 +0200 Subject: [PATCH 3/3] =?UTF-8?q?Modules.Interfaces:=20Log-Meldungen=20erg?= =?UTF-8?q?=C3=A4nzt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Interfaces/ZUGFeRDInterface.vb | 6 ++++++ Interfaces/ZUGFeRDInterface/Validator.vb | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/Interfaces/ZUGFeRDInterface.vb b/Interfaces/ZUGFeRDInterface.vb index 603cf7e4..f88bdf26 100644 --- a/Interfaces/ZUGFeRDInterface.vb +++ b/Interfaces/ZUGFeRDInterface.vb @@ -196,6 +196,12 @@ Public Class ZUGFeRDInterface oResult = _Validator.ValidateZUGFeRDDocument(oResult) + If oResult.ValidationErrors.Count > 0 Then + _logger.Warn($"XML-Logik - Nach Validator() Errors: {oResult.ValidationErrors.Count}") + Else + _logger.Info($"XML-Logik - Nach Validator() NO Errors.") + End If + 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. diff --git a/Interfaces/ZUGFeRDInterface/Validator.vb b/Interfaces/ZUGFeRDInterface/Validator.vb index 29e9e643..4219056e 100644 --- a/Interfaces/ZUGFeRDInterface/Validator.vb +++ b/Interfaces/ZUGFeRDInterface/Validator.vb @@ -26,6 +26,7 @@ Public Class Validator For Each oNode As XElement In oDecimalNodes Dim oParsedValue As Decimal = 0.0 If Decimal.TryParse(oNode.Value, oParsedValue) = False Then + _logger.Warn($"Invalid Decimal Value in {oNode.Name.LocalName}") pResult.ValidationErrors.Add(New ZugferdValidationError() With { .ElementName = oNode.Name.LocalName, .ElementValue = oNode.Value, @@ -50,6 +51,8 @@ Public Class Validator For Each oNode As XElement In oCurrencyCodeNodes Dim oValid = ValidateCurrencyCode(oNode.Value) If oValid = False Then + _logger.Warn($"Invalid CurrencyCode in {oNode.Name.LocalName}") + pResult.ValidationErrors.Add(New ZugferdValidationError() With { .ElementName = oNode.Name.LocalName, .ElementValue = oNode.Value, @@ -78,6 +81,7 @@ Public Class Validator Dim oValid = ValidateCurrencyCode(oCurrencyID) If oValid = False Then + _logger.Warn($"Invalid CurrencyID in {oNode.Name.LocalName}") pResult.ValidationErrors.Add(New ZugferdValidationError() With { .ElementName = oNode.Name.LocalName, .ElementValue = oCurrencyID,