aeat.domain.invoices._service module

Service helpers for invoice catalogues.

Exposes pure-function service operations over an InvoiceCatalogue: lookup (find_invoice(), find_unmatched()), in-memory linking (link_transaction()), reconciliation suggestions (suggest_reconciliations()), and bidirectional consistency checks (verify_link_consistency()). Operations that span both the invoice catalogue and the TransactionCatalogue accept each as an independent argument. Persisted cross-catalogue workflows belong in aeat.application.invoices.

class ReconciliationSuggestion(**data)[source]

Bases: BaseModel

Immutable suggestion emitted by the reconciliation heuristic.

Variables:
  • invoice_id – Stable invoice identifier.

  • transaction_id – Candidate transaction identifier.

  • amount_match – Whether the sign-aware amount matches within tolerance.

  • counterparty_match – Whether the counterparty name overlaps (case-insensitive substring match either direction).

  • score – Confidence in the inclusive 0..1 range.

Parameters:
  • invoice_id (str)

  • transaction_id (Annotated[str, StringConstraints(strip_whitespace=True, to_upper=None, to_lower=None, strict=None, min_length=64, max_length=64, pattern=^[0-9a-f]{64}$, ascii_only=None)])

  • amount_match (bool)

  • counterparty_match (bool)

  • score (Decimal)

invoice_id: str
transaction_id: TransactionId
amount_match: bool
counterparty_match: bool
score: Decimal
class LinkInconsistency(**data)[source]

Bases: BaseModel

Immutable record describing a one-sided link between the two catalogues.

Variables:
  • invoice_id – Identifier of the invoice involved in the bad link.

  • transaction_id – Identifier of the transaction involved.

  • direction – Which side cites the other without being cited back.

Parameters:
  • invoice_id (str)

  • transaction_id (Annotated[str, StringConstraints(strip_whitespace=True, to_upper=None, to_lower=None, strict=None, min_length=64, max_length=64, pattern=^[0-9a-f]{64}$, ascii_only=None)])

  • direction (Literal['invoice-only', 'transaction-only'])

invoice_id: str
transaction_id: TransactionId
direction: Literal['invoice-only', 'transaction-only']
find_invoice(catalogue, invoice_id)[source]

Return one invoice from a catalogue if present.

Parameters:
Return type:

Invoice | None

Returns:

The matching Invoice, or None when absent.

find_unmatched(catalogue, *, kind=None)[source]

Return the invoices that have no linked transactions yet.

Parameters:
Return type:

tuple[Invoice, ...]

Returns:

A tuple of Invoice objects whose linked_transaction_ids is empty, preserving insertion order. When kind is supplied, only invoices of that kind are returned.

Return a new catalogue with transaction_id linked to invoice_id.

Parameters:
  • catalogue (InvoiceCatalogue) – Source catalogue.

  • invoice_id (str) – Invoice identifier to update.

  • transaction_id (str) – Transaction identifier to append to the invoice’s linked_transaction_ids tuple.

Return type:

InvoiceCatalogue

Returns:

A fresh immutable InvoiceCatalogue with the updated invoice. Duplicate links are idempotent: calling this helper with an already-linked transaction returns a value-equal catalogue rather than raising.

Raises:

InvoiceLinkError – If transaction_id is not a 64-character lowercase hex digest.

suggest_reconciliations(invoices, transactions, *, amount_tolerance=Decimal('0.01'))[source]

Return auto-suggested invoice/transaction links sorted by score.

Only unlinked invoices (empty linked_transaction_ids) and transactions whose invoice_id is None are considered. Suggestions are emitted only when the amount matches within amount_tolerance. Counterparty similarity acts as a score-boost (case-insensitive substring match) but is never sufficient on its own.

Parameters:
Return type:

tuple[ReconciliationSuggestion, ...]

Returns:

Deterministic tuple of ReconciliationSuggestion objects sorted by (score desc, invoice_id asc, transaction_id asc).

Return every one-sided link between the two catalogues.

A link is invoice-only when an invoice cites a transaction that does not cite it back, and transaction-only when a transaction cites an invoice that does not cite it back.

Parameters:
Return type:

tuple[LinkInconsistency, ...]

Returns:

Deterministic tuple of LinkInconsistency items sorted by (invoice_id, transaction_id).