By: Neil Barkhina
In the many years that I have worked with SharePoint workflows, I have found that one most asked for components is a loopback. The idea behind the loopback workflow is if you have for example 2 approvers, where the first one approves and the second rejects, the workflow should “loop back” to the first approver. This process will continue until both parties give their approval.
There are many different ways to create and leverage workflows in SharePoint 2010. Generally speaking, workflow comes in 3 different flavors:
1) Out of the Box: these include all the workflows you get in the SharePoint interface including Approval 2010 and Collect Signatures.
2) SharePoint Designer: you have more control over actions such as sending emails, delays, and variables. Deployment is easy and can be done by non-developers.
3) Visual Studio: this gives you full control of your workflow leveraging the entire .NET framework. However the solutions can only be deployed by a system administrator through central admin.
In order to create a true loopback workflow, the only option I have found is through Visual Studio. I was really hoping that Designer would allow for loopbacks but that did not make it in this release of SharePoint. When searching the web for information on how to create a loopback workflow, I had trouble finding a good template or sample code. In this post I will highlight the key components of this workflow and at the end you will also find a link to download the code so you can use this as a starting point in creating your own loopback workflows.
Workflow Architecture

The entire workflow runs inside a single while activity. Within that is a sequence activity with two more while activities for the two task change events.
While Loop
The main while loop uses a code condition to check if both people have approved their tasks. This is stored in the workflow code as simple bool variables.
private void while_bothnotapproved(object sender, ConditionalEventArgs e)
{
if (accounting_approved.Equals("Approved") && marketing_approved.Equals("Approved"))
bothapproved = true;
if (bothapproved)
e.Result = false;
else
e.Result = true;
}
Creating the task
The next component is creating the task. This is done in the createTask activity. You have to set the task ID to a new GUID because each time it loops back you need to make sure it’s a new task. Then you set some properties on the task such as the title, assigned to and percent complete. In this example I simply hard coded the Assigned To field but what you can do is capture these values from a workflow initiation page.
private void createTask1_MethodInvoking(object sender, EventArgs e)
{
this.createTask1_TaskId1 = Guid.NewGuid();
SPListItem item = workflowProperties.Item;
this.createTask1_TaskProperties1.Title = "Review task for Accounting - " + item.Name;
if (createTask1_TaskProperties1.AssignedTo == null)
{
this.createTask1_TaskProperties1.AssignedTo = "gig-werks\\neilb";
}
this.createTask1_TaskProperties1.PercentComplete = 0.0f;
this.createTask1_TaskProperties1.SendEmailNotification = true;
}
Within the workflow designer you will need to set up several properties. I have found that these settings must be done perfectly or else the workflow will bomb. The key things to remember here are when setting the TaskId and TaskProperties, I like to use fields versus .NET properties. For the correlationToken just type taskToken1 and make sure the ownerActivityName is the sequence activity. On the second task you will type taskToken2 with the same ownerActivityName.

On Task Changed
How you want to determine the completion of the tasks is entirely up to you. You can check for the % complete, or the Status. In my case I actually chose to have a Choice Column on the Task List with the choices “Pending”, “Rejected” and “Approved”. During the On Task Changed event I simply extract that value using the following code:
private void onTaskChanged1_Invoked(object sender, ExternalDataEventArgs e)
{
try
{
accounting_approved = workflowProperties.TaskList.Items.GetItemById(onTaskChanged1_AfterProperties1.TaskItemId)["Approval"].ToString();
}
catch (Exception ex)
{ }
}
Again as with the Task Created activity, make sure you use that same taskToken1 Correlation Token and also set the owner to sequenceActivity1.

As I mentioned earlier, after I deployed this solution I created a choice column on the Task List called Approval. I also hid all the other columns from the Workflow Task content type to make the interface a little friendlier for end users. Once all this is done, here is what your edit form should look like:

If you would like to download the visual studio project, you can get it here:
http://www.thesharepointblog.net/Documents/LoopbackWorkflow.zip
By: Neil Barkhina