Files
MBS/PROYECTO/otrodir/procesoEncf.4gl
T

871 lines
29 KiB
Plaintext

import os
import com
import xml
import util
TYPE tMensaje RECORD
codigo STRING,
valor STRING
END RECORD
TYPE tRespDGII RECORD
codigo INTEGER, -- 1=OK, 2=Rechazado, etc. (cuando venga)
estado STRING, -- "Aceptado" | "Rechazado" | etc.
encf STRING,
secuenciaUtilizada BOOLEAN,
hash STRING,
fechaFirmaDigital STRING,
qrcodeurl STRING,
trackId STRING,
mensajes DYNAMIC ARRAY OF tMensaje
END RECORD
TYPE consultaRespuesta RECORD
trackid,
codigo,
estado,
rnc,
encf,
secuenciaUtilizada,
fechaRecepcion STRING,
mensajes DYNAMIC ARRAY OF tmensaje
END RECORD
TYPE dgiimensaje RECORD
codigo,estado,ecf,secuenciaUtilizada STRING,
mensajes DYNAMIC ARRAY OF tmensaje
END RECORD
DEFINE url_semilla, url_validasemilla,url_anulacion,
url_recepcion,url_consulta,url_consulta_timbre STRING
DEFINE codigo,tokenxml,nombreFile,filexml,token,respuesta,ruta_firmados,rutaSemilla,rutaCert STRING
DEFINE doc xml.DomDocument,
xfacturainterna,gsucid,gbodega INT,
goperacion VARCHAR(30)
FUNCTION procesoEncf(fileporfirmar,ambiente,tiporecepcion,xsucid,xbodega,xoperacion,krespuesta)
DEFINE fileporfirmar,rtoken,ambiente,tiporecepcion,krespuesta STRING,
xhash VARCHAR(6),xfechafirmadigital VARCHAR(50),
xsucid,xbodega INT,
xoperacion CHAR(30)
DEFINE dtrackid RECORD
trackId,error,mensaje STRING
END RECORD,
xfecha DATETIME YEAR TO minute
CALL STARTLOG("procesoencf.txt")
# LET ptipoRecepcion = tiporecepcion
LET ruta_firmados = fgl_getenv("RUTA_XML_FIRMADOS")
LET rutaSemilla = fgl_getenv("RUTA_SEMILLA")
LET rutaCert = fgl_getenv("RUTA_CERT")
IF ambiente <> "produccion" THEN
IF ambiente <> "test" THEN
LET respuesta = "no llego bien ",ambiente
RETURN ' ',respuesta,'400'
END IF
END IF
# LET xambiente = ambiente
CALL urls(ambiente,tiporecepcion)
{
SELECT a.valor,a.fecha INTO rtoken,xfecha
FROM token a
DISPLAY "tiempos: ",xfecha," ",CURRENT HOUR TO MINUTE}
# IF CURRENT HOUR TO MINUTE- xfecha > "0:44" THEN
CALL buscatoken(url_semilla) RETURNING codigo, tokenxml
IF codigo <> "200" THEN
LET respuesta = "respuesta buscatoken: ",tokenxml," ",codigo
RETURN ' ',respuesta,'400'
END IF
LET gsucid = xsucid
LET gbodega = xbodega
LET goperacion = xoperacion
# Create DomDocument object
LET doc = xml.DomDocument.Create()
# Notice that whitespaces are significant in cryptography,
# therefore it is recommended to remove unnecessary ones
CALL doc.setFeature("whitespace-in-element-content",FALSE)
CALL doc.loadFromString(tokenxml)
# CALL doc.save(".\\filesXML\\marmotech\\mtechTokenString.xml")
CALL doc.save(rutaSemilla||"/TokenString.xml")
#FIRMA SEMILLA
IF os.Path.exists(rutaSemilla||"/TokenString.xml") THEN
CALL firmasemilla()
ELSE
LET respuesta = "NO PUDE CREAR SEMILLA"
RETURN ' ',respuesta,'400'
END IF
IF os.Path.exists(rutaSemilla||"/Signature.xml") THEN
CALL validasemilla(url_validasemilla) RETURNING codigo,respuesta
IF codigo = 400 THEN
RETURN ' ',respuesta,'400'
END IF
ELSE
LET respuesta = "NO ENCONTRE LA SEMILLA FIRMADA"
RETURN ' ',respuesta,'400'
END IF
IF respuesta IS NOT NULL THEN
LET doc = xml.DomDocument.Create()
CALL doc.loadFromString(respuesta)
CALL doc.save(rutaSemilla||"/RespuestaValida.xml")
CALL gettoken() RETURNING rtoken
LET token = rtoken
# UPDATE token SET valor = rtoken,fecha=getdate()
ELSE
LET respuesta = "NO TENEMOS RESPUESTA DE VALIDA SEMILLA"
RETURN ' ',respuesta,'400'
END IF
# ELSE
# DISPLAY "en validar semilla"
# CALL validasemilla() RETURNING codigo,respuesta
# IF codigo = 400 THEN
# RETURN ' ',respuesta,'400'
# END IF
# END IF
# CUANDO EL PROCESO NO ES FIRMAR EL DOCUMENTO
IF xoperacion <> 'consultatrackid' AND xoperacion <> 'consultastatus' THEN
LET filexml = fileporfirmar
CALL firmadocumento(fileporfirmar)
LET filexml = ruta_firmados CLIPPED,os.Path.baseName(fileporfirmar)
#DISPLAY "file a enviar :",filexml
CALL enviafiles(token,filexml) RETURNING codigo,respuesta
CALL gethash(filexml) RETURNING xhash,xfechafirmadigital,xfacturainterna
# UPDATE vetb00002 SET hash = xhash WHERE factura = xfacturainterna AND sucid = xsucid
ELSE
IF xoperacion = 'consultatrackid' THEN
LET token = " Bearer ",token
CALL consultaResultado(token,krespuesta) RETURNING codigo, respuesta
END IF
IF xoperacion = 'consultastatus' THEN
LET token = " ApiKey ",token
CALL obtenerStatus(token)
END IF
END IF
RETURN xhash,respuesta,codigo
END FUNCTION
FUNCTION firmadocumento(fileafirmar)
DEFINE doc xml.DomDocument
DEFINE doc2 xml.DomDocument
DEFINE root xml.DomNode
DEFINE node xml.DomNode
DEFINE signNode xml.DomNode
DEFINE sig xml.Signature
DEFINE key xml.CryptoKey
DEFINE cert xml.CryptoX509
DEFINE index INTEGER,
fileafirmar STRING
LET rutaCert = fgl_getenv("RUTA_CERT")
LET ruta_firmados = fgl_getenv("RUTA_XML_FIRMADOS")
# Create DomDocument object
LET doc = xml.DomDocument.Create()
# Notice that whitespaces are significant in cryptography,
# therefore it is recommended to remove unnecessary ones
CALL doc.setFeature("whitespace-in-element-content",FALSE)
LET filexml = fileafirmar
CALL doc.load(fileafirmar)
TRY
# Create rsa key
LET key = xml.CryptoKey.Create("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256")
#CALL key.loadPEM(".\\cert\\marmotech\\onlyRSA.pem")
CALL key.loadPEM(rutaCert clipped||"/onlyRSA.pem")
# Create an X509 certificate with the constructor of the CryptoX509 class.
LET cert = xml.CryptoX509.Create()
CALL cert.setFeature("X509Certificate",TRUE)
# Load the X509 certificate associated to the RSA or DSA private key into the CryptoKey object.
# CALL cert.loadPEM("cert509.crt")
CALL cert.loadPEM(rutaCert clipped||"/onlyCert.pem")
# Create signature object with the key to use
LET sig = xml.Signature.Create()
# Assign the CryptoKey object to the Signature object.
CALL sig.setKey(KEY)
# Assign the CryptoX509 object to the Signature object.
CALL sig.setCertificate(cert)
# Set XML node to be signed. In our case, the entire document
# LET index = sig.createReference("",
# "http://www.w3.org/2001/04/xmlenc#sha256")
LET index = sig.createReference('""',
"http://www.w3.org/2001/04/xmlenc#sha256")
# Add enveloped method to not take the XML signature node into account
# when computing the entire document.
CALL sig.appendReferenceTransformation(index,
"http://www.w3.org/2000/09/xmldsig#enveloped-signature",doc.getDocumentElement())
# Set canonicalization method on the XML fragment to be signed.
# Compute enveloped signature
CALL sig.compute(doc)
# Retrieve signature document
LET doc2=sig.getDocument()
# Append the signature node to the original document to get
# a valid enveloped signature
# Notice that the enveloped signature can be added anywhere in the
# original document
LET signNode = doc2.getDocumentElement() # Get Signature node
# Import it into the original document
LET node = doc.importNode(signNode,true)
# Retrieve the original document root node
LET root = doc.getDocumentElement()
# Append the signature node as last child of the original document
CALL root.appendChild(node)
# Save document with enveloped signature back to disk
CALL doc.setFeature("format-pretty-print",TRUE)
LET fileafirmar = ruta_firmados CLIPPED,os.Path.baseName(fileafirmar)
CALL doc.save(fileafirmar)
CATCH
DISPLAY "Unable to create an enveloped signature :",status," ",sqlca.sqlerrm
DISPLAY "aqui"
END TRY
END FUNCTION
FUNCTION firmasemilla()
DEFINE doc xml.DomDocument
DEFINE doc2 xml.DomDocument
DEFINE root xml.DomNode
DEFINE node xml.DomNode
DEFINE signNode xml.DomNode
DEFINE sig xml.Signature
DEFINE key xml.CryptoKey
DEFINE cert xml.CryptoX509
DEFINE index INTEGER
LET rutaSemilla = fgl_getenv("RUTA_SEMILLA")
LET rutaCert = fgl_getenv("RUTA_CERT")
# Create DomDocument object
LET doc = xml.DomDocument.Create()
# Notice that whitespaces are significant in cryptography,
# therefore it is recommended to remove unnecessary ones
CALL doc.setFeature("whitespace-in-element-content",FALSE)
LET filexml = rutaSemilla||"/TokenString.xml"
IF os.Path.exists(filexml) THEN
CALL doc.load(filexml)
ELSE
DISPLAY "NO LO ENCONTRE"
RETURN
END IF
TRY
# Create rsa key
LET key = xml.CryptoKey.Create("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256")
CALL key.loadPEM(rutaCert||"/onlyRSA.pem")
# Create an X509 certificate with the constructor of the CryptoX509 class.
LET cert = xml.CryptoX509.Create()
CALL cert.setFeature("X509Certificate",TRUE)
# Load the X509 certificate associated to the RSA or DSA private key into the CryptoKey object.
# CALL cert.loadPEM("cert509.crt")
CALL cert.loadPEM(rutaCert||"/onlyCert.pem")
# Create signature object with the key to use
LET sig = xml.Signature.Create()
# Assign the CryptoKey object to the Signature object.
CALL sig.setKey(KEY)
# Assign the CryptoX509 object to the Signature object.
CALL sig.setCertificate(cert)
# Set XML node to be signed. In our case, the entire document
# LET index = sig.createReference("",
# "http://www.w3.org/2001/04/xmlenc#sha256")
LET index = sig.createReference('""',
"http://www.w3.org/2001/04/xmlenc#sha256")
# Add enveloped method to not take the XML signature node into account
# when computing the entire document.
CALL sig.appendReferenceTransformation(index,
"http://www.w3.org/2000/09/xmldsig#enveloped-signature",doc.getDocumentElement())
# Set canonicalization method on the XML fragment to be signed.
# CALL sig.appendReferenceTransformation(index,
# "http://www.w3.org/2001/10/xml-exc-c14n#")
# Compute enveloped signature
CALL sig.compute(doc)
# Retrieve signature document
LET doc2=sig.getDocument()
# Append the signature node to the original document to get
# a valid enveloped signature
# Notice that the enveloped signature can be added anywhere in the
# original document
LET signNode = doc2.getDocumentElement() # Get Signature node
# Import it into the original document
LET node = doc.importNode(signNode,true)
# Retrieve the original document root node
LET root = doc.getDocumentElement()
# Append the signature node as last child of the original document
CALL root.appendChild(node)
# Save document with enveloped signature back to disk
CALL doc.setFeature("format-pretty-print",TRUE)
CALL doc.save(rutaSemilla||"/Signature.xml")
CATCH
DISPLAY "Unable to create an enveloped signature :",status," ",sqlca.sqlerrm
END TRY
END FUNCTION
FUNCTION validasemilla(url_validasemilla1)
DEFINE respuesta,codigo,url_validasemilla1 STRING,
http_req com.HttpRequest,
http_resp com.HTTPResponse
LET rutaSemilla = fgl_getenv("RUTA_SEMILLA")
LET http_req = com.HTTPRequest.Create(url_validasemilla1)
CALL http_req.setMethod("POST")
CALL http_req.setCharset("UTF-8")
CALL http_req.setHeader("accept","application/xml")
CALL http_req.setMultipartType("form-data",NULL,NULL)
CALL http_req.setConnectionTimeOut(10)
IF os.Path.exists(rutaSemilla||"/Signature.xml") THEN
# CALL http_req.setHeader("Content-Disposition", "form-data; name=\"xml\"; filename=\"naceSignature.xml\"")
CALL http_req.setHeader("Content-Disposition", "form-data; name=\"xml\"; filename=\"Signature.xml\"")
# TRY
CALL http_req.doFileRequest(rutaSemilla||"/Signature.xml")
# CATCH
-- Intentar obtener la
# RETURN 400, "NO OBTUVE RESPUESTA DEL SERICIO AL VALIDAR SEMILLA"
# END TRY
-- Continuar con la ejecución normal si no se produjo una excepción
LET http_resp = http_req.getResponse()
LET codigo = http_resp.getStatusCode()
LET respuesta = http_resp.getTextResponse()
ELSE
LET codigo=400
LET respuesta='NO ENCONTRE EL FILE PARA VALIDAR SEMILLA'
END IF
RETURN codigo, respuesta
END FUNCTION
FUNCTION enviafiles(btoken,archivo)
DEFINE respuesta,btoken,codigo,archivo,contenido,consultaResp,body STRING,
http_req com.HttpRequest,
http_resp com.HTTPResponse,
xresp RECORD
codigo,estado,mensajes,encf,secuenciaUtilizada STRING
END RECORD
DEFINE api tRespDGII
DEFINE r RECORD
codigo INTEGER,
estado STRING,
mensajes DYNAMIC ARRAY OF RECORD
codigo STRING,
valor STRING
END RECORD,
encf STRING,
secuenciaUtilizada BOOLEAN,
hash STRING,
fechaFirmaDigital STRING,
qrcodeurl STRING,
trackId STRING
END RECORD
DEFINE dummy INTEGER
DEFINE drespuesta consultaRespuesta
DEFINE otrosMensajes dgiimensaje
LET btoken =" Bearer ",btoken
DISPLAY "url: ",url_recepcion
LET http_req = com.HTTPRequest.Create(url_recepcion)
CALL http_req.setMethod("POST")
CALL http_req.setCharset("UTF-8")
CALL http_req.setHeader("accept","application/json")
CALL http_req.setHeader("Authorization",btoken)
CALL http_req.setConnectionTimeOut(10)
CALL http_req.setMultipartType("form-data",NULL,NULL)
# "form-data; name=\"xml\"; filename=\"naceSignature.xml\""
IF os.Path.exists(archivo) THEN
LET contenido = "form-data; name=\"xml\"; filename=",os.path.basename(archivo)
# DISPLAY "contenido: ",contenido
# CALL http_req.setHeader("Content-Disposition", "form-data; name=\"xml\"; filename=\"131880681E310000000001.xml\"")
CALL http_req.setHeader("Content-Disposition", contenido CLIPPED)
CALL http_req.doFileRequest(archivo)
LET http_resp= http_req.getResponse()
LET body = http_resp.getTextResponse()
DISPLAY "respuesta body: ",body
LET codigo = http_resp.getStatusCode()
CALL parse_dgii_response(body) RETURNING api.*
DISPLAY "despues de parse_dgii_response: ",api.*
IF api.estado IS NULL OR api.estado = "" THEN
IF api.mensajes[1].codigo IS NOT NULL AND api.mensajes.getLength() > 0 THEN
LET api.estado = "Rechazado"
IF api.codigo IS NULL THEN LET api.codigo = 2 END IF
# ELSE
# LET api.estado = "Procesando"
END IF
END IF
IF http_resp.getStatusCode() != 200 THEN
RETURN http_resp.getStatusCode(), util.JSON.stringify(api)
END IF
IF (api.hash IS NULL OR api.hash = "") OR (api.qrcodeurl IS NULL OR api.qrcodeurl = "") THEN
TRY
CALL util.JSON.parse(body,otrosMensajes)
LET api.codigo = otrosmensajes.codigo
LET api.encf = otrosmensajes.ecf
LET api.estado = otrosmensajes.estado
LET api.secuenciaUtilizada = otrosmensajes.secuenciaUtilizada
LET api.mensajes = otrosmensajes.mensajes
CATCH
CALL consultaResultado(btoken, util.JSON.stringify(api))
RETURNING dummy, consultaResp
TRY
CALL UTIL.JSON.parse(consultaResp,drespuesta)
CATCH
END TRY
LET api.codigo = drespuesta.codigo
LET api.encf = drespuesta.encf
LET api.estado = drespuesta.estado
LET api.fechaFirmaDigital = drespuesta.fechaRecepcion
LET api.trackId = drespuesta.trackid
LET api.secuenciaUtilizada = drespuesta.secuenciaUtilizada
IF dummy = 200 AND consultaResp <> "" THEN
RETURN 200, util.JSON.stringify(api)
END IF
END TRY
END IF
ELSE
LET api.codigo=401
LET api.estado = "INPROG"
LET api.mensajes[1].valor='NO ENCOENTRE EL FILE A ENVIAR'
RETURN 401, util.JSON.stringify(api)
END IF
RETURN http_resp.getStatusCode(), util.JSON.stringify(api)
END FUNCTION
FUNCTION consultaResultado(ctoken,data)
DEFINE data,ctoken,mensaje_dgii,message_err STRING
DEFINE crespuesta STRING,
http_req com.HttpRequest,
http_resp com.HTTPResponse
DEFINE dtrackid RECORD
trackId,error,mensaje STRING
END RECORD
DISPLAY "consultatrackid: ",ctoken," || ",data
TRY
CALL util.JSON.parse(data,dtrackid)
CATCH
LET message_Err ='Error EN JSON CONSULTA RESULTADO: ',STATUS
CALL errorlog(message_Err)
END TRY
LET url_consulta = url_consulta CLIPPED,"?TrackId=",dtrackid.trackid CLIPPED
LET http_req = com.HTTPRequest.Create(url_consulta)
CALL http_req.setMethod("GET")
CALL http_req.setCharset("UTF-8")
CALL http_req.setConnectionTimeOut(10)
CALL http_req.setHeader("accept","application/json")
CALL http_req.setHeader("Authorization",ctoken)
TRY
CALL http_req.doRequest()
LET http_resp= http_req.getResponse()
LET crespuesta = http_resp.getTextResponse()
LET mensaje_dgii = "Trackid: ", dtrackid.trackid CLIPPED," respuesta: ",crespuesta, " code: ",http_resp.getStatusCode()
CATCH
LET crespuesta = 'Servicio no responde, no consulta'
RETURN 400,crespuesta
END TRY
RETURN http_resp.getStatusCode(),crespuesta
END FUNCTION
FUNCTION gettoken()
DEFINE i, l INTEGER
DEFINE r om.XmlReader
DEFINE e,tok String
DEFINE a om.SaxAttributes
# DISPLAY "filexml: ",filexml
LET r = om.XmlReader.createFileReader(rutaSemilla||"/RespuestaValida.xml")
LET l = 0
LET e = r.read()
WHILE e IS NOT NULL
CASE e
WHEN "StartDocument"
# DISPLAY "StartDocument:"
WHEN "StartElement"
LET l=l+1
# DISPLAY l SPACES, "StartElement:", r.getTagName()
LET a = r.getAttributes()
FOR i=1 to a.getLength()
IF a.getName(i) = "token" THEN
# DISPLAY l SPACES," ",
# a.getName(i)," = ",
# a.getValueByIndex(i)
END IF
END FOR
WHEN "Characters"
IF r.getTagName() = "token" THEN
LET tok = r.getCharacters()
# DISPLAY "token dentro de gettoken: ",tok
EXIT CASE
END IF
WHEN "SkippedEntity"
# DISPLAY "Entity:'",r.skippedEntity(),"'"
WHEN "EndElement"
# DISPLAY l SPACES, "EndElement:", r.getTagName()
LET l=l-1
WHEN "EndDocument"
# DISPLAY "EndDocument:"
OTHERWISE
# DISPLAY "Invalid event: ",e
END CASE
LET e=r.read()
END WHILE
RETURN tok
END FUNCTION
FUNCTION gethash(envfile)
DEFINE i, l INTEGER
DEFINE r om.XmlReader
DEFINE e,envfile STRING,
phash VARCHAR(6),
pfechafirmadigital VARCHAR(50),
facturainterna INT
DEFINE a om.SaxAttributes
LET r = om.XmlReader.createFileReader(envfile)
LET l = 0
LET e = r.read()
WHILE e IS NOT NULL
CASE e
WHEN "StartDocument"
# DISPLAY "StartDocument:"
WHEN "StartElement"
LET l=l+1
#DISPLAY l SPACES, "StartElement:", r.getTagName()
LET a = r.getAttributes()
FOR i=1 to a.getLength()
IF a.getName(i) = "SignatureValue" THEN
LET phash = r.getCharacters()
# DISPLAY l SPACES," ",
# a.getName(i)," = ",
# a.getValueByIndex(i)
END IF
END FOR
WHEN "Characters"
IF r.getTagName() = "SignatureValue" THEN
LET phash = r.getCharacters()
# DISPLAY "token dentro de gettoken: ",tok
EXIT CASE
END IF
IF r.getTagName() = "FechaHoraFirma" THEN
LET pfechafirmadigital = r.getCharacters()
# DISPLAY "token dentro de gettoken: ",tok
EXIT CASE
END IF
IF r.getTagName() = "NumeroFacturaInterna" THEN
LET facturainterna = r.getCharacters()
EXIT CASE
END IF
WHEN "SkippedEntity"
# DISPLAY "Entity:'",r.skippedEntity(),"'"
WHEN "EndElement"
# DISPLAY l SPACES, "EndElement:", r.getTagName()
LET l=l-1
WHEN "EndDocument"
# DISPLAY "EndDocument:"
OTHERWISE
# DISPLAY "Invalid event: ",e
END CASE
LET e=r.read()
END WHILE
RETURN phash,pfechafirmadigital,facturainterna
END FUNCTION
FUNCTION buscatoken(url_semilla1)
DEFINE respuesta,url_semilla1 STRING,
http_req com.HttpRequest,
http_resp com.HTTPResponse
#SELECT a.urltoken INTO url FROM companias a
#"https://ecf.dgii.gov.do/testecf/autenticacion/api/autenticacion/semilla"
#"https://ecf.dgii.gov.do/CerteCF/Autenticacion/api/Autenticacion/Semilla"
LET http_req = com.HTTPRequest.Create(url_semilla1)
CALL http_req.setMethod("GET")
CALL http_req.setCharset("UTF-8")
CALL http_req.setHeader("accept","application/xml")
# CALL http_req.setConnectionTimeOut(10)
# TRY
CALL http_req.doRequest()
LET http_resp= http_req.getResponse()
LET respuesta = http_resp.getTextResponse()
# CATCH
# LET respuesta = 'No pude conseguir el token'
# RETURN 400,respuesta
# END TRY
#DISPLAY "cod token ",http_resp.getTextResponse()," ",http_resp.getStatusCode()
# IF http_resp.getStatusCode() != 200 THEN
# RETURN http_resp.getStatusCode(), http_resp.getTextResponse()
# END IF
DISPLAY "busca token: ",respuesta
RETURN http_resp.getStatusCode(),respuesta
END FUNCTION
FUNCTION urls(xambiente,ptipoRecepcion)
DEFINE xambiente,ptipoRecepcion STRING
IF xambiente = "produccion" THEN
IF ptipoRecepcion = "normal" THEN
LET url_recepcion ="https://ecf.dgii.gov.do/ecf/Recepcion/api/FacturasElectronicas"
ELSE
IF ptipoRecepcion = 'consumo' THEN
LET url_recepcion ="https://ecf.dgii.gov.do/ecf/Recepcion/api/FacturasElectronicas"
END IF
END IF
IF ptipoRecepcion = 'normal32' THEN
LET url_recepcion ="https://fc.dgii.gov.do/ecf/RecepcionFC/api/Recepcion/ecf"
END IF
LET url_semilla ="https://ecf.dgii.gov.do/ecf/autenticacion/api/autenticacion/semilla"
LET url_validasemilla ="https://ecf.dgii.gov.do/ecf/Autenticacion/api/Autenticacion/ValidarSemilla"
LET url_consulta = "https://ecf.dgii.gov.do/ecf/ConsultaResultado/api/consultas/estado"
LET url_anulacion = "https://ecf.dgii.gov.do/eCF/anulacionrangos/api/operaciones/anularRango"
IF ptipoRecepcion = 'anular' THEN
LET url_recepcion = url_anulacion
END IF
END IF
IF xambiente = "certificacion" THEN
IF ptipoRecepcion = "normal" THEN
LET url_recepcion ="https://ecf.dgii.gov.do/CerteCF/Recepcion/api/FacturasElectronicas"
ELSE
IF ptipoRecepcion = 'consumo' THEN
LET url_recepcion ="https://ecf.dgii.gov.do/CerteCF/Recepcion/api/FacturasElectronicas"
END IF
END IF
IF ptipoRecepcion = 'normal32' THEN
LET url_recepcion ="https://fc.dgii.gov.do/CerteCF/RecepcionFC/api/Recepcion/ecf"
END IF
LET url_semilla ="https://ecf.dgii.gov.do/CerteCF/autenticacion/api/autenticacion/semilla"
LET url_validasemilla ="https://ecf.dgii.gov.do/CerteCF/Autenticacion/api/Autenticacion/ValidarSemilla"
LET url_consulta = "https://ecf.dgii.gov.do/CerteCF/ConsultaResultado/api/consultas/estado"
END IF
IF xambiente = "test" THEN
IF ptipoRecepcion = "normal" THEN
LET url_recepcion ="https://ecf.dgii.gov.do/TesteCF/Recepcion/api/FacturasElectronicas"
ELSE
IF ptipoRecepcion = 'consumo' THEN
LET url_recepcion ="https://fc.dgii.gov.do/TesteCF/RecepcionFC/api/Recepcion/ecf"
END IF
END IF
IF ptipoRecepcion = 'normal32' THEN
LET url_recepcion ="https://fc.dgii.gov.do/TesteCF/RecepcionFC/api/Recepcion/ecf"
END IF
IF ptipoRecepcion = 'anular' THEN
LET url_Recepcion = "https://ecf.dgii.gov.do/TesteCF/anulacionrangos/api/operaciones/anularRango"
END IF
LET url_semilla ="https://ecf.dgii.gov.do/TesteCF/autenticacion/api/autenticacion/semilla"
LET url_validasemilla ="https://ecf.dgii.gov.do/TesteCF/Autenticacion/api/Autenticacion/ValidarSemilla"
LET url_consulta = "https://ecf.dgii.gov.do/TesteCF/ConsultaResultado/api/consultas/estado"
LET url_anulacion = "https://ecf.dgii.gov.do/TesteCF/anulacionrangos/api/operaciones/anularRango"
END IF
LET url_consulta_timbre ="https://ecf.dgii.gov.do/TesteCF/consultatimbre"
# DISPLAY url_recepcion TO act_url
END FUNCTION
FUNCTION obtenerStatus(ctoken)
DEFINE respuesta,btoken,codigo,archivo,contenido,consultaResp,ctoken STRING,
http_req com.HttpRequest,
http_resp com.HTTPResponse,
xresp RECORD
codigo,estado,mensajes,encf,secuenciaUtilizada STRING
END RECORD
LET http_req = com.HttpRequest.Create("https://statusecf.dgii.gov.do/api/estatusservicios/obtenerestatus")
CALL http_req.setMethod("GET")
CALL http_req.setCharset("UTF-8")
CALL http_req.setConnectionTimeOut(10)
CALL http_req.setHeader("accept","application/json")
CALL http_req.setHeader("Authorization",ctoken)
CALL http_req.doRequest()
LET http_resp= http_req.getResponse()
LET respuesta = http_resp.getTextResponse()
LET codigo = http_resp.getStatusCode()
END FUNCTION
FUNCTION parse_dgii_response(raw STRING)
DEFINE s STRING,
resp tRespDGII
DEFINE w RECORD
data1 tRespDGII
END RECORD
-- ltimo intento: levantar slo los campos conocidos si vienen sueltos
DEFINE m RECORD
codigo INTEGER,
estado STRING,
encf STRING,
hash STRING,
qrcodeurl STRING,
fechaFirmaDigital STRING
END RECORD
LET s = raw.trim()
IF s IS NULL OR s = "" THEN
RETURN resp.*
END IF
-- Si la raz es un arreglo, envulvelo para mapearlo a RESP.mensajes
IF s.subString(1,1) = "[" THEN
LET s = '{"mensajes":' || s || '}'
END IF
TRY
CALL util.JSON.parse(s, resp)
RETURN resp.*
CATCH
-- Algunos endpoints devuelven dentro de "data1" u otro contenedor.
TRY
CALL util.JSON.parse(s, w)
LET resp = w.data1
RETURN resp.*
CATCH
TRY
CALL util.JSON.parse(s, m)
LET resp.codigo = m.codigo
LET resp.estado = m.estado
LET resp.encf = m.encf
LET resp.hash = m.hash
LET resp.qrcodeurl = m.qrcodeurl
LET resp.fechaFirmaDigital = m.fechaFirmaDigital
RETURN resp.*
CATCH
-- Si nada funcion, deja 'resp' vaco: que el llamador trate el raw
RETURN resp.*
END TRY
END TRY
END TRY
END FUNCTION