Showing posts with label Project Server 2007. Show all posts
Showing posts with label Project Server 2007. Show all posts

Monday, May 31, 2010

Daily Timesheet Comment in Project Server 2007

Project server, Out of the Box, Timesheet (my timesheet) allow us to enter comments for each task (single comments for whole week). But it does not allow us to enter daily comments for each task.
For Example, in one week I have worked on 2 tasks , as - Task 1 - Mon , Tue, Wed ; Task2 – Thu , Fri
OOB I can only enter 2 comments (one for Task 1 and one for Task 2) , there is no provision for entering comments for individual day. So it is difficult for a manger to find out what a resource has done on any day (date).
We can accomplish this with the help of ‘Enterprise Custom Field’ features in following way…..
  • Add New Custom fields -
    • Open Server Setting page and click on Enterprise Custom Field Definition link (Server Settings -> Enterprise Data section -> Enterprise Custom Field Definition)
    • On Custom Fields and Lookup Table page , Click on New Field button
    • Create new comment field of type Task for Monday
    • Similar way create comment fields for other day e.g. Comment(Tue), Comment(Wed),Comment(Thu), Comment(Fri), Comment(Sat), Comment(Sun)
  • Edit MyTimeSheet View - Now add all these field into my timesheet entry screen (Mytimesheet view)
    • On Server Setting Page , Click on Manage View link (Server Settings -> Look and Feel section -> Manage Views)
    • On Manage View page , Click on my timesheet view under Timesheet Section
    • Add all the comments fields in the order of day (Comment(Mon) .. Comment(Sun))
    • Comment Will appear in time sheet entry screen , like this
      Now user can enter daily comments for each individual task.
  •  
  • Access comment data - How to access these comment data and mapped them with Timesheet task and date in report -
    SELECT v.TS_UID as TimesheetId,v.TS_LINE_UID as TimesheetLineId, v.TEXT_VALUE as Comment,
    cast((
    case
    when c.MD_PROP_NAME like 'Comment(Mon)' then p.startdate
    when c.MD_PROP_NAME like 'Comment(Tue)' then DATEADD(day, 1, p.startdate)
    when c.MD_PROP_NAME like 'Comment(Wed)' then DATEADD(day, 2, p.startdate)
    when c.MD_PROP_NAME like 'Comment(Thu)' then DATEADD(day, 3, p.startdate)
    when c.MD_PROP_NAME like 'Comment(Fri)' then DATEADD(day, 4, p.startdate)
    when c.MD_PROP_NAME like 'Comment(Sat)' then DATEADD(day, 5, p.startdate)
    when c.MD_PROP_NAME like 'Comment(Sun)' then DATEADD(day, 6, p.startdate)
    else ''
    End
    ) as varchar) as CommentDate
    FROM
    [ProjectServer_Published].[dbo].[MSP_TIMESHEET_CUSTOM_FIELD_VALUES] v
    INNER JOIN
    [ProjectServer_Published].[dbo].[MSP_CUSTOM_FIELDS] c
    ON c.MD_PROP_UID = v.MD_PROP_UID
    Inner Join MSP_Timesheet t ON
    t.TimesheetUID = v.TS_UID
    Inner Join MSP_TimesheetPeriod p
    On p.PeriodUID = t.PeriodUID
    WHERE c.MD_PROP_NAME in ('Comment(Mon)','Comment(Tue)','Comment(Wed)','Comment(Thu)','Comment(Fri)','Comment(Sat)','Comment(Sun)')
  •  
  • Remove Comment Column - How to remove existing Comment Column
    • Make a copy TimesheetPart.htc under C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS\PWA\LIBRARY
    • Open TimesheetPart.htc and add the following line (function onload()):
      for(var i = 0; i < idGrid.rows.length; i++) {idGrid.rows.deleteCell(3)};
    • It will look like this
      …..
      …….
      if (typeof(idGrid) != 'undefined')
      {
      idGrid.attachEvent("OnRowSelectedStateChange", ChangeControlStates);
      idGrid.attachEvent("OnLoadCompleted",onGirdLoadComplete);
      idGrid.attachEvent("OnDataChanged",OnDataChanged);
      for(var i = 0; i < idGrid.rows.length; i++)
      {
       idGrid.rows.deleteCell(3); // Comment Column
      }
      }
      ……

Wednesday, November 18, 2009

Custom Workflow in Project Server 2007 - Part 4

Part 1
Part 2
Part 3


Writing Codes for Activities

Add the following using directives to the top of the class file, If already not there:

using Microsoft.SharePoint.Workflow;
using System.Collections.Specialized;
using System.Text;
using Microsoft.SharePoint;


Add the following class member fields :

public string m_ProjectName;
public bool m_LoginSuccessfull;
public int m_PublishRequestUserId;


OnWorkflowActivated1_Invoked - This is the first method to be called in the workflow execution. Add the following code to initialize some variables using the workflowProperties field (extracting properties from the list item that initiated the workflow).

private void OnWorkflowActivated1_Invoked(object sender, ExternalDataEventArgs e)
{
workflowId = workflowProperties.WorkflowId;
m_ProjectGuid = new Guid((string)workflowProperties.Item
[EPMWFConstants.CON_ProjectGuidColumn]);
m_ProjectName = (string)workflowProperties.Item
[EPMWFConstants.CON_ProjectTitleColumn];
string userToken = (string)workflowProperties.Item
[EPMWFConstants.CON_PublishRequestorColumn];
m_PublishRequestUserId = Convert.ToInt32(userToken.Substring(0,userToken.IndexOf(";")));
}


SendRequestsForApproval_Invoking - Set up the email fields for the request to approvers.

private void SendRequestsForApproval_Invoking(object sender, EventArgs e)
{
m_MailToHeader = new StringDictionary();
StringBuilder returnString = new StringBuilder();
SPGroup approverGroup = workflowProperties.Web.SiteGroups[EPMWFConstants.CON_ApproversGroupName];
foreach (SPUser currentApprover in approverGroup.Users)
{
if (!string.IsNullOrEmpty(currentApprover.Email))
{
returnString.AppendFormat("{0};", currentApprover.Email);
}
}
m_MailToHeader.Add("To", returnString.ToString());
m_MailToHeader.Add("Subject", string.Format("Project publishing approval request : \"{0}\"", m_ProjectName));
StringBuilder mailBody = new StringBuilder();

mailBody.AppendFormat("{0} has requested approval to publish the Project" +
"\"{1}\".
", workflowProperties.Web.Users.GetByID(m_PublishRequestUserId).Name, m_ProjectName);
m_MailToBody = mailBody.ToString();
}


SendPendingApproval_Invoking - Send pending notices to publishers

private void SendPendingApproval_Invoking(object sender, EventArgs e)
{
m_MailToHeader = new StringDictionary();
m_MailToHeader.Add("To", workflowProperties.Web.Users.GetByID(m_PublishRequestUserId).Email);
m_MailToHeader.Add("Subject", string.Format("Project \"{0}\" submitted for approval", m_ProjectName));
m_MailToBody = "The project has been submitted for " +
"approval. You will be notified when the item has been approved/rejected.";
}


WhileWaitingForApproval_Condition - Set Result to true if the status on the list item is set to Waiting for Approval,which causes the loop to continue.

private void WhileWaitingForApproval_Condition(object sender, ConditionalEventArgs e)
{
e.Result = (string)workflowProperties.Item[EPMWFConstants.CON_ApprovalStatusColumn] == EPMWFConstants.CON_StatusWaitingText;
}


IfApproved_Condition - checks whether the item is approved Else assumes that the item has been rejected.

private void IfApproved_Condition(object sender, ConditionalEventArgs e)
{
e.Result = (string)workflowProperties.Item[EPMWFConstants.CON_ApprovalStatusColumn] == EPMWFConstants.CON_StatusApprovedText;
}


PsiQueuePublish_Invoking - code for the actual web service call
to the Queue System PSI.

private void PsiQueuePublish_Invoking(object sender, InvokeWebServiceEventArgs e)
{
//Create a new Job Guid for this operation
m_PublishJobGuid = Guid.NewGuid();
//Get the web service proxy from the activity
EPMWF.psiProjects.Project webService = (EPMWF.psiProjects.Project)e.WebServiceProxy;
//use the default credentials
webService.UseDefaultCredentials = true;
//Set the URL to the web service
webService.Url = workflowProperties.WebUrl + "/_vti_bin/PSI/Project.asmx";
//Set an empty string for the publish wss url
m_PublishWssUrl = string.Empty;
}


SendApproval_Invoking - Send an Approved notification to requester.

private void SendApproval_Invoking(object sender, EventArgs e)
{
string subject = "Publishing of Project \"{0}\" has been APPROVED";
string body = "Publishing of the project \"{0}\" has been approved.";
m_MailToHeader = new StringDictionary();
m_MailToHeader.Add("To", workflowProperties.Web.Users.GetByID(m_PublishRequestUserId).Email);
m_MailToHeader.Add("Subject", string.Format(subject, m_ProjectName));
m_MailToBody = string.Format(body, m_ProjectName);
}


SendRejected_Invoking - Send an rejected notification to requester.

private void SendRejected_Invoking(object sender, EventArgs e)
{
string subject = "Publishing of Project \"{0}\" has been REJECTED";
string body = "Publishing of the project \"{0}\" has been rejected.";
m_MailToHeader = new StringDictionary();
m_MailToHeader.Add("To", workflowProperties.Web.Users.GetByID(m_PublishRequestUserId).Email);
m_MailToHeader.Add("Subject", string.Format(subject, m_ProjectName));
m_MailToBody = string.Format(body, m_ProjectName);
}


Deploying the Solution

  • Sign assembly with a strong name key & install in the Global Assembly Cache

  • Workflow registration with WSS - create and register a feature that exposes the custom workflow.

    • Create following dir ,sub dir & files in your Project/Solution dir
      \TEMPLATE\FEATURES\EPMWF

    • Add two xml files , feature.xml & workflow.xml in this sub dir

    • open the feature.XML file and add the following:

      <?xml version="1.0" encoding="utf-8" ?>
      <Feature xmlns="http://schemas.microsoft.com/sharepoint/"
      Id="{guid}" Title="EPM Workflow Sample" Scope="Site" Hidden="False" Version="1.0.0.0">
      <ElementManifests><ElementManifest Location="workflow.xml" /></ElementManifests>
      <Properties><Property Key="GloballyAvailable" Value="true" /></Properties>
      </Feature>

      Create a new GUID and replace the {guid}tag.

    • open the workflow.xml file and add the following:

      <?xml version="1.0" encoding="utf-8" ?>
      <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
      <Workflow Id="{guid}" Name="Publishing Approval" Description="EPM Publishing Approval" CodeBesideClass="EPMWF.PublishingWorkflow" CodeBesideAssembly="EPMWF, Version=1.0.0.0, Culture=neutral, PublicKeyToken={token} " >
      <Categories />
      <MetaData><StatusPageUrl>_layouts/WrkStat.aspx</StatusPageUrl></MetaData>
      </Workflow>
      </Elements>

      Replace the {token} tag with the public key token of your assembly.
      Create a new GUID and replace the {guid}tag.

    • Install and activate this feature on your PWA site
      %STSADM% -o InstallFeature -filename EPMWF\feature.xml –force
      %STSADM% -o activatefeature -name EPMWF -url http://server/PWA

    • Attach the workflow to the custom list - browse to the Workflow Settings page. Select Publishing Approval Workflow ,set Name field,task and history lists. Finally, select Start This Workflow When a New Item Is Created under Start Options.


  • Registering the server-side event handler with Project Server 2007-

    • Browse to the ‘Server-Side Event Handler Configuration’ page link.
    • select the Publishing event for Project group, and click the link.
    • Add a new handler by clicking the New Event Handler link.
    • Enter a name such as ‘EPM Publishing Workflow’ and a description.
    • Then enter the assembly name - name, Version=1.0.0.0, Culture=neutral, PublicKeyToken={token}
    • Enter the class name - .
    • enter 1 as the order of the handler.
    • Click the Save button to register the event handler

    For More details on Project server Event Handler check this article .


For testing Create a new project using Project Professional or Create a Proposal using PWA site and publish it.

Thursday, November 12, 2009

Custom Workflow in Project Server 2007 - Part 3

Part 1
Part 2



Step 4 - Create a custom workflow


For More details on WSS workflow check this article .


Open the Sequential Workflow file (PublishingWorkflow.cs) in design mode and add following activites -
  1. OnWorkFlowActivated activity

  2. Sequence activity : Rename this activity as 'PendingNotfications' and add following child activites -
    • SendEmail - Rename this activity as 'SendRequestForApproval'

    • SendEmail - Rename this activity as 'SendPendingNoticeToPublisher'

  3. While activity – Rename this activity as 'WhileWaitingForApproval' and add following child activities.
    • OnWorkflowItemChanged activity

  4. IfElse activity
    • First branch : Add following child activities -
      • InvokeWebService activity – Rename this activity as 'EPMProjects'.Add the web reference as -
        Reference name – psiProjects ,
        URL = http://server/pwa/_vti_bin/psi/project.asmx

      • SendEmail activities - Rename this activity as 'SendApprovalEmail'

    • Second Branch : Add following child activities -
      • SendEmail activities - Rename this activity as 'SendRejectedEmail'


The final design view should look like this -


The red exclamation icon in the upper-right corner of activities icon indicates that a required property must be set.Clicking the icon displays the list.

Now open the PublishingWorkflow.cs file in code view and add following using statement & class members -

  • using EPMWF.psiProjects; //NameSpace.Psi Web Refrence Name

  • public Guid workflowId = default(System.Guid);
    public SPWorkflowActivationProperties workflowProperties = new SPWorkflowActivationProperties();


Set Activity Properties
Open the workflow file in design view and set the required properties of each activity as mentioned below -
  • Activity - OnWorkFlowActivated1
    • Correlation Token = publishWorkflowToken
      Correlation Token\OwnerActivityName = PublishingWorkflow
      WorkflowProperties\Name = PublishingWorkflow
      WorkflowProperties\Path = workflowProperties

    • Invoked = OnWorkflowActivated1_Invoked
      After You Enter method name here, VS.net will jump to code with a method signature created.

  • Activity = SendRequestForApproval
    • Correlation Token = publishWorkflowToken
      Correlation Token\OwnerActivityName = PublishingWorkflow

    • Body - select the Body row and click the ellipsis.Click Bind a New member field.enter name = m_MailToBody ; Select Create field option, click Ok .Verify Name and Path
      Body\Name = PublishingWorkflow
      Body\Path = m_MailToBody

    • Headers - Create field in the same as done for Body.Name =m_MailToHeader.The Headers property is a hash where the Subject and To fields can be specified
      Headers\Name = PublishingWorkflow
      Headers\Path = m_MailToHeader

    • MethodInvoking = SendRequestsForApproval_Invoking
      After You Enter method name here, VS.net will jump to code with a method signature created.

  • Activity = SendPendingNoticeToPublisher
    • Correlation Token = publishWorkflowToken
      Correlation Token\OwnerActivityName = PublishingWorkflow
      Body\Name = PublishingWorkflow
      Body\Path = m_MailToBody
      Headers\Name = PublishingWorkflow
      Headers\Path = = m_MailToHeader
      MethodInvoking = SendPendingApproval_Invoking



  • Activity = WhileWaitingForApproval
    • Condition = Code Condition
    • Condition = WhileWaitingForApproval_ Condition
      After You Enter method name here, VS.net will jump to code with a method signature created.


  • Activity = OnWorkflowItemChanged
    • Correlation Token = publishWorkflowToken
      Correlation Token\OwnerActivityName = PublishingWorkflow


  • Activity = ifElseBranchActivity1
    • Condition =Code Condition
      Condition = IfApproved_Condition


  • Activity = EPMProjects
    • MethodName =QueuePublish

    • Create fields for following properties in the same way as in Body
      ReturnValue = m_PublishResult
      JobUid = m_PublishJobGuid
      ProjectUid = m_ProjectGuid
      WssUrl = m_PublishWssUrl

    • FullPublish=True

    • Invoking =PsiQueuePublish_Invoking
      VS.net will jump to code with a method signature created.


  • Activity = SendApprovalEmail
    • Correlation Token = publishWorkflowToken
      Correlation Token\OwnerActivityName = PublishingWorkflow
      Body\Name = PublishingWorkflow
      Body\Path = m_MailToBody
      Headers\Name = PublishingWorkflow
      Headers\Path = = m_MailToHeader
      MethodInvoking = SendApproval_Invoking



  • Activity = SendRejectedEmail

    • Correlation Token = publishWorkflowToken
      Correlation Token\OwnerActivityName = PublishingWorkflow
      Body\Name = PublishingWorkflow
      Body\Path = m_MailToBody
      Headers\Name = PublishingWorkflow
      Headers\Path = = m_MailToHeader
      MethodInvoking = SendRejected_Invoking




After setting all these properties Visual studio will automatically create some member declaration & empty method signatures for you. The code file will look like this...


namespace EPMWF
{
public sealed partial class PublishingWorkflow: Microsoft.SharePoint.WorkflowActions.SharePointSequentialWorkflowActivity
{
public PublishingWorkflow()
{
InitializeComponent();
}

public Guid workflowId = default(System.Guid);
public SPWorkflowActivationProperties workflowProperties = new SPWorkflowActivationProperties();

public String m_MailToBody = default(System.String);
public System.Collections.Specialized.StringDictionary m_MailToHeader = new System.Collections.Specialized.StringDictionary();

private void OnWorkflowActivated1_Invoked(object sender, ExternalDataEventArgs e){}

private void SendRequestsForApproval_Invoking(object sender, EventArgs e){}

private void SendPendingApproval_Invoking(object sender, EventArgs e){}

private void WhileWaitingForApproval_Condition(object sender, ConditionalEventArgs e)
{}

private void IfApproved_Condition(object sender, ConditionalEventArgs e){}

public Guid m_ProjectGuid = default(System.Guid);
public ProjectRelationsDataSet m_PublishResult = new EPMWF.psiProjects.ProjectRelationsDataSet();
public Guid m_PublishJobGuid = default(System.Guid);
public String m_PublishWssUrl = default(System.String);

private void PsiQueuePublish_Invoking(object sender, InvokeWebServiceEventArgs e){}

private void SendRejected_Invoking(object sender, EventArgs e){}

private void SendApproval_Invoking(object sender, EventArgs e){}
}
}


Part 4 - Writing Codes for Activities

Friday, November 6, 2009

Custom Workflow in Project Server 2007 - Part 2

For implementing this Workflow , we need to do following -
  1. Create a WSS Custom list.
  2. Create a Sharepoint user group for Approvers.
  3. Create a server side project publishing event handler.
  4. Create a custom workflow using Workflow Foundation (WF) and attach it to WSS list created in step 1.
  5. Deploy the solution


Step 1- Create a WSS Custom list
Create a WSS custom list at the root web of Project Web Access 2007 site.
  • Browse to the root Project Web Access 2007 site. http://server/pwa
  • Create a custom list(Site Actions ->Create) on root web – Name = Project Publishing;
  • Add following columns in 'Project Publishing' list -
    • Title = Single line of text – Holds the project name.
    • ProjectGuid = Single line of text = Holds the project ID that this item represents.
    • Status = Choice = Drop-down list for the approval status for this item. The choices are - Waiting for Approval, Rejected, and Approved.
    • Requester = Person or Group = Lists the user who requested the project publish.



Step 2 - Create a Sharepoint user group
Create the Publishing Approvers Sharepoint group on Project Web Access 2007 site.
  • Browse to the root Project Web Access 2007 site. http://server/pwa
  • Create the Publishing Approvers Sharepoint group(Site Actions - Site Settings -People and Groups -New menu -New Group) - Name= 'Publishing Approvers'
  • Add individual users in the group (New Menu -Add Users)


Step 3 - Create server side event receiver
We will create a single visual studio solution for step3 (Event Handler) & step 4 (Workflow).
  • Open Visual Studio .net 2005 and create a new project using 'Sequential Workflow Library template' - Name = EPMWF

  • Add following Project server & Sharepoint assembly references -

    Microsoft.Office.Project.Server.Events.dll
    Microsoft.Office.Project.Server.Library.dll
    Microsoft.SharePoint.dll
    Microsoft.SharePoint.Library.dll
    Microsoft.SharePoint.Security.dll
    Microsoft.SharePoint.WorkflowActions.dll

  • For Project Server dlls.Select the Browse tab in Add reference dialog and browse to the folder containing the Microsoft Office Project Server assemblies. Select them and click OK.
  • Delete Workflow1 file from Visual studio solution, which is created by default

  • Add following items in the visual studio project
    1. EPMWFConstants.cs - A static class that will hold constants needed by custom workflow & Event Handler.
    2. PublishingEventHandler.cs - A class file for handling project publishing event.
    3. PublishingWorkflow.cs - A Sequential Workflow item by Right click the project, select Add, and click on Sequential Workflow.

  • Coding EPMWFConstants.cs - This file will contain a static class that will hold constants needed for interfacing to WSS by the custom workflow & Event Handler.These constants will be string constants that will hold the custom list and columns details & Approver Group details. Add following constant in this class

    public const string CON_PublishListTitle = "Project Publishing";
    public const string CON_ProjectTitleColumn = "Title";
    public const string CON_ProjectGuidColumn = "GUID0";
    public const string CON_ApprovalStatusColumn = "Status";
    public const string CON_PublishRequestorColumn = "Requester";

    public const string CON_StatusApprovedText = "Approved";
    public const string CON_StatusRejectedText = "Rejected";
    public const string CON_StatusWaitingText = "Waiting for Approval";

    public const string CON_ApproversGroupName = "Publishing Approvers";


  • Coding PublishingEventHandler.cs - The event handler method first checks whether a list item for the project being published has already been created. If an item exists, the publish is allowed to proceed only if it has been approved. If the item does not exist, a new item is added, which initiates the custom workflow.

    • Check this for the structure of the class file for Event Handler.

    • Add following code in 'OnPublishing' method

      public override void OnPublishing(PSContextInfo contextInfo, ProjectPrePublishEventArgs e)
      {
      //Open PWA site Object
      using (SPSite site = new SPSite(contextInfo.SiteGuid))
      {
      //Open root web object
      using (SPWeb web = site.OpenWeb())
      {
      //create an object of the Publishing Approval custom list
      SPList list = web.Lists[EPMWFConstants.CON_PublishListTitle];

      string projectGuid = e.ProjectGuid.ToString("N").ToUpper();
      SPQuery query = new SPQuery();
      query.Query = "" + projectGuid + "";
      SPListItemCollection items = list.GetItems(query);
      SPListItem item;
      if (items == null items.Count == 0)
      {
      //Create a new list item
      item = list.Items.Add();
      item[EPMWFConstants.CON_ProjectGuidColumn] = projectGuid;
      item[EPMWFConstants.CON_ProjectTitleColumn] = e.ProjectName;
      item[EPMWFConstants.CON_ApprovalStatusColumn] = EPMWFConstants.CON_StatusWaitingText;
      item[EPMWFConstants.CON_PublishRequestorColumn] = web.Users[contextInfo.UserName];
      item.Update();
      }
      else
      {
      item = items[0];
      }

      //Cancel the publish event if the item isn’t approved
      switch ((string)item[EPMWFConstants.CON_ApprovalStatusColumn])
      {
      case EPMWFConstants.CON_StatusRejectedText:
      e.CancelReason = "Publishing for this project has been rejected.";
      e.Cancel = true;
      break;
      case EPMWFConstants.CON_StatusWaitingText:
      e.CancelReason = "Publishing for this project is pending approval.";
      e.Cancel = true;
      break;
      }
      }
      }
      }


For More details on Project server Event Handler check this article .


Part-3 : Create a custom workflow

Tuesday, November 3, 2009

Custom Workflow in Project Server 2007 - Part 1



Workflow is a powerful way to guide business processes. As Project Server 2007 is hosted in WSS , so by default it allow us to create workflow for WSS object such as Document Library , Lists . Project Server 2007 does not provide us an ability to build direct workflows around Project Server objects. For example there may be some business need to have an workflow on server side process e.g. workflow on project Publishing.
We can accomplish this with the help of a server-side event handler & a WSS list workflow. A server side event listener can capture the event for that process and cancel it. It then kicks off a workflow in WSS by altering a list item. After a workflow condition has been met, the workflow can re execute the operation.

For exploring the workflow in EPM , we will take an example of a business process (Project Publishing Workflow ) where an approval is required on project publishing. Project managers are required an approval from a program manager or a Delivery Manager before publishing any project. In this scenario the workflow steps may be look like this-

  1. Project Manager Creates a Project and send an approval request email to Program manger

  2. Program manager will then analyze the schedule and Approve/reject the request. And send an notification to requestor

  3. In case of approve , project manager will publish the project.



With the help of an project server event handler , a WSS list workflow & Project server Interface(PSI), we can create an automated workflow which will accomplish the above task in following steps

  1. Project manager create and publish a project

  2. An event handler ,attached to a Project Publishing server side event, will cancel the process and add an item in a WSS list.

  3. WSS list item kickoff a custom workflow (Automatic workflow on item creation)

  4. The workflow will send an notification to Approver, and wait for the status change

  5. Approver then open the list item and change the status to Approve.

  6. Once the status field is changed , The workflow then Publish the project through the project server 2007 web services(PSI) and send an notification to requestor.







Implementation : Part 2


Monday, September 14, 2009

Event Handler in project Server 2007

Project Server Event facilitate the addition of new business logic by extending
the capabilities of Project Server events to developers. PS 2007 allow us to override most of the pre-event and postevent. For this example we will create a pre publishing event to check whether project name is following some creteria or not.

To create a new event handler, follow these steps:

  1. Open Visual Studio 2005.

  2. Select File, New, Project, and create a new class library. Name it MyPSEvent.

  3. Rename the class Class1 to MYPSHandler.

  4. In the Solution Explorer, right-click the project name and select Add Reference. And add references to Microsoft.Office.Project.Server.Events.Receivers.dll and Microsoft.Office.Project.Server.Library.dll assemblies.

  5. Add following using statement in your class
    System.Diagnostics - This namespace contain Event Log object ,that will be used to log the progress, status, and results in the event handler.
    Microsoft.Office.Project.Server.Events - this namespace contains the base event receiver classes of each Project business object.
    Microsoft.Office.Project.Server.Library - this namespace contains the PSContextInfo class, which holds the UserGuid and UserName properties.

  6. Derive your MYPSHandler from the abstract class ProjectEventReceiver .and Create a method to override the base method for the Publishing event by overriding the onPublishing method.

  7. In this method, you can get the username from the object contextInfo and the project
    name from the Event Arguments object e. In this example, we will check if the project name
    meets the set criteria. If it does not, cancel the publishing event by setting the property e.Cancel to true. You should also log the results of this method.


    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Diagnostics;
    using Microsoft.Office.Project.Server.Events;
    using Microsoft.Office.Project.Server.Library;
    using System.Web.Mail;
    namespace MyPSEvent
    {
    public class MYPSHandler : ProjectEventReceiver
    {
    public override void OnPublishing(PSContextInfo
    contextInfo,ProjectPrePublishEventArgs e)
    {
    base.OnPublishing(contextInfo, e);

    //creating object to log results
    //and setting the log source.
    EventLog myLog = new EventLog();
    myLog.Source = “Project Event Handler”;

    //Getting user and project information
    // from event arguments
    // from event arguments
    string userName = contextInfo.UserName.ToString();
    string ProjectName = e.ProjectName.ToString();
    int eventId = 3651;
    string logEntry = “Publishing of project “
    + ProjectName + “started by “ + userName;
    e.Cancel = false;

    //if the project name does not meet
    //the criteria cancel the event.
    if (ProjectName.StartsWith(“Project”))
    {
    myLog.WriteEntry(logEntry,
    EventLogEntryType.Information, eventId);
    }
    else
    {
    logEntry += “\nProject name is invalid.
    The name of all published”
    + “projects must start with ‘Project’”;
    myLog.WriteEntry(logEntry,
    EventLogEntryType.Warning, eventId);
    e.Cancel = true;
    }
    }
    }
    }



  8. Create a strong name key file and Build the solution

  9. Add dll to the global assembly cache.

  10. Register the event hander in Project Server 2007,

    • log on to PWA using an account with administrative permissions. On the left page, select Server Settings and under the Operation Policies section, click Server-Side Event Handler Configuration,

    • In the Events page, scroll down the Events list and click the Project link for the Publishing event. Then click New Event Handler in the Event Handlers grid
      On the Event Handler page, type the following values,
      . Name—event handler name, such as MyPSEvent.
      . Description—event handler description.
      . Assembly Name—Assembly name, version, culture, and public key token
      . Class Name—Fully qualified class name, such as MyPSEvent. MYPSHandler .
      . Order—In case there is more than one event handler, this sets the order in which
      they are invoked.

    • When finished, click Save.



  11. Project Server 2007 adds the Project Server event handler in an asynchronous
    process, and it might take a few seconds or minutes for the Event Handlers grid to
    update after the event handler registers.

  12. Testing the Event Handler - To test the event handler, follow these steps:

    • Under Projects in the left pane, select Proposals and Activities.

    • In the Proposals and Activities page, click New, and then click Proposal.

    • In the New Proposal page, select New and enter a proposal name and description.

    • Click Save, and then click Save and Publish.

    • Open the Event Viewer and select Application in the left pane. You
      should be able to see a warning from the event handler near the top of the list.




  13. Debugging the Event Handler in Visual Studio 2005

    • Attach debugging process – To debug an event handler, you must use Visual Studio 2005 and attach the debugger to the Project Server Eventing process.
      Note – For debugging from a remote computer, install the Microsoft Visual
      Studio Remote Debugging Monitor in the Project Server computer and follow these steps:

      • On the Debug menu, click Attach to Process.
      • select the default transport and browse to the Project Server computer as the qualifier.
      • Select Microsoft Office Project Server Eventing Process and click Attach.




    • After the process attached, Select Tools, Options.

    • Expand the Debugging node and select Symbols.

    • Click the folder icon and copy the path to the debug directory of your project.

    • Select the option Load Symbols Using the Updated Settings When This Dialog Is
      Closed, and click OK.

    • Place a breakpoint at the onPublishing method and trigger the
      Publishing event by publishing a project. The process will stop in your breakpoint and
      you can step through the method.

    • Debugging will not work if the code changes after the event handler has been registered
      in Project Server. If the code changes and is recompiled, you will need to reregister the
      event handle. For this registering the new assembly in the Global Assembly Cache and restart the service (go to the Central Admin- > select Operations ->Services on Server. Stop and restart the “Project Application Service” ). This will register the new assemblies from the Global Assembly Cache in Project Server. If you want to reregister it in production environment where you cant restart the services then Go to the Events page and select the event the event handler was registered to. Select the event handler you want to unregister in the Event Handlers grid and click Delete Event Handler. Register the new Event Handler assembly in the global assembly cache. Register the new event handler in Project Server.



Tuesday, August 11, 2009

Modify the Default Workspace Template in Project Server

In Project Server when we create a new project, by default a workspace is created which contain lists like issues, risks, shared document etc. Project server creates project workspace based on a WSS site template which is created at the time of installation. Project server allows us to customize this template, if the default installation does not meet our needs. The WSS site template that resides on the server is referred to as the site definition. There are two ways to customize Project Workspace template-

  1. Site Template - A site template is a .stp file. It is a package containing a set of differences and changes from a base site definition.

  2. Site definition - A site definition is a complete definition of a site. It is installed on file system (..\12\Template\SiteTemplates). A site definition consists of .aspx pages and .xml files with Collaborative Application Mark-up Language (CAML).



Create Project Workspace Template(.stp)
  • Create a sample project in Project server 2007. It will create a workspace for this project based on default workspace template.

  • Open the newly created project workspace site.

  • Make all the desired changes on site, e.g. create new list/document library, add web parts etc.

  • Navigate to Site Actions | Site Settings.

  • Select Save Site as Template from the Look and Feel section of the Site Settings page

  • Name the template. select the Include Content checkbox and select OK.

  • Navigate to the PWA Project Web Access Home Page

  • Select Site Actions -> Site Settings -> SiteTemplate Gallery.

  • Locate the template that was just saved, right-click it, and choose Save Target As to get the actual file.

  • Place the new .stp file in Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN.

  • From the command prompt change the directory to c:\Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN and run following command

    stsadm -o addtemplate -filename "path\YourNewStpFileName.stp" -title "yoursitetitle"


  • Restart Internet Information Services (IIS).

  • After registering the template, go to the Server Settings on the PWA Site.

  • Select the Project Workspace Provisioning Settings link. Then change the Default Project Workspace Template setting to the new template and click Save.

  • All new projects will take on this template.



Create Project workspace site definition
The WSS site template that resides on the server is referred as the site definition.
The primary files that control the site definitions are located on the WSS Server in \\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\ and its subdirectories.The WSS sites’ HTML is produced on the fly based on the template.Use the following steps to create a new PWS site definition:

  • Create a copy of the default project workspace site by performing the following:
    • Locate the folder in the SiteTemplates directory(~12\ TEMPLATE\SiteTemplates) named PWS.
    • Make a copy of the PWS folder.
    • Rename the copy of the PWS folder and give it a meaningful name. e.g. MyPWS.


  • Create a new WebTemp*.xml file - A WebTemp.xml file contains the site definitions that are available to choose from when creating a project workspace.
    • Locate the file in the ~12\ TEMPLATE\1033\XML folder called webtemppwa.xml.
    • Make a copy of this webtemppwa.xml file.
    • Rename the copy to a meaningful name, prefixed with WebTemp. e.g. webtempMyPWS.xml.


  • Modify the new WebTemp*.xml file (webtempMyPWS.xml) to include the appropriate settings, specify a Template section followed by a Configuration section. E.g.

    <?xml version="1.0" encoding="utf-8"?>
    <Templates xmlns:ows="...">
    <Template Name="MyPWS" SetupPath="SiteTemplates\MyPWS" ID="6666">
    <Configuration
    ID="0"
    Title="My PWS"
    Hidden="False"
    Imageurl="..."
    Description="..."
    DisplayCategory="Collaboration">
    </Configuration>
    </Template>
    </Templates>


    Attributes -
    Name — The exact name of the site definition folder you have created.
    SetupPath — The path to the site definition folder(SiteTemplate\)
    ID — ID of the template. The ID can be any number as long as
    no other site definition is using it. However, the ID must be between 6000 and
    7000 for it to be identified as a project workspace definition.

    Attributes in the Configuration section are -
    ID — If more than one configuration is specified, the ID is used in combination with the template name as a unique identifier.
    Title — The title of this configuration of the site definition. This value will appear as a choice in Site Provisioning Settings page.
    Description — The description of the site configuration.

  • Now you can modify the definition and add custom content, such as lists or web parts, to your newly created definition. E.g. add a new list - Follow these steps to create a custom list as a feature, and include it in your new site definition:
    • Create a feature for you list (in feature directory)e.g. MyCustomListFeature.

    • Install the feature, you must run the stsadm.exe command as follows:

      stsadm.exe -o installfeature -filename MyCustomListFeature\Feature.xml


    • Add this feature to the custom site definition you created earlier.Open the ONET.XML file in the TEMPLATE\SiteTemplates\MyPWS\XML
      folder. Look for the WebFeatures section toward the bottom of the ONET.XML file and add the FeatureId,

      <?xml version="1.0" encoding="utf-8"?>
      <Project ...>
      <ListTemplates ...>
      <DocumentTemplates ...>
      <Configurations>
      <Configuration ID="0" Name="Default>
      <Lists ...>
      <Modules ...>
      <SiteFeatures ...>
      <WebFeatures>
      ...
      <Feature ID="..." /> <!-- PWS Feature -->
      <Feature ID="*-*-*-*-*" /> <!-- your list Feature -->
      </WebFeatures>
      </Configuration>
      </Configurations>
      ...
      </Project>




  • Restart Internet Information Services (IIS) for the new definition to be seen by IIS.

  • Your new template should now appear in the Site Provisioning Settings page

Thursday, July 9, 2009

Project Server Problem - Corrupted Cache

Problem
Some time we face following problems when we try to edit /open a project in Project professional-
  • "Not able to edit project, Check-in Pending state" : this problem is typically caused by a project manager publishing his or her project, then closing the project before Project Professional 2007 completes the publish operation. It can also occur if a project is closed and an attempt is made to reopen it prior to the completion of the initial close process.
  • “Custom fields’ lookup tables are scrambled.” : when there are multiple Project Server accounts on a machine, the Enterprise Global template is undergoing frequent modification, and the cached version of the Enterprise Global template becomes corrupted.
Solution
we can resolve both issues by taking one of two approaches:
  • Performing a Project Cache cleanup operation from within Project
    Professional,
  • Deleting all of the folders that reside under the folder C:\Documents and
    Settings\USERNAME\Application Data\Microsoft\MS Project\Cache.
    You should close Project Professional before performing this operation. By doing so, you bypass the benefits of performing only an incremental open of the project, and force Project Professional to transfer the full project file (Full Open) the next time it is opened.

Saturday, July 4, 2009

SQL Server 2005 Analysis Services with the Project Server 2007 : Part 4

Managing Cube Building Service

The Microsoft Office Project Server 2007 Cube Building Service uses the technology provided by SQL Analysis Services to create a database containing several online analytical processing (OLAP) cubes that are used for data analysis reporting. After configuration, you need to manage tasks such as cube build & configuration setting, manage view .
  • Analysis Services settings In Project Server
    • Build Settings
      1. Log on to Project Web Access as an administrator.
      2. Click Server Settings. In the Cube section, click Build Settings.
      3. Analysis Services Settings - specify the information for the server on which SQL Server Analysis Services is running,name of the database that is used by Analysis Services(If the database does not exist, it will be automatically created.),Extranet URL for accessing the OLAP cube and Portfolio Analysis views from outside the Intranet and Description
      4. Database Date Range - Specify the date range of data you want included on the cube ·
      5. Cube Update Frequency - Specify how often you want the cube to be updated
      6. click Save / Save and Build.
    • Cube Configuration
      customize the Project Server OLAP cubes by adding custom fields as dimensions or measures to the cubes associated with the selected entity, and by adding calculated measures. The OLAP cube will contain this information the next time you update the cube, and any selected custom field will only appear after its data have been published.
      1. Log on to Project Web Access as an administrator.
      2. Click Server Settings. In the Cube section, click Configuration.
      3. Cube Dimensions section - Specify the custom fields you want to add to the cube as dimensions. The selected custom fields will be added to both Timephased and Non-timephased cubes, when applicable.Note: Only custom fields that use lookup tables will appear in list.
      4. Cube Measures section - Specify the custom fields you want to add to the cube as measures. The selected custom fields will be added to the related Non-Timephased cube.
      5. Calculated Measures section - Specify an MDX expression to define the calculated measure
      6. Save data
  • View OLAP Cube data
    • Create a Data Analysis view
      1. Log on to Project Web Access as an administrator.
      2. Click Server Settings.In the Look and Feel section, click Manage Views.
      3. On the Manage Views page, click New View.
      4. Name and Type section - select Data Analysis type and enter a name and description for the Data Analysis view.
      5. Analysis Services Settings section -
        a. select the Default server option, you will use the instance of SQL Server Analysis Services you specified when you configured your cube build and configuration settings. (If you select the Custom server option, you have the option to select a different instance of SQL Server Analysis Services.)
        b. select the database that hosts the Project Server 2007 cube and select the cube you want to use for this view. There are fourteen cubes to choose from that are automatically generated by the Cube Building Service (CBS). You can also create cubes that store additional data not created by the CBS.
      6. View Options section - choose how you want the data to be displayed
      7. View Definition section - pick default measures and dimensions from the PivotField List and add them to the PivotTable or PivotChart. Choose the data you want to display in the view and drag it to the row, column, or filter field in which you want it to appear.
      8. Security categories section - select the categories that you want to make available to this view.
      9. Click Save to create the view.

    • Example : Timesheet Compliance view
    • To create this view, follow these steps:
      1. Open PWA -> Server Settings -> Manage Views -> Select New View
      2. In the View Type section, select Data Analysis. Type Timesheet Audit Report in the Name box and a description in the Description box.
      3. In Analysis Services Settings section, select your Analysis Services server
      4. In the Analysis Services Database list, select the appropriate database.
      5. In the Cube list, select the MSP_Project_Timesheet cube.
      6. In the View Options section, select PivotTable with PivotChart and Show Toolbar.
      7. Select Timesheet List, Timesheet Period and any enterprise custom field, that you might have defined and configure in cube configuration, from the PivotTable Field List and drag them to the Drop Filter Fields Here area of the PivotTable workspace.
      8. Add the Fiscal Time dimension to the Drop Column Fields Here PivotTable area to organize your view data by years, quarters, months, and days.
      9. Select Project List and Resource List from the PivotTable Field List and drag them to the Drop Row Fields Here PivotTable area
      10. Expand the Totals set of fields in the PivotTable Field List, select Work, Actual Work,and Remaining Work, and then add them to the Drop Totals or Detail Fields Here PivotTable area.
      11. Now all your projects and resources are displayed as part of the view, making the view, especially the chart part, too cluttered. Use any filter field to restrict the data displayed.
      12. You can also control the graph type you want to use with your Data Analysis views.Review the default char.Change to a different chart type by selecting the Chart Type button
      13. Add the appropriate security categories to access the view.
      14. select Save at the bottom of the page.






-------------------------
<<Part 3
-----

SQL Server 2005 Analysis Services with the Project Server 2007 : Part 3

Configure SQL Server 2005 Analysis Services
After installing require component and configuring SSP account , we will see how to configure SQL Server 2005 Analysis Services to enable access to the repository. You can create the repository in either of two ways:
· Create the repository by using a SQL Server 2000 Microsoft Jet database
· Create the repository in a SQL Server 2005 database
we will take the second approach in this article ......
  • Create the Repository database in SQL Server 2005
    1. Connect to Database Engine in SQL Server Management Studio
    2. Create New Database 'Analysis Services Repository'.
    3. In the Object Explorer list, expand the Security folder. Right-click Logins and then click New Login.
    4. In the Select Users or Groups page, Add this group 'SQLServer2005MSOLAPUser$$MSSQLSERVER'.
    5. In the Select a page list, click User Mappings. In the Users mapped to this login list, select Analysis Services Repository.
    6. In the Database role membership for: list for the repository database, select db_owner. Click OK.
    7. In Microsoft SQL Server Management Studio, expand the Databases folder and right-click Analysis Services Repository. Click New Query.
    8. In the Query Editor screen, enter the following text:
      CREATE TABLE [dbo].[OlapObjects] (
      [ID] [varchar] (36) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
      [ParentID] [varchar] (36) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
      [ObjectName] [nvarchar] (150) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
      [ClassType] [int] NOT NULL ,
      [ObjectDefinition] [ntext] COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
      [LastUpdated] [datetime] NULL ,
      [Changed] [bit] NULL ,
      [Version] [int] NULL
      ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
      GO

      CREATE TABLE [dbo].[Server] (
      [ObjectDefinition] [ntext] COLLATE SQL_Latin1_General_CP1_CI_AS NULL
      ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
    9. Execute the script. The script will create the database scheme required for the repository.
  • Configure Analysis Services to use a SQL Server repository database
    1. Connect to Analysis Services in SQL Server Management Studio.
    2. Right click the Analysis Services name, and then choose Properties.
    3. On the Analysis Services Properties page, in the Select a page section select General. Select Show Advanced (All) Properties.
    4. Select DSO\RepositoryConnectionString from the Name list.
      a. Select the corresponding value for the string in the Value column, and then click the box that appears to the right of the value to display the Connection Manager page.
      b. On the Connection Manager page, in the Provider list, select Native OLE DB\SQL Native Client.
      c. In the Server Name list, select the server on which the repository database is located.
      d. In the Logon to the server field, enter the account information to log onto the server.
      e. In the Connect to database section, select a database name.
      f. Click OK.
    5. Select DSO\RemoteRepositoryConnectionString from the Name list.
      a. Repeat all the steps from step 4
    6. On the Analysis Server Properties page, click OK.
  • Grant permissions to the SQL Server Analysis Service account to access the Project Server Reporting database
    1. Connect to database engine in SQL Server Management Studio
    2. In Management Studio, expand the Security folder, right-click Logins, and then click New Login.
    3. On the General page, enter the Windows Authenticated account for the user running the SQL Server Analysis Services service.
    4. In the Select a page list, click User Mapping.
    5. In the Database list, select Project Server_Reporting. Select the corresponding Map check box.
    6. In the Database role membership for: ProjectServer_Reporting section, select db_datareader.
    7. Click OK.
  • Enable the "Access data sources across domains" security setting in Internet Explorer
    1. In Internet Explorer, click Tools, and then click Internet Options.
    2. Click the Security tab, click the zone that you use to connect to the Office Project Server 2007, and then click Custom Level.
    3. Under Access data sources across domains, select Enable.






    --------------------------
    << Part 2    
    Part 4 >>

    ---------

    SQL Server 2005 Analysis Services with the Project Server 2007 : Part 2

    Configure SSP account

    The second step in SQL Server 2005 Analysis Services configuration is to give correct permission to Shared Services Provider (SSP) account on Analysis Service.

    • Determine the SSP account

      1. On the SharePoint Central Administration Web site, in the Quick Launch, click Shared Services Administration.
      2. On the Manage this Farm's Shared Services page, from the drop-down list for the Shared Services Provider you are using, click Edit Properties.
      3. On the Edit Shared Services Provider page, in the SSP Services Credential section, note the account name in the Username field. This is the SSP account.
    • Add the SSP account to the OLAP users local group
      1. Open Computer management : Start->All Programs->Administrative Tools->Computer Management.
      2. Open OLAP user group : Computer Management page->Local Users and Groups->Groups->"SQLServer2005MSOLAPUser$$MSSQLSERVER"
      3. On the SQLServer2005MSOLAPUser$$MSSQLSERVER properties page, click Add.
      4. On the Select Users, Computers, or Groups page, go to the Enter the object names to select section and add the name of the SSP account. Click Check Name to verify that the account exists.
      5. Click OK.

    • Add the SSP account as a server role member in SQL Server 2005 Analysis Services
      1. Connect to the instance of SQL Server 2005 Analysis Services on SQL Server Management Studio.
      2. Right click your SQL Server 2005 Analysis Services instance name, and then click Properties.
      3. Click Security in the Select a page pane.
      4. Click Add. In the Select Users or Groups page, go to the Enter the object names to select field and enter the name of the SSP account that you are adding to the server role. Click Check Name to verify that the account exists.
      5. Click OK.




    ------------------------------------------------------------------------------
    <<Part 1    
    Part 3 >>



    ----

    SQL Server 2005 Analysis Services with the Project Server 2007 : Part 1

    The Microsoft Office Project Server 2007 Cube Building Service is a reporting feature that allows to perform complex analysis on project data. It uses SQL Server Analysis Services to create an online analytical processing (OLAP) database containing several cubes that are used for data analysis reporting. It allows for data cubes to be built from selections within the Reporting database. This article describes Configuration settings for cube building process।

    Installation
    In order for SQL Server 2005 Analysis Services to function correctly with the Office Project Server 2007 Cube Building Service, you must install following Component

    • SQL Server 2005 Service Pack 1 or higher.
    • DSO client components - These components can be downloaded from the Feature Pack for Microsoft SQL Server 2005 (
    http://go.microsoft.com/fwlink/?LinkId=87078&clcid=0x409).
    • Microsoft SQL Server Native Client (sqlncl.msi)
    • Microsoft SQL Server 2005 Management Objects Collection (sqlserver2005_xm.msi)
    • Microsoft SQL Server 2005 Backward Compatibility Components (SQLServer2005_BC.msi)
  • Microsoft SQL Server 2005 Analysis Services 9.0 OLE DB Provider (SQLServer2005_ASOLEDB9.msi) - This component can be downloaded from the Feature Pack for Microsoft SQL Server 2005(http://go.microsoft.com/fwlink/?LinkId=87078&clcid=0x409).
  • Microsoft Office Web Components - Users are prompted to download the ActiveX components to their computer when they first build a Data Analysis view or when they attempt to use such a view. The Microsoft Office Web Components are a collection of ActiveX components that allows Project Web Access users to use PivotTable and Chart components to access OLAP cube data. This component can be downloaded from Office XP Tool: Web Components (http://go.microsoft.com/fwlink/?LinkId=87125&clcid=0x409).


  • ---------------------------------

    Part 2 >>