diff --git a/Jobs/Jobs.vbproj b/Jobs/Jobs.vbproj
index cf0838a5..a9c4900e 100644
--- a/Jobs/Jobs.vbproj
+++ b/Jobs/Jobs.vbproj
@@ -14,6 +14,8 @@
42016,41999,42017,42018,42019,42032,42036,42020,42021,42022
true
+
+
AnyCPU
@@ -116,12 +118,16 @@
True
Settings.settings
+
..\packages\FirebirdSql.Data.FirebirdClient.7.5.0\lib\net452\FirebirdSql.Data.FirebirdClient.dll
+
+ ..\packages\GdPicture.14.2.90\lib\net462\GdPicture.NET.14.dll
+
..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll
@@ -143,4 +149,11 @@
powershell.exe -command "& { &'$(SolutionDir)copy-binary.ps1' '$(TargetPath)' '$(TargetFileName)' '$(ConfigurationName)' '$(ProjectName)' }"
+
+
+
+ Dieses Projekt verweist auf mindestens ein NuGet-Paket, das auf diesem Computer fehlt. Verwenden Sie die Wiederherstellung von NuGet-Paketen, um die fehlenden Dateien herunterzuladen. Weitere Informationen finden Sie unter "http://go.microsoft.com/fwlink/?LinkID=322105". Die fehlende Datei ist "{0}".
+
+
+
\ No newline at end of file
diff --git a/Jobs/My Project/AssemblyInfo.vb b/Jobs/My Project/AssemblyInfo.vb
index 644ecb87..5c21ef84 100644
--- a/Jobs/My Project/AssemblyInfo.vb
+++ b/Jobs/My Project/AssemblyInfo.vb
@@ -30,5 +30,5 @@ Imports System.Runtime.InteropServices
' Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern
' übernehmen, indem Sie "*" eingeben:
-
-
+
+
diff --git a/Jobs/ZUGFeRD/ImportZUGFeRDFiles.vb b/Jobs/ZUGFeRD/ImportZUGFeRDFiles.vb
index 06a0ea4b..6dbadc87 100644
--- a/Jobs/ZUGFeRD/ImportZUGFeRDFiles.vb
+++ b/Jobs/ZUGFeRD/ImportZUGFeRDFiles.vb
@@ -40,11 +40,15 @@ Public Class ImportZUGFeRDFiles
Private ReadOnly _hash As HashFunctions
Private ReadOnly _embeds As PDFEmbeds
- Private ReadOnly _gdpictureLicenseKey As String
+ Private SQL_xRechnung_ItemTemplate As String = ""
+ Private ReadOnly _gdpictureLicenseKey As String
+ Private _xRechnungCreator As XRechnungViewDocument
Private _zugferd As ZUGFeRDInterface
Private _EmailOutAccountId As Integer
+ Private MyTemplateValues_xInvDT As DataTable
+
Private Class ProcessFileResult
Public ZugferdFileFound As Boolean = False
@@ -70,7 +74,7 @@ Public Class ImportZUGFeRDFiles
_history = New ZUGFeRD.HistoryFunctions(LogConfig, _mssql)
_embeds = New PDFEmbeds(LogConfig)
_hash = New HashFunctions(_logConfig, _mssql)
-
+ _xRechnungCreator = New XRechnungViewDocument(_logConfig, _mssql, _gdpictureLicenseKey)
_logger.Debug("Registering GDPicture License")
If _mssql IsNot Nothing Then
_gdpictureLicenseKey = ConfigDbFunct.GetProductLicense("GDPICTURE", "11.2024", _logConfig, _mssql.CurrentConnectionString)
@@ -92,6 +96,11 @@ Public Class ImportZUGFeRDFiles
})
_logger.Debug("Starting Job {0}", [GetType].Name)
+ If oArgs.AllowXRechnung Then
+ Dim oSQL = "Select SQL_COMMAND from TBDD_SQL_COMMANDS WHERE TITLE = 'VWDD_ZUGFERD_VIEW_RECEIPT_TEMPLATE_ITEMS'"
+ SQL_xRechnung_ItemTemplate = _mssql.GetScalarValue(oSQL)
+ End If
+
Try
'For Each oPath As String In oArgs.WatchDirectory
@@ -123,12 +132,23 @@ Public Class ImportZUGFeRDFiles
_logger.Info("Found {0} file groups", oGrouped.Count)
- ' Process each file group together
+ 'Process each file group together
+ 'oGrouped equals one e-invoice
For Each oFileGroup In oGrouped
' Start a new transaction for each file group.
' This way we can rollback database changes for the whole filegroup in case something goes wrong.
-
Dim oSQLConnection As SqlConnection = _mssql.GetConnection()
+
+ If oArgs.AllowXRechnung Then
+ 'but before we need to get all Data we need
+ MyTemplateValues_xInvDT = Nothing
+ Dim oSQL_MsgIDReplacec = SQL_xRechnung_ItemTemplate
+ oSQL_MsgIDReplacec = oSQL_MsgIDReplacec.Replace("@MSG_ID", oFileGroup.Key)
+ MyTemplateValues_xInvDT = _mssql.GetDatatable(oSQL_MsgIDReplacec)
+ End If
+
+
+
Dim oSQLTransaction As SqlTransaction = oSQLConnection?.BeginTransaction()
Dim oConnections As New DatabaseConnections() With {
@@ -151,7 +171,7 @@ Public Class ImportZUGFeRDFiles
Dim oExpectedError As Boolean = True
' Create file lists
- Dim oFileGroupFiles As List(Of FileInfo) = oFileGroup.Value
+ Dim oEInvoiceFileGroup As List(Of FileInfo) = oFileGroup.Value
Dim oEmailAttachmentFiles As New List(Of FileInfo)
Dim oEmbeddedAttachmentFiles As New List(Of PDFEmbeds.EmbeddedFile)
@@ -160,7 +180,7 @@ Public Class ImportZUGFeRDFiles
_logger.Info("START processing file group {0}", oMessageId)
- If _file.CheckFileAge(oFileGroupFiles, oArgs.MinFileAgeInMinutes) Then
+ If _file.CheckFileAge(oEInvoiceFileGroup, oArgs.MinFileAgeInMinutes) Then
_logger.Info("At least one file was created less than [{0}] minutes ago. Skipping file group.", oArgs.MinFileAgeInMinutes)
Continue For
End If
@@ -169,7 +189,8 @@ Public Class ImportZUGFeRDFiles
Dim oFileCounter As Integer = 0
Try
- For Each oFile In oFileGroupFiles
+
+ For Each oFile In oEInvoiceFileGroup
oFileCounter += 1
Dim oResult As ProcessFileResult
@@ -395,15 +416,28 @@ Public Class ImportZUGFeRDFiles
Finally
Try
+ Dim oxRechnungHandle As Boolean = False
+ Dim oRegularMove As Boolean = False
' If an application error occurred, dont move files so they will be processed again later
If oMoveDirectory = DIRECTORY_DONT_MOVE Then
_logger.Info("Application Error occurred. Files for message Id {0} will not be moved.", oMessageId)
-
- ElseIf (1 = 0) Then
+ ElseIf oArgs.AllowXRechnung And oIsSuccess And oEInvoiceFileGroup.Item(0).Extension = ".xml" Then
+ oxRechnungHandle = True
' Hier das neue PDF erzeugen
+ If Not IsNothing(MyTemplateValues_xInvDT) Then
+ Dim oViewReceiptFileInfo As FileInfo = _xRechnungCreator.Create_PDFfromXML(oEInvoiceFileGroup.Item(0), MyTemplateValues_xInvDT)
+ If Not IsNothing(oViewReceiptFileInfo) Then
+ oEInvoiceFileGroup.Item(0) = oViewReceiptFileInfo
+ oRegularMove = True
+ End If
+ End If
+
Else
+ oRegularMove = True
+ End If
+ If oRegularMove Then
' Move all files of the current group
- _file.MoveFiles(oArgs, oMessageId, oFileGroupFiles, oEmailAttachmentFiles, oEmbeddedAttachmentFiles, oMoveDirectory, oIsSuccess)
+ _file.MoveFiles(oArgs, oMessageId, oEInvoiceFileGroup, oEmailAttachmentFiles, oEmbeddedAttachmentFiles, oMoveDirectory, oIsSuccess)
End If
_logger.Info("END processing file group {0}", oMessageId)
Catch ex As Exception
diff --git a/Jobs/ZUGFeRD/XRechnungStrings.vb b/Jobs/ZUGFeRD/XRechnungStrings.vb
new file mode 100644
index 00000000..7137f4eb
--- /dev/null
+++ b/Jobs/ZUGFeRD/XRechnungStrings.vb
@@ -0,0 +1,7 @@
+Public Class XRechnungStrings
+ Public Const CommentSichtbeleg_DE_Row1 = "Achtung: dies ist ein technisch erstelltes Abbild einer digitalen Rechnung."
+ Public Const CommentSichtbeleg_DE_Row2 = "Die Darstellung basiert auf den Inhalten der xml-Datei, welche als Anhang in diese PDF integriert wurde!"
+ Public Const CommentSichtbeleg_EN_Row1 = "Please note: this is a technically created image of a digital invoice."
+ Public Const CommentSichtbeleg_EN_Row2 = "The representation is based on the contents of the xml file, which has been integrated into this PDF as an attachment!"
+ Public Const Seperator_Line = "-------------------------------------------------------------------------"
+End Class
diff --git a/Jobs/ZUGFeRD/XRechnungViewDocument.vb b/Jobs/ZUGFeRD/XRechnungViewDocument.vb
index c2ae9d69..1a57fdfb 100644
--- a/Jobs/ZUGFeRD/XRechnungViewDocument.vb
+++ b/Jobs/ZUGFeRD/XRechnungViewDocument.vb
@@ -1,3 +1,249 @@
-Public Class XRechnungViewDocument
+Imports System.Data
+Imports System.Data.SqlClient
+Imports System.IO
+Imports DigitalData.Modules.Base
+Imports DigitalData.Modules.Database
+Imports DigitalData.Modules.Logging
+Imports FirebirdSql.Data
+Imports GdPicture14
+
+Public Class XRechnungViewDocument
+ Private ReadOnly _logger As Logger
+ Private ReadOnly _logConfig As LogConfig
+ Private ReadOnly _filesystem As FilesystemEx
+ 'Private ReadOnly _mssql As MSSQLServer
+ Private ReadOnly _file As ZUGFeRD.FileFunctions
+ Private ReadOnly _gdpictureLicenseKey As String
+
+ Public Sub New(LogConfig As LogConfig, MSSQL As MSSQLServer, GDPictureLicenseKey As String)
+ _logConfig = LogConfig
+ _logger = LogConfig.GetLogger()
+ _filesystem = New FilesystemEx(_logConfig)
+ _file = New ZUGFeRD.FileFunctions(LogConfig, MSSQL)
+ _gdpictureLicenseKey = GDPictureLicenseKey
+ End Sub
+ Public Function Create_PDFfromXML(oxmlFile As FileInfo, pDTItemValues As DataTable) As FileInfo
+ Try
+ Dim oXRechnungFile = oxmlFile.FullName
+ Dim oNewFileinfo As FileInfo
+ Dim oxmlFilePath = oxmlFile.FullName
+ Dim oViewRecieptFilename = oxmlFile.Name
+ Dim oTempFilePath = Path.GetDirectoryName(oxmlFilePath) + "\Temp"
+ If Not Directory.Exists(oTempFilePath) Then
+ Directory.CreateDirectory(oTempFilePath)
+ End If
+
+ oTempFilePath = oTempFilePath + "\xrechnung.xml"
+ If File.Exists(oTempFilePath) Then
+ File.Delete(oTempFilePath)
+ End If
+ File.Move(oxmlFilePath, oTempFilePath)
+ oxmlFile = New FileInfo(oTempFilePath)
+ oViewRecieptFilename = oViewRecieptFilename.Replace("xml", "pdf")
+ Dim oOutputPath = Path.GetDirectoryName(oxmlFilePath) + "\" + oViewRecieptFilename
+ If File.Exists(oOutputPath) Then
+ File.Delete(oOutputPath)
+ End If
+
+ Dim gdpicturePDF As GdPicturePDF = New GdPicturePDF()
+ gdpicturePDF.NewPDF(PdfConformance.PDF_A_2a)
+ Dim ostatus As GdPictureStatus = gdpicturePDF.NewPDF()
+ If ostatus <> GdPictureStatus.OK Then
+ _logger.Warn($"Error initializing PDF: {ostatus}")
+ Return Nothing
+ End If
+ gdpicturePDF.SetOrigin(PdfOrigin.PdfOriginTopLeft)
+ gdpicturePDF.SetMeasurementUnit(PdfMeasurementUnit.PdfMeasurementUnitMillimeter)
+ gdpicturePDF.SetLineWidth(1)
+ Dim fontResName = gdpicturePDF.AddStandardFont(PdfStandardFont.PdfStandardFontHelvetica)
+ Dim fontResNameBold = gdpicturePDF.AddStandardFont(PdfStandardFont.PdfStandardFontHelveticaBold)
+ Dim fontResNameItalic = gdpicturePDF.AddStandardFont(PdfStandardFont.PdfStandardFontHelveticaBoldOblique)
+ gdpicturePDF.SetTitle("xInvoice VisualReceipt")
+ gdpicturePDF.SetAuthor("Digital Data GmbH, Heuchelheim")
+ 'Create a New page
+ gdpicturePDF.NewPage(PdfPageSizes.PdfPageSizeA4)
+ 'Draw content on the PDF
+ Dim yPosition As Integer = 20
+ gdpicturePDF.SetTextSize(18)
+ gdpicturePDF.DrawText(fontResName, 10, yPosition, "xRechnung Sichtbeleg - xInvoice Visual Receipt")
+ yPosition += 10
+ gdpicturePDF.SetTextSize(10)
+ gdpicturePDF.DrawText(fontResNameItalic, 10, yPosition, XRechnungStrings.CommentSichtbeleg_DE_Row1)
+ yPosition += 5
+ gdpicturePDF.DrawText(fontResNameItalic, 10, yPosition, XRechnungStrings.CommentSichtbeleg_DE_Row2)
+ yPosition += 5
+ gdpicturePDF.DrawText(fontResNameItalic, 10, yPosition, XRechnungStrings.CommentSichtbeleg_EN_Row1)
+ yPosition += 5
+ gdpicturePDF.DrawText(fontResNameItalic, 10, yPosition, XRechnungStrings.CommentSichtbeleg_EN_Row2)
+ Dim oArea As String = ""
+ Dim oIsPosition As Boolean = False
+ Dim oPosCount = 0
+ Dim oPosTerm As String = ""
+ Dim oCurrencySymbol = "€"
+ yPosition += 5
+ Dim oIndex As Integer = 0
+ For Each oRow As DataRow In pDTItemValues.Rows
+ Dim Y_eq_lastrow As Boolean = CBool(oRow.Item("Y_eq_lastrow"))
+ Dim oRowCaption As String = oRow.Item("Row_Caption")
+ Dim oItemSPECNAME As String = oRow.Item("SPEC_NAME")
+ Dim oItemValue As String = oRow.Item("ITEM_VALUE")
+ Dim oDisplay As Boolean = oRow.Item("Display")
+ Dim oRowGUID As String = oRow.Item("GUID")
+ Dim oAreaSwitch As Boolean = False
+ _logger.Debug($"Working on SPEC_NAME: {oItemSPECNAME}")
+
+ If oArea <> oRow.Item("Area") Then
+ '########## AREA WECHSEL ###########
+ oAreaSwitch = True
+ oArea = oRow.Item("Area")
+ Dim oAREACaption As String
+ If oArea = "TYPE" Then
+ oAREACaption = $"{Return_InvType(oItemValue)} [{oItemValue}]"
+ ElseIf oArea = "SELLER" Then
+ oAREACaption = "Verkäufer / Seller:"
+ ElseIf oArea = "BUYER" Then
+ oAREACaption = "Käufer / Buyer:"
+ ElseIf oArea = "POSITION" Then
+ oAREACaption = "Positionen / Positions:"
+ oIsPosition = True
+ ElseIf oArea = "AMOUNT" Then
+ oAREACaption = "Steuern / Taxes:"
+ ElseIf oArea = "PAYMENT" Then
+ oAREACaption = "Zahlungsinformationen / Payment details:"
+ Else
+ oAREACaption = String.Empty
+ End If
+
+ If Not oAREACaption = String.Empty Then
+ 'erste Area-Linie
+ yPosition += 8
+ gdpicturePDF.DrawLine(10, yPosition, 125, yPosition)
+ 'gdpicturePDF.DrawText(fontResName, 10, yPosition, XRechnungStrings.Seperator_Line)
+ yPosition += 5
+ 'Area caption
+ gdpicturePDF.DrawText(fontResNameBold, 10, yPosition, oAREACaption)
+ yPosition += 5
+ If oArea = "TYPE" Then
+ gdpicturePDF.DrawLine(10, yPosition, 125, yPosition)
+ ' gdpicturePDF.DrawText(fontResName, 10, yPosition, XRechnungStrings.Seperator_Line)
+ yPosition += 5
+ End If
+ End If
+ If oArea = "TYPE" Then
+ If oItemSPECNAME = "INVOICE_CURRENCY" Then
+ If oItemValue <> "EUR" Then
+ oCurrencySymbol = oItemValue
+ End If
+ End If
+ End If
+ If oArea = "POSITION" Then
+ oIsPosition = True
+ If oItemSPECNAME = "INVOICE_POSITION_AMOUNT" Then
+ oPosCount += 1
+ oPosTerm = $"{oPosCount}. {oItemValue} * "
+ End If
+ End If
+ Else
+ 'INDIVIDUELLES VERHALTEN BEI Folge-ITEMS
+ If oArea = "POSITION" Then
+ oIsPosition = True
+ If oItemSPECNAME = "INVOICE_POSITION_AMOUNT" Then
+ oPosCount += 1
+ oPosTerm = $"{oPosCount}. {oItemValue} * "
+ ElseIf oItemSPECNAME = "INVOICE_POSITION_ARTICLE" Then
+ oPosTerm += $" {oItemValue}"
+ ElseIf oItemSPECNAME = "INVOICE_TAXPOS_TAX_RATE" Or oItemSPECNAME = "INVOICE_TAXPOS_RATE" Then
+ oPosTerm += $" - ({oItemValue} %)"
+ End If
+ oItemValue = oPosTerm
+ If oPosCount >= 9 Then
+ oDisplay = False
+ End If
+ ElseIf oArea = "AMOUNT" Then
+ If oItemSPECNAME = "INVOICE_TOTAL_NET" Or oItemSPECNAME = "INVOICE_TOTAL_TAX" Then
+ oItemValue += $" {oCurrencySymbol}"
+ End If
+ ElseIf oArea = "HEAD" Then
+ If oItemSPECNAME = "INVOICE_DATE" Or oItemSPECNAME = "INVOICE_SERVICE_DATE" Then
+ Dim oDateString As String = oItemValue
+ Dim oParsedDate As DateTime = DateTime.ParseExact(oDateString, "yyyyMMdd", System.Globalization.CultureInfo.InvariantCulture)
+ oItemValue = oParsedDate.ToString("dd.MM.yyyy")
+ End If
+ End If
+ End If
+
+ If oDisplay = True Then
+ If Y_eq_lastrow = False And oAreaSwitch = False Then
+ yPosition += 5
+ End If
+ If oRowCaption <> String.Empty Then
+ gdpicturePDF.DrawText(fontResName, 10, yPosition, oRowCaption)
+ gdpicturePDF.DrawText(fontResName, 70, yPosition, oItemValue)
+ Else
+ If Y_eq_lastrow = True Then
+ If oIsPosition = True And oPosCount = 9 Then
+ gdpicturePDF.DrawText(fontResName, 10, yPosition, "...es gibt noch mehr Positionen, diese werden aber aus Layoutgründen nicht dargestellt.")
+ gdpicturePDF.DrawText(fontResName, 10, yPosition, "...There are more positions, but these are not shown for layout reasons.")
+ Else
+ gdpicturePDF.DrawText(fontResName, oRow.Item("xPosition"), yPosition, oItemValue)
+ End If
+ Else
+ gdpicturePDF.DrawText(fontResName, 10, yPosition, oItemValue)
+ End If
+ End If
+ End If
+ oIndex += 1
+ Next
+ Dim oCreated = Now.ToString
+
+ gdpicturePDF.DrawLine(10, 280, 200, 280)
+ 'gdpicturePDF.DrawText(fontResName, 10, 285, XRechnungStrings.Seperator_Line)
+ Dim oCreatedString = $"Maschinell erstellt durch/Automatically created by Digital Data E-Rechnung Parser: {oCreated}"
+ gdpicturePDF.DrawText(fontResName, 10, 285, oCreatedString)
+ Dim oeinv_Format As PdfInvoiceDataFormat = PdfInvoiceDataFormat.ZUGFeRD_2_0
+ gdpicturePDF.EmbedFile(oTempFilePath, "Rechnungsdaten im ZUGFeRD-XML-Format")
+ 'Finalize And save the PDF
+ ostatus = gdpicturePDF.SaveToFile(oOutputPath)
+ If ostatus = GdPictureStatus.OK Then
+ _logger.Info("PDF VisualReceipt generated successfully!")
+ Else
+ _logger.Warn($"Error generating PDF VisualReceipt: {ostatus}")
+ End If
+
+ 'Release resources
+ gdpicturePDF.CloseDocument()
+ If ostatus = GdPictureStatus.OK Then
+ File.Delete(oXRechnungFile)
+ oNewFileinfo = New FileInfo(oOutputPath)
+ Return oNewFileinfo
+ Else
+ Return Nothing
+ End If
+
+ Catch ex As Exception
+ _logger.Error(ex)
+ Return Nothing
+ End Try
+ End Function
+ Private Function Return_InvType(pType As String) As String
+ Dim oReturn As String = "Rechnung/invoice"
+ If pType = "380" Then
+ oReturn = "Handelsrechnung/Commercial invoice"
+ ElseIf pType = "381" Then
+ oReturn = "Gutschriftanzeige/Credit advice"
+ ElseIf pType = "384" Then
+ oReturn = "Rechnungskorrektur/Invoice correction"
+ ElseIf pType = "386" Then
+ oReturn = "Vorauszahlungsrechnung/Prepayment invoice"
+ ElseIf pType = "326" Then
+ oReturn = "Teilrechnung/Partial invoice"
+ ElseIf pType = "84" Then
+ oReturn = "Gutschrift/Credit note"
+ ElseIf pType = "389" Then
+ oReturn = "Gutschriftsverfahren/Credit note procedure"
+ End If
+ Return oReturn
+ End Function
+
End Class
diff --git a/Jobs/packages.config b/Jobs/packages.config
index 91d16086..a70f210b 100644
--- a/Jobs/packages.config
+++ b/Jobs/packages.config
@@ -1,6 +1,8 @@
+
+
\ No newline at end of file