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
ColbridgeColbridge 

CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, maximum trigger depth exceeded

I have this trigger in which, when a new quote record is inserted, I am updating couple records, which works fine in the after insert serction.

But when an approval process updates a record, I want some records to be updated in the after update section, which is causing the recurssive error: 

QuoteTrigger: execution of AfterUpdate caused by: System.DmlException: Update failed. First exception on row 0 with id 0Q05D0000007jBySAI; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, QuoteTrigger: maximum trigger depth exceeded Quote trigger event AfterUpdate Quote trigger event 

How can I get around this error and implement my logic? Trigger code is below. Error occours on update qtList; line. I am trying to implement in the // If the quote is approved unmark - section.

 
trigger QuoteTrigger on Quote (after insert,after update) {
    
    Set<String> oppIds = new Set<String>();
    for(Quote q : Trigger.New){
        oppIds.add(q.opportunityId);  
    }
    
    public static Boolean preventRecursive = true;
    if(preventRecursive){
        preventRecursive = false;
        
        // To mark the newly inserted quote as latest and unmark the previous quote if there is any
        if(Trigger.isInsert && Trigger.isAfter){
            List<Quote> quoteList = [select id,opportunityId,Latest_quote__c from quote where opportunityId IN :oppIds ORDER BY CreatedDate DESC LIMIT 2];
            if(quoteList.size() == 1){
                quoteList[0].Latest_quote__c = true;
                update quoteList;
            } else if (quoteList.size() > 1) {
            quoteList[0].Latest_quote__c = true;
                quoteList[1].Latest_quote__c = false;
                update quoteList;
            }
        }
        
        if(Trigger.isAfter && Trigger.isUpdate){
            if(trigger.new != null){
                for(quote qt:trigger.new){
                    if(Trigger.new[0].Status== 'Approved' && qt.Quote_Link__c == Null && qt.Proposal_PDF__c == Null && qt.Site_Services_PDF__c == Null){                
                       // Quote_Lcs.sendemailtemplate(qt.id);
                    } 
                } 
                
                // If the quote is approved unmark all as latest and mark last updated (approved) quote as latest
                if(Trigger.new[0].Status== 'Approved'){ 
                    System.debug('Approved');
                    List<Quote> qtList = [select id,opportunityId,Latest_quote__c from quote where opportunityId IN :oppIds  ORDER BY LastModifiedDate DESC];
                    if (qtList.size() > 1) {
                        for(Integer i = 0; i < qtList.size(); i++){ // uncheck all from being latest
                            qtList[i].Latest_quote__c = false;
                        }
                    }
                    qtList[0].Latest_quote__c = true; // mark only the last updated/approved quote as latest
                    update qtList;
                }
            }
        }
    }
}

 
Best Answer chosen by Colbridge
Naveen KNNaveen KN
You can try to implement this using the record-triggered flow. At least the second part of your trigger where you are updating the records based on the approval process status 
User-added image


 

All Answers

Naveen KNNaveen KN
You can try to implement this using the record-triggered flow. At least the second part of your trigger where you are updating the records based on the approval process status 
User-added image


 
This was selected as the best answer
ColbridgeColbridge
Sounds like a plan...
ColbridgeColbridge
Hi Naveen, the Flow route worked. Thanks!
ColbridgeColbridge