Files
provisionsmanager95/tests/test_kern.py
T

188 lines
8.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Tests für Import, Datenbank und Export – ausschließlich mit erfundenen Testdaten."""
from datetime import datetime
import openpyxl
import pytest
from provtool import export
from provtool.db import UNZUGEORDNET, Datenbank, Haendler
from provtool.importer import ImportFehler, lies_datei
from provtool.money import apply_percent, fmt, parse_cent
FREENET_KOPF = ("Zeitraum;Verguetungsart;Haendlernummer;Unterhaendler;Vertragsnummer;Aktiv;Deaktiv;Rufnummer;"
"Kartennummer;IMEI_SN;Geraetename;Kundenvorname;Kundename;Tarif-Kurz;Tarif;Prozent;Betrag;Grund;"
"externe Vertragsnummer;Mitarbeiternummer;Abrechnungsnummer;Netz-Kurz;Netz;Dienst-Kurz;Dienst;"
"Aktionscode;Auftragserfassungsdatum;Detailausweisung;Teilzahlung Nr.;Event-Datum;FAQ;Bonusschreiben;"
"Leistungsdatum;Couponcode")
def freenet_zeile(art, unterh, aktiv, rufnr, name, tarif, betrag, netz="VF", aktion="", zeitraum="2026.10.01-2026.10.07"):
f = [""] * 34
f[0], f[1], f[2], f[3], f[4], f[5] = zeitraum, art, "28000000", unterh, "123", aktiv
f[7], f[12], f[14], f[16], f[22], f[24], f[25] = rufnr, name, tarif, betrag, netz, "Teilnehmerverhaeltnis", aktion
return ";".join(f)
@pytest.fixture
def freenet_csv(tmp_path):
zeilen = [
FREENET_KOPF,
freenet_zeile("Grundvergütung Mobilfunk Credit freenet", "111", "05.10.2026", "1601111111", "Muster GmbH", "Allnet Flat 5GB", "50"),
freenet_zeile("SIM-Karten", "111", "05.10.2026", "1601111111", "Muster GmbH", "Allnet Flat 5GB", "8"),
freenet_zeile("Sonderbonus Aktion", "111", "07.10.2026", "1602222222", "Beispiel KG", "Business Classic", "170", "D1", "A123"),
freenet_zeile("Grundvergütung Mobilfunk Credit freenet", "111", "06.10.2026", "1602222222", "Beispiel KG", "Business Classic", "12,50", "D1"),
freenet_zeile("SIM-Karten", "999", "01.10.2026", "1609999999", "Eigener Kunde", "Flex", "-8"),
]
p = tmp_path / "freenet.csv"
p.write_bytes(("\r\n".join(zeilen) + "\r\n").encode("cp1252"))
return p
@pytest.fixture
def vodafone_xlsx(tmp_path):
wb = openpyxl.Workbook()
ws = wb.active
ws.title = "All"
ws["A1"] = "Provisionsclearing Euronics e.G."
ws["B3"], ws["C3"] = "Kundennummer:", 1
ws.append([])
ws.append([])
ws["A6"] = None
kopf = ["Anschaltdatum", "Kartennummer", "IMEI", "Rufnummer", "Kunde", "Artikelbezeichnung", "Tarif",
"TarifKey02", "Prämie in EUR", "Abrechnungslauf", "Vo-Nr", "Lieferantennr", "Text"]
for c, h in enumerate(kopf, 1):
ws.cell(6, c, h)
daten = [
(datetime(2026, 9, 8), "3225601 ", "", "491726400000 ", "Testkunde ", "Freischaltungsvergütung Vodafone",
"Aktivierung Smart L ", "Smart ", 345, "VF2609 ", "80211721 ", "705136", "SMART3L"),
(datetime(2026, 9, 8), "3225601 ", "", "491726400000 ", "Testkunde ", "Freischaltungsvergütung Vodafone",
"Basispreisrabatt", "Promotion", -40, "VF2609 ", "80211721 ", "705136", "SMART3L"),
(datetime(2026, 9, 3), "", "", "182935058", "Kabelkunde", "Freischaltungsvergütung Vodafone Cable",
"VF Cable/GigaZuhause 50", "VF Internet Cable", 120, "VF2609", "EU133301", "705136", "5BV:FPT"),
]
for r, row in enumerate(daten, 7):
for c, v in enumerate(row, 1):
ws.cell(r, c, v)
leer = wb.create_sheet("VF2609 Fil 0 Ref 1")
leer["A5"], leer["B5"] = "Anschaltdatum", "Kartennummer"
p = tmp_path / "vodafone.xlsx"
wb.save(p)
return p
@pytest.fixture
def db(tmp_path):
d = Datenbank(tmp_path / "test.db")
yield d
d.close()
# --------------------------------------------------------------------------- Geld
@pytest.mark.parametrize("ein,cent", [("30", 3000), ("12,50", 1250), ("1.234,56", 123456), ("-8", -800),
(12.5, 1250), (8, 800), ("30,00-", -3000), ("", 0), (None, 0),
("1,234.56", 123456), ("0,1", 10)])
def test_parse_cent(ein, cent):
assert parse_cent(ein) == cent
def test_prozent_und_format():
assert apply_percent(17000, 80) == 13600
assert apply_percent(1250, 33.33) == 417
assert apply_percent(-800, 50) == -400
assert fmt(123456) == "1.234,56 €"
assert fmt(-5) == "-0,05 €"
# --------------------------------------------------------------------------- Import
def test_freenet_import(freenet_csv):
erg = lies_datei(freenet_csv)
assert erg.format == "freenet"
assert len(erg.positionen) == 5
p = erg.positionen[0]
assert p.provisionsart == "Grundvergütung Mobilfunk Credit freenet"
assert p.kennung == "111"
assert p.datum.isoformat() == "2026-10-05"
assert p.betrag_cent == 5000
assert erg.positionen[3].betrag_cent == 1250
assert erg.positionen[2].aktionscode == "A123"
def test_vodafone_import(vodafone_xlsx):
erg = lies_datei(vodafone_xlsx)
assert erg.format == "vodafone"
assert len(erg.positionen) == 3
p = erg.positionen[0]
assert p.kennung == "80211721" # Leerzeichen entfernt
assert p.rufnummer == "491726400000"
assert p.betrag_cent == 34500
assert p.zeitraum == "VF2609"
assert erg.positionen[2].netz == "Cable"
def test_unbekanntes_format(tmp_path):
p = tmp_path / "x.csv"
p.write_text("a;b;c\n1;2;3\n")
with pytest.raises(ImportFehler):
lies_datei(p)
# --------------------------------------------------------------------------- Datenbank
def test_zuordnung_regeln_und_export(db, freenet_csv, vodafone_xlsx, tmp_path):
hid = db.haendler_speichern(Haendler(0, "Händler A", standard_prozent=100),
[("freenet", "111"), ("vodafone", "80211721")])
aid = db.abrechnung_neu("Oktober 2026")
db.importieren(aid, lies_datei(freenet_csv))
db.importieren(aid, lies_datei(vodafone_xlsx))
pos = db.positionen(aid)
eigene = [p for p in pos if p["haendler_id"] == hid]
assert len(eigene) == 6
assert sum(1 for p in pos if p["haendler_id"] == UNZUGEORDNET) == 2
# Regel: Sonderbonus nur 80 %
db.regel_setzen(hid, "Sonderbonus Aktion", 80)
db.neu_berechnen(aid)
sb = next(p for p in db.positionen(aid) if p["provisionsart"] == "Sonderbonus Aktion")
assert sb["betrag"] == 13600 and sb["prozent"] == 80
# manuelle Änderung bleibt bei Neuberechnung erhalten
sim = next(p for p in db.positionen(aid) if p["provisionsart"] == "SIM-Karten" and p["haendler_id"] == hid)
db.betrag_setzen(sim["id"], 500)
db.neu_berechnen(aid)
sim = next(p for p in db.positionen(aid) if p["id"] == sim["id"])
assert sim["betrag"] == 500 and sim["manuell"] == 1
db.neu_berechnen(aid, auch_manuelle=True)
sim = next(p for p in db.positionen(aid) if p["id"] == sim["id"])
assert sim["betrag"] == 800 and sim["manuell"] == 0
# Export
eigene = [p for p in db.positionen(aid) if p["haendler_id"] == hid]
dateien = export.exportiere_haendler(tmp_path / "out", "Händler A", eigene, "Oktober 2026")
assert [d.name for d in dateien] == ["Händler A - freenet - Oktober 2026.xlsx",
"Händler A - Vodafone - Oktober 2026.xlsx"]
ws = openpyxl.load_workbook(dateien[0]).active
zeilen = [[c.value for c in r] for r in ws.iter_rows(min_row=1, max_row=4)]
# Sortierung Zeitraum → Provisionsart → Datum
assert [z[1] for z in zeilen] == ["Grundvergütung Mobilfunk Credit freenet"] * 2 + ["SIM-Karten", "Sonderbonus Aktion"]
assert zeilen[0][2] == 111 and zeilen[0][4] == 1601111111
assert zeilen[3][10] == 136.0 and zeilen[3][13] == "A123"
assert ws["K6"].value == "=SUM(K1:K4)"
def test_doppelte_kennung_verboten(db):
db.haendler_speichern(Haendler(0, "A"), [("freenet", "1")])
with pytest.raises(ValueError):
db.haendler_speichern(Haendler(0, "B"), [("freenet", "1")])
def test_datei_doppelt_erkannt_und_entfernbar(db, freenet_csv):
aid = db.abrechnung_neu("X")
erg = lies_datei(freenet_csv)
db.importieren(aid, erg)
assert db.datei_schon_importiert(erg.sha256) == ["X"]
did = db.dateien(aid)[0]["id"]
db.datei_entfernen(did)
assert db.positionen(aid) == []