cadrumo.application.ledger.actions_manual module¶
Manual ledger transaction services and read projections.
The services build Transaction records from
ManualLedgerTransactionCommand, persist them
in a loaded TransactionCatalogue, append bucket events, and return
ManualLedgerTransactionResult values.
Evidence paths validate purchase-invoice, attachment, and
UsageRatioProfile references before
persistence.
- create_manual_transaction(command, *, ports, occurred_at=None, currency_normalizer=None)[source]¶
Persist one manual ledger transaction in the command’s bucket.
Returns a
ManualLedgerTransactionResultwith the created transaction and associated bucket event.- Return type:
- Parameters:
command (ManualLedgerTransactionCommand)
ports (LedgerActionPorts)
occurred_at (datetime | None)
currency_normalizer (CurrencyNormalizationService | None)
- attach_manual_transaction_evidence(*, bucket_id, transaction_id, actor, purchase_invoice_evidence_id=None, attachment_ids=(), source_command='aeat app ledger attach', ports, occurred_at=None)[source]¶
Attach purchase evidence or supplementary attachments to one ledger transaction.
Returns a
ManualLedgerTransactionResult.- Return type:
- Parameters:
- detach_manual_transaction_attachments(*, bucket_id, transaction_id, actor, attachment_ids, source_command='aeat app ledger detach', ports, occurred_at=None)[source]¶
Detach named supplementary attachments from one ledger transaction.
The inverse of
attach_manual_transaction_evidence()for the axis that can express it.attachment_idsis a whole-tuple patch, so the remaining ids are computed here and written as the new set – the attach path merges into the same field, and both go through the oneupdate_manual_transaction_fields()writer rather than editing the catalogue directly.PURCHASE EVIDENCE IS DELIBERATELY OUT OF SCOPE and refuses in
attach_manual_transaction_evidence()instead of being cleared here.ManualLedgerTransactionPatchcannot express the difference between “clear this field” and “leave it unchanged”:purchase_invoice_evidence_idis an optional text field whose validator normalises an empty string toNone, which is also the patch’s own “no change” value. Clearing it needs a sentinel the patch model does not have, and inventing one here – rather than deciding it once for every optional field on that model – would put a second clearing convention into the ledger command shape.Detaching does NOT delete the attachment’s bytes. The attachment is a content-addressed secure object that other transactions and finalized revisions may reference; this removes one transaction’s reference to it, and the stale-revision notices the caller already surfaces report where a finalized revision used what is now detached.
Returns a
ManualLedgerTransactionResult.- Return type:
- Parameters:
- link_manual_transaction_invoice(*, bucket_id, transaction_id, invoice_id, actor='operator', source_command='aeat app ledger link', ports, occurred_at=None)[source]¶
Establish an atomic invoice-only relationship for one ledger transaction.
This is the sole invoice-linkage writer. It resolves the transaction, enforces the invoice’s missing and cross-bucket policy up front, then delegates the bidirectional catalogue mutation and persistence to
link_invoice_transaction_repositories(). It never touches purchase evidence or attachments: evidence mutation is reserved forattach_manual_transaction_evidence(). Every rejection fires before any catalogue write, so a refused link leaves the transaction, invoice catalogue, and event history unchanged. The accepted path is equally all-or-nothing: the two catalogues and theLEDGER_TRANSACTION_INVOICE_LINKEDaudit event are co-committed in one secure-object batch, so no failure can leave one side citing the other without being cited back, and no event can record a link that did not land.Returns an
InvoiceTransactionLinkResult.- Return type:
- Parameters:
- get_manual_transaction(*, bucket_id, transaction_id, ports)[source]¶
Return one
ManualLedgerTransactionResultfrom a bucket catalogue.- Return type:
- Parameters:
bucket_id (str)
transaction_id (str)
ports (LedgerActionPorts)
- list_manual_transactions(*, bucket_id, ports, catalogue=None)[source]¶
Return every transaction in a bucket, sorted by effective date and id.
Each element is a
ManualLedgerTransactionResultfor one stored transaction.catalogueis the bucket’s already-loaded catalogue when the caller holds one; otherwise it is loaded here.Core types:
TransactionCatalogue.- Return type:
- Parameters:
bucket_id (str)
ports (LedgerActionPorts)
catalogue (TransactionCatalogue | None)
- query_ledger_review_rows(query, *, ports, catalogue=None)[source]¶
Return review rows for bucket-local ledger transactions.
Returns a
LedgerReviewQueryResult.catalogueis the query bucket’s already-loaded catalogue when the caller holds one; otherwise it is loaded here.Core types:
TransactionCatalogue.- Return type:
- Parameters:
query (LedgerReviewQuery)
ports (LedgerActionPorts)
catalogue (TransactionCatalogue | None)
- ledger_transaction_payload(transaction)[source]¶
Return the
LedgerTransactionPayloadfor one ledger transaction.- Return type:
- Parameters:
transaction (Transaction)
- ledger_transaction_review_payload(transaction)[source]¶
Return one ledger transaction projection plus derived operator review status.
Returns a
LedgerTransactionReviewPayloadwith all operator-facing fields populated from the transaction record.- Return type:
- Parameters:
transaction (Transaction)
- ledger_transaction_result_payload(result)[source]¶
Return the canonical result payload for one ledger mutation/read result.
Returns a
LedgerTransactionResultPayload.- Return type:
- Parameters:
result (ManualLedgerTransactionResult)
- ledger_transaction_tracking_payload(transaction)[source]¶
Return durable event lineage fields for one ledger transaction.
Returns a
LedgerTransactionTrackingPayload.- Return type:
- Parameters:
transaction (Transaction)
- summarize_manual_transactions(*, bucket_id, period=None, ports, catalogue=None)[source]¶
Return a read-only
LedgerStatusReportfor one bucket.cataloguelets a caller that has already loaded this bucket’s transactions summarise that exact snapshot. Reloading would cost a second decrypted read and, if a write interleaved, would describe a different instant from the rows the caller is projecting beside it.Core types:
TransactionCatalogue.- Return type:
- Parameters:
bucket_id (str)
period (Period | None)
ports (LedgerActionPorts)
catalogue (TransactionCatalogue | None)
- update_manual_transaction(*, transaction_id, command, ports, occurred_at=None, catalogue=None, _evidence_authority=False)[source]¶
Replace one manual ledger transaction from a validated command payload.
The replacement is built from
ManualLedgerTransactionCommandand saved as a newTransactionrevision._evidence_authorityis a private flag threaded only by the evidence attach authority (attach_manual_transaction_evidence()) and the evidence-driven split inheritance. When it isFalse(every generic manual-field update) the command MUST NOT changepurchase_invoice_evidence_idorattachment_ids; evidence catalogue and provenance mutation are reserved foraeat app ledger attach.catalogueis the snapshot a caller in the same action has already decrypted; nothing writes between that load and this replacement, so decrypting the whole catalogue again would only repeat the read.Returns a
ManualLedgerTransactionResult.Core types:
TransactionCatalogue.- Return type:
- Parameters:
transaction_id (str)
command (ManualLedgerTransactionCommand)
ports (LedgerActionPorts)
occurred_at (datetime | None)
catalogue (TransactionCatalogue | None)
_evidence_authority (bool)
- update_manual_transaction_fields(*, bucket_id, transaction_id, patch, actor, source_command, classified_by_override=None, reaffirm=False, ports, occurred_at=None, catalogue=None, _evidence_authority=False)[source]¶
Apply a typed field patch to one active bucket-scoped ledger transaction.
The patch is a
ManualLedgerTransactionPatchconverted into aManualLedgerTransactionCommandbefore the same replacement path used byupdate_manual_transaction().When
reaffirmisTruethe automatic re-affirmation no-op guard is bypassed and the command is forced through even if the patched fields are field-for-field identical to the stored transaction. This is the explicit operator-driven counterpart to the automatic silent no-op.catalogueis the bucketTransactionCataloguea caller in the same action has already decrypted (e.g. the CLI resolving an id prefix, orattach_manual_transaction_evidence()), passed through so the whole catalogue is not decrypted a second time. The caller must not write between its load and this call, so the view is current.Returns a
ManualLedgerTransactionResultreflecting the updated transaction state after the patch is applied.- Return type:
- Parameters:
bucket_id (str)
transaction_id (str)
patch (ManualLedgerTransactionPatch)
actor (str)
source_command (str)
classified_by_override (str | None)
reaffirm (bool)
ports (LedgerActionPorts)
occurred_at (datetime | None)
catalogue (TransactionCatalogue | None)
_evidence_authority (bool)
- command_from_patch(*, bucket_id, current, patch, actor, source_command, classified_by_override=None)¶
- Return type:
- Parameters:
bucket_id (str)
current (Transaction)
patch (ManualLedgerTransactionPatch)
actor (str)
source_command (str)
classified_by_override (str | None)
- prepare_manual_transaction_update(*, current, command, previous_transaction_id, now, currency_normalizer=None, ports)¶
Build a replacement transaction and bucket events for one in-memory edit.
Returns
Nonewhen the command is a field-for-field no-op (the caller decides whether that is an error or a skip). Verifies evidence and usage-ratio references but performs no persistence and no catalogue load - the caller owns a single load/save so a batch re-encrypts the catalogue once rather than per row (thebulk_classify_from_csvload-once/save-once contract). Lifecycle and blocking-modelo guards remain the caller’s responsibility before invoking this builder.- Return type:
tuple[Transaction,tuple[BucketEvent,...]] |None- Parameters:
current (Transaction)
command (ManualLedgerTransactionCommand)
previous_transaction_id (str)
now (datetime)
currency_normalizer (CurrencyNormalizationService | None)
ports (LedgerActionPorts)