feat: create validated ZUGFeRD invoices in one console command

This commit is contained in:
admin committed 2026-10-16 09:29:08 +02:00
1 parent e0c15fc7f2
commit a643cf5227
30 files changed
+1509 -207

No files matched your search

+21 -17
View File
@@ -1,24 +1,28 @@
from __future__ import annotations
from dataclasses import dataclass
from typing import Dict
from decimal import Decimal, ROUND_HALF_UP
from .models import Invoice
CENT = Decimal('0.01')
def rounded(value: Decimal) -> Decimal:
return value.quantize(CENT, rounding=ROUND_HALF_UP)
def line_net(item) -> Decimal:
return rounded(item.quantity * item.unit_price_net)
@dataclass(frozen=True)
class Totals:
net_total: float
tax_total: float
gross_total: float
tax_by_rate: Dict[float, float]
net_total: Decimal
tax_total: Decimal
gross_total: Decimal
tax_by_rate: dict[Decimal, Decimal]
basis_by_rate: dict[Decimal, Decimal]
def compute_totals(inv: Invoice) -> Totals:
net = 0.0
tax_total = 0.0
tax_by_rate: Dict[float, float] = {}
for it in inv.items:
line_net = float(it.quantity) * float(it.unit_price_net)
net += line_net
tax = line_net * float(it.tax_rate) / 100.0
tax_total += tax
tax_by_rate[it.tax_rate] = tax_by_rate.get(it.tax_rate, 0.0) + tax
gross = net + tax_total
return Totals(net_total=net, tax_total=tax_total, gross_total=gross, tax_by_rate=tax_by_rate)
bases = {}
for item in inv.items:
bases[item.tax_rate] = bases.get(item.tax_rate, Decimal(0)) + line_net(item)
taxes = {rate: rounded(base * rate / 100) for rate, base in bases.items()}
net = sum(bases.values(), Decimal(0))
tax = sum(taxes.values(), Decimal(0))
return Totals(net, tax, net + tax, taxes, bases)