Files
Vorrania/backend/tests/test_warranty.py
Scarriffle 4a950acd85 Backend: Zeilenpreise als Kaufpreis-Kandidaten anbieten
Bei einer Rechnung mit mehreren Artikeln soll man den Zeilenpreis des passenden
Produkts wählen können. Die Kandidatenliste enthaelt daher wieder alle
geldartigen Betraege (Zeilen- und Summenbetraege), nur ohne MwSt-Satz und
Nicht-Geld-Zahlen; der Auto-Tipp bleibt die Gesamtsumme und steht vorne.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-27 10:45:08 +02:00

159 lines
5.1 KiB
Python

"""Lokale Garantieende-Schätzung aus Belegtext (ohne echtes PDF)."""
from datetime import date
from app.services.warranty import (
guess_acquired_on,
guess_price_candidates,
guess_price_cents,
guess_shop,
guess_warranty_until,
)
def test_zeitraum_plus_kaufdatum_vom_stueck():
# Beleg nennt nur den Zeitraum; das Kaufdatum kommt vom Einzelstück.
text = "Vielen Dank für Ihren Einkauf. 24 Monate Garantie auf dieses Gerät."
assert guess_warranty_until(text, acquired_on=date(2024, 3, 31)) == date(2026, 3, 31)
def test_jahre_werden_verstanden():
text = "2 Jahre Gewährleistung"
assert guess_warranty_until(text, acquired_on=date(2023, 1, 15)) == date(2025, 1, 15)
def test_zeitraum_plus_rechnungsdatum_aus_dem_beleg():
text = "Rechnungsdatum: 05.06.2024\nGarantie: 12 Monate"
assert guess_warranty_until(text) == date(2025, 6, 5)
def test_warranty_keyword_before_period_english():
text = "Warranty period is 36 months from purchase."
assert guess_warranty_until(text, acquired_on=date(2022, 2, 1)) == date(2025, 2, 1)
def test_explizites_datum_neben_stichwort():
text = "Garantie gültig bis 31.12.2027."
assert guess_warranty_until(text) == date(2027, 12, 31)
def test_ohne_hinweise_kein_vorschlag():
assert guess_warranty_until("Nur ein Kassenbon ohne alles.") is None
def test_leerer_text_ist_none():
assert guess_warranty_until("", acquired_on=date(2024, 1, 1)) is None
# ---- Preis ----
def test_preis_nahe_total_stichwort():
text = "Artikel 49.00\nVersand 5.90\nGesamtbetrag: 54.90 CHF"
assert guess_price_cents(text) == 5490
def test_preis_mit_tausendertrenner_apostroph():
text = "Total CHF 1'299.00"
assert guess_price_cents(text) == 129900
def test_preis_deutsches_format():
text = "Rechnungsbetrag 1.299,00 EUR"
assert guess_price_cents(text) == 129900
def test_preis_ohne_waehrung_und_ohne_stichwort_ist_none():
# Reine Zahlen ohne Waehrung/Summen-Stichwort werden NICHT als Preis geraten.
assert guess_price_cents("Position A 12,90\nPosition B 199,00\nDanke.") is None
def test_preis_mit_waehrung_ohne_stichwort_nimmt_groessten():
text = "Kabel 12.90 CHF\nGeraet 199.00 CHF"
assert guess_price_cents(text) == 19900
def test_datum_wird_nicht_als_preis_gelesen():
assert guess_price_cents("Garantie gültig bis 31.12.2027.") is None
assert guess_price_candidates("Kaufdatum 05.06.2024, Garantie bis 31.12.2027") == []
def test_preis_ohne_betrag_ist_none():
assert guess_price_cents("Kein Preis hier.") is None
assert guess_price_cents("") is None
def test_preis_kandidaten_bester_zuerst_ohne_dubletten():
text = "Artikel 49.00 CHF\nVersand 5.90 CHF\nGesamtbetrag: 54.90 CHF\nnochmal 49.00 CHF"
kandidaten = guess_price_candidates(text)
assert kandidaten[0] == 5490 # bester Tipp (Summe) vorne
assert set(kandidaten) == {5490, 4900, 590} # ohne Dubletten
assert guess_price_candidates("") == []
# ---- Kaufdatum & Shop ----
def test_kaufdatum_aus_beleg():
assert guess_acquired_on("Rechnungsdatum: 05.06.2024") == date(2024, 6, 5)
assert guess_acquired_on("nichts hier") is None
def test_shop_erkennt_bekannten_namen():
shops = [(1, "Digitec"), (2, "Galaxus")]
assert guess_shop("Rechnung von Digitec AG, Zürich", shops) == (1, "Digitec")
def test_shop_schlaegt_neuen_namen_vor():
sid, name = guess_shop("ACME Electronics GmbH\nRechnung\nDatum 01.01.2024", [(1, "Galaxus")])
assert sid is None
assert name == "ACME Electronics GmbH"
def test_shop_ohne_text_leer():
assert guess_shop("", [(1, "Digitec")]) == (None, None)
# ---- Realer Galaxus-Beleg (vereinfacht) ----
GALAXUS = """Kaufbeleg / Rechnung Auftrag 161498087
Bestell- / Rechnungsdatum 05.10.2025
Fälligkeitsdatum 26.10.2025
Währung CHF
Delock USB2.0-Ladekabel 10079671 2 8.10% 16.56 17.90 33.12 35.80
24 Monate Garantie (06.10.2025 - 06.10.2027)
Logitech G Pro X 13489068 1 8.10% 102.68 111.00 102.68 111.00
24 Monate Garantie (06.10.2025 - 06.10.2027)
Gesamtbetrag 135.80 146.80
Gesamtbetrag enthält folgende Mehrwertsteuer:
MwSt. 8.10% 11.00
Total aller Lieferungen und Leistungen CHF 146.80
03.11.2025 Zahlung geleistet -146.80
Offener Betrag 0.00
"""
def test_galaxus_kaufdatum_nicht_faelligkeit():
assert guess_acquired_on(GALAXUS) == date(2025, 10, 5)
def test_galaxus_preis_ist_gesamt_inkl():
assert guess_price_cents(GALAXUS) == 14680
def test_galaxus_mwst_satz_ist_kein_preis():
kandidaten = guess_price_candidates(GALAXUS)
assert 810 not in kandidaten # 8.10 % ist der Steuersatz, kein Preis
assert kandidaten[0] == 14680 # bester Tipp: Gesamt inkl.
def test_galaxus_garantieende_aus_zeitraum():
assert guess_warranty_until(GALAXUS, acquired_on=date(2025, 10, 5)) == date(2027, 10, 6)
def test_galaxus_zeilenpreise_sind_kandidaten():
# Bei mehreren Artikeln soll man den Zeilenpreis wählen können.
kandidaten = guess_price_candidates(GALAXUS)
assert 14680 in kandidaten # Gesamt inkl.
assert 11100 in kandidaten # Logitech, Betrag/Preis inkl.
assert 3580 in kandidaten # Kabel, Betrag inkl.
assert 810 not in kandidaten # MwSt-Satz weiterhin draußen