Source code for cadrumo.domain.calculations.registry.gasto193_bindings
"""Modelo 193 gastos-relationship row-set binding helpers.Modelo 193's hoja anexo (registro tipo 2, relación de gastos) carries one rowper contribuyente for whom the declarante perceived the art. 26.1.a) LIRPFgastos de administracion y deposito de valores. This family validates theobservation and binding-selector shapes consumed by row-set ingestion. Therequired declarante total is a separate explicit input until a secureobservation owner exists."""from__future__importannotationsfromdatetimeimportdatefromdecimalimportDecimalfromtypingimportTYPE_CHECKING,LiteralfrompydanticimportBaseModel,Fieldfrom....core.aggregationimportBindingAggregationOp,BindingSourceKindfrom....core.identity.tax_idimportTaxIdIdentityTokenfrom....core.modelsimportSTRICT_FROZEN_CONFIGfrom.binding_aggregationimportbinding_aggregation_opfrom.binding_selector_utilsimport(provider_member,)from.errorsimportRegistryValidationErrorfrom.schema_exportsimportExportFieldDataTypeifTYPE_CHECKING:from.schemaimportBindingDefinition__all__=["Gasto193ContributorProvider","Gasto193Observation","validate_gasto193_binding_selector_shape",]_Gasto193RowField=Literal["contributor_tax_id","contributor_legal_name","representative_tax_id","importe_gastos",]_Gasto193Fact=Literal["row_field"]def_runtime_object(value:object)->object:"""Capture a selector token before applying its runtime invariant check."""returnvalue
[docs]classGasto193Observation(BaseModel):"""One modelo 193 gastos-relationship row: contribuyente plus annual gastos."""model_config=STRICT_FROZEN_CONFIGsource_id:str=Field(min_length=1,max_length=128)contributor_tax_id:TaxIdIdentityToken=Field(min_length=1,max_length=64)contributor_legal_name:str=Field(default="",max_length=200)representative_tax_id:TaxIdIdentityToken|None=Field(default=None,min_length=9,max_length=9)"""NIF of the minor's legal representative, declared by the design only when the contribuyente is a minor; spaces elsewhere."""transaction_date:dateimporte_gastos:Decimal=Decimal("0")"""The annual gastos de administracion y deposito amount (positions 195-206), the design's own zeros when none."""def_non_negative_gastos(self)->None:ifself.importe_gastos<Decimal("0"):raiseRegistryValidationError("gasto amounts must be non-negative")
[docs]classGasto193ContributorProvider(BaseModel):"""The Modelo 193 expense-contributor provider over the detail-record store."""model_config=STRICT_FROZEN_CONFIGkind:Literal[BindingSourceKind.GASTO193_CONTRIBUTOR]=BindingSourceKind.GASTO193_CONTRIBUTORfact:_Gasto193Factclaves:tuple[str,...]=()row_field:_Gasto193RowField|None=Nonegrouping:Literal["per_gasto193_contribuyente"]|None=Nonerecord:str|None=Field(default=None,min_length=1,max_length=64)data_type:ExportFieldDataType|None=None
[docs]defvalidate_gasto193_binding_selector_shape(binding:BindingDefinition)->list[str]:"""Validate a ``gasto193`` binding's fact/aggregation invariants. The provider shape is the union member's own gate; only the fact/op cross-invariant needs lifting to build time. """selector=_gasto193_selector(binding)try:op=binding_aggregation_op(binding)fact=_runtime_object(selector.fact)iffact=="row_field":ifop!=BindingAggregationOp.ROWS:raiseRegistryValidationError("gasto193 fact 'row_field' requires aggregation op 'rows'")ifselector.row_fieldisNone:raiseRegistryValidationError("gasto193 fact 'row_field' requires a 'row_field' selector key")ifselector.groupingisNone:raiseRegistryValidationError("gasto193 fact 'row_field' requires a 'grouping' selector key")exceptRegistryValidationErrorasexc:return[f"binding {binding.id!r} (source={binding.source!r}) gasto193 invariants violated: {exc}"]return[]