Generate multiple RITMs based on list collector variable

danreesejr
Kilo Contributor

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

1 ACCEPTED SOLUTION

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:

find_real_file.png

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).

find_real_file.png

find_real_file.png

find_real_file.png

find_real_file.png

 

 

6.  The Request workflow needed to be updated.  You may need to adjust this to your specific situation:

find_real_file.png

 

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.

 

 

View solution in original post

8 REPLIES 8

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

 

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?

 

find_real_file.png


RK
If my response is helpful, please select Helpful. If my response answers your question, please select Accept as Solution.

debalina1
Kilo Contributor

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?

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:

find_real_file.png

 

(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);