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
RohRoh 

GENERIC HISTORY CLASS FOR YOU TO USE

HELLO ALL,
THIS IS THE CUSTOM CODE WRITTEN TO FETCH THE HISTORY FOR ANY OBJECT IN SALESFORCE.
MODIFY IT AS PER NEED

public class yourClassForHistories
{
    public Id caseId {get; set;}
    public List<HistoryDetailClass> histories;
    // Variables
    public Static final Map<String, Schema.SObjectField> CaseFieldmap = Schema.SObjectType.Request__c.fields.getMap();
    public Static final List<Schema.PicklistEntry> fieldPicklistValues = Request__History.Field.getDescribe().getPicklistValues();

    public List<HistoryDetailClass> getHistories()
    {
        histories = new List<HistoryDetailClass>();
        List<Request__c> // Your Query
        
        list<Request__History>  // Your Query

        
        for(Request__History nowHistory : your List){
            GenericHistoryClass cHistory = new GenericHistoryClass();
            cHistory.createdById = nowHistory.CreatedBy.Id;
            cHistory.createdByName = nowHistory.CreatedBy.Name;
            cHistory.createdDate = nowHistory.CreatedDate;
            cHistory.field = nowHistory.Field;
            cHistory.id = nowHistory.Id;
            cHistory.newValue = String.valueOf(nowHistory.newValue);
            cHistory.oldValue = String.valueOf(nowHistory.oldValue);
            cHistory.parentId = nowHistory.ParentID;

            HistoryDetailClass tempHistory = new HistoryDetailClass();
            tempHistory = createHistoryEntry(cHistory);

            // Add to the list
            if(tempHistory != null){
                histories.add(tempHistory);
            }
        }

        histories.sort();
        return histories;
    }

    //Function to populate a temporary history record
    public HistoryDetailClass createHistoryEntry(GenericHistoryClass cHistory){
        HistoryDetailClass tempHistory = new HistoryDetailClass();
        String prevDate = '';

        if((cHistory.newValue == null && cHistory.oldValue == null)
                || (cHistory.newValue != null && !(string.valueOf(cHistory.newValue).startsWith('a0t') || string.valueOf(cHistory.newValue).startsWith('00G') ||
                    string.valueOf(cHistory.newValue).startsWith('005f') || string.valueOf(cHistory.newValue).startsWith('005e') ||
                    string.valueOf(cHistory.newValue).startsWith('005a')))
                || (cHistory.oldValue != null && !(string.valueOf(cHistory.oldValue).startsWith('a0t') || string.valueOf(cHistory.oldValue).startsWith('00G') ||
                    string.valueOf(cHistory.oldValue).startsWith('005f') || string.valueOf(cHistory.oldValue).startsWith('005e') ||
                    string.valueOf(cHistory.oldValue).startsWith('005a'))))
            {
                // Set the Date and who performed the action
                if(String.valueOf(cHistory.createdDate) != prevDate)
                {
                    tempHistory.theDate = String.valueOf(cHistory.createdDate);
                    tempHistory.who = cHistory.createdByName;
                    tempHistory.userId = cHistory.createdById;
                }
                else
                {
                    tempHistory.theDate = '';
                    tempHistory.who = '';
                    tempHistory.userId = cHistory.createdById;
                }
                prevDate = String.valueOf(cHistory.createdDate);

                // Get the field label
                String fieldLabel = YouClassForHistories.returnFieldLabel(cHistory.field);

                // Set the Action value
                if (String.valueOf(cHistory.field) == 'created')
                {
                    // on Creation
                    tempHistory.action = 'Created.';
                }
                else if(cHistory.oldValue != null && cHistory.newValue == null)
                {
                    // when deleting a value from a field
                    // Format the Date and if there's an error, catch it and re
                    try {
                        tempHistory.action = 'Deleted ' + Date.valueOf(cHistory.oldValue).format() + ' in <b>' + fieldLabel + '</b>.';
                    }
                    catch (Exception e)
                    {
                        tempHistory.action = 'Deleted ' + String.valueOf(cHistory.oldValue) + ' in <b>' + fieldLabel + '</b>.';
                    }
                }
                else
                {
                    // all other scenarios
                    String fromText = '';
                    if (cHistory.oldValue != null)
                    {
                        try {
                            fromText = ' from ' + Date.valueOf(cHistory.oldValue).format();
                        }
                        catch (Exception e)
                        {
                            fromText = ' from ' + String.valueOf(cHistory.oldValue);
                        }
                    }

                    String toText = '';
                    if (cHistory.NewValue != null)
                    {
                        try {
                            toText = Date.valueOf(cHistory.newValue).format();
                        }
                        catch (Exception e)
                        {
                            toText = String.valueOf(cHistory.newValue);
                        }
                    }

                    if(toText != '')
                        tempHistory.action = 'Changed <b>' + fieldLabel + '</b>' + fromText + ' to <b>' + toText + '</b>.';
                    else
                        tempHistory.action = 'Changed <b>' + fieldLabel;

                }

                String fieldValue=cHistory.field.replaceAll('__c','');
                fieldValue=fieldValue.replaceAll('_',' ');
                tempHistory.field=fieldValue;

            }

            return tempHistory;

    }

    // Function to return Field Label of a Case field given a Field API name
    public Static String returnFieldLabel(String fieldName)
    {
        if(yourClassForHistories.CaseFieldmap.containsKey(fieldName))
        return yourClassForHistories.CaseFieldmap.get(fieldName).getDescribe().getLabel();
        else
        {
            for(Schema.PicklistEntry pickList : fieldPicklistValues)
            {
                if(pickList.getValue() == fieldName)
                {
                    if(pickList.getLabel() != null){
                        return pickList.getLabel();
                    }
                    else{
                        return pickList.getValue();
                    }
                }
            }
        }
        return '';
    }


    // Inner Class to store the detail of the case history
    public class HistoryDetailClass implements Comparable{
        public String theDate {get; set;}
        public String who {get; set;}
        public Id userId {get; set;}
        public String action {get; set;}
        public String field{get; set;}
        public String OfferName{get; set;}

        public Integer compareTo(Object compareTo) {
            HistoryDetailClass compareToHistory = (HistoryDetailClass)compareTo;
            if (theDate == compareToHistory.theDate){
                return 0;
            }
            if (theDate > compareToHistory.theDate){
                return -1;
            }
            return 1;        
        }       
    }

    //Generic Inner Class that replecates the History Object
    public class GenericHistoryClass{
        public Id createdById {get;set;}
        public String createdByName {get;set;}
        public Datetime createdDate {get;set;}
        public String field {get;set;}
        public Id id {get;set;}
        public boolean isDeleted {get;set;}
        public String newValue {get;set;}
        public String oldValue {get;set;}
        public Id parentId {get;set;}
        public String offerName {get;set;}
    }

Thanks,
Rohit Alladi.

Please choose as best answer if you liked it !
SBishtSBisht

Hi Roh,

Thanks for the generic class code, now i am having a big challange to write a test class and cover this code.
History tables are ReadOnly, can you post how to test this generic history class code???

Thanks,
SBisht