Mahendra RC
Mega Sage

Hello Everyone,
I would like to share my experience on the below issue so that it can be helpful to others if someone face similar issue.

Recently while working on a requirement to create the REQ and RITMs via script we ran into an issue where duplicate RITMs were getting created. Now as per the requirement multiple REQ should be created as soon as the user record is created in ServiceNow. So, suppose 200 user records created in 5 seconds then the script will run to create 200 REQ for this 200 users.

We tried to use the Cart() to create REQ as shown below:

_createNewJoinerRequest: function(usrID) {
        var newJoinerCatId = gs.getProperty("new.joiner.catalog.item");
        var cart = new Cart();
        var item = cart.addItem(newJoinerCatId);
        cart.setVariable(item, 'requested_for', usrID);
        var rc = cart.placeOrder();
        var request = rc.getDisplayValue();
        return request;
    },

But when we tested this, we observed that Duplicate REQs and RITMs were created for same user. For example in ideal scenario if say 3 users are created Arnaud, Sujay and Nick then we should have 3 REQs with 1 RITM each as shown below:

REQ0040061 --> RITM0040062  for user Arnaud

REQ0040062 --> RITM0040063  for user Sujay

REQ0040063 --> RITM0040064  for user Nick

But the REQs and RITMs were created as shown below:

REQ0040061 (Requested for = Arnaud) and has 2 RITMs

--> RITM0040062  (Requested for = Arnaud) & RITM0040065 (Requested for = Sujay)

REQ0040062  (Requested for = Arnaud) and has 2 RITMs

--> RITM0040063 (Requested for = Arnaud) & RITM0040066 (Requested for = Sujay)

find_real_file.png

 

find_real_file.png

find_real_file.png

find_real_file.png

After checking on this we observed that there is some issue with the timing. The Cart was getting created as expected but the cart was taking 3-4 seconds to get submitted and hence by the time the Cart is submitted there are multiple Items that are added in the Cart. So, the Cart was getting submitted with more than 1 item in it.

This was happening for most (not all) of the REQ or User. The Cart was getting created for each user record that is created in ServiceNow but by the time the order is placed or Cart is submitted other items were also added to the same cart and hence this issue was observed. We tried different ways to fix this issue like using new sn_sc.CartJS() or new sn_sc.CartJS(gs.generateGUID()) so that there is a unique id generated for each cart. But this does not resolved the issue.

We checked with ServiceNow on this and were able to fix this. There was slight change that was required in the script which we were not able to figure out as that was not clearly mentioned anywhere in documentation. Below is the script that fixed this issue:

_createNewJoinerRequest: function(usrID) {
        var newJoinerCatId = gs.getProperty("new.joiner.catalog.item");
        var cartid = "cart_" + gs.generateGUID(); // along with gs.generateGUID() we should append "cart_". This can be used as unique id for the Cart.
        var cart = new sn_sc.CartJS(cartid);
        var request = {
            "sysparm_id": newJoinerCatId,
            "sysparm_quantity": "1",
            "variables": {
                "requested_for": usrID
            },
            "sysparm_cart_name": cartid // Use "sysparm_cart_name" to set the Cart ID for this cart. This was something that was not clear to me.
        };
        var cartRequest = cart.orderNow(request);
        var requestNumber = "";
        if (cartRequest.request_number)
            requestNumber = cartRequest.request_number;
        return requestNumber;
    },

If you find this as helpful or helped you to learn something new, please do mark it helpful.

Thanks.

Comments
Shane J
Tera Guru

This post should be shouted from the mountains.

 

😫

Salvador Marcha
Kilo Guru

Hi, What is the value in "new.joiner.catalog.item" property"?

Shane J
Tera Guru

It's not needed for this to work, I think it was just in his original example.

sneha77
Tera Explorer

I encountered a similar requirement where a Record Producer, let’s call it "Rec A," needed to create multiple tickets simultaneously. To address this, I implemented a solution by introducing another Record Producer, "Rec B." The goal was to allow users to upload an Excel file and automatically populate a Multi-Row Variable Set (MRVS) in Rec B using the GlideExcelParser(). For each row in the MRVS, a corresponding ticket for Rec A would be created.

To achieve this, I utilized the CART API as follows:

var rowCount = mrvs.getRowCount();
for (var i = 0; i < rowCount; i++) {
var row = mrvs.getRow(i);

var cart = new sn_sc.CartJS();
var newItem = cart.addToCart({
"sysparm_id": "SYSID of Rec A",
"sysparm_quantity": "1",
"variables": {
"requested_by": row.requested_by,
// Additional field mappings here
}
});

var checkoutInfo = cart.checkoutCart();
var gr = new GlideRecord('table_name'); // As i wanted whatever child records will create it should have parent value of the ticket created by Rec B
gr.get('sys_id', checkoutInfo.sys_id);
gr.parent = current.getUniqueValue();
gr.update();
}

 

However, I encountered an intermittent issue where an extra ticket for Rec A was occasionally created. There were also instances where a delay of up to 10 minutes was observed. After raising an HI case with ServiceNow support, we discovered that the problem stemmed from the default cart name being used in the business rule that triggered the CART API:

var cart = new sn_sc.CartJS();

 

This default naming convention led to multiple items being added to the same cart during concurrent request executions, causing duplicate tickets.

Resolution: The solution provided by ServiceNow was to assign a unique cart name for each cart creation. The sample code shared was as follows:

var cartName = "cart_" + gs.generateGUID() + "_" + itemId;
var cart = new sn_sc.CartJS(cartName);
request_body.sysparm_cart_name = cartName;

 

I modified the code accordingly

var cartid = "cart_" + gs.generateGUID();
var cart = new sn_sc.CartJS(cartid);
var newItem = cart.addToCart({
"sysparm_id": "SYSID of Rec A",
"sysparm_quantity": "1",
"sysparm_cart_name": cartid,
"variables": {
"requested_by": row.requested_by,
// Additional field mappings here
}
});

var checkoutInfo = cart.checkoutCart();
var gr = new GlideRecord('table_name');
gr.get('sys_id', checkoutInfo.sys_id);
gr.parent = current.getUniqueValue();
gr.update();

 

This modification resolved the issue by ensuring that each cart operation used a unique identifier, thereby preventing the occurrence of duplicate tickets during concurrent requests.

Hope this helps.

subhadeep1618
Tera Guru

Truly brilliant post - extremely helpful.

Thank you so much @Mahendra RC 

Version history
Last update:
‎08-02-2022 10:42 PM
Updated by: