Tag: Workflow/BPM

Use the Status Bar to Display Active Workflows

Over the past six months I’ve found myself moving more and more towards using the new Client OM for things that I used to use jQuery and SPServices for.  While I still love SPServices, it is not always required and now that I am getting more knowledgeable about how to do things in the Client OM, things are getting a lot easier (although you have to go back to writing CAML).

After a recent session at SharePoint Saturday The Conference an attendee asked me about ways to show a user they have an open workflow task.  After thinking about it, it was pretty similar to something else I had done recently that involved reading for a SharePoint list and adding an item to the status bar using the Client OM.  This particular request involved a little more code in order to properly filter down the task list, but it works like a charm.  It is important to remember that the client OM only works within the given Site Collection, and this particular code as-is will only look at the site the user is on at the time.

If you want this to display on a single page, you can simply add it to the page. In order to have it show up throughout the site though, you will want to add it to the MasterPage. If the MasterPage is used throughout many sites and or site collections, it will show any open tasks for the specific site.

To start off, we will create a div container. I typically put something like this just inside the tag of the MasterPage. Add in some global variables and then add in the Ajax Execute/Delay command that will call the first method, getUser() when the page is fully loaded.

   <div id="SetStatus"><script type="text/ecmascript" language="ecmascript">
    var url = '';
    var statusId = '';
    var isitDlg = window.location.href.match(/isDlg/i) != null;
    var taskOutput;
    var context = null;
    var web = null;
    var curUser = null;

    if (!isitDlg) {
        ExecuteOrDelayUntilScriptLoaded(getUser, "sp.js");
    }
</script></div>[/sourcecode]   

Next, within the script block we will add the methods to support getUser(). These methods will get the current user's information which is needed to be able to load only the current user's assigned tasks.

[sourcecode language="js"] function getUser() { context = new SP.ClientContext.get_current(); web = context.get_web(); curUser = web.get_currentUser(); curUser.retrieve(); context.load(web); context.executeQueryAsync(Function.createDelegate(this, this.onSuccessMethod), Function.createDelegate(this, this.onFailureMethod)); } function onSuccessMethod(sender, args) { var user = web.get_currentUser(); LoadNotifications(); } function onFailureMethod(sender, args) { alert('Error: ' + args.get_message() + 'n' + args.get_stackTrace()); }

With the user’s name available we can now read the list items from the local Task List that are active and assigned to the user. If successfull the (ReadListItemSucceeded() method is called otherwise if an error is raised the ReadListItemFailed() is called.

function LoadNotifications() {  	
var listTitle = "Tasks";  	
context = SP.ClientContext.get_current();  	
var list = context.get_web().get_lists().getByTitle(listTitle);  	
var camlQuery = new SP.CamlQuery();  	
camlQuery.set_viewXml("<view><query><viewfields><fieldref name="ID" /><fieldref name="Title" /><fieldref name="FileDirRef" /><fieldref name="StartDate" /><fieldref name="DueDate" /></viewfields><where><and><eq><fieldref name="AssignedTo" /><value type="User">" + curUser.get_title() + "</value></eq><or><eq><fieldref name="Status" /><value type="Choice">In Progress</value></eq><eq><fieldref name="Status" /><value type="Choice">Not Started</value></eq></or></and></where></query></view>");  	
this.listItems = list.getItems(camlQuery);  	
context.load(listItems);  	
context.executeQueryAsync(ReadListItemSucceeded, ReadListItemFailed);  
}  

The returned list of tasks is now processed and the output is prepared. If tasks are prepared, the SetStatus() method is called to show the status bar message.

function ReadListItemSucceeded(sender, args) {  	
var itemCount = 0;  	
taskOutput = " <div id="tasks"> <table width="800"> <tbody> <tr style="font-weight: bold"> <td width="500">Task</td> <td width="150">Start Date</td> <td width="150">Due Date</td></tr>";  	var items = listItems.getEnumerator();          
while (items.moveNext()) {             
itemCount += 1;             
var listItem = items.get_current();             
var isLate = false;             
taskOutput += "<tr><td><a href="&quot; + listItem.get_item(" FileDirRef') + "/DispForm.aspx?ID=" + listItem.get_item('ID') + "' target='_top'>" + listItem.get_item('Title') + "</a></td><td>" + listItem.get_item('StartDate') + "</td><td>" + listItem.get_item('DueDate') + "</td></tr>";         
}         
taskOutput += "</table></div>";         
if (itemCount > 0) {             
SetStatus("Reminder: ", "You have a workflow task! <a href="javascript:ShowTasks()">View open Workflow Tasks</a>", isLate);         
} 
} 
function ReadListItemFailed(sender, args) {         
alert('Error: ' + args.get_message() + 'n' + args.get_stackTrace()); 
} 

The SetStatus() method shows how simple it is to work with the Client OM. The SP.UI.Status.addStatus call will post the message including the title and the body of the message. We then make a second call to SP.UI.Status.setStatusPriColor to change the color of the bar. Pretty simple, yet so powerfull!

function SetStatus(title, message, isLate) { 	
statusId = SP.UI.Status.addStatus(title, message, false);         
if (isLate) {             
SP.UI.Status.setStatusPriColor(statusId, 'red');         
}         
else {             
SP.UI.Status.setStatusPriColor(statusId, 'yellow');         }     } 

The last method is the ShowTasks method which is the javascript function that is called from within the status messages to show a simple output inside of the Client OM’s ModalDialog. First format the display options for the window and then call the SP.UI.ModalDialog.showModalDialot() method.

function ShowTasks() {  	
var _html = document.createElement('div');  	
_html.innerHTML = taskOutput;  	
var options = { html: _html, autoSize:true, allowMaximize:true, title: 'Open Workflow Tasks', showClose: true };  	
var dialog = SP.UI.ModalDialog.showModalDialog(options);  
}  

Not a lot of code to provide a very usefull solution that does not require anything to be deployed to the server. Below are screenshots of the solution in action.

Open Workflow Tasks Status

Open Workflow Tasks Listing

There are definitely some things that can be done to better format the output of the ModalDialog, but you get the idea. This is just one way to leverage the Client OM for some very useful business features.

SPS The Conference Slides and Additional Info

SharePoint Saturday The Conference has been a pretty impressive event so far.  It is amazing how well it has been run which is a real testament to the organizers and volunteers that have made it all happen. 

Both of my sessions seemed to go off fairly well, hopefully everyone managed to learn something and has a takeaway.

Here is the slide deck for the Developing Reusable Wokflow Features as well as the VS project code for SPBlueprints.Activities.

Here is the slide deck for the afternoon session Getting the Most from the User Profiles.

Another full day of sessions tomorrow, with many great sessions still on the schedule.  I’ll be roaming around as an attendee, if you have any questions feel free to stop and say hello.

SharePoint Saturday New York– Wrap-up

SharePoint Saturday New York has been a lot of fun with a great set of speakers, volunteers, and attendees. 

A big thank you to everyone that sat through my presentation on Developing Reusable Workflow Features.  The slide deck is available here:  http://www.slideshare.net/nextconnect/developing-reusable-workflow-features 

And the Visual Studio project is available here:  SPBlueprints.Activities

I hope that the information was helpful!

A Portfolio Approach to Developing Workflows and Processes

One of the common pitfalls I see with process optimization projects is that they tend to focus on a specific process at a time.  This may be ok when you are just starting out, or working with informal processes, but as the number of complex processes improves it is important to try and take a step back and look at things from an overall portfolio perspective.  In many cases processes overlap or are interrelated.  I most often see this in finance processes because they are so common in all organizations.  Something like a Check Request process should be a pretty standard, well defined process but it is often part of a number of other process flows.  It is easy to ignore the fact that the same steps and activities are followed elsewhere, but that leads to a lot of extra work for the process designers and administrators as well as non-standard activities for your process workers to follow.

To overcome this, it is important to consider the following points when analyzing and designing the process:

  • Is there a natural collection of steps or activities?
  • Are these steps also done to support another process?
  • Is a different group or department responsible for those steps?

While performing the process analysis and design, some activities may form a natural grouping.  It could be a set of steps that are referred to under a particular label and they are likely to be assigned to or processed by a specific group of users.  For large complex workflows, it may be a good idea to make that a sub-process that can be referred to as a set unit.  It is important to talk to the stakeholders that perform those tasks and understand if those same tasks or processes are are also performed to support another process.  If they are, then it would be better to design a standard sub-process that is called from the other processes than to build in the specific steps into each process.

The Check Request example I mentioned before is one that I have seen come up in more than one organization.  There is a set of common steps where requests have to be approved, logged, and then processed.  Standard compliance activities are another example of a common central process that may be leveraged by a number of other processes.  Some times these opportunities present themselves early, but other times you have to dig to identify these sub-processes.  In cases where there are multiple groups involved the main process owner or stakeholder may not fully understand the details of how every step is executed so it is important to interview the actual project participants to understand what they are doing and other processes that may use those steps.  Within the Check Request example, it is unlikely that a process owner in Operations understands all of the various corporate activities that may generate a check request, they only understand that it is part of their one process.  By talking to the process workers in Finance, the other perspective can be considered.

By taking a Portfolio Approach in this case, you can potentially make real improvements that extend the process design and automation benefits not just to the one process, but to multiple processes across the entire organization.  Those processes will also get easier to expand and manage as they can leverage common sub-processes and existing functionality.

SharePoint Designer 2010 Available Workflow Actions

A colleague of mine was asking for a comprehensive list of available workflow actions in SharePoint Designer 2010.  I did some searches and couldn’t find the details so I thought I would provide them here.

Core Actions
  • Add a Comment 
  • Add Time to Date 
  • Do Calculation 
  • Log to History List 
  • Pause for Duration 
  • Pause until Date 
  • Send an Email 
  • Set Time Portion of Date/Time Field
  • Set Workflow Status 
  • Set Workflow Variable 
  • Stop Workflow
Document Set Actions
  • Capture a version of the Document Set 
  • Send Document Set to Repository 
  • Set Content Approval Status for the Document Set 
  • Start Document Set Approval Process
List Actions
  • Check In Item 
  • Check Out Item 
  • Copy List Item 
  • Create List Item 
  • Declare Record 
  • Delete Item 
  • Discard Check Out Item 
  • Set Content Approval Status
  • Set Field in Current Item 
  • Undeclare Record 
  • Update List Item 
  • Wait for Field Change in Current Item
Relational Actions
  • Lookup Manager of a User
Task Actions
  • Assign a Form to a Group 
  • Assign a To-do Item 
  • Collect Data from a User 
  • Start Approval Process 
  • Start Custom Task Process 
  • Start Feedback Process
Utility Actions
  • Extract Substring from End of String 
  • Extract Substring from Index of String 
  • Extract Substring from Start of String 
  • Extract Substring of String from Index with Length 
  • Find Interval Between Dates

I was disappointed to report that there is still no out of the box action for calling a Web Service or action to bring back other attributes of the User’s Profile.  Custom or Third-Party actions will still have to be used to support this.

User Profiles – Driving Business Process

The workflow features first introduced in WSS 3.0/MOSS in 2007 and enhanced in the 2010 offerings present an opportunity for organizations with SharePoint to start to automate the coordination of their business processes.  While many have been working with it, one of the limitations I have seen is that everything is localized to a particular site or process.  In many cases there are configuration or user attributes managed in a local list that can be used as a data source. 

Manage the Data Centrally

One technique that is not widely used, but could greatly enhance the capabilities and manageability of the workflows as a whole would be to utilize the User Profiles more to house and maintain information relating to the users.  By managing it centrally it can be used by all processes throughout the organization.  For user maintained properties, it provides a central and secure mechanism for them to maintain it.  For system maintained properties, synchronized from an external system through AD or the BCS (HRIS, CRM, etc) there are already mechanisms in place to manage this.

In SharePoint Designer 2010 there is a new action that supports a lookup for a user’s manager.  This would be a critical component to support approval workflows obviously, but for most business processes there are other attributes that are also needed.  Some could be based on default user profile fields like Location or Hire Date, but others are likely to be custom to the organization.  Custom properties could include employee IDs, department charge codes, division identification, etc.  [Note: See User Profiles – Creating Custom Properties for a walk through] 

How to Access the Data

Typically the information is accessed via the API with UserProfileManager or the UserProfileService web service (/_vti_bin/userprofileservice.asmx).

InfoPath – From InfoPath you can identify a DataSource through a Web Service call pointing to the UserProfileService.  [Note: See Itay Shakury’s blog for full walk through]

Visual Studio Workflows – In visual studio with the full ASP.NET capabilities it is easiest and most effective to use the UserProfileManager to access the profile and all properties.

SharePoint Designer Workflows – With the exception of the manager lookup action that was added, SharePoint Designer workflows will need either a custom or third party action that can interact with the User Profiles. 

I am currently working on a simple action that I will blog about and post to CodePlex.

Other Uses – Delegation of Authority

This process could also be used to provide a mechanism for maintaining additional, more complex properties.  An example would be something like Delegation of Authority which allows a person of authority to be able to delegate (or pass) that responsibility to another person.  SharePoint does not handle this at all out of the box.  A series of fields could be defined to support this; Start Date, End Date, Delegate.  This information could be read into the discrete processes with management being centralized in the User Profiles.

The limitation with this model is that the User Profiles are not like a list and do not support advanced business rules.  If that is required a separate system would need to be build, but I would recommend you try and keep it centralized and not built into the specific process.

Summary

By leveraging the User Profiles as a central repository that can support your organization’s processes you will simplify the management of the information and make it much easier to reuse in a consistent manner across the many processes. 

Finding the Sweet Spot with Process Improvement

Today while visiting a grocery (super-)store I witnessed a strange event in the parking lot where a couple of guys were “pushing” carts.  This is something I did in high school so it is a task I understand very well.  They had a 60’ plus train of carts along with a motorized device at the end that helped to push which is what grabbed my attention.  My assumption is that since they had the motorized device (technology innovation) they could take on more work (process efficiency).  What I witnessed was something completely different.  I watched them for well over five minutes.  In that time the train grew and grew and became very difficult to manage.  You can also imagine that a 60’ train of carts in a busy parking lot blocks quite a few cars, including my own.  From my time of pushing carts I knew what a manageable load was and that it was often more efficient to manage smaller subset of work.  In the time I watched them in this farce, the two individuals without the aid of any motorized cart should have been able to collect and return twice what they ended up collecting without unconvincing any of the customers by blocking them in.

This story is a great example of what happens when you overuse technology in an attempt to increase business efficiency.  It is important to look for the sweet spot, adding just enough value without overbuilding or you will see diminished returns. 

I’m sure everyone that has worked with workflow or Business Process Management (BPM) for any period of time will have lived through projects that went passed the sweet spot.  It is not always as clear as the shopping cart story above.  In my experience it typically comes from either trying to automate too much in a previously manual process or from trying to handle too many process exceptions.  One of my favorite things about process improvement is that it is not a one cycle process.  You go through iterations of improvement and continue to tighten up the process.  With this iterative approach it affords the team some time to automate the manual processes and helps the process mature a bit before you try and handle all of the potential exceptions. 

In one project where clearly things had been taken too far, the team had spent a pretty substantial amount of time working through all of the different types of process exceptions.  I think there were eight possible paths at one point.  After the process went live we ended up finding that a few of the paths were never followed, and a few others were followed fewer than 3% of the time.  Clearly mistakes had been made and the process was overbuilt.  Working in a few steps that were a bit more generic and only partially automated would have been a better alternative.  By planning smaller, more focused iterations you will show value quicker and make it a lot easier to plan the next improvement cycle. 

%d bloggers like this: