Some time we might need to track the history of the long text field or the rich text area field and Salesforce doesn't store the values for that, or might some time you need more than what Salesforce do in history tracking
Here is the custom solution how you can achieve the custom history tracking
Create a custom setting which will hold the sobject name and field to be tracked . Changes will be stored as a note to the parent record you may create a custom object if you want
Invocation on Account Object
/**
* This is the trigger to capture the changes made in long text area
**/
trigger AccountHistoryTrigger on Account (after update) {
//checking the conditions. Target org may have existing trigger
if(TRIGGER.isAfter && TRIGGER.isUpdate){
HistoryTrackingHandler handler = new HistoryTrackingHandler();
handler.checkAndCreateNote(Trigger.newMap,Trigger.oldMap,'Account');
}
}
Handler class
/**
* This class is the handler for the triggers on the sobjects those want to track values
**/
public class HistoryTrackingHandler{
/**
* This method will take the new map and old map along with the Sobject name
* and comapre the values present in the custom setting for the Sobject
* If any values found then it will insert a note with al the changes
**/
public void checkAndCreateNote(Map<Id,Sobject> newMapValues, Map<Id,Sobject> oldMapValues,String sobj){
/**
* Checking if the custom setting value exists
* input newMap,oldMap, Api name of the Sobject
**/
if(LongTextAreaFieldstoTrack__c.getInstance(sobj)<> NULL && LongTextAreaFieldstoTrack__c.getInstance(sobj).Field__c <> NULL && LongTextAreaFieldstoTrack__c.getInstance(sobj).Field__c.trim() <> '' && LongTextAreaFieldstoTrack__c.getInstance(sobj).Active__c == TRUE){
// getting the values from the custom setting
String selectedFields = LongTextAreaFieldstoTrack__c.getInstance(sobj).Field__c;
List<Note> noteList = new List<Note>(); // creating a list to insert notes
Map<String, Schema.SObjectType> gd = Schema.getGlobalDescribe();
Schema.SobjectType oType = gd.get(sobj); // getting the object type in runtime
// getting all the fields at runtime
Map <String, Schema.SObjectField> fieldMap = Schema.getGlobalDescribe().get(sobj).getDescribe().fields.getMap();
//Iterate through the loop and check for the field if the field present in the custom setting
//and the values are modified then create a note record for per transction for each record
for(Sobject currentSobj : newMapValues.values()){
sObject newObjectInstance = oType.newSObject(); // will hold new instance
sObject oldObjectInstance = oType.newSObject(); // will hold old instance
newObjectInstance = currentSobj; // getting the new instance
oldObjectInstance= oldMapValues.get(currentSobj.Id); // getting the old values
for (String fieldName : fieldMap.keyset()) {
if(selectedFields.containsIgnoreCase(fieldName)){// checking if present in the custom setting or not
if(newObjectInstance.get(fieldName) != oldObjectInstance.get(fieldName) && oldObjectInstance.get(fieldName) <> NULL){
String nodeTitle = ''+ fieldName + ' has been changed by ' + userInfo.getName() + ' at ' + System.now();
//value has been changed, so append in the body
String nodeBody = 'Old value was \n'+ oldObjectInstance.get(fieldName) ;
Note newNote = new Note(IsPrivate=false,ParentId=newObjectInstance.Id,Body=nodeBody,Title=nodeTitle);
noteList.add(newNote);
}
}
}
}
// if added in list inserting the recod
if(noteList.size() > 0){
try{
insert noteList;
}
catch(Exception e){ System.debug('Error while inserting Note : ' + e.getMessage()); }
}
}
}
}
Here is the custom solution how you can achieve the custom history tracking
Create a custom setting which will hold the sobject name and field to be tracked . Changes will be stored as a note to the parent record you may create a custom object if you want
Invocation on Account Object
/**
* This is the trigger to capture the changes made in long text area
**/
trigger AccountHistoryTrigger on Account (after update) {
//checking the conditions. Target org may have existing trigger
if(TRIGGER.isAfter && TRIGGER.isUpdate){
HistoryTrackingHandler handler = new HistoryTrackingHandler();
handler.checkAndCreateNote(Trigger.newMap,Trigger.oldMap,'Account');
}
}
Handler class
/**
* This class is the handler for the triggers on the sobjects those want to track values
**/
public class HistoryTrackingHandler{
/**
* This method will take the new map and old map along with the Sobject name
* and comapre the values present in the custom setting for the Sobject
* If any values found then it will insert a note with al the changes
**/
public void checkAndCreateNote(Map<Id,Sobject> newMapValues, Map<Id,Sobject> oldMapValues,String sobj){
/**
* Checking if the custom setting value exists
* input newMap,oldMap, Api name of the Sobject
**/
if(LongTextAreaFieldstoTrack__c.getInstance(sobj)<> NULL && LongTextAreaFieldstoTrack__c.getInstance(sobj).Field__c <> NULL && LongTextAreaFieldstoTrack__c.getInstance(sobj).Field__c.trim() <> '' && LongTextAreaFieldstoTrack__c.getInstance(sobj).Active__c == TRUE){
// getting the values from the custom setting
String selectedFields = LongTextAreaFieldstoTrack__c.getInstance(sobj).Field__c;
List<Note> noteList = new List<Note>(); // creating a list to insert notes
Map<String, Schema.SObjectType> gd = Schema.getGlobalDescribe();
Schema.SobjectType oType = gd.get(sobj); // getting the object type in runtime
// getting all the fields at runtime
Map <String, Schema.SObjectField> fieldMap = Schema.getGlobalDescribe().get(sobj).getDescribe().fields.getMap();
//Iterate through the loop and check for the field if the field present in the custom setting
//and the values are modified then create a note record for per transction for each record
for(Sobject currentSobj : newMapValues.values()){
sObject newObjectInstance = oType.newSObject(); // will hold new instance
sObject oldObjectInstance = oType.newSObject(); // will hold old instance
newObjectInstance = currentSobj; // getting the new instance
oldObjectInstance= oldMapValues.get(currentSobj.Id); // getting the old values
for (String fieldName : fieldMap.keyset()) {
if(selectedFields.containsIgnoreCase(fieldName)){// checking if present in the custom setting or not
if(newObjectInstance.get(fieldName) != oldObjectInstance.get(fieldName) && oldObjectInstance.get(fieldName) <> NULL){
String nodeTitle = ''+ fieldName + ' has been changed by ' + userInfo.getName() + ' at ' + System.now();
//value has been changed, so append in the body
String nodeBody = 'Old value was \n'+ oldObjectInstance.get(fieldName) ;
Note newNote = new Note(IsPrivate=false,ParentId=newObjectInstance.Id,Body=nodeBody,Title=nodeTitle);
noteList.add(newNote);
}
}
}
}
// if added in list inserting the recod
if(noteList.size() > 0){
try{
insert noteList;
}
catch(Exception e){ System.debug('Error while inserting Note : ' + e.getMessage()); }
}
}
}
}



No comments:
Post a Comment