import json from dataclasses import dataclass, field from pathlib import Path from cashflow_model.account import Account from cashflow_model.asset import Asset from cashflow_model.liability import Liability from cashflow_model.recurring import RecurringCashflow from cashflow_model.scenario import ForecastScenario from cashflow_model.transaction import Transaction @dataclass class FinancialModel: accounts: list[Account] = field(default_factory=list) transactions: list[Transaction] = field(default_factory=list) recurring: list[RecurringCashflow] = field(default_factory=list) assets: list[Asset] = field(default_factory=list) liabilities: list[Liability] = field(default_factory=list) scenarios: list[ForecastScenario] = field(default_factory=list) def to_dict(self) -> dict: return { "accounts": [a.to_dict() for a in self.accounts], "transactions": [t.to_dict() for t in self.transactions], "recurring": [r.to_dict() for r in self.recurring], "assets": [a.to_dict() for a in self.assets], "liabilities": [li.to_dict() for li in self.liabilities], "scenarios": [s.to_dict() for s in self.scenarios], } @classmethod def from_dict(cls, data: dict) -> "FinancialModel": return cls( accounts=[Account.from_dict(a) for a in data.get("accounts", [])], transactions=[Transaction.from_dict(t) for t in data.get("transactions", [])], recurring=[RecurringCashflow.from_dict(r) for r in data.get("recurring", [])], assets=[Asset.from_dict(a) for a in data.get("assets", [])], liabilities=[Liability.from_dict(li) for li in data.get("liabilities", [])], scenarios=[ForecastScenario.from_dict(s) for s in data.get("scenarios", [])], ) def save(self, path: str | Path) -> None: path = Path(path) path.parent.mkdir(parents=True, exist_ok=True) with open(path, "w", encoding="utf-8") as f: json.dump(self.to_dict(), f, indent=2, ensure_ascii=False) @classmethod def load(cls, path: str | Path) -> "FinancialModel": path = Path(path) with open(path, "r", encoding="utf-8") as f: data = json.load(f) return cls.from_dict(data)