aeat.domain.prorrata_register package¶
Per-ejercicio cross-period IVA prorrata register (LIVA arts. 102-106).
The provisional-to-definitive IVA prorrata lifecycle is inherently cross-year: under prorrata general only the deduction percentage of soportado is deductible in each liquidation period (art. 104.Uno); the percentage provisionally applicable each year is the prior year’s definitive (art. 105.Uno), with the regulated alternatives of an AEAT-authorised provisional (art. 105.Dos) and the inicio-de-actividades proposed percentage (art. 105.Tres via art. 111.Dos); the last liquidation of the year computes the definitive prorrata from the year’s actual operations and regularises the provisional deductions (art. 105.Cuatro).
This module is the CARRY HOME for that lifecycle: a durable per-ejercicio
ProrrataRegister, one ProrrataRegisterEntry per
(ejercicio, sector) carrying the regime, the provisional percentage in force
with its regulated ProrrataProvisionalProvenance, and — once
settled — the definitive percentage with the annual volume inputs it derived
from. The pure precedence-ladder resolver
(resolve_provisional_percentage()) selects the in-force provisional
percentage among candidate provenances (authorised/inicio outranking the carried
prior definitive) and returns a visible unresolved state rather than any
fabricated default — no percentage is ever assumed.
This is a taxpayer-fact store, sibling to domain.bienes_inversion: it
holds the per-ejercicio percentages and their provenance, never the regulatory
constants. The prorrata compute substrate (domain.iva:
compute_prorrata_definitiva_anual, compute_regularizacion_prorrata_anual)
is consumed at settlement, not re-implemented here, and this module reads no
secure-object store — the seed, in-year apportionment, and settlement write-back
live in the application layer.
See also
adapters.persistence.profile.prorrata_registerFINANCIAL secure-object repository that stores the register singleton.
domain.ivaLegal prorrata substrate that computes the definitive percentage from annual volumes and the art. 105.Cuatro regularisation cuota.
domain.bienes_inversionSibling per-taxpayer-fact register whose shape this mirrors.
- exception ProrrataRegisterError(message=None, *, context=None, suggestion=None, translated_message=None)[source]¶
Bases:
AeatErrorRaised when a prorrata-register record is structurally invalid.
- Parameters:
- Return type:
None
- code: ClassVar[ErrorCode]¶
- exception ProrrataRegisterValidationError(message=None, *, context=None, suggestion=None, translated_message=None)[source]¶
Bases:
ProrrataRegisterError,ValueErrorRaised when a prorrata-register model fails Pydantic validation.
- Parameters:
- Return type:
None
- code: ClassVar[ErrorCode]¶
- PRORRATA_REGISTER_SCHEMA_VERSION¶
Forward-compatible schema version stamped onto every record in this module.
- class SectorDefinition(**data)[source]¶
Bases:
BaseModelOne operator-declared differentiated sector (LIVA arts. 9.1.c / 101).
Strict, frozen, no extra fields. The art. 9.1.c partition of a taxpayer’s activities into differentiated sectors is a legal judgment the ledger cannot infer (which CNAE groups are run, whether their prorrata percentages diverge by more than 50 percentage points, whether a special-regime activity is present), so it is operator-declared: each sector carries a stable
sector_id(the key the register entries and the ledger rows reference), the member activity codes it groups, and theSectorDiferenciadoLetrathat makes it differentiated. Fail-closed: a register with no sector definitions is a whole-entity register (sector_id = Nonethroughout), the landed cross-period behaviour, never a silently inferred partition.- Variables:
sector_id – Stable identifier the register entries and ledger rows reference. Must match the
sector_idon the per-sectorProrrataRegisterEntryrows.letra – The
SectorDiferenciadoLetra(art. 9.1.c letra a’/b’/c’/d’) on which this sector is differentiated.member_activity_codes – The CNAE / IAE-epígrafe activity codes grouped into this sector. Non-empty: a declared sector groups at least one activity. Recorded for provenance and operator audit; the per-sector routing keys on
sector_id, never on these codes.
- Parameters:
sector_id (str)
letra (SectorDiferenciadoLetra)
- sector_id: str¶
- letra: SectorDiferenciadoLetra¶
- member_activity_codes: tuple[str, ...]¶
- class ProrrataRegisterEntry(**data)[source]¶
Bases:
BaseModelOne
(ejercicio, sector)entry in the cross-period prorrata register.Strict, frozen, no extra fields. Carries the regime in force, the provisional percentage with its regulated provenance (and, for the referenced provenances, its authorisation/proposal reference), and — populated only at settlement — the definitive percentage with the annual volume inputs it derived from. The provisional, referenced, and settlement field groups each travel together (present or absent as a unit), enforced by
_validate_field_coupling().- Variables:
ejercicio – Filing year the entry covers.
regime –
ProrrataRegisterRegimein force for the ejercicio.sector_id – Sector identifier for a sectores-diferenciados register, or
Nonefor the whole-entity register. Present from birth so sectores land without migration; the per-sector compute is deferred.interrupted – The art. 105.Cinco “sin operaciones” marker —
Truewhen the taxpayer (or the differentiated sector) performed no operations during the ejercicio. Distinct from theningunaregime (an active year under no prorrata): an interrupted year is inactive. An interrupted entry carries no provisional or definitive percentage and no volume inputs; the three-active-years seed walk skips it. The register thereby retains a truthful active/inactive history.provisional_percentage – The provisional deduction percentage (0-100) in force during the year’s liquidations (art. 104.Uno + 105.Uno), or
Nonewhen no percentage has resolved yet (never a fabricated default).provisional_provenance – The
ProrrataProvisionalProvenancethe provisional percentage came from. Present iffprovisional_percentageis present.authorisation_reference – The AEAT authorisation (art. 105.Dos) or inicio-de-actividades proposal (art. 105.Tres) reference. Required iff
provisional_provenanceis a referenced provenance; forbidden otherwise.definitive_percentage – The definitive deduction percentage (0-100) computed at settlement from the annual volumes (art. 105.Cuatro), or
Nonebefore settlement.definitive_volume_con_derecho – The annual con-derecho operations volume the definitive percentage derived from. Present iff
definitive_percentageis present.definitive_volume_sin_derecho – The annual sin-derecho operations volume the definitive percentage derived from. Present iff
definitive_percentageis present.source_observation_ref – The prior settlement observation identity a
carried_prior_definitivaentry was seeded from, so the register stays cross-checkable against the prior filing. Permitted only for the carried provenance.schema_version – Forward-compatible schema version.
"1".
- Parameters:
ejercicio (int)
regime (ProrrataRegisterRegime)
sector_id (str | None)
interrupted (bool)
provisional_percentage (Decimal | None)
provisional_provenance (ProrrataProvisionalProvenance | None)
authorisation_reference (str | None)
definitive_percentage (Decimal | None)
definitive_volume_con_derecho (Decimal | None)
definitive_volume_sin_derecho (Decimal | None)
source_observation_ref (str | None)
schema_version (str)
- ejercicio: int¶
- regime: ProrrataRegisterRegime¶
- sector_id: str | None¶
- interrupted: bool¶
- provisional_percentage: Decimal | None¶
- provisional_provenance: ProrrataProvisionalProvenance | None¶
- authorisation_reference: str | None¶
- definitive_percentage: Decimal | None¶
- definitive_volume_con_derecho: Decimal | None¶
- definitive_volume_sin_derecho: Decimal | None¶
- source_observation_ref: str | None¶
- schema_version: str¶
- class ProrrataProvisionalResolution(**data)[source]¶
Bases:
BaseModelOutcome of the precedence-ladder resolution of the in-force provisional percentage.
- Variables:
percentage – The in-force provisional deduction percentage (0-100), or
Nonewhen the ladder resolved no value (the visible unresolved state — the caller surfaces an advisory, never a silent default).provenance – The winning
ProrrataProvisionalProvenance, orNonewhen unresolved.
- Parameters:
percentage (Decimal | None)
provenance (ProrrataProvisionalProvenance | None)
- percentage: Decimal | None¶
- provenance: ProrrataProvisionalProvenance | None¶
- resolve_provisional_percentage(candidates)[source]¶
Resolve the in-force provisional percentage among candidate entries by the LIVA art. 105 ladder.
Applies the single declared precedence ladder (
_PROVENANCE_PRECEDENCE): an AEAT-authorised (art. 105.Dos) or inicio-de-actividades (art. 105.Tres) provisional percentage outranks the carried prior definitive (art. 105.Uno). Only candidates that actually carry a provisional percentage participate; a candidate recording a regime but no percentage does not contribute a value. When no candidate carries a percentage the result is the visible unresolved state (both fieldsNone) — never a fabricated default.- Parameters:
candidates (
Iterable[ProrrataRegisterEntry]) – Register entries to resolve among. In the normal register this is the (at most one) entry for a(ejercicio, sector)key; the seeding/override recording path supplies several provenance candidates.- Return type:
- Returns:
A
ProrrataProvisionalResolutionnaming the winning percentage and provenance, or bothNonewhen unresolved.
- class ThreeActiveYearsAggregate(**data)[source]¶
Bases:
BaseModelAggregated volume inputs of the last three ACTIVE años naturales (LIVA art. 105.Cinco).
The art. 105.Cinco interrupted-activity rule seeds a resumed ejercicio from the percentage that “globalmente corresponda al conjunto de los tres últimos años naturales en que se hubiesen realizado operaciones”: a GLOBAL percentage over the AGGREGATE volumes of the last three active years, not the average of their three definitive percentages. This carrier holds those summed volumes and the contributing ejercicios (newest-first).
sufficientisTrueonly when a full three active years were found; with fewer, the application seed surfaces an advisory rather than assuming a percentage.- Variables:
contributing_ejercicios – The active ejercicios whose volumes were summed, newest first (at most three).
summed_volume_con_derecho – Sum of the contributing years’ annual con-derecho operation volumes.
summed_volume_sin_derecho – Sum of the contributing years’ annual sin-derecho operation volumes.
- Parameters:
- contributing_ejercicios: tuple[int, ...]¶
- summed_volume_con_derecho: Decimal¶
- summed_volume_sin_derecho: Decimal¶
- class ProrrataRegister(**data)[source]¶
Bases:
BaseModelEncrypted JSON document holding the per-ejercicio prorrata register.
Holds one
ProrrataRegisterEntryper(ejercicio, sector_id)key; a duplicate key is rejected at construction. The regime and sector axes are present from birth so prorrata especial and sectores diferenciados land without a schema migration (no-legacy-compatibility).- Variables:
schema_version – Forward-compatible schema version.
"1".entries – Tuple of
ProrrataRegisterEntryrows.sector_definitions – The operator-declared differentiated-sector partition (LIVA arts. 9.1.c / 101). Empty for a whole-entity register — the fail-closed default; when non-empty every per-sector
ProrrataRegisterEntrysector_idand every sectored ledger row references one of these declared sectors.
- Parameters:
schema_version (str)
entries (tuple[ProrrataRegisterEntry, ...])
sector_definitions (tuple[SectorDefinition, ...])
- schema_version: str¶
- entries: tuple[ProrrataRegisterEntry, ...]¶
- sector_definitions: tuple[SectorDefinition, ...]¶
- property is_sectorized: bool¶
Whether the register declares a differentiated-sector partition.
Fail-closed:
False(whole-entity) when no sector definition exists, so a taxpayer with no declared partition keeps the landed cross-period behaviour byte-identical.
- sector_definition_for(sector_id)[source]¶
Return the declared
SectorDefinitionforsector_id, orNone.- Return type:
- Parameters:
sector_id (str)
- entries_for_ejercicio(ejercicio)[source]¶
Return every entry recorded for
ejercicioacross all sectors.- Return type:
- Parameters:
ejercicio (int)
- entry_for(ejercicio, *, sector_id=None)[source]¶
Return the entry for a
(ejercicio, sector_id)key, orNonewhen absent.- Return type:
- Parameters:
- resolve_provisional(ejercicio, *, sector_id=None)[source]¶
Resolve the in-force provisional percentage for a
(ejercicio, sector_id)key.Filters the register to the key’s entry and applies
resolve_provisional_percentage(), returning the visible unresolved state when no percentage is recorded.- Return type:
- Parameters:
- collect_last_three_active_years(*, before_ejercicio, sector_id=None)[source]¶
Aggregate the volume inputs of the last three ACTIVE años naturales (LIVA art. 105.Cinco).
Walks the register backward from
before_ejerciciofor the givensector_id, SKIPPING interrupted (sin operaciones) years and any year that has not settled (no definitive volumes), and sums the con-derecho and sin-derecho volume inputs of the last three active años naturales. An “active” year is a settled, non-interrupted entry; the walk is over active years, not calendar years, so the interruption gap is skipped.Returns a
ThreeActiveYearsAggregatewhosesufficientisTrueonly when three active years contributed; the application seed turns an insufficient aggregate into a visible advisory rather than assuming a percentage.- Return type:
- Parameters: