How to create 1 Req with multiple Ritms from list collector.

2021mb21965
Mega Contributor

Hello All,

I am facing an issue with a Service Request (SR) catalog item.

Requirement:
When the SR form is submitted, it contains a List Collector variable (multi-select). Based on the selected values, the system should:

- Create only 1 Request (REQ)
- Create multiple RITMs (one per selected value)

Current Issue:
If I select multiple values (e.g., 2 values), the system is creating:

- 2 Requests (REQs)
- 2 RITMs

However, the expected behavior is 1 REQ with multiple RITMs.

Current Approach:
I am using a Business Rule on "sc_req_item" with Cart API to recreate the request.

I believe the issue might be due to the Business Rule being triggered multiple times during request creation.

 

Attaching code for reference 

(function executeRule(current, previous) {

 

    if (gs.getProperty('x_app.feature_toggle') != 'true')

        return;

 

    if (current.operation() != 'insert')

        return;

 

    if (current.u_split_processed == true)

        return;

 

    var values = current.variables.u_multi_field;

    if (!values)

        return;

 

    values = values.toString().split(',');

 

    if (values.length <= 1)

        return;

 

    if (!current.cat_item)

        return;

 

    var cart = new Cart();

    cart.setName('Auto Generated Request');

 

    if (current.requested_for)

        cart.setRequestedFor(current.requested_for.toString());

 

    for (var i = 0; i < values.length; i++) {

 

        var val = values[i].trim();

        if (!val) continue;

 

        var item = cart.addItem(current.cat_item);

 

        var vars = current.variables.getElements();

 

        for (var v = 0; v < vars.length; v++) {

            cart.setVariable(item, vars[v].getName(), vars[v].getValue());

        }

 

        cart.setVariable(item, 'u_multi_field', val);

    }

 

    var newReq = cart.placeOrder();

 

    if (!newReq || gs.nil(newReq.sys_id))

        return;

 

    var ritmGR = new GlideRecord('sc_req_item');

    ritmGR.addQuery('request', newReq.sys_id);

    ritmGR.query();

 

    while (ritmGR.next()) {

        ritmGR.u_split_processed = true;

        ritmGR.update();

    }

 

    current.setAbortAction(true);

 

    gs.addInfoMessage('Request created: ' + newReq.number);

 

})(current, previous);

 

Can some one help me with this or suggest best example to get my requirement done

 

 

Thanks 

 

 

3 REPLIES 3

ayushraj7012933
Mega Guru

Hi, the issue occurs because your Business Rule on sc_req_item is executing multiple times (once per RITM insert), and since you are using the Cart API (placeOrder()) inside it, a new Request (REQ) is created on each execution, resulting in multiple REQs instead of one. This approach is not recommended as it can cause duplicate and recursive request creation. The best practice is to avoid using Cart API in a Business Rule and instead implement this logic using Flow Designer or an Order Guide, where you can loop through the List Collector values and create multiple RITMs under a single REQ. If you must continue with scripting, you need to add a guard condition (e.g., a flag on the Request) to ensure the logic runs only once.                                               script:-                                                                                                                                                                                                  

(function executeRule(current, previous) {

// Feature toggle check
if (gs.getProperty('x_app.feature_toggle') != 'true')
return;

// Run only on insert
if (current.operation() != 'insert')
return;

// Ensure request exists
if (!current.request)
return;

var reqGR = current.request.getRefRecord();

//  Prevent multiple executions (MAIN FIX)
if (reqGR.u_split_processed == true)
return;

// Get list collector values
var values = current.variables.u_multi_field;
if (!values)
return;

values = values.toString().split(',');

// If only one value → no split needed
if (values.length <= 1)
return;

if (!current.cat_item)
return;

// Mark original request as processed (so BR won't run again)
reqGR.u_split_processed = true;
reqGR.update();

// Create Cart
var cart = new Cart();
cart.setName('Auto Generated Request');

if (current.requested_for)
cart.setRequestedFor(current.requested_for.toString());

// Loop through values and create items
for (var i = 0; i < values.length; i++) {

var val = values[i].trim();
if (!val)
continue;

var item = cart.addItem(current.cat_item);

// Copy all variables
var vars = current.variables.getElements();
for (var v = 0; v < vars.length; v++) {
cart.setVariable(item, vars[v].getName(), vars[v].getValue());
}

// Override list collector with single value
cart.setVariable(item, 'u_multi_field', val);
}

// Place order → creates 1 REQ with multiple RITMs
var newReq = cart.placeOrder();

if (!newReq || gs.nil(newReq.sys_id))
return;

// Mark all new RITMs as processed
var ritmGR = new GlideRecord('sc_req_item');
ritmGR.addQuery('request', newReq.sys_id);
ritmGR.query();

while (ritmGR.next()) {
ritmGR.u_split_processed = true;
ritmGR.update();
}

// Abort original RITM creation
current.setAbortAction(true);

gs.addInfoMessage('Request created: ' + newReq.number);

})(current, previous);

 

Hi Ayush 

Can you help me to understand how to get this requirement done via flow design?

 

Appreciate if you can tell me in detail.

 

Thanks 

ayushraj7012933
Mega Guru

Hi,

You can achieve this requirement using Flow Designer instead of scripting or Cart API. Below are the steps to implement it:

  1. Create a Flow
    Navigate to Flow Designer and create a new flow with a trigger on Requested Item [sc_req_item] → Created. Add a condition to run only for your specific catalog item.

  2. Get Catalog Variables
    Use the “Get Catalog Variables” action to fetch the List Collector variable (e.g., u_multi_feild) from the RITM.

  3. Split List Collector Values
    Since the List Collector stores values as a comma-separated string, add a Script step to split it into an array:

     
    return inputs.u_multi_field.split(',');
     
  4. Add For Each Loop
    Use a For Each action to iterate through each value from the array.

  5. Create Multiple RITMs under Same REQ
    Inside the loop, use Create Record (sc_req_item) or Create Catalog Request Item action:

    • Set Request = Trigger → Request (this ensures only one REQ is used)

    • Set Catalog Item = same as original

    • Copy all required variables

    • Override the List Collector variable with the current loop value

  6. Handle Original RITM
    If multiple values are selected, you can either delete or ignore the original RITM to avoid duplication.

  7. Add a Guard Condition
    Update a flag (e.g., u_spliti_process = true) on the Request or RITM to prevent the flow from running multiple times.