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
isalewisalew 

Display Last Activity Subject on Lead Object

SF Admin new to Apex.

 

I am trying to create a field on the Lead object (and eventually contact/account objects) to display the subject field from the last activity. I have already figured out how to display the last activity date, but I'm stuck on how to display the last activity subject. The field should pull from both Task & Event records.

 

Any suggestions?

Best Answer chosen by Admin (Salesforce Developers) 
isalewisalew

Thank you for your help, Tim. You sent me in the right direction. I played with the code some more and found a working solution:

 

public with sharing class LeadLastActivitySubject {
    
    public static String ldPrefix =  Lead.sObjectType.getDescribe().getKeyPrefix();
    
    public static void updateLeadLastActivitySubject(Set<ID> leadIds){

        //Query all Leads and task-event child relationships
        List<Lead> Leads = [SELECT Id, LastActivityDate, Last_Activity_Subject__c,
            (SELECT Id, WhoId, Subject, ActivityDate FROM Tasks order by ActivityDate Desc limit 1),
            (SELECT Id, WhoId, Subject, ActivityDate FROM Events order by ActivityDate Desc limit 1)
            FROM Lead WHERE ID IN :leadIds];
        
        List<Lead> updateLeads = new List<Lead>();

        //LOGIC to determine most recent task or event and update Lead.Last_Activity_Subject__c field

    for (Lead l : Leads) {

        Integer count = l.Tasks.size() + l.Events.size();

        if (count != 0) {

            for (Event e : l.Events){
                if (l.LastActivityDate <= e.ActivityDate) {
                    l.Last_Activity_Subject__c = e.subject;
                }
            }

            for (Task t : l.Tasks){
                if (l.LastActivityDate <= t.ActivityDate) {
                    l.Last_Activity_Subject__c = t.subject;
                }
            }

        } else {
            l.Last_Activity_Subject__c = null;
        }

        updateLeads.add(l);
    }

  
        if(updateLeads.size()>0) {
            try{
                update updateLeads;
            }
                catch (Exception e) {
            }
        }
}
}

 

All Answers

isalewisalew

Here is my Apex so far. Could be totally off. I borrowed heavily from this post:

http://www.radialweb.com/2010/08/summarizing_salesforce_fields_with_triggers/

 

Areas where I have no idea where to go are noted with the word LOGIC.

 

//------------------------------------------------------------------------------------------------

//Apex Class

//------------------------------------------------------------------------------------------------

 

public with sharing class LeadLastActivitySubject {

 

    public static String ldPrefix =  Lead.sObjectType.getDescribe().getKeyPrefix();

 

public static void updateLeadLastActivitySubject(Set<ID> leadIds){

 

//Query all Leads and task-event child relationships

        List<Lead> Leads = [SELECT Id, Last_Activity_Subject__c, (SELECT Id, Subject, ActivityDate FROM Tasks order by ActivityDate Desc limit 1), (SELECT Id, Subject, ActivityDate FROM Events order by ActivityDate Desc limit 1) FROM Lead WHERE ID IN :leadIds]

        List<Lead> updateLeads = new List<Lead>();

 

for (Lead l : Leads) {

//LOGIC to determine most recent task or event and update Lead.Last_Activity_Subject__c field

}

 

try {

update updateLeads;

}

catch (Exception e) {

}

}

}

 

//------------------------------------------------------------------------------------------------

//Apex Task Trigger

//------------------------------------------------------------------------------------------------

 

trigger TaskUpdateLeadLastActivitySubject on Task (after delete, after insert, after undelete, after update) {

 

Set<ID> ldIds = new Set<ID>();

//Isolate Tasks linked to leads

String prefix = LeadLastActivitySubject.ldPrefix;

 

//Adds lead ids coming from new data

    if (Trigger.new != null) {

        for (Task t : Trigger.new) {

            if (t.WhoId != null && String.valueOf(t.whoId).startsWith(prefix) ) {

                ldIds.add(t.whoId);

            }

        }

    }

 

    //Adds lead ids coming from old data (deletes, moving an activity from one lead to another)

    if (Trigger.old != null) {

        for (Task t : Trigger.old) {

            if (t.WhoId != null && String.valueOf(t.whoId).startsWith(prefix) ) {

                ldIds.add(t.whoId);

            }

        }

    }

 

//LOGIC MAY BE WRONG HERE

if (ldIds.size() > 0)

LeadLastActivitySubject.updateLeadLastActivitySubject(ldIds);

 

}

 

 

//------------------------------------------------------------------------------------------------

//Apex Event Trigger

//------------------------------------------------------------------------------------------------

 

trigger EventUpdateLeadLastActivitySubject on Event (after delete, after insert, after undelete, after update) {

 

    Set<ID> ldIds = new Set<ID>();

 

//Isolate Events linked to leads

    String prefix = LeadActivityCount.ldPrefix;

 

    //Adds lead ids coming from new data

    if (Trigger.new != null) {

        for (Event e : Trigger.new) {

            if (e.WhoId != null && String.valueOf(e.whoId).startsWith(prefix) ) {

                ldIds.add(e.whoId);

            }

        }

    }

 

    //Adds lead ids coming from old data (deletes, moving an activity from one opportunity to another)

    if (Trigger.old != null) {

        for (Event e : Trigger.old) {

            if (e.WhoId != null && String.valueOf(e.whoId).startsWith(prefix) ) {

                ldIds.add(e.whoId);

            }

        }

    }

 

//LOGIC MAY BE WRONG HERE

if (ldIds.size() > 0)

LeadLastActivitySubject.updateLeadLastActivitySubject(ldIds);

}

 

Tim BarsottiTim Barsotti

I think you are looking for how to iterate through child objects from your SOQL query. Hope the below snippet helps.

 

for (Lead l : Leads) {
    for(Task t: l.Tasks){
        l.YOUR_CUSTOM_FIELD__c = t.subject;
    }
    updateLeads.add(l);
}
 
if(updateLeads.size()>0) {
    try{
        update updateLeads;
    }
        catch (Exception e) {
    }
}

 

 

isalewisalew

Thank you Tim, that helps, but I'm trying to go one step further, to compare the date and event activity dates so the latest task or event will display. I tried to adapt your code, but my adaptation didn't work.

 

Any suggestions regarding comparative logic?

 

    for (Lead l : Leads) {
        for(Event e : l.Events){
            for(Task t : l.Tasks){
                    if(t.activitydate >= e.activitydate){
                        l.Last_Activity_Subject__c = t.subject;
                    } else {
                        l.Last_Activity_Subject__c = e.subject;                     
                    }
            }
        }
        updateLeads.add(l);
    }

 

isalewisalew

Thank you for your help, Tim. You sent me in the right direction. I played with the code some more and found a working solution:

 

public with sharing class LeadLastActivitySubject {
    
    public static String ldPrefix =  Lead.sObjectType.getDescribe().getKeyPrefix();
    
    public static void updateLeadLastActivitySubject(Set<ID> leadIds){

        //Query all Leads and task-event child relationships
        List<Lead> Leads = [SELECT Id, LastActivityDate, Last_Activity_Subject__c,
            (SELECT Id, WhoId, Subject, ActivityDate FROM Tasks order by ActivityDate Desc limit 1),
            (SELECT Id, WhoId, Subject, ActivityDate FROM Events order by ActivityDate Desc limit 1)
            FROM Lead WHERE ID IN :leadIds];
        
        List<Lead> updateLeads = new List<Lead>();

        //LOGIC to determine most recent task or event and update Lead.Last_Activity_Subject__c field

    for (Lead l : Leads) {

        Integer count = l.Tasks.size() + l.Events.size();

        if (count != 0) {

            for (Event e : l.Events){
                if (l.LastActivityDate <= e.ActivityDate) {
                    l.Last_Activity_Subject__c = e.subject;
                }
            }

            for (Task t : l.Tasks){
                if (l.LastActivityDate <= t.ActivityDate) {
                    l.Last_Activity_Subject__c = t.subject;
                }
            }

        } else {
            l.Last_Activity_Subject__c = null;
        }

        updateLeads.add(l);
    }

  
        if(updateLeads.size()>0) {
            try{
                update updateLeads;
            }
                catch (Exception e) {
            }
        }
}
}

 

This was selected as the best answer
flor1anflor1an

first of all thanks ilewi

but this still doesnt work for me, did u change somtehing else? e.g. in the trigger? The customfield Last_Activity_Subject_c ist Type text, isn't it?

 

isalewisalew

Hello flor1an,

 

Yes, I modified the class. Here is the code I developed for the activity subject & date. The trigger should be the same, with some changes to variable/class names.

 

public with sharing class TP_Activities {
    
    public static String ldPrefix =  Lead.sObjectType.getDescribe().getKeyPrefix();
    
    public static void updateActivities(Set<ID> leadIds){

        //Queries all Leads and task-event child relationships
        List<Lead> Leads = [SELECT
			Id, 
			CreatedDate, 
			LastActivityDate, 
			TP_Last_Closed_Activity_Subject__c, 
			TP_Last_Closed_Activity_Date__c, 
			TP_Next_Planned_Activity_Subject__c, 
			TP_Next_Planned_Activity_Date__c,
            (SELECT Id, WhoId, Subject, ActivityDate, IsClosed FROM Tasks order by ActivityDate Desc),
            (SELECT Id, WhoId, Subject, EndDateTime FROM Events order by EndDateTime Desc)
            FROM Lead WHERE ID IN :leadIds];
        
        List<Lead> updateLeads = new List<Lead>();

        for (Lead l : Leads) {
    
			//Prepares comparison variables
            String LastActivitySubject = null;
            Date LastActivityDate = null;
            String NextActivitySubject = null;
            Date NextActivityDate = null;
            Date CreatedDate = date.newinstance(l.CreatedDate.year(),l.CreatedDate.month(),l.CreatedDate.day());

			//Only runs for leads with tasks or events
            if (TotalCount != 0) {
                for (Event E : l.Events) {
                    Date EndDate = date.newinstance(e.EndDateTime.year(),e.EndDateTime.month(),e.EndDateTime.day());
                    
                    //Logic for completed events
                    if (EndDate <= date.today()){

                        //Compares event with last activity
                        if (EndDate >= LastActivityDate || LastActivityDate == null) {
                            LastActivitySubject = e.subject;
                            LastActivityDate = EndDate;
                        }

                    } else {

                        //Compares event with next activity
                        if (EndDate <= NextActivityDate || NextActivityDate == null) {
                            NextActivitySubject = e.Subject;
                            NextActivityDate = EndDate;
                        }
                    }
                }

                for (Task T : l.Tasks) {

                    Date ActivityDate = null;
                    
                    if (t.ActivityDate != null) {
	                    ActivityDate = date.newinstance(t.ActivityDate.year(),t.ActivityDate.month(),t.ActivityDate.day());                    
                    }

                    //Logic for completed tasks
                    if (t.IsClosed == TRUE) {

                        //Compares task with last activity
                        if (LastActivityDate == null || ActivityDate >= LastActivityDate) {
                            LastActivitySubject = t.subject;
                            LastActivityDate = ActivityDate;
                        }
                    } else {

                        //Compares task with next activity
                        if (NextActivityDate == null || ActivityDate <= NextActivityDate) {
                            NextActivitySubject = t.Subject;
                            NextActivityDate = ActivityDate;
                        }
                    }
                }
                
                //Updates lead fields to match updated variables
                if (
                    l.TP_Last_Closed_Activity_Subject__c != LastActivitySubject ||
                    l.TP_Last_Closed_Activity_Date__c != LastActivityDate ||
                    l.TP_Next_Planned_Activity_Subject__c != NextActivitySubject ||
                    l.TP_Next_Planned_Activity_Date__c != NextActivityDate
                    ){
                        l.TP_Last_Closed_Activity_Subject__c = LastActivitySubject;
                        l.TP_Last_Closed_Activity_Date__c = LastActivityDate;
                        l.TP_Next_Planned_Activity_Subject__c = NextActivitySubject;
                        l.TP_Next_Planned_Activity_Date__c = NextActivityDate;
                        updateLeads.add(l);
                    }
            } else {
                //Updates lead fields if there is no activity
                l.TP_Last_Closed_Activity_Subject__c = 'Lead Created';
                l.TP_Last_Closed_Activity_Date__c = CreatedDate;
                l.TP_Next_Planned_Activity_Subject__c = NextActivitySubject;
                l.TP_Next_Planned_Activity_Date__c = NextActivityDate;
		        updateLeads.add(l);  
            }
        }

        //Commits the changes
        if(updateLeads.size()>0) {
            try{
                update updateLeads;
            }
                catch (Exception e) {
            }
        }
    }
}

 

 

 

flor1anflor1an

Thanks for your answer! But i'm afrais to say it still doesn't work for me..  I'm just interested in the subject of the Activity, so the "old trigger" you posted in the beginning still should work i guess, but it doesnt -.-

could you maybe check the trigger once again?

Thank you very much so far...

isalewisalew

Sorry to hear it's not working flor1an. I'm not sure how to help without knowing the nature of your problem. Did the developer console give you any error messages that might indicate why it's not working?

 

I should mention that the code I displayed is cut from a larger project, so will not work with just cut-and-paste. You will need to adapt it to fit your project.

Dhairya MistryDhairya Mistry
Hi ilewi,

I am Admin and new to coding. I have created similar scenario in my org and using your Oct 15, 2013 code you posted. I am getting an error at line 32 "Variable does not exist: TotalCount". Where should I declare that variable? I also wanted to know after the Apex class is created, can I use the task and event triggers you have mentioned in inital question?