Service Portal:OOB Approval widget

gomathyshankar
Tera Contributor

Hi,

How to add the comments field in the OOB Approval widget and make it mandatory when the approvers rejects it.

1 ACCEPTED SOLUTION

Hi Selva,



Use the below and it wil work ( we have to change both client and server to update user comments in approval table)



Highlighted are the changes



Client controller:


function ($scope, spUtil, snRecordWatcher,spModal) {



  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-9";


  }




  $scope.data.op = "";


  snRecordWatcher.initList("sysapproval_approver", "state=requested^approver=" + window.NOW.user_id);




  function get() {


      spUtil.update($scope);


  }




  $scope.$on('record.updated', function(name, data) {


  get();


  })




  $scope.approve = function(id) {


      $scope.data.op = "approved";


      $scope.data.target = id;


      get();


  }




  $scope.reject = function(id) {


    c.onPrompt(id);


  }


c.onPrompt = function(id) {  


                spModal.open({  


                      title: 'Give me a comment',  


                      message: 'Your comment please?',  


                      input: true,  


                      value: c.comment  


              }).then(function(comment) {  


                      c.comment = comment;  


  if(comment)


  {


                      $scope.data.comment = comment;  


  $scope.data.op = "rejected";


  $scope.data.target = id;


  get();


  }


              })  


      }


}



Server side:


Replace


if (input && input.op) {


  var app = new GlideRecord("sysapproval_approver");


  if (app.get(input.target)) {


      app.state = input.op;


      app.update();


  }



With



if (input && input.op) {



  if(input.op == 'approved')


  {


  var app = new GlideRecord("sysapproval_approver");


  if (app.get(input.target)) {


      app.state = input.op;


      app.update();


  }


  }


  else if(input.op == 'rejected' && input.comment)


  {


  var app = new GlideRecord("sysapproval_approver");


  if (app.get(input.target)) {


    app.comments = input.comment;


      app.state = input.op;


      app.update();


  }


  }




Thanks and regards


Swamy


View solution in original post

38 REPLIES 38

Hi Karthik,



Please use this below mentioned code,



HTML:


<div class="panel panel-{{::options.color}} b">


  <div class="panel-heading">


      <h4 class="panel-title"><fa ng-if="::options.glyph.length" name="{{::options.glyph}}" class="m-r-sm" />${My Approvals}</h4>


      <p style="float:right;margin-top:-10px">


          <!-- <a ng-click="changeSort('name')" style="cursor:pointer;">Sort By: item<span class="fa fa-caret-up fa-lg" style="display:none;"></span><span class="fa fa-caret-down fa-lg" style="display:none;"></span></a><a ng-click="changeSort('number')" style="cursor:pointer;padding-left:3px;">Sort by: Number</a> -->


        </p>


  </div>


  <div class="panel-body">


      <div ng-if="data.approvals.length == 0">


          ${You have no pending approvals}


      </div>


      <div ng-repeat="approval in data.approvals" class="sp-approval m-b">


          <div class="row">


              <div ng-class="contentColClass">


                  <div ng-if="approval.task.number || approval.task.short_description">


                      <a ng-href="?id=approval&table=sysapproval_approver&sys_id={{::approval.sys_id}}" title="{{data.ViewApprovalPageMsg}}">


                          <span ng-if="approval.task.number">{{::approval.task.number}}</span>


                          <span ng-if="approval.task.number && approval.task.short_description"> - </span>


                          <span ng-if="approval.task.short_description">{{::approval.task.short_description}}</span>


                      </a>


                  </div>


                  <div ng-if="approval.task.opened_by"><label>${Requestor}</label> {{::approval.task.opened_by}}</div>


                  <div ng-if="approval.task.start_date"><label>${Start}</label> {{::approval.task.start_date}}</div>


                  <div ng-if="approval.task.end_date"><label>${End}</label> {{::approval.task.end_date}}</div>


                  <div ng-if="approval.task.price"><label>${Price}</label> {{::approval.task.price}}


                      <span ng-if="approval.task.recurring_price"><label>${Recurring price}</label> {{::approval.task.recurring_price}} {{::approval.task.recurring_frequency}}</span>


                  </div>


                  <div ng-if="approval.items.length == 1">


                      <div ng-repeat="item in approval.items">


                          <div ng-if="item.variables.length > 0" ng-init="variable_toggle=false">


                              <a href="javascript:void(0)" ng-click="variable_toggle = !variable_toggle">


                                  <span class="glyphicon"


                                              ng-class="{'glyphicon-chevron-down': !variable_toggle, 'glyphicon-chevron-up': variable_toggle}">


                                  </span>


                                  ${Options}


                              </a>


                              <div ng-repeat="variable in item.variables" ng-if="variable_toggle">


                                  <label class="text-muted">{{::variable.label}}</label>


                                  <div>{{::variable.display_value}}</div>


                              </div>


                          </div>


                      </div>


                  </div>




                  <div ng-if="approval.variables.length > 0" ng-init="variable_toggle=false">


                      <a href="javascript:void(0)" ng-click="variable_toggle = !variable_toggle">


                          <span class="glyphicon"


                                      ng-class="{'glyphicon-chevron-down': !variable_toggle, 'glyphicon-chevron-up': variable_toggle}">


                          </span>


                          ${Options}


                      </a>


                      <div ng-repeat="variable in approval.variables" ng-if="variable_toggle">


                          <label>{{::variable.label}}</label>


                          <div>{{::variable.display_value}}</div>


                      </div>


                  </div>


              </div>




              <div ng-if="!options.portal" class="col-sm-3">


                  <button name="approve" ng-if="approval.state == 'requested'" class="btn btn-primary btn-block" style="border-width:1px;" ng-click="approve(approval.sys_id);">${Approve}</button>


                  <button name="reject" ng-if="approval.state == 'requested'" class="btn btn-default btn-block" ng-click="reject(approval.sys_id);">${Reject}</button>


                  <button ng-if="approval.state == 'approved'" class="btn btn-success btn-block">{{approval.stateLabel}}</button>


                  <button ng-if="approval.state == 'rejected'" class="btn btn-danger btn-block">{{approval.stateLabel}}</button>


                  <button ng-if="approval.state != 'requested'" class="btn btn-default btn-block" style="visibility:hidden">{{approval.stateLabel}}</button>


              </div>


              <div ng-if="options.portal && approval.state == 'requested'" class="col-xs-6">


                  <button name="reject" class="btn btn-default btn-block" ng-click="reject(approval.sys_id);">${Reject}</button>


              </div>


              <div ng-if="options.portal && approval.state == 'requested'" class="col-xs-6">


                  <button name="approve" class="btn btn-primary btn-block" ng-click="approve(approval.sys_id);">${Approve}</button>


              </div>


              <div ng-if="options.portal && approval.state != 'requested'" class="col-xs-12">


                  <button ng-if="approval.state == 'approved'" class="btn btn-success btn-block">{{approval.stateLabel}}</button>


                  <button ng-if="approval.state == 'rejected'" class="btn btn-danger btn-block">{{approval.stateLabel}}</button>


              </div>


          </div>          


      </div>  



Server script:



function ($scope, spUtil, snRecordWatcher,$window,$location,spModal,$uibModal) {


  var c = this;


  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-9";


  }


  $scope.data.op = "";


  snRecordWatcher.initList("sysapproval_approver", "state=requested^approver=" + window.NOW.user_id);


  function get() {


      spUtil.update($scope);


  }


  $scope.$on('record.updated', function(name, data) {


  get();


  })


  $scope.approve = function(id) {      


      $scope.data.op = "approved";


      $scope.data.target = id;


      get();


  }


  spUtil.recordWatch($scope, c.options.table, c.options.filter);


  $scope.reject = function(id) {


        c.onPrompt(id);



  }


  c.onPrompt = function(id) {  


                spModal.open({  


                      title: 'Give me a comment',  


                      message: 'Your comment please?',  


                      input: true,  


                      value: c.comment  


              }).then(function(comment) {  


                      c.comment = comment;  


  if(comment)


  {


                      $scope.data.comment = comment;  


  $scope.data.op = "rejected";


  $scope.data.target = id;


  get();


  }


              })  


      }


}




Client script:



if (input && input.op) {



  if(input.op == 'approved')


  {


  var app = new GlideRecord("sysapproval_approver");


  if (app.get(input.target)) {


      app.state = input.op;


      app.update();


  }


  }


  else if(input.op == 'rejected' && input.comment)


  {


  var app = new GlideRecord("sysapproval_approver");


  if (app.get(input.target)) {


    app.comments = input.comment;


      app.state = input.op;


      app.update();


  }


  }



}


options.table = 'sysapproval_approver';


options.filter = 'approver='+gs.getUserID();




data.ViewApprovalPageMsg = gs.getMessage("View approval page");


var recordIdx = 0;


var gr = new GlideRecord('sysapproval_approver');


gr.setLimit(50);


var qc1 = gr.addQuery("state", "requested");


if (input)


  qc1.addOrCondition("sys_id", "IN", input.ids);




gr.addQuery("approver", gs.getUserID());


gr.orderBy("sys_created_on");


gr.query();




var approvals = [];


var ids = [];


while (gr.next()) {


  var task = getRecordBeingApproved(gr);


  recordIdx++;


  if (!task.isValidRecord())


  continue;


  //if (recordIdx == 4)


  // break;


  ids.push(gr.getUniqueValue());


  var t = {};


  t.number = task.getDisplayValue();


  t.short_description = task.short_description.toString();


  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.toString();


  t.end_date = task.end_date.toString();


  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 = $sp.getRecordVariablesArray(itemsGR);


          t.short_description = itemsGR.short_description.toString();


      }


      items[idx] = item;


      idx++;


  }


  var j = {};


  j.sys_id = gr.getUniqueValue();


  j.table = gr.getRecordClassName();


  j.task = t;


  if (task)


      j.variables = $sp.getRecordVariablesArray(task);


  j.items = items;


  j.state = gr.getValue("state");


  j.stateLabel = gr.state.getDisplayValue();


  approvals.push(j);


}


data.ids = ids;


data.approvals = approvals;




function getRecordBeingApproved(gr) {


  if (!gr.sysapproval.nil())


      return gr.sysapproval.getRefRecord();




  return gr.document_id.getRefRecord();


}


same comments are copied 5-7 times on the same record. can you help on this?


Hi Selva,


I tried to change the code for both(making comments for approval and reject as mandatory).But even when I click approval and giving comments it is marking it as "rejected". Please help me on this.



Regards,


Gope


Hi Gope,



Please share your code



Regards,


Swamy


Hi Amaradi,



This is my code.


----->>>>>>>>>>Client Code:


function ($scope, spUtil, snRecordWatcher,$window,$location,spModal,$uibModal) {


  var c = this;


  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-9";


  }


  $scope.data.op = "";


  snRecordWatcher.initList("sysapproval_approver", "state=requested^approver=" + window.NOW.user_id);


  function get() {


      spUtil.update($scope);


  }


  $scope.$on('record.updated', function(name, data) {


  get();


  })


  /*$scope.approve = function(id) {    


      $scope.data.op = "approved";


      $scope.data.target = id;


      get();


  }*/


$scope.approve = function(id) {


        c.onPrompt(id);



  }


  c.onPrompt = function(id) {


                spModal.open({


                      title: 'Give me a comment',


                      message: 'Your comment please?',


                      input: true,


                      value: c.comment


              }).then(function(comment) {


                      c.comment = comment;


  if(comment)


  {


                      $scope.data.comment = comment;


  $scope.data.op = "approved";


  $scope.data.target = id;


  get();


  }


              })


      }



  spUtil.recordWatch($scope, c.options.table, c.options.filter);


  $scope.reject = function(id) {


        c.onPrompt(id);



  }


  c.onPrompt = function(id) {


                spModal.open({


                      title: 'Give me a comment',


                      message: 'Your comment please?',


                      input: true,


                      value: c.comment


              }).then(function(comment) {


                      c.comment = comment;


  if(comment)


  {


                      $scope.data.comment = comment;


  $scope.data.op = "rejected";


  $scope.data.target = id;


  get();


  }


              })


      }


}




------>>>>>>>>>>Server Code



if (input && input.op) {



  if(input.op == 'approved' && input.comment)


  {


  var app = new GlideRecord("sysapproval_approver");


  if (app.get(input.target)) {


    app.comments = input.comment;


      app.state = input.op;


      app.update();


  }


  }



  else if(input.op == 'rejected' && input.comment)


  {


  var app = new GlideRecord("sysapproval_approver");


  if (app.get(input.target)) {


    app.comments = input.comment;


      app.state = input.op;


      app.update();


  }


  }



}


options.table = 'sysapproval_approver';


options.filter = 'approver='+gs.getUserID();




data.ViewApprovalPageMsg = gs.getMessage("View approval page");


var recordIdx = 0;


var gr = new GlideRecord('sysapproval_approver');


gr.setLimit(50);


var qc1 = gr.addQuery("state", "requested");


if (input)


  qc1.addOrCondition("sys_id", "IN", input.ids);




gr.addQuery("approver", gs.getUserID());


gr.orderBy("sys_created_on");


gr.query();




var approvals = [];


var ids = [];


while (gr.next()) {


  var task = getRecordBeingApproved(gr);


  recordIdx++;


  if (!task.isValidRecord())


  continue;


  //if (recordIdx == 4)


  // break;


  ids.push(gr.getUniqueValue());


  var t = {};


  t.number = task.getDisplayValue();


  t.short_description = task.short_description.toString();


  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.toString();


  t.end_date = task.end_date.toString();


  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 = $sp.getRecordVariablesArray(itemsGR);


          t.short_description = itemsGR.short_description.toString();


      }


      items[idx] = item;


      idx++;


  }


  var j = {};


  j.sys_id = gr.getUniqueValue();


  j.table = gr.getRecordClassName();


  j.task = t;


  if (task)


      j.variables = $sp.getRecordVariablesArray(task);


  j.items = items;


  j.state = gr.getValue("state");


  j.stateLabel = gr.state.getDisplayValue();


  approvals.push(j);


}


data.ids = ids;


data.approvals = approvals;




function getRecordBeingApproved(gr) {


  if (!gr.sysapproval.nil())


      return gr.sysapproval.getRefRecord();




  return gr.document_id.getRefRecord();


}