149 lines
8.5 KiB
Markdown
149 lines
8.5 KiB
Markdown
# JR eInvoice: Desktop-Oberfläche
|
|
|
|
Die Oberfläche ist Teil des bestehenden eInvoice-Repositorys. Berechnung,
|
|
Rechnungsnummern, XML, PDF/A und Mustang-Validierung werden gemeinsam mit der
|
|
Konsole weiterentwickelt. Es gibt weder einen Webserver noch ein Cloudkonto.
|
|
Das Fenster benötigt eine lokale Wayland- oder X11-Sitzung.
|
|
|
|
## Start und Installation
|
|
|
|
Auf Johannes' Rechner: **JR eInvoice** im Anwendungsmenü oder `einvoice-ui` in der
|
|
Konsole. `einvoice --gui` startet dasselbe Fenster. Die bestehende CLI funktioniert
|
|
weiter wie bisher.
|
|
|
|
```bash
|
|
cd /home/johannes/localdev/einvoice
|
|
einvoice --update --apply --with-gui
|
|
python3 scripts/install_commands.py --desktop
|
|
einvoice-ui
|
|
```
|
|
|
|
Der Updater erstellt eine isolierte Laufzeit mit PDF- und GUI-Abhängigkeiten,
|
|
prüft sie und aktiviert sie erst bei Erfolg. GUI-Installation wird im
|
|
Laufzeitmanifest gemerkt und bei weiteren Updates beibehalten.
|
|
`einvoice --update --rollback` stellt die vorherige Laufzeit wieder her. Falls
|
|
diese noch keine GUI hat, funktioniert die Konsole weiterhin und der GUI-Starter
|
|
zeigt den Installationsbefehl. Es werden keine Rechnungsdaten zurückgerollt.
|
|
|
|
Entwickler: `pip install -e '.[pdf,gui]'`; anschließend
|
|
`.venv/bin/einvoice-ui`. Nach Wheel-Installation heißt der Einstieg ebenfalls
|
|
`einvoice-ui`. PySide6 bringt Qt und die PDF-Ansicht mit; Java und die nativen
|
|
WeasyPrint-Bibliotheken bleiben Systemvoraussetzungen. Ein vorhandenes System-
|
|
PySide kann unvollständig sein; die isolierte Projektinstallation verwenden.
|
|
|
|
## Eine Rechnung erstellen
|
|
|
|
1. Eine eigene Vorlage oder frühere Rechnung aus der Auswahl laden. „Datei öffnen“
|
|
liest auch eine beliebige kompatible YAML-Datei. „Neue Rechnung“ beginnt leer.
|
|
2. Einen gespeicherten Kunden wählen oder einen neuen Kunden mit Anschrift anlegen.
|
|
E-Mail und USt-ID sind optional. Neue Kunden werden bei der endgültigen
|
|
Erstellung einmalig gespeichert. Bei gespeicherten Kunden zeigt „Anschrift
|
|
anzeigen / verbergen“ die vollständigen schreibgeschützten Stammdaten.
|
|
3. Rechnungsdatum, tatsächlichen Leistungszeitraum, Zahlungsziel und bei Bedarf
|
|
Kundenreferenz oder Bestellnummer festlegen. Gleiches Von-/Bis-Datum bezeichnet
|
|
eine Leistung an einem Tag. Eine leere Rechnungsnummer wird automatisch vergeben.
|
|
4. Positionen ergänzen oder entfernen. Menge und Preis akzeptieren zum Beispiel
|
|
`7,5`, `85,00 €` und `1.234,56 EUR`. Preise sind netto je Einheit. Stunden, Stück
|
|
und Tage stehen zur Auswahl. Weitere Einheiten aus geladenen Rechnungen bleiben
|
|
erhalten. Zusätzliche Beschreibungen sind mehrzeilig.
|
|
5. „Entwurf ansehen“ erzeugt eine PDF im rechten Fensterbereich. Sie ist als Entwurf
|
|
gekennzeichnet, erhält keine Nummer und speichert keinen Kunden. Die Entwurfs-
|
|
PDF ist noch keine technisch validierte E-Rechnung. Die Vorschau lässt sich auf
|
|
Seitenbreite, ganze Seite oder 100 Prozent stellen; mehrere Seiten sind scrollbar.
|
|
6. „E-Rechnung erstellen“ legt einen neuen Rechnungsordner an, reserviert die Nummer
|
|
und erzeugt und prüft PDF/A und EN16931-XML. Nach Erfolg erscheint die **fertige
|
|
ZUGFeRD-PDF** im Fenster. „PDF extern öffnen“, „Rechnungsordner“ und „Prüfbericht“
|
|
führen zu den gespeicherten Ergebnissen. Den PDF-Anhang direkt versenden.
|
|
|
|
Die Betragsübersicht nutzt dieselbe Dezimalrechnung und Rundung pro Position und
|
|
Steuergruppe wie die Konsole. Ohne vollständige Eingaben wird keine Rechnung
|
|
angelegt. Nach erfolgreicher Erstellung ist der Knopf für dasselbe unveränderte
|
|
Formular gesperrt, damit ein Doppelklick keine weitere Rechnung anlegt.
|
|
|
|
Wenn Eingaben geändert werden, bleibt die bisherige PDF sichtbar, erhält aber
|
|
einen Hinweis auf den vorherigen Stand. Die Ergebnis-Knöpfe werden gesperrt, bis
|
|
erneut eine endgültige Rechnung erfolgreich erstellt wurde. Eine erzeugte Rechnung
|
|
wird durch Formularänderungen nicht nachträglich verändert. Auch „Neue Rechnung“
|
|
löscht keine vorhandene Rechnung.
|
|
|
|
Technische Validierung prüft das Dokumentformat und die strukturierten Daten.
|
|
Empfänger, Leistungsdaten, Nummer und Betrag vor Versand inhaltlich prüfen.
|
|
Der Assistent unterstützt dieselben Rechnungstypen wie die Konsole; insbesondere
|
|
noch keine Gutschriften, Stornierung, Steuerbefreiung oder Reverse Charge.
|
|
|
|
## Vorlagen und Layout
|
|
|
|
„Als Vorlage speichern“ legt eine geschützte YAML-Datei unter
|
|
`private/templates/` an; vorhandene Namen werden nur nach Bestätigung ersetzt.
|
|
Eine Vorlage speichert Kunde, Positionen, Zahlungsziel, Hinweise und Referenzen.
|
|
**Rechnungsnummer, Rechnungsdatum und Leistungszeitraum sind nicht enthalten.**
|
|
Beim Laden werden Rechnungsdatum auf heute und Leistungszeitraum auf den aktuellen
|
|
Kalendermonat gesetzt. Das gilt ebenso beim Laden einer bestehenden `invoice.yaml`.
|
|
Beschreibungen mit alten Monatsnamen und alte Bestellnummern werden nicht automatisch
|
|
umgeschrieben; sie sind vor der nächsten Rechnung zu aktualisieren.
|
|
|
|
Alte Rechnungen bleiben unverändert. Es werden aktuelle lokale Absender- und
|
|
Zahlungsdaten verwendet; fremde Bankdaten aus einer importierten Rechnung werden
|
|
nicht in die neue Rechnung übernommen. Kundenstammdaten bleiben vollständig erhalten.
|
|
Wenn derselbe Kundenname bereits mit einer anderen Anschrift oder anderen Angaben
|
|
gespeichert ist, wird die Erstellung gestoppt. Dann den passenden gespeicherten
|
|
Kunden auswählen oder die lokale Kundendatei bewusst korrigieren.
|
|
|
|
Die gemeinsame Layoutvorlage liegt in `templates/invoice.html.j2`; es gibt keinen
|
|
visuellen Layoutdesigner. Ein eigenes Logo wird aus `private/presets/logo.svg`
|
|
geladen. Die Oberfläche rendert dieselbe Vorlage wie die Konsole. Unterstützung
|
|
der PDF-Ansicht beruht auf den offiziellen Qt-Komponenten
|
|
[QPdfDocument](https://doc.qt.io/qtforpython-6/PySide6/QtPdf/QPdfDocument.html) und
|
|
[QPdfView](https://doc.qt.io/qtforpython-6/PySide6/QtPdfWidgets/QPdfView.html).
|
|
|
|
## Daten, Fehler und Betrieb
|
|
|
|
`JR_EINVOICE_HOME`, `JR_EINVOICE_PRESETS` und `JR_EINVOICE_MUSTANG_JAR` gelten auch
|
|
für die Oberfläche. `einvoice-ui --root /pfad/rechnungen` ändert den Rechnungsstamm;
|
|
`--mustang-jar /pfad/Mustang-CLI.jar` wählt eine andere Mustang-Datei. Private Daten,
|
|
Vorlagen und Rechnungen werden nicht mit Git veröffentlicht. Vorlagen enthalten
|
|
Kundenangaben und gehören deshalb ebenfalls ins eigene geschützte Backup.
|
|
|
|
Die PDF-Erzeugung läuft über `QProcess` in einem eigenen Python-Prozess. Das hält
|
|
das Fenster bedienbar und trennt die nativen Qt- und PDF-Bibliotheken voneinander.
|
|
Der Austausch erfolgt über einen temporären Ordner mit Modus 0700; die Auftrags-
|
|
datei hat Modus 0600. Aufträge und Entwurfsvorschau werden nach normalem Abschluss
|
|
bzw. Schließen bereinigt. Nach einem harten Prozessabbruch können temporäre Dateien
|
|
im Benutzer-/System-Tempverzeichnis verbleiben; sie werden nicht als Rechnungen
|
|
oder Vorlagen registriert. Es werden weder Nutzereingaben als Shell-Befehle
|
|
ausgeführt noch Serverports geöffnet.
|
|
|
|
Während einer Erstellung kann das Fenster nicht geschlossen werden. Ein Fehler
|
|
erscheint mit Diagnosepfad. Nach erfolgter Nummernreservierung bleiben Nummer,
|
|
Entwurf und Log erhalten; der Knopf ist nach dem Fehler wieder bedienbar. Ein neuer
|
|
Versuch mit automatischer Nummer kann die nächste Nummer reservieren. Den vorhandenen
|
|
Entwurf stattdessen über `jr-einvoice generate <Rechnungsordner>` wiederholen.
|
|
Ein technischer Fehler veröffentlicht keine fertige E-Rechnung. Beim erfolgreichen
|
|
Ergebnis bleiben `invoice.yaml`, XML, PDF, Prüfbericht, Log und Hashmanifest im
|
|
Rechnungsordner erhalten.
|
|
|
|
## Entwicklung und Prüfung
|
|
|
|
Neuer Quellcode und Kommentare sind deutsch beschrieben:
|
|
|
|
| Datei | Aufgabe |
|
|
| --- | --- |
|
|
| `jr_einvoice/gui.py` | Fenster, Formulare, PDF-Ansicht, Prozesssteuerung |
|
|
| `jr_einvoice/gui_data.py` | Geprüfte Formulardaten und Vorlagen |
|
|
| `jr_einvoice/gui_worker.py` | PDF-Aufträge ohne Qt im eigenen Prozess |
|
|
| `jr_einvoice/create.py` | Gemeinsame Rechnungserstellung für GUI und CLI |
|
|
| `tests/test_gui.py` | Vorlagen, Fehlerfälle, Vorschau, echter Erstellungsablauf |
|
|
|
|
```bash
|
|
QT_QPA_PLATFORM=offscreen .venv/bin/python -m unittest discover -s tests -v
|
|
QT_QPA_PLATFORM=offscreen JR_EINVOICE_INTEGRATION=1 \
|
|
.venv/bin/python -m unittest discover -s tests -v
|
|
```
|
|
|
|
Ohne GUI-Extra werden Qt-Tests übersprungen, Vorlagentests laufen weiterhin.
|
|
Die Integration prüft einen tatsächlichen Button-Klick bis zur validierten PDF in
|
|
der eingebetteten Ansicht. Hinzu kommen ungültige Eingaben, geschützte Vorlagen,
|
|
alte Rechnungsdaten, Kundenkonflikte, Hintergrundfehler und Doppelklickschutz.
|
|
Tests verwenden ausschließlich temporäre Verzeichnisse und fiktive Beispieldaten;
|
|
sie belegen keine Nummern im echten Rechnungsstamm.
|