
arielgritti
Mega Sage
Options
- Post History
- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
on 02-28-2018 06:23 AM
Objetivo/Necesidad
- Se nos planteó la necesidad de implementar un proceso por el cual un usuario gestor del inventario pudiera actualizar, a partir de un Excel (que convierte en un fichero .CSV) la tabla de asset (alm_asset) de forma autónoma y lo más dinámica posible.
Requisitos
- Que el usuario final, a través del Service Portal, pueda elegir que campos de la tabla alm_asset quiere actualizar
- Adjuntar un fichero .CSV que contiene la información en columnas que se corresponden con los campos de alm_asset
Restricciones
- Lo único que indicamos como obligatorio por parte del usuario en la generación del fichero .CSV es que la primer columna sea el asset_tag (el campo por el cual podemos saber que asset vamos a actualizar) y que las columnas estén en el mismo orden que los campos que elige en el item de actualización masiva
- El fichero .CSV no lleva encabezado
Implementación
- Creamos un item de catálogo donde le pedimos que campos, mediante variables del tipo Reference a la tabla sys_dictionary, quiere actualizar. Con esto nos aseguramos varias cosas:
- Que el nombre del campo será el correcto (evitamos tener que poner un encabezado en el .CSV)
- Que solo los campos que nosotros "publicamos" se puedan actualizar
- Obtener información de metadatos de los campos para saber si son a su vez Reference a otras tablas para su tratamiento posterior
- Un workflow con una tarea del tipo "run script" que se encarga de procesar el excel y actualizar la tabla alm_asset
Detalle de la implementación
- Las variables reference a los campos de la tabla alm_asset tienen esta carecterística:
- La tabla es alm_asset
- Los campos no contienen "sys"
- Y así se puede ir filtrando que campos queremos que aparezcan (el filtro es más grande en mi caso)
El ítem, para elegir los campos, queda así (puse 4 campos, pero podemos poner 2, 6, 10, los que querramos)
- La tarea del tipo "Run Script" del workflow, tiene el siguiente código, y las siguientes consideraciones (o retos 😉
-
- Como la selección del campo es dinámica, se presentaban dos retos: Saber el nombre del campo para luego actualizarlo, y los campos del tipo Reference (a otras tablas) debía identificarlos, saber de que tabla se trataba, con el dato del fichero .CSV ir a buscar el registro y obtener el SYS_ID para la actualización.
//Variables globales
var vSysId1 = '';
var vSysId2 = '';
var vSysId3 = '';
var vSysId4 = '';
var vValor1 = '';
var vValor2 = '';
var vValor3 = '';
var vValor4 = '';
var debug = true;
var attachment = '';
var attachmentData = '';
var splited = '';
var splited2 = '';
var vAssetTag = '';
//Recupero attach
var attGr = new GlideRecord('sys_attachment');
attGr.addQuery('table_name', 'sc_req_item');
attGr.addQuery('table_sys_id', current.sys_id);
attGr.query();
//Si tengo attach
if(attGr.next()) {
//Proceso attach
var gsu = (typeof GlideStringUtil != 'undefined') ? (GlideStringUtil) : (Packages.com.glide.util.StringUtil);
var gsa = (typeof GlideSysAttachment != 'undefined') ? (new GlideSysAttachment()) : (new Packages.com.glide.ui.SysAttachment());
var attachmentData = gsa.getBytes(attGr);
var attachment = String(Packages.java.lang.String(attachmentData));
//Splito
splited = attachment.split('\n');
//Itero cada fila del attach
for (var i=0; i<splited.length; i++) {
//Splito again
split2 = splited[i].split(';');
vAssetTag = split2[0].trim();
//Valores de campo directos
vValor1 = split2[1].trim();
vValor2 = split2[2].trim();
vValor3 = split2[3].trim();
vValor4 = split2[4].trim();
//Si los valores de campos son reference
//asset_field1
if (current.variables.asset_field1.internal_type == 'reference') {
//es reference, va el sys_id
vSysId1=devuelveSYSID(current.variables.asset_field1.reference,vValor1);
vValor1 = vSysId1;
}
//asset_field2
if (current.variables.asset_field2.internal_type == 'reference') {
//es reference, va el sys_id
vSysId2=devuelveSYSID(current.variables.asset_field2.reference,vValor2);
vValor2 = vSysId2;
}
//asset_field3
if (current.variables.asset_field3.internal_type == 'reference') {
//es reference, va el sys_id
vSysId3=devuelveSYSID(current.variables.asset_field3.reference,vValor3);
vValor3 = vSysId3;
}
//asset_field4
if (current.variables.asset_field4.internal_type == 'reference') {
//es reference, va el sys_id
vSysId4=devuelveSYSID(current.variables.asset_field4.reference,vValor4);
vValor4 = vSysId4;
}
//Recupero asset a actualizar
var grAssetUpd = new GlideRecord("alm_asset");
grAssetUpd.addQuery("asset_tag", vAssetTag);
grAssetUpd.query();
if (grAssetUpd.next()) {
grAssetUpd.setValue(current.variables.asset_field1.element,vValor1);
grAssetUpd.setValue(current.variables.asset_field2.element,vValor2);
grAssetUpd.setValue(current.variables.asset_field3.element,vValor3);
grAssetUpd.setValue(current.variables.asset_field4.element,vValor4);
//Actualizo
grAssetUpd.update();
}
else {gs.log('NOOOOOO encontre asset ' + vAssetTag);}
}
}
//Funcion que devuelve el sys_id segun el reference y el valor
function devuelveSYSID (vReference,vValor) {
var vQuery = '';
//Segun que tabla sea debo filtrar por diferentes campos
if (vReference == 'u_acreditaciones') {
vQuery = "u_acreditacion";
}
if (vReference == 'core_company') {
vQuery = "u_codigo";
}
if (vReference == 'cmn_department') {
vQuery = "name";
}
if (vReference == 'cmdb_model_category') {
vQuery = "name";
}
if (vReference == 'cmdb_model') {
vQuery = "name";
}
if (vReference == 'cmn_location') {
vQuery = "name";
}
if (vReference == 'u_secciones') {
vQuery = "u_name";
}
if (vReference == 'sys_user') {
vQuery = "user_name";
}
//Busco la tabla segun vReference
var gr = new GlideRecord(vReference);
gr.addQuery(vQuery,vValor);
gr.query();
//Encuentro
if (gr.next()) {
var retorno = gr.getUniqueValue();
return retorno;
}
}
Conclusiones
- Como todo, el proceso es mejorable y hay muchas cosas por hacer, pero es un método bastante sencillo y fiable para darle al usuario una funcionalidad de actualización masiva de asset (podría ser realmente cualquier otra tabla), que no tiene que entrar en la interface UI y que le facilita su operación porque están muy acostumbrados al uso del Excel/CSV
Espero que os sea de utilidad, y como digo siempre, no he inventado nada, solo he reaprovechado lo que la propia comunidad comparte, modificado un poco allí, retocado aquí e implementado en nuestras instancias para obtener un resultado. Por eso, gracias por compartir y os animo a hacerlo!
PD: Si el artículo te ha sido de utilidad, te agradeceré lo marques como tal y lo compartas.
- 633 Views