Fixed type hints, added cart item counter on main

This commit is contained in:
2026-02-08 13:31:28 +07:00
parent 9e96da8f53
commit e8a61c05b3
5 changed files with 57 additions and 16 deletions

View File

@@ -16,4 +16,4 @@ POSTGRES_URL = os.getenv(
### Constants ### ### Constants ###
PAGE_SIZE = 5 PAGE_SIZE = 6

View File

@@ -22,20 +22,29 @@ router = Router()
@router.message(Command("start")) @router.message(Command("start"))
async def main_menu(msg: Message, state: FSMContext): async def main_menu(
msg: Message, state: FSMContext, session: AsyncSession, order_service: OrderService
):
await state.clear() await state.clear()
cart_items = await order_service.get_cart_items_count(session, msg.from_user.id)
await msg.answer( await msg.answer(
"hii!", reply_markup=main_menu_kb(msg.from_user.id) "hii!", reply_markup=main_menu_kb(cart_items)
) # TODO: Write a welcome message ) # TODO: Write a welcome message
@router.callback_query(F.data.startswith("menu:")) @router.callback_query(F.data.startswith("menu:"))
async def main_menu_cb(cb: CallbackQuery, state: FSMContext): async def main_menu_cb(
cb: CallbackQuery,
state: FSMContext,
session: AsyncSession,
order_service: OrderService,
):
await state.clear() await state.clear()
cart_items = await order_service.get_cart_items_count(session, cb.from_user.id)
await cb.message.edit_text( await cb.message.edit_text(
"hii!", reply_markup=main_menu_kb(cb.from_user.id) "hii!", reply_markup=main_menu_kb(cart_items)
) # TODO: Write a welcome message ) # TODO: Write a welcome message
@@ -198,8 +207,16 @@ async def product_card(
return return
if not os.path.isfile(product.img_path): if not os.path.isfile(product.img_path):
await cb.answer("something has gone wrong, try again later...") await cb.message.edit_text(
return # TODO: Add logging + Admin notifications 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
await cb.message.delete() await cb.message.delete()
msg = await cb.message.answer_photo( msg = await cb.message.answer_photo(

View File

@@ -7,10 +7,10 @@ from db.models import Category
from db.models.products import Product from db.models.products import Product
def cart_btn(user_id: int) -> InlineKeyboardButton: def cart_btn(cart_items: int) -> InlineKeyboardButton:
return InlineKeyboardButton( return InlineKeyboardButton(
text="🛒 Корзина ()", callback_data="cart" text=f"🛒 Корзина ({cart_items})", callback_data="cart"
) # TODO: Database integration, get cart items count )
def get_back_to_catalogue( def get_back_to_catalogue(
@@ -21,14 +21,14 @@ def get_back_to_catalogue(
).as_markup() ).as_markup()
def main_menu_kb(user_id: int) -> InlineKeyboardMarkup: def main_menu_kb(cart_items: int) -> InlineKeyboardMarkup:
return InlineKeyboardBuilder( return InlineKeyboardBuilder(
[ [
[ [
InlineKeyboardButton(text="📦 Каталог", callback_data="cat:root"), InlineKeyboardButton(text="📦 Каталог", callback_data="cat:root"),
InlineKeyboardButton(text="🔍", callback_data="find"), InlineKeyboardButton(text="🔍", callback_data="find"),
], ],
[cart_btn(user_id)], [cart_btn(cart_items)],
] ]
).as_markup() ).as_markup()
@@ -71,7 +71,7 @@ def render_products(
show_next: Optional[bool] = False, show_next: Optional[bool] = False,
) -> InlineKeyboardMarkup: ) -> InlineKeyboardMarkup:
btns = [ btns = [
[InlineKeyboardButton(text=product.name, callback_data=f"product:{product.id}")] InlineKeyboardButton(text=product.name, callback_data=f"product:{product.id}")
for product in products for product in products
] ]
@@ -102,7 +102,7 @@ def render_products(
) )
] ]
] ]
+ btns + [btns[i : i + 2] for i in range(0, len(products), 2)]
+ [nav] + [nav]
).as_markup() ).as_markup()

View File

@@ -2,7 +2,7 @@ from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, update from sqlalchemy import select, update
from typing import Optional from typing import Optional
from db.models.orders import OrderItem from db.models.orders import Order, OrderItem
class OrderItemRepository: class OrderItemRepository:
@@ -12,6 +12,14 @@ class OrderItemRepository:
stmt = select(OrderItem).where(OrderItem.id == item_id) stmt = select(OrderItem).where(OrderItem.id == item_id)
return await session.scalar(stmt) return await session.scalar(stmt)
async def get_items_by_order(
self, session: AsyncSession, order_id: int
) -> list[OrderItem]:
stmt = select(OrderItem).where(OrderItem.order_id == order_id)
result = await session.scalars(stmt)
return list(result)
async def get_item_by_order_and_product( async def get_item_by_order_and_product(
self, session: AsyncSession, *, order_id: int, product_id: int self, session: AsyncSession, *, order_id: int, product_id: int
) -> Optional[OrderItem]: ) -> Optional[OrderItem]:

View File

@@ -93,9 +93,15 @@ class OrderService:
order_item = await self.order_items_repo.get_item_by_order_and_product( order_item = await self.order_items_repo.get_item_by_order_and_product(
session, order_id=order.id, product_id=product_id session, order_id=order.id, product_id=product_id
) )
if not order_item:
return 0
return order_item.quantity return order_item.quantity
async def clear_cart_item(self, session, *, customer: int, product_id: int) -> None: async def clear_cart_item(
self, session: AsyncSession, *, customer: int, product_id: int
) -> None:
order = await self.order_repo.get_draft_order_by_user(session, customer) order = await self.order_repo.get_draft_order_by_user(session, customer)
if not order: if not order:
@@ -115,3 +121,13 @@ class OrderService:
await self.order_items_repo.update_order_item_quantity( await self.order_items_repo.update_order_item_quantity(
session, order_item_id=order_item.id, quantity=0 session, order_item_id=order_item.id, quantity=0
) )
async def get_cart_items_count(self, session: AsyncSession, customer: int) -> int:
order = await self.order_repo.get_draft_order_by_user(session, customer)
if not order:
return 0
order_item = await self.order_items_repo.get_items_by_order(
session, order_id=order.id
)
return len(order_item)