import os import logging from re import Match from aiogram import Router, F from aiogram.types import CallbackQuery, FSInputFile from aiogram.exceptions import TelegramBadRequest from aiogram.fsm.context import FSMContext from sqlalchemy.ext.asyncio import AsyncSession from config import VERIFIED_ACCOUNTS from misc.kb import admins from misc.kb.client import ( render_catalogue, render_product_interactions, ) from misc.texts import get_product_description from repositories.products import ProductRepository from services.catalogue import CatalogueService from services.orders import OrderService router = Router() logger = logging.getLogger(__name__) @router.callback_query( F.data.regexp(r"products:(?P.*):(?P\d+)").as_( "pagination_match" ) ) async def products_pagination( cb: CallbackQuery, state: FSMContext, pagination_match: Match[str], session: AsyncSession, catalogue_service: CatalogueService, ): await state.clear() pagination_data = pagination_match.groupdict() category_id = int(pagination_data.get("category_id")) page_id = int(pagination_data.get("page_id", 0)) view = await catalogue_service.build_category_view( session, category_id, page=page_id ) is_admin = cb.from_user.id in VERIFIED_ACCOUNTS kb = render_catalogue(view, is_admin=is_admin) await cb.message.edit_reply_markup(reply_markup=kb) @router.callback_query(F.data.startswith("product:")) async def product_card( cb: CallbackQuery, state: FSMContext, session: AsyncSession, products_repo: ProductRepository, order_service: OrderService, ): await state.clear() product_id = int(cb.data.split(":")[1]) product = await products_repo.get_product_by_id(session, product_id) if cb.from_user.id in VERIFIED_ACCOUNTS: kb = admins.edit_product(product_id=product.id, category_id=product.category_id) else: order_item = await order_service.get_cart_product_amount( session, customer=cb.from_user.id, product_id=product_id ) kb = render_product_interactions( product_id=product.id, category_id=product.category_id, show_cart=bool(order_item), cart_amount=order_item, ) if not product.file_id and not ( product.img_path and os.path.isfile(product.img_path) ): await cb.message.edit_text( get_product_description(product), reply_markup=kb, ) return await cb.message.delete() if product.file_id: msg = await cb.message.answer_photo( product.file_id, caption=get_product_description(product), reply_markup=kb, ) return try: await cb.message.edit_text("⏳ Загружаем карточку товара...") except TelegramBadRequest: ... msg = await cb.message.answer_photo( FSInputFile(product.img_path), caption=get_product_description(product), reply_markup=kb, ) if not msg.photo: logger.warning("didnt get a photo back wahhh :(") return # TODO: Add logging await products_repo.add_product_file_id( session, product_id, file_id=msg.photo[-1].file_id ) @router.callback_query(F.data.startswith("cart_action:")) async def cart_action( cb: CallbackQuery, state: FSMContext, session: AsyncSession, order_service: OrderService, products_repo: ProductRepository, ): await state.clear() action = cb.data.split(":")[1] product_id = int(cb.data.split(":")[2]) product = await products_repo.get_product_by_id(session, product_id) show_cart = True if action == "add": quantity = await order_service.add_to_cart( session, customer=cb.from_user.id, product_id=product_id ) elif action == "remove": quantity = await order_service.remove_from_cart( session, customer=cb.from_user.id, product_id=product_id ) show_cart = bool(quantity) else: show_cart = False quantity = 0 await order_service.clear_from_cart( session, customer=cb.from_user.id, product_id=product_id ) try: await cb.message.edit_reply_markup( reply_markup=render_product_interactions( product_id=product_id, category_id=product.category_id, show_cart=show_cart, cart_amount=quantity, ) ) except Exception as e: await cb.answer("🍃") raise e