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
Eclipse DeveloperEclipse Developer 

Deep Clone - Opportunity with related list custom object

How to deep clone opportunity with related list custom object?
Suggest me the best solution, please.
Raj VakatiRaj Vakati
You have to call the code from the custom button .. i have a similar blog .. refer this link 

Refer this link

https://rajvakati.com/2018/10/17/lightning-component-clone-with-related-records/
https://rajvakati.com/2018/10/17/clone-to-any-sobject-record-with-lightning-component/
 
public class SuperClone {
    private static SuperCloneService service = new SuperCloneService();
    @AuraEnabled
    public static Id doClone(Id parentId) {
        Id clonedId = service.doClone(parentId);
        return clonedId;
    }
}
 
public class SuperCloneService {
    public Id doClone(String parentId) {
        Set<String> querySobject = new Set<String>();
        for(Super_Clone_Objects__mdt m : [select Id, DeveloperName, Label, API_Name__c 
                                          from Super_Clone_Objects__mdt  ]){ 
                                              querySobject.add(m.API_Name__c) ;  
                                          }
        Map <String, Schema.SObjectType> schemaMap = Schema.getGlobalDescribe();
        String objectAPIName = '';
        String keyPrefix = parentId.substring(0,3);
        for( Schema.SObjectType obj : schemaMap.Values() ){
            String prefix = obj.getDescribe().getKeyPrefix();
            if(prefix == keyPrefix){
                objectAPIName = obj.getDescribe().getName();
                break;
            }
        }
        Set <String> fieldMap = schemaMap.get(objectAPIName).getDescribe().fields.getMap().keySet();
        List<String> finalFields = new List<String>() ;
        finalFields.addAll(fieldMap);
        
        SObjectType objToken = Schema.getGlobalDescribe().get(objectAPIName); 
        DescribeSObjectResult objDef = objToken.getDescribe();
        Map<String,String> so = new Map<String,String>();
        Map<String,String> so1 = new Map<String,String>();
        
        for (Schema.ChildRelationship cr: objDef.getChildRelationships()) 
        {
            if(cr.getField().getDescribe().isAccessible()&& cr.getField().getDescribe().isCreateable()&&cr.getField().getDescribe().isAccessible() && cr.getRelationshipName()!=null){
                if(querySobject.contains(''+cr.getChildSObject())){
                    so.put(''+cr.getChildSObject()  , ''+cr.getRelationshipName());
                    so1.put(''+cr.getRelationshipName()  , ''+cr.getField());
                }
            }
        } 
        
        List<String> subqueries = prepareSubqueries(so, schemaMap);
        String query =
            'SELECT ' + String.join(finalFields, ',')+
            ','+String.join(subqueries, ',') +
            ' FROM ' +objectAPIName +
            ' WHERE Id = \''+parentId+'\'';
        
        List<Sobject> parentObj = Database.query(query);
        Sobject parentRecordId = parentObj[0];
        
        Sobject clonedRecord = parentRecordId.clone();
        insert clonedRecord;
        List<sObject> childObjects =cloneChildren(parentRecordId, clonedRecord, so  ,so1);
        insert childObjects;
        System.debug('clonedRecord'+clonedRecord.Id);
        return clonedRecord.Id ;
        
    }
    
    private List<sObject> cloneChildren(
        Sobject parent,
        Sobject child,
        Map<String , String> childRelatedListObjects,
        Map<String , String> childRelatedListObjects1
    ){
        
        List<sObject> childObjects = new List<SObject>();
        for (String childObjectDefinition : childRelatedListObjects.values()) {
            List<sObject> parentRecords = parent.getSObjects(childObjectDefinition);
            System.debug('parentRecords'+parentRecords);
            if (parentRecords != null) {
                List<sObject> records = parentRecords.deepClone();
                System.debug('records'+records);
                for (sObject record : records) {
                    record.put(childRelatedListObjects1.get(childObjectDefinition), child.Id);
                }
                childObjects.addAll(records);
            }
        }
        return childObjects;
    }
    
    private List<String> prepareSubqueries(
        Map<String , String> childrelatedListObjects,
        Map <String, Schema.SObjectType> schemaMap
    ){
        List<String> subqueries = new List<String>();
        for(String childObject : childrelatedListObjects.keySet()){
            List<String> childFields = new List<String>();
            Map <String, Schema.SObjectField> fieldMap = schemaMap.get(childObject).getDescribe().fields.getMap();
            System.debug('fieldMap'+fieldMap);
            for(Schema.SObjectField sof : fieldMap.values()){
                DescribeFieldResult dfr = sof.getDescribe();
                if(dfr.isCreateable()){
                    childFields.add(dfr.getName());
                }
            }
            if(!childFields.isEmpty()){
                String query = '(SELECT ' + String.join(childFields, ',') + ' FROM ' + childrelatedListObjects.get(childObject) + ')';
                subqueries.add(query);
            }
            
        }
        return subqueries;
    }
    
}