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
Mathew Andresen 5Mathew Andresen 5 

clone opportunities with products in lightning

Hi,

Is there an easy way to clone opportunities and products in lightning?  

Thanks,
GauravGargGauravGarg
Hi Mathew,
For Lightning Expericence this option is not availble yet,you can still go to classic version and clone the opportunity with products.If you want to achieve something autamted then you can go ahead with process builder suggested by Rakesh Gupta (https://automationchampion.com/tag/clone-opportunity-with-opportunity-products/)

Hope this helps!!!

Thanks,
Gaurav
Skype: gaurav62990
Mathew Andresen 5Mathew Andresen 5
So does using clone in apex not work?  Something like
 
Opportunity opp = [SELECT Id FROM Opportunity WHERE Id = 'xxx'];
Opportunity newOpp = opp.clone(false, false, false, false)
insert newOpp;

 
Mathew Andresen 5Mathew Andresen 5
I ended up doing a quick action to a lightning component, and new apex class. I hate flows.
 
<aura:component implements="force:lightningQuickActionWithoutHeader,force:hasRecordId" controller="CloneOpportunityProducts">
    <aura:attribute name="recordId" type="String"/>
    <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
		<h1>Cloning Opportunity...</h1>
    
	
</aura:component>
 
({
	doInit : function(component, event, helper) {
        var recordId = component.get("v.recordId")
		console.log('recordId = ' + recordId);
        var action = component.get("c.getCloneOpp");
       action.setParams({"oldId": recordId});
        action.setCallback(this, function(response){
            var state = response.getState();
            if (component.isValid() && state === "SUCCESS") {
                var returned =response.getReturnValue();
                console.log("SUCCESS returned: " + JSON.stringify(returned));
                
                var navEvt = $A.get("e.force:navigateToSObject");
                    navEvt.setParams({
                      "recordId": returned,
                     // "slideDevName": "related"
                    });
                    navEvt.fire();                
 
            }
        });
        $A.enqueueAction(action);             
		
	} // end doInit function
    

})
 
public class CloneOpportunityProducts {
    
    @AuraEnabled
    public static String getCloneOpp(String oldId) {
        system.debug('oldId ' + oldId);
        
        // Initialize setup variables
        String objectName = 'Opportunity';  // modify as needed
        String query = 'SELECT';
        Map<String, Schema.SObjectField> objectFields = Schema.getGlobalDescribe().get(objectName).getDescribe().fields.getMap();
        
        // Grab the fields from the describe method and append them to the queryString one by one.
        for(String s : objectFields.keySet()) {
           query += ' ' + s + ', ';
        }
        
        // Manually add related object's fields that are needed.
        query += 'Account.Name '; // modify as needed    'Account.Name';
        
        // Strip off the last comma if it exists.
        if (query.subString(query.Length()-1,query.Length()) == ','){
            query = query.subString(0,query.Length()-1);
        }
        
        // Add FROM statement
        query += ' FROM ' + objectName;
        
        // Add on a WHERE/ORDER/LIMIT statement as needed
        query += ' WHERE Id =  \''+ oldId +'\'  LIMIT 1'; // modify as needed   WHERE Id = \'test\' AND HasOpportunityLineItem = true LIMIT 1'; 
        system.debug(query);    
          
        Opportunity opp = database.query(query);
        system.debug(opp);
        Opportunity newOpp = opp.clone(false, false, false, false);
        newOpp.Name='new clone';
        insert newOpp;   
        if (opp.HasOpportunityLineItem == true) {
            List<OpportunityLineItem> products = [SELECT Id, 
                                                  Name, 
                                                  Quantity, 
                                                  Vintage__c, 
                                                  Tier__c, 
                                                  Variety__c, 
                                                  Appellation__c,
                                                  Country__c,
                                                  COGS__c, TotalPrice, PricebookEntryId FROM OpportunityLineITem WHERE OpportunityId = :opp.Id];
            
            system.debug('product List = ' +products);
    
            system.debug('newOpp Id = ' + newOpp.Id);
            List<OpportunityLineItem> newProdList = new List<OpportunityLineItem>();
            for (OpportunityLineItem prod:products) {
                OpportunityLineItem newProd = prod.clone(false, false, false, false);
                newProd.OpportunityId = newOpp.id;
                newProdList.add(newProd);
            }
            insert(newProdList);
            system.debug('newProdList ' + newProdList);           
        } // end if
        
        return newOpp.id;
        

   }

}

 
Razia Khan 7Razia Khan 7
@Mathew Andresen 5

Its works like a Pro..Good Job
Georges MardiniGeorges Mardini
Hi,
I have a little question,
i create a new clone button on opportunity, but when i use this button to clone a won opportunity (so the opportunity is closed), my apex code put StageName into the first step but the opportunity is still closed.
What should i do? 

Thanks
Ashish Kumar 28897Ashish Kumar 28897
@Mathew 
Thanks you so much , it's work Successfully