# app/api/v1/public/vendors/cart.py """ Shopping cart endpoints (customer-facing). """ import logging from fastapi import APIRouter, Depends, Path, Body from sqlalchemy.orm import Session from pydantic import BaseModel, Field from app.core.database import get_db from app.services.cart_service import cart_service from models.database.vendor import Vendor router = APIRouter() logger = logging.getLogger(__name__) class AddToCartRequest(BaseModel): """Request model for adding to cart.""" product_id: int = Field(..., description="Product ID to add") quantity: int = Field(1, ge=1, description="Quantity to add") class UpdateCartItemRequest(BaseModel): """Request model for updating cart item.""" quantity: int = Field(..., ge=1, description="New quantity") @router.get("/{vendor_id}/cart/{session_id}") def get_cart( vendor_id: int = Path(..., description="Vendor ID"), session_id: str = Path(..., description="Session ID"), db: Session = Depends(get_db), ): """ Get shopping cart contents. No authentication required - uses session ID. """ # Verify vendor exists vendor = db.query(Vendor).filter( Vendor.id == vendor_id, Vendor.is_active == True ).first() if not vendor: from app.exceptions import VendorNotFoundException raise VendorNotFoundException(str(vendor_id), identifier_type="id") cart = cart_service.get_cart( db=db, vendor_id=vendor_id, session_id=session_id ) return cart @router.post("/{vendor_id}/cart/{session_id}/items") def add_to_cart( vendor_id: int = Path(..., description="Vendor ID"), session_id: str = Path(..., description="Session ID"), cart_data: AddToCartRequest = Body(...), db: Session = Depends(get_db), ): """ Add product to cart. No authentication required - uses session ID. """ # Verify vendor vendor = db.query(Vendor).filter( Vendor.id == vendor_id, Vendor.is_active == True ).first() if not vendor: from app.exceptions import VendorNotFoundException raise VendorNotFoundException(str(vendor_id), identifier_type="id") result = cart_service.add_to_cart( db=db, vendor_id=vendor_id, session_id=session_id, product_id=cart_data.product_id, quantity=cart_data.quantity ) return result @router.put("/{vendor_id}/cart/{session_id}/items/{product_id}") def update_cart_item( vendor_id: int = Path(..., description="Vendor ID"), session_id: str = Path(..., description="Session ID"), product_id: int = Path(..., description="Product ID"), cart_data: UpdateCartItemRequest = Body(...), db: Session = Depends(get_db), ): """Update cart item quantity.""" # Verify vendor vendor = db.query(Vendor).filter( Vendor.id == vendor_id, Vendor.is_active == True ).first() if not vendor: from app.exceptions import VendorNotFoundException raise VendorNotFoundException(str(vendor_id), identifier_type="id") result = cart_service.update_cart_item( db=db, vendor_id=vendor_id, session_id=session_id, product_id=product_id, quantity=cart_data.quantity ) return result @router.delete("/{vendor_id}/cart/{session_id}/items/{product_id}") def remove_from_cart( vendor_id: int = Path(..., description="Vendor ID"), session_id: str = Path(..., description="Session ID"), product_id: int = Path(..., description="Product ID"), db: Session = Depends(get_db), ): """Remove item from cart.""" # Verify vendor vendor = db.query(Vendor).filter( Vendor.id == vendor_id, Vendor.is_active == True ).first() if not vendor: from app.exceptions import VendorNotFoundException raise VendorNotFoundException(str(vendor_id), identifier_type="id") result = cart_service.remove_from_cart( db=db, vendor_id=vendor_id, session_id=session_id, product_id=product_id ) return result @router.delete("/{vendor_id}/cart/{session_id}") def clear_cart( vendor_id: int = Path(..., description="Vendor ID"), session_id: str = Path(..., description="Session ID"), db: Session = Depends(get_db), ): """Clear all items from cart.""" result = cart_service.clear_cart( db=db, vendor_id=vendor_id, session_id=session_id ) return result