Sunday, April 10, 2016

Salesforce SObjects - Dynamic Cloning using Field Sets (Re-usable)

Using Field Sets (with a given set of fields) you can dynamic clone objects.

Sample Code:
//Fetch the fields from the field set
Schema.SObjectType SObjectTypeObj = GlobalDescribeMap.get('User');
Schema.DescribeSObjectResult DescribeSObjectResultObj = SObjectTypeObj.getDescribe();
Schema.FieldSet fieldSetObj = DescribeSObjectResultObj.FieldSets.getMap().get('<<Pass UserFieldSetName>>');
Set<string> fieldSetFields = new Set<string>();
for(Schema.FieldSetMember f : fieldSetObj.getFields())
{
    fieldSetFields.add(f.getFieldPath());
}
//custom clone original User (clone only those fields which are defined in fieldset)
Id userId = UserInfo.getUserId();
List<SObject> sObjects = AllFieldCloner.cloneByIds(new List<Id> { userId }, 'User', fieldSetFields);

// Clone a list of objects to a particular object type
public class AllFieldCloner
{
    /**
    * Clone list of SOBject Ids with the given set of fields from a field set
    * Parameters:
    * - List<Id> sObjectsIds - the list of Ids of the objects to be cloned. Objects must exist already in the database.
    * - Schema.SobjectType objectType - the type of object to be cloned.
    * - Set<String> sObjectFields - set of object fields to be cloned.
    */
    public static List<sObject> cloneObjectsByIds(List<Id> sObjectIds, Schema.SObjectType objectType, Set<String> sObjectFields)
    {
        return cloneObjectsByIds(sObjectIds, objectType, new List<String>(sObjectFields));
    }

    /**
    * Clone list of SOBject Ids with the given list of fields from a field set
    * Parameters:
    * - List<Id> sObjectsIds - the list of Ids of the objects to be cloned. Objects must exist already in the database.
    * - Schema.SobjectType objectType - the type of object to be cloned.
    * - List<String> sObjectFields - list of object fields to be cloned.
    */
    public static List<sObject> cloneByIds(List<Id> sObjectIds, Schema.SObjectType objectType, List<String> sObjectFields)
    {
        // A list of new cloned sObjects
        List<sObject> clonedSObjects = new List<sObject>{};

        // If there are no objects sent into the method,
        // then return an empty list
        if (sObjectIds != null && !sObjectIds.isEmpty() && !sObjectFields.isEmpty())
        {
            /* Using the list of sObject IDs and the object type,
            we can construct a string based SOQL query
            to retrieve the field values of all the objects.*/

            String allSObjectFieldsQuery = 'SELECT ' + String.join(sObjectFields, ', ') +
                                          ' FROM ' + objectType.getDescribe().getName() +
                                          ' WHERE Id IN (\'' + String.join(sObjectIds, '\', \'') + '\')';

            try
            {
                // Execute the query. For every result returned,
                // use the clone method on the generic sObject
                // and add to the collection of cloned objects
                for (SObject sObjectFromDatabase : Database.query(allSObjectFieldsQuery))
                {
                    clonedSObjects.add(sObjectFromDatabase.clone(false,true));  
                }
            }
            catch (exception e)
            {
                // Write exception capture method
                System.Debug('Error During Cloning:'+e);
            }
        }    

        // return the cloned sObject collection.
        return clonedSObjects;
    }
}

Dynamic clone of objects for all fields (except a set of fields by using Exclude logic).

Sample Code:

/**
    * Clone the given SOBJectIds with all the fields which is updatable
    * Parameters:
    * - List<Id> sObjectsIds - the list of Ids of the objects to be cloned. Objects must exist already in the database.
    * - Schema.SobjectType objectType - the type of object to be cloned.
    * - Set<String> sObjectExcludeFields - clone all createable/updateable fields EXCEPT these fields.
    */
    public static List<sObject> cloneByIdsAllfields(List<Id> sObjectIds, Schema.SObjectType objectType, Set<String> sObjectExcludeFields)
    {
        // A list of fields for the sObject being cloned
        List<String> sObjectFields = new List<String>{};

        // Get all the fields from the selected object type using
        // the get describe method on the object type.
        Map<String, Schema.SObjectField> fieldMap = objectType.getDescribe().fields.getMap();
        for(String field : fieldMap.keySet())
        {
            // go inside if condition when exclusion set is either null or it does not contain give field
            if(sObjectExcludeFields == null || !sObjectExcludeFields.contains(field))
            {
                Schema.DescribeFieldResult fieldDescribe = fieldMap.get(field).getDescribe();
                if(fieldDescribe.isCreateable() && fieldDescribe.isUpdateable() && !fieldDescribe.isCalculated())
                    sObjectFields.add(field);
            }
        }

        return cloneObjectsByIds(sObjectIds, objectType, sObjectFields);
    }

No comments:

Post a Comment