aeat.application.calculations._iva_compensation_history module¶
Profile-scoped IVA compensation history built from filed Modelo 303s.
Records are stored at
SensitivityClass AUDIT under
the
adapters.persistence.storage.IVA_COMPENSATION_HISTORY_NAMESPACE.
The repository exposes typed
IvaCompensationPeriodState
objects; carry-forward projection is produced by
build_iva_compensation_carry_forward_report().
Rows are written through
SecureBoundRepository, so
the namespace, schema version, and sensitivity declared by the storage registry
remain the persistence authority.
This module uses
IvaCompensationAnnualSummary
and
IvaCompensationAnnualCrossCheck
for Modelo 303-to-Modelo 390 annual cross-checking.
See also
domain.iva_compensation._carry_forwardPure FIFO lot projection and four-year review policy.
application.calculations._iva_wallet_balanceOffline balance query built from this repository.
application.calculations._iva_wallet_reconciliationWallet/local-history reconciliation consumer for Modelo 303 prior compensation.
- class IvaCompensationAnnualSummary(**data)[source]¶
Bases:
BaseModelFiled Modelo 390 annual IVA compensation summary for cross-checking.
Compared against the
IvaCompensationCarryForwardReportbuilt from Modelo 303 period states bycross_check_iva_compensation_annual_summary().- Parameters:
- taxpayer_nif: str¶
- filing_year: int¶
- expediente_id: str¶
- status: str¶
- presented_at: datetime¶
- last_period_compensation_amount: Decimal¶
- generated_not_in_last_period_amount: Decimal¶
- total_pending_amount: Decimal¶
- source_observation_key: str¶
- source_artefact_sha256: str | None¶
- class IvaCompensationAnnualCrossCheck(**data)[source]¶
Bases:
BaseModelComparison between Modelo 303 carry-forward lots and a filed Modelo 390 summary.
Carries the expected Modelo 390 annual carry fields derived by
derive_iva_compensation_year_end_carry_partition()plus any mismatchedCasillaIdvalues.- Parameters:
filing_year (int)
carry_forward_remaining_amount (Decimal)
modelo_390_total_pending_amount (Decimal)
expected_last_period_compensation_amount (Decimal)
expected_generated_not_in_last_period_amount (Decimal)
difference_amount (Decimal)
last_period_difference_amount (Decimal)
generated_not_in_last_period_difference_amount (Decimal)
matches (bool)
mismatched_casilla_ids (tuple[CasillaId, ...])
summary_source_observation_key (str)
- filing_year: int¶
- carry_forward_remaining_amount: Decimal¶
- modelo_390_total_pending_amount: Decimal¶
- expected_last_period_compensation_amount: Decimal¶
- expected_generated_not_in_last_period_amount: Decimal¶
- difference_amount: Decimal¶
- last_period_difference_amount: Decimal¶
- generated_not_in_last_period_difference_amount: Decimal¶
- matches: bool¶
- mismatched_casilla_ids: tuple[CasillaId, ...]¶
- expiry_review_states: tuple[str, ...]¶
- summary_source_observation_key: str¶
- class IvaCompensationHistoryRepository(*, bucket_id=None, objects=None, settings=None)[source]¶
Bases:
SecureBoundRepository[IvaCompensationPeriodState]Encrypted profile-local store of Modelo 303 IVA compensation history.
Persists
IvaCompensationPeriodStaterows inadapters.persistence.storage.IVA_COMPENSATION_HISTORY_NAMESPACEfor later carry-forward, balance, and reconciliation reads. TheSecureBoundRepositorybase writes those rows as encrypted AUDIT-class envelopes for active-bucket lookup.- Parameters:
bucket_id (str | None)
objects (SecureObjectRepository | None)
settings (Settings | None)
-
sensitivity:
ClassVar[SensitivityClass]¶
- payload_type¶
alias of
IvaCompensationPeriodState
- 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:
- Parameters:
payload (IvaCompensationPeriodState)
- load_period(period)[source]¶
Return latest stored state for one period.
Returns an
IvaCompensationPeriodStatewhen a record exists, orNonewhen none has been persisted for the given period.- Return type:
- Parameters:
period (Period)
- save_period(state)[source]¶
Persist latest stored state for one period.
- Return type:
- Parameters:
state (IvaCompensationPeriodState)
- list_periods()[source]¶
Return stored
IvaCompensationPeriodStaterows.The returned tuple is sorted in chronological filing order using the same period sort key consumed by the domain carry-forward projection.
- Return type:
- seed_iva_compensation_period(*, taxpayer_nif, period, amount, repository=None, seeded_at=None)[source]¶
Persist a manually declared carry-forward balance for one Modelo 303 period.
Returns an
IvaCompensationPeriodState.Intended for first-time users whose historical M303 carry-forward pre-dates the local compensation history. The seeded state is structurally identical to a filed-observation state but carries
status='seeded'and synthetic provenance so downstream diagnostics can distinguish seed from filed records.Raises
IvaCompensationSeedConflictErrorif a state already exists for the specified period — seeding must not overwrite an existing record.- Return type:
- Parameters:
taxpayer_nif (str)
period (Period)
amount (Decimal)
repository (IvaCompensationHistoryRepository | None)
seeded_at (datetime | None)
- correct_iva_compensation_period(*, taxpayer_nif, period, amount, repository=None, corrected_at=None)[source]¶
Overwrite a manually-seeded carry-forward balance for one Modelo 303 period.
Returns the corrected
IvaCompensationPeriodState.The single-writer companion of
seed_iva_compensation_period(): where seeding refuses if a record already exists, correction is the deliberate re-write path for a wrong opening compensation balance whose period pre-dates local history. It writes through the sameIvaCompensationHistoryRepository(no parallel write path), so the corrected state replaces the stored record at the same period key.The guard that a sealed (already-filed) Modelo 303 must not have its compensation basis silently changed lives one layer up, in the modelo application facade that resolves the bucket’s taxpayer and revisions; this primitive is the unguarded write the facade delegates to once that guard has passed. It refuses to fabricate a record from nothing: an absent period is a seed, not a correction, and raises
IvaCompensationSeedConflictErrorwith acorrection-on-missingmarker so the facade can surface the seed-first guidance.- Return type:
- Parameters:
taxpayer_nif (str)
period (Period)
amount (Decimal)
repository (IvaCompensationHistoryRepository | None)
corrected_at (datetime | None)
- iva_compensation_state_from_filed_observation(observation)[source]¶
Build an
IvaCompensationPeriodState.The source is a filed Modelo 303
FiledDeclaracionObservationProtocolcaptured from live or imported filed-declaration evidence.- Return type:
- Parameters:
observation (FiledDeclaracionObservationProtocol)
- iva_compensation_state_from_registry_observation(observation, *, taxpayer_nif, expediente_id, status, presented_at, source_observation_key=None, source_artefact_sha256=None)[source]¶
Build an
IvaCompensationPeriodState.The source is a registry-grounded Modelo 303
RegistryModeloObservation, usually promoted from local calculation evidence or filed-observation conversion.- Return type:
- Parameters:
- iva_compensation_annual_summary_from_filed_observation(observation)[source]¶
Build an
IvaCompensationAnnualSummary.The source is a filed Modelo 390
FiledDeclaracionObservationProtocol.iva.anual.compensacion-ultimo-periodo-97carries the final-period amount to compensate.iva.anual.compensacion-generada-ejercicio-no-97carries generated pending compensation from the exercise that is not included in the final-period annual carry id. The summary is evidence for cross-checking the Modelo 303 carry-forward projection; it is not stored as a period state.- Return type:
- Parameters:
observation (FiledDeclaracionObservationProtocol)
- cross_check_iva_compensation_annual_summary(report, summary, *, period_states=())[source]¶
Compare projections with filed evidence.
Returns an
IvaCompensationAnnualCrossCheck.The expected
iva.anual.compensacion-ultimo-periodo-97andiva.anual.compensacion-generada-ejercicio-no-97figures are derived through the SAME FIFO carry partition that drives the Modelo 390 calculation (derive_iva_compensation_year_end_carry_partition()), so the cross-check and both annual carry bindings cannot diverge: all three read one partition of the year’s pending credit.period_statesis the same tuple of filed Modelo 303 states the carry-forwardreportwas built from; it supplies the last period’s disponible that discriminates the final-period carry from the generated-not-carried amount.- Return type:
- Parameters:
report (IvaCompensationCarryForwardReport)
summary (IvaCompensationAnnualSummary)
period_states (tuple[IvaCompensationPeriodState, ...])