Source code for aeat.domain.calculations.registry._period_offset_math
"""Period-offset arithmetic shared by previous-filing and relation binding helpers.Supports quarterly (``1T``..``4T``), pago-fraccionado (``1P``..``3P``), andzero-padded monthly (``01``..``12``) period codes. Offsets wrap acrosscalendar-year boundaries and return the derived period plus the relative yeardelta.See Also: :mod:`aeat.domain.calculations.registry._bindings_previous_filing` Previous-filing selectors that derive target-relative source period anchors. :mod:`aeat.domain.calculations.registry._relations` Relation source requirements that use the same offset arithmetic."""from__future__importannotationsfrom._errorsimportRegistryValidationError_QUARTERLY_PERIOD_ORDINAL:dict[str,int]={"1T":1,"2T":2,"3T":3,"4T":4}_ORDINAL_TO_QUARTERLY:dict[int,str]={ordinal:codeforcode,ordinalin_QUARTERLY_PERIOD_ORDINAL.items()}_PAGO_FRACCIONADO_PERIOD_ORDINAL:dict[str,int]={"1P":1,"2P":2,"3P":3}_ORDINAL_TO_PAGO_FRACCIONADO:dict[int,str]={ordinal:codeforcode,ordinalin_PAGO_FRACCIONADO_PERIOD_ORDINAL.items()}
[docs]defapply_period_offset(offset:int,*,target_period:str)->tuple[int,str]:"""Apply an integer period offset to a target period code. Returns ``(year_delta, derived_period)`` where ``year_delta`` is the number of calendar years by which the derived period precedes or follows the target year (negative = prior year, positive = following year). The tuple is consumed by previous-filing and :class:`~aeat.domain.calculations.registry.RelationDefinition` ``source_period_offset_from_target`` resolution. Raises: :exc:`~aeat.domain.calculations.registry.RegistryValidationError`: When ``target_period`` is not a recognised period-code format. """iftarget_periodin_QUARTERLY_PERIOD_ORDINAL:year_delta,zero_based=divmod(_QUARTERLY_PERIOD_ORDINAL[target_period]-1+offset,4)returnyear_delta,_ORDINAL_TO_QUARTERLY[zero_based+1]iftarget_periodin_PAGO_FRACCIONADO_PERIOD_ORDINAL:year_delta,zero_based=divmod(_PAGO_FRACCIONADO_PERIOD_ORDINAL[target_period]-1+offset,3)returnyear_delta,_ORDINAL_TO_PAGO_FRACCIONADO[zero_based+1]iflen(target_period)==2andtarget_period.isdigit():year_delta,zero_based=divmod(int(target_period)-1+offset,12)returnyear_delta,f"{zero_based+1:02d}"raiseRegistryValidationError(f"source_period_offset_from_target cannot interpret target period {target_period!r}")