2025-06-04 22:37:35 +00:00

172 lines
4.6 KiB
Python

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