aeat.application.live._justificante module¶
Application-live persistence for captured AEAT justificante receipts.
The live justificante pull retrieves the authentic, AEAT-signed
justificante de presentación PDF for a filed work unit through the
read-only sede surface (capture_justificante →
SedeCapture) and persists it
as a bucket-scoped, content-addressed secure object. The persisted
artefact is the durable, official evidence the local reconciler reads —
the operator no longer hand-downloads the receipt.
This service is a stateful SnapshotService sibling of the
Modelo 100 borrador service: it keys supersession on the
(modelo, filing_year, period) axis so a re-filed period’s fresh
capture supersedes the prior ACTIVE one, and it persists each snapshot
through a SecureObjectRepository
at FINANCIAL sensitivity under
aeat.adapters.persistence.storage.LIVE_JUSTIFICANTE_CAPTURE_SNAPSHOT_NAMESPACE,
and records each capture as a lifecycle event via
BucketEventHistoryRepository.
The captured PDF bytes ride inside the encrypted snapshot Envelope
as a base64 str (binary cannot survive the JSON envelope verbatim); the
raw-bytes pdf_sha256 is the content address used for snapshot-id
derivation and dedup.
See also
aeat.application.livePublic read-only live facade that orchestrates capture and reports
JustificanteCaptureOutcome.aeat.application.live._filed_observation_persistence.enroll_filed_justificante_evidence()Filed-history path that performs the same metadata registration and current-record evidence stamping from declaration-register artefacts.
aeat.application.overviewCalendar projection that reads
JustificanteCaptureSnapshotrows and matching domain justificante metadata as AEAT-side evidence.aeat.application.live._snapshot_base.SecureSnapshotRepositoryShared encrypted snapshot repository used by this bucket-scoped capture repository.
ModeloRecordLocal filing record stamped with live
ExternalEvidenceonly after the receipt matches the current filing axis.
- exception JustificanteCaptureSnapshotNotFoundError(message=None, *, context=None, suggestion=None, translated_message=None)[source]¶
Bases:
SnapshotNotFoundErrorRaised when a live justificante-capture snapshot lookup misses by id.
- Parameters:
- Return type:
None
- code: ClassVar[ErrorCode]¶
- class JustificanteCaptureSnapshot(**data)[source]¶
Bases:
BaseModelOne live-captured AEAT justificante receipt persisted for a bucket.
Bundles the work-unit axis (
modelo/filing_year/period), the sede provenance (expediente_id/csv), the content address (pdf_sha256over the raw bytes), and the receipt itself (pdf_base64). The officialsource_kindrecords that the receipt came from an authenticated live capture.- Parameters:
snapshot_id (str)
bucket_id (Annotated[str, StringConstraints(strip_whitespace=True, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=128, pattern=None, ascii_only=None)])
modelo (str)
filing_year (int)
period (Period)
expediente_id (str)
csv (str)
pdf_sha256 (str)
pdf_base64 (str)
source_kind (str)
captured_at (datetime)
state (SnapshotLifecycleState)
superseded_by_snapshot_id (str | None)
discarded_at (datetime | None)
discarded_by (str)
discard_reason (str)
- snapshot_id: str¶
- bucket_id: BucketId¶
- modelo: str¶
- filing_year: int¶
- period: Period¶
- expediente_id: str¶
- csv: str¶
- pdf_sha256: str¶
- pdf_base64: str¶
- source_kind: str¶
- captured_at: datetime¶
- state: SnapshotLifecycleState¶
- superseded_by_snapshot_id: str | None¶
- discarded_at: datetime | None¶
- discarded_by: str¶
- discard_reason: str¶
- decoded_pdf_bytes()[source]¶
Return the raw PDF bytes decoded from
pdf_base64.- Return type:
- justificante_capture_snapshot_object_key(bucket_id, snapshot_id)[source]¶
Return the secure-object key for one bucket’s justificante-capture snapshot.
The key shape is the object-key grammar declared by
aeat.adapters.persistence.storage.LIVE_JUSTIFICANTE_CAPTURE_SNAPSHOT_NAMESPACE.
- derive_justificante_capture_snapshot_id(*, modelo, filing_year, period, pdf_sha256)[source]¶
Return the content-addressed id for one justificante capture.
The id is derived from the work-unit axis plus the raw-PDF content address, so re-capturing the identical receipt is idempotent while a re-filed period (a different signed PDF) yields a new id that supersedes the prior ACTIVE snapshot on the same axis.
- resolve_period_expediente(*, declarations, expedientes, modelo, period)[source]¶
Resolve the capturable expediente for one
(modelo, period)filing.The procedure-tree
Expedientecarries no period, so for a multi-period modelo (quarterly 1T-4T) it cannot disambiguate which quarter’s receipt to pull. The period-bearing surface is the filed declarations register (Declaracioncarriesperiodandexpediente_id). This resolver picks the declaration matching the target(modelo, period)(the latest filing for that period when a period was re-filed), then cross-references itsexpediente_idagainst the tree to return the capturable expediente. It NEVER returns a different period’s expediente: a missing or unmatched declaration raises rather than falling back to a wrong-quarter receipt.The within-period tiebreak ranks the accepted (
ALTA) declaration ahead ofpresented_at, matching the two sibling period-resolution surfaces (latest_declarations_by_periodand the sede walker’s latest-selection), so a later cancellation / correction row (a non-ALTAestadosuch asAnuladaorBaja) presented after the accepted filing does not win and pull the wrong-state receipt.- Raises:
LiveApplicationInputError – when no declaration matches the requested period, or the matched declaration’s expediente is absent from the tree.
- Return type:
- Parameters:
declarations (Sequence[Declaracion])
expedientes (Sequence[Expediente])
modelo (str)
period (Period)
- class JustificanteCaptureSnapshotRepository(*, bucket_id, objects=None)[source]¶
Bases:
objectSecure-DB repository for captured justificante snapshots in one bucket.
Composes the shared
SecureSnapshotRepositoryfor the read surface (load / resolve / list / exists), preserving the class identity,JustificanteCaptureSnapshotNotFoundErrormessages, and thecaptured_atlist ordering.saveis kept local because justificante stamps the envelopewritten_atwith the capture time (notnow()), a deliberate divergence from the shared base.The namespace, sensitivity, schema version, and key grammar come from
aeat.adapters.persistence.storage.LIVE_JUSTIFICANTE_CAPTURE_SNAPSHOT_NAMESPACE. EachJustificanteCaptureSnapshotis written through anEnvelopeso the captured PDF, CSV, and expediente metadata stay inside the encryptedSecureObjectRepositorybucket store.- Parameters:
bucket_id (str)
objects (SecureObjectRepository | None)
- save(snapshot)[source]¶
- Return type:
- Parameters:
snapshot (JustificanteCaptureSnapshot)
- class JustificanteCaptureSnapshotService(*, bucket_id, repository=None)[source]¶
Bases:
SnapshotService[JustificanteCaptureSnapshot]Canonical backend service for bucket-scoped live justificante captures.
- Parameters:
bucket_id (str)
repository (JustificanteCaptureSnapshotRepository | None)
- capture(*, modelo, filing_year, period, expediente_id, csv, pdf_bytes, pdf_sha256, captured_at)[source]¶
Persist one captured justificante and return the ACTIVE
JustificanteCaptureSnapshot.Idempotent on the receipt content address: re-capturing the same signed PDF returns the existing snapshot. A re-filed period (a new signed PDF) supersedes the prior ACTIVE snapshot on the
(modelo, filing_year, period)axis.
- list_snapshots(*, filing_year=None, state=SnapshotLifecycleState.ACTIVE)[source]¶
- Return type:
- Parameters:
filing_year (int | None)
state (SnapshotLifecycleState | None)
- parse_capture_to_justificante(snapshot)[source]¶
Parse a persisted capture’s PDF into a strict domain
Justificante.Reads the encrypted snapshot’s bytes in memory and runs the inbound parser. Used to register the captured receipt as official filing evidence and to reconcile against it.
- Return type:
- Parameters:
snapshot (JustificanteCaptureSnapshot)
- register_capture_justificante_metadata(*, snapshot)[source]¶
Persist parsed justificante metadata for a live capture.
This records the official AEAT receipt metadata even when the local app has no current
ModeloRecordfor the period. It does not stamp or create a local filing row; that remains owned byregister_capture_as_filing_evidence().Returns the persisted
Justificante, orNonewhen the captured snapshot cannot be parsed into one.- Return type:
- Parameters:
snapshot (JustificanteCaptureSnapshot)
- reconcile_capture(*, work_unit_id, snapshot, actor='operator')[source]¶
Reconcile a work unit against a persisted live capture.
Reads the captured PDF from secure storage into memory and delegates to the existing local-only reconciler; the reconciler never contacts AEAT and never writes the plaintext receipt to disk. This is the live-sourced equivalent of the operator hand-passing a downloaded justificante via the local
reconcile file --file PATHsurface.- Return type:
- Returns:
A
ModeloReconciliationReportfor the in-memory receipt comparison.- Parameters:
work_unit_id (str)
snapshot (JustificanteCaptureSnapshot)
actor (str)
- register_capture_as_filing_evidence(*, snapshot)[source]¶
Stamp a persisted live capture as official evidence on its filing record.
Loads the work unit’s current filing record first; with one present, parses the captured receipt into a domain
Justificante(keyed by the capture’s CSV, which is the gate’s evidence reference), registers it, and updates the filing record to carryAEAT_LIVE_CAPTUREexternal evidence referencing it. After this, the cross-period clean-state gate’sMISSING_JUSTIFICANTE_VERIFICATIONblocker clears for the period, becauseaeat_live_captureis a justificante-verified evidence kind and the referenced justificante record loads. Emits aMODELO_LIVE_EVIDENCE_STAMPEDbucket event recording the action.Returns the stamped
ModeloRecord.- Raises:
LiveApplicationInputError – when no current filing record exists for the captured
(modelo, filing_year, period)— the operator must file the period before attaching live-capture evidence to it.- Return type:
- Parameters:
snapshot (JustificanteCaptureSnapshot)
- stamp_capture_evidence_if_filed(snapshot)[source]¶
Best-effort variant of
register_capture_as_filing_evidence().Returns the stamped
ModeloRecordwhen the captured period has a current filing record, orNonewhen none exists yet (the snapshot is still persisted; the operator can stamp later by filing the period, then re-capturing) or the captured PDF is not parseable into a justificante. Used by the capture orchestrator so a capture of a period not yet filed in-app does not fail. A present-but-conflicting local filing record is not best-effort: identity, period, modelo, and existing-evidence conflicts propagate to the caller.- Return type:
- Parameters:
snapshot (JustificanteCaptureSnapshot)