none
Updating Timesheet via Timesheet. Not showing up in PWA RRS feed

  • Question

  • I have two questions regarding the timesheet in Project Server 2010.

    1) We are currently running our Project Server 2010 in "Single Entry Mode".  When I update actuals via the Timesheet Service the time doesn't show up in PWA.  If I disable "Singer Entry Mode"  I can see the time.  What method should I be calling in addition to updating the actuals dataset?

    2)  How do I refresh the timesheet after running my import?  The users are clicking a custom button on the ribbon which opens ModalDialog.

    Thanks

    Wednesday, August 25, 2010 3:12 PM

Answers

  • Hi Aqil,

    I don't see that you submit anywhere in your code.  Is the problem that the timesheet is already submitted?  You can use the QueueRecall option, but some of these queued jobs may not be the best thing to be using in a modal dialog.  I can also imagine you will run into some timing issues as you appear to be programmatically adding any assignments that are not already present - which will be a challenge if the project is checked out.

    It feels like you would be better to use the statusing web service rather than interfacing through the timesheet - or just use timesheet lines if these are not really project tasks, which from your description they are not.

    Best regards,

    Brian

     


    Blog | Facebook | Twitter | Posting is provided "AS IS" with no warranties, and confers no rights.
    Project Server TechCenter | Project Developer Center | Project Server Help | Project Product Page
    Friday, September 3, 2010 8:19 PM
    Owner

All replies

  • Aqil can you be more precise about #1 "time doesn't show up in PWA". Please remember that there is an approval process that takes place and until the task updates have been approved and the project republished actual work will not appear in the Project Center
    Blog | Facebook | Twitter | Posting is provided "AS IS" with no warranties, and confers no rights.
    Project Server TechCenter | Project Developer Center | Project Server Help | Project Product Page
    Wednesday, August 25, 2010 4:38 PM
  • Here is the scenario:

    We have a call management where user track part of their time.  We want the users to be able to import the time into certain projects in Project Server.  What we have done is added a button to the timesheet to import the time into the timesheet. When the button is pressed a modaldialog is opened which runs a aspx page to call the psi wcf services.  Here is the code we are using to add the entries:

            private static void AddEntries(List<ProgramHours> hours, ProjectClient psc, AdminClient asc, TimeSheetClient tsc, QueueSystemClient qsc, ref TimesheetDataSet timesheetDs, Guid timeSheetUID)
            {
                List<Guid> linesToUpdate = new List<Guid>();
                foreach (ProgramHours entry in hours)
                {
                    // todo: error catch each entry
                    if (entry.ProjectID == null)
                        continue;
                    // Retrieve project info
                    ProjectDataSet dsProject = psc.ReadProject(new Guid(entry.ProjectID), SvcProject.DataStoreEnum.PublishedStore);
                    WriteTablesToConsole(dsProject.Tables);
                    // Retrieve ITSM Task
                    DataTable tasks = dsProject.Tables["Task"];
                    DataRow itsmTaskRow = null;
                    foreach (DataRow row in tasks.Rows)
                    {
                        if (row["Task_Name"].ToString() == "ITSM")
                        {
                            itsmTaskRow = row;
                            break;
                        }
                    }

                    DataTable assignment = dsProject.Tables["Assignment"];
                    DataRow assignmentTaskRow = null;
                    //Retrieve the Assignmentrow
                    foreach (DataRow row in assignment.Rows)
                    {
                        if (row["TASK_UID"].ToString() == itsmTaskRow["TASK_UID"].ToString() && myUid.ToString() == row["RES_UID"].ToString())
                        {
                            assignmentTaskRow = row;
                            break;
                        }
                    }
                    //create assignment on the project if not found
                    if (assignmentTaskRow == null)
                    {
                        ProjectDataSet dstmp = new ProjectDataSet();
                        ProjectDataSet.AssignmentRow assignmentRow = dstmp.Assignment.NewAssignmentRow();

                        assignmentRow.PROJ_UID = new Guid(entry.ProjectID);
                        assignmentRow.ASSN_UID = Guid.NewGuid();
                        assignmentRow.TASK_UID = (Guid)itsmTaskRow["TASK_UID"];
                        assignmentRow.RES_UID = myUid;
                        dstmp.Assignment.AddAssignmentRow(assignmentRow);
                
                        try
                        {
                            UpdateProjectInformation(psc, new Guid(entry.ProjectID), qsc, dstmp);
                        }
                        catch (FaultException e1)
                        {
                            WriteFaultOutput(e1);
                        }

                        assignmentTaskRow = (DataRow)assignmentRow;
                    }
                   
                    Guid lineGuid = Guid.Empty;
                    //Get the timesheet line item if exists
                    foreach (DataRow row in timesheetDs.Tables["Lines"].Rows)
                    {
                        if (row["PROJ_UID"].ToString() == entry.ProjectID && row["TASK_UID"].ToString() == itsmTaskRow["TASK_UID"].ToString())
                        {
                            lineGuid = new Guid(row["TS_LINE_UID"].ToString());
                            break;
                        }
                    }
                    // Create new line item if it doesn't already exist.
                    Guid projectID = new Guid(entry.ProjectID);
                    Guid taskID = new Guid(itsmTaskRow["TASK_UID"].ToString());
                    Guid assignmentID = new Guid(assignmentTaskRow["ASSN_UID"].ToString());

                    if (lineGuid == Guid.Empty)
                    {
                        SvcAdmin.TimesheetLineClassDataSet tsLineClassDs = asc.ReadLineClasses(SvcAdmin.LineClassType.All, SvcAdmin.LineClassState.Enabled);
                        SvcTimeSheet.TimesheetDataSet.LinesRow line = timesheetDs.Lines.NewLinesRow();

                        line.TS_UID = timeSheetUID;
                        line.TS_LINE_UID = Guid.NewGuid();
                        line.TS_LINE_CLASS_UID = tsLineClassDs.LineClasses[0].TS_LINE_CLASS_UID;//new Guid("fcdb0e4e-b9c7-4a39-804f-fa44796f71a0");
                        line.TS_LINE_COMMENT = "Added by automated ITSM import process.";
                        line.TS_LINE_STATUS = (byte)TimesheetEnum.LineStatus.PendingApproval;//(byte)PSLibrary.TimesheetEnum.LineStatus.NotApplicable;
                        line.TS_LINE_VALIDATION_TYPE = (byte)PSLibrary.TimesheetEnum.ValidationType.Verified;
                        line.TS_LINE_CACHED_ASSIGN_NAME = tsLineClassDs.LineClasses[0].TS_LINE_CLASS_DESC;
                        lineGuid = line.TS_LINE_UID;
                        line.PROJ_UID = projectID;
                        line.TASK_UID = taskID;
                        line.ASSN_UID = assignmentID;
                        timesheetDs.Lines.AddLinesRow(line);
                    }

                    lineHoursList.Add(new LineHours { LineID = lineGuid, Date = entry.EntryDate.Date, Hours = Decimal.Parse((ConvertHoursToMilliseconds(entry.HoursTotal) / 60).ToString()) });
                }
                tsc.PrepareTimesheetLine(timeSheetUID, ref timesheetDs, linesToUpdate.ToArray());
                foreach (SvcTimeSheet.TimesheetDataSet.ActualsRow actualrow in timesheetDs.Actuals)
                {
                   // LineHours find = lineHoursList.Find(delegate(LineHours lh) { return lh.LineID == actualrow.TS_LINE_UID; });
                    var find = from linehour in lineHoursList
                               where linehour.LineID == actualrow.TS_LINE_UID  &&  linehour.Date.Date== actualrow.TS_ACT_START_DATE.Date
                                     select linehour;
                    if (find.Count() >0)
                    {
                       LineHours getHours= (LineHours) find.First();
                       actualrow.TS_ACT_VALUE = getHours.Hours;
                    }
                }
            }

    Wednesday, August 25, 2010 5:19 PM
  • Ok so again how do you handle the standard approval workflow to ensure that the update appears as actual work in the project plan?
    Blog | Facebook | Twitter | Posting is provided "AS IS" with no warranties, and confers no rights.
    Project Server TechCenter | Project Developer Center | Project Server Help | Project Product Page
    Wednesday, August 25, 2010 6:04 PM
  • We are pretty new to project server development.  I am not sure how to handle it in the code.  The typical end user workflow is that the user adds the time to timesheet for a task and submits the time.  the manager aproves the time and task updates.

     

    Wednesday, August 25, 2010 9:57 PM
  • I jsut need some guidance on what else I need to do to have the timesheet to show a not submitted status in the timesheet.  The users should be able to update the time one time before submitting the line item.
    Thursday, August 26, 2010 3:01 PM
  • Any help?
    Wednesday, September 1, 2010 4:37 PM
  • Hi Aqil,

    I don't see that you submit anywhere in your code.  Is the problem that the timesheet is already submitted?  You can use the QueueRecall option, but some of these queued jobs may not be the best thing to be using in a modal dialog.  I can also imagine you will run into some timing issues as you appear to be programmatically adding any assignments that are not already present - which will be a challenge if the project is checked out.

    It feels like you would be better to use the statusing web service rather than interfacing through the timesheet - or just use timesheet lines if these are not really project tasks, which from your description they are not.

    Best regards,

    Brian

     


    Blog | Facebook | Twitter | Posting is provided "AS IS" with no warranties, and confers no rights.
    Project Server TechCenter | Project Developer Center | Project Server Help | Project Product Page
    Friday, September 3, 2010 8:19 PM
    Owner
  • The Statusing Services were the way to go.

    Thanks,


    Aqil

     

    Wednesday, September 15, 2010 6:07 PM