From 235129a04a1375d3032335ebba8c7317d0e06794 Mon Sep 17 00:00:00 2001 From: acazares Date: Sat, 6 Dec 2025 23:39:48 -0600 Subject: [PATCH] feat: add DODA module with routes, DTOs, models, and service layer for managing DODA operations --- .../a76/general_catalogs/doda/routes.py | 266 ++++++++++++++++++ 1 file changed, 266 insertions(+) create mode 100644 backend/api/v1/modules/a76/general_catalogs/doda/routes.py diff --git a/backend/api/v1/modules/a76/general_catalogs/doda/routes.py b/backend/api/v1/modules/a76/general_catalogs/doda/routes.py new file mode 100644 index 00000000..e06e0ea3 --- /dev/null +++ b/backend/api/v1/modules/a76/general_catalogs/doda/routes.py @@ -0,0 +1,266 @@ +""" +Rutas para gestión de DODA (Documentos de Operación de Aduana) +""" + +from typing import List + +from fastapi import APIRouter, Depends, HTTPException, Query, status +from sqlalchemy.orm import Session + +from core.database import get_core_db +from .dto import ( + DodaCreateDTO, + DodaResponseDTO, + DodaUpdateDTO, + DodaDetailResponseDTO, + DodaContainerCreateDTO, + DodaContainerResponseDTO, + DodaContainerUpdateDTO, + DodaAmericanPedimentoCreateDTO, + DodaAmericanPedimentoResponseDTO, + DodaAmericanPedimentoUpdateDTO, + DodaPedimentoCreateDTO, + DodaPedimentoResponseDTO, + DodaPedimentoUpdateDTO, +) +from .models import Doda +from .service import DodaService + +router = APIRouter(prefix="/doda", tags=["doda"]) + + +# ============ MAIN DODA ENDPOINTS ============ +@router.get( + "", + response_model=dict, + summary="Get all DODAs", +) +async def get_all_dodas( + skip: int = Query(0, ge=0), + limit: int = Query(50, ge=1, le=100), + integration_number: str = Query(None), + status: str = Query(None), + patent: str = Query(None), + db: Session = Depends(get_core_db), +): + """Get all DODAs with optional filtering and pagination""" + filters = {} + if integration_number: + filters["integration_number"] = integration_number + if status: + filters["status"] = status + if patent: + filters["patent"] = patent + + dodas, total = DodaService.get_all(db, skip, limit, filters) + + return { + "data": [DodaResponseDTO.model_validate(doda) for doda in dodas], + "total": total, + "skip": skip, + "limit": limit, + } + + +@router.get( + "/{sys_id}", + response_model=DodaDetailResponseDTO, + summary="Get DODA by ID with all details", +) +async def get_doda( + sys_id: int, + db: Session = Depends(get_core_db), +): + """Get a DODA by its ID with all related data""" + doda = DodaService.get_by_id(db, sys_id) + if not doda: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail="DODA not found", + ) + return DodaDetailResponseDTO.model_validate(doda) + + +@router.post( + "", + response_model=DodaResponseDTO, + status_code=status.HTTP_201_CREATED, + summary="Create DODA", +) +async def create_doda( + doda_data: DodaCreateDTO, + db: Session = Depends(get_core_db), +): + """Create a new DODA""" + doda = DodaService.create(db, doda_data) + return DodaResponseDTO.model_validate(doda) + + +@router.put( + "/{sys_id}", + response_model=DodaResponseDTO, + summary="Update DODA", +) +async def update_doda( + sys_id: int, + doda_data: DodaUpdateDTO, + db: Session = Depends(get_core_db), +): + """Update a DODA""" + doda = DodaService.update(db, sys_id, doda_data) + if not doda: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail="DODA not found", + ) + return DodaResponseDTO.model_validate(doda) + + +@router.delete( + "/{sys_id}", + status_code=status.HTTP_204_NO_CONTENT, + summary="Delete DODA", +) +async def delete_doda( + sys_id: int, + db: Session = Depends(get_core_db), +): + """Delete a DODA""" + success = DodaService.delete(db, sys_id) + if not success: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail="DODA not found", + ) + return None + + +# ============ CONTAINERS ENDPOINTS ============ +@router.get( + "/{sys_id}/containers", + response_model=List[DodaContainerResponseDTO], + summary="Get containers for DODA", +) +async def get_doda_containers( + sys_id: int, + db: Session = Depends(get_core_db), +): + """Get all containers for a specific DODA""" + containers = DodaService.get_containers(db, sys_id) + return [DodaContainerResponseDTO.model_validate(c) for c in containers] + + +@router.post( + "/{sys_id}/containers", + response_model=DodaContainerResponseDTO, + status_code=status.HTTP_201_CREATED, + summary="Add container to DODA", +) +async def add_container( + sys_id: int, + container_data: DodaContainerCreateDTO, + db: Session = Depends(get_core_db), +): + """Add a new container to a DODA""" + container = DodaService.add_container(db, sys_id, container_data) + if not container: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail="DODA not found", + ) + return DodaContainerResponseDTO.model_validate(container) + + +@router.put( + "/{sys_id}/containers/{container_line}", + response_model=DodaContainerResponseDTO, + summary="Update container", +) +async def update_container( + sys_id: int, + container_line: int, + container_data: DodaContainerUpdateDTO, + db: Session = Depends(get_core_db), +): + """Update a container""" + container = DodaService.update_container( + db, sys_id, container_line, container_data + ) + if not container: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail="Container not found", + ) + return DodaContainerResponseDTO.model_validate(container) + + +# ============ AMERICAN PEDIMENTOS ENDPOINTS ============ +@router.get( + "/{sys_id}/american-pedimentos", + response_model=List[DodaAmericanPedimentoResponseDTO], + summary="Get American pedimentos for DODA", +) +async def get_american_pedimentos( + sys_id: int, + db: Session = Depends(get_core_db), +): + """Get all American pedimentos for a specific DODA""" + pedimentos = DodaService.get_american_pedimentos(db, sys_id) + return [DodaAmericanPedimentoResponseDTO.model_validate(p) for p in pedimentos] + + +@router.post( + "/{sys_id}/american-pedimentos", + response_model=DodaAmericanPedimentoResponseDTO, + status_code=status.HTTP_201_CREATED, + summary="Add American pedimento to DODA", +) +async def add_american_pedimento( + sys_id: int, + pedimento_data: DodaAmericanPedimentoCreateDTO, + db: Session = Depends(get_core_db), +): + """Add a new American pedimento to a DODA""" + pedimento = DodaService.add_american_pedimento(db, sys_id, pedimento_data) + if not pedimento: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail="DODA not found", + ) + return DodaAmericanPedimentoResponseDTO.model_validate(pedimento) + + +# ============ PEDIMENTOS ENDPOINTS ============ +@router.get( + "/{sys_id}/pedimentos", + response_model=List[DodaPedimentoResponseDTO], + summary="Get pedimentos for DODA", +) +async def get_doda_pedimentos( + sys_id: int, + db: Session = Depends(get_core_db), +): + """Get all pedimentos for a specific DODA""" + pedimentos = DodaService.get_pedimentos(db, sys_id) + return [DodaPedimentoResponseDTO.model_validate(p) for p in pedimentos] + + +@router.post( + "/{sys_id}/pedimentos", + response_model=DodaPedimentoResponseDTO, + status_code=status.HTTP_201_CREATED, + summary="Add pedimento to DODA", +) +async def add_pedimento( + sys_id: int, + pedimento_data: DodaPedimentoCreateDTO, + db: Session = Depends(get_core_db), +): + """Add a new pedimento to a DODA""" + pedimento = DodaService.add_pedimento(db, sys_id, pedimento_data) + if not pedimento: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail="DODA not found", + ) + return DodaPedimentoResponseDTO.model_validate(pedimento)