bootstrap
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
from cashflow_model.account import Account
|
||||
from cashflow_model.asset import Asset
|
||||
from cashflow_model.liability import Liability
|
||||
from cashflow_model.model import FinancialModel
|
||||
from cashflow_model.recurring import RecurringCashflow
|
||||
from cashflow_model.scenario import ForecastScenario
|
||||
from cashflow_model.transaction import Transaction
|
||||
|
||||
__all__ = [
|
||||
"Account",
|
||||
"Transaction",
|
||||
"RecurringCashflow",
|
||||
"Asset",
|
||||
"Liability",
|
||||
"ForecastScenario",
|
||||
"FinancialModel",
|
||||
]
|
||||
@@ -0,0 +1,27 @@
|
||||
from dataclasses import dataclass, field
|
||||
from uuid import UUID, uuid4
|
||||
|
||||
|
||||
@dataclass
|
||||
class Account:
|
||||
id: UUID = field(default_factory=uuid4)
|
||||
name: str = ""
|
||||
currency: str = "USD"
|
||||
balance: float = 0.0
|
||||
|
||||
def to_dict(self) -> dict:
|
||||
return {
|
||||
"id": str(self.id),
|
||||
"name": self.name,
|
||||
"currency": self.currency,
|
||||
"balance": self.balance,
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, data: dict) -> "Account":
|
||||
return cls(
|
||||
id=UUID(data["id"]),
|
||||
name=data["name"],
|
||||
currency=data.get("currency", "USD"),
|
||||
balance=data.get("balance", 0.0),
|
||||
)
|
||||
@@ -0,0 +1,27 @@
|
||||
from dataclasses import dataclass, field
|
||||
from uuid import UUID, uuid4
|
||||
|
||||
|
||||
@dataclass
|
||||
class Asset:
|
||||
id: UUID = field(default_factory=uuid4)
|
||||
name: str = ""
|
||||
value: float = 0.0
|
||||
growth_rate: float = 0.0
|
||||
|
||||
def to_dict(self) -> dict:
|
||||
return {
|
||||
"id": str(self.id),
|
||||
"name": self.name,
|
||||
"value": self.value,
|
||||
"growth_rate": self.growth_rate,
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, data: dict) -> "Asset":
|
||||
return cls(
|
||||
id=UUID(data["id"]),
|
||||
name=data["name"],
|
||||
value=data.get("value", 0.0),
|
||||
growth_rate=data.get("growth_rate", 0.0),
|
||||
)
|
||||
@@ -0,0 +1,30 @@
|
||||
from dataclasses import dataclass, field
|
||||
from uuid import UUID, uuid4
|
||||
|
||||
|
||||
@dataclass
|
||||
class Liability:
|
||||
id: UUID = field(default_factory=uuid4)
|
||||
name: str = ""
|
||||
balance: float = 0.0
|
||||
interest: float = 0.0
|
||||
payment: float = 0.0
|
||||
|
||||
def to_dict(self) -> dict:
|
||||
return {
|
||||
"id": str(self.id),
|
||||
"name": self.name,
|
||||
"balance": self.balance,
|
||||
"interest": self.interest,
|
||||
"payment": self.payment,
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, data: dict) -> "Liability":
|
||||
return cls(
|
||||
id=UUID(data["id"]),
|
||||
name=data["name"],
|
||||
balance=data.get("balance", 0.0),
|
||||
interest=data.get("interest", 0.0),
|
||||
payment=data.get("payment", 0.0),
|
||||
)
|
||||
@@ -0,0 +1,54 @@
|
||||
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)
|
||||
@@ -0,0 +1,33 @@
|
||||
from dataclasses import dataclass, field
|
||||
from uuid import UUID, uuid4
|
||||
|
||||
|
||||
@dataclass
|
||||
class RecurringCashflow:
|
||||
id: UUID = field(default_factory=uuid4)
|
||||
start_date: str = ""
|
||||
end_date: str = ""
|
||||
frequency: str = "monthly"
|
||||
amount: float = 0.0
|
||||
category: str = ""
|
||||
|
||||
def to_dict(self) -> dict:
|
||||
return {
|
||||
"id": str(self.id),
|
||||
"start_date": self.start_date,
|
||||
"end_date": self.end_date,
|
||||
"frequency": self.frequency,
|
||||
"amount": self.amount,
|
||||
"category": self.category,
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, data: dict) -> "RecurringCashflow":
|
||||
return cls(
|
||||
id=UUID(data["id"]),
|
||||
start_date=data.get("start_date", ""),
|
||||
end_date=data.get("end_date", ""),
|
||||
frequency=data.get("frequency", "monthly"),
|
||||
amount=data.get("amount", 0.0),
|
||||
category=data.get("category", ""),
|
||||
)
|
||||
@@ -0,0 +1,33 @@
|
||||
from dataclasses import dataclass, field
|
||||
from uuid import UUID, uuid4
|
||||
|
||||
|
||||
@dataclass
|
||||
class ForecastScenario:
|
||||
id: UUID = field(default_factory=uuid4)
|
||||
name: str = "baseline"
|
||||
income_multiplier: float = 1.0
|
||||
expense_multiplier: float = 1.0
|
||||
growth_multiplier: float = 1.0
|
||||
description: str = ""
|
||||
|
||||
def to_dict(self) -> dict:
|
||||
return {
|
||||
"id": str(self.id),
|
||||
"name": self.name,
|
||||
"income_multiplier": self.income_multiplier,
|
||||
"expense_multiplier": self.expense_multiplier,
|
||||
"growth_multiplier": self.growth_multiplier,
|
||||
"description": self.description,
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, data: dict) -> "ForecastScenario":
|
||||
return cls(
|
||||
id=UUID(data["id"]),
|
||||
name=data["name"],
|
||||
income_multiplier=data.get("income_multiplier", 1.0),
|
||||
expense_multiplier=data.get("expense_multiplier", 1.0),
|
||||
growth_multiplier=data.get("growth_multiplier", 1.0),
|
||||
description=data.get("description", ""),
|
||||
)
|
||||
@@ -0,0 +1,33 @@
|
||||
from dataclasses import dataclass, field
|
||||
from uuid import UUID, uuid4
|
||||
|
||||
|
||||
@dataclass
|
||||
class Transaction:
|
||||
id: UUID = field(default_factory=uuid4)
|
||||
date: str = ""
|
||||
account: str = ""
|
||||
category: str = ""
|
||||
amount: float = 0.0
|
||||
description: str = ""
|
||||
|
||||
def to_dict(self) -> dict:
|
||||
return {
|
||||
"id": str(self.id),
|
||||
"date": self.date,
|
||||
"account": self.account,
|
||||
"category": self.category,
|
||||
"amount": self.amount,
|
||||
"description": self.description,
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, data: dict) -> "Transaction":
|
||||
return cls(
|
||||
id=UUID(data["id"]),
|
||||
date=data["date"],
|
||||
account=data.get("account", ""),
|
||||
category=data.get("category", ""),
|
||||
amount=data.get("amount", 0.0),
|
||||
description=data.get("description", ""),
|
||||
)
|
||||
Reference in New Issue
Block a user