from typing import Any, List from fastapi import APIRouter, Depends, HTTPException, Body from sqlalchemy.orm import Session from app import crud, models, schemas from app.api import deps from app.models.order import OrderStatus router = APIRouter() @router.get("/", response_model=List[schemas.Order]) def read_orders( db: Session = Depends(deps.get_db), skip: int = 0, limit: int = 100, status: OrderStatus = None, current_user: models.User = Depends(deps.get_current_active_user), ) -> Any: """ Retrieve orders. """ if crud.user.is_superuser(current_user): if status: orders = crud.order.get_by_status(db, status=status, skip=skip, limit=limit) else: orders = crud.order.get_multi(db, skip=skip, limit=limit) else: orders = crud.order.get_by_user(db, user_id=current_user.id, skip=skip, limit=limit) if status: orders = [order for order in orders if order.status == status] return orders @router.post("/", response_model=schemas.Order) def create_order( *, db: Session = Depends(deps.get_db), order_in: schemas.OrderCreate, current_user: models.User = Depends(deps.get_current_active_user), ) -> Any: """ Create new order. """ # Verify all products exist for item in order_in.order_items: product = crud.product.get(db, id=item.product_id) if not product: raise HTTPException( status_code=404, detail=f"Product with id {item.product_id} not found" ) # Check if there's enough inventory inventory = crud.inventory.get_by_product(db, product_id=item.product_id) if inventory and inventory.quantity < item.quantity: raise HTTPException( status_code=400, detail=f"Not enough stock for product {product.name}. Available: {inventory.quantity}" ) # Create order order = crud.order.create(db, obj_in=order_in, user_id=current_user.id) # Update inventory for item in order_in.order_items: inventory = crud.inventory.get_by_product(db, product_id=item.product_id) if inventory: crud.inventory.update_quantity(db, item_id=inventory.id, quantity_change=-item.quantity) return order @router.put("/{id}/status", response_model=schemas.Order) def update_order_status( *, db: Session = Depends(deps.get_db), id: int, status: OrderStatus = Body(..., embed=True), current_user: models.User = Depends(deps.get_current_active_user), ) -> Any: """ Update order status. """ order = crud.order.get(db, id=id) if not order: raise HTTPException(status_code=404, detail="Order not found") # Only superusers can update orders they don't own if order.user_id != current_user.id and not crud.user.is_superuser(current_user): raise HTTPException(status_code=403, detail="Not enough permissions") order_in = schemas.OrderUpdate(status=status) order = crud.order.update(db, db_obj=order, obj_in=order_in) return order @router.get("/{id}", response_model=schemas.Order) def read_order( *, db: Session = Depends(deps.get_db), id: int, current_user: models.User = Depends(deps.get_current_active_user), ) -> Any: """ Get order by ID. """ order = crud.order.get(db, id=id) if not order: raise HTTPException(status_code=404, detail="Order not found") # Only superusers can view orders they don't own if order.user_id != current_user.id and not crud.user.is_superuser(current_user): raise HTTPException(status_code=403, detail="Not enough permissions") return order @router.delete("/{id}", response_model=schemas.Order) def delete_order( *, db: Session = Depends(deps.get_db), id: int, current_user: models.User = Depends(deps.get_current_active_superuser), ) -> Any: """ Delete an order. """ order = crud.order.get(db, id=id) if not order: raise HTTPException(status_code=404, detail="Order not found") order = crud.order.remove(db, id=id) return order