88 lines
2 KiB
Python
88 lines
2 KiB
Python
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
from datetime import datetime
|
|
from enum import Enum
|
|
|
|
|
|
class TransactionKind(str, Enum):
|
|
EXPENSE = "expense"
|
|
INCOME = "income"
|
|
|
|
|
|
class Category(str, Enum):
|
|
PRODUCTS = "products"
|
|
ENTERTAINMENT = "entertainment"
|
|
CAR = "car"
|
|
CREDITS = "credits"
|
|
RENOVATION = "renovation"
|
|
OTHER = "other"
|
|
INCOME = "income"
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class ParsedTransaction:
|
|
amount_kopecks: int
|
|
description: str
|
|
kind: TransactionKind
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class Transaction:
|
|
id: int
|
|
user_id: int
|
|
amount_kopecks: int
|
|
description: str
|
|
kind: TransactionKind
|
|
category: Category
|
|
occurred_at: datetime
|
|
author_name: str | None = None
|
|
budget_category_id: int | None = None
|
|
budget_category_name: str | None = None
|
|
budget_category_icon: str | None = None
|
|
parent_category_name: str | None = None
|
|
parent_category_icon: str | None = None
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class BudgetCategory:
|
|
id: int
|
|
name: str
|
|
icon: str
|
|
parent_id: int | None
|
|
parent_name: str | None = None
|
|
parent_icon: str | None = None
|
|
system_key: str | None = None
|
|
|
|
@property
|
|
def display_name(self) -> str:
|
|
if self.parent_name:
|
|
return f"{self.parent_icon or '📁'} {self.parent_name} → {self.icon} {self.name}"
|
|
return f"{self.icon} {self.name}"
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class FamilyInfo:
|
|
household_id: int
|
|
invite_code: str
|
|
members: tuple[str, ...]
|
|
owner_user_id: int
|
|
notification_chat_id: int | None = None
|
|
notification_chat_title: str | None = None
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class FamilyJoinRequest:
|
|
candidate_user_id: int
|
|
candidate_name: str
|
|
owner_chat_id: int
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class Totals:
|
|
income: int = 0
|
|
expense: int = 0
|
|
|
|
@property
|
|
def balance(self) -> int:
|
|
return self.income - self.expense
|