Cost Workflow Settings page – CU2 changes

Code Samples, Project Financial Server, SDK

The upgrade to CU2 brings some changes to the behavior of the Cost Workflow Settings page. Prior to CU2, for Enterprise Project Types with workflows, the page displayed only the stages used by the associated workflow. Currently, for EPTs with workflows other than the out-of-the-box workflow (UMT Project Financial Server 2010 Sample Workflow), it displays all the stages defined in Project Server, regardless of whether they are used by the workflow or not.

image

image

This does not affect the functioning of the workflows in any way; you can simply configure only the relevant stages for the workflow and ignore the rest.

To revert to the old behavior and have the page display only the stages which are relevant for the EPT’s workflow, you should implement a WorkflowMetadataProvider class for your workflow and register it. To this extent new classes and interfaces are exposed in the UMT.CostModule.Library assembly.

The WorkflowMetadataProvider class must implement the GetStages method of the UMT.CostModule.Library.Workflow. IWorkflowStageListProvider interface, returning a list of UMT.CostModule.Library.Workflow.WorkflowStageInfo objects. Each WorkflowStageInfo element specifies the identifier of the stage, the order in the workflow, if it supports PFS settings (it contains EnterFinancialStage and LeaveFinancialStage activities), if it has approvals or if it is a final stage.

The following code snippet shows how to create the WorkflowMetadataProvider for the Workflow.MajorWithPFS workflow delivered with the Project Financial Server Demo Content Pack:

public class WorkflowMajorWithPFSMetadataProvider : IWorkflowStageListProvider
{
    public WorkflowMajorWithPFSMetadataProvider(WorkflowMetadataManager wmm, Guid templateId)
    {
        //must provide this constructor to be able to unregister the provider
    }

    #region IWorkflowStageListProvider

    public List<WorkflowStageInfo> GetStages(SPWorkflowAssociation association)
    {
        List<WorkflowStageInfo> projectWFStages = new List<WorkflowStageInfo>();
        //Initial review
        projectWFStages.Add(new WorkflowStageInfo(
           1, new Guid("1c18ba89-cc47-49c6-b0ce-8ee3baf4fb84"), false, false, false));
        //Define
        projectWFStages.Add(new WorkflowStageInfo(
           2, new Guid("3605914b-6652-44b3-88e1-80cc34a2af77"), true, false, false));
        //Select Checkpoint
        projectWFStages.Add(new WorkflowStageInfo(
           3, new Guid("cddff07c-c646-4dd3-86dc-51837efc228f"), true, false, false));
        //Rejected
        projectWFStages.Add(new WorkflowStageInfo(
           4, new Guid("1368af1b-911e-4829-b51c-2a591afd3b39"), false, false, false));
        //Not Selected
        projectWFStages.Add(new WorkflowStageInfo(
           5, new Guid("ceb058a6-4e4d-4583-86dc-052fad340912"), true, false, false));
        //Plan Stage
        projectWFStages.Add(new WorkflowStageInfo(
           6, new Guid("71074ec0-4693-40fd-9636-b4f2f8b2c1e7"), true, false, false));
        //Plan Checkpoint
        projectWFStages.Add(new WorkflowStageInfo(
           7, new Guid("dd1f6c66-a56c-436d-98d8-f82a17ad2e9a"), true, false, false));
        //Manage Stage
        projectWFStages.Add(new WorkflowStageInfo(
           8, new Guid("851172ab-d7b7-47dd-ac60-5ba32447823c"), true, false, false));
        //Manage Checkpoint
        projectWFStages.Add(new WorkflowStageInfo(
           9, new Guid("04f73c81-98d9-4f12-9ce4-1ffb7b7d1c38"), true, false, false));
        return projectWFStages;
    }

    #endregion
}

The assembly containing the provider must be deployed to the GAC, we recommed that you include the class in the same assembly as the workflow code. You have to also register the newly created provider using the UMT.CostModule.Library.Workflow.WorkflowMetadataManager class:

//this is the Id value in the Elements.xml file of the workflow feature
Guid wfTemplateUid = new Guid("E02FD620-3433-4e09-8D09-FFCAB4A5CAEF");

using(SPSite site = new SPSite("http://project.contoso.com/pwa/"))
{
    using (SPWeb web = site.OpenWeb())
    {
        WorkflowMetadataManager wfMetadataManager = new WorkflowMetadataManager(web);
        wfMetadataManager.RegisterProvider(wfTemplateUid, typeof(WorkflowMajorWithPFSMetadataProvider));
    }
}

The WorkflowMetadataManager class also provides methods to unregister the provider, when removing the workflow from the PWA site. It is convenient to register/unregister the metadata provider on the activated / de-activated event handler for the workflow feature.

The product SDK will be updated in the following days to include these changes.

What do you think?