Fixed type hints, added cart item counter on main
This commit is contained in:
@@ -16,4 +16,4 @@ POSTGRES_URL = os.getenv(
|
|||||||
|
|
||||||
### Constants ###
|
### Constants ###
|
||||||
|
|
||||||
PAGE_SIZE = 5
|
PAGE_SIZE = 6
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|
||||||
|
|||||||
@@ -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]:
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user