Files
shveitechbot/handlers/client/products.py
2026-03-11 20:26:38 +07:00

161 lines
4.6 KiB
Python

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<category_id>.*):(?P<page_id>\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("<b>⏳ Загружаем карточку товара...</b>")
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