from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.orm import Session from typing import List import uuid from app.db.session import get_db from app.models.cart import Cart, CartItem from app.schemas import ( CartCreate, CartResponse, CartItemCreate, CartItemResponse, CheckoutRequest, CheckoutResponse, ) router = APIRouter() @router.post("/carts/", response_model=CartResponse) def create_cart(cart: CartCreate, db: Session = Depends(get_db)): db_cart = Cart(user_id=cart.user_id) db.add(db_cart) db.commit() db.refresh(db_cart) # Calculate total total = sum(item.price * item.quantity for item in db_cart.items) response = CartResponse.model_validate(db_cart) response.total = total return response @router.get("/carts/{cart_id}", response_model=CartResponse) def get_cart(cart_id: int, db: Session = Depends(get_db)): cart = db.query(Cart).filter(Cart.id == cart_id).first() if cart is None: raise HTTPException(status_code=404, detail="Cart not found") # Calculate total total = sum(item.price * item.quantity for item in cart.items) response = CartResponse.model_validate(cart) response.total = total return response @router.get("/carts/user/{user_id}", response_model=List[CartResponse]) def get_user_carts(user_id: str, db: Session = Depends(get_db)): carts = db.query(Cart).filter(Cart.user_id == user_id).all() response_carts = [] for cart in carts: total = sum(item.price * item.quantity for item in cart.items) cart_response = CartResponse.model_validate(cart) cart_response.total = total response_carts.append(cart_response) return response_carts @router.post("/carts/{cart_id}/items/", response_model=CartItemResponse) def add_item_to_cart(cart_id: int, item: CartItemCreate, db: Session = Depends(get_db)): cart = db.query(Cart).filter(Cart.id == cart_id).first() if cart is None: raise HTTPException(status_code=404, detail="Cart not found") if cart.status != "active": raise HTTPException(status_code=400, detail="Cannot add items to inactive cart") # Check if item already exists in cart existing_item = ( db.query(CartItem) .filter(CartItem.cart_id == cart_id, CartItem.product_id == item.product_id) .first() ) if existing_item: # Update quantity if item exists existing_item.quantity += item.quantity db.commit() db.refresh(existing_item) return CartItemResponse.model_validate(existing_item) else: # Create new item if it doesn't exist db_item = CartItem( cart_id=cart_id, product_id=item.product_id, product_name=item.product_name, price=item.price, quantity=item.quantity, ) db.add(db_item) db.commit() db.refresh(db_item) return CartItemResponse.model_validate(db_item) @router.put("/carts/{cart_id}/items/{item_id}", response_model=CartItemResponse) def update_cart_item( cart_id: int, item_id: int, quantity: int, db: Session = Depends(get_db) ): cart = db.query(Cart).filter(Cart.id == cart_id).first() if cart is None: raise HTTPException(status_code=404, detail="Cart not found") if cart.status != "active": raise HTTPException( status_code=400, detail="Cannot modify items in inactive cart" ) item = ( db.query(CartItem) .filter(CartItem.id == item_id, CartItem.cart_id == cart_id) .first() ) if item is None: raise HTTPException(status_code=404, detail="Cart item not found") if quantity <= 0: db.delete(item) db.commit() return {"message": "Item removed from cart"} else: item.quantity = quantity db.commit() db.refresh(item) return CartItemResponse.model_validate(item) @router.delete("/carts/{cart_id}/items/{item_id}") def remove_item_from_cart(cart_id: int, item_id: int, db: Session = Depends(get_db)): cart = db.query(Cart).filter(Cart.id == cart_id).first() if cart is None: raise HTTPException(status_code=404, detail="Cart not found") if cart.status != "active": raise HTTPException( status_code=400, detail="Cannot remove items from inactive cart" ) item = ( db.query(CartItem) .filter(CartItem.id == item_id, CartItem.cart_id == cart_id) .first() ) if item is None: raise HTTPException(status_code=404, detail="Cart item not found") db.delete(item) db.commit() return {"message": "Item removed from cart"} @router.delete("/carts/{cart_id}") def clear_cart(cart_id: int, db: Session = Depends(get_db)): cart = db.query(Cart).filter(Cart.id == cart_id).first() if cart is None: raise HTTPException(status_code=404, detail="Cart not found") if cart.status != "active": raise HTTPException(status_code=400, detail="Cannot clear inactive cart") # Delete all items in the cart db.query(CartItem).filter(CartItem.cart_id == cart_id).delete() db.commit() return {"message": "Cart cleared successfully"} @router.post("/checkout/", response_model=CheckoutResponse) def checkout(checkout_request: CheckoutRequest, db: Session = Depends(get_db)): cart = db.query(Cart).filter(Cart.id == checkout_request.cart_id).first() if cart is None: raise HTTPException(status_code=404, detail="Cart not found") if cart.status != "active": raise HTTPException(status_code=400, detail="Cart is not active") if not cart.items: raise HTTPException(status_code=400, detail="Cart is empty") # Calculate total total_amount = sum(item.price * item.quantity for item in cart.items) # In a real system, you would process payment here # For now, we'll simulate a successful payment # Generate order ID order_id = str(uuid.uuid4()) # Update cart status to checked_out cart.status = "checked_out" db.commit() return CheckoutResponse( success=True, order_id=order_id, total_amount=total_amount, message="Checkout completed successfully", )