Delegation - Approvals different types

poyntzj
Kilo Sage

Delegation,   Great at allowing us to delegate approvers amongst other things.

Has anyone enhanced this to split the types of approval ?

What I mean is if a user is off, they may want to delegate the approvals of changes to person A, the delegation of Knowledge to Person B and the delegation of Orders to Person C

At the moment we would give Persons A, B and C approval delegation and hope they realise what they are approving before doing so..... hmmmmmm

I have in the past done work and split the various task types so that notifications were sent to the right people and items visible on dashboards, but the requirement for approvals was never there.   At the current client I may need to look at this for the approval side.

Any ideas / assistance or considerations are appreciated if anyone else has done this.

Cheers

8 REPLIES 8

LaurentChicoine
Tera Guru

Hi Julian,



You will have to go custom on this. Here is how the actual delegation works:



  • A specific delegate has a start date, end date, and properties like Approvals which is what is interesting us in this case
  • My approvals module uses the function getMyApprovals() has the filter for the approval. This is actually the function leveraging the delegates
  • There are read, write and delete ACLs used to manage access to the approval record. The function used here is isApprovalMine(record_sys_id).
  • The checkAllApprovers(approver) function is then calling back the getMyApprovals() function.
  • There is also the approval emails that are only sent if the CC Notifications was checked but this is sending every notifications and not only specific approvals. To leverage notifications delegate for only specific approvals you would probably have to script this in an event parameter of the approval.inserted getting called by either the "Approval Events (Task)" business rule or the "Approval Events (Non-Task)" business rule


The three functions I referred to are defined in the "getMyApprovals" business rule.



So based on your need, the three business rule I mentioned is where you should look for to code your required logic. You can either modify the OOTB business rules or copy them and change the function names and update the function being called every where they are called. Personally, I prefer modifying OOTB function as the collision upgrade engine of servicenow is pretty good and allows be to review potential upgrades to my modified code. If I just copied the business rule, I would probably never go back to look for improvement to my copied business rule. Also this options allow to limit impact, at most you impact 3 records, no need to update OOTB modules and ACLs, so if you eventually chose to go back OOTB on this, there is only 3 business rules to revert back at most.



I hope this helped you as to where to look for related to this customization.


Yeah, last time I removed the default options from the delegation page and added different tabs, one for notifications and one for dashboards


They could then choose what they wanted for each delegate.


The benefit here is that all the existing OOB code is there, just bypassed



The DB's were a change to using a reference qualifier to check you and any delegations assigned to you


A few new DB / gauges added too


The emails were via BR on the mail table to add a new notification to a delegate



Looks like a similar re-working will need to be done



Hey ho


Hi Laurent,



I have the same kind of requirement in the approver can create a delegate to approve their approvals, but that delegate only receives approvals for service request not other approvals like change or others. Can you please suggest on this.


Hi Sabitha,



Here is what I would do:



  1. Add a true/false field to the Delegate table: Service request approvals [u_service_request_approvals]
  2. Add the following function to the getMyApprovals business rule:

function getMyServiceRequestApprovals(){


      var u = gs.getUserID();


      var answer = new Array();


      var i = 0;


      answer[i++] = new String(u);


      var g = new GlideRecord("sys_user_delegate");


      g.addQuery("delegate", u);


      g.addQuery("u_service_request_approvals", "true");


      g.addQuery("starts", "<=", gs.daysAgo(0));


      g.addQuery("ends", ">=", gs.daysAgo(0));


      g.query();


      while( g.next())


              answer[i++] = new String(g.user);


     


      return answer;


};



    3. Update the checkAllApprovers function from getMyApprovals business rule:


function checkAllApprovers(approver, table){ //Added a table parameter



      if(JSUtil.nil(approver))


            return false;


           


      var apps = getMyApprovals();


     


      //Add Service Request approvals if it is a Service Request


      if(table == 'sc_request' || table == 'sc_req_item'){


              var serviceRequestApps = getMyServiceRequestApprovals();


              apps = apps.concat(serviceRequestApps);


      }


      for (key in apps) {


              if (apps[key] == approver)


                      return true;


      }


     


      return false;


}



    4. Update the isApprovalMine function from getMyApprovals business rule:


function isApprovalMine(gr) {


      var approver = gr.approver + '';


      // if this is the sysapproval_group table, gr.approver


      // would evaluate to 'undefined'


      if (!gr.isValidField('approver'))


              approver = '';


      var approverSysId = gr.sys_id + '';


      // Check if approver is nil due to being on a list


      // of records that contain a related list of approvers


      // or due to checking a group approval


      if(JSUtil.nil(approver) && JSUtil.notNil(approverSysId)) {


              // Look at the sysapprover_approval table


              var app = new GlideRecord('sysapproval_approver');


              if (gr.getTableName() == 'sysapproval_group')


                      app.addQuery('group', approverSysId);


              else


                      app.addQuery('sysapproval', approverSysId);


              app.query();


              while(app.next()) {


                      approver = app.approver;


                      if(checkAllApprovers(approver))


                              return true;


              }


      }


     


      //Evaluating the table that the approval record is for


      var table = '';


      if(gr.source_table){


              table = gr.source_table;


      }


      else if(gr.sysapproval){


              table = gr.sysapproval.sys_class_name;


      }


      return checkAllApprovers(approver, table);


}



    5. Update the My Approvals menus to add this new delegation


The filter should now look something like this:


find_real_file.png



I did not cover the notification system as it is kind of a separated thing because the delegation default setting is to delegate all emails, even the standard approvals delegation does not include emails.



The customization I propose include modification to OOTB script, so if done this way, skipped update should be reviewed on upgrade to make sure this customization still make sens with the OOTB script if it gets modified. If you don't plan on doing this review, you should probably, create a seperate business rules using different function names and then replacing the use of these functions in every module (menus), business rules, ACL, or other script that would need to take the Service Request delegation into account.