Requirement where a designer has create a workflow assigning multiple parallel tasks to multiple parallel groups of approvers is complex.
Basically, Nintex offers us two approaches: either assign task to a group and wait for the first response or to wait for all responses. But what when we need to have multiple groups assigned a task in parallel?
Approach
Doing multiple parallel approvals requires either parallel block or... unchecking the option for waiting until task is completed.
The first approach require the workflow to be edited every time number of parallel groups is changed - to add or remove branches. It makes it quite fixed. And therefore hard in maintenance.
The second approach is better. This way you can build a loop and in the loop assign all tasks to all groups. But what then? What if you need to pause the workflow, so that it actually waits for all the responses before moving on?
This can be done by first collecting all the IDs of tasks generated and then by using a loop to check if they are completed.
If any was completed, it should be removed from a collection. Once collection is empty the workflow can move one. Of course, after each check workflow has to pause, so that the loop won't run endlessly.
Challenges
In both approaches there are challenges quite hard to overcome. The first one requires a fixed approach. If number of tasks' groups is changed - you need to edit the workflow.
The second one is even worse - because workflow has to check multiple items on the Workflow Tasks list, every 5 minutes (or slower - up to you) it may easily reach the boundary (Daily email limit has exceeded and your workflow has been suspended) of 5k calls to the SharePoint. And then it requires you to resume it after a day. Useless...
The pattern
I have created a pattern that gets out the best from the second solution and allowing the workflow to overcome the limit. How?
I simply moved the need of checking if the task is completed or not to the tasks' list. And a State Machine action in the primary workflow.
- Primary workflow assigns tasks
- After all tasks in a group are assigned, it then calls, for each assigned task, a workflow on the Workflow Tasks list, that monitors completeness of the task.
- Once a task is completed, the workflow on Tasks list changes a field value of the item, running the primary workflow, so that the primary workflow unpauses.
- Once unpaused it checks how many from the assigned tasks are still waiting for completion and if there are any - it again changes the trigger field value and waits.
- The primary workflow has to start the workflow on Workflow Tasks list, because item there is created by the system - what does not trigger the "start workflow when item is created" option.
- Workflow must wait for the field change - the field is being changed if the assigned task is completed.
- After unpaused the primary workflow then sets the field to previous value, so that once it reaches it again, it will again wait for other tasks to be completed.
- If task is completed, it should be removed from the "monitor" collection, so that next time workflow will not check if it is completed.
Workflow Tasks list workflow
Workflow is triggered by the primary workflow. It works for any task that is not yet completed (1). It pauses (2) until Task Status equals "Completed". Once unpaused, it gets related item data and extracts (3) ID of the related record, using the following pattern (the "Related Item" attributes is stored in a JSON formatted string):
(?<=Id":)(.*)(?=,"Web)
Then it gets item 0 from the collection (4) and updates field of the item (5), on which the primary workflow runs, so that it can move on.
Brief summary
Following this approach you can build solutions that assign tasks to multiple approvers' groups in parallel, so that you can have e.g. 10 tasks each assigned to a group of 10 different persons, having completion criteria set either to wait for all responses or just a first one.
Very useful and reliable. Try it out yourself!