A design firm is working on a complex project. Project leadership decided to use ProjectWise workflows to manage review and approval process of project deliverables. Use of workflows will ensure that everyone in the project follows the same process.
The design work will be done by ProjectWise Explorer users. Design review will happen partially with native applications and partially in the Bentley Connect environment via ProjectWise Web. Most of approval work will be done by users who use only cloud.
Many of reviewers and majority of approvers are only occasional ProjectWise users. They will login to the system only when there is review or approve tasks pending.
Users need to be informed when there is something to review or approve. In the past projects communicating about new work was done manually by project team members. Sometimes the work was delayed because reviewers were not notified about pending reviews and they did not go into the system to check for it.
Project information manager has decided to improve project communication. She decided to create a distribution matrix in ProjectWise and a Microsoft Flow that will send notifications automatically based on the matrix.
This Flow was created using ProjectWise sample datasource available with ProjectWise Design Integration server installation. We have used project \Documents\Gas Authority, Inc\Groningen Refinery\BSI700 - Storage Facility Expansion for this example. Every ProjectWise configuration is unique, so this Flow may need to be adapted to your actual configuration and project requirements.
Distribution list for the project is stored in a new folder 900 – Admin\Distribution. Information manager created a new environment ‘Distribution’ for this purpose. The environment has these columns:
A notification will be sent to Email asking to do Action for all documents of ‘Complex’ environment in this project that are in State and have AreaShort code will be sent to Email for Action.
If there are several rules that match one document, then several people will be notified. For example, when something needs to be reviewed additional email can be sent for information to other people.
The project BSI700 has two new saved searches:
The image below shows major steps of the flow. The brown boxes are Scopes. In Microsoft Flow scopes are used to group several actions. Scopes were used in this flow to make break it down into separate major steps and make it easier to understand.
Let’s see what each major step is for:
First read document information, including attribute values, into array ‘Documents’.
This is done in two steps:
With some combinations of ProjectWise and WSG versions ‘Find documents by saved search’ action does not always return attribute values correctly. This flow retrieves attributes in a separate loop for better compatibility.
Distribution matrix information is retrieved using the same technique as documents:
In this part Flow fills in two variables declared below:
The Recipients variable will be simple array of email addresses that will be sent a notification email.
The NotificationItem is an array that has a distribution item matched with a document data.
Let’s see how they are filled in:
This scope contains a loop named ‘Apply to each document’. This loop runs for each document in Documents array.
The ‘Filter Array’ action takes document information and selects matching distribution rules. Expression used to filter is this:
@and(equals(item()?['attributes']?['AreaShort'], items('Apply_to_each_document')?['attributes']?['AreaShort']), equals(item()?['attributes']?['State'],items('Apply_to_each_document')?['statename']))
This long expression selects distribution items that have the same AreaShort and State values as current document.
Function items(‘loop name’) can only be used inside a loop and returns current loop item.
Function item() is used inside looping actions, like Filter Array in this case. It returns current item of the looping action.
The ‘Apply to each 3’ is used to fill NotificationItem and Recipient arrays.
‘Append to array variable 3’ simply stores current document and current distribution item into notification item array.
Then an email address is added to Recipient array, but only if it was not there before. Left side of Condition expression is this:
contains(variables('Recipients'), items('Apply_to_each_3')?['attributes']?['Email'])
The right one is:
@true
The last part of the flow is to send emails.
‘Apply to each 4’ loops through list of recipients. There will be one email sent per recipient.
‘Set variable’ begins new email body in HTML. We set some basic styling to make table have visible borders.
<style> table {border-collapse: collapse;} table, td, th {border: 1px solid black;} th, td {padding: 5px; text-align: left;} </style> <table> <tr> <th>Document</th> <th>Version</th> <th>State</th> <th>Requested Action</th> </tr>
<style>
table {border-collapse: collapse;}
table, td, th {border: 1px solid black;}
th, td {padding: 5px; text-align: left;}
</style>
<table>
<tr>
<th>Document</th>
<th>Version</th>
<th>State</th>
<th>Requested Action</th>
</tr>
‘Filter array 2’ selects distribution items for applicable this current email address. In advanced mode the where condition looks like this:
@equals(item()?['distr']?['attributes']?['Email'], items('Apply_to_each_4'))
‘Apply to each 5’ loops through filtered items and adds a single table row with document information as well as distribution information to EmailBody variable using ‘Append to string variable 2’:
<tr> <td>@{items('Apply_to_each_5')?['doc']?['name']}<br> (<a href='@{items('Apply_to_each_5')?['doc']?['projectShareUrl']}'>Web Link</a>) (<a href='@{items('Apply_to_each_5')?['doc']?['projectWiseUrl']}'>PW Link</a>)</td> <td>@{items('Apply_to_each_5')?['doc']?['version']}</td> <td>@{items('Apply_to_each_5')?['doc']?['stateName']}</td> <td>@{items('Apply_to_each_5')?['distr']?['attributes']?['Action']}</td> </tr>
<td>@{items('Apply_to_each_5')?['doc']?['name']}<br>
(<a href='@{items('Apply_to_each_5')?['doc']?['projectShareUrl']}'>Web Link</a>) (<a href='@{items('Apply_to_each_5')?['doc']?['projectWiseUrl']}'>PW Link</a>)</td>
<td>@{items('Apply_to_each_5')?['doc']?['version']}</td>
<td>@{items('Apply_to_each_5')?['doc']?['stateName']}</td>
<td>@{items('Apply_to_each_5')?['distr']?['attributes']?['Action']}</td>
Lastly ‘Send an email (V2)’ sends the email to a recipient (current item of ‘Apply to each 4’) with EmailBody variable as contents of the email.
The flow is ready to run now!
I hope someone is still watching this...I am trying to implement this flow, but am having some odd results.The PW search the flow runs returns seven (7) documents. When I run the flow, and even though I have only one recipient defined (me), I get seven identical emails, each listing all seven documents for approval.
Is there anyone out there than can help me, please?
Thank you,
Scott
Lookup values are usually built using documents without files. This example is using similar approach. It uses saved searches to find the needed contacts instead of SQL statements that would be used in attribute lookup configuration. With the recent update to Flow connector you can also get list of documents in a folder or run WSG queries to retrieve lists of documents. The latter would be closest to attribute lookup technique.
Could this process use User lookup values that are built in to an environment.
Example: Author of a document select who the checker and approver would be from a drop down list that called up from attribute lookups. These contain users email addresses.
Your suggestion is taken as a product improvement request. Thank you!
Audrius
Okay, then take my comments as a suggestion for an API addition, please :-)
Glenn, as of today, ProjectWise WSG plugin does not have functions to access ProjectWise access lists so we chose to use documents for contacts.
Interesting example. However, creating an environment just for distribution, especially when a workflow is in use, will not be desirable to most I think. Using a workflow, most would have workflow security and use user lists to control who can do what at each stage of the workflow.
So, following the example, we would have an access list for 'Pending Approval' and 'Pending Review'. These lists would have PW accounts in them that were authorised to 'review' and 'approve' at the relevant states in the workflow. Seeing as we have these already, why not have a flow action that reads a particular user list, grabs the users, reads their name and email from the user object and then uses that information to send notifications?
This way you are using existing user security access lists, which will be maintained and are most likely the single source of truth. Having to modify an access list AND the documents in the environment is not ideal IMHO.
Regardless, the examples provided are interesting - please keep them coming.
Regards
G.