Get the Approver of a RITM populated into a Catalog Item variable

Basim Zaidi
Mega Expert

Hi Community,

I am trying to populate a variable on a Catalog Item with the Approver of a RITM that is being selected via another variable.  When selecting the RITM via the 'Request Item' variable (variable name is 'request_item' and variable is a reference to sysapproval_approver table), I would like the 'Current approver' variable (variable name is 'current_approver') to be populated with the Approver of the associated request item approval record.

find_real_file.png

I can do this via the following Catalog Client Script, however this does not work on the Service Portal.

function onChange(control, oldValue, newValue, isLoading) {
   if (isLoading || newValue == '') {
      return;
   }
	
	var gr = g_form.getReference('request_item');
	
	g_form.setValue('current_approver', gr.approver);
}

I therefore believe that I need a Script Include and call this in the Catalog Client Script, however I am struggling to get this to work!

Any help would be greatly appreciated!

Thanks,

Bas

1 ACCEPTED SOLUTION

Okay worked out the issue.

Your reference variable "request_item" is on the sysapproval_approver table rather than the sc_req_item table that my script was expecting.

In your scenario there will only be ever one approver returned as a single approver is only ever assigned to each sysapproval_approver record.

Set up your "request_item" variable conditions and attributes as follows:

Conditions (restrict results to sc_req_item table and only show approvals that have been "Requested")

find_real_file.png

Attributes (show the approver column when searching)

find_real_file.png

It would also be worthwhile adding the approver to the list layout of the search list.

Select search icon >> List Layout >> Select Approver column to move to right >> Save

find_real_file.png

find_real_file.png

find_real_file.png

The approver will now show in the list view along with the approval for reference.

In this scenario I would question why you still need to populate the approvers name into a separate variable?

However, if you do need this then the following code should work for you:

Client Script:

NOTE: Your scenario does not actually need an array but I've left the logic in the script encase your use case changes. 

function onChange(control, oldValue, newValue, isLoading) {
	if (isLoading) {}

	if (newValue != '') {
		if (newValue != oldValue) {
			var ga = new GlideAjax("ApprovalAJAXUtils");
			ga.addParam("sysparm_name", "ritmApproversHandler");
			ga.addParam("sysparm_approvalSysId", newValue);
			ga.getXMLAnswer(processAnswer);
		}
	}
	else
		g_form.clearValue("current_approver");

	function processAnswer(answer) {
		if (answer) {
			var approversInfo = JSON.parse(answer);
			var approvers = "";

			for (var i=0; i< approversInfo.length; i++) {
				if (i === 0) {
					approvers = approversInfo[i].display_value;
				}
				else
					approvers += ", " + approversInfo[i].display_value;
			}
			g_form.setValue("current_approver",approvers);
		}
	}
}

Script Include:

var ApprovalAJAXUtils = Class.create();
ApprovalAJAXUtils.prototype = Object.extendsObject(AbstractAjaxProcessor, {

	ritmApproversHandler : function() {
		var approvalSysId = this.getParameter("sysparm_approvalSysId");
		answer = this.getApprovers(approvalSysId); //call getApprovers to return an array off approvers
		
		return JSON.stringify(answer);
	},

	getApprovers : function(input) {
		var gr = new GlideRecord("sysapproval_approver");

		var approvers = []; //set an array to hold the results

		if (gr.get(input)) {
			//add desired attributes to the object
			var approver = {
				value : gr.approver.getValue(), //sys_id of user
				display_value: gr.approver.getDisplayValue(), //display value for approver i.e. readable name
				email: gr.approver.email.getValue() //email addrees or whatever else you want to return
			};
			approvers.push(approver); //push object to array.
		}
		
		return approvers;
	},

	type: 'ApprovalAJAXUtils'
});

Hopefully this works for you.

Brent

P.S. If my suggestion helped then please mark as helpful and/or correct so other community members can benefit from this information.

View solution in original post

15 REPLIES 15

Brent Sutton
Mega Sage

How do you intend to handle multiple approvers or is this never the case with catalog items?

Hi Brent, Thanks for your response. You raise a good point regarding multiple approvers. For this particular purpose there would be only one approver (approval record) for the catalog item. However if you know of a solution that could return all approvers (from associated approval records) to comma separated string values, that would certainly satisfy any future requirement!

Any ideas (for either one ritm to one approval or one ritm to many approvals)?

Hi Basim,

You'll need to set up a client script (client side) and script include (server side) to return the approvers:

Script Include (Client Callable):

Configuration

find_real_file.png

Code

var ApprovalAJXUtils = Class.create();
ApprovalAJXUtils.prototype = Object.extendsObject(AbstractAjaxProcessor, {

	ritmApproversHandler : function() {
		var ritmSysId = this.getParameter("sysparm_ritmSysId");
		var answer = {};
		answer = this.getApprovers(ritmSysId); //call getApprovers to return an array off approvers
		
		return JSON.stringify(answer);
	},

	getApprovers : function(input) {
		var gr = new GlideRecord("sysapproval_approver");
		gr.addQuery("sysapproval", input);
		gr.addQuery("state","requested"); //only return approvals that have been requested
		gr.query();

		var approvers = []; //set an array to hold the results

		while (gr.next()) {
			//cycle through results and add desired attributes to the object
			var approver = {
				value : gr.approver.getValue(), //sys_id of user
				display_value: gr.approver.getDisplayValue(), //display value for approver i.e. readable name
				email: gr.approver.email.getValue() //email addrees or whatever else you want to return
			};
			approvers.push(approver); //push object to array.
		}
		
		return approvers;
	},

	type: 'ApprovalAJXUtils'
});

Client Script (onChange):

Configuration

find_real_file.png

Code

function onChange(control, oldValue, newValue, isLoading) {
	if (isLoading) {}

	if (newValue != '') {
		if (newValue != oldValue) {
			var ga = new GlideAjax("ApprovalAJXUtils");
			ga.addParam("sysparm_name", "ritmApproversHandler");
			ga.addParam("sysparm_ritmSysId", newValue);
			ga.getXMLAnswer(processAnswer);
		}
	}
	else
		g_form.clearValue("current_approver");

	function processAnswer(answer) {
		if (answer) {
			var approversInfo = JSON.parse(answer);
			var approvers = "";

			for (var i=0; i< approversInfo.length; i++) {
				if (i === 0) {
					approvers = approversInfo[i].display_value;
				}
				else
					approvers += ", " + approversInfo[i].display_value;
			}
			g_form.setValue("current_approver",approvers);
		}
	}
}

The example will populate a string variable with a comma separated list of the names of outstanding approval requests. This is just an example to show you how to access the values held in each object. You could for example use approversInfo[i].email to access the email key within the object.

Let me know if this worked for you.

Brent

P.S. If my suggestion helped then please mark as helpful and/or correct so other community members can benefit from this information.

Hi Brent,

Thanks for this - I owe you a beer or two!

I think we're getting closer but not quite there. Not sure why this is coming back 'Undefined' or whether the values are being added to the array? Any ideas?

find_real_file.png

Thanks,

Bas