import base64 import os import logging import re import xml.etree.ElementTree as ET from fastapi import HTTPException from controllers.RESTController import rest_controller from controllers.SOAPController import soap_controller from cryptography.hazmat.primitives import serialization, hashes from cryptography.hazmat.primitives.asymmetric import padding from cryptography.hazmat.primitives.serialization import load_der_private_key import tempfile from utils.helpers import soap_error from .controllers import partida_rest_controller, partida_vu_controller # Logger para el módulo logger = logging.getLogger(__name__) # Logica de negocio para consumir el servicio SOAP de VUCEM y procesar la respuesta async def consume_ws_get_partida(**kwargs): """ Consume el servicio SOAP para obtener un partida y procesar la respuesta. Args: **kwargs: Debe contener 'credencial', 'pedimento' y 'partida' Returns: Dict serializable con 'documento' y 'partida_put_response' Raises: Exception: Si hay errores en el procesamiento """ try: logger.info("Iniciando procesamiento de partidas") credenciales = kwargs.get('credencial') username = credenciales.get('user') pedimento_app = kwargs.get('pedimento', {}).get('pedimento_app', 'N/A') partida = kwargs.get('partida', {}) if not credenciales or not username or not partida: raise Exception("Credenciales o Partida no proporcionados correctamente") logger.info(f"Procesando Partida: {partida} para usuario: {username}") # Generar template SOAP soap_xml = partida_vu_controller.generate_partidas_template( username=username, password=credenciales.get('password'), aduana=kwargs.get('pedimento', {}).get('aduana', 'N/A'), patente=kwargs.get('pedimento', {}).get('patente', 'N/A'), pedimento=kwargs.get('pedimento', {}).get('pedimento', 'N/A'), numero_operacion=kwargs.get('pedimento', {}).get('numero_operacion', ''), partida=partida.get('numero', '') ) soap_headers = { 'Content-Type': 'text/xml; charset=utf-8' } logger.info("Enviando petición SOAP a VUCEM") soap_response = await partida_vu_controller.make_request_async( "/ventanilla-ws-pedimentos/ConsultarPartidaService", data=soap_xml, headers=soap_headers ) if not soap_response: raise Exception("No se recibió respuesta del servicio SOAP") if soap_error(soap_response): raise Exception("Error en la respuesta del servicio SOAP") logger.info("Respuesta SOAP exitosa, enviando documento") # Enviar documento _file_name = f"vu_PT_{pedimento_app}_{partida.get('numero', '')}.xml" document_response = await partida_rest_controller.post_document( soap_response=soap_response, organizacion=kwargs.get('pedimento').get('organizacion'), pedimento=kwargs.get('pedimento').get('id'), file_name=_file_name, document_type=1, ) logger.info("Documento enviado, actualizando status de Partida") # Actualizar status del partida partida_status_response = await change_partida_status( partida=kwargs.get('partida'), status=True, pedimento=kwargs.get('pedimento') ) logger.info(f"Partida {partida.get('numero', '')} procesado exitosamente") # Asegurar que la respuesta sea serializable result = { "documento": document_response if document_response else None, "partida_update_response": partida_status_response if partida_status_response else None } return result except Exception as e: logger.error(f"Error procesando la partida: {str(e)}", exc_info=True) # Asegurar que no se retornen datos binarios en el error raise Exception(f"Error interno al procesar la partida: {str(e)}") async def change_partida_status(partida: dict, status: bool, pedimento: dict): data = { "id": partida.get("id"), "numero_partida": partida.get("numero"), "descargado": status, "pedimento": pedimento.get("id"), "organizacion": pedimento.get("organizacion"), } print(data) response = await partida_rest_controller.put_partida(partida_id=partida.get("id"), data=data) return response