Compare commits

...

3 Commits

Author SHA1 Message Date
7951902b4a merge 2026-04-27 17:11:31 +02:00
c88b8435c8 itext 7 2026-04-27 17:10:01 +02:00
9b4f3fe866 Update von itext7 von Vers 7 auf 9. etc. 2026-04-27 17:09:49 +02:00
11 changed files with 9495 additions and 1806 deletions

View File

@@ -173,6 +173,18 @@
<assemblyIdentity name="System.Threading.Tasks.Extensions" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.2.0.1" newVersion="4.2.0.1" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.1.2" newVersion="4.0.1.2" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Numerics.Vectors" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.4.0" newVersion="4.1.4.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<applicationSettings>

View File

@@ -2860,7 +2860,7 @@ Public Class cFakturierung
If enableZugpferd Then
'tmpPath = VERAG_PROG_ALLGEMEIN.DATENVERVER_OPTIONS.addAttachementToPDF(tmpPath, createZUGFeRD(True, RECHNUNG,), "ZUGFeRD-invoice.xml")
Dim pdfA = VERAG_PROG_ALLGEMEIN.DATENVERVER_OPTIONS.ConvertToPdfA3(tmpPath)
tmpPath = VERAG_PROG_ALLGEMEIN.DATENVERVER_OPTIONS.AddZugferdXml(tmpPath, createZUGFeRD(True, RECHNUNG,))
tmpPath = VERAG_PROG_ALLGEMEIN.DATENVERVER_OPTIONS.addZugferdXML(pdfA, createZUGFeRD(True, RECHNUNG,))
Else
Dim Zugferdpath = createZUGFeRD(True, RECHNUNG)

View File

@@ -53,6 +53,8 @@ Public Class frmAbrechnungsMaske
FirmaTmp = "VERAGIMEX"
End If
FirmaTmp = "AMBAR"
cboSachbearbeiter.Items.Clear()
Select Case FirmaTmp
@@ -223,9 +225,13 @@ Public Class frmAbrechnungsMaske
.Columns("Firma_ID").Visible = False
.Columns("RechnungsLandKz").Visible = False
.Columns("RechnungsKundenNr").Visible = False
.Columns("BelegartenKz").Visible = False
.Columns("PosNr").HeaderText = "Pos-Nr."
If .Columns.Contains("BelegartenKz") Then
.Columns("BelegartenKz").Visible = False
End If
If .Columns.Contains("ReNr") Then
.Columns("ReNr").HeaderText = "ReNr."
End If

5903
SDL/SDL.vbproj Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -112,6 +112,35 @@ Public Class frmKundenUebersichtZollRgDetails
cFakturierung.doRechnungsDruck_SRorER(RK_ID,, False, 3,,,,, sammelrechnungskopie)
End Sub
Public Shared Function ConvertToPdfA3_WithMustang(inputPdf As String) As String
Dim outputPdf As String = inputPdf & ".a3.pdf"
Dim mustangJar As String = "C:\Users\d.breimaier\Downloads\Mustang-CLI-2.21.0.jar" ' Pfad anpassen!
Dim psi As New ProcessStartInfo()
psi.FileName = "C:\Program Files\Eclipse Adoptium\jre-11.0.28.6-hotspot\bin\java.exe"
psi.Arguments = $"-Xmx1G -Dfile.encoding=UTF-8 -jar ""{mustangJar}"" --action a3only --source ""{inputPdf}"" --out ""{outputPdf}"""
psi.UseShellExecute = False
psi.RedirectStandardOutput = True
psi.RedirectStandardError = True
psi.CreateNoWindow = True
Using proc As Process = Process.Start(psi)
Dim stdout As String = proc.StandardOutput.ReadToEnd()
Dim stderr As String = proc.StandardError.ReadToEnd()
proc.WaitForExit()
If proc.ExitCode <> 0 Then
Throw New Exception("Mustang Fehler: " & stderr)
End If
End Using
Return outputPdf
End Function
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim Path_temp As String = ""
@@ -121,6 +150,7 @@ Public Class frmKundenUebersichtZollRgDetails
If Path_temp <> "" Then
Try
'ConvertToPdfA3_WithMustang(Path_temp)
Dim psi As New ProcessStartInfo()
@@ -141,9 +171,9 @@ Public Class frmKundenUebersichtZollRgDetails
Console.WriteLine(output)
Console.WriteLine(err)
If err <> "" Then
If output <> "" Then
Dim tmpPath_Report = VERAG_PROG_ALLGEMEIN.DATENVERVER_OPTIONS.getTMPPath("MUSTANG-REPORT", ".pdf", , False)
CreateValidationPdf(err, Path_temp, RK_ID, tmpPath_Report)
CreateValidationPdf(output, Path_temp, RK_ID, tmpPath_Report)
If tmpPath_Report <> "" Then Process.Start(tmpPath_Report)
End If
@@ -157,28 +187,94 @@ Public Class frmKundenUebersichtZollRgDetails
End Sub
Private Function ExtractMustangResult(log As String, Invoice_file As String, RK_ID As Integer) As String
Private Function ExtractMustangResult(xmlLog As String, invoiceFile As String, RK_ID As Integer) As String
Dim pdfStatus = If(log.Contains("Parsed PDF:invalid"), "INVALID", "VALID")
Dim xmlStatus = If(log.Contains("XML:valid"), "VALID", "INVALID")
Dim FileInfo As New FileInfo(Invoice_file)
Dim Invoice As New cRechnungsausgang(RK_ID)
Dim doc As New Xml.XmlDocument()
doc.LoadXml(xmlLog)
Dim profile As String = "EN16931"
If log.Contains("EN16931") Then profile = "EN16931"
Dim fileInfo As New FileInfo(invoiceFile)
Dim invoice As New cRechnungsausgang(RK_ID)
Dim took As String = ""
Dim m = System.Text.RegularExpressions.Regex.Match(log, "Took:(\d+)ms")
If m.Success Then took = m.Groups(1).Value & " ms"
' --- PDF Status ---
Dim pdfNode = doc.SelectSingleNode("//pdf/summary")
Dim pdfStatus As String = If(pdfNode?.Attributes("status")?.Value = "valid", "VALID", "INVALID")
Return $"ZUGFeRD VALIDATION RESULT" & vbCrLf &
$"--------------------------------" & vbCrLf &
$"PDF File : {FileInfo.Name}" & vbCrLf &
$"Invoice No : {Invoice.RechnungsNr}" & vbCrLf &
$"PDF Status : {pdfStatus}" & vbCrLf &
$"XML Status : {xmlStatus}" & vbCrLf &
$"Profile : {profile}" & vbCrLf &
$"Duration : {took}"
' --- XML Status ---
Dim xmlNode = doc.SelectSingleNode("//xml/summary")
Dim xmlStatus As String = If(xmlNode?.Attributes("status")?.Value = "valid", "VALID", "INVALID")
' --- Profile ---
Dim profileNode = doc.SelectSingleNode("//xml/info/profile")
Dim profile As String = If(profileNode IsNot Nothing, profileNode.InnerText, "UNKNOWN")
' --- XML Version ---
Dim xmlVersionNode = doc.SelectSingleNode("//xml/info/version")
Dim xmlVersion As String = If(xmlVersionNode IsNot Nothing, xmlVersionNode.InnerText, "-")
' --- Validator Version ---
Dim validatorNode = doc.SelectSingleNode("//xml/info/validator")
Dim validatorVersion As String = validatorNode?.Attributes("version")?.Value
' --- Duration ---
Dim pdfDuration = doc.SelectSingleNode("//pdf/info/duration")?.InnerText
Dim xmlDuration = doc.SelectSingleNode("//xml/info/duration")?.InnerText
Dim duration As String = ""
If pdfDuration IsNot Nothing AndAlso xmlDuration IsNot Nothing Then
duration = $"{pdfDuration} ms (PDF) / {xmlDuration} ms (XML)"
End If
' --- Tests ---
Dim firedNode = doc.SelectSingleNode("//xml/info/rules/fired")
Dim failedNode = doc.SelectSingleNode("//xml/info/rules/failed")
Dim fired As Integer = If(firedNode IsNot Nothing, Integer.Parse(firedNode.InnerText), 0)
Dim failed As Integer = If(failedNode IsNot Nothing, Integer.Parse(failedNode.InnerText), 0)
Dim passed As Integer = fired - failed
' --- PDF Errors ---
Dim failedAssertions = doc.SelectNodes("//pdf//TestAssertion[@status='failed']")
Dim errorCount As Integer = If(failedAssertions IsNot Nothing, failedAssertions.Count, 0)
' --- Top Errors ---
Dim errorDetails As New List(Of String)
If failedAssertions IsNot Nothing Then
For i = 0 To Math.Min(2, failedAssertions.Count - 1)
Dim msg = failedAssertions(i).Attributes("message")?.Value
If msg IsNot Nothing Then errorDetails.Add("- " & msg)
Next
End If
' --- Output ---
Dim result As New Text.StringBuilder()
result.AppendLine("ZUGFeRD VALIDATION RESULT")
result.AppendLine("================================")
result.AppendLine($"PDF File : {fileInfo.Name}")
result.AppendLine($"Invoice No : {invoice.RechnungsNr}")
result.AppendLine("--------------------------------")
result.AppendLine($"PDF Status : {pdfStatus}")
result.AppendLine($"XML Status : {xmlStatus}")
result.AppendLine($"Profile : {profile}")
result.AppendLine($"XML Version : {xmlVersion}")
result.AppendLine($"Validator : {validatorVersion}")
result.AppendLine("--------------------------------")
result.AppendLine($"Tests Passed : {passed} / {fired}")
result.AppendLine($"XML Failed : {failed}")
result.AppendLine($"PDF Errors : {errorCount}")
result.AppendLine($"Duration : {duration}")
If errorDetails.Count > 0 Then
result.AppendLine("--------------------------------")
result.AppendLine("Top Errors:")
For Each err_ In errorDetails
result.AppendLine(err_)
Next
End If
result.AppendLine("================================")
Return result.ToString()
End Function

View File

@@ -18,7 +18,9 @@
<package id="fiskaltrust.Middleware.Interface.Client.Soap" version="1.3.45" targetFramework="net48" />
<package id="Hardcodet.NotifyIcon.Wpf" version="1.0.5" targetFramework="net40-Client" requireReinstallation="True" />
<package id="IKVM" version="8.0.5449.1" targetFramework="net47" />
<package id="itext7" version="7.1.11" targetFramework="net48" />
<package id="itext" version="9.6.0" targetFramework="net48" />
<package id="itext.commons" version="9.6.0" targetFramework="net48" />
<package id="itext7" version="9.6.0" targetFramework="net48" />
<package id="LiveCharts" version="0.6.7.0" targetFramework="net40-Client" requireReinstallation="True" />
<package id="MESCIUS.ActiveReports" version="18.2.2" targetFramework="net48" />
<package id="MESCIUS.ActiveReports.Chart" version="18.0.4" targetFramework="net48" />
@@ -59,21 +61,35 @@
<package id="MESCIUS.Data.VBFunctionLib" version="4.0.3" targetFramework="net48" />
<package id="Microsoft.Bcl.AsyncInterfaces" version="6.0.0" targetFramework="net48" />
<package id="Microsoft.CSharp" version="4.7.0" targetFramework="net47" />
<package id="Microsoft.Extensions.DependencyInjection" version="5.0.0" targetFramework="net48" />
<package id="Microsoft.Extensions.DependencyInjection.Abstractions" version="5.0.0" targetFramework="net48" />
<package id="Microsoft.Extensions.Logging" version="5.0.0" targetFramework="net48" />
<package id="Microsoft.Extensions.Logging.Abstractions" version="5.0.0" targetFramework="net48" />
<package id="Microsoft.Extensions.Options" version="5.0.0" targetFramework="net48" />
<package id="Microsoft.Extensions.Primitives" version="5.0.0" targetFramework="net48" />
<package id="Newtonsoft.Json" version="13.0.4" targetFramework="net48" />
<package id="Portable.BouncyCastle" version="1.8.5" targetFramework="net48" />
<package id="System.Buffers" version="4.5.1" targetFramework="net48" />
<package id="System.Diagnostics.DiagnosticSource" version="5.0.0" targetFramework="net48" />
<package id="System.Interactive.Async" version="4.0.0" targetFramework="net48" />
<package id="System.IO" version="4.3.0" targetFramework="net48" />
<package id="System.IO.FileSystem.Primitives" version="4.3.0" targetFramework="net48" />
<package id="System.IO.Packaging" version="4.5.0" targetFramework="net48" />
<package id="System.Linq.Async" version="4.0.0" targetFramework="net48" />
<package id="System.Memory" version="4.5.5" targetFramework="net48" />
<package id="System.Net.Http" version="4.3.4" targetFramework="net48" />
<package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net48" />
<package id="System.Runtime" version="4.3.0" targetFramework="net48" />
<package id="System.Runtime.CompilerServices.Unsafe" version="6.1.2" targetFramework="net48" />
<package id="System.Security.AccessControl" version="6.0.1" targetFramework="net48" />
<package id="System.Security.Cryptography.Algorithms" version="4.3.0" targetFramework="net48" />
<package id="System.Security.Cryptography.Encoding" version="4.3.0" targetFramework="net48" />
<package id="System.Security.Cryptography.Primitives" version="4.3.0" targetFramework="net48" />
<package id="System.Security.Cryptography.X509Certificates" version="4.3.0" targetFramework="net48" />
<package id="System.Security.Cryptography.Xml" version="6.0.2" targetFramework="net48" />
<package id="System.Security.Principal.Windows" version="5.0.0" targetFramework="net48" />
<package id="System.Threading.Tasks.Extensions" version="4.5.4" targetFramework="net48" />
<package id="System.ValueTuple" version="4.5.0" targetFramework="net48" />
<package id="TAlex.WPF.Controls" version="2.0.1.0" targetFramework="net40-Client" />
<package id="WpfAnimatedGif" version="1.4.14" targetFramework="net45" />
<package id="ZUGFeRD.NET" version="1.0.1" targetFramework="net48" />

View File

@@ -6,10 +6,20 @@ Imports System.Net
Imports System.Text
Imports System.Text.RegularExpressions
Imports System.Windows.Forms
Imports DocumentFormat.OpenXml
Imports iText.Kernel.Pdf
Imports iText.Kernel.Pdf.Filespec
Imports iText.Kernel.XMP
Imports iText.Kernel.XMP.Options
Imports iText.Pdfa
Imports iText.Pdfa.Exceptions
Imports iTextSharp.text.pdf
Imports Spire.Pdf
Imports Spire.Pdf.Attachments
Imports Spire.Pdf.Graphics
Imports Spire.Pdf.Print
Imports PdfName = iTextSharp.text.pdf.PdfName
Public Class cDATENSERVER
@@ -2438,109 +2448,109 @@ Public Class DATENVERVER_OPTIONS
End Function
Public Shared Function addZugferdXML(File As String, attPath As String) As String
Dim tempFile As String = File & ".tmp"
Using reader As New PdfReader(File)
Using fs As New FileStream(tempFile, FileMode.Create)
Using stamper As New PdfStamper(reader, fs)
Dim xmlBytes = System.IO.File.ReadAllBytes(attPath)
Dim fileName As String = "factur-x.xml"
Dim fspec = PdfFileSpecification.FileEmbedded(
stamper.Writer,
fileName,
fileName,
xmlBytes,
"application/xml",
Nothing,
0
)
fspec.Put(PdfName.AFRELATIONSHIP, New PdfName("Alternative"))
stamper.Writer.AddFileAttachment("ZUGFeRD", fspec)
Dim af As New PdfArray()
af.Add(fspec.Reference)
stamper.Writer.ExtraCatalog.Put(PdfName.AFRELATIONSHIP, af)
Public Shared Function addZugferdXML(pdfPath As String, xmlPath As String) As String
SetZugferdXmp(stamper, fileName)
Dim tempFile As String = pdfPath & ".tmp"
Using pdf As New iText.Kernel.Pdf.PdfDocument(New iText.Kernel.Pdf.PdfReader(pdfPath), New iText.Kernel.Pdf.PdfWriter(tempFile))
Dim xmlBytes = File.ReadAllBytes(xmlPath)
Dim fileName As String = "factur-x.xml"
Dim fs = PdfFileSpec.CreateEmbeddedFileSpec(
pdf,
xmlBytes,
"ZUGFeRD XML",
fileName,
New iText.Kernel.Pdf.PdfName("text/xml"),
Nothing,
New iText.Kernel.Pdf.PdfName("Alternative")
)
pdf.AddFileAttachment("ZUGFeRD", fs)
' ✔ AF-Eintrag (PFLICHT!)
Dim afArray As New iText.Kernel.Pdf.PdfArray()
afArray.Add(fs.GetPdfObject())
pdf.GetCatalog().Put(New iText.Kernel.Pdf.PdfName("AF"), afArray)
' ✔ XMP setzen
SetZugferdXmp_NEW(pdf, fileName)
End Using
End Using
End Using
System.IO.File.Delete(File)
System.IO.File.Move(tempFile, File)
System.IO.File.Delete(pdfPath)
System.IO.File.Move(tempFile, pdfPath)
Return pdfPath
Return File
End Function
Public Shared Function ConvertToPdfA3(inputPdf As String) As String
Dim tempFile As String = inputPdf & ".tmp"
Dim outputPdf As String = inputPdf & ".pdfa.pdf"
Dim reader As New PdfReader(inputPdf)
Dim iccBytes As Byte() = My.Resources.sRGB2014
Dim iccStream As New MemoryStream(iccBytes)
Using fs As New FileStream(tempFile, FileMode.Create, FileAccess.Write)
Using stamper As New PdfStamper(reader, fs)
' ✔ DAS ist in iTextSharp 5 der einzig relevante PDF/A-Baustein
Dim iccPath As String =
"C:\Windows\System32\spool\drivers\color\sRGB Color Space Profile.icm"
Dim icc = ICC_Profile.GetInstance(File.ReadAllBytes(iccPath))
stamper.Writer.SetOutputIntents(
Using writer As New iText.Kernel.Pdf.PdfWriter(outputPdf)
Using pdf As New PdfADocument(
writer,
PdfAConformance.PDF_A_3B,
New PdfOutputIntent(
"Custom",
"",
"http://www.color.org",
"sRGB IEC61966-2.1",
icc
iccStream
)
)
stamper.Writer.PDFXConformance = PdfWriter.PDFX32002
Dim reader As New iText.Kernel.Pdf.PdfReader(inputPdf)
Dim srcDoc As New iText.Kernel.Pdf.PdfDocument(reader)
srcDoc.CopyPagesTo(1, srcDoc.GetNumberOfPages(), pdf)
srcDoc.Close()
End Using
End Using
reader.Close()
If File.Exists(inputPdf) Then File.Delete(inputPdf)
File.Move(tempFile, inputPdf)
Return inputPdf
Return outputPdf
End Function
Private Shared Sub SetZugferdXmp(stamper As PdfStamper, xmlFileName As String)
Dim xmp As String =
"<?xpacket begin="""" id=""W5M0MpCehiHzreSzNTczkc9d""?>" &
"<x:xmpmeta xmlns:x=""adobe:ns:meta/"">" &
"<rdf:RDF xmlns:rdf=""http://www.w3.org/1999/02/22-rdf-syntax-ns#"" " &
"xmlns:pdfaid=""http://www.aiim.org/pdfa/ns/id/"" " &
"xmlns:zf=""urn:factur-x:pdfa:CrossIndustryDocument:invoice:2#"" >" &
"<rdf:Description rdf:about="""">" &
"<pdfaid:part>3</pdfaid:part>" &
"<pdfaid:conformance>B</pdfaid:conformance>" &
"<zf:DocumentType>INVOICE</zf:DocumentType>" &
"<zf:DocumentFileName>" & xmlFileName & "</zf:DocumentFileName>" &
"<zf:Version>2.1</zf:Version>" &
"<zf:ConformanceLevel>EN 16931</zf:ConformanceLevel>" &
"</rdf:Description>" &
"</rdf:RDF>" &
"</x:xmpmeta>" &
"<?xpacket end=""w""?>"
Private Shared Sub SetZugferdXmp_NEW(pdf As iText.Kernel.Pdf.PdfDocument, xmlFileName As String)
stamper.XmpMetadata = Encoding.UTF8.GetBytes(xmp)
Dim xmp As XMPMeta = XMPMetaFactory.Create()
' =========================
' PDF/A
' =========================
Dim pdfaNs As String = "http://www.aiim.org/pdfa/ns/id/"
xmp.SetProperty(pdfaNs, "part", "3")
xmp.SetProperty(pdfaNs, "conformance", "B")
' =========================
' Factur-X Namespace
' =========================
Dim fxNs As String = "urn:factur-x:pdfa:CrossIndustryDocument:invoice:1p0#"
XMPMetaFactory.GetSchemaRegistry().RegisterNamespace(fxNs, "fx")
xmp.SetProperty(fxNs, "DocumentType", "INVOICE")
xmp.SetProperty(fxNs, "DocumentFileName", xmlFileName)
xmp.SetProperty(fxNs, "Version", "1.0")
xmp.SetProperty(fxNs, "ConformanceLevel", "EN 16931")
' =========================
' WICHTIG: KEIN XML-MANIPULATION
' =========================
pdf.SetXmpMetadata(xmp)
End Sub

View File

@@ -530,6 +530,16 @@ Namespace My.Resources
End Get
End Property
'''<summary>
''' Sucht eine lokalisierte Ressource vom Typ System.Byte[].
'''</summary>
Friend ReadOnly Property sRGB2014() As Byte()
Get
Dim obj As Object = ResourceManager.GetObject("sRGB2014", resourceCulture)
Return CType(obj,Byte())
End Get
End Property
'''<summary>
''' Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
'''</summary>

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff