6 Commits

6 changed files with 580 additions and 223 deletions

View File

@@ -758,14 +758,17 @@ Public Class DocumentViewer
SpreadsheetControl1.Dock = DockStyle.Fill
Case Else
GdViewer.ZoomMode = ViewerZoomMode.ZoomModeWidthViewer
GdViewer.DocumentAlignment = ViewerDocumentAlignment.DocumentAlignmentTopCenter
If Viewer_ForceTemporaryMode = True Then
GdViewer.ForceTemporaryMode = True
End If
GdViewer.AnnotationDropShadow = True
If Not GdViewer Is Nothing Then
GdViewer.ZoomMode = ViewerZoomMode.ZoomModeWidthViewer
GdViewer.DocumentAlignment = ViewerDocumentAlignment.DocumentAlignmentTopCenter
If Viewer_ForceTemporaryMode = True Then
GdViewer.ForceTemporaryMode = True
End If
GdViewer.AnnotationDropShadow = True
GdViewer.DisplayFromStream(Stream)
End If
GdViewer.DisplayFromStream(Stream)
End Select

View File

@@ -23,10 +23,8 @@ Partial Class frmFilesystem
<System.Diagnostics.DebuggerStepThrough()> _
Private Sub InitializeComponent()
Me.Button1 = New System.Windows.Forms.Button()
Me.Button2 = New System.Windows.Forms.Button()
Me.btnStreamSimpleFile = New System.Windows.Forms.Button()
Me.GroupBox1 = New System.Windows.Forms.GroupBox()
Me.Button3 = New System.Windows.Forms.Button()
Me.TextBox1 = New System.Windows.Forms.TextBox()
Me.SaveFileDialog1 = New System.Windows.Forms.SaveFileDialog()
Me.txtServiceAddress = New DevExpress.XtraEditors.TextEdit()
Me.Label1 = New System.Windows.Forms.Label()
@@ -40,52 +38,35 @@ Partial Class frmFilesystem
'
'Button1
'
Me.Button1.Location = New System.Drawing.Point(59, 343)
Me.Button1.Location = New System.Drawing.Point(42, 234)
Me.Button1.Name = "Button1"
Me.Button1.Size = New System.Drawing.Size(288, 23)
Me.Button1.TabIndex = 0
Me.Button1.Text = "CreateDateDirectory"
Me.Button1.UseVisualStyleBackColor = True
'
'Button2
'btnStreamSimpleFile
'
Me.Button2.Location = New System.Drawing.Point(6, 71)
Me.Button2.Name = "Button2"
Me.Button2.Size = New System.Drawing.Size(288, 23)
Me.Button2.TabIndex = 1
Me.Button2.Text = "Stream simple file"
Me.Button2.UseVisualStyleBackColor = True
Me.btnStreamSimpleFile.Location = New System.Drawing.Point(6, 19)
Me.btnStreamSimpleFile.Name = "btnStreamSimpleFile"
Me.btnStreamSimpleFile.Size = New System.Drawing.Size(288, 23)
Me.btnStreamSimpleFile.TabIndex = 1
Me.btnStreamSimpleFile.Text = "Stream simple file"
Me.btnStreamSimpleFile.UseVisualStyleBackColor = True
'
'GroupBox1
'
Me.GroupBox1.Controls.Add(Me.Button3)
Me.GroupBox1.Controls.Add(Me.TextBox1)
Me.GroupBox1.Controls.Add(Me.Button2)
Me.GroupBox1.Controls.Add(Me.btnStreamSimpleFile)
Me.GroupBox1.Location = New System.Drawing.Point(36, 153)
Me.GroupBox1.Name = "GroupBox1"
Me.GroupBox1.Size = New System.Drawing.Size(709, 157)
Me.GroupBox1.Size = New System.Drawing.Size(709, 58)
Me.GroupBox1.TabIndex = 2
Me.GroupBox1.TabStop = False
Me.GroupBox1.Text = "Stream simple file"
'
'Button3
'
Me.Button3.Location = New System.Drawing.Point(6, 19)
Me.Button3.Name = "Button3"
Me.Button3.Size = New System.Drawing.Size(181, 23)
Me.Button3.TabIndex = 3
Me.Button3.Text = "1. Choose file"
Me.Button3.UseVisualStyleBackColor = True
'
'TextBox1
'
Me.TextBox1.Location = New System.Drawing.Point(6, 45)
Me.TextBox1.Name = "TextBox1"
Me.TextBox1.Size = New System.Drawing.Size(669, 20)
Me.TextBox1.TabIndex = 2
'
'txtServiceAddress
'
Me.txtServiceAddress.EditValue = "172.24.12.12"
Me.txtServiceAddress.Location = New System.Drawing.Point(36, 37)
Me.txtServiceAddress.Name = "txtServiceAddress"
Me.txtServiceAddress.Size = New System.Drawing.Size(485, 20)
@@ -96,9 +77,9 @@ Partial Class frmFilesystem
Me.Label1.AutoSize = True
Me.Label1.Location = New System.Drawing.Point(33, 21)
Me.Label1.Name = "Label1"
Me.Label1.Size = New System.Drawing.Size(81, 13)
Me.Label1.Size = New System.Drawing.Size(136, 13)
Me.Label1.TabIndex = 6
Me.Label1.Text = "ServiceAdresse"
Me.Label1.Text = "EDMI Service Adresse: (IP)"
'
'txtServicePort
'
@@ -114,7 +95,7 @@ Partial Class frmFilesystem
'
Me.Button4.Location = New System.Drawing.Point(36, 89)
Me.Button4.Name = "Button4"
Me.Button4.Size = New System.Drawing.Size(75, 23)
Me.Button4.Size = New System.Drawing.Size(85, 23)
Me.Button4.TabIndex = 8
Me.Button4.Text = "Connect"
Me.Button4.UseVisualStyleBackColor = True
@@ -123,7 +104,7 @@ Partial Class frmFilesystem
'
Me.txtStatus.Location = New System.Drawing.Point(527, 37)
Me.txtStatus.Name = "txtStatus"
Me.txtStatus.Size = New System.Drawing.Size(100, 20)
Me.txtStatus.Size = New System.Drawing.Size(184, 20)
Me.txtStatus.TabIndex = 9
'
'frmFilesystem
@@ -141,7 +122,6 @@ Partial Class frmFilesystem
Me.Name = "frmFilesystem"
Me.Text = "frmFilesystem"
Me.GroupBox1.ResumeLayout(False)
Me.GroupBox1.PerformLayout()
CType(Me.txtServiceAddress.Properties, System.ComponentModel.ISupportInitialize).EndInit()
CType(Me.txtServicePort.Properties, System.ComponentModel.ISupportInitialize).EndInit()
Me.ResumeLayout(False)
@@ -150,10 +130,8 @@ Partial Class frmFilesystem
End Sub
Friend WithEvents Button1 As Button
Friend WithEvents Button2 As Button
Friend WithEvents btnStreamSimpleFile As Button
Friend WithEvents GroupBox1 As GroupBox
Friend WithEvents Button3 As Button
Friend WithEvents TextBox1 As TextBox
Friend WithEvents SaveFileDialog1 As SaveFileDialog
Friend WithEvents txtServiceAddress As DevExpress.XtraEditors.TextEdit
Friend WithEvents Label1 As Label

View File

@@ -9,9 +9,11 @@ Imports DigitalData.Modules.EDMI.API
Imports DigitalData.Modules.EDMI.API.EDMIServiceReference
Imports DigitalData.Modules.Logging
Imports DigitalData.Modules.ZooFlow.State
Imports DigitalData.Services.EDMIService
Imports DigitalData.Services.EDMIService.GlobalState
Public Class frmFilesystem
Private Client As Client
Private EDMIClient As Client
Private Logger As Logger
Private Const STATUS_CONNECTED = "Connection Established"
@@ -59,17 +61,73 @@ Public Class frmFilesystem
Dim oDateString = MYDD_Filesystem.CreateDateDirectory("E:\")
End Sub
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Private Sub Button3_Click(sender As Object, e As EventArgs)
If SaveFileDialog1.ShowDialog = DialogResult.OK Then
' Fallback: einfache Textdatei schreiben
System.IO.File.WriteAllText(SaveFileDialog1.FileName, "Some text data")
End If
End Sub
Private Async Function Button2_ClickAsync(sender As Object, e As EventArgs) As Task Handles Button2.Click
Public Class SecureStorageHandler
End Class
Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
Try
Dim oIPAddress = txtServiceAddress.Text
Dim oPort = Integer.Parse(txtServicePort.Text)
EDMIClient = New Client(LogConfig, oIPAddress, oPort)
txtStatus.Text = STATUS_CONNECTING
Dim oResult = EDMIClient.Connect()
If oResult = True Then
ServiceAddress = $"{oIPAddress}:{oPort}"
ServiceOnline = True
txtStatus.Text = STATUS_CONNECTED
txtStatus.BackColor = Color.LightGreen
My.Application.Service.Client = EDMIClient
Logger.Debug("Loading client config..")
Dim oClientConfig = My.Application.Service.Client.ClientConfig
Logger.Debug("Establishing ECM connection..")
Dim oECMConnectionString = oClientConfig.ConnectionStringECM
My.DatabaseECM = New MSSQLServer(LogConfig, oECMConnectionString)
Logger.Debug("Establishing IDB connection..")
Dim oIDBConnectionString = oClientConfig.ConnectionStringIDB
My.DatabaseIDB = New MSSQLServer(LogConfig, oIDBConnectionString)
Logger.Debug("Establishing Database connection with fallback..")
My.Database = New DatabaseWithFallback(LogConfig, My.Application.Service.Client, My.DatabaseECM, My.DatabaseIDB)
Else
ServiceAddress = ""
ServiceOnline = True
txtStatus.Text = STATUS_FAILED
txtStatus.BackColor = Color.LightCoral
' TODO: Make a connection test that is as elaborate as this one :D
'Select Case oResult
' Case ClassService.ConnectionTestResult.NotFound
' lblStatus.Text = "Dienst konnte nicht gefunden werden. Bitte überprüfen sie Addresse und Port."
' Case ClassService.ConnectionTestResult.EmptyURI
' lblStatus.Text = "Bitte tragen Sie eine gültige Dienst Adresse ein."
' Case ClassService.ConnectionTestResult.Authentication
' lblStatus.Text = "Authentifizierungsfehler. Prüfen Sie, ob sich Ihr Gerät in der korrekten Domäne befindet."
' Case Else
' lblStatus.Text = "Unbekannter Fehler."
'End Select
End If
Catch ex As Exception
If Logger IsNot Nothing Then Logger.Error(ex)
MsgBox("Fehler beim Verbindungsaufbau", MsgBoxStyle.Critical, Text)
End Try
End Sub
Private Sub Button2_ClickAsync(sender As Object, e As EventArgs) Handles btnStreamSimpleFile.Click
' Import a file via EDMI Globix ImportFile API to test Service.EDMIService ImportFileMethod
Try
If Client Is Nothing OrElse ServiceOnline = False Then
If EDMIClient Is Nothing OrElse ServiceOnline = False Then
MsgBox("Bitte zuerst Verbindung zum EDMI Service herstellen.", MsgBoxStyle.Exclamation, Text)
Return
End If
@@ -92,7 +150,7 @@ Public Class frmFilesystem
.LanguageId = 1031
}
Dim oObjectStore As String = "SelectedDocType.ObjectStore"
Dim oObjectStore As String = "WORK"
Dim oIDBDoctypeId As Long = 1
Dim oObjectKind As String = "DOC"
Dim oProfileId As Integer = 1
@@ -105,89 +163,11 @@ Public Class frmFilesystem
Logger.Debug("ProfileId: [{0}]", oProfileId)
Logger.Debug("IDB DoctypeId: [{0}]", oIDBDoctypeId)
Logger.Info("Running Import")
Dim oResult = Await My.Application.Service.Client.Globix_ImportFileAsync(
oFilePath, oProfileId, oAttributes, oObjectStore, oObjectKind, oIDBDoctypeId, oOptions)
Logger.Info("Import result: [{0}]", oResult.OK)
Logger.Info("Imported file got ObjectId [{0}]", oResult.ObjectId)
If oResult.OK Then
MsgBox("Alles OK")
Else
Logger.Warn("Import failed with message: [{0}] and details [{1}]", oResult.ErrorMessage, oResult.ErrorDetails)
Dim oMsg As String, oTitle As String
If My.Application.User.Language = "de-DE" Then
oMsg = $"Die Datei wurde nicht verarbeitet.{vbNewLine}{vbNewLine}Fehler: {oResult.ErrorMessage}"
oTitle = "Achtung"
Else
oMsg = $"Unexpected Error in FileFlow{vbNewLine}{vbNewLine}Fehler: {oResult.ErrorMessage}"
oTitle = "Attention"
End If
MsgBox("Fehler")
End If
End Using
Catch ex As Exception
If Logger IsNot Nothing Then Logger.Error(ex)
MsgBox("Fehler beim Datei-Import.", MsgBoxStyle.Critical, Text)
End Try
End Function
Public Class SecureStorageHandler
End Class
Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
Try
Dim oIPAddress = txtServiceAddress.Text
Dim oPort = Integer.Parse(txtServicePort.Text)
Client = New Client(LogConfig, oIPAddress, oPort)
txtStatus.Text = STATUS_CONNECTING
Dim oResult = Client.Connect()
If oResult = True Then
ServiceAddress = $"{oIPAddress}:{oPort}"
ServiceOnline = True
txtStatus.Text = STATUS_CONNECTED
My.Application.Service.Client = Client
Logger.Debug("Loading client config..")
Dim oClientConfig = My.Application.Service.Client.ClientConfig
Logger.Debug("Establishing ECM connection..")
Dim oECMConnectionString = oClientConfig.ConnectionStringECM
My.DatabaseECM = New MSSQLServer(My.LogConfig, oECMConnectionString)
Logger.Debug("Establishing IDB connection..")
Dim oIDBConnectionString = oClientConfig.ConnectionStringIDB
My.DatabaseIDB = New MSSQLServer(My.LogConfig, oIDBConnectionString)
Logger.Debug("Establishing Database connection with fallback..")
My.Database = New DatabaseWithFallback(LogConfig, My.Application.Service.Client, My.DatabaseECM, My.DatabaseIDB)
Else
ServiceAddress = ""
ServiceOnline = True
txtStatus.Text = STATUS_FAILED
' TODO: Make a connection test that is as elaborate as this one :D
'Select Case oResult
' Case ClassService.ConnectionTestResult.NotFound
' lblStatus.Text = "Dienst konnte nicht gefunden werden. Bitte überprüfen sie Addresse und Port."
' Case ClassService.ConnectionTestResult.EmptyURI
' lblStatus.Text = "Bitte tragen Sie eine gültige Dienst Adresse ein."
' Case ClassService.ConnectionTestResult.Authentication
' lblStatus.Text = "Authentifizierungsfehler. Prüfen Sie, ob sich Ihr Gerät in der korrekten Domäne befindet."
' Case Else
' lblStatus.Text = "Unbekannter Fehler."
'End Select
End If
Catch ex As Exception
If Logger IsNot Nothing Then Logger.Error(ex)
MsgBox("Fehler beim Verbindungsaufbau", MsgBoxStyle.Critical, Text)
End Try
End Sub
End Class

View File

@@ -86,14 +86,7 @@ Namespace Methods.GlobalIndexer.ImportFile
oAutoAttributes = oAutomaticIndexing.ApplyAutomaticeAttributes(oUserAttributes, pData.File.FileInfoRaw, User)
' Import the file
Dim oNewFile As New NewFile.NewFileMethod(LogConfig, DatabaseIDB, DatabaseECM, GlobalState)
Dim oResponse = oNewFile.Run(New NewFile.NewFileRequest With {
.File = pData.File,
.IDBDoctypeId = pData.IDBDoctypeId,
.KindType = pData.KindType,
.StoreName = pData.StoreName,
.User = User
})
Dim oResponse = ImportFile(pData)
If oResponse.OK Then
Logger.Info("Import of file [{0}] under ObjectId [{1}] successful!", pData.File.FileName, oResponse.ObjectId)
@@ -147,7 +140,16 @@ Namespace Methods.GlobalIndexer.ImportFile
Return New Globix_ImportFileResponse(ex)
End Try
End Function
Private Function ImportFile(pData As Globix_ImportFileRequest) As NewFile.NewFileResponse
Dim oNewFile As New NewFile.NewFileMethod(LogConfig, DatabaseIDB, DatabaseECM, GlobalState)
Return oNewFile.Run(New NewFile.NewFileRequest With {
.File = pData.File,
.IDBDoctypeId = pData.IDBDoctypeId,
.KindType = pData.KindType,
.StoreName = pData.StoreName,
.User = User
})
End Function
Private Function GetVirtualPath(pFileInfo As FileInfo, pPathConvention As String, pUser As UserState, pUserAttributes As List(Of UserAttributeValue), pAutoAttributes As List(Of UserAttributeValue))
Logger.Info("Generating virtual path for file [{0}]", pFileInfo.Name)

View File

@@ -1,18 +1,18 @@
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;
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 +26,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<string> _ValidationErrors;
private const int MAX_FILE_SIZE_DEFAULT = 25;
private readonly ZUGFeRDInterface _zugferd;
@@ -82,7 +105,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<String>() {
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!");
}
@@ -165,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");
}
@@ -174,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))
{
@@ -185,23 +230,23 @@ namespace ZUGFeRDRESTService.Controllers
};
oZugferdResult = _zugferd.SerializeZUGFeRDDocument(oResult);
oZugferdResult.ReceiptFileType = "XML";
}
_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");
@@ -219,24 +264,21 @@ 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");
}
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 +286,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 +298,8 @@ namespace ZUGFeRDRESTService.Controllers
message = oMessage
};
}
};
}
}
catch (ZUGFeRDExecption ex)
{
@@ -299,9 +342,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 +358,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,20 +393,20 @@ namespace ZUGFeRDRESTService.Controllers
}
}
private Tuple<bool, string> ValidateBuyerOrderReference(List<ValidProperty> pProperties)
/// <summary>
/// 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)
{
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)
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.");
@@ -377,6 +422,64 @@ 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;
}
// 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;
}
}
}
_logger.Debug("Validation terminal Result message: " + oReturnValue);
return new Tuple<bool, string>(true, oReturnValue);
}
@@ -390,7 +493,122 @@ namespace ZUGFeRDRESTService.Controllers
{
_logger.Error(e);
return new Tuple<bool, string>(false, string.Empty);
}
}
}
private string GetReplaceText1_30003_3(List<ValidProperty> 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 += "<li>[BuyerOrderReferencedDocument] (BT-13) = [" + valueBt13 + "]</li>";
// BuyerReference
var itemBT10 = pProperties.Where(i => i.TableColumn == "INVOICE_REFERENCE3").FirstOrDefault();
string valueBt10 = "-";
if (itemBT10 != null)
{
valueBt10 = string.IsNullOrEmpty(itemBT10.Value) ? "-" : itemBT10.Value;
}
oReplaceParam1 += "<li>[BuyerReference] (BT-10) = [" + valueBt10 + "]</li>";
// 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 += "<li>[CostCenter] (BT-19) = [" + valueBt19 + "]</li>";
// 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 += "<li>[BuyerTradeParty] (BT-46) = [" + valueBt46 + "]</li>";
oReplaceParam1 = "<ul>" + oReplaceParam1 + "</ul>";
_logger.Debug("oReplaceParam1-Text: " + oReplaceParam1);
return oReplaceParam1;
}
private string GetReplaceText2_30003_2(List<ValidProperty> 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 += "<li>[BuyerTradeParty.Name] (BT-44) = [" + valueBt44 + "]</li>";
// 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 += "<li>[BuyerTradeParty.PostalTradeAddress.LineTwo] (BT-51) = [" + valueBt51 + "]</li>";
oReplaceParam2 = "<ul>" + oReplaceParam2 + "</ul>";
_logger.Debug("oReplaceParam2-Text: " + oReplaceParam2);
return oReplaceParam2;
}
private string GetReplaceText1_30003_2(List<ValidProperty> 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 += "<li>[BuyerOrderReferencedDocument] (BT-13) = [" + valueBt13 + "]</li>";
// BuyerReference
var itemBT10 = pProperties.Where(i => i.TableColumn == "INVOICE_REFERENCE3").FirstOrDefault();
string valueBt10 = "-";
if (itemBT10 != null)
{
valueBt10 = string.IsNullOrEmpty(itemBT10.Value) ? "-" : itemBT10.Value;
}
oReplaceParam1 += "<li>[BuyerReference] (BT-10) = [" + valueBt10 + "]</li>";
// 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 += "<li>[CostCenter] (BT-19) = [" + valueBt19 + "]</li>";
oReplaceParam1 = "<ul>" + oReplaceParam1 + "</ul>";
_logger.Debug("oReplaceParam1-Text: " + oReplaceParam1);
return oReplaceParam1;
}
public string GetMessageId()
@@ -398,60 +616,207 @@ 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)
var delItemValueSQL = "DELETE FROM TBEDMI_ITEM_VALUE WHERE REFERENCE_GUID = '" + pMessageId + "';";
var oCommand = new SqlCommand(delItemValueSQL);
var retValue = _database.MSSQL.ExecuteNonQuery(oCommand);
if (!retValue)
{
// Wir speichern keine Attachment-Werte in die DB
return true;
_logger.Warn("DELETE FROM TBEDMI_ITEM_VALUE NOT successfull");
return false;
}
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);
_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);
var retValue = _database.MSSQL.ExecuteNonQuery(oCommand);
if (!retValue)
{
_logger.Warn("DELETE FROM TBEDMI_ITEM_FILES NOT successfull");
return false;
}
_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>
@@ -463,7 +828,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)
@@ -508,5 +891,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;
}
}
}

View File

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