from typing import Any, List from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy.orm import Session from app import schemas from app.api.deps import get_current_active_superuser, get_current_active_user, get_db from app.models.user import User from app.services import cart_service, order_service, product_service router = APIRouter() @router.get("/", response_model=List[schemas.Order]) def read_orders( db: Session = Depends(get_db), skip: int = 0, limit: int = 100, current_user: User = Depends(get_current_active_user), ) -> Any: """ Retrieve user's orders. """ if current_user.is_superuser: orders = order_service.get_multi(db, skip=skip, limit=limit) else: orders = order_service.get_user_orders( db, user_id=current_user.id, skip=skip, limit=limit ) return orders @router.post("/", response_model=schemas.Order) def create_order( *, db: Session = Depends(get_db), order_in: schemas.OrderCreate, current_user: User = Depends(get_current_active_user), ) -> Any: """ Create new order from user's cart. """ # Get user's cart cart_items = cart_service.get_cart_items(db, user_id=current_user.id) if not cart_items: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Cart is empty", ) # Check if all products have enough stock for item in cart_items: product = product_service.get(db, id=item.product_id) if not product or not product.is_active: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=f"Product {item.product_id} is not available", ) if product.stock < item.quantity: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=f"Not enough stock for product {product.name}. Available: {product.stock}", ) # Create order order = order_service.create_from_cart( db, user_id=current_user.id, cart_items=cart_items, shipping_address=order_in.shipping_address ) # Update product stock for item in order.items: product = product_service.get(db, id=item.product_id) product_service.update_stock( db, db_obj=product, new_stock=product.stock - item.quantity ) # Clear user's cart cart_service.clear_cart(db, user_id=current_user.id) return order @router.get("/{id}", response_model=schemas.Order) def read_order( *, db: Session = Depends(get_db), id: int, current_user: User = Depends(get_current_active_user), ) -> Any: """ Get order by ID. """ order = order_service.get(db, id=id) if not order: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Order not found", ) if order.user_id != current_user.id and not current_user.is_superuser: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="Not enough permissions", ) return order @router.put("/{id}/status", response_model=schemas.Order) def update_order_status( *, db: Session = Depends(get_db), id: int, order_in: schemas.OrderUpdate, current_user: User = Depends(get_current_active_superuser), ) -> Any: """ Update order status (admin only). """ order = order_service.get(db, id=id) if not order: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Order not found", ) order = order_service.update(db, db_obj=order, obj_in=order_in) return order