4

I am using below trigger to track history as I need to track more than 20 fields.In my case I am tracking lookup fields on Account object.If there is any update to lookup field then it creates history record with old value and new value as IDs.How should I get Name instead of ID

    trigger AccountHistoryTracker on Account (after update) {
List<Schema.FieldSetMember> trackedFields =     SObjectType.Account.FieldSets.HistoryTracking.getFields();
if (trackedFields.isEmpty()) return;

 List<AccountHistoryTracking__c> fieldChanges = new List<AccountHistoryTracking__c>();

 List<string> apiNameList = new List<string>();        

if(Trigger.isUpdate){
for (Account aNew : trigger.new) {

Account aOld = trigger.oldmap.get(aNew.Id);

for (Schema.FieldSetMember fsm : trackedFields) {

 String fieldName  = fsm.getFieldPath();
String fieldLabel = fsm.getLabel();

if (aNew.get(fieldName) != aOld.get(fieldName)) {

String oldValue = String.valueOf(aOld.get(fieldName));
String newValue = String.valueOf(aNew.get(fieldName));
if (oldValue != null && oldValue.length()>255) oldValue = oldValue.substring(0,255);
 if (newValue != null && newValue.length()>255) newValue = newValue.substring(0,255); 

 AccountHistoryTracking__c aht = new AccountHistoryTracking__c();
aht.name         = fieldLabel;
aht.apiName__c   = fieldName;
aht.User__c      = aNew.Id;
aht.ChangedBy__c = UserInfo.getUserId();
aht.OldValue__c  = oldValue;
 aht.NewValue__c  = newValue;

 apiNameList.add(aht.apiName__c);
 fieldChanges.add(aht);
}        
}
}
}
if (!fieldChanges.isEmpty()) {
 insert fieldChanges;
 }
 }
3

By looking at your current code, things are looking to be dynamic, which means a lookup field to any sObject could be potentially found in your fieldset. Having that in mind, you need to find a way to dynamically query the parent object that the Account is looking up to and get it's name. I wrote a quick solution for you demonstrating some methods of how that can be achieved. It's not necessarily the best or most efficient way but it should give you some ideas of how that can be done. Please note that this code has not been compiled and you need to tweak it in order to plug it in in your current trigger:

// a map that keeps the lookup object name as a key, and a map of the old and the new lookup record Ids with their corresponding names as a value
Map <String, Map <Id, String>> lookupRecords = new Map <String, Map <Id, String>> ();

// ...
// your existing for loops
// ...

if (aNew.get(fieldName) != aOld.get(fieldName)) 
{
    // Check whether field set memeber is of type Reference (Lookup)
    if (fsm.getType() == Schema.DisplayType.REFERENCE)
    {
        // Get the field name
        //String fieldName = fsm.getFieldPath();
        // Get the Ids of the parent records (old and new)
        Id newLookupId = Id.valueOf(String.valueof(aNew.get(fieldName)));
        Id oldLookupId = Id.valueOf(String.valueof(aOld.get(fieldName)));
        // Determine the object name that is lookin up to, based on the ID
        String sObjName = newLookupId.getSObjectType().getDescribe().getName();

        if (lookupRecords.get(sObjName) == null)
        {
            lookupRecords.put(sObjName, new Map <Id, String> ());
        }

        lookupRecords.get(sObjName).put(newLookupId, null);
        lookupRecords.get(sObjName).put(oldLookupId, null);
    }
    else
    {
        // ...
        // your existing code to create AccountHistoryTracking__c (excluding lookups)
        // ...
    }
}

// Put this outside all other loops
// Populate the map with ObjectName => RecordId => Name for both old and new lookups that have changed
for (String objectName : lookupRecords.keySet())
{
    Set <Id> recordIds = lookupRecords.get(objectName).keySet();
    for (sObject sObjectRecord : Database.query('SELECT Id, Name FROM ' + objectName + ' WHERE Id IN :recordIds'))
    {
        lookupRecords.get(objectName).put((Id)sObjectRecord.get('Id'), (String)sObjectRecord.get('Name'));
    }
}

// Again loop like the first time
for (Account aNew : trigger.new) 
{
    Account aOld = trigger.oldmap.get(aNew.Id);
    for (Schema.FieldSetMember fsm : trackedFields) 
    {
        if (fsm.getType() == Schema.DisplayType.REFERENCE)
        {
            String fieldName  = fsm.getFieldPath();
            String fieldLabel = fsm.getLabel();

            if (aNew.get(fieldName) != null && aOld.get(fieldName) != null && aNew.get(fieldName) != aOld.get(fieldName)) 
            {
                Id newLookupId = Id.valueOf(String.valueof(aNew.get(fieldName)));
                Id oldLookupId = Id.valueOf(String.valueof(aOld.get(fieldName)));
                String sObjName = newLookupId.getSObjectType().getDescribe().getName();

                if (lookupRecords.get(sObjName) != null)
                {
                    String oldName = lookupRecords.get(sObjName).get(oldLookupId);
                    String newName = lookupRecords.get(sObjName).get(newLookupId);

                    // create the additional AccountHistoryTracking__c for lookups
                }
            }
        }
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.