Sunday, March 25, 2012

SharePoint 2010 State Machine Workflows with Custom Task Forms (InfoPath) using Visual Studio 2010 (Part 3)


Download Only State machine Example as guide in State machine Article at here
Open Project and view Flow Chart

Open Workflow1.cs

In method createTask1_MethodInvoking Delete all code and replace by this segment code

private void createTask1_MethodInvoking(object sender, EventArgs e)
        {
            try
            {
                //Create a new TaskId for the Task
                this.createTask1_TaskId1 = Guid.NewGuid();
                //TaskProperties field is used to configure the Task Details.
                this.createTask1_TaskProperties1.Title = "General Direct Manage Review";
                //You can assign a Task to an user or to a group.
                //Here we assign the task to Direct manager User
                this.createTask1_TaskProperties1.AssignedTo = "quochung-axioo\\Instructor";
                //Task Type corresponds to TaskURN specified in Elements.xml
                this.createTask1_TaskProperties1.TaskType = 1;
                this.createTask1_TaskProperties1.DueDate = DateTime.Today.AddDays(5.0);
            }
            catch (Exception ex)
            {
                //Logging is used so that we can debug the errors in the workflow.
                System.Diagnostics.EventLog.WriteEntry("mstechshareing.com Workflow",
                    ex.StackTrace, System.Diagnostics.EventLogEntryType.Error);
                LogToHistoryListActivity log = new LogToHistoryListActivity();
                log.HistoryDescription = ex.StackTrace;
            }
        }
In method onTaskChanged1_Invoked Delete all code and replace by this segment code

private void onTaskChanged1_Invoked(object sender, ExternalDataEventArgs e)
        {
            try
            {
                this.onTaskChanged1_AfterProperties1 = this.onTaskChanged1.AfterProperties;
                this.onTaskChanged1_BeforeProperties1 = this.onTaskChanged1.BeforeProperties;
                //Set the PercentComplete property to 1.0 (i.e. 100%)
                //to indicate that the task has been completed.
                this.onTaskChanged1_AfterProperties1.PercentComplete = (float)1.0;
            }
            catch (Exception ex)
            {
                System.Diagnostics.EventLog.WriteEntry("mstechshareing.com Workflow",
                    ex.StackTrace, System.Diagnostics.EventLogEntryType.Error);
                LogToHistoryListActivity log = new LogToHistoryListActivity();
                log.HistoryDescription = ex.StackTrace;
                //throw ex;
            }
        }
In method ReadyForReview Delete all code and replace by this segment code

private void ReadyForReview(object sender, ConditionalEventArgs e)
        {
            try
            {
                if (this.onTaskChanged1_AfterProperties1.PercentComplete == (float)1.0 )
                    //&&this.onTaskChanged1_AfterProperties1.
                    //ExtendedProperties["Status"].ToString().Contains("Approve")
                {
                    e.Result = true;
                }
                else
                {
                    e.Result = false;
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.EventLog.WriteEntry("mstechshareing.com Workflow",
                    ex.StackTrace, System.Diagnostics.EventLogEntryType.Error);
                LogToHistoryListActivity log = new LogToHistoryListActivity();
                log.HistoryDescription = ex.StackTrace;
            }
        }
In method createReviewTask_MethodInvoking Delete all code and replace by this segment code

private void createReviewTask_MethodInvoking(object sender, EventArgs e)
        {
            try
            {
                //Create a new TaskId for the Task
                this.createReviewTask_TaskId1 = Guid.NewGuid();
                //TaskProperties field is used to configure the Task Details.
                this.createReviewTask_TaskProperties1.Title = "HR Manager Review";
                //You can assign a Task to an user or to a group. Here we assign the task to HR User
                this.createReviewTask_TaskProperties1.AssignedTo = "quochung-axioo\\Learner";
                //Task Type corresponds to TaskURN specified in Elements.xml
                this.createReviewTask_TaskProperties1.TaskType = 2;
                this.createReviewTask_TaskProperties1.DueDate = DateTime.Today.AddDays(2.0);
            }
            catch (Exception ex)
            {
                //Logging is used so that we can debug the errors in the workflow.
                System.Diagnostics.EventLog.WriteEntry("mstechshareing.com Workflow",
                    ex.StackTrace, System.Diagnostics.EventLogEntryType.Error);
                LogToHistoryListActivity log = new LogToHistoryListActivity();
                log.HistoryDescription = ex.StackTrace;
            }
        }
In method onTaskChanged2_Invoked Delete all code and replace by this segment code

private void onTaskChanged2_Invoked(object sender, ExternalDataEventArgs e)
        {
            try
            {
                this.onTaskChanged2_AfterProperties1 = this.onTaskChanged2.AfterProperties;
                this.onTaskChanged2_BeforeProperties1 = this.onTaskChanged2.BeforeProperties;
                //Set the PercentComplete property to 1.0 (i.e. 100%)
                //to indicate that the task has been completed.
                this.onTaskChanged2_AfterProperties1.PercentComplete = (float)1.0;
                //Get the value of Remarks Column (InfoPath Form) by using the ExtendedProperties property
                //string remarks = this.onTaskChanged2_BeforeProperties1.ExtendedProperties["Remarks"].ToString();
            }
            catch (Exception ex)
            {
                System.Diagnostics.EventLog.WriteEntry("mstechshareing.com Workflow",
                    ex.StackTrace, System.Diagnostics.EventLogEntryType.Error);
                LogToHistoryListActivity log = new LogToHistoryListActivity();
                log.HistoryDescription = ex.StackTrace;
                //throw ex;
            }
        }

In method ReviewFinished Delete all code and replace by this segment code

private void ReviewFinished(object sender, ConditionalEventArgs e)
        {
            try
            {
                if (this.onTaskChanged2_AfterProperties1.PercentComplete == (float)1.0)
                {
                    e.Result = true;
                }
                else
                {
                    e.Result = false;
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.EventLog.WriteEntry("mstechshareing.com Workflow",
                    ex.StackTrace, System.Diagnostics.EventLogEntryType.Error);
                LogToHistoryListActivity log = new LogToHistoryListActivity();
                log.HistoryDescription = ex.StackTrace;
            }
        }
///////////////////////////////////   All Code ////////////////////////
using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Collections;
using System.Drawing;
using System.Linq;
using System.Workflow.ComponentModel.Compiler;
using System.Workflow.ComponentModel.Serialization;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Design;
using System.Workflow.Runtime;
using System.Workflow.Activities;
using System.Workflow.Activities.Rules;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Workflow;
using Microsoft.SharePoint.WorkflowActions;

namespace StateMachineWorkflow.Workflow1
{
    public sealed partial class Workflow1 : StateMachineWorkflowActivity
    {
        public Workflow1()
        {
            InitializeComponent();
        }

        public SPWorkflowActivationProperties workflowProperties = new SPWorkflowActivationProperties();
        public Guid createTask1_TaskId1 = default(System.Guid);
        public SPWorkflowTaskProperties createTask1_TaskProperties1 = new Microsoft.SharePoint.Workflow.SPWorkflowTaskProperties();

        private void createTask1_MethodInvoking(object sender, EventArgs e)
        {
            try
            {
                //Create a new TaskId for the Task
                this.createTask1_TaskId1 = Guid.NewGuid();
                //TaskProperties field is used to configure the Task Details.
                this.createTask1_TaskProperties1.Title = "General Direct Manage Review";
                //You can assign a Task to an user or to a group.
                //Here we assign the task to Direct manager User
                this.createTask1_TaskProperties1.AssignedTo = "quochung-axioo\\Instructor";
                //Task Type corresponds to TaskURN specified in Elements.xml
                this.createTask1_TaskProperties1.TaskType = 1;
                this.createTask1_TaskProperties1.DueDate = DateTime.Today.AddDays(5.0);
            }
            catch (Exception ex)
            {
                //Logging is used so that we can debug the errors in the workflow.
                System.Diagnostics.EventLog.WriteEntry("mstechshareing.com Workflow",
                    ex.StackTrace, System.Diagnostics.EventLogEntryType.Error);
                LogToHistoryListActivity log = new LogToHistoryListActivity();
                log.HistoryDescription = ex.StackTrace;
            }
        }

        public SPWorkflowTaskProperties onTaskChanged1_AfterProperties1 = new Microsoft.SharePoint.Workflow.SPWorkflowTaskProperties();
        public SPWorkflowTaskProperties onTaskChanged1_BeforeProperties1 = new Microsoft.SharePoint.Workflow.SPWorkflowTaskProperties();

        private void onTaskChanged1_Invoked(object sender, ExternalDataEventArgs e)
        {
            try
            {
                this.onTaskChanged1_AfterProperties1 = this.onTaskChanged1.AfterProperties;
                this.onTaskChanged1_BeforeProperties1 = this.onTaskChanged1.BeforeProperties;
                //Set the PercentComplete property to 1.0 (i.e. 100%)
                //to indicate that the task has been completed.
                this.onTaskChanged1_AfterProperties1.PercentComplete = (float)1.0;
            }
            catch (Exception ex)
            {
                System.Diagnostics.EventLog.WriteEntry("mstechshareing.com Workflow",
                    ex.StackTrace, System.Diagnostics.EventLogEntryType.Error);
                LogToHistoryListActivity log = new LogToHistoryListActivity();
                log.HistoryDescription = ex.StackTrace;
                //throw ex;
            }
        }

        private void ReadyForReview(object sender, ConditionalEventArgs e)
        {
            try
            {
                if (this.onTaskChanged1_AfterProperties1.PercentComplete == (float)1.0 )
                    //&&this.onTaskChanged1_AfterProperties1.
                    //ExtendedProperties["Status"].ToString().Contains("Approve")
                {
                    e.Result = true;
                }
                else
                {
                    e.Result = false;
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.EventLog.WriteEntry("mstechshareing.com Workflow",
                    ex.StackTrace, System.Diagnostics.EventLogEntryType.Error);
                LogToHistoryListActivity log = new LogToHistoryListActivity();
                log.HistoryDescription = ex.StackTrace;
            }
        }

        public Guid createReviewTask_TaskId1 = default(System.Guid);
        public SPWorkflowTaskProperties createReviewTask_TaskProperties1 = new Microsoft.SharePoint.Workflow.SPWorkflowTaskProperties();

        private void createReviewTask_MethodInvoking(object sender, EventArgs e)
        {
            try
            {
                //Create a new TaskId for the Task
                this.createReviewTask_TaskId1 = Guid.NewGuid();
                //TaskProperties field is used to configure the Task Details.
                this.createReviewTask_TaskProperties1.Title = "HR Manager Review";
                //You can assign a Task to an user or to a group. Here we assign the task to HR User
                this.createReviewTask_TaskProperties1.AssignedTo = "quochung-axioo\\Learner";
                //Task Type corresponds to TaskURN specified in Elements.xml
                this.createReviewTask_TaskProperties1.TaskType = 2;
                this.createReviewTask_TaskProperties1.DueDate = DateTime.Today.AddDays(2.0);
            }
            catch (Exception ex)
            {
                //Logging is used so that we can debug the errors in the workflow.
                System.Diagnostics.EventLog.WriteEntry("mstechshareing.com Workflow",
                    ex.StackTrace, System.Diagnostics.EventLogEntryType.Error);
                LogToHistoryListActivity log = new LogToHistoryListActivity();
                log.HistoryDescription = ex.StackTrace;
            }
        }

        public SPWorkflowTaskProperties onTaskChanged2_AfterProperties1 = new Microsoft.SharePoint.Workflow.SPWorkflowTaskProperties();
        public SPWorkflowTaskProperties onTaskChanged2_BeforeProperties1 = new Microsoft.SharePoint.Workflow.SPWorkflowTaskProperties();

        private void onTaskChanged2_Invoked(object sender, ExternalDataEventArgs e)
        {
            try
            {
                this.onTaskChanged2_AfterProperties1 = this.onTaskChanged2.AfterProperties;
                this.onTaskChanged2_BeforeProperties1 = this.onTaskChanged2.BeforeProperties;
                //Set the PercentComplete property to 1.0 (i.e. 100%)
                //to indicate that the task has been completed.
                this.onTaskChanged2_AfterProperties1.PercentComplete = (float)1.0;
                //Get the value of Remarks Column (InfoPath Form) by using the ExtendedProperties property
                //string remarks = this.onTaskChanged2_BeforeProperties1.ExtendedProperties["Remarks"].ToString();
            }
            catch (Exception ex)
            {
                System.Diagnostics.EventLog.WriteEntry("mstechshareing.com Workflow",
                    ex.StackTrace, System.Diagnostics.EventLogEntryType.Error);
                LogToHistoryListActivity log = new LogToHistoryListActivity();
                log.HistoryDescription = ex.StackTrace;
                //throw ex;
            }
        }

        private void ReviewFinished(object sender, ConditionalEventArgs e)
        {
            try
            {
                if (this.onTaskChanged2_AfterProperties1.PercentComplete == (float)1.0)
                {
                    e.Result = true;
                }
                else
                {
                    e.Result = false;
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.EventLog.WriteEntry("mstechshareing.com Workflow",
                    ex.StackTrace, System.Diagnostics.EventLogEntryType.Error);
                LogToHistoryListActivity log = new LogToHistoryListActivity();
                log.HistoryDescription = ex.StackTrace;
            }
        }

    }
}

///////////////////////////////////   End All Code ////////////////////////
Right click Workflow1 | Add new item | Module and provide name is Forms

Delete Sample.txt file and right click Forms Add | Existing Item (Image 10)

Right click to Workflow1 | Properties

Expand Feature Receiver:
At Assembly paste code: Microsoft.Office.Workflow.Feature, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c
At Class Name Paste code: Microsoft.Office.Workflow.Feature.WorkflowFeatureReceiver

Right click Workflow1.cs | Properties

At Deployment Type: choose ElementFile

Right click Feature1.Template.xml | Open

Copy this segment code and paste to here

<Property Key="RegisterForms" Value="Forms\*.xsn"/>
Right click to Elements.xml  of Workflow1| Open

Step 1: Copy this segment code and paste to here

TaskListContentTypeId="0x01080100C9C9515DE4E24001905074F980F93160"

Step 2: Copy this segment code and paste to here

<AssociationData>
    <Data></Data>
</AssociationData>

Step 3: Copy this segment code and paste to here (Image 20)

<Task1_FormURN>urn:schemas-microsoft-com:office:infopath:GeneralDirectorAppovePublish:-myXSD-2012-03-23T08-37-10</Task1_FormURN>
<Task2_FormURN>urn:schemas-microsoft-com:office:infopath:HRManagerApprovePublish:-myXSD-2012-03-23T09-35-52</Task2_FormURN>

Deploy Project
Open your site | go to Shared Documents | upload document | workflow automatic run

Click to “In Progress” link

You see have a Task is assigned to Direct Manager

Click to Title

Input Approve to Status and comment

After Direct manager was Approved, auto create new task and assign to HR Manager

Click to Title of HR Manager

Input Status and comment as follows:

After Direct Manager and HR Manager were Approved => Status is Completed

Back to Shared documents you see your document is completed

Download Project and Infopath form after Finished Project 

15 comments:

  1. Thanks Quoc Hung for the great post series and would like to clarify couple questions with you:

    1- Do you use GUID tool to generate TaskListContentTypeId="0x01080100C9C9515DE4E24001905074F980F93160"?

    What version of sharepoint 2010 you used: Foundation or Server and how about OS 32bit or 64bit for

    At Assembly paste code: Microsoft.Office.Workflow.Feature, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c
    At Class Name Paste code: Microsoft.Office.Workflow.Feature.WorkflowFeatureReceiver

    C. Ho

    ReplyDelete
  2. Thanks, on visual studio have available tool to generated GUID, but this is very important "0x01080100" this is content type of Tasks list, also C9C9515DE4E24001905074F980F93160 you can change number or any number on it, this thing i copy on internet then make 0x01080100 and C9C9515DE4E24001905074F980F93160 into one string of TaskListContentTypeId.
    version of SP 2010: 64bit

    ReplyDelete
  3. It is too helpful. Thanks for the post

    ReplyDelete
  4. This comment has been removed by the author.

    ReplyDelete
  5. Hi Quoc Hung its too helpfull for me but can you just explain how you created infopath form and how you integrated in your state machine workflow

    ReplyDelete
  6. Hi sukumar,
    you know i have 4 part for this article, you can see on 4 link below:

    Part 1: http://mstechsharing.blogspot.com/2012/03/sharepoint-2010-state-machine-workflows_2183.html
    part 2: http://mstechsharing.blogspot.com/2012/03/sharepoint-2010-state-machine-workflows_2141.html
    part 3: http://mstechsharing.blogspot.com/2012/03/sharepoint-2010-state-machine-workflows_25.html
    part 4: http://mstechsharing.blogspot.com/2012/03/sharepoint-2010-state-machine-workflows.html

    ReplyDelete
  7. Hi Quoc Hung,

    Thank you very much it was very useful for me I am doing the workflow user requesting and task created for manager then manager approved again task created for admin

    it was very usefull for me...............

    I have one query???
    When manager is rejected i dont want to create admin task and i want to complete the task list can you explain.....

    ReplyDelete
  8. Very Impportant....
    Hi Quoc Hung,

    Can you tell me I want to disable delete item link button....

    Please help me very urgent....

    ReplyDelete
  9. Hi Sukumar, very sorry about answer late,
    the first: When manager is rejected i dont want to create admin task and i want to complete the task list can you explain.....
    => you can design workflow at step manager reject (terminate workflow)
    the second: Can you tell me I want to disable delete item link button....
    this is default infopath feature, you need develop to disable it

    This article is so so, can not resolve all prolem!!!

    You can refer this articles:

    http://mstechsharing.blogspot.com/2012/05/create-workflow-with-custom-task-form_7581.html
    http://mstechsharing.blogspot.com/2012/05/create-workflow-with-custom-task-form_20.html
    http://mstechsharing.blogspot.com/2012/05/create-workflow-with-custom-task-form.html

    Thanks for comment.

    ReplyDelete
  10. Hi Quoc Hung,
    I am getting an error as failed on start(retrying) in document library.I thought it may be error in code so i tried it again but still getting the same error.can you please where can be problem

    ReplyDelete
  11. Hello Quoc Hung,
    I overcome the above error,but now i am getting other one,when i click the title in the list in the form
    infopath form is not getting opened showing an error as The specified form cannot be found.

    can you please help me to overcome this issue.......
    will be waiting for reply...

    ReplyDelete
  12. your sharepoint is sharepoint server or foundation, if it is SPS did you active infopath in central admin ?

    ReplyDelete
  13. Hello Quoc Hung,

    I am getting following error while deploying project.
    "Error occurred in deployment step 'Activate Features': Failed to create workflow association 'StateMachineWorkflow - Workflow1'. Cannot find SharePoint list with name "Shared Documents" or GUID "efe55f7f-f7f4-406e-816a-e98c6e6146a3"."

    Can U please help.

    ReplyDelete
  14. Hi,

    What's step you got error when you debug? you try check Shared Documents is exist or not?

    Thanks.

    ReplyDelete