Approval widgets saving comments twice

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-22-2019 02:45 AM
Hello,
I've updated the Approval Info widget and added a comment field, but when I add a comment and reject or accept a particular approval request, the comments are updated twice. I checked for UI Action, Client Script and others but cant find a solution.
Any suggestion would be appreciated.
- Labels:
-
Service Portal Development

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-22-2019 03:37 AM
did you try to put some log in the script? and see where exactly it has stopped . log would be help you to troubleshoot this issue.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-22-2019 03:39 AM
can you share the complete widget code?, Also did you check that whether comments aren't duplicating if you add them using normal UI, could be some BR doing that as well.
Thanks

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-22-2019 05:02 AM
Hi
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="Comments" class="form-control" rows="5"></textarea>
</div>
</form>
</div>
</div>
Server Script
(function() {
var gr = $sp.getRecord();
if (gr == null || !gr.isValid()) {
data.isValid = false;
return;
}
data.isValid = true;
data.isMine = gr.getValue("approver") == gs.getUserID();
if (!data.isMine && !gr.approver.nil())
data.approver = gr.approver.getDisplayValue();
if (input && input.op) {
gr.state = input.op;
gr.comments = input.comment; //Code to take input comment- different from OOB
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();
data.esignature = {
username: gs.getUserName(),
userSysId: gs.getUserID(),
e_sig_required: checkESig(gr.getValue("source_table"))
};
function checkESig(table) {
var esigRegistryGR = new GlideRecord("e_signature_registry");
if (!esigRegistryGR.isValid())
return false;
esigRegistryGR.addQuery("enabled", "true");
esigRegistryGR.addQuery("table_name", table);
esigRegistryGR.query();
return esigRegistryGR.hasNext();
}
function getRecordBeingApproved(gr) {
if (!gr.sysapproval.nil())
return gr.sysapproval.getRefRecord();
return gr.document_id.getRefRecord();
}
})();
Client Controller
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.esignature.e_sig_required) {
var requestParams = {
username: c.data.esignature.username,
userSysId: c.data.esignature.userSysId
};
c.data.comment = "TEST"; //code to
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();
}
}
}
I checked all BR, CS, UI Action, couldnt find anything.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-22-2019 05:55 AM
I couldn't see buttons from your widget, but never mind. This is the widget which I use, which also does the same thing. Check and let me if that helps
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>
css
.question {
text-align: center;
margin-top: 1em;
}
.spacer {
display:inline-block;
width:5%;
}
.btn-question {
width: 45%;
}
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();
}
})();
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
10-29-2019 05:18 AM
Hi,
Did you had a chance to solve it? I am facing the same issue, when the approver is saving comments in SP, system is populating the comments twice every time.
I checked that when I am performing such action from the backend perspective (and saving approval comments), system is not creating duplicates, so the issue is somewhere in the "Approval info" widget most probably.
I've used solution from below link, but still the issue persist.
Thanks