Modules/Jobs/ZUGFeRD/XRechnungViewDocument.vb
2025-02-11 10:15:26 +01:00

297 lines
15 KiB
VB.net

Imports System.Collections.Generic
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 _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 = 15
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 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 = "Beträge / Amounts:"
ElseIf oArea = "TAXPOS" Then
oAREACaption = "Steuerbeträge / Tax amounts:"
oIsPosition = True
ElseIf oArea = "PAYMENT" Then
oAREACaption = "Zahlungsinformationen / Payment details:"
Else
oAREACaption = String.Empty
End If
If Not oAREACaption = String.Empty Then
'erste Area-Linie
yPosition += 5
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
ElseIf oArea = "POSITION" Then
oIsPosition = True
If oItemSPECNAME = "INVOICE_POSITION_AMOUNT" Then
oPosCount += 1
oPosTerm = $"{oPosCount}. {oItemValue} * "
oItemValue = oPosTerm
oDisplay = False
yPosition -= 5
End If
ElseIf oArea = "TAXPOS" Then
oIsPosition = True
If oItemSPECNAME = "INVOICE_TAXPOS_RATE" Then
oPosCount = 1
oPosTerm = $"{oItemValue} %:"
oItemValue = oPosTerm
oDisplay = False
yPosition -= 5
End If
End If
Else
'INDIVIDUELLES VERHALTEN BEI Folge-ITEMS
If oArea = "POSITION" Then
If oItemSPECNAME = "INVOICE_POSITION_AMOUNT" Then
oPosCount += 1
oPosTerm = $"{oPosCount}. {oItemValue} * "
oDisplay = False
ElseIf oItemSPECNAME = "INVOICE_POSITION_ARTICLE" Then
oPosTerm += $" {oItemValue}"
oDisplay = False
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 = "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
ElseIf oArea = "TAXPOS" Then
If oItemSPECNAME = "INVOICE_TAXPOS_RATE" Then
oPosCount += 1
oPosTerm = $"{oItemValue} %:"
oDisplay = False
ElseIf oItemSPECNAME = "INVOICE_TAXPOS_AMOUNT" Then
oPosTerm += $" {oItemValue} {oCurrencySymbol}"
oDisplay = False
ElseIf oItemSPECNAME = "INVOICE_TAXPOS_TYPE" Then
oPosTerm += $" - {oItemValue}"
End If
oItemValue = oPosTerm
End If
End If
If oDisplay = True Then
If Y_eq_lastrow = False And oAreaSwitch = False Then
yPosition += 5
End If
If oArea = "AMOUNT" Then
If oItemSPECNAME = "INVOICE_TOTAL_NET" Or oItemSPECNAME = "INVOICE_TOTAL_GROSS" Then
oItemValue += $" {oCurrencySymbol}"
End If
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
If oItemValue.Length > 112 Then
' Liste zur Speicherung der Teilstrings
Dim teilStrings As New List(Of String)
' Schleife, um den String in Teilstrings zu zerlegen
For i As Integer = 0 To oItemValue.Length - 1 Step 112
' Sicherstellen, dass wir nicht über die Länge des Strings hinausgehen
Dim laenge As Integer = Math.Min(112, oItemValue.Length - i)
Dim teilString As String = oItemValue.Substring(i, laenge)
teilStrings.Add(teilString)
Next
' Ausgabe der Teilstrings
For Each teilString As String In teilStrings
gdpicturePDF.DrawText(fontResName, 10, yPosition, teilString)
yPosition += 5
Next
Else
gdpicturePDF.DrawText(fontResName, 10, yPosition, oItemValue)
End If
End If
End If
End If
oIndex += 1
Next
Dim oCreated = Now.ToString
gdpicturePDF.DrawLine(10, 280, 200, 280)
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