Product rendering, cart functionality

This commit is contained in:
2026-02-08 12:40:04 +07:00
parent d8cad25f33
commit 9e96da8f53
9 changed files with 399 additions and 14 deletions

View File

@@ -1,13 +1,19 @@
import os
from re import Match
from aiogram import Router, F
from aiogram.types import CallbackQuery, Message
from aiogram.types import CallbackQuery, FSInputFile, Message
from aiogram.filters import Command
from aiogram.fsm.context import FSMContext
from sqlalchemy.ext.asyncio import AsyncSession
from config import PAGE_SIZE
from misc.kb import main_menu_kb, render_category
from misc.kb.client import get_back_to_catalogue, render_products
from misc.kb.client import (
get_back_to_catalogue,
render_product_interactions,
render_products,
)
from misc.texts import get_product_description
from repositories.categories import CategoriesRepository
from repositories.products import ProductRepository
from services.orders import OrderService
@@ -86,10 +92,26 @@ async def subcatalogue(
)
return
if cb.message.photo:
await cb.message.delete()
await cb.message.answer(
"hya",
reply_markup=render_products(
products[:PAGE_SIZE],
parent_id=parent_id,
cat_id=cat_id,
page=0,
show_prev=products_len < 0,
show_next=products_len > PAGE_SIZE,
),
)
return
await cb.message.edit_text(
"hya",
reply_markup=render_products(
products[:PAGE_SIZE],
parent_id=parent_id,
cat_id=cat_id,
page=0,
show_prev=products_len < 0,
@@ -117,11 +139,13 @@ async def products_pagination(
pagination_match: Match[str],
session: AsyncSession,
products_repo: ProductRepository,
categories_repo: CategoriesRepository,
):
await state.clear()
pagination_data = pagination_match.groupdict()
category_id = int(pagination_data.get("category_id"))
category = await categories_repo.get_category_by_id(session, category_id)
page_id = int(pagination_data.get("page_id", 0))
products = await products_repo.get_product_by_category(
@@ -132,9 +156,108 @@ async def products_pagination(
await cb.message.edit_reply_markup(
reply_markup=render_products(
products[:PAGE_SIZE],
parent_id=category.parent_id,
cat_id=category_id,
page=page_id,
show_prev=page_id > 0,
show_next=products_len > PAGE_SIZE,
),
)
@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)
order_item = await order_service.get_cart_product_amount(
session, customer=cb.from_user.id, product_id=product_id
)
if product.file_id:
await cb.message.delete()
msg = await cb.message.answer_photo(
product.file_id,
caption=get_product_description(product),
reply_markup=render_product_interactions(
product_id=product.id,
category_id=product.category_id,
show_cart=bool(order_item),
cart_amount=order_item,
),
)
return
if not os.path.isfile(product.img_path):
await cb.answer("something has gone wrong, try again later...")
return # TODO: Add logging + Admin notifications
await cb.message.delete()
msg = await cb.message.answer_photo(
FSInputFile(product.img_path),
caption=get_product_description(product),
reply_markup=render_product_interactions(
product_id=product.id,
category_id=product.category_id,
show_cart=bool(order_item),
cart_amount=order_item,
),
)
if not msg.photo:
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 add_to_cart(
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
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:
await cb.answer("🍃 Корзина уже пуста.")
return