Alle drei Bank-Parser gegen die realen Fixtures gehaertet: - DKB/VR/HVB: Sammlung endet am Schlusssaldo (break), damit Summen, Rechnungsabschluss und Hinweisseiten nicht mehr in die letzte Buchung rutschen. - Generische, rein strukturelle Noise-Filter fuer wiederkehrende Seitenfuss-/Kopfbloecke und Blattwechsel-Reste (keine Kontodaten hart codiert); Kopf-/Hinweisbloecke werden als Sequenz uebersprungen. - VR: Rekonstruktion harter Zeilenumbrueche im Verwendungszweck unter konservativen Schutzbedingungen (nur purpose, nicht counterparty). - Neue Noise- und expected-Value-Tests; expected_*.json gitignored. - Audit-Werkzeug scripts/parser_audit.py ergaenzt (nur lokale Nutzung). Transaktionszahlen und Saldo-Differenzen unveraendert; max. Laenge des Verwendungszwecks je Bank deutlich unter 300 Zeichen. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
30 lines
1.1 KiB
Python
30 lines
1.1 KiB
Python
"""Parser-Audit: geparste Transaktionen + Rohtext einer Fixture anzeigen.
|
|
|
|
NUR lokal verwenden - Ausgabe enthaelt echte Kontodaten und darf nicht
|
|
in Commits, Reports oder Tickets uebernommen werden.
|
|
Aufruf: python scripts/parser_audit.py tests/fixtures/dkb_beispiel.pdf
|
|
"""
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
import pdfplumber
|
|
|
|
from app.parsers.registry import parse_pdf
|
|
from app.parsers.validate import balance_difference
|
|
|
|
path = Path(sys.argv[1])
|
|
stmt = parse_pdf(path)
|
|
print(f"bank={stmt.bank} iban={stmt.iban} "
|
|
f"period={stmt.period_start}..{stmt.period_end}")
|
|
print(f"opening={stmt.opening_balance} closing={stmt.closing_balance} "
|
|
f"diff={balance_difference(stmt)} n_tx={len(stmt.transactions)}")
|
|
print("-" * 100)
|
|
for i, t in enumerate(stmt.transactions):
|
|
print(f"#{i:3d} | {t.booking_date} | {t.value_date} | {t.amount:>12} "
|
|
f"| {t.counterparty[:40]:40} | {t.purpose[:60]}")
|
|
print("=" * 100)
|
|
with pdfplumber.open(path) as pdf:
|
|
for n, page in enumerate(pdf.pages, 1):
|
|
print(f"--- Seite {n} ---")
|
|
print(page.extract_text() or "(kein Text)")
|