cadrumo.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
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.perceptor_nifis normalised to its canonical identity token on construction, so the identity this aggregator groups by is the identity the encrypted per-perceptor store keys by. Holding the raw declaration here split the two: the repository trimmed and uppercased the NIF before hashing it into the object key, so two canonically-equal declarations produced two rollups and two perceptors in the count while sharing one stored row – the later write overwriting the earlier evidence for a perceptor the declaration still counts twice.accrued_onis admitted by the canonical date authority. A ten-character length bound is not a date check:2026-99-99and2026-02-30both satisfy it, and the aggregators then summed and counted a row whose accrual date does not exist, with the encrypted store persisting it as declared evidence.- Parameters:
data (Any)
- source_kind: BindingSourceKind¶
- source_object_id: str¶
- perceptor_nif: TaxIdIdentityToken¶
- perceptor_name: str¶
- scheme: RetencionScheme¶
- taxable_base: Decimal¶
- retencion_amount: Decimal¶
- accrued_on: IsoDateString¶
- class RetencionPerceptorRollup(**data)[source]¶
Bases:
BaseModelOne row in the aggregation: a perceptor’s totals across schemes.
- Parameters:
data (Any)
- source_kind: BindingSourceKind¶
- perceptor_nif: TaxIdIdentityToken¶
- perceptor_name: str¶
- scheme: RetencionScheme¶
- observations_count: NonNegativeInt¶
- 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:
data (Any)
- modelo: str¶
- period: InstanceOf[Period]¶
- rollups: tuple[RetencionPerceptorRollup, ...]¶
- total_perceptors: NonNegativeInt¶
- total_taxable_base: Decimal¶
- total_retencion: Decimal¶
- registry_work_income_retencion_treatments(effective_date, *, authority=None)[source]¶
Resolve work-income treatment declarations from the dated fact mapping.
- Return type:
- Parameters:
effective_date (date)
authority (GovernedFactSource | None)
- aggregate_retenciones_111(observations, *, period, operation=None)[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)
operation (PinnedAuthorityOperation | None)
- aggregate_retenciones_115(observations, *, period, operation=None)[source]¶
Aggregate Modelo 115 (retenciones sobre arrendamiento urbano).
Only the schemes declared for this modelo by the registry are in scope.
Returns a
RetencionesAggregationwith per-perceptor rollups and grand totals for Modelo 115.- Return type:
- Parameters:
observations (tuple[RetencionObservation, ...])
period (Period)
operation (PinnedAuthorityOperation | None)
- aggregate_retenciones_123(observations, *, period, operation=None)[source]¶
Aggregate Modelo 123 retenciones into a
RetencionesAggregation.Covers the capital-income schemes selected by the registry.
- Return type:
- Parameters:
observations (tuple[RetencionObservation, ...])
period (Period)
operation (PinnedAuthorityOperation | None)
- aggregate_retenciones_180(observations, *, period, operation=None)[source]¶
Aggregate Modelo 180 (resumen anual de retenciones sobre arrendamiento urbano).
Shares the selected scheme catalogue with the corresponding quarterly model; 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)
operation (PinnedAuthorityOperation | None)
- aggregate_retenciones_190(observations, *, period, operation=None)[source]¶
Aggregate Modelo 190 (resumen anual de retenciones IRPF de Modelo 111).
Shares the selected quarterly scheme catalogue 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)
operation (PinnedAuthorityOperation | None)
- aggregate_retenciones_193(observations, *, period, operation=None)[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)
operation (PinnedAuthorityOperation | None)