from typing import Any from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy.orm import Session from app.api.deps import get_current_user from app.db.session import get_db from app.models.cart import CartItem from app.models.product import Product from app.models.user import User from app.schemas.cart import Cart, CartItem as CartItemSchema from app.schemas.cart import CartItemCreate, CartItemUpdate router = APIRouter() @router.get("/", response_model=Cart) def read_cart( db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ) -> Any: """ Retrieve current user's cart. """ cart_items = db.query(CartItem).filter(CartItem.user_id == current_user.id).all() # Calculate total total = 0.0 for item in cart_items: product = db.query(Product).filter(Product.id == item.product_id).first() if product: total += product.price * item.quantity return { "items": cart_items, "total": total, } @router.post("/items", response_model=CartItemSchema) def add_to_cart( *, db: Session = Depends(get_db), item_in: CartItemCreate, current_user: User = Depends(get_current_user), ) -> Any: """ Add item to cart. """ # Check if product exists and is active product = db.query(Product).filter(Product.id == item_in.product_id).first() if not product or not product.is_active: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Product not found", ) # Check if product has enough stock if product.stock_quantity < item_in.quantity: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Not enough stock available", ) # Check if item is already in cart cart_item = db.query(CartItem).filter( CartItem.user_id == current_user.id, CartItem.product_id == item_in.product_id, ).first() if cart_item: # Update quantity cart_item.quantity += item_in.quantity db.add(cart_item) db.commit() db.refresh(cart_item) return cart_item # Create new cart item cart_item = CartItem( user_id=current_user.id, product_id=item_in.product_id, quantity=item_in.quantity, ) db.add(cart_item) db.commit() db.refresh(cart_item) return cart_item @router.put("/items/{item_id}", response_model=CartItemSchema) def update_cart_item( *, db: Session = Depends(get_db), item_id: str, item_in: CartItemUpdate, current_user: User = Depends(get_current_user), ) -> Any: """ Update cart item quantity. """ cart_item = db.query(CartItem).filter( CartItem.id == item_id, CartItem.user_id == current_user.id, ).first() if not cart_item: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Cart item not found", ) # Check if product has enough stock product = db.query(Product).filter(Product.id == cart_item.product_id).first() if not product or not product.is_active: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Product not found", ) if product.stock_quantity < item_in.quantity: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Not enough stock available", ) cart_item.quantity = item_in.quantity db.add(cart_item) db.commit() db.refresh(cart_item) return cart_item @router.delete("/items/{item_id}", status_code=status.HTTP_204_NO_CONTENT, response_model=None) def remove_cart_item( *, db: Session = Depends(get_db), item_id: str, current_user: User = Depends(get_current_user), ) -> Any: """ Remove item from cart. """ cart_item = db.query(CartItem).filter( CartItem.id == item_id, CartItem.user_id == current_user.id, ).first() if not cart_item: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Cart item not found", ) db.delete(cart_item) db.commit() return None @router.delete("/", status_code=status.HTTP_204_NO_CONTENT, response_model=None) def clear_cart( db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ) -> Any: """ Clear cart. """ db.query(CartItem).filter(CartItem.user_id == current_user.id).delete() db.commit() return None