- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
12-27-2018 08:02 AM
I have kind of a tricky situation which I am trying to figure out how to approach.
We have an Order Guide with three Catalog Items to choose from. The Order Guide itself does not have a workflow attached to it. 2 of the 3 Catalog Items in my Order Guide do. They are pretty straight forward, creating a single RITM, so those Workflows run off of sc_req_item and are available to be selected from the Workflow field on the Catalog Item.
However, my third one is a bit trickier. It needs to create multiple RITMs, so the Workflow needs to run against sc_request so we can create multiple RITMs within that workflow. However, when we create a workflow based on sc_request, it is not available to be selected from the Workflow field on the Catalog Item.
I see from Workflow -> Properties -> Conditions, I could try to set a condition of which the workflow should run. We have done this before, based on the Order Guide value. However, that Order Guide was pretty straight forward and didn't have three different Catalog Items, each with their own workflow, listed underneath it. So the Order Guide field,in and of itself, does not contain enough information regarding when the workflow should be called. It is dependent upon the Catalog Item selected in the Order Guide (have a variable for that selection).
So, how can I do this? How can I set up the Workflow for this third option to run off of sc_request and get it to be called when that third option is selected?
Thanks
Solved! Go to Solution.
- Labels:
-
Scripting and Coding

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
12-27-2018 12:47 PM
This is what I have used to trigger new items from an initial item and added to the same request.
var reqHelper = new GlideappCalculationHelper();
reqHelper.addItemToExistingRequest(current.request,<sysID of the item>, 1); // 1 is the qty
reqHelper.rebalanceRequest(current.request);
My use case:
We had an item that collected multiple share file locations, but needed individual approvals for each location. My setup was an initial item that runs a script with this code in it to generate the individual items under the same REQ. The original item closes automatically after the fact, so one 'item' spawns x number of individual items (dependent upon how many share file locations they request), all on the same REQ.
https://developer.servicenow.com/app.do#!/api_doc?v=jakarta&id=GlideappCalcHelperAPI
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-03-2019 08:27 AM
OK, that much did work. I will start playing around with it to see if I can build it to do what I need.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-03-2019 08:57 AM
OK, I have a good working shell now, that is dynamic, and will insert new items for each of the items I select in my List Collector (so if I choose 3 items, it will add three RITMs). Here is what that code looks like:
//capture key fields from original ritm
var orig_req = current.request;
var orig_ritm = current.number;
//capture key fields off of catalog item
var applications = current.variables.facets_applications_role_needs_access_to; //list collector
//split applications list collector
var ind_app = applications.toString().split(',');
var catItemId = orig_cat_item; //Catalog Item sys_id of Facets Role Maint
var requestId = orig_req; //sys_id of original request
//loop through each application and create a new ritm
for(var i = 0; i < ind_app.length; i++){
var app = ind_app[i];
var helper = new GlideappCalculationHelper();
helper.addItemToExistingRequest(requestId, catItemId, "1");
helper.rebalanceRequest(requestId);
}
My next challenge is to populate these new RITMs with the proper values from the original RITMs and Catalog Item variables. Any idea on how to do that? I think I might be able to use a GlideRecord to populate the RITM values, if I can get the sys_id of the newly created RITM, but am not exactly sure how to do that using this GlideappCalculationHelpder code.
Thanks

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-03-2019 09:14 AM
Here is some sample code I used...
// grab common variables from original
var justify = current.variables.justification;
var shares = current.variables.server_ro.toString();
var shareArray = shares.split(',');
// Loop through variable array
if (shareArray){
for (var i=0; i < shareArray.length; i++) {
// look up information for each reference variable in array
var gr = new GlideRecord('u_cmdb_ci_server_file');
gr.get(shareArray[i]);
var file = gr.name;
var sysID = gr.sys_id;
// update/add values to variables on item
var grReqItem = new GlideRecord('sc_req_item');
grReqItem.addQuery('request', current.request);
grReqItem.addQuery('parent', '');
grReqItem.setLimit(1);
grReqItem.query();
while(grReqItem.next()) {
grReqItem.variables.server_file = sysID;
grReqItem.variables.justification = justify;
grReqItem.variables.access_type = 'Read Only';
grReqItem.parent = current.sys_id;
grReqItem.update();
}
}
}
Note that the items that I created already had the variables associated with it (just blank), so I just loop through the RITMs associated with my original REQ and add the variable values needed.
I also populate the 'parent' field on the RITM as a sort of flag that it already has variables added. This is so each result of the query should be decremented by one.
This is all done in the original item workflow in a run script activity, same as the GlideappCalculationHelper one.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-03-2019 10:13 AM
OK. I was wondering if there was anyway to do it in the same loop that they get created in. But I wasn't sure if it is possible to get the sys_id of the new RITM as it is being created by the GlideappCalculationHelper.
Where it gets a little tricky is that I need to get the individual values from my ind_app array, and apply them separately to each RITM.
Or is there a way to easily build an array of the new RITMs that get created, and then just match up the indexes from the two arrays?
This gets even trickier in the more complex one that I have to do, that is an array of arrays. So if the first list collector returns 4 items, and the second returns 3, then I will be creating 12 new RITMs, and need to make sure I apply the appropriate values from each array to each one. But I am not worrying about that yet. I think if I can find a way to do this more basic one, I can just built upon it.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-04-2019 08:01 AM
I finally got it to do all that I needed to! I was able to easily copy over all my Catalog Item variables by deleting all the variables in the blank shell that gets created for the new RITM like this (where "nid" is the sys_id of my new RITM).
var scvar2 = new GlideRecord('sc_item_option_mtom');
scvar2.addQuery('request_item.sys_id', nid);
scvar2.query();
scvar2.deleteMultiple();
Then, I can copy over the existing Catalog Item variable values from my original RITM like this:
//copy variable section from original ritm to new ritms
var scvar = new GlideRecord('sc_item_option_mtom');
scvar.addQuery('request_item.sys_id', orig_sys_id);
scvar.query();
while (scvar.next()) {
var vown = new GlideRecord('sc_item_option_mtom');
vown.newRecord();
vown.sc_item_option = scvar.sc_item_option;
vown.request_item = nid;
vown.insert();
}
Thanks for all the help!