test: add end-to-end integration test covering all Phase 1 features together
This commit is contained in:
parent
3b3a2dce90
commit
3a621eb805
|
|
@ -360,3 +360,48 @@ def test_extract_hardware_serial_numbers_finds_sn_pattern():
|
||||||
|
|
||||||
def test_extract_hardware_serial_numbers_empty_when_absent():
|
def test_extract_hardware_serial_numbers_empty_when_absent():
|
||||||
assert extract_hardware_serial_numbers("Keine Seriennummern hier.") == []
|
assert extract_hardware_serial_numbers("Keine Seriennummern hier.") == []
|
||||||
|
|
||||||
|
|
||||||
|
def test_full_invoice_with_all_phase1_features_combined():
|
||||||
|
"""Realistische IT-Systemhaus-Rechnung: gemischte Steuersaetze, Rabatt, Skonto,
|
||||||
|
dynamischer Zahlungsmittelcode und IT-spezifische Abrechnungseinheiten - alles zusammen."""
|
||||||
|
items = [
|
||||||
|
{"name": "Managed-Services-Pauschale", "description": "", "quantity": 1.0, "unit": "Monat(e)",
|
||||||
|
"unit_price": 500.0, "total_amount": 500.0, "vat_rate_percent": 19.0},
|
||||||
|
{"name": "Fachliteratur", "description": "", "quantity": 1.0, "unit": "Stk.",
|
||||||
|
"unit_price": 40.0, "total_amount": 40.0, "vat_rate_percent": 7.0},
|
||||||
|
]
|
||||||
|
totals = compute_invoice_totals(items, discount_percent=5.0)
|
||||||
|
|
||||||
|
data = _single_rate_invoice()
|
||||||
|
data["items"] = items
|
||||||
|
data["tax_buckets"] = totals["tax_buckets"]
|
||||||
|
data["line_net_total"] = totals["line_net_total"]
|
||||||
|
data["allowance_amount"] = totals["allowance_amount"]
|
||||||
|
data["allowance_reason"] = "Neukundenrabatt"
|
||||||
|
data["total_net_amount"] = totals["tax_basis_total"]
|
||||||
|
data["total_vat_amount"] = totals["total_vat_amount"]
|
||||||
|
data["total_gross_amount"] = totals["total_gross_amount"]
|
||||||
|
data["skonto_percent"] = 2.0
|
||||||
|
data["skonto_days"] = "14"
|
||||||
|
data["payment_means_code"] = "31"
|
||||||
|
|
||||||
|
ubl_xml = generate_compliant_xrechnung(data)
|
||||||
|
ubl_root = ET.fromstring(ubl_xml.encode("utf-8"))
|
||||||
|
ubl_ns = {"cbc": "urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2",
|
||||||
|
"cac": "urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"}
|
||||||
|
assert len(ubl_root.findall(".//cac:TaxTotal/cac:TaxSubtotal", ubl_ns)) == 2
|
||||||
|
assert ubl_root.find(".//cac:PaymentMeans/cbc:PaymentMeansCode", ubl_ns).text == "31"
|
||||||
|
ubl_allowances = ubl_root.findall(".//cac:AllowanceCharge", ubl_ns)
|
||||||
|
assert len(ubl_allowances) == 2 # ein Rabatt-Block je Steuersatz (19% und 7%)
|
||||||
|
assert abs(sum(float(a.find("cbc:Amount", ubl_ns).text) for a in ubl_allowances) - 27.0) < 0.001
|
||||||
|
assert "Skonto" in ubl_root.find(".//cac:PaymentTerms/cbc:Note", ubl_ns).text
|
||||||
|
|
||||||
|
cii_xml = generate_compliant_zugferd_cii(data)
|
||||||
|
cii_root = ET.fromstring(cii_xml.encode("utf-8"))
|
||||||
|
cii_ns = {"ram": "urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100"}
|
||||||
|
assert len(cii_root.findall(".//ram:ApplicableHeaderTradeSettlement/ram:ApplicableTradeTax", cii_ns)) == 2
|
||||||
|
assert cii_root.find(".//ram:SpecifiedTradeSettlementPaymentMeans/ram:TypeCode", cii_ns).text == "31"
|
||||||
|
cii_allowances = cii_root.findall(".//ram:SpecifiedTradeAllowanceCharge", cii_ns)
|
||||||
|
assert len(cii_allowances) == 2 # ein Rabatt-Block je Steuersatz (19% und 7%)
|
||||||
|
assert abs(sum(float(a.find("ram:ActualAmount", cii_ns).text) for a in cii_allowances) - 27.0) < 0.001
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue