aeat.application.aggregation._withholding_source module

Calc-mesh source resolver for the per-perceptor-clave withholding store (#28 P03).

Reads the dedicated PercepcionObservationRepository for the modelo’s annual window and materialises the Modelo 190 “número total de percepciones” box with the DISTINCT (perceptor, clave, subclave) count (the percepcion_count withholding fact) — replacing the wrong sum-of-quarterly-M111-perceptor-counts relations. The pull and calculate surfaces read this ONE store (one-aggregation-path-pull-equals-calculate).

Lives in its own module (rather than _modelo_bindings.py) so the percepciones source is isolated from the contended retenciones/ledger mesh surface; it is enrolled in merge_source_resolutions exactly like the other source resolvers. It reads the withholding bindings declared on the snapshot’s ModeloRevision and returns its result as a CalculationSourceResolution.

Empty-store behaviour follows the RET-1 ruling: materialise an explicit ZERO count AND surface a non-blocking advisory (NOT a hard refusal) — a legitimate nil-percepciones filer must still be able to calculate, and the bound casilla requires its fact (no-silent-under-declaration: the zero is loud, not silent).

class WithholdingSourceResolver(*, withholding_repository=None)[source]

Bases: object

Source mesh resolver for the dedicated per-perceptor-clave withholding store (#28).

Materialises the Modelo 190 “número total de percepciones” box with the DISTINCT (perceptor_tax_id, clave, subclave) count (the percepcion_count fact) over the persisted withholding detail — the percepciones counterpart of RetencionesAggregationSourceResolver (which counts distinct perceptores for M180/M193). The pull and calculate surfaces read this one store (one-aggregation-path).

Parameters:

withholding_repository (PercepcionObservationRepository | None)

resolver_id
owned_sources
resolve(context)[source]
Return type:

CalculationSourceResolution

Parameters:

context (CalculationSourceContext)