2025-05-18 18:02:59 +00:00

222 lines
6.1 KiB
Python

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