From ea40a0c74e41631ca6fc9e4237bfbc7022c20c4e Mon Sep 17 00:00:00 2001 From: Kevin Rosales Date: Wed, 6 Aug 2025 14:28:34 -0600 Subject: [PATCH] Se agrego coves --- api/api_v1/endpoints/pedimentos.py | 18 ++++++++---------- controllers/RESTController.py | 30 +++++++++++++++++------------- utils/peticiones.py | 12 +++++++++--- 3 files changed, 34 insertions(+), 26 deletions(-) diff --git a/api/api_v1/endpoints/pedimentos.py b/api/api_v1/endpoints/pedimentos.py index 0431e2a..a549d61 100644 --- a/api/api_v1/endpoints/pedimentos.py +++ b/api/api_v1/endpoints/pedimentos.py @@ -1142,27 +1142,25 @@ async def get_cove(request: ServiceRemesaSchema): # Obtener COVES logger.info("Obteniendo COVES...") + try: coves = await rest_controller.get_coves(service_data['pedimento']['id']) - if not coves: logger.warning("No se encontraron COVES para el pedimento") await _update_service_status(service_data['id'], ESTADO_ERROR, service_data, operation_name) raise HTTPException(status_code=404, detail="No se encontraron COVES para el pedimento") - logger.info(f"Se encontraron {len(coves)} COVES") - except HTTPException: raise except Exception as e: logger.error(f"Error al obtener COVES: {e}") await _update_service_status(service_data['id'], ESTADO_ERROR, service_data, operation_name) raise HTTPException(status_code=500, detail="Error al obtener COVES") - + # Procesar acuses de documentos digitalizados documentos_procesados = [] documentos_exitosos = 0 - + logger.info(f"Procesando COVE para {len(coves)} documentos...") for idx, cove in enumerate(coves): @@ -1173,17 +1171,17 @@ async def get_cove(request: ServiceRemesaSchema): "procesado": False, "error": None } - + # Verificar que el documento tenga número de cove if not cove.get('numero_cove'): logger.warning(f"Documento {idx + 1} no tiene numero_cove, saltando...") documento_info["error"] = "Sin número de cove" documentos_procesados.append(documento_info) continue - + try: logger.info(f"Procesando cove para documento {idx + 1}: {cove['numero_cove']}") - + # Procesar cove del documento soap_response = await get_soap_cove( credenciales=credentials, response_service=service_data, @@ -1191,7 +1189,7 @@ async def get_cove(request: ServiceRemesaSchema): cove=cove, idx=idx + 1 ) - + if soap_response: documento_info["procesado"] = True documento_info["documento"] = soap_response.get('documento', {}) @@ -1205,7 +1203,7 @@ async def get_cove(request: ServiceRemesaSchema): logger.error(f"Error al procesar cove del documento {idx + 1}: {e}") documento_info["error"] = str(e) # Continuar con los siguientes documentos - + documentos_procesados.append(documento_info) # Verificar si se procesó al menos un documento diff --git a/controllers/RESTController.py b/controllers/RESTController.py index fdac624..301e1bd 100644 --- a/controllers/RESTController.py +++ b/controllers/RESTController.py @@ -253,25 +253,27 @@ class APIController: """ return await self._make_request_async('PUT', f'customs/edocuments/{edocument_id}/', data=data) - async def get_cer(self, id: str) -> Dict[str, Any]: + async def get_cer(self, id: str) -> bytes: """ - Método para obtener un certificado específico desde la API. - + Método para obtener un certificado específico desde la API (como binario). Args: id: UUID del certificado a consultar + Returns: + bytes: Contenido binario del certificado """ - return await self._make_request_async('GET', f'vucem/vucem/{id}/download_cer/') + return await self._make_request_async('GET', f'vucem/vucem/{id}/download_cer/', return_bytes=True) - async def get_key(self, id: str) -> Dict[str, Any]: + async def get_key(self, id: str) -> bytes: """ - Método para obtener una llave específica desde la API. - + Método para obtener una llave específica desde la API (como binario). Args: id: UUID de la llave a consultar + Returns: + bytes: Contenido binario de la llave """ - return await self._make_request_async('GET', f'vucem/vucem/{id}/download_key/') - - async def _make_request_async(self, method: str, endpoint: str, data=None): + return await self._make_request_async('GET', f'vucem/vucem/{id}/download_key/', return_bytes=True) + + async def _make_request_async(self, method: str, endpoint: str, data=None, return_bytes: bool = False): """ Método asíncrono para hacer peticiones a la API usando httpx. """ @@ -296,9 +298,11 @@ class APIController: response.raise_for_status() logger.info(f"Respuesta exitosa: {response.status_code}") - - result = response.json() if response.content else {} - return result + if return_bytes: + return response.content + else: + result = response.json() if response.content else {} + return result except httpx.TimeoutException as e: logger.error(f"Timeout en petición a {url}: {e}") diff --git a/utils/peticiones.py b/utils/peticiones.py index d5310d0..3ca8f6b 100644 --- a/utils/peticiones.py +++ b/utils/peticiones.py @@ -934,13 +934,19 @@ async def get_soap_cove(credenciales, response_service, soap_controller, cove, i # Cadena original que vas a firmar cadena_original = f"|{username}|{cove['numero_cove']}|" - # Obtener certificado base64 y firma - cer = rest_controller.get_cer(credenciales['id']) + # Obtener certificado base64 y firma (await async calls) + cer = await rest_controller.get_cer(credenciales['id']) + if cer is None: + logger.error(f"No se pudo obtener el certificado (cer) para credencial ID: {credenciales['id']}") + raise HTTPException(status_code=500, detail="No se pudo obtener el certificado para firmar el COVE") certificado = base64.b64encode(cer).decode('utf-8') # Obtener la key como binario y guardarla en un archivo temporal import tempfile - key_bytes = rest_controller.get_key(credenciales['id']) + key_bytes = await rest_controller.get_key(credenciales['id']) + if key_bytes is None: + logger.error(f"No se pudo obtener la llave privada (key) para credencial ID: {credenciales['id']}") + raise HTTPException(status_code=500, detail="No se pudo obtener la llave privada para firmar el COVE") with tempfile.NamedTemporaryFile(delete=False) as tmp_key_file: tmp_key_file.write(key_bytes) tmp_key_path = tmp_key_file.name