Update Timesheet Using PSI in Project Server 2013

Update Timesheet Using PSI in Project Server 2013

Update Timesheet Using PSI in Project Server 2013. Hello, friends today I will describe you how to Update Timesheet Using PSI. Basically, in this post, you will learn how to update actual hours. Actual hour decide by the project manager and actual hour decide by the resource. Programmatically when we update actual task means we are talking about TS_ACT_VALUE.

If you don’t know how to add service reference then follow my post. Add PSI Web Reference in Solution file

Below is Image to show the required namespace


Update Timesheet

If you are not able to add reference ProjectServerService namespace then follow my post:-
How to Create Project Server Service dll

Update Timesheet Using PSI in Project Server 2013 code:-


using System;
using System.Collections.Generic;
using System.Data;
using PSLibrary = Microsoft.Office.Project.Server.Library;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Xml;
using SvcAdmin;
using System.Security.Principal;
namespace UpdateTimesheet

    class Program
        //update timesheet====
        public static string ENDPOINT_PROJECT = "basicHttp_Project";
        public static string ENDPOINT_RESOURCE = "basicHttp_Resource";
        public static string ENDPOINT_TIMESHEET = "basicHttp_TimeSheet";
        public static string ENDPOINT_ADMIN = "basicHttp_Admin";
        public static string ENDPOINT_QUEUESYSTEM = "basicHttp_QueueSystem";
        public static SvcResource.ResourceClient resourceClient;
        public static SvcResource.Resource resourceWS = null;
        public static SvcResource.ResourceDataSet ResourceDs = null;
        private static SvcStatusing.StatusingClient statusingClient;
        public static SvcTimeSheet.TimeSheetClient timesheetClient;
        public static SvcAdmin.AdminClient adminClient;
        public static SvcQueueSystem.QueueSystemClient queueSystemClient;
        public static string CurrentUser = string.Empty;
        public static Guid CurrentUserUID = Guid.Empty;
        public static Guid timesheetuid;
        public static Guid perioduid;
        public static Guid approveduid = new Guid("edcc4c52-05e8-e411-931d-00155d013b12"); //Timesheet Manager GUID
        public static Guid jobUid;
        public static int index;

        public static string PWAURL = "http://Server/PWAPath/"; //
        static void Main(string[] args)
        public static void UpdateTimesheet()

                string UserId = "Donald"; //Enter username, which user's task you want update
                string TimeByDay = "07/21/2015";//Enter task assignment date ,on which you want to update your timesheet task
                string TaskName = "analysis"; //Enter Task Name
                string ActualHours = "2"; //Enter Assign Actual Update Time

                ResourceDs = resourceClient.ReadResources("", false);
                UserId = string.Concat("i:0#.w|epm", @"", UserId); // epm is domain name
                CurrentUser = string.Concat("epm", @"", UserId);
                DataRow[] dr = ResourceDs.Tables[0].Select("WRES_ACCOUNT='" + UserId + "'");
                Guid ResourceUid = new Guid(dr[0][0].ToString());//resourceClient.GetCurrentUserUid();

                DateTime TimeByDate = DateTime.Parse(TimeByDay);
                int dayOfWeek = (int)TimeByDate.DayOfWeek;
                dayOfWeek = dayOfWeek == 0 ? 7 : dayOfWeek;
                int delta = DayOfWeek.Monday - TimeByDate.DayOfWeek;
                DateTime startDateOfWeek = TimeByDate.AddDays(delta); //Date of Monday of week
                if (dayOfWeek <= 0 || dayOfWeek > 5)
                    Console.WriteLine("Staurday And Sunday no Task");

                    if (dayOfWeek > 0)
                        TimePeriodDataSet period = adminClient.ReadPeriods(PeriodState.Open);//All period data set inside EMP
                        perioduid = new Guid(period.Tables[0].Select("WPRD_START_DATE='" + startDateOfWeek + "'")[0]["WPRD_UID"].ToString());
                        PSLibrary.PSContextInfo contextInfo = new PSLibrary.PSContextInfo(true, CurrentUser, ResourceUid, Guid.Empty, Guid.Empty, null, null);
                        string contextInfoString = PSLibrary.PSContextInfo.SerializeToString(contextInfo);
                        using (OperationContextScope scope = new OperationContextScope(timesheetClient.InnerChannel))
                            WebOperationContext.Current.OutgoingRequest.Headers.Add("PjAuth", contextInfoString);
                            WebOperationContext.Current.OutgoingRequest.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f");
                            SvcTimeSheet.TimesheetDataSet Mytimesheet1 = timesheetClient.ReadTimesheetByPeriod(ResourceUid, perioduid, SvcTimeSheet.Navigation.Current);
                            timesheetuid = new Guid(Mytimesheet1.Headers.Select("WPRD_UID ='" + perioduid + "'")[0]["TS_UID"].ToString());
                            var status = (PSLibrary.TimesheetEnum.Status)Mytimesheet1.Headers[0].TS_STATUS_ENUM;
                            if (status.ToString() == "Submitted" || status.ToString() == "PendingSubmit")
                                timesheetClient.QueueRecallTimesheet(Guid.NewGuid(), timesheetuid);
                            Mytimesheet1 = timesheetClient.ReadTimesheet(timesheetuid);
                            DataTable TaskRow = Mytimesheet1.Lines.Select("TS_LINE_CACHED_ASSIGN_NAME='" + TaskName + "'").CopyToDataTable();
                            int count = TaskRow.Rows.Count;
                            string TS_LINE_UID = TaskRow.Rows[0]["TS_LINE_UID"].ToString();
                            DataRow[] ActualRow = Mytimesheet1.Actuals.Select("TS_LINE_UID='" + TS_LINE_UID + "'");
                            int i = 0;
                            SvcTimeSheet.TimesheetDataSet timesheetds = new SvcTimeSheet.TimesheetDataSet();
                            if (Mytimesheet1.Actuals.Rows.Count > 0)
                                foreach (DataRow row in ActualRow)
                                    DateTime dd = Convert.ToDateTime(row[2]).Date;
                                    if (TimeByDate == dd)
                                        index = Mytimesheet1.Actuals.Rows.IndexOf(row);
                                Mytimesheet1.Actuals.Rows[index]["TS_ACT_VALUE"] = int.Parse(ActualHours) * 60000;
                            jobUid = Guid.NewGuid();
                            status = (PSLibrary.TimesheetEnum.Status)Mytimesheet1.Headers[0].TS_STATUS_ENUM;
                            if (status.ToString() == "Approved")
                                timesheetClient.QueueRecallTimesheet(Guid.NewGuid(), timesheetuid);
                            if (status.ToString() != "Submitted")
                                timesheetClient.QueueSubmitTimesheet(Guid.NewGuid(), timesheetuid, approveduid, "submit by program");
                            timesheetClient.QueueRecallTimesheet(Guid.NewGuid(), timesheetuid);
                            timesheetClient.QueueUpdateTimesheet(jobUid, timesheetuid, Mytimesheet1);
                            WaitForQueueJobCompletion(jobUid, -1);
                            timesheetClient.QueueSubmitTimesheet(Guid.NewGuid(), timesheetuid, approveduid, "test data");



            catch (FaultException fault)
                // WriteFaultOutput(fault);




  1. Hi Can we read all employee timesheets of Project Online using CSOM?.

    Is there any way to read all employees timesheets? What is the best approach, I am using CSOM through a console application?

    Please suggest me the best approach, where I can read all timesheets from Project Online based on resource type and need to export to csv ?

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

error: Content is protected !!