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
SFDCIronManSFDCIronMan 

Help me Create a Trigger for CheckBox to clone Opportunity and OpportunityLineItem

Help me Create a Trigger for CheckBox to clone Opportunity and OpportunityLineItem
//This is what i have coded please help resolve this
trigger CloneParentOpportunityTrigger on Opportunity (After insert,After update) 
{
    List<Opportunity> oppsToUpdate = new List<Opportunity>();
    Map<Id,Opportunity> OldOppId = new Map<Id,Opportunity>();
    Opportunity newopp = new Opportunity(); 
    if(Trigger.IsAfter)
    {
        if(Trigger.IsInsert || Trigger.IsUpdate)
        {
            if(newopp.Clone_Opportunity__c)
            {
                for(Opportunity opp : Trigger.new)
                { 
                    //opportunity list item
                    newopp.Name = opp.Name;
                    newopp.AccountId = opp.AccountId;
                    newopp.Product_Type__c = opp.Product_Type__c;
                    newopp.CloseDate = opp.CloseDate;
                    newopp.StageName = opp.StageName;
                    newopp.Payment_Frequency__c = opp.Payment_Frequency__c;
                    newopp.Most_Recent_Invoice_Date__c  = opp.Most_Recent_Invoice_Date__c;
                    newopp.Billing_Start_Date__c = opp.Billing_Start_Date__c;
                    newopp.Parent_Opportunity__c = opp.Id;
                    oppsToUpdate.add(newopp);
                    OldOppId.put(opp.id,opp);
                }
                
                insert oppsToUpdate;
                
                Map<Id,Opportunity> NewOppId = new Map<Id,Opportunity>();
                for(Opportunity opp1 : oppsToUpdate)
                {
                    NewOppId.put(opp1.Id, opp1);
                }
                
                List<OpportunityLineItem> oppitemList = new List<OpportunityLineItem>([SELECT Id, Product2Id, Quantity, UnitPrice, OpportunityId FROM OpportunityLineItem Where OpportunityId IN : OldOppId.keyset()]);
                for(OpportunityLineItem oppitem : oppitemList)
                {
                    OpportunityLineItem oli = new OpportunityLineitem();
                    oli.OpportunityId = NewOppId.get(oppitem.OpportunityId).Id;
                    oli.Product2Id = oppitem.Product2Id;
                    oli.Quantity = oppitem.Quantity;
                    oli.UnitPrice = oppitem.UnitPrice;
                    oppitemlist.add(oli);
                }
                insert oppitemList;
            }
        }   
    }
}
Best Answer chosen by SFDCIronMan
Maharajan CMaharajan C
Hi,

Even after you have tried above code and still facing the same error then use below things.

Maximum Trigger Depth Exceeded Error in Salesforce occurs due to recursion in your CloneParentOpportunityTrigger trigger. This recurssion due some opportunity Line Item Trigger or triggers or automation firing your CloneParentOpportunityTrigger trigger again. So it's going unstoppable

Use the below  way to avoid this error:

Add static Boolean in trigger context to handle this recurrsion error - Commonly used trick.

Create New Apex Class:

 
public class RecursiveTriggerHandler{
    public static Boolean isFirstTime = true;
}

And Update your trigger like below with static boolean check :
 
trigger CloneParentOpportunityTrigger on Opportunity (After insert,After update) 
{
    List<Opportunity> oppsToUpdate = new List<Opportunity>();
    Map<Id,Opportunity> OldOppId = new Map<Id,Opportunity>();
    Map<Id,List<OpportunityLineItem>> oplitemsMap = new  Map<Id,List<OpportunityLineItem>>();
    List<OpportunityLineItem> oppitemlist = new List<OpportunityLineItem>();
    Set<id> oppIds = new set<Id>();
    if(RecursiveTriggerHandler.isFirstTime)
    {
        RecursiveTriggerHandler.isFirstTime = false;
        if(Trigger.IsAfter)
        {
            if(Trigger.IsInsert)
            {
                for(Opportunity opp : Trigger.new)
                { 
                    if(opp.Clone_Opportunity__c){
                        oppIds.add(opp.Id);
                        Opportunity newopp = new Opportunity(); 
                        newopp.Name = opp.Name;
                        newopp.AccountId = opp.AccountId;
                        //newopp.Product_Type__c = opp.Product_Type__c;
                        newopp.CloseDate = opp.CloseDate;
                        newopp.StageName = opp.StageName;
                        //newopp.Payment_Frequency__c = opp.Payment_Frequency__c;
                        //newopp.Most_Recent_Invoice_Date__c  = opp.Most_Recent_Invoice_Date__c;
                        //newopp.Billing_Start_Date__c = opp.Billing_Start_Date__c;
                        newopp.Parent_Opportunity__c = opp.Id;
                        oppsToUpdate.add(newopp);
                    }
                }
            }
            else if(Trigger.IsUpdate){
                for(Opportunity opp : Trigger.new)
                { 
                    if(Trigger.oldMap.get(opp.Id).Clone_Opportunity__c != opp.Clone_Opportunity__c && opp.Clone_Opportunity__c){
                        oppIds.add(opp.Id);
                        Opportunity newopp = new Opportunity(); 
                        newopp.Name = opp.Name;
                        newopp.AccountId = opp.AccountId;
                        //newopp.Product_Type__c = opp.Product_Type__c;
                        newopp.CloseDate = opp.CloseDate;
                        newopp.StageName = opp.StageName;
                        //newopp.Payment_Frequency__c = opp.Payment_Frequency__c;
                        //newopp.Most_Recent_Invoice_Date__c  = opp.Most_Recent_Invoice_Date__c;
                        //newopp.Billing_Start_Date__c = opp.Billing_Start_Date__c;
                        newopp.Parent_Opportunity__c = opp.Id;
                        oppsToUpdate.add(newopp);
                    }
                }       
            }
        }
        
        for(OpportunityLineitem opl : [SELECT Id, Product2Id, Quantity, UnitPrice,pricebookentryid, OpportunityId FROM OpportunityLineItem Where OpportunityId IN : oppIds]){
            if(!oplitemsMap.containsKey(opl.OpportunityId)){
                oplitemsMap.put(opl.OpportunityId, new List<OpportunityLineitem>{opl});
            }
            else{
                oplitemsMap.get(opl.OpportunityId).add(opl);
            }
        }
        
        if(!oppsToUpdate.IsEmpty()){
            insert oppsToUpdate;
            
            for(Opportunity op : oppsToUpdate){
                system.debug(' Id --> ' + op.Id);
                system.debug(' Parent Id --> ' + op.Parent_Opportunity__c);
                if(oplitemsMap.containsKey(op.Parent_Opportunity__c)){
                    for(OpportunityLineitem ol : oplitemsMap.get(op.Parent_Opportunity__c)){
                        OpportunityLineItem oli = new OpportunityLineitem();
                        oli.OpportunityId = op.Id;
                        oli.Product2Id = ol.Product2Id;
                        oli.Quantity = ol.Quantity;
                        oli.UnitPrice = ol.UnitPrice;
                        oli.pricebookentryid=ol.pricebookentryid;
                        oppitemlist.add(oli);
                    }
                }
            }
            
            if(!oppitemlist.isEmpty()){
                insert oppitemlist;
            }
        }
    }
}


Thanks,
Maharajan.C

All Answers

SFDCIronManSFDCIronMan
im hitting this snag

Review the errors on this page.
CloneParentOpportunityTrigger: execution of AfterInsert caused by: System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, CloneParentOpportunityTrigger: maximum trigger depth exceeded Opportunity trigger event AfterInsert Opportunity trigger event AfterInsert Opportunity trigger event AfterInsert Opportunity trigger event AfterInsert Opportunity trigger event AfterInsert Opportunity trigger event AfterInsert Opportunity trigger event AfterInsert Opportunity trigger event AfterInsert Opportunity trigger event AfterInsert Opportunity trigger event AfterInsert Opportunity trigger event AfterInsert Opportunity trigger event AfterInsert Opportunity trigger event AfterInsert Opportunity trigger event AfterInsert Opportunity trigger event AfterInsert Opportunity trigger event AfterInsert: [] Trigger.CloneParentOpportunityTrigger: line 27, column 1
 
Maharajan CMaharajan C
Hi,

Can you please try the below Updated code:
 
trigger CloneParentOpportunityTrigger on Opportunity (After insert,After update) 
{
    List<Opportunity> oppsToUpdate = new List<Opportunity>();
    Map<Id,Opportunity> OldOppId = new Map<Id,Opportunity>();
    Map<Id,List<OpportunityLineItem>> oplitemsMap = new  Map<Id,List<OpportunityLineItem>>();
    List<OpportunityLineItem> oppitemlist = new List<OpportunityLineItem>();
    Set<id> oppIds = new set<Id>();
    if(Trigger.IsAfter)
    {
        if(Trigger.IsInsert)
        {
            for(Opportunity opp : Trigger.new)
            { 
                if(opp.Clone_Opportunity__c){
                    oppIds.add(opp.Id);
                    Opportunity newopp = new Opportunity(); 
                    newopp.Name = opp.Name;
                    newopp.AccountId = opp.AccountId;
                    newopp.Product_Type__c = opp.Product_Type__c;
                    newopp.CloseDate = opp.CloseDate;
                    newopp.StageName = opp.StageName;
                    newopp.Payment_Frequency__c = opp.Payment_Frequency__c;
                    newopp.Most_Recent_Invoice_Date__c  = opp.Most_Recent_Invoice_Date__c;
                    newopp.Billing_Start_Date__c = opp.Billing_Start_Date__c;
                    newopp.Parent_Opportunity__c = opp.Id;
                    oppsToUpdate.add(newopp);
                }
            }
        }
        else if(Trigger.IsUpdate){
            for(Opportunity opp : Trigger.new)
            { 
                if(Trigger.oldMap.get(opp.Id).Clone_Opportunity__c != opp.Clone_Opportunity__c && opp.Clone_Opportunity__c){
                    oppIds.add(opp.Id);
                    Opportunity newopp = new Opportunity(); 
                    newopp.Name = opp.Name;
                    newopp.AccountId = opp.AccountId;
                    newopp.Product_Type__c = opp.Product_Type__c;
                    newopp.CloseDate = opp.CloseDate;
                    newopp.StageName = opp.StageName;
                    newopp.Payment_Frequency__c = opp.Payment_Frequency__c;
                    newopp.Most_Recent_Invoice_Date__c  = opp.Most_Recent_Invoice_Date__c;
                    newopp.Billing_Start_Date__c = opp.Billing_Start_Date__c;
                    newopp.Parent_Opportunity__c = opp.Id;
                    oppsToUpdate.add(newopp);
                }
            }       
        }
    }
    
    for(OpportunityLineitem opl : [SELECT Id, Product2Id, Quantity, UnitPrice,pricebookentryid, OpportunityId FROM OpportunityLineItem Where OpportunityId IN : oppIds]){
        if(!oplitemsMap.containsKey(opl.OpportunityId)){
            oplitemsMap.put(opl.OpportunityId, new List<OpportunityLineitem>{opl});
        }
        else{
            oplitemsMap.get(opl.OpportunityId).add(opl);
        }
    }
    
    if(!oppsToUpdate.IsEmpty()){
        insert oppsToUpdate;
        
        for(Opportunity op : oppsToUpdate){
            system.debug(' Id --> ' + op.Id);
            system.debug(' Parent Id --> ' + op.Parent_Opportunity__c);
            if(oplitemsMap.containsKey(op.Parent_Opportunity__c)){
                for(OpportunityLineitem ol : oplitemsMap.get(op.Parent_Opportunity__c)){
                    OpportunityLineItem oli = new OpportunityLineitem();
                    oli.OpportunityId = op.Id;
                    oli.Product2Id = ol.Product2Id;
                    oli.Quantity = ol.Quantity;
                    oli.UnitPrice = ol.UnitPrice;
                    oli.pricebookentryid=ol.pricebookentryid;
                    oppitemlist.add(oli);
                }
            }
        }
        
        if(!oppitemlist.isEmpty()){
            insert oppitemlist;
        }
    }
}

Thanks,
Maharajan.C
Maharajan CMaharajan C
Hi,

Even after you have tried above code and still facing the same error then use below things.

Maximum Trigger Depth Exceeded Error in Salesforce occurs due to recursion in your CloneParentOpportunityTrigger trigger. This recurssion due some opportunity Line Item Trigger or triggers or automation firing your CloneParentOpportunityTrigger trigger again. So it's going unstoppable

Use the below  way to avoid this error:

Add static Boolean in trigger context to handle this recurrsion error - Commonly used trick.

Create New Apex Class:

 
public class RecursiveTriggerHandler{
    public static Boolean isFirstTime = true;
}

And Update your trigger like below with static boolean check :
 
trigger CloneParentOpportunityTrigger on Opportunity (After insert,After update) 
{
    List<Opportunity> oppsToUpdate = new List<Opportunity>();
    Map<Id,Opportunity> OldOppId = new Map<Id,Opportunity>();
    Map<Id,List<OpportunityLineItem>> oplitemsMap = new  Map<Id,List<OpportunityLineItem>>();
    List<OpportunityLineItem> oppitemlist = new List<OpportunityLineItem>();
    Set<id> oppIds = new set<Id>();
    if(RecursiveTriggerHandler.isFirstTime)
    {
        RecursiveTriggerHandler.isFirstTime = false;
        if(Trigger.IsAfter)
        {
            if(Trigger.IsInsert)
            {
                for(Opportunity opp : Trigger.new)
                { 
                    if(opp.Clone_Opportunity__c){
                        oppIds.add(opp.Id);
                        Opportunity newopp = new Opportunity(); 
                        newopp.Name = opp.Name;
                        newopp.AccountId = opp.AccountId;
                        //newopp.Product_Type__c = opp.Product_Type__c;
                        newopp.CloseDate = opp.CloseDate;
                        newopp.StageName = opp.StageName;
                        //newopp.Payment_Frequency__c = opp.Payment_Frequency__c;
                        //newopp.Most_Recent_Invoice_Date__c  = opp.Most_Recent_Invoice_Date__c;
                        //newopp.Billing_Start_Date__c = opp.Billing_Start_Date__c;
                        newopp.Parent_Opportunity__c = opp.Id;
                        oppsToUpdate.add(newopp);
                    }
                }
            }
            else if(Trigger.IsUpdate){
                for(Opportunity opp : Trigger.new)
                { 
                    if(Trigger.oldMap.get(opp.Id).Clone_Opportunity__c != opp.Clone_Opportunity__c && opp.Clone_Opportunity__c){
                        oppIds.add(opp.Id);
                        Opportunity newopp = new Opportunity(); 
                        newopp.Name = opp.Name;
                        newopp.AccountId = opp.AccountId;
                        //newopp.Product_Type__c = opp.Product_Type__c;
                        newopp.CloseDate = opp.CloseDate;
                        newopp.StageName = opp.StageName;
                        //newopp.Payment_Frequency__c = opp.Payment_Frequency__c;
                        //newopp.Most_Recent_Invoice_Date__c  = opp.Most_Recent_Invoice_Date__c;
                        //newopp.Billing_Start_Date__c = opp.Billing_Start_Date__c;
                        newopp.Parent_Opportunity__c = opp.Id;
                        oppsToUpdate.add(newopp);
                    }
                }       
            }
        }
        
        for(OpportunityLineitem opl : [SELECT Id, Product2Id, Quantity, UnitPrice,pricebookentryid, OpportunityId FROM OpportunityLineItem Where OpportunityId IN : oppIds]){
            if(!oplitemsMap.containsKey(opl.OpportunityId)){
                oplitemsMap.put(opl.OpportunityId, new List<OpportunityLineitem>{opl});
            }
            else{
                oplitemsMap.get(opl.OpportunityId).add(opl);
            }
        }
        
        if(!oppsToUpdate.IsEmpty()){
            insert oppsToUpdate;
            
            for(Opportunity op : oppsToUpdate){
                system.debug(' Id --> ' + op.Id);
                system.debug(' Parent Id --> ' + op.Parent_Opportunity__c);
                if(oplitemsMap.containsKey(op.Parent_Opportunity__c)){
                    for(OpportunityLineitem ol : oplitemsMap.get(op.Parent_Opportunity__c)){
                        OpportunityLineItem oli = new OpportunityLineitem();
                        oli.OpportunityId = op.Id;
                        oli.Product2Id = ol.Product2Id;
                        oli.Quantity = ol.Quantity;
                        oli.UnitPrice = ol.UnitPrice;
                        oli.pricebookentryid=ol.pricebookentryid;
                        oppitemlist.add(oli);
                    }
                }
            }
            
            if(!oppitemlist.isEmpty()){
                insert oppitemlist;
            }
        }
    }
}


Thanks,
Maharajan.C
This was selected as the best answer
SFDCIronManSFDCIronMan
@Maharajan.C

thank you so much for the solution 
have you tested this code on your org because its not working in mine like its not cloning opportunity when Inserted or updated.
please help me regarding this problem.
and provide this code in design pattern if you can 
 
SFDCIronManSFDCIronMan
Thanks you so much My code is working now 
Maharajan.C
 
Priya Singh 118Priya Singh 118
Check Here Latest Government jobs & Government schemes (https://vacancysquare.com/) information only on Vacancysquare.com 
gfdj gfdhggfdj gfdhg
Why are you trying to create a special trigger for the checkbox there are so many customs options available for you click here (https://laptopsadviser.com/how-to-access-advanced-bios-settings-hp/) to learn more about it.