feat: Pockets sind erkennbar und zuordenbar
Ein Revolut-Pocket bringt weder eigene IBAN noch eigenen Namen mit. Certain hielt bisher nur uid, IBAN, Name und Waehrung fest – mehrere Konten derselben Bank sahen damit gleich aus, und in der Zeile stand die rohe Kennung. Jetzt werden Produktbezeichnung und die Kennung fuer Konten ohne IBAN mitgefuehrt, der angezeigte Name faellt der Reihe nach auf Name, Details, Produkt, Kennung, IBAN zurueck statt auf die uid, und der uebermittelte Datensatz laesst sich aufklappen – nachsehen statt raten, wenn zwei Konten gleich aussehen. Beim Neuverbinden werden die Merkmale aufgefrischt, ohne die Zuordnung anzutasten. Fehlt ein Konto in der Waehrung des Bankkontos, steht das jetzt dabei; vorher war die Auswahl einfach leer. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -15,6 +15,7 @@ Sonderbehandlung greifen. Eine dritte Quelle, kein dritter Sonderweg.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import logging
|
||||
import secrets
|
||||
from datetime import date, datetime, timedelta, timezone
|
||||
@@ -174,6 +175,47 @@ def starte_verbindung(db: Session, user: User, aspsp_name: str, land: str,
|
||||
return {"url": antwort.get("url"), "connection_id": verbindung.id, "state": state}
|
||||
|
||||
|
||||
# Wie viel des uebermittelten Datensatzes aufgehoben wird. Ein Konto sind ein
|
||||
# paar hundert Zeichen; die Grenze ist nur da, damit eine ungewoehnlich
|
||||
# gespraechige Bank die Zeile nicht sprengt.
|
||||
ROHDATEN_MAX = 4000
|
||||
|
||||
|
||||
def _merkmale(konto: dict) -> dict:
|
||||
"""Woran sich ein Bankkonto erkennen laesst.
|
||||
|
||||
Ein Revolut-Pocket bringt weder eigene IBAN noch eigenen Namen mit. Ohne
|
||||
Produktbezeichnung und Ersatzkennung sehen mehrere Konten derselben Bank
|
||||
identisch aus – man kann sie dann weder unterscheiden noch zuordnen.
|
||||
"""
|
||||
kennung = konto.get("account_id") or {}
|
||||
iban = kennung.get("iban")
|
||||
|
||||
# PSD2 fuehrt Konten ohne IBAN unter ``other``; manche Banken liefern
|
||||
# stattdessen nur die Sammelliste.
|
||||
andere = (kennung.get("other") or {}).get("identification")
|
||||
if not andere:
|
||||
for eintrag in konto.get("all_account_ids") or []:
|
||||
wert = (eintrag or {}).get("identification")
|
||||
if wert and wert != iban:
|
||||
andere = wert
|
||||
break
|
||||
|
||||
produkt = konto.get("product") or konto.get("cash_account_type")
|
||||
# Reihenfolge nach Aussagekraft. Die uid steht bewusst am Ende: Sie ist
|
||||
# eindeutig, sagt aber niemandem, welches Konto gemeint ist.
|
||||
name = (konto.get("name") or konto.get("details") or produkt
|
||||
or andere or iban or konto.get("uid"))
|
||||
return {
|
||||
"iban": str(iban)[:64] if iban else None,
|
||||
"other_id": str(andere)[:128] if andere else None,
|
||||
"product": str(produkt)[:120] if produkt else None,
|
||||
"remote_name": str(name)[:255] if name else None,
|
||||
"currency": (konto.get("currency") or "EUR").upper()[:3],
|
||||
"raw_json": json.dumps(konto, ensure_ascii=False, default=str)[:ROHDATEN_MAX],
|
||||
}
|
||||
|
||||
|
||||
def schliesse_verbindung(db: Session, user: User, state: str, code: str) -> dict:
|
||||
"""Code gegen die Sitzung tauschen und die gefundenen Konten ablegen.
|
||||
|
||||
@@ -216,18 +258,18 @@ def schliesse_verbindung(db: Session, user: User, state: str, code: str) -> dict
|
||||
.filter(BankAccountLink.owner_id == user.id, BankAccountLink.remote_uid == uid)
|
||||
.first()
|
||||
)
|
||||
merkmale = _merkmale(konto)
|
||||
if vorhanden is not None:
|
||||
# Schon bekannt – die Zuordnung bleibt bewusst erhalten.
|
||||
# Schon bekannt – die Zuordnung bleibt bewusst erhalten. Die
|
||||
# Merkmale werden aber aufgefrischt, sonst muesste man loeschen,
|
||||
# um an eine spaetere Produktbezeichnung zu kommen.
|
||||
vorhanden.connection_id = verbindung.id
|
||||
for feld, wert in merkmale.items():
|
||||
setattr(vorhanden, feld, wert)
|
||||
bekannt += 1
|
||||
continue
|
||||
db.add(BankAccountLink(
|
||||
owner_id=user.id,
|
||||
connection_id=verbindung.id,
|
||||
remote_uid=uid,
|
||||
iban=(konto.get("account_id") or {}).get("iban"),
|
||||
remote_name=konto.get("name"),
|
||||
currency=(konto.get("currency") or "EUR").upper(),
|
||||
owner_id=user.id, connection_id=verbindung.id, remote_uid=uid, **merkmale,
|
||||
))
|
||||
neu += 1
|
||||
|
||||
|
||||
Reference in New Issue
Block a user