yes i can .. sorry it's more than 200 lines
i'll played something arround and I think i have a solution.
I use the Eventhandler OnPublished .. then I do my updates and publish the
project again. But this is slow because I had to publish a second time.
Is there any other way to do this?
Here's the code:
using System;
using System.Net;
using Microsoft.Practices.EnterpriseLibrary.Logging;
using Microsoft.SharePoint;
using ProjectStatusUpdate.Helpers;
using ProjectStatusUpdate.ProjectWebSvc;
using ProjectStatusUpdate.PSI;
using DataStoreEnum = ProjectStatusUpdate.ProjectWebSvc.DataStoreEnum;
using PSLib = Microsoft.Office.Project.Server.Library;
using System.Diagnostics;
using System.Threading;
using Microsoft.Office.Project.Server.Library;
using System.Web.Services.Protocols;
using System.Text;
using Microsoft.Practices.EnterpriseLibrary.ExceptionHandling;
namespace ProjectStatusUpdate
{
public class StatusUpdateHandler :
Microsoft.Office.Project.Server.Events.ProjectEventReceiver
{
// Loaded from ApplicationSettings
private string _sspName = "";
private const double MAX_PROJECTSTATUS = 3.0;
private const string IS_DELIVERY_MILESTONE_NAME =
"SMK_IsDeliveryMilestone";
private const string IS_PROJECT_CRITICAL_NAME =
"SMK_IsProjectCritical";
private const string TASK_STATUS_CRITICAL_NAME =
"SMK_TaskStatusCritical";
private const string PROJECT_STATUS_NAME = "Projektstatus";
public override void OnPublished(PSContextInfo contextInfo,
Microsoft.Office.Project.Server.Events.ProjectPostPublishEventArgs e)
{
base.OnPublished(contextInfo, e);
DoWork(contextInfo, e);
}
private void DoWork(IPSContextInfo contextInfo,
Microsoft.Office.Project.Server.Events.ProjectPostPublishEventArgs e)
{
using (new Tracer("StatusUpdateHandler", e.ProjectGuid))
{
Logger.Write("StatusUpdateHandler started...");
LoadSettings();
try
{
ProjectDerived project;
CustomFieldsDerived customFields;
QueueSystemDerived queueSystem;
using (SPSite spSite = new SPSite(contextInfo.SiteGuid))
{
project = new ProjectDerived();
project.Credentials =
CredentialCache.DefaultCredentials;
project.Url = WsUrl(spSite, "project", true);
customFields = new CustomFieldsDerived();
customFields.Credentials =
CredentialCache.DefaultCredentials;
customFields.Url = WsUrl(spSite, "customfields",
false);
queueSystem = new QueueSystemDerived();
queueSystem.Credentials =
CredentialCache.DefaultCredentials;
queueSystem.Url = WsUrl(spSite, "queuesystem", false);
}
Guid taskEntityId = new
Guid(EntityCollection.Entities.TaskEntity.UniqueId);
Guid projectEntityId = new
Guid(EntityCollection.Entities.ProjectEntity.UniqueId);
Guid isDeliveryMilestoneGuid =
FieldNameToGuid.GetGuidUsingFieldName(customFields,
IS_DELIVERY_MILESTONE_NAME,
taskEntityId);
Guid isProjectCriticalGuid =
FieldNameToGuid.GetGuidUsingFieldName(customFields,
IS_PROJECT_CRITICAL_NAME,
taskEntityId);
Guid taskStatusCriticalGuid =
FieldNameToGuid.GetGuidUsingFieldName(customFields,
TASK_STATUS_CRITICAL_NAME,
taskEntityId);
Guid projectStatusGuid =
FieldNameToGuid.GetGuidUsingFieldName(customFields,
PROJECT_STATUS_NAME,
projectEntityId);
bool isWindowsUser = contextInfo.IsWindowsUser ||
contextInfo.UserName.Contains("\\");
project.SetImpersonationContext(isWindowsUser,
contextInfo.UserName,
contextInfo.UserGuid,
contextInfo.TrackingGuid, contextInfo.SiteGuid,
contextInfo.Lcid);
Logger.Write(string.Format("Read Project {0}-{1} from
Server", e.ProjectGuid, e.ProjectName));
ProjectDataSet projectData =
project.ReadProject(e.ProjectGuid, DataStoreEnum.WorkingStore);
decimal projectStatus = 0;
// detect the max task status
foreach (ProjectDataSet.TaskRow task in
projectData.Task.Rows)
{
Guid taskUid = task.TASK_UID;
string taskName = task.TASK_NAME;
ProjectDataSet.TaskCustomFieldsRow
isDeliveryMileStoneField =
CustomFieldsHelper.GetTaskCustomFieldRow(projectData.TaskCustomFields,
taskUid, isDeliveryMilestoneGuid);
ProjectDataSet.TaskCustomFieldsRow
isProjectCriticalField =
CustomFieldsHelper.GetTaskCustomFieldRow(projectData.TaskCustomFields,
taskUid, isProjectCriticalGuid);
ProjectDataSet.TaskCustomFieldsRow
taskStatusCriticalField =
CustomFieldsHelper.GetTaskCustomFieldRow(projectData.TaskCustomFields,
taskUid, taskStatusCriticalGuid);
bool isDeliveryMilestone = isDeliveryMileStoneField
== null
? false
:
isDeliveryMileStoneField.FLAG_VALUE;
bool isProjectCritical = isProjectCriticalField ==
null
? false
:
isProjectCriticalField.FLAG_VALUE;
decimal taskStatus = taskStatusCriticalField == null
? 0 : taskStatusCriticalField.NUM_VALUE;
// Continue Loop when current task ist not
deliveryMilestone or not ProjectCritical
if (!isDeliveryMilestone && !isProjectCritical)
{
LogEntry entry = new LogEntry();
entry.Message =
string.Format(
"Current Task {0}-{1} is not a MileStone
then nor a project critical task", taskUid,
taskName);
entry.Severity = TraceEventType.Verbose;
if (Logger.ShouldLog(entry))
Logger.Write(entry);
continue;
}
// Set ProjectStatus
projectStatus = Math.Max(projectStatus, taskStatus);
// break loop if TaskStatus has max state
if (projectStatus.Equals(MAX_PROJECTSTATUS))
{
LogEntry entry = new LogEntry();
entry.Message = "projectStatus field has already
the max value.";
entry.Severity = TraceEventType.Verbose;
if (Logger.ShouldLog(entry))
Logger.Write(entry);
break;
}
}
// Set Project status field
ProjectDataSet.ProjectCustomFieldsRow projectStatusField =
CustomFieldsHelper.GetProjecctCustomFieldRow(projectData.ProjectCustomFields,
e.ProjectGuid, projectStatusGuid);
if (projectStatusField == null)
{
Logger.Write("Add new custom field
\"Projektstatus\"");
projectStatusField =
projectData.ProjectCustomFields.NewProjectCustomFieldsRow();
projectStatusField.CUSTOM_FIELD_UID = Guid.NewGuid();
projectStatusField.MD_PROP_UID = projectStatusGuid;
projectStatusField.NUM_VALUE = 0;
projectStatusField.PROJ_UID = e.ProjectGuid;
projectStatusField.FIELD_TYPE_ENUM =
(byte)PSDataType.NUMBER;
projectData.ProjectCustomFields.AddProjectCustomFieldsRow(projectStatusField);
}
Logger.Write(string.Format("Current value of
\"Projektstatus\" {0} => {1}. No Action required if the values are equal.",
projectStatusField.NUM_VALUE, projectStatus));
if (!projectStatusField.NUM_VALUE.Equals(projectStatus))
{
projectStatusField.NUM_VALUE = projectStatus;
ProjectDataSet.ProjectRow projectRow =
(ProjectDataSet.ProjectRow)projectData.Project.Rows[0];
Guid sessionId = projectRow.IsPROJ_SESSION_UIDNull()
? Guid.NewGuid()
: projectRow.PROJ_SESSION_UID;
Guid jobId = e.JobGuid;
Logger.Write("Updateing the current Project.");
project.QueueUpdateProject(jobId, sessionId,
projectData, false);
//TODO: Check wait required !?
int waitTime = queueSystem.GetJobWaitTime(jobId);
Thread.Sleep(waitTime * 1000);
Logger.Write("Publishing the current Project.");
project.QueuePublish(jobId, e.ProjectGuid,
e.FullPublish, "");
}
}
catch (SoapException ex)
{
PSClientError error = new PSClientError(ex);
StringBuilder sb = new StringBuilder();
sb.AppendFormat("An error occurred during
StatusUpdateHandler proccessing:\n");
if (error.HasErrors)
{
foreach(PSErrorInfo errorInfo in error.GetAllErrors())
{
sb.AppendFormat("Error Id: {0} - Error Uid: {1}
- Error Name {2} - Attributes: {3}\n",
errorInfo.ErrId, errorInfo.ErrUid,
errorInfo.ErrName, string.Join(";", errorInfo.ErrorAttributes));
}
}
Logger.Write(sb.ToString());
}
catch (Exception ex)
{
bool rethrow = ExceptionPolicy.HandleException(ex,
"Logging Policy");
if (rethrow)
throw;
}
}
}
#region private methods
private string WsUrl(SPSite ss, string wsName, bool impersonate)
{
if (impersonate)
return string.Format("{0}//{1}:56737/{2}/psi/{3}.asmx",
ss.Protocol, ss.HostName, _sspName,
wsName);
return string.Format("{0}/_vti_bin/psi/{1}.asmx",
ss.Url, wsName);
}
private void LoadSettings()
{
// Load settings from
Microsoft.Office.Project.Server.Eventing.exe.config
_sspName = Properties.Settings.Default.PWASSpName;
Logger.Write(string.Format("Current settings from
Microsoft.Office.Project.Eventing.exe.config: PWASSpName:{0}", _sspName));
}
#endregion
}
}
:
Can you please post your code?
--
Stephen Sanderlin
VP of Technology
MSProjectExperts
For Project Server Consulting:
http://www.msprojectexperts.com
For Project Server Training:
http://www.projectservertraining.com
Read my blog at:
http://www.projectserverhelp.com
Join the community at:
http://forums.epmfaq.com