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?

  • You can add a trigger on Opportunity update. You check if one of those two fields changed, and recalculate. – Martin Lezer Jan 12 '17 at 10:00
  • @Martin Lezer So do I have to remove the code from Child Trigger? – Dhananjay Patil Jan 12 '17 at 10:04
  • No you have two keep this trigger. – Martin Lezer Jan 12 '17 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 Jan 12 '17 at 18:30
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();
           }
     }
}
| improve this answer | |
  • 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: []: – – Dhananjay Patil Jan 12 '17 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);
}
| improve this answer | |
  • 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: []: – Dhananjay Patil Jan 12 '17 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. – NZ Dev Jan 13 '17 at 10:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.