from typing import Any, Dict from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.orm import Session from app.core.deps import get_current_active_user, get_db from app.models.user import User from app.schemas.cart import Cart, CartItem, CartItemCreate, CartItemUpdate from app.services import cart as cart_service from app.services import product as product_service router = APIRouter() @router.get("/", response_model=Cart) def read_cart( db: Session = Depends(get_db), current_user: User = Depends(get_current_active_user), ) -> Any: """ Get current user's cart """ cart = cart_service.get_by_user_id(db, user_id=current_user.id) if not cart: # Create a new cart if it doesn't exist cart = cart_service.ensure_cart_exists(db, user_id=current_user.id) return cart @router.post("/items", response_model=CartItem) def add_cart_item( *, db: Session = Depends(get_db), item_in: CartItemCreate, current_user: User = Depends(get_current_active_user), ) -> Any: """ Add item to cart """ # Verify product exists and is active product = product_service.get_by_id(db, product_id=item_in.product_id) if not product or not product.is_active: raise HTTPException( status_code=404, detail="Product not found or unavailable", ) # Check stock if product.stock < item_in.quantity: raise HTTPException( status_code=400, detail=f"Not enough stock. Available: {product.stock}", ) # Ensure cart exists cart = cart_service.ensure_cart_exists(db, user_id=current_user.id) # Add item to cart cart_item = cart_service.add_to_cart(db, cart_id=cart.id, obj_in=item_in) return cart_item @router.put("/items/{item_id}", response_model=CartItem) def update_cart_item( *, db: Session = Depends(get_db), item_id: str, item_in: CartItemUpdate, current_user: User = Depends(get_current_active_user), ) -> Any: """ Update cart item quantity """ # Ensure cart exists cart = cart_service.ensure_cart_exists(db, user_id=current_user.id) # Verify cart item exists and belongs to current user's cart cart_item = db.query(Cart).filter( Cart.id == cart.id ).join( CartItem, CartItem.cart_id == Cart.id ).filter( CartItem.id == item_id ).first() if not cart_item: raise HTTPException( status_code=404, detail="Cart item not found", ) # Check product stock product = product_service.get_by_id(db, product_id=cart_item.product_id) if product.stock < item_in.quantity: raise HTTPException( status_code=400, detail=f"Not enough stock. Available: {product.stock}", ) # Update cart item updated_item = cart_service.update_cart_item(db, item_id=item_id, obj_in=item_in) return updated_item @router.delete("/items/{item_id}", response_model=Dict[str, str]) def delete_cart_item( *, db: Session = Depends(get_db), item_id: str, current_user: User = Depends(get_current_active_user), ) -> Any: """ Remove item from cart """ # Ensure cart exists cart = cart_service.ensure_cart_exists(db, user_id=current_user.id) # Verify cart item exists and belongs to current user's cart cart_item = db.query(Cart).filter( Cart.id == cart.id ).join( CartItem, CartItem.cart_id == Cart.id ).filter( CartItem.id == item_id ).first() if not cart_item: raise HTTPException( status_code=404, detail="Cart item not found", ) # Remove item from cart cart_service.remove_from_cart(db, item_id=item_id) return {"status": "success", "message": "Item removed from cart"} @router.delete("/", response_model=Dict[str, str]) def clear_cart( db: Session = Depends(get_db), current_user: User = Depends(get_current_active_user), ) -> Any: """ Clear cart """ # Ensure cart exists cart = cart_service.ensure_cart_exists(db, user_id=current_user.id) # Clear cart cart_service.clear_cart(db, cart_id=cart.id) return {"status": "success", "message": "Cart cleared"}