- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
3 weeks ago
Hi Community,
I’m trying to figure out the best way to create multiple Requested Items (RITMs) from a single Catalog Item submission.
Use case:
We have one catalog item with several checkboxes. (It Systems, Information Security, Finance)
When the form is submitted, I want a separate RITM created for each selected checkbox.
Each RITM should contain the same variable values, but be assigned to a different group depending on which checkbox was selected.
All RITMs should roll up under the same REQ, and ideally be displayed on their own tabs within the request.
What I’ve tried so far:
Order Guides → but we want this to happen without extra clicks or navigating to multiple screens.
Cart APIs → I’ve tested a few approaches but haven’t been able to get them working for this use case (maybe I’m not setting them up correctly).
Workflow → I have a workflow triggered when the catalog item is submitted that checks each checkbox, but I don’t know how to branch it into separate RITMs.
Custom Action → I tried adding a custom action, but it doesn’t seem to show up as an option when I go to use it.
Has anyone successfully implemented this pattern before? My main focus is to drive this through Flow Designer. We have not implemented multiple RITMs in our environment before.
Any best practices, code samples, or pointers would be hugely appreciated.
Thanks
Philip H
Solved! Go to Solution.
- Labels:
-
Service Catalog
-
Service Portal
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
5 hours ago
I wanted to share the solution I was able to build in Flow Designer without using any custom actions or scripting.
I started with a Service Catalog trigger, then used Get Catalog Variables to retrieve the specific variables I needed.
To associate multiple RITMs with the REQ, I added a Look Up Record on the sc_request table to retrieve the Sys ID of the parent request.
From there, I applied If / Else If conditions based on the catalog variable checkboxes:
If IT Systems is true → update the primary Request Item record.
If Finance is true → create a Request Item record.
If Information Security is true → create a Request Item record.
For the Else If conditions:
If Information Security is true and IT Systems is false → update the primary Request Item.
If Finance is true → create a Request Item record.
For the final Else condition:
If IT Systems is false and Finance is true → update the primary Request Item.
If Information Security is true → create a new Request Item record.
Finally, I used an Update Request Record step.
The tricky part was ensuring that updates to the REQ didn’t wipe out values when non-primary RITMs were being updated (since the primary has the flow context attached to it). My workaround was to use the Look Up Trigger Service Catalog Request Item record to pull values from there.
Attempting to populate the REQ directly from the catalog variables would cause errors, but pulling them from the trigger record worked reliably.
I hope this helps!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
3 weeks ago
Ankur,
Thank You for your response.
Yes, I have been working on following what you have put together but have been having troubles getting it implemented correctly. I'm not familiar with JSON and how to utilize it effectively in the environment. Your article is not entirely clear.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
3 weeks ago
I believe I have explained it very well.
what did you start and share the script and please tell where are you stuck?
Ankur
✨ Certified Technical Architect || ✨ 9x ServiceNow MVP || ✨ ServiceNow Community Leader
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
3 weeks ago
Ankur,
Below is what I'm currently doing but running into a block to add the Action to my flow.
In BackGround Scripts I ran this to test my theory.
var params = {
it_systems: true,
infosec: false,
finance: true,
requested_for: 'b6912e76dbf37600cd073220ad9619b8', // sys_id of a user
requested_by: gs.getUserID(), // current user sys_id
u_vendor_name: 'Sample Vendor',
u_evaluation_type: 'Standard',
due_date: '2025-10-01',
short_description: 'Testing',
};
var reqNumber = new MultiRitmCreator().createRitms(params);
gs.info("Created Request Number: " + reqNumber);Action in flow designer
Here is my Script Include
var MultiRitmCreator = Class.create();
MultiRitmCreator.prototype = {
initialize: function() {
},
createRitms: function(params) {
try {
var catalogItem = 'c3278427fb2f22104a3dfbd14eefdcc8'; // your catalog item sys_id
// Build options based on checkbox inputs
var options = [];
if (params.it_systems)
options.push({group: '52d931d9dbb8cb00cd073220ad961930', value: 'IT Systems'});
if (params.infosec)
options.push({group: '5abb260bdb2cc700cd073220ad961997', value: 'Information Security'});
if (params.finance)
options.push({group: 'b528f51c8754c65010e0ca65dabb3511', value: 'Finance'});
if (!options.length)
throw "No areas selected (it_systems, infosec, finance).";
var cartId = GlideGuid.generate(null);
var cart = new Cart(cartId);
for (var i = 0; i < options.length; i++) {
var item = cart.addItem(catalogItem, 1);
// Set catalog variables
cart.setVariable(item, 'requested_for', params.requested_for);
cart.setVariable(item, 'requested_by', params.requested_by);
cart.setVariable(item, 'u_vendor_name', params.u_vendor_name);
cart.setVariable(item, 'u_evaluation_type', params.u_evaluation_type);
cart.setVariable(item, 'due_date', params.due_date);
cart.setVariable(item, 'selected_area', options[i].value);
}
var rc = cart.placeOrder();
return rc.number;
} catch (e) {
gs.error("MultiRitmCreator error: " + e);
return null;
}
},
type: 'MultiRitmCreator'
};
My Flow designer Action
Action Script
(function execute(inputs, outputs) {
try {
// Build params for the Script Include from action inputs
var params = {
it_systems: !!inputs.it_systems,
infosec: !!inputs.infosec,
finance: !!inputs.finance,
requested_for: inputs.requested_for, // pass sys_id (Reference) or string
};
// Call the Script Include
var creator = new MultiRitmCreator();
var reqNumber = creator.createRitms(params);
outputs.requestNumber = reqNumber;
} catch (ex) {
gs.error("Action Create Multiple RITMs error: " + ex);
outputs.requestNumber = '';
}
})(inputs, outputs);
Output
When I go to my flow it does not show up. I am in global scope and this is all built in global.
For your Solution I am unclear where to add the script you included. Is that a catalog script? Script Include?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
3 weeks ago - last edited 3 weeks ago
Hello @phugill ,
You can handle this in Flow Designer without using Order Guides.
Create a Flow with trigger “After Requested Item Created” for your catalog item.
Pass in the REQ, RITM, Catalog Item, and the checkbox variables.
Build a simple map of checkboxes → assignment group sys_ids.
In a Run Script step, loop through the selected checkboxes:
Use req.addItem() to create a new RITM under the same REQ.
Copy variables from the original RITM. (To copy Variables if you are using this functionality frequently, it's better to create a custom action to copy the variable values from 1 ritm to another)
Assign the RITM to the mapped group.
Result: one REQ, multiple RITMs (one per checkbox), all with the same variable values but routed to different groups. This keeps the user flow simple (one form, one submission) while giving you clean backend routing.
Regards,
Manikandan Thangaraj
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
3 weeks ago
Hi @phugill,
please follow below steps as per Requirement
Step 1: Background Script (Standalone Test)
Paste this into Scripts → Background in your dev instance:
(function() {
// Sys_id of your catalog item
var catalogItem = 'YOUR_CATALOG_ITEM_SYS_ID';
// Simulated form input variables (checkboxes + shared data)
var requested_for = '6816f79cc0a8016401c5a33be04be441'; // sys_id of "Abel Tuter"
var other_variable = 'Sample Value'; // some other shared variable
// Checkbox selections (true/false)
var it_systems = true;
var infosec = true;
var finance = false;
// Map selections to groups
var options = [];
if (it_systems) options.push({group: '287ebd7da9fe198100f92cc8d1d2154e', value: 'IT Systems'});
if (infosec) options.push({group: '62826bf03710200044e0bfc8bcbe5df1', value: 'Information Security'});
if (finance) options.push({group: '8a4dde73c6112278017a6a4baf547aa7', value: 'Finance'});
// Create cart
var cartId = GlideGuid.generate(null);
var cart = new Cart(cartId);
for (var i=0; i<options.length; i++) {
var item = cart.addItem(catalogItem, 1);
// Set catalog variables
cart.setVariable(item, 'requested_for', requested_for);
cart.setVariable(item, 'other_variable', other_variable);
cart.setVariable(item, 'selected_area', options[i].value);
// Optional: force assignment group
var ritm = cart.getCartItems()[i];
ritm.assignment_group = options[i].group; // sys_id of group
}
// Place order → creates REQ + RITMs
var rc = cart.placeOrder();
gs.info('✅ Request created: ' + rc.number);
})();
above script what it does means
Simulates checkboxes (it_systems, infosec, finance).
For each checked box:
Adds the catalog item to the cart.
Sets shared variables + selected_area.
Assigns the RITM to a group.
Creates one REQ with multiple RITMs.
Step 2: Move into Flow Designer
Once you confirm the Background Script works:
Go to Flow Designer → New Subflow.
Inputs:
requested_for (Reference → User)
other_variable (String)
it_systems (Boolean)
infosec (Boolean)
finance (Boolean)
Add a Run Script action and paste the core logic:
(function execute(inputs, outputs) {
var catalogItem = 'YOUR_CATALOG_ITEM_SYS_ID';
var options = [];
if (inputs.it_systems) options.push({group: 'IT_GROUP_SYSID', value: 'IT Systems'});
if (inputs.infosec) options.push({group: 'INFOSEC_GROUP_SYSID', value: 'Information Security'});
if (inputs.finance) options.push({group: 'FINANCE_GROUP_SYSID', value: 'Finance'});
var cartId = GlideGuid.generate(null);
var cart = new Cart(cartId);
for (var i=0; i<options.length; i++) {
var item = cart.addItem(catalogItem, 1);
cart.setVariable(item, 'requested_for', inputs.requested_for);
cart.setVariable(item, 'other_variable', inputs.other_variable);
cart.setVariable(item, 'selected_area', options[i].value);
var ritm = cart.getCartItems()[i];
ritm.assignment_group = options[i].group;
}
var rc = cart.placeOrder();
outputs.requestNumber = rc.number;
})(inputs, outputs);
Outputs:
requestNumber (String).
Now you can call this subflow in your main Catalog Item Flow.
Result:
User submits one form with checkboxes.
Flow → creates 1 REQ with multiple RITMs.
Each RITM is routed to the correct group.
Please mark as Correct Answer/Helpful, if applicable.
ServiceNow Developer
Chiranjeevi
ServiceNow Developer | | ITSM | | ServiceNow Discovery | | Event Management | | Service Mapping | | CMDB
Please mark as Correct Answer/Helpful, if applicable.