Pascal-Unit zum Erzeugen von ZUGFeRD XML

Zur Vorstellung von Komponenten und Units für Lazarus
Benutzeravatar
Jorg3000
Lazarusforum e. V.
Beiträge: 253
Registriert: So 10. Okt 2021, 10:24
OS, Lazarus, FPC: Win64
Wohnort: NRW

Pascal-Unit zum Erzeugen von ZUGFeRD XML

Beitrag von Jorg3000 »

Thema: E-Rechnung, elektronische Rechnung

Hallo!
An dieser Stelle (erster Post) erscheint ab sofort immer die aktuellste Version meiner Pascal-Unit zum Erstellen einer XML-Datei als ZUGFeRD-Rechnungsdokument.
Siehe unten: LGPL, Haftungsausschluss.

Aktuellste Version, Datum 2025-01-04
ZUGFeRD_xml.pas
(31.3 KiB) 32-mal heruntergeladen

Beispiel-Daten und -Verwendung siehe darin enthaltene function ZUGFeRD_Example_saveFile()

Änderungs-Historie:
- 27.12.2024 nur Entwurf, fehlerhaft
- 2024-12-31 Erste Version, die mit mehreren Steuersätzen den Validator-Test bestanden hat.
- 2025-01-04 Erweiterungen von Soner: 1.) Minimum_Profile (Buchungshilfe) 2.) Preise mit mehr als 2 Nachkommastellen im XML.

Die folgenden Kommentare hier im Forum auf Seite 1 beziehen sich auf einen alten Entwurf und sind veraltet und erledigt.
Bitte bei zukünftigen Kommentaren immer die Version (Datum aus dem Kopf der Unit) nennen, damit klar wird, ob der Kommentar/Frage noch aktuell ist.

Rechtliche Informationen:
Die o.g. Pascal-Unit ist ein Hobby-Projekt und ist nicht nach dem ZUGFeRD-Standard zertifiziert.
Die Unit und der Autor stehen in keiner Verbindung zu FeRD (Forum elektronische Rechnung Deutschland), siehe unten.

Die Nutzung der Pascal-Unit ist auch in proprietären, kommerziellen Programmen erlaubt.
Der Verwender/Programmierer muss selber dafür Sorge tragen, dass diese Pascal-Unit seinen Anforderungen genügt.
Der Quellcode wird gemäß der LGPL ohne jede Gewähr bereitgestellt; jegliche Haftung für Schäden wird im gesetzlich zulässigen Umfang ausgeschlossen.

Diese Unit steht unter der LGPL (GNU Lesser General Public License) Version 3 oder höher.
Anstelle einer Lizenztext-Datei siehe: https://www.gnu.org/licenses/lgpl-3.0.html

Zitat: "ZUGFeRD ist ein branchenübergreifendes Datenformat für den elektronischen Rechnungsdatenaustausch, das vom Forum elektronische Rechnung Deutschland (FeRD) – mit Unterstützung des Bundesministeriums für Wirtschaft und Energie – erarbeitet wurde."
https://www.ferd-net.de/standards/zugferd


Links:
Kostenloser XML/ZUGFeRD-Validator: https://www.portinvoice.com
Kostenlose Visualisierung: https://www.elster.de/eportal/e-rechnung

Grüße, Jörg
Zuletzt geändert von Jorg3000 am Sa 4. Jan 2025, 22:09, insgesamt 7-mal geändert.

MmVisual
Beiträge: 1552
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 3.6 FPC 3.2.2)
CPU-Target: 32/64Bit

Re: mein ZUGFeRD kommt nicht aus dem Stall

Beitrag von MmVisual »

Beim .Create diese Variablen nullen?

// Rechnungs-Summen
FTaxBasisTotal: Double; // Nettosumme
FTaxTotalAmount: Double; // Gesamte Steuer
FGrandTotalAmount: Double; // Bruttosumme
EleLa - Elektronik Lagerverwaltung - www.elela.de

Benutzeravatar
Jorg3000
Lazarusforum e. V.
Beiträge: 253
Registriert: So 10. Okt 2021, 10:24
OS, Lazarus, FPC: Win64
Wohnort: NRW

Re: mein ZUGFeRD kommt nicht aus dem Stall

Beitrag von Jorg3000 »

Jau stimmt, die Variablen werden nicht explizit genullt. Habe ich gar nicht dran gedacht.
Aber in diesem Fall ist das nicht nötig, weil der Speicher eines Klassenobjekts bei Erzeugung mit Nullen gefüllt wird.

Benutzeravatar
Jorg3000
Lazarusforum e. V.
Beiträge: 253
Registriert: So 10. Okt 2021, 10:24
OS, Lazarus, FPC: Win64
Wohnort: NRW

Re: mein ZUGFeRD kommt nicht aus dem Stall

Beitrag von Jorg3000 »

Hach, ich bin ja blöd.
Ich kann doch einfach den XML-Kopf aus den fertigen Beispielen der ZUGFerd-Dokumentation in die Knoten-Erzeugung umsetzen.
Das mache ich aber erst morgen früh. Jetzt erst mal Feierabend. :D

MmVisual
Beiträge: 1552
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 3.6 FPC 3.2.2)
CPU-Target: 32/64Bit

Re: mein ZUGFeRD kommt nicht aus dem Stall

Beitrag von MmVisual »

Beim Beispiel ist auch das "Invoice.addTotals();" nicht drin.

Un ein paar Typecastst Unicodestring() wären auch gut.
EleLa - Elektronik Lagerverwaltung - www.elela.de

MmVisual
Beiträge: 1552
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 3.6 FPC 3.2.2)
CPU-Target: 32/64Bit

Re: mein ZUGFeRD kommt nicht aus dem Stall

Beitrag von MmVisual »

Ich habe das mal hinzugefügt.
<<< DATEI GELÖSCHT >>> neuere gibt es direkt hier: viewtopic.php?p=146609#p146609
Zuletzt geändert von MmVisual am Mo 30. Dez 2024, 09:11, insgesamt 1-mal geändert.
EleLa - Elektronik Lagerverwaltung - www.elela.de

Benutzeravatar
Jorg3000
Lazarusforum e. V.
Beiträge: 253
Registriert: So 10. Okt 2021, 10:24
OS, Lazarus, FPC: Win64
Wohnort: NRW

Re: mein ZUGFeRD kommt nicht aus dem Stall

Beitrag von Jorg3000 »

Guten Morgen!

UPDATE: Bitte nicht mehr rätseln, denn ich baue die Unit heute nochmal um.

Ich hatte die ZUGFeRD-Spezifikation an Heiligabend runtergeladen und bin darin mit den verschiedenen "Profilen" (z.B. COMFORT und BASIC) durcheinander gekommen.
Ich hatte vermutet, es wäre alles schön kompatibel zueinander, aber so einfach ist es natürlich nicht. - Natürlich nicht.

Ich glaube ich bin inzwischen auf dem richtigen Weg, denn dem Validator gefällt inzwischen mein Umbau auf das BASIC-Profil und meldet nur noch 20 statt vorher 60 Verfehlungen der Spezifikation. :D
Aber ich muss jeden XML-Knoten nochmal prüfen.

Melde mich im Laufe des Tages mit einer ganz neuen Version der Unit.

UPDATE II (Samstag Nachmittag)
Das erzeugte XML hat gerade erstmals den Validator-Test bestanden. :)
Allerdings muss ich noch die Summen und Steuern richtig ausrechnen und meine umgebaute Unit ordentlich aufräumen. Es könnte also morgen werden bis ich sie hochlade.

Grüße, Jörg

Benutzeravatar
Jorg3000
Lazarusforum e. V.
Beiträge: 253
Registriert: So 10. Okt 2021, 10:24
OS, Lazarus, FPC: Win64
Wohnort: NRW

Pascal-Unit zum Erzeugen von ZUGFeRD XML

Beitrag von Jorg3000 »

Hallo!

Nachdem ich nochmal einen Tag mit dem Gaul gekämpft habe, hat das erzeugte XML nun den Validator-Test bestanden.

UPDATE: Die aktuellste Version findet man nun oben im ersten Beitrag (aktualisiert).
Zuletzt geändert von Jorg3000 am Mo 30. Dez 2024, 08:47, insgesamt 1-mal geändert.

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6533
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Pascal-Unit zum Erzeugen von ZUGFeRD XML

Beitrag von af0815 »

Jorg3000 hat geschrieben: So 29. Dez 2024, 11:37 Gerne Rückmeldungen, wer die Unit gebrauchen kann oder was verbessert werden muss.
Grüße, Jörg
Ich glaube, die werden mehr brauchen, nur mach bitte eine Lizenz wie zum Beispiel die vom FPC oder Lazarus (siehe in den Verzeichnissen dort) damit man die überhaupt verwenden kann.

Und die alten Versionen gehören aus den Beiträgen glöscht und man legt die aktuelle dann immer in den ersten Post. Damit erwicht keiner eine alte Version.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

kirchfritz
Beiträge: 214
Registriert: Mo 3. Jan 2011, 13:34
OS, Lazarus, FPC: Win11 (L 3.0 FPC 3.2.2)
CPU-Target: 64Bit
Wohnort: Nürnberg

Re: Pascal-Unit zum Erzeugen von ZUGFeRD XML

Beitrag von kirchfritz »

Gratulation, sehr gute Arbeit!
Darauf haben bestimmt viele gewartet.

Ich habe Deinen "example"-Datensatz um eine Rechnungsposition ergänzt, und dieser Position einen Mehrwertsteuersatz von 7% "verpasst".
Leider ist das XML dann nicht mehr valide!
Kannst Du herausfinden, wo ran das liegt?
Die Validierungsfehlermeldungen sind leider für mich unverständlich.
Klingt irgendwie, als stimmten die Berechnungen nicht.

Code: Alles auswählen

  // line items, Rechnungs-Posten
  i := Length(Data.Items);
  SetLength(Data.Items, i+1);  // append new line item, neuen Rechnungsposten anhängen
  with Data.Items[i] do
    begin
     LineID := IntToStr(i+1);
     GlobalID := '4012345001235';
     ProductName := 'GTIN: 4012345001235' +sLineBreak+
                          'Unsere Art.-Nr.: TB100A4' +sLineBreak+
                          'Trennblätter A4';
     Quantity := 20.0;        // Menge
     UnitCode := 'C62';       // unit: pieces, Einheit: Stück
     NetSinglePrice := 9.90;  // Netto-Einzelpreis
     TaxRate := 19.0;         // MwSt-Steuersatz in Prozent
     LineTotalNet := 198.00;  // Zeilensumme netto
    end;

  // line items, Rechnungs-Posten
  i := Length(Data.Items);
  SetLength(Data.Items, i+1);  // append new line item, neuen Rechnungsposten anhängen
  with Data.Items[i] do
    begin
     LineID := IntToStr(i+1);
     GlobalID := '4012345001236';
     ProductName := 'Bildband Tuvalu';
     Quantity := 1.0;        // Menge
     UnitCode := 'C62';       // unit: pieces, Einheit: Stück
     NetSinglePrice := 29.90;  // Netto-Einzelpreis
     TaxRate := 7.0;         // MwSt-Steuersatz in Prozent
     LineTotalNet := 29.90;  // Zeilensumme netto
    end;        

Und das hier wären die Fehlermeldungen bei der Validierung:
Das XML ist nicht valide.

Profil: urn:cen.eu:en16931:2017#compliant#urn:factur-x.eu:1p0:basic
Korrekte XML Struktur: Nein
Korrektes XML Schema: OK
Korrekte XML Namespaces: OK
Korrekte XML Kodierung: OK
Korrekte Code Listen: OK
Gibt es Warnungen? Ja

Details

[BR-CO-17]-Der Inhalt des Elementes „VAT category tax amount“ (BT-117) entspricht dem Inhalt des Elementes „VAT category taxable amount“ (BT-116), multipliziert mit dem Inhalt des Elementes „VAT category rate“ (BT-119) geteilt durch 100, gerundet auf zwei Dezimalstellen.

[BR-S-08]-Für jeden anderen Wert des kategoriespezifischen Umsatzsteuersatzes „VAT category rate“ (BT-119), bei dem als Code der Umsatzsteuerkategorie „VAT category code“ (BT-118) der Wert „Standard rated“ angegeben ist, muss der nach der Umsatzsteuerkategorie zu versteuernde Betrag „VAT category taxable amount“ (BT-116) in einer Umsatzsteueraufschlüsselung „VAT BREAKDOWN“ (BG-23) gleich der Summe der Rechnungszeilen-Nettobeträge „Invoice line net amount“ (BT-131) zuzüglich der Summe der Beträge aller Abgaben auf der Dokumentenebene „Document level charge amount“ (BT-99) abzüglich der Summe der Beträge aller Nachlässe auf der Dokumentenebene „Document level allowance amount“ (BT-92) sein; wobei als Code der Umsatzsteuerkategorie („Invoiced item VAT category code“ (BT-151), „Document level charge VAT category code“ (BT-102) und „Document level allowance VAT category code“ (BT-95)) der Wert „Standard rated“ angegeben wird und der Umsatzsteuersatz („Invoiced item VAT rate“ (BT-152), „Document level charge VAT rate“ (BT-103) und „Document level allowance VAT rate“ (BT-96)) gleich dem kategoriespezifischen Umsatzsteuersatz ist. Anmerkung: D.h. dass für jeden USt-Satz eine gesonderte Gruppe „VAT BREAKDOWN“ (BG-23) anzulegen ist.

[BR-S-09]-Der in der Umsatzsteueraufschlüsselung „VAT BREAKDOWN“ (BG-23) angegebene Betrag der nach Kategorie zu entrichtenden Umsatzsteuer, bei dem als Umsatzsteuerkategorie der Wert „Standard rated“ angegeben ist, muss gleich dem mit dem kategoriespezifischen Umsatzsteuersatz multiplizierten nach der Umsatzsteuerkategorie zu versteuernden Betrag sein.

[VD-Valitool-47]-Rechenfehler (ggf. wegen Rundungsfehler): ApplicableTradeTax -> CalculatedAmount = Sum (Line Item CalculatedAmount) Der angegebene Wert ist 39.71. Dies entspricht nicht dem rechnerisch richtigen Wert 37.62) mit der Bedingung [Type=VAT, Category=S, Percent=19.00]. Dieser Fehler kann auch auftreten, wenn fälschlicherweise auf Positionsebene derselbe Steuerfall mehrfach angegeben wurde.

[VD-Valitool-48]-Rechenfehler (ggf. wegen Rundungsfehler): ApplicableTradeTax -> BasisAmount = Sum (Line Item BasisAmount) + Document Charges Amount - Document Allowances Amount 198.00. Dies entspricht nicht dem angegebenen Wert 227.90) bei [Type=VAT, Category=S, Percent=19.00]

[VD-Valitool-49]-Rechenfehler (ggf. wegen Rundungsfehler): ApplicableTradeTax -> CalculatedAmount = BasisAmount * ApplicablePercent (227.90 * 0.19 = 39.71 Dies entspricht nicht dem angegebenen Wert 43.30) bei [Type=VAT, Category=S, Percent=19.00]

Schönen Sonntag
Fritz

kirchfritz
Beiträge: 214
Registriert: Mo 3. Jan 2011, 13:34
OS, Lazarus, FPC: Win11 (L 3.0 FPC 3.2.2)
CPU-Target: 64Bit
Wohnort: Nürnberg

Re: Pascal-Unit zum Erzeugen von ZUGFeRD XML

Beitrag von kirchfritz »

Was ich bisher herausgefunden habe:

Aus meinen zwei Rechnungspositionen erzeugt Dein Algorithmus genau einen ApplicableTradeTax-Knoten

Code: Alles auswählen

<ram:ApplicableTradeTax>
        <ram:CalculatedAmount>39.71</ram:CalculatedAmount>
        <ram:TypeCode>VAT</ram:TypeCode>
        <ram:BasisAmount>227.90</ram:BasisAmount>
        <ram:CategoryCode>S</ram:CategoryCode>
        <ram:RateApplicablePercent>19.00</ram:RateApplicablePercent>
      </ram:ApplicableTradeTax>
Das ist leider falsch. Richtig wären, nach meinem Verständnis, zwei ApplicableTradeTax-Knoten (für jeden Steuersatz ein Knoten)
Bezüglich meines Beispiels mit den zwei Rechnungsposition müssten folgende zwei ApplicableTradeTax-Knoten erstellt werden:

Code: Alles auswählen

	   <ram:ApplicableTradeTax>
                <ram:CalculatedAmount>2.09</ram:CalculatedAmount>
                <ram:TypeCode>VAT</ram:TypeCode>
                <ram:BasisAmount>29.90</ram:BasisAmount>
                <ram:CategoryCode>S</ram:CategoryCode>
                <ram:RateApplicablePercent>7.00</ram:RateApplicablePercent>
            </ram:ApplicableTradeTax>
            <ram:ApplicableTradeTax>
                <ram:CalculatedAmount>37.62</ram:CalculatedAmount>
                <ram:TypeCode>VAT</ram:TypeCode>
                <ram:BasisAmount>198.00</ram:BasisAmount>
                <ram:CategoryCode>S</ram:CategoryCode>
                <ram:RateApplicablePercent>19.00</ram:RateApplicablePercent>
            </ram:ApplicableTradeTax>
Nix für ungut.

Schönen Sonntag
Fritz

Benutzeravatar
Jorg3000
Lazarusforum e. V.
Beiträge: 253
Registriert: So 10. Okt 2021, 10:24
OS, Lazarus, FPC: Win64
Wohnort: NRW

Re: Pascal-Unit zum Erzeugen von ZUGFeRD XML

Beitrag von Jorg3000 »

Hi!
Selbstverständlich hatte ich mehrere Steuersätze gleichzeitig noch nicht ausprobiert. :lol:

Ich hatte mich bei der Summation schon gewundert, was man wohl mit einem Mischmasch anfangen will. Ok, war also so nicht gedacht.

Dann gibt's heute Abend oder morgen wieder ein Update.

Benutzeravatar
kralle
Lazarusforum e. V.
Beiträge: 1145
Registriert: Mi 17. Mär 2010, 14:50
OS, Lazarus, FPC: Manjaro Linux, Mint und Windows 10 ,Lazarus 3.99, FPC-Version: 3.3.1
CPU-Target: 64Bit
Wohnort: Bremerhaven
Kontaktdaten:

Re: Pascal-Unit zum Erzeugen von ZUGFeRD XML

Beitrag von kralle »

Das hier wurde im Delphi-Forum gepostet, vielleicht hilft es:

https://www.delphipraxis.net/216403-zug ... ost1544550

Gruß Kralle
OS: Manjaro Linux, Linux Mint und Windows 10
FPC-Version: 3.3.1 , Lazarus 3.99
+ Delphi XE7SP1

Benutzeravatar
Jorg3000
Lazarusforum e. V.
Beiträge: 253
Registriert: So 10. Okt 2021, 10:24
OS, Lazarus, FPC: Win64
Wohnort: NRW

Re: Pascal-Unit zum Erzeugen von ZUGFeRD XML

Beitrag von Jorg3000 »

kralle hat geschrieben: So 29. Dez 2024, 22:57 Das hier wurde im Delphi-Forum gepostet
Moin!
Habe dort mal geguckt: Es ist wohl eine neue Unit für Delphi aus dem letzten Monat, für die man bei kommerzieller Verwendung eine Lizenz kaufen muss. Dafür haben die allerdings schon eine PDF-Verbindung.

Für mich war klar, dass ich meine Unit kostenlos bereitstellen will (LGPL Lizenz), quasi als „Give Back“ an die Community, von der ich schon seit Jahren selber meinen Nutzen ziehe.

MmVisual hat geschrieben: Fr 27. Dez 2024, 22:41 Ich habe das mal hinzugefügt. ZUGFeRD_XML.pas
MmVisual, könntest du die alte, fehlerhafte Unit aus deinem Post löschen (schon 110x runtergeladen), damit es nicht zu Verwechslungen mit der aktuellen Version kommt (jetzt immer ganz oben im ersten Beitrag).

Danke, Jörg

Benutzeravatar
Jorg3000
Lazarusforum e. V.
Beiträge: 253
Registriert: So 10. Okt 2021, 10:24
OS, Lazarus, FPC: Win64
Wohnort: NRW

Re: Pascal-Unit zum Erzeugen von ZUGFeRD XML

Beitrag von Jorg3000 »

kirchfritz hat geschrieben: So 29. Dez 2024, 14:44 Richtig wären, nach meinem Verständnis, zwei ApplicableTradeTax-Knoten (für jeden Steuersatz ein Knoten)
Guten Morgen!

Damit hast du vollkommen Recht! Habe meiner Unit nun ein Array für Steuersätze hinzugefügt.
Bei jedem Hinzufügen eines Rechnungs-Postens (Line item) wird geschaut, ob es diesen Steuersatz schon gibt oder er wird bedarfsweise angelegt.
Außerdem gibt es eine Summation pro Steuersatz. Im XML werden nun so viele Tax-Knoten angelegt wie benötigt.

Zum Testen habe ich die Beispieldaten auf 5 Posten mit 3 Steuersätzen erweitert, siehe setExampleData().

Die neue Unit findet man nun ganz oben im ersten Beitrag.
Grüße, Jörg
Zuletzt geändert von Jorg3000 am Mo 30. Dez 2024, 16:36, insgesamt 1-mal geändert.

Antworten