feat: Diagnose zeigt Stichtag und Beispieltexte je Übertrag

Der Stichtag eines Kontos wird von der Saldo-Berechnung ignoriert – das
Skript weist jetzt aus, wie viel aus Buchungen bis zum Stichtag stammt
und trotzdem mitzählt. Die Übertrags-Matrix nennt dazu Beispieltexte,
Erkennungstexte der Konten und Transfer-Schlagwörter, damit sich ein
falscher Übertrag seinem Auslöser zuordnen lässt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Guido
2026-08-21 15:22:59 +02:00
co-authored by Claude Opus 5
parent e2387102c1
commit d88efebfeb
2 changed files with 44 additions and 2 deletions
+24
View File
@@ -41,6 +41,13 @@ for r in con.execute(
print(f"{name(r['a'])[:23]:<24}{name(r['b'])[:23]:<24}{r['n']:>5}"
f"{geld(r['raus']) + ' ' + waehrung(r['a']):>14}"
f"{geld(r['rein']) + ' ' + waehrung(r['b']):>14}")
# Beispieltexte: sie verraten, welches Schlagwort oder welcher Erkennungs-
# text den Übertrag ausgelöst hat.
for b in con.execute(
"SELECT COALESCE(payee,'') p, COALESCE(description,'') d, COUNT(*) n "
"FROM transactions WHERE type='transfer' AND account_id=? AND to_account_id=? "
"GROUP BY p, d ORDER BY n DESC LIMIT 3", (r["a"], r["b"])):
print(f" {b['n']:>3}x {(b['p'] + ' | ' + b['d']).strip(' |')[:66]}")
offen = con.execute(
"SELECT COUNT(*) n, SUM(amount_cents) s FROM transactions "
@@ -74,3 +81,20 @@ for r in con.execute(
ziel = name(r["b"]) if r["b"] else "– kein Ziel –"
print(f" {r['date']} {geld(r['amount_cents']):>10} {waehrung(r['a'])} "
f"{name(r['a'])[:18]:<18} -> {ziel[:18]:<18} {r['p'][:30]}")
print("\n=== Erkennungstexte der Konten ===")
print("Ein kurzer Text trifft zu viel: er wird als Teilstring gesucht.")
for r in con.execute(
"SELECT a.name, i.kind, i.value FROM account_identifiers i "
"JOIN accounts a ON a.id = i.account_id ORDER BY LENGTH(i.value), a.name"):
warn = " <-- sehr kurz, trifft leicht Fremdes" if len(r["value"]) < 8 else ""
print(f" {r['name'][:24]:<26}{r['kind']:<10}{r['value']}{warn}")
print("\n=== Transfer-Schlagwörter ===")
for r in con.execute(
"SELECT r.pattern, r.target_account_id t FROM categorization_rules r "
"WHERE r.is_transfer = 1 ORDER BY LENGTH(r.pattern)"):
ziel = name(r["t"]) if r["t"] else "– Ziel wird geraten –"
warn = " <-- sehr kurz" if len(r["pattern"]) < 8 else ""
print(f" {r['pattern'][:34]:<36}-> {ziel}{warn}")