Seite 1 von 2

Realisierung ZUGFeRD bzw. XRechnung (EN 16931) - PDFs

Verfasst: Mi, 22. Jun 2022 11:56
von Merlin
Hallo,

das ist mein erster Beitrag hier im Forum.

Ich programmierte früher mit Clipper und XHarbour und habe vor ca. einem Jahr eine xbase++ Applikation(ERP System) zur Softwarepflege übernommen, da der Entwickler leider verstorben ist.

Die Anwendung wurde vor x Jahren von Clipper nach xbase++ 1.9 portiert und damit auch weiterentwickelt.
Die Anwendung Ist noch MSDOS-Optik, aber mit Windows-Messageboxen, Druckpreview etc.
Läuft alles sehr stabil da der ADS-Server als Backend dient.

- Compiler ist xbase++ 1.90.355
- DBF/CDX Tabellen (keine ADT)
- Advantage Database Server als Backend
- Ausdrucke über die Top-Down Library Version 6.1 von Clayton Jones(leider verstorben)
- Anzahl gleichzeitig arbeitende User ca. 30

Das ERP läuft soweit sehr stabil, und ist sehr performant.
Ausdrucke über normale Windows-Drucker und auch auch PDF-Drucker im Netzwerk.

Habe in den letzten Tagen hier im Forum gestöbert und hoffe ihr könnt mir bei meinem Problem helfen und/oder habt Erfahrungen/Ideen diesbezüglich.

Zu meinen Fragen:

Es kommen nun einzelne Anforderung bzgl. ZUGFeRD bzw. XRechnung (EN 16931).
Der Rechungs-Empfänger möchte also eine PDF/A mit eingebetteter .xml Datei.

Die .XML Datei zu erzeugen bekomme ich bestimmt hin, denke dies ist viel Fleißarbeit und mit einem guten Validater im Internet machbar.
(habt ihr da Vorlagen, Internetlinks?, Validatoren?)

Aber die .xml dann in die .PDF einbetten macht mir Probleme.
Da ich ja keine eigene .PDF drucke, sondern über die Top-Down Library das Dokument aufbaue und an den gewählten Windows-Drucker schicke:
Der User wählt den Windows PDF-Drucker, sieht vorab noch ein PreView, druckt und hat dann eine PDF vorliegen..
oder
Der User wählt einen phys. Windows-Drucker, sieht vorab noch ein PreView, druckt und hat dann Papier vorliegen.


a.)
Habe hier im Form gelesen dass z.B. Hubert Brandel eine HBPrintPDF bereitstellt.
(http://www.familie-brandel.de/dateien/dat_index_d.html)

Diese benötigt noch einen LizenzKey von QuickPDF.com
(dies ist nun wohl Foxit? https://developers.foxit.com/ - kennt jemand die ungefähren Preise? auf der HP finde ich leider nichts)

und

- dass es eine OT4XB.dll über xbwin.com gibt (https://blog.xbwin.com)
- dass es eine XbpGraPDF / XbpPDF von Borger gibt.

Diese helfen wohl bei Generierung von PDFs inkl. Einbetten der .XML-Datei ?
Mit welchen obigen Erweiterungen arbeitet ihr?

b.)
Würde dies dann bedeuten dass ich alle Ausdrucke umstellen müsste auf nur noch "PDF-Erzeugung" ?
Das möchte ich mir eigentlich nicht antun, zumal in diesem ERP eine ganze Menge Ausdrucke anzupassen wären.
Auch ist dies seitens des Kunden bestimmt nicht erwünscht.

c.)
mMn würde es reichen wenn ich einen PDF-Netzwerkdrucker installieren könnte dem ich die .xml.Datei zur Einbettung gleich mitgeben könnte.
Kennt jemand so einen PDF-Drucker bei dem dies möglich ist?

d.)
Könnte vlt. auch alles so belassen wie es ist und nur bei manchen Rechnungen einen eigenen Worflow entwickeln der über die obigen Klassen (a) ein PDF mit eingebetteter .xml erzeugt.
Damit hätte ich aber unterschiedliche Workflows beim Rechnungsdruck. :|
Denn woher soll der User wissen dass die Rechnung die er gerade neu erstellt vom Empfänger als PDF/A mit eingebetteter .xlm gefordert wird, um dann den anderen Workflow auszuführen.

e.)
Alternativ schwebt mir noch die Lösung eines externen Programms vor.
Dies wird vom User gestartet, die Rechnungsdaten irgendwie importiert und das PDF/A erzeugt.
Dann würde doch aber das Layout des generierten PDFs anders aussehen als vom eigentlichen ERP-System gedruckt?
z.B. vielleicht sowas:
https://soft-xpansion.de/dev-tools/elek ... -rechnung/

f.)
Ulimative Lösung wäre natürlich wenn ab Stichtag X alle Rechnungen immer mit eingebetteter .xml wären, egal ob der Empfänger dies fordert. Nur wie bekomme ich das hin?

Ich hoffe ich habe mich einigermaßen verständlich ausgedrückt.
Irgendwie kommt es mir vor als sehe den Wald vor lauter Bäumen nicht #-o


Wie würdet ihr hier vorgehen?
Welchen Lösungsansatz würdet ihr vorschlagen?

Ich sage schonmal vorab vielen Dank fürs Lesen und hoffe auf eure Erfahrung und Unterstützung.

Grüße
Merlin

Re: Realisierung ZUGFeRD bzw. XRechnung (EN 16931) - PDFs

Verfasst: Mi, 22. Jun 2022 12:02
von Tom
Hallo, Merlin.
Die .XML Datei zu erzeugen bekomme ich bestimmt hin, denke dies ist viel Fleißarbeit und mit einem guten Validater im Internet machbar.
(habt ihr da Vorlagen, Internetlinks?, Validatoren?)
Im Umgang mit XML sind die Online-Tools der (genialen!) Chilkat-Library oft hilfreich. Da kannst Du Dir auch VFP-Code erzeugen lassen, um XML zu erzeugen oder auszuwerten, und den kann man sehr leicht nach Xbase++ portieren:

https://tools.chilkat.io/

Re: Realisierung ZUGFeRD bzw. XRechnung (EN 16931) - PDFs

Verfasst: Mi, 22. Jun 2022 12:28
von Jan
Hallo Merlin,

ich habe vergangenes Jahr angefangen, ZUGFeRD umzusetzen. Konnte aber dann zum Glück die benötigte Logik anders umsetzen. Das ist nicht sonderlich trivial. Um nicht zu sagen extrem komplex.

Ich arbeite bei der PDF-Erzeugung mit der Klasse von Edgar. Die auch die Möglichkeit anbietet, XML oder andere Strings einzubetten. Und natürlich auch den PDF-Typen auf unveränderlich zu setzen, wie das bei ZUGFeRD natürlich gefordert ist.

Der betreffende Kunde besteht übrigens auch auf zeichenorintierter Oberfläche. Und hat auch den ADS am laufen, nachdem ich den dort eingführt hab. Allerdings konnte ich ihn überreden, auf Xbase++ 2.0 upzudaten. Was viele Sachen extrem einfacher macht. Könnte bei Dir allerdings schwierig werden wegen TopDown, ich habe keine Ahnung ob das unter 2.0 funktioniert.

Jan

Re: Realisierung ZUGFeRD bzw. XRechnung (EN 16931) - PDFs

Verfasst: Mi, 22. Jun 2022 14:13
von ramses
Jan hat geschrieben: Mi, 22. Jun 2022 12:28 Könnte bei Dir allerdings schwierig werden wegen TopDown, ich habe keine Ahnung ob das unter 2.0 funktioniert.
Das ist keine Problem.
TopDown ist inzwischen inkl. dem Form-Designer Open Source.
Das ganze kann einfach unter xbase 2.00 neu übersetzt werden.

Du musst mal nachschauen welche Variante des Ausdrucks du unter Top-Down verwendest.
Es gibt eine die auch PDF's erstellen und Dateien in PDF's einbetten kann.

Re: Realisierung ZUGFeRD bzw. XRechnung (EN 16931) - PDFs

Verfasst: Mi, 22. Jun 2022 14:35
von Wolfgang Ciriack
Als Prüftool bietet sich z. B. OpenXRechnungToolbox an. Kann man konfigurieren, für welche Version geprüft werden soll.

Re: Realisierung ZUGFeRD bzw. XRechnung (EN 16931) - PDFs

Verfasst: Mi, 22. Jun 2022 16:41
von Marcus Herz
Zugferd ist auch in dsListLabel als Beispiel mit Code enthalten, setzt aber List&Label als Druckengine voraus.

Re: Realisierung ZUGFeRD bzw. XRechnung (EN 16931) - PDFs

Verfasst: Do, 23. Jun 2022 16:22
von ssemleit
Auch wir mussten/müssen uns mit Zugferd und XRechnung rumplagen.
Erzeugen tun wir das PDF durch List&Label. In den aktuellen Versionen kann da sogar das Zugferd-XML mit einbetten lassen.
Da das "früher" nicht ging, haben unsere Kollegen der C++ Fraktion eine Funktion (ich glaube basierend auf LeadTools) erstellt,
der wir den Datenamen des PDFs und der XML-Datei übergeben und daraus eine neue PDF-Datei generiert.

Also ist unser Weg: PDF erstellen und nachträglich das XML-File über Tools als Attachement anhängen.

Anmerkungen:
- Abhängig von der Zugferd-Version muss der Dateiname im PDF-Anhang anders lauten.
- XRechnung ist zwar vom Format her ein Zugferd-Format, dabei darf aber kein PDF versendet werden, sondern nur das XML!
- Den Begriff Zugferd (Version 2) möchte man am liebsten nicht mehr hören, sondern "FacturX". Damit wird sein internationaler Aspekt betont.

Gruß
Stefan

Re: Realisierung ZUGFeRD bzw. XRechnung (EN 16931) - PDFs

Verfasst: Do, 23. Jun 2022 16:30
von Tom
Den Begriff Zugferd (Version 2) möchte man am liebsten nicht mehr hören, sondern "FacturX". Damit wird sein internationaler Aspekt betont.
Dieses Akronym "ZUGFeRD" gehört m.E. sowieso in die Top 10 der bescheuertsten Abkürzungen der letzten zehn Dekaden (zumal sie es nicht einmal geschafft haben, noch irgendwie ein "P" unterzubringen). Und der damit einhergehende Hang, für IT-Produkte und -Verfahren durch Abkürzungen Tiernamen zu erzeugen (ELSTER), ist noch dusseliger.

Re: Realisierung ZUGFeRD bzw. XRechnung (EN 16931) - PDFs

Verfasst: Di, 28. Jun 2022 22:13
von Merlin
Vielen lieben Dank für Eure Antworten. Diese haben mir sehr geholfen.

Werde nun die Anwendung erstmal so laufen lassen und den PdfMailer beim betreffenden Kunden einsetzen.
Mit diesem kann ich per Steuerzeichen im Druckjob selbst alles mögliche bestimmen, Speichern unter, per Email versenden, Workflows etc.. und auch die Generierung von ZUGFeRD und XRechnungen.
(meiner Recherche nach der einzige PDF-Drucker den man über Steuerzeichen im DruckJob selbst ansteuern kann)

Im nächsten Schritt habe ich vor die ZUGFeRD .xml selbst zu erzeugen und per XbpPDF und auch XbpGraPDF (Foxit kommt bzgl. Kosten des Key für die QuickPdf leider nicht in die Puschen) die Rechnung/Storno-Rechnung zu erzeugen und die generierte .xlm anzuhängen.

Ich habe mich noch nicht abschliessend entschieden, aber ZUGFeRD erscheint mir sinnvoller, da auch noch von "Menschen lesebar"
@ssemleit, vielen Dank für den Tip bzgl. den Unterschieden der Generierung/Übertragung an dem Empfänger !

hätte da noch eine abschliessende Frage:
Habe heute die ersten Tests .pdfs mit XbpPDF bzw. XpbGraPDF erstellt.

...kann ich bei diesen Tools auch ein Firmen-Briefpapier hinterlegen? (am besten als .pdf)
Finde da leider nichts konkretes dazu #-o

Viele Grüße
Merlin

Re: Realisierung ZUGFeRD bzw. XRechnung (EN 16931) - PDFs

Verfasst: Mi, 29. Jun 2022 7:18
von Koverhage
Merlin,
ja z.B. so

Code: Alles auswählen

      nCurrentPage := oPdf:qCall( "SelectedPage", oPdf:oPdf )
      doc1 := oPdf:qCall( "SelectedDocument", oPdf:oPdf )
      oPdf:qCall("LoadFromFile",oPdf:oPdf, cSzAnsi2Wide(cAppData+"ok_neu.pdf") )
      doc2 := oPdf:qCall( "SelectedDocument", oPdf:oPdf )

      oPdf:qCall( "SelectDocument", oPdf:oPdf, doc1 )
      oPdf:qCall( "MergeDocument", oPdf:oPdf, doc2 )

      oPdf:qCall( "DeletePages", oPdf:oPdf, nCurrentPage, 1)
      oPdf:GotoPage( nCurrentPage )
Du kannst auf QuickPDF verzichten (wie vorstehendes Beispiel zeigt).
XbpPDF benutzt ja QuickPDF

Re: Realisierung ZUGFeRD bzw. XRechnung (EN 16931) - PDFs

Verfasst: Mi, 29. Jun 2022 8:05
von Koverhage
Alternativ kannst Du das auch mit pdftk lösen. Ist meistens einfacher und benötigt auch weniger Speicher.

Re: Realisierung ZUGFeRD bzw. XRechnung (EN 16931) - PDFs

Verfasst: Mi, 29. Jun 2022 8:15
von Martin Altmann
Moin,
ich mache das ein wenig anders - ich nehme eine PDF-Datei als Unterlage und drucke auf sie drauf (wie ein Blatt bedrucktes Papier, dass in den Drucker eingelegt wird):

Code: Alles auswählen

oPdf := XbpPDF():New()
oPdf:Create()

oPdf:VipOpen( cVorlage )
nqh := dllpreparecall( opdf:qDll, 8, "DPLPageHeight" )
nqw := dllpreparecall( opdf:qDll, 8, "DPLPageWidth" )
nh  := ndFpCall( nqh, opdf:oPdf )
nw  := ndFpCall( nqw, opdf:oPdf )
oPdf:Destroy()

oPdf := XbpPDF():New()
oPdf:Create()
oPdf:NewPage( XBPPRN_FORM_USER,,,,{nw, nh},GRA_PU_LOMETRIC, 0, 0 )
oPdf:VipInit( cVorlage )
oPdf:cName := cZielpfad + "Test.pdf"
cVorlage enthält Dateinamen und Pfad des Briefpapieres. Dieses wird erstmal geöffnet, um die Größe zu ermitteln. Danach wird eine neue PDF derselben Größe erzeugt und mit dem Briefpapier "unterlegt" - auf diesem wird dann positioniert und gedruckt.

Viele Grüße,
Martin

Re: Realisierung ZUGFeRD bzw. XRechnung (EN 16931) - PDFs

Verfasst: Mi, 29. Jun 2022 8:39
von ssemleit
Hallo Merlin,

Du schreibst:
Ich habe mich noch nicht abschliessend entschieden, aber ZUGFeRD erscheint mir sinnvoller, da auch noch von "Menschen lesebar"

Zwischen was möchtest Du Dich entscheiden? Zwischen Zugferd und XRechnung?
Das wird wohl nicht Deine Entscheidung werden. In der Regel gibt Dir der Rechnungsempfänger vor, welches Format notwendig ist.
XRechnung ist meist für öffentliche Auftraggeber wie Gemeinden, Kreise, Deutsche Bahn etc. notwendig.

Gruß
Stefan

Re: Realisierung ZUGFeRD bzw. XRechnung (EN 16931) - PDFs

Verfasst: Mi, 29. Jun 2022 15:20
von Merlin
Martin Altmann hat geschrieben: Mi, 29. Jun 2022 8:15 Moin,
ich mache das ein wenig anders - ich nehme eine PDF-Datei als Unterlage und drucke auf sie drauf (wie ein Blatt bedrucktes Papier, dass in den Drucker eingelegt wird):

Code: Alles auswählen

oPdf := XbpPDF():New()
oPdf:Create()

oPdf:VipOpen( cVorlage )
nqh := dllpreparecall( opdf:qDll, 8, "DPLPageHeight" )
nqw := dllpreparecall( opdf:qDll, 8, "DPLPageWidth" )
nh  := ndFpCall( nqh, opdf:oPdf )
nw  := ndFpCall( nqw, opdf:oPdf )
oPdf:Destroy()

oPdf := XbpPDF():New()
oPdf:Create()
oPdf:NewPage( XBPPRN_FORM_USER,,,,{nw, nh},GRA_PU_LOMETRIC, 0, 0 )
oPdf:VipInit( cVorlage )
oPdf:cName := cZielpfad + "Test.pdf"
cVorlage enthält Dateinamen und Pfad des Briefpapieres. Dieses wird erstmal geöffnet, um die Größe zu ermitteln. Danach wird eine neue PDF derselben Größe erzeugt und mit dem Briefpapier "unterlegt" - auf diesem wird dann positioniert und gedruckt.

Viele Grüße,
Martin
das ist ein guter Gedanke. Habe aber leider die ndFpCall Funktion nicht ...bekomme da Compiler-Fehler.

Grüße
Merlin

Re: Realisierung ZUGFeRD bzw. XRechnung (EN 16931) - PDFs

Verfasst: Mi, 29. Jun 2022 15:34
von Merlin
Irgendwie stehe ich auf dem Schlauch.Kenne mich damit aber auch noch nicht so gut aus.
Deshalb meine Frage: Warum ruft ihr die Funktionen von XbpPdf mit qCall und einem String als Parameter auf?
Sind da weitere Funktionen die man über die Funktionsbeschreibung kennen sollte?
Die Syntax ist mir ein wenig fremd.
doc2 := oPdf:qCall( "SelectedDocument", oPdf:oPdf )
oPdf:qCall( "SelectDocument", oPdf:oPdf, doc1 )
oPdf:qCall( "MergeDocument", oPdf:oPdf, doc2 )

Ich habe nun mein Briefpapier hinterlegen können mit ClonePage()
Kommt wohl direkt nach oPdf:NewPage()
oPdf := xbpPdf():New()
oPdf:Create("Neue-Datei.pdf")

oPdf:NewPage(XBPPRN_FORM_A4, XBPPRN_ORIENT_PORTRAIT, 80, 105, , 0)
oPdf:ClonePage("Briefpapier.pdf")
oPdf:Font(DEF_PRFONT_10)
oPdf:LineWidth(0.75)

oPdf:Text(nZl, nSp, "Hello World")
Druckt ihr eure .PDFs auch Zeilen/Spaltenbasiert?
Ich habe ein wenig gebraucht bis ich das DINA4 mit den Anzahl Zeilen/Spalten wie in der "alten" Lösung hinbekommen habe.

Grüß
Merlin

Re: Realisierung ZUGFeRD bzw. XRechnung (EN 16931) - PDFs

Verfasst: Mi, 29. Jun 2022 17:14
von Jan
Merlin,

qCall() ist die interne Funktion von Edgar, mit der er die Foxit-Funktionen aufruft. Das macht er bei all denen Funktionen, die er in Xbase++ "übersetzt" hat. Aber man kann die halt auch selber nutzen für Foxit-Funktionen, die Edgar noch nicht umgesetzt hat. Allerdings halt nur bei einfachen Sachen, die mit einem einmaligen Aufruf erledigt sind. Manche Funktionen müssen sehr intensiv aufbereitet werden, damit man mit einem Funktionsaufruf in Xbase++ das in Foxit nutzen kann.

Jan

Re: Realisierung ZUGFeRD bzw. XRechnung (EN 16931) - PDFs

Verfasst: Mi, 29. Jun 2022 17:33
von Tom
qCall() ist die interne Funktion
Nö. Das ist ganz offensichtlich eine Methode. 8)

Re: Realisierung ZUGFeRD bzw. XRechnung (EN 16931) - PDFs

Verfasst: Mi, 29. Jun 2022 17:38
von Jan
Tom,

selbstverständlich hast Du damit recht.

Wobei das Wichtige daran ist das diese ansich von Edgar in seiner Klasse intern verwendete Methode als Exported deklariert ist, nicht als Protected wie vieles andere in der Klasse.

Jan

Re: Realisierung ZUGFeRD bzw. XRechnung (EN 16931) - PDFs

Verfasst: Mi, 29. Jun 2022 18:01
von Merlin
Jan hat geschrieben: Mi, 29. Jun 2022 17:14 Merlin,

qCall() ist die interne Funktion von Edgar, mit der er die Foxit-Funktionen aufruft. Das macht er bei all denen Funktionen, die er in Xbase++ "übersetzt" hat. Aber man kann die halt auch selber nutzen für Foxit-Funktionen, die Edgar noch nicht umgesetzt hat. Allerdings halt nur bei einfachen Sachen, die mit einem einmaligen Aufruf erledigt sind. Manche Funktionen müssen sehr intensiv aufbereitet werden, damit man mit einem Funktionsaufruf in Xbase++ das in Foxit nutzen kann.

Jan
Vielen Dank für Die Info.

Gibts es da vielleicht irgendwo eine Beschreibung dafür ?

Danke.

Merlin

Re: Realisierung ZUGFeRD bzw. XRechnung (EN 16931) - PDFs

Verfasst: Mi, 29. Jun 2022 18:47
von Jan
Merlin,

nein. Es gibt aber hier im Forum verschiedene Beispiele. Darauf aufbauend kannst Du das mit der Foxit-Doku verknüpfen und Dir die fehlenden Sachen selber erstellen (wenn das einfach so machbar ist).

Du kannst aber auch immer Edgar anmailen wenn Dir was fehlt. Entweder baut er das demnächst ein, oder er gibt Dir ein Beispiel wie Du das z. B. per qCall selber machen kannst. Er ist da extrem hilfsbereit.

Jan

Re: Realisierung ZUGFeRD bzw. XRechnung (EN 16931) - PDFs

Verfasst: Mi, 29. Jun 2022 19:29
von Tom
Foxit ist tatsächlich ziemlich easy zu wrappen. Und die Doku ist exzellent.

Re: Realisierung ZUGFeRD bzw. XRechnung (EN 16931) - PDFs

Verfasst: Do, 30. Jun 2022 7:23
von Martin Altmann
Moin Merlin,
Merlin hat geschrieben: Mi, 29. Jun 2022 15:20das ist ein guter Gedanke. Habe aber leider die ndFpCall Funktion nicht ...bekomme da Compiler-Fehler.
hast Du denn auch die beiden relevanten LIBs mit eingebunden?

Code: Alles auswählen

#pragma Library( "ot4xb.lib", "xpppdf51.lib" )
Viele Grüße,
Martin

Re: Realisierung ZUGFeRD bzw. XRechnung (EN 16931) - PDFs

Verfasst: Do, 30. Jun 2022 7:52
von Jan
Martin Altmann hat geschrieben: Do, 30. Jun 2022 7:23 hast Du denn auch die beiden relevanten LIBs mit eingebunden?

Code: Alles auswählen

#pragma Library( "ot4xb.lib", "xpppdf51.lib" )
Bei seiner Bibliothek ist Edgar aktuell inzwischen bei der xpppdf61.lib.

Jan

Re: Realisierung ZUGFeRD bzw. XRechnung (EN 16931) - PDFs

Verfasst: Mi, 06. Jul 2022 10:41
von Merlin
Vielen lieben Dank für Eure Beiträge, haben mir sehr weitergeholfen.

Noch eine Frage:
Hat mir jemand einen Link zur Foxit-Doku?
Ich finde auf deren HP nichts.

Grüße
Merlin

Re: Realisierung ZUGFeRD bzw. XRechnung (EN 16931) - PDFs

Verfasst: Mi, 06. Jul 2022 11:38
von HaPe