Converting a business rule to a script include

Ian Mildon
Tera Guru

I have a fairly simple before business rule that adds a message if the CI entered on an Incident record has active Change Requests against it. My issue is that I have been tasked with making this functionality work more "real time", as an "onChange" of the Incident cmdb_ci field.

And this is where my lack of knowledge on script includes comes in. I've spent quite a bit of time trying to figure this out but Script Includes just seem to confuse me.

Here is the business rule that I'm wanting to convert, it  runs before insert and update on the Incident table. I would appreciate any help on this.

var gr = new GlideRecord('change_request');
gr.addQuery('cmdb_ci', current.cmdb_ci);
gr.addQuery('active', true);
gr.query();
if (gr.next()) {
	var rc = gr.getRowCount();
	gs.addErrorMessage("This CI has " + rc + " open Changes against it");
}

 

1 ACCEPTED SOLUTION

Ian Mildon
Tera Guru

Things are a little clearer now (still pretty cloudy though!) but the main thing is that I do have a working script include and a working GlideAjax call. Plus the gr.getRowCount() does still work, so I can provide a "live" count in the alert box.

Here is the modified Script Include based off Shane J's example:

var ChangeCheck = Class.create();
ChangeCheck.prototype = Object.extendsObject(AbstractAjaxProcessor, {
	
	getChangeRequests : function(){
		
		var ciVal = this.getParameter('sysparm_ciVal');		
		
		var gr = new GlideRecord('change_request');
		gr.addQuery('cmdb_ci', ciVal);
		gr.addQuery('active', true);
		gr.query();
		if (gr.hasNext()) {
			var rc = gr.getRowCount();
			return "This CI has " + rc + " open Changes against it";
		}
		else {
			return "This CI has no open Changes against it.";
		}
	},
	
	type: 'ChangeCheck'
});

And here is the modified onChange Client Script (also based off Shane J's example):

function onChange(control, oldValue, newValue, isLoading, isTemplate) {
	if (isLoading || newValue === '') {
		return;
	}
	
	var ciVal = g_form.getValue('cmdb_ci');
	
	var ga = new GlideAjax('ChangeCheck');
	ga.addParam('sysparm_name', 'getChangeRequests');
	ga.addParam('sysparm_ciVal', ciVal);
	ga.getXML(chgCallback);
	
	function chgCallback(response){
		var answer = response.responseXML.documentElement.getAttribute("answer");
		
		alert(answer);
	}

Currently this is working and I have only found 1 issue so far. I found that I had to provide an alert message for the "else" part of the Script Include, otherwise I was getting an alert popup with "null" as the value.

View solution in original post

9 REPLIES 9

Shane J
Tera Guru

Well here's a start at least (I think, I'm not comfortable with these usually either).  This should return a 'true' back to your Client Script.  I'll have to see if I have an example of that somewhere.

 

Name: ChangeCheck

Client callable:  true

var ChangeCheck = Class.create();
ChangeCheck.prototype = Object.extendsObject(AbstractAjaxProcessor, {
	
	getChangeRequests : function(){
		
		var chgreq = this.getParameter('sysparm_sys_id');


var gr = new GlideRecord('change_request');
gr.addQuery('cmdb_ci', chgreq);
gr.addQuery('active', true);
gr.query();
if (gr.hasNext()) {
	var rc = gr.getRowCount();
	return true;  
//gs.addErrorMessage("This CI has " + rc + " open Changes against it");
}
else {
return false;
}

},

type: 'ChangeCheck'
});

 

In your OnChange, probably something like this:

 

function onChange(control, oldValue, newValue, isLoading, isTemplate) {
	if (isLoading || newValue === '') {
		return;
	}
	
	var chgreq = g_form.getValue('sys_id');
	
var ga = new GlideAjax('ChangeCheck');
	ga.addParam('sysparm_name', 'getChangeRequests');
	ga.addParam('sysparm_sys_id', chgreq);
	ga.getXML(chgCallback);
	
	function chgCallback(response){
		var answer = response.responseXML.documentElement.getAttribute("answer");
		
		if (answer == true){
		alert("This CI has " + rc + " open Changes against it");
		}
	}
	
}

 

 Edited.

More Edits!  I think like 90% of the way there, though if you are running this via Client it may that you need to change from Sys ID to Number as sys_id may not be accessible?

Edit:  FYI:  This won't pull anything back for your count variable (rc)...  

William Busby
Tera Guru

The first decision you need to make is whether to develop in global or a scoped application. In nearly all cases the answer is to develop in a scoped application. Where as in the past I would have developed a script include called 'Functions' I now create a scoped application using the 'Start From Scratch' option that serves as a general bucket to hold script includes, business rules, etc. to support one or more scoped applications. Call the scoped app anything you like, even 'GlobalApp' or something more specific. You can't use 'Global' - it's a reserved word.

Within the scoped application you would create an application file of the type 'Script Include'. Here's your code as a script include within a scoped app:

find_real_file.png

If your script include needs to be accessed by applications outside of the application created you'll need to set the 'Accessible From' to 'All Applications Scopes'.

When you need to call your function you'll need to use the fully qualified name such as below:

var isCR = x_34484_globalapp.Functions().getCIChangeState(current.cmdb_ci);

If this is helpful or answers your question please mark it so.

Chuck Tomasi
Tera Patron

You're going to want to use a GlideAjax call from an onChange client script. I recommend watching some of the handy videos I've made on this topic in the past from this list. 

Client scripts - ep 5

Script includes - ep 6

GlideAjax - Ep 33

TechNow Episode List

Ian Mildon
Tera Guru

Things are a little clearer now (still pretty cloudy though!) but the main thing is that I do have a working script include and a working GlideAjax call. Plus the gr.getRowCount() does still work, so I can provide a "live" count in the alert box.

Here is the modified Script Include based off Shane J's example:

var ChangeCheck = Class.create();
ChangeCheck.prototype = Object.extendsObject(AbstractAjaxProcessor, {
	
	getChangeRequests : function(){
		
		var ciVal = this.getParameter('sysparm_ciVal');		
		
		var gr = new GlideRecord('change_request');
		gr.addQuery('cmdb_ci', ciVal);
		gr.addQuery('active', true);
		gr.query();
		if (gr.hasNext()) {
			var rc = gr.getRowCount();
			return "This CI has " + rc + " open Changes against it";
		}
		else {
			return "This CI has no open Changes against it.";
		}
	},
	
	type: 'ChangeCheck'
});

And here is the modified onChange Client Script (also based off Shane J's example):

function onChange(control, oldValue, newValue, isLoading, isTemplate) {
	if (isLoading || newValue === '') {
		return;
	}
	
	var ciVal = g_form.getValue('cmdb_ci');
	
	var ga = new GlideAjax('ChangeCheck');
	ga.addParam('sysparm_name', 'getChangeRequests');
	ga.addParam('sysparm_ciVal', ciVal);
	ga.getXML(chgCallback);
	
	function chgCallback(response){
		var answer = response.responseXML.documentElement.getAttribute("answer");
		
		alert(answer);
	}

Currently this is working and I have only found 1 issue so far. I found that I had to provide an alert message for the "else" part of the Script Include, otherwise I was getting an alert popup with "null" as the value.