XRechnungen erstellen und einlesen

Im Thread XRechnung: Elektronische Rechnung für Unternehmen untereinander ab 2025 voraussichtlich Pflicht habe ich bereits beschrieben, dass ab dem Jahr 2025 XRechnungen für die Rechnungsstellung unter Unternehmen Pflicht sind.

Nachdem ich das bisher vorliegende Material gesichtet habe konnte ich nur feststellen: Für den Normalgebrauch zur Zeit nur begrenzt geeignet. Das fängt an mit der Rechnungserstellung, die im Writer zwar sauber gestaltet werden kann, aber für Berechnungen besser einen Taschenrechner als die Formeln vom Writer nutzbar erscheinen. Nehme ich Calc, so ist die Gestaltung mit einer ordentlichen Fußzeile und Informationen zu allen möglichen Firmendaten schlicht nicht möglich.

Kurz: Ich habe das jetzt in Base realisiert und eine erste Beta-Variante auf meiner Homepage Datenbanken hoch geladen. Dort liegt in dem Kasten “Bearbeitungsversionen” eine Datenbankdatei “XRechnung.odb”, eine Vorlagendatei “Vorlage_Rechnung.ott” und eine Beschreibung “XRechnung.pdf”. Die Testdatei enthält bereits einige Einträge, vor allem auch aus den letzten Tests zum Einlesen von XRechnungen in beiden zulässigen Formaten. In der Beschreibung ist erwähnt, wie die Datensätze komplett gelöscht werden können, so dass mit einer leeren Datenbank begonnen werden kann. Vor dem Test also bitte die Beschreibung, zumindest die ersten Seiten, lesen.

So sieht das Einstiegsformular aus, wenn die Ausführung von Makros erlaubt werden. Über “Rechnung drucken” kann die Rechnung erstellt werden. Es wird in einem Archiv eine *.odt-Datei, eine *.pdf-Datei und eine .xml-Datei abgelegt. Dann startet das Mailprogrammm und eine Mail mit 2 Anhängen (.pdf und *.xml) steht zum Versand bereit.

Das Ganze läuft nur mit Makros, und weil ich das nicht anders geregelt bekomme und die Zeit zum Umlernen fehlt eben mit StarBasic.

Jetzt heißt es ein bisschen testen und Fehler bzw. Probleme zurückmelden. Anfang Februar 2024 will ich das Ganze auf die LibreOffice-Hompage hoch laden, damit Leute, die nach einer Lösung für die Rechnungserstellung von Firmen suchen, vielleicht doch bei LibreOffice fündig werden können.

Edit 27.12.23: Die Rückmeldung als Beitrag hier wird zusehends schwieriger. Ich bekomme inzwischen oft nicht einmal mehr neue Beiträge angezeigt. Dafür ist diese Art des Austausches einfach nicht gedacht. Also besser rückmelden per Mail. Änderungen schreibe ich hier in den Originalbeitrag.
Ich habe aktuell eine Version hoch geladen, in der bei der Rechnung auch die Art der Steuer (nach den XRechnungs-Vorgaben) und die Steuernummer des Kunden mit berücksichtigt werden kann.

Edit 10.01.24: Ich habe jetzt auch das Einlesen von binären Dateien in die XRechnung eingebaut. Dabei wird die binäre Datei jeweils in das Base64-Format umgewandelt. Die Beschreibung ist entsprechend angepasst. Das soll jetzt auch von den Features her die Version sein, die auf die LibreOffice-Homepage hoch geladen wird. Die Datenbankdatei hat jetzt den schlichten Namen XRechnung.odb.

Edit 12.01.24: Antworten unten einzutragen klappt bei diesem langen Thread nur selten. Die Möglichkeit erscheint oft gar nicht mehr. Deswegen hier: Ich habe jetzt die Rundung auf 2 Nachkommastellen an vielen Stellen eingebaut. Zum Schluss hin ist diese Rundung sicher notwendig und auch in der XRechnung erforderlich. Beim Einzelpreis einer Ware ist dies aber nicht der Fall. Hier wird nur der Nettopreis einer Rechnungzeile (Anzahl * Preis abzgl. Rabatt) gerundet.

Gruß

Robert

3 Likes

edit. erledigt!

Nach [Rechnung drucken] bleibt das Programm in Zeile 70 auf Modul “Druck” stehen mit der Fehlermeldung “BASIC runtime error.
An exception occurred
Type: com.sun.star.uno.RuntimeException
Message: no text selection at /home/buildslave/source/libo-core/sw/source/uibase/uno/unotxvw.cxx:968.”, und der Frame der Rechnungsvorlage ist irgendwie eingefroren, so dass man alle anderen Office-Fenster schließen und dann das Programm killen muss.

Schau einmal nach der aktuellsten Version. Ich habe da täglische Updates drin. Den Fehler habe ich jedenfalls bei mir nicht gehabt. Kann natprlich sein, dass ich da zwischendurch etwas daneben gesetzt habe, was jetzt wieder funktioniert.

Ich aktualisiere auch einmal den Screenshot oben. Der entspricht nicht mehr ganz dem aktuellen Formular, da ich die Maßeinheiten für die Anzahl auch mit rein genommen habe.

Gleiches Problem mit Deiner Version vom 14.12. und meiner Version:
Version: 7.6.4.1 (X86_64) / LibreOffice Community Build ID: e19e193f88cd6c0525a17fb7a176ed8e6a3e2aa1 CPU threads: 4; OS: Linux 5.15; UI render: default; VCL: x11 Locale: de-DE (de_DE.UTF-8); UI: en-US Calc: threaded

Wieso ist die Vorlage eingefroren? Ich finde in dem Code nichts mit “lockControllers”.

@Villeroy : Ich habe hier die gleiche Version zum Testen benutzt. Bei mir wird die Vorlage geöffnet und dann eine zweiseitige Rechnung erstellt.

Version: 7.6.4.1 (X86_64) / LibreOffice Community
Build ID: e19e193f88cd6c0525a17fb7a176ed8e6a3e2aa1
CPU threads: 6; OS: Linux 5.14; UI render: default; VCL: kf5 (cairo+xcb)
Locale: de-DE (de_DE.UTF-8); UI: de-DE
Calc: threaded

Bei mir dann KDE. Folgendes fällt mir bei den Versionen ab 7.5 auf: Wenn ich von der Version 7.4 (die ich zum Erstellen nutze) auf eine dieser Versionen wechsele erscheint beim ersten Start nahezu jedes Fenster im Minimalformat mitten auf dem Bildschirm. Das führt auch dazu, dass bereits die ersten Makros zum Zoom (Darstellungsgröße im Formular) eine Fehlermeldung erzeugen. Schließe ich dann die Version LO 7.6 und öffne sie erneut, so klappt da alles.

Lässt sich denn die Vorlage ganz normal öffnen? Nicht dass da bei der Übertragung ins Netz etwas schief gelaufen ist.

Edit: Habe das jetzt einmal unter Windows mit der aktuellen LO-Version 7.6.4.1 testen lassen. Dateien von meiner Website herunter geholt, die Datenbank läuft, der Button zum Erstellen der Rechnung wird gedrückt (ist ja eine Rechnung drin), die Rechnung wird erstellt und das Mailprogramm geht auf. An der mit Inhalt gefüllten Mail hängen eine PDF-Datei und eine XML-Datei.

Bin grad auf Arbeit. Unter Windows funktioniert es, und ja, ich kann alle Dateien ganz normal öffnen. Wie gesagt, unter Ubuntu 20.4 bricht das Makro an besagter Stelle mit besagtem Fehler ab, und merkwürdigerweise ist nach diesem Abbruch nur der Frame mit dem Text-Dokument eingefroren. Man kann dieses eine Fenster nicht schließen, es hat keinen Textcursor, die Symbollleisten, das Menü, das Navigatorfenster sind taub. Die anderen Office-Fenster sind intakt.


Normalerweise starte ich LO mit SAL_USE_VCLPLUGIN=gen weil gtk mit Formularen nicht funktioniert. Jetzt habe ich LO mit SAL_USE_VCLPLUGIN=gtk gestartet. Das Makro bricht immer noch an derselben Stelle ab, aber nach dem Schließen der Fehlermeldung ist das Textdokument zugänglich. Das LibreOffice-Logo ist selektiert, weshalb wohl der Fehler mit dem fehlenden Textcursor auftritt. Vielleicht ist es doch etwas überkandidelt, die Absender-Info und das Firmenlogo auch noch per Makro einzufügen?

Das Logo ist unter Ubuntu also da, oder ist das Tabellenfeld noch leer? Wenn es leer ist könnte das Ganze auch etwas mit dem Auslesen in den Temp-Pfad zu tun haben.

Die Geschichte mit dem Logo habe ich zuerst für jemanden gemacht, der dort je nach Ansprechpartener unterschiedliche Logos brauchte. Und der macht das Ganze auf Ubuntu. Ich hake da einmal nach.

Ja, das Logo ist da. Wie setzt man in Writer den Fokus auf den Text? Kenne mich überhaupt nicht aus.

	REM Der sichtbare Cursor wird geholt und in die erste Eingabezeile gesetzt.
	REM Der Cursor muss mit laufen, damit klar wird, wann ein Seitenumbruch stattfindet.

Echt jetzt? Wozu?

In dem Dokument wird einer keiner Stelle der Cursor in den Text gesetzt. Er läuft mit der Tabelle für die Rechnungsinhalte mit. Nur der Viewcursor bekommt mit, wenn da ein Seitenwechsel stattfindet. Und den Seitenwechsel brauche ich, um den Übertrag an die richtige Position zu bekommen.

Der Cursor ist immer in der neu erstellten, leeren Zeile der Tabelle, die ich mit dem Namen “Rechnungsinhalt” versehen habe. Rutscht diese Zeile auf die nächste Seite, so setze ich den Cursor 2 Seiten zurück und füge dort 2 Zeilen ein. Die erste der beiden Zeilen liegt dann auf jeden Fall auf der Vorseite. In beide zeilen trage ich den Übertrag ein. Dann setze ich den Cursor in die zweite der Zeilen und füge so lange Tabellenzeilen ein, bis die zweite Zeile auf jeden Fall auf der Folgeseite steht.

An welcher Stelle des Prozesses bleibt denn bei Dir das Verfahren stehen? Werden da schon Zeilen geschrieben?

Zeile 70 'oCursor.goToRange(oTxtRange,False)`.

Und wenn ich das Logo weglasse, läuft’s korrekt durch, also wenn ich ExportImageIntern(oStream,oNewDoc,oTableImage.getCellByPosition(0,0)) auskommentiere.

P.S. Dafür sind die Zahlen in den Rechnungen nicht korrekt. Da sind die Spalten für MwSt und Betrag vertauscht.
R-2023-00000001_2023-11-11.odt (31.9 KB)
PPS: und der Text–Body der Email ist in der Empfängerzeile
Bildschirmfoto von 2023-12-16 10-58-22

Das mit den Überträgen würde ich einsparen. Habe grade ein paar PDFs und einen Ordner durchgeblättert. Überträge sind sowas von 90iger.

Du hast da die alte Vorlagendatei und die neuere Version der Datenbank zusammen. In der aktuellen Vorlagendatei ist eine Spalte mehr mit drin. Das Ganze sieht dann so aus:


Das mit dem Text in der Empfängerzeile haben wir bei Ubuntu zusammen mit Thunderbird auch gehabt. Da scheint irgendetwas ziemlich schief zu laufen mit der Erkennung von Zeilenumbrüchen. Nach dem ersten Umbruch verschiebt sich der Rest in die Emfängerzeile. Schließlich ist die Person für das entsprechende Mailkonto auf einen anderen Mailer, Evolution glaube ich, gewechselt. Da klappte das alles sauber.

Das liegt nicht an Thunderbird selbst sondern an der Art, wie die Ubuntu-Version arbeitet. Bei mir unter SuSE kommt mit Thunderbird das hier raus:

Mit der Zeile zum Logo schaue ich einmal, was da wohl daneben gehen kann.

Die Absender-Info einer ausgehenden Rechnung sollte doch eigentlich in der Vorlage fest eingebaut sein. Und bei eingehenden XRechnungen ist doch gar kein Logo enthalten, oder habe ich da was übersehen?
Einen Übertrag könnte man auch in die Fußzeile einbauen. Ich würde ihn weg lassen.

Na ja, das Ganze soll ja nach meinen Vorstellungen so funktionieren, dass der Nutzer seine Firmendaten alle direkt in eine Tabelle schreibt, in diesem Fall “tbl_Firma”. Die Vorlage ist dann im Hintergrund und wird gar nicht angetastet. Mich interessiert hier viel mehr, warum das bei Dir nicht funktioniert. Ich habe jetzt extra einen Uraltrechner aus der Ecke geholt. Der braucht aber erst einmal für das Ubuntu-Update.

Natürlich kann, wer will, die Fußzeile raus nehmen. Ich schreibe in den Code mit einer Anmerkung vor der entsprechenden Schleife, wo das geschieht. Für mich ist das eine mögliche Information, die angefordert werden könnte. Ich habe aber sonst mit Rechnungsstellungen nichts zu tun.

Die ganze Darstellung in Form einer *.odt-Datei und einer *.pdf-Datei ist für XRechnungen ja nicht notwendig. Da zählt allein die *.xml-Datei.

Ergänzung 1: Ich habe das jetzt mit der Ubuntu-Version von LibreOffice (7.6.4.1, gerade neu herunter geladen) getestet. Zuerst hakte das Ganze daran, dass der Rechner die Vorlage für das Makro nicht schnell genug öffnen konnte. Der braucht eben etwas Zeit. Mit einem WAIT 2000 klappte das dann und die Rechnung wurde anstandslos komplett erstellt. Nur die Mail hat natürlich weiter ihre Macken.

Das Problem mit dem Logo kann ich wie folgt umgehen:
Stopmarke auf Zeile 67 oCursor = oNewDoc.CurrentController.ViewCursor.
Wenn der Code dort angekommen ist, den Fokus vom Logo auf die Tabelle setzen.
F5 drücken, um fortzufahren.

Das Problem ist also, dass der ViewCursor auf ein DrawPage-Objekt zeigt.
Wenn ich den obigen Trick mit der Stopmarke nicht anwende, sind die Eigenschaften oCursor.Text, oCursor.Start, oCursor.End Null-Werte.

Komisch ist nur, dass das in anderen Systemen (oder bei meiner Uraltkiste) klappt. Ich schaue mir das am Sonntag noch einmal an.

Linux ist nicht immer 100% konsistent. Ubuntu schon mal gar nicht.
Ich finde grade leider keinen Weg, den Focus programmatisch auf den Text zu setzen.

OK, das hier scheint zu funktionieren und schadet nicht auf Plattformen, wo es nicht nötig ist:

	oSelection = ThisComponent.getCurrentSelection()
	oStream = oForm.getBinaryStream(oForm.findColumn("Logo"))
	ExportImageIntern(oStream,oNewDoc,oTableImage.getCellByPosition(0,0))
	ThisComponent.CurrentController.select(oSelection)

EDIT: NEIN, geht doch nicht. Auf dem Windows-Rechner wird der Focus entsprechend korrigiert, aber daheim auf meinem Ubuntu-System bleibt der Focus auf dem Bild.

Das Setzen des Viewcursors geschieht, indem ich ihm die Position des Textcursors übergebe.

	oTable = oTables.getByName("Rechnungsinhalt")
	inCols = oTable.Columns.Count
	i = 1	
    oCursor = oNewDoc.CurrentController.ViewCursor
	oPos = oTable.getCellByPosition(0,i)
	oTxtRange = oPos.getEnd
	oCursor.goToRange(oTxtRange,False)

Bedeutet: Die Tabelle mit dem Namen “Rechnungsinhalt” hat 2 Zeilen. Die erste Zeile mit den Tabellenköpfen und in der zweiten Zeile startet die Inhaltseingabe. Da die Zählung mit 0|0 in der linken oberen Ecke beginnt weise ich dem Textkörper in der Zelle 0|1 seine Position zu und übergebe diese an den Viewcursor.

Vielleicht stößt sich Dein System daran, dass der Viewcursor bereits in der Prozedur “ImportImage” verwendet wurde.

Möglicherweise habe ich das Problem mit dem Logo gelöst. Du kannst es nachvollziehen, indem Du Auto-Caption für Bilder einschaltest. Dann wird nämlich ein Frame im Frame erzeugt, und der Cursor ist futsch. Die Beschriftung “Illustration 1” kam mir in diesem Zusammenhang merkwürdig vor.

Ich musste erst einmal nachschauen, wo das überhaupt einzustellen ist, da Du ja mit der englischsprachigen Oberfläche arbeitest.

Bei mir erscheint dann auch “Abbildung 1:” und danach ist nichts mehr. Da muss ich einmal nachschauen, wie ich so etwas abfangen kann.

Ich bin auf dem richtigen Lösungsweg. Ich erstelle jetzt das Bild direkt und nicht über .unoInsertGraphic. Lade das dann nachher hoch.

Edit: Habe die neue Datenbankdatei hoch geladen. Was mich etwas irritiert: Ich habe da eigentlich mehr Daten drin als vorher - nur die *.odb-Datei wird kleiner. Aber solange das funktioniert…