You need to sign in to do that
Don't have an account?
Stephanie 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
And here are the specifics of the Trigger and Apex class code if that is helpful:
EventTrigger
TaskTrigger:
ProsepctManagement (Apex Class)
TaskTriggerHandler (Apex Class) - Very similar to the EventTriggerHandler, but my post is already too long so I can't add it!
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
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!
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
To the same commenting for the trigger code, hander classes, test classes. Go order wise :
1. Trigger code
2. Handler class
3. Test class
Thanks!