fix: DKB-Empfaenger/Zweck-Split per CSV-Ground-Truth, Vergleichswerkzeug
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -5,6 +5,7 @@ from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from app.parsers.dkb import _split_counterparty
|
||||
from app.parsers.registry import parse_pdf
|
||||
from app.parsers.validate import balance_difference
|
||||
|
||||
@@ -56,3 +57,64 @@ def test_expected_values(filename, bank):
|
||||
assert str(t.amount) == c["amount"]
|
||||
assert c["counterparty_contains"].lower() in t.counterparty.lower()
|
||||
assert c["purpose_contains"].lower() in t.purpose.lower()
|
||||
|
||||
|
||||
# --- DKB Empfänger/Zweck-Split-Heuristik (D-T5-1/D-T5-2) -------------------
|
||||
# Ausschließlich synthetische Zeilen (fiktive Namen/Nummern), keine echten
|
||||
# Kontodaten.
|
||||
|
||||
def test_split_counterparty_legal_form_single():
|
||||
cp, rest = _split_counterparty(
|
||||
"Musterfirma Beispiel GmbH Rechnung Nr. F000123 vom 01.01.20")
|
||||
assert cp == "Musterfirma Beispiel GmbH"
|
||||
assert rest == "Rechnung Nr. F000123 vom 01.01.20"
|
||||
|
||||
|
||||
def test_split_counterparty_legal_form_et_cie_chain():
|
||||
cp, rest = _split_counterparty(
|
||||
"Fiktiv Global S.a.r.l. et Cie S.C.A Onlinedienst Referenz 999")
|
||||
assert cp == "Fiktiv Global S.a.r.l. et Cie S.C.A"
|
||||
assert rest == "Onlinedienst Referenz 999"
|
||||
|
||||
|
||||
def test_split_counterparty_reference_boundary_digit_token():
|
||||
cp, rest = _split_counterparty(
|
||||
"Beispiel Handelsgesellschaft Auftrag 84210 Sonderzahlung")
|
||||
assert cp == "Beispiel Handelsgesellschaft Auftrag"
|
||||
assert rest == "84210 Sonderzahlung"
|
||||
|
||||
|
||||
def test_split_counterparty_reference_boundary_keyword_token():
|
||||
cp, rest = _split_counterparty(
|
||||
"Servicepartner Nord Vertrag ABC123 Laufzeit")
|
||||
assert cp == "Servicepartner Nord"
|
||||
assert rest == "Vertrag ABC123 Laufzeit"
|
||||
|
||||
|
||||
def test_split_counterparty_no_split_pure_words():
|
||||
cp, rest = _split_counterparty("MUSTER PERSON Nebenkosten")
|
||||
assert cp == "MUSTER PERSON Nebenkosten"
|
||||
assert rest == ""
|
||||
|
||||
|
||||
def test_split_counterparty_siehe_anlage():
|
||||
cp, rest = _split_counterparty("siehe Anlage Nr. 7")
|
||||
assert cp == ""
|
||||
assert rest == "siehe Anlage Nr. 7"
|
||||
|
||||
|
||||
def test_split_counterparty_never_empty_guard():
|
||||
# Erstes Token enthält eine Ziffer, darf aber nie selbst die
|
||||
# Referenz-Grenze bilden (Regel greift frühestens ab Token 1) - da kein
|
||||
# weiteres Token eine Ziffer/Schlüsselwort liefert, bleibt die ganze
|
||||
# Zeile als counterparty erhalten (nie leer).
|
||||
cp, rest = _split_counterparty("42 Testfirma Ausgleich")
|
||||
assert cp == "42 Testfirma Ausgleich"
|
||||
assert rest == ""
|
||||
assert cp != ""
|
||||
|
||||
# Einzelnes Token (auch mit Ziffer): kein Schnitt möglich, bleibt
|
||||
# counterparty (nie leer, nie None).
|
||||
cp2, rest2 = _split_counterparty("12345")
|
||||
assert cp2 == "12345"
|
||||
assert rest2 == ""
|
||||
|
||||
Reference in New Issue
Block a user