Pulling Variables to Email Notification

Sofija
Giga Expert

Hi All,

I have an email script that pulls variables in an organized manner to an approval email notification. However, it only pulls them if in catalogue item I used a variables set rather than individual variables. For example, if my service catalog item has a variables set of 10 items, email script will pull all of them. However, if I have a catalogue item with 10 variables, it will pull just a few of them. Could anyone be able to help me with this so all variables are pulled no matter if there is a variable set or not?

Here is the email script:

var reqI = new GlideRecord("sc_req_item");
reqI.addQuery("sys_id", current.sysapproval);
reqI.query();
if(reqI.next()) {
new Var2Desc().printVariables(reqI,function(){}, true);

}

Here is script include:

var Var2Desc = Class.create();
Var2Desc.prototype = {
      initialize: function() {
  /* map: element vs internal field type */
this.UI_PAGE = 15,
this.MASKED = 25,
this.DATE = 9,
this.NUMERIC_SCALE = 4,
this.CHECKBOX = 7,
this.MULTIPLE_CHOICE = 3,
this.DATE_TIME = 10,
this.CONTAINER_END = 20,
this.LABEL = 11,
this.WIDE_SINGLE_LINE_TEXT = 16,
this.YES_NO = 1,
this.HTML = 23,
this.SELECT_BOX = 5,
this.MACRO = 14,
this.REFERENCE = 8,
this.LOOKUP_MULTIPLE_CHOICE = 22,
this.LIST_COLLECTOR = 21,
this.MULTI_LINE_TEXT = 2,
this.SINGLE_LINE_TEXT = 6,
this.MACRO_WITH_LABEL = 17,
this.LOOKUP_SELECT_BOX = 18,
this.SPLIT = 24,
/* this is a list of elements that will be ignored */
this.IGNORE = [this.UI_PAGE, this.CONTAINER_END, this.HTML, this.MACRO,
this.MACRO_WITH_LABEL, this.SPLIT, this.LABEL];

      },

/*
* ritm           GlideRecord object
* func           javascript function to customize conditions
*                     to skip centain variables values
* noBlanks   true|false to avoid empty variable's value
*/
printVariables: function(ritm, func, noBlanks) {
gs.print("here in script");
var d = '';
var noBlanks = noBlanks || false;
var vars = this._getVariablesSorted(ritm);

/* loop the variables */
for(var i =0; i < vars.length; i++) {
var o = vars[i];
var type = o.type;
var label = o.label;
/* ignore list of types */
if(this._isIgnored(o.type))
continue;

/* if custom function is provided, execute custom conditions */
if(func && typeof func == 'function') {
if(func.call(this,o)) continue;
}

  var v = o.value;
if(gs.nil(v)) {
if(noBlanks)
continue;
} else {
/* for reference fields get the Display Value */
if(type == this.REFERENCE || type == this.LIST_COLLECTOR) {
v = v.getDisplayValue();
} else if(type == this.MULTI_LINE_TEXT) {
/* for multi line place an extra line in front
and ident every line with one space */
v = "\n " + o.value.toString().replace(/\n/g,"\n ");
}   else if(type == this.MULTIPLE_CHOICE || type == this.SELECT_BOX) {
/* get choices */
var choices = question.getChoiceList();
/* get label of value selected */
v = choices.getLabelOf(v);
}
}

template.print("<br>"+label+"</br>");
template.print("<br>"+v+"</br>");
}

},

_getVariablesSorted: function(ritm) {
var vars = [];
for(var variableName in ritm.variables) {
/* GlideObject */
var go = ritm.variables[variableName].getGlideObject();
/* Question */
var question = go.getQuestion();
/* Label */
var label = go.getQuestion().getLabel();
/* Type (numeric value) */
var type = new Number(go.getType());
/* Order (numeric value) */
var order = new Number(go.getQuestion().getOrder());
/* creates an Object */
var o = {
'name': variableName,
'label': label,
'value': ritm.variables[variableName],
'order': order,
'type': type
};
vars.push(o);
}
/* return the variables in order as per the form */
return this._quicksort(vars);
},

/* quick sort algorithm */
_quicksort: function(arr) {
if (arr.length === 0) {
return [];
}
var left = [];
var right = [];
var pivot = arr[0];
for (var i = 1; i < arr.length; i++) {
/* compare order from object */
if (arr[i].order < pivot.order) {
left.push(arr[i]);
} else {
right.push(arr[i]);
}
}
return this._quicksort(left).concat(pivot, this._quicksort(right));
},

/* check if the given field type should be ignored */
_isIgnored: function(type) {
for(i=0; i < this.IGNORE.length; i++)
if( this.IGNORE[i] == type)
return true;
return false;
},


      type: 'Var2Desc'
}


Kind Regards,

Kamile

1 ACCEPTED SOLUTION

Sofija
Giga Expert

For those still looking for solution to this here email script that does the work beautifully:



// Get Requested Item


var reqitem = new GlideRecord('sc_req_item');


reqitem.addQuery("sys_id", current.sysapproval);


reqitem.query();


while(reqitem.next()) {


// Get Owned Variables for Requested Item and sort by Order


var ownvar = new GlideRecord('sc_item_option_mtom');


ownvar.addQuery('request_item.number', reqitem.number);


ownvar.addQuery('sc_item_option.value','!=','');


ownvar.orderBy('sc_item_option.order');


ownvar.query();


while(ownvar.next()) {


  // Add Question, Answer and Order into notification mail


  // Set variable v to variable name


  var field = ownvar.sc_item_option.item_option_new;


  var fieldValue = ownvar.sc_item_option.item_option_new.name;


 


  // Print variable name


  template.print( '<b>' + field.getDisplayValue() + '</b>' + '\n');


 


  // Print Display Value for each variable in Requested Item


  template.print( reqitem.variables[fieldValue].getDisplayValue() + "\n\n");


 


}


}


View solution in original post

51 REPLIES 51

emyrold
Giga Expert

Thanks Kamile for asking this question and everyone else who's contributed to the reply's.



I have this working now in my environment but was wondering if anyone had any suggestions on how I can check the variable "visible on summary" value?



@oslova is using getGlideObject() with getQuestion(), getLabel(), getOrder()   and after a lot of searching I could not seem to find where I can find what other methods are available to getGlideObject()...



This getGlideObject() is so cool and not having to go out to the variables table get info is great... I was hopping I could also do that as well for "visible on summary"



I rather write this inline in the include script and not try to do it using his "custom function" approach.



Basically, the requirement is:   if the Variable has "Visible on Summaries" set to false (so not showing up on the approval summarizer) then I do not want it included in the email notification either...



Thanks,



-e


Hi Emyrold,



I do not know how to access other functions or properties of getGlideObject(). But Oslava has included one functionality in his function calling script include. This functionality allows you to exclude the variables which you do not want to print into email notifications. However, this was hard coded part in script provided by Oscar. I modified it to be a dynamic one.




Original code available can be found below. It has a provision in the function call to include variable names which you do not want to print. You can go on and append the variables inside but that will force you to modify the code everytime you build new item or want to make some changes.


function populateDescription() {


  var v2d = new Var2Desc();


  current.description = v2d.getDescription(current, function(obj) {


  /* skip 'myothervariable' value */


  return current.variables.myvariable == 'Yes' &&


  obj.name == 'myothervariable';


  });


}


populateDescription();




Below is my code which I made dynamic.


var gr = new GlideRecord("sc_req_item");


gr.addQuery("request", current.sys_id);


gr.query();


while(gr.next())


{


  var stage = gr.stage.getDisplayValue();


  if (JSUtil.nil(stage))


  stage = gr.stage.getChoiceValue();


  template.print("<p id='Label'><b>Requested item Details:</b></p>\n");


  template.print('Number: ' + gr.number +'\n' + 'Name: '+ gr.cat_item.getDisplayValue() + '\n'+ "Stage: " + stage + "\n"+ '<div>  </div>');


  var excludeVars = (gs.getProperty('u_exclude_variables_in_email_summary'));


  var excudeVarsArray = excludeVars.split(',');


  //gs.log('>>>>>Deeepak<<<<<< :   in a loop ');


      var j = 0 ;


      var expression = '';


  var v2d = new u_Var2Notification();


  template.print('\n' + ' ' + v2d.getDescription(gr, function(obj) {


  if(excudeVarsArray.length == 1)


      {


  expression = obj.name == excudeVarsArray;


      }


  else(excudeVarsArray.length > 0)


      {


  expression = obj.name == excudeVarsArray[0];


      }


      for(var j=0 ; j<excudeVarsArray.length; j++)


      {


  expression = expression || obj.name == excudeVarsArray[j];


              //gs.log('Variable Name in excludeVarserty : ' + excudeVarsArray[j]);


              //gs.log("Deepak Expression :" + expression);


      }


  return expression;


  },true));


}



This is the email script which I am using to print variables to notifications. Now if you see line number 11, I have created a property with name "u_exclude"variables_in_email_summary". This propery stores all the variable names separated by , (comma)


You will have to modify this single property only by adding variable names inside it which you do not want to print out in notifcation.



I know this does not solves your actual query but atleast gives you the alternate solution which you can use. Only maintenace work would be to modify the property rather than touching the actual code.



Kindly mark it as helpful / like if it answers your query


Just a thought came to my mind, you can modify this property dynamically as well via schedule job.


Schedule job will run on the variable table will check for "Aviaalbe on summary" box. If that is not present, your schedule job will modify the property value with including new variable.


Hi Deepak,



Yes, I saw his funciton(obj) param but wanted to make things more straight forward for people after me.   So I wanted to query in the main body of the script include.



I like what you did with the property thing and your idea about using a scheduled job to update it.   However, I ended up writing a private function (line : ~182) to query the ritm variables looking for the visible_summary == false. and then I call it up on (line: ~54) inside the loop for the variables.



var Var2Notification = Class.create();


Var2Notification.prototype = {



  initialize: function() {


  /* map: element vs internal field type */


  this.UI_PAGE = 15,


  this.MASKED = 25,


  this.DATE = 9,


  this.NUMERIC_SCALE = 4,


  this.CHECKBOX = 7,


  this.MULTIPLE_CHOICE = 3,


  this.DATE_TIME = 10,


  this.CONTAINER_END = 20,


  this.LABEL = 11,


  this.WIDE_SINGLE_LINE_TEXT = 16,


  this.YES_NO = 1,


  this.HTML = 23,


  this.SELECT_BOX = 5,


  this.MACRO = 14,


  this.REFERENCE = 8,


  this.LOOKUP_MULTIPLE_CHOICE = 22,


  this.LIST_COLLECTOR = 21,


  this.MULTI_LINE_TEXT = 2,


  this.SINGLE_LINE_TEXT = 6,


  this.MACRO_WITH_LABEL = 17,


  this.LOOKUP_SELECT_BOX = 18,


  this.SPLIT = 24,


  /* this is a list of elements that will be ignored */


  this.IGNORE = [this.UI_PAGE, this.CONTAINER_END, this.HTML, this.MACRO, this.MACRO_WITH_LABEL, this.SPLIT, this.LABEL];


  },



  /*


  * ritm           GlideRecord object


  * func           javascript function to customize conditions


  *                   to skip centain variables values


  * noBlanks   true|false to avoid empty variable's value


  */


  getDescription: function(ritm, func, noBlanks, html) {


  var d = '';


  var noBlanks = noBlanks || false;


  var vars = this._getVariablesSorted(ritm);



  /* loop the variables */


  for(var i =0; i < vars.length; i++) {


  var o = vars[i];


  var type = o.type;


  var label = o.label;


  /* ignore list of types */


  if(this._isIgnored(o.type))


  continue;




  /* ignore summaryFalse */


  if(this._isSummaryFalse(ritm, o.name))


  continue;




  /*


  * If custom function is provided, execute custom conditions.


  * An example will be provided at the bottom of this Script


  * Include, however, might be easier to make changes to this


  * Script Include for any condition changes, easier for others


  * to understand later.


  *


  */



  if(func && typeof func == 'function') {


  if(func.call(this,o)) continue;


  }






  var v = o.value;


  if(gs.nil(v)) {


  if(noBlanks)


  continue;





  } else {


  /* for reference fields get the Display Value */


  if(type == this.REFERENCE || type == this.LIST_COLLECTOR) {


  v = v.getDisplayValue();


  } else if(type == this.MULTI_LINE_TEXT) {


  /* for multi line place an extra line in front


  and ident every line with one space */


  v = "\n " + o.value.toString().replace(/\n/g,"\n ");


  }   else if(type == this.MULTIPLE_CHOICE || type == this.SELECT_BOX) {


  /* get choices */


  //var choices = question.getChoiceList();


  /* get label of value selected */


  v = v.getDisplayValue();


  }


  }


  /* insert a new line for every variable/value pair */



  /*   I need to figure out how to write a html line styled output so lable can


  *   be 2 or 30 characters and then v (value) will start to write at character ~40



  "<table style="width:100%">


  <tr><td style="width:100px; font-weight:">" + l + "</td><td>" + v + "</td>"


  </tr>


  </table>


  */



  if(html == true) {


  if(d.length>0) {


  d+='\n';


  }


  /* set the label of the variable with it's corresponding value */


  d = d + '<div><div><b>' + label + '</b>' + ' ' + v + '</div></div>' +'\n';


  } else {


  if(d.length>0) {


  d+='\n';


  }


  /* set the label of the variable with it's corresponding value */


  d = d + label + ' ' + v;


  }


  }


  return d;


  },



  _getVariablesSorted: function(ritm) {


  var vars = [];




  for(var variableName in ritm.variables) {


  /* GlideObject */


  var go = ritm.variables[variableName].getGlideObject();


  /* Question */


  var question = go.getQuestion();


  /* Label */


  var label = go.getQuestion().getLabel();


  /* Type (numeric value) */


  var type = new Number(go.getType());


  /* Order (numeric value) */


  var order = new Number(go.getQuestion().getOrder());


  /* creates an Object */


  var o = {


  'name': variableName,


  'label': label,


  'value': ritm.variables[variableName],


  'order': order,


  'type': type


  };


  vars.push(o);


  }


  /* return the variables in order as per the form */


  return this._quicksort(vars);


  },



  /* quick sort algorithm */


  _quicksort: function(arr) {


  if (arr.length === 0) {


  return [];


  }


  var left = [];


  var right = [];


  var pivot = arr[0];


  for (var i = 1; i < arr.length; i++) {


  /* compare order from object */


  if (arr[i].order < pivot.order) {


  left.push(arr[i]);


  } else {


  right.push(arr[i]);


  }


  }


  return this._quicksort(left).concat(pivot, this._quicksort(right));


  },



  /* check if the given field type should be ignored */


  _isIgnored: function(type) {


  for(i=0; i < this.IGNORE.length; i++)


  if( this.IGNORE[i] == type)


  return true;


  return false;


  },




  /* check if the given variable has visible_summary set to false */


  _isSummaryFalse: function(ritm, name){


  var summaryFalse = [];


  var itemVars = new GlideRecord('sc_item_option_mtom');




  //Exclude variables where visible_summary = false


  itemVars.addQuery('request_item.sys_id', ritm.sys_id);


  itemVars.addQuery('sc_item_option.item_option_new.name', name);


  itemVars.addQuery('sc_item_option.item_option_new.visible_summary', false);


  itemVars.query();


  if(itemVars.next())


  return true;


  return false;


  },



  type: 'Var2Notification'


};


Sofija
Giga Expert

For those still looking for solution to this here email script that does the work beautifully:



// Get Requested Item


var reqitem = new GlideRecord('sc_req_item');


reqitem.addQuery("sys_id", current.sysapproval);


reqitem.query();


while(reqitem.next()) {


// Get Owned Variables for Requested Item and sort by Order


var ownvar = new GlideRecord('sc_item_option_mtom');


ownvar.addQuery('request_item.number', reqitem.number);


ownvar.addQuery('sc_item_option.value','!=','');


ownvar.orderBy('sc_item_option.order');


ownvar.query();


while(ownvar.next()) {


  // Add Question, Answer and Order into notification mail


  // Set variable v to variable name


  var field = ownvar.sc_item_option.item_option_new;


  var fieldValue = ownvar.sc_item_option.item_option_new.name;


 


  // Print variable name


  template.print( '<b>' + field.getDisplayValue() + '</b>' + '\n');


 


  // Print Display Value for each variable in Requested Item


  template.print( reqitem.variables[fieldValue].getDisplayValue() + "\n\n");


 


}


}