Hi Avinay,
You want to store or only display the value? because there is code to get the value from subgrid total, but I guess if you need to store, then here are the steps.
You can use this link to your code.
dynamicsofdynamicscrm.wordpress.com/.../aggregate-fetchxml-queries-for-dynamics-crm-20112013
Steps:
1. have you created the relationship self referential relationship Opportunity to Opportunity?
2. If you are using default revenue field in Opportunity, you need to set it to User Provided not System Calculated
www.pedroinnecco.com/.../opportunity-entity-2013
3. But, I would love to recommend you to use new field, create a new revenue field then make the default field to System Calculated (if you agree that revenue of the child is based on total product amount)
4. Create a plugin when Opportunity is created or updated (can filter attribute registered and run/executed only if revenue is changed)
5. The code I guess will be similar like this:
*I use early Bound class
if (TargetEntity.EstimatedValue!= null) //estimatedvalue of the child updated or created
{
//the logic is you have to find the Opportunity parent
Opportunity parentOpportunity = new Opportunity();
parentOpportunity = null;
if(TargetEntity.new_parentopportunityId != null)
parentOpportunity = TargetEntity.new_parentopportunityId;
else
{
if(preImageEntity.parentopportunityId != null) //you need to define preimage first
parentOpportunity = preImageEntity.new_parentopportunityId;
}
if(parentOpportunity !=null)
{
parentOpportunity["new_totalchildrevenue"] = new Money(TargetEntity.EstimatedValue);
service.Update(parentOpportunity);
}
}
//update the parent field it will be triggered from above transaction
if (TargetEntity.new_totalchildrevenue!= null) //triggered by new_totalchildrevenue //updated through Opportunity if Contains any update of Annual revenue
{
string strFetchXML = string.Empty;
strFetchXML = @"
<fetch distinct='false' mapping='logical' aggregate='true'>
<entity name='opportunity'>
<attribute name='tfp_totalinternaldeduction' alias='tfp_amount_sum' aggregate='sum' />
<filter type='and'>
<condition attribute='quoteid' operator='eq' value='{0}' />
</filter>
</entity>
</fetch>";
strFetchXML = string.Format(strFetchXML, TargetEntity.Id);
TargetEntity.tfp_TotalInternalDeduction = new Money(Utility.AggregateFetchXMLMoney(service, strFetchXML, "tfp_amount_sum"));
}
This is the referenced function
public static decimal AggregateFetchXMLMoney(IOrganizationService service, string strXMLParam, string strAggregateAlias)
{
string strXML = strXMLParam;
//string estimatedvalue_sum = @"
//<fetch distinct='false' mapping='logical' aggregate='true'>
// <entity name='opportunity'>
// <attribute name='estimatedvalue' alias='estimatedvalue_sum' aggregate='sum' />
// </entity>
//</fetch>";
EntityCollection aggregateResult = service.RetrieveMultiple(new FetchExpression(strXML));
decimal totalValue = 0;
foreach (var c in aggregateResult.Entities)
{
decimal aggregate2 = 0;
if (c.Attributes.Contains(strAggregateAlias))
{
aggregate2 = ((Money)((AliasedValue)c[strAggregateAlias]).Value).Value;
totalValue = aggregate2;
}
}
return totalValue;
}
Register during postCreate, postUpdate (with preimage), and postDelete
for postDelete, just define value for update as 0.
I am not sure it will work on your scenario, but I have similar situation before you might need to adjust the code modify it based on your entity and scenario and I am not using editor right now, then you can modify based on your field name and maybe I have some typos. I just help you to share some ideas and find out the method if you keen to use plugin.
But I guess you need to be careful since you will register in the same entity, that is Opportunity, the plugin can be executed infinite if you don't put proper filter attribute or maybe you can use context.Depth function.
Hope this helps!
Thanks.