Unable to update current Request with after insert BR

Vijay Kumar4
Mega Guru
(function executeRule(current, previous /*null when async*/) {
    var cardOrderSysId = '000e49541b0e0d10683742e7bd4bcbed';

    if (current.cat_item.toString() !== cardOrderSysId) {
        return;
    }

    var tinNumber = current.variables.u_tin;
    var memberNumber = current.variables.u_member_number;

    if (!tinNumber && !memberNumber) {
        return;
    }

    var matchingRITMs = [];
    var reqToRitmMap = {}; 

    var gr = new GlideRecord('sc_req_item');
    gr.addQuery('cat_item', cardOrderSysId);
    if (tinNumber) {
        gr.addQuery('u_tin', tinNumber);
    }
    if (memberNumber) {
        gr.addQuery('u_member_number', memberNumber);
    }
    gr.query();

    while (gr.next()) {
        var reqSysId = gr.request.toString();
        var ritmNum = gr.number.toString();

        matchingRITMs.push({
            reqSysId: reqSysId,
            ritmNum: ritmNum
        });

        if (!reqToRitmMap[reqSysId]) {
            reqToRitmMap[reqSysId] = [];
        }

        reqToRitmMap[reqSysId].push(ritmNum);
    }

    for (var reqId in reqToRitmMap) {
        var currentRitmNums = reqToRitmMap[reqId];
        var otherRitmNums = [];

        matchingRITMs.forEach(function(entry) {
            if (entry.reqSysId !== reqId) {
                otherRitmNums.push(entry.ritmNum);
            }
        });

        if (otherRitmNums.length > 0) {
            var reqRec = new GlideRecord('sc_request');
            if (reqRec.get(reqId)) {
                reqRec.u_isduplicate = true;
                reqRec.u_reference_ticket_number = otherRitmNums.join(', ');
                reqRec.update();
            }
        }
    }

})(current, previous);

BR: After insert

VijayKumar4_0-1744041154034.pngVijayKumar4_1-1744041176590.png

 

I’ve implemented a Business Rule to identify duplicate requests based on either the TIN or Member Number provided in the request. For example, we have a catalog item called Card Order, which includes two variables: TIN and Member Number. Users can enter either of these, and the value is then mapped to the corresponding field in the RITM.

Here's the intended logic:

If a user submits a request with 123 as the Member Number, it creates REQ001 → RITM001.

If another request is submitted with the same Member Number, it creates REQ002 → RITM002.

In this case, within REQ002, I expect:

isDuplicate to be set to true

u_reference_ticket_number to be updated with RITM001

Likewise, REQ001 should have its u_reference_ticket_number updated to include RITM002.

However, this is not working as expected. The values are not updating correctly. When I submit a third request (REQ003 → RITM003) with the same Member Number, the current result is:

REQ001 → u_reference_ticket_number = RITM002

REQ002 → u_reference_ticket_number = RITM001

REQ003 → u_reference_ticket_number = empty

But the expected behavior is:

REQ001 → u_reference_ticket_number = RITM002, RITM003

REQ002 → u_reference_ticket_number = RITM001, RITM003

REQ003 → u_reference_ticket_number = RITM001, RITM002

In short, the new request is not updating the reference field in previously created requests, and its own reference field is not being populated with existing matches either.

Could you please help me identify what's missing or going wrong in this logic?

 

5 REPLIES 5

Ankur Bawiskar
Tera Patron
Tera Patron

@Vijay Kumar4 

try this

(function executeRule(current, previous /*null when async*/) {
    var cardOrderSysId = '000e49541b0e0d10683742e7bd4bcbed';

    // Exit if the catalog item is not "Card Order"
    if (current.cat_item.toString() !== cardOrderSysId) {
        return;
    }

    var tinNumber = current.variables.u_tin;
    var memberNumber = current.variables.u_member_number;

    // Exit if neither TIN nor Member Number is provided
    if (!tinNumber && !memberNumber) {
        return;
    }

    // Collect all matching RITMs
    var matchingRITMs = [];
    var gr = new GlideRecord('sc_req_item');
    gr.addQuery('cat_item', cardOrderSysId); // Match the same catalog item
    if (tinNumber) {
        gr.addQuery('u_tin', tinNumber); // Match by TIN
    }
    if (memberNumber) {
        gr.addQuery('u_member_number', memberNumber); // Match by Member Number
    }
    gr.query();

    while (gr.next()) {
        matchingRITMs.push(gr.sys_id.toString());
    }

    // If there are no matches, exit
    if (matchingRITMs.length === 0) {
        return;
    }

    // Update all matching requests with the list of related RITMs
    var reqToUpdate = new GlideRecord('sc_request');
    reqToUpdate.addQuery('sys_id', 'IN', matchingRITMs); // Fetch all related requests
    reqToUpdate.query();

    while (reqToUpdate.next()) {
        var relatedRITMs = matchingRITMs.filter(function(ritmId) {
            return ritmId !== reqToUpdate.sys_id.toString(); // Exclude the current request's RITM
        });

        reqToUpdate.u_isduplicate = true; // Mark as duplicate
        reqToUpdate.u_reference_ticket_number = relatedRITMs.join(', '); // Add related RITMs as a comma-separated list
        reqToUpdate.update();
    }
})(current, previous);

Changes done

1) The script collects all matching RITMs into an array (matchingRITMs) using a single query.
2) The script iterates through all related requests and updates their u_reference_ticket_number field with a list of other matching RITMs.
3) When updating a request, its own RITM number is excluded from the u_reference_ticket_number field to avoid self-referencing.
4) Ensures that every related request is updated with the correct list of other related RITMs.

If my response helped please mark it correct and close the thread so that it benefits future readers.

Regards,
Ankur
✨ Certified Technical Architect  ||  ✨ 9x ServiceNow MVP  ||  ✨ ServiceNow Community Leader

@Ankur Bawiskar Thanks for your response, 

I tried this approach, but it's not working as expected. The result is as follows:

REQ001 → u_reference_ticket_number = RITM001, RITM003

REQ002 → u_reference_ticket_number = RITM002, RITM003

REQ003 → u_reference_ticket_number = (empty)

In this case, the u_reference_ticket_number is being updated with its own RITM and the new one, but one RITM is missing. Also, the latest request (REQ003) still has an empty reference field.

@Vijay Kumar4 

try this

(function executeRule(current, previous /*null when async*/) {
    var cardOrderSysId = '000e49541b0e0d10683742e7bd4bcbed';

    if (current.cat_item.toString() !== cardOrderSysId) {
        return;
    }

    var tinNumber = current.variables.u_tin;
    var memberNumber = current.variables.u_member_number;

    if (!tinNumber && !memberNumber) {
        return;
    }

    var matchingRITMs = [];
    var reqToRitmMap = {}; 

    var gr = new GlideRecord('sc_req_item');
    gr.addQuery('cat_item', cardOrderSysId);
    if (tinNumber) {
        gr.addQuery('u_tin', tinNumber);
    }
    if (memberNumber) {
        gr.addQuery('u_member_number', memberNumber);
    }
    gr.query();

    while (gr.next()) {
        var reqSysId = gr.request.toString();
        var ritmNum = gr.number.toString();

        matchingRITMs.push({
            reqSysId: reqSysId,
            ritmNum: ritmNum
        });

        if (!reqToRitmMap[reqSysId]) {
            reqToRitmMap[reqSysId] = [];
        }

        reqToRitmMap[reqSysId].push(ritmNum);
    }

    // Update all matching requests with the reference ticket numbers
    for (var reqId in reqToRitmMap) {
        var currentRitmNums = reqToRitmMap[reqId];
        var allRitmNums = matchingRITMs.map(function(entry) {
            return entry.ritmNum;
        }).join(', ');

        var reqRec = new GlideRecord('sc_request');
        if (reqRec.get(reqId)) {
            reqRec.u_isduplicate = true;
            reqRec.u_reference_ticket_number = allRitmNums;
            reqRec.update();
        }
    }

    // Update the current request with all matching RITMs
    var currentReqRec = new GlideRecord('sc_request');
    if (currentReqRec.get(current.request.toString())) {
        currentReqRec.u_isduplicate = true;
        var allOtherRitmNums = matchingRITMs.map(function(entry) {
            return entry.ritmNum;
        }).join(', ');
        currentReqRec.u_reference_ticket_number = allOtherRitmNums;
        currentReqRec.update();
    }

})(current, previous);

If my response helped please mark it correct and close the thread so that it benefits future readers.

Regards,
Ankur
✨ Certified Technical Architect  ||  ✨ 9x ServiceNow MVP  ||  ✨ ServiceNow Community Leader

Robert H
Mega Sage

Hello @Vijay Kumar4 ,

 

I would not recommend such a design. Imagine having 1000 requests regarding the same TIN or member: each of those 1000 RITM would have to reference the 999 other RITM. That's a lot of redundant data.

 

Have you considered creating tables specifically for that "Card order" management process?

One table (e.g. "Cards") would hold cards and their details, e.g. the TIN and member number.

The other table (e.g. "Card requests") would be for the requests related to that card, and would have a reference to a card, as well as to a request (RITM) related to that card.

 

With that, your Business Rule would just have to pull the TIN/member number from the variables, look up the corresponding "Card" record, and create a new entry in the "Card requests" table.

If you add the "Card requests" as a related list to the "Cards" form you could then see all the duplicate requests, without having any redundant data.

 

Regards,

Robert