Advanced Approval Process Write Back with Microsoft Flow
Robust, client-specific approval workflow & write-back is not a standard feature of many ERPs. Microsoft Flow meets requirements at a fraction of the cost.
Table of Content
A robust, client-specific approval workflow and write-back engine is not a standard feature of many ERP systems, which requires BI architects and data engineers to think outside the box to deliver scalable solutions. Microsoft Flow can meet these enterprise level requirements, and can do it at a fraction of the time and cost of any other solution on the market.
Keep reading to learn how your current business requirements, including SQL data warehouse write-backs, robust tiered approval cycles, and sales order approval requests can be addressed using Microsoft Flow and the new Power Platform.
The scenario described in this tutorial will operate on a SQL stored procedure and Approvals as shown below, but you are more than welcome to substitute any data that produces an array within Microsoft Flow so that you can follow along: a SharePoint list, a list of documents in OneDrive, tags from Computer Vision API, etc.
I will walk through how to build this flow from scratch, but you can also use this template to follow along yourself.
You can use the Recurrence trigger as we will be using an OData filter to find open transactions only.
Running a SQL Procedure to update the rows that are ‘Open’ to ‘Pending’ is important because we do not want those records re-entering the Approval cycle again, thereby effectively keeping them in the Approval cycle until approved (or rejected). Upon rejection, they will remain in the loop. Therefore, only new sales orders will be picked up by the approval cycle.
5. Click into each row in the “Enter value” column and use the formula below:
coalesce(item()?[‘SalesOrderNumber’],null)
The coalesce function is one of my favorite functions because if all of the arguments are blank, then the function returns blank, rather than an error.
union(body(‘SelectLIDCODE’),body(‘SelectLIDCODE’))
This union function returns a single array or object with all the elements that are in the array or object passed in. For parameters, this function only requires either the array or object from where we want all the items. The parameters for this function can either be a set of objects or a set of arrays, not a mixture of both. If there are two objects with the same name, the last item with that name appears in the result.
Below is an extra screenshot to show where which Output to use.
Now that we have set up the ex-ante variables and arrays, we will now start the approval process, which will proceed until all the sales orders are approved.
3. Insert a step and search for “Data Operations – Compose.”
4. Use the compose operation to retrieve the sales order number from the apply to each, using the formula below:
@items(‘Send_each_sales_order_indivdually’)[‘LIDCODE’]
It is very important not to forget to make your “Apple to each” execute in parallel by going to options and enabling “Concurrency control”.
Insert a step and navigate “Add a do until”. We set up the “Do Until” where the exit condition is when the isSecondApproved variable becomes 1 and the sales orders array is empty (meaning they have all been sent out). The variable will be checked at the start of every loop iteration, and once the approval is complete and variable set to 1, it will exit the loop iteration.
The “Do Until” loop will continue until both the approver(s) have approved the sales order. That will start out looking like this, once you add the approval step in using the following formula: @equals(variables(‘isSecondApproved’), 1))
Insert a step and search for “Data Operations – Select.” Again, we use coalesce to avoid any errors in the output.
Formula: length(body(‘MasterSelect’))
We need to create an array that captures the approvers who will be responsible for approving the sales order. By creating an array and then joining them, we will be able to add the output to the approval. We will then select the columns we need to de-duplicate and join.
2. Insert a step and search for “Data Operations – Compose.”
3. Insert a step and search for “Approval.”
Utilizing the output from the compose data operation above, we join all potential approvers that are on the sales order, using the formula: join(outputs(‘a1EmailUnion’),’;’)
Full shot:
4. Insert a step and search for “Condition.” We are going to set the condition as Response is equal to Approve.
If you are working in sharepoint and would like to know how to get a dynamic list of approvers, check out this article about sending parallel approval requests for a dynamic set of approvers.
Once the owner approves the sales order, there is a stored procedure that writes back the on-premises SQL Data Warehouse the results, and the second approver is set to pending.
We will not worry at this point what happens when the Owner rejects in this scenario. However, we will cover what happens when the second owner rejects the sales order.
Once the owner has approved the sales order, it is now the second owners turn to approve it. We are going to follow the steps we performed in setting up the owner:
2. Select the Approvers e-mail address from the body of the ‘Filter array’ action.
concat(item()?[‘ApproverEmail’],”)
3. Compose a union the Approvers e-mail address from the output of the Select operation.
union(body(‘Selecta2Emails’),body(‘Selecta2Emails’))
4. Join the Approvers e-mail address from the output of the compose operation and add them to the Assigned to field in the Approvals action.
join(outputs(‘a2EmailUnion’),’;’)
5. The important part here is to make sure to use the selected e-mail columns and compose action to create an array for the secondary approvers e-mails. Finally, we will use the join function to combine all potential approvers on the sales order.
Handling the Approving and Rejecting of the second approver.
The final difference will be in how we handle is the second approver rejects the sales order. We will send the owner an e-mail notifying them that the sales order has been rejected, and then we will set the variable so that the loop will resend the owner the approval.
Finally, just as we did with the owner we will make sure to set our variables depending on the outcome of the secondary approver’s decision.
If the sales order is approvedby Approver:
If the sales order is rejected by Approver:
The Owner will receive a notification the sales order has been rejected along with comments from the Approver on the modifications that are required for approval.
2. “SQL – Execute Stored Procedure” and enter the RowID as the Output from the ‘Filter_array’ action, and the ApprovalDate as Response date.
Future developments will look at allowing the manager to delete a rejected record or cancelling the sales order, maybe even a purge process that has been out there for an extended amount of time. There are many avenues to take the process, and the goal is to continue enhancing the capabilities of Microsoft Flow and the Power Platform. To learn about all the features of Power Platform, click here.
Talk to us about how Velosio can help you realize business value faster with end-to-end solutions and cloud services.
"*" indicates required fields