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
Rajat BurmanRajat Burman 

Apex CPU time limit exceeded in function saveopportunityAfterEdit()

Hi Experts, 
I am getting Apex CPU time limit exceeded.
Error is in expression '{!saveopportunityAfterEdit}' in component <apex:commandButton> in page unclonedopportunities_vf: (hed)
Kindly help me out.
Here is my code.
 
public class UnclonedOpportunities_CS {
    
    public List<Opportunity> opCheckList{get;set;}  
    
    public Id currentCycleId;     
    public UnclonedOpportunities_CS(ApexPages.StandardController controller){ 
        Id idsss;
        if(test.isRunningTest()) {
            
            Id OppRecordTypeId = Schema.SObjectType.Opportunity.getRecordTypeInfosByName().get('Internship Opportunity').getRecordTypeId();
            Date dt = System.Today();
            Account testAccount = new Account();
            testAccount.Name = 'Test Account' ;
            insert testAccount;
            
            Contact con = new Contact(Lastname='test Contact', AccountId=testAccount.id); 
            insert con;
            
            alu_Internship_Cycle__c cycle1= new alu_Internship_Cycle__c(Name='Cycle1', Start_Date__c = system.today(), End_Date__c=system.today());
            insert cycle1;
            
            Opportunity opp = new Opportunity();
            opp.RecordTypeId = OppRecordTypeId;
            opp.Name = 'Test Opportunity';
            opp.StageName = 'Under Discussion';
            opp.CloseDate = dt;
            opp.AccountId = testAccount.Id;
            opp.Internship_Cycle__c = cycle1.Id;
            opp.Number_of_Internships_Committed__c = 1;
            opp.Opportunity_Countries__c = 'Algeria';
            opp.Key_Contact__c = con.id;
            opp.Final_Commitment__c = 2000.00;
            insert opp;
            
            alu_Internship_Cycle__c cycle2= new alu_Internship_Cycle__c(Name='Cycle2', Start_Date__c = dt.addYears(1), End_Date__c=system.today(),Clone_Internship_Opportunity__c=true);
            insert cycle2;
            
            currentCycleId = cycle2.id;
        }
        else if(!test.isRunningTest()) {
            currentCycleId =  ApexPages.currentPage().getParameters().get('id'); 
        }
        alu_Internship_Cycle__c cycle = [SELECT Id,start_Date__c FROM alu_Internship_Cycle__c WHERE Id =: currentCycleId];  
        Set<Id> cloneOppPrevIds = new Set<Id>();
        List<Opportunity> clonedList = [SELECT id, Name, RecordTypeId, AccountId, Account.Name, Key_Contact__c,Internship_Cycle__c,
                                        CloseDate,  StageName ,Opportunity_Countries__c,Final_Commitment__c,Previous_Opportunity_Id__c
                                        FROM Opportunity WHERE Internship_Cycle__c =:currentCycleId]; 
        system.debug('cloned List '+clonedList);
        
        for(Opportunity ops : clonedList) {
            cloneOppPrevIds.add(ops.Previous_Opportunity_Id__c);
        }
        
        Map<Id,alu_Internship_Cycle__c> mapIdbyOldInternCyc = new Map<Id,alu_Internship_Cycle__c> ([SELECT Id, Name, Start_Date__c 
                                                                                                    FROM alu_Internship_Cycle__c 
                                                                                                    WHERE Id !=: currentCycleId 
                                                                                                    AND Start_Date__c =:  cycle.Start_Date__c.addYears(-1)]);
        system.debug('mapIdbyOldInternCyc '+mapIdbyOldInternCyc);   
        
        List<Opportunity> oppListByOldCyc = [SELECT id, Name, RecordTypeId, AccountId, Account.Name,Key_Contact__c,
                                             CloseDate,  StageName , Internship_Cycle__c, Opportunity_Countries__c,Final_Commitment__c,Previous_Opportunity_Id__c
                                             FROM Opportunity 
                                             WHERE Internship_Cycle__c IN: mapIdbyOldInternCyc.KeySet()];
        system.debug('oppListByOldCyc'+oppListByOldCyc);
        
        opCheckList = new List<Opportunity>(); 
        for(opportunity opOld : oppListByOldCyc){
            if(!cloneOppPrevIds.contains(opOld.Id)){
                opCheckList.add(opOld);  
            }
        }
        system.debug('opCheckList'+opCheckList);
    }
    
    public PageReference saveopportunityAfterEdit() {
        Set<Opportunity> insertSetList = new Set<Opportunity>();
        integer i = 0;
        try{
            if(opCheckList.size() > 0) {
                update this.opCheckList; 
                System.debug('opCheckList '+opCheckList);
            }
        } catch(Exception e){
            e.getMessage();
        }
        system.debug('this.opCheckList '+opCheckList);
        try 
        {
            Opportunity OppToInsertInNewIntCycle = new Opportunity();
            List<Opportunity> oppUnClonedList = new List<Opportunity>();
            for (Opportunity opppp : opCheckList) {
                if((opppp.CloseDate == null ) || String.isBlank(opppp.StageName) || String.isBlank(opppp.Opportunity_Countries__c) || String.isBlank(opppp.name) || String.isBlank(opppp.AccountId) || String.isBlank(opppp.Key_Contact__c) || String.isBlank(opppp.Internship_Cycle__c)) {
                    ApexPages.Message msg = new ApexPages.Message(ApexPages.Severity.info, 'Please fill all the details.');
                    apexPages.addMessage(msg);
                    system.debug('Error');
                    return null;
                } 
                else if((opppp.CloseDate != null ) && String.isNotBlank(opppp.StageName) && String.isNotBlank(opppp.Opportunity_Countries__c) && String.isNotBlank(opppp.name) && String.isNotBlank(opppp.AccountId) && String.isNotBlank(opppp.Key_Contact__c) && String.isNotBlank(opppp.Internship_Cycle__c)) {
                    OppToInsertInNewIntCycle.name =  opppp.name; 
                    OppToInsertInNewIntCycle.RecordTypeId = opppp.RecordTypeId;
                    OppToInsertInNewIntCycle.AccountId = opppp.AccountId;
                    OppToInsertInNewIntCycle.StageName = opppp.StageName;
                    OppToInsertInNewIntCycle.Key_Contact__c = opppp.Key_Contact__c;
                    OppToInsertInNewIntCycle.Internship_Cycle__c = currentCycleId;
                    OppToInsertInNewIntCycle.Opportunity_Countries__c = opppp.Opportunity_Countries__c;
                    OppToInsertInNewIntCycle.CloseDate = opppp.CloseDate;
                    OppToInsertInNewIntCycle.Previous_Opportunity_Id__c = opppp.id;
                }
                insertSetList.add(OppToInsertInNewIntCycle);
                if(insertSetList.size() > 0 ) {
                    oppUnClonedList.addAll(insertSetList);
                }
                system.debug('add to list ' + oppUnClonedList);
                system.debug('add to Set ' + insertSetList);
                System.debug('insertSetList.size() ' +insertSetList.size()); 
                System.debug('oppUnClonedList.size() ' +oppUnClonedList.size()); 
            }
            if(oppUnClonedList.size() > 0){
                system.debug('rec oppUnClonedList ' + oppUnClonedList);
                insert oppUnClonedList;
                System.debug('oppUnClonedListoppUnClonedListoppUnClonedList '+oppUnClonedList );
            }
        } catch(Exception e) {
            e.getMessage(); 
        }
        system.debug('currentCycleId pagereference '+ currentCycleId);
        PageReference page = new Pagereference('/'+currentCycleId);
        page.setRedirect(false);
        return page;
    }
}

 
NagendraNagendra (Salesforce Developers) 
Hi Rajat,

The Maximum CPU time on the Salesforce servers - 10,000 milliseconds (Synchronous limit) 60,000 milliseconds(Asynchronous limit)

Since your code execution takes a lot of time than allowed limit, try refining your code by removing unnecessary for loop, for loop inside for loop. Utilize sets, maps advantages and refine your code. Also, you can move the piece of code that does not need to be executed in the same context as the future method. 
 
By doing everything mentioned above you can overcome this issue. Hope this helps.

Please check with below link for more information. Hope this helps.

Kindly mark this as solved if it's resolved.

Thanks,
Nagendra