Tuesday 24 June 2014

Update Opportunity on 'Close as Won' or 'Close as Lost'

I had a requirement that I thought would be quite basic, on Close Won/Lost then update a field on Opportunity.

My first thought was that this could be on using the following Plugin setup:
  • Message - Update
  • Primary Entity - opportunity
  • Secondary Entity - none
However I found that the above did not fire. A bit of googling and I found that i instead needed to use the following:
  • Message - Win
  • Primary Entity - opportunity
  • Secondary Entity - none
AND
  • Message - Lose
  • Primary Entity - opportunity
  • Secondary Entity - none
This does not return the opportunity as "Target" as you might think it actually returns "Status" and "OpportunityClose". OpportunityClose contains the information listed on the form displayed when you try to Win/Lose an Opportunity,  CRM stores this as a separate entity.

Opportunity does provide you with the related opportunityid however so you can update the original opportunity if required (Just be aware that THIS will then fire any "Update opportunity" plugin steps!)

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


if (context.InputParameters.Contains("OpportunityClose")
 &&
 context.InputParameters["OpportunityClose"] is Entity)
{
 // Obtain the target entity from the input parameters.
 var entity = (Entity)context.InputParameters["OpportunityClose"];

 try {

  if (entity.Attributes.Contains("opportunityid")) {
   var opportunityId = ((EntityReference)entity.Attributes["opportunityid"]).Id;

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

   // Getting the service from the Organisation Service.
   IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);

   Entity opportunity = service.Retrieve("opportunity", opportunityId, new ColumnSet(new string[] { "closeprobability" }));
   opportunity["closeprobability"] = 50;
   service.Update(opportunity);
  }
 }
 catch (Exception ex) {
  tracingService.Trace("Plugin: {0}", ex.ToString());
  throw;
 }
}

4 comments:

  1. why does OpportunityClose do not provide status reason i.e. status code in plugin for CRM 2013?

    i have some custom status reasons.....

    ReplyDelete
  2. The Status Reason is part of the Opportunity record so change this line
    Entity opportunity = service.Retrieve("opportunity", opportunityId, new ColumnSet(new string[] { "statuscode", "closeprobability" }));

    Then you can retrieve the status reason
    var yourstatuscode = opportunity["statuscode"];

    ReplyDelete
  3. Thanks this helped me a lot :)

    ReplyDelete
  4. This is not working at all in D365. Instead I am getting error message pop up if I have active / draft quotes. Please help.

    Thanks

    ReplyDelete