Tuesday, August 14, 2012

Custom Approval Workflow in SharePoint

Download code from here

This workflow was created for beginner those wanted to learn the custom workflow in SharePoint from very scratch level.

Even I have created many complex workflows for my work in the past,I feel its time to introspect my knowledge on this simple workflow.

As I follow the many instruction those available in forums and blogs,I end up with confusion and if I wanted to apply my own business requirement out of this instruction,it was very tedious.

So here is the simplified version of my "Custom Approval Workflow in SharePoint using Visual Studio 2010".

Debugging is always enlighten you to apply and learn the secret of the workflow engine. Create a blank SharePoint project and add the new item from project template "Sequential Workflow".

On this design surface add the activities just like you seen here.

The workflow engine manage the following activities such as "Creating task and assigning to someone,after the task has been assigned to someone monitoring the status of Tasks(approved or rejected) and completing the task. Many times I was confused and identified the reason for it,assigning the correlation and Task Properties and Task id via "Property Window". Of course this will be useful for advanced developer[I personally feel those knows all properties of the task and workflow and how to apply these to their business requirement]. For simplicity I am going to create all properties behind the code and assigning to design surface. Required properties here I have created so far globally.
        public Guid TaskID = Guid.NewGuid();
        public SPWorkflowTaskProperties taskProp = new SPWorkflowTaskProperties();
        public SPWorkflowTaskProperties afterProp = new SPWorkflowTaskProperties();
        public SPWorkflowTaskProperties beforeProp = new SPWorkflowTaskProperties();
        public bool isComplete = false;
// This is nothing but "Task ContentType's" field "Status" GUID.
//You can find it by debugging the code line,You can find all field's guid and its value.
//HashTable tbl = afterProp.ExtendedProperites;
        public Guid idStatus = new Guid("c15b34c3-ce7d-490a-b133-3f4de8801b76");

Now we need to assign these properties to design workface.Once you created all these properties on code behind,you can see like this
Important tips to remember: Correlation token for task activities must be same throughout the workflow. So I am renaming the correlation token for my "CreateTask1" as taskToken. Assigning the Owner Activity to "Workflow1" just like below screenshot.
follow the same to all activities "OnTaskChanged1" and "CompleteTask". Secondly,We need to assign the unique GUID for task this one also common for all activities. Right click on CreateTask1 activities -> Properties and choose the "Task Id" click on the button and choose our own created "TaskID" for the task id. like shown here. And do the same for "Task Properties" too.
Here I am creating a method called "createTaskAndAssign".
private void createTaskAndAssign(object sender, EventArgs e)
        {

            taskProp.Title = "Type the title";
//Later you can try the dynamic title text may be workflow item's title using workflowproperties.
            taskProp.AssignedTo = "local\\administrator";
            taskProp.Description = "Please review";
            taskProp.DueDate = DateTime.Now.AddDays(2);

        }
Assign the above method to "MethodInvoking" properties of the "Create Task1" activity. For whileActivity you can manage your condition using "Code Declaration" or "Declarative Rule Condition. I have used "Code condition" you just need to assign the method name[CheckTaskStatus]to "Code Condition properties of "While Activity".
private void CheckTaskStatus(object sender, ConditionalEventArgs e)
        {
            e.Result = !isComplete; //When true - workflow ends up.
        }

Created a method for "OnTaskChange1" activity and assigned the same as did for while activity. This method will check the task content type's task status field value by using the task class's "ExtendedProperties".
 private void onTaskChangedInvoked(object sender, ExternalDataEventArgs e)
        {
            string tbl = afterProp.ExtendedProperties[idStatus].ToString();
            if (tbl.Equals("Completed"))
            {
                isComplete = true;
            }
            else
            {
                isComplete = false;
            }

        }
As soon as the boolean value set to true,the workflow calls the "Complete Task" activity and ends up its cycle. To test this demonstration on your development server,create two user for your sharepoint site and assign the task for them. And log in as different user by using new user check the "Task" list on their log do approve or reject and see the workflow status.