cadrumo.core.period module¶
Canonical period code enumeration for filing periods.
Period codes represent the filing frequency and scheme for tax returns: - Quarterly: 1T, 2T, 3T, 4T (standard filing periods) - Instalment: 1P, 2P, 3P, 4P (corporate-tax/IS instalment periods) - Annual: 0A - Monthly: 01-12 (calendar months) - OSS/IOSS: EXT-1T, EXT-2T, EXT-3T, EXT-4T (extra-Union scheme) - Ad-hoc/Event: AD-HOC, EVENT-N (event-driven filings)
StandardPeriodCode is the canonical StrEnum for
the closed standard vocabulary (1T-4T, 1P-4P, 0A, 01-12). It includes both
calendar spans and instalment claves, so callers that need date boundaries
must still check Period.has_date_span(). RegistryPeriodCode
is the pydantic field annotation for the full registry union: standard
members plus extended OSS/IOSS literals, AD-HOC, the open-ended event
shape, the administrative censo tokens, and the symbolic EVENT-N selector.
FilingPeriodCode is the narrower annotation for a period a taxpayer
files in — the same union minus the administrative tokens and the symbolic
selector, neither of which names one concrete filing period. Two boundaries
with different value spaces need two annotations:
widening one to admit a registry coordinate must not widen the other.
Period combines one accepted FILING code with a filing year, and
PeriodKind classifies the resulting cadence.
This module is the runtime counterpart to the registry
domain.calculations.registry.schema_scalars.PeriodCode alias and
domain.calculations.registry.schema_references.PeriodSelector schema. Registry
objects carry bare period tokens; application services that need a concrete
filing window compose those tokens with a year into Period.
Operator commands follow the same separated shape (--year YYYY --period
<AEAT-token>); any year-qualified filter mini-grammar is converted at the
CLI boundary before it reaches this model.
- class StandardPeriodCode(*values)[source]¶
Bases:
StrEnumCanonical enumeration of closed standard filing-period codes.
Quarterly, monthly, and annual members have calendar spans. Instalment members (
1P-4P) identify filing/payment events and intentionally do not imply a contiguous ledger date span.- Q1¶
- Q2¶
- Q3¶
- Q4¶
- P1¶
- P2¶
- P3¶
- P4¶
- ANNUAL¶
- JAN¶
- FEB¶
- MAR¶
- APR¶
- MAY¶
- JUN¶
- JUL¶
- AUG¶
- SEP¶
- OCT¶
- NOV¶
- DEC¶
- is_administrative_period_token(token)[source]¶
Return whether
tokenis one of the administrative censo period codes.The administrative sub-vocabulary (Modelo 036’s
ALTA/MODIFICACION/BAJA, Modelo 145’sCOMUNICACION/VARIACION) addresses a registry revision rather than naming a period, so a caller holding a raw registry token generally needs to route it somewhere other thanPeriod. This is the one public way to ask, so the membership test cannot be hand-copied into a second, drifting set.Matching is on the registry’s own unaccented spelling. A caller reading a token off an AEAT-rendered surface — where Spanish prints
MODIFICACIÓN,COMUNICACIÓN,VARIACIÓN— folds it withfold_diacritics()first; admitting accented spellings here would put this predicate andRegistryPeriodCodeinto disagreement about the same token.- Raises:
ValueError – When
tokenis not a string.- Return type:
- Parameters:
token (str)
- is_symbolic_event_selector(token)[source]¶
Return whether
tokenis the symbolicEVENT-Nregistry selector.The selector covers the concrete
EVENT-1/EVENT-2periods without being one, so a registry coordinate carrying it has no filing period.- Raises:
ValueError – When
tokenis not a string.- Return type:
- Parameters:
token (str)
- is_filing_period_token(token)[source]¶
Return whether
tokennames exactly one period a taxpayer can file.Registry selectors also carry administrative censo tokens and the symbolic
EVENT-Nselector, which cover filings without being one; neither builds aPeriod.- Raises:
ValueError – When
tokenis not a string.- Return type:
- Parameters:
token (str)
- accepted_filing_period_codes()[source]¶
Return the fully enumerable codes a
Periodaccepts.The administrative tokens are excluded — they address a registry revision, not a filing period — as is the infinite
EVENT-<number>family.
- accepted_filing_period_patterns()[source]¶
Return human-readable patterns for the periods a
Periodaccepts.
- exception PeriodError(message=None, *, context=None, translated_message=None)[source]¶
Bases:
CadrumoErrorRaised when a
Periodis constructed from an invalid year/code.Pydantic boundaries translate this registered failure to
ValueErrorwhen they need Pydantic’s structured validation envelope.- Parameters:
- Return type:
None
- code¶
- class PeriodKind(*values)[source]¶
Bases:
StrEnumCadence class of a filing period, derived from its registry code.
- QUARTERLY¶
- MONTHLY¶
- ANNUAL¶
- INSTALMENT¶
- EXTENDED¶
- registry_period_kind(token)[source]¶
Return the cadence class of any REGISTRY period token.
Accepts the full
RegistryPeriodCodevocabulary, so a registry-facing consistency check (afiling_schedulesdeclaration reconciling itsperiod_kindagainst itsperiods) can classify an administrative censo token or the symbolicEVENT-Nselector. Both classify asPeriodKind.EXTENDED, matching what aPeriodreported for them while one validator still served both boundaries.This lives here, rather than in the one registry validator that calls it, because
_period_kind_for_code()is the single cadence authorityPeriod.kindalso reads. Registry ownership would force either a cross-package import of that private helper or a second token-to-cadence map — a duplicate authority for “what cadence is this token”. One narrow public function for one narrow caller is the cheaper of the two, and it names the vocabulary it speaks now that two vocabularies exist.- Raises:
ValueError – When
tokenis not an accepted registry period code.- Return type:
- Parameters:
token (str)
- class Period(**data)[source]¶
Bases:
BaseModelA filing period as one typed value: a year paired with a registry code.
Periodis the canonical, fundamental representation of “which filing period” across the whole application. It composes exactly two authoritative fields — thefiling_yearand the registry periodcode(aStandardPeriodCodemember such as1T/0A/03, or an extended union member such asEXT-1T/AD-HOC/EVENT-3) — and never a combined calendar string (2026Q1/2026-03/2026). Those calendar shapes are neither accepted inputs nor canonical outputs. The only display projection is the space-separated__str__()form ("2026 1T"), and normal inbound construction is from a(year, code)pair viafrom_year_and_code().The model is frozen and hashes by
(filing_year, code), so aPeriodis a drop-in dict key, set member, and equality target wherever a typed period is required. The ledger and aggregation boundary routes throughapplication.aggregation.modelo_bindings.aggregation_period_for_modelo(), then usescontains()as the single date-boundary authority.- Variables:
filing_year – Filing year carried separately from the registry token.
code – Bare
FilingPeriodCodetoken — the registry union minus the coordinates that address a revision rather than a filing period.
- Parameters:
data (Any)
- filing_year: int¶
Deliberately wider than the registry’s authored filing-year window.
A period is a calendar span, not a claim that a revision exists for it. It must be able to EXPRESS a year the registry cannot serve – a pre-1995 IVA regime under Ley 41/1994, or a 1999 coordinate whose refusal is the behaviour under test – so narrowing it to the filing-year axis would make those cases unrepresentable rather than refusable.
- code: FilingPeriodCode¶
- classmethod from_year_and_code(year, code)[source]¶
Build a
Periodfrom a filing year and a bare registry code.- Parameters:
year (
int) – The filing year (e.g.2026).code (
str) – A bare filing period code — aStandardPeriodCodevalue (1T-4T/1P-4P/0A/01-12) or an extended union member (EXT-1T-EXT-4T/AD-HOC/EVENT-3). The code is validated againstFilingPeriodCode; a combined calendar string, an administrative censo token, and the symbolicEVENT-Nselector are all refused.
- Raises:
PeriodError – When
codeis not an accepted filing period code oryearis outside the supported range.- Return type:
- classmethod from_string(value)[source]¶
Parse the canonical display string emitted by
__str__().Only the separated
"YYYY <registry-code>"display form is accepted. Combined calendar strings such as"2026Q1"or"2026-1T"are refused; this method is for display round-trips, not an alternate CLI or registry grammar.- Parameters:
value (
str) – Space-separated display string containing a four-digit filing year and a bare registry period code.- Return type:
- Returns:
A
Periodparsed from the canonical display string.- Raises:
PeriodError – When
valueis not the display form or contains an invalid registry period code.
- property registry_token: str¶
Return the bare registry period code as a string (e.g.
"1T").Use this when calling registry APIs that expect the bare
domain.calculations.registry.schema_scalars.PeriodCodetoken rather than a structuredPeriod.
- property standard_code: StandardPeriodCode | None¶
Return the
StandardPeriodCodemember, orNonefor extended forms.
- property quarter_ordinal: int | None¶
Return the standard-quarter ordinal, or
Nonefor every non-quarter period.Only the ordinary
1Tthrough4Tregistry tokens are quarterly. Extended OSS/IOSS tokens such asEXT-1Tretain their extended cadence and therefore do not acquire a quarter ordinal.
- property kind: PeriodKind¶
Return the cadence class derived from the period code.
- has_date_span()[source]¶
Return whether the period maps to an inclusive calendar date span.
Quarterly, monthly, and annual periods cover a contiguous span of calendar dates. Instalment claves (
1P-4P) and the extended union members are filing/payment events, not calendar spans, so they returnFalseandstart_date/end_daterefuse for them.- Return type:
- property start_date: date¶
Return the inclusive first calendar date of the period.
- Raises:
PeriodError – When the period has no calendar span (
has_date_span()isFalse).
- property end_date: date¶
Return the inclusive last calendar date of the period.
- Raises:
PeriodError – When the period has no calendar span (
has_date_span()isFalse).
- contains(value)[source]¶
Return whether
valuefalls within this period’s inclusive span.- Raises:
PeriodError – When the period has no calendar span.
- Return type:
- Parameters:
value (date)