Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Lesedauer 17 Min.

Pflichterfüllung

.NET-Entwickler können die ab 2025 im B2B-Markt einsetzende Pflicht zur strukturierten elektronischen Rechnungsstellung und -annahme mit Open-Source-Lösungen erfüllen.
© dotnetpro
Das Thema strukturierter elektronischer Rechnungen (Electronic Billing, E-Invoicing) beschäftigt mich schon seit sehr vielen Jahren. 1998 schrieb ich dazu meine Diplomarbeit im Rahmen meines Wirtschaftsinformatikstudiums an der Universität Essen in Zusammenarbeit mit der damaligen Essener Telefongesellschaft o.tel.o (siehe auch [1]). Meine Diplomarbeit (siehe [2]) habe ich an mehrere Dutzend Firmen verkaufen können, die sich für meine Ideen interessierten. Auch mein erster Fachbeitrag in der Zeitschrift iX in Ausgabe 9/1998 handelte davon. In dem seither vergangenen ­guten Vierteljahrhundert passierte allerdings zunächst lange Zeit fast nichts. Erst in den letzten Jahren hat das Thema etwas Fahrt aufgenommen, aber nur im B2G- und B2B-Markt (siehe Kasten Zu wenig hat sich getan im B2C-Markt).

Zu wenig hat sich getan im B2C-Markt

Zu den Ideen in meiner Diplomarbeit gehörte auch ein effi­zienterer Weg für die Bezahlung von Rechnungen durch Endverbraucher. Rechnungssteller wie Telekommunikationsgesellschaften, Einzelhandelsgeschäfte, Ärzte und Behörden könnten Rechnungen elektronisch an die Bank des Kunden schicken. Die Bank benachrichtigt den Rechnungsempfänger, sie ­präsentiert diesem die Rechnung auf einer Website, und der Zahlungspflichtige kann mit einem Mausklick die Rechnung bestätigen oder zurückweisen. Bei diesem Prozess entfällt nicht nur der Versand der Rechnung, sondern auch das lästige und fehler­anfällige Abtippen von Zahlungsempfänger, Kontodaten, Betrag und Rechnungsnummer. Der Zahlungsempfänger könnte sicher sein, dass er alle notwendigen Angaben für die automa­tisierte Weiterverarbeitung auf der Überweisung erhält. Der Rechnungsempfänger hätte automatisch bei seiner Bank ein elektronisches Rechnungsarchiv; den Buchungsposi­tionen auf dem Konto wäre direkt ein Beleg zugeordnet.

Alternativen zu EDI

Schon seit den 1970er-Jahren gibt es das Konzept Electronic Data Interchange (EDI) [3] mit zahlreichen Standards wie EDIFACT und ODETTE, mit denen Unternehmen auch elektronische Rechnungen austauschen können. Alle diese EDI-Standards waren jedoch komplex in der Umsetzung, entsprechend kostenaufwendig und nur zwischen Großunternehmen verbreitet. Daher entstanden Ende der 1990er-Jahre einige Ideen zur Gestaltung des elektronischen Rechnungsprozesses auf Basis von XML-Daten über das Internet, die nicht nur zwischen Unternehmen, sondern auch zwischen Unternehmen und Endverbrauchern geeignet waren.

Schleppende Akzeptanz von PDF-Rechnungen

Viele Jahre war der elektronische Rechnungsversand in Deutschland an die Verwendung einer qualifizierten elektronischen Signatur gebunden. Erst durch das Steuervereinfachungsgesetz 2011 sind seit dem 1. Juli 2011 elektronische Rechnungen ohne Signatur erlaubt [4] und der Papierrechnung gleichgestellt. Auch danach musste aber das Unternehmen innerbetriebliche Kontrollverfahren etablieren, um die Echtheit der Herkunft, die Unversehrtheit des Inhalts und die Lesbarkeit der Rechnung zu gewährleisten. Das hat viele Unternehmen überfordert, und so verlangten sie von ihren Lieferanten stets eine Rechnung auf Papier. Erst die Corona-Pandemie gab bei den Unternehmen flächendeckend den Impuls, Rechnungen als PDF-Dokument per E-Mail anzunehmen.Eine PDF-Rechnung vereinfacht zwar den Versand, aber nicht die Erfassung in der Buchhaltung. Meist werden PDF-Rechnungen manuell erfasst, manchmal durch Screen-Scraping-Software ausgewertet, die aber meist erst angelernt werden muss. Der Einsatz von künstlicher Intelligenz kann dazu beitragen, die Erfolgsquote beim Screen Scraping deutlich erhöhen (siehe [5] und [6]). Das Thema entwickelt sich aber gerade erst noch.

ZUGFeRD

Dabei gibt es in Deutschland bereits seit dem Jahr 2014 einen Standard für strukturierte elektronische Rechnungen im XML-Format mit dem eigenwilligen Namen ZUGFeRD. Dieses Akronym steht für „Zentraler User Guide des Forums elektronische Rechnung Deutschland“ [7]. Das Forum elek­tronische Rechnung Deutschland wurde unter dem Dach der vom Bundesministerium für Wirtschaft und Energie (BMWi) auf Beschluss des Deutschen Bundestages geförderten Arbeitsgemeinschaft für wirtschaftliche Verwaltung (AWV) gegründet. ZUGFeRD basiert auf dem internationalen Standard Cross Industry Invoice (CII), das durch das United Nations Centre for Trade Facilitation and Electronic Business (UN/CEFACT), also dem Zentrum der Vereinten Nationen für Handelserleichterungen und elektronische Geschäftsprozesse, entwickelt wurde.Die XML-Daten werden bei ZUGFeRD in ein PDF-Dokument (PDF/A-3) als Anhang integriert, sodass der XML-Inhalt mit einem einfachen PDF-Viewer entnommen und betrachtet werden kann (siehe Bild 1). Man spricht daher von einem hybriden Format.
Beispiel für eine ZUGFeRD-Rechnung: Ein PDF mit XML-Anhang – hier in Adobe Acrobat Reader, wobei die enthaltene E-Invoice mit Visual Studio Code geöffnet wurde, weil dies die Standardverknüpfung auf dem System für XML-Dateien war (Bild 1) © Autor
Nach der ersten 2014er-Version von ZUGFeRD erschienen die Versionen 2.0 im März 2019 und 2.1 im März 2020. Hier erfolgte dann eine Angleichung an das parallel entwickelte französische Format Factur-X 1.0. Oft wird auch in Deutschland daher vom Factur-X-Format statt ZUGFeRD gesprochen.ZUGFeRD (aktuelle Version: 2.3 vom 18. September 2024) definiert mittlerweile sechs verschiedene Profile für den XML-Inhalt: Minimum, Basic WL, Basic, EN 16931 (ehemals Comfort genannt), Extended und XRechnung, wobei die ersten beiden XML-Formate in Deutschland umsatzsteuerlich nicht als gültige Rechnungen anerkannt sind.

XRechnung

Parallel zu ZUGFeRD ist das Format XRechnung entstanden. XRechnung ist ein reines XML-Format, welches der EU-Norm 16931 folgt. Diese Norm entstand durch die vom Europäischen Parlament und dem Rat der Europäischen Union am 16. April 2014 verabschiedete EU-Richtlinie 2014/55/EU mit dem Ziel, eine gemeinsame europaweit gültige Norm für das semantische Datenmodell der Kernelemente einer elektronischen Rechnung (also eine europäische Norm für die elektronische Rechnungsstellung) zu etablieren. Die Norm wurde von dem Europäischen Komitee für Normung (CEN) entwickelt und am 17. Oktober 2017 im Amtsblatt der EU als EN 16931 1:2017 veröffentlicht. Sie gibt einen Rahmen vor, lässt Mitgliedsstaaten jedoch eigene Spielräume für die rechtliche, organisatorische und technische Ausgestaltung bei Einführung der elektronischen Rechnung. Unter der Voraussetzung, dass die Ausgestaltung nationaler Standards nicht den Vorgaben der europäischen Richtlinie und Norm widerspricht, ist es jedem Mitgliedstaat gestattet, eigene Erweiterungen (Core Invoice Usage Specifications – CIUS) zu entwickeln. So gibt es in Deutschland zum Beispiel eine Erweiterung für Skonto [8], das in anderen Ländern nicht üblich ist.Die deutsche Version dieser EU-Norm, XRechnung, wurde am 22. Juni 2017 vom IT-Planungsrat für Bund und Länder in der Version 1.0 beschlossen. Seit dem 1. Januar 2019 wird XRechnung von der Koordinierungsstelle für IT-Standards (KoSIT) [9] verantwortet.XRechnungen verwenden als XML-Dialekt entweder den XML-Standard Universal Business Language (UBL) mit Wurzeltag <Invoice> oder Cross Industry Invoice (CII, wie bei ZUGFeRD) mit Wurzeltag <CrossIndustryInvoice>, siehe auch [10]. XRechnungen können Anhänge enthalten, zum Beispiel Lieferscheine, Reisekostenbelege oder auch die Rechnung noch mal als PDF-Dokument.Die Bundesbehörden wurden in Deutschland zum Vorreiter bei den elektronischen Rechnungen: Seit dem 27. November 2018 müssen die obersten Bundesbehörden und die Verfassungsorgane des Bundes XRechnungen empfangen können. Seit dem 27. November 2019 gilt dies für alle anderen Bundesbehörden und seit dem 18. April 2020 auch für die Landesbehörden. Seit dem 27. November 2020 sind Lieferanten des Bundes verpflichtet, die B2G-Rechnungsstellung im Rahmen öffentlicher Aufträge für alle Beträge ab 1000 Euro per XRechnung vorzunehmen. Während in einigen Bundesländern auch entsprechende Verpflichtungen auf Landesebene gelten (zum Beispiel Bremen, Baden-Württemberg, Saarland, Hessen, Rheinland-Pfalz), sind in anderen Bundesländern (zum Beispiel Nordrhein-Westfalen, Berlin, Bayern) Papier- und PDF-Rechnungen weiterhin grundsätzlich erlaubt. Behörden steht es aber frei, eine entsprechende Verpflichtung mit dem Lieferanten vertraglich zu vereinbaren.Erwähnt werden muss aber auch, dass innerhalb der EU andere Staaten Deutschland schon sehr weit voraus waren: E-Invoicing-Pflicht für B2G gilt in Dänemark seit dem Jahr 2005 (auf Basis von UBL 1.0 aus dem Jahr 2004), in Schweden seit 2008, Spanien und Finnland seit 2010 sowie seit 2014 in Italien und Österreich.

E-Rechnungspflicht für B2B-Rechnungen

Das Gesetz zur Stärkung von Wachstumschancen, Investitionen und Innovation sowie Steuervereinfachung und Steuerfairness (Wachstumschancengesetz) 2024 [11] erweitert die elektronische Rechnungspflicht nun in mehreren Schritten auch auf die Rechnungsstellung zwischen Unternehmen (B2B-Markt), was auch andere Länder schon zuvor eingeführt haben, zum Beispiel Italien seit dem 1. Januar 2019 (dort muss die maschinenlesbare Rechnung auch das Finanzamt gesendet werden). Das deutsche Wachstumschancengesetz wurde am 17. November 2023 im Bundestag beschlossen, kam aber dann in den Vermittlungsausschuss und passierte den Bundesrat erst am 23. März 2024.Elektronische Rechnung im Sinne des Wachstumschancengesetzes bedeutet dabei eine strukturierte elektronische Rechnung gemäß der EU-Norm 16931. Diese erlaubt die Formate ZUGFeRD (ab Version 2.0.1) und XRechnung/Factur-X, aber auch andere europäische Formate wie das italienische „FatturaPA. Bei hybriden Formaten gilt im Zweifelsfall die eingebettete XML-Datei als Original. Der Rechnungsempfänger muss diese also immer prüfen und darf sich nicht auf das verlassen, was die PDF-Datei anzeigt. EDI-Verfahren bleiben erlaubt, sofern ein Export der Daten in einer der EU-Norm 16931 gemäßen Form möglich ist.Einen bestimmten Übertragungsweg sieht das Wachstumschancengesetz nicht vor, daher ist die Übertragung der elektronischen Rechnung per E-Mail möglich, auch wenn E-Mail keine Zustellungsgarantie bietet und für Phishing anfällig ist. Für die angedachte zukünftige Umsatzsteuermeldung (siehe EU-Projekt „VAT in the Digital Age – ViDA) [12], bei der jede einzelne Rechnung unverzüglich an das Finanzamt geht (wie heute schon in Italien, Rumänien und der Türkei), wird wohl eine sicherere und strukturiertere Übertragungsmethode verpflichtend sein. Infrage kommt hier Pan-European Public Procurement OnLine (PEPPOL), siehe [13].Die Pflicht gilt für Rechnungen, Stornorechnungen und Gutschriften zwischen inländischen Unternehmen, auch für Kleinunternehmer beziehungsweise Land- und Forstwirte. Die E-Rechnungs-Pflicht gilt nicht:
  • wenn der Betrag kleiner als 250 Euro ist,
  • für Fahrausweise,
  • für Leistungen, die nach § 4 Nummer 8 bis 29 UStG steuerfrei sind (zum Beispiel Bankgeschäfte, Vermietung, Gesundheits- und Pflegedienstleistungen, Schulen),
  • wenn Endverbraucher beteiligt sind.
Unternehmen dürfen aber elektronische Rechnungen an Endverbraucher senden, insofern diese ausdrücklich zustimmen. Nicht durch das Gesetz betroffen sind andere kaufmännische Dokumente wie Bestellungen, Auftragsbestätigungen, Lieferscheine und Mahnungen, auch wenn es dafür schon elektronische Lösungen gibt.Die Pflicht gilt grundsätzlich ab dem 1. Januar 2025. Es gibt aber großzügige Übergangsregelungen bis Ende des Jahres 2027:
  • Bis Ende 2026 dürfen Rechnungen weiterhin auf Papier und elektronische Rechnungen in anderen Formaten (zum Beispiel reines PDF) versendet werden.
  • Bis Ende 2027 ist beides immer noch erlaubt, falls der Rechnungsaussteller einen Vorjahresumsatz (Gesamtumsatz nach § 19 Abs. 3 UStG) von maximal 800 000 Euro hat.
  • Erst ab 2028 sind die strukturierten elektronischen Rechnungen dann wirklich verpflichtend.
Im Netz kursieren auch abweichende Zeitpläne, zum Beispiel auf der Web­site des Buchhaltungssoftware-Anbieters Sage [14]. Die obigen Angaben ­basieren auf einem Beitrag von Haufe [15], der dem rechtlichen Stand vom März 2024 [11] entspricht.Für Rechnungsempfänger sind die Regeln strenger: Alle in Deutschland ansässigen Unternehmen müssen bereits ab dem 1. Januar 2025 strukturierte elektronische Rechnungen empfangen können. Wenn eine E-Mail mit einer XML-Datei eingeht, reicht es, diese in einem beliebigen Texteditor zu öffnen. In der Praxis wird man sich ein Werkzeug zur Visualisierung beschaffen. Ein solches wollte ursprünglich die Bundesregierung bereitstellen, man ist davon aber wieder abgekommen. Es gibt aber ein vom Bundesministerium für Bildung und Forschung (BMBF) via Prototype Fund [16] gefördertes kostenfreies Open-Source-Werkzeug [17] mit Namen „Quba E-Rechnungs-View (kurz: Quba-Viewer) [18], das alle gängigen elektronischen Rechnungsformate darstellen kann (siehe Bild 2). Quba-Viewer ist eine Cross-Platform-Anwendung für Windows, macOS und Linux auf Basis von JavaScript, Vue.js 3 und Electron.
Ausschnitt aus einer XRechnung im Quba-Viewer (Bild 2) © Autor
Bild 2 zeigt auch, dass XRechnung zahlreiche Felder bietet, die optional sind, zum Beispiel für den Abrechnungszeitraum, Projekt- und Vertragsnummern sowie eine Liste früherer Rechnungen.Neben dem Quba-Viewer gibt es für die XRechnung zahlreiche andere Werkzeuge im Netz, zum Beispiel den Validator für XRechnung unter [19].

.NET-Bibliotheken für strukturierte ­elektronische Rechnungen

Gängige kaufmännische Programme bieten längst Unterstützung für ZUGFeRD und XRechnung. Eine Herausforderung gibt es für Unternehmen,
  • die nicht mehr gewartete Programme einsetzen,
  • Rechnungen mit eigener Software generieren oder
  • Rechnungen mit eigener Software automatisiert auswerten.
Die deutsche .NET-Gemeinde hat drei Lösungen hervorgebracht:1. ZUGFeRD.NET [20], als NuGet-Paket unter [21]2. Aloaha ZUGFeRD SDK [22], als NuGet-Paket unter [23]3. ZUGFeRD-csharp [24], als NuGet-Paket unter [25]Lösung 1 ist leider 2015 in der Entwicklung stehen geblieben. Bei den Verbleibenden liegt das kostenlose ZUGFeRD-­csharp mit 367 000 NuGet-Downloads klar vor dem kostenpflichtigen Aloaha ZUGFeRD SDK (60 000 Downloads). ZUGFeRD-csharp kann (ungeachtet des Namens) auch XRechnung, da XRechnung ja, wie weiter oben dargestellt, inzwischen ein Profil innerhalb des ZUGFeRD-Standards ist.Die hier im Folgenden besprochene Bibliothek ZUGFeRD-csharp läuft in allen im Markt relevanten .NET-Versionen, also auf dem klassischen .NET Framework 4.6.1 sowie im modernen .NET ab .NET Core 2.0. Eine Liste von Lösungen für andere Sprachen/Frameworks (zum Beispiel Python, PHP, C++, Java und Delphi) zeigt die ZUGFeRD-Website unter [26].

E-Rechnung erstellen mit ZUGFeRD-csharp

Listing 1 zeigt den Kern der Generierung einer XRechnung ­unter Einsatz von ZUGFeRD-csharp: Man erstellt zunächst ­eine Instanz der zentralen Klasse InvoiceDescriptor mit der statischen Methode InvoiceDescriptor.CreateInvoice() unter Angabe der Rechnungsnummer, des Rechnungsdatums und der Währung.
Listing 1: Erstellung einer strukturierten elektronischen Rechnung mit der Klasse InvoiceDescriptor
/// &amp;lt;summary&amp;gt;&lt;br/&gt;/// Erstellt eine E-Rechnung mit ZUGFeRD-csharp&lt;br/&gt;/// &amp;lt;/summary&amp;gt;&lt;br/&gt;private InvoiceDescriptor CreateERechnung(&lt;br/&gt;    RE_Rechnungen re, P_Partner kunde, AG_Angebote ag)&lt;br/&gt;{&lt;br/&gt;  #region --- Ermitteln einiger Werte aus den &lt;br/&gt;  #Eingangsdaten&lt;br/&gt;  &lt;span class="hljs-built_in"&gt;int&lt;/span&gt; zahlfristInTagen = re.RE_Zahlfrist ?? &lt;br/&gt;    STANDARDZAHLFRIST;&lt;br/&gt;  DateTime zahlbarBis = re.RE_DAT.Value.AddDays(&lt;br/&gt;    zahlfristInTagen);&lt;br/&gt;  &lt;span class="hljs-built_in"&gt;decimal&lt;/span&gt; summeNetto = re.RP_RechnungsPositionen.Sum(&lt;br/&gt;    x =&amp;gt; x.RP_Summe.GetValueOrDefault());&lt;br/&gt;  &lt;span class="hljs-built_in"&gt;decimal&lt;/span&gt; ust = summeNetto * &lt;br/&gt;    ((re.UST_Satz.GetValueOrDefault() / &lt;span class="hljs-number"&gt;100&lt;/span&gt;m));&lt;br/&gt;  &lt;span class="hljs-built_in"&gt;decimal&lt;/span&gt; summeBrutto = summeNetto + ust;&lt;br/&gt;  #endregion&lt;br/&gt; &lt;br/&gt;  InvoiceDescriptor desc = InvoiceDescriptor.&lt;br/&gt;    CreateInvoice(&lt;span class="hljs-string"&gt;"R-"&lt;/span&gt; + re.RE_ID.ToString(), &lt;br/&gt;    re.RE_DAT.Value, CurrencyCodes.EUR);&lt;br/&gt;  desc.BusinessProcess = &lt;span class="hljs-string"&gt;"urn:fdc:peppol.eu:2017:&lt;/span&gt;&lt;br/&gt;&lt;span class="hljs-string"&gt;    poacc:billing:01:1.0"&lt;/span&gt;; // Neu ab XRechnung &lt;span class="hljs-number"&gt;3.0&lt;/span&gt;.&lt;span class="hljs-number"&gt;1&lt;/span&gt;&lt;br/&gt;  &lt;br/&gt;  #region --- Kopfdaten der Rechnung&lt;br/&gt;  &lt;span class="hljs-built_in"&gt;if&lt;/span&gt; (ag != null) // Es gab ein Angebot zu der Rechnung&lt;br/&gt;  {&lt;br/&gt;    desc.ReferenceOrderNo = &lt;br/&gt;      ag.LeitwegID; // Leitweg-ID für Behörden !!!&lt;br/&gt;    desc.AddNote(re.RE_Grund);&lt;br/&gt;    desc.AddNote(&lt;span class="hljs-string"&gt;"Angebotsnummer: "&lt;/span&gt; + ag.AG_GanzeID);&lt;br/&gt;    &lt;span class="hljs-built_in"&gt;if&lt;/span&gt; (ag?.AG_AuftragsDatum != null)&lt;br/&gt;    {&lt;br/&gt;      desc.AddNote(&lt;span class="hljs-string"&gt;"Ihr Auftrag vom "&lt;/span&gt; + &lt;br/&gt;        ag.AG_AuftragsDatum?.ToShortDateString());&lt;br/&gt;      desc.OrderDate = ag.AG_AuftragsDatum;&lt;br/&gt;    }&lt;br/&gt;    &lt;span class="hljs-built_in"&gt;if&lt;/span&gt; (ag?.AG_AuftragsNummer != null)&lt;br/&gt;    {&lt;br/&gt;      {&lt;br/&gt;        desc.AddNote(&lt;span class="hljs-string"&gt;"Ihre Auftragsnummer: "&lt;/span&gt; &lt;br/&gt;          + ag.AG_AuftragsNummer);&lt;br/&gt;        desc.OrderNo = ag.AG_AuftragsNummer;&lt;br/&gt;      }&lt;br/&gt;    }&lt;br/&gt;  }&lt;br/&gt; &lt;br/&gt;  desc.AddNote(&lt;span class="hljs-string"&gt;"Falls Sie mehrere Rechnungen von uns &lt;/span&gt;&lt;br/&gt;&lt;span class="hljs-string"&gt;    erhalten haben, zahlen Sie diese unbedingt getrennt &lt;/span&gt;&lt;br/&gt;&lt;span class="hljs-string"&gt;    unter Angabe der jeweiligen Rechnungsnummer, da die &lt;/span&gt;&lt;br/&gt;&lt;span class="hljs-string"&gt;    Buchhaltung vollautomatisiert ist. Zahlungsavis &lt;/span&gt;&lt;br/&gt;&lt;span class="hljs-string"&gt;    können nicht verarbeitet werden."&lt;/span&gt;);&lt;br/&gt;  desc.AddNote(&lt;span class="hljs-string"&gt;"Bitte beachten Sie, dass der deutsche &lt;/span&gt;&lt;br/&gt;&lt;span class="hljs-string"&gt;    Gesetzgeber uns verpflichtet, alle Nebenleistungen &lt;/span&gt;&lt;br/&gt;&lt;span class="hljs-string"&gt;    wie zum Beispiel Reise- und Hotelkosten sowie &lt;/span&gt;&lt;br/&gt;&lt;span class="hljs-string"&gt;    Fachbücher zum gleichen Umsatzsteuersatz wie die &lt;/span&gt;&lt;br/&gt;&lt;span class="hljs-string"&gt;    Hauptleistung weiter zu berechnen, selbst wenn &lt;/span&gt;&lt;br/&gt;&lt;span class="hljs-string"&gt;    dafür ursprünglich ein anderer Steuersatz galt."&lt;/span&gt;);&lt;br/&gt;  #endregion&lt;br/&gt; &lt;br/&gt;  #region --- Informationen über den Rechnungssteller&lt;br/&gt;  desc.SetSeller(&lt;br/&gt;    &lt;span class="hljs-built_in"&gt;na&lt;/span&gt;&lt;span class="hljs-symbol"&gt;me:&lt;/span&gt; &lt;span class="hljs-string"&gt;"www.IT-Visions.de Dr. Holger Schwichtenberg"&lt;/span&gt;,&lt;br/&gt;    postco&lt;span class="hljs-symbol"&gt;de:&lt;/span&gt; &lt;span class="hljs-string"&gt;"45257"&lt;/span&gt;,&lt;br/&gt;    ci&lt;span class="hljs-symbol"&gt;ty:&lt;/span&gt; &lt;span class="hljs-string"&gt;"Essen"&lt;/span&gt;,&lt;br/&gt;    stre&lt;span class="hljs-symbol"&gt;et:&lt;/span&gt; &lt;span class="hljs-string"&gt;"Fahrenberg 40b"&lt;/span&gt;,&lt;br/&gt;    &lt;span class="hljs-built_in"&gt;count&lt;/span&gt;&lt;span class="hljs-symbol"&gt;ry:&lt;/span&gt; CountryCodes.DE,&lt;br/&gt;    &lt;span class="hljs-symbol"&gt;id:&lt;/span&gt; &lt;span class="hljs-string"&gt;""&lt;/span&gt;,&lt;br/&gt;    global&lt;span class="hljs-symbol"&gt;ID:&lt;/span&gt; new GlobalID(&lt;br/&gt;      GlobalIDSchemeIdentifiers.DUNS, &lt;span class="hljs-string"&gt;"341344246"&lt;/span&gt;)&lt;br/&gt;  );&lt;br/&gt; &lt;br/&gt;  desc.SetSellerContact(&lt;br/&gt;    &lt;span class="hljs-built_in"&gt;na&lt;/span&gt;&lt;span class="hljs-symbol"&gt;me:&lt;/span&gt; &lt;span class="hljs-string"&gt;"Dr. Holger Schwichtenberg"&lt;/span&gt;,&lt;br/&gt;    orgun&lt;span class="hljs-symbol"&gt;it:&lt;/span&gt; &lt;span class="hljs-string"&gt;"Buchhaltung"&lt;/span&gt;,&lt;br/&gt;    emailAddre&lt;span class="hljs-symbol"&gt;ss:&lt;/span&gt; &lt;span class="hljs-string"&gt;"Buchhaltung@IT-Visions.de"&lt;/span&gt;,&lt;br/&gt;    phone&lt;span class="hljs-symbol"&gt;no:&lt;/span&gt; &lt;span class="hljs-string"&gt;"+4920164959044"&lt;/span&gt;&lt;br/&gt;  );&lt;br/&gt;  desc.SellerElectronicAddress = new ElectronicAddress() &lt;br/&gt;      // Neu ab XRechnung &lt;span class="hljs-number"&gt;3.0&lt;/span&gt;.&lt;span class="hljs-number"&gt;1&lt;/span&gt;&lt;br/&gt;  {&lt;br/&gt;    ElectronicAddressSchemeID = ElectronicAddressScheme&lt;br/&gt;      Identifiers.EM, // EM = E-Mail&lt;br/&gt;    &lt;span class="hljs-built_in"&gt;Address&lt;/span&gt; = &lt;span class="hljs-string"&gt;"Buchhaltung@IT-Visions.de"&lt;/span&gt;&lt;br/&gt;  };&lt;br/&gt; &lt;br/&gt;  desc.AddSellerTaxRegistration(&lt;span class="hljs-string"&gt;"112/5392/5120"&lt;/span&gt;, &lt;br/&gt;    TaxRegistrationSchemeID.FC);&lt;br/&gt;  desc.AddSellerTaxRegistration(&lt;span class="hljs-string"&gt;"DE 187321081"&lt;/span&gt;, &lt;br/&gt;    TaxRegistrationSchemeID.VA);&lt;br/&gt;  #endregion&lt;br/&gt; &lt;br/&gt;  #region --- Informationen über den Rechnungsempfänger&lt;br/&gt;  desc.SetBuyer(&lt;span class="hljs-built_in"&gt;na&lt;/span&gt;&lt;span class="hljs-symbol"&gt;me:&lt;/span&gt; kunde.P_Firma,&lt;br/&gt;    postco&lt;span class="hljs-symbol"&gt;de:&lt;/span&gt; kunde.P_PLZ,&lt;br/&gt;    ci&lt;span class="hljs-symbol"&gt;ty:&lt;/span&gt; kunde.P_Ort,&lt;br/&gt;    stre&lt;span class="hljs-symbol"&gt;et:&lt;/span&gt; kunde.P_Strasse,&lt;br/&gt;    &lt;span class="hljs-built_in"&gt;count&lt;/span&gt;&lt;span class="hljs-symbol"&gt;ry:&lt;/span&gt; CountryCodes.DE,&lt;br/&gt;    &lt;span class="hljs-symbol"&gt;id:&lt;/span&gt; kunde.P_ID.ToString());&lt;br/&gt; &lt;br/&gt;  desc.BuyerContact = new Contact()&lt;br/&gt;  {&lt;br/&gt;    Name = kunde.P_Vorname + &lt;span class="hljs-string"&gt;" "&lt;/span&gt; + kunde.P_Name,&lt;br/&gt;    EmailAddress = kunde.P_EMail,&lt;br/&gt;    PhoneNo = kunde.P_Telefon&lt;br/&gt;  };&lt;br/&gt; &lt;br/&gt;  desc.BuyerElectronicAddress = new ElectronicAddress() &lt;br/&gt;      // Neu ab XRechnung &lt;span class="hljs-number"&gt;3.0&lt;/span&gt;.&lt;span class="hljs-number"&gt;1&lt;/span&gt;&lt;br/&gt;  {&lt;br/&gt;    ElectronicAddressSchemeID = &lt;br/&gt;      ElectronicAddressSchemeIdentifiers.EM, &lt;br/&gt;      // EM = E-Mail&lt;br/&gt;    &lt;span class="hljs-built_in"&gt;Address&lt;/span&gt; = kunde.P_EMail&lt;br/&gt;  };&lt;br/&gt;  #endregion&lt;br/&gt; &lt;br/&gt;  #region --- Zahlungsbedingungen&lt;br/&gt;  desc.SetTradePaymentTerms(&lt;span class="hljs-string"&gt;"Bitte überweisen Sie den &lt;/span&gt;&lt;br/&gt;&lt;span class="hljs-string"&gt;    Betrag binnen "&lt;/span&gt; + zahlfristInTagen + &lt;span class="hljs-string"&gt;" Tagen ohne &lt;/span&gt;&lt;br/&gt;&lt;span class="hljs-string"&gt;    Abzüge auf unten genanntes Konto. Bitte beachten &lt;/span&gt;&lt;br/&gt;&lt;span class="hljs-string"&gt;    Sie, dass Sie nach §286 BGB automatisch in Verzug &lt;/span&gt;&lt;br/&gt;&lt;span class="hljs-string"&gt;    kommen."&lt;/span&gt;, zahlbarBis); &lt;br/&gt;      // wird sich in kommender Version ändern in &lt;br/&gt;      // AATradePaymentTerms()&lt;br/&gt;  desc.SetPaymentMeans(PaymentMeansTypeCodes.&lt;br/&gt;    SEPACreditTransfer, &lt;span class="hljs-string"&gt;"Zahlung per SEPA-Überweisung."&lt;/span&gt;);&lt;br/&gt;  desc.AddCreditorFinancialAccount( &lt;br/&gt;    ib&lt;span class="hljs-symbol"&gt;an:&lt;/span&gt;&lt;span class="hljs-string"&gt;"DE57360700240109002600"&lt;/span&gt;, b&lt;span class="hljs-symbol"&gt;ic:&lt;/span&gt; &lt;span class="hljs-string"&gt;"DEUTDEDBESS"&lt;/span&gt;, &lt;br/&gt;    &lt;span class="hljs-built_in"&gt;na&lt;/span&gt;&lt;span class="hljs-symbol"&gt;me:&lt;/span&gt; &lt;span class="hljs-string"&gt;"Deutsche Bank Essen"&lt;/span&gt;);&lt;br/&gt;  desc.AddApplicableTradeTax(&lt;br/&gt;    basisAmou&lt;span class="hljs-symbol"&gt;nt:&lt;/span&gt; summeNetto,&lt;br/&gt;    perce&lt;span class="hljs-symbol"&gt;nt:&lt;/span&gt; (&lt;span class="hljs-built_in"&gt;decimal&lt;/span&gt;)re.UST_Satz, // &lt;span class="hljs-number"&gt;19.0&lt;/span&gt; oder &lt;span class="hljs-number"&gt;7.0&lt;/span&gt;&lt;br/&gt;    typeCo&lt;span class="hljs-symbol"&gt;de:&lt;/span&gt; TaxTypes.VAT, // Umsatzsteuer&lt;br/&gt;    categoryCo&lt;span class="hljs-symbol"&gt;de:&lt;/span&gt; re.UST_Satz == &lt;span class="hljs-number"&gt;0&lt;/span&gt; ? &lt;br/&gt;    TaxCategoryCodes.AE &lt;span class="hljs-symbol"&gt;:&lt;/span&gt; TaxCategoryCodes.S &lt;br/&gt;      // &lt;span class="hljs-string"&gt;"Reverse Charge"&lt;/span&gt; oder &lt;span class="hljs-string"&gt;"Standard Tax Rate"&lt;/span&gt;&lt;br/&gt;  );&lt;br/&gt;  #endregion&lt;br/&gt; &lt;br/&gt;  #region --- Rechnungspositionen einfügen&lt;br/&gt;  foreach (&lt;span class="hljs-built_in"&gt;var&lt;/span&gt; rp in re.RP_RechnungsPositionen)&lt;br/&gt;  {&lt;br/&gt;    desc.AddTradeLineItem(&lt;br/&gt;      &lt;span class="hljs-built_in"&gt;na&lt;/span&gt;&lt;span class="hljs-symbol"&gt;me:&lt;/span&gt; rp.RP_Text,&lt;br/&gt;      unitCo&lt;span class="hljs-symbol"&gt;de:&lt;/span&gt; QuantityCodes.&lt;span class="hljs-symbol"&gt;H87&lt;/span&gt;, &lt;br/&gt;        // &lt;span class="hljs-symbol"&gt;H87&lt;/span&gt; = &lt;span class="hljs-string"&gt;"Stück"&lt;/span&gt; siehe htt&lt;span class="hljs-symbol"&gt;ps:&lt;/span&gt;//unece.org/trade/&lt;br/&gt;        // documents/&lt;span class="hljs-number"&gt;2021&lt;/span&gt;/&lt;span class="hljs-number"&gt;06&lt;/span&gt;/uncefact-rec20-&lt;span class="hljs-number"&gt;0&lt;/span&gt;&lt;br/&gt;      billedQuanti&lt;span class="hljs-symbol"&gt;ty:&lt;/span&gt; (&lt;span class="hljs-built_in"&gt;decimal&lt;/span&gt;)rp.RP_Menge.Value,&lt;br/&gt;      netUnitPri&lt;span class="hljs-symbol"&gt;ce:&lt;/span&gt; (&lt;span class="hljs-built_in"&gt;decimal&lt;/span&gt;)rp.RP_Betrag.Value,&lt;br/&gt;      taxTy&lt;span class="hljs-symbol"&gt;pe:&lt;/span&gt; TaxTypes.VAT,&lt;br/&gt;      categoryCo&lt;span class="hljs-symbol"&gt;de:&lt;/span&gt; re.UST_Satz == &lt;span class="hljs-number"&gt;0&lt;/span&gt; ? &lt;br/&gt;      TaxCategoryCodes.AE &lt;span class="hljs-symbol"&gt;:&lt;/span&gt; TaxCategoryCodes.S, &lt;br/&gt;        // &lt;span class="hljs-string"&gt;"Reverse Charge"&lt;/span&gt; oder &lt;span class="hljs-string"&gt;"Standard Tax Rate"&lt;/span&gt;&lt;br/&gt;      taxPerce&lt;span class="hljs-symbol"&gt;nt:&lt;/span&gt; (&lt;span class="hljs-built_in"&gt;decimal&lt;/span&gt;)re.UST_Satz, &lt;br/&gt;        // &lt;span class="hljs-number"&gt;19.0&lt;/span&gt; oder &lt;span class="hljs-number"&gt;7.0&lt;/span&gt; oder &lt;span class="hljs-number"&gt;0.0&lt;/span&gt;&lt;br/&gt;      lineTotalAmou&lt;span class="hljs-symbol"&gt;nt:&lt;/span&gt; (&lt;span class="hljs-built_in"&gt;decimal&lt;/span&gt;)rp.RP_Summe.Value &lt;br/&gt;        // optionale Angabe. Wenn vorhanden, muss das &lt;br/&gt;        // aber stimmen!&lt;br/&gt;                          );&lt;br/&gt;  }&lt;br/&gt;  #endregion&lt;br/&gt; &lt;br/&gt;  #region --- Gesamtwerte&lt;br/&gt;  desc.SetTotals(&lt;br/&gt;    lineTotalAmou&lt;span class="hljs-symbol"&gt;nt:&lt;/span&gt; summeNetto,&lt;br/&gt;    chargeTotalAmou&lt;span class="hljs-symbol"&gt;nt:&lt;/span&gt; &lt;span class="hljs-number"&gt;0.0&lt;/span&gt;m,&lt;br/&gt;    allowanceTotalAmou&lt;span class="hljs-symbol"&gt;nt:&lt;/span&gt; &lt;span class="hljs-number"&gt;0.0&lt;/span&gt;m,&lt;br/&gt;    taxBasisAmou&lt;span class="hljs-symbol"&gt;nt:&lt;/span&gt; summeNetto,&lt;br/&gt;    taxTotalAmou&lt;span class="hljs-symbol"&gt;nt:&lt;/span&gt; ust,&lt;br/&gt;    grandTotalAmou&lt;span class="hljs-symbol"&gt;nt:&lt;/span&gt; summeBrutto,&lt;br/&gt;    totalPrepaidAmou&lt;span class="hljs-symbol"&gt;nt:&lt;/span&gt; &lt;span class="hljs-number"&gt;0.0&lt;/span&gt;m,&lt;br/&gt;    duePayableAmou&lt;span class="hljs-symbol"&gt;nt:&lt;/span&gt; summeBrutto&lt;br/&gt;   );&lt;br/&gt;  #endregion&lt;br/&gt; &lt;br/&gt;  return desc;&lt;br/&gt;} 
Anschließend setzt man mit AddNote() weitere Kopfdaten der Rechnung in reiner Textform. Im Feld ReferenceOrderNo kann man die Auftragsnummer speichern, die der Kunde bei seiner Bestellung genannt hat.Zu beachten ist, dass die Property- und Parameternamen in der .NET-Bibliothek zum Teil von den XML-Tags abweichen. So werden aus der Eigenschaft ReferenceOrderNo in der XRechnung die folgenden XML-Tags:

<span class="hljs-tag">&lt;<span class="hljs-name">ram:BuyerOrderReferencedDocument</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">ram:IssuerAssignedID</span>&gt;</span>991-80008-08
    <span class="hljs-tag">&lt;/<span class="hljs-name">ram:IssuerAssignedID</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">ram:BuyerOrderReferencedDocument</span>&gt;</span> 
Bei Rechnungen an Behörden muss (zumindest bisher) über die Property ReferenceOrderNo zwingend die jeweilige Leitweg-ID [27] des Rechnungsempfängers übermittelt werden. Dabei handelt es sich um eine 5- bis 46-stellige Zeichenfolge, inklusive einem oder zwei Bindestrichen, zum Beispiel 991-80008-08 für die Deutsche Bundesbank und 059540036036-31001-59 für die Stadt Witten an der Ruhr. Die Leitweg-ID ermöglicht eine elektronische Adressierung und Weiterleitung der XRechnung durch die zentralen Rechnungseingangsplattformen des Bundes [28] beziehungsweise der Länder (zum Beispiel Bremen unter [29] und Nordrhein-Westfalen unter [30]) an die ERP- beziehungsweise Freigabesysteme der angeschlossenen Behörden und Einrichtungen.Ein öffentlicher Rechnungsempfänger hat mindestens eine Leitweg-ID, es können jedoch mehrere Leitweg-IDs pro In­stitution genutzt werden. Rechnungsaussteller an Behörden benötigen hingegen keine eigene Leitweg-ID.Wenn übrigens Behörden neben der Leitweg-ID in der Bestellung noch eine weitere Bestellnummer angeben, muss diese mit AddNote() hinzugefügt werden.Seit XRechnung 3.0.1 gibt es ein Tag <URIUniversalCommunication>, bei dem man neben der E-Mail-Adresse auch andere Kommunikationsadressen wie zum Beispiel eine Leitweg-ID angeben kann. In Listing 1 sieht man E-Mail-Adressen bei den Zuweisungen SellerElectronicAddress und Buyer­ElectronicAddress. Das Bundesministerium des Innern und für Heimat schreibt dazu in [31]: „Nach Absprache mit Ihrem Lieferanten können Sie auch eine Leitweg-ID … angeben beziehungsweise diese einfordern.“ Das Ministerium selbst macht von der Leitweg-ID keinen Gebrauch, ­sondern legt in [32] und [33] fest, dass immer noch das Feld „BT-10“ (das ist das Tag <BuyerOrderReferencedDocument><Issuer­Assig­nedID>) für die Leitweg-ID verwendet werden muss.Die E-Rechnungsportale des Bundes und der Länder bieten außerdem die Option, eine Rechnung manuell in einer Webmaske zu erfassen und daraus die XRechnung zu generieren und zu versenden. Auch auf verschiedenen Internetseiten findet man XRechnungs-Generatoren, zum Beispiel [34]. Das ist eine Alternative für Unternehmen, die nur sehr selten Rechnungen versenden (etwa Kleingewerbetreibende). Man muss sich aber beim Einsatz solcher Tools bewusst sein, dass der Seitenbetreiber die Rechnungsdaten speichern, einsehen und/oder verwenden könnte.Als Nächstes folgen im Listing 1 Daten über den Rechnungssteller via SetSeller(), SetSellerContact() und SellerElectronic­Address sowie AddSellerTaxRegistration() zur Angabe von nationaler und internationaler Steuernummer. Daran schließen sich dann in entsprechender Weise SetBuyer() und die Befüllung von BuyerElec­tronic­Address für die Daten des Rechnungsempfängers an. Bei Rechnungssteller und Rechnungsempfänger kann man optional eine eindeutige Identifikationsnummer angeben, zum Beispiel wie in Listing 1 gezeigt eine Nummer aus dem Data Universal Numbering System (D-U-N-S) [35].Danach kommen
  • die Zahlungsbedingungen mit SetTradePaymentTerms() mit Angabe in Textform und optional auch mit Datum,
  • die Zahlungsart mit SetPaymentMeans(),
  • das Zielbankkonto mit AddCreditorFinancialAccount(),
  • Steuerinformationen mit AddApplicableTradeTax().
Alle Methoden mit Add im Namen können mehrfach aufgerufen werden, zum Beispiel wenn es mehrere Zielkonten oder verschiedene Steuersätze gibt. Vier Tage vor Fertigstellung dieses Beitrags wurde im Master-Branch des Projekts ZUGFeRD-csharp die Methode AddTradePaymentTerms() ergänzt und SetTradePaymentTerms() auf obsolet gesetzt [36].Die Entwicklung ist im Fluss, denn hier kann man in Deutschland statt einer menschenlesbaren Zeichenkette auch formale Skontobedingungen angeben, zum Beispiel für 3 Prozent Skonto innerhalb von 14 Tagen:

desc.SetTradePaymentTerms(
  <span class="hljs-string">"<span class="hljs-subst">#SKONTO</span><span class="hljs-subst">#TAGE</span>=14<span class="hljs-subst">#PROZENT</span>=3.00# "</span>, zahlbarBis); 
Beziehungsweise dann in der kommenden Version:

desc.AddTradePaymentTerms(
  <span class="hljs-string">"<span class="hljs-subst">#SKONTO</span><span class="hljs-subst">#TAGE</span>=14<span class="hljs-subst">#PROZENT</span>=3.00# "</span>, zahlbarBis); 
Daran schließen sich in Listing 1 die einzelnen Rechnungspositionen mit AddTradeLineItem() jeweils unter Angabe von Text, Menge, Nettopreis, Steuersatz und einem TaxCategoryCode an. Standard ist TaxCategoryCodes.S. Andere sind ­TaxCategoryCodes.AE für Reverse Charge und Tax­Cate­gory­Codes.E für Umsatzsteuerausnahmen. Der Programmcode in Listing 1 zeigt nur eine Fallunterscheidung zwischen Standard (S) und Reverse Charge. Anders als bei einer Papier- und PDF-Rechnung muss der Rechnungssteller für jede Rechnungsposition einzeln den Steuertatbestand deklarieren.Merkwürdig erscheint der UnitCode QuantityCodes.H87. Dies ist die Angabe für „Stück und basiert auf der Empfehlung 20 „Codes for Units of Measure Used in International Trade der United Nations Economic Commission for Europe (UNECE), siehe [37].Eine Rechnungsposition kann auch eine globale Identifikation besitzen, zum Beispiel eine European Article Number (EAN). Dies kommt in Listing 1 nicht vor, weil die dort in Rechnung gestellten Schulungsdienstleistungen und Nebenkosten keine EAN besitzen. Der EAN-Fall soll daher hier noch einmal an einem Beispiel gezeigt werden:

desc.AddTradeLineItem(<span class="hljs-string">name:</span> <span class="hljs-string">"Trennblätter A4"</span>,
  <span class="hljs-string">unitCode:</span> QuantityCodes.H87,
  <span class="hljs-string">sellerAssignedID:</span> <span class="hljs-string">"TB100A4"</span>,
  <span class="hljs-string">id:</span> <span class="hljs-keyword">new</span> GlobalID(GlobalIDSchemeIdentifiers.EAN, 
    <span class="hljs-string">"400004672"</span>),
  <span class="hljs-string">grossUnitPrice:</span> <span class="hljs-number">9.9</span>m,
  <span class="hljs-string">netUnitPrice:</span> <span class="hljs-number">9.9</span>m,
  <span class="hljs-string">billedQuantity:</span> <span class="hljs-number">20</span>m,
  <span class="hljs-string">taxType:</span> TaxTypes.VAT,
  <span class="hljs-string">categoryCode:</span> TaxCategoryCodes.S,
  <span class="hljs-string">taxPercent:</span> <span class="hljs-number">19</span>m
); 
Die Routine zur Erstellung der Instanz von InvoiceDescriptor endet mit dem Setzen der Summenwerte für Netto, Brutto und Umsatzsteuer mit der Methode SetTotals().Hier im Beispiel in Listing 1 sieht man einige konstante Daten aus unserem Unternehmen (www.IT-Visions.de) im Programmcode, die eigentlich in Konfigurationsdaten liegen. Das Inlining dieser Daten als Zeichenketten in Listing 1 dient der besseren Veranschaulichung der Nutzung der Bibliothek. Dynamisch aus der Datenbank geladene Daten (Rechnungsnummer, Rechnungsempfänger, Auftragsdaten, Rechnungspositionen und dergleichen) werden aus einem per Entity Framework befüllten Objektmodell genommen. Hieraus stammen die Typen P_Partner, AG_Angebote und RE_Rechnungen; diese gehören also nicht zur Bibliothek ZUGFeRD-csharp. Die XRechnung, die in Listing 1 erstellt wird, entspricht der PDF-Rechnung aus Bild 1 und dem XRechnung-XML-Dokument, das auszugsweise in Listing 2 dargestellt ist.
Listing 2: Auszüge aus den XML-Inhalten der XRechnung, die in Listing 1 erstellt wurde
&lt;span class="php"&gt;&lt;span class="hljs-meta"&gt;&amp;lt;?&lt;/span&gt;xml version=&lt;span class="hljs-string"&gt;"1.0"&lt;/span&gt; encoding=&lt;span class="hljs-string"&gt;"utf-8"&lt;/span&gt;&lt;span class="hljs-meta"&gt;?&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br/&gt;&lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;rsm:CrossIndustryInvoice&lt;/span&gt; &lt;span class="hljs-attr"&gt;xmlns:a&lt;/span&gt;=&lt;span class="hljs-string"&gt;"urn:un:unece:&lt;/span&gt;&lt;/span&gt;&lt;br/&gt;&lt;span class="hljs-tag"&gt;&lt;span class="hljs-string"&gt;    uncefact:data:standard:QualifiedDataType:100"&lt;/span&gt; &lt;/span&gt;&lt;br/&gt;&lt;span class="hljs-tag"&gt;    &lt;span class="hljs-attr"&gt;xmlns:rsm&lt;/span&gt;=&lt;span class="hljs-string"&gt;"urn:un:unece:uncefact:data:standard:&lt;/span&gt;&lt;/span&gt;&lt;br/&gt;&lt;span class="hljs-tag"&gt;&lt;span class="hljs-string"&gt;    CrossIndustryInvoice:100"&lt;/span&gt; &lt;span class="hljs-attr"&gt;xmlns:qdt&lt;/span&gt;=&lt;span class="hljs-string"&gt;"urn:un:unece:&lt;/span&gt;&lt;/span&gt;&lt;br/&gt;&lt;span class="hljs-tag"&gt;&lt;span class="hljs-string"&gt;    uncefact:data:standard:QualifiedDataType:100"&lt;/span&gt; &lt;/span&gt;&lt;br/&gt;&lt;span class="hljs-tag"&gt;    &lt;span class="hljs-attr"&gt;xmlns:ram&lt;/span&gt;=&lt;span class="hljs-string"&gt;"urn:un:unece:uncefact:data:standard:&lt;/span&gt;&lt;/span&gt;&lt;br/&gt;&lt;span class="hljs-tag"&gt;&lt;span class="hljs-string"&gt;    ReusableAggregateBusinessInformationEntity:100"&lt;/span&gt; &lt;/span&gt;&lt;br/&gt;&lt;span class="hljs-tag"&gt;    &lt;span class="hljs-attr"&gt;xmlns:xs&lt;/span&gt;=&lt;span class="hljs-string"&gt;"http://www.w3.org/2001/XMLSchema"&lt;/span&gt; &lt;/span&gt;&lt;br/&gt;&lt;span class="hljs-tag"&gt;    &lt;span class="hljs-attr"&gt;xmlns:udt&lt;/span&gt;=&lt;span class="hljs-string"&gt;"urn:un:unece:uncefact:data:standard:&lt;/span&gt;&lt;/span&gt;&lt;br/&gt;&lt;span class="hljs-tag"&gt;&lt;span class="hljs-string"&gt;    UnqualifiedDataType:100"&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;  &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;rsm:ExchangedDocumentContext&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;    &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:BusinessProcessSpecifiedDocumentContext&lt;/span&gt;&lt;/span&gt;&lt;br/&gt;&lt;span class="hljs-tag"&gt;        &lt;span class="hljs-attr"&gt;Parameter&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;      &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:ID&lt;/span&gt;&amp;gt;&lt;/span&gt;urn:fdc:peppol.eu:2017:poacc:billing:&lt;br/&gt;        01:1.0&lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:ID&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;    &lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:BusinessProcessSpecifiedDocumentContext&lt;/span&gt;&lt;/span&gt;&lt;br/&gt;&lt;span class="hljs-tag"&gt;      &lt;span class="hljs-attr"&gt;Parameter&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;    &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:GuidelineSpecifiedDocumentContextParameter&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;      &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:ID&lt;/span&gt;&amp;gt;&lt;/span&gt;urn:cen.eu:en16931:2017#compliant#urn:&lt;br/&gt;        xeinkauf.de:kosit:xrechnung_3.0&lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:ID&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;    &lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:GuidelineSpecifiedDocumentContextParameter&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;  &lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;rsm:ExchangedDocumentContext&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;  &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;rsm:ExchangedDocument&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;    &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:ID&lt;/span&gt;&amp;gt;&lt;/span&gt;R-2200718&lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:ID&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;    &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:TypeCode&lt;/span&gt;&amp;gt;&lt;/span&gt;380&lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:TypeCode&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;    &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:IssueDateTime&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;      &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;udt:DateTimeString&lt;/span&gt; &lt;/span&gt;&lt;br/&gt;&lt;span class="hljs-tag"&gt;        &lt;span class="hljs-attr"&gt;format&lt;/span&gt;=&lt;span class="hljs-string"&gt;"102"&lt;/span&gt;&amp;gt;&lt;/span&gt;20240925&lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;udt:DateTimeString&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;    &lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:IssueDateTime&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;    &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:IncludedNote&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;      &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:Content&lt;/span&gt;&amp;gt;&lt;/span&gt;Schulung (In-House): &lt;br/&gt;        Umstieg von .NET 8.0 auf .NET 9.0&lt;br/&gt;        Mo, 23.09.2024 bis Di, 24.09.2024 (2 Tage)&lt;br/&gt;        Ort: Musterstraße 71, 12345 Musterstadt&lt;br/&gt;        &lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:Content&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;    &lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:IncludedNote&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;    &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:IncludedNote&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;      &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:Content&lt;/span&gt;&amp;gt;&lt;/span&gt;Angebotsnummer: A-2101869820&lt;br/&gt;        &lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:Content&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;    &lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:IncludedNote&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;    &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:IncludedNote&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;      &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:Content&lt;/span&gt;&amp;gt;&lt;/span&gt;Ihr Auftrag vom 01.08.2024 &lt;br/&gt;        &lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:Content&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;    &lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:IncludedNote&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;    &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:IncludedNote&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;      &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:Content&lt;/span&gt;&amp;gt;&lt;/span&gt;Ihre Auftragsnummer: 123-4567-89&lt;br/&gt;        &lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:Content&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;    &lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:IncludedNote&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;    &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:IncludedNote&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;      &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:Content&lt;/span&gt;&amp;gt;&lt;/span&gt;Falls Sie mehrere Rechnungen von &lt;br/&gt;        uns erhalten haben, zahlen Sie diese unbedingt &lt;br/&gt;        getrennt unter Angabe der jeweiligen &lt;br/&gt;        Rechnungsnummer, da die Buchhaltung &lt;br/&gt;        vollautomatisiert ist. Zahlungsavis können &lt;br/&gt;        nicht verarbeitet werden.&lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:Content&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;    &lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:IncludedNote&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;    &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:IncludedNote&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;      &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:Content&lt;/span&gt;&amp;gt;&lt;/span&gt;Bitte beachten Sie, dass der &lt;br/&gt;        deutsche Gesetzgeber uns verpflichtet, alle &lt;br/&gt;        Nebenleistungen wie z.B. Reise- und &lt;br/&gt;        Hotelkosten sowie Fachbücher zum gleichen &lt;br/&gt;        Umsatzsteuersatz wie die Hauptleistung weiter &lt;br/&gt;        zu berechnen, selbst wenn dafür ursprünglich &lt;br/&gt;        ein anderer Steuersatz galt.&lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:Content&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;    &lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:IncludedNote&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;  &lt;br/&gt;  ...&lt;br/&gt;  &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;rsm:SupplyChainTradeTransaction&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;    &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:IncludedSupplyChainTradeLineItem&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;      &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:AssociatedDocumentLineDocument&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;        &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:LineID&lt;/span&gt;&amp;gt;&lt;/span&gt;1&lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:LineID&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;      &lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:AssociatedDocumentLineDocument&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;      &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:SpecifiedTradeProduct&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;        &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:Name&lt;/span&gt;&amp;gt;&lt;/span&gt;Individuelle, maßgeschneiderte &lt;br/&gt;          Schulung vor Ort in Ihrem Unternehmen&lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:Name&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;      &lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:SpecifiedTradeProduct&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;      &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:SpecifiedLineTradeAgreement&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;        &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:NetPriceProductTradePrice&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;          &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:ChargeAmount&lt;/span&gt;&amp;gt;&lt;/span&gt;1500.00&lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:ChargeAmount&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;        &lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:NetPriceProductTradePrice&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;      &lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:SpecifiedLineTradeAgreement&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;      &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:SpecifiedLineTradeDelivery&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;        &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:BilledQuantity&lt;/span&gt; &lt;span class="hljs-attr"&gt;unitCode&lt;/span&gt;=&lt;span class="hljs-string"&gt;"H87"&lt;/span&gt;&amp;gt;&lt;/span&gt;2.0000&lt;br/&gt;          &lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:BilledQuantity&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;      &lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:SpecifiedLineTradeDelivery&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;      &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:SpecifiedLineTradeSettlement&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;        &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:ApplicableTradeTax&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;          &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:TypeCode&lt;/span&gt;&amp;gt;&lt;/span&gt;VAT&lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:TypeCode&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;          &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:CategoryCode&lt;/span&gt;&amp;gt;&lt;/span&gt;S&lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:CategoryCode&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;          &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:RateApplicablePercent&lt;/span&gt;&amp;gt;&lt;/span&gt;19.00&lt;br/&gt;            &lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:RateApplicablePercent&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;        &lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:ApplicableTradeTax&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;        &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:SpecifiedTradeSettlementLineMonetary&lt;/span&gt;&lt;/span&gt;&lt;br/&gt;&lt;span class="hljs-tag"&gt;            &lt;span class="hljs-attr"&gt;Summation&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;          &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:LineTotalAmount&lt;/span&gt;&amp;gt;&lt;/span&gt;3000.00&lt;br/&gt;            &lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:LineTotalAmount&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;        &lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:SpecifiedTradeSettlementLineMonetary&lt;/span&gt;&lt;/span&gt;&lt;br/&gt;&lt;span class="hljs-tag"&gt;          &lt;span class="hljs-attr"&gt;Summation&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;      &lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:SpecifiedLineTradeSettlement&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;    &lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:IncludedSupplyChainTradeLineItem&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;    ...&lt;br/&gt;    &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:ApplicableHeaderTradeDelivery&lt;/span&gt; /&amp;gt;&lt;/span&gt;&lt;br/&gt;    &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:ApplicableHeaderTradeSettlement&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;      &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:InvoiceCurrencyCode&lt;/span&gt;&amp;gt;&lt;/span&gt;EUR&lt;br/&gt;        &lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:InvoiceCurrencyCode&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;      &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:SpecifiedTradeSettlementPaymentMeans&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;        &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:TypeCode&lt;/span&gt;&amp;gt;&lt;/span&gt;58&lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:TypeCode&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;        &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:Information&lt;/span&gt;&amp;gt;&lt;/span&gt;Zahlung per &lt;br/&gt;          SEPA-Überweisung.&lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:Information&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;        &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:PayeePartyCreditorFinancialAccount&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;          &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:IBANID&lt;/span&gt;&amp;gt;&lt;/span&gt;DE57360700240109002600&lt;br/&gt;            &lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:IBANID&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;          &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:AccountName&lt;/span&gt;&amp;gt;&lt;/span&gt;Deutsche Bank Essen&lt;br/&gt;            &lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:AccountName&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;        &lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:PayeePartyCreditorFinancialAccount&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;        &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:PayeeSpecifiedCreditorFinancial&lt;/span&gt;&lt;/span&gt;&lt;br/&gt;&lt;span class="hljs-tag"&gt;            &lt;span class="hljs-attr"&gt;Institution&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;          &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:BICID&lt;/span&gt;&amp;gt;&lt;/span&gt;DEUTDEDBESS&lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:BICID&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;        &lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:PayeeSpecifiedCreditorFinancial&lt;/span&gt;&lt;/span&gt;&lt;br/&gt;&lt;span class="hljs-tag"&gt;          &lt;span class="hljs-attr"&gt;Institution&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;      &lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:SpecifiedTradeSettlementPaymentMeans&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;      &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:ApplicableTradeTax&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;        &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:CalculatedAmount&lt;/span&gt;&amp;gt;&lt;/span&gt;658.73&lt;br/&gt;          &lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:CalculatedAmount&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;        &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:TypeCode&lt;/span&gt;&amp;gt;&lt;/span&gt;VAT&lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:TypeCode&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;        &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:BasisAmount&lt;/span&gt;&amp;gt;&lt;/span&gt;3467.00&lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:BasisAmount&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;        &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:CategoryCode&lt;/span&gt;&amp;gt;&lt;/span&gt;S&lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:CategoryCode&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;        &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:RateApplicablePercent&lt;/span&gt;&amp;gt;&lt;/span&gt;19.00&lt;br/&gt;          &lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:RateApplicablePercent&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;      &lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:ApplicableTradeTax&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;      &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:SpecifiedTradePaymentTerms&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;        &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:Description&lt;/span&gt;&amp;gt;&lt;/span&gt;Bitte überweisen Sie den &lt;br/&gt;          Betrag binnen 10 Tagen ohne Abzüge auf unten &lt;br/&gt;          genanntes Konto. Bitte beachten Sie, dass &lt;br/&gt;          Sie nach §286 BGB automatisch in Verzug &lt;br/&gt;          kommen.&lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:Description&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;        &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:DueDateDateTime&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;          &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;udt:DateTimeString&lt;/span&gt; &lt;span class="hljs-attr"&gt;format&lt;/span&gt;=&lt;span class="hljs-string"&gt;"102"&lt;/span&gt;&amp;gt;&lt;/span&gt;20241005&lt;br/&gt;            &lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;udt:DateTimeString&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;        &lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:DueDateDateTime&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;      &lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:SpecifiedTradePaymentTerms&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;      &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:SpecifiedTradeSettlementHeaderMonetary&lt;/span&gt;&lt;/span&gt;&lt;br/&gt;&lt;span class="hljs-tag"&gt;          &lt;span class="hljs-attr"&gt;Summation&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;        &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:LineTotalAmount&lt;/span&gt;&amp;gt;&lt;/span&gt;3467.00&lt;br/&gt;          &lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:LineTotalAmount&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;        &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:ChargeTotalAmount&lt;/span&gt;&amp;gt;&lt;/span&gt;0.00&lt;br/&gt;          &lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:ChargeTotalAmount&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;        &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:AllowanceTotalAmount&lt;/span&gt;&amp;gt;&lt;/span&gt;0.00&lt;br/&gt;          &lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:AllowanceTotalAmount&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;        &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:TaxBasisTotalAmount&lt;/span&gt;&amp;gt;&lt;/span&gt;3467.00&lt;br/&gt;          &lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:TaxBasisTotalAmount&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;        &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:TaxTotalAmount&lt;/span&gt; &lt;span class="hljs-attr"&gt;currencyID&lt;/span&gt;=&lt;span class="hljs-string"&gt;"EUR"&lt;/span&gt;&amp;gt;&lt;/span&gt;658.73&lt;br/&gt;          &lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:TaxTotalAmount&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;        &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:GrandTotalAmount&lt;/span&gt;&amp;gt;&lt;/span&gt;4125.73&lt;br/&gt;          &lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:GrandTotalAmount&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;        &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:TotalPrepaidAmount&lt;/span&gt;&amp;gt;&lt;/span&gt;0.00&lt;br/&gt;          &lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:TotalPrepaidAmount&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;        &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;ram:DuePayableAmount&lt;/span&gt;&amp;gt;&lt;/span&gt;4125.73&lt;br/&gt;          &lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:DuePayableAmount&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;      &lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:SpecifiedTradeSettlementHeaderMonetary&lt;/span&gt;&lt;/span&gt;&lt;br/&gt;&lt;span class="hljs-tag"&gt;        &lt;span class="hljs-attr"&gt;Summation&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;    &lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;ram:ApplicableHeaderTradeSettlement&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;  &lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;rsm:SupplyChainTradeTransaction&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;&lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;rsm:CrossIndustryInvoice&lt;/span&gt;&amp;gt;&lt;/span&gt;  

Speichern der elektronischen Rechnung

Eine elektronische Rechnung speichert man ganz einfach ins Dateisystem, indem man in der Klasse InvoiceDescriptor die Methode Save() aufruft. Dabei kann man die gewünschte ZUGFeRD-Version und das Profil angeben, hier als Beispiel XRechnung:

<span class="hljs-selector-tag">desc</span><span class="hljs-selector-class">.Save</span>(<span class="hljs-selector-tag">ZielXMLPath</span>, <span class="hljs-selector-tag">ZUGFeRDVersion</span><span class="hljs-selector-class">.Version22</span>, 
  <span class="hljs-selector-tag">s2industries</span><span class="hljs-selector-class">.ZUGFeRD</span><span class="hljs-selector-class">.Profile</span><span class="hljs-selector-class">.XRechnung</span>); 
Das Profil für EN 16931 heißt in der Profile-Enumeration noch Comfort. Alternativ kann mit die XML-Daten bei Save() an ein Objekt des Typs System.IO.Stream übergeben und dann zum Beispiel per Netzwerk versenden.

<span class="hljs-selector-tag">desc</span><span class="hljs-selector-class">.Save</span>(<span class="hljs-selector-tag">stream</span>, <span class="hljs-selector-tag">ZUGFeRDVersion</span><span class="hljs-selector-class">.Version22</span>, <span class="hljs-selector-tag">s2industries</span>.
  <span class="hljs-selector-tag">ZUGFeRD</span><span class="hljs-selector-class">.Profile</span><span class="hljs-selector-class">.XRechnung</span>, <span class="hljs-selector-tag">ZUGFeRDFormats</span><span class="hljs-selector-class">.UBL</span>); 
Bei dieser Überladung von Save() kann man auch für XRechnung das Unterformat UBL mit Wurzeltag <Invoice> wählen. Das Save(), das in eine XML-Datei speichert, erzeugt immer das Unterformat CII mit Wurzeltag <CrossIndustryInvoice>.Für das Anhängen der XML-Datei an ein PDF bietet die Bibliothek ZUGFeRD-csharp leider keine eigene Lösung. Hier greift man zum Beispiel auf die kostenfreie Community-Lösung PdfSharp [38] zurück. Der Name des Anhangs sollte xrechnung.xml sein:

<span class="hljs-attribute">var ZielPDFDateiname</span> = PDFDateiname.Replace(<span class="hljs-string">".pdf"</span>, 
  <span class="hljs-string">".ZUGFeRD.pdf"</span>);
<span class="hljs-attribute">s</span><span class="hljs-attribute">t</span><span class="hljs-attribute">r</span><span class="hljs-attribute">i</span><span class="hljs-attribute">n</span><span class="hljs-attribute">g</span> <span class="hljs-attribute">Z</span><span class="hljs-attribute">i</span><span class="hljs-attribute">e</span><span class="hljs-attribute">l</span><span class="hljs-attribute">P</span><span class="hljs-attribute">D</span><span class="hljs-attribute">F</span><span class="hljs-attribute">P</span><span class="hljs-attribute">f</span><span class="hljs-attribute">a</span><span class="hljs-attribute">d</span> = $@<span class="hljs-string">"I:\Rechnungswesen\" +</span>
<span class="hljs-string">  "</span>AusgehendeRechnungen\{jahr}\{ZielPDFDateiname}<span class="hljs-string">";</span>
<span class="hljs-string">PdfDocument document = PdfReader.Open(PDFPfad);</span>
<span class="hljs-string">document.AddEmbeddedFile("</span>xrechnung.xml<span class="hljs-string">", </span>
<span class="hljs-string">  ZielXMLPfad);</span>
<span class="hljs-string">document.Save(ZielPDFPfad);</span> 
Ausschnitte aus dem resultierenden umfangreichen XRechnung-XML-Dokument zeigt Listing 2, das Sie in vollständiger Fassung in den Downloads zum Artikel finden.

Einlesen einer elektronischen Rechnung

Das Einlesen einer eingehenden E-Invoice in XML-Form erfolgt in einer Zeile via Load() aus einem Stream oder einer Datei:

<span class="hljs-attribute">InvoiceDescriptor desc</span> = 
  InvoiceDescriptor.Load(XMLPath); 
Sofern das ohne Laufzeitfehler klappt, ist die Datei strukturell in Ordnung. Nun kann man auf die zahlreichen Eigenschaften des InvoiceDescriptor-Objekts zugreifen, zum Beispiel
  • desc.Seller.Name
  • desc.TradeLineItems
  • desc.TaxTotalAmount
  • desc.GrandTotalAmount
Allerdings prüft ZUGFeRD-csharp nicht inhaltliche Korrektheit. Die Startseite des Projekts auf GitHub listet drei Punkte auf, die in ZUGFeRD-csharp fehlen:
  • Validierung mithilfe des Standard-XSL (die die KoSIT unter [39] bereitstellt)
  • Vollständige Unterstützung des UBL-Formats (Lesen und Schreiben). Im Test konnte jedoch mit ZUGFeRD-csharp in der bei Abfassung dieses Artikels aktuellen Version 14.1 die von der KoSIT bereitgestellte aktuellste Muster-UBL-Datei 03.06a-INVOICE_ubl.xml ohne Fehler eingelesen werden.
  • Rechnungsvisualisierung
Es gibt aber XRechnungs-Validatoren im Netz ohne Anmeldepflicht, zum Beispiel beim Land Baden-Württemberg [40]. So beschwert sich dieser Validator zum Beispiel über eine XRechnung, die aus diesem Code entsteht:

desc.AddApplicableTradeTax(basisAmount: summeNetto,
  percent: (decimal)re.UST_Satz, <span class="hljs-regexp">//</span> <span class="hljs-number">19.0</span> oder <span class="hljs-number">7.0</span>
  typeCode: TaxTypes.VAT, <span class="hljs-regexp">//</span> Umsatzsteuer
  categoryCode: TaxCategoryCodes.S, 
    <span class="hljs-regexp">//</span> <span class="hljs-string">"Standard Tax Rate"</span>
  exemptionReason: <span class="hljs-string">"Bitte beachten Sie, dass der </span>
<span class="hljs-string">    deutsche Gesetzgeber uns verpflichtet, alle </span>
<span class="hljs-string">    Nebenleistungen wie zum Beispiel Reise- und </span>
<span class="hljs-string">    Hotelkosten sowie Fachbücher zum gleichen </span>
<span class="hljs-string">    Umsatzsteuersatz wie die Hauptleistung weiter zu </span>
<span class="hljs-string">    berechnen, selbst wenn dafür ursprünglich ein </span>
<span class="hljs-string">    anderer Steuersatz galt."</span>
); 
Es gibt damit im Validator die Fehlermeldung in Bild 3. Richtig ist: Der Hinweis zum Steuersatz muss mit AddNote() übergeben werden, wie Listing 1 zeigt. Dann ist der Validator zufrieden, siehe Bild 4. Im Prüfbericht erhält man auf Wunsch ein visuelles Ergebnis. Der Validator erkennt mathematische Fehler, also wenn zum Beispiel bei einer Rechnungszeile der ­<LineTotalAmount> nicht dem Produkt aus <ChargeAmount> und <BilledQuantity> entspricht. AddTradeLineItem() in der Bibliothek ZUGFeRD-csharp beschwert sich aber nicht, wenn man bei der Eingabe einen derartigen Fehler macht.
Der XRechnung-Validator mag nicht, dass man einen Text in das Tag geschrieben hat, wenn auf „S“ (Standard) gesetzt wurde (Bild 3) © Autor
Der XRechnung-Validator des Landes Baden-Württemberg ist einverstanden mit der XRechnung (Bild 4) © Autor

XRechnung aus PDF extrahieren

Wenn man keine eigenständige XML-Datei, sondern eine PDF-Datei mit Anhang erhält, muss man wieder auf eine PDF-Bibliothek zurückgreifen. PdfSharp bietet hier leider keine Lösung. Listing 3 zeigt das Extrahieren aller Anhänge aus einer PDF-Datei mit PDFClown [41]. Die Methode Extract­Attachments() liefert ein Byte-Array zurück, das man dann in einen MemoryStream geben kann, den man wiederum mit der Klasse InvoiceDescriptor laden kann:
Listing 3: Extrahieren aller Anhänge aus einer PDF-Datei mit PDFClown
&lt;span class="hljs-keyword"&gt;using&lt;/span&gt; &lt;span class="hljs-type"&gt;System&lt;/span&gt;;&lt;br/&gt;&lt;span class="hljs-keyword"&gt;using&lt;/span&gt; &lt;span class="hljs-type"&gt;System&lt;/span&gt;.&lt;span class="hljs-type"&gt;Collections&lt;/span&gt;.&lt;span class="hljs-type"&gt;Generic&lt;/span&gt;;&lt;br/&gt;&lt;span class="hljs-keyword"&gt;using&lt;/span&gt; org.pdfclown.documents;&lt;br/&gt;&lt;span class="hljs-keyword"&gt;using&lt;/span&gt; org.pdfclown.documents.files;&lt;br/&gt;&lt;span class="hljs-keyword"&gt;using&lt;/span&gt; org.pdfclown.documents.interaction.annotations;&lt;br/&gt;&lt;span class="hljs-keyword"&gt;using&lt;/span&gt; org.pdfclown.objects;&lt;br/&gt; &lt;br/&gt;namespace &lt;span class="hljs-type"&gt;ITVisions&lt;/span&gt;;&lt;br/&gt; &lt;br/&gt;internal class &lt;span class="hljs-type"&gt;PDFUtil&lt;/span&gt;&lt;br/&gt;{&lt;br/&gt;  /// &amp;lt;summary&amp;gt;&lt;br/&gt;  /// &lt;span class="hljs-type"&gt;Extrahieren&lt;/span&gt; aller &lt;span class="hljs-type"&gt;Anh&lt;/span&gt;änge aus einer &lt;span class="hljs-type"&gt;PDF&lt;/span&gt;-&lt;span class="hljs-type"&gt;Datei&lt;/span&gt;   &lt;br/&gt;  /// mit &lt;span class="hljs-type"&gt;PDFClown&lt;/span&gt; (https://pdfclown.org/)&lt;br/&gt;  /// &amp;lt;/summary&amp;gt;&lt;br/&gt;  /// &amp;lt;param name=&lt;span class="hljs-string"&gt;"pdfPath"&lt;/span&gt;&amp;gt;&amp;lt;/param&amp;gt;&lt;br/&gt;  /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;br/&gt;  public &lt;span class="hljs-type"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span class="hljs-built_in"&gt;string&lt;/span&gt;, byte[]&amp;gt; &lt;br/&gt;      &lt;span class="hljs-type"&gt;ExtractAttachments&lt;/span&gt;(&lt;span class="hljs-built_in"&gt;string&lt;/span&gt; pdfPath)&lt;br/&gt;  {&lt;br/&gt;    &lt;span class="hljs-type"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span class="hljs-built_in"&gt;string&lt;/span&gt;, byte[]&amp;gt; allAttachments = &lt;br/&gt;      new &lt;span class="hljs-type"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span class="hljs-built_in"&gt;string&lt;/span&gt;, byte[]&amp;gt;();&lt;br/&gt;    &lt;span class="hljs-type"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span class="hljs-built_in"&gt;string&lt;/span&gt;, byte[]&amp;gt; documentAttachments = &lt;br/&gt;      new &lt;span class="hljs-type"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span class="hljs-built_in"&gt;string&lt;/span&gt;, byte[]&amp;gt;();&lt;br/&gt;    &lt;span class="hljs-type"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span class="hljs-built_in"&gt;string&lt;/span&gt;, byte[]&amp;gt; pageAttachments = &lt;br/&gt;      new &lt;span class="hljs-type"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span class="hljs-built_in"&gt;string&lt;/span&gt;, byte[]&amp;gt;();&lt;br/&gt;  &lt;br/&gt;    &lt;span class="hljs-keyword"&gt;using&lt;/span&gt; (org.pdfclown.files.&lt;span class="hljs-type"&gt;File&lt;/span&gt; file = &lt;br/&gt;        new org.pdfclown.files.&lt;span class="hljs-type"&gt;File&lt;/span&gt;(pdfPath))&lt;br/&gt;    {&lt;br/&gt;      &lt;span class="hljs-type"&gt;Document&lt;/span&gt; document = file.&lt;span class="hljs-type"&gt;Document&lt;/span&gt;;&lt;br/&gt; &lt;br/&gt;      // &lt;span class="hljs-number"&gt;1&lt;/span&gt;. &lt;span class="hljs-type"&gt;Embedded&lt;/span&gt; files (document level).&lt;br/&gt;      foreach (&lt;span class="hljs-type"&gt;KeyValuePair&lt;/span&gt;&amp;lt;&lt;span class="hljs-type"&gt;PdfString&lt;/span&gt;, &lt;br/&gt;          &lt;span class="hljs-type"&gt;FileSpecification&lt;/span&gt;&amp;gt; entry &lt;br/&gt;          &lt;span class="hljs-keyword"&gt;in&lt;/span&gt; document.&lt;span class="hljs-type"&gt;Names&lt;/span&gt;.&lt;span class="hljs-type"&gt;EmbeddedFiles&lt;/span&gt;)&lt;br/&gt;      {&lt;br/&gt;        &lt;span class="hljs-type"&gt;EvaluateDataFile&lt;/span&gt;(documentAttachments, &lt;br/&gt;          entry.&lt;span class="hljs-type"&gt;Value&lt;/span&gt;);&lt;br/&gt;      }&lt;br/&gt;      &lt;span class="hljs-type"&gt;Console&lt;/span&gt;.&lt;span class="hljs-type"&gt;WriteLine&lt;/span&gt;(&lt;br/&gt;        &lt;span class="hljs-string"&gt;"PDF-Anhänge auf Dokumentebene: "&lt;/span&gt; + &lt;br/&gt;        documentAttachments.&lt;span class="hljs-type"&gt;Count&lt;/span&gt;);&lt;br/&gt; &lt;br/&gt;      // &lt;span class="hljs-number"&gt;2&lt;/span&gt;. &lt;span class="hljs-type"&gt;File&lt;/span&gt; attachments (page level).&lt;br/&gt;      foreach (org.pdfclown.documents.&lt;span class="hljs-type"&gt;Page&lt;/span&gt; page &lt;span class="hljs-keyword"&gt;in&lt;/span&gt; &lt;br/&gt;          document.&lt;span class="hljs-type"&gt;Pages&lt;/span&gt;)&lt;br/&gt;      {&lt;br/&gt;        foreach (org.pdfclown.documents.interaction.&lt;br/&gt;            annotations.&lt;span class="hljs-type"&gt;Annotation&lt;/span&gt; annotation &lt;span class="hljs-keyword"&gt;in&lt;/span&gt; &lt;br/&gt;            page.&lt;span class="hljs-type"&gt;Annotations&lt;/span&gt;)&lt;br/&gt;        {&lt;br/&gt;          &lt;span class="hljs-keyword"&gt;if&lt;/span&gt; (annotation &lt;span class="hljs-keyword"&gt;is&lt;/span&gt; &lt;span class="hljs-type"&gt;FileAttachment&lt;/span&gt;)&lt;br/&gt;          { &lt;span class="hljs-type"&gt;EvaluateDataFile&lt;/span&gt;(pageAttachments, &lt;br/&gt;            ((&lt;span class="hljs-type"&gt;FileAttachment&lt;/span&gt;)annotation).&lt;span class="hljs-type"&gt;DataFile&lt;/span&gt;); }&lt;br/&gt;        }&lt;br/&gt;      }&lt;br/&gt;      &lt;span class="hljs-type"&gt;Console&lt;/span&gt;.&lt;span class="hljs-type"&gt;WriteLine&lt;/span&gt;(&lt;span class="hljs-string"&gt;"PDF-Anhänge auf Seitenebene: "&lt;/span&gt; &lt;br/&gt;        + pageAttachments.&lt;span class="hljs-type"&gt;Count&lt;/span&gt;);&lt;br/&gt;    }&lt;br/&gt;    allAttachments.&lt;span class="hljs-type"&gt;AddRange&lt;/span&gt;(documentAttachments);&lt;br/&gt;    allAttachments.&lt;span class="hljs-type"&gt;AddRange&lt;/span&gt;(pageAttachments);&lt;br/&gt; &lt;br/&gt;    &lt;span class="hljs-type"&gt;Console&lt;/span&gt;.&lt;span class="hljs-type"&gt;WriteLine&lt;/span&gt;(&lt;span class="hljs-string"&gt;"PDF-Anhänge insgesamt: "&lt;/span&gt; + &lt;br/&gt;      allAttachments.&lt;span class="hljs-type"&gt;Count&lt;/span&gt;);&lt;br/&gt; &lt;br/&gt;    &lt;span class="hljs-keyword"&gt;return&lt;/span&gt; allAttachments;&lt;br/&gt;  }&lt;br/&gt;  &lt;br/&gt;  private &lt;span class="hljs-built_in"&gt;void&lt;/span&gt; &lt;span class="hljs-type"&gt;EvaluateDataFile&lt;/span&gt;(&lt;span class="hljs-type"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span class="hljs-built_in"&gt;string&lt;/span&gt;, &lt;br/&gt;      byte[]&amp;gt; attachments, &lt;span class="hljs-type"&gt;FileSpecification&lt;/span&gt; dataFile)&lt;br/&gt;  {&lt;br/&gt;    &lt;span class="hljs-keyword"&gt;if&lt;/span&gt; (dataFile &lt;span class="hljs-keyword"&gt;is&lt;/span&gt; &lt;span class="hljs-type"&gt;FullFileSpecification&lt;/span&gt;)&lt;br/&gt;    {&lt;br/&gt;      &lt;span class="hljs-type"&gt;EmbeddedFile&lt;/span&gt; embeddedFile = &lt;br/&gt;        ((&lt;span class="hljs-type"&gt;FullFileSpecification&lt;/span&gt;)dataFile).&lt;span class="hljs-type"&gt;EmbeddedFile&lt;/span&gt;;&lt;br/&gt;      &lt;span class="hljs-keyword"&gt;if&lt;/span&gt; (embeddedFile != null)&lt;br/&gt;      { attachments[dataFile.&lt;span class="hljs-type"&gt;Path&lt;/span&gt;] = &lt;br/&gt;        embeddedFile.&lt;span class="hljs-type"&gt;Data&lt;/span&gt;.&lt;span class="hljs-type"&gt;ToByteArray&lt;/span&gt;(); }&lt;br/&gt;    }&lt;br/&gt;  }&lt;br/&gt;} 

<span class="hljs-keyword">var</span> attachments = 
  <span class="hljs-keyword">new</span><span class="hljs-type"></span> PDFUtil().ExtractAttachments(ZielPDFPfad);
<span class="hljs-keyword">var</span> xRechnungAttachment = attachments.FirstOrDefault(
  x =&gt; x.Key.ToLower().Contains(<span class="hljs-string">"xrechnung.xml"</span>));
<span class="hljs-keyword">using</span> (<span class="hljs-keyword">var</span> stream = 
    <span class="hljs-keyword">new</span><span class="hljs-type"></span> MemoryStream(xRechnungAttachment.Value))
{
  <span class="hljs-keyword">var</span> desc = InvoiceDescriptor.Load(stream);
  <span class="hljs-comment">// Weiterverarbeitung der Daten</span>
<span class="hljs-comment">}</span> 
Leider ist PDFClown etwas in die Jahre gekommen, und in der Dokumentation lässt sich auch nicht finden, wie man PDF-Anhänge damit erstellen kann. Wenn Sie sich wünschen, für das Einbetten und das Extrahieren von PDF-Anhängen nicht zwei verschiedene Open-Source-Bibliotheken verwenden zu müssen, dann könnten Sie kommerzielle Lösungen wie TextControl [42], iTextSharp [43], iText Core [44] oder Aspose.PDF [45] in Betracht ziehen, die jeweils beide Wege beherrschen.

Fazit

Dank der kostenfreien Lösung ZUGFeRD-csharp ist das Erstellen und Auslesen von strukturierten elektronischen Rechnungen in .NET-Anwendungen sehr einfach. Auch für das Anhängen von XML-Rechnungen an PDF-Dokumenten beziehungsweise die Extraktion gibt es kostenfreie Commu­nity-Lösungen.Da XRechnung bei den Behörden Pflicht ist und ZUGFeRD auch ein Profil für XRechnung bietet, zeichnet sich ab, dass sich das XML-Format von XRechnung durchsetzen wird. Spannend bleibt die Frage, was sich behaupten wird: Reines XML oder PDF mit XML-Anhang (also ZUGFeRD) sowie bei den XRechnung-Formaten UBL oder CII.
Projektdateien herunterladen

Fussnoten

  1. [1] o.tel.o communications bei Wikipedia, http://www.dotnetpro.de/SL2501DataAccess1
  2. [2] Holger Schwichtenberg, Internet Bill Presentment and Payment als neue Form des Electronic Billing, Diplomarbeit 1998, http://www.dotnetpro.de/SL2501DataAccess2
  3. [3] Electronic data interchange bei Wikipedia, http://www.dotnetpro.de/SL2501DataAccess3
  4. [4] nwb Datenbank: Umsatzsteuer; Vereinfachung der elektronischen Rechnungsstellung zum 1. Juli 2011 durch das Steuervereinfachungsgesetz 2011, http://www.dotnetpro.de/SL2501DataAccess4
  5. [5] avanade, Künstliche Intelligenz für Rechnungen, http://www.dotnetpro.de/SL2501DataAccess5
  6. [6] InvoiceNet, Deep neural network to extract intelligent information from invoice documents, http://www.dotnetpro.de/SL2501DataAccess6
  7. [7] Forum elektronische Rechnung Deutschland, https://www.ferd-net.de
  8. [8] Aloaha SDK, Skonto und Verzugszinsen, http://www.dotnetpro.de/SL2501DataAccess7
  9. [9] KoSIT, https://www.xoev.de
  10. Koordinierungsstelle für IT-Standards, XRechnung Test Suite, http://www.dotnetpro.de/SL2501DataAccess8
  11. Bundesgesetzblatt, Wachstumschancengesetz 2024, http://www.dotnetpro.de/SL2501DataAccess9
  12. European Commission, ViDA, http://www.dotnetpro.de/SL2501DataAccess10
  13. BMI, Der Übertragungskanal Peppol, http://www.dotnetpro.de/SL2501DataAccess11
  14. Sage-Lexikon, E-Rechnung, http://www.dotnetpro.de/SL2501DataAccess12
  15. Haufe Online, Verpflichtung zur elektronischen Rechnung, http://www.dotnetpro.de/SL2501DataAccess13
  16. Prototype Fund, https://prototypefund.de
  17. Quba-Quellcode auf GitHub, http://www.dotnetpro.de/SL2501DataAccess14
  18. Quba E-Rechnungs-View, https://quba-viewer.org
  19. Validator für XRechnung, http://www.dotnetpro.de/SL2501DataAccess15
  20. ZUGFeRD.NET, https://konik.io
  21. ZUGFeRD.NET bei NuGet, http://www.dotnetpro.de/SL2501DataAccess16
  22. Aloaha ZUGFeRD SDK, https://www.zugferdpro.com
  23. Aloaha ZUGFeRD SDK bei NuGet, http://www.dotnetpro.de/SL2501DataAccess17
  24. ZUGFeRD-csharp, http://www.dotnetpro.de/SL2501DataAccess18
  25. ZUGFeRD-csharp bei NuGet, http://www.dotnetpro.de/SL2501DataAccess19
  26. ZUGFeRD, Open-Source Libraries and Tools, http://www.dotnetpro.de/SL2501DataAccess20
  27. BMI, FAQ zum Thema Leitweg-ID, http://www.dotnetpro.de/SL2501DataAccess21
  28. ZRE, https://xrechnung.bund.de
  29. Bremer E-Rechnungsportal, https://www.e-rechnung.bremen.de
  30. E-Rechnungsportal in NRW, https://erechnung.nrw
  31. BMI, Neue Version Standard XRechnung 3.0.1 verfügbar, http://www.dotnetpro.de/SL2501DataAccess22
  32. BBMI, E-Rechnung für Rechnungssteller der Bundesverwaltung, http://www.dotnetpro.de/SL2501DataAccess23
  33. BMI, Übersicht über die BT-Felder der OZG-RE, http://www.dotnetpro.de/SL2501DataAccess24
  34. Manfred Durm, XRechnung nach aktuellem Standard erstellen, https://xrechnung-erstellen.com
  35. Dun & Bradstreet, Data Universal Numbering System, https://www.dnb.com/duns-number.html
  36. Klasse InvoiceDescriptor in ZUGFeRD-csharp auf GitHub, http://www.dotnetpro.de/SL2501DataAccess25
  37. UNECE-Recommendation No. 20, http://www.dotnetpro.de/SL2501DataAccess26
  38. PdfSharp, https://www.pdfsharp.net
  39. GitHub-Seite der Koordinierungsstelle für IT-Standards, https://github.com/itplr-kosit
  40. Land Baden-Württemberg, E-Rechnungs-Validator, http://www.dotnetpro.de/SL2501DataAccess27
  41. PDFClown, https://pdfclown.org
  42. TextControl, https://www.textcontrol.com
  43. iTextSharp, https://itextpdf.com/products/itextsharp
  44. iText Core, https://itextpdf.com/products/itext-core
  45. Aspose.PDF, https://products.aspose.com/pdf/
  46. Manfred Durm, Zahlen mit Code, https://zahlen-mit-code.com

Neueste Beiträge

DWX hakt nach: Wie stellt man Daten besonders lesbar dar?
Dass das Design von Websites maßgeblich für die Lesbarkeit der Inhalte verantwortlich ist, ist klar. Das gleiche gilt aber auch für die Aufbereitung von Daten für Berichte. Worauf besonders zu achten ist, erklären Dr. Ina Humpert und Dr. Julia Norget.
3 Minuten
27. Jun 2025
DWX hakt nach: Wie gestaltet man intuitive User Experiences?
DWX hakt nach: Wie gestaltet man intuitive User Experiences? Intuitive Bedienbarkeit klingt gut – doch wie gelingt sie in der Praxis? UX-Expertin Vicky Pirker verrät auf der Developer Week, worauf es wirklich ankommt. Hier gibt sie vorab einen Einblick in ihre Session.
4 Minuten
27. Jun 2025
„Sieh die KI als Juniorentwickler“
CTO Christian Weyer fühlt sich jung wie schon lange nicht mehr. Woran das liegt und warum er keine Angst um seinen Job hat, erzählt er im dotnetpro-Interview.
15 Minuten
27. Jun 2025
Miscellaneous

Das könnte Dich auch interessieren

UIs für Linux - Bedienoberflächen entwickeln mithilfe von C#, .NET und Avalonia
Es gibt viele UI-Frameworks für .NET, doch nur sehr wenige davon unterstützen Linux. Avalonia schafft als etabliertes Open-Source-Projekt Abhilfe.
16 Minuten
16. Jun 2025
Mythos Motivation - Teamentwicklung
Entwickler bringen Arbeitsfreude und Engagement meist schon von Haus aus mit. Diesen inneren Antrieb zu erhalten sollte für Führungskräfte im Fokus stehen.
13 Minuten
19. Jan 2017
Evolutionäres Prototyping von Business-Apps - Low Code/No Code und KI mit Power Apps
Microsoft baut Power Apps zunehmend mit Features aus, um die Low-Code-/No-Code-Welt mit der KI und der professionellen Programmierung zu verbinden.
19 Minuten
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige