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
karthikeya 2karthikeya 2 

How to get old values and new vales in Apex class when field changes.

Hi All,

I need to send email when the filed is changed to the record owner with old values and new value in the template.
It should be a class with out using trigger.
Can any one provide with the code.

Thanks in advance.
NagendraNagendra (Salesforce Developers) 
Hi Karthikeya,

May I suggest you please find the below explanation with a similar requirement.

Below is a gist
(https://gist.github.com/brianmfear/b147b7eca2ff7bb2736635cd3bef4e17) that demonstrates how to detect changes from between when the page loads and the edits a user makes. The main feature is that you need to clone the original object, and then you can compare the differences in your save method.
public class UpdateChangedFieldsController {
    SObject oldRecord, currentRecord;
    public UpdateChangedFieldsController(ApexPages.StandardController controller) {
        oldRecord = controller.getRecord().clone();
        currentRecord = controller.getRecord();
    }
    public PageReference saveChanges() {
        SObject newClone = currentRecord.getSObjectType().newSObject(currentRecord.Id);
        Map<String, Object> 
            oldValues = oldRecord.getPopulatedFieldsAsMap(),
            newValues = currentRecord.getPopulatedFieldsAsMap();
        for(String key: newValues.keySet()) {
            if(newValues.get(key) != oldValues.get(key)) {
                newClone.put(key, newValues.get(key));
            }
        }
        try {
            upsert newClone;
            return new ApexPages.StandardController(newClone).view();
        } catch(Exception e) {
            return null;
        }
    }
}
The above code primarily demonstrates how a single record could be loaded by two different users, and each could edit separate field values without clobbering each other's edits. Realistically, I'd expect some modification to be required for other purposes, such as the OP, but the concept is similar.

Hope this helps.

Please mark this as solved if the information helps so that it gets removed from the unanswered queue which results in helping others who are encountering a similar issue.

Thanks,
Nagendra

 
Rahul KumarRahul Kumar (Salesforce Developers) 
Hi Karthikeya,

This trigger is designed to send an email when a field is changed...You just have to change the object and field names, I will highlight the important bits. It works by getting triggered when a field is changed and then uses an email handler to send the email.

Email handler class:
public class EmailHandler{


      //ClientPath Emails
      public static void sendTriggerEmail (List<String> contactids){
     
        Messaging.MassEmailMessage mail = new Messaging.MassEmailMessage();
        //set the email properties
        mail.setTargetObjectIds(contactids);
        mail.setSenderDisplayName('Your company customer service'); //change to whatever
        mail.setTemplateId('00X90000001F79Z'); //Id of the Email Template
     
        //send the email
        Messaging.sendEmail (new Messaging.MassEmailMessage[] { mail } );
        }
     
        
}

 Trigger:
trigger SendEmailtocontact on Service__c (after Update)
{
    List<String> lcontactEmails = new List<String>();
    Set<Id> sIds = new Set<Id>();
//Added
    Set<ID> accIds = new Set<ID>();
    for(Service__c qItr : Trigger.new)
{
        if(Trigger.isUpdate)
  {
 <strong>           if(Trigger.oldmap.get(qItr.id).Last_Email_Sent__c!= qItr.Last_Email_Sent__c ) //basically says that if this field is changed it will trigger the trigger</strong>
   {
                sIds.add(qItr.id);
    //Added
    accIds.add(qItr.Account__c);
            }
        }
  //Will Never Execute as trigger will fire only if a record is updated
        else if(Trigger.isInsert)
  {
           
                sIds.add(qItr.id);
            
        }
    }
// Modified
    //for(Account accItr : [SELECT id,(SELECT id FROM Contacts) FROM Account WHERE id IN (SELECT Account__c FROM Service__c WHERE Id IN: sIds)])
for(Account accItr : [SELECT id,(SELECT id FROM Contacts) FROM Account WHERE id IN : accIds])
{
        for(Contact con : accItr.contacts)
  {
            if(!String.isBlank(con.id))
   {
                lcontactEmails.add(con.id);
            }
        }
       // No need to put this condition here.
  /*if(!lcontactEmails.isEmpty())
  {
   EmailHandler.sendEmail(lcontactEmails);
  }*/   
    }
//Put this here
if(!lcontactEmails.isEmpty())
{
for(Service__c serv : Trigger.new)
{        
       <strong> //Email handler Updated
        if(Serv.Last_Email_Sent__c == 'IPC Support Expiry') //Set critera if statement..Add others to set different emails based on different criteria
        {
        EmailHandler.sendTriggerEmail(lcontactEmails);
        }</strong>

}   
}
}
hope it helps.

Please mark it as best answer if the information is informative.

Thanks
Rahul Kumar