Ask for Approval in flow designer - How is manual approval intended to work?

Jesper Slot
Tera Guru

Hi, 

We're running Paris, I'm building a scoped application, based on the task table, with a flow for the "lifecycle" of the requests.

We need several options for approval. It could be line manager or a list/group of predefined users, which is quite simple to set up in Flow Designer.

However for some requests we would also need the supporter to investigate before applying the approver, so in that scenario I would like to use the Ask for Approval with manual approvers option. I just can't see how this was intended to be used... which is where I call for your help.

I've been googling and searching the ServiceNow documentation, but haven't been able to see any examples or just a description of how this is intended to work.

So far I've set up the Ask for Approval action like this:

find_real_file.png

And normally, with the line manager or group of approvers, I'd follow up with a Wait for condition action on the approval state. But in this case, this do not work. 

Any knowledge on how to follow up on the Ask for Approval with manual approval? 

 

KR
Jesper S. Grumsen

1 ACCEPTED SOLUTION

Having the approvers added to the record before coming to this Ask For Approval action in the flow worked very well - even with multiple approves added.

So here is a snip of my workflow:

- In step 30 I update the "Work Note" telling the support agent that this specific request requires approvers to be added manually and that they should follow up by setting the State to "Pending Approval". I build a UI Action for changing the state.

- In step 31 I put in a "Wait For Condition" action that waits for the state to become "Pending Approval". 

- This is then followed up by an "Ask For Approval" action in step 32. 

When the state is changed to pending approval, the Ask For Approval action grabs the related approval records, changes their state from "Not Yet Requested" to "Requested". When approved, the Approval field on the record is changed to approved.

   

find_real_file.png

 

 

Well, simple enough... when you know the process 😉

View solution in original post

12 REPLIES 12

Hi Joel,
I don't have access to that right now, but it was more or less a copy of the out-of-the-box UI Actions. Here is an example of the Resolve button for incidents - basically you have one function for client side and one for server side (make sure the "action name" and "onclick" (name like client side function) are updated accordingly): 
JesperS_Grums_0-1704195646456.png

Here the values for server side state are wrapped in a script include, but you could just have the value set here instead: current.state = "6";

mpmacconnell
Tera Guru

We got it working using the following script:

 

(function execute(inputs, outputs) {
var assigned_to = inputs.assignedTo;
var startdate = inputs.planned_start;
var enddate = inputs.planned_end;
var rfcnum = inputs.rfcNumber;
var rfcsysid = inputs.rfcsysid;
var currentdt = new GlideDateTime();
currentdt = startdate.getDisplayValue().split(' ')[0];

var location_temp = [];


var contact_loc = new GlideAggregate('u_rfc_contacts'); //GlideAggregate
contact_loc.addQuery('u_change_request', rfcsysid);
contact_loc.addQuery('u_key_card_request_needed', true);
contact_loc.addQuery('u_vendor', false);
contact_loc.groupBy('u_building');
contact_loc.query();
while (contact_loc.next()) {
location_temp.push(contact_loc.u_building.toString());
}
var location_arr = new ArrayUtil().unique(location_temp);

var hddcart = new Cart(generateId());
//for each location create a RITM for all users in each location
for (var i = 0; i < location_arr.length; i++) {
///query the user for the location and add it to user array
var userarray = [];
var suite = '';
var contact_user = new GlideRecord('u_rfc_contacts');
contact_user.addQuery('u_change_request', rfcsysid);
contact_user.addQuery('u_key_card_request_needed', true);
contact_user.addQuery('u_building', location_arr[i]);
contact_user.addQuery('u_vendor', false);
contact_user.query();
while (contact_user.next()) {
userarray.push(contact_user.u_name.toString()); //array of all users for that particular location.
suite = suite + " " + contact_user.u_suites_room;
}

var item = hddcart.addItem('c0bda6c2b41fa04044e97357a6539f7c');
hddcart.setVariable(item, 'scif_user_type', 'Employee');
hddcart.setVariable(item, 'sc5_confirmation_begin', 'true');
hddcart.setVariable(item, 'sc5_action_require', 'Exception to ID Keycard');
hddcart.setVariable(item, 'sc5_exception_mulitple', 'Yes');
hddcart.setVariable(item, 'sc5_exception_reason2', 'Changing Access Hours and Location');
hddcart.setVariable(item, 'sc5_scif_location_selection', location_arr[i]);
hddcart.setVariable(item, 'sc5_scif_exception_users', userarray.toString());
hddcart.setVariable(item, 'sc5_excep_access_hrs', 'Release Coordinator Access');
hddcart.setVariable(item, 'sc5_start_exception', startdate);
hddcart.setVariable(item, 'sc5_end_exception', enddate);
hddcart.setVariable(item, 'sc5_exception_reason', rfcnum + ' - Keycard request for change request.');
hddcart.setVariable(item, 'sc5_exception_suite', suite);
hddcart.setVariable(item, 'scif_start_date', currentdt);
hddcart.setVariable(item, 'scif_time', '06:00:00');
}
// set the requested for
var cartGR = hddcart.getCart();
cartGR.special_instructions = "Note: This is a system generated Keycard request for " + rfcnum;
cartGR.requested_for = assigned_to;

//cartGR.submitted_by = cartowner;
//cartGR.user = cartowner;
//cartGR.u_impacted_location = userloc;
//cartGR.sys_created_by = requestor;
//cartGR.opend_by = cartowner;
//cartGR.location = userloc;
cartGR.update();

//Place the order
var cartid = hddcart.placeOrder();

outputs.request = cartid;

var ritm = new GlideRecord("sc_req_item");
ritm.addQuery("request", cartid.sys_id);
ritm.query();
while (ritm.next()) {
ritm.contact_type = 'RFC keycard';
ritm.opened_by = assigned_to;
ritm.update();
}

var req = new GlideRecord("sc_request");
req.addQuery("sys_id", cartid.sys_id);
req.query();
if (req.next()) {
req.opened_by = assigned_to;
req.update();
}


// note this is an example.
function generateId() {
var text = "CART-";
var possible = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
for (var i = 0; i < 7; i++)
text += possible.charAt(Math.floor(Math.random() * possible.length));
return text;
}

 

})(inputs, outputs);

Hi, 

I don't see the connection to this topic, I fear you're replying to a wrong topic 🙂

Kr

Jesper