feature/doda-endpoints-faltantes
This commit is contained in:
@@ -8,6 +8,7 @@ from pydantic import BaseModel, Field
|
||||
class DodaAltaLogCreateDTO(BaseModel):
|
||||
doda_id: Optional[int] = None
|
||||
variant: Optional[str] = Field(None, max_length=10)
|
||||
action: Optional[str] = Field(None, max_length=20)
|
||||
responsible: Optional[str] = Field(None, max_length=20)
|
||||
patent: Optional[str] = Field(None, max_length=10)
|
||||
dispatch_customs: Optional[str] = Field(None, max_length=10)
|
||||
@@ -29,6 +30,7 @@ class DodaAltaLogResponseDTO(BaseModel):
|
||||
id: int
|
||||
doda_id: Optional[int] = None
|
||||
variant: Optional[str] = None
|
||||
action: Optional[str] = None
|
||||
responsible: Optional[str] = None
|
||||
patent: Optional[str] = None
|
||||
dispatch_customs: Optional[str] = None
|
||||
|
||||
@@ -23,6 +23,7 @@ class DodaAltaLog(Base, TenantScopedMixin, TimestampMixin):
|
||||
|
||||
# Tipo de alta (doda / pita)
|
||||
variant: Mapped[str | None] = mapped_column(String(10), nullable=True)
|
||||
action: Mapped[str | None] = mapped_column(String(20), nullable=True)
|
||||
|
||||
# Datos copiados del DODA al momento del envío (para historial)
|
||||
responsible: Mapped[str | None] = mapped_column(String(20), nullable=True)
|
||||
|
||||
@@ -115,6 +115,7 @@ class DodaAltaLogService:
|
||||
tenant_id: int,
|
||||
variant: str,
|
||||
ext_result: dict,
|
||||
action: str = "alta",
|
||||
) -> DodaAltaLog:
|
||||
"""
|
||||
Crea un registro de log a partir de la respuesta del servicio externo de alta.
|
||||
@@ -127,6 +128,7 @@ class DodaAltaLogService:
|
||||
dto = DodaAltaLogCreateDTO(
|
||||
doda_id=doda.id,
|
||||
variant=variant,
|
||||
action=action,
|
||||
responsible=doda.responsible,
|
||||
patent=doda.patent,
|
||||
dispatch_customs=doda.dispatch_customs,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import base64
|
||||
import json
|
||||
import logging
|
||||
from dataclasses import dataclass, field
|
||||
from typing import Any, Dict, List, Optional
|
||||
@@ -16,6 +17,7 @@ from core.storage_s3 import get_object_bytes, object_exists
|
||||
from api.v1.modules.a76.customs_brokers import models as cb_models
|
||||
|
||||
from .models import Doda, DodaContainer, DodaAmericanPedimento, DodaPedimento
|
||||
from .alta_log_models import DodaAltaLog
|
||||
from .payload_normalizer import (
|
||||
normalize_aduana_despacho,
|
||||
normalize_aduana_seccion,
|
||||
@@ -487,6 +489,40 @@ class DodaAltaService:
|
||||
# Build full payload
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
def _latest_alta_log(
|
||||
self,
|
||||
doda_id: int,
|
||||
tenant_id: int,
|
||||
company_id: int,
|
||||
variant: str,
|
||||
) -> Optional[DodaAltaLog]:
|
||||
return (
|
||||
self.db.query(DodaAltaLog)
|
||||
.filter(
|
||||
DodaAltaLog.doda_id == doda_id,
|
||||
DodaAltaLog.tenant_id == tenant_id,
|
||||
DodaAltaLog.company_id == company_id,
|
||||
DodaAltaLog.variant == variant,
|
||||
DodaAltaLog.deleted_at.is_(None),
|
||||
)
|
||||
.order_by(DodaAltaLog.id.desc())
|
||||
.first()
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _extract_numero_transaccion(log_record: DodaAltaLog) -> str:
|
||||
raw_json = (log_record.result_json or "").strip()
|
||||
if raw_json:
|
||||
try:
|
||||
parsed = json.loads(raw_json)
|
||||
for key in ("numero_transaccion", "transaction_number"):
|
||||
value = parsed.get(key)
|
||||
if value:
|
||||
return str(value).strip()
|
||||
except Exception:
|
||||
logger.warning("No se pudo parsear result_json de DodaAltaLog id=%s", log_record.id)
|
||||
return ""
|
||||
|
||||
def build_alta_payload(
|
||||
self,
|
||||
doda_id: int,
|
||||
@@ -549,3 +585,59 @@ class DodaAltaService:
|
||||
}
|
||||
|
||||
return payload
|
||||
|
||||
def build_consulta_payload(
|
||||
self,
|
||||
doda_id: int,
|
||||
tenant_id: int,
|
||||
company_id: int,
|
||||
variant: str = "doda",
|
||||
user_email: str = "",
|
||||
) -> Dict[str, Any]:
|
||||
payload = self.build_alta_payload(
|
||||
doda_id=doda_id,
|
||||
tenant_id=tenant_id,
|
||||
company_id=company_id,
|
||||
variant=variant,
|
||||
user_email=user_email,
|
||||
)
|
||||
latest_log = self._latest_alta_log(doda_id, tenant_id, company_id, variant)
|
||||
if not latest_log:
|
||||
raise ValueError(
|
||||
"No existe un alta DODA previa para construir la consulta (falta task/log)."
|
||||
)
|
||||
numero_transaccion = self._extract_numero_transaccion(latest_log)
|
||||
if not numero_transaccion:
|
||||
raise ValueError(
|
||||
"No se encontro numero_transaccion en el ultimo resultado de alta DODA."
|
||||
)
|
||||
payload["numero_transaccion"] = numero_transaccion
|
||||
return payload
|
||||
|
||||
def build_eliminar_payload(
|
||||
self,
|
||||
doda_id: int,
|
||||
tenant_id: int,
|
||||
company_id: int,
|
||||
variant: str = "doda",
|
||||
user_email: str = "",
|
||||
) -> Dict[str, Any]:
|
||||
payload = self.build_alta_payload(
|
||||
doda_id=doda_id,
|
||||
tenant_id=tenant_id,
|
||||
company_id=company_id,
|
||||
variant=variant,
|
||||
user_email=user_email,
|
||||
)
|
||||
latest_log = self._latest_alta_log(doda_id, tenant_id, company_id, variant)
|
||||
if not latest_log:
|
||||
raise ValueError(
|
||||
"No existe un alta DODA previa para construir la eliminacion."
|
||||
)
|
||||
numero_integracion = (latest_log.integration_number or "").strip()
|
||||
if not numero_integracion:
|
||||
raise ValueError(
|
||||
"No se encontro numero_integracion en el historial de alta DODA."
|
||||
)
|
||||
payload["numero_integracion"] = numero_integracion
|
||||
return payload
|
||||
|
||||
@@ -17,6 +17,10 @@ class DodaExternalService:
|
||||
Endpoints:
|
||||
POST {base_url}/api/v1/doda/alta
|
||||
GET {base_url}/api/v1/doda/alta-status/{task_id}
|
||||
POST {base_url}/api/v1/doda/consulta
|
||||
GET {base_url}/api/v1/doda/consulta-status/{task_id}
|
||||
POST {base_url}/api/v1/doda/eliminar
|
||||
GET {base_url}/api/v1/doda/eliminar-status/{task_id}
|
||||
|
||||
Usa COVE_API_URL como URL base (la misma variable que COVE y Expediente).
|
||||
"""
|
||||
@@ -61,3 +65,43 @@ class DodaExternalService:
|
||||
response = client.get(url)
|
||||
response.raise_for_status()
|
||||
return response.json()
|
||||
|
||||
def post_consulta(self, payload: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""Envia consulta DODA y retorna {task_id, status, message}."""
|
||||
url = f"{self.base_url.rstrip('/')}/api/v1/doda/consulta"
|
||||
with httpx.Client(
|
||||
timeout=httpx.Timeout(60.0, connect=10.0), verify=self.verify_ssl
|
||||
) as client:
|
||||
response = client.post(url, json=payload)
|
||||
response.raise_for_status()
|
||||
return response.json()
|
||||
|
||||
def get_consulta_status(self, task_id: str) -> Dict[str, Any]:
|
||||
"""Consulta el estado de una tarea de consulta DODA."""
|
||||
url = f"{self.base_url.rstrip('/')}/api/v1/doda/consulta-status/{task_id}"
|
||||
with httpx.Client(
|
||||
timeout=httpx.Timeout(30.0, connect=10.0), verify=self.verify_ssl
|
||||
) as client:
|
||||
response = client.get(url)
|
||||
response.raise_for_status()
|
||||
return response.json()
|
||||
|
||||
def post_eliminar(self, payload: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""Envia eliminacion DODA y retorna {task_id, status, message}."""
|
||||
url = f"{self.base_url.rstrip('/')}/api/v1/doda/eliminar"
|
||||
with httpx.Client(
|
||||
timeout=httpx.Timeout(60.0, connect=10.0), verify=self.verify_ssl
|
||||
) as client:
|
||||
response = client.post(url, json=payload)
|
||||
response.raise_for_status()
|
||||
return response.json()
|
||||
|
||||
def get_eliminar_status(self, task_id: str) -> Dict[str, Any]:
|
||||
"""Consulta el estado de una tarea de eliminacion DODA."""
|
||||
url = f"{self.base_url.rstrip('/')}/api/v1/doda/eliminar-status/{task_id}"
|
||||
with httpx.Client(
|
||||
timeout=httpx.Timeout(30.0, connect=10.0), verify=self.verify_ssl
|
||||
) as client:
|
||||
response = client.get(url)
|
||||
response.raise_for_status()
|
||||
return response.json()
|
||||
|
||||
@@ -60,6 +60,47 @@ from core.security import get_current_user, validate_access_to_resource
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _coalesce_external_result_payload(payload: Dict[str, Any]) -> Dict[str, Any]:
|
||||
result = payload.get("result")
|
||||
if isinstance(result, dict):
|
||||
return result
|
||||
return payload
|
||||
|
||||
|
||||
def _apply_consulta_success_to_doda(
|
||||
doda: Doda,
|
||||
payload: Dict[str, Any],
|
||||
) -> None:
|
||||
source = _coalesce_external_result_payload(payload)
|
||||
mapping = {
|
||||
"integration_number": "integration_number",
|
||||
"numero_integracion": "integration_number",
|
||||
"transaction_number": "transaction_number",
|
||||
"numero_transaccion": "transaction_number",
|
||||
"sat_digital_seal": "sat_digital_seal",
|
||||
"sello_digital_sat": "sat_digital_seal",
|
||||
"sat_certificate": "sat_certificate",
|
||||
"certificado_sat": "sat_certificate",
|
||||
"serial_number": "serial_number",
|
||||
"numero_serie": "serial_number",
|
||||
"electronic_signature": "electronic_signature",
|
||||
"firma_electronica": "electronic_signature",
|
||||
"original_chain": "original_chain",
|
||||
"cadena_original": "original_chain",
|
||||
"sat_original_chain": "sat_original_chain",
|
||||
"cadena_original_sat": "sat_original_chain",
|
||||
"linq_sat_qr": "linq_sat_qr",
|
||||
"link_sat_qr": "linq_sat_qr",
|
||||
"xml_doda_sent_path": "xml_doda_sent_path",
|
||||
"xml_doda_response_path": "xml_doda_response_path",
|
||||
"status": "status",
|
||||
}
|
||||
for src_key, dst_attr in mapping.items():
|
||||
value = source.get(src_key)
|
||||
if value is not None and value != "":
|
||||
setattr(doda, dst_attr, str(value))
|
||||
|
||||
# Router independiente para rutas literales (deben registrarse antes que /{id})
|
||||
router = APIRouter(prefix="/doda", tags=["doda"])
|
||||
|
||||
@@ -633,6 +674,7 @@ async def post_doda_alta(
|
||||
tenant_id=int(tenant_id),
|
||||
variant=variant,
|
||||
ext_result=result,
|
||||
action="alta",
|
||||
)
|
||||
except Exception:
|
||||
logger.exception("Error persistiendo DodaAltaLog para doda_id=%s", doda_id)
|
||||
@@ -668,6 +710,269 @@ async def get_doda_alta_status(
|
||||
) from exc
|
||||
|
||||
|
||||
@router.post(
|
||||
"/{doda_id}/consulta",
|
||||
summary="Enviar Consulta DODA al servicio externo (asíncrono)",
|
||||
tags=["doda-alta"],
|
||||
)
|
||||
async def post_doda_consulta(
|
||||
doda_id: int,
|
||||
company_id: int = Query(..., description="Company ID"),
|
||||
variant: str = Query("doda", description="Tipo de alta: 'doda' o 'pita'"),
|
||||
db: Session = Depends(get_core_db),
|
||||
current_user: dict = Depends(get_current_user),
|
||||
) -> Dict[str, Any]:
|
||||
tenant_id = validate_access_to_resource(db, company_id, current_user)
|
||||
user_email = (
|
||||
current_user.get("email")
|
||||
or current_user.get("preferred_username")
|
||||
or ""
|
||||
)
|
||||
service = DodaAltaService(db)
|
||||
try:
|
||||
payload = service.build_consulta_payload(
|
||||
doda_id=doda_id,
|
||||
tenant_id=int(tenant_id),
|
||||
company_id=company_id,
|
||||
variant=variant,
|
||||
user_email=user_email,
|
||||
)
|
||||
except ValueError as exc:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
||||
detail=str(exc),
|
||||
) from exc
|
||||
|
||||
ext_result: Dict[str, Any]
|
||||
try:
|
||||
ext = DodaExternalService()
|
||||
ext_result = ext.post_consulta(payload)
|
||||
except ValueError as exc:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
|
||||
detail=str(exc),
|
||||
) from exc
|
||||
except Exception as exc:
|
||||
logger.exception("Error al enviar consulta DODA al servicio externo: doda_id=%s", doda_id)
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_502_BAD_GATEWAY,
|
||||
detail=f"Error al contactar el servicio DODA externo (consulta): {exc}",
|
||||
) from exc
|
||||
|
||||
doda_record = DodaService.get_by_id(db, doda_id, int(tenant_id), company_id)
|
||||
if doda_record:
|
||||
try:
|
||||
DodaAltaLogService.create_from_alta_result(
|
||||
db=db,
|
||||
doda=doda_record,
|
||||
company_id=company_id,
|
||||
tenant_id=int(tenant_id),
|
||||
variant=variant,
|
||||
ext_result=ext_result,
|
||||
action="consulta",
|
||||
)
|
||||
except Exception:
|
||||
logger.exception("Error persistiendo DodaAltaLog(consulta) para doda_id=%s", doda_id)
|
||||
return ext_result
|
||||
|
||||
|
||||
@router.get(
|
||||
"/consulta-status/{task_id}",
|
||||
summary="Consultar estado de tarea de Consulta DODA",
|
||||
tags=["doda-alta"],
|
||||
)
|
||||
async def get_doda_consulta_status(
|
||||
task_id: str,
|
||||
current_user: dict = Depends(get_current_user),
|
||||
) -> Any:
|
||||
try:
|
||||
ext = DodaExternalService()
|
||||
return ext.get_consulta_status(task_id)
|
||||
except ValueError as exc:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
|
||||
detail=str(exc),
|
||||
) from exc
|
||||
except Exception as exc:
|
||||
logger.exception("Error consultando consulta-status DODA task_id=%s", task_id)
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_502_BAD_GATEWAY,
|
||||
detail=f"Error al consultar el estado de la consulta DODA: {exc}",
|
||||
) from exc
|
||||
|
||||
|
||||
@router.post(
|
||||
"/{doda_id}/consulta-apply/{task_id}",
|
||||
summary="Aplicar resultado exitoso de consulta DODA al registro local",
|
||||
tags=["doda-alta"],
|
||||
)
|
||||
async def post_doda_consulta_apply(
|
||||
doda_id: int,
|
||||
task_id: str,
|
||||
company_id: int = Query(..., description="Company ID"),
|
||||
db: Session = Depends(get_core_db),
|
||||
current_user: dict = Depends(get_current_user),
|
||||
) -> Dict[str, Any]:
|
||||
tenant_id = int(validate_access_to_resource(db, company_id, current_user))
|
||||
doda_record = DodaService.get_by_id(db, doda_id, tenant_id, company_id)
|
||||
if not doda_record:
|
||||
raise HTTPException(status_code=404, detail="DODA no encontrado.")
|
||||
|
||||
try:
|
||||
ext = DodaExternalService()
|
||||
status_payload = ext.get_consulta_status(task_id)
|
||||
except ValueError as exc:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
|
||||
detail=str(exc),
|
||||
) from exc
|
||||
except Exception as exc:
|
||||
logger.exception("Error al consultar consulta-status para aplicar: task_id=%s", task_id)
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_502_BAD_GATEWAY,
|
||||
detail=f"Error al consultar el estado de la consulta DODA: {exc}",
|
||||
) from exc
|
||||
|
||||
task_state = str(status_payload.get("state") or status_payload.get("status") or "").upper()
|
||||
if task_state != "SUCCESS":
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_409_CONFLICT,
|
||||
detail="La tarea de consulta aún no está en estado SUCCESS.",
|
||||
)
|
||||
|
||||
try:
|
||||
_apply_consulta_success_to_doda(doda_record, status_payload)
|
||||
if not (doda_record.status or "").strip():
|
||||
doda_record.status = "VALIDADO"
|
||||
db.add(doda_record)
|
||||
db.commit()
|
||||
db.refresh(doda_record)
|
||||
except Exception as exc:
|
||||
db.rollback()
|
||||
logger.exception("Error aplicando consulta-status al DODA id=%s", doda_id)
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail=f"No se pudo aplicar el resultado de consulta al DODA: {exc}",
|
||||
) from exc
|
||||
|
||||
return {
|
||||
"message": "Resultado de consulta aplicado correctamente.",
|
||||
"doda_id": doda_id,
|
||||
"task_id": task_id,
|
||||
"state": task_state,
|
||||
}
|
||||
|
||||
|
||||
@router.post(
|
||||
"/{doda_id}/eliminar",
|
||||
summary="Enviar Eliminación DODA al servicio externo (asíncrono)",
|
||||
tags=["doda-alta"],
|
||||
)
|
||||
async def post_doda_eliminar(
|
||||
doda_id: int,
|
||||
company_id: int = Query(..., description="Company ID"),
|
||||
variant: str = Query("doda", description="Tipo de alta: 'doda' o 'pita'"),
|
||||
db: Session = Depends(get_core_db),
|
||||
current_user: dict = Depends(get_current_user),
|
||||
) -> Dict[str, Any]:
|
||||
tenant_id = validate_access_to_resource(db, company_id, current_user)
|
||||
user_email = (
|
||||
current_user.get("email")
|
||||
or current_user.get("preferred_username")
|
||||
or ""
|
||||
)
|
||||
service = DodaAltaService(db)
|
||||
try:
|
||||
payload = service.build_eliminar_payload(
|
||||
doda_id=doda_id,
|
||||
tenant_id=int(tenant_id),
|
||||
company_id=company_id,
|
||||
variant=variant,
|
||||
user_email=user_email,
|
||||
)
|
||||
except ValueError as exc:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
||||
detail=str(exc),
|
||||
) from exc
|
||||
|
||||
ext_result: Dict[str, Any]
|
||||
try:
|
||||
ext = DodaExternalService()
|
||||
ext_result = ext.post_eliminar(payload)
|
||||
except ValueError as exc:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
|
||||
detail=str(exc),
|
||||
) from exc
|
||||
except Exception as exc:
|
||||
logger.exception("Error al enviar eliminación DODA al servicio externo: doda_id=%s", doda_id)
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_502_BAD_GATEWAY,
|
||||
detail=f"Error al contactar el servicio DODA externo (eliminación): {exc}",
|
||||
) from exc
|
||||
|
||||
doda_record = DodaService.get_by_id(db, doda_id, int(tenant_id), company_id)
|
||||
if doda_record:
|
||||
try:
|
||||
DodaAltaLogService.create_from_alta_result(
|
||||
db=db,
|
||||
doda=doda_record,
|
||||
company_id=company_id,
|
||||
tenant_id=int(tenant_id),
|
||||
variant=variant,
|
||||
ext_result=ext_result,
|
||||
action="eliminar",
|
||||
)
|
||||
except Exception:
|
||||
logger.exception("Error persistiendo DodaAltaLog(eliminar) para doda_id=%s", doda_id)
|
||||
|
||||
try:
|
||||
doda_record.integration_number = None
|
||||
doda_record.transaction_number = None
|
||||
doda_record.status = "PENDIENTE"
|
||||
doda_record.sat_digital_seal = None
|
||||
doda_record.sat_certificate = None
|
||||
doda_record.serial_number = None
|
||||
doda_record.electronic_signature = None
|
||||
doda_record.original_chain = None
|
||||
doda_record.sat_original_chain = None
|
||||
doda_record.linq_sat_qr = None
|
||||
doda_record.xml_doda_sent_path = None
|
||||
doda_record.xml_doda_response_path = None
|
||||
db.add(doda_record)
|
||||
db.commit()
|
||||
except Exception:
|
||||
db.rollback()
|
||||
logger.exception("Error desprocesando DODA local tras eliminación id=%s", doda_id)
|
||||
return ext_result
|
||||
|
||||
|
||||
@router.get(
|
||||
"/eliminar-status/{task_id}",
|
||||
summary="Consultar estado de tarea de Eliminación DODA",
|
||||
tags=["doda-alta"],
|
||||
)
|
||||
async def get_doda_eliminar_status(
|
||||
task_id: str,
|
||||
current_user: dict = Depends(get_current_user),
|
||||
) -> Any:
|
||||
try:
|
||||
ext = DodaExternalService()
|
||||
return ext.get_eliminar_status(task_id)
|
||||
except ValueError as exc:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
|
||||
detail=str(exc),
|
||||
) from exc
|
||||
except Exception as exc:
|
||||
logger.exception("Error consultando eliminar-status DODA task_id=%s", task_id)
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_502_BAD_GATEWAY,
|
||||
detail=f"Error al consultar el estado de la eliminación DODA: {exc}",
|
||||
) from exc
|
||||
|
||||
|
||||
# ============ DODA ALTA LOG CRUD ============
|
||||
|
||||
|
||||
|
||||
@@ -37,6 +37,19 @@ logger = logging.getLogger(__name__)
|
||||
class DodaService:
|
||||
"""Servicio para gestión de DODA"""
|
||||
|
||||
@staticmethod
|
||||
def _ensure_editable_doda(doda: Optional[Doda]) -> None:
|
||||
if not doda:
|
||||
return
|
||||
if (doda.integration_number or "").strip():
|
||||
raise HTTPException(
|
||||
status_code=422,
|
||||
detail=(
|
||||
"El DODA ya fue generado (tiene número de integración). "
|
||||
"Elimínelo primero para poder editarlo."
|
||||
),
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _invalidate_report_after_mutation(
|
||||
db: Session,
|
||||
@@ -132,6 +145,7 @@ class DodaService:
|
||||
db_doda = DodaService.get_by_id(db, id, tenant_id, company_id)
|
||||
if not db_doda:
|
||||
return None
|
||||
DodaService._ensure_editable_doda(db_doda)
|
||||
|
||||
for key, value in doda_data.model_dump(exclude_unset=True).items():
|
||||
setattr(db_doda, key, value)
|
||||
@@ -195,6 +209,7 @@ class DodaService:
|
||||
doda = db.query(Doda).filter(Doda.id == doda_id).first()
|
||||
if not doda:
|
||||
return None
|
||||
DodaService._ensure_editable_doda(doda)
|
||||
|
||||
cv = (container_data.container_value or "").strip()
|
||||
if not cv:
|
||||
@@ -259,6 +274,8 @@ class DodaService:
|
||||
)
|
||||
if not db_container:
|
||||
return None
|
||||
doda = db.get(Doda, doda_id)
|
||||
DodaService._ensure_editable_doda(doda)
|
||||
|
||||
for key, value in container_data.model_dump(exclude_unset=True).items():
|
||||
setattr(db_container, key, value)
|
||||
@@ -308,6 +325,8 @@ class DodaService:
|
||||
)
|
||||
if not db_container:
|
||||
raise HTTPException(status_code=404, detail="Contenedor no encontrado.")
|
||||
doda = db.get(Doda, doda_id)
|
||||
DodaService._ensure_editable_doda(doda)
|
||||
|
||||
has_seals = bool(db_container.seals_detail)
|
||||
if not has_seals and db_container.seals:
|
||||
@@ -376,6 +395,7 @@ class DodaService:
|
||||
doda = db.query(Doda).filter(Doda.id == doda_id).first()
|
||||
if not doda:
|
||||
raise HTTPException(status_code=404, detail="DODA no encontrado.")
|
||||
DodaService._ensure_editable_doda(doda)
|
||||
|
||||
container = (
|
||||
db.query(DodaContainer)
|
||||
@@ -387,6 +407,8 @@ class DodaService:
|
||||
)
|
||||
if not container:
|
||||
raise HTTPException(status_code=404, detail="Contenedor no encontrado.")
|
||||
doda = db.get(Doda, doda_id)
|
||||
DodaService._ensure_editable_doda(doda)
|
||||
|
||||
raw_value = (seal_data.seal_value or "").strip()
|
||||
if not raw_value:
|
||||
@@ -504,6 +526,7 @@ class DodaService:
|
||||
doda = db.query(Doda).filter(Doda.id == doda_id).first()
|
||||
if not doda:
|
||||
return None
|
||||
DodaService._ensure_editable_doda(doda)
|
||||
|
||||
tipo = (pedimento_data.american_pedimento_type or "").strip()
|
||||
valor = (pedimento_data.american_pedimento_value or "").strip()
|
||||
@@ -595,8 +618,9 @@ class DodaService:
|
||||
raise HTTPException(
|
||||
status_code=404, detail="Pedimento americano no encontrado."
|
||||
)
|
||||
doda = db.get(Doda, doda_id)
|
||||
DodaService._ensure_editable_doda(doda)
|
||||
try:
|
||||
doda = db.get(Doda, doda_id)
|
||||
db.delete(db_pedimento)
|
||||
db.commit()
|
||||
if doda:
|
||||
@@ -625,6 +649,7 @@ class DodaService:
|
||||
doda = db.query(Doda).filter(Doda.id == doda_id).first()
|
||||
if not doda:
|
||||
return None
|
||||
DodaService._ensure_editable_doda(doda)
|
||||
|
||||
max_line = (
|
||||
db.query(DodaPedimento)
|
||||
@@ -681,8 +706,9 @@ class DodaService:
|
||||
)
|
||||
if not db_pedimento:
|
||||
raise HTTPException(status_code=404, detail="Pedimento no encontrado.")
|
||||
doda = db.get(Doda, doda_id)
|
||||
DodaService._ensure_editable_doda(doda)
|
||||
try:
|
||||
doda = db.get(Doda, doda_id)
|
||||
db.delete(db_pedimento)
|
||||
db.commit()
|
||||
if doda:
|
||||
|
||||
Reference in New Issue
Block a user