aeat.domain.calculations.registry._ledger_bindings module

Ledger-backed registry binding helpers.

class OssIossLedgerObservation(**data)[source]

Bases: BaseModel

One factual ledger line tagged with substrate-grounded classification.

Modelo 369 binding selectors filter these observations by the four classification axes (regime, destination Member State, rate tier, invoice direction) plus the optional transaction kind set; the runtime aggregates the matched lines through the binding’s aggregation operator.

Variables:
  • ledger_id – Stable id of the source ledger line.

  • transaction_date – When the supply takes place.

  • regime – OSS / IOSS Esquema the line is filed under.

  • destination_member_state – Member State of consumption (the destination MS for the supply, which determines the applicable IVA rate per the OSS / IOSS rules).

  • rate_kind – Substrate rate tier (general / reduced / etc.).

  • invoice_direction – Whether the autónomo issued or received the invoice.

  • transaction_kind – Substrate aeat.domain.iva.TransactionKind the line resolves to.

  • base_amount – Taxable base in EUR.

  • iva_amount – IVA amount in EUR (already applied at the destination MS rate per OSS / IOSS rules).

Parameters:
ledger_id: str
transaction_date: date
regime: OssIossRegime
destination_member_state: EUMemberState
rate_kind: IvaRateKind
invoice_direction: InvoiceKind
transaction_kind: TransactionKind
base_amount: Decimal
iva_amount: Decimal
validate_ledger_oss_aggregation_binding_definition(binding)[source]

Validate a ledger_oss_aggregation binding’s selector and aggregation.

Parameters:

binding (DataBindingDefinition) – The DataBindingDefinition to validate. Must have source == "ledger_oss_aggregation".

Raises:

RegistryValidationError – If the selector is malformed (unknown regime / member state / rate kind / invoice direction / transaction kind), or if the aggregation operator is inconsistent with the declared fact.

Return type:

None

resolve_ledger_oss_aggregation_binding_values(revision, observations)[source]

Resolve every ledger_oss_aggregation binding on revision.

For each binding, observations are filtered by the four classification axes plus the transaction-kind set; matched observations are aggregated through the binding’s declared fact (iva_amount_sum defaults; base_amount_sum selects the base). The resolver is deterministic and side-effect-free.

Parameters:
Return type:

dict[TypeAliasType, Decimal]

Returns:

Mapping of binding id to the aggregated Decimal value. Empty match sets resolve to Decimal("0").

unsupported_ledger_oss_observations(revision, observations)[source]

Return the OssIossLedgerObservation rows no binding on revision can consume.

Fail-closed counterpart to resolve_ledger_oss_aggregation_binding_values(), mirroring unsupported_ledger_iva_observations(). An observation whose regime/destination/rate/direction/transaction-kind tuple matches no ledger_oss_aggregation binding has its base/cuota silently dropped — a modelling gap, not a legitimate zero.

False-fire guard: an observation carrying neither base nor IVA (both zero) contributes nothing whether or not it is routed and is excluded; only a non-zero declarable OSS line reaching no binding is surfaced.

Parameters:
Return type:

tuple[OssIossLedgerObservation, ...]

Returns:

Tuple of observations whose non-zero base/cuota is selected by no ledger_oss_aggregation binding.

class IvaLedgerObservation(**data)[source]

Bases: BaseModel

One factual ledger line tagged with the IVA classification triple.

Modelo 303 / 322 / 353 / 309 / 390 binding selectors filter these observations by category, rate kind, and flow direction; the runtime aggregates the matched lines through the binding’s aggregation operator.

Variables:
  • ledger_id – Stable id of the source ledger line.

  • transaction_date – When the supply takes place.

  • category – Substrate IvaCategory resolved by the classifier.

  • rate_kind – Substrate IvaRateKind rate tier.

  • flow_direction – Substrate IvaFlowDirection (output / input / self-assessed reverse charge).

  • base_amount – Taxable base in EUR.

  • iva_amount – IVA amount in EUR (cuota repercutida or soportada, depending on flow direction).

Parameters:
ledger_id: str
transaction_date: date
category: IvaCategory
exemption_article: IvaExemptionArticle | None
rate_kind: IvaRateKind
flow_direction: IvaFlowDirection
base_amount: Decimal
iva_amount: Decimal
recargo_amount: Decimal

Recargo de equivalencia cuota the supplier charged on a repercutido sale to a recargo-regime retailer, in EUR. Decimal("0") on every line that carries no recargo. Modelo 303 recargo cuota casillas select these via the recargo_amount_sum fact, routed by the line’s IVA rate tier.

prorrata_reference_id: str | None

Stable id of the linked ProrrataLedgerReference row, when set.

Populated by the aggregator only on SOPORTADO (input IVA) flows that carry a validated prorrata reference. Downstream Modelo 303 / 390 binding selectors filter prorrata-linked observations without a manual join against the parallel prorrata_references tuple.

cash_accounting_treatment: IvaCashAccountingTreatment

Independent criterio-de-caja axis.

Settlement observations use NONE and therefore flow through the normal Modelo 303 base/cuota bindings. Informational observations for boxes 62/63/74/75 carry the actual cash-accounting treatment so ordinary domestic rows cannot be confused with art. 75 projections.

input_classification: InputClassification | None

Operator-declared LIVA art. 106 prorrata-especial per-input use class.

Carried from the source ledger transaction’s input_classification. Meaningful only for SOPORTADO (input IVA) rows in a bucket under prorrata especial: the regime-aware ledger IVA apportionment routes the deducible cuota by this classification (the art. 106.Uno reglas 100%/0%/general). None for every row not under especial or carrying no per-input use declaration; the general-regime apportionment ignores it.

prorrata_sector_id: str | None

Operator-declared LIVA arts. 9.1.c / 101 differentiated sector.

Carried from the source ledger transaction’s prorrata_sector_id. Meaningful only for SOPORTADO (input IVA) rows in a sectorized bucket: the sector-aware ledger IVA apportionment applies THAT sector’s provisional percentage to the deducible cuota. None is a common-use input in a sectorized bucket (apportioned by the art. 104.Dos common percentage) and the whole-entity default otherwise; the non-sectorized apportionment ignores it.

validate_ledger_iva_aggregation_binding_definition(binding)[source]

Validate a ledger_iva_aggregation binding’s selector and aggregation.

Parameters:

binding (DataBindingDefinition) – The DataBindingDefinition to validate. Must have source == "ledger_iva_aggregation".

Raises:

RegistryValidationError – If the selector is malformed (unknown category / rate kind / flow direction / fact, empty tuple), if the aggregation operator is not “sum”, or if the binding source is not “ledger_iva_aggregation”.

Return type:

None

resolve_ledger_iva_aggregation_binding_values(revision, observations)[source]

Resolve every ledger_iva_aggregation binding on revision.

Filters observations by the three classification axes (category in selector.categories, rate_kind in selector.rate_kinds, flow_direction matches selector.flow_direction) and aggregates the matched lines’ iva_amount or base_amount per the declared fact.

Parameters:
Return type:

dict[TypeAliasType, Decimal]

Returns:

Mapping of binding id to the aggregated Decimal value. Empty match sets resolve to Decimal("0").

unsupported_ledger_iva_observations(revision, observations)[source]

Return IVA observations no binding on revision can consume.

Parameters:
Return type:

tuple[IvaLedgerObservation, ...]

Returns:

Tuple of IvaLedgerObservation instances not matched by any binding.

This is the fail-closed counterpart to resolve_ledger_iva_aggregation_binding_values(). Empty match sets on supported bindings still resolve to zero, but a concrete observation whose category/rate/flow triple is not selected by any ledger_iva_aggregation binding is a modelling gap and must not be silently inferred into an annual or periodic form.

Categories that bear no Modelo 303 cuota by law (CUOTA_LESS_M303_IVA_CATEGORIES — exempt, zero-rated, not-subject, exempt intra-community supplies/exports, triangulation, and régimen simplificado) are excluded: they correctly match no cuota binding, so flagging them would be a false positive. After the M303 routing tail (domestic / intra-community reverse-charge bindings, the import deducible binding) landed, every cuota-bearing declarable category has a consuming binding, so the residual unsupported set is empty for the known declarable categories; the function still fail-closes on any new declarable triple that no binding selects.

class RentaExpenseObservationProtocol(*args, **kwargs)[source]

Bases: Protocol

Structural protocol for first-slice Renta expense observations.

The registry only needs these four attributes to resolve ledger_renta_expense_aggregation bindings; the full RentaDeductibleExpenseObservation satisfies this protocol without any explicit declaration.

Properties are declared read-only so that Literal-typed concrete attributes (e.g. modelo: Literal[Modelo.M100]) satisfy the protocol under strict covariant checking.

property modelo: str
property period: str
property target_casilla_id: CasillaId
property deductible_amount: Decimal
validate_ledger_renta_expense_aggregation_binding_definition(binding)[source]

Validate a ledger_renta_expense_aggregation binding definition.

Return type:

None

Parameters:

binding (DataBindingDefinition)

resolve_ledger_renta_expense_aggregation_binding_values(revision, observations)[source]

Resolve every ledger_renta_expense_aggregation binding on revision.

Parameters:
Return type:

dict[TypeAliasType, Decimal]

unsupported_ledger_renta_expense_observations(revision, observations)[source]

Return the RentaExpenseObservationProtocol rows no binding on revision can consume.

Fail-closed counterpart to resolve_ledger_renta_expense_aggregation_binding_values(), mirroring unsupported_ledger_iva_observations(). An observation whose modelo/period/target_casilla_id triple matches no ledger_renta_expense_aggregation binding has its deductible amount silently dropped from the filing — a modelling gap, not a legitimate zero.

False-fire guard (ledger-iva-advisory-only-on-cuota-bearing-categories precedent): an observation that carries a zero deductible_amount contributes nothing whether or not it is routed, so it is excluded — only a non-zero declarable expense that reaches no casilla is surfaced.

Parameters:
Return type:

tuple[RentaExpenseObservationProtocol, ...]

Returns:

Tuple of observations whose non-zero deductible amount is selected by no ledger_renta_expense_aggregation binding.

renta_first_slice_binding_target_casillas(revision)[source]

Return the target_casilla_id set this revision’s own bindings route to.

Unlike aeat.domain.renta._first_slice_routing.FIRST_SLICE_EXPENSE_CASILLAS (the universal BOE-prescribed routing table spanning every filing year the application supports), this returns only the casillas a ledger_renta_expense_aggregation binding on THIS revision actually targets. Older Modelo 100 revisions (2020-2023) declare no such bindings at all – the first-slice ledger-aggregation mechanism did not yet exist for them – so their required set is legitimately empty even though the universal routing table’s codomain is wider. The snapshot-time referential-integrity gate (aeat.domain.renta._first_slice_routing_integrity) uses this per-revision set rather than the universal table so it only fails when a binding THIS revision actually declares points at a casilla absent from that same revision – the real defect class the gate exists to catch, not “does every filing year’s estimación directa casilla exist on every other filing year’s revision” (it does not, by BOE design: casillas are added, split, and renumbered across years).

Parameters:

revision (ModeloRevision) – The ModeloRevision whose own ledger_renta_expense_aggregation binding selectors are inspected.

Return type:

frozenset[TypeAliasType]

validate_ledger_renta_income_aggregation_binding_definition(binding)[source]

Validate a ledger_renta_income_aggregation binding definition.

Return type:

None

Parameters:

binding (DataBindingDefinition)

class RentaIncomeObservationProtocol(*args, **kwargs)[source]

Bases: Protocol

Structural protocol for actividad-económica income observations.

The registry only needs these attributes to resolve ledger_renta_income_aggregation bindings; the full RentaIncomeObservation satisfies this protocol without any explicit declaration.

property target_casilla_id: CasillaId
property gross_amount: Decimal
property taxable_base_amount: Decimal | None
property withheld_amount: Decimal
resolve_ledger_renta_income_aggregation_binding_values(revision, observations)[source]

Resolve every ledger_renta_income_aggregation binding on revision.

The fact declared in the binding selector controls which field is summed: "ingresos_integros_sum"observation.taxable_base_amount when declared, else observation.gross_amount (per-observation fallback); "gross_income_sum"observation.gross_amount; "taxable_base_sum"observation.taxable_base_amount (zero when None); "withheld_amount_sum"observation.withheld_amount.

Parameters:
Return type:

dict[TypeAliasType, Decimal]

unsupported_ledger_renta_income_observations(revision, observations)[source]

Return the RentaIncomeObservationProtocol rows no binding on revision can consume.

Fail-closed counterpart to resolve_ledger_renta_income_aggregation_binding_values(), mirroring unsupported_ledger_iva_observations(). An observation whose target_casilla_id matches no ledger_renta_income_aggregation binding has its income silently dropped from the filing — a modelling gap, not a legitimate zero.

False-fire guard: an observation whose declarable income is zero (both gross_amount and any declared taxable_base_amount are zero) contributes nothing whether or not it is routed and is excluded; only a non-zero income reaching no casilla is surfaced.

Parameters:
Return type:

tuple[RentaIncomeObservationProtocol, ...]

Returns:

Tuple of observations whose non-zero income is selected by no ledger_renta_income_aggregation binding.

validate_ledger_impatriado_income_aggregation_binding_definition(binding)[source]

Validate a ledger_impatriado_income_aggregation binding definition.

Return type:

None

Parameters:

binding (DataBindingDefinition)

validate_ledger_impatriado_income_aggregation_binding(binding)[source]

Validate a ledger_impatriado_income_aggregation binding at registry-build time.

Accumulating list[str] validator over _ImpatriadoLedgerIncomeSelector; lifts the casilla / fact / aggregation-op invariant via the raise-style validate_ledger_impatriado_income_aggregation_binding_definition().

Return type:

list[str]

Parameters:

binding (DataBindingDefinition)

class ImpatriadoIncomeObservationProtocol(*args, **kwargs)[source]

Bases: Protocol

Structural protocol for Modelo 151 impatriado Spanish-source income observations.

The registry only needs these attributes to resolve ledger_impatriado_income_aggregation bindings; the full ImpatriadoIncomeObservation satisfies this protocol without any explicit declaration.

property target_casilla_id: CasillaId
property gross_amount: Decimal
property taxable_base_amount: Decimal | None
resolve_ledger_impatriado_income_aggregation_binding_values(revision, observations)[source]

Resolve every ledger_impatriado_income_aggregation binding on revision.

The fact declared in the binding selector controls which field is summed: "ingresos_integros_sum"observation.taxable_base_amount when declared, else observation.gross_amount; "gross_income_sum"observation.gross_amount. Only ES-scoped observations reach this resolver; the source-scope segregation is owned by the application classifier.

Parameters:
Return type:

dict[TypeAliasType, Decimal]

unsupported_ledger_impatriado_income_observations(revision, observations)[source]

Return ES-scoped impatriado observations no binding on revision can consume.

The ModeloRevision supplies the ledger_impatriado_income_aggregation binding selectors that define which impatriado base casillas are supported.

Fail-closed counterpart to resolve_ledger_impatriado_income_aggregation_binding_values(). An ES-source observation whose target_casilla_id matches no ledger_impatriado_income_aggregation binding would otherwise have its income silently dropped from the impatriado base — a modelling gap, not a legitimate zero. A zero-income observation contributes nothing and is excluded.

Return type:

tuple[ImpatriadoIncomeObservationProtocol, ...]

Returns:

The unsupported ImpatriadoIncomeObservationProtocol rows, in input order.

Parameters:
class RentaGastoObservationProtocol(*args, **kwargs)[source]

Bases: Protocol

Structural protocol for M130 deductible-expense (gasto) observations.

The registry only needs these two attributes to resolve ledger_renta_gasto_aggregation bindings; the full RentaGastoObservation satisfies this protocol without any explicit declaration. Mirrors RentaIncomeObservationProtocol for the expense dimension.

property target_casilla_id: CasillaId
property deductible_amount: Decimal
validate_ledger_renta_gasto_aggregation_binding_definition(binding)[source]

Validate a ledger_renta_gasto_aggregation binding definition.

Return type:

None

Parameters:

binding (DataBindingDefinition)

resolve_ledger_renta_gasto_aggregation_binding_values(revision, observations)[source]

Resolve every ledger_renta_gasto_aggregation binding on revision.

Matches observations by target_casilla_id and sums their deductible_amount, mirroring the income resolver’s casilla-keyed fold.

Parameters:
Return type:

dict[TypeAliasType, Decimal]

unsupported_ledger_renta_gasto_observations(revision, observations)[source]

Return the gasto observations no binding on the ModeloRevision revision can consume.

Fail-closed counterpart to resolve_ledger_renta_gasto_aggregation_binding_values(), mirroring unsupported_ledger_renta_income_observations(). An observation whose target_casilla_id matches no ledger_renta_gasto_aggregation binding has its deductible expense silently dropped — a modelling gap, not a legitimate zero (no-silent-under-declaration).

False-fire guard: a zero-deductible_amount observation contributes nothing whether or not it is routed and is excluded; only a non-zero declarable gasto reaching no casilla is surfaced.

Return type:

tuple[RentaGastoObservationProtocol, ...]

Returns:

Unsupported RentaGastoObservationProtocol observations.

Parameters:
validate_ledger_oss_aggregation_binding(binding)[source]

Validate a ledger_oss_aggregation binding at registry-build time.

Accumulating list[str] validator: validates the selector shape against _OssIossLedgerSelector (preserving the underlying pydantic field error) then lifts the fact/aggregation-op invariant to build time via the raise-style validate_ledger_oss_aggregation_binding_definition(), which stays as a defence-in-depth resolve-time re-check.

Return type:

list[str]

Parameters:

binding (DataBindingDefinition)

validate_ledger_iva_aggregation_binding(binding)[source]

Validate a ledger_iva_aggregation binding at registry-build time.

Accumulating list[str] validator over _IvaLedgerSelector; lifts the fact/aggregation-op invariant via the raise-style validate_ledger_iva_aggregation_binding_definition().

Return type:

list[str]

Parameters:

binding (DataBindingDefinition)

validate_ledger_renta_expense_aggregation_binding(binding)[source]

Validate a ledger_renta_expense_aggregation binding at registry-build time.

Accumulating list[str] validator over _RentaLedgerExpenseSelector; lifts the fact/aggregation-op invariant via the raise-style validate_ledger_renta_expense_aggregation_binding_definition().

Return type:

list[str]

Parameters:

binding (DataBindingDefinition)

validate_ledger_renta_income_aggregation_binding(binding)[source]

Validate a ledger_renta_income_aggregation binding at registry-build time.

Accumulating list[str] validator over _RentaLedgerIncomeSelector; lifts the fact/aggregation-op invariant via the raise-style validate_ledger_renta_income_aggregation_binding_definition().

Return type:

list[str]

Parameters:

binding (DataBindingDefinition)

validate_ledger_renta_gasto_aggregation_binding(binding)[source]

Validate a ledger_renta_gasto_aggregation binding at registry-build time.

Accumulating list[str] validator over _RentaLedgerGastoSelector; lifts the casilla / fact / aggregation-op invariant via the raise-style validate_ledger_renta_gasto_aggregation_binding_definition().

Return type:

list[str]

Parameters:

binding (DataBindingDefinition)