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) 'TODO Validate Datumsfelder 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.", .ErrorMessageDE = "Der Wert konnte nicht in eine Dezimalzahl umgewandelt werden." }) 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.", .ErrorMessageDE = "Ungültiger Währungscode. Es sind nur 3-stellige Codes erlaubt." }) 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.", .ErrorMessageDE = "Ungültige WährungsID. Es sind nur 3-Zeichen lange Codes oder ein leerer Wert erlaubt." }) 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