Step by Step Tutorial. Creating Workflows for Windows Sharepoint Services and MOSS2007 (part 3/20)

 

 

image

By Serge Luca

MVP

image

 

Step 3/20. Extending the workflow: finding the manager and creating a custom activity

 
 

Download the code

The Scenario :

Click here to get to the previous article.

If the expense report requests manager approval, we need to find the current user’s manager and assign him a task. In this step, we will focus on finding the manager. We will code this in a custom code activity and we will refactor and encapsulate our code in a custom activity.

Make sure the Sharepoint object model namespace has been specified in ExpensereportWorkflow.cs:

 

using Microsoft.SharePoint;

 

Let’s create a general function that Retrieves a manager from a list :

 

        private string FindManager( string managerListTitle,
                                    string managerColumnName,
                                    string manageeColumnName,
                                    string managee,
                                    SPWeb webSite)
        {
    
           
            SPList managerList = webSite.Lists[managerListTitle];
            string manager = string.Empty;
            foreach (SPListItem managerItem in managerList.Items)
            {
                if (managerItem[managerColumnName] == null)
                    break;
                if (managerItem[manageeColumnName] == null)
                    break;
                //workflowProperties.Originator is the userId
                if (managerItem[manageeColumnName].ToString().Contains(managee))
                {
                    manager = managerItem[managerColumnName].ToString();
                    return manager;
                }
            }
            return manager;
        }

 

We can invoke this function from our requetsManagerApproval event handler:

SPWorkflowActivationProperties.Originator  is the user id of the workflow caller.

SPWorkflowActivationProperties.Web is the web site associated with the workflow instance.

 

        private void requestManagerApproval_ExecuteCode(object sender, EventArgs e)
        {
            string manager = this.FindManager(  "Managers",
                                                "Manager",
                                                "Manager Of",
                                                WorkflowProperties.Originator,
                                                WorkflowProperties.Web);
            WorkflowProperties.Item["Status"] = "Must be approved by " + manager;
            WorkflowProperties.Item.Update();
        }

 

Build the project, call install.bat and test the workflow by logging in with the “Serge” account (Serge’s manager is Jim)

 

There are still some extra characters we need to remove in the FindManager function 

 

                if (managerItem[managerColumnName].ToString().Contains(managee))
                {
                  
                    manager = manager.Remove(0, manager.IndexOf(‘#’) + 1);
                    return manager;
                }

Build the project, call install.bat and test the workflow :

Creating a Custom activity

If we need to access the FindManager function in several workflows it make sense to encapsulate it in an Custom activity.

Add a new Workflow project the  solution : select the Workflow  Activity Library template; name it U2U.ManagerActivity:

Reference  Microsoft.Sharepoint.dll in order to use the Sharepoint Object Model :

Delete the file Activity1.cs and add a new Activity component (Select Add new Item-Activity).

Name the file RetriveManager.cs:

 

Go the  activity code and derive RetrieveManager from the Activity class :

 

            public partial class RetrieveManager: Activity
            {
            public RetrieveManager()
            {
                  InitializeComponent();
            }

Declare:

using Microsoft.SharePoint

Define a public property for each data that can be know at design time :

 

  • ·         ManagerListTitle,
  • ·         ManagerColumnName,
  • ·         ManageeColumnName

 

We have to define a dependency property for each information that can only be retrieved at runtime:

  • Managee
  • WebSite

Make sure the snippet for dependency property is available, otherwise click on CTRL K+B , select Visual C# and add the workflow folder :

Define a dependency property for the WebSite :

 

Replace MyProperty with WebSite:

 

Replace the type with SPWeb:

 

 

Create another 2 other Dependency properties : Managee and Manager; keep string as the type.

Override Execute Method of the Activity:

 

        protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
        {
           
            return ActivityExecutionStatus.Closed;
 
        }

Call the Findmanager function in Execute()

 

        protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
        {
           this.Manager = this.FindManager(
                this.ManagerListTitle,
                this.ManagerColumnName,
                this.ManageeColumnName,
                this.Managee,
                this.WebSite);
 
           return ActivityExecutionStatus.Closed;
        }

      }

 

Sign and rebuild your assembly.

If you display  the ExpenseReportWorkflow in the Workflow Designer, the new Activity should show up in the toolbox :

We can drag and drop it just before the RequestManagerApproval activity:

 

Set  the properties known at design time: (pay attention to the case sensitivity):

 

Select the WebSite property , click on the ellipsis button (…) and bind it to an existing member : the Web property the WorkflowProperties field :

 

 

Select the Managee property and bind it to an existing member  : the Originator property of the workflowProperties member :

 

The activity will retrieve the manager and we will store this maneger into a new workflow property :

Create a new public field in the workflow : Manager

 

       public sealed partial class ExpenseReportWorkflow: SequentialWorkflowActivity
       {
        public string Manager;

 

Bind the activity Manager property to rthe workflow Manager property:

 

In the workflow, update  the requestManagerApprovalexecuteCode function to display the Manager:

 

        private void requestManagerApproval_ExecuteCode(object sender, EventArgs e)
        {
            WorkflowProperties.Item["Status"] = "Must be approved by " + this.Manager;
            WorkflowProperties.Item.Update();
        }
 
Set  the copy local property  of the reference to the U2UManagerActivity assembly to true:
 

 
Sign the new project, rebuild the solution and update install.bat in order to register the new assembly into the Gac.

Make sure your account has a manager defined in the Managers list.

Build the project and test the workflow. If you get the error message "Failed on start", this probably means that the activity assembly has not been registered into the Gac.


This hands-on training is the property of Redwood S.L sprl and may not be organized in class or in group without the prior written permission of Serge Luca. Should you wish to organize this hands-on training in your company or institution, please contact Serge Luca  first to enter into a licence agreement. Each trainer or teacher using this hands-on training should have a licence agreement. Please ask your trainer or Serge Luca whether he or she has entered into a licence agreement with Redwood S.L sprl.

The hyperlink to this hands-on training may be placed on your website for free, on the condition that the name Serge Luca is clearly mentioned in the reference. Please send us a mail containing the link to the web page our reference is used on.


One response to “Step by Step Tutorial. Creating Workflows for Windows Sharepoint Services and MOSS2007 (part 3/20)

  1. serge following this example was a little frustrating because you were a little confusing for me. my first problem was that you mentioned we must add 3 properties and after that you defined 3 dependency properties. I believed they are one and the same 😦 the second problem was that you never mentioned to remove the FindManager from the main project. I found eventually what I needed to know in the source code of the next step. and there is the second time when I am having errors in the SharePoint site because the workflow did not compile properly.
    but, overall, I must tell you that you are doing a great job with this tutorials and that you offer hints and solutions for problems that can not be found anywhere else on the net.
    keep it going 🙂

Leave a comment