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

190 lines
5.8 KiB
Python

from typing import Any, List
from fastapi import APIRouter, Depends, HTTPException, Path, Query, 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.shipment import ShipmentStatus
from app.models.user import User
from app.schemas.shipment import (
Shipment,
ShipmentCreate,
ShipmentItem,
ShipmentTracking,
ShipmentUpdate,
)
from app.services import shipment as shipment_service
router = APIRouter()
@router.get("/", response_model=List[Shipment])
def read_shipments(
db: Session = Depends(get_db),
skip: int = 0,
limit: int = 100,
order_id: int = Query(None, description="Filter by order ID"),
current_user: User = Depends(get_current_active_user),
) -> Any:
"""
Retrieve shipments.
"""
shipments = shipment_service.get_multi(
db, skip=skip, limit=limit, order_id=order_id
)
return shipments
@router.post("/", response_model=Shipment)
def create_shipment(
*,
db: Session = Depends(get_db),
shipment_in: ShipmentCreate,
current_user: User = Depends(get_current_active_user),
) -> Any:
"""
Create new shipment.
"""
# Set current user as creator if not provided
if not shipment_in.created_by_id:
shipment_in.created_by_id = current_user.id
# Only superusers can create shipments for other users
if not current_user.is_superuser and shipment_in.created_by_id != current_user.id:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="You can only create shipments for yourself",
)
try:
shipment = shipment_service.create(db, obj_in=shipment_in)
return shipment
except ValueError as e:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail=str(e),
)
@router.get("/{shipment_id}", response_model=Shipment)
def read_shipment(
*,
db: Session = Depends(get_db),
shipment_id: int = Path(..., description="The ID of the shipment to get"),
current_user: User = Depends(get_current_active_user),
) -> Any:
"""
Get shipment by ID.
"""
shipment = shipment_service.get(db, shipment_id=shipment_id)
if not shipment:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Shipment not found",
)
return shipment
@router.get("/tracking/{tracking_number}", response_model=ShipmentTracking)
def read_shipment_by_tracking(
*,
db: Session = Depends(get_db),
tracking_number: str = Path(..., description="The tracking number of the shipment"),
) -> Any:
"""
Get shipment tracking information by tracking number. This endpoint is public.
"""
shipment = shipment_service.get_by_tracking_number(db, tracking_number=tracking_number)
if not shipment:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Shipment not found",
)
return {
"tracking_number": shipment.tracking_number,
"status": shipment.status,
"carrier": shipment.carrier,
"estimated_delivery": shipment.estimated_delivery,
"actual_delivery": shipment.actual_delivery,
}
@router.put("/{shipment_id}", response_model=Shipment)
def update_shipment(
*,
db: Session = Depends(get_db),
shipment_id: int = Path(..., description="The ID of the shipment to update"),
shipment_in: ShipmentUpdate,
current_user: User = Depends(get_current_active_user),
) -> Any:
"""
Update a shipment.
"""
shipment = shipment_service.get(db, shipment_id=shipment_id)
if not shipment:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Shipment not found",
)
# Only superusers or the creator can update shipments
if not current_user.is_superuser and shipment.created_by_id != current_user.id:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="Not enough permissions",
)
shipment = shipment_service.update(db, db_obj=shipment, obj_in=shipment_in)
return shipment
@router.put("/{shipment_id}/status", response_model=Shipment)
def update_shipment_status(
*,
db: Session = Depends(get_db),
shipment_id: int = Path(..., description="The ID of the shipment to update"),
status: ShipmentStatus,
current_user: User = Depends(get_current_active_user),
) -> Any:
"""
Update shipment status.
"""
shipment = shipment_service.get(db, shipment_id=shipment_id)
if not shipment:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Shipment not found",
)
# Only superusers or the creator can update shipment status
if not current_user.is_superuser and shipment.created_by_id != current_user.id:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="Not enough permissions",
)
shipment = shipment_service.update_status(db, shipment_id=shipment_id, status=status)
return shipment
@router.get("/{shipment_id}/items", response_model=List[ShipmentItem])
def read_shipment_items(
*,
db: Session = Depends(get_db),
shipment_id: int = Path(..., description="The ID of the shipment to get items for"),
current_user: User = Depends(get_current_active_user),
) -> Any:
"""
Get all items for a specific shipment.
"""
shipment = shipment_service.get(db, shipment_id=shipment_id)
if not shipment:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Shipment not found",
)
items = shipment_service.get_shipment_items(db, shipment_id=shipment_id)
return items