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)