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
Ed055Ed055 

help with apex and soql

Hi all  -  I need help with apex and soql
Account object has a custom date field called "Last followup"
I would like to update this field on insert/edit/update/delete of CONTACT. I have a contact trigger and "Last followup" needs to be updated in this trigger
"Last followup" field on account object should be updated with  MAX of  ActivityDate field FROM  ActivityHistories object.of all contacts tied to that account.. As per my understanding, ActivityHistories  records can only be queried as a subquery.

Thanks for help


 
Best Answer chosen by Ed055
Nayana KNayana K
public class ContactHandler
{
    public ContactHandler()
    {
    }
    
    public void onAfterInsert(List<Contact> lstNewCon)
    {
        populateLastFollowup(lstNewCon);
    }
    
    public void onAfterUpdate(List<Contact> lstNewCon)
    {
        populateLastFollowup(lstNewCon);
    }
    
    public void onAfterDelete(List<Contact> lstOldCon)
    {
        populateLastFollowup(lstOldCon);
    }
    
    public void onAfterUnDelete(List<Contact> lstNewCon)
    {
        populateLastFollowup(lstNewCon);
    }
    
    private void populateLastFollowup(List<Contact> lstCon)
    {
        Set<Id> setIdAcc = new Set<Id>();
        Map<Id, Date> mapAccIdToDate = new Map<Id, Date>();
        Map<Id, Account> mapAccWithOriginalDate = new Map<Id, Account>();
        Date dt;
        for(Contact objCon : lstCon)
        {
            setIdAcc.addAll(objCon.AccountId);
        }
        setIdAcc.remove(NULL);
        
        if(!setIdAcc.isEmpty())
        for(Contact objCon : [SELECT Id, AccountId, Account.LastFollowup__c, 
                                (SELECT ActivityDate 
                                FROM ActivityHistories 
                                ORDER BY ActivityDate DESC NULLS LAST, LastModifiedDate DESC 
                                LIMIT 1)
                             FROM Contact
                             WHERE AccountId IN: setIdAcc
                                ])
        {
            if(!mapAccIdToOriginalDate.containsKey(objCon.AccountId))
            {
                mapAccIdToOriginalDate.put(objCon.AccountId, new Account(Id = objCon.AccountId, LastFollowup__c = objCon.Account.LastFollowup__c));
            }
            dt = NULL;
            if(!objCon.ActivityHistories.isEmpty())
            {
                dt = objCon.ActivityHistories[0].ActivityDate;
            }
            
            if(dt != NULL)
            if((mapAcc.containsKey(objCon.AccountId) && dt > mapAcc.containsKey(objCon.AccountId)) ||  !mapAcc.containsKey(objCon.AccountId))
            {
                mapAccIdToDate.put(objCon.AccountId, dt);
            }
        }
        
        /* if an account has already set with same LastFollowup__c, then stop updating it [=> Avoiding unnecessary update on account*/
        for(Id idAcc : mapAccIdToOriginalDate.keySet())
        {
            if(mapAcc.containsKey(idAcc))
            {
                if(mapAccIdToOriginalDate.get(idAcc).LastFollowup__c != mapAcc.get(idAcc))
                {
                    mapAccIdToOriginalDate.get(idAcc).LastFollowup__c = mapAcc.get(idAcc);
                }
                else
                {
                    mapAccIdToOriginalDate.remove(idAcc);
                }
            }
            else
            {
                if(mapAccIdToOriginalDate.get(idAcc).LastFollowup__c == NULL)
                {
                    mapAccIdToOriginalDate.remove(idAcc);
                }
            }
        }
        if(!mapAccIdToOriginalDate.isEmpty())
        {
            update mapAccIdToOriginalDate.values();
        }
    }
}


 
trigger ContactTrigger on Contact(after insert, after delete, after update, after undelete)
{
	ContactHandler objHandler = new ContactHandler();
	if(Trigger.isAfter)
	{
		if(Trigger.isInsert)
		{
			objHandler.onAfterInsert(Trigger.new);
		}
		else if(Trigger.isUpdate)
		{
			objHandler.onAfterUpdate(Trigger.new);
		}
		else if(Trigger.isDelete)
		{
			objHandler.onAfterDelete(Trigger.old);
		}
		else if(Trigger.isUndelete)
		{
			objHandler.onAfterUnDelete(Trigger.new);
		}
	}
}
If it helps, please mark this as solved.
 

All Answers

Nayana KNayana K
public class ContactHandler
{
    public ContactHandler()
    {
    }
    
    public void onAfterInsert(List<Contact> lstNewCon)
    {
        populateLastFollowup(lstNewCon);
    }
    
    public void onAfterUpdate(List<Contact> lstNewCon)
    {
        populateLastFollowup(lstNewCon);
    }
    
    public void onAfterDelete(List<Contact> lstOldCon)
    {
        populateLastFollowup(lstOldCon);
    }
    
    public void onAfterUnDelete(List<Contact> lstNewCon)
    {
        populateLastFollowup(lstNewCon);
    }
    
    private void populateLastFollowup(List<Contact> lstCon)
    {
        Set<Id> setIdAcc = new Set<Id>();
        Map<Id, Date> mapAccIdToDate = new Map<Id, Date>();
        Map<Id, Account> mapAccWithOriginalDate = new Map<Id, Account>();
        Date dt;
        for(Contact objCon : lstCon)
        {
            setIdAcc.addAll(objCon.AccountId);
        }
        setIdAcc.remove(NULL);
        
        if(!setIdAcc.isEmpty())
        for(Contact objCon : [SELECT Id, AccountId, Account.LastFollowup__c, 
                                (SELECT ActivityDate 
                                FROM ActivityHistories 
                                ORDER BY ActivityDate DESC NULLS LAST, LastModifiedDate DESC 
                                LIMIT 1)
                             FROM Contact
                             WHERE AccountId IN: setIdAcc
                                ])
        {
            if(!mapAccIdToOriginalDate.containsKey(objCon.AccountId))
            {
                mapAccIdToOriginalDate.put(objCon.AccountId, new Account(Id = objCon.AccountId, LastFollowup__c = objCon.Account.LastFollowup__c));
            }
            dt = NULL;
            if(!objCon.ActivityHistories.isEmpty())
            {
                dt = objCon.ActivityHistories[0].ActivityDate;
            }
            
            if(dt != NULL)
            if((mapAcc.containsKey(objCon.AccountId) && dt > mapAcc.containsKey(objCon.AccountId)) ||  !mapAcc.containsKey(objCon.AccountId))
            {
                mapAccIdToDate.put(objCon.AccountId, dt);
            }
        }
        
        /* if an account has already set with same LastFollowup__c, then stop updating it [=> Avoiding unnecessary update on account*/
        for(Id idAcc : mapAccIdToOriginalDate.keySet())
        {
            if(mapAcc.containsKey(idAcc))
            {
                if(mapAccIdToOriginalDate.get(idAcc).LastFollowup__c != mapAcc.get(idAcc))
                {
                    mapAccIdToOriginalDate.get(idAcc).LastFollowup__c = mapAcc.get(idAcc);
                }
                else
                {
                    mapAccIdToOriginalDate.remove(idAcc);
                }
            }
            else
            {
                if(mapAccIdToOriginalDate.get(idAcc).LastFollowup__c == NULL)
                {
                    mapAccIdToOriginalDate.remove(idAcc);
                }
            }
        }
        if(!mapAccIdToOriginalDate.isEmpty())
        {
            update mapAccIdToOriginalDate.values();
        }
    }
}


 
trigger ContactTrigger on Contact(after insert, after delete, after update, after undelete)
{
	ContactHandler objHandler = new ContactHandler();
	if(Trigger.isAfter)
	{
		if(Trigger.isInsert)
		{
			objHandler.onAfterInsert(Trigger.new);
		}
		else if(Trigger.isUpdate)
		{
			objHandler.onAfterUpdate(Trigger.new);
		}
		else if(Trigger.isDelete)
		{
			objHandler.onAfterDelete(Trigger.old);
		}
		else if(Trigger.isUndelete)
		{
			objHandler.onAfterUnDelete(Trigger.new);
		}
	}
}
If it helps, please mark this as solved.
 
This was selected as the best answer
Ed055Ed055
Thanks Nayana for your help. 
Nayana KNayana K
Most welcome  :)