Se soluciono efocs
This commit is contained in:
@@ -11,30 +11,33 @@ class EdocVuController(VUCEMController):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
def generate_edoc_template(self, **kwargs) -> str:
|
|
||||||
|
|
||||||
|
def generate_edocument_template(self, username: str, password: str, idEDocument: str) -> str:
|
||||||
"""
|
"""
|
||||||
Genera el template XML de la solicitud SOAP para un edoc.
|
Genera el template SOAP para consultar un EDocument específico
|
||||||
|
|
||||||
|
Args:
|
||||||
|
username: Usuario de VUCEM
|
||||||
|
password: Contraseña de VUCEM
|
||||||
|
idEDocument: ID del EDocument
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: Template SOAP XML completo
|
||||||
"""
|
"""
|
||||||
credencial = kwargs.get("credencial", {})
|
|
||||||
username = credencial.get("user")
|
|
||||||
password = credencial.get("password")
|
|
||||||
# Aquí usamos `numero_documento` en lugar de `idEDocument` para reflejar el esquema de edocs
|
|
||||||
numero_documento = kwargs['edoc'].get("numero_edocument", "N/A")
|
|
||||||
|
|
||||||
soap_template = f'''
|
soap_template = f'''
|
||||||
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:edoc="http://www.ventanillaunica.gob.mx/consulta/edocs/oxml">
|
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
|
||||||
|
xmlns:tem="http://tempuri.org/">
|
||||||
<soapenv:Header>
|
<soapenv:Header>
|
||||||
<wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
|
<tem:UserName>{username}</tem:UserName>
|
||||||
<wsse:UsernameToken>
|
<tem:Password>{password}</tem:Password>
|
||||||
<wsse:Username>{username}</wsse:Username>
|
|
||||||
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">{password}</wsse:Password>
|
|
||||||
</wsse:UsernameToken>
|
|
||||||
</wsse:Security>
|
|
||||||
</soapenv:Header>
|
</soapenv:Header>
|
||||||
<soapenv:Body>
|
<soapenv:Body>
|
||||||
<edoc:consultaEdocumentoPeticion>
|
<tem:DocumentoIn>
|
||||||
<idEdocument>{numero_documento}</idEdocument>
|
<tem:Edocument>{idEDocument}</tem:Edocument>
|
||||||
</edoc:consultaEdocumentoPeticion>
|
<tem:IsCertificado>1</tem:IsCertificado>
|
||||||
|
</tem:DocumentoIn>
|
||||||
</soapenv:Body>
|
</soapenv:Body>
|
||||||
</soapenv:Envelope>
|
</soapenv:Envelope>
|
||||||
'''
|
'''
|
||||||
|
|||||||
@@ -9,11 +9,7 @@ from .controllers import edocs_rest_controller, edocs_vu_controller
|
|||||||
|
|
||||||
logger = logging.getLogger("app.api")
|
logger = logging.getLogger("app.api")
|
||||||
|
|
||||||
soap_headers = {
|
|
||||||
'Content-Type': 'text/xml; charset=utf-8',
|
|
||||||
'SOAPAction': 'http://www.ventanillaunica.gob.mx/ventanilla/EdocumentosService/consultarEdocumento',
|
|
||||||
'Accept-Encoding': 'gzip,deflate',
|
|
||||||
}
|
|
||||||
|
|
||||||
# --- FUNCIONES AUXILIARES ---
|
# --- FUNCIONES AUXILIARES ---
|
||||||
|
|
||||||
@@ -77,14 +73,22 @@ def _get_file_name(**kwargs) -> str:
|
|||||||
# --- FUNCIONES DE SERVICIO ---
|
# --- FUNCIONES DE SERVICIO ---
|
||||||
|
|
||||||
async def obtener_edoc(**kwargs):
|
async def obtener_edoc(**kwargs):
|
||||||
soap_xml = edocs_vu_controller.generate_edoc_template(**kwargs)
|
credencial = kwargs.get('credencial', {})
|
||||||
|
usuario = credencial.get('user', '')
|
||||||
|
password = credencial.get('password', '')
|
||||||
|
numero_documento = kwargs['edoc'].get('numero_edocument', '')
|
||||||
|
soap_headers = {
|
||||||
|
'Content-Type': 'text/xml; charset=utf-8',
|
||||||
|
'SOAPAction': 'http://tempuri.org/IServicioEdocument/GetDocumento'
|
||||||
|
}
|
||||||
|
soap_xml = edocs_vu_controller.generate_edocument_template(username=usuario, password=password, idEDocument=numero_documento)
|
||||||
|
print(soap_xml)
|
||||||
response = await edocs_vu_controller.make_request_async(
|
response = await edocs_vu_controller.make_request_async(
|
||||||
"ventanilla-edocs-HA/EdocumentosServiceWS?wsdl",
|
"Ventanilla-HA/ServicioEdocument/ServicioEdocument.svc",
|
||||||
data=soap_xml,
|
data=soap_xml,
|
||||||
headers=soap_headers
|
headers=soap_headers
|
||||||
)
|
)
|
||||||
|
print(response.text)
|
||||||
if response is None:
|
if response is None:
|
||||||
raise Exception("No se obtuvo respuesta del servicio SOAP.")
|
raise Exception("No se obtuvo respuesta del servicio SOAP.")
|
||||||
|
|
||||||
@@ -94,11 +98,11 @@ async def obtener_edoc(**kwargs):
|
|||||||
if soap_error(response):
|
if soap_error(response):
|
||||||
raise Exception("Respuesta SOAP contiene error de VUCEM.")
|
raise Exception("Respuesta SOAP contiene error de VUCEM.")
|
||||||
|
|
||||||
edoc_base64 = _extract_edoc_data(response.text)
|
edoc_base64 = extract_pdf_bytes_from_xml_content(response.text)
|
||||||
if edoc_base64 is None:
|
if edoc_base64 is None:
|
||||||
raise Exception("No se pudo extraer el documento de la respuesta SOAP.")
|
raise Exception("No se pudo extraer el documento de la respuesta SOAP.")
|
||||||
|
|
||||||
pdf_bytes = _decode_base64_content(edoc_base64)
|
pdf_bytes = edoc_base64['pdf_bytes']
|
||||||
if not pdf_bytes:
|
if not pdf_bytes:
|
||||||
raise HTTPException(status_code=500, detail="No se pudo decodificar el documento")
|
raise HTTPException(status_code=500, detail="No se pudo decodificar el documento")
|
||||||
|
|
||||||
@@ -186,3 +190,44 @@ async def obtener_edocs_masivo(**kwargs):
|
|||||||
"total_documentos": len(numeros_documentos),
|
"total_documentos": len(numeros_documentos),
|
||||||
"message": "La orquestación de descarga masiva ha sido registrada."
|
"message": "La orquestación de descarga masiva ha sido registrada."
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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.")
|
||||||
40
test.xml
40
test.xml
@@ -1,27 +1,13 @@
|
|||||||
<?xml version='1.0' encoding='UTF-8'?>
|
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
|
||||||
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
|
xmlns:tem="http://tempuri.org/">
|
||||||
<S:Header>
|
<soapenv:Header>
|
||||||
<wsse:Security
|
<tem:UserName>MTK861014317</tem:UserName>
|
||||||
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
|
<tem:Password>+PNjq4gtAm7IH3tAuipUNxXO2/ivgLbNdlwjV/teOc4PocnOtX/NYUiRezhxubN9</tem:Password>
|
||||||
S:mustUnderstand="1">
|
</soapenv:Header>
|
||||||
<wsu:Timestamp
|
<soapenv:Body>
|
||||||
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
|
<tem:DocumentoIn>
|
||||||
<wsu:Created>2025-10-06T01:09:44Z</wsu:Created>
|
<tem:Edocument>0192240XOKJH3</tem:Edocument>
|
||||||
<wsu:Expires>2025-10-06T01:10:44Z</wsu:Expires>
|
<tem:IsCertificado>1</tem:IsCertificado>
|
||||||
</wsu:Timestamp>
|
</tem:DocumentoIn>
|
||||||
</wsse:Security>
|
</soapenv:Body>
|
||||||
</S:Header>
|
</soapenv:Envelope>
|
||||||
<S:Body>
|
|
||||||
<ns3:responseConsultaAcuses
|
|
||||||
xmlns:ns2="http://www.ventanillaunica.gob.mx/consulta/acuses/oxml"
|
|
||||||
xmlns:ns3="http://www.ventanillaunica.gob.mx/ws/consulta/acuses/">
|
|
||||||
<code>0</code>
|
|
||||||
<error>true</error>
|
|
||||||
<mensajeErrores>
|
|
||||||
<claveMensaje>4</claveMensaje>
|
|
||||||
<descripcion>El RFC no tiene relación con el eDocument. </descripcion>
|
|
||||||
</mensajeErrores>
|
|
||||||
</ns3:responseConsultaAcuses>
|
|
||||||
</S:Body>
|
|
||||||
</S:Envelope>
|
|
||||||
--uuid:29d62a47-b685-4746-9959-43ab40c1ef88--
|
|
||||||
Reference in New Issue
Block a user