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
Stephanie Holt 2Stephanie Holt 2 

How do I "Comment Out" an entire Apex Class?

Sorry for the really long post, but I am a struggling solo admin trying to make sense of some Apex. I have been getting a lot of errors with various (VERY SIMPLE) process builders, and at Salesforce World Tour Boston, some developers suggested that it may be causing some sort of loop with an existing trigger/Apex in our instance. (I'm getting the "Too many SOQL queries" errors very often, mostly with bulk lead imports). 

We have quite a few managed packages, but only 2 triggers, and 3 Apex classes that were created in-house by a consultant before I started at my company. I have documentation on what exactly it does, and we are willing to remove the functionality that these perform, and just want to get rid of them. 

I tried deactivating the 2 triggers in sandbox and push them to production but got many test failures. So I assumed that I also need to do something with the Apex classes, and found the suggestion to "comment out" the entire thing on another post here in the community.

So my question is how to do that. I tried adding /* at the very beggining and */ at the end, but that gave me the error below. Any help would be GREATLY appreciated. I'm looking forward to learning some of this stuff on my own, but we need to get this done ASAP. 

Best,
Steph

User-added image

And here are the specifics of the Trigger and Apex class code if that is helpful:

EventTrigger 
trigger EventTrigger on Event (after insert, after update) {

    EventTriggerHandler handler = new EventTriggerHandler();

    if (Trigger.isAfter && Trigger.isInsert) {
        handler.afterInsert(Trigger.new);
    } else if (Trigger.isAfter && Trigger.isUpdate) {
        handler.afterUpdate(Trigger.oldMap, Trigger.newMap, Trigger.new);
    }

}

TaskTrigger:
trigger TaskTrigger on Task (after insert, after update) {

    TaskTriggerHandler handler = new TaskTriggerHandler();

    if (Trigger.isAfter && Trigger.isInsert) {
        handler.afterInsert(Trigger.new);
    } else if (Trigger.isAfter && Trigger.isUpdate) {
        handler.afterUpdate(Trigger.oldMap, Trigger.newMap, Trigger.new);
    }

}

ProsepctManagement (Apex Class)
public with sharing class ProspectManagement {

    public static final Set<String> SALES_TASK_TYPES = new Set<String> {
        'Call', 'Email - Sent', 'Email - Opened', 'Email - Clicked', 'Other'
    };

    public static final Set<String> SALES_EVENT_TYPES = new Set<String>{
        'Scheduled Call - Sales', 'Demo', 'Scheduled Call - Cust Success', 'In-person Meeting', 'Other'
    };
    
    private final DateTime NOW;
    private Map<ID, Lead> leads;
    private Map<ID, Contact> contacts;
    
    public ProspectManagement(Set<ID> entityIds) {
        this.leads = this.getLeads(entityIds);
        this.contacts = this.getContacts(entityIds);
        NOW = DateTime.now();
    }
    
    public ProspectManagement(Map<ID, Lead> leads, Map<ID, Contact> contacts) {
        this.leads = leads;
        this.contacts = contacts;
        NOW = DateTime.now();
    }
    
    public Map<ID, Lead> getLeads() {
        return this.leads;
    }
    
    public Map<ID, Contact> getContacts() {
        return this.contacts;
    }
    
    private Map<ID, Lead> getLeads(Set<ID> leadIds) {
        return new Map<ID, Lead>([
            SELECT Id, First_Connect_Date__c, First_Connect_Touch__c, First_Sales_Activity_Date__c,
                Total_Completed_Touches__c
            FROM Lead
            WHERE Id IN :leadIds
        ]);
    }
    
    private Map<ID, Contact> getContacts(Set<ID> contactIds) {
        return new Map<ID, Contact>([
            SELECT Id, First_Connect_Date__c, First_Connect_Touch__c, First_Sales_Activity_Date__c,
                Total_Completed_Touches__c, AccountId
            FROM Contact
            WHERE Id IN :contactIds
        ]);
    }
    
    /**
     * Updates the First_Sales_Activity_Date__c field to now if it wasn't previously set.
     */
    public void updateFirstSalesActivityDateTime(ID entityId) {    
        if (entityId.getSObjectType() == Contact.SObjectType && 
            this.contacts.get(entityId).First_Sales_Activity_Date__c == null) {
            Contact c = this.contacts.get(entityId);
            if (c.First_Sales_Activity_Date__c == null) {
                c.First_Sales_Activity_Date__c = DateTime.now();
            }
        } else if (entityId.getSObjectType() == Lead.SObjectType && 
            this.leads.get(entityId).First_Sales_Activity_Date__c == null) {
            Lead l = leads.get(entityId);
            if (l.First_Sales_Activity_Date__c == null) {
                l.First_Sales_Activity_Date__c = DateTime.now();
            }
        }    
    }
    
    /**
     * Updates leads and contacts, the IDs of which are in entityIds, such that Last_Contacted_Date__c is now.
     * If a Contact has an Account, the Last_Contacted_Date__c field on the Account is also updated.
     * THIS METHOD EXECUTES A DML STATEMENT.
     */
    public void updateLastContactedDate(Set<ID> entityIds) {
        System.debug('Entity IDs: ' + entityIds);
        Set<ID> accountIds = new Set<ID>();
        for (ID entityId: entityIds) {
            if (this.leads.containsKey(entityId)) {
                System.debug('upating lead ' + entityId);
                this.leads.get(entityId).Last_Contacted_Date__c = NOW;
            } else if (this.contacts.containsKey(entityId)) {
                this.contacts.get(entityId).Last_Contacted_Date__c = NOW;
                System.debug('updating contact ' + entityId);
                if (this.contacts.get(entityId).AccountId != null) {
                    accountIds.add(this.contacts.get(entityId).AccountId);
                }
            }
        }
        System.debug('Account IDs: ' + accountIds);
        
        List<Account> accounts = [SELECT Id, Last_Contacted_Date__c FROM Account WHERE Id in :accountIds];
        for (Account a: accounts) {
            a.Last_Contacted_Date__c = NOW;
        }
        
        update accounts;
    }
    
    /**
     * Updates Total_Completed_Touches__c on Leads and Contacts if the ID is contained in entityIds.
     */
    public void updateTotalCompletedTouches(Set<ID> entityIds) {       
        List<AggregateResult> countsPerEntity =([
            SELECT Who.Id entityId, Count(ID)
            FROM Task
            WHERE Cancelled__c = false AND
                Status = 'Completed' AND
                Type IN :SALES_TASK_TYPES AND
                Who.Id IN :entityIds
            GROUP BY Who.Id
        ]);
        countsPerEntity.addAll([
            Select Who.Id entityId, Count(ID)
            FROM Event
            WHERE Cancelled__c = false AND
                StartDateTime <= :now AND
                Type IN :SALES_EVENT_TYPES AND
                Who.Id in :entityIds
            GROUP BY Who.Id
        ]);
        
        Set<ID> entitiesTouched = new Set<ID>();
        for (AggregateResult result: countsPerEntity) {
            ID entityId = (ID) result.get('entityId');
            Integer count = Integer.valueOf(result.get('expr0'));
            if (entityId.getSObjectType() == Contact.SObjectType) {
                Contact c = contacts.get(entityId);
                if (entitiesTouched.contains(entityId)) {
                    c.Total_Completed_Touches__c += count;
                } else {
                    c.Total_Completed_Touches__c = count;
                    entitiesTouched.add(entityId);
                }
            } else if (entityId.getSObjectType() == Lead.SObjectType) {
                Lead l = leads.get(entityId);
                if (entitiesTouched.contains(entityId)) {
                    l.Total_Completed_Touches__c += count;
                } else {
                    l.Total_Completed_Touches__c = count;
                    entitiesTouched.add(entityId);
                }
            }
        }
    }
    
    /**
     * entityIds is a set of IDs of Contacts and Leads associated with a Task where First_Connect__c is set to true.
     */
    public void updateFirstConnectInfo(Set<ID> entityIds) {
        // Count matching tasks and events, and group by the Who.Id
        
        // TODO: Comments from Maggie say we should account for this on a PER ENTITY basis, where we basically have to
        // replay all tasks and events to figure out when the earliest task or event labeled first_connect exists.
        
        // Get eligible leads and contacts associated with the First_Contact__c tasks.
        
        Set<ID> allIds = new Set<ID>();
        // Filter out any entity ids where we've already connected for the first time.
        for (ID leadId: this.leads.keySet()) {
            Lead l = this.leads.get(leadId);
            if (l.First_Connect_Date__c == null && l.First_Connect_Touch__c == null && entityIds.contains(leadId)) {
                allIds.add(leadId);
            }
        }
        for (ID contactId: this.contacts.keySet()) {
            Contact c = this.contacts.get(contactId);
            if (c.First_Connect_Date__c == null & c.First_Connect_Touch__c == null && entityIds.contains(contactId)) {
                allIds.add(contactId);
            }
        }
        
        List<AggregateResult> countPerEntity = [
            SELECT Who.Id entityId, Count(ID)
            FROM Task
            WHERE Cancelled__c = false AND
                Status = 'Completed' AND
                Type IN :SALES_TASK_TYPES AND
                Who.Id IN :allIds
            GROUP BY Who.Id
        ];
        countPerEntity.addAll([
            Select Who.Id entityId, Count(ID)
            FROM Event
            WHERE Cancelled__c = false AND
                StartDateTime <= :now AND
                Type IN :SALES_EVENT_TYPES AND
                Who.Id in :allIds
            GROUP BY Who.Id
        ]);

        // Since there may be two AggregateResults per WhoId, acknowledge when we've SET the value, so next time
        // We increment the value instead.
        Set<ID> entitiesTouched = new Set<ID>();
        for (AggregateResult entityTasks: countPerEntity) {
            ID entityId = (ID) entityTasks.get('entityId');
            Integer count = Integer.valueOf(entityTasks.get('expr0'));
            if (leads.containsKey(entityId)) {
                Lead l = leads.get(entityId);
                if (entitiesTouched.contains(entityId)) {
                    l.First_Connect_Touch__c += count;
                } else {
                    l.First_Connect_Touch__c = count;
                    l.First_Connect_Date__c = now;
                    entitiesTouched.add(entityId);
                }
            } else if (contacts.containsKey(entityId)) {
                Contact c = contacts.get(entityId);
                if (entitiesTouched.contains(entityId)) {
                    c.First_Connect_Touch__c += count;
                } else {
                    c.First_Connect_Touch__c = count;
                    c.First_Connect_Date__c = now;
                    entitiesTouched.add(entityId);
                }
            }
        }
    }
    
    public void updateTotalSalesTouches() {
        // Sum all open and completed tasks of the appropriate types.
        // This includes cancelled touches, per mfitzgerald.
        
        Set<ID> allIds = new Set<ID>();
        // Get eligible leads and contacts associated with the First_Contact__c tasks.
        for (Lead l: this.leads.values()) {
            allIds.add(l.id);
        }
        for(Contact c: this.contacts.values()) {
            allIds.add(c.id);
        }

        List<AggregateResult> tasksPerEntity = [
            SELECT Who.Id entityId, Count(ID)
            FROM Task
            WHERE
                Type IN :SALES_TASK_TYPES AND
                Who.Id IN :allIds
            GROUP BY Who.Id
        ];
        List<AggregateResult> eventsPerEntity = [
            Select Who.Id entityId, Count(ID)
            FROM Event
            WHERE
                Type IN :SALES_EVENT_TYPES AND
                Who.Id in :allIds
            GROUP BY Who.Id
        ];

        // Condense the values of these maps into single values per ID, and stamp those onto the appropriate entity.
        Map<ID, Integer> counts = new Map<ID, Integer>();
        for (AggregateResult agg: tasksPerEntity) {
            counts.put((ID) agg.get('entityId'), Integer.valueOf(agg.get('expr0')));
        }

        for (AggregateResult agg: eventsPerEntity) {
            Integer count = Integer.valueOf(agg.get('expr0'));
            ID entityId = (ID) agg.get('entityId');
            if (counts.containsKey(entityId)) {
                counts.put(entityId, counts.get(entityId) + count);
            } else {
                counts.put(entityId, count);
            }
        }
        
        for (ID leadId: this.leads.keySet()) {
            if (counts.containsKey(leadId)) {
                this.leads.get(leadId).Total_Sales_Touches__c = counts.get(leadId);
            }
        }
        for (ID contactId: this.contacts.keySet()) {
            if (counts.containsKey(contactId)) {
                this.contacts.get(contactId).Total_Sales_Touches__c = counts.get(contactId);
            }
        }
    }
    
    public static Boolean isTaskAllowed(Task t) {
        return SALES_TASK_TYPES.contains(t.Type);
    }
    
    public static Boolean isEventAllowed(Event e) {
        return SALES_EVENT_TYPES.contains(e.Type);
    }
    
    public static Boolean taskJustCompleted(Task oldT, Task newT) {
        return oldT.Status != 'Completed' && newT.Status == 'Completed';
    }
    
    public static Boolean eventJustCompleted(Event oldE, Event newE) {
        return !oldE.Event_Completed__c && newE.Event_Completed__c;
    }

    @future
    public static void handleTasksAndEventsWithNoWhoId(Set<ID> activityIds) {
        List<Task> tasks = [
            SELECT WhoId, Status, Type, Cancelled__c, First_Connect__c
            FROM Task 
            WHERE Id IN :activityIds
        ];
        List<Event> events = [
            SELECT WhoId, Event_Completed__c, Type, Cancelled__c, First_Connect__c
            FROM Event
            WHERE Id IN :activityIds
        ];
        
        if (tasks.size() > 0) {
            TaskTriggerHandler taskHandler = new TaskTriggerHandler(true);
            taskHandler.afterInsert(tasks);       
        }
        
        if (events.size() > 0) {
            EventTriggerHandler eventHandler = new EventTriggerHandler(true);
            eventHandler.afterInsert(events);
        }
    }
}
EventTriggerHandler (Apex Class)
public with sharing class EventTriggerHandler {

    private ProspectManagement prospectManager;
    private Boolean isFutureContext = false;
    
    public EventTriggerHandler() {
    
    }
    
    public EventTriggerHandler(Boolean isFuture) {
        this.isFutureContext = isFuture;
    }
    
    public void afterInsert(List<Event> newEvents) {
        Set<ID> allIds = new Set<ID>();
        List<Event> validEvents = new List<Event>();
        Set<ID> eventsWithoutTargets = new Set<ID>();
        for (Event e: newEvents) {
            if (!ProspectManagement.isEventAllowed(e)) {
                continue;
            }
            if (e.WhoId == null) {
                eventsWithoutTargets.add(e.Id);
                continue;
            }
            allIds.add(e.WhoId);
            validEvents.add(e);
        }

        this.prospectManager = new ProspectManagement(allIds);
        
        this.prospectManager.updateTotalSalesTouches();
        this.updateFirstConnectInfo(validEvents);
        this.updateFirstSalesActivityDateTimeOnInsert(validEvents);
        this.updateTotalCompletedTouchesOnInsert(validEvents);
        this.updateLastContactedDateOnInsert(validEvents);
        
        update this.prospectManager.getLeads().values();
        update this.prospectManager.getContacts().values();
        
        if (!this.isFutureContext && eventsWithoutTargets.size() > 0) {
            ProspectManagement.handleTasksAndEventsWithNoWhoId(eventsWithoutTargets);
        }
    }

    public void afterUpdate(Map<ID, Event> oldMap, Map<ID, Event> newMap, List<Event> newEvents) {
        Set<ID> allIds = new Set<ID>();
        List<Event> validEvents = new List<Event>();
        Map<ID, Event> oldValidEvents = new Map<ID, Event>();
        Map<ID, Event> newValidEvents = new Map<ID, Event>();
        for (Event e: newEvents) {
            if (e.WhoId == null || !ProspectManagement.isEventAllowed(e)) {
                continue;
            }
            allIds.add(e.WhoId);
            validEvents.add(e);
            oldValidEvents.put(e.Id, oldMap.get(e.Id));
            newValidEvents.put(e.Id, newMap.get(e.Id));
        }

        this.prospectManager = new ProspectManagement(allIds);
        this.updateFirstConnectInfo(validEvents);
        this.updateFirstSalesActivityDateTimeOnUpdate(oldValidEvents, newValidEvents);
        this.updateTotalCompletedTouchesOnUpdate(oldValidEvents, newValidEvents);
        this.updateLastContactedDateOnUpdate(oldValidEvents, newValidEvents);
        
        update this.prospectManager.getLeads().values();
        update this.prospectManager.getContacts().values();
    }
    
    /**
     * When a Task or Event is updated to have “First Connect?” = True (manually set by Sales Rep when logging calls
     * and emails), find the Lead or Contact referenced in the “Name” (Who) field, and set the following fields on 
     * that Lead or Contact record only if they are currently blank (we’re looking at FIRST time this happens):
     *     First Connect Touch Number = Get all completed activities associated to the Lead/Contact, ordered by due 
     *         date or event start date, and count the number of activities before and including the first activity 
     *         where Connect = true
     *     First Connect DateTime = Set NOW
     */
    private void updateFirstConnectInfo(List<Event> events) {
        Set<ID> allIds = new Set<ID>();
        Set<ID> updatedEntities = new Set<ID>();
        Set<ID> firstConnectTaskEntities = new Set<ID>();

        // Accumulate the entities associated with First_Contact__c tasks.
        for (Event e: events) {
            if (e.First_Connect__c) {
                firstConnectTaskEntities.add(e.WhoId);
            }
        }
        
        this.prospectManager.updateFirstConnectInfo(firstConnectTaskEntities);
    }
    
    
    /**
     * When a Task is updated to Status = Completed OR an Event startdate time is in the past and Cancelled = false,
     * find the Lead or Contact referenced in the “Name” (Who) field, and if the First Sales Activity Datetime field 
     * is blank, set NOW
     */
    private void updateFirstSalesActivityDateTimeOnInsert(List<Event> events) {
        for (Event e: events) {
            if (e.Event_Completed__c && !e.Cancelled__c) {
                this.prospectManager.updateFirstSalesActivityDateTime(e.WhoId);
            }
        }
    }
    
    /**
     * When a Task is updated to Status = Completed OR an Event startdate time is in the past and Cancelled = false,
     * find the Lead or Contact referenced in the “Name” (Who) field, and if the First Sales Activity Datetime field 
     * is blank, set NOW.
     */
    private void updateFirstSalesActivityDateTimeOnUpdate(Map<ID, Event> oldEvents, Map<ID, Event> newEvents) {
        for (ID eventId: newEvents.keySet()) {
            Event e = newEvents.get(eventId);
            if (ProspectManagement.eventJustCompleted(oldEvents.get(eventId), e)) {
                this.prospectManager.updateFirstSalesActivityDateTime(e.WhoId);    
            }
        }
    }

    /**
     * When a Task is updated to Status = Completed OR an Event startdate time is in the past and Cancelled = false,
     * find the Lead or Contact referenced in the “Name” (Who) field,
     * count all related activities that are “completed” (ignore open tasks and future events), and stamp the number in 
     * this field.
     */    
    private void updateTotalCompletedTouchesOnInsert(List<Event> newEvents) {
        Set<ID> entityIds = new Set<ID>();
        for (Event e: newEvents) {
            if (e.Event_Completed__c && !e.Cancelled__c) {
                entityIds.add(e.WhoId);
            }
        }
        this.prospectManager.updateTotalCompletedTouches(entityIds);
    }

    /**
     * When a Task is updated to Status = Completed OR an Event startdate time is in the past and Cancelled = false,
     * find the Lead or Contact referenced in the “Name” (Who) field,
     * count all related activities that are “completed” (ignore open tasks and future events), and stamp the number in 
     * this field.
     */
    private void updateTotalCompletedTouchesOnUpdate(Map<ID, Event> oldEvents, Map<ID, Event> newEvents) {
        Set<ID> entityIds = new Set<ID>();
        for (ID eventId: oldEvents.keySet()) {
            Event e = newEvents.get(eventId);
            if (ProspectManagement.eventJustCompleted(oldEvents.get(eventId), e)) {
                entityIds.add(newEvents.get(eventId).WhoId);
            }
        }
        this.prospectManager.updateTotalCompletedTouches(entityIds);
    }
    
    private void updateLastContactedDateOnInsert(List<Event> newEvents) {
        Set<ID> entityIds = new Set<ID>();
        for (Event e: newEvents) {
            if (e.Event_Completed__c && !e.Cancelled__c) {
                entityIds.add(e.WhoId);
            }
        }
        this.prospectManager.updateLastContactedDate(entityIds);
    }

    /**
     * When an activity is updated to Status = Completed OR an Event startdate time is in the past and
     * Cancelled = false, find the Lead or Contact referenced in the “Name” (Who) field, and update Last Reach Out Date to NOW
     * Also find the Account associated, and update Last Contacted Date to NOW
     */
    private void updateLastContactedDateOnUpdate(Map<ID, Event> oldEvents, Map<ID, Event> newEvents) {        
        Set<ID> entityIds = new Set<ID>();
        for (ID eventId: oldEvents.keySet()) {
            Event e = newEvents.get(eventId);
            if (ProspectManagement.eventJustCompleted(oldEvents.get(eventId), e)) {
                entityIds.add(e.WhoId);
            }
        }
        this.prospectManager.updateLastContactedDate(entityIds);   
    }       
}

TaskTriggerHandler (Apex Class) - Very similar to the EventTriggerHandler, but my post is already too long so I can't add it! 

 
Best Answer chosen by Stephanie Holt 2
Nayana KNayana K
To make it easy for you, remove all the comments inside the trigger handler and add /* at the very beggining and */ at the end :
public with sharing class ProspectManagement {

    /*public static final Set<String> SALES_TASK_TYPES = new Set<String> {
        'Call', 'Email - Sent', 'Email - Opened', 'Email - Clicked', 'Other'
    };

    public static final Set<String> SALES_EVENT_TYPES = new Set<String>{
        'Scheduled Call - Sales', 'Demo', 'Scheduled Call - Cust Success', 'In-person Meeting', 'Other'
    };
    
    private final DateTime NOW;
    private Map<ID, Lead> leads;
    private Map<ID, Contact> contacts;
    
    public ProspectManagement(Set<ID> entityIds) {
        this.leads = this.getLeads(entityIds);
        this.contacts = this.getContacts(entityIds);
        NOW = DateTime.now();
    }
    
    public ProspectManagement(Map<ID, Lead> leads, Map<ID, Contact> contacts) {
        this.leads = leads;
        this.contacts = contacts;
        NOW = DateTime.now();
    }
    
    public Map<ID, Lead> getLeads() {
        return this.leads;
    }
    
    public Map<ID, Contact> getContacts() {
        return this.contacts;
    }
    
    private Map<ID, Lead> getLeads(Set<ID> leadIds) {
        return new Map<ID, Lead>([
            SELECT Id, First_Connect_Date__c, First_Connect_Touch__c, First_Sales_Activity_Date__c,
                Total_Completed_Touches__c
            FROM Lead
            WHERE Id IN :leadIds
        ]);
    }
    
    private Map<ID, Contact> getContacts(Set<ID> contactIds) {
        return new Map<ID, Contact>([
            SELECT Id, First_Connect_Date__c, First_Connect_Touch__c, First_Sales_Activity_Date__c,
                Total_Completed_Touches__c, AccountId
            FROM Contact
            WHERE Id IN :contactIds
        ]);
    }
 
    public void updateFirstSalesActivityDateTime(ID entityId) {    
        if (entityId.getSObjectType() == Contact.SObjectType && 
            this.contacts.get(entityId).First_Sales_Activity_Date__c == null) {
            Contact c = this.contacts.get(entityId);
            if (c.First_Sales_Activity_Date__c == null) {
                c.First_Sales_Activity_Date__c = DateTime.now();
            }
        } else if (entityId.getSObjectType() == Lead.SObjectType && 
            this.leads.get(entityId).First_Sales_Activity_Date__c == null) {
            Lead l = leads.get(entityId);
            if (l.First_Sales_Activity_Date__c == null) {
                l.First_Sales_Activity_Date__c = DateTime.now();
            }
        }    
    }
    
   
    public void updateLastContactedDate(Set<ID> entityIds) {
        System.debug('Entity IDs: ' + entityIds);
        Set<ID> accountIds = new Set<ID>();
        for (ID entityId: entityIds) {
            if (this.leads.containsKey(entityId)) {
                System.debug('upating lead ' + entityId);
                this.leads.get(entityId).Last_Contacted_Date__c = NOW;
            } else if (this.contacts.containsKey(entityId)) {
                this.contacts.get(entityId).Last_Contacted_Date__c = NOW;
                System.debug('updating contact ' + entityId);
                if (this.contacts.get(entityId).AccountId != null) {
                    accountIds.add(this.contacts.get(entityId).AccountId);
                }
            }
        }
        System.debug('Account IDs: ' + accountIds);
        
        List<Account> accounts = [SELECT Id, Last_Contacted_Date__c FROM Account WHERE Id in :accountIds];
        for (Account a: accounts) {
            a.Last_Contacted_Date__c = NOW;
        }
        
        update accounts;
    }
    
    
    public void updateTotalCompletedTouches(Set<ID> entityIds) {       
        List<AggregateResult> countsPerEntity =([
            SELECT Who.Id entityId, Count(ID)
            FROM Task
            WHERE Cancelled__c = false AND
                Status = 'Completed' AND
                Type IN :SALES_TASK_TYPES AND
                Who.Id IN :entityIds
            GROUP BY Who.Id
        ]);
        countsPerEntity.addAll([
            Select Who.Id entityId, Count(ID)
            FROM Event
            WHERE Cancelled__c = false AND
                StartDateTime <= :now AND
                Type IN :SALES_EVENT_TYPES AND
                Who.Id in :entityIds
            GROUP BY Who.Id
        ]);
        
        Set<ID> entitiesTouched = new Set<ID>();
        for (AggregateResult result: countsPerEntity) {
            ID entityId = (ID) result.get('entityId');
            Integer count = Integer.valueOf(result.get('expr0'));
            if (entityId.getSObjectType() == Contact.SObjectType) {
                Contact c = contacts.get(entityId);
                if (entitiesTouched.contains(entityId)) {
                    c.Total_Completed_Touches__c += count;
                } else {
                    c.Total_Completed_Touches__c = count;
                    entitiesTouched.add(entityId);
                }
            } else if (entityId.getSObjectType() == Lead.SObjectType) {
                Lead l = leads.get(entityId);
                if (entitiesTouched.contains(entityId)) {
                    l.Total_Completed_Touches__c += count;
                } else {
                    l.Total_Completed_Touches__c = count;
                    entitiesTouched.add(entityId);
                }
            }
        }
    }
    
   
    public void updateFirstConnectInfo(Set<ID> entityIds) {
        // Count matching tasks and events, and group by the Who.Id
        
        // TODO: Comments from Maggie say we should account for this on a PER ENTITY basis, where we basically have to
        // replay all tasks and events to figure out when the earliest task or event labeled first_connect exists.
        
        // Get eligible leads and contacts associated with the First_Contact__c tasks.
        
        Set<ID> allIds = new Set<ID>();
        // Filter out any entity ids where we've already connected for the first time.
        for (ID leadId: this.leads.keySet()) {
            Lead l = this.leads.get(leadId);
            if (l.First_Connect_Date__c == null && l.First_Connect_Touch__c == null && entityIds.contains(leadId)) {
                allIds.add(leadId);
            }
        }
        for (ID contactId: this.contacts.keySet()) {
            Contact c = this.contacts.get(contactId);
            if (c.First_Connect_Date__c == null & c.First_Connect_Touch__c == null && entityIds.contains(contactId)) {
                allIds.add(contactId);
            }
        }
        
        List<AggregateResult> countPerEntity = [
            SELECT Who.Id entityId, Count(ID)
            FROM Task
            WHERE Cancelled__c = false AND
                Status = 'Completed' AND
                Type IN :SALES_TASK_TYPES AND
                Who.Id IN :allIds
            GROUP BY Who.Id
        ];
        countPerEntity.addAll([
            Select Who.Id entityId, Count(ID)
            FROM Event
            WHERE Cancelled__c = false AND
                StartDateTime <= :now AND
                Type IN :SALES_EVENT_TYPES AND
                Who.Id in :allIds
            GROUP BY Who.Id
        ]);

        // Since there may be two AggregateResults per WhoId, acknowledge when we've SET the value, so next time
        // We increment the value instead.
        Set<ID> entitiesTouched = new Set<ID>();
        for (AggregateResult entityTasks: countPerEntity) {
            ID entityId = (ID) entityTasks.get('entityId');
            Integer count = Integer.valueOf(entityTasks.get('expr0'));
            if (leads.containsKey(entityId)) {
                Lead l = leads.get(entityId);
                if (entitiesTouched.contains(entityId)) {
                    l.First_Connect_Touch__c += count;
                } else {
                    l.First_Connect_Touch__c = count;
                    l.First_Connect_Date__c = now;
                    entitiesTouched.add(entityId);
                }
            } else if (contacts.containsKey(entityId)) {
                Contact c = contacts.get(entityId);
                if (entitiesTouched.contains(entityId)) {
                    c.First_Connect_Touch__c += count;
                } else {
                    c.First_Connect_Touch__c = count;
                    c.First_Connect_Date__c = now;
                    entitiesTouched.add(entityId);
                }
            }
        }
    }
    
    public void updateTotalSalesTouches() {
        // Sum all open and completed tasks of the appropriate types.
        // This includes cancelled touches, per mfitzgerald.
        
        Set<ID> allIds = new Set<ID>();
        // Get eligible leads and contacts associated with the First_Contact__c tasks.
        for (Lead l: this.leads.values()) {
            allIds.add(l.id);
        }
        for(Contact c: this.contacts.values()) {
            allIds.add(c.id);
        }

        List<AggregateResult> tasksPerEntity = [
            SELECT Who.Id entityId, Count(ID)
            FROM Task
            WHERE
                Type IN :SALES_TASK_TYPES AND
                Who.Id IN :allIds
            GROUP BY Who.Id
        ];
        List<AggregateResult> eventsPerEntity = [
            Select Who.Id entityId, Count(ID)
            FROM Event
            WHERE
                Type IN :SALES_EVENT_TYPES AND
                Who.Id in :allIds
            GROUP BY Who.Id
        ];

        // Condense the values of these maps into single values per ID, and stamp those onto the appropriate entity.
        Map<ID, Integer> counts = new Map<ID, Integer>();
        for (AggregateResult agg: tasksPerEntity) {
            counts.put((ID) agg.get('entityId'), Integer.valueOf(agg.get('expr0')));
        }

        for (AggregateResult agg: eventsPerEntity) {
            Integer count = Integer.valueOf(agg.get('expr0'));
            ID entityId = (ID) agg.get('entityId');
            if (counts.containsKey(entityId)) {
                counts.put(entityId, counts.get(entityId) + count);
            } else {
                counts.put(entityId, count);
            }
        }
        
        for (ID leadId: this.leads.keySet()) {
            if (counts.containsKey(leadId)) {
                this.leads.get(leadId).Total_Sales_Touches__c = counts.get(leadId);
            }
        }
        for (ID contactId: this.contacts.keySet()) {
            if (counts.containsKey(contactId)) {
                this.contacts.get(contactId).Total_Sales_Touches__c = counts.get(contactId);
            }
        }
    }
    
    public static Boolean isTaskAllowed(Task t) {
        return SALES_TASK_TYPES.contains(t.Type);
    }
    
    public static Boolean isEventAllowed(Event e) {
        return SALES_EVENT_TYPES.contains(e.Type);
    }
    
    public static Boolean taskJustCompleted(Task oldT, Task newT) {
        return oldT.Status != 'Completed' && newT.Status == 'Completed';
    }
    
    public static Boolean eventJustCompleted(Event oldE, Event newE) {
        return !oldE.Event_Completed__c && newE.Event_Completed__c;
    }

    @future
    public static void handleTasksAndEventsWithNoWhoId(Set<ID> activityIds) {
        List<Task> tasks = [
            SELECT WhoId, Status, Type, Cancelled__c, First_Connect__c
            FROM Task 
            WHERE Id IN :activityIds
        ];
        List<Event> events = [
            SELECT WhoId, Event_Completed__c, Type, Cancelled__c, First_Connect__c
            FROM Event
            WHERE Id IN :activityIds
        ];
        
        if (tasks.size() > 0) {
            TaskTriggerHandler taskHandler = new TaskTriggerHandler(true);
            taskHandler.afterInsert(tasks);       
        }
        
        if (events.size() > 0) {
            EventTriggerHandler eventHandler = new EventTriggerHandler(true);
            eventHandler.afterInsert(events);
        }
    }*/
}

To the same commenting for the trigger code, hander classes, test classes. Go order wise :
1. Trigger code 
2. Handler class
3. Test class

 

All Answers

Nayana KNayana K
To make it easy for you, remove all the comments inside the trigger handler and add /* at the very beggining and */ at the end :
public with sharing class ProspectManagement {

    /*public static final Set<String> SALES_TASK_TYPES = new Set<String> {
        'Call', 'Email - Sent', 'Email - Opened', 'Email - Clicked', 'Other'
    };

    public static final Set<String> SALES_EVENT_TYPES = new Set<String>{
        'Scheduled Call - Sales', 'Demo', 'Scheduled Call - Cust Success', 'In-person Meeting', 'Other'
    };
    
    private final DateTime NOW;
    private Map<ID, Lead> leads;
    private Map<ID, Contact> contacts;
    
    public ProspectManagement(Set<ID> entityIds) {
        this.leads = this.getLeads(entityIds);
        this.contacts = this.getContacts(entityIds);
        NOW = DateTime.now();
    }
    
    public ProspectManagement(Map<ID, Lead> leads, Map<ID, Contact> contacts) {
        this.leads = leads;
        this.contacts = contacts;
        NOW = DateTime.now();
    }
    
    public Map<ID, Lead> getLeads() {
        return this.leads;
    }
    
    public Map<ID, Contact> getContacts() {
        return this.contacts;
    }
    
    private Map<ID, Lead> getLeads(Set<ID> leadIds) {
        return new Map<ID, Lead>([
            SELECT Id, First_Connect_Date__c, First_Connect_Touch__c, First_Sales_Activity_Date__c,
                Total_Completed_Touches__c
            FROM Lead
            WHERE Id IN :leadIds
        ]);
    }
    
    private Map<ID, Contact> getContacts(Set<ID> contactIds) {
        return new Map<ID, Contact>([
            SELECT Id, First_Connect_Date__c, First_Connect_Touch__c, First_Sales_Activity_Date__c,
                Total_Completed_Touches__c, AccountId
            FROM Contact
            WHERE Id IN :contactIds
        ]);
    }
 
    public void updateFirstSalesActivityDateTime(ID entityId) {    
        if (entityId.getSObjectType() == Contact.SObjectType && 
            this.contacts.get(entityId).First_Sales_Activity_Date__c == null) {
            Contact c = this.contacts.get(entityId);
            if (c.First_Sales_Activity_Date__c == null) {
                c.First_Sales_Activity_Date__c = DateTime.now();
            }
        } else if (entityId.getSObjectType() == Lead.SObjectType && 
            this.leads.get(entityId).First_Sales_Activity_Date__c == null) {
            Lead l = leads.get(entityId);
            if (l.First_Sales_Activity_Date__c == null) {
                l.First_Sales_Activity_Date__c = DateTime.now();
            }
        }    
    }
    
   
    public void updateLastContactedDate(Set<ID> entityIds) {
        System.debug('Entity IDs: ' + entityIds);
        Set<ID> accountIds = new Set<ID>();
        for (ID entityId: entityIds) {
            if (this.leads.containsKey(entityId)) {
                System.debug('upating lead ' + entityId);
                this.leads.get(entityId).Last_Contacted_Date__c = NOW;
            } else if (this.contacts.containsKey(entityId)) {
                this.contacts.get(entityId).Last_Contacted_Date__c = NOW;
                System.debug('updating contact ' + entityId);
                if (this.contacts.get(entityId).AccountId != null) {
                    accountIds.add(this.contacts.get(entityId).AccountId);
                }
            }
        }
        System.debug('Account IDs: ' + accountIds);
        
        List<Account> accounts = [SELECT Id, Last_Contacted_Date__c FROM Account WHERE Id in :accountIds];
        for (Account a: accounts) {
            a.Last_Contacted_Date__c = NOW;
        }
        
        update accounts;
    }
    
    
    public void updateTotalCompletedTouches(Set<ID> entityIds) {       
        List<AggregateResult> countsPerEntity =([
            SELECT Who.Id entityId, Count(ID)
            FROM Task
            WHERE Cancelled__c = false AND
                Status = 'Completed' AND
                Type IN :SALES_TASK_TYPES AND
                Who.Id IN :entityIds
            GROUP BY Who.Id
        ]);
        countsPerEntity.addAll([
            Select Who.Id entityId, Count(ID)
            FROM Event
            WHERE Cancelled__c = false AND
                StartDateTime <= :now AND
                Type IN :SALES_EVENT_TYPES AND
                Who.Id in :entityIds
            GROUP BY Who.Id
        ]);
        
        Set<ID> entitiesTouched = new Set<ID>();
        for (AggregateResult result: countsPerEntity) {
            ID entityId = (ID) result.get('entityId');
            Integer count = Integer.valueOf(result.get('expr0'));
            if (entityId.getSObjectType() == Contact.SObjectType) {
                Contact c = contacts.get(entityId);
                if (entitiesTouched.contains(entityId)) {
                    c.Total_Completed_Touches__c += count;
                } else {
                    c.Total_Completed_Touches__c = count;
                    entitiesTouched.add(entityId);
                }
            } else if (entityId.getSObjectType() == Lead.SObjectType) {
                Lead l = leads.get(entityId);
                if (entitiesTouched.contains(entityId)) {
                    l.Total_Completed_Touches__c += count;
                } else {
                    l.Total_Completed_Touches__c = count;
                    entitiesTouched.add(entityId);
                }
            }
        }
    }
    
   
    public void updateFirstConnectInfo(Set<ID> entityIds) {
        // Count matching tasks and events, and group by the Who.Id
        
        // TODO: Comments from Maggie say we should account for this on a PER ENTITY basis, where we basically have to
        // replay all tasks and events to figure out when the earliest task or event labeled first_connect exists.
        
        // Get eligible leads and contacts associated with the First_Contact__c tasks.
        
        Set<ID> allIds = new Set<ID>();
        // Filter out any entity ids where we've already connected for the first time.
        for (ID leadId: this.leads.keySet()) {
            Lead l = this.leads.get(leadId);
            if (l.First_Connect_Date__c == null && l.First_Connect_Touch__c == null && entityIds.contains(leadId)) {
                allIds.add(leadId);
            }
        }
        for (ID contactId: this.contacts.keySet()) {
            Contact c = this.contacts.get(contactId);
            if (c.First_Connect_Date__c == null & c.First_Connect_Touch__c == null && entityIds.contains(contactId)) {
                allIds.add(contactId);
            }
        }
        
        List<AggregateResult> countPerEntity = [
            SELECT Who.Id entityId, Count(ID)
            FROM Task
            WHERE Cancelled__c = false AND
                Status = 'Completed' AND
                Type IN :SALES_TASK_TYPES AND
                Who.Id IN :allIds
            GROUP BY Who.Id
        ];
        countPerEntity.addAll([
            Select Who.Id entityId, Count(ID)
            FROM Event
            WHERE Cancelled__c = false AND
                StartDateTime <= :now AND
                Type IN :SALES_EVENT_TYPES AND
                Who.Id in :allIds
            GROUP BY Who.Id
        ]);

        // Since there may be two AggregateResults per WhoId, acknowledge when we've SET the value, so next time
        // We increment the value instead.
        Set<ID> entitiesTouched = new Set<ID>();
        for (AggregateResult entityTasks: countPerEntity) {
            ID entityId = (ID) entityTasks.get('entityId');
            Integer count = Integer.valueOf(entityTasks.get('expr0'));
            if (leads.containsKey(entityId)) {
                Lead l = leads.get(entityId);
                if (entitiesTouched.contains(entityId)) {
                    l.First_Connect_Touch__c += count;
                } else {
                    l.First_Connect_Touch__c = count;
                    l.First_Connect_Date__c = now;
                    entitiesTouched.add(entityId);
                }
            } else if (contacts.containsKey(entityId)) {
                Contact c = contacts.get(entityId);
                if (entitiesTouched.contains(entityId)) {
                    c.First_Connect_Touch__c += count;
                } else {
                    c.First_Connect_Touch__c = count;
                    c.First_Connect_Date__c = now;
                    entitiesTouched.add(entityId);
                }
            }
        }
    }
    
    public void updateTotalSalesTouches() {
        // Sum all open and completed tasks of the appropriate types.
        // This includes cancelled touches, per mfitzgerald.
        
        Set<ID> allIds = new Set<ID>();
        // Get eligible leads and contacts associated with the First_Contact__c tasks.
        for (Lead l: this.leads.values()) {
            allIds.add(l.id);
        }
        for(Contact c: this.contacts.values()) {
            allIds.add(c.id);
        }

        List<AggregateResult> tasksPerEntity = [
            SELECT Who.Id entityId, Count(ID)
            FROM Task
            WHERE
                Type IN :SALES_TASK_TYPES AND
                Who.Id IN :allIds
            GROUP BY Who.Id
        ];
        List<AggregateResult> eventsPerEntity = [
            Select Who.Id entityId, Count(ID)
            FROM Event
            WHERE
                Type IN :SALES_EVENT_TYPES AND
                Who.Id in :allIds
            GROUP BY Who.Id
        ];

        // Condense the values of these maps into single values per ID, and stamp those onto the appropriate entity.
        Map<ID, Integer> counts = new Map<ID, Integer>();
        for (AggregateResult agg: tasksPerEntity) {
            counts.put((ID) agg.get('entityId'), Integer.valueOf(agg.get('expr0')));
        }

        for (AggregateResult agg: eventsPerEntity) {
            Integer count = Integer.valueOf(agg.get('expr0'));
            ID entityId = (ID) agg.get('entityId');
            if (counts.containsKey(entityId)) {
                counts.put(entityId, counts.get(entityId) + count);
            } else {
                counts.put(entityId, count);
            }
        }
        
        for (ID leadId: this.leads.keySet()) {
            if (counts.containsKey(leadId)) {
                this.leads.get(leadId).Total_Sales_Touches__c = counts.get(leadId);
            }
        }
        for (ID contactId: this.contacts.keySet()) {
            if (counts.containsKey(contactId)) {
                this.contacts.get(contactId).Total_Sales_Touches__c = counts.get(contactId);
            }
        }
    }
    
    public static Boolean isTaskAllowed(Task t) {
        return SALES_TASK_TYPES.contains(t.Type);
    }
    
    public static Boolean isEventAllowed(Event e) {
        return SALES_EVENT_TYPES.contains(e.Type);
    }
    
    public static Boolean taskJustCompleted(Task oldT, Task newT) {
        return oldT.Status != 'Completed' && newT.Status == 'Completed';
    }
    
    public static Boolean eventJustCompleted(Event oldE, Event newE) {
        return !oldE.Event_Completed__c && newE.Event_Completed__c;
    }

    @future
    public static void handleTasksAndEventsWithNoWhoId(Set<ID> activityIds) {
        List<Task> tasks = [
            SELECT WhoId, Status, Type, Cancelled__c, First_Connect__c
            FROM Task 
            WHERE Id IN :activityIds
        ];
        List<Event> events = [
            SELECT WhoId, Event_Completed__c, Type, Cancelled__c, First_Connect__c
            FROM Event
            WHERE Id IN :activityIds
        ];
        
        if (tasks.size() > 0) {
            TaskTriggerHandler taskHandler = new TaskTriggerHandler(true);
            taskHandler.afterInsert(tasks);       
        }
        
        if (events.size() > 0) {
            EventTriggerHandler eventHandler = new EventTriggerHandler(true);
            eventHandler.afterInsert(events);
        }
    }*/
}

To the same commenting for the trigger code, hander classes, test classes. Go order wise :
1. Trigger code 
2. Handler class
3. Test class

 
This was selected as the best answer
Nayana KNayana K
Take a backup of all before commenting
Stephanie Holt 2Stephanie Holt 2
Thank you! I'll try this today.
Stephanie Holt 2Stephanie Holt 2
Follow up question. Once I comment out everything (and remove the existing comments in the code) should I still de-activate the triggers in sandbox before uploading in a change set? Or leave them active, but commented out?

Thanks!
Nayana KNayana K
No need to deactivate.. Because you have commented the code it does nothing. 
Stephanie Holt 2Stephanie Holt 2
Thank you so much! This worked :)
Nayana KNayana K
Most welcome :)
Steven BauerSteven Bauer
Thank you very much, I have learned a lot of useful things. slope unblocked (https://slopeunblocked.app) mapquest driving directions (https://mapquestdrivingdirections.app)