from fastapi import APIRouter, Depends, Query, status from sqlalchemy.orm import Session from core.database import get_core_db from core.security import get_current_user from . import service from .dto import ( ShipmentCreate, ShipmentDocumentCreate, ShipmentDocumentResponse, ShipmentDocumentUpdate, ShipmentEventCreate, ShipmentEventResponse, ShipmentEventUpdate, ShipmentResponse, ShipmentUpdate, ) router = APIRouter() def _user_id(current_user: dict) -> str | None: return current_user.get("sub") or current_user.get("id") @router.get("/shipments", response_model=list[ShipmentResponse]) def list_shipments( company_id: int = Query(..., description="Company ID"), search: str | None = Query(None), shipment_status: str | None = Query(None, alias="status"), account_id: int | None = Query(None), current_user: dict = Depends(get_current_user), db: Session = Depends(get_core_db), ): tenant_id = current_user["tenant_id"] return service.get_shipments(db, tenant_id, company_id, search, shipment_status, account_id) @router.get("/shipments/{shipment_id}", response_model=ShipmentResponse) def get_shipment( shipment_id: int, company_id: int = Query(..., description="Company ID"), current_user: dict = Depends(get_current_user), db: Session = Depends(get_core_db), ): return service.get_shipment(db, shipment_id, current_user["tenant_id"], company_id) @router.post("/shipments", response_model=ShipmentResponse, status_code=status.HTTP_201_CREATED) def create_shipment( payload: ShipmentCreate, company_id: int = Query(..., description="Company ID"), current_user: dict = Depends(get_current_user), db: Session = Depends(get_core_db), ): tenant_id = current_user["tenant_id"] return service.create_shipment(db, payload, tenant_id, company_id, _user_id(current_user)) @router.post("/shipments/from-quote", response_model=ShipmentResponse, status_code=status.HTTP_201_CREATED) def create_shipment_from_quote( quote_id: int = Query(..., description="Cotización aceptada a liberar"), company_id: int = Query(..., description="Company ID"), current_user: dict = Depends(get_current_user), db: Session = Depends(get_core_db), ): tenant_id = current_user["tenant_id"] return service.create_shipment_from_quote(db, quote_id, tenant_id, company_id, _user_id(current_user)) @router.patch("/shipments/{shipment_id}", response_model=ShipmentResponse) def update_shipment( shipment_id: int, payload: ShipmentUpdate, company_id: int = Query(..., description="Company ID"), current_user: dict = Depends(get_current_user), db: Session = Depends(get_core_db), ): tenant_id = current_user["tenant_id"] return service.update_shipment(db, shipment_id, payload, tenant_id, company_id, _user_id(current_user)) @router.delete("/shipments/{shipment_id}", status_code=status.HTTP_204_NO_CONTENT) def delete_shipment( shipment_id: int, company_id: int = Query(..., description="Company ID"), current_user: dict = Depends(get_current_user), db: Session = Depends(get_core_db), ): service.delete_shipment(db, shipment_id, current_user["tenant_id"], company_id) # ----- Documentos del embarque ----- @router.get("/shipments/{shipment_id}/documents", response_model=list[ShipmentDocumentResponse]) def list_shipment_documents( shipment_id: int, company_id: int = Query(..., description="Company ID"), current_user: dict = Depends(get_current_user), db: Session = Depends(get_core_db), ): service.get_shipment(db, shipment_id, current_user["tenant_id"], company_id) return service.get_shipment_documents(db, current_user["tenant_id"], company_id, shipment_id) @router.post("/shipment-documents", response_model=ShipmentDocumentResponse, status_code=status.HTTP_201_CREATED) def create_shipment_document( payload: ShipmentDocumentCreate, company_id: int = Query(..., description="Company ID"), current_user: dict = Depends(get_current_user), db: Session = Depends(get_core_db), ): return service.create_shipment_document(db, payload, current_user["tenant_id"], company_id) @router.patch("/shipment-documents/{doc_id}", response_model=ShipmentDocumentResponse) def update_shipment_document( doc_id: int, payload: ShipmentDocumentUpdate, company_id: int = Query(..., description="Company ID"), current_user: dict = Depends(get_current_user), db: Session = Depends(get_core_db), ): return service.update_shipment_document(db, doc_id, payload, current_user["tenant_id"], company_id) @router.delete("/shipment-documents/{doc_id}", status_code=status.HTTP_204_NO_CONTENT) def delete_shipment_document( doc_id: int, company_id: int = Query(..., description="Company ID"), current_user: dict = Depends(get_current_user), db: Session = Depends(get_core_db), ): service.delete_shipment_document(db, doc_id, current_user["tenant_id"], company_id) # ----- Bitácora / hitos ----- @router.get("/shipments/{shipment_id}/events", response_model=list[ShipmentEventResponse]) def list_shipment_events( shipment_id: int, company_id: int = Query(..., description="Company ID"), current_user: dict = Depends(get_current_user), db: Session = Depends(get_core_db), ): service.get_shipment(db, shipment_id, current_user["tenant_id"], company_id) return service.get_shipment_events(db, current_user["tenant_id"], company_id, shipment_id) @router.post("/shipments/{shipment_id}/events/seed", response_model=list[ShipmentEventResponse]) def seed_shipment_events( shipment_id: int, company_id: int = Query(..., description="Company ID"), current_user: dict = Depends(get_current_user), db: Session = Depends(get_core_db), ): return service.seed_default_milestones(db, shipment_id, current_user["tenant_id"], company_id) @router.post("/shipment-events", response_model=ShipmentEventResponse, status_code=status.HTTP_201_CREATED) def create_shipment_event( payload: ShipmentEventCreate, company_id: int = Query(..., description="Company ID"), current_user: dict = Depends(get_current_user), db: Session = Depends(get_core_db), ): return service.create_shipment_event(db, payload, current_user["tenant_id"], company_id) @router.patch("/shipment-events/{event_id}", response_model=ShipmentEventResponse) def update_shipment_event( event_id: int, payload: ShipmentEventUpdate, company_id: int = Query(..., description="Company ID"), current_user: dict = Depends(get_current_user), db: Session = Depends(get_core_db), ): return service.update_shipment_event(db, event_id, payload, current_user["tenant_id"], company_id) @router.patch("/shipment-events/{event_id}/complete", response_model=ShipmentEventResponse) def complete_shipment_event( event_id: int, company_id: int = Query(..., description="Company ID"), current_user: dict = Depends(get_current_user), db: Session = Depends(get_core_db), ): return service.complete_shipment_event(db, event_id, current_user["tenant_id"], company_id) @router.delete("/shipment-events/{event_id}", status_code=status.HTTP_204_NO_CONTENT) def delete_shipment_event( event_id: int, company_id: int = Query(..., description="Company ID"), current_user: dict = Depends(get_current_user), db: Session = Depends(get_core_db), ): service.delete_shipment_event(db, event_id, current_user["tenant_id"], company_id)