This commit is contained in:
2026-03-01 01:53:17 +03:00
parent 901c0c479e
commit 84df1fe56b
8 changed files with 734 additions and 14 deletions
@@ -8,6 +8,7 @@ from dutylog.application.bot.user_dialogs.admin_dialogs.residents_management imp
residents_list_window, residents_list_window,
resident_info_window, resident_info_window,
resident_logout_confirm_window, resident_logout_confirm_window,
resident_delete_confirm_window,
create_resident_name_window, create_resident_name_window,
create_resident_floor_window, create_resident_floor_window,
create_resident_room_window, create_resident_room_window,
@@ -20,6 +21,20 @@ from dutylog.application.bot.user_dialogs.admin_dialogs.residents_filter import
filter_hours_input_window, filter_hours_input_window,
filtered_results_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 ( from dutylog.application.bot.user_dialogs.admin_dialogs.hours_management import (
add_hours_select_window, add_hours_select_window,
remove_hours_select_window, remove_hours_select_window,
@@ -39,6 +54,7 @@ admin_menu_dialog = Dialog(
residents_list_window, residents_list_window,
resident_info_window, resident_info_window,
resident_logout_confirm_window, resident_logout_confirm_window,
resident_delete_confirm_window,
add_hours_select_window, add_hours_select_window,
remove_hours_select_window, remove_hours_select_window,
add_hours_custom_window, add_hours_custom_window,
@@ -49,6 +65,16 @@ admin_menu_dialog = Dialog(
create_resident_floor_window, create_resident_floor_window,
create_resident_room_window, create_resident_room_window,
create_resident_confirm_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, statistics_window,
broadcast_window, broadcast_window,
broadcast_confirm_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): 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): 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( main_menu_window = Window(
@@ -13,6 +13,9 @@ from dutylog.infrastructure.database.repositories.residents_repository import (
from dutylog.infrastructure.database.repositories.rooms_repository import ( from dutylog.infrastructure.database.repositories.rooms_repository import (
RoomsRepository, RoomsRepository,
) )
from dutylog.infrastructure.database.repositories.floors_repository import (
FloorsRepository,
)
async def on_filter_residents( async def on_filter_residents(
@@ -76,6 +79,7 @@ async def get_filtered_results_data(
dialog_manager: DialogManager, dialog_manager: DialogManager,
residents_repository: FromDishka[ResidentsRepository], residents_repository: FromDishka[ResidentsRepository],
rooms_repository: FromDishka[RoomsRepository], rooms_repository: FromDishka[RoomsRepository],
floors_repository: FromDishka[FloorsRepository],
**kwargs, **kwargs,
): ):
filter_type: str = dialog_manager.dialog_data["filter_type"] filter_type: str = dialog_manager.dialog_data["filter_type"]
@@ -121,13 +125,19 @@ async def get_filtered_results_data(
residents_with_rooms = [] residents_with_rooms = []
for resident in filtered: for resident in filtered:
room = await rooms_repository.get_room_by_id(resident.room) room = await rooms_repository.get_room_by_id(resident.room)
room_number = room.number if room else 999999 if room:
residents_with_rooms.append((resident, room_number)) 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 = [] 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 "⚪️" status = "🟢" if resident.is_busy else "⚪️"
name = resident.real_name if resident.real_name 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( async def get_residents_list_data(
residents_repository: FromDishka[ResidentsRepository], residents_repository: FromDishka[ResidentsRepository],
rooms_repository: FromDishka[RoomsRepository], rooms_repository: FromDishka[RoomsRepository],
floors_repository: FromDishka[FloorsRepository],
**kwargs, **kwargs,
): ):
all_residents = await residents_repository.get_all_residents() all_residents = await residents_repository.get_all_residents()
@@ -33,13 +34,19 @@ async def get_residents_list_data(
residents_with_rooms = [] residents_with_rooms = []
for resident in all_residents: for resident in all_residents:
room = await rooms_repository.get_room_by_id(resident.room) room = await rooms_repository.get_room_by_id(resident.room)
room_number = room.number if room else 999999 if room:
residents_with_rooms.append((resident, room_number)) 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 = [] 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 "⚪️" status = "🟢" if resident.is_busy else "⚪️"
name = resident.real_name if resident.real_name 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) 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( async def on_resident_name_input(
message: Message, message: Message,
widget: MessageInput, widget: MessageInput,
@@ -304,6 +335,7 @@ async def get_search_results_data(
dialog_manager: DialogManager, dialog_manager: DialogManager,
residents_repository: FromDishka[ResidentsRepository], residents_repository: FromDishka[ResidentsRepository],
rooms_repository: FromDishka[RoomsRepository], rooms_repository: FromDishka[RoomsRepository],
floors_repository: FromDishka[FloorsRepository],
users_repository: FromDishka[UsersRepository], users_repository: FromDishka[UsersRepository],
**kwargs, **kwargs,
): ):
@@ -329,13 +361,19 @@ async def get_search_results_data(
residents_with_rooms = [] residents_with_rooms = []
for resident in residents: for resident in residents:
room = await rooms_repository.get_room_by_id(resident.room) room = await rooms_repository.get_room_by_id(resident.room)
room_number = room.number if room else 999999 if room:
residents_with_rooms.append((resident, room_number)) 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 = [] 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 "⚪️" status = "🟢" if resident.is_busy else "⚪️"
name = resident.real_name if resident.real_name 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), on_click=lambda c, b, m: m.switch_to(AdminMenuSG.resident_logout_confirm),
when="is_busy", when="is_busy",
), ),
Button(
Const("🗑 Удалить резидента"),
id="delete_resident_btn",
on_click=lambda c, b, m: m.switch_to(AdminMenuSG.resident_delete_confirm),
),
SwitchTo( SwitchTo(
Const("◀️ Назад к результатам поиска"), Const("◀️ Назад к результатам поиска"),
id="back_to_search_results", id="back_to_search_results",
@@ -581,3 +624,22 @@ search_results_window = Window(
state=AdminMenuSG.residents_search_results, state=AdminMenuSG.residents_search_results,
getter=get_search_results_data, 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() residents_filtered_results = State()
resident_info = State() resident_info = State()
resident_logout_confirm = State() resident_logout_confirm = State()
resident_delete_confirm = State()
add_hours_select = State() add_hours_select = State()
remove_hours_select = State() remove_hours_select = State()
add_hours_custom = State() add_hours_custom = State()
@@ -27,6 +28,16 @@ class AdminMenuSG(StatesGroup):
create_resident_floor = State() create_resident_floor = State()
create_resident_room = State() create_resident_room = State()
create_resident_confirm = 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() statistics = State()
broadcast = State() broadcast = State()
broadcast_confirm = State() broadcast_confirm = State()
@@ -22,5 +22,9 @@ class FloorsRepository:
async def get_all_floors(self) -> list[Floor]: async def get_all_floors(self) -> list[Floor]:
return await self.floors_dao.get_all() 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: async def delete_floor(self, floor_id: int) -> None:
await self.floors_dao.delete(floor_id) await self.floors_dao.delete(floor_id)