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
Ankit Garg 117Ankit Garg 117 

Clone custom object while cloning the opportunity

HI,

We have a custom object called ''Banner''. Whenever a user creates an opportunity, they add a banner to that opportunity. Now, whenever a user closes an opportunity, they clone it and name it ''Renewal (opportunity Name). This way they have created another opportunity for the same business to sell them again in future. 

Now, when they clone the opportunity, the Banner details don't get cloned so they have to add the Banners again. Some opps have 10+ Banners so they have to add them again. Banner is shown as a related list on the opportunity page. How can I get Banners to be cloned with all the information when they clone an opportunity? Can someone please help me with the trigger to achieve this?

Thanks 
Best Answer chosen by Ankit Garg 117
Malika Pathak 9Malika Pathak 9

Hi Ankit Garg 117,


here below I have made your solution for cloning.


TriggerHelper Class

public class OppCloneClass {
    public static void OppCloneFun(list<Opportunity> newRecordsList, Map<id, Opportunity> oldRecordsMap)
    {
        list<Opportunity>oppCloneList=new list<Opportunity>();
        List<Opportunity> closedOpp = new Opportunity();
        for(Opportunity op : newRecordsList) {
                if((op.StageName != oldRecordsMap.get(op.Id).StageName)&&(op.StageName == 'ClosedWon' || op.StageName == 'ClosedLost')) {
                    closedOpp.add(op);
                }
        }
        list<bannner__c> banners=[select id ,OppID,Name from bannner__c where OppID in:closedOpp];
        
            for(opportunity op:closedOpp)
            {
                Opportunity Opclone= new Opportunity();
                Opclone.Name='Renewal'+op.Name;
                Opclone.CloseDate=op.CloseDate;
                oppCloneList.add(Opclone);
            }
        
        insert oppCloneList;
        map<id,list<bannner__c>> mapBanner= new map<id,list<bannner__c>>();
        for( bannner__c ban:banners)
            {
                if(!mapBanner.containskey(op.OppID))
                {
                list<bannner__c> listBanner=new List<bannner__c>();
                listBanner.add(ban)
                mapBanner.put(op.id,ban);
                }
                else
                {
                list<bannner__c> listBanner=mapBanner.get(op.OppID);
                listBanner.add(ban);
                mapBanner.put(op.OppID,listBanner);
                }
            }
        
        map<id,id> IdMap=new map<id,id>();
        for(integer i=0;i<closedOpp.size();i++)
        {
                IdMap.put(closedOpp[i].id,oppCloneList.id[i]);
        }
        list<bannner__c>banclonelist= new list<bannner__c>();
        for(id OppIds:mapBanner.keyset())
        {    
            for( bannner__c ban:mapBanner.get(OppIds))
            {
                bannner__c banclone=new bannner__c();
                banclone.OppID=IdMap.get(OppIds);
                banclonelist.add(banclone);
                
            }
        }
        insert banclonelist;
    }
 


  Trigger
 

trigger Trigger1 on Opportunity (after update)
{           
      OppCloneClass.OppCloneFun(trigger.new);

}
 

Let me know if this helps, if it does, please mark this answer as best so that others facing the same issue will find this information useful. 

Thank You,
Malika Pathak
 

All Answers

AbhishekAbhishek (Salesforce Developers) 
I think the feature you are requesting is still in idea face,
https://trailblazer.salesforce.com/ideaView?id=08730000000BpUXAA0

If it helps mark this as the best answer.
Malika Pathak 9Malika Pathak 9

Hi Ankit Garg 117,


here below I have made your solution for cloning.


TriggerHelper Class

public class OppCloneClass {
    public static void OppCloneFun(list<Opportunity> newRecordsList, Map<id, Opportunity> oldRecordsMap)
    {
        list<Opportunity>oppCloneList=new list<Opportunity>();
        List<Opportunity> closedOpp = new Opportunity();
        for(Opportunity op : newRecordsList) {
                if((op.StageName != oldRecordsMap.get(op.Id).StageName)&&(op.StageName == 'ClosedWon' || op.StageName == 'ClosedLost')) {
                    closedOpp.add(op);
                }
        }
        list<bannner__c> banners=[select id ,OppID,Name from bannner__c where OppID in:closedOpp];
        
            for(opportunity op:closedOpp)
            {
                Opportunity Opclone= new Opportunity();
                Opclone.Name='Renewal'+op.Name;
                Opclone.CloseDate=op.CloseDate;
                oppCloneList.add(Opclone);
            }
        
        insert oppCloneList;
        map<id,list<bannner__c>> mapBanner= new map<id,list<bannner__c>>();
        for( bannner__c ban:banners)
            {
                if(!mapBanner.containskey(op.OppID))
                {
                list<bannner__c> listBanner=new List<bannner__c>();
                listBanner.add(ban)
                mapBanner.put(op.id,ban);
                }
                else
                {
                list<bannner__c> listBanner=mapBanner.get(op.OppID);
                listBanner.add(ban);
                mapBanner.put(op.OppID,listBanner);
                }
            }
        
        map<id,id> IdMap=new map<id,id>();
        for(integer i=0;i<closedOpp.size();i++)
        {
                IdMap.put(closedOpp[i].id,oppCloneList.id[i]);
        }
        list<bannner__c>banclonelist= new list<bannner__c>();
        for(id OppIds:mapBanner.keyset())
        {    
            for( bannner__c ban:mapBanner.get(OppIds))
            {
                bannner__c banclone=new bannner__c();
                banclone.OppID=IdMap.get(OppIds);
                banclonelist.add(banclone);
                
            }
        }
        insert banclonelist;
    }
 


  Trigger
 

trigger Trigger1 on Opportunity (after update)
{           
      OppCloneClass.OppCloneFun(trigger.new);

}
 

Let me know if this helps, if it does, please mark this answer as best so that others facing the same issue will find this information useful. 

Thank You,
Malika Pathak
 

This was selected as the best answer
Ankit Garg 117Ankit Garg 117
Hi Malika Pathak,

Thank you so very much for this. Do I need to go to Developer Console -> File -> New -> Aspex Class and then past the first section of the code there and then Developer Console -> File -> New -> Apex Trigger and paste the second part of the code?


Regards 
Malika Pathak 9Malika Pathak 9

yes....!!

 

Ankit Garg 117Ankit Garg 117
Thanks Malika,

There are few errors on the first code when I copy pasted. Are there any changes that I need to make in the first code?
Ankit Garg 117Ankit Garg 117
Thanks Malika for your effort. Reallyt appriciate it. Atleast I am going somewher now :)