Friday, April 27, 2012

How to update the parent record when children records are created or updated

Few months ago, I wrote a blog on “How to update the children records when parent record is updated”. Here is link to that blog. In this blog I am posting a code on “How to update the parent record when child record is created or updated”. The scenario is that I want to display the sum of total of "Estimated Revenue” of the opportunities on the parent account record. Here are the steps
  • Create a new attribute named “new_oppamount” on the account entity and place it on the account entity form.
  • Publish the account entity
  • Create the plugin
  • Register this plugin on postcreate, postupdate , postsetstate and postsetstatedynamic  events of opportunity entity.
Here is the code. The code is using the fetch xml to get the sum of “Estimated Revenue” field of the open opportunities. Follow the steps mentioned in here and replace the ExecutePostAccountUpdateContacts method with follwing method
protected void ExecutePostOpportunityCreate(LocalPluginContext localContext)
{
    if (localContext == null)
    {
        throw new ArgumentNullException("localContext");
    }
            

    IPluginExecutionContext context = localContext.PluginExecutionContext;

    //Get a IOrganizationService
    IOrganizationService service = localContext.OrganizationService;

    //create a service context
    var ServiceContext = new OrganizationServiceContext(service);
    //ITracingService tracingService = localContext.TracingService;

    // The InputParameters collection contains all the data passed in the message request.
    if (context.InputParameters.Contains("Target") &&
    context.InputParameters["Target"] is Entity)
    {
        // Obtain the target entity from the input parmameters.
        Entity entity = (Entity)context.InputParameters["Target"];

        //get the customerid
        EntityReference a = (EntityReference)entity.Attributes["customerid"];
                
        decimal totalAmount=0;
                
        try
        {   
            //fetchxml to get the sum total of estimatedvalue
            string estimatedvalue_sum = string.Format(@" 
            <fetch distinct='false' mapping='logical' aggregate='true'> 
                <entity name='opportunity'> 
                    <attribute name='estimatedvalue' alias='estimatedvalue_sum' aggregate='sum' /> 
                    <filter type='and'>
                        <condition attribute='statecode' operator='eq' value='Open' />
                            <condition attribute='customerid' operator='eq' value='{0}' uiname='' uitype='' />
                    </filter>
                </entity>
            </fetch>", a.Id);
            EntityCollection estimatedvalue_sum_result = service.RetrieveMultiple(new FetchExpression(estimatedvalue_sum));

            foreach (var c in estimatedvalue_sum_result.Entities)
            {
                totalAmount = ((Money)((AliasedValue)c["estimatedvalue_sum"]).Value).Value;
            }
                    
            //updating the field on the account
            Entity acc = new Entity("account");
            acc.Id = a.Id;
            acc.Attributes.Add("new_oppamount", new Money(totalAmount));
            service.Update(acc);
                    
                    
        }
        catch (FaultException ex)
        {
                throw new InvalidPluginExecutionException("An error occurred in the plug-in.", ex);
        }
    }

}
Good Luck…

13 comments:

  1. You might be interested in checking out our demo video which shows how to achieve this with any coding...

    http://www.youtube.com/watch?v=73qgfE5cn6o

    ReplyDelete
  2. nice posting.. thanks for sharing.

    ReplyDelete
  3. Microsoft Dynamics CRM training will help you manage and prioritize your business goals, customize.we teach MS Dynamics CRM training and class available at Hyderabad.

    ReplyDelete
  4. Thanks Buddy...

    Great simple post for starters

    ReplyDelete
  5. Great collection. Very effective post. I will back again.

    fostering

    ReplyDelete
  6. Nico van der HeidenApril 6, 2013 at 4:33 AM

    Hi Amreek,

    I changed the code above to my specific needs and the plugin works like a charm on the create, but on the update, setstate and setstatedynamicentity my code errors on the following:
    EntityReference a = (EntityReference)entity.Attributes["customerid"];

    Looks like thet entity gives only he changed values fields and does not give all fields. We can work around this with the pre image, but I think this can be easier / I am doing something wrong? Hope you can help me out! Thanks in advance.

    ReplyDelete
  7. I keep getting the "The given key was not present in the dictionary.", anyone know a reason why?

    ReplyDelete
  8. Interesting. I'm curious about the fetchxml portion of the script. I have the requirement to pull parent records when ALL child records meet a certain criteria. Is there a clause in the fetchxml that looks at ALL child records for a value? e.g. Pull all accounts where ALL related Opps = Lost

    ReplyDelete
  9. Great Post!!! Work perfectly for Create.
    But i have an issue, when i deploy the plugin for Update i have an error : the given key was not present in the dictionary, I try to debug, and the problem is on this line :

    EntityReference a = (EntityReference)entity.Attributes["new_cuentaid"];

    But in create Works perfectly..... someone has any idea?

    ReplyDelete
  10. I am also having the same problems...in that it works perfect for create but I get the The given key was not present in the dictionary." error in update. Any help appreciated....

    ReplyDelete
  11. H. Kazemi

    http://Dynamics.Blogfa.com

    Within a plugin, the Attributes collection of an Entity that you obtain from the "Target" InputParameter will only contain attributes that were modified in the corresponding Create or Update method. Using the example above, if this were in a plugin registered on the Update message, the "name" attribute would only be present if the "customerid" attribute was changed as part of the Update; the "Target" InputParameter will not contain all the attributes for the entity
    and gives you error : The given key was not present in the dictionary

    ReplyDelete