• Stephanie Holt 2
  • NEWBIE
  • 15 Points
  • Member since 2018
  • Sales & Marketing Operations Lead
  • Barkly


  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 3
    Questions
  • 6
    Replies
Hi everyone, 

I have multiple simple Process Builders that are failing (sometimes). The error in the emails says:
 
Error element myRule_1_A1 (FlowRecordUpdate).
This error occurred when the flow tried to update records: Too many SOQL queries: 101. For details, see API Exceptions.

I originally thought that it could be caused by one of 2 Apex Triggers, or 3 Classes that were built by a contractor before I started at the company. I have de-activated and commented out the triggers, and commented out the Classes, because the function they performed is less important than these processes builders working correctly.  The errors are still happening with my Process Builder processes. This leads me to believe it may be Apex from a managed package?

We have many managed packages. I found an article that we could get debug logs enabled for the managed package with their permission, but does anyone have any suggestion on how I could pinpoint which one may be the problem? Or do I need to contact every managed package provider and have them submit a case on my behalf to enable the logs? (That is what SFDC support told me to have them do). 

Second, even if those logs are enabled, I don't know if I'll be able to figure out the debug logs on my own. I have only done the "Developer Console Basics" trailhead module. Any suggestions/ help would be appreciated. 
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! 

 
I have a pretty simple process that is throwing an error when I try to use data loader or the data import wizard to add campaign members. It starts when a Campaign Member is created --> No criteria-just execute the actions! --> 2 immediate actions:

1. Update Lead First Campaign: 
User-added image
2. Update Contact First Campaign:
User-added image

Any ideas as to why this would throw a "too many SOQL queries" error? Here is the email with details: 


Error element myRule_1_A1 (FlowRecordUpdate).
This error occurred when the flow tried to update records: Too many SOQL queries: 101. For details, see API Exceptions.

This report lists the elements that the flow interview executed. The report is a beta feature.
We welcome your feedback on IdeaExchange.

Flow Details
Flow Name: Update_First_Asset_on_Lead
Type: Record Change Process
Version: 8
Status: Active

Flow Interview Details
Interview Label: Update_First_Asset_on_Lead-8_InterviewLabel
Current User: Stephanie Holt (00541000004Rm2r)
Start time: 3/16/2018 3:50 PM
Duration: 0 seconds

How the Interview Started
Stephanie Holt (00541000004Rm2r) started the flow interview.
Some of this flow's variables were set when the interview started.
myVariable_old = null
myVariable_current = 00v4100000RHJgBAAX

ASSIGNMENT: myVariable_waitStartTimeAssignment
{!myVariable_waitStartTimeVariable} Equals {!Flow.CurrentDateTime}
Result
{!myVariable_waitStartTimeVariable} = "3/16/2018 3:50 PM"

DECISION: myDecision
Executed this outcome: myRule_1
Outcome conditions: and
1. {!formula_myRule_1} (true) Equals true
Logic: All conditions must be true (AND)

RECORD UPDATE: myRule_1_A1
Find all Lead records where:
First_Campaign__c Is null true
Id Equals {!myVariable_current.LeadId} (00Q4100000kHPKzEAO)
Update the records’ field values.
First_Campaign__c = {!myVariable_current.CampaignId} (70141000000LFrIAAW)
Result
Failed to update records that meet the filter criteria.

Error Occurred: Too many SOQL queries: 101
 
Hi everyone, 

I have multiple simple Process Builders that are failing (sometimes). The error in the emails says:
 
Error element myRule_1_A1 (FlowRecordUpdate).
This error occurred when the flow tried to update records: Too many SOQL queries: 101. For details, see API Exceptions.

I originally thought that it could be caused by one of 2 Apex Triggers, or 3 Classes that were built by a contractor before I started at the company. I have de-activated and commented out the triggers, and commented out the Classes, because the function they performed is less important than these processes builders working correctly.  The errors are still happening with my Process Builder processes. This leads me to believe it may be Apex from a managed package?

We have many managed packages. I found an article that we could get debug logs enabled for the managed package with their permission, but does anyone have any suggestion on how I could pinpoint which one may be the problem? Or do I need to contact every managed package provider and have them submit a case on my behalf to enable the logs? (That is what SFDC support told me to have them do). 

Second, even if those logs are enabled, I don't know if I'll be able to figure out the debug logs on my own. I have only done the "Developer Console Basics" trailhead module. Any suggestions/ help would be appreciated. 
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! 

 
I have a pretty simple process that is throwing an error when I try to use data loader or the data import wizard to add campaign members. It starts when a Campaign Member is created --> No criteria-just execute the actions! --> 2 immediate actions:

1. Update Lead First Campaign: 
User-added image
2. Update Contact First Campaign:
User-added image

Any ideas as to why this would throw a "too many SOQL queries" error? Here is the email with details: 


Error element myRule_1_A1 (FlowRecordUpdate).
This error occurred when the flow tried to update records: Too many SOQL queries: 101. For details, see API Exceptions.

This report lists the elements that the flow interview executed. The report is a beta feature.
We welcome your feedback on IdeaExchange.

Flow Details
Flow Name: Update_First_Asset_on_Lead
Type: Record Change Process
Version: 8
Status: Active

Flow Interview Details
Interview Label: Update_First_Asset_on_Lead-8_InterviewLabel
Current User: Stephanie Holt (00541000004Rm2r)
Start time: 3/16/2018 3:50 PM
Duration: 0 seconds

How the Interview Started
Stephanie Holt (00541000004Rm2r) started the flow interview.
Some of this flow's variables were set when the interview started.
myVariable_old = null
myVariable_current = 00v4100000RHJgBAAX

ASSIGNMENT: myVariable_waitStartTimeAssignment
{!myVariable_waitStartTimeVariable} Equals {!Flow.CurrentDateTime}
Result
{!myVariable_waitStartTimeVariable} = "3/16/2018 3:50 PM"

DECISION: myDecision
Executed this outcome: myRule_1
Outcome conditions: and
1. {!formula_myRule_1} (true) Equals true
Logic: All conditions must be true (AND)

RECORD UPDATE: myRule_1_A1
Find all Lead records where:
First_Campaign__c Is null true
Id Equals {!myVariable_current.LeadId} (00Q4100000kHPKzEAO)
Update the records’ field values.
First_Campaign__c = {!myVariable_current.CampaignId} (70141000000LFrIAAW)
Result
Failed to update records that meet the filter criteria.

Error Occurred: Too many SOQL queries: 101