aeat.domain.invoices._models module¶
Strict immutable models for the invoice catalogue.
Defines the pydantic v2 records that back aeat.domain.invoices:
InvoiceLine, Invoice, and the keyed
InvoiceCatalogue. Every model is strict, frozen, and forbids
extra fields; identity-bearing fields on Invoice are
canonicalised in a model_validator and the stable
Invoice.invoice_id is derived via derive_invoice_id().
Counterparty identity validation is delegated to
aeat.domain.invoices._validators.
- derive_invoice_id(*, kind, invoice_number, issued_at, counterparty_tax_id, currency, grand_total)[source]¶
Return the stable invoice hash for one invoice record.
The digest is computed over a canonical JSON payload so that two invoices with equal logical identity produce identical IDs regardless of whitespace or numeric formatting.
- Parameters:
kind (
InvoiceKind) – Invoice direction (issued / received).invoice_number (
str) – AEAT-significant invoice number as printed on the document.issued_at (
date) – ISO calendar date printed on the invoice.counterparty_tax_id (
str) – Counterparty NIF / NIE / CIF / IVA number already validated and uppercased.currency (
str) – ISO-4217 currency code already uppercased.grand_total (
Decimal) – Invoice grand total.
- Return type:
- Returns:
A lowercase SHA-256 digest that uniquely identifies the invoice.
- class InvoiceLine(**data)[source]¶
Bases:
BaseModelImmutable line item on an invoice.
- Parameters:
- description: str¶
- quantity: Decimal¶
- unit_price: Decimal¶
- subtotal: Decimal¶
- iva_rate: IvaRate¶
- iva_amount: Decimal¶
- category_id: str | None¶
- oss_rate_kind: IvaRateKind | None¶
- class Invoice(**data)[source]¶
Bases:
BaseModelStrict frozen record for one issued or received invoice.
- Parameters:
invoice_id (Annotated[str, StringConstraints(strip_whitespace=True, to_upper=None, to_lower=None, strict=None, min_length=64, max_length=64, pattern=^[0-9a-f]{64}$, ascii_only=None)])
bucket_id (Annotated[str, StringConstraints(strip_whitespace=True, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=128, pattern=None, ascii_only=None)] | None)
kind (InvoiceKind)
invoice_number (str)
issued_at (date)
counterparty_name (str)
counterparty_tax_id (str)
counterparty_country (str)
base_total (Decimal)
iva_total (Decimal)
grand_total (Decimal)
currency (str)
lines (tuple[InvoiceLine, ...])
payment_status (PaymentStatus)
notes (str)
iva_category (IvaCategory | None)
operation_type (IntracomOperationType | None)
oss_ioss_regime (OssIossRegime | None)
oss_transaction_kind (TransactionKind | None)
retention_rate (Decimal | None)
retention_amount (Decimal | None)
payment_id (str | None)
- invoice_id: InvoiceId¶
- bucket_id: BucketId | None¶
- kind: InvoiceKind¶
- invoice_number: str¶
- issued_at: date¶
- counterparty_name: str¶
- counterparty_tax_id: str¶
- counterparty_country: str¶
- base_total: Decimal¶
- iva_total: Decimal¶
- grand_total: Decimal¶
- currency: str¶
- lines: tuple[InvoiceLine, ...]¶
- payment_status: PaymentStatus¶
- linked_transaction_ids: tuple[str, ...]¶
- notes: str¶
- iva_category: IvaCategory | None¶
- operation_type: IntracomOperationType | None¶
- oss_ioss_regime: OssIossRegime | None¶
- oss_transaction_kind: TransactionKind | None¶
- retention_rate: Decimal | None¶
- retention_amount: Decimal | None¶
- payment_id: str | None¶
- property counterparty_eu_member_state: EUMemberState | None¶
Return the substrate-typed EUMemberState for the counterparty, or
Nonefor non-EU.counterparty_countrycarries the raw uppercase ISO-3166-1 alpha-2 code (validated at construction time). This typed accessor lets downstream consumers (Modelo 369 OSS bindings, intra-community classification, OSS classifier dispatch) work with the closed substrate enum without a per-call lowercase / membership check. Anchored toaeat.domain.invoices.EU_MEMBER_STATE_CODESwhich derives fromaeat.domain.iva.EUMemberState.
- property counterparty_is_eu_member: bool¶
Return
Trueiff the counterparty is in one of the 27 EU Member States.Convenience predicate keyed off the substrate enum; equivalent to
invoice.counterparty_eu_member_state is not None. Modelo classification routes (OSS / IOSS / intra-community) gate on this predicate to decide which substrate flow path applies.
- class InvoiceCatalogue(**data)[source]¶
Bases:
BaseModelImmutable invoice catalogue keyed by
invoice_id.- invoices: Mapping[str, Invoice]¶
- classmethod from_invoices(invoices)[source]¶
Build an immutable catalogue from an iterable of invoices.