From c230a27cff333413d8a1591300780eef42d8f577 Mon Sep 17 00:00:00 2001 From: TheMockTv Date: Thu, 3 Sep 2026 21:41:14 +0200 Subject: [PATCH] Angebote werden nicht gebucht - doppelt gesichert Das Rechnungstool schreibt jetzt unverbindliche Angebote (frueher Proforma). Uebersprungen werden sie zuerst ueber die Kenndaten (art=angebot, die ueberleben auch ein Umbenennen) und, falls die einmal fehlen, ueber Dateiname und Unterordner ('Angebot_...' bzw. 'Angebote/') - sein Vorschlag: 'kann er ja am dateinamen festmachen, steht ja dann rechnung oder angebot'. Eine echte Rechnung wird davon nicht erfasst, das prueft pruef_angebot.py mit. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01GYeAfLtccFrbU3MTj1MMTx --- pdf_parser.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/pdf_parser.py b/pdf_parser.py index 8578125..4bc73eb 100644 --- a/pdf_parser.py +++ b/pdf_parser.py @@ -177,6 +177,11 @@ def _aus_metadaten(pfad: str): return daten +# Blaetter, die nichts abrechnen und deshalb nicht gebucht werden. +# "proforma" steht aus der ersten Fassung des Angebots-Blattes noch mit drin. +KEINE_BUCHUNG = ("berichtigung", "angebot", "proforma") + + def berichtigung_daten(pfad: str): """Kenndaten eines Berichtigungsblatts (ยง 31 Abs. 5 UStDV), sonst None. @@ -200,10 +205,18 @@ def keine_buchung(pfad: str) -> bool: """ if berichtigung_daten(pfad) is not None: return True - # Die Proforma ist eine unverbindliche Vorab-Aufstellung, kein Umsatz: + # Das Angebot ist eine unverbindliche Vorab-Aufstellung, kein Umsatz: # gemeldet wird eine Uebernachtung erst, wenn sie abgerechnet ist. kopf = _aus_metadaten(pfad) - return bool(kopf and kopf.get("art") == "proforma") + if kopf and kopf.get("art") in KEINE_BUCHUNG: + return True + # Zweite Sicherung ueber den Dateinamen: die Kenndaten sind die erste + # Quelle (sie ueberleben auch ein Umbenennen), aber fehlen sie einmal, + # sagt der Name es auch - das Rechnungstool schreibt "Angebot_..." und + # legt sie in den Unterordner "Angebote". + name = os.path.basename(pfad).lower() + ordner = os.path.basename(os.path.dirname(os.path.abspath(pfad))).lower() + return name.startswith("angebot_") or ordner == "angebote" def parse_pdf(pfad: str, standard_satz: float = STANDARD_SATZ) -> Buchung: