Source code for aeat.domain.calculations.registry._retenciones_bindings
"""Retenciones-aggregation registry binding helpers (RET-1).The per-family module for the ``retenciones_aggregation`` binding source — thecalc-mesh source that materialises retenciones-family scalars from the dedicatedper-perceptor retención store.Extracted as its own family module per ``registry-resolver-family-extraction``;the cross-family validator dispatch in :mod:`._bindings` registers this family's``validate(binding) -> list[str]`` entry.The materialisation depends on a :class:`_RetencionesAggregationProtocol` ratherthan the application-layer ``RetencionesAggregation``, so the domain layer staysindependent of the application aggregation service.The resolver walks the declared :class:`ModeloRevision` bindings and emits onlycanonical binding values for this source family."""from__future__importannotationsfromdecimalimportDecimalfromtypingimportLiteral,ProtocolfrompydanticimportBaseModel,ConfigDictfrom....coreimportBindingSourceKindfrom....core.aggregationimportRetencionSchemefrom._binding_selector_utilsimportselector_against_modelfrom._binding_selector_utilsimportselector_as_dictas_selector_as_dictfrom._idsimportBindingId,CasillaIdfrom._schemaimportDataBindingDefinition,ModeloRevisionclass_RetencionesAggregationProtocol(Protocol):"""The scalar totals the retenciones-aggregation source materialises."""@propertydefrollups(self)->tuple[_RetencionesRollupProtocol,...]:...@propertydeftotal_perceptors(self)->int:...@propertydeftotal_taxable_base(self)->Decimal:...@propertydeftotal_retencion(self)->Decimal:...class_RetencionesRollupProtocol(Protocol):"""One per-perceptor/scheme rollup row exposed by the retenciones source."""@propertydefperceptor_nif(self)->str:...@propertydefscheme(self)->RetencionScheme:...@propertydeftotal_taxable_base(self)->Decimal:...@propertydeftotal_retencion(self)->Decimal:...class_RetencionesAggregationSelector(BaseModel):"""Validated form of a ``retenciones_aggregation`` binding selector. Carries the target casilla id and the scalar fact this source serves. Annual summary modelos still keep their monetary totals on relation-prefill bindings; Modelo 115 uses the same per-perceptor store directly for its quarterly perceptor count and taxable base. """model_config=ConfigDict(strict=False,frozen=True,extra="forbid")target_casilla_id:CasillaIdschemes:tuple[RetencionScheme,...]=()fact:Literal["perceptor_count_distinct","taxable_base_sum","retencion_amount_sum"]="perceptor_count_distinct"
[docs]defvalidate_retenciones_aggregation_binding(binding:DataBindingDefinition)->list[str]:"""Accumulating registry-build validator for a ``retenciones_aggregation`` binding. Validates the selector shape against :class:`_RetencionesAggregationSelector` (the single build-time contract per ``binding-validation-single-contract``), preserving the underlying pydantic field message in the diagnostic. """returnselector_against_model(binding,_RetencionesAggregationSelector)
[docs]defresolve_retenciones_aggregation_binding_values(revision:ModeloRevision,aggregation:_RetencionesAggregationProtocol,)->dict[BindingId,Decimal]:"""Materialise every ``retenciones_aggregation`` binding on a :class:`ModeloRevision`. Returns a binding value for every binding whose ``source`` is :attr:`BindingSourceKind.RETENCIONES_AGGREGATION`, keyed by the selector's declared fact. """resolved:dict[BindingId,Decimal]={}forbindinginrevision.bindings:ifbinding.source!=BindingSourceKind.RETENCIONES_AGGREGATION:continueselector=_RetencionesAggregationSelector.model_validate(_selector_as_dict(binding))resolved[binding.id]=_retenciones_selector_value(selector,aggregation)returnresolved