fix: Ein Umsatz unter neuer Kennung kam ein zweites Mal herein

Der Bankabruf nahm die ERSTE Kennung, die ein Umsatz mitbringt – meist die
Referenz der Bank. Vergibt die Bank sie beim Buchen neu (aus vorgemerkt wird
gebucht), ist es fuer Certain ein anderer Umsatz, und dieselbe Zahlung steht
zweimal da. Genau so sind zwei Mietbuchungen ueber 288 Euro am selben Tag
entstanden.

Zwei Aenderungen:

- Geprueft wird gegen ALLE Kennungen des Umsatzes, nicht nur gegen eine. Damit
  treffen auch Eintraege, die frueher unter einer anderen abgelegt wurden.
- Gespeichert wird die bestaendigste: die eigene Kennung der Schnittstelle
  bleibt gleich, wenn die Bank ihre Referenz austauscht.

Das ist eine von vier Stellen, an denen Certain Dubletten erkennt – neben dem
Import-Schluessel, dem unscharfen Eingangs-Abgleich und dem
Ueberschneidungsschutz. Diese vier gehoeren zusammengefuehrt; das ist ein
eigener Umbau und nicht Teil dieser Korrektur.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Guido
2026-08-30 13:51:50 +02:00
co-authored by Claude Opus 5
parent 67a32bdda9
commit 1509695760
2 changed files with 55 additions and 5 deletions
+39
View File
@@ -1307,3 +1307,42 @@ def test_zu_knapper_takt_wird_gebremst():
# Nach sechs Stunden schon.
knapp.last_sync_at = jetzt - timedelta(hours=7)
assert bank_sync.faellig(knapp, jetzt) is True
def test_umsatz_unter_anderer_kennung_kommt_nicht_zweimal(admin, fake_bank):
"""Liefert die Bank denselben Umsatz spaeter unter einer anderen Kennung –
etwa weil aus vorgemerkt gebucht wurde –, waeren es fuer Certain zwei.
Geprueft wird deshalb gegen ALLE Kennungen, die er mitbringt."""
_app(admin)
heute = date.today().isoformat()
uid = f"acc-{secrets.token_hex(4)}"
stabil = f"tx-{secrets.token_hex(5)}"
salden = [{"balance_type": "CLBD",
"balance_amount": {"amount": "0.00", "currency": "EUR"}}]
def umsatz(referenz):
return {"entry_reference": referenz, "transaction_id": stabil,
"booking_date": heute,
"transaction_amount": {"amount": "288.00", "currency": "EUR"},
"credit_debit_indicator": "DBIT",
"creditor": {"name": "Noemi Koenig"}}
fake_bank(konten=[{"uid": uid, "currency": "EUR"}], salden=salden,
umsaetze=[umsatz("ref-vorgemerkt")])
state = admin.post("/api/bank/connect",
json={"aspsp_name": f"Kennung-{secrets.token_hex(3)}",
"country": "DE"}).json()["state"]
admin.post(f"/api/bank/callback?state={state}&code=guter-code")
link = [v for v in admin.get("/api/bank/links").json() if v["remote_uid"] == uid][0]
konto = _konto(admin, name=f"Kennung {secrets.token_hex(3)}", currency="EUR")
admin.post(f"/api/bank/links/{link['id']}/account/{konto['id']}")
assert admin.post(f"/api/bank/links/{link['id']}/sync").json()["neu"] == 1
assert admin.get(f"/api/accounts/{konto['id']}").json()["balance_cents"] == -28800
# Zweiter Abruf: andere entry_reference, dieselbe transaction_id.
fake_bank(konten=[{"uid": uid, "currency": "EUR"}], salden=salden,
umsaetze=[umsatz("ref-gebucht")])
zweiter = admin.post(f"/api/bank/links/{link['id']}/sync").json()
assert zweiter["neu"] == 0, "unter neuer Referenz noch einmal gebucht"
assert admin.get(f"/api/accounts/{konto['id']}").json()["balance_cents"] == -28800