Welcome to WordPress.com. This is your first post. Edit or delete it and start blogging!
-
Recent Posts
Archives
Categories
Meta
Welcome to WordPress.com. This is your first post. Edit or delete it and start blogging!
In project server 2007, timesheet is a very good new feature. However, when user enters timesheet and save it back to server, the server does not validate the number. For example, user can enter 30 hours for a day. You can set the limitation in Timesheet settings, however project server only validate timesheet hours when user submits it. What if you don’t want team members to enter ridiculous hours, here is a solution. You can use PSI event handler to track the changes and cancel the change for whatever reason. Here is how to do it.
Step 1: create a project server event handler to validate user input.
Timesheet Updating event occurs when a user tries to save timesheet but before it is actually saved. You can use this event to validate user input. If the timesheet is valid, you will let timesheet being saved. Otherwise you can cancel the process and abort saving.
You can use Timesheet web service to find the hours saved before. And you can find what user changed in the TimesheetPreUpdateArgs class, which is stored in DsDelta dataset. DsDelta dataset would only store the changed hours not all hours. You need to merge the two dataset to get “real” updating dataset.
If you find the hours are not valid, you can set the TimesheetPreUpdateEventArgs.Cancel=True and TimesheetPreUpdateEventArgs.CancelReason=”Timesheet cancel reson”. Then project server will stop processing timesheet updating and return to timesheet page. Project server will also save an error message to event log.
However, when you return to timesheet page, the project server does not show any message for cancelling timesheet. You will need the second step to show the actual reason.
Here is some sample code that it can check if actual hours in one day is more than 24 hours. If so, it will cancel the event.
public override void OnUpdating(PSContextInfo contextInfo, TimesheetPreUpdateEventArgs e)
{
if (e.DsDelta == null)
{
return;
}
TimesheetSvc.TimeSheet ts = new TimesheetSvc.TimeSheet();
ts.Url = _EPMSite + _TimesheetSvc;
ts.Credentials = CredentialCache.DefaultCredentials;
TimesheetSvc.TimesheetDataSet tsDs = ts.ReadTimesheet(e.TsUID);
TimesheetSvc.TimesheetDataSet.ActualsDataTable tblActuals = MergeActuals(tsDs.Actuals, e.DsDelta.Actuals);
Dictionary<DateTime, Decimal> TblTotal = AccumulateActuals(tblActuals);
string Msg = ValidateActuals(TblTotal);
if (Msg != "")
{
e.CancelEvent(Msg);
}
}
Since the timesheet page cannot show cancel reason from event handler, you may need to create a custom web part to show the reason. You can just create a very simple web part which contains a label control. The web part will read event log and display if it found any recent error log.