from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy.orm import Session from app.db.session import get_db from app.db.models.cart import Cart, CartItem from app.db.models.product import Product from app.db.models.user import User from app.schemas.cart import ( CartResponse, CartItemResponse, AddToCartRequest, CartItemUpdate, CartSummary ) from app.core.security import get_current_active_user router = APIRouter() @router.post("/cart/items/", response_model=CartItemResponse, status_code=status.HTTP_201_CREATED) def add_to_cart( item_in: AddToCartRequest, db: Session = Depends(get_db), current_user: User = Depends(get_current_active_user) ): """ Add an item to the user's cart. """ # Check if product exists and has enough stock product = db.query(Product).filter(Product.id == item_in.product_id).first() if not product: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Product not found" ) if product.stock < item_in.quantity: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Not enough stock available" ) # Get user's active cart or create a new one cart = db.query(Cart).filter(Cart.user_id == current_user.id).first() if not cart: cart = Cart(user_id=current_user.id) db.add(cart) db.commit() db.refresh(cart) # Check if the product is already in the cart cart_item = db.query(CartItem).filter( CartItem.cart_id == cart.id, CartItem.product_id == item_in.product_id ).first() if cart_item: # Update existing cart item quantity new_quantity = cart_item.quantity + item_in.quantity # Check if enough stock if product.stock < new_quantity: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Not enough stock available" ) cart_item.quantity = new_quantity else: # Add new cart item cart_item = CartItem( cart_id=cart.id, product_id=item_in.product_id, user_id=current_user.id, quantity=item_in.quantity, unit_price=product.price ) db.add(cart_item) db.commit() db.refresh(cart_item) return cart_item @router.get("/cart/", response_model=CartResponse) def get_cart( db: Session = Depends(get_db), current_user: User = Depends(get_current_active_user) ): """ Get the current user's cart. """ cart = db.query(Cart).filter(Cart.user_id == current_user.id).first() if not cart: cart = Cart(user_id=current_user.id) db.add(cart) db.commit() db.refresh(cart) return cart @router.get("/cart/summary", response_model=CartSummary) def get_cart_summary( db: Session = Depends(get_db), current_user: User = Depends(get_current_active_user) ): """ Get a summary of the current user's cart. """ cart = db.query(Cart).filter(Cart.user_id == current_user.id).first() if not cart: cart = Cart(user_id=current_user.id) db.add(cart) db.commit() db.refresh(cart) items_count = db.query(CartItem).filter(CartItem.cart_id == cart.id).count() return { "id": cart.id, "total": cart.total, "items_count": items_count } @router.patch("/cart/items/{item_id}", response_model=CartItemResponse) def update_cart_item( item_id: int, item_in: CartItemUpdate, db: Session = Depends(get_db), current_user: User = Depends(get_current_active_user) ): """ Update quantity of an item in the 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" ) if item_in.quantity: if item_in.quantity < 1: # Remove item if quantity is zero or negative db.delete(cart_item) db.commit() raise HTTPException( status_code=status.HTTP_204_NO_CONTENT, detail="Item removed from cart" ) # Check if product has enough stock product = db.query(Product).filter(Product.id == cart_item.product_id).first() if not product: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Product not found" ) if product.stock < 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("/cart/items/{item_id}", status_code=status.HTTP_204_NO_CONTENT, response_model=None) def remove_from_cart( item_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_active_user) ): """ Remove an item from the 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("/cart/", status_code=status.HTTP_204_NO_CONTENT, response_model=None) def clear_cart( db: Session = Depends(get_db), current_user: User = Depends(get_current_active_user) ): """ Clear the user's cart (remove all items). """ cart = db.query(Cart).filter(Cart.user_id == current_user.id).first() if not cart: return None # Delete all cart items db.query(CartItem).filter(CartItem.cart_id == cart.id).delete() db.commit() return None