function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Robert Davis 16Robert Davis 16 

Opportunity Trigger Recursion Problem

I have a Trigger on the Opportunity which will update a field on the OpportunityLineItem, which updates the Opportunity which the fires the trigger to update the OpportunityLineItems. I think it is a classic recursion issue my problem is I do not know how to stop it. Please help:
 
trigger UpdateOTRev on Opportunity (after insert, after update) {
    Set<id> triggerIds = new Set<id>();
    List<OpportunityLineItem> lstOLIUpdate = new List<OpportunityLineItem>();
    for(Opportunity Opps : Trigger.new){
        triggerIds.add(Opps.Id);
    }
    List<Opportunity> lstOpps = [SELECT id, CloseDate, (SELECT id, TotalPrice FROM OpportunityLineItems) FROM Opportunity 
                                 WHERE id in: triggerIds];
    for(Opportunity opp: lstOpps){
        for(OpportunityLineItem oli : opp.OpportunityLineItems){
            
            if(opp.CloseDate > Date.valueOf('2017-12-31') && opp.CloseDate < Date.valueOf('2018-04-01')){
                oli.Test_Q1_2018__c = oli.TotalPrice;
                oli.Test_Q2_2018__c = 0;
                oli.Test_Q3_2018__c = 0;
                oli.Test_Q4_2018__c = 0;
                oli.Test_Q1_2019__c = 0;
                oli.Test_Q2_2019__c = 0;
                oli.Test_Q3_2019__c = 0;
                oli.Test_Q4_2019__c = 0;
                lstOLIUpdate.add(oli);              
            }//END if 2018 Q1
            if(opp.CloseDate > Date.valueOf('2018-03-31') && opp.CloseDate < Date.valueOf('2018-07-01')){
                oli.Test_Q1_2018__c = 0;
                oli.Test_Q2_2018__c = oli.TotalPrice;
                oli.Test_Q3_2018__c = 0;
                oli.Test_Q4_2018__c = 0;
                oli.Test_Q1_2019__c = 0;
                oli.Test_Q2_2019__c = 0;
                oli.Test_Q3_2019__c = 0;
                oli.Test_Q4_2019__c = 0;
                lstOLIUpdate.add(oli);              
            }//END if 2018 Q2
            if(opp.CloseDate > Date.valueOf('2018-06-30') && opp.CloseDate < Date.valueOf('2018-10-01')){
                oli.Test_Q1_2018__c = 0;
                oli.Test_Q2_2018__c = 0;
                oli.Test_Q3_2018__c = oli.TotalPrice;
                oli.Test_Q4_2018__c = 0;
                oli.Test_Q1_2019__c = 0;
                oli.Test_Q2_2019__c = 0;
                oli.Test_Q3_2019__c = 0;
                oli.Test_Q4_2019__c = 0;
                lstOLIUpdate.add(oli);              
            }//END if 2018 Q3
            if(opp.CloseDate > Date.valueOf('2018-09-30') && opp.CloseDate < Date.valueOf('2019-01-01')){
                oli.Test_Q1_2018__c = 0;
                oli.Test_Q2_2018__c = 0;
                oli.Test_Q3_2018__c = oli.TotalPrice;
                oli.Test_Q4_2018__c = 0;
                oli.Test_Q1_2019__c = 0;
                oli.Test_Q2_2019__c = 0;
                oli.Test_Q3_2019__c = 0;
                oli.Test_Q4_2019__c = 0;
                lstOLIUpdate.add(oli);              
            }//END if 2018 Q4
        }//END For(OpportunityLineItem)
    }//END for(Opportunity)
    if(lstOLIUpdate.size()){
        update lstOLIUpdate;
    }

}

Thank you,

Robert​
Best Answer chosen by Robert Davis 16
Maharajan CMaharajan C
Hi Robert,

The above Triggers looks good may be you have any other workflow field update or Process builder or some other trigger which updates the Opportunity.

To avoid the recusive you have to Static boolean variable to make the trigger fire only once.

-----------
Create this below Apex class:

public class RecursiveTriggerHandler{
     public static Boolean isFirstTime = true;


-------------

Call the above class in your apex trigger  if conditons like below:


trigger UpdateOTRev on Opportunity (after insert, after update) {
    Set<id> triggerIds = new Set<id>();
    List<OpportunityLineItem> lstOLIUpdate = new List<OpportunityLineItem>();
     if(RecursiveTriggerHandler.isFirstTime)
     {
        RecursiveTriggerHandler.isFirstTime = false;

    for(Opportunity Opps : Trigger.new){
        triggerIds.add(Opps.Id);
    }
    List<Opportunity> lstOpps = [SELECT id, CloseDate, (SELECT id, TotalPrice FROM OpportunityLineItems) FROM Opportunity 
                                 WHERE id in: triggerIds];
    for(Opportunity opp: lstOpps){
        for(OpportunityLineItem oli : opp.OpportunityLineItems){
            
            if(opp.CloseDate > Date.valueOf('2017-12-31') && opp.CloseDate < Date.valueOf('2018-04-01')){
                oli.Test_Q1_2018__c = oli.TotalPrice;
                oli.Test_Q2_2018__c = 0;
                oli.Test_Q3_2018__c = 0;
                oli.Test_Q4_2018__c = 0;
                oli.Test_Q1_2019__c = 0;
                oli.Test_Q2_2019__c = 0;
                oli.Test_Q3_2019__c = 0;
                oli.Test_Q4_2019__c = 0;
                lstOLIUpdate.add(oli);              
            }//END if 2018 Q1
            if(opp.CloseDate > Date.valueOf('2018-03-31') && opp.CloseDate < Date.valueOf('2018-07-01')){
                oli.Test_Q1_2018__c = 0;
                oli.Test_Q2_2018__c = oli.TotalPrice;
                oli.Test_Q3_2018__c = 0;
                oli.Test_Q4_2018__c = 0;
                oli.Test_Q1_2019__c = 0;
                oli.Test_Q2_2019__c = 0;
                oli.Test_Q3_2019__c = 0;
                oli.Test_Q4_2019__c = 0;
                lstOLIUpdate.add(oli);              
            }//END if 2018 Q2
            if(opp.CloseDate > Date.valueOf('2018-06-30') && opp.CloseDate < Date.valueOf('2018-10-01')){
                oli.Test_Q1_2018__c = 0;
                oli.Test_Q2_2018__c = 0;
                oli.Test_Q3_2018__c = oli.TotalPrice;
                oli.Test_Q4_2018__c = 0;
                oli.Test_Q1_2019__c = 0;
                oli.Test_Q2_2019__c = 0;
                oli.Test_Q3_2019__c = 0;
                oli.Test_Q4_2019__c = 0;
                lstOLIUpdate.add(oli);              
            }//END if 2018 Q3
            if(opp.CloseDate > Date.valueOf('2018-09-30') && opp.CloseDate < Date.valueOf('2019-01-01')){
                oli.Test_Q1_2018__c = 0;
                oli.Test_Q2_2018__c = 0;
                oli.Test_Q3_2018__c = oli.TotalPrice;
                oli.Test_Q4_2018__c = 0;
                oli.Test_Q1_2019__c = 0;
                oli.Test_Q2_2019__c = 0;
                oli.Test_Q3_2019__c = 0;
                oli.Test_Q4_2019__c = 0;
                lstOLIUpdate.add(oli);              
            }//END if 2018 Q4
        }//END For(OpportunityLineItem)
    }//END for(Opportunity)
    if(lstOLIUpdate.size()){
        update lstOLIUpdate;
    }
}
}


Reference Links:

http://www.sfdcpoint.com/salesforce/avoid-recursive-trigger-salesforce/
https://help.salesforce.com/articleView?id=000133752&language=en_US&type=1
http://www.infallibletechie.com/2012/08/recursive-triggers-in-salesforce.html
http://sfdcbeginner.com/stop-recursive-trigger-in-salesforce.html


Can you please Let me know if it helps or not!!!

If it helps don't forget to mark this as a best answer!!!


Thanks,
​Raj

All Answers

Maharajan CMaharajan C
Hi Robert,

The above Triggers looks good may be you have any other workflow field update or Process builder or some other trigger which updates the Opportunity.

To avoid the recusive you have to Static boolean variable to make the trigger fire only once.

-----------
Create this below Apex class:

public class RecursiveTriggerHandler{
     public static Boolean isFirstTime = true;


-------------

Call the above class in your apex trigger  if conditons like below:


trigger UpdateOTRev on Opportunity (after insert, after update) {
    Set<id> triggerIds = new Set<id>();
    List<OpportunityLineItem> lstOLIUpdate = new List<OpportunityLineItem>();
     if(RecursiveTriggerHandler.isFirstTime)
     {
        RecursiveTriggerHandler.isFirstTime = false;

    for(Opportunity Opps : Trigger.new){
        triggerIds.add(Opps.Id);
    }
    List<Opportunity> lstOpps = [SELECT id, CloseDate, (SELECT id, TotalPrice FROM OpportunityLineItems) FROM Opportunity 
                                 WHERE id in: triggerIds];
    for(Opportunity opp: lstOpps){
        for(OpportunityLineItem oli : opp.OpportunityLineItems){
            
            if(opp.CloseDate > Date.valueOf('2017-12-31') && opp.CloseDate < Date.valueOf('2018-04-01')){
                oli.Test_Q1_2018__c = oli.TotalPrice;
                oli.Test_Q2_2018__c = 0;
                oli.Test_Q3_2018__c = 0;
                oli.Test_Q4_2018__c = 0;
                oli.Test_Q1_2019__c = 0;
                oli.Test_Q2_2019__c = 0;
                oli.Test_Q3_2019__c = 0;
                oli.Test_Q4_2019__c = 0;
                lstOLIUpdate.add(oli);              
            }//END if 2018 Q1
            if(opp.CloseDate > Date.valueOf('2018-03-31') && opp.CloseDate < Date.valueOf('2018-07-01')){
                oli.Test_Q1_2018__c = 0;
                oli.Test_Q2_2018__c = oli.TotalPrice;
                oli.Test_Q3_2018__c = 0;
                oli.Test_Q4_2018__c = 0;
                oli.Test_Q1_2019__c = 0;
                oli.Test_Q2_2019__c = 0;
                oli.Test_Q3_2019__c = 0;
                oli.Test_Q4_2019__c = 0;
                lstOLIUpdate.add(oli);              
            }//END if 2018 Q2
            if(opp.CloseDate > Date.valueOf('2018-06-30') && opp.CloseDate < Date.valueOf('2018-10-01')){
                oli.Test_Q1_2018__c = 0;
                oli.Test_Q2_2018__c = 0;
                oli.Test_Q3_2018__c = oli.TotalPrice;
                oli.Test_Q4_2018__c = 0;
                oli.Test_Q1_2019__c = 0;
                oli.Test_Q2_2019__c = 0;
                oli.Test_Q3_2019__c = 0;
                oli.Test_Q4_2019__c = 0;
                lstOLIUpdate.add(oli);              
            }//END if 2018 Q3
            if(opp.CloseDate > Date.valueOf('2018-09-30') && opp.CloseDate < Date.valueOf('2019-01-01')){
                oli.Test_Q1_2018__c = 0;
                oli.Test_Q2_2018__c = 0;
                oli.Test_Q3_2018__c = oli.TotalPrice;
                oli.Test_Q4_2018__c = 0;
                oli.Test_Q1_2019__c = 0;
                oli.Test_Q2_2019__c = 0;
                oli.Test_Q3_2019__c = 0;
                oli.Test_Q4_2019__c = 0;
                lstOLIUpdate.add(oli);              
            }//END if 2018 Q4
        }//END For(OpportunityLineItem)
    }//END for(Opportunity)
    if(lstOLIUpdate.size()){
        update lstOLIUpdate;
    }
}
}


Reference Links:

http://www.sfdcpoint.com/salesforce/avoid-recursive-trigger-salesforce/
https://help.salesforce.com/articleView?id=000133752&language=en_US&type=1
http://www.infallibletechie.com/2012/08/recursive-triggers-in-salesforce.html
http://sfdcbeginner.com/stop-recursive-trigger-in-salesforce.html


Can you please Let me know if it helps or not!!!

If it helps don't forget to mark this as a best answer!!!


Thanks,
​Raj
This was selected as the best answer
Robert Davis 16Robert Davis 16
THANK YOU, Raj