from __future__ import annotations from datetime import date from typing import List, Optional from pydantic import BaseModel, Field # --------------------------------------------------------------------------- # CRUD DTOs # --------------------------------------------------------------------------- class ExpedienteArchivoCreateDTO(BaseModel): e_document: Optional[str] = Field(None, max_length=50) num_operacion: Optional[str] = Field(None, max_length=50) tipo_documento: Optional[str] = Field(None, max_length=10) archivo_digitalizado_en: Optional[str] = Field(None, max_length=500) fecha_digitalizacion: Optional[date] = None agente_aduanal: Optional[str] = Field(None, max_length=50) pedimento: Optional[str] = Field(None, max_length=21) rfc_consulta: Optional[str] = Field(None, max_length=13) nombre_archivo: Optional[str] = Field(None, max_length=255) class ExpedienteArchivoUpdateDTO(BaseModel): e_document: Optional[str] = Field(None, max_length=50) num_operacion: Optional[str] = Field(None, max_length=50) tipo_documento: Optional[str] = Field(None, max_length=10) archivo_digitalizado_en: Optional[str] = Field(None, max_length=500) fecha_digitalizacion: Optional[date] = None agente_aduanal: Optional[str] = Field(None, max_length=50) pedimento: Optional[str] = Field(None, max_length=21) rfc_consulta: Optional[str] = Field(None, max_length=13) nombre_archivo: Optional[str] = Field(None, max_length=255) class ExpedienteArchivoResponseDTO(BaseModel): id: int e_document: Optional[str] = None num_operacion: Optional[str] = None tipo_documento: Optional[str] = None archivo_digitalizado_en: Optional[str] = None fecha_digitalizacion: Optional[date] = None agente_aduanal: Optional[str] = None pedimento: Optional[str] = None rfc_consulta: Optional[str] = None nombre_archivo: Optional[str] = None status: Optional[str] = None task_id: Optional[str] = None external_task_id: Optional[str] = None acuse_pdf_path: Optional[str] = None envio_xml_path: Optional[str] = None respuesta_xml_path: Optional[str] = None consulta_envio_xml_path: Optional[str] = None consulta_respuesta_xml_path: Optional[str] = None company_id: int tenant_id: int model_config = {"from_attributes": True} class ExpedienteArchivoListResponse(BaseModel): items: List[ExpedienteArchivoResponseDTO] total: int page: int page_size: int # --------------------------------------------------------------------------- # Digitalización DTOs # --------------------------------------------------------------------------- class DigitalizarRequest(BaseModel): """ Solicitud de digitalización enviada por el frontend. La configuracion_vu se ensambla server-side desde CustomsBrokerVU / company. """ rfc_consulta: Optional[str] = Field(None, max_length=13) clave_documento: Optional[str] = Field(None, max_length=10) nombre_archivo: Optional[str] = Field(None, max_length=255) archivo_base64: Optional[str] = None # contenido del archivo en base64; opcional si el expediente ya tiene archivo almacenado class RegistrarDigitalizacionRequest(BaseModel): """Digitalizar múltiples expedientes existentes por ID.""" rfc_consulta: Optional[str] = Field(None, max_length=13) ids_archivos: List[int] class DigitalizarResponse(BaseModel): task_id: str message: str status: str # --------------------------------------------------------------------------- # Task status DTOs (espejo del schema del servicio externo) # --------------------------------------------------------------------------- class DigitalizacionResult(BaseModel): status: Optional[str] = None message: Optional[str] = None request_id: Optional[str] = None response_code: Optional[int] = None xml_path: Optional[str] = None response_path: Optional[str] = None acuese_digitalizacion_pdf_base64: Optional[str] = None nombre_archivo: Optional[str] = None timestamp: Optional[str] = None numero_operacion: Optional[str] = None e_document: Optional[str] = None envio_xml_base64: Optional[str] = None respuesta_xml_base64: Optional[str] = None consulta_envio_xml_base64: Optional[str] = None consulta_respuesta_xml_base64: Optional[str] = None class DigitalizacionErrorDetail(BaseModel): codigo: Optional[str] = None descripcion: Optional[str] = None paso: Optional[str] = None sugerencias: Optional[List[str]] = None class DigitalizacionTaskDetailResponse(BaseModel): task_id: str external_task_id: Optional[str] = None state: str status: Optional[str] = None current_step: Optional[str] = None progress: Optional[int] = None total_steps: Optional[int] = None request_id: Optional[str] = None result: Optional[DigitalizacionResult] = None error: Optional[str] = None error_type: Optional[str] = None error_detail: Optional[DigitalizacionErrorDetail] = None info: Optional[dict] = None