fix: Status-Prüfung beim Import ist sprachunabhängig

Die neue Statusprüfung ließ nur „COMPLETED" durch. Deutsche Bank-Exporte
schreiben aber „ABGESCHLOSSEN", wodurch keine einzige Zeile mehr buchbar war.

Statt einer Positivliste jetzt eine Sperrliste (storniert/ausstehend/abgelehnt/
fehlgeschlagen, jeweils deutsch und englisch); unbekannte Status werden gebucht,
damit keine echten Buchungen still verloren gehen.

Test mit echtem deutschem Revolut-Export inkl. reiner Gebührenzeile
(Betrag 0.00, Gebühr 10.99): Endsaldo trifft die Kontostand-Spalte. 81 grün.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Guido
2026-08-21 06:41:32 +02:00
co-authored by Claude Opus 4.8
parent d725f5cf57
commit 4520c7318f
2 changed files with 68 additions and 1 deletions
+21 -1
View File
@@ -211,6 +211,26 @@ def _guess_target_account(text_idents: list[tuple[str, int]], payee: str, purpos
return best[1] if best else None
# Status-Werte, die eine Buchung NICHT wirksam werden lassen. Bewusst als
# Sperrliste (nicht Positivliste): Bank-Exporte sind lokalisiert – „COMPLETED"
# heißt auf Deutsch „ABGESCHLOSSEN". Unbekannte Werte werden gebucht, damit
# keine echten Buchungen still verloren gehen.
UNBOOKABLE_STATES = (
"PENDING", "AUSSTEHEND", "SCHWEBEND",
"REVERTED", "RUECKGAENGIG", "RÜCKGÄNGIG", "STORNIERT", "STORNO",
"DECLINED", "ABGELEHNT",
"FAILED", "FEHLGESCHLAGEN",
"CANCELLED", "CANCELED", "ABGEBROCHEN",
)
def state_is_bookable(state: str | None) -> bool:
s = (state or "").strip().upper()
if not s:
return True
return not any(bad in s for bad in UNBOOKABLE_STATES)
# Fenster, in dem eine Buchung als Gegenseite eines bestehenden Transfers gilt
# (Buchungs-/Valutadatum können ein paar Tage auseinanderliegen).
COUNTERPART_DAYS = 5
@@ -329,7 +349,7 @@ def detect_rows(db: Session, user: User, account: Account, candidates: list[dict
# (REVERTED) und schwebende (PENDING) Zeilen mit – die dürfen den Saldo
# nicht verändern.
state = (cand.get("state") or "").upper()
state_ok = state in ("", "COMPLETED")
state_ok = state_is_bookable(state)
# Zeile in fremder Währung (Revolut-Export enthält alle Währungs-Pockets).
row_cur = (cand.get("row_currency") or "").upper()
currency_ok = not row_cur or row_cur == account.currency.upper()