aeat.application.calculations._observations_repository module

Encrypted persistence for past-filing casilla observations.

Stores RegistryModeloObservation records — (modelo, filing_year, period, casilla_values) — as encrypted audit envelopes in the SecureObjectRepository. Past-filing value rows are bound to CALCULATION_OBSERVATIONS_NAMESPACE; IVA wallet decisions are split between the latest-state IVA_WALLET_RECONCILIATION_DECISIONS_NAMESPACE and immutable IVA_WALLET_RECONCILIATION_DECISION_EVENTS_NAMESPACE namespaces. The records are the substrate read by PreviousFilingSourceResolver and RelationPrefillSourceResolver so annual modelos can roll up prior quarterlies, IVA prorrata can compute its four-year backward mean, IS BIN carryforward can replay prior-year bases imponibles negativas, and IVA regularización inversiones can apply its 5/10 year straight-line schedule.

Producers are out of scope for this module: the modelo filing flow will write here when an operator successfully files via the app, and the live-AEAT capture path will write here when justificantes are parsed. This module exposes only the typed read/write surface.

Sensitivity is SensitivityClass AUDIT — these records reconstruct exactly what was filed and so are identity-bearing tax substrate. They are stored encrypted at rest through an Envelope-wrapped repository.

The store is value-centric. Clean-state proof still has to join these rows with filing records, verification reports, and justificante evidence through evaluate_cross_period_clean_state().

class IvaWalletDecisionEnvelopePayload(**data)[source]

Bases: BaseModel

Serialisable wrapper for an IVA wallet reconciliation decision.

Parameters:

decision (IvaCompensationReconciliationDecision)

decision: IvaCompensationReconciliationDecision
observation_key_for_token(modelo, filing_year, period_token)[source]

Stable repository key for a modelo/year/raw registry-period token triple.

Censo modelos can declare non-date registry tokens such as alta or modificacion that are not valid Period codes. The encrypted observation store still keys them by the same logical triple.

Return type:

str

Parameters:
  • modelo (str)

  • filing_year (int)

  • period_token (str)

observation_key(modelo, period)[source]

Stable repository key for a (modelo, Period) pair.

Validated through safe_repository_id() so each component is constrained to the SecureObjectRepository id contract before composition.

Return type:

str

Parameters:
member_observation_key_for_token(modelo, filing_year, period_token, member_nif)[source]

Storage key for an observation keyed by a raw registry period token.

Return type:

str

Parameters:
  • modelo (str)

  • filing_year (int)

  • period_token (str)

  • member_nif (str | None)

member_observation_key(modelo, period, member_nif)[source]

Storage key for an observation, widened by a grupo member NIF when present.

When member_nif is None the key is the single-filer observation_key unchanged, so every existing consumer (the default previous_filing path, the multi-year resolver) keys identically. When set, the member NIF is appended so two members’ filings for the same (modelo, filing_year, period) persist as distinct rows — the cross-member fan-in the 353<-322 per_grupo_member aggregation enumerates and sums.

Return type:

str

Parameters:
iva_wallet_decision_key(taxpayer_nif, target_period)[source]

Opaque latest-decision key for one taxpayer and Modelo 303 target period.

Secure-object payloads are encrypted, but object keys are storage metadata. Hash the taxpayer/period tuple so the repository does not expose NIF/NIE values in cleartext database rows.

Return type:

str

Parameters:
iva_wallet_decision_event_key(decision)[source]

Opaque immutable event key for one persisted reconciliation decision.

Return type:

str

Parameters:

decision (IvaCompensationReconciliationDecision)

class CalculationObservationRepository(*, bucket_id=None, objects=None, settings=None)[source]

Bases: SecureBoundRepository[_ObservationEnvelopePayload]

Repository over encrypted SQL-backed past-filing observations.

Stores RegistryModeloObservation rows for resolve_bindings_from_local_store(), resolve_relations_from_local_store(), and evaluate_cross_period_clean_state(). It owns encrypted value history only; filing-grade source proof is assembled by the clean-state service from this repository plus filing, verification, and justificante repositories.

The repository binds each Envelope payload to CALCULATION_OBSERVATIONS_NAMESPACE through SecureBoundRepository.

Parameters:
namespace: ClassVar[str]
sensitivity: ClassVar[SensitivityClass]
schema_version: ClassVar[int]
payload_type

alias of _ObservationEnvelopePayload

extract_identifier(payload)[source]

Return the natural id for payload (used as the SQL object key).

Subclasses MUST override. The base implementation raises NotImplementedError.

Return type:

str

Parameters:

payload (_ObservationEnvelopePayload)

load_observation(modelo, period)[source]

Return the persisted observation for one (modelo, year, period token) or None.

Return type:

_ObservationEnvelopePayload | None

Parameters:
save_observation(observation, *, source_kind, captured_at=None, member_nif=None, stamped_revision_id=None, source_metadata=None)[source]

Persist observation keyed by its (modelo, filing_year, period).

member_nif is an optional grupo-de-entidades member NIF. When supplied, the storage identifier is widened (see member_observation_key()) so distinct members’ filings for the same (modelo, filing_year, period) persist as separate rows instead of overwriting — the cross-member fan-in the 353<-322 per_grupo_member aggregation enumerates. When None the single-filer key is unchanged.

stamped_revision_id is the registry revision id the source filing resolved to at capture time. Producers that hold a RegistrySnapshot MUST pass snapshot.revision.id here. If omitted, the repository resolves the law-determined revision from the observation’s (modelo, filing_year, period) before persisting.

source_metadata is source-specific encrypted provenance. It is never part of repository keys and must only contain data that belongs inside the AUDIT-class secure payload; live AEAT captures use it for register status, expediente identity, and authenticated taxpayer/member identity consumed by the cross-period clean-state proof.

Return type:

None

Parameters:
iter_modelo(modelo)[source]

Yield every persisted observation for modelo in unspecified order.

Used by grouped previous-filing and clean-state readers to enumerate all known source rows for a modelo, including member-widened keys.

Return type:

Iterator[_ObservationEnvelopePayload]

Parameters:

modelo (str)

class IvaWalletDecisionRepository(*, bucket_id=None, objects=None, settings=None)[source]

Bases: SecureBoundRepository[IvaWalletDecisionEnvelopePayload]

Repository over encrypted SQL-backed IVA wallet reconciliation decisions.

Holds one latest decision per (taxpayer_nif, target_year, target_period) triple for calculation lookup, and also writes every distinct decision to an immutable audit-event namespace. Decisions are AUDIT-class — they record the resolved gap between a taxpayer’s local IVA compensation recurrence and the live AEAT wallet, which downstream calculation chains consult through IvaWalletDecisionSourceResolver.

Latest-state rows use IVA_WALLET_RECONCILIATION_DECISIONS_NAMESPACE; immutable audit events use IVA_WALLET_RECONCILIATION_DECISION_EVENTS_NAMESPACE. Both store IvaCompensationReconciliationDecision payloads in Envelope records through SecureBoundRepository.

Parameters:
namespace: ClassVar[str]
history_namespace: ClassVar[str]
sensitivity: ClassVar[SensitivityClass]
schema_version: ClassVar[int]
payload_type

alias of IvaWalletDecisionEnvelopePayload

extract_identifier(payload)[source]

Return the natural id for payload (used as the SQL object key).

Subclasses MUST override. The base implementation raises NotImplementedError.

Return type:

str

Parameters:

payload (IvaWalletDecisionEnvelopePayload)

save_decision(decision)[source]

Persist decision to latest lookup and immutable audit history.

Return type:

None

Parameters:

decision (IvaCompensationReconciliationDecision)

load_decision(taxpayer_nif, target_period)[source]

Return the latest persisted IvaCompensationReconciliationDecision for the given period.

Return type:

IvaCompensationReconciliationDecision | None

Parameters:
list_decisions()[source]

Return the latest persisted IVA wallet decisions in target-period order.

Each element is an IvaCompensationReconciliationDecision sorted by (target_year, target_period, taxpayer_nif, decided_at).

Return type:

tuple[IvaCompensationReconciliationDecision, ...]

load_decision_history(taxpayer_nif, target_period)[source]

Return decision history for one taxpayer and target period.

Returns an immutable tuple of IvaCompensationReconciliationDecision.

Return type:

tuple[IvaCompensationReconciliationDecision, ...]

Parameters: