sharepointsharepoint-2013csomms-project-server-2013

Update Task Status Progress Project Server 2013


I attempt to update the task status progress (Status Assignment) using project server 2013 CSOM, but I got "Unknown Error" Exception and the following StackTrace:

at Microsoft.SharePoint.Client.ClientRequest.ProcessResponseStream(Stream responseStream) at Microsoft.SharePoint.Client.ClientRequest.ProcessResponse() at Limitless.Components.Project2013.ProjectComponent.UpdateTask(ProjectServerConnection connection, Guid ProjectUID, List`1 data)

ProjectContext context = GetProjectContext(connection);
// Get the user name  and their assignments
EnterpriseResource self = EnterpriseResource.GetSelf(context);
context.Load(self, r => r.Name, r => r.Assignments
    .IncludeWithDefaultProperties(a => a.Project, a=>a.Comments));
context.ExecuteQuery();
foreach(var item in self.Assignments)
{
    Entities.Task task = data.Where(t => t.ID == item.Id).SingleOrDefault();
    if(task!= null)
    {
        item.PercentComplete = (short)task.PercentComplete;
        item.Comments = "comment";
    }
}

// Update the assignments and submit the status updates.
self.Assignments.Update();
self.Assignments.SubmitAllStatusUpdates("By PS Web App");
context.ExecuteQuery();

I couldn't find any error in the sharepoint logs. its a fresh installation Project Server 2013, and it retrieves Tasks (StatusAssignments) successfully, but after self.Assignments.Update(); and self.Assignments.SubmitAllStatusUpdates("By PS Web App"); the exception is thrown on context.ExecuteQuery();.

any one came cross such scenario ?


Solution

  • I hope it's not that late for anyone who face the same issue, this was solved and working properly but I'm not sure if it is the right way.

    instead of updating the TaskAssignment by the current user context, I get it using elevated context (admin context for example), and get resource's assignments, and update them.

    //private function to get admin context
    ProjectContext elevatedContext = GetProjectElevatedContext(connection);
    //private function to get current user context
    ProjectContext context = GetProjectContext(connection);
    
    // Get the user name  and their assignments
    EnterpriseResource self = EnterpriseResource.GetSelf(context);
    context.Load(self, r => r.Id, r => r.Assignments.IncludeWithDefaultProperties(a => a.ActualFinish));
    context.ExecuteQuery();
    
    var resource = elevatedContext.EnterpriseResources.GetById(self.Id.ToString());
    elevatedContext.Load(resource, r => r.Assignments
        .IncludeWithDefaultProperties(a => a.Project, a => a.Comments, a => a.PercentComplete));
    elevatedContext.ExecuteQuery();
    
    int count = 0;
    
    foreach (var item in resource.Assignments)
    {
        Entities.Task task = data.Where(t => t.ID == item.Id).SingleOrDefault();
        if (task != null)
        {
            item.PercentComplete = (short)task.PercentComplete;
            item.Comments = "comment";
            count++;
        }
    }
    
    resource.Assignments.Update();
    resource.Assignments.SubmitAllStatusUpdates($"comment");
    elevatedContext.ExecuteQuery();
    

    I couldn't find a permission that is granted for such functionality from CSOM.

    If anyone has a better tested solution please contribute :)