Pending approval Reminder

vijay_kumar
Giga Contributor

Need to send approval reminder to approvers every day .A single notification should have all the approval requests which are in requested along with the description,change type and additional info so the approver can prioritise the request.

 

 

 

Thanks in advance

vijay

1 ACCEPTED SOLUTION

marcguy
ServiceNow Employee
ServiceNow Employee

This is quite a lengthy answer but we have done this for a few different tables to give users weekly reminders of various different things like projects, approvals, etc.



What you will need to do to get all of them in one email is fire an event for any user whom has an outstanding approval, in a scheduled script job (sysauto_script).



var users = []; //start with an empty list of approval users



var apps = new GlideRecord('sysapproval_approver');


apps.addQuery('state','requested'); //find requested approvals, you may want to specify which table i.e line below


apps.addQuery('sysapproval.sys_class_name', 'change_request'); //only find change related approvals


apps.query();


while (apps.next());


//now add the outstanding approver to the list


users.push(apps.approver);


}


//now we need to dedupe the list of users



var au = new ArrayUtil();


var noDupesApprovalUsers = au.unique(users);



//now we need to go through this unique list of users and fire an event against the users which in turn fire an email notification which will go and gather all of their outstanding approvals.



for (var i=0; i< noDupesApprovalUsers.length; i++) {


  gs.eventQueue('approval.reminder',noDupesApprovalUsers[i],'sys_user');


}




OK so now if you look in event log, you should see some events being fired called approval.reminder which is an event for every user that we have found who has an outstanding approval.



now we need to build a notification and template to find that users outstanding approvals and bunch them into ONE email.



So create a notification and it will be on sys_user table when approval.reminder event is fired:


Subject: Something like you have approvals outstanding....


Now I normally use an email template and script include to store the script and HTML in order to build a table of those approval records.



<mail_script>


var dem = new ApprovalReminderEmail();     //call the script include


template.print(dem.send(current.sys_id));       //call the send function and pass in the users sys_id


</mail_script>


</font>




Within this script include you are going to find the users outstanding approval records via GlideRecord and them add them to a HTML Table



send : function (user){



var outputString = ''; //put some html in here and your table header columns, styles etc.



var approvals = new GlideRecord('sysapproval_approver');


approvals.addQuery('state','requested');


approvals.addQuery('sysapproval.sys_class_name','change_request');


approvals.addQuery('approver',user);


approvals.query();


while (approvals.next()({


// up to you how pretty you want to make your html but I normally build a var called outputString and keep adding to that with my new records i.e.


outputString = outputString +"<tr><a href=" + uri + "sysapproval_approver.do?sys_id="+approvals.sys_id+">"+approvals.sysapproval.getDisplayValue()+ "</a>"+" "+"</td><td width='150px'>" + approvals.sysapproval.short_description + " "+"</td><td width='150px'>" + approvals.sysapproval.start_date + " "+"</td><td>" + approvals.sysapproval.end_date + " "+"</td><td width='100px'>" + approvals.sysapproval.phase.getDisplayValue() + " "+"</td><td width='200px'>"+ approvals.sysapproval.assigned_to.getDisplayValue() + "</td></tr>";


}



//eventually you should end up with some html and a table



then just return all of that and I normally log it whilst building for troubleshooting bad html etc.



gs.log(outputString,'approval reminders');
return outputString;

View solution in original post

9 REPLIES 9

Thanks Mguy for your help , process is going fine even my script include geting called .but the data in notiifcation is not getting populated



pasting the sample html code


var outputString = "<table border='1'   style='width:300px'> <tr><th>Change number</th><th>Description</th><th>Planstartdate</th></tr>";




outputString = outputString +"<tr><td width='150px'>" + approvals.sysapproval.getDisplayValue() + " "+"</td><td width='150px'>" + approvals.sysapproval.short_description + " "+"</td><td>" + approvals.sysapproval.start_date   + " "+"</td></tr>";



reminder notification.JPG


marcguy
ServiceNow Employee
ServiceNow Employee

Ok That's good that the script include is getting called, we should also add some gs.log lines as we are building this to ensure we are getting the correct records etc.



gs.log('found approval record for ' + approvals.approver.getDisplayValue());



So my script include HTML has these lines in it in order to build a table and then iterate through each record, you can use this to make yours look like this or you can tidy it up, etc.



var uri = gs.getProperty('glide.instance.url');
outputString = '<body style="color: #000000; font-family: arial, helvetica, sans-serif; font-size:12px;">'
+ '<span style="color: #000000; font-family: arial, helvetica, sans-serif; font-size:12px;" >';
th = "<th bgcolor=#C0C0C0>";
tableHeader = "<table style='width: 90%; color: #000000; font-family: arial, helvetica, sans-serif;   font-size:12px;'>";
tableFooter = "</table></br></br>\r\n";
outputString = outputString + "<tr>"+th+"Number</th>"+th+"Planned Start</th>"+th+"Planned End</th>"+th+"Title</th>"+th+"State</th>"+th+"Assignee</th></tr>";


then we go through the individual records adding a new row for each one to the outputString:



while (approvers.next()) {
outputString = outputString +"<tr><td width='150px'><a href=" + uri + "sysapproval_approver.do?sys_id="+approvers.sys_id+">"+approvers.number + "</a>"+" "+"</td><td width='150px'>" + approvers.start_date + " "+"</td><td width='150px'>" + approvers.end_date + " "+"</td><td>" + approvers.short_description.getDisplayValue() + " "+"</td><td width='100px'>" + approvers.state.getDisplayValue() + " "+"</td><td width='200px'>"+ approvers.assigned_to.getDisplayValue() + "</td></tr>";
}


you need to make sure here that the fields i'm using are the ones you want, so change these as appropriate.



Now at the end of the script include we piece it all together:



outputString = outputString + "</table><table style='width: 90%; color: #000000; font-family: arial, helvetica, sans-serif;   font-size:12px;'>";
}


outputString = outputString + tableFooter + '</body></span>';



Then I would print it to the log to see what it looks like. gs.log(outputString);



In my notification template, this is all I have



<font face="Arial"><center>Approval Reminders Report - Click the links below to access the records.</center>




<mail_script>


var dem = new ApprovalReminderEmail();


template.print(dem.send(current.sys_id));


</mail_script>


Thanks Mguy your script helped me alot am getting my data populated correctly in my notification.


only correction i want to make in your script is



template.print(dem.send(event.parm1));



Thanks alot again.



Regards,


vijay


madhvi
Giga Contributor

how to get link for approval and rejection of that requested item in the list.


I have similar requirement,i have to populate details of the items like:requester,date of request creation,approval and rejection link.


Any help will be appreciated.Thanks


danielbilling
Kilo Guru

Hi,



maybe try another approach similar to Incident SLA alerts (task sla).


if you set a default time for approvals and create a Workflow that trigger notifications based on the deadline time.


gives you the option to set % notification levels