128 lines
2.6 KiB
Python
128 lines
2.6 KiB
Python
from __future__ import annotations
|
|
|
|
from datetime import date
|
|
|
|
from pydantic import BaseModel, Field
|
|
|
|
|
|
class BudgetOut(BaseModel):
|
|
id: int
|
|
user_id: int
|
|
name: str
|
|
total_amount: float
|
|
start_date: date
|
|
end_date: date
|
|
currency: str
|
|
is_active: bool
|
|
|
|
|
|
class BudgetStatusOut(BaseModel):
|
|
budget: BudgetOut
|
|
today: date
|
|
days_left: int
|
|
total_spent: float
|
|
remaining: float
|
|
daily_limit: float
|
|
spent_today: float
|
|
remaining_today: float
|
|
is_over_daily: bool
|
|
is_over_budget: bool
|
|
is_expired: bool
|
|
selected: bool = False
|
|
|
|
|
|
class ExpenseOut(BaseModel):
|
|
id: int
|
|
budget_id: int
|
|
amount: float
|
|
note: str | None
|
|
spent_at: date
|
|
|
|
|
|
class ExpensesPageOut(BaseModel):
|
|
page: int
|
|
total_pages: int
|
|
total_count: int
|
|
total_sum: float
|
|
page_size: int
|
|
budget_id: int
|
|
items: list[ExpenseOut]
|
|
|
|
|
|
class BudgetsListOut(BaseModel):
|
|
items: list[BudgetStatusOut] = Field(default_factory=list)
|
|
|
|
|
|
class TelegramLoginIn(BaseModel):
|
|
id: int
|
|
first_name: str
|
|
last_name: str | None = None
|
|
username: str | None = None
|
|
photo_url: str | None = None
|
|
auth_date: int
|
|
hash: str
|
|
|
|
|
|
class InternalAuthIn(BaseModel):
|
|
"""Service auth for trusted clients (Telegram bot) acting as a user."""
|
|
|
|
user_id: int = Field(gt=0)
|
|
first_name: str | None = None
|
|
last_name: str | None = None
|
|
username: str | None = None
|
|
|
|
|
|
class AuthUserOut(BaseModel):
|
|
user_id: int
|
|
first_name: str | None = None
|
|
last_name: str | None = None
|
|
username: str | None = None
|
|
photo_url: str | None = None
|
|
|
|
|
|
class AuthSessionOut(BaseModel):
|
|
access_token: str
|
|
token_type: str = "bearer"
|
|
user: AuthUserOut
|
|
|
|
|
|
class ExpenseCreateIn(BaseModel):
|
|
amount: float = Field(gt=0)
|
|
note: str | None = None
|
|
spent_at: date | None = None
|
|
budget_id: int | None = None
|
|
|
|
|
|
class BudgetCreateIn(BaseModel):
|
|
total_amount: float = Field(gt=0)
|
|
end_date: date
|
|
name: str = "Бюджет"
|
|
is_active: bool = True
|
|
select: bool = True
|
|
|
|
|
|
class BudgetUpdateIn(BaseModel):
|
|
total_amount: float | None = Field(default=None, gt=0)
|
|
end_date: date | None = None
|
|
name: str | None = None
|
|
reset_expenses: bool = False
|
|
|
|
|
|
class BudgetActiveIn(BaseModel):
|
|
is_active: bool
|
|
|
|
|
|
class BudgetUpsertIn(BaseModel):
|
|
"""Legacy upsert against selected budget (or create if none)."""
|
|
|
|
total_amount: float = Field(gt=0)
|
|
end_date: date
|
|
reset_expenses: bool = True
|
|
name: str | None = None
|
|
budget_id: int | None = None
|
|
|
|
|
|
class UndoExpenseOut(BaseModel):
|
|
deleted_amount: float
|
|
status: BudgetStatusOut
|