aeat.domain.calculations.registry._withholding_bindings module

Withholding row-set binding helpers.

Withholding-source bindings declared on a ModeloRevision are resolved from per-perceptor withholding observations into scalar values or row outputs.

class WithholdingObservation(**data)[source]

Bases: BaseModel

Per-perceptor retencion / ingreso-a-cuenta observation for modelo 190 / 193.

Parameters:
source_id: str
perceptor_tax_id: str
country_code: str
transaction_date: date
clave: RetencionClave
subclave: str
percibido_dinerario: Decimal
percibido_especie: Decimal
retencion_practicada: Decimal
ingreso_a_cuenta: Decimal
class WithholdingObservationRequirement(**data)[source]

Bases: BaseModel

Withholding-source slice declared by one or more withholding bindings.

Parameters:
binding_ids: tuple[BindingId, ...]
claves: tuple[RetencionClave, ...]
validate_withholding_binding_selector_shape(binding)[source]

Validate withholding selector shape and fact/op invariants for snapshot build.

Return type:

list[str]

Parameters:

binding (DataBindingDefinition)

withholding_binding_requirements(revision)[source]

Return WithholdingObservationRequirement slices needed by revision’s withholding bindings.

The ModeloRevision is introspected for withholding bindings and grouped by the clave filters their selectors declare.

Return type:

tuple[WithholdingObservationRequirement, ...]

Parameters:

revision (ModeloRevision)

resolve_withholding_binding_values(revision, observations)[source]

Resolve scalar withholding-source bindings into Decimal aggregates.

The ModeloRevision contributes scalar withholding bindings; row producer bindings are handled by resolve_withholding_binding_row_values.

Return type:

dict[TypeAliasType, Decimal]

Parameters:
resolve_withholding_binding_row_values(revision, observations)[source]

Resolve row-producer withholding bindings into per-row indexed values.

The ModeloRevision contributes row-field withholding bindings, which are grouped into deterministic per-row output slots.

Return type:

dict[tuple[TypeAliasType, int], Decimal | str]

Parameters:
class WithholdingClaveBreakdown(**data)[source]

Bases: BaseModel

One per-clave row of the Modelo 190 retención reconciliation breakdown.

Groups the per-perceptor-clave withholding detail (the AEAT Diseño de Registros type-2 records) by clave de percepción and carries that clave’s distinct percepción count and percibido / retención magnitudes. The figures reuse the scalar withholding-fact arithmetic (resolve_withholding_binding_values()): percepcion_count is the distinct (perceptor, clave, subclave) count, percibido_total is percibido_dinerario + percibido_especie, and retencion_total is retencion_practicada + ingreso_a_cuenta. It is a projection of the same store the percepciones-count resolver reads, so the operator can reconcile the annual Modelo 190 totals against the individual Modelo 111 quarterly filings clave by clave.

Parameters:
clave: RetencionClave
percepcion_count: int
percibido_total: Decimal
retencion_total: Decimal
aggregate_withholding_by_clave(observations)[source]

Project withholding observations into WithholdingClaveBreakdown rows.

Pure function: identical observations in any order yield the same tuple, sorted by clave. No new aggregation is introduced — the magnitudes apply the exact percepcion_count / percibido_sum / retencion_sum field arithmetic of resolve_withholding_binding_values(), so the breakdown cannot drift from the bound facts that feed the calculation. Per clave, the distinct percepción key is (perceptor_tax_id, subclave) (the clave is the grouping axis).

Return type:

tuple[WithholdingClaveBreakdown, ...]

Parameters:

observations (Iterable[WithholdingObservation])

class WithholdingTotalsParity(**data)[source]

Bases: BaseModel

Totals-parity verdict between per-perceptor withholding rows and the Modelo 190 resumen-anual summary casillas.

Modelo 190’s summary casillas (decl.percepciones-total, decl.retenciones-total) are computed by SUMMING the taxpayer’s four Modelo 111 quarterly filings (source = "relation_prefill", op = "sum" over casillas 02/05/08/.../26 and 28 respectively) — an entirely INDEPENDENT source from the per-perceptor-clave WithholdingObservation detail (the AEAT Diseño de Registros type-2 “registro de perceptor” rows, source = "withholding") that materialises the modelo-190-perceptor-row-* bindings and the distinct-percepción count. Nothing in the registry cross-checks that the two sources agree.

This model is the pure comparison result of that cross-check: the sum of every persisted perceptor’s percibido_dinerario + percibido_especie against the resolved decl.percepciones-total value, and the sum of every persisted perceptor’s retencion_practicada + ingreso_a_cuenta against the resolved decl.retenciones-total value. is_consistent is True only when both deltas are within tolerance — a divergence on either side surfaces as a loud, actionable finding (no-silent-under-declaration), never a silent pass.

Parameters:
percepciones_row_total: Decimal
percepciones_summary_total: Decimal
percepciones_delta: Decimal
retenciones_row_total: Decimal
retenciones_summary_total: Decimal
retenciones_delta: Decimal
row_count: int
tolerance: Decimal
is_consistent: bool
compute_withholding_totals_parity(observations, *, percepciones_summary_total, retenciones_summary_total, tolerance=Decimal('0.01'))[source]

Cross-check summed per-perceptor withholding rows against the resolved Modelo 190 summary casillas.

Parameters:
  • observations (Iterable[WithholdingObservation]) – The persisted per-perceptor-clave WithholdingObservation rows (the AEAT Diseño de Registros type-2 “registro de perceptor” detail).

  • percepciones_summary_total (Decimal) – The resolved value of casilla decl.percepciones-total (the M111-relation-derived summary total), typically read from revision.casilla_values["decl.percepciones-total"].

  • retenciones_summary_total (Decimal) – The resolved value of casilla decl.retenciones-total, typically read from revision.casilla_values["decl.retenciones-total"].

  • tolerance (Decimal) – Maximum absolute delta (EUR) that does not surface a divergence. Defaults to one cent, matching the registry’s standard rounding tolerance.

Return type:

WithholdingTotalsParity

Returns:

A WithholdingTotalsParity verdict. is_consistent is False whenever either summed total diverges from its corresponding summary casilla by more than tolerance — a missing or dropped perceptor row under-declares the row-level total below the summary casilla and must surface as a divergence, never silently collapse into is_consistent=True.