ValidationController: BulkInsert, XML-Schema etc für die Datenbank mitnehmen. Korrekturen
This commit is contained in:
@@ -4,6 +4,7 @@ using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Data.SqlClient;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
@@ -36,14 +37,14 @@ namespace ZUGFeRDRESTService.Controllers
|
||||
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_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 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<string> _ValidationErrors;
|
||||
@@ -209,7 +210,6 @@ namespace ZUGFeRDRESTService.Controllers
|
||||
|
||||
if (oFileSizeIsOK == false)
|
||||
{
|
||||
//throw new ZUGFeRDExecption(ErrorType.FileTooBig, "FileTooBig");
|
||||
throw new ZUGFeRDExecption(ErrorCodes.FileSizeLimitReachedException, _MaxFileSizeInMegabytes.ToString(), string.Empty, "FileTooBig");
|
||||
}
|
||||
|
||||
@@ -218,6 +218,7 @@ namespace ZUGFeRDRESTService.Controllers
|
||||
if (file.FileName.EndsWith(".pdf", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
oZugferdResult = _zugferd.ExtractZUGFeRDFileWithGDPicture(oStream);
|
||||
oZugferdResult.ReceiptFileType = "PDF";
|
||||
}
|
||||
else if (file.FileName.EndsWith(".xml", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
@@ -229,6 +230,7 @@ namespace ZUGFeRDRESTService.Controllers
|
||||
};
|
||||
|
||||
oZugferdResult = _zugferd.SerializeZUGFeRDDocument(oResult);
|
||||
oZugferdResult.ReceiptFileType = "XML";
|
||||
}
|
||||
|
||||
_logger.Info("Detected Specification was: [{0}]", oZugferdResult.Specification);
|
||||
@@ -238,7 +240,6 @@ namespace ZUGFeRDRESTService.Controllers
|
||||
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
|
||||
@@ -263,15 +264,13 @@ namespace ZUGFeRDRESTService.Controllers
|
||||
|
||||
if (oPropertyResult.MissingProperties.Count > 0)
|
||||
{
|
||||
//throw new ZUGFeRDExecption(ErrorType.MissingProperties, "Missing Properties");
|
||||
throw new ZUGFeRDExecption(ErrorCodes.MissingValueException, "Missing Properties");
|
||||
}
|
||||
|
||||
Tuple<bool, string> oValidateResult = ValidateBuyerOrderReference(oPropertyResult.ValidProperties);
|
||||
Tuple<bool, string> oValidateResult = ValidateBuyerOrderReference(oPropertyResult.ValidProperties, oZugferdResult);
|
||||
|
||||
if (oValidateResult.Item1 == false)
|
||||
{
|
||||
//throw new ZUGFeRDExecption(ErrorType.UnknownError, "Unknown Error");
|
||||
throw new ZUGFeRDExecption(ErrorCodes.UnhandledException, "Unknown Error");
|
||||
}
|
||||
|
||||
@@ -398,20 +397,16 @@ 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)
|
||||
private Tuple<bool, string> ValidateBuyerOrderReference(List<ValidProperty> pProperties, ZugferdResult pZugferdResult)
|
||||
{
|
||||
var oMessageId = GetMessageId();
|
||||
_logger.Debug("Created new MessageId: [{0}]", oMessageId);
|
||||
|
||||
_logger.Debug("Inserting properties into database.");
|
||||
foreach (var oItem in pProperties)
|
||||
if (!BulkInsertDataToDatabase(oMessageId, pProperties, pZugferdResult))
|
||||
{
|
||||
var oResult = InsertPropertyMap(oItem, oMessageId);
|
||||
|
||||
if (oResult == false)
|
||||
{
|
||||
_logger.Warn("Error while inserting the Property [{0}] into the Database!", oItem.Description);
|
||||
}
|
||||
_logger.Warn("Error while Inserting properties into database!");
|
||||
return new Tuple<bool, string>(false, string.Empty);
|
||||
}
|
||||
|
||||
_logger.Debug("Calling validation prodecure.");
|
||||
@@ -472,8 +467,13 @@ namespace ZUGFeRDRESTService.Controllers
|
||||
oReturnValue = oDbMessage;
|
||||
}
|
||||
|
||||
// Für alle den RejectionCode setzen
|
||||
oReturnValue = oReturnValue.Replace("@REJECTION_CODE", oRejectionItem);
|
||||
// Der REJECTION-Code wird in alle Meldungen eingefügt.
|
||||
if (!string.IsNullOrEmpty(oRejectionItem) && oReturnValue.Contains("@REJECTION_CODE", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var rejectionCodeNumber = GetRejectionCodeNumber(oRejectionItem);
|
||||
oReturnValue = Regex.Replace(oReturnValue, "@REJECTION_CODE", "Ablehnungscode: " + rejectionCodeNumber, RegexOptions.IgnoreCase);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -616,60 +616,194 @@ namespace ZUGFeRDRESTService.Controllers
|
||||
return $"{Guid.NewGuid()}@{MESSAGEID_DOMAIN}";
|
||||
}
|
||||
|
||||
public bool InsertPropertyMap(ValidProperty pProperty, string pMessageId)
|
||||
private bool BulkInsertDataToDatabase(string pMessageId, List<ValidProperty> pProperties, ZugferdResult pZugferdResult)
|
||||
{
|
||||
if (string.IsNullOrEmpty(pMessageId))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!DeleteExistingPropertyValues(pMessageId))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
DataTable oDataTable = PrepareDataTable(pMessageId, pProperties, pZugferdResult);
|
||||
|
||||
// ColumnList initialisieren
|
||||
List<string> oColumnNames = new List<string> {
|
||||
"REFERENCE_GUID",
|
||||
"ITEM_DESCRIPTION",
|
||||
"ITEM_VALUE",
|
||||
"GROUP_COUNTER",
|
||||
"SPEC_NAME",
|
||||
"IS_REQUIRED"
|
||||
};
|
||||
|
||||
bool oBulkResult = BulkInsert(oDataTable, "TBEDMI_ITEM_VALUE", oColumnNames);
|
||||
|
||||
if (!oBulkResult)
|
||||
{
|
||||
_logger.Error("Bulk Insert for MessageId [{0}] failed!", pMessageId);
|
||||
return false;
|
||||
}
|
||||
|
||||
_logger.Info("Bulk Insert finished. [{0}] rows inserted for MessageId [{1}].", oDataTable.Rows.Count, pMessageId);
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool BulkInsert(DataTable pDataTable, string pDestinationTable, List<string> pColumnNames)
|
||||
{
|
||||
using (var oSqlBulkCopy = new SqlBulkCopy(_database.MSSQL.GetConnection()))
|
||||
{
|
||||
oSqlBulkCopy.DestinationTableName = pDestinationTable;
|
||||
foreach (var columnItem in pColumnNames)
|
||||
{
|
||||
oSqlBulkCopy.ColumnMappings.Add(new SqlBulkCopyColumnMapping(columnItem, columnItem));
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
oSqlBulkCopy.WriteToServer(pDataTable);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error(ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private DataTable PrepareDataTable(string pMessageId, List<ValidProperty> pProperties, ZugferdResult pDocument)
|
||||
{
|
||||
DataTable oDataTable = new DataTable();
|
||||
oDataTable.Columns.Add(new DataColumn("REFERENCE_GUID", typeof(string)));
|
||||
oDataTable.Columns.Add(new DataColumn("ITEM_DESCRIPTION", typeof(string)));
|
||||
oDataTable.Columns.Add(new DataColumn("ITEM_VALUE", typeof(string)));
|
||||
oDataTable.Columns.Add(new DataColumn("GROUP_COUNTER", typeof(Int32)));
|
||||
oDataTable.Columns.Add(new DataColumn("SPEC_NAME", typeof(string)));
|
||||
oDataTable.Columns.Add(new DataColumn("IS_REQUIRED", typeof(bool)));
|
||||
|
||||
// Erste Zeile enthält die Spezifikation
|
||||
DataRow oFirstRow = oDataTable.NewRow();
|
||||
oFirstRow["REFERENCE_GUID"] = pMessageId;
|
||||
oFirstRow["ITEM_DESCRIPTION"] = "Verwendete Spezifikation der E-Rechnung";
|
||||
oFirstRow["ITEM_VALUE"] = pDocument.Specification;
|
||||
oFirstRow["GROUP_COUNTER"] = 0;
|
||||
oFirstRow["SPEC_NAME"] = "ZUGFERD_SPECIFICATION";
|
||||
oFirstRow["IS_REQUIRED"] = false;
|
||||
|
||||
_logger.Debug("Mapping Property [ZUGFERD_SPECIFICATION] with value [{0}]", pDocument.Specification);
|
||||
oDataTable.Rows.Add(oFirstRow);
|
||||
|
||||
//' Zweite Zeile enthält das verwendete XML Schema
|
||||
DataRow oSecondRow = oDataTable.NewRow();
|
||||
oSecondRow["REFERENCE_GUID"] = pMessageId;
|
||||
oSecondRow["ITEM_DESCRIPTION"] = "Verwendetes XML-Schema (XSD) der E-Rechnung";
|
||||
oSecondRow["ITEM_VALUE"] = pDocument.UsedXMLSchema;
|
||||
oSecondRow["GROUP_COUNTER"] = 0;
|
||||
oSecondRow["SPEC_NAME"] = "ZUGFERD_XML_SCHEMA";
|
||||
oSecondRow["IS_REQUIRED"] = false;
|
||||
|
||||
_logger.Debug("Mapping Property [ZUGFERD_XML_SCHEMA] with value [{0}]", pDocument.UsedXMLSchema);
|
||||
oDataTable.Rows.Add(oSecondRow);
|
||||
|
||||
//' Dritte Zeile enthält das verwendete Datei-Format des Belegs (PDF/XML)
|
||||
if (pDocument.ReceiptFileType != null)
|
||||
{
|
||||
DataRow oThirdRow = oDataTable.NewRow();
|
||||
oThirdRow["REFERENCE_GUID"] = pMessageId;
|
||||
oThirdRow["ITEM_DESCRIPTION"] = "Dateityp der E-Rechnung";
|
||||
oThirdRow["ITEM_VALUE"] = pDocument.ReceiptFileType;
|
||||
oThirdRow["GROUP_COUNTER"] = 0;
|
||||
oThirdRow["SPEC_NAME"] = "RECEIPT_FILE_TYPE";
|
||||
oThirdRow["IS_REQUIRED"] = false;
|
||||
|
||||
_logger.Debug("Mapping Property [RECEIPT_FILE_TYPE] with value [{0}]", pDocument.ReceiptFileType);
|
||||
oDataTable.Rows.Add(oThirdRow);
|
||||
}
|
||||
|
||||
foreach (var propertyItem in pProperties)
|
||||
{
|
||||
|
||||
// ItemType = 3 => eingebettete Datei, nicht den base64 speichern
|
||||
if (propertyItem.ItemType == 3)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// ItemType = 0 (normale texte) dürfen nicht leer sein - leere Werte werden überlesen
|
||||
if (propertyItem.ItemType == 0 && string.IsNullOrEmpty(propertyItem.Value))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// If GroupCounter is -1, it means this is a default property that can only occur once.
|
||||
// Set the actual inserted value to 0
|
||||
var oGroupCounterValue = propertyItem.GroupCounter < 0 ? 0 : propertyItem.GroupCounter;
|
||||
|
||||
if (propertyItem.Value.Length > 4000)
|
||||
{
|
||||
_logger.Warn("Value for field [{0}] is longer than 4000 characters, will be truncated!", propertyItem.TableColumn);
|
||||
propertyItem.Value = propertyItem.Value.Substring(0, 4000);
|
||||
}
|
||||
|
||||
// Description mit BT-Feld aufbereiten
|
||||
var betterDescription = propertyItem.Description;
|
||||
if (!string.IsNullOrEmpty(propertyItem.EN16931_ID))
|
||||
{
|
||||
betterDescription = propertyItem.EN16931_ID + " (" + propertyItem.Description + ")";
|
||||
}
|
||||
|
||||
DataRow newRow = oDataTable.NewRow();
|
||||
newRow["REFERENCE_GUID"] = pMessageId;
|
||||
newRow["ITEM_DESCRIPTION"] = betterDescription;
|
||||
newRow["ITEM_VALUE"] = propertyItem.Value;
|
||||
newRow["GROUP_COUNTER"] = oGroupCounterValue;
|
||||
newRow["SPEC_NAME"] = propertyItem.TableColumn;
|
||||
newRow["IS_REQUIRED"] = propertyItem.IsRequired;
|
||||
|
||||
_logger.Debug("Mapping Property [{0}] with value [{1}]", propertyItem.TableColumn, propertyItem.Value);
|
||||
oDataTable.Rows.Add(newRow);
|
||||
}
|
||||
|
||||
return oDataTable;
|
||||
}
|
||||
|
||||
public bool DeleteExistingPropertyValues(string pMessageId)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (pProperty.ItemType == 3)
|
||||
{
|
||||
// Wir speichern keine Attachment-Werte in die DB
|
||||
return true;
|
||||
}
|
||||
|
||||
if (pProperty.ItemType == 0 && string.IsNullOrEmpty(pProperty.Value.ToString()))
|
||||
{
|
||||
// Leere Texte speichern wir nicht in der DB
|
||||
return true;
|
||||
}
|
||||
|
||||
var oSql = $"INSERT INTO {pProperty.TableName} " +
|
||||
"(REFERENCE_GUID, ITEM_DESCRIPTION, ITEM_VALUE, CREATEDWHO, SPEC_NAME, GROUP_COUNTER, IS_REQUIRED) VALUES " +
|
||||
"(@REFERENCE_GUID, @ITEM_DESCRIPTION, @ITEM_VALUE, @CREATEDWHO, @SPEC_NAME, @GROUP_COUNTER, @IS_REQUIRED)";
|
||||
|
||||
string itemValue = string.Empty;
|
||||
if (pProperty.Value.Length > 4000)
|
||||
{
|
||||
itemValue = pProperty.Value.Substring(1, 4000);
|
||||
_logger.Warn("Value for field [{0}] is longer than 4000 characters, will be truncated!", pProperty.TableColumn);
|
||||
}
|
||||
else
|
||||
{
|
||||
itemValue = pProperty.Value;
|
||||
}
|
||||
|
||||
var oParams = new SqlParameter[]
|
||||
{
|
||||
new SqlParameter("@REFERENCE_GUID", pMessageId),
|
||||
new SqlParameter("@ITEM_DESCRIPTION", pProperty.Description),
|
||||
new SqlParameter("@ITEM_VALUE", itemValue.Replace("'", "''")),
|
||||
new SqlParameter("@CREATEDWHO", ADDED_WHO),
|
||||
new SqlParameter("@GROUP_COUNTER", pProperty.GroupCounter),
|
||||
new SqlParameter("@SPEC_NAME", pProperty.TableColumn),
|
||||
new SqlParameter("@IS_REQUIRED", pProperty.IsRequired)
|
||||
};
|
||||
|
||||
var oCommand = new SqlCommand(oSql);
|
||||
oCommand.Parameters.AddRange(oParams);
|
||||
|
||||
return _database.MSSQL.ExecuteNonQuery(oCommand);
|
||||
var delItemValueSQL = "DELETE FROM TBEDMI_ITEM_VALUE WHERE REFERENCE_GUID '" + pMessageId + "';";
|
||||
var oCommand = new SqlCommand(delItemValueSQL);
|
||||
_database.MSSQL.ExecuteNonQuery(oCommand);
|
||||
_logger.Debug("DELETE FROM TBEDMI_ITEM_VALUE successfull");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error(ex);
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var delItemFilesSQL = "DELETE FROM TBEDMI_ITEM_FILES WHERE REFERENCE_GUID '" + pMessageId + "';";
|
||||
var oCommand = new SqlCommand(delItemFilesSQL);
|
||||
_database.MSSQL.ExecuteNonQuery(oCommand);
|
||||
_logger.Debug("DELETE FROM TBEDMI_ITEM_FILES successfull");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error(ex);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Ermittelt die Ausgabe-nachricht für einen Fehlercode
|
||||
/// </summary>
|
||||
@@ -744,5 +878,16 @@ namespace ZUGFeRDRESTService.Controllers
|
||||
return "20010";
|
||||
}
|
||||
}
|
||||
|
||||
private string GetRejectionCodeNumber(string rejectionCode)
|
||||
{
|
||||
if (rejectionCode.StartsWith("REFERENCES_Rejection_"))
|
||||
{
|
||||
var retValue = rejectionCode.Replace("REFERENCES_Rejection_", "");
|
||||
return retValue;
|
||||
}
|
||||
|
||||
return rejectionCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user