from typing import Any, List from fastapi import APIRouter, Depends, HTTPException, Path, status from sqlalchemy.orm import Session from app.core.deps import get_current_active_user from app.db.session import get_db from app.models.order import OrderStatus from app.models.user import User from app.schemas.order import Order, OrderCreate, OrderItem, OrderUpdate from app.services import order as order_service router = APIRouter() @router.get("/", response_model=List[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 orders. """ if not current_user.is_superuser: # Regular users can only see their own orders orders = order_service.get_multi( db, skip=skip, limit=limit, user_id=current_user.id ) else: # Superusers can see all orders orders = order_service.get_multi(db, skip=skip, limit=limit) return orders @router.post("/", response_model=Order) def create_order( *, db: Session = Depends(get_db), order_in: OrderCreate, current_user: User = Depends(get_current_active_user), ) -> Any: """ Create new order. """ # Regular users can only create orders for themselves if not current_user.is_superuser and order_in.user_id != current_user.id: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="You can only create orders for yourself", ) try: order = order_service.create(db, obj_in=order_in) return order except ValueError as e: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=str(e), ) @router.get("/{order_id}", response_model=Order) def read_order( *, db: Session = Depends(get_db), order_id: int = Path(..., description="The ID of the order to get"), current_user: User = Depends(get_current_active_user), ) -> Any: """ Get order by ID. """ order = order_service.get(db, order_id=order_id) if not order: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Order not found", ) # Regular users can only see their own orders if not current_user.is_superuser and order.user_id != current_user.id: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="Not enough permissions", ) return order @router.put("/{order_id}", response_model=Order) def update_order( *, db: Session = Depends(get_db), order_id: int = Path(..., description="The ID of the order to update"), order_in: OrderUpdate, current_user: User = Depends(get_current_active_user), ) -> Any: """ Update an order. """ order = order_service.get(db, order_id=order_id) if not order: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Order not found", ) # Regular users can only update their own orders if not current_user.is_superuser and order.user_id != current_user.id: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="Not enough permissions", ) # Regular users cannot update orders that are already shipped or delivered if not current_user.is_superuser and order.status in [OrderStatus.SHIPPED, OrderStatus.DELIVERED]: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Cannot update an order that has already been shipped or delivered", ) order = order_service.update(db, db_obj=order, obj_in=order_in) return order @router.put("/{order_id}/status", response_model=Order) def update_order_status( *, db: Session = Depends(get_db), order_id: int = Path(..., description="The ID of the order to update"), status: OrderStatus, current_user: User = Depends(get_current_active_user), ) -> Any: """ Update order status. """ order = order_service.get(db, order_id=order_id) if not order: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Order not found", ) # Only superusers can change order status if not current_user.is_superuser: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="Not enough permissions", ) order = order_service.update_status(db, order_id=order_id, status=status) return order @router.delete("/{order_id}/cancel", response_model=Order) def cancel_order( *, db: Session = Depends(get_db), order_id: int = Path(..., description="The ID of the order to cancel"), current_user: User = Depends(get_current_active_user), ) -> Any: """ Cancel an order if it hasn't been shipped yet. """ order = order_service.get(db, order_id=order_id) if not order: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Order not found", ) # Regular users can only cancel their own orders if not current_user.is_superuser and order.user_id != current_user.id: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="Not enough permissions", ) try: order = order_service.cancel_order(db, order_id=order_id) return order except ValueError as e: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=str(e), ) @router.get("/{order_id}/items", response_model=List[OrderItem]) def read_order_items( *, db: Session = Depends(get_db), order_id: int = Path(..., description="The ID of the order to get items for"), current_user: User = Depends(get_current_active_user), ) -> Any: """ Get all items for a specific order. """ order = order_service.get(db, order_id=order_id) if not order: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Order not found", ) # Regular users can only see their own orders' items if not current_user.is_superuser and order.user_id != current_user.id: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="Not enough permissions", ) items = order_service.get_order_items(db, order_id=order_id) return items