ZUGFeRD: Validate errors in xml and throw ValidationException
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
Public Class Exceptions
|
||||
Imports DigitalData.Modules.Interfaces.ZUGFeRDInterface
|
||||
|
||||
Public Class Exceptions
|
||||
Public Class ZUGFeRDExecption
|
||||
Inherits ApplicationException
|
||||
|
||||
@@ -23,4 +25,14 @@
|
||||
_XmlFile = pXmlFileName
|
||||
End Sub
|
||||
End Class
|
||||
|
||||
Public Class ValidationException
|
||||
Inherits ApplicationException
|
||||
|
||||
Public ValidationErrors As List(Of ZugferdValidationError)
|
||||
|
||||
Public Sub New()
|
||||
MyBase.New("ZUGFeRD document found but validation failed!")
|
||||
End Sub
|
||||
End Class
|
||||
End Class
|
||||
|
||||
98
Interfaces/ZUGFeRDInterface/Validator.vb
Normal file
98
Interfaces/ZUGFeRDInterface/Validator.vb
Normal file
@@ -0,0 +1,98 @@
|
||||
Imports DigitalData.Modules.Interfaces.ZUGFeRDInterface
|
||||
Imports DigitalData.Modules.Logging
|
||||
|
||||
Public Class Validator
|
||||
Private ReadOnly _logConfig As LogConfig
|
||||
Private ReadOnly _logger As Logger
|
||||
|
||||
Public Sub New(pLogConfig As LogConfig)
|
||||
_logConfig = pLogConfig
|
||||
_logger = pLogConfig.GetLogger()
|
||||
End Sub
|
||||
|
||||
Public Function ValidateZUGFeRDDocument(pResult As ZugferdResult) As ZugferdResult
|
||||
ValidateDecimalNodes(pResult)
|
||||
ValidateCurrencyNodes(pResult)
|
||||
|
||||
Return pResult
|
||||
End Function
|
||||
|
||||
Private Sub ValidateDecimalNodes(ByRef pResult As ZugferdResult)
|
||||
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
|
||||
End Sub
|
||||
|
||||
Private Sub ValidateCurrencyNodes(ByRef pResult As ZugferdResult)
|
||||
' CurrencyCode Nodes
|
||||
Try
|
||||
Dim oCurrencyCodeNodes = pResult.XElementObject.Descendants().
|
||||
Where(Function(n) n.Name.ToString.EndsWith("CurrencyCode"))
|
||||
|
||||
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.LocalName,
|
||||
.ElementValue = oNode.Value,
|
||||
.ErrorMessage = "Invalid CurrencyCode. Only 3-Character codes are allowed."
|
||||
})
|
||||
End If
|
||||
Next
|
||||
Catch ex As Exception
|
||||
_logger.Error(ex)
|
||||
End Try
|
||||
|
||||
' currencyID
|
||||
Try
|
||||
Dim oCurrencyIDNodes = pResult.XElementObject.Descendants().
|
||||
Where(Function(n) n.Attributes.Any(Function(a) a.Name.LocalName = "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 For
|
||||
End If
|
||||
|
||||
Dim oValid = ValidateCurrencyCode(oCurrencyID)
|
||||
If oValid = False Then
|
||||
pResult.ValidationErrors.Add(New ZugferdValidationError() With {
|
||||
.ElementName = oNode.Name.LocalName,
|
||||
.ElementValue = oCurrencyID,
|
||||
.ErrorMessage = "Invalid currencyID. Only 3-Character codes or empty values are allowed."
|
||||
})
|
||||
End If
|
||||
Next
|
||||
|
||||
Catch ex As Exception
|
||||
_logger.Error(ex)
|
||||
End Try
|
||||
End Sub
|
||||
|
||||
Private Function ValidateCurrencyCode(pValue As String) As Boolean
|
||||
Dim oValueRegex As New Text.RegularExpressions.Regex("[A-Z]{3}")
|
||||
|
||||
If oValueRegex.IsMatch(pValue) = False Then
|
||||
Return False
|
||||
End If
|
||||
|
||||
Return True
|
||||
End Function
|
||||
End Class
|
||||
Reference in New Issue
Block a user