From 24dbed32ccd6ee79754de2c6ec54a3084ca39773 Mon Sep 17 00:00:00 2001 From: pitzm Date: Mon, 2 Feb 2026 14:40:55 +0100 Subject: [PATCH] ZUGFeRdRESTService - Validation Controller: REFERENCES_Rejection-Messages auswerten und als WebMessage ausgeben --- .../Controllers/ValidationController.cs | 292 ++++++++++++++++-- .../appsettings.Development.json | 10 +- 2 files changed, 269 insertions(+), 33 deletions(-) diff --git a/WEBSERVICES/ZUGFeRDRESTService/Controllers/ValidationController.cs b/WEBSERVICES/ZUGFeRDRESTService/Controllers/ValidationController.cs index 0ac2c0e8..ae616ab0 100644 --- a/WEBSERVICES/ZUGFeRDRESTService/Controllers/ValidationController.cs +++ b/WEBSERVICES/ZUGFeRDRESTService/Controllers/ValidationController.cs @@ -1,18 +1,17 @@ -using System; -using System.IO; -using System.Linq; -using System.Collections.Generic; +using DigitalData.Modules.Interfaces; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; -using DigitalData.Modules.Interfaces; -using static DigitalData.Modules.Interfaces.Exceptions; -using static DigitalData.Modules.Interfaces.ZUGFeRDInterface; -using static DigitalData.Modules.Interfaces.PropertyValues; -using System.Data.SqlClient; using Microsoft.Extensions.Configuration; -using System.Xml.Linq; -using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.Data.SqlClient; +using System.IO; +using System.Linq; using System.Text.RegularExpressions; +using System.Xml.Linq; +using static DigitalData.Modules.Interfaces.Exceptions; +using static DigitalData.Modules.Interfaces.PropertyValues; +using static DigitalData.Modules.Interfaces.ZUGFeRDInterface; namespace ZUGFeRDRESTService.Controllers { @@ -26,6 +25,29 @@ namespace ZUGFeRDRESTService.Controllers public const string ADDED_WHO = "ZUGFeRD REST Service"; public const string MESSAGEID_DOMAIN = "test.wisag.de"; + public const string VALIDATION_SUCCESS = "VALIDATION SUCCESS"; + public const string REFERENCES_Rejection_30001 = "REFERENCES_Rejection_30001"; + public const string REFERENCES_Rejection_30002 = "REFERENCES_Rejection_30002"; + public const string REFERENCES_Rejection_30003_1 = "REFERENCES_Rejection_30003_1"; + public const string REFERENCES_Rejection_30003_2 = "REFERENCES_Rejection_30003_2"; + public const string REFERENCES_Rejection_30003_3 = "REFERENCES_Rejection_30003_3"; + public const string REFERENCES_Rejection_30004_1 = "REFERENCES_Rejection_30004_1"; + public const string REFERENCES_Rejection_30004_2 = "REFERENCES_Rejection_30004_2"; + public const string REFERENCES_Rejection_30004_3 = "REFERENCES_Rejection_30004_3"; + public const string REFERENCES_Rejection_30005_1 = "REFERENCES_Rejection_30005_1"; + public const string REFERENCES_Rejection_30005_2 = "REFERENCES_Rejection_30005_2"; + public const string REFERENCES_Rejection_30006 = "REFERENCES_Rejection_30006" ; + public const string REFERENCES_Rejection_30007 = "REFERENCES_Rejection_30007" ; + public const string REFERENCES_Rejection_30007_1 = "REFERENCES_Rejection_30007_1"; + public const string REFERENCES_Rejection_30008 = "REFERENCES_Rejection_30008" ; + public const string REFERENCES_Rejection_30009 = "REFERENCES_Rejection_30009" ; + public const string REFERENCES_Rejection_30010 = "REFERENCES_Rejection_30010" ; + public const string REFERENCES_Rejection_30011 = "REFERENCES_Rejection_30011" ; + public const string REFERENCES_Rejection_30012 = "REFERENCES_Rejection_30012" ; + public const string AMOUNT_CALC_REJECTION = "AMOUNT_CALC_REJECTION"; + + private List _ValidationErrors; + private const int MAX_FILE_SIZE_DEFAULT = 25; private readonly ZUGFeRDInterface _zugferd; @@ -82,7 +104,29 @@ namespace ZUGFeRDRESTService.Controllers _logger.Debug("Property Map list initial: [{0}] entries found. [{1}] entries will be available.", oPropertyMapList.Count, _propertyMapList.Count); _RecjectionMessageList = database.GetRejectionMessageList(); - + + _ValidationErrors = new List() { + REFERENCES_Rejection_30001, + REFERENCES_Rejection_30002, + REFERENCES_Rejection_30003_1, + REFERENCES_Rejection_30003_2, + REFERENCES_Rejection_30003_3, + REFERENCES_Rejection_30004_1, + REFERENCES_Rejection_30004_2, + REFERENCES_Rejection_30004_3, + REFERENCES_Rejection_30005_1, + REFERENCES_Rejection_30005_2, + REFERENCES_Rejection_30006, + REFERENCES_Rejection_30007, + REFERENCES_Rejection_30007_1, + REFERENCES_Rejection_30008, + REFERENCES_Rejection_30009, + REFERENCES_Rejection_30010, + REFERENCES_Rejection_30011, + REFERENCES_Rejection_30012, + AMOUNT_CALC_REJECTION + }; + _logger.Debug("Validation Controller initialized!"); } @@ -189,19 +233,19 @@ namespace ZUGFeRDRESTService.Controllers _logger.Info("Detected Specification was: [{0}]", oZugferdResult.Specification); - var oFilteredPropertyMap = _zugferd.FilterPropertyMap(_propertyMapList, oZugferdResult.Specification); + var oFilteredPropertyMap = _zugferd.FilterPropertyMap(_propertyMapList, oZugferdResult.Specification); if (oFilteredPropertyMap.Count == 0) { _logger.Warn("No properties found in property map for specification [{0}]", oZugferdResult.Specification); //throw new ZUGFeRDExecption(ErrorType.UnsupportedFormat, "Unsupported Format"); throw new ZUGFeRDExecption(ErrorCodes.UnsupportedFerdException, "Unsupported Format"); - } + } else { _logger.Debug("Property map contains [{0}] entries for specification [{1}]", oFilteredPropertyMap.Count, oZugferdResult.Specification); } - + _logger.Info("Starting structural check against the database."); oPropertyResult = _props.CheckPropertyValues(oZugferdResult.SchemaObject, oFilteredPropertyMap, "MESSAGEID"); @@ -221,7 +265,7 @@ namespace ZUGFeRDRESTService.Controllers { //throw new ZUGFeRDExecption(ErrorType.MissingProperties, "Missing Properties"); throw new ZUGFeRDExecption(ErrorCodes.MissingValueException, "Missing Properties"); - } + } Tuple oValidateResult = ValidateBuyerOrderReference(oPropertyResult.ValidProperties); @@ -233,10 +277,9 @@ namespace ZUGFeRDRESTService.Controllers string oValidateResultString = oValidateResult.Item2; - if (oValidateResultString == "ALL REFERENCES CHECKED POSITIVE") + if (oValidateResultString.Equals(VALIDATION_SUCCESS)) { string oMessage = "Die hochgeladene Datei ist eine gültige-ZUGFeRD Rechnung"; - _logger.Info($"Responding with message: [{oMessage}]"); return new ValidationResponse() @@ -244,10 +287,10 @@ namespace ZUGFeRDRESTService.Controllers status = RESPONSE_OK, message = oMessage }; - } else + } + else { string oMessage = oValidateResultString; - _logger.Info($"Responding with message: [{oMessage}]"); return new ValidationResponse() @@ -256,7 +299,8 @@ namespace ZUGFeRDRESTService.Controllers message = oMessage }; } - }; + } + } catch (ZUGFeRDExecption ex) { @@ -299,9 +343,9 @@ namespace ZUGFeRDRESTService.Controllers break; } } - else + else { - oMessage = "Alte Logik. Meldung nicht gefunden"; + oMessage = "Alte Logik. Meldung nicht gefunden"; } _logger.Info($"Responding with message: [{oMessage}]"); @@ -315,6 +359,8 @@ namespace ZUGFeRDRESTService.Controllers } catch (ValidationException ex) { + _logger.Error(ex); + var rejectionCodeNumber = this.GetRejectionCodeNumber(ex.ErrorCode); // Der gesamte Ausgabetext muss anhand des ErrorCodes ermittelt werden @@ -348,10 +394,14 @@ namespace ZUGFeRDRESTService.Controllers } } + /// + /// Hier wird eine externe Prozedur gerufen, PRCUST_INV_CHECK_FROM_PORTAL, + /// die das Ergebnis der Referenzpruefung liefert. + /// private Tuple ValidateBuyerOrderReference(List pProperties) { var oMessageId = GetMessageId(); - _logger.Debug("Created new MessageId: [{0}]", oMessageId); + _logger.Debug("Created new MessageId: [{0}]", oMessageId); _logger.Debug("Inserting properties into database."); foreach (var oItem in pProperties) @@ -377,6 +427,59 @@ namespace ZUGFeRDRESTService.Controllers if (_database.MSSQL.ExecuteNonQuery(oCommand)) { string oReturnValue = (string)oCommand.Parameters["@MSG_OUTPUT"].Value; + + _logger.Debug("Validation Result message from DB: " + oReturnValue); + + if (oReturnValue.Equals("ALL REFERENCES CHECKED POSITIVE", StringComparison.OrdinalIgnoreCase)) + { + _logger.Debug("Validation Success"); + oReturnValue = VALIDATION_SUCCESS; + } + else + { + // Gehe durch die möglichen Fehler, und ermittle Rückmeldung + foreach (var oRejectionItem in _ValidationErrors) + { + if (oReturnValue.Contains(oRejectionItem, StringComparison.OrdinalIgnoreCase)) + { + _logger.Debug("oRejectionItem match: " + oRejectionItem); + + var oDbMessage = this.GetRejectionMessage(oRejectionItem); + + //Jetzt müssen ggf Platzhalter ersetzt werden. + if (oRejectionItem == REFERENCES_Rejection_30003_2) + { + string oReplaceParam1 = GetReplaceText1_30003_2(pProperties); + string oReplaceParam2 = GetReplaceText2_30003_2(pProperties); + + oReturnValue = oDbMessage.Replace("@REPLACE_PARAM1", oReplaceParam1); + oReturnValue = oReturnValue.Replace("@REPLACE_PARAM2", oReplaceParam2); + + } + else if (oRejectionItem == REFERENCES_Rejection_30003_3) + { + string oReplaceParam1 = GetReplaceText1_30003_3(pProperties); + + oReturnValue = oDbMessage.Replace("@REPLACE_PARAM1", oReplaceParam1); + } + else if (oRejectionItem == REFERENCES_Rejection_30001) + { + // TODO - BUKR? + oReturnValue = oDbMessage.Replace("@REPLACE_PARAM1", "9999"); + } + else + { + oReturnValue = oDbMessage; + } + + // Für alle den RejectionCode setzen + oReturnValue = oReturnValue.Replace("@REJECTION_CODE", oRejectionItem); + break; + } + } + } + + _logger.Debug("Validation terminal Result message: " + oReturnValue); return new Tuple(true, oReturnValue); } @@ -390,7 +493,122 @@ namespace ZUGFeRDRESTService.Controllers { _logger.Error(e); return new Tuple(false, string.Empty); - } + } + } + + private string GetReplaceText1_30003_3(List pProperties) + { + string oReplaceParam1 = string.Empty; + + // BuyerOrderReferencedDocument + var itemBT13 = pProperties.Where(i => i.TableColumn == "INVOICE_REFERENCE").FirstOrDefault(); + string valueBt13 = "-"; + if (itemBT13 != null) + { + valueBt13 = string.IsNullOrEmpty(itemBT13.Value) ? "-" : itemBT13.Value; + } + oReplaceParam1 += "
  • [BuyerOrderReferencedDocument] (BT-13) = [" + valueBt13 + "]
  • "; + + + // BuyerReference + var itemBT10 = pProperties.Where(i => i.TableColumn == "INVOICE_REFERENCE3").FirstOrDefault(); + string valueBt10 = "-"; + if (itemBT10 != null) + { + valueBt10 = string.IsNullOrEmpty(itemBT10.Value) ? "-" : itemBT10.Value; + } + oReplaceParam1 += "
  • [BuyerReference] (BT-10) = [" + valueBt10 + "]
  • "; + + + // CostCenter + var itemBT19 = pProperties.Where(i => i.TableColumn == "INVOICE_COST_CENTER").FirstOrDefault(); + string valueBt19 = "-"; + if (itemBT19 != null) + { + valueBt19 = string.IsNullOrEmpty(itemBT19.Value) ? "-" : itemBT19.Value; + } + oReplaceParam1 += "
  • [CostCenter] (BT-19) = [" + valueBt19 + "]
  • "; + + // BuyerID + var itemBT46 = pProperties.Where(i => i.TableColumn == "INVOICE_BUYER_ID").FirstOrDefault(); + string valueBt46 = "-"; + if (itemBT46 != null) + { + valueBt46 = string.IsNullOrEmpty(itemBT46.Value) ? "-" : itemBT46.Value; + } + oReplaceParam1 += "
  • [BuyerTradeParty] (BT-46) = [" + valueBt46 + "]
  • "; + + oReplaceParam1 = "
      " + oReplaceParam1 + "
    "; + _logger.Debug("oReplaceParam1-Text: " + oReplaceParam1); + + return oReplaceParam1; + } + + private string GetReplaceText2_30003_2(List pProperties) + { + string oReplaceParam2 = string.Empty; + + // BuyerTradeParty.Name + var itemBT44 = pProperties.Where(i => i.TableColumn == "INVOICE_BUYER_NAME").FirstOrDefault(); + string valueBt44 = "-"; + if (itemBT44 != null) + { + valueBt44 = string.IsNullOrEmpty(itemBT44.Value) ? "-" : itemBT44.Value; + } + oReplaceParam2 += "
  • [BuyerTradeParty.Name] (BT-44) = [" + valueBt44 + "]
  • "; + + // BuyerTradeParty.PostalTradeAddress.LineTwo + var itemBT51 = pProperties.Where(i => i.TableColumn == "INVOICE_BUYER_ADRESS2").FirstOrDefault(); + string valueBt51 = "-"; + if (itemBT51 != null) + { + valueBt51 = string.IsNullOrEmpty(itemBT51.Value) ? "-" : itemBT51.Value; + } + oReplaceParam2 += "
  • [BuyerTradeParty.PostalTradeAddress.LineTwo] (BT-51) = [" + valueBt51 + "]
  • "; + + oReplaceParam2 = "
      " + oReplaceParam2 + "
    "; + _logger.Debug("oReplaceParam2-Text: " + oReplaceParam2); + + return oReplaceParam2; + } + + private string GetReplaceText1_30003_2(List pProperties) + { + string oReplaceParam1 = string.Empty; + + // BuyerOrderReferencedDocument + var itemBT13 = pProperties.Where(i => i.TableColumn == "INVOICE_REFERENCE").FirstOrDefault(); + string valueBt13 = "-"; + if (itemBT13 != null) + { + valueBt13 = string.IsNullOrEmpty(itemBT13.Value) ? "-" : itemBT13.Value; + } + oReplaceParam1 += "
  • [BuyerOrderReferencedDocument] (BT-13) = [" + valueBt13 + "]
  • "; + + + // BuyerReference + var itemBT10 = pProperties.Where(i => i.TableColumn == "INVOICE_REFERENCE3").FirstOrDefault(); + string valueBt10 = "-"; + if (itemBT10 != null) + { + valueBt10 = string.IsNullOrEmpty(itemBT10.Value) ? "-" : itemBT10.Value; + } + oReplaceParam1 += "
  • [BuyerReference] (BT-10) = [" + valueBt10 + "]
  • "; + + + // CostCenter + var itemBT19 = pProperties.Where(i => i.TableColumn == "INVOICE_COST_CENTER").FirstOrDefault(); + string valueBt19 = "-"; + if (itemBT19 != null) + { + valueBt19 = string.IsNullOrEmpty(itemBT19.Value) ? "-" : itemBT19.Value; + } + oReplaceParam1 += "
  • [CostCenter] (BT-19) = [" + valueBt19 + "]
  • "; + + oReplaceParam1 = "
      " + oReplaceParam1 + "
    "; + _logger.Debug("oReplaceParam1-Text: " + oReplaceParam1); + + return oReplaceParam1; } public string GetMessageId() @@ -428,7 +646,7 @@ namespace ZUGFeRDRESTService.Controllers { itemValue = pProperty.Value; } - + var oParams = new SqlParameter[] { new SqlParameter("@REFERENCE_GUID", pMessageId), @@ -449,7 +667,7 @@ namespace ZUGFeRDRESTService.Controllers { _logger.Error(ex); return false; - } + } } /// @@ -463,7 +681,25 @@ namespace ZUGFeRDRESTService.Controllers // Sprache wird man vielleicht mal auswählen können var language = "de-DE"; - var searchTitle = "ZUGFERD_Rejection_" + pErrorCode + "_Web"; + var searchTitle = string.Empty; + + if (pErrorCode.Contains("2000")) + { + searchTitle = "ZUGFERD_Rejection_" + pErrorCode + "_Web"; + } + else if (pErrorCode.Contains("REFERENCES_Rejection_3000")) + { + searchTitle = pErrorCode + "_Web"; + } + else if (pErrorCode.Contains("AMOUNT_CALC")) + { + searchTitle = "AMOUNT_CALC_REJECTION_Web"; + } + else + { + // else-Fall muss noch geklärt werden. + searchTitle = "AMOUNT_CALC_REJECTION_Web"; + } var messageItem = _RecjectionMessageList.Where(i => i.Title.Equals(searchTitle, StringComparison.OrdinalIgnoreCase) && i.Language.Equals(language, StringComparison.OrdinalIgnoreCase)).FirstOrDefault(); if (messageItem != null) diff --git a/WEBSERVICES/ZUGFeRDRESTService/appsettings.Development.json b/WEBSERVICES/ZUGFeRDRESTService/appsettings.Development.json index b6613161..1bf7cf67 100644 --- a/WEBSERVICES/ZUGFeRDRESTService/appsettings.Development.json +++ b/WEBSERVICES/ZUGFeRDRESTService/appsettings.Development.json @@ -20,11 +20,11 @@ }, "Zugferd": { "AllowZugferd10": true, - "AllowZugferd2x": false, - "AllowZugferd23x": false, - "AllowFacturX": false, - "AllowXRechnung": false, - "AllowPeppolBISBill3x": false + "AllowZugferd2x": true, + "AllowZugferd23x": true, + "AllowFacturX": true, + "AllowXRechnung": true, + "AllowPeppolBISBill3x": true }, "GDPictureVersion": "", "MaxFileSizeInMegabytes": 25