From 555272bcf67a518b4a7b178693f5e2c7e7309974 Mon Sep 17 00:00:00 2001 From: dfuhrmann3 Date: Tue, 14 Jul 2026 16:06:36 +0200 Subject: [PATCH] =?UTF-8?q?fix(v3):=20Seiten-M=C3=B6blierung=20aus=20BT-22?= =?UTF-8?q?-Freitext=20strippen=20(mehrseitige=20Rechnungen)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bei mehrseitigen Rechnungen steht die erste 'Pos.'-Zeile auf Seite 1, die erste echte Position aber erst nach einem Seitenumbruch. Dadurch rutschte die dazwischen liegende Seiten-Möblierung (Seitenkopf RECHNUNG..Betrag €, Bank-/Registerzeilen) in den globalen Freitext BT-22. extract_pre_position_freetext strippt jetzt diese Möblierung (via _strip_bundle_furniture), bevor die Referenzzeilen entfernt werden. Verifiziert: R26-252 hat nun leeren BT-22; die 7 bekannten Rechnungen behalten ihren Freitext unverändert. Co-Authored-By: Claude Opus 4.8 --- invoice_logic.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/invoice_logic.py b/invoice_logic.py index 161db51..1b9eeb8 100644 --- a/invoice_logic.py +++ b/invoice_logic.py @@ -202,8 +202,11 @@ def extract_pre_position_freetext(text): Position deterministisch aus dem PDF-Text - unabhaengig vom (oft unvollstaendigen) LLM. Alles zwischen der ersten 'Pos.'-Zeile und der ersten Positionsnummer wird uebernommen, ausser den Referenzzeilen (Auftragsbestaetigung/Angebot/Vergabeangebot/Lieferschein/Vertrag), die eigene - Felder haben. Gibt den Freitext zurueck ("" wenn keiner vorhanden) oder None, wenn die - Tabellenstruktur nicht erkennbar ist (dann bleibt ein evtl. LLM-Freitext unveraendert).""" + Felder haben, und der zwischen Seiten wiederholten Moeblierung (Seitenkopf, Bank-/Register- + zeilen, Uebertrag/Vortrag) - relevant bei mehrseitigen Rechnungen, deren erste 'Pos.'-Zeile auf + Seite 1 steht, die erste echte Position aber erst nach einem Seitenumbruch. Gibt den Freitext + zurueck ("" wenn keiner vorhanden) oder None, wenn die Tabellenstruktur nicht erkennbar ist + (dann bleibt ein evtl. LLM-Freitext unveraendert).""" lines = [ln.strip() for ln in text.split("\n")] header_idx = next((i for i, ln in enumerate(lines) if ln == "Pos."), None) @@ -217,10 +220,11 @@ def extract_pre_position_freetext(text): if first_pos_idx is None: return None - freetext_lines = [ - ln for ln in lines[header_idx + 1:first_pos_idx] - if ln and not _REFERENCE_LINE_PATTERN.match(ln) - ] + # Leere Zeilen raus, dann die Seiten-Moeblierung strippen (Seitenkopf 'RECHNUNG'..'Betrag €', + # Bank-/Registerzeilen, Uebertrag/Vortrag), zuletzt die Referenzzeilen mit eigenem Feld. + region = [ln for ln in lines[header_idx + 1:first_pos_idx] if ln] + region = _strip_bundle_furniture(region) + freetext_lines = [ln for ln in region if not _REFERENCE_LINE_PATTERN.match(ln)] return "\n".join(freetext_lines)