Implemented attaching XRechnung to Factur-X PDF

This commit is contained in:
dankito 2024-11-26 15:57:14 +01:00
parent ef42ddee37
commit 6ec302e50f
5 changed files with 63 additions and 10 deletions

View File

@ -88,7 +88,7 @@ val creator = EInvoiceCreator()
creator.attachInvoiceXmlToPdf(invoice, existingPdf, output)
// or if you already have the invoice XML:
val invoiceXml: String = "..." // e.g. creator.createZugferdXml(invoice)
val invoiceXml = creator.createXRechnungXml(invoice) // or creator.createZugferdXml(invoice), ...
creator.attachInvoiceXmlToPdf(invoiceXml, existingPdf, output)
creator.attachInvoiceXmlToPdf(invoiceXml, EInvoiceXmlFormat.XRechnung, existingPdf, output)
```

View File

@ -1,6 +1,7 @@
package net.codinux.invoicing.creation
import net.codinux.invoicing.mapper.MustangMapper
import net.codinux.invoicing.model.EInvoiceXmlFormat
import net.codinux.invoicing.model.Invoice
import org.mustangproject.ZUGFeRD.*
import java.io.File
@ -36,14 +37,30 @@ open class EInvoiceCreator(
open fun createFacturXPdf(invoice: Invoice, outputFile: File) {
val xml = createFacturXXml(invoice)
createFacturXPdf(xml, EInvoiceXmlFormat.FacturX, outputFile)
}
/**
* Synonym for [createFacturXPdfWithXRechnungXML] (ZUGFeRD 2 is a synonym for Factur-X).
*/
open fun createZugferdPdfWithXRechnungXML(invoice: Invoice, outputFile: File) = createFacturXPdfWithXRechnungXML(invoice, outputFile)
open fun createFacturXPdfWithXRechnungXML(invoice: Invoice, outputFile: File) {
val xml = createXRechnungXml(invoice)
createFacturXPdf(xml, EInvoiceXmlFormat.XRechnung, outputFile)
}
protected open fun createFacturXPdf(invoiceXml: String, format: EInvoiceXmlFormat, outputFile: File) {
val xmlFile = File.createTempFile(outputFile.nameWithoutExtension, ".xml")
.also { it.writeText(xml) }
.also { it.writeText(invoiceXml) }
val pdfFile = File(xmlFile.parentFile, xmlFile.nameWithoutExtension + ".pdf")
val visualizer = ZUGFeRDVisualizer()
visualizer.toPDF(xmlFile.absolutePath, pdfFile.absolutePath)
attachInvoiceXmlToPdf(xml, pdfFile, outputFile)
attachInvoiceXmlToPdf(invoiceXml, format, pdfFile, outputFile)
xmlFile.delete()
pdfFile.delete()
@ -51,13 +68,13 @@ open class EInvoiceCreator(
open fun attachInvoiceXmlToPdf(invoice: Invoice, pdfFile: File, outputFile: File) =
attachInvoiceXmlToPdf(createFacturXXml(invoice), pdfFile, outputFile)
attachInvoiceXmlToPdf(createFacturXXml(invoice), EInvoiceXmlFormat.FacturX, pdfFile, outputFile)
open fun attachInvoiceXmlToPdf(invoiceXml: String, pdfFile: File, outputFile: File) {
open fun attachInvoiceXmlToPdf(invoiceXml: String, format: EInvoiceXmlFormat, pdfFile: File, outputFile: File) {
val exporter = ZUGFeRDExporterFromA3()
.setZUGFeRDVersion(2)
.setProfile("EN16931") // available values: MINIMUM, BASICWL, BASIC, CIUS, EN16931, EXTENDED, XRECHNUNG
// .disableFacturX()
.setProfile(getProfileNameForFormat(format))
.disableFacturX()
.setProducer("danki die geile Sau")
.setCreator(System.getProperty("user.name"))
@ -78,4 +95,16 @@ open class EInvoiceCreator(
return String(provider.xml, Charsets.UTF_8)
}
protected open fun getProfileNameForFormat(format: EInvoiceXmlFormat) = when (format) {
EInvoiceXmlFormat.FacturX -> "EN16931" // available values: MINIMUM, BASICWL, BASIC, CIUS, EN16931, EXTENDED, XRECHNUNG
EInvoiceXmlFormat.XRechnung -> "XRECHNUNG"
}
protected open fun getFilenameForFormat(format: EInvoiceXmlFormat) = when (format) {
EInvoiceXmlFormat.FacturX -> "factur-x.xml"
EInvoiceXmlFormat.XRechnung -> "xrechnung.xml"
// other available values: "zugferd-invoice.xml" (ZF v2), "ZUGFeRD-invoice.xml" (ZF v1) ("order-x.xml", "cida.xml")
}
}

View File

@ -0,0 +1,10 @@
package net.codinux.invoicing.model
enum class EInvoiceXmlFormat {
/**
* Factur-X is equal / synonym to ZUGFeRD 2
*/
FacturX,
XRechnung
}

View File

@ -3,6 +3,7 @@ package net.codinux.invoicing
import net.codinux.invoicing.creation.EInvoiceCreator
import net.codinux.invoicing.email.model.EmailAccount
import net.codinux.invoicing.email.EmailsFetcher
import net.codinux.invoicing.model.EInvoiceXmlFormat
import net.codinux.invoicing.model.Invoice
import net.codinux.invoicing.model.InvoiceItem
import net.codinux.invoicing.model.Party
@ -76,9 +77,9 @@ class Demonstration {
creator.attachInvoiceXmlToPdf(invoice, existingPdf, output)
// or if you already have the invoice XML:
val invoiceXml: String = "..." // e.g. creator.createZugferdXml(invoice)
val invoiceXml = creator.createXRechnungXml(invoice) // or creator.createZugferdXml(invoice), ...
creator.attachInvoiceXmlToPdf(invoiceXml, existingPdf, output)
creator.attachInvoiceXmlToPdf(invoiceXml, EInvoiceXmlFormat.XRechnung, existingPdf, output)
}

View File

@ -42,6 +42,19 @@ class EInvoiceCreatorTest {
assertInvoiceXml(xml)
}
@Test
fun createFacturXPdfWithXRechnungXML() {
val invoice = createInvoice()
val testFile = File.createTempFile("Zugferd", ".pdf")
underTest.createFacturXPdfWithXRechnungXML(invoice, testFile)
val importer = testFile.inputStream().use { ZUGFeRDInvoiceImporter(it) }
val xml = String(importer.rawXML, Charsets.UTF_8)
assertInvoiceXml(xml)
}
private fun createInvoice() = DataGenerator.createInvoice()