XRechnungen erstellen und einlesen

Gut gemacht. :+1: Die Email mit Ubuntus Thunderbird gelingt nur dann, wenn man außer Steuerzeichen auch noch die Kommas weglässt, ansonsten ist schon nach “Sehr geehrte Damen und Herren” schluss. Das ist total kaputt.

Hallo Robert,

Die gerade frisch heruntergeladene Version läuft bei mir erstmal problemlos unter Win10 und Thunderbird.


Zwei Punkte muss ich für mich ändern/ erweitern/ anders lösen:

  • Einmal brauche ich eine Art Katalognummer sichtbar in der Rechnung (PDF). Abgesehen von Gewohnheiten ermöglicht mir die Katalognummer den Zugriff auf verschiedene Übersetzungen der Objektbeschreibung im Rechnungstext. Du nutzt die Zeilennummer auch als Objektidentifikation im XML, was ich so nicht machen würde.
      <cac:Item>
         <cbc:Description>Tintenkartusche cyan</cbc:Description>
         <cbc:Name>Tintenkartusche cyan</cbc:Name>
         <cac:SellersItemIdentification>
            <cbc:ID>9</cbc:ID>
         </cac:SellersItemIdentification>

Die Zeilennummer eignet sich meiner Ansicht nach nicht als “SellersItemIdentification” und die direkte Verwendung der ID schränkt Katalognummern ein. Ich brauch schon Codes wie 1234a, andere Bestellsysteme mögen 1234-aca-xyz-54321 und ähnliches nehmen.

  • Eher im Thema Erweiterungen steht das Problem mit der Mehrwertsteuerberechnung zwischen Unternehmen in der EG. Innerhalb Deutschlands weisen wir die Steuer aus und der Rechnungsempfänger verbucht das entsprechend. Bei Unternehmen mit entsprechend geprüfter Steuer-Id innerhalb der EG wird dagegen auf der Rechnung keine Mehrwertsteuer ausgewiesen. Bisher speichern wir daher nur die Steuer-Ids von Unternehmen, die zur “Steuerbefreiung” berechtigen im System und generieren dann Rechnungen mit 0% Mehrwertsteuer/VAT. (Ob das noch so einfach funktioniert, wenn eingehende XRechnungen uns automatisch alle möglichen Steuer-Ids liefern, muss ich mal abwarten… Eine automatische Prüfung der Nummern vor Rechnungsstellung ist wohl ebenfalls sinnvoll: Vies on-the-Web - European Commission

@Wanderer : SellersItemIdentification - Das, was ich da als einfaches System zusammengebaut habe, hat nicht einmal eine Warenverwaltung dabei. Ansonsten würde ich da sicher die entsprechende Warennummer aus dem System nehmen - im Prinzip so etwas wie eine Bestellnummer. Ich habe das eben so einfach wie möglich gehalten. Damit finde ich die Rechung und die Nummerierung innerhalb der Rechnung (die durch den Primärschlüssel gewährleistet wird). Ich kann da natürlich noch ein Feld (für die freiwillige Eingabe einer “Bestellnummer”) einbauen. Entsprechend würde, wenn in dem Feld nichts steht, die Zeilennummer genommen.

Von den ganzen Steuergeschichten habe ich überhaupt keine Ahnung. Ich kenne nur das an Rechnungen, was ich als Privatperson bekomme und das, was Firmen, für die ich eine Datenbank bisher erstellt habe, selbst stellen. Das war bisher alles innerhalb von Deutschland. 0% lässt sich zur Zeit ja locker als Steuersatz in die Rechnung eintragen. Was ich also mit irgendwelchen Steuernummern von Firmen anfangen soll - keine Ahnung. Reicht da eine Tabelle mit SteuerIDs, bei denen dann der Steuersatz auch noch verzeichnet ist? Haben die SteuerIDs eine bstimmte Form (wie bei mir privat die Trennung 3 Zahlen - 4 Zahlen - 4 Zahlen)?

Nachtrag: Das mit den Bestellnummern (oder wie immer die heißen) habe ich direkt mit eingebaut. Dabei auch noch einen kleinen Makrofehler beseitigt, der bei der Eingabe von Rechnungsposten auftauchte. Die Nummern müssten jetzt in der X-Rechnung satt der Zeilennummer auftauchen, falls diese Bestellnummern vergeben wurden. In der normalen Rechnung tauchen sie als separater Absatz bei den Waren auf.

Im Prinzip ja, Du brauchst nicht einmal den Steuersatz, es geht nur um 1 Flag: Die Steuernummer ist gültig. Eventuell kann es sinnvoll sein, das Datum der Gültigkeitsprüfung zu speichern.

Mit einer Formatprüfung kommt man nicht weiter. Jedes Land hat seine eigenen Besonderheiten unsere (DE) sind numerisch daher steht da meist etwas wie DE 123 456 789 aber in Österreich beginnen die mit U, so dass wir ATU1234567 sehen.
.
Das eigentliche “Problem” ist, dass es um die aktuelle Gültigkeit geht. Ich kann also z.B. nicht davon ausgehen, dass jemand der vor 2 Jahren als Händler eingekauft hat immer noch diese Nummer nutzen darf. Er könnte inzwischen verkauft haben, in Rente sein, den Firmensitz verlegen…
.
Link aus Österreich, ist aber EG-weit ähnlich:

@Wanderer: Diese Nummer ist doch die UST-IdNr, die ich bei den Lieferanten einlese, oder? Diese Nummer ist nach XRechnungs-Standard nicht einmal erforderlich. Sie braucht also auch nicht (von der eigenen) Firma in der Rechnung zu stehen. Ehrlich: Dafür fehlt mir das Wissen. Und die zur Verfügung stehende Überprüfung hat für mich so gar nichts mit der XRechnungs-Erstellung zu tun.

Das, was ich da zusammengebaut habe, ist erst einmal nicht irgendetwas zur kompletten Verwaltung von irgendwelchen Rechnungsstellungen. Da würde ich als Laie ja zumindest erst einmal auch eine Warenverwaltung (mit Eingängen, Ausgängen, veränderbaren Preisen usw.) mit einbauen.

Wenn ich einem deutschen Unternehmen eine Rechnung schreibe gebe ich die Nummer auch nicht an. Sobald ich einem EG-Unternehmen eine Rechnung schreibe, gebe ich sie an, damit klar ist, warum ich die Mehrwertsteuer auf 0 gesetzt habe.
.
Da der Steuersatz damit nicht nur von der Warengruppe abhängig ist (Pferd vs Esel), sondern auch vom Käufer kann ich das nicht komplett entkoppeln.
.
Grundsätzlich hast Du recht, die Steuernummer gehört in die Stammdatenverwaltung, genau wie die Prüfung, ob die Rechnung ohne Steuer erfolgen darf. Und wie schon gesagt: Bisher speichere ich nur dann eine Steuernummer, wenn Sie für diesen Zweck benötigt wird.
.

Ist auch meiner Ansicht nach nicht sinnvoll. Ich stelle mir eher vor, dass ich zur bisherigen Rechnung (= Datenbankabfrage) eine zweite Ansicht erzeuge, die die Daten in passende Felder zu einem XRechnungs-Modul einträgt. Daraus sollte Dein Macro oder die X-Rechnung extension dann die xml-Datei erzeugen. Ich schätze nur die wenigsten möchten Ihr bisheriges Warensystem ändern nur um X-Rechnungen zu schreiben…

Hallo Robert,
bisher hatte ich mich noch nie mit Base und Basic Makros beschäftigt und bin wirklich sehr beeindruckt, was damit möglich ist! Unter Windows 11, LibreOffice 7.5.9.2 und mit Thunderbird 115.6.1 funktioniert die XRechnung.odb tadellos. Nachdem ich alles nach Anleitung eingestellt und eine einfache Rechnung erstellt hatte, habe ich diese mit einem Online-Validator geprüft, der bereits die kommenden Schemata (01.02.2024) implementiert (xrechnung-validator von epoconsulting).
Es wurden zwei Fehler gemeldet und die Rechnung wurde zurückgewiesen:

  • [BR-DEC-20]-The allowed maximum number of decimals for the VAT category tax amount (BT-117) is 2.
  • [UBL-DT-01]-Amounts shall be decimal up to two fraction digits

Bei Durchsicht der xml-Datei habe ich festgestellt, dass bei Eurobeträgen teilweise gar keine Nachkommastelle angegeben wird, manchmal auch nur eine, aber auch mal vier! Nachdem ich per Hand überall zwei Nachkommastellen eingegeben hatte, wurde die Rechnung als regelkonform angenommen.

Im Programm gibt es bereits eine Funktion, die auf zwei Nachkommastellen rundet. Diese wird aber nur auf zwei Eurobeträge angewandt und nicht auf alle. Damit alle Eurobeträge stets mit zwei Nachkommastellen ausgegeben werden, habe ich eine kleine Funktion geschrieben, die immer aufgerufen wird, wenn in der Ausgabe die currency “EUR” erscheint. Die Funktion benötigt Zahlen (Double) als Input und gibt den Betrag als String aus:

Function EuroCent(EuroVal As Double) As String
    EuroVal = Round2Decimalplaces(EuroVal)
    EuroCent = Trim(Str(EuroVal))
    If (InStr(EuroCent, ".") = 0) Then      Rem No decimal point
      EuroCent = EuroCent & ".00"
    End If
    If (InStr(EuroCent, ".") = 1) Then      Rem Decimal point at beginning
      EuroCent = "0" & EuroCent
    End If
    If ((Len(EuroCent) - InStr(EuroCent, ".")) = 0) Then      Rem Decimal point at the end
      EuroCent = EuroCent  & "00"
    End If
    If ((Len(EuroCent) - InStr(EuroCent, ".")) = 1) Then      Rem Only one digit after decimal point
      EuroCent = EuroCent  & "0"
    End If
End Function

Das geht sicherlich eleganter, wie gesagt mein erster Makro Basic Code überhaupt, erfüllt aber seinen Zweck. Damit es auf alle Eurobeträge angewandt werden kann, müssen einige Variablen von String nach Double umdeklariert werden (stNetto, stSteuer, stBrutto) oder Umwandlungen von Double nach String entfernt werden (arDataPrice(inI), arDataRabatt(inI), arDataAmount(inI)).
Das ist mein allererster Post überhaupt in diesem Forum und mir ist nicht klar, ob ich den modifizierten Code einfach als Datei anhängen soll oder der Austausch in so einem Fall besser direkt per E-Mail läuft. Da wäre ich für einen Hinweis dankbar.
Auf jeden Fall nochmal ein dickes Lob und großes Dankeschön für dieses tolle Tool!
Mit herzlichem Gruß
Ulrich

PS. Beim Vergleich der xml-Dateien ist mir aufgefallen, dass damit nebenbei noch ein anderer Fehler beseitigt wird: Bisher werden Rabattangaben auch ausgegeben, wenn der Rabatt 0 Euro ist. Die Abfrage, die das ausschließen soll, funktioniert erst richtig, wenn der Rabattbetrag eine Zahl ist.

@ottu : Danke für die Rückmeldung.

Bei den Beträgen bin ich wohl mit der Zeit durcheinander gekommen. Bei Einzelpreisen ist eine Preisangabe mit beliebig viel Nachkommastellen möglich. (UNIT PRICE AMOUNT) Bei zusammengefassten Preisen (also auch bei der für jede Zeile der Rechnung enthaltene Nettoangabe) muss der Preis genau 2 Nachkommastellen haben. Da werde ich noch nachbessern müssen.

Das mit den Rabattangaben werde ich mir auch noch anschauen. Zum Schluss (nach der Änderung der möglichen Anzahl - anfangs hatte ich nur ganze Zahlen durch gelassen) habe ich auf die Beträge in der XML-Rechnung nicht so geachtet.

Der Makrocode ist so gut zu kopieren. Mal sehen, ob ich den da einbaue oder an anderer Stelle etwas ändere. Da taucht nämlich auch wieder die Trim-Funktion auf, die nur wegen eines Fehlers der Firebird-Datenbank erforderlich ist. Und das habe ich teilweise über die Firebird-Datenbank geregelt. Vielleicht regele ich da wesentlich mehr über die Ansichten aus der Datenbank - dann wird das Problem mit den Nachkommastellen direkt an der Quelle behoben.

@RobertG: Danke für die Rundung auf 2 Nachkommastellen!
Im Makro SaveXRechnung Zeile 119 bei “arDataPrice(inI)” wird keine Rundung vorgenommen, ist auch nicht nötig. Aber bei den Einzelpreisen in der XRechnung (XML) führt das dazu, dass die Preisangaben mit Komma statt Punkt erfolgen, z.B.:

<cbc:PriceAmount currencyID=“EUR”>12,45</cbc:PriceAmount>
<cbc:PriceAmount currencyID=“EUR”>21,9</cbc:PriceAmount>

Bei XEinkauf.de habe ich das Bundle XRechnung Version 3.0.1 mit dem Validator heruntergeladen. Die entsprechenden Preisangaben werden als fehlerhaft bewertet und die Rechnung wird zurückgewesen. Die Kommata müssten vor der Ausgabe durch Punkte ersetzt werden (die Function DecimalPoint gibt es ja schon im Import).

Beim Code für Portokosten wird ein Fehler gemeldet, weil der Charge reason code (UNCL7161) ungültig wäre. Dort steht die Zahl “34”, in der entsprechenden Liste sind es jedoch Buchstabencodes. Für Delivery beispielsweise DL. Wenn ich die “34” mit “DL” ersetze, wird die Rechnung akzeptiert.

In der Dropdown-Liste zum Wechseln zwischen den Formularen gibt es oberhalb von “Einstellungen” noch einen leeren Eintrag. Wenn man da drauf klickt, erzeugt das einen Laufzeitfehler.

Zu guter Letzt noch eine Frage: Die acht Stellen für die laufende Rechnungsnummer finde ich etwas ambitioniert - bisher hatte ich zwei Stellen :slight_smile: An welchen Stellen müsste ich Änderungen vornehmen, um das anzupassen? Oder ließe sich das ohne großen Aufwand über eine Option in den Einstellungen festlegen? Nullen abzählen zu müssen, macht einfach keinen Spaß, und die Dateinamen würden dann auch nicht ganz so lange … :wink:

Herzliche Grüße
Ulrich

Hallo Ulrich,

ich schicke das jetzt per Mail, da der Thread so lang geworden ist, dass
er bei mir manchmal gar nicht mehr bis zum Ende angezeigt wird.

<cbc:PriceAmount currencyID=“EUR”>12,45</cbc:PriceAmount>
<cbc:PriceAmount currencyID=“EUR”>21,9</cbc:PriceAmount>

Das kann ich einfach lösen, indem ich das Ganze als Text von der
Datenbank einlese. Das Merkwürdige ist ja, dass die Benutzeroberfläche
da dann irgendwo greift, wenn ich Zahlen aus der Datenbank als
Dezimalzahlen importiere. Jetzt kommen die Zahlen allerdings mit der
Anzahl an Nachkommastellen, die auch die Datenbank erlaubt. Das war auch
bei der Angabe der Quantity so falsch. Da habe ich nur Ganzzahlen
ausgelesen …

Beim Code für Portokosten wird ein Fehler gemeldet, weil der Charge reason code (UNCL7161) ungültig wäre. Dort steht die Zahl “34”, in der entsprechenden Liste sind es jedoch Buchstabencodes. Für Delivery beispielsweise DL. Wenn ich die “34” mit “DL” ersetze, wird die Rechnung akzeptiert.

Na ja, dass ist der Charge Reason Code 5184. Ich komme da langsam ins
Schwimmen, weil die Beispiele das nicht her geben. Die nutzen den Code
5184 teilweise, den Code 7161 überhaupt nicht. Ich überlege, ob ich den
Code nicht komplett raus nehme. Auch das ist nämlich erlaubt, wenn ich
das Ganze korrekt sehe.

In der Dropdown-Liste zum Wechseln zwischen den Formularen gibt es oberhalb von “Einstellungen” noch einen leeren Eintrag. Wenn man da drauf klickt, erzeugt das einen Laufzeitfehler.

Den habe ich raus bekommen, indem bei einem leeren Eintrag einfach
nichts passiert.

Zu guter Letzt noch eine Frage: Die acht Stellen für die laufende Rechnungsnummer finde ich etwas ambitioniert - bisher hatte ich zwei Stellen :slight_smile: An welchen Stellen müsste ich Änderungen vornehmen, um das anzupassen? Oder ließe sich das ohne großen Aufwand über eine Option in den Einstellungen festlegen? Nullen abzählen zu müssen, macht einfach keinen Spaß, und die Dateinamen würden dann auch nicht ganz so lange … :wink:

Ich schaue einmal. Das kommt nicht nur in der Ansicht viw_Rechnung
sondern auch im Makrocode für die eingebauten Anhänge vor.

Teste doch einmal ohne die Zeile mit dem Charge Reason Code. Wenn das
ohne Code durch geht brauche ich mir da keine Gedanken drum zu machen
und schmeiße das raus.

Gruß

Robert

Meine Kollegen haben auch gemosert, als ich von 4 auf 5 Ziffern ging, aber 8 oder gar 10 sehe ich bei einigen Kleinunternehmern, die “Rechnungsnummern” wie 05/10/23 verwenden, wobei ich annehme, dass es die 5. Rechnung im Oktober 2023 war.
.
Für einen allgemeinen Ansatz muss man also Platz vorsehen und evtl. dann einen angepassten Formatierungsstring verwenden …

[RobertG] RobertG https://ask.libreoffice.org/u/robertg
January 13

<cbc:PriceAmount currencyID=“EUR”>21,9</cbc:PriceAmount>

Das kann ich einfach lösen, indem ich das Ganze als Text von der
Datenbank einlese.

Das geht auch mit der Funktion DecimalPoint sehr einfach.
SaveXRechnung, Zeile 490:
… currencyID="“EUR”">" & DecimalPoint(arDataPrice(i)) & …

Beim Code für Portokosten wird ein Fehler gemeldet, weil der Charge
reason code (UNCL7161) ungültig wäre. ...

Na ja, dass ist der Charge Reason Code 5184. … überlege, ob ich den
Code nicht komplett raus nehme. Auch das ist nämlich erlaubt, wenn ich
das Ganze korrekt sehe.

Ja, es geht auch ohne. Zeile 409 auskommentiert:

REM … “cbc:AllowanceChargeReasonCode” & arAllowCode(i) & …

Und mit beiden Änderungen wird die XML-Rechnung als valide akzeptiert.

Zu guter Letzt noch eine Frage: Die acht Stellen für die laufende
Rechnungsnummer finde ich etwas ambitioniert ...

Ich schaue einmal. Das kommt nicht nur in der Ansicht viw_Rechnung
sondern auch im Makrocode für die eingebauten Anhänge vor.

Mit diesem Hinweis habe ich alle drei Stellen gefunden und habe die
Nummer auf vier Stellen reduziert. :slightly_smiling_face:

Teste doch einmal ohne die Zeile mit dem Charge Reason Code. Wenn das
ohne Code durch geht brauche ich mir da keine Gedanken drum zu machen
und schmeiße das raus.

Ja, siehe oben.

Mit herzlichem Gruß

Ulrich

Ich habe jetzt:
Die unterschiedlichen Codes für Zuschläge und Gebühren raus genommen.
Sie sind für die XRechnung nicht erforderlich. Wenn sie aber gesetzt
werden, müssen sie zum entsprechenden Inhalt passen. Da das auch noch
unterschiedliche Codes sind scheint mir das doch etwas für
Speziallösungen zu sein.
Die Preisangaben und die Mengenangaben sind jetzt mit dem Dezimaltrenner
“Punkt” drin. Die Einzelpreise und die Mengen dürfen ja beliebig viele
Nachkommastellen haben, so dass ich einfach die Werte aus der Datenbank
als Text übernommen habe.
Für die Anzahl der Stellen in der Rechnungsnummer habe ich ein Feld in
die Tabelle für die Einstellungen gesetzt. Ist dort nichts eingetragen,
so wird die Rechnungsnummer 6-stellig.

Und bitte wieder testen…

Gruß

Robert

RobertG schrieb:

Ich habe jetzt:

Und bitte wieder testen…

Mit der neuen Version werden die zwei Beispielrechnungen vom KoSIT
Validator 1.5.0 als valide XRechnung 3.0.1 akzeptiert. :+1:
Beim Lesen der Dokumentation sind mir ein paar Fehler ins Auge gesprungen:
Seite 8 vorletzter Absatz: Felder, in Im → im
8 letzter Absatz: geschaffen, um (Komma fehlt)
10 dritter Absatz: wird, muss (Komma fehlt)
vor Abb.: des Elements, dass → das
letzter Absatz: Loge - > Logo
12: Screenshot von Einstellungen: (Stellenanzahl) Rechung → Rechnung
14: eines des Pflichtfelder → der
darunter: wurde, steht (Komma fehlt)
15 im Tipp: Standard-Mailprogramm → Standardmailprogramm (einheitlich)
27: werden muss, um (Komma fehlt)
37: erstellt ist, kann (Komma fehlt)
WICHTIG: Den Hinweis auf das Löschen der Tabellen für den produktiven
Gebrauch im letzten Absatz bitte auch nach vorne, um bei Nutzern Frust
mit Fehlermeldungen zu vermeiden! :wink:
41/42: Rechnungsnummer im Code und Text noch mit 10 Stellen!
72: SaveXRechnung: Makro: Fehler. Verweis nicht gefunden (Round2Decimalplaces )

Sehr gute, ausführliche und lehrreiche Dokumentation!

Ulrich

Alles angepasst und wieder hochgeladen - bis auf diese Anmerkung, die so nicht ganz passt. Das liegt vielleicht daran, dass Du mit dem Code nicht so viel anfangen kannst. Im Code, Zeile 16, steht folgendes:

'R-'||"c"."Jahr"||'-'||RIGHT('0000000000'||"c"."lfdJahr", COALESCE("tbl_Firma"."ReStellen",6)) AS "Rechnungsnummer"

Da sind jetzt 10 führende Nullen gesetzt. An diese 10 Nullen wird die laufende Nummer für das Jahr angehängt. Macht bei einstelligen Nummern zum Anfang also erst einmal eine 11-stellige Nummer. Dieser zusammenhängende String wird von rechts aus mit der entsprechend festgelegten Anzahl von Zeichen gelesen. Und diese Anzahl hole ich aus “tbl_Firma”.“ReStellen”. Dort ist schon von mir ‘4’ als Vorschlag hinterlegt. Sollte das Feld leer sein, so wird über den Befehl COALESCE der 2. vorgesehene Vorschlag, in diesem Fall die ‘6’, gewählt.

Hallo Robert,

vielen Dank erstmal fürs Erstellen und Bereitstellen dieser Lösung. Ich weiß nicht wie ich dich eventuell direkt Kontaktioeren kann oder Fehler melden kann, deshalb eine kurze Frage von mir: bei der ZUGFeRD erstellung wird geschrieben, dass ein Pfad sowie Dokumente erstellt werden, dies passiert bei mir nicht, Fehlermeldung gibt’s keine. Gibt es hierzu eventuell einen Hinweis?

Viele Grüße,
Paul

@PaulS : Meine Homepage steht etwas weiter oben. Die Mailadresse schicke ich Dir privat zu.