Wednesday, January 25, 2012

Update a Closed / Completed Task

Sometimes there may be an instance where you need to update some fields on a task activity through the SDK, but there is an initial problem.  If you just try to run UpdateObject on the record, it will tell you that you can't update a task that is closed.

What you have to do is temporarily re-open the task, make the change, then close it again.  This will reflect in your audit log, and any plugin's on the SetState message will fire, so use accordingly.

In my Method, I am clearing a custom field called InternalQueueId that is a lookup to another entity.



int RecordCount = 1;
int TaskClosedState, TaskClosedStatus;


List<SPS.Task> Tasks = (from t in xrmConnection.TaskSet
                            where t.StatusCode == 5
                                && t.custom_internalqueueid != null
                            orderby t.ActivityId 
                            select t).Take(MaxRecordsToProcess).ToList();
if (Tasks.Count > 0)
{
    foreach (var t in Tasks)
    {
        TaskClosedState = t.StateCode.Value;
        TaskClosedStatus = t.StatusCode.Value;


        RecordCount += 1;


        // Reopen the task    
        SetStateRequest ssr = new SetStateRequest();
        ssr.EntityMoniker = t.ToEntityReference();
        ssr.State = new OptionSetValue(0);
        ssr.Status = new OptionSetValue(2);
        SetStateResponse resp1 = (SetStateResponse)xrmConnection.Execute(ssr);


        // Update the field and set it back to null
        if (t.custom_internalqueueid != null)
        {
            SPS.Task tUpdate = (Task)xrmConnection.Retrieve(Task.EntityLogicalName, t.Id, new ColumnSet("activityid", "custom_internalqueueid"));
            tUpdate.custom_internalqueueid = null;
            UpdateRequest ur = new UpdateRequest()
                {
                    Target = tUpdate,
                };
            xrmConnection.Execute(ur);


        }


        // Re-Close the task
        SetStateRequest Closed = new SetStateRequest();
        Closed.EntityMoniker = new EntityReference(t.LogicalName, t.Id);
        Closed.State = new OptionSetValue(TaskClosedState);
        Closed.Status = new OptionSetValue(TaskClosedStatus);
        SetStateResponse resp2 = (SetStateResponse)xrmConnection.Execute(Closed);


        xrmConnection.SaveChanges();


    }


    RecordCount -= 1;
    xrmConnection.SaveChanges();
}

Kudos to David Jennaway @ http://mscrmuk.blogspot.com/ for pointing me in the right direction to solve this.


No comments:

Post a Comment