+ Start a Discussion
Frances AllenFrances Allen 

How to preseve the original record after cloning in Apex?

I want to clone a record through Apex using a trigger to customize staging and update date fields.
I've run into two problems:

1. My original record isn't saved. I want the original record to save and a copy to be made from it. I'm looking for an automatic cloning action essentially.

The copy is known by the addage "planning" onto the name of the Opportunity.

2. The trigger is acting on all updates, meaning I can't change and save a field without activating the trigger. Do
I just need to change the parameters? Is there a way to check and limit with Trigger.Old?

Trigger that conditionally stages.
trigger FinancialPlanning on Opportunity (before update) {
 List<Opportunity> oppList = new List<Opportunity>();
    //creating list of opps in which items will live  
    for(Opportunity x : Trigger.new) {
          x.Name = x.Name + ' planning';
          
      
          if (x.StageName == '0 - Deferred'){
    			x.StageName = '1 - Research';
                x.Ask_Ready_Date__c = x.Ask_Ready_Date__c + 365;
                x.npsp__Ask_Date__c = x.npsp__Ask_Date__c + 365;
                x.Verbal_Date__c = x.Verbal_Date__c + 365; 
                x.Committed_Date__c = x.Committed_Date__c +365; 
                x.CloseDate = x.CloseDate + 365;
              
          }else if (x.StageName == '0 - Declined'){
                x.StageName = '1 - Research';
                x.Ask_Ready_Date__c = x.Ask_Ready_Date__c + 365;
                x.npsp__Ask_Date__c = x.npsp__Ask_Date__c + 365;
                x.Verbal_Date__c = x.Verbal_Date__c + 365; 
                x.Committed_Date__c = x.Committed_Date__c +365; 
                x.CloseDate = x.CloseDate + 365;
                
          }else if (x.StageName == '0 - Unresponsive') {
                x.StageName = '1 - Research';
                x.Ask_Ready_Date__c = x.Ask_Ready_Date__c + 365;
                x.npsp__Ask_Date__c = x.npsp__Ask_Date__c + 365;
                x.Verbal_Date__c = x.Verbal_Date__c + 365; 
                x.Committed_Date__c = x.Committed_Date__c +365; 
                x.CloseDate = x.CloseDate + 365;
               
          }else if (x.StageName == '1 - Research') {
				x.Ask_Ready_Date__c = x.Ask_Ready_Date__c + 365;
                x.npsp__Ask_Date__c = x.npsp__Ask_Date__c + 365;
                x.Verbal_Date__c = x.Verbal_Date__c + 365; 
                x.Committed_Date__c = x.Committed_Date__c +365; 
                x.CloseDate = x.CloseDate + 365;
               
          }else if (x.StageName == '2 - Intro'){
                x.Ask_Ready_Date__c = x.Ask_Ready_Date__c + 365;
                x.npsp__Ask_Date__c = x.npsp__Ask_Date__c + 365;
                x.Verbal_Date__c = x.Verbal_Date__c + 365; 
                x.Committed_Date__c = x.Committed_Date__c +365; 
                x.CloseDate = x.CloseDate + 365;
              
          }else if (x.StageName == '3 - Educate'){
                x.Ask_Ready_Date__c = x.Ask_Ready_Date__c + 365;
                x.npsp__Ask_Date__c = x.npsp__Ask_Date__c + 365;
                x.Verbal_Date__c = x.Verbal_Date__c + 365; 
                x.Committed_Date__c = x.Committed_Date__c +365; 
                x.CloseDate = x.CloseDate + 365;
              
          }else if (x.StageName == '4 - Ask Ready'){
                x.npsp__Ask_Date__c = x.npsp__Ask_Date__c + 365;
                x.Verbal_Date__c = x.Verbal_Date__c + 365; 
                x.Committed_Date__c = x.Committed_Date__c +365; 
                x.CloseDate = x.CloseDate + 365;
              
          }else if (x.StageName == '5 - Request'){
                x.Verbal_Date__c = x.Verbal_Date__c + 365; 
                x.Committed_Date__c = x.Committed_Date__c +365; 
                x.CloseDate = x.CloseDate + 365;
              
          }else if (x.StageName == '6 - Verbal'){
                x.Committed_Date__c = x.Committed_Date__c +365; 
                x.CloseDate = x.CloseDate + 365;
              
          }else if (x.StageName == '7 - Committed'){
                x.Committed_Date__c = x.Committed_Date__c +365; 
                x.CloseDate = x.CloseDate + 365;
              
          }else{
                x.Committed_Date__c = x.Committed_Date__c +365; 
                x.CloseDate = x.CloseDate + 365;
          }
          //get this picklist's value and update field with method. 
          x.Designated_Fiscal_Year__c = x.Designated_Fiscal_Year__c ; 
		  
        if (oppList.size() > 0) insert oppList;
            oppList.add(x);
      }
     
}
Here is what I've got in my controller class:
public class FinancialCloningController {
    //added an instance varaible for the standard controller
    private ApexPages.StandardController controller {get; set;}
    
    //instance for the variables being passed by id on the url
	private Opportunity opp {get;set;}
    
    //set the id of the record that is created
    public ID newRecordId {get;set;}
    
    public FinancialCloningController(ApexPages.StandardController controller) {
        this.opp = (Opportunity)controller.getRecord();
        this.controller = controller;
        opp = (Opportunity)controller.getRecord(); 
         
    }
    
    public PageReference cloneOpportunity() {

         // setup the save point for rollback
         Savepoint sp = Database.setSavepoint();
         Opportunity newOpp;

         try{

             //Copy the Opportunity - only include the records you want to clone 
             opp = [SELECT Id, Name, StageName FROM Opportunity WHERE ID = :opp.id];
             insert newOpp;
             newOpp.clone(false, false, false, false);

             //set the id of the new po created for testing
             newRecordId = newOpp.id;
             

         } catch (Exception e){
             // roll everything back in case of error
            Database.rollback(sp);
            ApexPages.addMessages(e);
            return null;
         }

          return new PageReference('/'+newOpp.id+'/e?retURL=%2F'+newOpp.id);
        
    }

}
I'm not sure that I can isolate a triggers actions to a button. Obviously, I'm very new to Salesforce and don't know if there is a way to do this without triggers. I feel the trigger is too powerful in this case. Why is the original record saving as a new record (conditional logic is fine and works), and can this trigger be isolated to a button action?

Thanks.





 
Best Answer chosen by Frances Allen
GauravGargGauravGarg
Hi Frances,

Yes, we can make trigger run only once and in your scenario it is quite easy. Below scenario is for Before Update as in Before Insert call Trigger will always processed once. 
Trigger OpportunityTrigger_AT on Opportunity(before update) {
	for(Opportunity opp : Trigger.New)
	{
		if(opp.CreatedDate == Trigger.oldMap(opp.id).CreatedDate )
		{
				//apex code
		}
	}
}
In Above example, update call will always run once when record is inserted and updated. 

If you require to make an update once after the record is inserted, then please follow below steps:
  • Create a Boolean field. default false. 
  • Make this field true after first trigger run. 
  • Check condition in Trigger that is field_value == False. 


Hope this helps!!!

Thanks,

Gaurav
Skype: gaurav62990

All Answers

GauravGargGauravGarg
Hi Francis,

I understand your first problem
  • Create a List<Opportunity>, and add Opportunity record into it. 
  • Clone the first record and update the name of Opportunity_Planning and add the record in list. 
  • Now, save List. This wil save both the record. 
Could you please explain your second problem. 

Thanks,
Gaurav
Skype: gaurav62990
Frances AllenFrances Allen
I am creating a list and passing new opps in. Is this code for cloning not correct? I understand the false parameters to be certain fields you wouldn't want cloned over, such as read-only fields, and wouldn't prevent a whole record from being cloned over.
insert newOpp;
newOpp.clone(false, false, false, false);
The second question is if I can modify the behavior of a trigger to only act on a record once and never again? I understand that triggers operate on certain parameters (you're updating, inserting, deleting, etc.), however, users are going to need to update these records again, and without changing the fields. For example, if you update the record again an additional 'planning' and 365 days to the date is also added.
I only need this trigger to fire once, but any updates I make to the document trigger the changes.

 
GauravGargGauravGarg
Hi Frances,

Yes, we can make trigger run only once and in your scenario it is quite easy. Below scenario is for Before Update as in Before Insert call Trigger will always processed once. 
Trigger OpportunityTrigger_AT on Opportunity(before update) {
	for(Opportunity opp : Trigger.New)
	{
		if(opp.CreatedDate == Trigger.oldMap(opp.id).CreatedDate )
		{
				//apex code
		}
	}
}
In Above example, update call will always run once when record is inserted and updated. 

If you require to make an update once after the record is inserted, then please follow below steps:
  • Create a Boolean field. default false. 
  • Make this field true after first trigger run. 
  • Check condition in Trigger that is field_value == False. 


Hope this helps!!!

Thanks,

Gaurav
Skype: gaurav62990

This was selected as the best answer
Frances AllenFrances Allen
Hello,

Thank you for this solution, however, I am still getting an error that 'Trigger does not exist'.
trigger FinancialPlanning on Opportunity (before update) {
 List<Opportunity> oppList = new List<Opportunity>();
    //creating list of opps in which items will live  
    
    for(Opportunity x : Trigger.new) {
        if(x.CreatedDate == Trigger.oldMap(x.id).CreatedDate){    
        x.Name = x.Name + ' planning';
          
            if (x.StageName == '0 - Deferred'){
    			x.StageName = '1 - Research';
                x.Ask_Ready_Date__c = x.Ask_Ready_Date__c + 365;
                x.npsp__Ask_Date__c = x.npsp__Ask_Date__c + 365;
                x.Verbal_Date__c = x.Verbal_Date__c + 365; 
                x.Committed_Date__c = x.Committed_Date__c +365; 
                x.CloseDate = x.CloseDate + 365;
              
          }else if (x.StageName == '0 - Declined'){
                x.StageName = '1 - Research';
                x.Ask_Ready_Date__c = x.Ask_Ready_Date__c + 365;
                x.npsp__Ask_Date__c = x.npsp__Ask_Date__c + 365;
                x.Verbal_Date__c = x.Verbal_Date__c + 365; 
                x.Committed_Date__c = x.Committed_Date__c +365; 
                x.CloseDate = x.CloseDate + 365;
                
          }else if (x.StageName == '0 - Unresponsive') {
                x.StageName = '1 - Research';
                x.Ask_Ready_Date__c = x.Ask_Ready_Date__c + 365;
                x.npsp__Ask_Date__c = x.npsp__Ask_Date__c + 365;
                x.Verbal_Date__c = x.Verbal_Date__c + 365; 
                x.Committed_Date__c = x.Committed_Date__c +365; 
                x.CloseDate = x.CloseDate + 365;
               
          }else if (x.StageName == '1 - Research') {
				x.Ask_Ready_Date__c = x.Ask_Ready_Date__c + 365;
                x.npsp__Ask_Date__c = x.npsp__Ask_Date__c + 365;
                x.Verbal_Date__c = x.Verbal_Date__c + 365; 
                x.Committed_Date__c = x.Committed_Date__c +365; 
                x.CloseDate = x.CloseDate + 365;
               
          }else if (x.StageName == '2 - Intro'){
                x.Ask_Ready_Date__c = x.Ask_Ready_Date__c + 365;
                x.npsp__Ask_Date__c = x.npsp__Ask_Date__c + 365;
                x.Verbal_Date__c = x.Verbal_Date__c + 365; 
                x.Committed_Date__c = x.Committed_Date__c +365; 
                x.CloseDate = x.CloseDate + 365;
              
          }else if (x.StageName == '3 - Educate'){
                x.Ask_Ready_Date__c = x.Ask_Ready_Date__c + 365;
                x.npsp__Ask_Date__c = x.npsp__Ask_Date__c + 365;
                x.Verbal_Date__c = x.Verbal_Date__c + 365; 
                x.Committed_Date__c = x.Committed_Date__c +365; 
                x.CloseDate = x.CloseDate + 365;
              
          }else if (x.StageName == '4 - Ask Ready'){
                x.npsp__Ask_Date__c = x.npsp__Ask_Date__c + 365;
                x.Verbal_Date__c = x.Verbal_Date__c + 365; 
                x.Committed_Date__c = x.Committed_Date__c +365; 
                x.CloseDate = x.CloseDate + 365;
              
          }else if (x.StageName == '5 - Request'){
                x.StageName = '4 - Ask Ready';
                x.Verbal_Date__c = x.Verbal_Date__c + 365; 
                x.Committed_Date__c = x.Committed_Date__c +365; 
                x.CloseDate = x.CloseDate + 365;
              
          }else if (x.StageName == '6 - Verbal'){
                x.StageName = '4 - Ask Ready';
                x.Committed_Date__c = x.Committed_Date__c +365; 
                x.CloseDate = x.CloseDate + 365;
              
          }else if (x.StageName == '7 - Committed'){
                x.StageName = '4 - Ask Ready';
                x.Committed_Date__c = x.Committed_Date__c +365; 
                x.CloseDate = x.CloseDate + 365;
              
          }else{
                x.StageName = '4 - Ask Ready';
                x.Committed_Date__c = x.Committed_Date__c +365; 
                x.CloseDate = x.CloseDate + 365;
          }
     
		  
        if (oppList.size() > 0) insert oppList;
            oppList.add(x);
      }
   } 
}

 
GauravGargGauravGarg
Hi Francis,


Can we do a screen sharing session and figure out what is actually failing on your side.  Please contact me on skype: gaurav62990

Thanks,
Gaurav
Ajesh Pillai 2Ajesh Pillai 2
Hi Gaurav help me withstoring the previous value of Amount field into  new field when opportyunity is cloned.how should i approached this