Join the #BuildWithBuildAgent Challenge! Get recognized, earn exclusive swag, and inspire the ServiceNow Community with what you can build using Build Agent.  Join the Challenge.

Business Rule not working as expected

Gal Katz
Kilo Sage

I have a business rule on the 'alm_asset' table that after an update of a record, updates all other records that have the same Serial Number.
After updating the icon that indicates a change on a field appears but the value is not updated:

Screenshot 2023-10-02 135715.png

 The business rule script is:

(function executeRule(current, previous /*null when async*/ ) {

    ////////////////////// Query the 'alm_asset' table for records with the same serial number///////////////
    var serialNumber = current.serial_number;
    var assetGr = new GlideRecord('alm_asset');
    assetGr.addQuery('serial_number', serialNumber);
    assetGr.query();
    ///////////////////////Get all fields///////////////////////////////////////////////////////////////////
    var arr_fields = [];
    var fields = new GlideRecord('sys_dictionary');
    fields.addQuery('name', 'alm_asset');
    fields.query();

    while (fields.next()) {
        arr_fields.push(fields.element.toString());
    }

    ///////////////////// Loop through matching records and update them/////////////////////////////////////////
    while (assetGr.next()) {
        if (assetGr.sys_id != current.sys_id) {
            // Update the fields on related records
            for (i = 0; i < arr_fields.length; i++) {
                assetGr.setValue(arr_fields[i], current.getValue(arr_fields[i]));
            }
			assetGr.update();
        }
	}

})(current, previous);
1 ACCEPTED SOLUTION

Gal Katz
Kilo Sage

The problem was that my script was trying to change the sys_id.
The working script is:

(function executeRule(current, previous /*null when async*/ ) {

    ////////////////////// Query the 'alm_asset' table for records with the same serial number///////////////
    var serialNumber = current.serial_number;
    var assetGr = new GlideRecord('alm_asset');
    assetGr.addQuery('serial_number', serialNumber);
	assetGr.addQuery('sys_id', '!=', current.sys_id);
    assetGr.query();
    ///////////////////////Get all fields///////////////////////////////////////////////////////////////////
    var arr_fields = [];
    var fields = new GlideRecord('sys_dictionary');
    fields.addQuery('name', 'alm_asset');
    fields.query();

    while (fields.next()) {
        arr_fields.push(fields.element.toString());
    }
    ///////////////////// Loop through matching records and update them///////////////////////
    while (assetGr.next()) {
            for (i = 0; i < arr_fields.length; i++) {
                if(arr_fields[i] != 'sys_id'){
                    assetGr.setValue(arr_fields[i], current[arr_fields[i]]);             
                }
          
            }
			assetGr.update();
        }
})(current, previous);

View solution in original post

8 REPLIES 8

Peter Bodelier
Giga Sage

Hi @Gal Katz,

 

It looks like you are updating the record self, and may even be creating a loop.

 

Try it like this:

(function executeRule(current, previous /*null when async*/ ) {

    ////////////////////// Query the 'alm_asset' table for records with the same serial number///////////////
    var serialNumber = current.serial_number;
    var assetGr = new GlideRecord('alm_asset');
    assetGr.addQuery('serial_number', serialNumber);
    assetGr.addQuery('sys_id', '!=', current.getUniqueValue());
    assetGr.query();
    ///////////////////////Get all fields///////////////////////////////////////////////////////////////////
    var arr_fields = [];
    var fields = new GlideRecord('sys_dictionary');
    fields.addQuery('name', 'alm_asset');
    fields.query();

    while (fields.next()) {
        arr_fields.push(fields.element.toString());
    }

    ///////////////////// Loop through matching records and update them/////////////////////////////////////////
    while (assetGr.next()) {
        if (assetGr.sys_id != current.sys_id) {
            // Update the fields on related records
            for (i = 0; i < arr_fields.length; i++) {
                assetGr.setValue(arr_fields[i], current.getValue(arr_fields[i]));
            }
			assetGr.update();
        }
	}

})(current, previous);

 

I wanted to add assetGr.setWorkflow(false); as well, but this may have negative impact on related records which do need to be updated.

 

I'd suggest to add a custom field (and exclude that form synchronising), Add this field as condition so this BR rule doesn't trigger again on records being updated by it.  


Help others to find a correct solution by marking the appropriate response as accepted solution and helpful.

Hi @Peter Bodelier Thank you for your time and help.
I tried assetGr.setWorkflow(false) and also tried adding a custom field like you suggested.
Unfortunately it didn't work for me. 

can you please write me an example on how to use the custom field I created on the script to get the results?

Hi @Gal Katz,

 

It could be something like this. (in trigger condition of BR set <custom field> changes to true

 

(function executeRule(current, previous /*null when async*/ ) {

if(current.<<customfield>> == false){
    ////////////////////// Query the 'alm_asset' table for records with the same serial number///////////////
    var serialNumber = current.serial_number;
    var assetGr = new GlideRecord('alm_asset');
    assetGr.addQuery('serial_number', serialNumber);
    assetGr.addQuery('sys_id', '!=', current.getUniqueValue());
    assetGr.query();
    ///////////////////////Get all fields///////////////////////////////////////////////////////////////////
    var arr_fields = [];
    var fields = new GlideRecord('sys_dictionary');
    fields.addQuery('name', 'alm_asset');
    fields.query();

    while (fields.next()) {
        arr_fields.push(fields.element.toString());
    }

    ///////////////////// Loop through matching records and update them/////////////////////////////////////////
    while (assetGr.next()) {
        if (assetGr.sys_id != current.sys_id) {
            // Update the fields on related records
            for (i = 0; i < arr_fields.length; i++) {
                assetGr.setValue(arr_fields[i], current.getValue(arr_fields[i]));
            }
			assetGr.update();
        }
	}
}
else{

current.<<customefield>> = false;

}
})(current, previous);

Help others to find a correct solution by marking the appropriate response as accepted solution and helpful.

Community Alums
Not applicable

By any chance it has report on ACL on the fields?

Regards

Suman P.