import logging from aiogram import F, Router from aiogram.fsm.context import FSMContext from aiogram.types import CallbackQuery, Message from sqlalchemy.ext.asyncio import AsyncSession from dto.catalogue import CategoryActionContext from dto.control import EditProductContext from misc.filters import IsVerified from misc.kb import admins from misc.kb.admins import back_to_product_kb from misc.kb.client import get_back_to_catalogue from misc.mapper import parse_cat_id from misc.states import AdminControlStorage from misc.texts import product_editing_mapping from repositories.categories import CategoriesRepository from repositories.products import ProductRepository logger = logging.getLogger(__name__) router = Router() @router.callback_query(IsVerified(), F.data.regexp(r"^edit_product:\d+:(name|description|price)$")) async def edit_product(cb: CallbackQuery, state: FSMContext): await state.clear() data = cb.data.split(":") product_id = data[1] mode = data[2] if cb.message.photo: await cb.message.delete() msg = await cb.message.answer( f"✍️ Введите {product_editing_mapping.get(mode)}", reply_markup=back_to_product_kb(product_id, cb_factory=lambda p: f"product:{p}"), ) else: msg = cb.message await cb.message.edit_text( f"✍️ Введите {product_editing_mapping.get(mode)}", reply_markup=back_to_product_kb(product_id, cb_factory=lambda p: f"product:{p}"), ) ctx = EditProductContext(int(product_id), mode, msg) await state.set_state(AdminControlStorage.edit_product) await state.set_data({"ctx": ctx}) @router.message(AdminControlStorage.edit_product) async def edit_product_query( msg: Message, state: FSMContext, session: AsyncSession, products_repo: ProductRepository, ): data = await state.get_data() await state.clear() await msg.delete() ctx: EditProductContext = data.get("ctx", EditProductContext) kb = back_to_product_kb(ctx.product_id, cb_factory=lambda p: f"product:{p}") try: await ctx.msg.edit_text("⏳") if ctx.mode == "name": await products_repo.update_product_name_by_id(session, ctx.product_id, msg.text) elif ctx.mode == "description": await products_repo.update_product_description_by_id(session, ctx.product_id, msg.text) elif ctx.mode == "price": if msg.text.isdigit(): await products_repo.update_product_price_by_id( session, ctx.product_id, int(msg.text) ) else: await ctx.msg.edit_text( "❌ Вы ввели не число, попробуйте ещё раз...", reply_markup=kb, ) await state.set_state(AdminControlStorage.edit_product) await state.set_data({"ctx": ctx}) return else: await ctx.msg.edit_text("🍃", reply_markup=kb) return await ctx.msg.edit_text("✅ Изменения применены.", reply_markup=kb) except Exception as e: logger.exception(e) await ctx.msg.edit_text(text="‼️ Что-то пошло не так.", reply_markup=kb) @router.callback_query(IsVerified(), F.data.startswith("edit_product:"), F.data.endswith(":hide")) async def toggle_product_visibility( cb: CallbackQuery, state: FSMContext, session: AsyncSession, products_repo: ProductRepository, ): await state.clear() product_id = int(cb.data.split(":")[1]) product = await products_repo.toggle_product_hidden_by_id(session, product_id) if not product: await cb.answer("Товар не найден.", show_alert=True) return await cb.answer("Товар скрыт." if product.is_hidden else "Товар снова виден.") if cb.message.photo: await cb.message.edit_caption( caption=cb.message.caption, reply_markup=admins.edit_product(product), ) return await cb.message.edit_reply_markup(reply_markup=admins.edit_product(product)) @router.callback_query(F.data.startswith("edit:")) async def edit_entry(cb: CallbackQuery, state: FSMContext): await state.clear() data = cb.data.split(":") mode = data[1] entry_id = data[2] if mode == "category": await cb.message.edit_text( "✍️ Введите новое название категории.", reply_markup=get_back_to_catalogue(entry_id), ) ctx = CategoryActionContext(cb.message, entry_id) await state.set_state(AdminControlStorage.edit_category) await state.set_data({"ctx": ctx}) if mode == "product": ... @router.message(AdminControlStorage.edit_category) async def edit_category( msg: Message, state: FSMContext, session: AsyncSession, categories_repo: CategoriesRepository, ): await msg.delete() data = await state.get_data() await state.clear() ctx: CategoryActionContext | None = data.get("ctx") if not ctx: await msg.answer("❌ Ошибка при редактировании категории.") logger.error("no context found while editing category!") return await ctx.msg.edit_text("⏳") cat = await categories_repo.update_category_name( session=session, category_id=parse_cat_id(ctx.parent_id), value=msg.text ) await ctx.msg.edit_text("✅ Успешно.", reply_markup=get_back_to_catalogue(cat.parent_id))