En esta entrada del blog, veremos cómo hacer peticiones desde Sage a un fichero JavaScript de manera asíncrona, además de algún consejo para hacernos la vida más fácil.
Hacer peticiones desde Sage a un fichero JavaScript de manera asíncrona
Crear estructura de archivos
Empezamos con lo básico, creamos una nueva carpeta y creamos la siguiente estructura de archivos:
Es en esta imagen cuando ya podemos apreciar el primer truco para nuestros desarrollos, y es que, para hacer algún cambio en nuestros scripts, si solo tenemos el index, tendríamos que ir reiniciando Syracuse para que estos cambios fuesen efectivos. Sin embargo, si en nuestro index, enlazamos un js aparte (en nuestro caso, eaxexample-service._js) y lo llamamos desde la función requireUncache, nuestro js no se guardará en caché y podremos ir actualizándolo.
function requireUncached(module) { delete require.cache[require.resolve(module)] return require(module) }
Realizar función asíncrona
Otro punto a mencionar, es que la extensión utilizada (_js) es para indicar a Sage que se va a realizar una función asíncrona, utilizando el paquete streamline.js con el callback _. Más información en la correspondiente guía de Sage.
Una vez hecha la estructura de estructura de archivos, vamos a escribir nuestro package.json, en el que declararemos nuestro autor, nombre del script, versión y descripción del mismo y el/los módulo(s) a cargar:
Configurar index
Por último, antes de empezar a desarrollar la llamada a la api, configuraremos el index para que llame a nuestro servicio. Para ello, dentro del js creamos la funcion exports.query del siguiente modo:
exports.query = function(_, params) { let res; const EAXExampleService = requireUncached("./services/eaxexample-service"); const eaxexample = new EAXExampleService(); try { res = eaxexample.query(_, params); // Result of http response } catch (error) { //If any error happens, it's written inside a log fs.appendFileSync("C:/logpath/eax_log.txt", "n-----------------------------------------------n[" + new Date().toLocaleString() + "] SUBMIT => Error Data: " + error); } return res }
Llamar a la API
Como vemos, dentro de la función, primero creamos un servicio llamando al script con nuestra función requireUncached para asegurarnos que se carga con los últimos cambios realizados. Acto seguido, se ejecuta la query pasando por parámetros la _ y los parámetros que lleguen por Sage. Por último, si no ha habido ningún error (en ese caso se escribiría un log en la ruta especificada), devuelve la respuesta de la api.
Dentro de nuestro servicio (eaxexample-service._js) nos exportamos la clase EAXExampleService.
En el constructor de nuestra clase nos encontraremos con la url y el path de la api a la que haremos la petición:
Acto seguido, nos creamos una pequeña función para pasar los argumentos recibidos desde Sage a un string para poder pasárselo por parámetro a la URL:
Y por último, nos creamos nuestra función query, que es la que se encargará de hacer la llamada:
query = (_, args) => { let response = ''; let params, res; try { params = this.objectToQueryParams(args); // Declaring request options var options = { 'method': 'GET', 'url': this.HOSTNAME+this.BASE_PATH+params, 'headers': this.BASE_HEADERS, }; // Setting up the request response = httpClient.httpRequest(_, options).end().response(_); res = response.readAll(_); res = JSON.parse(res); return res; } catch (error) { //If any error happens, it's written inside a log fs.appendFileSync("C:/logPath/eax_log.txt", "QUERY REQUEST ERROR - [" + new Date().toLocaleString() + "] " + error + "n"); res = { 'error': 'Error fetching query' }; } return res; } }
Recibir respuesta
Como vemos, usamos la librería de httpClient para hacer un request junto a las opciones previamente configuradas pasándole nuestro callback “_”, acto seguido, leemos su respuesta y parseamos nuestra respuesta a un objeto.
Una vez más, si sucede un error en alguna parte de nuestra query, lo capturamos y lo escribimos en nuestro log.
Por último, en caso de querer solo algunos datos, podemos crear una función que filtre nuestra respuesta antes de devolverlo.
Si todo ha ido bien, nuestra respuesta será enviada de vuelta a Sage.
Preparar/Modificar script
Una vez escrito el json y el index, abrimos la ruta de los módulos de Node de nuestro Syracuse (normalmente localizado en C:SageSafeX3SyracuseComponentsyracusebinnode_modules) y copiamos la carpeta recién creada:
Después, reiniciamos el servicio de Syracuse y, una vez iniciado, ya tendremos nuestro script preparado y, si queremos modificarlo, no tendremos que reiniciar de nuevo el servicio.
Llamar al fichero JavaScript
Por último, dentro del script de Sage, para llamar al fichero JavaScript, declaramos los argumentos que le pasaremos a la función EXEC_JS
### Module, function and element to be returned Local Char MODULE(100) : MODULE = "zeaxexample/lib/index" # Script location Local Char FONCTION(30) : FONCTION = "query" #'getUserProfile' Local Char RETURNS(50) : RETURNS = "" ### The function is asynchronous Local Char MODE(4) : MODE = "wait" ### The callback argument is located in the first place for this function Local Integer CALLB : CALLB = -1 ### No Base 64 in or out coding, the arguments can remain empty Local Char B64_IN(20): B64_IN = "0" Local Char B64_OUT(20): B64_OUT = "0" ### No additional arguments Local Clbfile ARGUMENTS : ARGUMENTS = DATOS # Let's call the function STATUSCODE = func ASYRWEBSER.EXEC_JS(MODULE, FONCTION, MODE, ARGUMENTS, B64_IN, CALLB, RETURNS, B64_OUT, RESHEAD, RESBODY)
Dicha función coge como parámetros el archivo que necesita (el ._js), el nombre de la función, si necesita filtrar la respuesta, si la función es asíncrona, si está codificada la respuesta y los parámetros del mismo.
Cuando esa función haya finalizado, la respuesta de la api estará guardada en la variable RESBODY.
¿Quieres implantar Sage X3 en tu empresa?
¡Nosotros te ayudamos!
En Emiral sabemos cuánto vale tu empresa, ya sea pequeña, mediana o grande. Por ello, queremos ofrecerte las mejores soluciones de gestión ERP para que tu negocio siga creciendo.