2025-06-02 11:37:11 +00:00

215 lines
6.5 KiB
Python

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