190 lines
5.8 KiB
Python
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 |