Auto Reject an approval after 14 days

magoo
Kilo Expert

Hi All,

I have been trying to find a easy way to make it so any approvals older than 14 days will auto reject and then fire off a notification on why its being rejected.   Has anyone else had any luck with this?   I have tried approval rules based on create time etc and they don't seem to mark as rejected.   Does this need to be a business rule instead? If so does anyone have one they could provide?

 

Thanks!

 

Steve

10 REPLIES 10

david_legrand
Kilo Sage

Hi Steve,



Firstly you should move your topic in the Support space because the Community Updates & Feedback is dedicated to the communities topics (like 'how to ask a question').



Then, is it possible to do what you want, yes sure


The right approach is to check the "tools" you have:



So what do we want? We want that every day/hour/... the approvals "requested" from 14 days being set "rejected" with an automatic message. It's what we want.



So could I ask you questions?


1) You are the ServiceNow code, "How do you recognize these approvals?"


find_real_file.png


I added a screenshot of a demo instance, are you able to make a filter to show me the ones you want to reject? (the most important part of the picture will be the filter as you imagine).


==> The idea is "if you want ServiceNow to do things automatically, you have to be able to do it manually"



2) Do you know http://wiki.servicenow.com/index.php?title=Creating_a_Scheduled_Job? Because it's the tool you'll use finally after having the logic.



The question 1 is the most important because it'll give you the logic, then it'll be just "writing proper code using proper tools".



I don't give the direct answer of the question 1 but I'll help you if you have troubles because I do think that trying by ourselves is the best way to learn (and when the answer will be provided, I strongly encourage people to not just "read" and "copy" but "spend the necessary time to do the exercise" and "verify").



So, if you have any question, feel free to ask.



Regards,


David, Thanks for the reply.



I am able to filter down to what I am looking for manually. I am looking at anything on the sysapproval_appover table with a state= requested and a create date before Last 7 days (do not have a default of 14 without entering a date).



Here is what I have so far, when I tried to run it under scheduled it did not seem to eliminate any of my old approvals in Dev.



Condition: current.getValue("state") == 'requested'


When: After


on Update



rejectOldApprovalRecord ();



function rejectOldApprovalRecord ()


            {


            var approval = new GlideRecord("sysapproval_appover");


            approval.addQuery('sys_created_on' , '>=' , gs.daysAgo(14));


            approval.query();


       


  if (approval.next())


                      {


                      approval.state = 'rejected';


                      approval.update();


                      gs.addInfoMessage(gs.getMessage('Request rejected after 14 days due to lack of approval'));



                      }


            }


You need to write a scheduled script and not a business rule.


Also in your script there is one change needed (less than and not greater than).


Existing:


approval.addQuery('sys_created_on' , '>=' , gs.daysAgo(14));


Modified


approval.addQuery('sys_created_on' , '<=' , gs.daysAgo(14));



I would suggest you copy the code I have shared in my earlier comment and try in background script.


As Bhavesh said, you can take example on his code but in the same time to help you understanding the little mistakes, I see:



Firstly, very good for your conditions, so now you know exactly what ServiceNow has to do automatically



Then, for the little mistakes:



Condition: current.getValue("state") == 'requested' (and btw, in a business rule, i would rather write current.state == 'requested')


==> You can't make a condition like that, because when you are in a "scheduled script", current doesn't exist


==> To learn "scheduled scripts", you can use the "background script". The background script allows you to make any server side script and to execute it. Warning: if you modify something with the "background script", you'll modify it for real in your database



Why do I want to use the background scripts?


==> Because, we would like to test manually the code we'll ask ServiceNow to do automatically (to make sure we won't make mistakes)



How to use background scripts?


http://www.servicenowelite.com/blog/2014/1/17/how-to-use-background-scripts is a good start



I'll rewrite your code a little bit:


rejectOldApprovalRecord ();



function rejectOldApprovalRecord ()


{


      var approval = new GlideRecord("sysapproval_approver");


      approval.addQuery('sys_created_on' , '<=' , gs.daysAgo(14)); //As said by Bhavesh, you want   to have the approvals where the "creation date" is before or equal to 14 days


      approval.addQuery('state', 'requested'); //Or approval.addQuery('state', '=', 'requested');, it's the same because we are like you on the list of approvals, we have to make the filters right


      approval.query();


      gs.log('TEST : How many approval do I want to reject? ' + approval.getRowCount() + ' approvals', 'approval_testing'); //This line will be deleted, it's a debug to check if the filter is correct


     


     


      while (approval.next())


              //not If, if will be for 1 record, here you want to update once a day all the approvals found before


      {


              approval.state = 'rejected';


              approval.comments = 'Request rejected after 14 days due to lack of approval'; //We could also use a property here if necessary http://wiki.servicenow.com/index.php?title=System_Properties_Best_Practices


              //gs.addInfoMessage(gs.getMessage('Request rejected after 14 days due to lack of approval')); We can't really use the addInfoMessage here because we aren't on one form


              //For the first try with "background scripts", I always comment the .update(), because my first try is about testing my code and make sure I won't make mistake


              gs.log('The approval from ' + approval.approver.name + ' for the task ' + approval.sysapproval.number + ' will be ' + approval.state + '. It was created on ' + approval.sys_created_on, 'approval_testing');


              //approval.update();


      }


}



So try to use this code into a "background script" to understand how it works, if you have any questions about the , feel free to ask.


And then, you'll be able to make your scheduled job because the scheduled job will be just "I want to execute automatically the code I run and tested manually"



Regards,


Thank you both of you for your responses and assistance with this.   It is working great!  


David, Thank you for the comments (and links) you had added in the script, it helps me start to understand why I should/ shouldn't use certain code in specific situations.   It is a great learning experience and hope to continue to learn much more about Java in the near future to be able to be able to assist and be a resource to others in the community.