feature/pedimento completo carga remesas, coves, edocs y acuses y aparte descarga sus documentos, se corrigieron las formulas de remesas, acuse y e documents para permitir la correcta descarga de susdocumentos y se aseguro que el status sea el correcto
This commit is contained in:
@@ -48,12 +48,13 @@ async def obtener_edoc(**kwargs):
|
||||
|
||||
file_name_request = f"VU_ED_{pedimento_app}_{numero_documento}_REQUEST.xml"
|
||||
|
||||
document_response = await edocs_rest_controller.post_document(
|
||||
document_response = await edocs_rest_controller.post_or_update_document(
|
||||
soap_response=soap_xml,
|
||||
organizacion=organizacion_efc,
|
||||
pedimento=pedimento_id_efc,
|
||||
file_name=file_name_request,
|
||||
document_type=21 # Tipo de documento para request de e-document,
|
||||
document_type=21,
|
||||
identifier=numero_documento,
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
@@ -97,6 +98,21 @@ async def obtener_edoc(**kwargs):
|
||||
|
||||
if soap_error(response):
|
||||
logger.error("Respuesta SOAP contiene error de VUCEM")
|
||||
_pedimento_efc = kwargs.get('pedimento', {})
|
||||
_file_name_error = f"VU_ED_{_pedimento_efc.get('pedimento_app', 'N/A')}_{numero_documento}_RESPONSE_ERROR.xml"
|
||||
logger.info(f"Guardando RESPONSE_ERROR doc_type=22: file={_file_name_error}, organizacion={_pedimento_efc.get('organizacion')}, pedimento={_pedimento_efc.get('id')}")
|
||||
_doc_result = await edocs_rest_controller.post_or_update_document(
|
||||
soap_response=response.text,
|
||||
organizacion=_pedimento_efc.get('organizacion'),
|
||||
pedimento=_pedimento_efc.get('id'),
|
||||
file_name=_file_name_error,
|
||||
document_type=22,
|
||||
identifier=numero_documento,
|
||||
)
|
||||
if _doc_result is None:
|
||||
logger.error("post_or_update_document retornó None para RESPONSE_ERROR doc_type=22 — archivo físico sin registro en BD")
|
||||
else:
|
||||
logger.info(f"RESPONSE_ERROR registrado en BD: id={_doc_result.get('id')}, document_type={_doc_result.get('document_type')}")
|
||||
raise HTTPException(
|
||||
status_code=500,
|
||||
detail=create_error_response(
|
||||
@@ -109,8 +125,23 @@ async def obtener_edoc(**kwargs):
|
||||
|
||||
try:
|
||||
edoc_base64 = extract_pdf_bytes_from_xml_content(response.text)
|
||||
except ValueError as ve:
|
||||
except Exception as ve:
|
||||
logger.error(f"Error extrayendo contenido del XML: {ve}")
|
||||
_pedimento_efc = kwargs.get('pedimento', {})
|
||||
_file_name_error = f"VU_ED_{_pedimento_efc.get('pedimento_app', 'N/A')}_{numero_documento}_RESPONSE_ERROR.xml"
|
||||
logger.info(f"Guardando RESPONSE_ERROR doc_type=22 (parse error): file={_file_name_error}")
|
||||
_doc_result = await edocs_rest_controller.post_or_update_document(
|
||||
soap_response=response.text,
|
||||
organizacion=_pedimento_efc.get('organizacion'),
|
||||
pedimento=_pedimento_efc.get('id'),
|
||||
file_name=_file_name_error,
|
||||
document_type=22,
|
||||
identifier=numero_documento,
|
||||
)
|
||||
if _doc_result is None:
|
||||
logger.error("post_document retornó None para RESPONSE_ERROR doc_type=22 (parse error)")
|
||||
else:
|
||||
logger.info(f"RESPONSE_ERROR registrado en BD: id={_doc_result.get('id')}, document_type={_doc_result.get('document_type')}")
|
||||
raise HTTPException(
|
||||
status_code=500,
|
||||
detail=create_error_response(
|
||||
@@ -180,6 +211,8 @@ async def obtener_edoc(**kwargs):
|
||||
document_type=5
|
||||
)
|
||||
|
||||
print(f"rest_response >>>> {rest_response}")
|
||||
|
||||
if rest_response is None:
|
||||
logger.error("Error al enviar el documento a la API interna")
|
||||
raise HTTPException(
|
||||
@@ -239,9 +272,10 @@ async def obtener_edoc(**kwargs):
|
||||
|
||||
|
||||
async def change_edocument_status(edoc: dict, status: bool, pedimento: dict):
|
||||
# estaba acualizando mal el status de descarga, actualizaba otro campo que no le correspondia
|
||||
data = {
|
||||
"id": edoc.get("id"),
|
||||
"acuse_descargado": status,
|
||||
"edocument_descargado": status,
|
||||
"numero_edocument": edoc.get("numero_edocument"),
|
||||
"pedimento": pedimento.get("id"),
|
||||
"organizacion": pedimento.get("organizacion"),
|
||||
@@ -252,42 +286,42 @@ async def change_edocument_status(edoc: dict, status: bool, pedimento: dict):
|
||||
return response
|
||||
|
||||
|
||||
NS = {
|
||||
's': 'http://schemas.xmlsoap.org/soap/envelope/',
|
||||
't': 'http://tempuri.org/',
|
||||
'i': 'http://www.w3.org/2001/XMLSchema-instance'
|
||||
}
|
||||
|
||||
# mejorar la extraccion de seccion File
|
||||
def extract_pdf_bytes_from_xml_content(xml_content: str):
|
||||
"""
|
||||
Extrae el PDF y metadatos desde un string XML.
|
||||
"""
|
||||
root = ET.fromstring(xml_content)
|
||||
file_elem = root.find('.//File')
|
||||
if file_elem is None:
|
||||
for elem in root.iter():
|
||||
if elem.tag.endswith('File') and elem.text:
|
||||
file_elem = elem
|
||||
break
|
||||
if file_elem is not None and file_elem.text and file_elem.text.strip():
|
||||
base64_data = file_elem.text.strip().replace('\n', '').replace('\r', '')
|
||||
pdf_bytes = base64.b64decode(base64_data)
|
||||
cadena_original = None
|
||||
sello_digital = None
|
||||
cadena_elem = root.find('.//CadenaOriginal')
|
||||
if cadena_elem is None:
|
||||
for elem in root.iter():
|
||||
if elem.tag.endswith('CadenaOriginal') and elem.text:
|
||||
cadena_elem = elem
|
||||
break
|
||||
if cadena_elem is not None and cadena_elem.text:
|
||||
cadena_original = cadena_elem.text.strip()
|
||||
sello_elem = root.find('.//SelloDigital')
|
||||
if sello_elem is None:
|
||||
for elem in root.iter():
|
||||
if elem.tag.endswith('SelloDigital') and elem.text:
|
||||
sello_elem = elem
|
||||
break
|
||||
if sello_elem is not None and sello_elem.text:
|
||||
sello_digital = sello_elem.text.strip()
|
||||
return {
|
||||
"pdf_bytes": pdf_bytes,
|
||||
"cadena_original": cadena_original,
|
||||
"sello_digital": sello_digital
|
||||
}
|
||||
else:
|
||||
raise ValueError("No se encontró el tag <File> con contenido válido. Verifique que el XML contiene el tag <File> con datos base64.")
|
||||
|
||||
errores = root.find('.//t:Errores', NS)
|
||||
tiene_error = root.find('.//t:TieneError', NS)
|
||||
|
||||
if tiene_error is not None and tiene_error.text == 'true':
|
||||
err_msg = errores.text if errores is not None else 'Error desconocido'
|
||||
raise Exception(f"VUCEM informa error: {err_msg}")
|
||||
|
||||
file_elem = root.find('.//t:File', NS)
|
||||
if file_elem is None or file_elem.get('{http://www.w3.org/2001/XMLSchema-instance}nil') == 'true' or not file_elem.text:
|
||||
raise ValueError("No se encontró el tag <File> con contenido válido.")
|
||||
|
||||
base64_data = file_elem.text.strip().replace('\n', '').replace('\r', '')
|
||||
pdf_bytes = base64.b64decode(base64_data)
|
||||
|
||||
# Extraer CadenaOriginal y SelloDigital con namespaces
|
||||
cadena_original = None
|
||||
sello_digital = None
|
||||
cadena_elem = root.find('.//t:CadenaOriginal', NS)
|
||||
if cadena_elem is not None and cadena_elem.get('{http://www.w3.org/2001/XMLSchema-instance}nil') != 'true':
|
||||
cadena_original = cadena_elem.text.strip() if cadena_elem.text else None
|
||||
sello_elem = root.find('.//t:SelloDigital', NS)
|
||||
if sello_elem is not None and sello_elem.get('{http://www.w3.org/2001/XMLSchema-instance}nil') != 'true':
|
||||
sello_digital = sello_elem.text.strip() if sello_elem.text else None
|
||||
|
||||
return {
|
||||
"pdf_bytes": pdf_bytes,
|
||||
"cadena_original": cadena_original,
|
||||
"sello_digital": sello_digital
|
||||
}
|
||||
Reference in New Issue
Block a user