Find your people. Pick a challenge. Ship something real. The CreatorCon Hackathon is coming to the Community Pavilion for one epic night. Every skill level, every role welcome. Join us on May 5th and learn more here.

Approval Info widget - record rejection comments

Keith Morgan2
Mega Contributor

Hello all,

I have cloned the 'Approval Info' Service Portal widget, and added this line to the HTML to get my comments box 

<textarea ng-if="c.data.isMine && (c.data.state == 'requested')" ng-model="c.data.comment" style="color: grey; width: 100%; margin-top: .5em;" placeholder="Comments are mandatory for a rejection" class="form-control" rows="5"></textarea>

I have updated my client script to check that this new text box has been completed, for rejections only 

function ($scope, spUIActionsExecuter, spUtil) {
	var c = this;
	
	var ESIGNATURE = {
		"approved": "cbfe291147220100ba13a5554ee4904d",
		"rejected": "580f711147220100ba13a5554ee4904b"
	};
	
	spUtil.recordWatch($scope, "sysapproval_approver", "state=requested^sys_id="+ c.data.sys_id);

	c.action = function(state) {

	if ((c.data.comment == '' || c.data.comment== undefined) && state == 'rejected'){
		window.alert("Please add some rejection comments.")
		return false; }

		//reloading window after ui action location.reload(); //here
		
		if(c.data.esignature.e_sig_required) {
			var requestParams = {
				username: c.data.esignature.username,
				userSysId: c.data.esignature.userSysId
			};
			spUIActionsExecuter.executeFormAction(ESIGNATURE[state], "sysapproval_approver" , c.data.sys_id, [] , "", requestParams).then(function(response) {
			});
		} else {
			c.data.op = state;
			c.data.state = state;
			c.server.update();
		}
	}	
}

However, I can't work out how to get the rejection comment to be recorded to the relevant table. At the minute, it just vanishes into the ether. 

Can anyone assist?

Thanks, in advance.

1 ACCEPTED SOLUTION

VigneshMC
Mega Sage

This is what we have to capture rejection comments and update it in approval record

HTML

<div ng-if="c.data.isValid" class="panel panel-{{::c.options.color}} b">
  <div class="panel-heading">
    <h4 class="panel-title" ng-if="c.data.isMine && (c.data.state == 'requested')">${This {{c.data.label}} requires your approval}</h4>
    <h4 class="panel-title" ng-if="!c.data.isMine && (c.data.state == 'requested')">${This {{c.data.label}} requires approval <span ng-if="c.data.approver"> by {{c.data.approver}}}</span></h4>
    <h4 class="panel-title" ng-if="c.data.state == 'approved'">${Approved} <sn-time-ago timestamp="::c.data.sys_updated_on" /></h4>
    <h4 class="panel-title" ng-if="c.data.state == 'rejected'">${Rejected} <sn-time-ago timestamp="::c.data.sys_updated_on" /></h4>
  </div>  
  <div class="panel-body">
    <form ng-submit="$event.preventDefault()" class="form-horizontal">
      <div ng-if="c.data.fields.length > 0">
        <div ng-repeat="field in c.data.fields" class="m-b-xs" ng-if="field.value">
          <label class="m-n">{{field.label}}</label>
          <span ng-switch="field.type">
            <div ng-switch-when="glide_date_time" title="{{field.display_value}}"><sn-time-ago timestamp="::field.value" /></div>
            <div ng-switch-default >{{field.display_value}}</div>
          </span>
        </div>
      </div>
      <div ng-if="c.data.isMine && (c.data.state == 'requested')" class="question">
        <button type="button" name="approve" class="btn btn-success btn-question" ng-click="c.action('approved')">${Approve}</button>
        <div class="spacer"></div>
        <button type="button" name="reject" class="btn btn-default btn-question" ng-click="c.action('rejected')">${Reject}</button>
      <textarea ng-model="c.data.comment" style="color: grey; width: 100%; margin-top: .5em;" placeholder="Rejection Comments" class="form-control" rows="5"></textarea>
      </div>
    </form>
  </div>  
</div>

Client script

function ($scope, $window) {
	var c = this;	
	
	c.action = function(state) {
		
		if( (c.data.comment ==  undefined || c.data.comment ==  '' )&& state == 'rejected'){
			$window.alert('Rejection Comments cannot be empty');
			return false;
		}

		c.data.op = state;
		c.data.state = state;
		c.server.update();		
	};	
}

Server

(function() {
	var gr = $sp.getRecord();
	if (gr == null || !gr.isValid()) {
		data.isValid = false;
		return;
	}
	data.isValid = true;
	//data.isMine = gr.getValue("approver") == gs.getUserID();
	//data.isMine = getMyApprovals().toString().indexOf(gr.getValue("approver") >= 0);
	data.isMine = (getMyApprovals().toString().indexOf(gr.getValue("approver")) >= 0);
	data.approvers = getMyApprovals();
	data.approval = gr.getValue("approver");
	if (!data.isMine && !gr.approver.nil())
		data.approver = gr.approver.getDisplayValue();
	if (input && input.op) { 
		gr.state = input.op;
		if (input.comment){
		gr.comments = input.comment;
		}
		gr.update();
	}
/*if (input.comment){
	gr.comments = input.comment;
	gr.update();
	
}*/
	var fields = $sp.getFields(gr, 'state,sys_created_on');

	if (gr.sys_mod_count > 0)
		fields.push($sp.getField(gr, 'sys_updated_on'));

	data.fields = fields;
	data.state = gr.state.toString();
	data.sys_updated_on = gr.sys_updated_on.toString();
	data.sys_id = gr.getUniqueValue();
	data.table = gr.getTableName();
	data.label = getRecordBeingApproved(gr).getLabel();

	function getRecordBeingApproved(gr) {
		if (!gr.sysapproval.nil())
			return gr.sysapproval.getRefRecord();

		return gr.document_id.getRefRecord();
	}
})();

Thanks

View solution in original post

6 REPLIES 6

VigneshMC
Mega Sage

This is what we have to capture rejection comments and update it in approval record

HTML

<div ng-if="c.data.isValid" class="panel panel-{{::c.options.color}} b">
  <div class="panel-heading">
    <h4 class="panel-title" ng-if="c.data.isMine && (c.data.state == 'requested')">${This {{c.data.label}} requires your approval}</h4>
    <h4 class="panel-title" ng-if="!c.data.isMine && (c.data.state == 'requested')">${This {{c.data.label}} requires approval <span ng-if="c.data.approver"> by {{c.data.approver}}}</span></h4>
    <h4 class="panel-title" ng-if="c.data.state == 'approved'">${Approved} <sn-time-ago timestamp="::c.data.sys_updated_on" /></h4>
    <h4 class="panel-title" ng-if="c.data.state == 'rejected'">${Rejected} <sn-time-ago timestamp="::c.data.sys_updated_on" /></h4>
  </div>  
  <div class="panel-body">
    <form ng-submit="$event.preventDefault()" class="form-horizontal">
      <div ng-if="c.data.fields.length > 0">
        <div ng-repeat="field in c.data.fields" class="m-b-xs" ng-if="field.value">
          <label class="m-n">{{field.label}}</label>
          <span ng-switch="field.type">
            <div ng-switch-when="glide_date_time" title="{{field.display_value}}"><sn-time-ago timestamp="::field.value" /></div>
            <div ng-switch-default >{{field.display_value}}</div>
          </span>
        </div>
      </div>
      <div ng-if="c.data.isMine && (c.data.state == 'requested')" class="question">
        <button type="button" name="approve" class="btn btn-success btn-question" ng-click="c.action('approved')">${Approve}</button>
        <div class="spacer"></div>
        <button type="button" name="reject" class="btn btn-default btn-question" ng-click="c.action('rejected')">${Reject}</button>
      <textarea ng-model="c.data.comment" style="color: grey; width: 100%; margin-top: .5em;" placeholder="Rejection Comments" class="form-control" rows="5"></textarea>
      </div>
    </form>
  </div>  
</div>

Client script

function ($scope, $window) {
	var c = this;	
	
	c.action = function(state) {
		
		if( (c.data.comment ==  undefined || c.data.comment ==  '' )&& state == 'rejected'){
			$window.alert('Rejection Comments cannot be empty');
			return false;
		}

		c.data.op = state;
		c.data.state = state;
		c.server.update();		
	};	
}

Server

(function() {
	var gr = $sp.getRecord();
	if (gr == null || !gr.isValid()) {
		data.isValid = false;
		return;
	}
	data.isValid = true;
	//data.isMine = gr.getValue("approver") == gs.getUserID();
	//data.isMine = getMyApprovals().toString().indexOf(gr.getValue("approver") >= 0);
	data.isMine = (getMyApprovals().toString().indexOf(gr.getValue("approver")) >= 0);
	data.approvers = getMyApprovals();
	data.approval = gr.getValue("approver");
	if (!data.isMine && !gr.approver.nil())
		data.approver = gr.approver.getDisplayValue();
	if (input && input.op) { 
		gr.state = input.op;
		if (input.comment){
		gr.comments = input.comment;
		}
		gr.update();
	}
/*if (input.comment){
	gr.comments = input.comment;
	gr.update();
	
}*/
	var fields = $sp.getFields(gr, 'state,sys_created_on');

	if (gr.sys_mod_count > 0)
		fields.push($sp.getField(gr, 'sys_updated_on'));

	data.fields = fields;
	data.state = gr.state.toString();
	data.sys_updated_on = gr.sys_updated_on.toString();
	data.sys_id = gr.getUniqueValue();
	data.table = gr.getTableName();
	data.label = getRecordBeingApproved(gr).getLabel();

	function getRecordBeingApproved(gr) {
		if (!gr.sysapproval.nil())
			return gr.sysapproval.getRefRecord();

		return gr.document_id.getRefRecord();
	}
})();

Thanks

Thanks, that was perfect

Hello Vignesh,

Which widget did you clone and update?  I am having difficulty getting this to work.

I started with same solution as the original post and had the same issue.

What we need is to have rejection comments captured when approving from My Approvals:

find_real_file.png

And also when rejecting from Approval form:

find_real_file.png

Can you help me?

Thank you,

Laurie

So the above code is for your second picture. I ended up using a popup modal because I needed the comments on the approvals and the approvals info widgets. You only have to change the client script. I believe there was another question on this website where they added the modal to the my approvals widget.

 

Client Script of the Approval Info widget: The added code is bellow the //rejection comment

function ($scope, spUIActionsExecuter, spUtil, spModal) {
	var c = this;

	var ESIGNATURE = {
		"approved": "cbfe291147220100ba13a5554ee4904d",
		"rejected": "580f711147220100ba13a5554ee4904b"
	};

	spUtil.recordWatch($scope, "sysapproval_approver", "state=requested^sys_id="+ c.data.sys_id);
	//spUtil.recordWatch($scope, "sysapproval_approver", "state=requested^approverIN" + $scope.data.myApprovals.toString(), function(response) {});
	
	c.action = function(state) {
		if(c.data.esignature.e_sig_required) {
			var requestParams = {
				username: c.data.esignature.username,
				userSysId: c.data.esignature.userSysId
			};
			spUIActionsExecuter.executeFormAction(ESIGNATURE[state], "sysapproval_approver" , c.data.sys_id, [] , "", requestParams).then(function(response) {
			});
		} else {	
			if (state == "rejected") {
				//rejection button modal popup for comments
				spModal.prompt("Please enter your reason for rejection, note this will be communicated with the requestor").then(function(newComments) {
					c.data.comments = newComments;
					c.data.op = state;
					c.server.update().then(function() {
						if (!c.data.updateID) // update failed
							spUtil.addErrorMessage(c.data.actionPreventedMsg);
						else
							c.data.state = state;
					});
				});
			}
			else 
			{
				c.data.op = state;
				c.server.update().then(function() {
					if (!c.data.updateID) // update failed
						spUtil.addErrorMessage(c.data.actionPreventedMsg);
					else
						c.data.state = state;
				});
			}
		}
	}	
}