fix: extract tax number, price basis quantity, spaced VAT IDs and contact email
- supplier/buyer: extract FC tax registration (BT-32/BT-49) into new tax_number field; previously only VA (USt-IdNr.) was read - pflichtfelder: critical error only when neither vat_id nor tax_number is present (EN 16931 BR-CO-26) - ustid: tolerate formatting whitespace inside VAT IDs (e.g. 'DE 140 978 617') - line items: normalize unit price by basis quantity (BT-149), so a price per 100 units no longer inflates line totals by factor 100 - supplier email: also look in DefinedTradeContact (BT-42) - rewrite xrechnung fallback test to assert only our own behavior, independent of factur-x version specifics
This commit is contained in:
@@ -149,6 +149,58 @@ class TestValidatePflichtfelder:
|
||||
assert any(e.field == "supplier.vat_id" for e in errors)
|
||||
assert any(e.severity == "critical" for e in errors)
|
||||
|
||||
def test_tax_number_only_supplier_no_critical_error(self):
|
||||
"""Supplier with only a tax number (no VAT ID) should pass BR-CO-26."""
|
||||
xml_data = XmlData(
|
||||
invoice_number="INV001",
|
||||
invoice_date="2024-01-15",
|
||||
supplier=Supplier(
|
||||
name="Werkstatt gGmbH",
|
||||
vat_id=None,
|
||||
tax_number="2281410000697",
|
||||
),
|
||||
buyer=Buyer(name="Test Buyer AG"),
|
||||
line_items=[
|
||||
LineItem(
|
||||
position=1,
|
||||
description="Test Product",
|
||||
quantity=2.0,
|
||||
unit="HUR",
|
||||
unit_price=5.0,
|
||||
line_total=10.0,
|
||||
vat_rate=7.0,
|
||||
)
|
||||
],
|
||||
totals=Totals(line_total_sum=10.0, net=10.0, vat_total=0.7, gross=10.7),
|
||||
)
|
||||
errors = validate_pflichtfelder(xml_data)
|
||||
assert not any(e.field == "supplier.vat_id" for e in errors)
|
||||
|
||||
def test_missing_vat_id_and_tax_number_critical(self):
|
||||
"""Supplier with neither VAT ID nor tax number stays critical."""
|
||||
xml_data = XmlData(
|
||||
invoice_number="INV001",
|
||||
invoice_date="2024-01-15",
|
||||
supplier=Supplier(name="Test Supplier GmbH", vat_id="", tax_number=""),
|
||||
buyer=Buyer(name="Test Buyer AG"),
|
||||
line_items=[
|
||||
LineItem(
|
||||
position=1,
|
||||
description="Test Product",
|
||||
quantity=2.0,
|
||||
unit="HUR",
|
||||
unit_price=5.0,
|
||||
line_total=10.0,
|
||||
vat_rate=7.0,
|
||||
)
|
||||
],
|
||||
totals=Totals(line_total_sum=10.0, net=10.0, vat_total=0.7, gross=10.7),
|
||||
)
|
||||
errors = validate_pflichtfelder(xml_data)
|
||||
assert any(e.field == "supplier.vat_id" for e in errors)
|
||||
assert any(e.severity == "critical" for e in errors)
|
||||
assert any("tax number" in e.message for e in errors)
|
||||
|
||||
def test_missing_buyer_name_critical(self):
|
||||
"""Missing buyer.name should produce critical error."""
|
||||
xml_data = XmlData(
|
||||
@@ -720,6 +772,11 @@ class TestValidateUstid:
|
||||
error = validate_ustid("DE123456789")
|
||||
assert error is None
|
||||
|
||||
def test_valid_german_vat_id_with_spaces(self):
|
||||
"""German VAT ID with formatting spaces (e.g. 'DE 140 978 617') passes."""
|
||||
error = validate_ustid("DE 140 978 617")
|
||||
assert error is None
|
||||
|
||||
def test_valid_austrian_vat_id(self):
|
||||
"""Valid Austrian VAT ID should pass."""
|
||||
error = validate_ustid("ATU12345678")
|
||||
|
||||
Reference in New Issue
Block a user