Allow zero-euro line item amounts

This commit is contained in:
m3ta-chiron
2026-06-03 07:52:52 +02:00
parent d497a4cb5b
commit e2e1d8c046
5 changed files with 71 additions and 36 deletions
+20 -9
View File
@@ -5,6 +5,7 @@ import time
from typing import Any
from pydantic import ValidationError
from src.models import (
ErrorDetail,
ValidateRequest,
@@ -78,10 +79,10 @@ def validate_pflichtfelder(xml_data: XmlData) -> list[ErrorDetail]:
if item.quantity == 0:
add_error(f"{field_prefix}.quantity", "critical")
if item.unit_price == 0:
if item.unit_price is None:
add_error(f"{field_prefix}.unit_price", "critical")
if item.line_total == 0:
if item.line_total is None:
add_error(f"{field_prefix}.line_total", "critical")
if item.vat_rate is None:
@@ -94,7 +95,7 @@ def validate_betraege(xml_data: XmlData) -> list[ErrorDetail]:
"""Check amount calculations are correct."""
errors = []
def add_mismatch(field: str, expected: float, actual: float) -> None:
def add_mismatch(field: str, expected: float, actual: float | None) -> None:
errors.append(
ErrorDetail(
check="betraege",
@@ -107,16 +108,24 @@ def validate_betraege(xml_data: XmlData) -> list[ErrorDetail]:
# Check line_total = quantity × unit_price
for idx, item in enumerate(xml_data.line_items):
expected_line_total = item.quantity * item.unit_price
if not amounts_match(item.line_total, expected_line_total):
unit_price = item.unit_price
line_total = item.line_total
if unit_price is None or line_total is None:
continue
expected_line_total = item.quantity * unit_price
if not amounts_match(line_total, expected_line_total):
add_mismatch(
f"line_items[{idx}].line_total",
expected_line_total,
item.line_total,
line_total,
)
# Check totals.net = sum(line_items.line_total)
line_total_sum = sum(item.line_total for item in xml_data.line_items)
line_total_sum = 0.0
for item in xml_data.line_items:
if item.line_total is not None:
line_total_sum += item.line_total
if not amounts_match(xml_data.totals.net, line_total_sum):
add_mismatch("totals.net", line_total_sum, xml_data.totals.net)
@@ -280,12 +289,14 @@ def validate_invoice(request: ValidateRequest) -> ValidationResult:
xml_data = XmlData(**request.xml_data)
except ValidationError as e:
# Convert Pydantic validation errors to ValidationResult
validation_errors = []
validation_errors: list[ErrorDetail] = []
for error in e.errors():
loc = error["loc"]
field = str(loc[0]) if loc else None
validation_errors.append(
ErrorDetail(
check="schema_validation",
field=error["loc"][0] if error["loc"] else None,
field=field,
error_code=error["type"],
message=error["msg"],
severity="critical",