3 Commits

Author SHA1 Message Date
Jonathan Jenne
0da1eb55a9 Interfaces: Version 1.11.0.0 2023-06-21 13:10:16 +02:00
Jonathan Jenne
18b0d4cdaf Jobs: Fix zugferd email string typo 2023-06-21 13:09:32 +02:00
Jonathan Jenne
a05156a1a6 Interfaces: Rewrite ValidateZugferdDocument, add validation for invalid decimals 2023-06-21 13:09:11 +02:00
3 changed files with 51 additions and 21 deletions

View File

@@ -13,7 +13,7 @@ Imports System.Runtime.InteropServices
<Assembly: AssemblyCompany("Digital Data")>
<Assembly: AssemblyProduct("Modules.Interfaces")>
<Assembly: AssemblyCopyright("Copyright © 2023")>
<Assembly: AssemblyTrademark("1.10.5.1")>
<Assembly: AssemblyTrademark("1.11.0.0")>
<Assembly: ComVisible(False)>
@@ -31,5 +31,5 @@ Imports System.Runtime.InteropServices
' übernehmen, indem Sie "*" eingeben:
' <Assembly: AssemblyVersion("1.0.*")>
<Assembly: AssemblyVersion("1.10.5.1")>
<Assembly: AssemblyFileVersion("1.10.5.1")>
<Assembly: AssemblyVersion("1.11.0.0")>
<Assembly: AssemblyFileVersion("1.11.0.0")>

View File

@@ -39,6 +39,7 @@ Public Class ZUGFeRDInterface
UnsupportedFormat
FileTooBig
UnknownError
ValidationFailed
End Enum
Public ReadOnly Property FileGroup As FileGroups
@@ -54,6 +55,7 @@ Public Class ZUGFeRDInterface
Public Class ZugferdResult
Public Property DataFileName As String
Public Property XPathObject As XPathDocument
Public Property XElementObject As XElement
Public Property SchemaObject As Object
Public Property Specification As String
Public Property ValidationErrors As New List(Of ZugferdValidationError)
@@ -246,13 +248,22 @@ Public Class ZUGFeRDInterface
End If
Try
Dim oXPathObject As XPathDocument = Nothing
Using oStream As New MemoryStream(oAllowedResult.FileContents)
Return New ZugferdResult With {
.DataFileName = oAllowedResult.FileName,
.XPathObject = New XPathDocument(oStream)
}
oXPathObject = New XPathDocument(oStream)
End Using
Dim oXElementObject As XElement = Nothing
Using oStream As New MemoryStream(oAllowedResult.FileContents)
oXElementObject = XElement.Load(oStream)
End Using
Return New ZugferdResult With {
.DataFileName = oAllowedResult.FileName,
.XElementObject = oXElementObject,
.XPathObject = oXPathObject
}
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.
@@ -276,48 +287,67 @@ Public Class ZUGFeRDInterface
oNamespaceManager.AddNamespace("ram", "urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:12")
oNamespaceManager.AddNamespace("rsm", "urn:ferd:CrossIndustryDocument:invoice:1p0")
Try
Dim oDecimalNodes = pResult.XElementObject.Descendants().
Where(Function(n) n.Name.ToString.EndsWith("Amount") Or n.Name.ToString.EndsWith("Percent"))
For Each oNode As XElement In oDecimalNodes
Dim oParsedValue As Decimal = 0.0
If Decimal.TryParse(oNode.Value, oParsedValue) = False Then
pResult.ValidationErrors.Add(New ZugferdValidationError() With {
.ElementName = oNode.Name.LocalName,
.ElementValue = oNode.Value,
.ErrorMessage = "Value could not be parsed as Decimal"
})
End If
Next
Catch ex As Exception
_logger.Error(ex)
End Try
' CurrencyCode Nodes
Try
Dim oCurrencyCodeIterator As XPathNodeIterator = oNavigator.
Select("//ram:InvoiceCurrencyCode | //ram:TaxCurrencyCode | //ram:TaxCurrencyCode | //ram:SourceCurrencyCode", oNamespaceManager)
Dim oCurrencyCodeNodes = pResult.XElementObject.Descendants().
Where(Function(n) n.Name.ToString.EndsWith("CurrencyCode"))
While oCurrencyCodeIterator.MoveNext()
Dim oNode As XPathNavigator = oCurrencyCodeIterator.Current
For Each oNode As XElement In oCurrencyCodeNodes
Dim oValid = ValidateCurrencyCode(oNode.Value)
If oValid = False Then
pResult.ValidationErrors.Add(New ZugferdValidationError() With {
.ElementName = oNode.Name,
.ElementName = oNode.Name.LocalName,
.ElementValue = oNode.Value,
.ErrorMessage = "Invalid CurrencyCode. Only 3-Character codes are allowed."
})
End If
End While
Next
Catch ex As Exception
_logger.Error(ex)
End Try
' currencyID
Try
Dim oCurrencyIDIterator As XPathNodeIterator = oNavigator.Select("//*[@currencyID]")
Dim oCurrencyIDNodes = pResult.XElementObject.Descendants().
Where(Function(n) n.Attributes.Any(Function(a) a.Name.LocalName = "currencyID"))
While oCurrencyIDIterator.MoveNext()
Dim oNode As XPathNavigator = oCurrencyIDIterator.Current
Dim oCurrencyID As String = oNode.GetAttribute("currencyID", "")
For Each oNode As XElement In oCurrencyIDNodes
Dim oCurrencyID As String = oNode.Attribute("currencyID")?.Value
' CurrencyID is optional per spec
If String.IsNullOrWhiteSpace(oCurrencyID) Then
Continue While
Continue For
End If
Dim oValid = ValidateCurrencyCode(oCurrencyID)
If oValid = False Then
pResult.ValidationErrors.Add(New ZugferdValidationError() With {
.ElementName = oNode.Name,
.ElementName = oNode.Name.LocalName,
.ElementValue = oCurrencyID,
.ErrorMessage = "Invalid currencyID. Only 3-Character codes or empty values are allowed."
})
End If
End While
Next
Catch ex As Exception
_logger.Error(ex)
End Try

View File

@@ -38,7 +38,7 @@
Public Const EMAIL_INVALID_DOCUMENT = "
<p>Ihre Email ({0}) enthielt ein ZUGFeRD Dokument, welches aber inkorrekt formatiert wurde.</p>
<p>Mögliche Gründe für ein inkorrektes Format:<ul>
<li>Betrags-Werte weisen ungültiges Format auf (25,01 anstatt 25.01)</li>
<li>Betrags-Werte weisen ungültiges Format auf (z.B. 25,01 anstatt 25.01)</li>
</ul></p>
"