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,11 +1,117 @@
import logging
from sqlalchemy.ext.asyncio import AsyncSession
from db.models.orders import OrderStatus
from repositories.order_items import OrderItemRepository
from repositories.orders import OrderRepository
logger = logging.getLogger(__name__)
class OrderServiceException(Exception): ...
class OrderService:
def __init__(self, order_repo: OrderRepository):
def __init__(
self, order_repo: OrderRepository, order_items_repo: OrderItemRepository
):
self.order_repo = order_repo
self.order_items_repo = order_items_repo
async def get_order_count(self, session: AsyncSession, user_id: int) -> int:
orders = await self.order_repo.get_orders_by_user(session, user_id)
async def get_order_count(self, session: AsyncSession, customer: int) -> int:
orders = await self.order_repo.get_orders_by_user(session, customer)
return len(orders)
async def add_to_cart(
self,
session: AsyncSession,
*,
customer: int,
product_id: int,
quantity: int = 1,
) -> int:
order = await self.order_repo.get_draft_order_by_user(session, customer)
if not order:
order = await self.order_repo.create_order(
session, customer, OrderStatus.DRAFT
)
order_item = await self.order_items_repo.get_item_by_order_and_product(
session, order_id=order.id, product_id=product_id
)
if not order_item:
order_item = await self.order_items_repo.create_order_item(
session, order_id=order.id, product_id=product_id, quantity=quantity
)
else:
await self.order_items_repo.update_order_item_quantity(
session, order_item.id, quantity=order_item.quantity + quantity
)
return order_item.quantity + quantity
async def remove_from_cart(
self,
session: AsyncSession,
*,
customer: int,
product_id: int,
quantity: int = 1,
) -> int:
order = await self.order_repo.get_draft_order_by_user(session, customer)
if not order:
raise OrderServiceException(
"attempt of removing product from non-existing cart, potential callback_query exploit, ignoring..."
)
order_item = await self.order_items_repo.get_item_by_order_and_product(
session, order_id=order.id, product_id=product_id
)
if not order_item:
raise OrderServiceException(
"attempt of decreasing quantity of non-existing order_item, potential callback_query exploit, ignoring..."
)
new_quantity = max(0, order_item.quantity - quantity)
await self.order_items_repo.update_order_item_quantity(
session, order_item_id=order_item.id, quantity=new_quantity
)
return new_quantity
async def get_cart_product_amount(
self, session: AsyncSession, *, customer: int, product_id: 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_item_by_order_and_product(
session, order_id=order.id, product_id=product_id
)
return order_item.quantity
async def clear_cart_item(self, session, *, customer: int, product_id: int) -> None:
order = await self.order_repo.get_draft_order_by_user(session, customer)
if not order:
raise OrderServiceException(
"attempt of clearing a non-existing cart, potential callback_query exploit, ignoring..."
)
order_item = await self.order_items_repo.get_item_by_order_and_product(
session, order_id=order.id, product_id=product_id
)
if not order_item:
raise OrderServiceException(
"attempt of clearing an order_item that isn't in a cart, potential callback_query exploit, ignoring..."
)
await self.order_items_repo.update_order_item_quantity(
session, order_item_id=order_item.id, quantity=0
)