• Marcel Haas

SharePoint Advanced Document Approval with Microsoft Flow

Updated: Feb 7, 2019

In this article, you can learn how to build an enterprise document approval process for Modern SharePoint with Microsoft Flow.

Introduction

Microsoft Flow Approvals are great for simple approval processes, but

Microsoft is working on a deeper integration of Approval w


Business usecase

Let's look at our real world customer usecase. My goal is to give you as much information as possible on the implementation steps, the core concepts of the solution and the overall solution, so you can avoid some traps and get value out of my experiences, which I had to pay myself for ;-)

In the past, the customer was using SharePoint2010 OOTB approval workflows. Nothing was customized in SPD. Workflow was just bound to library and basic configuration was set. Users initialized the workflow manually and defined the workflow initialization settings like approvers, type of approval, due date, etc. and started the workflow. So each workflow had a individual run context and was run on the pretty old but still fancy SharePoint2010 workflow engine on SharePoint Online.

Users didn't like the style of the quite cryptic e-mail notifications, but loved the flexibility of the OOTB functionality. If to look a bit deeper under the hood, this thing was quite powerful and more expensive 3rd party solutions weren't always needed. The engine could be extended pretty easily with managed code and custom actions, to integrate other systems and services.

Things should actually be easier nowadays, but sometimes new and different complexity is hitting us hard

As we arrived in the "modern" episode of it technology where all is decentralized, everything became a service and is talking to everything, client side code owns the world and data is structured and interacted within a Graph.

Key requirements

Some of the key requirements an enterprise level document approval process typically requires.

The Flow insiders know, that this list contains a lot of challenges and the main challenge is to connect all the individual ingridients to one final pie:


  • Parallel and serial approval task flow

  • Dynamic number of approvers

  • Approval due date

  • Automated reminder e-mail based on approval date

  • Approval escalation/timeout when no response

  • Centralized and "immutable" approval log

  • Enforced versioning, versioning comments

  • SharePoint integrated via Flow launch panel

  • Advanced error handling with notification to initiator

Solution Overview



SharePoint Integration


  • Modern Document Library

  • Custom Metadata

  • Flow Launch Panel


  • Dynamics Initialization Context

  • SharePoint Column Formatting


Azure Storage Queues

Storage Queues are providing us with enterprise software capabilities at our fingertips for a very reasonable price. The impact on the solution stability of this robust, highly scalable and easy to use lego brick, is insane.

Azure Storage Queues are a very cost effective solution. These connectors belong to the set of Standard Connectors and don't require a premium plan for each user. As for example the HTTP connectors will require starting from spring 2019. This makes a huge difference in price, as 1GB of queue storage costs about $0.07 and max message size is 64k.

JSON used as a data exchange format for the state object, is very flexible and can basically contain any data, even binary.


So, which Queues do we need actually need for our solution? Basically every Flow get's a Queue. So we are talking about a 1:1 mapping between Flows and Queues.



Approval Controller

Parallel Approval

Sequential Approval

Approval Logger

Approval Error


Microsoft Flow

Approval Controller

Parallel Approval

Sequential Approval

Approval Logger

Approval Error





Solution Overview

I visualized the high level solution architecture in color, so you can get an idea of the whole thing and come back, when reading the details later on.



Step 1: Create Azure Storage Account

As we are using Azure Storage to pass state object between controller and worker, we need to create our needed queues.


Please find all details here: https://docs.microsoft.com/en-us/azure/storage/common/storage-quickstart-create-account?tabs=azure-portal


Step 2: Create Azure Storage Queues

https://docs.microsoft.com/en-us/azure/storage/common/storage-quickstart-create-account?tabs=azure-portal


For our scenario, we need to create the following queues:

  1. approval-controller

  2. parallel-approval

  3. sequential-approval

  4. approval-logger


Step 3: Create Azure Storage Table

https://docs.microsoft.com/en-us/azure/cosmos-db/table-storage-overview

Step 4: Controller Flow

The Controller Flow is the main entity, handling the overall state of the process and being stateless itself. Compared to software development practices, this could be seen as the main routine of your application.

In this section you will learn how to implement it and all it's dependencies. If you want to learn more on the theory, please start with the Introduction or the the basics of the Controller Flow.

Flow Overview

Beauty often lies in simplicity. So, let's see how it's done. As you can see based on the sample implementation, this Flow has a very clear and easy to read and understand structure and is scalable in all dimensions.

Controller Flow - Overview

Part 1: Initialization

Let's start with implementing the queue trigger and store the state message object data in the Flow context.


1. Create a new Flow As a frist action, we need to create a new Flow. I suggest you create a Flow from blank and add your triggers and actions later on. For our scenario


2. Configure trigger action Use "When new message in queue" trigger from the Azure Queue actions and connect it to your storage account. Then choose the "approval controller" queue, which we created in the steps before as your trigger.


3. Initialize messageItem variable Create a new variable of type string to store the state message object. As value, set the "Message Text" property of the Azure Queue trigger to catch the message from the queue and prepare it for next steps.


As variables can't be initialized in a scope, add it, directly after the trigger and before the "Main" scope, which are going to create next.



Flow trigger and messageItem variable

Part 2 - Main Scope / Global Error Handling


Let's build our main Flow structure. As we want to do things right, we implement two scopes to group our actions and implement proper error handling based on the "Run after" configuration of the error handling scope.


Step 1: Create Main Scope

Add a new scope and name it as you like. I call it "Main" as the main appplication logic get's added in here. Add the scope directly under the messageItem variable.


Step 2: Create Global Error Handling Scope


A aproach to error handling in #Flow ist to make use of scopes and define their run after condition


Create a first scope to wrap your actions and with that define your error scope and granularity of error notification. Basically every action could have a separate error handling condition, but obviously this doesnt make any sense and you wouldn't to that in code eigther.


Create a second scope to put your error handling activities like logging to a #SharePoint list or any repository or send e-mail notifications



Step 3: Configure "Run after" properties


Configure the "run after condition" on the second "Error handling" scope to run only if the first "Main" scopehas an error

This simply catches the error and you can notify the process initiator and owner, so they can inspect the issue in the #Flow run history.





Parse JSON object input, write to variable

Add a switch to handle messageType

Add another switch to handle messagePayload

Create queue message for worker Flow




Worker Flow





Content Index

There is a lot more content available to you:

> Introduction

> Implementation Guide

> Controller Flow

> Worker Flows

> Post Processor Flow

> Azure Queue Storage

> Azure Table Storage

> JSON Message State Object


  • Grey Twitter Icon

© 2019 | Marcel Haas | marcel.haas@cnext.ch | +41 76 390 23 17