adding debt app

This commit is contained in:
2025-06-20 10:31:59 +07:00
parent 047290e2ea
commit b1068ecd2c
18 changed files with 208 additions and 526 deletions
+47 -93
View File
@@ -1,103 +1,57 @@
from typing import List, Optional
from datetime import datetime
from models.debt_group import HomeMember, Expense, ExpenseShare
from models.home_debt import DiscordHomeDebt
from infra.db import postgres
class HomeDebtRepository:
_instance = None
_initialized = False
def __new__(cls):
if cls._instance is None:
cls._instance = super(HomeDebtRepository, cls).__new__(cls)
return cls._instance
def __init__(self):
if not HomeDebtRepository._initialized:
self.db = postgres.get_table('home_members')
HomeDebtRepository._initialized = True
self.table = postgres.get_table('discord_home_debt')
async def add_member(self, discord_user_id: int, name: str) -> HomeMember:
"""Thêm thành viên mới vào nhà"""
data = await self.db.table("home_members").insert({
"discord_user_id": discord_user_id,
"name": name
}).execute()
return HomeMember(**data.data[0])
async def get_member(self, discord_user_id: int) -> Optional[HomeMember]:
"""Lấy thông tin thành viên theo discord_user_id"""
data = await self.db.table("home_members").select("*").eq("discord_user_id", discord_user_id).execute()
if not data.data:
async def get(self, discord_user_id: int) -> Optional[DiscordHomeDebt]:
"""Lấy thông tin thành viên"""
try:
response = self.table.select('*').eq('user_id', discord_user_id).execute()
if response.data:
return DiscordHomeDebt(**response.data[0])
return None
return HomeMember(**data.data[0])
async def get_all_members(self) -> List[HomeMember]:
"""Lấy danh sách tất cả thành viên"""
data = await self.db.table("home_members").select("*").execute()
return [HomeMember(**member) for member in data.data]
async def add_expense(self, amount: float, description: str, paid_by: int) -> Expense:
"""Thêm khoản chi tiêu mới"""
# Tạo expense
expense_data = await self.db.table("expenses").insert({
"amount": amount,
"description": description,
"paid_by": paid_by
}).execute()
expense = Expense(**expense_data.data[0])
# Lấy danh sách thành viên
members = await self.get_all_members()
share_amount = amount / len(members)
# Tạo expense shares cho từng thành viên
for member in members:
await self.db.table("expense_shares").insert({
"expense_id": expense.id,
"member_id": member.discord_user_id,
"share_amount": share_amount,
"is_paid": member.discord_user_id == paid_by # Người trả tiền được đánh dấu là đã trả
}).execute()
return expense
async def get_expense(self, expense_id: int) -> Optional[Expense]:
"""Lấy thông tin khoản chi tiêu"""
data = await self.db.table("expenses").select("*").eq("id", expense_id).execute()
if not data.data:
except Exception as e:
print(f"Error getting user: {e}")
return None
return Expense(**data.data[0])
async def get_all_expenses(self) -> List[Expense]:
"""Lấy danh sách tất cả khoản chi tiêu"""
data = await self.db.table("expenses").select("*").order("created_at", desc=True).execute()
return [Expense(**expense) for expense in data.data]
async def get_expense_shares(self, expense_id: int) -> List[ExpenseShare]:
"""Lấy danh sách chia tiền của một khoản chi tiêu"""
data = await self.db.table("expense_shares").select("*").eq("expense_id", expense_id).execute()
return [ExpenseShare(**share) for share in data.data]
async def mark_share_as_paid(self, share_id: int) -> Optional[ExpenseShare]:
"""Đánh dấu một phần chia tiền đã được trả"""
data = await self.db.table("expense_shares").update({
"is_paid": True
}).eq("id", share_id).execute()
if not data.data:
return None
return ExpenseShare(**data.data[0])
async def get_member_balance(self, discord_user_id: int) -> float:
"""Tính số dư của một thành viên (số tiền phải trả - số tiền đã trả)"""
# Lấy tất cả expense shares của thành viên
data = await self.db.table("expense_shares").select("*").eq("member_id", discord_user_id).execute()
shares = [ExpenseShare(**share) for share in data.data]
# Tính tổng số tiền phải trả
total_owed = sum(share.share_amount for share in shares)
# Tính tổng số tiền đã trả
total_paid = sum(share.share_amount for share in shares if share.is_paid)
async def get_other(self, discord_user_id: int) -> Optional[DiscordHomeDebt]:
"""Lấy thông tin thành viên khác"""
try:
response = self.table.select('*').neq('user_id', discord_user_id).execute()
if response.data:
return DiscordHomeDebt(**response.data[0])
return None
except Exception as e:
print(f"Error getting other member: {e}")
return None
return total_owed - total_paid
async def create_home_debt(self, user_id: int, value: int) -> Optional[DiscordHomeDebt]:
"""Tạo mới khoản nợ"""
try:
home_debt = DiscordHomeDebt(user_id=user_id, value=value)
response = self.table.insert(home_debt.dict(exclude_none=True)).execute()
return DiscordHomeDebt(**response.data[0])
except Exception as e:
print(f"Error creating home debt: {e}")
return None
async def update_home_debt(self, home_debt: DiscordHomeDebt) -> Optional[DiscordHomeDebt]:
"""Cập nhật khoản nợ"""
try:
response = self.table.update(home_debt.dict(exclude_none=True)).eq('user_id', home_debt.user_id).execute()
return DiscordHomeDebt(**response.data[0])
except Exception as e:
print(f"Error updating home debt: {e}")
return None
async def get_all(self) -> List[DiscordHomeDebt]:
"""Lấy tất cả khoản nợ"""
try:
response = self.table.select('*').execute()
return [DiscordHomeDebt(**home_debt) for home_debt in response.data]
except Exception as e:
print(f"Error getting all home debts: {e}")
return []