Lokalen Rechnungsassistenten mit Vorlagen und PDF-Vorschau ergänzen
This commit is contained in:
1 parent
f447603af4
commit
b9f307fc81
15 files changed
+1423
-26
No files matched your search
Binary file not shown.
|
After Width: | Height: | Size: 198 KiB |
@@ -0,0 +1,148 @@
|
||||
# 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.
|
||||
Reference in new issue
Block a user