Gary Van Roy
ServiceNow Employee

First you will want to review the Ask for Approval Action from Flow and Scripted Approvals.

 

Use Cases:

I need to gather approval groups from the CIs in the Affected CI list and generate approvals for each.  I also need to look at the Group to CI (cmdb_rel_group) table and find Groups that need to approve.

 

It should work just like the Approval Group functionality in Workflow where I can pass the string of groups and the activity will generate an approval for each.  It should also only require one approval from each Group and reject if any member of any of the Group rejects.

 

Solution:

Create a Subflow (we want to make this reusable) to leverage Ask for Approval in Flow and use Scripted Approvals.

 

How to do this:

While I'm not going to detail creating a Subflow and getting data, you should use the concepts below to support the approval step.

  • Create a Variable for your Flow (Approval Groups as an example)
  • When you have your list of records containing the Group records, loop through them and set the Variable you created with the values

Example:

Overall Subflow

GaryVanRoy_0-1727884072054.png

 

Looping through and setting your Variable

GaryVanRoy_1-1727884139642.png

Sample code to set your Variable

 

var appr = fd_data._2__for_each.item.ci_item.change_control;
var apprgrp = fd_data.flow_var.approval_groups;
if(appr != '' && apprgrp.indexOf(appr)==-1){
    if(apprgrp == ''){
        return appr.toString();
    }else{
        return apprgrp + ',' + appr.toString();
    }
}else{
    return apprgrp.toString();
}

 

 

Once you have your data, you will need to setup the Ask for Approval in your Flow.  This is where we can use the action and script it to perform like the Group Approval activity in Workflow.

 

When you setup Ask for Approval, if you will have other Approvals in the main Flow, set the Approval Field to something other than Approval as the value.  This will prevent the record that the Flow is running against from setting the Approval to Approved after the action has completed.  You can do an update to the target record in the main Flow and set the Approval value once you have finished all your approvals.

 

When setting the Rules via a script, you can refer to Scripted Approvals for your options.  What the article doesn't tell you is how to do AND as an option.  The answer is this format, "ApprovesAnyG[group sys id]&AnyG[group sys id]".  You also can't just set the Group Sys ID to the string of Groups either.  Otherwise in this scenario they are all treated as one Approval.  That means one approval from any member of the various Groups would Approve the record for all.  What we want is to replicate the Group Approval Workflow Activity where you could pass the string of Groups and treat them as their own Approval independent of the other Groups, but to also reject if anyone rejects.  You can achieve this without scripting, however you have to code each group in the condition.  That doesn't work for us since we have a string of Groups.

 

To achieve this you will use the following in the Rules script:

 

var grps = fd_data.flow_var.approval_groups.split(',');
var rgrps = fd_data.flow_var.approval_groups;
var rl = '';

for (var i = 0; i < grps.length; i++) {
    if(rl == ''){
        rl = 'ApprovesAnyG['+grps[i]+']';
    }else{
        rl = rl +'&AnyG['+grps[i]+']';
    }
}
if(rl != ''){
    rl = rl+"OrRejectsAnyG["+rgrps+"]";
}
return rl;

 

 

You can see we are taking our string of Groups from our Variable and building the Approval Rule.  The last piece that we add to the Rule at the end is the Or option for rejecting if any of the Groups reject.  This should work just like the Group Approval Workflow Activity now.

 

Example:

GaryVanRoy_2-1727884853026.png

 

If you set the Approval Field value to something different so you can control how the target record is approved from the main Flow, you will want to add a new Variable and capture the Output.  Then when the Subflow completes, you can use the Output to decide if you are going to Approve/Reject from the main Flow.

 

Example:

GaryVanRoy_0-1727887094789.png

 

Summary:

There are many ways to accomplish things in ServiceNow and this is just one example.  You could create your own custom Action in Flow, but this way we can just create an overall Subflow to do all the work for us.  If you were looking to have the functionality of the Group Approval Workflow Activity in Flow, this is the solution I've come up with.  Hopefully this is helpful.

 

 

5 Comments
Thiago_Pereira
Tera Contributor

Hi @Gary Van Roy 

I am trying to make a "AND" condition.

I have two groups, I need at least one member of each group to approve.

I have tried 2 diffetent aproachs:

 

1 - ApprovesAnyG[SysID1]&AnyG[SysID2]OrRejectsAnyG[SysID1,SysID2]


2 - ApprovesAnyG[SysID1]&ApprovesAnyG[SysID2]OrRejectsAnyG[SysID1,SysID2]


In the 2 scenarios the approvals are getting created but once one group member is approving the other group approval is not required it is moving to next step.

Do you have any idea?

 

Mani Kishan
Tera Contributor

Hi @Gary Van Roy 

 

I have a similar use case as above from @Thiago_Pereira where the group approvals are setting to no longer required if any one user is approved from any group out of several approval groups. As per the Business rule 'SNC - Moot user approvals for group' only the other members of the approval group should be set to no longer required but not the approvals of other groups. Any help or idea on how this can be achieved?

 

Thanks in advance!

MaheshK79583647
Tera Expert

Hi @Mani Kishan @Thiago_Pereira We are on the same boat my friends. Even i triggered parallel approvals for multiple groups. If any user from one group approves, automatically approvals from other groups also changing into no longer required state. Not sure why. Still waiting for the help.

Mani Kishan
Tera Contributor

Hi @MaheshK79583647 

 

Based on the behavior of approvals and who it's designed OOTB. I used script logic to overcome the problem. Below is how I designed my action to function. This makes the action to wait for an appproval from each group and all users to approve. It may help you.

var query = [];
var id = fd_data.trigger.current.sys_id;
var grpApprovals = <group approvals sys_id with comma separated>;
var usrApprovals = <user approvals sys_id with comma separated>;

var sp = grpApprovals.toString().split(',');
for (var i = 0; i < sp.length; i++) {
    query.push("ApprovesAnyG[" + sp[i] + "]");
}
var groupApprovalQuery = query.toString().replaceAll(',','&').trim().toString();
var userAndRejectApprovalQuery = "&AllU["+ usrApprovals +"]OrRejectsAnyU["+ usrApprovals +"]G["+ grpApprovals +"]";

return groupApprovalQuery + userAndRejectApprovalQuery;
sejalP23
Tera Explorer

@Gary Van Roy Here is our requirement:

We use a list collector variable, and upon request submission an approval process is initiated for each selected option. Once a selected option is individually approved, it triggers the creation of a corresponding catalog task, independent of the approval status of other options.

 

For example, if options A, B, and C are selected from the list collector variable, parallel approvals are sent to groups A, B, and C. When approval for Group A is approved, a catalog task is created for Group X; upon approval from Group B, a catalog task for Group Y is created. If Group C rejects the approval, it will not impact the catalog tasks generated for Groups A and B.

 

We have implemented the parallel approval logic but need solution for catalog task generation. Do you have any insights on how we can proceed?