- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-21-2018 12:53 PM
Hello,
Requirement is a new catalog item for a training request. Requestor should have the ability to select multiple "requested for" users who will be participants in the requested training. Each of the participants may have different approval managers. Submitting the request should generate a RITM for each user in the participants list with their name in the requested for of the RITM and all the variables cloned to each request.
Is this possible?
I have attempted the solution in the following thread:
To trigger multiple request items on a single request based on the list collector variable
My adjusted code in a runscript looks like this:
var listStr = current.variables.list_collector.toString(); // Assuming you have a variable called 'list_collector' change as appropriate
var list = listStr.split(',');
for (var i = 0; i < list.length; i++) {
var ritm = new GlideRecord('sc_req_item');
ritm.initialize(); // ritm.newRecord() seems to have the same result
ritm.request = current.request;
// populate other fields here
ritm.requested_for = list[i];
ritm.cat_item = current.cat_item;
ritm.insert();
}
The code successfully creates a new RITM for the corresponding number of items in the list collector. It correctly populates the values for the parent request and catalog item, but not the requested_for (it seems to default to the requested by value).
Also,it is not attaching or starting the item workflow to the newly created items:
Is this even possible to accomplish?
Thanks,
Dan
Solved! Go to Solution.
- Labels:
-
Best Practices
-
Scripting and Coding
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-24-2018 06:17 AM
Ok, so here (I think) is everything I had to do to get this to work.
1. On the Request table, setup a List Collector referencing the User table (I called it: Also Requested For).
2. on the Request table, setup a checkbox field (I called it: Copy Completed).
3. on the Request table, create a before Business Rule with the following parameters:
Use the following script. Take note of some of my notes in the script, as they directly address some of the issues you are seeing.
(function executeRule(current, previous /*null when async*/) {
var copyList = current.u_also_requested_for;
var copyArray = copyList.split(",").sort();
var arrayUtil = new ArrayUtil();
for (u = 0; u < copyArray.length; u++)
{
//this was using Incident to test validity of code
// var gr = new GlideRecord('incident');
//gr.initialize();
//gr.caller_id = copyArray[u]; //using the slice of the array [u]
//gr.insert();
//Create the extra Request for each person in 'Also Requested For'
var gr = new GlideRecord('sc_request');
gr.initialize();
gr.requested_for = copyArray[u]; //using the slice of the array [u]
gr.parent = current.sys_id; //all copied have a Parent
gr.opened_by = current.opened_by;
gr.insert();
gs.log("Also Request For Create Records BR run: " + current.number + ' ' + gr.number + ' requested for ' + gr.requested_for.getDisplayValue());
//Find the Requested Item children of the current Request
var items = new GlideRecord('sc_req_item');
items.addQuery('request', current.sys_id);
items.query();
//Create Requested Item child for each found
while (items.next()){
var citems = new GlideRecord('sc_req_item');
citems.initialize();
citems.request = gr.sys_id;
citems.requested_for = copyArray[u];
citems.cat_item = items.cat_item;
citems.insert();
var TheItem = items.cat_item.toString();
var tecvar = new GlideRecord('io_set_item');
tecvar.addQuery('sc_cat_item',TheItem);
tecvar.query();
//Put catalog item "'Request other equipment'" variable sets list to array OtherEquipmentVariableSetsList
var OtherEquipmentVariableSetsList = [];
while (tecvar.next())
{
OtherEquipmentVariableSetsList.push(tecvar.getValue('variable_set'));
}
//gs.log("lotg:" + "OtherEquipmentVariableSetsList =" + OtherEquipmentVariableSetsList);
//Search for stored variables for current request
var vgr = new GlideRecord('sc_item_option_mtom');
vgr.addQuery('request_item',items.sys_id);
vgr.query();
while (vgr.next()){
vgr.request_item = citems.sys_id;
vgr.insert();
}
//Update the RITM to cause Start Workflow BR to trigger
citems.description = '.';
citems.update();
/**
//meant to copy the variables, modified from BR to copy variables from RITM to Catalog Task
var questions = [];
var catalogItem = items.cat_item.toString();
var variableSets = [];
var getVariableSets = new GlideRecord('io_set_item');
getVariableSets.addQuery('sc_cat_item',catalogItem);
getVariableSets.query();
while(getVariableSets.next()) {
variableSets.push(getVariableSets.getValue('variable_set'));
}
var getCatalogVariables = new GlideRecord('item_option_new'); getCatalogVariables.addQuery('cat_item='+catalogItem+'^active=true^NQvariable_set.sys_idIN'+variableSets.toString()+'^active=true');
getCatalogVariables.query();
while(getCatalogVariables.next()) {
questions.push(getCatalogVariables.getValue('sys_id'));
}
var variablesCount = questions.length;
var currentTaskID = items.sys_id.toString();
//this part creates the variables
for(var i=0;i<variablesCount;i++)
{
var getTaskVariables = new GlideRecord('sc_item_variables_task');
getTaskVariables.addQuery('task',currentTaskID);
getTaskVariables.addQuery('variable',questions[i]);
getTaskVariables.setLimit(1);
getTaskVariables.query();
if(!getTaskVariables.hasNext())
{
getTaskVariables.initialize();
getTaskVariables.setValue('task',currentTaskID);
getTaskVariables.setValue('variable',questions[i]);
getTaskVariables.insert();
}
}**/
}
}
current.u_copy_completed = true;
})(current, previous);
4. In my case I needed this for an Order Guide, so I created one specific to when people needed to request the same thing for multiple people.
5. In that Order Guide, I needed a way to get the other users. I did so via a Variable Set (in theory so I could use this anywhere).
6. The Request workflow needed to be updated. You may need to adjust this to your specific situation:
The Run Script: Get Also Requested For, use this script:
var critm = new GlideRecord ('sc_req_item');
critm.addQuery('request', current.sys_id);
critm.orderByDesc('number');
critm.setLimit(1);
critm.query();
if (critm.next()){
if (critm.variables.copy_user_list != ''){
current.u_also_requested_for = critm.variables.copy_user_list;
//current.update();
}
}
I think that's everything... Getting this to work has taken a long time and a bunch of different updates as issues were found, but hopefully I didn't miss anything.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-24-2018 02:58 PM
Hi Shane,
Thank you so much for all this detail!
I REALLY appreciate you taking the time to share this with me.
My requirement is slightly different, but I think you code has what I need in it, I just need to tweak it a bit. I'll let you know and share once I have it.
FYI, I followed your steps and it does exactly what you expected it to do...an exact copy REQ with RITM fo everyone selected. Nice.
Stay tuned,
Dan
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-21-2019 11:59 AM
Hi Shane,
I do not see list collector field in Madrid, which we are using now. Would this also work, if it is just list field? Or does it have to be list collector?
RK
If my response is helpful, please select Helpful. If my response answers your question, please select Accept as Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
10-24-2018 06:25 AM
Hi,
Is there any solution to the above case? I too have a similar request where I need to create multiple RITM group by user's manager.
I have added the logic in the run script but don't see workflow getting attached to the child RITMs. Any solution?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
10-24-2018 06:51 AM
If I recall correctly, the RITM workflows won't start unless the REQ workflow updates them properly (I think there's a BR on the RITM table that triggers the WF to start?).
I recently updated the BR used in this setup (to do some custom color coding, which you can probably comment out), maybe that will help:
(function executeRule(current, previous /*null when async*/) {
var copyList = current.u_also_requested_for;
var copyArray = copyList.split(",").sort();
var arrayUtil = new ArrayUtil();
for (u = 0; u < copyArray.length; u++){
//start color stuff
var maxcolor = new GlideRecord('u_portal_colors');
maxcolor.orderByDesc('u_order');
maxcolor.setLimit(1);
maxcolor.query();
while (maxcolor.next()){
var maxorder = maxcolor.u_order;
var mycolor = new GlideRecord('u_portal_colors');
mycolor.addQuery('u_color', current.u_related_color);
mycolor.query();
while (mycolor.next()){
var setcolor = mycolor.u_order + u + 1; //use the combo of the array and order to get the next color in order
//Create the extra Request for each person in 'Also Requested For'
var gr = new GlideRecord('sc_request');
gr.initialize();
gr.requested_for = copyArray[u]; //using the slice of the array [u]
gr.parent = current.sys_id; //all copied have a Parent
gr.u_order_guide = current.u_order_guide; //Order Guide is the same
var newcolor = new GlideRecord('u_portal_colors');
newcolor.addQuery('u_order', setcolor);
newcolor.query();
if (newcolor.next()){
gr.u_related_color = newcolor.u_color;
}
else {
if (setcolor > maxorder){ //if you run out of colors, start over
var startorder = setcolor - maxorder;
var newcolorreset = new GlideRecord('u_portal_colors');
newcolorreset.addQuery('u_order', startorder);
newcolorreset.query();
if (newcolorreset.next()){
gr.u_related_color = newcolorreset.u_color;
}
}
// else {
// var newcolorreset2 = new GlideRecord('u_portal_colors');
// newcolorreset2.addQuery('u_order', setcolor);
// newcolorreset2.query();
// if (newcolorreset2.next()){
// gr.u_related_color = newcolorreset2.u_color;
// }
// }
}
gr.insert();
gs.log("Also Request For Create Records BR run: " + current.number + ' ' + gr.number + ' requested for ' + gr.requested_for.getDisplayValue());
gs.log(current.number + ' which is to be copied has a color of ' + current.u_related_color);
//Find the Requested Item children of the current Request
var items = new GlideRecord('sc_req_item');
items.addQuery('request', current.sys_id);
items.query();
while (items.next()){
//Create Requested Item child for each found
var citems = new GlideRecord('sc_req_item');
citems.initialize();
citems.request = gr.sys_id;
citems.requested_for = copyArray[u];
citems.u_related_color = gr.u_related_color;
citems.cat_item = items.cat_item;
citems.order_guide = current.u_order_guide;
citems.insert();
var TheItem = items.cat_item.toString();
var tecvar = new GlideRecord('io_set_item');
tecvar.addQuery('sc_cat_item',TheItem);
tecvar.query();
//Put catalog item "'Request other equipment'" variable sets list to array OtherEquipmentVariableSetsList
var OtherEquipmentVariableSetsList = [];
while (tecvar.next()){
OtherEquipmentVariableSetsList.push(tecvar.getValue('variable_set'));
}
//Create MTOM records to point to the existing variables instead of copying all of them
var vgr = new GlideRecord('sc_item_option_mtom');
vgr.initialize();
vgr.addQuery('request_item',items.sys_id);
vgr.query();
while (vgr.next()){
//except for anytime Requested For is the question, make a copy instead with the right Requested For
if (vgr.sc_item_option.item_option_new.getDisplayValue() == 'Requested For'){
gs.log("Requested for should be: " + gr.requested_for.getDisplayValue());
//Create the Requested For variable record from the Options table
var cgr = new GlideRecord('sc_item_option');
cgr.initialize();
cgr.it_option_new = vgr.sc_item_option.item_option_new;
cgr.order = vgr.sc_item_option.order;
cgr.sys_created_by = vgr.sc_item_option.sys_created_by;
cgr.sys_created_on = vgr.sc_item_option.sys_created_on;
//and set it to the proper Requested For
cgr.value = gr.requested_for;
cgr.insert();
//Create the MTOM to point back to the new copied variable
vgr.request_item = citems.sys_id;
vgr.sc_item_option = cgr.sys_id;
}
//Question is not 'Requested For'
else
{
//Create MTOM records to reference the variables of the original - since they are the same
vgr.request_item = citems.sys_id;
}
vgr.insert();
}
//Update the new RITMs to cause Start Workflow BR to trigger
citems.description = '.';
citems.update();
}
}//end Create the extra Request
}
}//end color stuff
})(current, previous);