spb/air Public MIT
AIR — The Language of Accounting.
Python 100%
1# =============================================================================2# Projet : AIR — Accounting Intermediate Representation3# Auteur : Simon-Pierre Boucher4# Contact : contact@spboucher.ai5# Fichier : classification.py6# Description : Classification pass — applies ALSL classification policies (e.g. capitalization).7# =============================================================================8"""Classification pass.910Decides which account role receives the debit side of a Purchase11(expense vs capitalized asset) by evaluating ALSL classification policies —12e.g. "capitalize equipment purchases at or above the policy threshold".13Thresholds live in ALSL, never here.14"""15from __future__ import annotations1617from aic.diagnostics import Diagnostic, Severity18from aic.passes.base import Pass19from aic.unit import CompilationUnit20from alsl.evaluator import applicable_classifications21from core.events import EventType222324class ClassificationPass(Pass):25 name = "classification"2627 def run(self, unit: CompilationUnit) -> list[Diagnostic]:28 diags: list[Diagnostic] = []29 for event in unit.document.events:30 if event.type is not EventType.PURCHASE:31 continue32 state = unit.event_state(event.id)33 if state.subtotal is None:34 continue # validation already failed this event3536 hits = applicable_classifications(unit.policies, event, state.subtotal)37 if not hits:38 continue39 if len(hits) > 1:40 diags.append(Diagnostic(41 code="AIR-W300", severity=Severity.WARNING,42 message=(43 "multiple classification policies match: "44 + ", ".join(p.name for p in hits)45 + f"; applying '{hits[0].name}'"46 ),47 location=f"event {event.id}",48 suggestion="tighten the policies' when-clauses so at most one matches",49 origin_pass=self.name,50 ))51 policy = hits[0]52 state.classify_as = policy.classify_as53 state.classification_role = policy.account_role54 state.classification_policy = policy.name55 return diags56