This commit is contained in:
2026-03-01 16:19:55 +03:00
parent cf0b0309fc
commit 3d0dd57752
6 changed files with 128 additions and 18 deletions
@@ -1,8 +1,7 @@
from aiogram.types import User
from aiogram_dialog import Window
from aiogram_dialog.widgets.text import Format
from aiogram_dialog.widgets.text import Format, Const
from aiogram_dialog.widgets.kbd import Back
from aiogram_dialog.widgets.text import Const
from dishka import FromDishka
from dishka.integrations.aiogram_dialog import inject
@@ -13,6 +12,7 @@ from dutylog.infrastructure.database.repositories.residents_repository import (
from dutylog.infrastructure.database.repositories.hours_transactions_repository import (
HoursTransactionsRepository,
)
from dutylog.infrastructure.utils.datetime import msk_now
@inject
@@ -21,19 +21,19 @@ async def get_history_data(
residents_repository: FromDishka[ResidentsRepository],
transactions_repository: FromDishka[HoursTransactionsRepository],
**kwargs,
):
) -> dict[str, str]:
resident = await residents_repository.get_resident_by_user_id(event_from_user.id)
if not resident:
history_text = """
<blockquote>📜 <b>История операций</b></blockquote>
<i>Профиль не найден</i>
⚠️ <i>Профиль не найден</i>
"""
else:
transactions = await transactions_repository.get_resident_history(resident.id)
transactions_sorted = sorted(transactions, key=lambda x: x.created_at)
last_10 = transactions_sorted[:10]
last_10 = transactions_sorted[-10:]
if not last_10:
history_text = """
@@ -42,20 +42,20 @@ async def get_history_data(
<i>История операций пуста</i>
"""
else:
history_lines = []
for tx in last_10:
emoji = "+" if tx.transaction_type == "increase" else "-"
date_str = tx.created_at.strftime("%d.%m.%Y %H:%M")
history_lines.append(
f"{emoji} <code>{tx.amount}</code> ч • <i>{date_str}</i>"
)
history_text = f"""
history_text = """
<blockquote>📜 <b>История операций</b></blockquote>
{"".join(f"{line}\n" for line in history_lines)}
<i>Показаны последние 10 операций</i>
"""
for tx in last_10:
operation = "Начислено" if tx.transaction_type == "increase" else "Списано"
emoji = "+" if tx.transaction_type == "increase" else ""
msk_time = tx.created_at.astimezone(msk_now().tzinfo).replace(tzinfo=None)
date_str = msk_time.strftime("%d.%m.%Y %H:%M")
remark_text = f"\n💬 <i>{tx.remark}</i>" if tx.remark else ""
history_text += f"<blockquote><b>{operation}</b> {emoji}<code>{tx.amount}</code> ч\n📅 {date_str}{remark_text}</blockquote>\n"
return {"history_content": history_text}
@@ -108,6 +108,12 @@ main_menu_window = Window(
state=MainMenuSG.history,
when="has_resident",
),
SwitchTo(
Const("🏆 Топ общежития"),
id="top_btn",
state=MainMenuSG.top_residents,
when="is_regular_user",
),
SwitchTo(
Const("❓ FAQ"),
id="faq_btn",
@@ -0,0 +1,64 @@
from aiogram_dialog import Window
from aiogram_dialog.widgets.text import Format, Const
from aiogram_dialog.widgets.kbd import SwitchTo
from dishka import FromDishka
from dishka.integrations.aiogram_dialog import inject
from dutylog.application.bot.user_dialogs.states import MainMenuSG
from dutylog.infrastructure.database.repositories.residents_repository import (
ResidentsRepository,
)
@inject
async def get_top_residents_data(
residents_repository: FromDishka[ResidentsRepository],
**kwargs,
) -> dict[str, str]:
all_residents = await residents_repository.get_all_residents()
residents_with_hours = [
r for r in all_residents
if (r.inactive_hours + r.active_hours) > 0
]
sorted_residents = sorted(
residents_with_hours,
key=lambda r: r.inactive_hours + r.active_hours,
reverse=True
)
top_residents = sorted_residents[:5]
if not top_residents:
content = """
<blockquote>🏆 <b>Топ общежития</b></blockquote>
⚠️ Нет данных для отображения топа.
"""
else:
content = """
<blockquote>🏆 <b>Топ общежития</b></blockquote>
"""
medals = ["🥇", "🥈", "🥉", "4.", "5."]
for idx, resident in enumerate(top_residents):
total_hours = resident.inactive_hours + resident.active_hours
name = resident.real_name or "Без имени"
content += f"<blockquote>{medals[idx]} <b>{name}</b> — <code>{total_hours}</code> ч</blockquote>\n"
return {"content": content}
top_residents_window = Window(
Format("{content}"),
SwitchTo(
Const("◀️ Назад"),
id="back_to_main",
state=MainMenuSG.main,
),
state=MainMenuSG.top_residents,
getter=get_top_residents_data,
)