0

I have 2 fields on opportunity object Contact Start Date and Contact End Date which is of type date field.Based on the no days,I am adjusting Product Values which is OpportunityLineItem(we have a calculated fields that take care of this request).

Now requirement is i have to create a Summary fields on opportunity objects that summarize all products vale and display it on opportunity object.for this i have written a trigger on Opportunity Line Item and whenever I change or add Products,it calculates the summary field which is working as expected.

Problem is when if I change the Contract Start or end date value on opportunity object,it does not calculates summarize field.To get the latest value of summary field I have to edit the products then i get the latest value. Can someone suggest me how can I avoid recursion here?

4
  • You can add a trigger on Opportunity update. You check if one of those two fields changed, and recalculate. Commented Jan 12, 2017 at 10:00
  • @Martin Lezer So do I have to remove the code from Child Trigger?
    – SFDCDJ
    Commented Jan 12, 2017 at 10:04
  • No you have two keep this trigger. Commented Jan 12, 2017 at 10:06
  • It looks like you need AfterUpdate trigger on Opportunity object to run the similar code you have on Opportunity Line Item trigger or call the method that does recalculations.
    – o-lexi
    Commented Jan 12, 2017 at 18:30

2 Answers 2

0

You can add a trigger on the opportunities:

trigger ContactDatesChanged on Opportunity (before update) {
      for(Opportunity opp : Trigger.new){
           Date oldDateStart = Trigger.oldMap.get(opp.Id).ContactStartDate;
           Date newDateStart = opp.ContactStartDate;

           Date oldDateEnd = Trigger.oldMap.get(opp.Id).ContactEndDate;
           Date newDateEnd = opp.ContactEndDate;

           if(oldDateStart != newDateStart || oldDateEnd != newDateEnd){
                recalculate();
           }
     }
}
1
  • It throws below error: Apex trigger OpportunityTrigger caused an unexpected exception, contact your administrator: OpportunityTrigger: execution of BeforeUpdate caused by: System.DmlException: Update failed. First exception on row 0 with id ; first error: SELF_REFERENCE_FROM_TRIGGER, Object (id = ) is currently in trigger OpportunityTrigger, therefore it cannot recursively update itself: []: –
    – SFDCDJ
    Commented Jan 12, 2017 at 11:05
0

So I understand: You have a formula on OLI. But only when an OLI is updated does the Opportunity get updated via trigger. You also need to update the Opp Roll Up when Opp dates are updated.

You should not need to prevent recursion. On Opp Update you are querying the formulas of the OLI and updating (before update trigger) the Opp.

If you need to update the child (OLI) then this is another story. In which case you need a trigger handler only allowing 1 pass through.

I can post a raw example code to prevent recursion if you need.

ALSO: Your first trigger should have helper methods. You should reuse these methods in your 2nd (Opp trigger) if possible to calculate your OLI values.

@Martins Code will work: I would comment on his post but not enough reputation. To add to martins code: Within the recalculate method pass the list of Opportunity Ids that need recalculation.

//THIS IS THE HANDLER CLASS TO GATHER THE DATA
OpportunityLineItemHandler{
    public map<Id,decimal> recalculate(Set<Id> OppId_Set){
        OLIs = [SELECT id, value FROM OpportunityLineItem WHERE OpportunityId IN :OppId_Set];
    for(OpportunityLineItem oli :OLIs){
        //map each parents summed value Value
        OppIdValue_Map.put(oli.opportunityId, sumofchildrensvalue);
    }
    return OppIdValue_Map;
}

You first Trigger something similar. So if you have to rewrite the first trigger it is worthwhile.

Add to Martins Code the return of the OppIdValueMap and then iterate across Opportunities again to store the values.

//THIS IS IN THE BEFORE TRIGGER TO PROCESS THE DATA
if(oldDateStart != newDateStart || oldDateEnd != newDateEnd){
     map<id,decimal> OppIdValue_Map = recalculate(OppId_Set);
}
for(Opportunity opp: trigger.new){
    if(OppIdValue_Map.containsKey(opp.Id) opp.sum__c = OppIdValue_Map.get(opp.Id);
}
2
  • It throws below error: Apex trigger OpportunityTrigger caused an unexpected exception, contact your administrator: OpportunityTrigger: execution of BeforeUpdate caused by: System.DmlException: Update failed. First exception on row 0 with id ; first error: SELF_REFERENCE_FROM_TRIGGER, Object (id = ) is currently in trigger OpportunityTrigger, therefore it cannot recursively update itself: []:
    – SFDCDJ
    Commented Jan 12, 2017 at 11:05
  • Could you post your code. It is very hard to assess things without any code. The code we have posted should not throw any recursive errors. All depends on how you handle your data within the trigger. When updating the OLI this should update the Opportunities summed value and should not fire the Opp trigger for date change. And conversely the Opp trigger reacts to Date Changes and should only update it's own Summed Value (Before Update Trigger). Both scenarios should utilise the same business logic (Helper Class) Post your code and I will re write it. Commented Jan 13, 2017 at 10:15

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .