133 lines
3.9 KiB
Python

from typing import Any, List
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session
from app import schemas
from app.api.deps import get_current_active_user, get_db
from app.models.user import User
from app.services import cart_service, product_service
router = APIRouter()
@router.get("/", response_model=schemas.CartSummary)
def read_cart(
db: Session = Depends(get_db),
current_user: User = Depends(get_current_active_user),
) -> Any:
"""
Retrieve user's cart.
"""
cart_items = cart_service.get_cart_items(db, user_id=current_user.id)
total = sum(item.unit_price * item.quantity for item in cart_items)
return {"items": cart_items, "total": total}
@router.post("/items", response_model=schemas.CartItem)
def add_cart_item(
*,
db: Session = Depends(get_db),
item_in: schemas.CartItemCreate,
current_user: User = Depends(get_current_active_user),
) -> Any:
"""
Add item to cart.
"""
# Check if product exists and is in stock
product = product_service.get(db, id=item_in.product_id)
if not product:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Product not found",
)
if not product.is_active:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Product is not available",
)
if product.stock < item_in.quantity:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail=f"Not enough stock. Available: {product.stock}",
)
# Check if item already in cart
existing_item = cart_service.get_cart_item(
db, user_id=current_user.id, product_id=item_in.product_id
)
if existing_item:
# Update quantity if already in cart
return cart_service.update_item_quantity(
db,
db_obj=existing_item,
quantity=existing_item.quantity + item_in.quantity
)
# Add new item to cart
return cart_service.add_item_to_cart(
db,
obj_in=item_in,
user_id=current_user.id,
unit_price=product.price
)
@router.put("/items/{item_id}", response_model=schemas.CartItem)
def update_cart_item(
*,
db: Session = Depends(get_db),
item_id: int,
item_in: schemas.CartItemUpdate,
current_user: User = Depends(get_current_active_user),
) -> Any:
"""
Update cart item quantity.
"""
cart_item = cart_service.get(db, id=item_id)
if not cart_item or cart_item.user_id != current_user.id:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Cart item not found",
)
# Check if product has enough stock
product = product_service.get(db, id=cart_item.product_id)
if product.stock < item_in.quantity:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail=f"Not enough stock. Available: {product.stock}",
)
cart_item = cart_service.update_item_quantity(
db, db_obj=cart_item, quantity=item_in.quantity
)
return cart_item
@router.delete("/items/{item_id}", response_model=schemas.CartItem)
def remove_cart_item(
*,
db: Session = Depends(get_db),
item_id: int,
current_user: User = Depends(get_current_active_user),
) -> Any:
"""
Remove item from cart.
"""
cart_item = cart_service.get(db, id=item_id)
if not cart_item or cart_item.user_id != current_user.id:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Cart item not found",
)
cart_item = cart_service.remove(db, id=item_id)
return cart_item
@router.delete("/", response_model=List[schemas.CartItem])
def clear_cart(
db: Session = Depends(get_db),
current_user: User = Depends(get_current_active_user),
) -> Any:
"""
Clear user's cart.
"""
return cart_service.clear_cart(db, user_id=current_user.id)