From 7cc194abe576c0c3f295c591c3f1773aa853ad42 Mon Sep 17 00:00:00 2001 From: kolo Date: Wed, 7 Jan 2026 10:58:25 +0300 Subject: [PATCH] update --- .../application/bot/shared_dialogs/states.py | 1 + .../application/bot/shared_dialogs/tests.py | 39 +++++++++++++++++++ .../infrastructure/database/dao/test.py | 2 +- src/quizzi/infrastructure/database/models.py | 7 +++- 4 files changed, 47 insertions(+), 2 deletions(-) diff --git a/src/quizzi/application/bot/shared_dialogs/states.py b/src/quizzi/application/bot/shared_dialogs/states.py index bfc7ac5..50041a2 100644 --- a/src/quizzi/application/bot/shared_dialogs/states.py +++ b/src/quizzi/application/bot/shared_dialogs/states.py @@ -21,6 +21,7 @@ class SharedTestsSG(StatesGroup): statistics = State() attempt_detail = State() export_select_group = State() + delete_confirm = State() class SharedBroadcastSG(StatesGroup): diff --git a/src/quizzi/application/bot/shared_dialogs/tests.py b/src/quizzi/application/bot/shared_dialogs/tests.py index a949384..12d2c97 100644 --- a/src/quizzi/application/bot/shared_dialogs/tests.py +++ b/src/quizzi/application/bot/shared_dialogs/tests.py @@ -299,6 +299,35 @@ async def on_edit_expires(_callback: CallbackQuery, _button: Button, manager: Di await manager.switch_to(SharedTestsSG.edit_expires) +async def on_delete_test(_callback: CallbackQuery, _button: Button, manager: DialogManager): + await manager.switch_to(SharedTestsSG.delete_confirm) + + +@inject +async def get_delete_confirm_data(dialog_manager: DialogManager, test_dao: FromDishka[TestDAO], **_kwargs): + test_id = dialog_manager.dialog_data.get("selected_test_id") + if not test_id: + return {"test_title": "Неизвестный тест"} + + test = await test_dao.get_by_id(test_id) + return {"test_title": test.title if test else "Неизвестный тест"} + + +@inject +async def on_confirm_delete(_callback: CallbackQuery, _button: Button, manager: DialogManager, test_dao: FromDishka[TestDAO]): + test_id = manager.dialog_data.get("selected_test_id") + if not test_id: + await _callback.answer("❌ Тест не найден") + return + + deleted = await test_dao.delete(test_id) + if deleted: + await _callback.answer("✅ Тест удалён") + await manager.switch_to(SharedTestsSG.tests_list) + else: + await _callback.answer("❌ Не удалось удалить тест") + + @inject async def on_password_input(message: Message, _widget: MessageInput, manager: DialogManager, test_dao: FromDishka[TestDAO]): test_id = manager.dialog_data.get("selected_test_id") @@ -689,6 +718,7 @@ shared_tests_dialog = Dialog( Button(Const("⏱️ Лимит времени"), id="edit_time_limit", on_click=on_edit_time_limit), Button(Const("👥 Группа"), id="edit_group", on_click=on_edit_group), Button(Const("📅 Срок действия"), id="edit_expires", on_click=on_edit_expires), + Button(Const("🗑 Удалить тест"), id="delete_test", on_click=on_delete_test), Button(Const("◀️ Назад"), id="back", on_click=on_back_to_detail), ), state=SharedTestsSG.edit_menu, @@ -795,4 +825,13 @@ shared_tests_dialog = Dialog( state=SharedTestsSG.export_select_group, getter=get_groups_for_export, ), + Window( + Format("🗑 Удаление теста\n\n⚠️ Вы уверены, что хотите удалить тест {test_title}?\n\nБудут удалены все вопросы, варианты ответов и результаты прохождений."), + Row( + Button(Const("✅ Да, удалить"), id="confirm_delete", on_click=on_confirm_delete), + Button(Const("❌ Отмена"), id="cancel_delete", on_click=on_back_to_edit_menu), + ), + state=SharedTestsSG.delete_confirm, + getter=get_delete_confirm_data, + ), ) diff --git a/src/quizzi/infrastructure/database/dao/test.py b/src/quizzi/infrastructure/database/dao/test.py index 1fbccf5..44a4069 100644 --- a/src/quizzi/infrastructure/database/dao/test.py +++ b/src/quizzi/infrastructure/database/dao/test.py @@ -41,7 +41,7 @@ class TestDAO: async def get_all(self) -> list[DomainTest]: result = await self.session.execute( - select(Test).order_by(Test.created_at.desc()) + select(Test).order_by(Test.is_active.desc(), Test.created_at.desc()) ) models = list(result.scalars().all()) return [TestDTO(model).to_domain() for model in models] diff --git a/src/quizzi/infrastructure/database/models.py b/src/quizzi/infrastructure/database/models.py index 897905f..68da7c3 100644 --- a/src/quizzi/infrastructure/database/models.py +++ b/src/quizzi/infrastructure/database/models.py @@ -63,6 +63,11 @@ class Test(Base): cascade="all, delete-orphan", order_by="Question.position" ) + + test_attempts: Mapped[list["TestAttempt"]] = relationship( + back_populates="test", + cascade="all, delete-orphan", + ) @final @@ -110,7 +115,7 @@ class TestAttempt(Base): is_passed: Mapped[bool] = mapped_column(default=False) user: Mapped["User"] = relationship() - test: Mapped["Test"] = relationship() + test: Mapped["Test"] = relationship(back_populates="test_attempts") answers: Mapped[list["UserAnswer"]] = relationship( back_populates="attempt", cascade="all, delete-orphan"