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.

Make comment mandatory when rejecting an approval on service portal

Gab
Tera Expert

We have a requirement to make the comment mandatory when rejecting an approval in Service Portal. I've already see Portal diaries: Service Portal — Making Rejection Comments Mandatory on Approval Record this thread but the problem is I don't know how to apply this on a Scope Application and also the comment is being duplicated.

How do you require a comment whenever these buttons below are clicked?

find_real_file.png

 

find_real_file.png

I'm using Rome version

1 ACCEPTED SOLUTION

Service_RNow
Mega Sage

Please Try this below code:

Client Controller:

function ($scope, spUtil, spUIActionsExecuter, spModal) {
	var ESIGNATURE = {
		TYPE: "form",
		APPROVE_SYS: "cbfe291147220100ba13a5554ee4904d",
		REJECT_SYS: "580f711147220100ba13a5554ee4904b"
	};

	if ($scope.options.portal == true || $scope.options.portal == 'true') {
		$scope.contentColClass = "col-xs-12";
		$scope.options.portal = true;
	} else {
		$scope.options.portal = false;
		$scope.contentColClass = "col-sm-8";
	}

	$scope.data.op = "";
	spUtil.recordWatch($scope, "sysapproval_approver", "state=requested^approverIN" + $scope.data.myApprovals.toString(), function(data) {
		// don't double-roundtrip if update came from record just approved/rejected
		if (data.data.sys_id != $scope.data.target)
			spUtil.update($scope);
	});

	function get() {
		spUtil.update($scope);
	}

	$scope.approve = function(id, esigRequired) {
		var requestParams = {
			username: $scope.data.esignature.username,
			userSysId: $scope.data.esignature.userSysId
		};

		if($scope.data.esignature.e_sig_required && esigRequired) {
			spUIActionsExecuter.executeFormAction(ESIGNATURE.APPROVE_SYS, "sysapproval_approver" , id, [] , "", requestParams).then(function(response) {
			});			
		} else {
			$scope.data.op = "approved";
			$scope.data.target = id;
			get();
		}
	}

	$scope.reject = function(id, esigRequired) {

		spModal.open({
			title: 'Reject Approval',
			message: 'Provide a reason for rejecting this approval',
			input: true,
			value: $scope.name
		}).then(function(name) {
			$scope.name = name;

			var requestParams = {
				username: $scope.data.esignature.username,
				userSysId: $scope.data.esignature.userSysId
			};

			if($scope.data.esignature.e_sig_required && esigRequired) {
				spUIActionsExecuter.executeFormAction(ESIGNATURE.REJECT_SYS, "sysapproval_approver" , id, [] , "", requestParams).then(function(response) {
				});
			} else {
				$scope.data.op = "rejected";
				$scope.data.target = id;
				$scope.data.reject_comment = "Rejection reason: " + $scope.name;
				get();
			}
		});
	};

	// pagination
	$scope.previousPage = function() {
		if ($scope.data.pagination.currentPage > 1)
			$scope.data.pagination.currentPage = $scope.data.pagination.currentPage - 1;
		else
			$scope.data.pagination.currentPage = 0;

		get();
	}

	$scope.nextPage = function() {
		$scope.data.pagination.currentPage = $scope.data.pagination.currentPage+1;
		get();
	}

	$scope.getItemDisplay = function(task) {
		if (task.number && task.short_description)
			return task.number + " - " + task.short_description;

		return task.number || task.short_description || "";
	}
}

 

Server Side:

 

g_approval_form_request = true;

//we get only a max number of elements to avoid to have a big list of it
var maxNumberOfItemsInTheList = parseInt(options.max_number_of_elements_shown_on_the_list);
//set 10 if maxnumber is undefined, empty or negative value
maxNumberOfItemsInTheList = maxNumberOfItemsInTheList>0 ? maxNumberOfItemsInTheList : 10; 
var initRow = 0;
var lastRow = maxNumberOfItemsInTheList;
var currentPage = 0; //0 is the first page
if (input) {
	// update pagination
	currentPage = input.pagination.currentPage;
	initRow = (currentPage * maxNumberOfItemsInTheList);
	lastRow = initRow + maxNumberOfItemsInTheList;

	if (input.op == 'approved' || input.op == 'rejected') {
		var app = new GlideRecord("sysapproval_approver");
		if (app.get(input.target)) {
			app.state = input.op;
			if(input.op == 'rejected'){
				app.comments = input.reject_comment;
			}

			app.update();

		}
	}
}

data.ViewApprovalPageMsg = gs.getMessage("View approval page");
data.esignature = {
	username:  gs.getUserName(),
	userSysId: gs.getUserID(),
	e_sig_required: GlidePluginManager.isRegistered('com.glide.e_signature_approvals')
};

var esigRequiredMap = {};
if (data.esignature.e_sig_required) {
	var esigRegistryGR = new GlideRecord("e_signature_registry");
	esigRegistryGR.addQuery("enabled", "true");
	esigRegistryGR.query();
	while(esigRegistryGR.next()) {
		esigRequiredMap[esigRegistryGR.getValue("table_name")] = true;
	}
}

var gr = new GlideRecord('sysapproval_approver');
gr.chooseWindow(initRow, lastRow);
var qc1 = gr.addQuery("state", "requested");
//if (input)
//  qc1.addOrCondition("sys_id", "IN", input.ids);
data.myApprovals = getMyApprovals();
gr.addQuery("approver", data.myApprovals);
gr.orderBy("sys_created_on");
gr.query();
var rowCount = gr.getRowCount();
var approvals = [];
var ids = [];
var source_tables = [];

while (gr.next()) {
	var task = getRecordBeingApproved(gr);
	if (!task.isValidRecord())
		continue;

	ids.push(gr.getUniqueValue());
	var t = {};
	t.number = task.getDisplayValue();
	t.short_description = task.short_description.toString();
	if (gr.getValue("approver") != gs.getUserID())
		t.approver = gr.approver.getDisplayValue();
	if (task.isValidField("opened_by") && !task.opened_by.nil())
		t.opened_by = task.opened_by.getDisplayValue();

	// requestor >> opener
	if (task.isValidField("requested_by") && !task.requested_by.nil())
		t.opened_by = task.requested_by.getDisplayValue();

	t.start_date = task.start_date.getDisplayValue();
	t.end_date = task.end_date.getDisplayValue();
	t.quantity = task.quantity.getDisplayValue();
	t.table = task.getLabel();
	if (task.getValue("price") > 0)
		t.price = task.getDisplayValue("price");

	if (task.getValue("recurring_price") > 0)
		t.recurring_price = task.getDisplayValue("recurring_price");

	t.recurring_frequency = task.getDisplayValue("recurring_frequency");

	var items = [];
	var idx = 0;
	var itemsGR = new GlideRecord("sc_req_item");
	itemsGR.addQuery("request", task.sys_id);
	itemsGR.query();
	if (itemsGR.getRowCount() > 1)
		t.short_description = itemsGR.getRowCount() + " requested items";

	while (itemsGR.next()) {
		var item = {};
		item.short_description = itemsGR.short_description.toString();
		if (itemsGR.getValue("price") > 0)
			item.price = itemsGR.getDisplayValue("price");
		if (itemsGR.getValue("recurring_price") > 0) {
			item.recurring_price = itemsGR.getDisplayValue("recurring_price");
			item.recurring_frequency = itemsGR.getDisplayValue("recurring_frequency");
		}
		if (itemsGR.getRowCount() == 1) {
			item.variables = new GlobalServiceCatalogUtil().getVariablesForTask(itemsGR, true);
			item.variableSummarizerWidget = $sp.getWidget('sc-variable-summarizer', {'variables' : item.variables, 'toggle' : false, 'task' :t.number });
			t.short_description = itemsGR.short_description.toString();
		}

		items[idx] = item;
		idx++;
	}

	var j = {};
	j.sys_id = gr.getUniqueValue();
	j.table = gr.getRecordClassName();
	j.approval_source_table = gr.getValue("source_table");
	if (!j.approval_source_table)
		j.approval_source_table = gr.sysapproval.sys_class_name + "";
	j.requireEsigApproval = esigRequiredMap[j.approval_source_table];
	j.task = t;
	if (task) {
		j.variables = new GlobalServiceCatalogUtil().getVariablesForTask(task, true);
		j.variableSummarizerWidget = $sp.getWidget('sc-variable-summarizer', {'variables' : j.variables, 'toggle' : false, 'task': t.number });
	}
	j.items = items;
	j.state = gr.getValue("state");
	j.stateLabel = gr.state.getDisplayValue();
	approvals.push(j);
}

data.ids = ids;
data.approvals = approvals;
data.showApprovals = gs.getUser().hasRole('approver_user');
// for pagination
data.pagination = {};
data.pagination.hasNext = (approvals.length == (parseInt(lastRow) - parseInt(initRow)) && lastRow < rowCount);
data.pagination.hasPrevious = parseInt(initRow) > 0;
data.pagination.from = parseInt(initRow + 1);
data.pagination.to = parseInt(lastRow) < parseInt(rowCount) ? parseInt(lastRow) : parseInt(rowCount);
data.pagination.of = parseInt(rowCount);
data.pagination.showPagination = data.pagination.hasPrevious || data.pagination.hasNext;
data.pagination.currentPage = data.pagination.from > data.pagination.to ? currentPage -1 : currentPage;
delete g_approval_form_request;
function getRecordBeingApproved(gr) {
	if (!gr.sysapproval.nil())
		return gr.sysapproval.getRefRecord();

	return gr.document_id.getRefRecord();
}


 

 

Adding xml of the widget which i have tried on my personal instance and working fine. 

 

Quick Demo:

 

find_real_file.png

 

If my answer helped you, kindly mark it as correct and helpful.

View solution in original post

16 REPLIES 16

Service_RNow
Mega Sage

Please Try this below code:

Client Controller:

function ($scope, spUtil, spUIActionsExecuter, spModal) {
	var ESIGNATURE = {
		TYPE: "form",
		APPROVE_SYS: "cbfe291147220100ba13a5554ee4904d",
		REJECT_SYS: "580f711147220100ba13a5554ee4904b"
	};

	if ($scope.options.portal == true || $scope.options.portal == 'true') {
		$scope.contentColClass = "col-xs-12";
		$scope.options.portal = true;
	} else {
		$scope.options.portal = false;
		$scope.contentColClass = "col-sm-8";
	}

	$scope.data.op = "";
	spUtil.recordWatch($scope, "sysapproval_approver", "state=requested^approverIN" + $scope.data.myApprovals.toString(), function(data) {
		// don't double-roundtrip if update came from record just approved/rejected
		if (data.data.sys_id != $scope.data.target)
			spUtil.update($scope);
	});

	function get() {
		spUtil.update($scope);
	}

	$scope.approve = function(id, esigRequired) {
		var requestParams = {
			username: $scope.data.esignature.username,
			userSysId: $scope.data.esignature.userSysId
		};

		if($scope.data.esignature.e_sig_required && esigRequired) {
			spUIActionsExecuter.executeFormAction(ESIGNATURE.APPROVE_SYS, "sysapproval_approver" , id, [] , "", requestParams).then(function(response) {
			});			
		} else {
			$scope.data.op = "approved";
			$scope.data.target = id;
			get();
		}
	}

	$scope.reject = function(id, esigRequired) {

		spModal.open({
			title: 'Reject Approval',
			message: 'Provide a reason for rejecting this approval',
			input: true,
			value: $scope.name
		}).then(function(name) {
			$scope.name = name;

			var requestParams = {
				username: $scope.data.esignature.username,
				userSysId: $scope.data.esignature.userSysId
			};

			if($scope.data.esignature.e_sig_required && esigRequired) {
				spUIActionsExecuter.executeFormAction(ESIGNATURE.REJECT_SYS, "sysapproval_approver" , id, [] , "", requestParams).then(function(response) {
				});
			} else {
				$scope.data.op = "rejected";
				$scope.data.target = id;
				$scope.data.reject_comment = "Rejection reason: " + $scope.name;
				get();
			}
		});
	};

	// pagination
	$scope.previousPage = function() {
		if ($scope.data.pagination.currentPage > 1)
			$scope.data.pagination.currentPage = $scope.data.pagination.currentPage - 1;
		else
			$scope.data.pagination.currentPage = 0;

		get();
	}

	$scope.nextPage = function() {
		$scope.data.pagination.currentPage = $scope.data.pagination.currentPage+1;
		get();
	}

	$scope.getItemDisplay = function(task) {
		if (task.number && task.short_description)
			return task.number + " - " + task.short_description;

		return task.number || task.short_description || "";
	}
}

 

Server Side:

 

g_approval_form_request = true;

//we get only a max number of elements to avoid to have a big list of it
var maxNumberOfItemsInTheList = parseInt(options.max_number_of_elements_shown_on_the_list);
//set 10 if maxnumber is undefined, empty or negative value
maxNumberOfItemsInTheList = maxNumberOfItemsInTheList>0 ? maxNumberOfItemsInTheList : 10; 
var initRow = 0;
var lastRow = maxNumberOfItemsInTheList;
var currentPage = 0; //0 is the first page
if (input) {
	// update pagination
	currentPage = input.pagination.currentPage;
	initRow = (currentPage * maxNumberOfItemsInTheList);
	lastRow = initRow + maxNumberOfItemsInTheList;

	if (input.op == 'approved' || input.op == 'rejected') {
		var app = new GlideRecord("sysapproval_approver");
		if (app.get(input.target)) {
			app.state = input.op;
			if(input.op == 'rejected'){
				app.comments = input.reject_comment;
			}

			app.update();

		}
	}
}

data.ViewApprovalPageMsg = gs.getMessage("View approval page");
data.esignature = {
	username:  gs.getUserName(),
	userSysId: gs.getUserID(),
	e_sig_required: GlidePluginManager.isRegistered('com.glide.e_signature_approvals')
};

var esigRequiredMap = {};
if (data.esignature.e_sig_required) {
	var esigRegistryGR = new GlideRecord("e_signature_registry");
	esigRegistryGR.addQuery("enabled", "true");
	esigRegistryGR.query();
	while(esigRegistryGR.next()) {
		esigRequiredMap[esigRegistryGR.getValue("table_name")] = true;
	}
}

var gr = new GlideRecord('sysapproval_approver');
gr.chooseWindow(initRow, lastRow);
var qc1 = gr.addQuery("state", "requested");
//if (input)
//  qc1.addOrCondition("sys_id", "IN", input.ids);
data.myApprovals = getMyApprovals();
gr.addQuery("approver", data.myApprovals);
gr.orderBy("sys_created_on");
gr.query();
var rowCount = gr.getRowCount();
var approvals = [];
var ids = [];
var source_tables = [];

while (gr.next()) {
	var task = getRecordBeingApproved(gr);
	if (!task.isValidRecord())
		continue;

	ids.push(gr.getUniqueValue());
	var t = {};
	t.number = task.getDisplayValue();
	t.short_description = task.short_description.toString();
	if (gr.getValue("approver") != gs.getUserID())
		t.approver = gr.approver.getDisplayValue();
	if (task.isValidField("opened_by") && !task.opened_by.nil())
		t.opened_by = task.opened_by.getDisplayValue();

	// requestor >> opener
	if (task.isValidField("requested_by") && !task.requested_by.nil())
		t.opened_by = task.requested_by.getDisplayValue();

	t.start_date = task.start_date.getDisplayValue();
	t.end_date = task.end_date.getDisplayValue();
	t.quantity = task.quantity.getDisplayValue();
	t.table = task.getLabel();
	if (task.getValue("price") > 0)
		t.price = task.getDisplayValue("price");

	if (task.getValue("recurring_price") > 0)
		t.recurring_price = task.getDisplayValue("recurring_price");

	t.recurring_frequency = task.getDisplayValue("recurring_frequency");

	var items = [];
	var idx = 0;
	var itemsGR = new GlideRecord("sc_req_item");
	itemsGR.addQuery("request", task.sys_id);
	itemsGR.query();
	if (itemsGR.getRowCount() > 1)
		t.short_description = itemsGR.getRowCount() + " requested items";

	while (itemsGR.next()) {
		var item = {};
		item.short_description = itemsGR.short_description.toString();
		if (itemsGR.getValue("price") > 0)
			item.price = itemsGR.getDisplayValue("price");
		if (itemsGR.getValue("recurring_price") > 0) {
			item.recurring_price = itemsGR.getDisplayValue("recurring_price");
			item.recurring_frequency = itemsGR.getDisplayValue("recurring_frequency");
		}
		if (itemsGR.getRowCount() == 1) {
			item.variables = new GlobalServiceCatalogUtil().getVariablesForTask(itemsGR, true);
			item.variableSummarizerWidget = $sp.getWidget('sc-variable-summarizer', {'variables' : item.variables, 'toggle' : false, 'task' :t.number });
			t.short_description = itemsGR.short_description.toString();
		}

		items[idx] = item;
		idx++;
	}

	var j = {};
	j.sys_id = gr.getUniqueValue();
	j.table = gr.getRecordClassName();
	j.approval_source_table = gr.getValue("source_table");
	if (!j.approval_source_table)
		j.approval_source_table = gr.sysapproval.sys_class_name + "";
	j.requireEsigApproval = esigRequiredMap[j.approval_source_table];
	j.task = t;
	if (task) {
		j.variables = new GlobalServiceCatalogUtil().getVariablesForTask(task, true);
		j.variableSummarizerWidget = $sp.getWidget('sc-variable-summarizer', {'variables' : j.variables, 'toggle' : false, 'task': t.number });
	}
	j.items = items;
	j.state = gr.getValue("state");
	j.stateLabel = gr.state.getDisplayValue();
	approvals.push(j);
}

data.ids = ids;
data.approvals = approvals;
data.showApprovals = gs.getUser().hasRole('approver_user');
// for pagination
data.pagination = {};
data.pagination.hasNext = (approvals.length == (parseInt(lastRow) - parseInt(initRow)) && lastRow < rowCount);
data.pagination.hasPrevious = parseInt(initRow) > 0;
data.pagination.from = parseInt(initRow + 1);
data.pagination.to = parseInt(lastRow) < parseInt(rowCount) ? parseInt(lastRow) : parseInt(rowCount);
data.pagination.of = parseInt(rowCount);
data.pagination.showPagination = data.pagination.hasPrevious || data.pagination.hasNext;
data.pagination.currentPage = data.pagination.from > data.pagination.to ? currentPage -1 : currentPage;
delete g_approval_form_request;
function getRecordBeingApproved(gr) {
	if (!gr.sysapproval.nil())
		return gr.sysapproval.getRefRecord();

	return gr.document_id.getRefRecord();
}


 

 

Adding xml of the widget which i have tried on my personal instance and working fine. 

 

Quick Demo:

 

find_real_file.png

 

If my answer helped you, kindly mark it as correct and helpful.

@Service_RNow How to configure the same alert  for "approval info" widget.

hi.PNG