cadrumo.application.ledger.evidence_reference module

The one definition of what a transaction’s evidence reference may name.

purchase_invoice_evidence_id addresses TWO bucket-scoped id spaces, and this module is the single place that says so, in what order they are consulted, and which outcomes are acceptable:

  1. A PurchaseInvoiceEvidence record minted by aeat app ledger evidence add – a registered PDF/image whose bytes live in the encrypted attachment store. This is the only space that can supply document BYTES, so it is the only one an on-host reader can extract from.

  2. An imported received-invoice id in the rich InvoiceCatalogue – bucket-matched and RECEIVED. This space carries the fiscal TOTALS a calculation can fold in, but no bytes.

The PIE space is consulted first, so an id minted by evidence add is accepted by aeat app ledger attach in the same shell session. Ids minted by aeat app ledger invoice add (slim operator invoice records) are deliberately in neither space and resolve as EvidenceReferenceOutcome.UNRESOLVED.

Every consumer of the field MUST route its decision through classify_evidence_reference() (when it holds both lookups) or find_bytes_bearing_evidence_record() (when it only needs the bytes-bearing half), so that no call site re-derives which space an id belongs to. Re-deriving it is how two readers came to disagree: one resolved only the invoice catalogue and reported a valid evidence record as “absent”, the other resolved only the evidence store and raised “not found” for a valid invoice id.

This module holds no adapter dependency on purpose: it takes the loaded records and catalogue as arguments so it stays a pure decision surface, testable without storage.

class EvidenceReferenceOutcome(*values)[source]

Bases: StrEnum

Closed taxonomy of what an evidence reference resolved to.

Variables:
  • PURCHASE_INVOICE_EVIDENCE – A registered evidence record; carries document bytes.

  • CATALOGUE_INVOICE – A bucket-matched received catalogue invoice; carries fiscal totals but no bytes.

  • UNRESOLVED – The id names neither space.

  • INVOICE_OUTSIDE_BUCKET – A catalogue invoice exists but belongs to another bucket.

  • INVOICE_WRONG_KIND – A catalogue invoice exists but is not RECEIVED, so it cannot stand as purchase evidence.

PURCHASE_INVOICE_EVIDENCE
CATALOGUE_INVOICE
UNRESOLVED
INVOICE_OUTSIDE_BUCKET
INVOICE_WRONG_KIND
ACCEPTABLE_EVIDENCE_REFERENCE_OUTCOMES

Outcomes that make the reference usable as purchase evidence for the bucket.

class EvidenceReference(**data)[source]

Bases: BaseModel

One resolved evidence reference: the outcome plus whichever record backs it.

Parameters:

data (Any)

evidence_id: str
outcome: EvidenceReferenceOutcome
record: PurchaseInvoiceEvidence | None
invoice: Invoice | None
property is_acceptable: bool

Whether the reference is usable as purchase evidence for its bucket.

classify_evidence_reference(evidence_id, *, bucket_id, evidence_records, invoices)[source]

Resolve one purchase_invoice_evidence_id against both id spaces.

Consults the evidence-record space first, then the invoice catalogue, and applies the bucket-ownership and RECEIVED-kind policy to an invoice hit. Never raises for an unusable reference: the caller decides how to report the outcome, so a write gate can refuse while a read path can degrade.

Parameters:
Returns:

The outcome plus whichever record backs it.

Return type:

EvidenceReference

find_bytes_bearing_evidence_record(evidence_id, *, evidence_records)[source]

Return the evidence record backing evidence_id, or None.

The bytes-bearing half of classify_evidence_reference(), for a reader that needs document bytes and holds no invoice catalogue. None does NOT mean the reference is invalid – it may be a legitimate catalogue-invoice id, which simply has no document behind it (see this module’s docstring). A reader that must refuse should use refuse_reference_without_document_bytes() so the operator is told which of the two spaces the id landed in.

Parameters:
Return type:

PurchaseInvoiceEvidence | None

Returns:

The matching PurchaseInvoiceEvidence, or None when the id is not in the evidence-record space.

refuse_reference_without_document_bytes(evidence_id)[source]

Build the refusal for a reference that resolves outside the bytes-bearing space.

Worded once, here, so every on-host reader names the same remedy. Use this when the reference is (or may be) a legitimate catalogue-invoice id: it is a VALID evidence reference that simply holds fiscal totals rather than a document, so the operator must not be told their id does not exist. A caller that has established the id names nothing at all should raise refuse_unresolved_evidence_reference() instead, which is more specific.

Parameters:

evidence_id (str) – The reference that could not supply bytes.

Return type:

PurchaseInvoiceEvidenceInputError

Returns:

The typed error for the caller to raise.

refuse_unresolved_evidence_reference(evidence_id)[source]

Build the refusal for a reference that names nothing in either id space.

Only for EvidenceReferenceOutcome.UNRESOLVED, which a caller can establish only by consulting BOTH spaces. It is the more pointed of the two refusals – a typo’d id gets “no such record” rather than an explanation of the invoice space – so a caller that consulted only the evidence-record half must not raise it.

Parameters:

evidence_id (str) – The reference that resolved to neither space.

Return type:

PurchaseInvoiceEvidenceNotFoundError

Returns:

The typed error for the caller to raise.