fix: Dieselbe Zahlung ueber zwei Bankzugaenge kam doppelt herein
Wer dieselbe Bank zweimal verbindet, bekommt fuer dieselbe Zahlung zwei verschiedene Kennungen – Enable Banking fuehrt eine Bank je Land getrennt. Genau das passiert bei Revolut: Ueber den DE-Eintrag kommen drei Konten, ueber den LT-Eintrag zusaetzlich die Pockets, also verbindet man beide. Zeigen dann zwei Bankkonten auf dasselbe Konto in Certain, holt jeder Zugang dieselben Umsaetze, und der Duplikatschutz kann sie nicht als dieselben erkennen. Drei Aenderungen: - Ein Konto in Certain wird nur noch von EINEM Bankkonto gefuellt. Ordnet man ein zweites zu, wird die alte Zuordnung geloest. Sie ist ohnehin nie richtig, und stillschweigend doppelt zu buchen ist schlimmer als eine geloeste Zuordnung. - Die Ausnahme im Ueberschneidungsschutz gilt nur noch fuer DASSELBE Bankkonto. Dort entscheidet die Kennung der Bank, und die ist exakt – zwei Aufrundungen ueber 1.00 duerfen sich nicht verschlucken. Buchungen aus einem ANDEREN Zugang zaehlen jetzt mit. - Das Aufraeumskript kennt den Fall: Findet es in einer Gruppe (Konto, Art, Tag, Betrag) Buchungen aus zwei Zugaengen, bleibt die Fassung EINES Zugangs stehen. Aufrundungen aus einem einzigen Zugang bleiben unangetastet, auch wenn sie gleich aussehen. An nachgestellten Daten geprueft: Aus -579.50 wird -290.50; die drei gleichen Aufrundungen aus einem Zugang bleiben alle stehen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -532,21 +532,29 @@ def _startdatum(db: Session, user: User, konto: Account,
|
||||
return min(heute, max(frueheste, letzte + timedelta(days=1)))
|
||||
|
||||
|
||||
def _fremde_buchungen(db: Session, user: User, konto: Account,
|
||||
seit: date) -> dict[tuple[str, int], list]:
|
||||
"""Buchungen des Kontos, die NICHT von der Bank kamen, nach Art und Betrag.
|
||||
def _fremde_buchungen(db: Session, user: User, konto: Account, seit: date,
|
||||
remote_uid: str) -> dict[tuple[str, int], list]:
|
||||
"""Buchungen des Kontos, die NICHT aus DIESEM Bankkonto stammen.
|
||||
|
||||
Ein Abruf ueber einen laengeren Zeitraum greift in Monate zurueck, die
|
||||
schon per CSV eingelesen sind. Der Duplikatschutz erkennt das nicht: Sein
|
||||
Schluessel enthaelt den Empfaengertext, und der lautet bei der Bank anders
|
||||
als im Auszug. Ohne diese Pruefung stuende die Zahlung zweimal da.
|
||||
|
||||
Ausgenommen sind nur Buchungen aus DEMSELBEN Bankkonto: Dort entscheidet
|
||||
die Kennung der Bank, und die ist exakt – zwei Aufrundungen ueber 1.00
|
||||
duerfen sich nicht gegenseitig verschlucken. Buchungen aus einem ANDEREN
|
||||
Bankzugang zaehlen dagegen mit. Genau das passiert, wenn dieselbe Bank
|
||||
zweimal verbunden ist (Enable Banking vergibt je Land eigene Kennungen):
|
||||
Dieselbe Zahlung kaeme sonst ueber beide Zugaenge herein.
|
||||
"""
|
||||
aus_bank = {
|
||||
aus_diesem_konto = {
|
||||
txn_id
|
||||
for (txn_id,) in db.query(InboxItem.transaction_id).filter(
|
||||
InboxItem.owner_id == user.id,
|
||||
InboxItem.source == InboxSource.bank,
|
||||
InboxItem.transaction_id.isnot(None),
|
||||
InboxItem.external_id.startswith(f"{remote_uid}:"),
|
||||
)
|
||||
}
|
||||
je_schluessel: dict[tuple[str, int], list] = {}
|
||||
@@ -556,7 +564,7 @@ def _fremde_buchungen(db: Session, user: User, konto: Account,
|
||||
Transaction.type != TxnType.transfer,
|
||||
Transaction.date >= seit - timedelta(days=csv_import.INBOX_TAGE),
|
||||
):
|
||||
if txn.id in aus_bank:
|
||||
if txn.id in aus_diesem_konto:
|
||||
continue
|
||||
je_schluessel.setdefault((txn.type.value, txn.amount_cents), []).append(txn)
|
||||
return je_schluessel
|
||||
@@ -610,7 +618,8 @@ def hole_umsaetze(db: Session, user: User, verbindung: BankConnection,
|
||||
verbraucht: set[int] = set()
|
||||
# ... und eine fuer schon vorhandene, nicht von der Bank stammende
|
||||
# Buchungen. Beide muessen ueber alle Zeilen des Kontos halten.
|
||||
fremde = _fremde_buchungen(db, user, konto, seit)
|
||||
fremde = _fremde_buchungen(db, user, konto, seit,
|
||||
verknuepfung.remote_uid)
|
||||
fremde_verbraucht: set[int] = set()
|
||||
for umsatz in client.umsaetze(verknuepfung.remote_uid, seit):
|
||||
geholt += 1
|
||||
|
||||
Reference in New Issue
Block a user