mirror of
https://github.com/koloideal/DutyLog.git
synced 2026-06-10 02:15:30 +03:00
update
This commit is contained in:
@@ -8,6 +8,7 @@ from dutylog.application.bot.user_dialogs.admin_dialogs.residents_management imp
|
||||
residents_list_window,
|
||||
resident_info_window,
|
||||
resident_logout_confirm_window,
|
||||
resident_delete_confirm_window,
|
||||
create_resident_name_window,
|
||||
create_resident_floor_window,
|
||||
create_resident_room_window,
|
||||
@@ -20,6 +21,20 @@ from dutylog.application.bot.user_dialogs.admin_dialogs.residents_filter import
|
||||
filter_hours_input_window,
|
||||
filtered_results_window,
|
||||
)
|
||||
from dutylog.application.bot.user_dialogs.admin_dialogs.floors_management import (
|
||||
floors_list_window,
|
||||
floor_delete_confirm_window,
|
||||
create_floor_input_window,
|
||||
create_floor_confirm_window,
|
||||
)
|
||||
from dutylog.application.bot.user_dialogs.admin_dialogs.rooms_management import (
|
||||
rooms_select_floor_window,
|
||||
rooms_list_window,
|
||||
room_delete_confirm_window,
|
||||
create_room_select_floor_window,
|
||||
create_room_input_window,
|
||||
create_room_confirm_window,
|
||||
)
|
||||
from dutylog.application.bot.user_dialogs.admin_dialogs.hours_management import (
|
||||
add_hours_select_window,
|
||||
remove_hours_select_window,
|
||||
@@ -39,6 +54,7 @@ admin_menu_dialog = Dialog(
|
||||
residents_list_window,
|
||||
resident_info_window,
|
||||
resident_logout_confirm_window,
|
||||
resident_delete_confirm_window,
|
||||
add_hours_select_window,
|
||||
remove_hours_select_window,
|
||||
add_hours_custom_window,
|
||||
@@ -49,6 +65,16 @@ admin_menu_dialog = Dialog(
|
||||
create_resident_floor_window,
|
||||
create_resident_room_window,
|
||||
create_resident_confirm_window,
|
||||
floors_list_window,
|
||||
floor_delete_confirm_window,
|
||||
create_floor_input_window,
|
||||
create_floor_confirm_window,
|
||||
rooms_select_floor_window,
|
||||
rooms_list_window,
|
||||
room_delete_confirm_window,
|
||||
create_room_select_floor_window,
|
||||
create_room_input_window,
|
||||
create_room_confirm_window,
|
||||
statistics_window,
|
||||
broadcast_window,
|
||||
broadcast_confirm_window,
|
||||
|
||||
@@ -0,0 +1,241 @@
|
||||
from aiogram.types import Message, CallbackQuery
|
||||
from aiogram_dialog import Window, DialogManager
|
||||
from aiogram_dialog.widgets.text import Format, Const
|
||||
from aiogram_dialog.widgets.kbd import SwitchTo, Button, ScrollingGroup, Select, Row
|
||||
from aiogram_dialog.widgets.input import MessageInput
|
||||
from dishka import FromDishka
|
||||
from dishka.integrations.aiogram_dialog import inject
|
||||
|
||||
from dutylog.application.bot.user_dialogs.states import AdminMenuSG
|
||||
from dutylog.infrastructure.database.repositories.floors_repository import (
|
||||
FloorsRepository,
|
||||
)
|
||||
|
||||
|
||||
async def on_floors_click(
|
||||
callback: CallbackQuery,
|
||||
button: Button,
|
||||
dialog_manager: DialogManager,
|
||||
):
|
||||
await dialog_manager.switch_to(AdminMenuSG.floors)
|
||||
|
||||
|
||||
@inject
|
||||
async def get_floors_list_data(
|
||||
floors_repository: FromDishka[FloorsRepository],
|
||||
**kwargs,
|
||||
):
|
||||
all_floors = await floors_repository.get_all_floors()
|
||||
all_floors.sort(key=lambda f: f.number)
|
||||
|
||||
floors_data = [(f"🏢 Этаж {f.number}", f.id) for f in all_floors]
|
||||
|
||||
content = f"""
|
||||
<blockquote>🏢 <b>Этажи</b></blockquote>
|
||||
|
||||
<b>Всего этажей:</b> <code>{len(all_floors)}</code>
|
||||
|
||||
Выберите этаж для удаления:
|
||||
"""
|
||||
|
||||
return {
|
||||
"content": content,
|
||||
"floors": floors_data,
|
||||
}
|
||||
|
||||
|
||||
async def on_floor_selected(
|
||||
callback: CallbackQuery,
|
||||
widget: Select,
|
||||
dialog_manager: DialogManager,
|
||||
item_id: str,
|
||||
):
|
||||
dialog_manager.dialog_data["selected_floor_id"] = int(item_id)
|
||||
await dialog_manager.switch_to(AdminMenuSG.floor_delete_confirm)
|
||||
|
||||
|
||||
async def on_add_floor_click(
|
||||
callback: CallbackQuery,
|
||||
button: Button,
|
||||
dialog_manager: DialogManager,
|
||||
):
|
||||
await dialog_manager.switch_to(AdminMenuSG.create_floor_input)
|
||||
|
||||
|
||||
async def on_floor_number_input(
|
||||
message: Message,
|
||||
widget: MessageInput,
|
||||
dialog_manager: DialogManager,
|
||||
):
|
||||
if not message.text:
|
||||
await message.answer("⚠️ Пожалуйста, введите номер этажа")
|
||||
return
|
||||
|
||||
try:
|
||||
floor_number = int(message.text)
|
||||
if floor_number <= 0:
|
||||
await message.answer("⚠️ Номер этажа должен быть положительным числом")
|
||||
return
|
||||
|
||||
dialog_manager.dialog_data["new_floor_number"] = floor_number
|
||||
await dialog_manager.switch_to(AdminMenuSG.create_floor_confirm)
|
||||
except ValueError:
|
||||
await message.answer("⚠️ Пожалуйста, введите корректное число")
|
||||
|
||||
|
||||
async def get_create_floor_confirm_data(
|
||||
dialog_manager: DialogManager,
|
||||
**kwargs,
|
||||
):
|
||||
floor_number = dialog_manager.dialog_data.get("new_floor_number", "???")
|
||||
return {"floor_number": floor_number}
|
||||
|
||||
|
||||
@inject
|
||||
async def on_create_floor_confirm(
|
||||
callback: CallbackQuery,
|
||||
button: Button,
|
||||
dialog_manager: DialogManager,
|
||||
floors_repository: FromDishka[FloorsRepository],
|
||||
):
|
||||
floor_number = dialog_manager.dialog_data.get("new_floor_number")
|
||||
|
||||
if floor_number:
|
||||
existing_floor = await floors_repository.get_floor_by_number(floor_number)
|
||||
if existing_floor:
|
||||
await callback.answer(
|
||||
f"⚠️ Этаж {floor_number} уже существует!",
|
||||
show_alert=True
|
||||
)
|
||||
await dialog_manager.switch_to(AdminMenuSG.floors)
|
||||
return
|
||||
|
||||
await floors_repository.create_floor(floor_number)
|
||||
await callback.answer("✅ Этаж создан!")
|
||||
|
||||
await dialog_manager.switch_to(AdminMenuSG.floors)
|
||||
|
||||
|
||||
async def on_create_floor_cancel(
|
||||
callback: CallbackQuery,
|
||||
button: Button,
|
||||
dialog_manager: DialogManager,
|
||||
):
|
||||
await dialog_manager.switch_to(AdminMenuSG.floors)
|
||||
|
||||
|
||||
@inject
|
||||
async def get_floor_delete_confirm_data(
|
||||
dialog_manager: DialogManager,
|
||||
floors_repository: FromDishka[FloorsRepository],
|
||||
**kwargs,
|
||||
):
|
||||
floor_id = dialog_manager.dialog_data.get("selected_floor_id")
|
||||
|
||||
if not floor_id:
|
||||
return {"floor_number": "???"}
|
||||
|
||||
floor = await floors_repository.get_floor_by_id(floor_id)
|
||||
floor_number = floor.number if floor else "???"
|
||||
|
||||
return {"floor_number": floor_number}
|
||||
|
||||
|
||||
@inject
|
||||
async def on_delete_floor_confirm(
|
||||
callback: CallbackQuery,
|
||||
button: Button,
|
||||
dialog_manager: DialogManager,
|
||||
floors_repository: FromDishka[FloorsRepository],
|
||||
):
|
||||
floor_id = dialog_manager.dialog_data.get("selected_floor_id")
|
||||
|
||||
if floor_id:
|
||||
await floors_repository.delete_floor(floor_id)
|
||||
await callback.answer("✅ Этаж удален!")
|
||||
|
||||
await dialog_manager.switch_to(AdminMenuSG.floors)
|
||||
|
||||
|
||||
async def on_delete_floor_cancel(
|
||||
callback: CallbackQuery,
|
||||
button: Button,
|
||||
dialog_manager: DialogManager,
|
||||
):
|
||||
await dialog_manager.switch_to(AdminMenuSG.floors)
|
||||
|
||||
|
||||
floors_list_window = Window(
|
||||
Format("{content}"),
|
||||
ScrollingGroup(
|
||||
Select(
|
||||
Format("{item[0]}"),
|
||||
id="floors_select",
|
||||
item_id_getter=lambda x: x[1],
|
||||
items="floors",
|
||||
on_click=on_floor_selected,
|
||||
),
|
||||
id="floors_scroll",
|
||||
width=1,
|
||||
height=7,
|
||||
),
|
||||
Button(
|
||||
Const("➕ Добавить этаж"),
|
||||
id="add_floor_btn",
|
||||
on_click=on_add_floor_click,
|
||||
),
|
||||
SwitchTo(
|
||||
Const("◀️ Назад"),
|
||||
id="back_to_admin_menu_from_floors",
|
||||
state=AdminMenuSG.main,
|
||||
),
|
||||
state=AdminMenuSG.floors,
|
||||
getter=get_floors_list_data,
|
||||
)
|
||||
|
||||
floor_delete_confirm_window = Window(
|
||||
Format("<blockquote>⚠️ <b>Подтверждение удаления</b></blockquote>\n\nВы точно хотите удалить этаж <code>{floor_number}</code>? Это действие необратимо и удалит все комнаты на этом этаже!"),
|
||||
Row(
|
||||
Button(
|
||||
Const("✅ Да, удалить"),
|
||||
id="confirm_delete_floor",
|
||||
on_click=on_delete_floor_confirm,
|
||||
),
|
||||
Button(
|
||||
Const("❌ Отмена"),
|
||||
id="cancel_delete_floor",
|
||||
on_click=on_delete_floor_cancel,
|
||||
),
|
||||
),
|
||||
state=AdminMenuSG.floor_delete_confirm,
|
||||
getter=get_floor_delete_confirm_data,
|
||||
)
|
||||
|
||||
create_floor_input_window = Window(
|
||||
Const("<blockquote>➕ <b>Создание этажа</b></blockquote>\n\nВведите номер этажа:"),
|
||||
MessageInput(on_floor_number_input),
|
||||
SwitchTo(
|
||||
Const("◀️ Отмена"),
|
||||
id="cancel_create_floor_input",
|
||||
state=AdminMenuSG.floors,
|
||||
),
|
||||
state=AdminMenuSG.create_floor_input,
|
||||
)
|
||||
|
||||
create_floor_confirm_window = Window(
|
||||
Format("<blockquote>✅ <b>Подтверждение</b></blockquote>\n\nСоздать этаж <code>{floor_number}</code>?"),
|
||||
Row(
|
||||
Button(
|
||||
Const("✅ Да"),
|
||||
id="confirm_create_floor",
|
||||
on_click=on_create_floor_confirm,
|
||||
),
|
||||
Button(
|
||||
Const("❌ Нет"),
|
||||
id="cancel_create_floor",
|
||||
on_click=on_create_floor_cancel,
|
||||
),
|
||||
),
|
||||
state=AdminMenuSG.create_floor_confirm,
|
||||
getter=get_create_floor_confirm_data,
|
||||
)
|
||||
@@ -84,11 +84,11 @@ async def get_statistics_data(
|
||||
|
||||
|
||||
async def on_rooms_click(callback, button, dialog_manager):
|
||||
await callback.answer("⚠️ Функционал в разработке", show_alert=True)
|
||||
await dialog_manager.switch_to(AdminMenuSG.rooms_select_floor)
|
||||
|
||||
|
||||
async def on_floors_click(callback, button, dialog_manager):
|
||||
await callback.answer("⚠️ Функционал в разработке", show_alert=True)
|
||||
await dialog_manager.switch_to(AdminMenuSG.floors)
|
||||
|
||||
|
||||
main_menu_window = Window(
|
||||
|
||||
@@ -13,6 +13,9 @@ from dutylog.infrastructure.database.repositories.residents_repository import (
|
||||
from dutylog.infrastructure.database.repositories.rooms_repository import (
|
||||
RoomsRepository,
|
||||
)
|
||||
from dutylog.infrastructure.database.repositories.floors_repository import (
|
||||
FloorsRepository,
|
||||
)
|
||||
|
||||
|
||||
async def on_filter_residents(
|
||||
@@ -76,6 +79,7 @@ async def get_filtered_results_data(
|
||||
dialog_manager: DialogManager,
|
||||
residents_repository: FromDishka[ResidentsRepository],
|
||||
rooms_repository: FromDishka[RoomsRepository],
|
||||
floors_repository: FromDishka[FloorsRepository],
|
||||
**kwargs,
|
||||
):
|
||||
filter_type: str = dialog_manager.dialog_data["filter_type"]
|
||||
@@ -121,13 +125,19 @@ async def get_filtered_results_data(
|
||||
residents_with_rooms = []
|
||||
for resident in filtered:
|
||||
room = await rooms_repository.get_room_by_id(resident.room)
|
||||
room_number = room.number if room else 999999
|
||||
residents_with_rooms.append((resident, room_number))
|
||||
if room:
|
||||
floor = await floors_repository.get_floor_by_id(room.on_floor)
|
||||
floor_number = floor.number if floor else 999999
|
||||
room_number = room.number
|
||||
else:
|
||||
floor_number = 999999
|
||||
room_number = 999999
|
||||
residents_with_rooms.append((resident, floor_number, room_number))
|
||||
|
||||
residents_with_rooms.sort(key=lambda x: x[1])
|
||||
residents_with_rooms.sort(key=lambda x: (x[1], x[2]))
|
||||
|
||||
residents_data = []
|
||||
for resident, room_number in residents_with_rooms:
|
||||
for resident, floor_number, room_number in residents_with_rooms:
|
||||
status = "🟢" if resident.is_busy else "⚪️"
|
||||
name = resident.real_name if resident.real_name else "Без имени"
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ from dutylog.infrastructure.database.repositories.users_repository import (
|
||||
async def get_residents_list_data(
|
||||
residents_repository: FromDishka[ResidentsRepository],
|
||||
rooms_repository: FromDishka[RoomsRepository],
|
||||
floors_repository: FromDishka[FloorsRepository],
|
||||
**kwargs,
|
||||
):
|
||||
all_residents = await residents_repository.get_all_residents()
|
||||
@@ -33,13 +34,19 @@ async def get_residents_list_data(
|
||||
residents_with_rooms = []
|
||||
for resident in all_residents:
|
||||
room = await rooms_repository.get_room_by_id(resident.room)
|
||||
room_number = room.number if room else 999999
|
||||
residents_with_rooms.append((resident, room_number))
|
||||
if room:
|
||||
floor = await floors_repository.get_floor_by_id(room.on_floor)
|
||||
floor_number = floor.number if floor else 999999
|
||||
room_number = room.number
|
||||
else:
|
||||
floor_number = 999999
|
||||
room_number = 999999
|
||||
residents_with_rooms.append((resident, floor_number, room_number))
|
||||
|
||||
residents_with_rooms.sort(key=lambda x: x[1])
|
||||
residents_with_rooms.sort(key=lambda x: (x[1], x[2]))
|
||||
|
||||
residents_data = []
|
||||
for resident, room_number in residents_with_rooms:
|
||||
for resident, floor_number, room_number in residents_with_rooms:
|
||||
status = "🟢" if resident.is_busy else "⚪️"
|
||||
name = resident.real_name if resident.real_name else "Без имени"
|
||||
|
||||
@@ -180,6 +187,30 @@ async def on_logout_resident_cancel(
|
||||
await dialog_manager.switch_to(AdminMenuSG.resident_info)
|
||||
|
||||
|
||||
@inject
|
||||
async def on_delete_resident_confirm(
|
||||
callback: CallbackQuery,
|
||||
button: Button,
|
||||
dialog_manager: DialogManager,
|
||||
residents_repository: FromDishka[ResidentsRepository],
|
||||
):
|
||||
resident_id = dialog_manager.dialog_data.get("selected_resident_id")
|
||||
|
||||
if resident_id:
|
||||
await residents_repository.delete_resident(resident_id)
|
||||
await callback.answer("✅ Резидент удален!")
|
||||
|
||||
await dialog_manager.switch_to(AdminMenuSG.residents)
|
||||
|
||||
|
||||
async def on_delete_resident_cancel(
|
||||
callback: CallbackQuery,
|
||||
button: Button,
|
||||
dialog_manager: DialogManager,
|
||||
):
|
||||
await dialog_manager.switch_to(AdminMenuSG.resident_info)
|
||||
|
||||
|
||||
async def on_resident_name_input(
|
||||
message: Message,
|
||||
widget: MessageInput,
|
||||
@@ -304,6 +335,7 @@ async def get_search_results_data(
|
||||
dialog_manager: DialogManager,
|
||||
residents_repository: FromDishka[ResidentsRepository],
|
||||
rooms_repository: FromDishka[RoomsRepository],
|
||||
floors_repository: FromDishka[FloorsRepository],
|
||||
users_repository: FromDishka[UsersRepository],
|
||||
**kwargs,
|
||||
):
|
||||
@@ -329,13 +361,19 @@ async def get_search_results_data(
|
||||
residents_with_rooms = []
|
||||
for resident in residents:
|
||||
room = await rooms_repository.get_room_by_id(resident.room)
|
||||
room_number = room.number if room else 999999
|
||||
residents_with_rooms.append((resident, room_number))
|
||||
if room:
|
||||
floor = await floors_repository.get_floor_by_id(room.on_floor)
|
||||
floor_number = floor.number if floor else 999999
|
||||
room_number = room.number
|
||||
else:
|
||||
floor_number = 999999
|
||||
room_number = 999999
|
||||
residents_with_rooms.append((resident, floor_number, room_number))
|
||||
|
||||
residents_with_rooms.sort(key=lambda x: x[1])
|
||||
residents_with_rooms.sort(key=lambda x: (x[1], x[2]))
|
||||
|
||||
residents_data = []
|
||||
for resident, room_number in residents_with_rooms:
|
||||
for resident, floor_number, room_number in residents_with_rooms:
|
||||
status = "🟢" if resident.is_busy else "⚪️"
|
||||
name = resident.real_name if resident.real_name else "Без имени"
|
||||
|
||||
@@ -430,6 +468,11 @@ resident_info_window = Window(
|
||||
on_click=lambda c, b, m: m.switch_to(AdminMenuSG.resident_logout_confirm),
|
||||
when="is_busy",
|
||||
),
|
||||
Button(
|
||||
Const("🗑 Удалить резидента"),
|
||||
id="delete_resident_btn",
|
||||
on_click=lambda c, b, m: m.switch_to(AdminMenuSG.resident_delete_confirm),
|
||||
),
|
||||
SwitchTo(
|
||||
Const("◀️ Назад к результатам поиска"),
|
||||
id="back_to_search_results",
|
||||
@@ -581,3 +624,22 @@ search_results_window = Window(
|
||||
state=AdminMenuSG.residents_search_results,
|
||||
getter=get_search_results_data,
|
||||
)
|
||||
|
||||
resident_delete_confirm_window = Window(
|
||||
Const(
|
||||
"<blockquote>⚠️ <b>Подтверждение удаления</b></blockquote>\n\nВы уверены, что хотите удалить этого резидента? Это действие необратимо!"
|
||||
),
|
||||
Row(
|
||||
Button(
|
||||
Const("✅ Да, удалить"),
|
||||
id="confirm_delete",
|
||||
on_click=on_delete_resident_confirm,
|
||||
),
|
||||
Button(
|
||||
Const("❌ Отмена"),
|
||||
id="cancel_delete",
|
||||
on_click=on_delete_resident_cancel,
|
||||
),
|
||||
),
|
||||
state=AdminMenuSG.resident_delete_confirm,
|
||||
)
|
||||
|
||||
@@ -0,0 +1,366 @@
|
||||
from aiogram.types import Message, CallbackQuery
|
||||
from aiogram_dialog import Window, DialogManager
|
||||
from aiogram_dialog.widgets.text import Format, Const
|
||||
from aiogram_dialog.widgets.kbd import SwitchTo, Button, ScrollingGroup, Select, Row, Group
|
||||
from aiogram_dialog.widgets.input import MessageInput
|
||||
from dishka import FromDishka
|
||||
from dishka.integrations.aiogram_dialog import inject
|
||||
|
||||
from dutylog.application.bot.user_dialogs.states import AdminMenuSG
|
||||
from dutylog.infrastructure.database.repositories.rooms_repository import (
|
||||
RoomsRepository,
|
||||
)
|
||||
from dutylog.infrastructure.database.repositories.floors_repository import (
|
||||
FloorsRepository,
|
||||
)
|
||||
|
||||
|
||||
async def on_rooms_click(
|
||||
callback: CallbackQuery,
|
||||
button: Button,
|
||||
dialog_manager: DialogManager,
|
||||
):
|
||||
await dialog_manager.switch_to(AdminMenuSG.rooms_select_floor)
|
||||
|
||||
|
||||
@inject
|
||||
async def get_rooms_floors_data(
|
||||
floors_repository: FromDishka[FloorsRepository],
|
||||
**kwargs,
|
||||
):
|
||||
all_floors = await floors_repository.get_all_floors()
|
||||
all_floors.sort(key=lambda f: f.number)
|
||||
|
||||
floors_data = [(f"🏢 Этаж {f.number}", f.id) for f in all_floors]
|
||||
|
||||
content = """
|
||||
<blockquote>🚪 <b>Комнаты</b></blockquote>
|
||||
|
||||
Выберите этаж для просмотра комнат:
|
||||
"""
|
||||
|
||||
return {
|
||||
"content": content,
|
||||
"floors": floors_data,
|
||||
}
|
||||
|
||||
|
||||
async def on_rooms_floor_selected(
|
||||
callback: CallbackQuery,
|
||||
widget: Select,
|
||||
dialog_manager: DialogManager,
|
||||
item_id: str,
|
||||
):
|
||||
dialog_manager.dialog_data["selected_floor_id"] = int(item_id)
|
||||
await dialog_manager.switch_to(AdminMenuSG.rooms_list)
|
||||
|
||||
|
||||
@inject
|
||||
async def get_rooms_list_data(
|
||||
dialog_manager: DialogManager,
|
||||
rooms_repository: FromDishka[RoomsRepository],
|
||||
floors_repository: FromDishka[FloorsRepository],
|
||||
**kwargs,
|
||||
):
|
||||
floor_id = dialog_manager.dialog_data.get("selected_floor_id")
|
||||
|
||||
if not floor_id:
|
||||
return {
|
||||
"content": "Ошибка: этаж не выбран",
|
||||
"rooms": [],
|
||||
"floor_number": "???",
|
||||
}
|
||||
|
||||
floor = await floors_repository.get_floor_by_id(floor_id)
|
||||
floor_number = floor.number if floor else "???"
|
||||
|
||||
rooms = await rooms_repository.get_rooms_by_floor(floor_id)
|
||||
rooms.sort(key=lambda r: r.number)
|
||||
|
||||
rooms_data = [(f"🚪 Комната {r.number}", r.id) for r in rooms]
|
||||
|
||||
content = f"""
|
||||
<blockquote>🚪 <b>Комнаты на этаже {floor_number}</b></blockquote>
|
||||
|
||||
<b>Всего комнат:</b> <code>{len(rooms)}</code>
|
||||
|
||||
Выберите комнату для удаления:
|
||||
"""
|
||||
|
||||
return {
|
||||
"content": content,
|
||||
"rooms": rooms_data,
|
||||
"floor_number": floor_number,
|
||||
}
|
||||
|
||||
|
||||
async def on_room_selected(
|
||||
callback: CallbackQuery,
|
||||
widget: Select,
|
||||
dialog_manager: DialogManager,
|
||||
item_id: str,
|
||||
):
|
||||
dialog_manager.dialog_data["selected_room_id"] = int(item_id)
|
||||
await dialog_manager.switch_to(AdminMenuSG.room_delete_confirm)
|
||||
|
||||
|
||||
async def on_add_room_click(
|
||||
callback: CallbackQuery,
|
||||
button: Button,
|
||||
dialog_manager: DialogManager,
|
||||
):
|
||||
await dialog_manager.switch_to(AdminMenuSG.create_room_select_floor)
|
||||
|
||||
|
||||
@inject
|
||||
async def get_create_room_floors_data(
|
||||
floors_repository: FromDishka[FloorsRepository],
|
||||
**kwargs,
|
||||
):
|
||||
all_floors = await floors_repository.get_all_floors()
|
||||
all_floors.sort(key=lambda f: f.number)
|
||||
|
||||
floors_data = [(f"🏢 Этаж {f.number}", f.id) for f in all_floors]
|
||||
|
||||
content = """
|
||||
<blockquote>➕ <b>Создание комнаты</b></blockquote>
|
||||
|
||||
Выберите этаж для новой комнаты:
|
||||
"""
|
||||
|
||||
return {
|
||||
"content": content,
|
||||
"floors": floors_data,
|
||||
}
|
||||
|
||||
|
||||
async def on_create_room_floor_selected(
|
||||
callback: CallbackQuery,
|
||||
widget: Select,
|
||||
dialog_manager: DialogManager,
|
||||
item_id: str,
|
||||
):
|
||||
dialog_manager.dialog_data["new_room_floor_id"] = int(item_id)
|
||||
await dialog_manager.switch_to(AdminMenuSG.create_room_input)
|
||||
|
||||
|
||||
async def on_room_number_input(
|
||||
message: Message,
|
||||
widget: MessageInput,
|
||||
dialog_manager: DialogManager,
|
||||
):
|
||||
if not message.text:
|
||||
await message.answer("⚠️ Пожалуйста, введите номер комнаты")
|
||||
return
|
||||
|
||||
try:
|
||||
room_number = int(message.text)
|
||||
if room_number <= 0:
|
||||
await message.answer("⚠️ Номер комнаты должен быть положительным числом")
|
||||
return
|
||||
|
||||
dialog_manager.dialog_data["new_room_number"] = room_number
|
||||
await dialog_manager.switch_to(AdminMenuSG.create_room_confirm)
|
||||
except ValueError:
|
||||
await message.answer("⚠️ Пожалуйста, введите корректное число")
|
||||
|
||||
|
||||
async def get_create_room_confirm_data(
|
||||
dialog_manager: DialogManager,
|
||||
**kwargs,
|
||||
):
|
||||
room_number = dialog_manager.dialog_data.get("new_room_number", "???")
|
||||
return {"room_number": room_number}
|
||||
|
||||
|
||||
@inject
|
||||
async def on_create_room_confirm(
|
||||
callback: CallbackQuery,
|
||||
button: Button,
|
||||
dialog_manager: DialogManager,
|
||||
rooms_repository: FromDishka[RoomsRepository],
|
||||
):
|
||||
room_number = dialog_manager.dialog_data.get("new_room_number")
|
||||
floor_id = dialog_manager.dialog_data.get("new_room_floor_id")
|
||||
|
||||
if room_number and floor_id:
|
||||
existing_room = await rooms_repository.get_room_by_number(room_number)
|
||||
if existing_room:
|
||||
await callback.answer(
|
||||
f"⚠️ Комната {room_number} уже существует!",
|
||||
show_alert=True
|
||||
)
|
||||
await dialog_manager.switch_to(AdminMenuSG.rooms_select_floor)
|
||||
return
|
||||
|
||||
await rooms_repository.create_room(room_number, floor_id)
|
||||
await callback.answer("✅ Комната создана!")
|
||||
|
||||
await dialog_manager.switch_to(AdminMenuSG.rooms_select_floor)
|
||||
|
||||
|
||||
async def on_create_room_cancel(
|
||||
callback: CallbackQuery,
|
||||
button: Button,
|
||||
dialog_manager: DialogManager,
|
||||
):
|
||||
await dialog_manager.switch_to(AdminMenuSG.rooms_select_floor)
|
||||
|
||||
|
||||
@inject
|
||||
async def get_room_delete_confirm_data(
|
||||
dialog_manager: DialogManager,
|
||||
rooms_repository: FromDishka[RoomsRepository],
|
||||
**kwargs,
|
||||
):
|
||||
room_id = dialog_manager.dialog_data.get("selected_room_id")
|
||||
|
||||
if not room_id:
|
||||
return {"room_number": "???"}
|
||||
|
||||
room = await rooms_repository.get_room_by_id(room_id)
|
||||
room_number = room.number if room else "???"
|
||||
|
||||
return {"room_number": room_number}
|
||||
|
||||
|
||||
@inject
|
||||
async def on_delete_room_confirm(
|
||||
callback: CallbackQuery,
|
||||
button: Button,
|
||||
dialog_manager: DialogManager,
|
||||
rooms_repository: FromDishka[RoomsRepository],
|
||||
):
|
||||
room_id = dialog_manager.dialog_data.get("selected_room_id")
|
||||
|
||||
if room_id:
|
||||
await rooms_repository.delete_room(room_id)
|
||||
await callback.answer("✅ Комната удалена!")
|
||||
|
||||
await dialog_manager.switch_to(AdminMenuSG.rooms_list)
|
||||
|
||||
|
||||
async def on_delete_room_cancel(
|
||||
callback: CallbackQuery,
|
||||
button: Button,
|
||||
dialog_manager: DialogManager,
|
||||
):
|
||||
await dialog_manager.switch_to(AdminMenuSG.rooms_list)
|
||||
|
||||
|
||||
rooms_select_floor_window = Window(
|
||||
Format("{content}"),
|
||||
Group(
|
||||
Select(
|
||||
Format("{item[0]}"),
|
||||
id="rooms_floors_select",
|
||||
item_id_getter=lambda x: x[1],
|
||||
items="floors",
|
||||
on_click=on_rooms_floor_selected,
|
||||
),
|
||||
width=2,
|
||||
),
|
||||
Button(
|
||||
Const("➕ Добавить комнату"),
|
||||
id="add_room_btn",
|
||||
on_click=on_add_room_click,
|
||||
),
|
||||
SwitchTo(
|
||||
Const("◀️ Назад"),
|
||||
id="back_to_admin_menu_from_rooms",
|
||||
state=AdminMenuSG.main,
|
||||
),
|
||||
state=AdminMenuSG.rooms_select_floor,
|
||||
getter=get_rooms_floors_data,
|
||||
)
|
||||
|
||||
rooms_list_window = Window(
|
||||
Format("{content}"),
|
||||
ScrollingGroup(
|
||||
Select(
|
||||
Format("{item[0]}"),
|
||||
id="rooms_select",
|
||||
item_id_getter=lambda x: x[1],
|
||||
items="rooms",
|
||||
on_click=on_room_selected,
|
||||
),
|
||||
id="rooms_scroll",
|
||||
width=1,
|
||||
height=7,
|
||||
),
|
||||
SwitchTo(
|
||||
Const("◀️ Назад к этажам"),
|
||||
id="back_to_rooms_floors",
|
||||
state=AdminMenuSG.rooms_select_floor,
|
||||
),
|
||||
state=AdminMenuSG.rooms_list,
|
||||
getter=get_rooms_list_data,
|
||||
)
|
||||
|
||||
room_delete_confirm_window = Window(
|
||||
Format("<blockquote>⚠️ <b>Подтверждение удаления</b></blockquote>\n\nВы точно хотите удалить комнату <code>{room_number}</code>? Это действие необратимо и удалит всех резидентов в этой комнате!"),
|
||||
Row(
|
||||
Button(
|
||||
Const("✅ Да, удалить"),
|
||||
id="confirm_delete_room",
|
||||
on_click=on_delete_room_confirm,
|
||||
),
|
||||
Button(
|
||||
Const("❌ Отмена"),
|
||||
id="cancel_delete_room",
|
||||
on_click=on_delete_room_cancel,
|
||||
),
|
||||
),
|
||||
state=AdminMenuSG.room_delete_confirm,
|
||||
getter=get_room_delete_confirm_data,
|
||||
)
|
||||
|
||||
create_room_select_floor_window = Window(
|
||||
Format("{content}"),
|
||||
Group(
|
||||
Select(
|
||||
Format("{item[0]}"),
|
||||
id="create_room_floors_select",
|
||||
item_id_getter=lambda x: x[1],
|
||||
items="floors",
|
||||
on_click=on_create_room_floor_selected,
|
||||
),
|
||||
width=2,
|
||||
),
|
||||
SwitchTo(
|
||||
Const("◀️ Отмена"),
|
||||
id="cancel_create_room_floor",
|
||||
state=AdminMenuSG.rooms_select_floor,
|
||||
),
|
||||
state=AdminMenuSG.create_room_select_floor,
|
||||
getter=get_create_room_floors_data,
|
||||
)
|
||||
|
||||
create_room_input_window = Window(
|
||||
Const("<blockquote>➕ <b>Создание комнаты</b></blockquote>\n\nВведите номер комнаты:"),
|
||||
MessageInput(on_room_number_input),
|
||||
SwitchTo(
|
||||
Const("◀️ Назад"),
|
||||
id="back_to_create_room_floor",
|
||||
state=AdminMenuSG.create_room_select_floor,
|
||||
),
|
||||
state=AdminMenuSG.create_room_input,
|
||||
)
|
||||
|
||||
create_room_confirm_window = Window(
|
||||
Format("<blockquote>✅ <b>Подтверждение</b></blockquote>\n\nСоздать комнату <code>{room_number}</code>?"),
|
||||
Row(
|
||||
Button(
|
||||
Const("✅ Да"),
|
||||
id="confirm_create_room",
|
||||
on_click=on_create_room_confirm,
|
||||
),
|
||||
Button(
|
||||
Const("❌ Нет"),
|
||||
id="cancel_create_room",
|
||||
on_click=on_create_room_cancel,
|
||||
),
|
||||
),
|
||||
state=AdminMenuSG.create_room_confirm,
|
||||
getter=get_create_room_confirm_data,
|
||||
)
|
||||
@@ -17,6 +17,7 @@ class AdminMenuSG(StatesGroup):
|
||||
residents_filtered_results = State()
|
||||
resident_info = State()
|
||||
resident_logout_confirm = State()
|
||||
resident_delete_confirm = State()
|
||||
add_hours_select = State()
|
||||
remove_hours_select = State()
|
||||
add_hours_custom = State()
|
||||
@@ -27,6 +28,16 @@ class AdminMenuSG(StatesGroup):
|
||||
create_resident_floor = State()
|
||||
create_resident_room = State()
|
||||
create_resident_confirm = State()
|
||||
floors = State()
|
||||
floor_delete_confirm = State()
|
||||
create_floor_input = State()
|
||||
create_floor_confirm = State()
|
||||
rooms_select_floor = State()
|
||||
rooms_list = State()
|
||||
room_delete_confirm = State()
|
||||
create_room_select_floor = State()
|
||||
create_room_input = State()
|
||||
create_room_confirm = State()
|
||||
statistics = State()
|
||||
broadcast = State()
|
||||
broadcast_confirm = State()
|
||||
|
||||
@@ -22,5 +22,9 @@ class FloorsRepository:
|
||||
async def get_all_floors(self) -> list[Floor]:
|
||||
return await self.floors_dao.get_all()
|
||||
|
||||
async def create_floor(self, number: int) -> Floor:
|
||||
floor = Floor(number=number)
|
||||
return await self.floors_dao.create(floor)
|
||||
|
||||
async def delete_floor(self, floor_id: int) -> None:
|
||||
await self.floors_dao.delete(floor_id)
|
||||
|
||||
Reference in New Issue
Block a user