Monday, 1 December 2014

How to Update Activity Entity Record When Completed/Canceled Using CRM SDK C#

As we know, in the activity entity, after you completed or close/canceled an activity record, you cannot modify any value of this activity record. Well, it happened to any entity and you might need to re-open it first. But, sometimes, you need to update some fields when you cancel or complete activities, such as you want to give additional description, you want to save field based on the regarding field, or you want to add some calculation inside when you close any activities.

So, here we are, this is the code to update field when you close the activity, you need a plugin.

public void Execute(IServiceProvider serviceProvider)
        {
            #region must to have

            IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));

            IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));

            // Create service with context of current user
            IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);

            //create tracing service
            ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));

            #endregion

            string strStatus = string.Empty;

            if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
            {

                //create entity context
                Entity entity = (Entity)context.InputParameters["Target"];

                if (entity.LogicalName != TFP.Xrm.Contoso.Task.EntityLogicalName)

                    return;

                try
                {
                    if (entity.Contains("statecode"))
                    {
                        //Update the description
                        strStatus = GetStateCodeText(service, entity.LogicalName, "statecode", 
                            ((OptionSetValue)entity["statecode"]).Value);
                        
                        //update the description field
                        entity["description"] = String.Format("{0} on {1}", strStatus, DateTime.Now.ToString("dd/MM/yyyy"));
                    }
                }
                catch (Exception ex)
                {
                    throw new InvalidPluginExecutionException(ex.Message);

                }

            }
        }



The most notable is this line:
if (entity.Contains("statecode"))
{


}

You can have your own logic, in my scenario is I want to update the description field in Task entity to capture the status (in text) + the time, I am sure that you guys have your own scenario Smile, for example update another field based on the status and so one.

And the most important thing is you need to register this plugin onPreUpdate

image

Result:

image

See the updated Description field below.

image

Hope this helps!

Thanks.

9 comments:

  1. Hi,
    Awesome article. I often come to your blog to learn if I have any doubt. You give a very good indepth explanation which I like the most. Thanks for your articles.
    Also, regarding this article..What is this function "GetStateCodeText"? I am seeing does not exist in the current context.

    ReplyDelete
    Replies
    1. Hi,

      Thank you for your comment.
      Oh yes, I forgot to put it into the content.
      I'll update my post, thank you again for correction.
      This function is supposedly to get the text of the status code, because my purpose in this example is to fill the Description name, you might have different scenario and might not need this function in your scenario.

      Delete
  2. One more question..
    What should the condition be if I only want to change the description field when the statecode is about to change to 'Completed' or to 'Canceled'?
    Thanks

    ReplyDelete
    Replies
    1. Hi,

      You need to add more If statement as conditional after here:

      if (entity.Contains("statecode"))
      {
      //to get the current statecode:
      int intStateCode = (OptionSetValue)entity["statecode"]).Value;

      //and to get the Completed or Canceled
      if (intStateCode == 1 || intStateCode == 2)
      {
      //then put your logic here
      }

      }

      You can see the statecode list here:

      http://mostlymscrm.blogspot.com/2012/06/entity-statecodes-and-statuscodes.html

      Thank you.

      Delete
  3. Hi,
    I have a requirement to change the value of a lookup field like you did for an attribute.
    if(entity.Contains("statecode"))
    {
    OptionSetValue entityStatusCode =
    (OptionSetValue)entity.Attributes["statecode"];

    if(entityStatusCode.Value==2)
    {
    entity["new_instructions"] = String.Format("Canceled on {0}", DateTime.Now.ToString("dd/MM/yyyy"));
    Entity task = new Entity("task");
    task["new_issuephase"] = "Work Complete";
    EntityReference primaryIssuePhaseId = new EntityReference("new_issuephase", new Guid("56B224740-2C48-E511-93F0-001D09724UD0"));
    task["activityid"] = primaryIssuePhaseId;
    }
    }

    What am I doing wrong?

    ReplyDelete
  4. if(entity.Contains("statecode"))
    {
    OptionSetValue entityStatusCode =
    (OptionSetValue)entity.Attributes["statecode"];
    var statecode = entityStatusCode.value.ToString();

    if(statecode.Value==2)
    {
    entity["new_instructions"] = String.Format("Canceled on {0}", DateTime.Now.ToString("dd/MM/yyyy"));
    Entity task = new Entity("task");
    task["new_issuephase"] = "Work Complete";
    EntityReference primaryIssuePhaseId = new EntityReference("new_issuephase", new Guid("56B224740-2C48-E511-93F0-001D09724UD0"));
    task["activityid"] = primaryIssuePhaseId;
    }
    }

    ReplyDelete
  5. This comment has been removed by the author.

    ReplyDelete
  6. Hi.. thanks for this.in my code i have got exception in service.update() method. can you please help.. this line not used in your code. so the service.update() is not required??

    ReplyDelete
  7. Hi Aileen, I have a query why Pre-Operation is used for "Update" message at register a step in a plugin.
    could you elaborate this?

    ReplyDelete

My Name is..