- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
3 weeks ago
Hi everyone,
I have a Catalog Item with an MRVS for bulk Server Access. When Bulk Access = Yes, each MRVS row should create one RITM, and all RITMs should belong to the same existing REQ.
I can use Create Record → sc_req_item and link each new RITM to the existing REQ, but I cannot populate the catalog variables on the newly created RITM from the current MRVS row.
I also tried Submit Catalog Item Request, which allows variable mapping, but it creates a new REQ instead of using the existing one.
What is the recommended OOB/Flow Designer approach for this? Would a Custom Action + CartJS be appropriate, or is there a better pattern?
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
2 weeks ago
Hi @Aditya_hublikar thank you for following up. I’m still working on it, but I’m currently stuck with the REQ handling.
The MRVS is working and the Flow correctly loops through all the rows. The custom action also runs for each row and creates the RITMs, but when I use CartJS, it creates empty REQs for the generated RITMs.
function getSysId(value) {
if (!value) return '';
if (typeof value == 'string') return value;
if (value.getUniqueValue) return value.getUniqueValue();
return '';
}
(function execute(inputs, outputs) {
var existingReqSysId = getSysId(inputs.original_request);
var ritm = inputs.requested_item;
var catalogItem = ritm.cat_item.getRefRecord();
var catalogItemSysId = catalogItem.getUniqueValue();
try {
var mrvsRows = [{
'mrvs_server_name': getSysId(inputs.server_name),
'mrvs_technical_owner': getSysId(inputs.technical_owner),
'mrvs_virtual_machine_name': getSysId(inputs.virtual_machine_name),
'mrvs_what_access': inputs.what_access + ''
}];
var mrvsJSON = JSON.stringify(mrvsRows);
// Create CartJS
var cart = new sn_sc.CartJS();
// Build catalog item payload
var itemPayload = {
'sysparm_id': catalogItemSysId,
'sysparm_quantity': '1',
'variables': {
'multi_row_variable_set': mrvsJSON,
'select_the_permission_level_server': inputs.permission_level + '',
'full_sql': inputs.full_sql,
'requested_for': getSysId(inputs.requested_for),
}
};
gs.info('[Server Access] CartJS PAYLOAD = ' + JSON.stringify(itemPayload));
// Submit the catalog item
var cartResult = cart.orderNow(itemPayload);
// Get temporary REQ
var newRequestSysId = cartResult.request_id + '';
gs.info('[Server Access] Temporary REQ sys_id: ' + newRequestSysId);
var ritmGR = new GlideRecord('sc_req_item');
ritmGR.addQuery('request', newRequestSysId);
ritmGR.addQuery('cat_item', catalogItemSysId);
ritmGR.query();
if (ritmGR.next()) {
gs.info('New RITM found: ' + ritmGR.getValue('number'));
ritmGR.setValue('request', existingReqSysId);
var updateResult = ritmGR.update();
gs.info('[Server Access] RITM moved to original REQ');
gs.info('[Server Access] Updated RITM sys_id: ' + updateResult);
gs.info('[Server Access] Original REQ: ' + existingReqSysId);
outputs.ritm_number = ritmGR.getValue('number');
} else {
gs.error(' ERROR: Could not find newly created RITM.');
}
} catch (ex) {
gs.error('[Server Access] ERROR: ' + ex.getMessage());
gs.error('[Server Access] ERROR details: ' + ex);
}
})(inputs, outputs);
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
2 weeks ago
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
3 weeks ago
you can iterate each MRVS row and use OOTB flow action "Submit Catalog Item Request" and it will create REQ and RITM
Yes it will create new REQ and new RITM, you can cancel the new REQ and update the new RITM with the existing REQ by using "Update Record" flow action
I shared solution last year, check and enhance
Create multiple RITM based on data in MRVS using Flow Designer
💡 If my response helped, please mark it as correct ✅ and close the thread 🔒— this helps future readers find the solution faster! 🙏
Ankur
✨ Certified Technical Architect || ✨ 10x ServiceNow MVP || ✨ ServiceNow Community Leader
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
3 weeks ago
Hello @AidaS ,
I have tried your use case :
Created custom action in flow designer to create individual ritm and its code is as below :
(function execute(inputs, outputs) {
var existingReqSysId = inputs.req;
var catalogItemSysId = inputs.catid;
try {
var mrvs = {
server: inputs.server,
access: inputs.access
};
var existingReqSysId = existingReqSysId;
var catalogItemSysId = catalogItemSysId;
var mrvsRows = [
{
server: mrvs.server + '',
access: mrvs.access + ''
}
];
var mrvsJSON = JSON.stringify(mrvsRows);
gs.info('MRVS JSON = ' + mrvsJSON);
var cart = new sn_sc.CartJS();
var itemPayload = {
'sysparm_id': catalogItemSysId,
'sysparm_quantity': '1',
'variables': {
'mrvs_usecase': mrvsJSON // Set MRVS variable container name
}
};
var cartResult = cart.orderNow(itemPayload);
var newRequestSysId = cartResult.request_id;
gs.info('Temporary REQ = ' + newRequestSysId);
var ritmGR = new GlideRecord('sc_req_item');
ritmGR.addQuery('request', newRequestSysId);
ritmGR.query();
while (ritmGR.next()) {
gs.info(
'RITM = ' +
ritmGR.getValue('number')
);
gs.info(
'RITM sys_id = ' +
ritmGR.getUniqueValue()
);
var optionGR = new GlideRecord('sc_item_option_mtom');
optionGR.addQuery('request_item', ritmGR.getUniqueValue());
optionGR.query();
while (optionGR.next()) {
var itemOption = optionGR.sc_item_option.getRefRecord();
gs.info(
'VARIABLE = ' +
itemOption.getDisplayValue('item_option_new') +
' VALUE = ' +
itemOption.getValue('value')
);
}
ritmGR.setValue('request', existingReqSysId);
ritmGR.update();
}
var emptyReq = new GlideRecord('sc_request');
if (emptyReq.get(newRequestSysId)) {
emptyReq.deleteRecord();
gs.info(
'Temporary REQ deleted = ' +
newRequestSysId
);
}
outputs.ritmnum= ritmGR.number.toString();
} catch (ex) {
var message = ex.getMessage();
gs.error("CartJS Execution Error: " + message);
}
})(inputs, outputs);
Called it in flow :
Outcome :
If this helps you then mark it as helpful and accept as solution.
Regards,
Aditya
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
3 weeks ago
Hello @AidaS ,
I hope you are doing well . Does your query is resolved ? If yes then accept as solution and close this thread .
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
2 weeks ago
Hi @Aditya_hublikar thank you for following up. I’m still working on it, but I’m currently stuck with the REQ handling.
The MRVS is working and the Flow correctly loops through all the rows. The custom action also runs for each row and creates the RITMs, but when I use CartJS, it creates empty REQs for the generated RITMs.
function getSysId(value) {
if (!value) return '';
if (typeof value == 'string') return value;
if (value.getUniqueValue) return value.getUniqueValue();
return '';
}
(function execute(inputs, outputs) {
var existingReqSysId = getSysId(inputs.original_request);
var ritm = inputs.requested_item;
var catalogItem = ritm.cat_item.getRefRecord();
var catalogItemSysId = catalogItem.getUniqueValue();
try {
var mrvsRows = [{
'mrvs_server_name': getSysId(inputs.server_name),
'mrvs_technical_owner': getSysId(inputs.technical_owner),
'mrvs_virtual_machine_name': getSysId(inputs.virtual_machine_name),
'mrvs_what_access': inputs.what_access + ''
}];
var mrvsJSON = JSON.stringify(mrvsRows);
// Create CartJS
var cart = new sn_sc.CartJS();
// Build catalog item payload
var itemPayload = {
'sysparm_id': catalogItemSysId,
'sysparm_quantity': '1',
'variables': {
'multi_row_variable_set': mrvsJSON,
'select_the_permission_level_server': inputs.permission_level + '',
'full_sql': inputs.full_sql,
'requested_for': getSysId(inputs.requested_for),
}
};
gs.info('[Server Access] CartJS PAYLOAD = ' + JSON.stringify(itemPayload));
// Submit the catalog item
var cartResult = cart.orderNow(itemPayload);
// Get temporary REQ
var newRequestSysId = cartResult.request_id + '';
gs.info('[Server Access] Temporary REQ sys_id: ' + newRequestSysId);
var ritmGR = new GlideRecord('sc_req_item');
ritmGR.addQuery('request', newRequestSysId);
ritmGR.addQuery('cat_item', catalogItemSysId);
ritmGR.query();
if (ritmGR.next()) {
gs.info('New RITM found: ' + ritmGR.getValue('number'));
ritmGR.setValue('request', existingReqSysId);
var updateResult = ritmGR.update();
gs.info('[Server Access] RITM moved to original REQ');
gs.info('[Server Access] Updated RITM sys_id: ' + updateResult);
gs.info('[Server Access] Original REQ: ' + existingReqSysId);
outputs.ritm_number = ritmGR.getValue('number');
} else {
gs.error(' ERROR: Could not find newly created RITM.');
}
} catch (ex) {
gs.error('[Server Access] ERROR: ' + ex.getMessage());
gs.error('[Server Access] ERROR details: ' + ex);
}
})(inputs, outputs);
