From 8ef60de3ad5ddb78ff16804420bd17603b40b3e7 Mon Sep 17 00:00:00 2001 From: pitzm Date: Fri, 11 Sep 2026 16:24:23 +0200 Subject: [PATCH] ZUGFeRDRESTParser: - Validierung - Neue Tabelle TBEDMI_PARSER_RESULTS (INSERT, etc.) --- .../Controllers/ParserResult.cs | 152 ++++++++++++++++++ .../Controllers/ValidationController.cs | 111 ++++++++++++- .../appsettings.Development.json | 4 +- 3 files changed, 258 insertions(+), 9 deletions(-) create mode 100644 WEBSERVICES/ZUGFeRDRESTService/Controllers/ParserResult.cs diff --git a/WEBSERVICES/ZUGFeRDRESTService/Controllers/ParserResult.cs b/WEBSERVICES/ZUGFeRDRESTService/Controllers/ParserResult.cs new file mode 100644 index 00000000..0abb9131 --- /dev/null +++ b/WEBSERVICES/ZUGFeRDRESTService/Controllers/ParserResult.cs @@ -0,0 +1,152 @@ +namespace ZUGFeRDRESTService.Controllers +{ + public class ParserResult + { + private string _MessageId; + private string _WebFilename; + private string _WebMailAdress; + private string _WebLanguage; + private string _ResultString; + private string _XML_InvoiceNumber; + private string _XML_SellerTradePartyName; + private string _XML_SellerEmailAdress; + private string _XML_Specification; + private string _XML_Schema; + private string _XML_FileType; + + public string MessageId + { + get + { + return string.IsNullOrEmpty(_MessageId) ? "NO VALUE" : _MessageId; + } + + set + { + _MessageId = value; + } + } + + public string WebFilename + { + get + { + return string.IsNullOrEmpty(_WebFilename) ? "NO VALUE" : _WebFilename; + } + + set + { + _WebFilename = value; + } + } + public string WebMailAdress + { + get + { + return string.IsNullOrEmpty(_WebMailAdress) ? "NO VALUE" : _WebMailAdress; + } + + set + { + _WebMailAdress = value; + } + } + public string WebLanguage + { + get + { + return string.IsNullOrEmpty(_WebLanguage) ? "NO VALUE" : _WebLanguage; + } + + set + { + _WebLanguage = value; + } + } + public string ResultString + { + get + { + return string.IsNullOrEmpty(_ResultString) ? "NO VALUE" : _ResultString; + } + + set + { + _ResultString = value; + } + } + public string XML_InvoiceNumber + { + get + { + return string.IsNullOrEmpty(_XML_InvoiceNumber) ? "NO VALUE" : _XML_InvoiceNumber; + } + + set + { + _XML_InvoiceNumber = value; + } + } + public string XML_SellerTradePartyName + { + get + { + return string.IsNullOrEmpty(_XML_SellerTradePartyName) ? "NO VALUE" : _XML_SellerTradePartyName; + } + + set + { + _XML_SellerTradePartyName = value; + } + } + public string XML_SellerEmailAdress + { + get + { + return string.IsNullOrEmpty(_XML_SellerEmailAdress) ? "NO VALUE" : _XML_SellerEmailAdress; + } + + set + { + _XML_SellerEmailAdress = value; + } + } + public string XML_Specification + { + get + { + return string.IsNullOrEmpty(_XML_Specification) ? "NO VALUE" : _XML_Specification; + } + + set + { + _XML_Specification = value; + } + } + public string XML_Schema + { + get + { + return string.IsNullOrEmpty(_XML_Schema) ? "NO VALUE" : _XML_Schema; + } + + set + { + _XML_Schema = value; + } + } + public string XML_FileType + { + get + { + return string.IsNullOrEmpty(_XML_FileType) ? "NO VALUE" : _XML_FileType; + } + + set + { + _XML_FileType = value; + } + } + + } +} diff --git a/WEBSERVICES/ZUGFeRDRESTService/Controllers/ValidationController.cs b/WEBSERVICES/ZUGFeRDRESTService/Controllers/ValidationController.cs index ce5b797e..4a343ecf 100644 --- a/WEBSERVICES/ZUGFeRDRESTService/Controllers/ValidationController.cs +++ b/WEBSERVICES/ZUGFeRDRESTService/Controllers/ValidationController.cs @@ -1,16 +1,14 @@ using DigitalData.Modules.Interfaces; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; -using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.Extensions.Configuration; -using Microsoft.VisualStudio.Web.CodeGeneration.Contracts.Messaging; using System; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; using System.IO; using System.Linq; -using System.Net.Http; +using System.Net.Mail; using System.Text.RegularExpressions; using System.Xml.Linq; using static DigitalData.Modules.Interfaces.Exceptions; @@ -30,6 +28,19 @@ namespace ZUGFeRDRESTService.Controllers public const string MESSAGEID_DOMAIN = "test.wisag.de"; public const string VALIDATION_SUCCESS = "VALIDATION SUCCESS"; + + public const string ZUGFERD_Rejection_20001 = "ZUGFERD_Rejection_20001"; + public const string ZUGFERD_Rejection_20002 = "ZUGFERD_Rejection_20002"; + public const string ZUGFERD_Rejection_20003 = "ZUGFERD_Rejection_20003"; + public const string ZUGFERD_Rejection_20004 = "ZUGFERD_Rejection_20004"; + public const string ZUGFERD_Rejection_20005 = "ZUGFERD_Rejection_20005"; + public const string ZUGFERD_Rejection_20006 = "ZUGFERD_Rejection_20006"; + public const string ZUGFERD_Rejection_20007 = "ZUGFERD_Rejection_20007"; + public const string ZUGFERD_Rejection_20008 = "ZUGFERD_Rejection_20008"; + public const string ZUGFERD_Rejection_20009 = "ZUGFERD_Rejection_20009"; + public const string ZUGFERD_Rejection_20010 = "ZUGFERD_Rejection_20010"; + public const string ZUGFERD_Rejection_20011 = "ZUGFERD_Rejection_20011"; + public const string REFERENCES_Rejection_30001 = "REFERENCES_Rejection_30001"; public const string REFERENCES_Rejection_30002 = "REFERENCES_Rejection_30002"; public const string REFERENCES_Rejection_30002_1 = "REFERENCES_Rejection_30002_1"; @@ -84,6 +95,8 @@ namespace ZUGFeRDRESTService.Controllers private string _GDPictureVersion; + private ParserResult _ParserResult; + public ValidationController(ILogging logging, IDatabase database, IConfiguration Config) { _logConfig = logging.LogConfig; @@ -146,6 +159,9 @@ namespace ZUGFeRDRESTService.Controllers SPAIN, }; + _ParserResult = new ParserResult(); + _ParserResult.MessageId = GetMessageId(); + _logger.Debug("Validation Controller initialized!"); } @@ -267,6 +283,10 @@ namespace ZUGFeRDRESTService.Controllers _UserLanguageCode = GERMAN; } + _ParserResult.WebFilename = file.FileName; + _ParserResult.WebMailAdress = oUserId; + _ParserResult.WebLanguage = _UserLanguageCode; + try { using Stream oStream = file.OpenReadStream(); @@ -297,10 +317,15 @@ namespace ZUGFeRDRESTService.Controllers XElementObject = XElement.Load(oStream) }; + oResult = _zugferd.ValidateZUGFeRDDocument(oResult); oZugferdResult = _zugferd.SerializeZUGFeRDDocument(oResult); oZugferdResult.ReceiptFileType = "XML"; } + _ParserResult.XML_Specification = oZugferdResult.Specification; + _ParserResult.XML_Schema = oZugferdResult.UsedXMLSchema; + _ParserResult.XML_FileType = oZugferdResult.ReceiptFileType; + _logger.Info("Detected Specification was: [{0}]", oZugferdResult.Specification); var oFilteredPropertyMap = _zugferd.FilterPropertyMap(_propertyMapList, oZugferdResult.Specification); @@ -335,7 +360,7 @@ namespace ZUGFeRDRESTService.Controllers throw new ZUGFeRDExecption(ErrorCodes.MissingValueException, "Missing Properties"); } - Tuple oValidateResult = ValidateBuyerOrderReference(oPropertyResult.ValidProperties, oZugferdResult); + Tuple oValidateResult = ValidateBuyerOrderReference(oPropertyResult.ValidProperties, _ParserResult, oZugferdResult); if (oValidateResult.Item1 == false) { @@ -346,9 +371,13 @@ namespace ZUGFeRDRESTService.Controllers if (oValidateResultString.Equals(VALIDATION_SUCCESS)) { + _ParserResult.ResultString = "SUCCESS"; + InsertWebParserResult(_ParserResult); + string oMessage = "Die hochgeladene Datei ist eine gültige-ZUGFeRD Rechnung"; _logger.Info($"Responding with message: [{oMessage}]"); + return new ValidationResponse() { status = RESPONSE_OK, @@ -357,6 +386,7 @@ namespace ZUGFeRDRESTService.Controllers } else { + InsertWebParserResult(_ParserResult); string oMessage = oValidateResultString; _logger.Info($"Responding with message: [{oMessage}]"); @@ -413,6 +443,8 @@ namespace ZUGFeRDRESTService.Controllers oMessage = "Alte Logik. Meldung nicht gefunden"; } + InsertWebParserResult(_ParserResult); + _logger.Info($"Responding with message: [{oMessage}]"); return new ValidationResponse() @@ -474,7 +506,9 @@ namespace ZUGFeRDRESTService.Controllers oMessage += " " + htmlResultString; } - + + InsertWebParserResult(_ParserResult); + return new ValidationResponse() { status = RESPONSE_ERROR, @@ -487,6 +521,9 @@ namespace ZUGFeRDRESTService.Controllers string oMessage = "Die hochgeladene Datei kann nicht validiert werden, weil ein unbekannter Fehler aufgetreten ist."; + _ParserResult.ResultString = ZUGFERD_Rejection_20010; + InsertWebParserResult(_ParserResult); + _logger.Info($"Responding with message: [{oMessage}]"); return new ValidationResponse() @@ -497,6 +534,48 @@ namespace ZUGFeRDRESTService.Controllers } } + private void InsertWebParserResult(ParserResult oParserResult) + { + try + { + var insertResultSQL = "INSERT INTO TBEDMI_PARSER_RESULTS (" + + " REFERENCE_GUID, WEB_FILENAME, WEB_MAIL_ADRESS, WEB_LANGUAGE, PARSER_RESULT, XML_INVOICE_NUMBER, XML_SELLER_TRADE_PARTY_NAME, XML_SELLER_MAIL_ADRESS, " + + " XML_SPECIFICATION, XML_SCHEMA, XML_FILE_TYPE, ADDED_WHO " + + ") VALUES (" + + " @REFERENCE_GUID, @WEB_FILENAME, @WEB_MAIL_ADRESS, @WEB_LANGUAGE, @PARSER_RESULT, @XML_INVOICE_NUMBER, @XML_SELLER_TRADE_PARTY_NAME, @XML_SELLER_MAIL_ADRESS, " + + " @XML_SPECIFICATION, @XML_SCHEMA, @XML_FILE_TYPE, @ADDED_WHO " + + ");"; + var oCommand = new SqlCommand(insertResultSQL); + + oCommand.Parameters.Add("@REFERENCE_GUID", SqlDbType.VarChar, 250).Value = oParserResult.MessageId; + oCommand.Parameters.Add("@WEB_FILENAME", SqlDbType.VarChar, 250).Value = oParserResult.WebFilename; + oCommand.Parameters.Add("@WEB_MAIL_ADRESS", SqlDbType.VarChar, 250).Value = oParserResult.WebMailAdress; + oCommand.Parameters.Add("@WEB_LANGUAGE", SqlDbType.VarChar, 5).Value = oParserResult.WebLanguage; + oCommand.Parameters.Add("@PARSER_RESULT", SqlDbType.VarChar, 50).Value = oParserResult.ResultString; + oCommand.Parameters.Add("@XML_INVOICE_NUMBER", SqlDbType.VarChar, 50).Value = oParserResult.XML_InvoiceNumber; + oCommand.Parameters.Add("@XML_SELLER_TRADE_PARTY_NAME", SqlDbType.VarChar, 250).Value = oParserResult.XML_SellerTradePartyName; + oCommand.Parameters.Add("@XML_SELLER_MAIL_ADRESS", SqlDbType.VarChar, 250).Value = oParserResult.XML_SellerEmailAdress; + oCommand.Parameters.Add("@XML_SPECIFICATION", SqlDbType.VarChar, 50).Value = oParserResult.XML_Specification; + oCommand.Parameters.Add("@XML_SCHEMA", SqlDbType.VarChar, 50).Value = oParserResult.XML_Schema; + oCommand.Parameters.Add("@XML_FILE_TYPE", SqlDbType.VarChar, 50).Value = oParserResult.XML_FileType; + oCommand.Parameters.Add("@ADDED_WHO", SqlDbType.VarChar, 50).Value = "DD Web Parser"; + + var retValue = _database.MSSQL.ExecuteNonQuery(oCommand); + + if (!retValue) + { + _logger.Warn("INSERT to TBEDMI_PARSER_RESULTS NOT successfull"); + } + + _logger.Debug("INSERT to TBEDMI_PARSER_RESULTS successfull"); + } + catch (Exception ex) + { + _logger.Error(ex); + } + + } + private string GetMissingValuesListString(List missingProperties) { if (missingProperties == null || missingProperties.Count == 0) @@ -554,9 +633,9 @@ 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, ZugferdResult pZugferdResult) + private Tuple ValidateBuyerOrderReference(List pProperties, ParserResult oParserResult, ZugferdResult pZugferdResult) { - var oMessageId = GetMessageId(); + var oMessageId = oParserResult.MessageId; _logger.Debug("Created new MessageId: [{0}]", oMessageId); _logger.Debug("Inserting properties into database."); @@ -566,6 +645,10 @@ namespace ZUGFeRDRESTService.Controllers return new Tuple(false, string.Empty); } + oParserResult.XML_InvoiceNumber = pProperties.Where(p => p.EN16931_ID == "BT-1").FirstOrDefault().Value; + oParserResult.XML_SellerTradePartyName = pProperties.Where(p => p.EN16931_ID == "BT-27").FirstOrDefault().Value; + oParserResult.XML_SellerEmailAdress = pProperties.Where(p => p.EN16931_ID == "BT-34").FirstOrDefault().Value; + _logger.Debug("Calling validation prodecure."); try { @@ -585,6 +668,7 @@ namespace ZUGFeRDRESTService.Controllers if (oReturnValue.Equals("ALL REFERENCES CHECKED POSITIVE", StringComparison.OrdinalIgnoreCase)) { _logger.Debug("Validation Success"); + oParserResult.ResultString = "SUCCESS"; oReturnValue = VALIDATION_SUCCESS; } else @@ -594,6 +678,7 @@ namespace ZUGFeRDRESTService.Controllers { if (oReturnValue.Contains(oRejectionItem, StringComparison.OrdinalIgnoreCase)) { + oParserResult.ResultString = oRejectionItem; _logger.Debug("oRejectionItem match: " + oRejectionItem); var oDbMessage = this.GetRejectionMessage(oRejectionItem); @@ -1050,28 +1135,40 @@ namespace ZUGFeRDRESTService.Controllers switch (rejectionCode) { case ErrorCodes.ValidationException: + _ParserResult.ResultString = ZUGFERD_Rejection_20001; return "20001"; case ErrorCodes.MD5HashException: + _ParserResult.ResultString = ZUGFERD_Rejection_20002; return "20002"; case ErrorCodes.UnsupportedFerdException: + _ParserResult.ResultString = ZUGFERD_Rejection_20003; return "20003"; case ErrorCodes.InvalidFerdException: + _ParserResult.ResultString = ZUGFERD_Rejection_20004; return "20004"; case ErrorCodes.TooMuchFerdsException: + _ParserResult.ResultString = ZUGFERD_Rejection_20005; return "20005"; case ErrorCodes.InvalidFerdNoXMLAttachmentFound: + _ParserResult.ResultString = ZUGFERD_Rejection_20006; return "20006"; case ErrorCodes.MissingValueException: + _ParserResult.ResultString = ZUGFERD_Rejection_20007; return "20007"; case ErrorCodes.FileSizeLimitReachedException: + _ParserResult.ResultString = ZUGFERD_Rejection_20008; return "20008"; case ErrorCodes.OutOfMemoryException: + _ParserResult.ResultString = ZUGFERD_Rejection_20009; return "20009"; case ErrorCodes.UnhandledException: + _ParserResult.ResultString = ZUGFERD_Rejection_20010; return "20010"; case ErrorCodes.FileMoveException: + _ParserResult.ResultString = ZUGFERD_Rejection_20011; return "20011"; default: + _ParserResult.ResultString = ZUGFERD_Rejection_20010; return "20010"; } } diff --git a/WEBSERVICES/ZUGFeRDRESTService/appsettings.Development.json b/WEBSERVICES/ZUGFeRDRESTService/appsettings.Development.json index 88f6d17f..87dbf787 100644 --- a/WEBSERVICES/ZUGFeRDRESTService/appsettings.Development.json +++ b/WEBSERVICES/ZUGFeRDRESTService/appsettings.Development.json @@ -11,7 +11,7 @@ "LogPath": "E:\\ZUGFeRDRESTService", "LogDebug": true, "Name": "ZUGFeRD REST API", - "MSSQLConnectionString": "Server=SDD-VMP04-SQL17\\DD_DEVELOP01;Database=DD_ECM;User Id=sa;Password=dd;", + "MSSQLConnectionString": "Server=SDD-VHP04-SQL19\\DD_TESTING01;Database=DD_ECM;User Id=sa;Password=123456789dD!;", "Firebird": { "Datasource": "172.24.12.41", "Database": "172.24.12.41:E:\\DB\\Firebird\\Databases\\EDMI_TEMPLATE\\EDMI_MASTER.FDB", @@ -27,7 +27,7 @@ "AllowPeppolBISBill3x": true, "AllowEBInterface": true }, - "GDPictureVersion": "", + "GDPictureVersion": "11.2024", "MaxFileSizeInMegabytes": 25 } }