SPB Git

spb/air Public MIT

AIR — The Language of Accounting.

Python 100%
2.8 KB · 82 lines python
Raw Blame History
1# =============================================================================2# Projet : AIR — Accounting Intermediate Representation3# Auteur : Simon-Pierre Boucher4# Contact : contact@spboucher.ai5# Fichier : unit.py6# Description : CompilationUnit — the mutable state threaded through AIC passes.7# =============================================================================8"""The compilation unit: AIR document in, journal entries out.910Passes read the immutable AIR events and accumulate derived state here11(subtotals, tax lines, FX conversions, classifications), all anchored in the12provenance graph. The pass manager verifies the double-entry invariant on13`entries` after every pass.14"""15from __future__ import annotations1617from dataclasses import dataclass, field1819from aic.diagnostics import Diagnostic20from alsl.model import PolicySet21from core.events import AirDocument, EconomicEvent22from core.journal import JournalEntry23from core.money import Money24from core.provenance import ProvenanceGraph252627@dataclass28class TaxLineState:29    """A computed tax amount for one event (transaction currency)."""3031    code: str32    amount: Money33    node_id: str34    payable_role: str35    receivable_role: str36    recoverable: bool37    policy: str                       # name of the ALSL policy that produced it383940@dataclass41class EventState:42    """Everything the passes derive for a single event."""4344    # transaction-currency amounts45    subtotal: Money | None = None46    subtotal_node: str | None = None47    taxes: list[TaxLineState] = field(default_factory=list)4849    # classification (purchases): account role for the debit side50    classify_as: str | None = None          # "asset" | "expense"51    classification_role: str | None = None52    classification_policy: str | None = None5354    # functional-currency amounts, ready for posting (set by the FX pass)55    post_subtotal: Money | None = None56    post_subtotal_node: str | None = None57    post_taxes: list[TaxLineState] = field(default_factory=list)5859    # settlement FX difference (payments): + = more functional units than booked60    fx_diff: Money | None = None61    fx_diff_node: str | None = None62    booked_amount: Money | None = None      # functional value at booking rate636465@dataclass66class CompilationUnit:67    document: AirDocument68    policies: PolicySet69    provenance: ProvenanceGraph = field(default_factory=ProvenanceGraph)70    state: dict[str, EventState] = field(default_factory=dict)71    entries: list[JournalEntry] = field(default_factory=list)72    diagnostics: list[Diagnostic] = field(default_factory=list)7374    def event_state(self, event_id: str) -> EventState:75        return self.state.setdefault(event_id, EventState())7677    def find_event(self, event_id: str) -> EconomicEvent | None:78        for event in self.document.events:79            if event.id == event_id:80                return event81        return None82