aeat.application.aggregation._retenciones module¶
Pure aggregation primitives for the retenciones modelo family.
This module groups typed RetencionObservation rows into stable
per-perceptor rollups and totals for Modelos 111, 115, 123, 180, 190, and 193.
Observations must carry canonical source kinds from
BindingSourceKind; bare invoice provenance
is rejected in favour of payable_invoice or collectible_invoice.
The live calculation mesh uses these primitives through
RetencionesAggregationSourceResolver for the RET-1
Modelo 180/193 distinct-NIF perceptor count. Modelo 190’s distinct
perceptor/clave/subclave percepciones count is intentionally handled by
WithholdingSourceResolver, not by this rollup
family.
- class RetencionObservation(**data)[source]¶
Bases:
BaseModelOne typed observation feeding a retenciones aggregator.
The source ledger transaction (
source_object_id) is referenced by its canonical source kindledger_transaction. Bareinvoicesource bindings are forbidden at the registry domain layer; observations originating from invoice records carry one ofpayable_invoice/collectible_invoiceinstead.- Parameters:
source_kind (BindingSourceKind)
source_object_id (str)
perceptor_nif (str)
perceptor_name (str)
scheme (RetencionScheme)
taxable_base (Decimal)
retencion_amount (Decimal)
accrued_on (str)
- source_kind: BindingSourceKind¶
- source_object_id: str¶
- perceptor_nif: str¶
- perceptor_name: str¶
- scheme: RetencionScheme¶
- taxable_base: Decimal¶
- retencion_amount: Decimal¶
- accrued_on: str¶
- class RetencionPerceptorRollup(**data)[source]¶
Bases:
BaseModelOne row in the aggregation: a perceptor’s totals across schemes.
- Parameters:
source_kind (BindingSourceKind)
perceptor_nif (str)
perceptor_name (str)
scheme (RetencionScheme)
observations_count (int)
total_taxable_base (Decimal)
total_retencion (Decimal)
- source_kind: BindingSourceKind¶
- perceptor_nif: str¶
- perceptor_name: str¶
- scheme: RetencionScheme¶
- observations_count: int¶
- total_taxable_base: Decimal¶
- total_retencion: Decimal¶
- class RetencionesAggregation(**data)[source]¶
Bases:
BaseModelAggregate output for a retenciones modelo + period.
The output is content-addressable: identical input observations in any order produce the same rollup tuple (sorted by perceptor + scheme) and the same totals.
- Parameters:
- modelo: str¶
- period: InstanceOf[Period]¶
- rollups: tuple[RetencionPerceptorRollup, ...]¶
- total_perceptors: int¶
- total_taxable_base: Decimal¶
- total_retencion: Decimal¶
- aggregate_retenciones_111(observations, *, period)[source]¶
Aggregate per (perceptor_nif, scheme) into a Modelo 111 payload.
Pure function: identical observation input + period yields identical output. Rollups are sorted by (perceptor_nif, scheme.value) so two equal aggregations serialise to identical bytes.
Returns a
RetencionesAggregation.- Return type:
- Parameters:
observations (tuple[RetencionObservation, ...])
period (Period)
- aggregate_retenciones_115(observations, *, period)[source]¶
Aggregate Modelo 115 (retenciones sobre arrendamiento urbano).
Only
URBAN_RENTALscheme observations are in scope.Returns a
RetencionesAggregationwith per-perceptor rollups and grand totals for Modelo 115.- Return type:
- Parameters:
observations (tuple[RetencionObservation, ...])
period (Period)
- aggregate_retenciones_123(observations, *, period)[source]¶
Aggregate Modelo 123 retenciones into a
RetencionesAggregation.Covers rendimientos del capital mobiliario: intereses, dividendos, y otros. In-scope schemes: CAPITAL_INTEREST, CAPITAL_DIVIDEND, CAPITAL_OTHER.
- Return type:
- Parameters:
observations (tuple[RetencionObservation, ...])
period (Period)
- aggregate_retenciones_180(observations, *, period)[source]¶
Aggregate Modelo 180 (resumen anual de retenciones sobre arrendamiento urbano).
Shares the URBAN_RENTAL scheme catalogue with Modelo 115; the difference is the period scope (full year vs quarter) which the caller supplies. Callers should pass an annual period string (e.g.
"2025") and feed in the union of the year’s 115 observations.Returns a
RetencionesAggregation.- Return type:
- Parameters:
observations (tuple[RetencionObservation, ...])
period (Period)
- aggregate_retenciones_190(observations, *, period)[source]¶
Aggregate Modelo 190 (resumen anual de retenciones IRPF de Modelo 111).
Shares the 111 scheme catalogue (WORK_INCOME + ECONOMIC_ACTIVITY + PROFESSIONAL + PRIZE) widened over the annual period.
Returns a
RetencionesAggregationwith per-perceptor rollups and grand totals for the annual summary.- Return type:
- Parameters:
observations (tuple[RetencionObservation, ...])
period (Period)
- aggregate_retenciones_193(observations, *, period)[source]¶
Aggregate Modelo 193 retenciones into a
RetencionesAggregation.Resumen anual de retenciones sobre capital mobiliario. Shares the 123 scheme catalogue.
- Return type:
- Parameters:
observations (tuple[RetencionObservation, ...])
period (Period)
- class RetencionesTotalsParity(**data)[source]¶
Bases:
BaseModelTotals-parity verdict between the dedicated per-perceptor retención store and a resumen-anual summary.
Modelo 193’s (and Modelo 180’s) monetary resumen casillas (
decl.base-total,decl.retenciones-total) are computed by the registry as a SUM of the taxpayer’s four Modelo 123 (Modelo 115 for 180) quarterly filings (source = "relation_prefill"), and the distinct-NIF perceptor count (decl.total-perceptores) is bound toaggregate_retenciones_193()/aggregate_retenciones_180()over the dedicated per-perceptor retención store (RetencionesAggregation, RET-1). Both are independently sourced: nothing in the registry cross-checks that the quarterly-relation totals and the per-perceptor store’s totals agree.This model is the pure comparison result of that cross-check: the aggregation’s
total_perceptors/total_taxable_base/total_retencionagainst the resolved summary casilla values.is_consistentisTrueonly when every delta is withintolerance(the perceptor-count delta is compared as an exact integer match) — a divergence on any axis surfaces as a loud, actionable finding (no-silent-under-declaration), never a silent pass.- Parameters:
perceptores_aggregation_total (int)
perceptores_summary_total (int)
perceptores_delta (int)
base_aggregation_total (Decimal)
base_summary_total (Decimal)
base_delta (Decimal)
retenciones_aggregation_total (Decimal)
retenciones_summary_total (Decimal)
retenciones_delta (Decimal)
tolerance (Decimal)
is_consistent (bool)
- perceptores_aggregation_total: int¶
- perceptores_summary_total: int¶
- perceptores_delta: int¶
- base_aggregation_total: Decimal¶
- base_summary_total: Decimal¶
- base_delta: Decimal¶
- retenciones_aggregation_total: Decimal¶
- retenciones_summary_total: Decimal¶
- retenciones_delta: Decimal¶
- tolerance: Decimal¶
- is_consistent: bool¶
- compute_retenciones_totals_parity(aggregation, *, perceptores_summary_total, base_summary_total, retenciones_summary_total, tolerance=Decimal('0.01'))[source]¶
Cross-check a
RetencionesAggregationagainst a resumen-anual summary’s casillas.- Parameters:
aggregation (
RetencionesAggregation) – The real per-perceptorRetencionesAggregation(typicallyaggregate_retenciones_193()oraggregate_retenciones_180()) built from the dedicated per-perceptor retención store for the filing year.perceptores_summary_total (
int) – The resolved value of casilladecl.total-perceptores(already sourced from the SAME aggregation via theretenciones_aggregationbinding, so this axis is expected to always match; included for completeness and to catch a stale/desynchronised binding read).base_summary_total (
Decimal) – The resolved value of casilladecl.base-total(the relation-prefill sum of the taxpayer’s quarterly filings’ base casilla).retenciones_summary_total (
Decimal) – The resolved value of casilladecl.retenciones-total(the relation-prefill sum of the taxpayer’s quarterly filings’ retenciones casilla).tolerance (
Decimal) – Maximum absolute EUR delta that does not surface a divergence on the monetary axes. Defaults to one cent, matching the registry’s standard rounding tolerance.
- Return type:
- Returns:
A
RetencionesTotalsParityverdict.is_consistentisFalsewhenever the perceptor count differs at all, or either monetary total diverges from its corresponding summary casilla by more thantolerance— a dropped or double-counted perceptor row, or a quarterly filing missing from the relation-prefill sum, must surface as a divergence, never silently collapse intois_consistent=True.