Source code for aeat.domain.calculations.registry._schedules
"""Filing schedule selection from registry profile predicates.Evaluates the profile conditions declared on filing schedules of a:class:`ModeloRevision` against a profile facts mapping and returns onlythe schedules whose predicates are satisfied."""from__future__importannotationsfromcollections.abcimportMappingfromtypingimportFinalfrom._errorsimportRegistryValidationErrorfrom._schemaimportModeloRevision,ModeloScheduleDefinition,ProfilePredicateDefinition__all__=["applicable_filing_schedules","evaluate_profile_conditions","profile_condition_matches",]_IVA_REGIME_PATH:Final[str]="iva.regime"_IRPF_ESTIMATION_REGIME_PATH:Final[str]="irpf.estimation_regime"_TAXPAYER_ENTITY_TYPE_PATH:Final[str]="taxpayer.entity_type"
[docs]defapplicable_filing_schedules(revision:ModeloRevision,profile_facts:Mapping[str,object]|object,*,period:str|None=None,)->tuple[ModeloScheduleDefinition,...]:"""Return :class:`ModeloScheduleDefinition` items whose profile predicates match the supplied facts. Args: revision: The :class:`ModeloRevision` whose filing schedules to evaluate. profile_facts: Profile facts (mapping or aggregate) consulted by each schedule's :class:`ProfilePredicateDefinition` set. period: Optional period token; when supplied, schedules whose ``periods`` set excludes it are filtered out before predicate evaluation. """matched:list[ModeloScheduleDefinition]=[]forscheduleinrevision.filing_schedules:ifperiodisnotNoneandperiodnotinschedule.periods:continueif(evaluate_profile_conditions(schedule.profile_conditions,profile_facts,mode=schedule.profile_condition_mode,)isnotNone):matched.append(schedule)returntuple(matched)
[docs]defprofile_condition_matches(condition:ProfilePredicateDefinition,profile_facts:Mapping[str,object]|object,)->bool:observed=_resolve_profile_fact(profile_facts,condition.field)ifcondition.op=="equals":returnobserved==condition.valueifcondition.op=="not_equals":returnobserved!=condition.valueraiseRegistryValidationError(f"profile condition uses unsupported op {condition.op!r}")
def_resolve_profile_fact(profile_facts:object,field:str)->object:ifisinstance(profile_facts,Mapping)andfieldinprofile_facts:returnnext(vfork,vinprofile_facts.items()ifk==field)# Schema predicate path "iva.regime" maps to the TaxpayerProfile.iva_regime# attribute. The dotted path form is what the TOML registry declares; the# attribute name is what the Python dataclass exposes without nesting.iffield==_IVA_REGIME_PATHandhasattr(profile_facts,"iva_regime"):_attr="iva_regime"observed=getattr(profile_facts,_attr)returngetattr(observed,"value",observed)iffield==_IRPF_ESTIMATION_REGIME_PATHandhasattr(profile_facts,"irpf_estimation_regime"):_attr="irpf_estimation_regime"observed=getattr(profile_facts,_attr)returngetattr(observed,"value",observed)# Schema predicate path "taxpayer.entity_type" maps to# TaxpayerProfile.entity_type. The "taxpayer." prefix is the namespace used# in the registry TOML; the attribute is a flat field on the profile object.iffield==_TAXPAYER_ENTITY_TYPE_PATHandhasattr(profile_facts,"entity_type"):_attr="entity_type"returngetattr(profile_facts,_attr)current:object=profile_factsforpartinfield.split("."):ifisinstance(current,Mapping):ifpartnotincurrent:raiseRegistryValidationError(f"profile facts missing {field!r}")current=next(vfork,vincurrent.items()ifk==part)continueifnothasattr(current,part):raiseRegistryValidationError(f"profile facts missing {field!r}")current=getattr(current,part)returncurrent