fix: Abruf ueber schon eingelesene Monate buchte alles doppelt
"Aelteres nachholen" greift 90 Tage zurueck – mitten in Monate, die schon per CSV eingelesen sind. Genau davor schuetzt sonst das Startdatum, und der Knopf haengt es aus. Der Duplikatschutz faengt das nicht: Sein Schluessel enthaelt den Empfaengertext, und der lautet bei der Bank anders als im Auszug. Ergebnis: jede Zahlung des Zeitraums zweimal. Das war mein Fehler – ich habe den Knopf gebaut UND empfohlen, ohne die Sicherung zu ersetzen, die er aushebelt. Der Abruf prueft jetzt selbst: Gibt es auf dem Konto schon eine Buchung gleicher Richtung und gleichen Betrags im Umkreis von drei Tagen, die NICHT von der Bank kam, ist der Umsatz dieselbe Bewegung und wird uebersprungen. Jede vorhandene Buchung erklaert dabei hoechstens einen Umsatz – sonst verschluckte eine Kaffeezahlung alle weiteren desselben Betrags. Die Zahl der uebersprungenen steht in der Rueckmeldung. Fuer den bereits angerichteten Schaden gibt es scripts/raeume_doppelte_bankumsaetze.py: Es findet Bank-Umsaetze, die eine vorhandene Buchung wiederholen, und entfernt IMMER die von der Bank – die eigene traegt die Kategorie des Nutzers. Sie wird verworfen, nicht geloescht, damit kein spaeterer Abruf sie wiederholt. Ohne --wirklich passiert nichts; mit --wirklich wird zuerst eine Kopie der Datenbank angelegt. An nachgestellten Daten geprueft: Aus -95.80 wird -48.40, die eigenen Buchungen samt Kategorie bleiben, der echte neue Umsatz bleibt. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1085,3 +1085,47 @@ def test_startdatum_liegt_nie_in_der_zukunft(admin, fake_bank):
|
||||
assert gegenstelle.date_from <= heute.isoformat(), \
|
||||
f"date_from liegt in der Zukunft: {gegenstelle.date_from}"
|
||||
assert r.json()["ab"] == heute.isoformat()
|
||||
|
||||
|
||||
def test_abruf_ueber_schon_eingelesene_monate_bucht_nicht_doppelt(admin, fake_bank):
|
||||
"""'Aelteres nachholen' greift in Monate zurueck, die schon per CSV
|
||||
eingelesen sind. Der Schluessel des Duplikatschutzes enthaelt den
|
||||
Empfaengertext, und der lautet bei der Bank anders – ohne eigene Pruefung
|
||||
stuende die Zahlung zweimal da."""
|
||||
_app(admin)
|
||||
vor_wochen = date.today() - timedelta(days=30)
|
||||
uid = f"acc-{secrets.token_hex(4)}"
|
||||
fake_bank(
|
||||
konten=[{"uid": uid, "currency": "CHF"}],
|
||||
umsaetze=[
|
||||
{"entry_reference": f"tx-{secrets.token_hex(4)}",
|
||||
"booking_date": vor_wochen.isoformat(),
|
||||
"transaction_amount": {"amount": "35.00", "currency": "CHF"},
|
||||
"credit_debit_indicator": "DBIT",
|
||||
"creditor": {"name": "Coop 6141"}},
|
||||
# Und ein Umsatz, den es noch NICHT gibt – der muss ankommen.
|
||||
{"entry_reference": f"tx-{secrets.token_hex(4)}",
|
||||
"booking_date": vor_wochen.isoformat(),
|
||||
"transaction_amount": {"amount": "7.77", "currency": "CHF"},
|
||||
"credit_debit_indicator": "DBIT",
|
||||
"creditor": {"name": "Neu und echt"}},
|
||||
])
|
||||
state = admin.post("/api/bank/connect",
|
||||
json={"aspsp_name": f"Ueberlapp-{secrets.token_hex(3)}",
|
||||
"country": "CH"}).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"Ueberlapp {secrets.token_hex(3)}", currency="CHF")
|
||||
admin.post(f"/api/bank/links/{link['id']}/account/{konto['id']}")
|
||||
|
||||
# So sieht der schon eingelesene Auszug aus – anderer Text, ein Tag daneben.
|
||||
admin.post("/api/transactions", json={
|
||||
"type": "expense", "date": (vor_wochen + timedelta(days=1)).isoformat(),
|
||||
"account_id": konto["id"], "amount_cents": 3500,
|
||||
"payee": "COOP-6141 KILLWANGEN"})
|
||||
|
||||
r = admin.post(f"/api/bank/links/{link['id']}/sync", params={"tage": 90}).json()
|
||||
assert r["doppelt"] == 1, r
|
||||
assert r["neu"] == 1, "der echte Umsatz muss ankommen"
|
||||
# 35.00 einmal (aus der CSV) plus 7.77 neu – nicht 35.00 zweimal.
|
||||
assert admin.get(f"/api/accounts/{konto['id']}").json()["balance_cents"] == -4277
|
||||
|
||||
Reference in New Issue
Block a user