cadrumo.domain.iva.components module

Typed IVA component models and the registry projection boundary.

Concrete category/component rows are canonical registry data. This module retains only opaque registry tokens, validation models, generic component calculations, and the explicit boundary that accepts a registry-projected catalogue.

class IvaComponentPresence(value, *, _registry_validated=False)[source]

Bases: _IvaRegistryToken

Registry-projected component-presence token.

Parameters:
  • value (str)

  • _registry_validated (bool)

Return type:

Self

class IvaRetencionExpectation(value, *, _registry_validated=False)[source]

Bases: _IvaRegistryToken

Registry-projected retención-expectation token.

Parameters:
  • value (str)

  • _registry_validated (bool)

Return type:

Self

class IvaRetencionRole(value, *, _registry_validated=False)[source]

Bases: _IvaRegistryToken

Registry-projected retención-role token.

Parameters:
  • value (str)

  • _registry_validated (bool)

Return type:

Self

class IvaKindApplicability(value, *, _registry_validated=False)[source]

Bases: _IvaRegistryToken

Registry-projected category/kind applicability token.

Parameters:
  • value (str)

  • _registry_validated (bool)

Return type:

Self

class IvaCuotaSettlement[source]

Bases: str

Opaque registry-projected IVA cuota-settlement token.

Membership and legal semantics are selected from fact 0084. This type carries only the token shape; production rows are accepted through the typed 0084 projection below.

property value: str

Return the opaque token for string-oriented serialization.

class IvaCuotaSettlementDefinition(token, description, legal_ref)[source]

Bases: object

One registry-declared cuota-settlement token and its semantics.

Parameters:
token: IvaCuotaSettlement
description: str
legal_ref: str
class IvaCuotaSettlementCatalogue(definitions, no_settlement_token)[source]

Bases: object

Typed projection of the dated 0084 cuota-settlement vocabulary.

Parameters:
definitions: tuple[IvaCuotaSettlementDefinition, ...]
no_settlement_token: IvaCuotaSettlement
property all_settlements: frozenset[IvaCuotaSettlement]

Return every settlement token declared by the selected authority.

require(value)[source]

Validate one opaque settlement token against the selected authority.

Return type:

IvaCuotaSettlement

Parameters:

value (object)

class IvaComponentVocabulary(component_presence, retencion_expectation, retencion_role, kind_applicability)[source]

Bases: object

Typed membership projection for the four component axes in fact 0084.

Parameters:
component_presence: frozenset[IvaComponentPresence]
retencion_expectation: frozenset[IvaRetencionExpectation]
retencion_role: frozenset[IvaRetencionRole]
kind_applicability: frozenset[IvaKindApplicability]
require_component_presence(value)[source]

Validate and return one component-presence token.

Return type:

IvaComponentPresence

Parameters:

value (object)

require_retencion_expectation(value)[source]

Validate and return one retencion-expectation token.

Return type:

IvaRetencionExpectation

Parameters:

value (object)

require_retencion_role(value)[source]

Validate and return one retencion-role token.

Return type:

IvaRetencionRole

Parameters:

value (object)

require_kind_applicability(value)[source]

Validate and return one kind-applicability token.

Return type:

IvaKindApplicability

Parameters:

value (object)

class IvaGroundingConfidence(*values)[source]

Bases: StrEnum

How well a declared component expectation is grounded in legal text.

This is the honesty marker. An expectation the author could not bottom out must be declared UNGROUNDED rather than stated as if verified: an unmarked guess in a legal table is worse than a gap, because the next reader treats it as confirmed.

BUNDLED_CORPUS

Verified against a provision present in the bundled legal catalogue and named in IvaCategoryComponents.legal_refs.

LIVE_SOURCE_ONLY

Verified against live BOE/AEAT consolidated text, but the binding provision is not yet bundled. The provision is named in IvaCategoryComponents.pending_legal_refs.

REASONED

Inferred from bundled provisions; no bundled provision states it directly. Not a measured claim.

UNGROUNDED

No legal basis established — a declared gap, not an assertion.

class IvaCategoryComponents(**data)[source]

Bases: _IvaStrictFrozen

One Axis-A row: which components an operation in category has.

A row is keyed by the PAIR (category, kind). Category alone cannot express the retención role, which inverts with direction — the same withheld euro is the taxpayer’s credit on an invoice they issued and their liability to AEAT on one they received — and cannot express that several categories are one-directional by law.

Variables:
  • category – The IVA situation this row describes.

  • kind – Which side of the operation the taxpayer is on. Half the key.

  • applicability – Whether this (category, kind) pair describes an operation that can occur at all.

  • retencion_role – Whose money a retención here is. Validated against kind and retencion rather than trusted, so a row cannot declare a credit on a received invoice.

  • base – Whether a taxable base (contraprestación) exists.

  • cuota – Whether an IVA cuota exists.

  • cuota_settlement – Who settles the cuota, and where.

  • cuota_grounding – Grounding confidence for the cuota columns.

  • recargo – Whether a recargo de equivalencia may exist.

  • recargo_grounding – Grounding confidence for the recargo column.

  • retencion – Whether an IRPF retención is expected.

  • retencion_grounding – Grounding confidence for the retención column.

  • retencion_note – Carve-outs and caveats behind the retención expectation. Required whenever the retención grounding is anything other than IvaGroundingConfidence.BUNDLED_CORPUS, so a weakly-grounded expectation can never travel without its caveat.

  • legal_refs – Registry legal-reference ids backing the row. Every id resolves in the bundled legal catalogue.

  • pending_legal_refs – Registry legal-reference ids for provisions verified against live BOE/AEAT but not yet bundled. Every id here is expected not to resolve; bundling one reds the gate so the author promotes it into legal_refs.

Parameters:

data (Any)

category: IvaCategory
kind: InvoiceKind
applicability: IvaKindApplicability
retencion_role: IvaRetencionRole
base: IvaComponentPresence
cuota: IvaComponentPresence
cuota_settlement: IvaCuotaSettlement
cuota_grounding: IvaGroundingConfidence
recargo: IvaComponentPresence
recargo_grounding: IvaGroundingConfidence
retencion: IvaRetencionExpectation
retencion_grounding: IvaGroundingConfidence
retencion_note: str
legal_refs: tuple[_RegistryLegalRef, ...]
registry_cuota_settlement_catalogue(*, effective_date=None, authority=None)[source]

Resolve the explicit cuota-settlement vocabulary from published 0084.

Return type:

IvaCuotaSettlementCatalogue

Parameters:
registry_component_vocabulary(*, effective_date=None, authority=None)[source]

Resolve the four typed component-axis memberships from fact 0084.

Return type:

IvaComponentVocabulary

Parameters:
registry_component_presence_token(value, *, effective_date=None, authority=None)[source]

Resolve one component-presence token through the governed registry.

Return type:

IvaComponentPresence

Parameters:
registry_retencion_role_token(value, *, effective_date=None, authority=None)[source]

Resolve one retencion-role token through the governed registry.

Return type:

IvaRetencionRole

Parameters:
registry_kind_applicability_token(value, *, effective_date=None, authority=None)[source]

Resolve one kind-applicability token through the governed registry.

Return type:

IvaKindApplicability

Parameters:
registry_category_projection(projection, *, effective_date=None, authority=None)[source]

Resolve an explicit category membership projection from published 0084.

There is intentionally no derived or Python-owned fallback. Missing, malformed, duplicate, or stale projection entries fail through IvaValidationError.

Return type:

frozenset[IvaCategory]

Parameters:
  • projection (Literal['cuota_less_m303', 'm303_base_out_of_scope', 'evidence_exempt', 'no_printed_tax', 'cash_accounting_excluded'])

  • effective_date (date | None)

  • authority (GovernedFactSource | None)

registry_component_catalogue(*, effective_date=None, authority=None)[source]

Return the Axis-A catalogue projected by the validated registry authority.

Callers must provide an operation or run inside its governed-fact scope; tests and review tooling can pass an isolated generation to inspect another governed projection without introducing a second source of row data.

Return type:

Mapping[tuple[IvaCategory, InvoiceKind], IvaCategoryComponents]

Parameters:
category_components(category, kind, *, component_catalogue=None)[source]

Return a registry-projected Axis-A row for category on kind.

kind is required, deliberately. A category-only accessor over a pair-keyed table would have to pick one of the two rows for any category whose sides differ, and would return the wrong one silently on a filing path — worse than the gap this key closes. Callers hold an invoice, so they hold its kind.

Parameters:
Return type:

IvaCategoryComponents

Returns:

The IvaCategoryComponents row for the pair. A row whose applicability is the registry’s does_not_arise applicability token is a real answer — the combination is not an operation — not a lookup failure.

Raises:

IvaValidationError – If no registry catalogue was supplied or it has no row for the pair.

category_bears_taxable_base(category, kind, *, component_catalogue=None)[source]

Return True when a declared taxable base is legally required.

Cuota-less is not substrate-less: an entrega intracomunitaria exenta and an IVA-exempt professional service both return True here even though they carry no cuota, which is why a base-less row in either category is ungrounded rather than legitimately empty.

A non-arising pair returns False: there is no operation to require a base of, and reporting a missing base on an impossible combination would be a second, misleading defect on top of the real one.

Parameters:
Return type:

bool

Returns:

True when the pair requires a taxable base.

category_cuota_is_zero_by_law(category, kind, *, component_catalogue=None)[source]

Return True when the pair’s IVA cuota is structurally zero.

Consumed by the retención-inference precondition: a declared-exempt invoice has a determinable cuota (zero), so it can qualify for bounded inference even though no explicit iva_amount was recorded.

The kind matters here rather than being incidental. A domestic reverse-charge invoice the taxpayer ISSUED carries no cuota (the recipient self-assesses), while one they RECEIVED carries a self-assessed cuota that is emphatically not zero.

Parameters:
Return type:

bool

Returns:

True when the cuota is zero by law for this pair.