222 lines
6.1 KiB
Python
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 |