ZUGFeRDRESTParser:

- Validierung
- Neue Tabelle TBEDMI_PARSER_RESULTS (INSERT, etc.)
This commit is contained in:
2026-09-11 16:24:23 +02:00
parent a5773e9b8f
commit 8ef60de3ad
3 changed files with 258 additions and 9 deletions

View File

@@ -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;
}
}
}
}

View File

@@ -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<bool, string> oValidateResult = ValidateBuyerOrderReference(oPropertyResult.ValidProperties, oZugferdResult);
Tuple<bool, string> 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<MissingProperty> 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.
/// </summary>
private Tuple<bool, string> ValidateBuyerOrderReference(List<ValidProperty> pProperties, ZugferdResult pZugferdResult)
private Tuple<bool, string> ValidateBuyerOrderReference(List<ValidProperty> 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<bool, string>(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";
}
}

View File

@@ -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
}
}