This commit is contained in:
2026-03-17 20:36:51 +03:00
parent c80faeb665
commit f59791caf1
9 changed files with 106 additions and 6 deletions
@@ -1,5 +1,8 @@
from dutylog.application.bot.creator_dialogs.creator_menu_dialog import (
creator_menu_dialog,
)
from dutylog.application.bot.creator_dialogs.transactions_history import (
transactions_history_window,
)
__all__ = ["creator_menu_dialog"]
__all__ = ["creator_menu_dialog", "transactions_history_window"]
@@ -289,6 +289,21 @@ admins_list_window = Window(
id="add_admin_btn",
on_click=on_add_admin_click,
),
Button(
Const("──────────"),
id="separator_btn",
on_click=lambda c, b, m: None,
),
SwitchTo(
Const("👨‍💼 Админы"),
id="admins_btn",
state=CreatorMenuSG.admins_list,
),
SwitchTo(
Const("📜 История"),
id="history_btn",
state=CreatorMenuSG.transactions_history,
),
Button(
Const("◀️ Назад"),
id="back_to_main_from_admins",
@@ -7,6 +7,9 @@ from dutylog.application.bot.creator_dialogs.admins_management import (
add_admin_select_user_window,
add_admin_confirm_window,
)
from dutylog.application.bot.creator_dialogs.transactions_history import (
transactions_history_window,
)
creator_menu_dialog = Dialog(
@@ -15,4 +18,5 @@ creator_menu_dialog = Dialog(
remove_admin_confirm_window,
add_admin_select_user_window,
add_admin_confirm_window,
transactions_history_window,
)
@@ -0,0 +1,79 @@
from aiogram_dialog import Window
from aiogram_dialog.widgets.text import Format, Const
from aiogram_dialog.widgets.kbd import Back, NumberedPager, Group
from dishka import FromDishka
from dishka.integrations.aiogram_dialog import inject
from dutylog.application.bot.user_dialogs.states import CreatorMenuSG
from dutylog.infrastructure.database.repositories.hours_transactions_repository import (
HoursTransactionsRepository,
)
from dutylog.infrastructure.database.repositories.residents_repository import (
ResidentsRepository,
)
from dutylog.infrastructure.database.repositories.rooms_repository import (
RoomsRepository,
)
from dutylog.infrastructure.utils.datetime import msk_now
@inject
async def get_transactions_history_data(
transactions_repository: FromDishka[HoursTransactionsRepository],
residents_repository: FromDishka[ResidentsRepository],
rooms_repository: FromDishka[RoomsRepository],
dialog_manager,
**kwargs,
) -> dict:
all_transactions = await transactions_repository.get_all_transactions()
all_transactions.sort(key=lambda t: t.created_at, reverse=True)
page = await dialog_manager.find("transactions_pager").get_page()
per_page = 7
start_idx = page * per_page
end_idx = start_idx + per_page
page_transactions = all_transactions[start_idx:end_idx]
if not page_transactions:
content = "<blockquote>📜 <b>История всех транзакций</b></blockquote>\n\n<i>Нет транзакций</i>"
else:
content = "<blockquote>📜 <b>История всех транзакций</b></blockquote>\n\n"
for tx in page_transactions:
resident = await residents_repository.get_by_id(tx.resident_id)
if not resident:
continue
room = await rooms_repository.get_by_id(resident.room)
room_number = room.number if room else "???"
operation = "Начислено" if tx.transaction_type == "increase" else "Списано"
emoji = "+" if tx.transaction_type == "increase" else ""
room_mark = " 🚪" if tx.per_room 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 ""
content += f"<blockquote><b>{operation}</b> {emoji}<code>{tx.amount}</code> ч{room_mark}\n👤 {resident.real_name or 'Без имени'} (к. {room_number})\n📅 {date_str}{remark_text}</blockquote>\n"
total_pages = (len(all_transactions) + per_page - 1) // per_page
return {
"content": content,
"pages": total_pages,
}
transactions_history_window = Window(
Format("{content}"),
Group(
NumberedPager(scroll="transactions_pager", when="pages"),
width=8,
),
Back(Const("◀️ Назад")),
state=CreatorMenuSG.transactions_history,
getter=get_transactions_history_data,
)
@@ -67,6 +67,7 @@ class CreatorMenuSG(StatesGroup):
remove_admin_confirm = State()
add_admin_select_user = State()
add_admin_confirm = State()
transactions_history = State()
class RegistrationSG(StatesGroup):