Background
In our organisation we have the nintex workflow actions tightly controlled as follows:
- Untrained users: no access to any actions
- Trained users: access to subset of actions
- SharePoint support users: full access to all actions
The reason for this is governance (which I will get round to blogging about one day I am sure). We do not allow the trained users any actions that can loop that with poor configuration could maybe bring down the environment or affect the performance in some way.
Problem
These trained users almost always have a requirement for a "reminder" workflow of sorts, to notify people when a document is due for review, or if a task is outstanding and x days overdue (like many users on the community). Anyone on the community with this requirement will have been sent by me to my blog post Site Workflow - Document Review Date Approaching Reminders or to the solution on Nintex Xchange Document Review Reminder Process. However, these users are not allowed any looping actions so are unable to use the for each and so, at the moment, have to come to SharePoint support staff to get the solution they require.
Solution - Site Workflow UDA
Inspired by Nintex Xchange and a UDA solution posted by Vadim Tabakman I decided to see if I could create a site workflow UDA whereby the UDA could do the looping for the user and it therefore wouldn't matter that they do not have access to the actions inside the UDA. This is one of the best things about UDAs - it's a fantastic way of empowering your users to do something cool without "letting" them develop it themselves. This way you have control of these more complex actions and can be confident that the environment won't be impacted by their configuration. Well, if they do impact environment performance, then you know who is to blame - haha.
I called the UDA "Notification Date Reached UDA" and configured it as follows:
Parameters:
Name | Type | Direction | Comments |
---|---|---|---|
List Name | Text | Input | The name of the list that the items need to be pulled from when meeting the date specified, I.e. "Procedures" |
Date Field Name | Text | Input | The name of the date field in the {List Name} to compare with the specified date |
Email Subject | Text | Input | Subject of email to be sent |
Email To Field | Text | Input | The name of the column used to locate the recipient of email |
Email Message | Text | Input | Body of email to be sent |
Error | Text | Output | To be used to store any error messages |
Number of Days After | Number | Input | If date comparison is not for today, but for x number of days after the event |
Number of Days Before | Number | Input | If date comparison is not for today, but for x number of days before the event |
Variables:
Name | Type | Comments |
---|---|---|
vCollReturnedIDs | Collection | Inside the UDA, the query list of the specified list name will return 0 or more items and store the IDs into the collection |
vDateComparison | Date and Time | The date calculated based on the parameters above to compare with the list and filter the returned items |
vTextCurrentID | Single line of text | The current item in the collection (stored as text for the CAML query) used to query the given list name to find the {Email To Field} value |
vTextNotificationContact | Single line of text | Used to store the value for {Email To Field} |
Workflow:
I do some checking of the "number of days after" and "number of days before" parameters. If both are zero then it would indicate that the user would like to match for items where {Date Field Name} = today's date. So in this instance I set variable value vDateComparison = Common:CurrentDate. If both parameters are not zero then it would imply that the user either wants to send a notification x days before the {Date Field Name}, or x days after. This logic does just that:
OK, so now we have our comparison date I go ahead and query the specified list matching where the specified date field = specified date. I do this using CAML query and return the IDs into the collection variable vCollReturnedIDs:
Using for each to loop through my collection, I use the current item in the collection (vTextCurrentID) and query the specified list again to get the specified {Email To Field}. This is again done with a CAML query as follows and outputs the variable vTextNotificationContact:
Still in the for each I send an email to the variable value returned using the subject and message body specified in the parameters. Job done.
Using this UDA
To use the UDA I created a brand new site workflow, added the UDA and configured it as follows:
and the list looked like this:
When I run the site workflow today (20/02/2017) I get three emails!
Flaws
Ok so this is early days and there are many!
- The fact that I need to use the internal names in my parameters (because of the CAML query). I don't want these users to loop for fear they don't understand looping, so do I think they will know how to find the internal name of a column?!
- This is only bringing back some dynamic data from the list - the rest is static. This could be extended to suit and pull additional information about the item due for review - but there doesn't seem to one size fits all approach when I have no idea what sort of list it will be used on
- At this point I have only set it up for either a date before or a date after. In reality most people want to remind before the date, remind on the date, and remind after the date! This can be easily overcome.
- (enter yours in the comments)
The solution will be posted on shortly.