Files
finance/backend/app/analytics/router.py
T

110 lines
3.2 KiB
Python

from datetime import date
from fastapi import APIRouter, Query
from app.analytics import service
from app.dependencies import Context, Db
router = APIRouter(prefix="/analytics", tags=["analytics"])
@router.get("/category-spend")
def category_spend(
date_from: date = Query(alias="from"),
date_to: date = Query(alias="to"),
*,
db: Db,
context: Context,
) -> list[dict]:
rows = service.category_spend(
db, space_id=context.space.id, date_from=date_from, date_to=date_to
)
return [
{
"categoryId": row["category_id"],
"name": row["name"],
"nameKey": row["name_key"],
"amountKopecks": row["amount_kopecks"],
}
for row in rows
]
@router.get("/cash-flow")
def cash_flow(
date_from: date = Query(alias="from"),
date_to: date = Query(alias="to"),
*,
db: Db,
context: Context,
) -> list[dict]:
rows = service.cash_flow(db, space_id=context.space.id, date_from=date_from, date_to=date_to)
months: dict[str, dict[str, int | str]] = {}
for row in rows:
month = row["date"].strftime("%Y-%m")
bucket = months.setdefault(
month,
{
"month": month,
"incomeKopecks": 0,
"expenseKopecks": 0,
"refundsKopecks": 0,
"netKopecks": 0,
},
)
amount = int(row["amount_kopecks"])
key = {
"income": "incomeKopecks",
"expense": "expenseKopecks",
"refund": "refundsKopecks",
}[row["type"]]
bucket[key] = int(bucket[key]) + abs(amount)
bucket["netKopecks"] = int(bucket["netKopecks"]) + amount
return list(months.values())
@router.get("/plan-fact")
def plan_fact(month: str, db: Db, context: Context) -> dict:
from app.budgeting.router import parse_month
year, month_number = parse_month(month)
state = service.plan_fact(db, space_id=context.space.id, year=year, month=month_number)
categories = state.get("monthly_categories", [])
return {
"month": month,
"items": [
{
"categoryId": row["category_id"],
"name": row.get("name"),
"nameKey": row.get("name_key"),
"plannedKopecks": row["planned"],
"actualKopecks": row["spent"],
}
for row in categories
],
}
@router.get("/balances")
def balances(db: Db, context: Context) -> dict:
from datetime import UTC, datetime
rows = service.balances(db, space_id=context.space.id)
assets = sum(max(row["balance_kopecks"], 0) for row in rows if row["kind"] != "credit")
liabilities = sum(row["debt_kopecks"] for row in rows)
return {
"asOf": datetime.now(UTC).date(),
"assetsKopecks": assets,
"liabilitiesKopecks": liabilities,
"netKopecks": assets - liabilities,
"items": [
{
"accountId": row["account_id"],
"name": row["account"],
"type": row["kind"],
"balanceKopecks": row["balance_kopecks"],
}
for row in rows
],
}