mirror of
https://github.com/koloideal/DutyLog.git
synced 2026-06-10 02:15:30 +03:00
update
This commit is contained in:
@@ -55,7 +55,6 @@ async def main():
|
||||
setup_dialogs(dp)
|
||||
setup_dishka(container, dp, auto_inject=True)
|
||||
|
||||
# Устанавливаем команды бота
|
||||
await set_bot_commands(bot)
|
||||
|
||||
await dp.start_polling(bot)
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
from datetime import datetime, time
|
||||
|
||||
from sqlalchemy import select, delete
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
@@ -41,8 +43,6 @@ class HoursTransactionsDAO:
|
||||
await self.session.commit()
|
||||
|
||||
async def get_by_period(self, start_date, end_date) -> list[HoursTransaction]:
|
||||
from datetime import datetime, time
|
||||
|
||||
start_datetime = datetime.combine(start_date, time.min)
|
||||
end_datetime = datetime.combine(end_date, time.max)
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ from sqlalchemy import select, update, delete
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from dutylog.infrastructure.database.models.resident import Resident
|
||||
from dutylog.infrastructure.database.models.room import Room
|
||||
|
||||
|
||||
class ResidentsDAO:
|
||||
@@ -37,7 +38,6 @@ class ResidentsDAO:
|
||||
return list(result.scalars().all())
|
||||
|
||||
async def search_by_room_number(self, room_number: int) -> list[Resident]:
|
||||
from dutylog.infrastructure.database.models.room import Room
|
||||
result = await self.session.execute(
|
||||
select(Resident)
|
||||
.join(Room, Resident.room == Room.id)
|
||||
|
||||
@@ -43,7 +43,6 @@ class ReportService:
|
||||
start_date, end_date
|
||||
)
|
||||
|
||||
# Разделяем транзакции на личные и комнатные
|
||||
resident_transactions = [t for t in all_transactions if not t.per_room]
|
||||
room_transactions = [t for t in all_transactions if t.per_room]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user