dodil/erp-brick-ar
DODIL ERP brick: accounts receivable
src/brick_ar/domain/readiness.py
"""Readiness (shared.yaml conventions.readiness): every gate of a transition as {gate, met, reason, fix}.
`met` is computed at read time; `reason` says why not in the customer's words; `fix` names the action (and who can take it).
"""
from dataclasses import asdict, dataclass
from brick_ar.domain.errors import RuleBroken
@dataclass(frozen=True)
class Gate:
gate: str
met: bool
reason: str
fix: str
def as_dict(self) -> dict:
return asdict(self)
def met(gate: str) -> Gate:
return Gate(gate, True, "", "")
def unmet(gate: str, reason: str, fix: str) -> Gate:
return Gate(gate, False, reason, fix)
class GatesUnmet(RuleBroken):
"""A transition refused because gates are unmet: the words are the gates' own, the list is kept for the screen."""
def __init__(self, what: str, gates):
self.gates = [g.as_dict() for g in gates if not g.met]
super().__init__(f"cannot {what}: " + "; ".join(f"[{g['gate']}] {g['reason']} (fix: {g['fix']})" for g in self.gates))
def require(what: str, gates) -> None:
if any(not g.met for g in gates):
raise GatesUnmet(what, gates)