Files
einvoice/Documentation.md
T

219 lines
12 KiB
Markdown

# Bedienung und technische Dokumentation
Stand: 16.10.2026 · Version 1.0
## Einrichtung und persönliche Vorlagen
Die README enthält den sofort nutzbaren Ein-Aufruf-Ablauf mit `einvoice --create`. Installation aus dem Repository
mit `pip install -e '.[pdf]'`; Java wird für Mustang benötigt. `setup-mustang`
installiert die geprüfte Referenzversion 2.26.0 aus Maven Central mit SHA1-Abgleich.
Der Abgleich prüft die Downloadintegrität; er ist keine Signaturprüfung.
`mustang-update` zeigt neuere Versionen, `mustang-update --apply` installiert sie.
Danach eine Testrechnung erneut prüfen. `JR_EINVOICE_MUSTANG_JAR` überschreibt den
Standardpfad. Downloads erfolgen nur bei Setup/Update; Generierung und Validierung
laufen lokal ohne Upload der Rechnungsdaten.
Vorlagen werden in dieser Reihenfolge zusammengeführt:
1. `examples/invoice.init.yaml`.
2. Versionierte `presets/seller.default.yaml` mit Beispieldaten.
3. Lokale `private/presets/seller.default.yaml`.
4. Lokale `private/presets/customers/<kunde>.yaml`, sonst die versionierte Kunden-Datei,
sonst `presets/customers.yaml`.
5. Rechnungsnummer, Datum, Zahlungsziel und Monats-/Stundenangaben des Befehls.
`JR_EINVOICE_HOME=/absoluter/pfad` setzt das private Datenverzeichnis.
`JR_EINVOICE_PRESETS=/absoluter/pfad` setzt ein anderes Verzeichnis für die lokalen
Vorlagen (gleiche Unterstruktur). Persönliche Daten nicht in die versionierten
Beispieldateien eintragen. `private/`, `invoices/`, die virtuelle Umgebung und
Ausgabeordner sind gitignoriert. Externe Rechnungsordner separat gegen versehentliches
Committen sichern. Die lokale IDV-Vorlage ist nur historischer Bestand; keine Empfängeradresse ist dafür erforderlich.
## Befehle
`jr-einvoice --help` und `<befehl> --help` zeigen alle Parameter.
```bash
# Vollständig erzeugen und validieren (normaler Ablauf):
einvoice --create --Customer "Kundenfirma GmbH" \
--Entry "Geleistete Stunden Oktober 2026" --Volume 120 --Price "85,00 €"
# Expertenablauf für mehrere Positionen / manuell bearbeitete YAML-Dateien:
jr-einvoice init private/invoices --auto-folder --open
jr-einvoice generate /pfad/zum/rechnungsordner --json
jr-einvoice email /pfad/zum/rechnungsordner --to rechnung@empfaenger.example
```
### Ein-Aufruf-Erstellung
`einvoice` ist ein eigener Konsolenbefehl. Die Optionen `--Customer`, `--Entry`,
`--Volume` und `--Price` sind erforderlich. Der Kunde wird über den Namen oder einen
angezeigten Schlüssel aus `einvoice --customers` gefunden. Für neue Kunden erfasst
der Befehl einmalig eine vollständige Rechnungsanschrift. Alternativ können diese
Daten mit `--Street`, `--PostalCode`, `--City` und optional `--Country`, `--Email`,
`--VatId` übergeben werden. In Skripten führen fehlende Daten zu einer konkreten
Fehlermeldung; es gibt keine erfundenen Adressen oder hängenden Eingabeaufforderungen.
Adressoptionen überschreiben keine bereits gespeicherten Kunden. Deren Stammdaten
gezielt in der lokalen Kundendatei bearbeiten. Der Kunde IDV ist ein ehemaliger
Kunde und hat keine besondere Rolle im Ablauf.
`--Price` ist der Nettopreis pro Einheit. Deutsche Schreibweise (`85,00 €`,
`1.234,56 EUR`) und ungegliederte Dezimalpunkt-Schreibweise (`85.00`) sind zulässig.
`--Volume` und `--Tax` verstehen dieselben Dezimalzahlen. Ohne Dezimalkomma gilt ein
Punkt als Dezimalpunkt; `1.234` bedeutet daher 1,234 und nicht 1234. Gemischte oder
ungültige Angaben werden abgewiesen. Standardwerte: `--Unit HUR`, `--Tax 19`,
`--DueDays 30`, Rechnungsdatum heute. Preis, Menge und Steuer werden ausdrücklich
angegeben bzw. verwenden diese dokumentierten Standardwerte; ein alter
kundenspezifischer Stundensatz wird nicht unbemerkt übernommen.
Ein deutscher Monatsname plus Jahr in `--Entry`, z. B. „Oktober 2026“, ergibt den
vollständigen Leistungsmonat. `--Month YYYY-MM` setzt ihn ausdrücklich;
`--ServiceDate YYYY-MM-DD` überschreibt die automatische Erkennung durch ein
Einzeldatum. Beide expliziten Optionen zusammen sind nicht zulässig. Ohne Monat
oder Leistungsdatum gilt das Rechnungsdatum als Leistungsdatum. Die Konsole zeigt
den verwendeten Zeitraum; tatsächliche Leistungsdaten vor Versand prüfen.
Nummern werden unter Dateisperre im gewählten `--root` automatisch als
`JR-JJJJ-NNNN` vergeben. Alle gespeicherten YAML-Rechnungen auf der ersten Ebene
werden auf bereits verwendete Nummern geprüft; `--Number` kann eine eigene freie
Nummer setzen. Bei fehlgeschlagenem PDF-Build bleibt der Entwurf erhalten und
reserviert seine Nummer. Der Befehl meldet einen Fehler und veröffentlicht kein
fertiges Anhang-PDF. In `out/logs/run.log` stehen Details. Zum Korrigieren und
Wiederholen den betreffenden Entwurf mit `jr-einvoice generate` aufbauen; keinen
bereits versandten Datensatz verändern.
Nach erfolgreicher PDF/A- und XML-Validierung wird das vollständige hybride PDF
zusätzlich als `Rechnung_<Nummer>.pdf` im Rechnungsordner bereitgestellt. Diese
Datei direkt an eine E-Mail anhängen. `out/invoice.pdf` ist lediglich die Sichtkopie.
`out/manifest.json` hält SHA-256-Prüfsummen einschließlich des Anhang-PDFs fest.
`--json` schreibt nur ein JSON-Ergebnis mit Nummer, Ordner, PDF, Prüfbericht, Log
und `technical_validation: valid` nach stdout. Keine automatische Mailübertragung.
Die Konsole bestätigt „PDF/A und EN16931-XML technisch gültig“. Sie behauptet
keine vollständige rechtliche oder steuerliche Prüfung der Geschäftsdaten;
siehe [BMF-FAQ zur Validierung](https://www.bundesfinanzministerium.de/Content/DE/FAQ/e-rechnung.html).
### Älterer Monatsentwurf
Der ergänzende `jr-einvoice monthly`-Befehl bleibt für gespeicherte
Stundenvorlagen verfügbar; der neue Standard ist `einvoice --create`.
`monthly` übernimmt genau eine Stundenposition (`HUR`) aus der Kundenvorlage,
setzt deren Menge und deutschen Monatsnamen sowie Anfang/Ende des Monats. `--date`
setzt ein abweichendes Rechnungsdatum, ansonsten gilt heute. `--rate` überschreibt
den Nettostundensatz. Ungültige Monatsentwürfe hinterlassen keinen Rechnungsordner.
Explizite Nummern dürfen noch nicht vergeben sein. `monthly` prüft YAML-Rechnungen
auf der ersten Ordnerebene desselben Stamms, auch bei anderen Kunden, und verhindert
Überschreiben. Das optionale Nummernvorschlagen von `init --auto-folder` verwendet
weiter das Schema `YYYY-NNNN` aus Ordnernamen. Es kennt die bisherigen `YYYY-MM`-PDFs
nicht. Für den Wechsel daher eine freie Nummer ausdrücklich setzen; keine
bereits versandte Rechnung unter gleicher Nummer neu ausstellen. Die lokale
Ordneranlage ist per Dateisperre serialisiert; kein verteiltes Rechnungsregister.
`init --print-path-only`, `generate --print-artifacts-only` und `generate --json`
schreiben maschinenlesbare Ergebnisse nach stdout; Logs laufen nach stderr.
`--open` verwendet `$EDITOR`, danach verfügbare Editoren. Ein unbekannter Kunde
führt zu einem Fehler statt zu einer Rechnung mit generischem Empfänger.
## YAML und Beträge
Die vollständige Ausgangsvorlage steht in `examples/invoice.sample.yaml`.
Zusätzlich werden folgende optionale Meta-Felder unterstützt:
```yaml
meta:
# ... invoice_number, invoice_date, service_date, currency ...
service_period_start: '2026-10-01'
service_period_end: '2026-10-31'
buyer_reference: 'Kundenreferenz'
order_reference: 'Bestellnummer'
```
Alle Pflichtangaben einschließlich Leistungsbeschreibung und Zeitraum gelangen
in PDF und XML. Für Monatsrechnungen steht `service_date` auf dem Monatsende.
Bei Teilmonaten den tatsächlichen Zeitraum setzen. `payment.reference` ist der
Verwendungszweck, keine Bestellnummer. Kunden- und Bestellreferenzen stehen in den
eigenen Meta-Feldern. Ein B2B-Empfänger benötigt keine erfundene Leitweg-ID.
Geld, Mengen und Steuersätze verwenden `Decimal`. Jede Nettoposition wird kaufmännisch
auf Cent gerundet; je Steuersatz wird die Steuer aus der Summe der gerundeten
Nettopositionen berechnet und auf Cent gerundet. PDF und XML verwenden dieselbe
Berechnung. Dezimalpunkt verwenden; besonders genaue Mengen/Preise in YAML als
Zeichenkette angeben (`quantity: '72.5'`). Leere Positionen, nicht endliche Zahlen,
negative Preise, Nullsteuersätze, unbekannte YAML-Felder und ungültige IBAN-Prüfsummen
werden abgewiesen. Der Validator prüft zusätzlich Format und Geschäftsregeln.
## PDF/A, XML und Validierung
WeasyPrint erzeugt PDF/A-3b. Mustang kombiniert diese Sichtkopie mit dem CII-D16B-XML,
Profil EN16931 (`--format fx --version 1 --profile E`). Die konkrete Kombination
wurde mit Mustang 2.26.0 einschließlich PDF/A und eingebettetem XML erfolgreich
geprüft. Die CLI-Formatversion `1` bezeichnet Factur-X, nicht ZUGFeRD 1.
Es wird keine Behauptung einer Zertifizierung oder vollständigen Unterstützung
aller neuen ZUGFeRD-2.5.2-Funktionen abgeleitet.
Der frühere wkhtmltopdf-Fallback bleibt für eine Sichtkopie verfügbar, garantiert
aber kein PDF/A. Ohne gültiges PDF/A darf die abschließende Prüfung nicht bestehen.
Für den produktiven Weg WeasyPrint verwenden.
`generate` kombiniert und validiert immer. Die Python-Pipeline kann für interne
Anwendungsfälle auch nur Sichtkopie und XML erzeugen. Ein Erfolg erfordert einen
parsebaren Mustang-Bericht mit XML-Prüfabschnitt und ausschließlich gültigen
Zusammenfassungen einschließlich Gesamtergebnis. Ein Exitcode 0 allein genügt nicht.
Bei fehlgeschlagener Validierung bleibt der Bericht erhalten und das nicht freigegebene
hybride PDF wird entfernt. Alte Mailentwürfe werden bei einem neuen Build verworfen.
Pro Lauf stehen Details und Mustang-Ausgaben in `out/logs/run.log`.
Für Eingänge kann `validate` XML und hybride PDF prüfen. Eine normale PDF-Datei
wird nicht als strukturierte E-Rechnung akzeptiert. Quellen bleiben unverändert;
Berichte an einem eigenen Pfad aufbewahren. Inhaltliche Prüfung (Leistung, Parteien,
Betrag, Steuersatz, Doppelrechnung) bleibt zusätzlich erforderlich.
## Versand und Aufbewahrung
`email` erzeugt die Standardausgabe erneut aus `invoice.yaml` und legt erst nach
erfolgreicher Prüfung `invoice.eml` an. Absender kommt aus `seller.email`, Empfänger
aus `buyer.email` oder `--to`. Die Mail enthält nur das hybride PDF als Rechnungsanhang;
XML ist darin eingebettet. `X-Unsent: 1` kennzeichnet den Entwurf. Kein SMTP-Zugang,
kein Passwort und kein automatischer Versand sind nötig. Das konkrete Öffnen als
Entwurf hängt vom Mailprogramm ab. Versand und Zustellnachweis erfolgen dort.
`manifest.json` enthält SHA-256-Prüfsummen von YAML, XML, hybridem PDF, Bericht und
EML. Es unterstützt die Integritätskontrolle, schafft aber allein kein unveränderbares
Archiv. Nach Versand den vollständigen Rechnungsordner und die gesendete Originalmail
samt Versandnachweis in die bestehende gesicherte Ablage übernehmen. Versandte
Rechnungen nicht durch erneutes `generate` überschreiben. Für Berichtigungen einen
fachlich abgestimmten Prozess verwenden. Das Tool verwaltet keine Stornos.
## Prüfung der Überarbeitung
```bash
python -m unittest discover -s tests -v
# Einschließlich echter PDF-/XML-/Mail-Prüfung durch Mustang:
JR_EINVOICE_INTEGRATION=1 python -m unittest discover -s tests -v
```
Die Tests decken deutschen Preisparser, neue/wiederverwendete Kunden, Ein-Aufruf-Nummernvergabe,
Abbruch ohne fertigen PDF-Anhang sowie dezimale Rundung, mehrere Steuersätze, Pflichtdaten und ungültige
Zahlen/IBAN, XML-Inhalte, HTML-Escaping, Monatsgrenzen einschließlich Schaltjahr,
Nummernkollisionen, unbrauchbare oder widersprüchliche Validierungsberichte sowie
veraltete Mailentwürfe ab. Der echte Mustang-Lauf ist ein zusätzlicher Integrationstest
und erfordert Java und das lokale Jar.
Lokal wurde eine Testrechnung mit den Juli-Beispielwerten erstellt: 75 Stunden zu
85 EUR → 6.375,00 EUR netto + 1.211,25 EUR USt = 7.586,25 EUR. Nummer `TEST-2026-07`,
keine neue echte Rechnung. Der Mailtest verwendet die nicht zustellbare Adresse
`rechnung@example.invalid`. Die alten PDF-Rechnungen wurden nicht verändert.
## Bewusster Funktionsumfang
Normale positive Dienstleistungsrechnungen in EUR mit positiver Umsatzsteuer und mehreren
Steuersätzen sind unterstützt. Nicht implementiert sind steuerfreie Positionen,
Kleinunternehmer, Reverse Charge, Abschläge/Anzahlungen, Skonto/Zuschläge/Rabatte,
Gutschriften/Storno, Fremdwährungs-Steuerumrechnung, XRechnung-CIUS-Ausgabe,
Peppol, DATEV-API und automatischer Postfacheingang. Diese Fälle nicht durch bloße
Freitexthinweise nachbilden. Das vorhandene CII-XML ist keine XRechnung, auch wenn
beide Formate EN16931 verwenden. Aufbewahrung/Backups und fachliche Freigabe müssen
in den betrieblichen Ablauf eingebunden werden.