How to update outage Affected CI table when CI on incident changes.

Community Alums
Not applicable

Hello - I am trying to write a business rule that, when a CI is changed (to another CI or to nothing) on the incident form, the Affected CI's on associated outage (cmdb_outage_ci_mtom) reflects that change ... ie it deletes the old value and includes the new value (or nothing if the CI on the incident is deleted). 

I have this written, but it is not working. Thoughts? 

 

Business rule 1 (to delete the old value -- doesn't work):

When to run: Before; update; Configuration item changes

Table: incident

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

	var outageCIs = new GlideRecord('cmdb_outage_ci_mtom');
	outageCIs.addQuery('ci_item', current.ci_item);
	outageCIs.query();
	if (outageCIs.next()){
		outageCIs.deleteRecord();
	}

})(current, previous);

 

Business rule 2 (to add all Affected CI's from incident to outage -- does work): 

 

When to run: after; insert

Table: task_ci (CI's affected - on incident)

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


    var incident = new GlideRecord('incident');
    incident.addQuery('sys_id', current.task);
    incident.query();
    if (incident.next()) {
        gs.info('test1');
        var incidentCIs = new GlideRecord('task_ci');
        incidentCIs.addQuery('task', incident.sys_id);
        incidentCIs.query();
        while (incidentCIs.next()) {
            var outageCIs = new GlideRecord('cmdb_outage_ci_mtom');
            outageCIs.addEncodedQuery('ci_item=' + incidentCIs.ci_item + '^outage.task_number=' + incident.getUniqueValue())
            outageCIs.query();
            if (outageCIs.next()) {
                continue;
            }
            gs.info('test2');
            var outage = new GlideRecord('cmdb_ci_outage');
            outage.addQuery('task_number', current.task);
            outage.query();
            if (outage.next()) {
                gs.info('test3');
                outageCIs.initialize();
                outageCIs.ci_item = incidentCIs.ci_item;
                outageCIs.outage = outage.sys_id;
                outageCIs.insert();

            }

        }
    }





})(current, previous);

 

 

 Thank you!

 

Best,

Dan

1 ACCEPTED SOLUTION

Brad Bowman
Kilo Patron
Kilo Patron

Hi Dan,

You can actually achieve this with one Business Rule running after Update on the Incident table.  Either use the Filter Condition Configuration item changes, or you can put this as the Condition on the Advanced tab

current.cmdb_ci.changes()

I'm not entirely clear on the difference in condition placement, or if there even is one in this case, but the out of the box business rule that keeps the incident (and other tasks) affected CIs in sync with the CI on that  form puts this in the Condition field rather than using the When to run Filter Conditions.  In any event, here's the magic.  This solution covers the possibility that more than one Outage record is associated with an incident.

var outageArr = [];
var outGR = new GlideRecord('cmdb_ci_outage');
outGR.addQuery('task_number', current.sys_id);
outGR.query();
while(outGR.next()){
	outageArr.push(outGR.sys_id.toString());
}

if (!previous.cmdb_ci.nil())
   removePreviousCI();

if (!current.cmdb_ci.nil())
   addCurrentCI();

function removePreviousCI() {
   //Delete Affected CI records on the Outage(s) associated with this incident and previous CI
   var rec = new GlideRecord('cmdb_outage_ci_mtom');
   rec.addQuery('outage', 'IN', outageArr.join(','));
   rec.addQuery('ci_item', previous.cmdb_ci);
   rec.query();
   while(rec.next()){
      rec.deleteRecord();
   }
}

function addCurrentCI() {
	//Create Affected CI record for the Outage(s) associated with this incident and current CI
	for(var i=0;i<outageArr.length; i++){
		var rec = new GlideRecord('cmdb_outage_ci_mtom');
		rec.addQuery('outage', outageArr[i]);
		rec.addQuery('ci_item', current.cmdb_ci);
		rec.query();
		if (rec.next()){
			//Affected CI already found, so don't add a duplicate
			return;
		}
		rec.initialize();
		rec.outage = outageArr[i];
		rec.ci_item = current.cmdb_ci;
		rec.insert();
	}
}

 If you wanted to be super thorough, you would also need a similar rule on the task_ci table to update the Outage(s') Affected CIs when the Incident's Affected CIs are changed - except for when this is already happening due to the Incident cmdb_ci changing.  This covers the eventuality of someone adding or removing Affected CIs via the related list. 

View solution in original post

3 REPLIES 3

Brad Bowman
Kilo Patron
Kilo Patron

Hi Dan,

You can actually achieve this with one Business Rule running after Update on the Incident table.  Either use the Filter Condition Configuration item changes, or you can put this as the Condition on the Advanced tab

current.cmdb_ci.changes()

I'm not entirely clear on the difference in condition placement, or if there even is one in this case, but the out of the box business rule that keeps the incident (and other tasks) affected CIs in sync with the CI on that  form puts this in the Condition field rather than using the When to run Filter Conditions.  In any event, here's the magic.  This solution covers the possibility that more than one Outage record is associated with an incident.

var outageArr = [];
var outGR = new GlideRecord('cmdb_ci_outage');
outGR.addQuery('task_number', current.sys_id);
outGR.query();
while(outGR.next()){
	outageArr.push(outGR.sys_id.toString());
}

if (!previous.cmdb_ci.nil())
   removePreviousCI();

if (!current.cmdb_ci.nil())
   addCurrentCI();

function removePreviousCI() {
   //Delete Affected CI records on the Outage(s) associated with this incident and previous CI
   var rec = new GlideRecord('cmdb_outage_ci_mtom');
   rec.addQuery('outage', 'IN', outageArr.join(','));
   rec.addQuery('ci_item', previous.cmdb_ci);
   rec.query();
   while(rec.next()){
      rec.deleteRecord();
   }
}

function addCurrentCI() {
	//Create Affected CI record for the Outage(s) associated with this incident and current CI
	for(var i=0;i<outageArr.length; i++){
		var rec = new GlideRecord('cmdb_outage_ci_mtom');
		rec.addQuery('outage', outageArr[i]);
		rec.addQuery('ci_item', current.cmdb_ci);
		rec.query();
		if (rec.next()){
			//Affected CI already found, so don't add a duplicate
			return;
		}
		rec.initialize();
		rec.outage = outageArr[i];
		rec.ci_item = current.cmdb_ci;
		rec.insert();
	}
}

 If you wanted to be super thorough, you would also need a similar rule on the task_ci table to update the Outage(s') Affected CIs when the Incident's Affected CIs are changed - except for when this is already happening due to the Incident cmdb_ci changing.  This covers the eventuality of someone adding or removing Affected CIs via the related list. 

Were you able to test this solution to see if it meets your requirements?

Community Alums
Not applicable

Hi Brad,

I did test it - and it works well. Ended up using my business rules, but this is a great reference, thank you. Realized that what I was missing was I was using current.cmdb_ci instead of previous.cmdb_ci in my initial lookup of BR 1. 

Thanks for your help. 

 

-Dan