Business rule to change field not shown on form - skip current.update()?

kuba4
Kilo Expert

Hi There!

I need to create Incident based on Requested Item, using Business Rule, something like this:

var gr = new GlideRecord('incident');

gr.initialize();

gr.assignment_group = current.assignment_group;

gr.insert();

current.u_has_incident = true;

I have a problem with field "Has incident", which is not a form field. Without current.update() at the end, it will not be changed. On the other hand I saw few articles with advice not to use current.update() in Business rules... what should I do then to make it work?

1 ACCEPTED SOLUTION

Use an after business rule to create the incident as following



var gr = new GlideRecord('incident');


gr.initialize();


gr.assignment_group = current.assignment_group;


// add your fields that has to be ampped



gr.insert();




current.u_has_incident = true;


current.update();


current.setWorkflow(false);



The last will prevent any business rule or workflow condition to execute.



Please like or mark correct based on the impact of the response.


View solution in original post

14 REPLIES 14

According to the wiki, before business rules should not be used to update related records (see table below)



This is because another before Rule that runs after may interrupt the transaction and prevent the record from being saved.


In this scenario, you wouldn't want another record to be created unless the current record is to be saved.


ValueUse Case
displayUse to provide client scripts access to server-side objects. For more information, see Scripting with Display Business Rules.
beforeUse to update information on the current object. For example, a business rule containing current.state=3; would set the State field on the current record to the state with a Value of 3.
afterUse to update information on related objects that need to be displayed immediately, such as GlideRecord queries.
asyncUse to update information on related objects that do not need to be displayed immediately, such as calculating metrics and SLAs.


Business Rules Best Practices - ServiceNow Wiki


P.S. Cannot find the above document on the product docs site



So here lies the contradiction


  • After business rules should be used to update/create related objects
  • Business rules should not have current.update()
  • You need to update the current record only after the related record is created


So regardless of what you do, you are breaking some sort of best practice rule.



My recommendation would be:


  • Remove the u_has_incident field
  • Create a Reference field for the table of current on the incident table (i will call u_reference)
  • Write your 'After' Business Rule as follows:


var gr = new GlideRecord('incident');


gr.initialize();


gr.assignment_group = current.assignment_group;


gr.u_reference = current.sys_id;


gr.insert();





ServiceNow Nerd
ServiceNow Developer MVP 2020-2022
ServiceNow Community MVP 2019-2022

I think you may have found a winner by switching the direction of reference between the two records here (RITM <-- INC).   I was actually thinking of telling him he should drop the True/False flag in favor of a Reference field, simply because it provides more information and still accomplishes the job of the flag by either having a value or not.   But your approach is able to abide by the rules quite nicely.



Good catch.



-Brian


Hi,


Having a reference field in RITM table is not a good solution, because relationship has to be "many to one" (one RITM can have multiple incidents). This is why I'm using a reference field in Incident table to link it with RITM. Having a true/false flag in RITM table is enough from reporting perspective.



Ok, so currently my Business rule runs on RITM table as "After" BR:



var gr = new GlideRecord('incident');


gr.initialize();


gr.assignment_group = current.assignment_group;


gr.assigned_to = current.assigned_to;


gr.u_request = current.sys_id;


gr.insert();


current.u_has_incident = true;


current.update();



Is it OK to use current.update() here?


yes, since it's an After BR, the only way you can update the current record is to update it...just changing a field value without calling update() won't save the new value in the table.


HI Jakub,



I agree, which is why I said Paul's suggestion looks like the way to go... however I think you are missing a key part of his solution.   You would now establish the relationship by setting a reference value on the new INC pointing to the parent RITM, but you would no longer be adding a T/F flag to the RITM and you would not be updating 'current' in the business rule any more.



Instead, your code would just look like:


var gr = new GlideRecord('incident');


gr.initialize();


gr.assignment_group = current.assignment_group;


gr.assigned_to = current.assigned_to;


gr.u_request = current.sys_id;


gr.insert();




You could then add a Related List to your RITM form displaying the INCs that get created.




-Brian