• SeanCeno
  • NEWBIE
  • 200 Points
  • Member since 2013
  • Salesforce Developer
  • Colony NorthStar, Inc

  • Chatter
    Feed
  • 3
    Best Answers
  • 2
    Likes Received
  • 0
    Likes Given
  • 56
    Questions
  • 189
    Replies
Hi,
I have TextArea field named Attendance_Notes__c on object EventBooking. I developing a pageblocktable. One column of this table is shown here
When delegate has partial attendance for a course, trainer should put a note.
The checkbox will show Text Area field to put notes.
<apex:Column id="pa">
         <apex:facet name="header">Partial Attendance</apex:facet>
         <apex:inputCheckbox id="isPartialAttendance" value="{!ebrecs.EventBooking['Partial_Attendance_Flag__c']}" selected="false" rendered="{!ebrecs.isCheckBoxShow}">
                  <apex:actionsupport status="submitStatus" event="onclick" action="{!saveValues}" reRender="pa,pm">
                           <apex:param assignto="{!index}" name="param1" value="{!ebrecs.index}"/>
                  </apex:actionsupport>
        </apex:inputCheckbox>
        <apex:inputfield id="inputpa" label="Notes" value="{!ebrecs.EventBooking['Attendance_Notes__c']}" rendered="{!AND(if(ebrecs.EventBooking['Partial_Attendance_Flag__c']==true,true,false),ebrecs.isCheckBoxShow)}">
                 <apex:actionsupport immediate="true" status="submitStatus" event="onchange" action="{!saveValues}" reRender="pa,pm">
                         <apex:param assignto="{!index}" name="param1" value="{!ebrecs.index}"/>
                </apex:actionsupport>
       </apex:inputfield>
</apex:Column>
when inputfield is updated(event="onchange") with notes, action - saveValues on actionsupport should be invoked, which is not invoking now.
It is working fine for all other field type from other column
Could you please help ?

Best Regards,

Rahul
Using the one trigger per object best practice, my trigger is not updating the results back to old values when an update (that would NOT be counted in the SOQL query) or delete occurs. Please see code below:

Class:
public with sharing class CompletedEvents {
    protected final Event[] eventOldList;
    protected final Event[] eventNewList;
    Set<Id> contIds = new Set<Id>();

    public CompletedEvents(Event[] eventOldList, Event[] eventNewList) {
        this.eventOldList = eventOldList;
        this.eventNewList = eventNewList;
    }

    public CompletedEvents(List<Event> events){
        this.eventNewList = events;
    }
   
 public void executeTotalConferenceCalls(){
        for(Event e : eventNewList){
            if(e.WhoId != null){
                contIds.add(e.WhoId);
            }
        }

        AggregateResult [] ars = [Select WhoId eventId, count(id) ConfCount
                                  From Event
                                  Where WhoId in :contIds
                                  AND EndDateTime < :date.today()
                                  AND isDeleted = False
                                  AND Subject = 'Conference Call'
                                  GROUP BY WhoId All Rows];

        List<Contact> updCon = new List<Contact>();
        for(AggregateResult ar : ars){
            Contact c = new Contact();
            c.Id = (Id)ar.get('eventId');
            c.Total_Conference_Calls__c = Integer.ValueOf(ar.get('ConfCount'));
            updCon.Add(c);
        }

        if(updCon.size()>0){
            update updCon;
        }
    }

    public void executeLastCompletedEvent(){
        for(Event e : eventNewList){
            if(e.WhoId != null){
                contIds.add(e.WhoId);
            }
        }

        Event[] eventList = [Select WhoId, Subject, EndDateTime, ActivityDateTime, ActivityDate
                             From Event
                             Where WhoId in :contIds
                             AND EndDateTime < :date.today()
                             AND isDeleted = False
                             AND Subject != 'B/D-Conference'
                             AND Subject != 'Cancel/No Show'
                             AND Subject != 'DD Meeting'
                             AND Subject != 'NRS-Conference'
                             AND Subject != 'Other'
                             AND Subject != 'Drop-In'
                             AND Subject != 'Business Review'
                             AND Subject != 'One-On-One'
                             AND Subject != 'Travel'
                             AND Subject != 'Professional Association Event'
                             ORDER BY EndDateTime ASC All Rows];

        Map<Id, Contact> cMap = new Map<Id, Contact>();
        for(Event e : eventList){
            Contact c = new Contact(Id = e.WhoId);
            if(c.Id != null){
                c.Last_Completed_Event__c = e.EndDateTime;
                cMap.put(c.Id, c);
            }
        }

        update cMap.values();
    }
}

Trigger
trigger MasterEventTrigger on Event (
    before insert, after insert,
    before update, after update,
    before delete, after delete){
    Event[] eventOldList = trigger.IsDelete ? null : trigger.old;
    Event[] eventNewList = trigger.IsDelete ? trigger.old : trigger.new;
        
    if (Trigger.isBefore) {
        if (Trigger.isInsert) {
                new CompletedEvents(eventOldList, eventNewList).executeTotalConferenceCalls();
                new CompletedEvents(eventOldList, eventNewList).executeLastCompletedEvent();
        }

        if (Trigger.isUpdate) {
                new CompletedEvents(eventOldList, eventNewList).executeTotalConferenceCalls();
                new CompletedEvents(eventOldList, eventNewList).executeLastCompletedEvent();
        }

        if (Trigger.isDelete) {
                new CompletedEvents(eventOldList, eventNewList).executeTotalConferenceCalls();
                new CompletedEvents(eventOldList, eventNewList).executeLastCompletedEvent();
        }
    }
    
    if (Trigger.IsAfter) {
        if (Trigger.isInsert) {
        }
        if (Trigger.isUpdate) {
        }
        if (Trigger.isDelete) {
        }
    }
}

 
All,
I'm trying to refactor my trigger code to a batch. How can I execute my class to fire within the batch?

Class
public class Account_RollupProductInterest {
    protected final Account[] accountNewList;
    protected final Account[] accountOldList;
    Set<Id> acctIds = new Set<Id>();
    Decimal RXRsum = 0;
    Decimal A40Actsum = 0;
    Decimal DSTsum = 0;
    Decimal PPsum = 0;
    Decimal ITSum = 0;
    Decimal ActiveRepsSum = 0;
    Decimal NSTickets = 0;

    public Account_RollupProductInterest(Account[] accountOldList, Account[] accountNewList) {
        this.accountNewList = accountNewList;
        this.accountOldList = accountOldList;
    }

    public Account_RollupProductInterest(){
        new Account_RollupProductInterest().executeTableRollup();
    }

    //Update Numbers Table
    public void executeTableRollup(){
        for(Account a : accountNewList){
            if(a.ParentId != null){
                acctIds.add(a.ParentId);
            }
        }

        List<Account> updAcc = new List<Account>();
        List<Account> childAccts = new List<Account>([Select Id, Number_of_NS_RXR_Propects__c,
                                                        Number_of_40_Act_Fund_Prospects__c,
                                                        Number_of_DST_Prospects__c,
                                                        Number_of_Private_Placement_Prospects__c,
                                                        Number_of_Investor_Tickets__c,
                                                        Number_Of_Active_Reps__c,
                                                        Number_of_NorthStar_Tickets__c,
                                                   (Select Id, Number_of_NS_RXR_Propects__c,
                                                        Number_of_40_Act_Fund_Prospects__c,
                                                        Number_of_DST_Prospects__c,
                                                        Number_of_Private_Placement_Prospects__c,
                                                        Number_of_Investor_Tickets__c,
                                                        Number_Of_Active_Reps__c,
                                                        Number_of_NorthStar_Tickets__c
                                                From ChildAccounts)
                                                  From Account
                                                  Where Id in :acctIds]);
        for(Account acc : childAccts){
            for(Account child : acc.ChildAccounts){
                    RXRsum += (child.Number_of_NS_RXR_Propects__c != null ? RXRsum + child.Number_of_NS_RXR_Propects__c : 0);
                    acc.Number_of_NS_RXR_Propects__c = RXRsum;

                    A40Actsum += (child.Number_of_40_Act_Fund_Prospects__c != null ? A40Actsum + child.Number_of_40_Act_Fund_Prospects__c : 0);
                    acc.Number_of_40_Act_Fund_Prospects__c = A40Actsum;

                    DSTsum += (child.Number_of_DST_Prospects__c != null ? DSTsum + child.Number_of_DST_Prospects__c : 0);
                    acc.Number_of_DST_Prospects__c = DSTsum;

                    PPsum += (child.Number_of_Private_Placement_Prospects__c != null ? PPsum + child.Number_of_Private_Placement_Prospects__c : 0);
                    acc.Number_of_Private_Placement_Prospects__c = PPsum;

                    ITSum += (child.Number_of_Investor_Tickets__c != null ? ITSum + child.Number_of_Investor_Tickets__c : 0);
                    acc.Number_of_Investor_Tickets__c = ITSum;

                    ActiveRepsSum += (child.Number_Of_Active_Reps__c != null ? ActiveRepsSum + child.Number_Of_Active_Reps__c : 0);
                    acc.Number_Of_Active_Reps__c = ActiveRepsSum;

                    NSTickets += (child.Number_Of_NorthStar_Tickets__c != null ? NSTickets + child.Number_Of_NorthStar_Tickets__c : 0);
                    acc.Number_Of_NorthStar_Tickets__c = NSTickets;
            }
            
            updAcc.add(acc);
        }

        try {
            update updAcc;
        }
        Catch (Exception e) {
            System.debug('Exception : '+e.getMessage());
        }
    }
}

Batch:
Batch:
global class Contact_RollupProductInterestBatchable implements Database.Batchable<sObject> {
     global Database.QueryLocator start(Database.BatchableContext batchableContext){
	 	        return Database.getQueryLocator('Select Id From Account');

         /**String query = 'Select Id, Number_of_NS_RXR_Propects__c,'
                                 + 'Number_of_40_Act_Fund_Prospects__c,'
                                 + 'Number_of_DST_Prospects__c,'
                                 + 'Number_of_Private_Placement_Prospects__c,'
                                 + 'Number_of_Investor_Tickets__c,'
                                 + 'Number_Of_Active_Reps__c,'
                                 + 'Number_of_NorthStar_Tickets__c,'
                                 + '(Select Id, Number_of_NS_RXR_Propects__c,'
                                             + 'Number_of_40_Act_Fund_Prospects__c,'
                                             + 'Number_of_DST_Prospects__c,'
                                             + 'Number_of_Private_Placement_Prospects__c,'
                                             + 'Number_of_Investor_Tickets__c,'
                                             + 'Number_Of_Active_Reps__c,'
                                             + 'Number_of_NorthStar_Tickets__c'
                                             + 'From ChildAccounts)'
                                  + 'From Account';
         return Database.getQueryLocator(query);**/

    }

    global void execute(Database.BatchableContext batchableContext, Account[] accountNewList) {
        // Execute the rollup. It will auto-update the branch accounts once complete
        for(Account a : accountNewList){
        	a.Number_of_NS_RXR_Propects__c = a.ChildAccounts.Number_of_NS_RXR_Propects__c;
        	a.Number_of_40_Act_Fund_Prospects__c = a.ChildAccounts.Number_of_40_Act_Fund_Prospects__c;
        	a.Number_of_DST_Prospects__c = a.ChildAccounts.Number_of_DST_Prospects__c;
        	a.Number_of_Private_Placement_Prospects__c = a.ChildAccounts.Number_of_Private_Placement_Prospects__c;
        	a.Number_of_Investor_Tickets__c = a.ChildAccounts.Number_of_Investor_Tickets__c;
        	a.Number_Of_Active_Reps__c = a.ChildAccounts.Number_Of_Active_Reps__c;
        	a.Number_of_NorthStar_Tickets__c = a.ChildAccounts.Number_of_NorthStar_Tickets__c;
        }

        update accountNewList
    }

    global void finish(Database.BatchableContext batchableContext) {

    }
}

 
All,
I'm trying to sum the number of Contacts for Parent Accounts with certain checkboxes = true. We have a hiearchy of Accounts: Branch level and National Account level. The trigger is updating on the Branch level, but not on the National Account level (Parent Account). Do I need to write a separate trigger on Accounts to sum these values? Would that not cause a recursive trigger?

Class:
public class Contact_RollupProductInterest {
    protected final Contact[] contactNewList;
    protected final Contact[] contactOldList;
	Set<Id> acctIds = new Set<Id>();

    public Contact_RollupProductInterest(Contact[] contactOldList, Contact[] contactNewList) {
        this.contactNewList = contactNewList;
        this.contactOldList = contactOldList;
    }

    //Update Number of RXR Prospects
    public void executeNumberRXRProspects(){
    	for(Contact c : contactNewList){
    		if(c.AccountId != null){
    			acctIds.add(c.AccountId);
    		}
    	}

    List<Account> updAcc = new List<Account>();
    	for(AggregateResult ar: [Select AccountId acctId, count(id) ContactCount 
    						 	 From Contact
    						 	 Where AccountId in :acctIds AND NS_RXR_Prospect__c = true
    						 	 Group BY AccountId]){
    		Account a = new Account();
    		a.Id = (Id)ar.get('acctId');
    		a.Number_of_NS_RXR_Propects__c = Integer.ValueOf(ar.get('ContactCount'));
    		updAcc.Add(a);
    	}
    		if(updAcc.size()>0){
    	 		update updAcc;
    		}
    }
}

Trigger:
trigger MasterContactTrigger on Contact (
    before insert, after insert, 
    before update, after update, 
    before delete, after delete){
    Contact[] contactOldList = trigger.IsDelete ? null : trigger.old;
    Contact[] contactNewList = trigger.IsDelete ? trigger.old : trigger.new;
        
    if (Trigger.isBefore) {
        if (Trigger.isInsert) {
            // Call class logic here!
        }
        if (Trigger.isUpdate) {
            new CompletedEvents(contactOldList, contactNewList).executeTotalCompletedEvents();
            new CompletedEvents(contactOldList, contactNewList).executeTotalMeetings();
            new CompletedEvents(contactOldList, contactNewList).executeTotalConferenceCalls();
            new CompletedEvents(contactOldList, contactNewList).executeLastCompletedEvent();
            new CompletedEvents(contactOldList, contactNewList).executeFirstCompletedEvent();
            new CompletedEvents(contactOldList, contactNewList).executeLastCompletedMeeting();
            new CompletedEvents(contactOldList, contactNewList).executeFirstCompletedMeeting();
            new Contact_RollupProductInterest(contactOldList, contactNewList).executeNumberRXRProspects();
        }
        if (Trigger.isDelete) {
            // Call class logic here!
        }
    }
        
    if (Trigger.IsAfter) {
        if (Trigger.isInsert) {
            // Call class logic here!
        }
        if (Trigger.isUpdate) {
            // Call class logic here!
        }
        if (Trigger.isDelete) {
            // Call class logic here!
        }
    }
}

 
All,

I'm trying to populate the Account Website field based on a child Contact's Email field. I need to grab the characters that occur after (to the right of) the '@' character. What is the proper String Method to use here?
a.Website = String.valueOf(con.Email.Split('@')); //Incorrect String Method
Below is the full trigger I've written so far:

Class:
public class Update_AccountWebsite {
    protected final Contact[] contactNewList;
    protected final Contact[] contactOldList;
    
    public Update_AccountWebsite (Contact[] contactOldList, Contact[] contactNewList) {
        this.contactNewList = contactNewList;
        this.contactOldList = contactOldList;
    }
    
    public void executeUpdate_AccountWebsite() {
        List<Contact> contList = new List<Contact>(contactNewList);
        Set<Id> accountIds = new Set<Id>();
        for(Contact c :contactNewList){
            if(c.id != null && c.Email != null){
                accountIds.add(c.AccountId);
            }
        }
        List<Account> acctList = [Select Id, Name, Website, (Select Id, AccountId, Email From Contacts) From Account Where Id in :accountIds];
        for(Account a :acctList){
            for(Contact con :a.Contacts){
                a.Website = String.valueOf(con.Email.Split('@')); //Incorrect String Method
                a.Contacts.add(con);
                system.debug(acctList);
                system.debug(contList);
                system.debug(a.Contacts);
            }
        }
    }
}

Trigger:
trigger MasterContactTrigger on Contact (
    before insert, after insert, 
    before update, after update, 
    before delete, after delete) {
        Contact[] contactOldList = trigger.IsDelete ? null : trigger.old;
        Contact[] contactNewList = trigger.IsDelete ? trigger.old : trigger.new;
        
        if (Trigger.isBefore) {
            if (Trigger.isInsert) {
            }
            if (Trigger.isUpdate) {
            }
            if (Trigger.isDelete) {
            }
        }
        
        if (Trigger.IsAfter) {
            if (Trigger.isInsert) {
                new Update_AccountWebsite(contactOldList, contactNewList).executeUpdate_AccountWebsite();
            }
            if (Trigger.isUpdate) {
                new Update_AccountWebsite(contactOldList, contactNewList).executeUpdate_AccountWebsite();
            }
            if (Trigger.isDelete) {
            }
        }
}

 
All,
I'm trying to display a pageBlockSection based on the value of a picklist. But when I make the selection in the picklist, the pageBlockSection is not displayed. I have also tried wrapping it in an outputPanel container as well. Is my syntax incorrect in the rendered attribute? Here is a snippet of my code:
<apex:pageBlockSection title="Pre-Approval Form Required?" columns="2" rendered="{!NOT(ISBLANK(marketingReimbursementForm))}" collapsible="True">
        		<apex:pageBlockSectionItem >
        			<apex:outputLabel value="{!$ObjectType.Marketing_Reimbursement__c.Fields.Pre_Approval_Required__c.Label}" />
        			<apex:outputPanel layout="block" styleClass="requiredBlock">
        				<apex:actionRegion>
        					<apex:inputField value="{!MarketingReimbursement.Pre_Approval_Required__c}" required="true">
        						<apex:actionSupport event="onchange" rerender="preApprovalFormContainer" />
        					</apex:inputField>
        				</apex:actionRegion>
        			</apex:outputPanel>
        		</apex:pageBlockSectionItem>
        	</apex:pageBlockSection>
        	
        	<apex:outputPanel id="preApprovalFormContainer">
        	<apex:pageBlockSection id="preApprovalForm" title="Pre-Approval Form" columns="2" rendered="{!(marketingReimbursement.Pre_Approval_Required__c =='Yes')}" collapsible="False">
        		<apex:pageBlockSectionItem   >
        			<apex:outputLabel value="{!$ObjectType.Marketing_Reimbursement_Forms__c.Fields.Northstar_Registered_Representative__c.Label}" />
        			<apex:outputPanel layout="block" styleClass="requiredInput">
        				<apex:inputField value="{!marketingReimbursementForm.Northstar_Registered_Representative__c}" required="true"/>
        			</apex:outputPanel>
        		</apex:pageBlockSectionItem>

 
All,
I have a requirement to update a trigger to include Trigger.OldMap so that if a user edits a completed task, it doesn't fire the trigger again. Once I added Trigger.OldMap to the trigger, my test coverage went from 95% to 0%. Adding an Update to the inserted Task in the test code does not seem to help either. Below is my code:

Trigger:
trigger SalesBlitzProcess on Task (after insert, after update) {
    if(!RecursiveTriggerHelper.isAlreadyModified()){
        RecursiveTriggerHelper.setAlreadyModified();{
            Task[] taskOldList = trigger.IsDelete ? null : trigger.old;
            Task[] taskNewList = trigger.IsDelete ? trigger.old : trigger.new;
            if(trigger.oldMap != null) {
                for(task tsk: trigger.new) {
                    if(tsk.isClosed && trigger.oldMap.get(tsk.Id).isClosed == false){
                        new SalesBlitzProcess(trigger.Old, trigger.New).executeLeftMessage();
                        new SalesBlitzProcess(trigger.Old, trigger.New).executeContinueProcess();
                        new SalesBlitzProcess(trigger.Old, trigger.New).executeNotNow();
                        new SalesBlitzProcess(trigger.Old, trigger.New).executeHardNo();
                    }
                }
            }
        }
    }
}



Class
public class SalesBlitzProcess {
    //Grab List of tasks
    protected final Task[] taskNewList;
    protected final Task[] taskOldList;
    
    public SalesBlitzProcess (Task[] taskOldList, Task[] taskNewList){
        this.taskNewList = taskNewList;
        this.taskOldList = taskOldList;
    }
    
    List<Task> taskList = new List<Task>();
    List<Opportunity> oppList = new List<Opportunity>();
    Task t;
    Opportunity o;
    Contact c;
    Account a;
    
    //Left Message - Create new Tasks if the following Outcomes == 'Left Message' || 'No Answer'
    Set<Contact> cSet = new Set<Contact>();
    public void executeLeftMessage(){
        for(Task tsk : taskNewList){
            if(tsk.Status =='Completed' && tsk.Subject == 'Sales Blitz Call - Day 1' && (tsk.Outcome__c == 'Left Message' || tsk.Outcome__c == 'No Answer')){
                //Set c.Nurture_Paused__c = True; and c.Send_Day_1_Follow_Up_Email__c = true;
                if(tsk.WhoId != null && String.valueOf(tsk.whoId).substring(0,3) == '003') {
                    c = new Contact(Id = tsk.whoId);
                    c.Nurture_Paused__c = true;
                    c.Send_Day_1_Follow_Up_Email__c = true;
                    cSet.add(c);
                }
                t = new Task();
                t.OwnerId = tsk.OwnerId;
                t.WhoId = tsk.WhoId;
                t.Subject = 'Sales Blitz Call - Day 3';
                t.Status = 'Not Started';
                t.ActivityDate = System.Today().addDays(2);
                taskList.add(t);
                
            } else if (tsk.Status =='Completed' && tsk.Subject == 'Sales Blitz Call - Day 3' && (tsk.Outcome__c == 'Left Message' || tsk.Outcome__c == 'No Answer')){
                t = new Task();
                t.OwnerId = tsk.OwnerId;
                t.WhoId = tsk.WhoId;
                t.Subject = 'Sales Blitz Call - Day 5';
                t.Status = 'Not Started';
                t.ActivityDate = System.Today().addDays(2);
                taskList.add(t);
                
            } else if (tsk.Status =='Completed' && tsk.Subject == 'Sales Blitz Call - Day 5' && (tsk.Outcome__c == 'Left Message' || tsk.Outcome__c == 'No Answer')){
                //c.Send_Day_1_Follow_Up_Email__c = true;
                if(tsk.WhoId != null && String.valueOf(tsk.whoId).substring(0,3) == '003') {
                    c = new Contact(Id = tsk.whoId);
                    c.Send_Day_5_Follow_Up_Email__c = true;
                    cSet.add(c);
                }
                t = new Task();
                t.OwnerId = tsk.OwnerId;
                t.WhoId = tsk.WhoId;
                t.Subject = 'Sales Blitz Call - Day 8';
                t.Status = 'Not Started';
                t.ActivityDate = System.Today().addDays(3);
                taskList.add(t);
                
            } else if (tsk.Status =='Completed' && tsk.Subject == 'Sales Blitz Call - Day 8' && (tsk.Outcome__c == 'Left Message' || tsk.Outcome__c == 'No Answer')){
                //Set c.Nurture_Paused__c = False;
                if(tsk.WhoId != null && String.valueOf(tsk.whoId).substring(0,3) == '003') {
                    c = new Contact(Id = tsk.whoId);
                    c.Nurture_Paused__c = false;
                    c.Send_Day_1_Follow_Up_Email__c = false;
                    c.Send_Day_5_Follow_Up_Email__c = false;
                    cSet.add(c);
                }
            }
        }
        
        If(!taskList.isEmpty()){
            insert taskList;
        }
        If(!cSet.isEmpty()){
            update new List <Contact>(cSet);
        }
    }
    
    //Continue Process - Create Opportunity if Task has the following outcomes
    Set<Id> ContactIds = new Set<Id>();
    public void executeContinueProcess(){
        for(Task tsk : taskNewList){
            if(tsk.Status =='Completed' && (tsk.Outcome__c == 'Set First Advisor Briefing'
                                            || tsk.Outcome__c == 'Set Qualified Meeting'
                                            || tsk.Outcome__c == 'Set Existing Producer Meeting'
                                            || tsk.Outcome__c == 'Set Touch Base Meeting'
                                            || tsk.Outcome__c == 'Proposal Needed'
                                            || tsk.Outcome__c == 'Verbal Commitment')){
                                                String tId = tsk.WhoId;
                                                if(String.ValueOf(tsk.WhoId).substring(0,3) == '003'){
                                                    ContactIds.add(tsk.WhoId);
                                                }
                                            }
        }
        if(!ContactIds.isEmpty())
        {
            Map<Id, Contact> cIdMap = new Map<Id, Contact>([Select Id, AccountId, Account.Name, Nurture_Paused__c FROM Contact Where Id in:ContactIds]);
            Set<Id> accountIds=new Set<Id>();
            for(Task tsk : taskNewList)
            {
                if(tsk.WhoId != null && cIdMap.get(tsk.WhoId) != null){
                    //o.AccountId = cIdMap.get(tsk.WhoId).AccountId;
                    accountIds.add(cIdMap.get(tsk.WhoId).AccountId);
                }
            }
            
            if(!accountIds.isEmpty())
            {
                Map<Id,Account> mapAccount=new Map<Id,Account>([SELECT Id, (SELECT Id FROM Opportunities) FROM Account where Id IN : accountIds]);
                for(Id accId:accountIds)
                {
                    if(mapAccount.containsKey(accId))
                    {
                        if(mapAccount.get(accId).Opportunities.size() == 0)
                        {
                            Opportunity opp=new Opportunity();
                            opp.Name = 'New Sales Blitz Opportunity';
                            opp.AccountId = accId;
                            opp.StageName = 'New';
                            opp.Opportunity_Potential__c = 0.00;
                            opp.CloseDate = Date.today();
                            opp.OriginalOpportunitySource__c = 'Sales Blitz';
                            oppList.add(opp);
                        }
                    }
                }
                
            }
        }
        If(!oppList.isEmpty()){
            insert oppList;
        }
    }
    
    //Not Now - Check Nurture Paused for 3 weeks if Outcome__c == Follow Up Or TBD, then unpause.
    public void executeNotNow(){
        for(Task tsk : taskNewList){
            if(tsk.Status =='Completed' && (tsk.Outcome__c == 'Follow Up' || tsk.Outcome__c == 'TBD')){
                //Set c.Nurture_Paused__c = True;
                if(tsk.WhoId != null && String.valueOf(tsk.whoId).substring(0,3) == '003') {
                    c = new Contact(Id = tsk.whoId);
                    c.Nurture_Paused__c = true;
                    cSet.add(c);
                }
                t = new Task();
                t.OwnerId = '005F0000004E8iS';
                t.WhoId = tsk.WhoId;
                t.Subject = 'Unpause Nurture - 3 Weeks';
                t.Status = 'Not Started';
                t.Outcome__c = 'Unpause Nurture';
                t.ActivityDate = System.Today().addDays(21);
                taskList.add(t);
            }
            //After 3 weeks, unpause nurture
            //Once closed, uncheck checkbox
            else if (tsk.Status =='Completed' && tsk.Subject == 'Unpause Nurture - 3 Weeks' && tsk.Outcome__c == 'Unpause Nurture'){
                //Set c.Nurture_Paused__c = False;
                if(tsk.WhoId != null && String.valueOf(tsk.whoId).substring(0,3) == '003') {
                    c = new Contact(Id = tsk.whoId);
                    c.Nurture_Paused__c = false;
                    cSet.add(c);
                }
            }
        }
        If(!taskList.isEmpty()){
            insert t;
        }
        if(!cSet.isEmpty()){
            update new List <Contact>(cSet);
        }
    }
    //Hard No - Create reminder task to close in 90 days to unpause nurture
    public void executeHardNo(){
        for(Task tsk : taskNewList){
            if(tsk.Status =='Completed' && tsk.Outcome__c == 'Not Interested' && tsk.Subject.contains('Sales Blitz')){
                //Set c.Nurture_Paused__c = True;
                if(tsk.WhoId != null && String.valueOf(tsk.whoId).substring(0,3) == '003') {
                    c = new Contact(Id = tsk.whoId);
                    c.Nurture_Paused__c = true;
                    cSet.add(c);
                }
                t = new Task();
                t.OwnerId = '005F0000004E8iS';
                t.WhoId = tsk.WhoId;
                t.Subject = 'Unpause Nurture - 3 Months';
                t.Status = 'Not Started';
                t.Outcome__c = 'Unpause Nurture';
                t.ActivityDate = System.Today().addDays(90);
                taskList.add(t);
            }
            //After 3 months, unpause nurture
            //Once closed, uncheck checkbox
            else if (tsk.Status =='Completed' && tsk.Subject == 'Unpause Nurture - 3 Months' && tsk.Outcome__c == 'Unpause Nurture'){
                //Set c.Nurture_Paused__c = False;
                if(tsk.WhoId != null && String.valueOf(tsk.whoId).substring(0,3) == '003') {
                    c = new Contact(Id = tsk.whoId);
                    c.Nurture_Paused__c = false;
                    cSet.add(c);
                }
            }
        }
        If(!taskList.isEmpty()){
            insert t;
        }
        if(!cSet.isEmpty()){
            update new List <Contact>(cSet);
        }
    }
}

Test Class
@isTest
private class testSalesBlitzProcess {
    
    static testMethod void LeftMessage1(){
        Profile p=[SELECT Id From Profile WHERE Name='Standard User'];
        User u =new User(Alias = 'newUser' , Email ='testuser@361capital.com' , EmailEncodingKey = 'UTF-8' , LastName = 'Testing',
                         LanguageLocaleKey='en_US', LocaleSidKey='en_US', TimeZoneSidKey = 'GMT', UserName='testuser@361capital.com',ProfileId=p.Id);
        insert u;
        
        Account testAcct = new Account (Name = 'My Test Account');
        insert testAcct;
        
        Contact testCont = new Contact();
        testCont.FirstName = 'Test';
        testCont.LastName = 'User';
        testCont.AccountId = testAcct.Id;
        insert testCont;
        
        Task tsk = new Task();
        tsk.OwnerId = u.id;
        tsk.WhoId = testCont.Id;
        tsk.Subject = 'Sales Blitz Call - Day 1';
        tsk.Outcome__c = 'Left Message';
        tsk.Status = 'Completed';
        tsk.ActivityDate = System.Today().addDays(1);
        insert tsk;
    }
    
        static testMethod void LeftMessage1TESTNULL(){
        Profile p=[SELECT Id From Profile WHERE Name='Standard User'];
        User u =new User(Alias = 'newUser' , Email ='testuser@361capital.com' , EmailEncodingKey = 'UTF-8' , LastName = 'Testing',
                         LanguageLocaleKey='en_US', LocaleSidKey='en_US', TimeZoneSidKey = 'GMT', UserName='testuser@361capital.com',ProfileId=p.Id);
        insert u;
        
        Account testAcct = new Account (Name = 'My Test Account');
        insert testAcct;
        
        Contact testCont = new Contact();
        testCont.FirstName = 'Test';
        testCont.LastName = 'User';
        testCont.AccountId = testAcct.Id;
        insert testCont;
        
        Task tsk = new Task();
        tsk.OwnerId = u.id;
        tsk.WhoId = testCont.Id;
        tsk.Subject = 'Sales Blitz Call - Day 1';
        tsk.Outcome__c = 'Left Message';
        tsk.Status = null;
        tsk.ActivityDate = System.Today().addDays(1);
        insert tsk;
        
        test.startTest();
        tsk.Status='Completed';
        update tsk;
        test.stopTest();
        
         System.assertEquals(tsk.Status = 'Completed', null);
    }
    
    static testMethod void LeftMessage2(){
        Profile p=[SELECT Id From Profile WHERE Name='Standard User'];
        User u =new User(Alias = 'newUser' , Email ='testuser@361capital.com' , EmailEncodingKey = 'UTF-8' , LastName = 'Testing',
                         LanguageLocaleKey='en_US', LocaleSidKey='en_US', TimeZoneSidKey = 'GMT', UserName='testuser@361capital.com',ProfileId=p.Id);
        insert u;
        
        Account testAcct = new Account (Name = 'My Test Account');
        insert testAcct;
        
        Contact testCont = new Contact();
        testCont.FirstName = 'Test';
        testCont.LastName = 'User';
        testCont.AccountId = testAcct.Id;
        insert testCont;
        
        Task tsk = new Task();
        tsk.OwnerId = u.id;
        tsk.WhoId = testCont.Id;
        tsk.Subject = 'Sales Blitz Call - Day 3';
        tsk.Outcome__c = 'Left Message';
        tsk.Status = 'Completed';
        tsk.ActivityDate = System.Today().addDays(1);
        insert tsk;
    }
    
    static testMethod void LeftMessage3(){
        Profile p=[SELECT Id From Profile WHERE Name='Standard User'];
        User u =new User(Alias = 'newUser' , Email ='testuser@361capital.com' , EmailEncodingKey = 'UTF-8' , LastName = 'Testing',
                         LanguageLocaleKey='en_US', LocaleSidKey='en_US', TimeZoneSidKey = 'GMT', UserName='testuser@361capital.com',ProfileId=p.Id);
        insert u;
        
        Account testAcct = new Account (Name = 'My Test Account');
        insert testAcct;
        
        Contact testCont = new Contact();
        testCont.FirstName = 'Test';
        testCont.LastName = 'User';
        testCont.AccountId = testAcct.Id;
        insert testCont;
        
        Task tsk = new Task();
        tsk.OwnerId = u.id;
        tsk.WhoId = testCont.Id;
        tsk.Subject = 'Sales Blitz Call - Day 5';
        tsk.Outcome__c = 'Left Message';
        tsk.Status = 'Completed';
        tsk.ActivityDate = System.Today().addDays(1);
        insert tsk;
    }
    
    static testMethod void LeftMessage4(){
        Profile p=[SELECT Id From Profile WHERE Name='Standard User'];
        User u =new User(Alias = 'newUser' , Email ='testuser@361capital.com' , EmailEncodingKey = 'UTF-8' , LastName = 'Testing',
                         LanguageLocaleKey='en_US', LocaleSidKey='en_US', TimeZoneSidKey = 'GMT', UserName='testuser@361capital.com',ProfileId=p.Id);
        insert u;
        
        Account testAcct = new Account (Name = 'My Test Account');
        insert testAcct;
        
        Contact testCont = new Contact();
        testCont.FirstName = 'Test';
        testCont.LastName = 'User';
        testCont.AccountId = testAcct.Id;
        insert testCont;
        
        Task tsk = new Task();
        tsk.OwnerId = u.id;
        tsk.WhoId = testCont.Id;
        tsk.Subject = 'Sales Blitz Call - Day 8';
        tsk.Outcome__c = 'Left Message';
        tsk.Status = 'Completed';
        tsk.ActivityDate = System.Today().addDays(1);
        insert tsk;
    }
    
    static testMethod void notNow1(){
        Profile p=[SELECT Id From Profile WHERE Name='Standard User'];
        User u =new User(Alias = 'newUser' , Email ='testuser@361capital.com' , EmailEncodingKey = 'UTF-8' , LastName = 'Testing',
                         LanguageLocaleKey='en_US', LocaleSidKey='en_US', TimeZoneSidKey = 'GMT', UserName='testuser@361capital.com',ProfileId=p.Id);
        insert u;
        
        Account testAcct = new Account (Name = 'My Test Account');
        insert testAcct;
        
        Contact testCont = new Contact();
        testCont.FirstName = 'Test';
        testCont.LastName = 'User';
        testCont.AccountId = testAcct.Id;
        insert testCont;
        
        Task tsk = new Task();
        tsk.OwnerId = u.id;
        tsk.WhoId = testCont.Id;
        tsk.Subject = 'Unpause Nurture - 3 Weeks';
        tsk.Outcome__c = 'Follow Up';
        tsk.Status = 'Completed';
        tsk.ActivityDate = System.Today().addDays(21);
        insert tsk;
    }
    
    static testMethod void notNow2(){
        Profile p=[SELECT Id From Profile WHERE Name='Standard User'];
        User u =new User(Alias = 'newUser' , Email ='testuser@361capital.com' , EmailEncodingKey = 'UTF-8' , LastName = 'Testing',
                         LanguageLocaleKey='en_US', LocaleSidKey='en_US', TimeZoneSidKey = 'GMT', UserName='testuser@361capital.com',ProfileId=p.Id);
        insert u;
        
        Account testAcct = new Account (Name = 'My Test Account');
        insert testAcct;
        
        Contact testCont = new Contact();
        testCont.FirstName = 'Test';
        testCont.LastName = 'User';
        testCont.AccountId = testAcct.Id;
        insert testCont;
        
        Task tsk = new Task();
        tsk.OwnerId = u.id;
        tsk.WhoId = testCont.Id;
        tsk.Subject = 'Unpause Nurture - 3 Weeks';
        tsk.Outcome__c = 'TBD';
        tsk.Status = 'Completed';
        tsk.ActivityDate = System.Today().addDays(21);
        insert tsk;
    }
    
    static testMethod void notNow3(){
        Profile p=[SELECT Id From Profile WHERE Name='Standard User'];
        User u =new User(Alias = 'newUser' , Email ='testuser@361capital.com' , EmailEncodingKey = 'UTF-8' , LastName = 'Testing',
                         LanguageLocaleKey='en_US', LocaleSidKey='en_US', TimeZoneSidKey = 'GMT', UserName='testuser@361capital.com',ProfileId=p.Id);
        insert u;
        
        Account testAcct = new Account (Name = 'My Test Account');
        insert testAcct;
        
        Contact testCont = new Contact();
        testCont.FirstName = 'Test';
        testCont.LastName = 'User';
        testCont.AccountId = testAcct.Id;
        insert testCont;
        
        Task tsk = new Task();
        tsk.OwnerId = u.id;
        tsk.WhoId = testCont.Id;
        tsk.Subject = 'Unpause Nurture - 3 Weeks';
        tsk.Outcome__c = 'Unpause Nurture';
        tsk.Status = 'Completed';
        tsk.ActivityDate = System.Today().addDays(21);
        insert tsk;
    }
    
    static testMethod void HardNo1(){
        Profile p=[SELECT Id From Profile WHERE Name='Standard User'];
        User u =new User(Alias = 'newUser' , Email ='testuser@361capital.com' , EmailEncodingKey = 'UTF-8' , LastName = 'Testing',
                         LanguageLocaleKey='en_US', LocaleSidKey='en_US', TimeZoneSidKey = 'GMT', UserName='testuser@361capital.com',ProfileId=p.Id);
        insert u;
        
        Account testAcct = new Account (Name = 'My Test Account');
        insert testAcct;
        
        Contact testCont = new Contact();
        testCont.FirstName = 'Test';
        testCont.LastName = 'User';
        testCont.AccountId = testAcct.Id;
        insert testCont;
        
        Task tsk = new Task();
        tsk.OwnerId = u.id;
        tsk.WhoId = testCont.Id;
        tsk.Subject = 'Unpause Nurture - 3 Months';
        tsk.Outcome__c = 'Not Interested';
        tsk.Status = 'Completed';
        tsk.ActivityDate = System.Today().addDays(21);
        insert tsk;
    }
        static testMethod void HardNo2(){
        Profile p=[SELECT Id From Profile WHERE Name='Standard User'];
        User u =new User(Alias = 'newUser' , Email ='testuser@361capital.com' , EmailEncodingKey = 'UTF-8' , LastName = 'Testing',
                         LanguageLocaleKey='en_US', LocaleSidKey='en_US', TimeZoneSidKey = 'GMT', UserName='testuser@361capital.com',ProfileId=p.Id);
        insert u;
        
        Account testAcct = new Account (Name = 'My Test Account');
        insert testAcct;
        
        Contact testCont = new Contact();
        testCont.FirstName = 'Test';
        testCont.LastName = 'User';
        testCont.AccountId = testAcct.Id;
        insert testCont;
        
        Task tsk = new Task();
        tsk.OwnerId = u.id;
        tsk.WhoId = testCont.Id;
        tsk.Subject = 'Unpause Nurture - 3 Months';
        tsk.Outcome__c = 'Unpause Nurture';
        tsk.Status = 'Completed';
        tsk.ActivityDate = System.Today().addDays(21);
        insert tsk;
    }
    
    static testMethod void testOpportunity1(){
        //Create Account
        Account testAcct = new Account (Name = 'My Test Account');
        insert testAcct;
        
        Contact testCont = new Contact();
        testCont.FirstName = 'Test';
        testCont.LastName = 'User';
        testCont.AccountId = testAcct.Id;
        insert testCont;
        
        Task tsk = new Task();
        tsk.OwnerId = '005F0000003KmQ0';
        tsk.WhoId = testCont.Id;
        tsk.Subject = 'Create Opportunity';
        tsk.Outcome__c = 'Set First Advisor Briefing';
        tsk.Status = 'Completed';
        tsk.ActivityDate = System.Today().addDays(1);
        insert tsk;
        
        //Create Opportunity
        Opportunity oppt = new Opportunity();
        oppt.AccountId = testAcct.Id;
        oppt.Name = 'New Opportunity Name';
        oppt.Opportunity_Potential__c = 100.00;
        oppt.StageName = 'New';
        oppt.Amount = 5000;
        oppt.CloseDate = System.Today();
        insert oppt;
    }
    
    static testMethod void testOpportunity2(){
        //Create Account
        Account testAcct = new Account (Name = 'My Test Account');
        insert testAcct;
        
        Contact testCont = new Contact();
        testCont.FirstName = 'Test';
        testCont.LastName = 'User';
        testCont.AccountId = testAcct.Id;
        insert testCont;
        
        Task tsk = new Task();
        tsk.OwnerId = '005F0000003KmQ0';
        tsk.WhoId = testCont.Id;
        tsk.Subject = 'Create Opportunity';
        tsk.Outcome__c = 'Set Qualified Meeting';
        tsk.Status = 'Completed';
        tsk.ActivityDate = System.Today().addDays(1);
        insert tsk;
        
        //Create Opportunity
        Opportunity oppt = new Opportunity();
        oppt.AccountId = testAcct.Id;
        oppt.Name = 'New Opportunity Name';
        oppt.Opportunity_Potential__c = 100.00;
        oppt.StageName = 'New';
        oppt.Amount = 5000;
        oppt.CloseDate = System.Today();
        insert oppt;
    }
    
    static testMethod void testOpportunity3(){
        //Create Account
        Account testAcct = new Account (Name = 'My Test Account');
        insert testAcct;
        
        Contact testCont = new Contact();
        testCont.FirstName = 'Test';
        testCont.LastName = 'User';
        testCont.AccountId = testAcct.Id;
        insert testCont;
        
        Task tsk = new Task();
        tsk.OwnerId = '005F0000003KmQ0';
        tsk.WhoId = testCont.Id;
        tsk.Subject = 'Create Opportunity';
        tsk.Outcome__c = 'Set Existing Producer Meeting';
        tsk.Status = 'Completed';
        tsk.ActivityDate = System.Today().addDays(1);
        insert tsk;
        
        //Create Opportunity
        Opportunity oppt = new Opportunity();
        oppt.AccountId = testAcct.Id;
        oppt.Name = 'New Opportunity Name';
        oppt.Opportunity_Potential__c = 100.00;
        oppt.StageName = 'New';
        oppt.Amount = 5000;
        oppt.CloseDate = System.Today();
        insert oppt;
    }
    
    static testMethod void testOpportunity4(){
        //Create Account
        Account testAcct = new Account (Name = 'My Test Account');
        insert testAcct;
        
        Contact testCont = new Contact();
        testCont.FirstName = 'Test';
        testCont.LastName = 'User';
        testCont.AccountId = testAcct.Id;
        insert testCont;
        
        Task tsk = new Task();
        tsk.OwnerId = '005F0000003KmQ0';
        tsk.WhoId = testCont.Id;
        tsk.Subject = 'Create Opportunity';
        tsk.Outcome__c = 'Set Touch Base Meeting';
        tsk.Status = 'Completed';
        tsk.ActivityDate = System.Today().addDays(1);
        insert tsk;
        
        //Create Opportunity
        Opportunity oppt = new Opportunity();
        oppt.AccountId = testAcct.Id;
        oppt.Name = 'New Opportunity Name';
        oppt.Opportunity_Potential__c = 100.00;
        oppt.StageName = 'New';
        oppt.Amount = 5000;
        oppt.CloseDate = System.Today();
        insert oppt;
    }
    
    static testMethod void testOpportunity5(){
        //Create Account
        Account testAcct = new Account (Name = 'My Test Account');
        insert testAcct;
        
        Contact testCont = new Contact();
        testCont.FirstName = 'Test';
        testCont.LastName = 'User';
        testCont.AccountId = testAcct.Id;
        insert testCont;
        
        Task tsk = new Task();
        tsk.OwnerId = '005F0000003KmQ0';
        tsk.WhoId = testCont.Id;
        tsk.Subject = 'Create Opportunity';
        tsk.Outcome__c = 'Proposal Needed';
        tsk.Status = 'Completed';
        tsk.ActivityDate = System.Today().addDays(1);
        insert tsk;
        
        //Create Opportunity
        Opportunity oppt = new Opportunity();
        oppt.AccountId = testAcct.Id;
        oppt.Name = 'New Opportunity Name';
        oppt.Opportunity_Potential__c = 100.00;
        oppt.StageName = 'New';
        oppt.Amount = 5000;
        oppt.CloseDate = System.Today();
        insert oppt;
    }
    
    static testMethod void testOpportunity6(){
        //Create Account
        Account testAcct = new Account (Name = 'My Test Account');
        insert testAcct;
        
        Contact testCont = new Contact();
        testCont.FirstName = 'Test';
        testCont.LastName = 'User';
        testCont.AccountId = testAcct.Id;
        insert testCont;
        
        Task tsk = new Task();
        tsk.OwnerId = '005F0000003KmQ0';
        tsk.WhoId = testCont.Id;
        tsk.Subject = 'Create Opportunity';
        tsk.Outcome__c = 'Verbal Commitment';
        tsk.Status = 'Completed';
        tsk.ActivityDate = System.Today().addDays(1);
        insert tsk;
        
        //Create Opportunity
        Opportunity oppt = new Opportunity();
        oppt.AccountId = testAcct.Id;
        oppt.Name = 'New Opportunity Name';
        oppt.Opportunity_Potential__c = 100.00;
        oppt.StageName = 'New';
        oppt.Amount = 5000;
        oppt.CloseDate = System.Today();
        insert oppt;
    }
}
All,
I was asked to update some code so that instead of always inserting an Opportunity based on the Task insertion criteria, it only inserts an Opportunity if the related Account doesn't already have one. Usually I think this would be solved using Account.Opportunities.Size()==0, but I'm inserting the Opportunity based off a Task creation and finding the Account associated to the Contact using AccountId. And
​ cIdMap.get(tsk.whoId).AccountId.Opportunities.Size()==0
throws an Invalid foreign key relationship: Contact.AccountId error.

Does anyone know how I could solve this?

Here is the full code. The method is on lines 82-118.
public class SalesBlitzProcess {
    //Grab Lst of tasks
    protected final Task[] taskNewList;
    protected final Task[] taskOldList;
    
    public SalesBlitzProcess (Task[] taskOldList, Task[] taskNewList){
        this.taskNewList = taskNewList;
        this.taskOldList = taskOldList;
    }
    
    List<Task> taskList = new List<Task>();
    List<Opportunity> oppList = new List<Opportunity>();
    Task t;
    Opportunity o;
    Contact c;
    Account a;
    
    //Left Message - Create new Tasks if the following Outcomes == 'Left Message' || 'No Answer'
    Set<Contact> cSet = new Set<Contact>();
    public void executeLeftMessage(){
        for(Task tsk : taskNewList){
            if(tsk.Status =='Completed' && tsk.Subject == 'Sales Blitz Call - Day 1' && (tsk.Outcome__c == 'Left Message' || tsk.Outcome__c == 'No Answer')){
                //Set c.Nurture_Paused__c = True; and c.Send_Day_1_Follow_Up_Email__c = true;
                if(tsk.WhoId != null && String.valueOf(tsk.whoId).substring(0,3) == '003') {
                    c = new Contact(Id = tsk.whoId);
                    c.Nurture_Paused__c = true;
                    c.Send_Day_1_Follow_Up_Email__c = true;
                    cSet.add(c);
                }
                t = new Task();
                t.OwnerId = tsk.OwnerId;
                t.WhoId = tsk.WhoId;
                t.Subject = 'Sales Blitz Call - Day 3';
                t.Status = 'Not Started';
                t.ActivityDate = System.Today().addDays(2);
                taskList.add(t);
                
            } else if (tsk.Status =='Completed' && tsk.Subject == 'Sales Blitz Call - Day 3' && (tsk.Outcome__c == 'Left Message' || tsk.Outcome__c == 'No Answer')){
                t = new Task();
                t.OwnerId = tsk.OwnerId;
                t.WhoId = tsk.WhoId;
                t.Subject = 'Sales Blitz Call - Day 5';
                t.Status = 'Not Started';
                t.ActivityDate = System.Today().addDays(2);
                taskList.add(t);
                
            } else if (tsk.Status =='Completed' && tsk.Subject == 'Sales Blitz Call - Day 5' && (tsk.Outcome__c == 'Left Message' || tsk.Outcome__c == 'No Answer')){
                //c.Send_Day_1_Follow_Up_Email__c = true;
                if(tsk.WhoId != null && String.valueOf(tsk.whoId).substring(0,3) == '003') {
                    c = new Contact(Id = tsk.whoId);
                    c.Send_Day_5_Follow_Up_Email__c = true;
                    cSet.add(c);
                }
                t = new Task();
                t.OwnerId = tsk.OwnerId;
                t.WhoId = tsk.WhoId;
                t.Subject = 'Sales Blitz Call - Day 8';
                t.Status = 'Not Started';
                t.ActivityDate = System.Today().addDays(3);
                taskList.add(t);
                
            } else if (tsk.Status =='Completed' && tsk.Subject == 'Sales Blitz Call - Day 8' && (tsk.Outcome__c == 'Left Message' || tsk.Outcome__c == 'No Answer')){
                //Set c.Nurture_Paused__c = False;
                if(tsk.WhoId != null && String.valueOf(tsk.whoId).substring(0,3) == '003') {
                    c = new Contact(Id = tsk.whoId);
                    c.Nurture_Paused__c = false;
                    c.Send_Day_1_Follow_Up_Email__c = false;
                    c.Send_Day_5_Follow_Up_Email__c = false;
                    cSet.add(c);
                }
            }
        }
        
        If(!taskList.isEmpty()){
            insert taskList;
        }
        If(!cSet.isEmpty()){
            update new List <Contact>(cSet);
        }
    }
    
    //Continue Process - Create Opportunity if Task has the following outcomes
    Set<Id> ContactIds = new Set<Id>();
    public void executeContinueProcess(){
        for(Task tsk : taskNewList){
            if(tsk.Status =='Completed' && (tsk.Outcome__c == 'Set First Advisor Briefing'
                || tsk.Outcome__c == 'Set Qualified Meeting'
                || tsk.Outcome__c == 'Set Existing Producer Meeting'
                || tsk.Outcome__c == 'Set Touch Base Meeting'
                || tsk.Outcome__c == 'Proposal Needed'
                || tsk.Outcome__c == 'Verbal Commitment')){
                    String tId = tsk.WhoId;
                    if(String.ValueOf(tsk.WhoId).substring(0,3) == '003'){
                        ContactIds.add(tsk.WhoId);
                    }
                    
                    List<Contact> taskContacts = [Select Id, AccountId, Account.Name, Nurture_Paused__c FROM Contact Where Id in:ContactIds];
                    Map<Id, Contact> cIdMap = new Map<Id, Contact>(taskContacts);
                    //Create Opportunity if Task has the outcome above
                    o = new Opportunity();
                    //system.debug('==========Contact Id ========'+tsk.WhoId);
                    //system.debug('==========Contact record ========'+cIdMap.get(tsk.WhoId));
                    //system.debug('==========account Id ========'+cIdMap.get(tsk.WhoId).AccountId);
                    if(tsk.WhoId != null && cIdMap.get(tsk.WhoId) != null){
                        o.AccountId = cIdMap.get(tsk.WhoId).AccountId;
                    }
                    o.Name = 'New Sales Blitz Opportunity';
                    o.StageName = 'New';
                    o.Opportunity_Potential__c = 0.00;
                    o.CloseDate = Date.today();
                    o.OriginalOpportunitySource__c = 'Sales Blitz';
                    oppList.add(o);
                }
        }
        If(!oppList.isEmpty()){
            insert oppList;
        }
    }
    
    //Not Now - Check Nurture Paused for 3 weeks if Outcome__c == Follow Up Or TBD, then unpause.
    public void executeNotNow(){
        for(Task tsk : taskNewList){
            if(tsk.Status =='Completed' && (tsk.Outcome__c == 'Follow Up' || tsk.Outcome__c == 'TBD')){
                //Set c.Nurture_Paused__c = True;
                if(tsk.WhoId != null && String.valueOf(tsk.whoId).substring(0,3) == '003') {
                    c = new Contact(Id = tsk.whoId);
                    c.Nurture_Paused__c = true;
                    cSet.add(c);
                }
                t = new Task();
                t.OwnerId = tsk.OwnerId;
                t.WhoId = tsk.WhoId;
                t.Subject = 'Unpause Nurture - 3 Weeks';
                t.Status = 'Not Started';
                t.Outcome__c = 'Unpause Nurture';
                t.ActivityDate = System.Today().addDays(21);
                taskList.add(t);
            }
            //After 3 weeks, unpause nurture
            //Once closed, uncheck checkbox
            else if (tsk.Status =='Completed' && tsk.Subject == 'Unpause Nurture - 3 Weeks' && tsk.Outcome__c == 'Unpause Nurture'){
                //Set c.Nurture_Paused__c = False;
                if(tsk.WhoId != null && String.valueOf(tsk.whoId).substring(0,3) == '003') {
                    c = new Contact(Id = tsk.whoId);
                    c.Nurture_Paused__c = false;
                    cSet.add(c);
                }
            }
        }
        If(!taskList.isEmpty()){
            insert t;
        }
        if(!cSet.isEmpty()){
            update new List <Contact>(cSet);
        }
    }
    //Hard No - Create reminder task to close in 90 days to unpause nurture
    public void executeHardNo(){
        for(Task tsk : taskNewList){
            if(tsk.Status =='Completed' && tsk.Outcome__c == 'Not Interested' && tsk.Subject.contains('Sales Blitz')){
                //Set c.Nurture_Paused__c = True;
                if(tsk.WhoId != null && String.valueOf(tsk.whoId).substring(0,3) == '003') {
                    c = new Contact(Id = tsk.whoId);
                    c.Nurture_Paused__c = true;
                    cSet.add(c);
                }
                t = new Task();
                t.OwnerId = tsk.OwnerId;
                t.WhoId = tsk.WhoId;
                t.Subject = 'Unpause Nurture - 3 Months';
                t.Status = 'Not Started';
                t.Outcome__c = 'Unpause Nurture';
                t.ActivityDate = System.Today().addDays(90);
                taskList.add(t);
            }
            //After 3 months, unpause nurture
            //Once closed, uncheck checkbox
            else if (tsk.Status =='Completed' && tsk.Subject == 'Unpause Nurture - 3 Months' && tsk.Outcome__c == 'Unpause Nurture'){
                //Set c.Nurture_Paused__c = False;
                if(tsk.WhoId != null && String.valueOf(tsk.whoId).substring(0,3) == '003') {
                    c = new Contact(Id = tsk.whoId);
                    c.Nurture_Paused__c = false;
                    cSet.add(c);
                }
            }
        }
        If(!taskList.isEmpty()){
            insert t;
        }
        if(!cSet.isEmpty()){
            update new List <Contact>(cSet);
        }
    }
}

 

All,
I have two problems I'm trying to resolve in my trigger. FYI I'm using the design pattern of one trigger per object, so the class holds the code, and then execute the methods in the trigger. 

1.) Method executeLeftMesssage:
Line 42, updates the checkbox to true given the conditions, which is working perfectly. But at the end of this method (Line 74)  I'm trying to update the checkbox to false given Line 71 evaluates to true, but it's not updating the field in the list. What am I missing here?

2.) Method executeContinueProcess:
Line 104, when creating the new opportunity, I'm trying to grab the AccountId, but it keeps returning blank. How can I get this populate in the new opportunity?
 

public class SalesBlitzProcess {
    //Grab List of tasks
    protected final Task[] taskNewList;
    protected final Task[] taskOldList;
    
    public SalesBlitzProcess (Task[] taskOldList, Task[] taskNewList){
        this.taskNewList = taskNewList;
        this.taskOldList = taskOldList;
    }
    
    Set<Id> ContactIds = new Set<Id>();
    List<Contact> taskContacts = [Select Id, AccountId, Account.Name, Nurture_Paused__c FROM Contact Where Id in:ContactIds];
    Map<Id, Contact> cIdMap = new Map<Id, Contact>(taskContacts);
    
    List<Task> taskList = new List<Task>();
    List<Opportunity> oppList = new List<Opportunity>();
    Task t;
    Opportunity o;
    Contact c;
    Account a;
      
     //TODO: Create method to Check and Uncheck Nurture_Paused__c Checkbox within the below methods
    public void executeCheckNP(){
        for(Task t :taskNewList){
            String tId = t.WhoId;
            if(String.valueOf(t.whoId).substring(0,3) == '003'){
                ContactIds.add(t.WhoId);
            }
        }
    }

    
    //Left Message Sales Blitz Process
    private static set<Contact> cSet = new set<Contact>();
     public void executeLeftMessage(){
         if(!RecursiveTriggerHelper.isAlreadyModified()){
             RecursiveTriggerHelper.setAlreadyModified();
             for(Task tsk : taskNewList){
                 if(tsk.Status =='Completed' && tsk.Subject == 'Sales Blitz Call - Day 1' && tsk.Outcome__c == 'Left Message'){
                     //TODO: c.Nurture_Paused__c = True;
                     if(tsk.WhoId != null && String.valueOf(tsk.whoId).substring(0,3) == '003') {
                         c = new Contact(Id = tsk.whoId, Nurture_Paused__c = true);
                         cSet.add(c);
                     }
                     t = new Task();
                     t.OwnerId = tsk.OwnerId;
                     t.WhoId = tsk.WhoId;
                     t.Subject = 'Sales Blitz Call - Day 3';
                     t.Status = 'Not Started';
                     t.ActivityDate = System.Today().addDays(2);
                     taskList.add(t);
                     
                 } else if (tsk.Status =='Completed' && tsk.Subject == 'Sales Blitz Call - Day 3' && tsk.Outcome__c == 'Left Message'){
                     t = new Task();
                     t.OwnerId = tsk.OwnerId;
                     t.WhoId = tsk.WhoId;
                     t.Subject = 'Sales Blitz Call - Day 5';
                     t.Status = 'Not Started';
                     t.ActivityDate = System.Today().addDays(2);
                     taskList.add(t);
                     
                 } else if (tsk.Status =='Completed' && tsk.Subject == 'Sales Blitz Call - Day 5' && tsk.Outcome__c == 'Left Message'){
                     t = new Task();
                     t.OwnerId = tsk.OwnerId;
                     t.WhoId = tsk.WhoId;
                     t.Subject = 'Sales Blitz Call - Day 8';
                     t.Status = 'Not Started';
                     t.ActivityDate = System.Today().addDays(3);
                     taskList.add(t);
                     
                 } else if (tsk.Status =='Completed' && tsk.Subject == 'Sales Blitz Call - Day 8' && tsk.Outcome__c == 'Left Message'){
                     //TODO: c.Nurture_Paused__c = False;
                     if(tsk.WhoId != null && String.valueOf(tsk.whoId).substring(0,3) == '003') {
                         c = new Contact(Id = tsk.whoId, Nurture_Paused__c = false);
                         cSet.add(c);
                     }
                 }
             }
         }
         If(!taskList.isEmpty()){
             insert taskList;
             update new List <Contact>(cSet);
         }
     }
    
    //Create Opportunity if Task has the following outcome
    public void executeContinueProcess(){
        for(Task tsk : taskNewList){
            if(tsk.Status =='Completed' && tsk.Subject == 'Create Opportunity' &&
               (tsk.Outcome__c == 'Set First Advisor Briefing'
                || tsk.Outcome__c == 'Set Qualified Meeting'
                || tsk.Outcome__c == 'Set Existing Producer Meeting'
                || tsk.Outcome__c == 'Set Touch Base Meeting'
                || tsk.Outcome__c == 'Proposal Needed'
                || tsk.Outcome__c == 'Verbal Commitment')){
                    //TODO: c.Nurture_Paused__c = True;
                    if(tsk.WhoId != null && String.valueOf(tsk.whoId).substring(0,3) == '003') {
                        c = new Contact(Id = tsk.whoId, Nurture_Paused__c = true);
                        cSet.add(c);
                    }
                    //TODO Create Opportunity if Task has the following outcome
                    //executeCheckNP();
                    o = new Opportunity();
                    if(tsk.WhoId != null && cIdMap.get(tsk.WhoId) != null){
                        o.AccountId = cIdMap.get(tsk.WhoId).AccountId;
                    }
                    o.Name = 'Temp Opp Name';
                    o.StageName = 'New';
                    o.Opportunity_Potential__c = 0.00;
                    o.CloseDate = Date.today();
                    oppList.add(o);
                }
            //What is the deciding factor for unpausing Nurture here?
            /**if (tsk.WhoId != null && tsk.Status =='Completed' && tsk.Subject == 'Closed Opportunity' && tsk.Outcome__c == 'Closed'){
            //TODO: c.Nurture_Paused__c = False;
            }**/
        }
        If(!oppList.isEmpty()){
            insert oppList;
            update new List <Contact>(cSet);
        }
    }
}



 
trigger SalesBlitzProcess on Task (after insert, after update) {
    Task[] taskOldList = trigger.IsDelete ? null : trigger.old;
    Task[] taskNewList = trigger.IsDelete ? trigger.old : trigger.new;
    new SalesBlitzProcess(trigger.Old, trigger.New).executeLeftMessage();
    new SalesBlitzProcess(trigger.Old, trigger.New).executeContinueProcess();
    //new SalesBlitzProcess(trigger.Old, trigger.New).executeHardNo();
    //new SalesBlitzProcess(trigger.Old, trigger.New).executeNotNow();
}
In an attempt to clean up my org and remove some fields, I'm trying to modify code that grabs Trade totals from one specific Fund Number and applies to them to the corresponding fields, and instead combine Fund Numbers and sums them to one field. Here is my example with code snippets:
public static final Set<String> FUND_NUMBERS = new Set<String> {
        '3915',
        '3917',
    };

    // All amounts/shares
    public static final Map<String, SObjectField[]> FIELDMAP_TOTAL = new Map<String, SObjectField[]>  {
        '3915' => new SobjectField[] { Account.Total_NS_Income_II_Sales__c , Account.Total_NS_Income_II_Shares__c },
'3917' => new SobjectField[] { Account.Total_NS_Income_II_T_Share_Sales__c, Account.Total_NS_Income_II_T_Shares__c },
    };
        // Fetch all the trades for these accounts
        Trades__c[] tradesList = [
            SELECT Name
                 , Dollar_Amount_of_the_transaction__c
                 , Fund_Number__c
                 , Number_of_Shares_of_the_transaction__c
                 , Resolved_Firm_Trading_ID__c
                 , Trade_Date__c
              FROM Trades__c
             WHERE Resolved_Firm_Trading_ID__c IN :accountIds
               AND Resolved_Firm_Trading_ID__c <> NULL
               AND Fund_Number__c IN :FUND_NUMBERS
               AND Trade_Date__c != NULL
               AND Dollar_Amount_of_the_transaction__c >= 0
               AND Number_of_Shares_of_the_transaction__c >= 0
        ];

            Decimal amount = trade.Dollar_Amount_of_The_Transaction__c;
            Decimal shares = trade.Number_of_Shares_of_the_transaction__c;
            String fn = trade.Fund_Number__c;
            SobjectField f0, f1;

            // Always apply to totals
            if (true) {
                f0 = FIELDMAP_TOTAL.get(fn)[0];
                f1 = FIELDMAP_TOTAL.get(fn)[1];

                account.put(f0, (Decimal) account.get(f0) + amount);
                account.put(f1, (Decimal) account.get(f1) + shares);
            }
        }

        // Done, try to update
        update accountMap.values();
    }
Now if I want to combine Fund Numbers 3915 & 3917 to be summed into the same fields, like so:
'3915' + '3917' => new SobjectField[] { Account.Test_Total_Sales__c, Account.Test_Total_Shares__c}
I get thrown an "Attempt to de-reference a null object" error on line 36 (in first snippet), the f1 = FIELDMAP_TOTAL.get(fn)[1];.

What is the proper way to structure this map to combine Fund Numbers?
All,
Due to the Winter '16 update, my approval process submission started throwing an error for our expense reports. I have corrected most of the code so that the approval goes through, but I can't seem to get the redirect to work. What do I need to add to my code in order for the browser to redirect to main object page after the user clicks "I agree" or how can I provide a success message to the users?

Line 55:
//redirect page after submitted
        if(result.isSuccess()){
            new pageReference.getParameters().put('retURL', '/' +  controller.getId());
        }
Full Class:
public with sharing class ExpenseReport_ValidateBeforeSubmit {
    private ApexPages.StandardController controller;
    public Boolean isValidated { set; get; }
    
    public ExpenseReport_ValidateBeforeSubmit(ApexPages.StandardController controller) {
        this.controller = controller;
        this.isValidated = false;
    }
    
    public PageReference validateBeforeSubmit() {
        ExpenseReport expenseReport = new ExpenseReport(controller);
        
        if (expenseReport.getExpenseLineItemListSize() == 0) {
            expenseReport.addMessage(ApexPages.Severity.Error, 'Unable to submit: '
                + 'An expense report requires at least one expense line item.');
        }
        
        for(Expense_Line_Items__c expenseLineItem : expenseReport.getExpenseLineItemList()) {
            expenseReport.setExpenseLineItem(expenseLineItem);
            
            if (expenseReport.getIsAttendeeRequiredButMissing()) {
                expenseReport.addMessage(ApexPages.Severity.Error, 'Unable to submit: '
                    + 'The expense line item categorized as "' + expenseLineItem.Category__c + '" '
                    + 'dated "' + expenseLineItem.Date_of_Expense_Item__c.format() + '" '
                    + 'and in the amount of $' + expenseLineItem.Expense_line_Item_Amount__c + ' '
                    + 'requires at least one non-owner attendee.');
            }
        }
        
        if (ApexPages.hasMessages(ApexPages.Severity.Error))
            return null;
        
        // Update the expense report to a draft status if a status is missing
        if (expenseReport.getExpenseReport().Approval_Status__c == null) try {
            update new Expense_Record__c(Id = expenseReport.getExpenseReport().Id, Approval_Status__c = 'Draft');
        } catch (System.Exception pException) {
            ApexPages.addMessages(pException);
        }
        
        isValidated = ApexPages.hasMessages(ApexPages.Severity.Error) == false;
        return null;
    }
    
    //NEW CODE
    public void confirmCertificationStatement() {
        // Create an approval request for the Expense Report
        Approval.ProcessSubmitRequest req1 = new Approval.ProcessSubmitRequest();
        req1.setComments('Submitting request for approval.');
        req1.setObjectId(controller.getId());
        
        // Submit the approval request for the Expense Report
        Approval.ProcessResult result = Approval.process(req1);
        
        //redirect page after submitted
        if(result.isSuccess()){
            new pageReference.getParameters().put('retURL', '/' +  controller.getId());
        }
        
        //Verify the result
        System.assert(result.isSuccess());
        
        System.assertEquals(
        'Pending', result.getInstanceStatus(),
        'Instance Status'+result.getInstanceStatus());
        
        //OLD CODE
        //public pageReference confirmCertificationStatement() {
        //PageReference pageReference = new PageReference('/p/process/Submit');
        //pageReference.setRedirect(true);
        //pageReference.getParameters().put('id',  controller.getId());
        //pageReference.getParameters().put('retURL', '/' +  controller.getId());
        //return pageReference;
        //}
    }
}

Visualforce
<apex:page standardController="Expense_Record__c" extensions="ExpenseReport_ValidateBeforeSubmit" action="{!validateBeforeSubmit}">
    <apex:includeScript value="https://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" />
    <apex:includeScript value="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.1/jquery-ui.min.js" />
    <apex:sectionHeader title="Submit for Approval: {!$ObjectType.Expense_Record__c.Label}" subtitle="{!Expense_Record__c.Name}" />

    <apex:pageMessages />

    <apex:form style="padding: 1.5em;" styleClass="certificationStatement" rendered="{!AND(isValidated)}">
        <div style="font-size: 130%; font-weight: bold; padding-bottom: 1em;"><apex:outputText value="Certification Statement" /></div>
        <div><apex:outputText value="By submitting this report, I certify that all expenses were incurred while performing firm business and are true and correct. All listed expenses are allowable as described in the firms travel and entertainment and business expense policies. Any expenses not business related or in compliance with firm policy that do not have prior management approval may result in disciplinary action from the firm." /></div>
        <div>&nbsp;</div>
        <apex:commandButton action="{!confirmCertificationStatement}" value="I agree" />
        <apex:commandButton action="{!$Page.ExpenseReport}?id={!Expense_Record__c.Id}" value="I do not agree" />
    </apex:form>

    <apex:form style="padding: 1.5em;" rendered="{!NOT(isValidated)}">
        <apex:commandButton action="{!$Page.ExpenseReport}?id={!Expense_Record__c.Id}" value="Return to Expense Report" />
    </apex:form>
</apex:page>


 
All,

I have written code that finds the Last Completed Event Date, but I'm hoping someone can help me figure out how to add a method to find the First Completed Event Date. The trouble is I don't think there's a way to write a comparison argument to solve it as there is not standard date field in Salesforce that would represent the inception date of an org.

Here is my code thus far:
public class LastCompletedEventDate{
    //Grab list of contacts
    protected final Contact[] contactNewList = new Contact[] {};
    protected final Contact[] contactOldList = new Contact[] {};
    
    public LastCompletedEventDate(Contact[] contactOldList, Contact[] contactNewList) {
        this.contactNewList.addAll(contactNewList == null ? new Contact[] {} : contactNewList);
        this.contactOldList.addAll(contactOldList == null ? new Contact[] {} : contactOldList);
    }
    
    public void execute() {
        // Find all events associated to contacts
        Event[] eventList = [select ActivityDate, WhoId, EndDateTime, Subject, ActivityDateTime from Event where WhoId in :contactNewList];
        
        Map<Id, Contact> contactMap = new Map<Id, Contact>(contactNewList);
                for(Contact contact : contactNewList) {
                    contact.Last_Completed_Event__c = null;
        }
        
        //create if else statement to display most current completed event date
        for(Event event : eventList) {
            Contact contact = contactMap.get(event.WhoId);
            if(Contact == null)
                continue;
            if(Event.EndDateTime < Date.Today())
                Contact.Last_Completed_Event__c = Event.EndDateTime;
        }
    }
}
 
trigger LastCompletedEventDate on Contact (before update) {
    if(Contact_RollupTrades.inprog != true) {
        Set<ID> sID = new Set<ID>(trigger.newMap.keySet());
        new LastCompletedEventDate(trigger.old, trigger.new).execute();
    }
}
Hey guys,

I'm trying to do a date range to grab all trades from past 12 months, from yesterday's date. For some reason the following 2 formulas will not work. Any help would be greatly appreciated!

Returns nothing:
if(trade.trade_date__c < date.today().addDays(-1) && trade.trade_date__c > date.today().addDays(-366)) {
                            accounts.get(trade.Resolved_Firm_Trading_ID__c).put(prior12MOS.get(trade.fund_number__c)[0], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(prior12MOS.get(trade.fund_number__c)[0]))+trade.Dollar_Amount_of_The_Transaction__c);
                            accounts.get(trade.Resolved_Firm_Trading_ID__c).put(prior12MOS.get(trade.fund_number__c)[1], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(prior12MOS.get(trade.fund_number__c)[1]))+trade.Number_of_Shares_of_the_transaction__c);
                            system.debug(prior12MOS);
                            system.debug(LoggingLevel.DEBUG, + Limits.getCpuTime() + '/' + Limits.getLimitCpuTime());

Returns only dates within the past month:
if(trade.trade_date__c < date.today().addDays(-1) && trade.trade_date__c > date.today().addYears(-1)) {
                            

 

All,
I'm writing a trigger to send an email notification to our Internal Owner (a custom field - Internal_Owner__c) of the Contact if a User chooses the Type 'Inbound Queue'. I'm unsure how to:
1.) Add in the SOQL 'Where Task.Type = 'Inbound Queue'.
2.) Send the notification to our Internal Owner of the Contact instead of whom the task is assigned to. Not sure if I need to create a formula field.

Here is my code thus far:

trigger LogACall_Send_Email on Task (before insert) {
    Set<Id> ownerIds = new Set<Id>();
    
    for(Task tsk: Trigger.New)
        ownerIds.add(tsk.ownerId);

    Map<Id, User> userMap = new Map<Id,User>([select Name, Email from User where Id in :ownerIds]);
    for(Task tsk : Trigger.New) {
        User theUser = userMap.get(tsk.ownerId);
        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
        String[] toAddresses = new String[] {theUser.Email};
        mail.setToAddresses(toAddresses);
        mail.setSubject('Inbound Queue Call');
        String template = 'Hello {0}, \n\nAn Inbound Queue call was taken for you. Here are the details. \n\n';
        template+= 'Subject - {1}\n';
        template+= 'Due Date - {2}\n';
        template+= 'Type - {3}\n';
        template+= 'Comments - {4}\n';
        String duedate = '';
        if (tsk.ActivityDate==null)
            duedate = '';
        else
            duedate = tsk.ActivityDate.format();
        List<String> args = new List<String>();
        args.add(theUser.Name);
        args.add(tsk.Subject);
        args.add(duedate);
        args.add(tsk.type);
        args.add(tsk.Description);

        String formattedHtml = String.format(template, args);
       
        mail.setPlainTextBody(formattedHtml);
        Messaging.SendEmail(new Messaging.SingleEmailMessage[] {mail});
    }
}
All,
Our Salesforce org history is set to 24 months. I recently created some code to sum "Total Completed Events" and although I can still see completed Events older than 24 months on a Contact page, it doesn't include them to the sum. I read up on queryAll(), but I'm not sure how to use it in my current SOQL. Is there a way to grab older events since inception using queryAll() that also won't grab deleted events from the recycle bin? Here is my code if that helps:

Class
public class TotalCompletedEvents {
    //Grab list of contacts
    protected final Contact[] contactNewList;
    protected final Contact[] contactOldList;
        
    public TotalCompletedEvents(Contact[] contactOldList, Contact[] contactNewList) {
        this.contactNewList = contactNewList;
        this.contactOldList = contactOldList;
    }
    public void execute() {
        Map<Id, Contact> contactMap = new Map<Id, Contact>(contactNewList);
        AggregateResult[] ars = [select count(id),whoid from event where EndDateTime < :date.today() and whoid in :contactNewList group by whoid];
        Map<Id, Contact> contactMap1 = new Map<Id,Contact>(contactNewList);
        for (AggregateResult ar : ars) {
            //System.debug('Total Completed Events: ' + ar.get('expr0'));  //get count()
            //System.debug('Contact ID' + ar.get('whoid'));  //get id of contact
            Contact c = contactMap.get((id)ar.get('whoid'));
            c.total_completed_events__c = integer.valueof(ar.get('expr0'));
            contactMap1.remove((id)ar.get('whoid'));
        }
        for (Contact c : contactMap1.values()){
            c.total_completed_events__c = 0;
        }
        //update ContactNewList;
    }
}

Trigger
trigger TotalCompletedEvents on Contact (before update) {
    Contact[] contactOldList = trigger.IsDelete ? null : trigger.old;
    Contact[] contactNewList = trigger.IsDelete ? trigger.old : trigger.new;
    new TotalCompletedEvents(contactOldList, contactNewList).execute();
}

 
All,
I'm trying to create a field that totals all the completed events on a contact page. I think I'm on the right track, but I'm not sure how to go about making the event an integer, then sum all of them. This will eventually be a batch job that just runs every morning, but I have to get the class right first obviously. Any help would be great! Here's my code thus far:
public class TotalCompletedEvents {
    //Grab list of contacts
    protected final Contact[] contactNewList = new Contact[] {};
    protected final Contact[] contactOldList = new Contact[] {};
        
    public TotalCompletedEvents(Contact[] contactOldList, Contact[] contactNewList) {
        this.contactNewList.addAll(contactNewList == null ? new Contact[] {} : contactNewList);
        this.contactOldList.addAll(contactOldList == null ? new Contact[] {} : contactOldList);
    }
    public void execute() {
        // Find all events associated to contacts
        Event[] eventList = [select ActivityDate, WhoId, EndDateTime, Subject, ActivityDateTime from Event where WhoId in :contactNewList];
        Map<Id, Contact> contactMap = new Map<Id, Contact>(contactNewList);
        for(Contact contact : contactNewList) {
            contact.Total_Completed_Events__c = null;
        }
        for(Event event : eventList) {
            Contact contact = contactMap.get(event.WhoId);
            if(Contact == null)
                continue;
            if(Event.EndDateTime < Date.Today())
                Contact.Total_Completed_Events__c += Event.EndDateTime;
        }
    }
}


 
All,
I need to make my sales summary code more efficient. Once we hit 9,000 trades on a single Account, the system hits the CPU Limit governor limit, even in a batch job. Anybody have any ideas on the code below? Perhaps moving each calculation in the For loop under each  corresponding map? I'm not sure the best way to change this code, but any help would be greatly appreciated.

Debug log shows errors at random at lines 73, 79, or 92 in the Class and every time on line 4 in the trigger.
CPU Time varies on the number of trades inserted at a time, but even at 1 trade I can get up to 25000 out of 10000 (more than double).

Class:
public class Account_RollupTrades {
    public Static Account_Setting__c setting = Account_Setting__c.getInstance();
    public Static boolean inprog = false;

    public static void execute (Set<Id> accountIds, List<Account> accountsList) {
        Map<Id, Account> accounts = new Map<Id, Account> (AccountsList);
        system.debug ('execute');
        if(setting.Disable_RollupTrades__c != true) {
            //Map<Id, Account> accounts = new Map<Id, Account>();
            for(Id accountId:accountIds) {
                system.debug(accountid);
                accounts.put(accountId,
                   new Account(
                       Id=accountId,
                       /**YTD_NIOR_I_Sales__c = 0,         YTD_NIOR_I_Shares__c = 0,         QTD_NIOR_I_Sales__c = 0,         QTD_NIOR_I_Shares__c = 0,
                       MTD_NIOR_I_Sales__c = 0,         MTD_NIOR_I_Shares__c = 0,         PY_NIOR_I_Sales__c = 0,          PY_NIOR_I_Shares__c = 0,
                       Total_NIOR_I_Sales__c = 0,       Total_NIOR_I_Shares__c = 0,       YTD_NS_Income_Sales__c = 0,      YTD_NS_Income_Shares__c = 0,
                       QTD_NS_Income_Sales__c = 0,      QTD_NS_Income_Shares__c = 0,      MTD_NS_Income_Sales__c = 0,      MTD_NS_Income_Shares__c = 0,
                       PY_NS_Income_Sales__c = 0,       PY_NS_Income_Shares__c = 0,       Total_NS_Income_Sales__c = 0,    Total_NS_Income_Shares__c = 0,**/
                       Total_NS_HI_Sales__c = 0,       Total_NS_HI_Shares__c = 0,       YTD_NS_HI_Sales__c = 0,         YTD_NS_HI_Shares__c = 0,
                       QTD_NS_HI_Sales__c = 0,         QTD_NS_HI_Shares__c = 0,         MTD_NS_HI_Sales__c = 0,         MTD_NS_HI_Shares__c = 0,
                       PY_NS_HI_Sales__c = 0,          PY_NS_HI_Shares__c = 0,          Total_NS_Income_II_Sales__c = 0, Total_NS_Income_II_Shares__c = 0,
                       YTD_NS_Income_II_Sales__c = 0,   YTD_NS_Income_II_Shares__c = 0,   QTD_NS_Income_II_Sales__c = 0,   QTD_NS_Income_II_Shares__c = 0,
                       MTD_NS_Income_II_Sales__c = 0,   MTD_NS_Income_II_Shares__c = 0,   PY_NS_Income_II_Sales__c = 0,    PY_NS_Income_II_Shares__c = 0,
                       Rollup_Trades__c = DateTime.now()
                   )
                            );
            }
            Map<String, SObjectField[]>
                ytd = new map<string, sobjectfield[]> {
                    //'3910' => new sobjectfield[] { account.YTD_NIOR_I_Sales__c , account.YTD_NIOR_I_Shares__c},
                    //'3911' => new sobjectfield[] { account.YTD_NS_Income_Sales__c , account.YTD_NS_Income_Shares__c },
                    '3912' => new sobjectfield[] { account.YTD_NS_HI_Sales__c , account.YTD_NS_HI_Shares__c },
                    '3915' => new sobjectfield[] { account.YTD_NS_Income_II_Sales__c , account.YTD_NS_Income_II_Shares__c }    
                },
                qtd = new map<string, sobjectfield[]> {
                    //'3910' => new sobjectfield[] { account.QTD_NIOR_I_Sales__c , account.QTD_NIOR_I_Shares__c},
                    //'3911' => new sobjectfield[] { account.QTD_NS_Income_Sales__c , account.QTD_NS_Income_Shares__c },
                    '3912' => new sobjectfield[] { account.QTD_NS_HI_Sales__c , account.QTD_NS_HI_Shares__c },
                    '3915' => new sobjectfield[] { account.QTD_NS_Income_II_Sales__c , account.QTD_NS_Income_II_Shares__c }
                },
                mtd = new map<string, sobjectfield[]> {
                    //'3910' => new sobjectfield[] { account.MTD_NIOR_I_Sales__c , account.MTD_NIOR_I_Shares__c},
                    //'3911' => new sobjectfield[] { account.MTD_NS_Income_Sales__c , account.MTD_NS_Income_Shares__c },
                    '3912' => new sobjectfield[] { account.MTD_NS_HI_Sales__c , account.MTD_NS_HI_Shares__c },
                    '3915' => new sobjectfield[] { account.MTD_NS_Income_II_Sales__c , account.MTD_NS_Income_II_Shares__c }
                },
                py = new map<string, sobjectfield[]> {
                    //'3910' => new sobjectfield[] { account.PY_NIOR_I_Sales__c , account.PY_NIOR_I_Shares__c},
                    //'3911' => new sobjectfield[] { account.PY_NS_Income_Sales__c , account.PY_NS_Income_Shares__c },
                    '3912' => new sobjectfield[] { account.PY_NS_HI_Sales__c , account.PY_NS_HI_Shares__c },
                    '3915' => new sobjectfield[] { account.PY_NS_Income_II_Sales__c , account.PY_NS_Income_II_Shares__c }
                },
                total = new map<string, sobjectfield[]> {
                    //'3910' => new sobjectfield[] { account.Total_NIOR_I_Sales__c , account.Total_NIOR_I_Shares__c},
                    //'3911' => new sobjectfield[] { account.Total_NS_Income_Sales__c , account.Total_NS_Income_Shares__c },
                    '3912' => new sobjectfield[] { account.Total_NS_HI_Sales__c , account.Total_NS_HI_Shares__c },
                    '3915' => new sobjectfield[] { account.Total_NS_Income_II_Sales__c , account.Total_NS_Income_II_Shares__c }
                };
    
    // We make the select in a "for" so instead of selecting to many records at once hitting the heap size limit the for it will take only 200 records to work with at each iteration.
    for(Trades__c[] tradesList : [select Dollar_Amount_of_the_transaction__c, Fund_Number__c, Number_of_Shares_of_the_transaction__c, Resolved_Firm_Trading_ID__c, Resolved_Firm_Trading_IDs__c, Trade_Date__c from Trades__c where Resolved_Firm_Trading_ID__c in :accountIds and Fund_Number__c in (/**'3910', '3911',**/ '3912', '3915') and Dollar_Amount_of_the_transaction__c != null and Number_of_Shares_of_the_transaction__c != null and Trade_Date__c != null and Dollar_Amount_of_the_transaction__c >= 0 and Number_of_Shares_of_the_transaction__c >= 0 FOR UPDATE]){
        for(trades__c trade: tradesList) {
            
            if(date.today().year() == trade.trade_date__c.year()) {
                accounts.get(trade.Resolved_Firm_Trading_ID__c).put(ytd.get(trade.fund_number__c)[0], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(ytd.get(trade.fund_number__c)[0]))+trade.Dollar_Amount_of_The_Transaction__c);
                accounts.get(trade.Resolved_Firm_Trading_ID__c).put(ytd.get(trade.fund_number__c)[1], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(ytd.get(trade.fund_number__c)[1]))+trade.Number_of_Shares_of_the_transaction__c);
                //system.debug(ytd);
                //system.debug(LoggingLevel.DEBUG, + Limits.getCpuTime() + '/' + Limits.getLimitCpuTime());
                
                //( (date.ValueOf(date.today().month()).divide(3, 0) == date.ValueOf(trade.trade_date__c.month()).divide(3, 0)) )
                if((((date.today().month() - 1) / 3) + 1) == (((trade.Trade_Date__c.month() - 1) / 3) + 1))   {
                    accounts.get(trade.Resolved_Firm_Trading_ID__c).put(qtd.get(trade.fund_number__c)[0], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(qtd.get(trade.fund_number__c)[0]))+trade.Dollar_Amount_of_The_Transaction__c);
                    accounts.get(trade.Resolved_Firm_Trading_ID__c).put(qtd.get(trade.fund_number__c)[1], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(qtd.get(trade.fund_number__c)[1]))+trade.Number_of_Shares_of_the_transaction__c);
                    //system.debug(qtd);
                    //system.debug(LoggingLevel.DEBUG, + Limits.getCpuTime() + '/' + Limits.getLimitCpuTime());
                    
                    if(date.today().month()==trade.trade_date__c.month()) {
                        accounts.get(trade.Resolved_Firm_Trading_ID__c).put(mtd.get(trade.fund_number__c)[0], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(mtd.get(trade.fund_number__c)[0]))+trade.Dollar_Amount_of_The_Transaction__c);
                        accounts.get(trade.Resolved_Firm_Trading_ID__c).put(mtd.get(trade.fund_number__c)[1], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(mtd.get(trade.fund_number__c)[1]))+trade.Number_of_Shares_of_the_transaction__c);
                        //system.debug(mtd);
                        //system.debug(LoggingLevel.DEBUG, + Limits.getCpuTime() + '/' + Limits.getLimitCpuTime());
                    }
                }
            } 
            else if(date.today().year()-1==trade.trade_date__c.year()) {
                accounts.get(trade.Resolved_Firm_Trading_ID__c).put(py.get(trade.fund_number__c)[0], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(py.get(trade.fund_number__c)[0]))+trade.Dollar_Amount_of_The_Transaction__c);
                accounts.get(trade.Resolved_Firm_Trading_ID__c).put(py.get(trade.fund_number__c)[1], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(py.get(trade.fund_number__c)[1]))+trade.Number_of_Shares_of_the_transaction__c);
                //system.debug(py);
                //system.debug(LoggingLevel.DEBUG, + Limits.getCpuTime() + '/' + Limits.getLimitCpuTime());
            }
            accounts.get(trade.Resolved_Firm_Trading_ID__c).put(total.get(trade.fund_number__c)[0], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(total.get(trade.fund_number__c)[0]))+trade.Dollar_Amount_of_The_Transaction__c);
            accounts.get(trade.Resolved_Firm_Trading_ID__c).put(total.get(trade.fund_number__c)[1], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(total.get(trade.fund_number__c)[1]))+trade.Number_of_Shares_of_the_transaction__c);
            //system.debug(total);
            //system.debug(LoggingLevel.DEBUG, + Limits.getCpuTime() + '/' + Limits.getLimitCpuTime());
        }
            }
        }
        inprog = true;
        update accounts.values();
        inprog = false;
    }
}
Trigger:
trigger Account_RollupTrades on Account (after update) {
    if(Account_RollupTrades.inprog == false) {
        //set<ID> sID = new set<ID> (trigger.newMap.keySet());
        Account_RollupTrades.execute(trigger.newMap.keySet(), trigger.new);
    }
}



 
All,
I wrote a class and trigger to create a field that would display the most recent completed event for a Contact. I thought it worked well, but there seems to be one problem. If the Contact doesn't have a previous completed event and a User schedules a new event for sometime in the future, the field updates to the future Due Date. 

The line causing the problem is as follows:
if(Contact.Last_Completed_Event__c == null)
           Contact.Last_Completed_Event__c = Event.EndDateTime;

Now if I comment this out, it won't grab a future Due Date, but it also won't grab the most recent completed event if an OPEN event doesn't exist. Can somebody help me solve this so that it works properly?
public class LastCompletedEventDate{
    //Grab list of contacts
    protected final Contact[] contactNewList = new Contact[] {};
    protected final Contact[] contactOldList = new Contact[] {};
    
    public LastCompletedEventDate(Contact[] contactOldList, Contact[] contactNewList) {
        this.contactNewList.addAll(contactNewList == null ? new Contact[] {} : contactNewList);
        this.contactOldList.addAll(contactOldList == null ? new Contact[] {} : contactOldList);
    }
    
    public void execute() {
        // Find all events associated to contacts
        Event[] eventList = [select ActivityDate, WhoId, EndDateTime, Subject, ActivityDateTime from Event where WhoId in :contactNewList];
        
        Map<Id, Contact> contactMap = new Map<Id, Contact>(contactNewList);
                for(Contact contact : contactNewList) {
                    contact.Last_Completed_Event__c = null;
        }
        
        //create if else statement to display most current completed event date
        for(Event event : eventList) {
            Contact contact = contactMap.get(event.WhoId);
            
            if(contact == null)
                continue;
            //if(Contact.Last_Completed_Event__c == null)
                //Contact.Last_Completed_Event__c = Event.EndDateTime;
            if(Contact.Last_Completed_Event__c == null && Event.EndDateTime < Date.Today())
                Contact.Last_Completed_Event__c = Event.EndDateTime;
            if(Event.EndDateTime < Date.Today())
                Contact.Last_Completed_Event__c = Event.EndDateTime;
        }
    }
}
trigger LastCompletedEventDate on Contact (before update) {
    if(Contact_RollupTrades.inprog != true) {
        Set<ID> sID = new Set<ID>(trigger.newMap.keySet());
        new LastCompletedEventDate(trigger.old, trigger.new).execute();
    }
}
 My for loop updates sales summary fields. This code iterates 200 records as a time in a batch job, and works fine until an Account gets to about 5000+ trades in it. At this point, the CPU Limit begins to double and reaches the governor limit. If I insert 50 - 100 trades at a time, the CPU Limit seems to be avoided. I was hoping someone might be able to help me modify my for loop in order to avoid this limit in the future. Here is the below code:
 
public class Account_RollupTrades {
    public Static Account_Setting__c setting = Account_Setting__c.getInstance();
    public Static boolean inprog = false;
    
    public static void execute (Set<Id> accountIds, List<Account> accountsList) {
        Map<Id, Account> accounts = new Map<Id, Account> (AccountsList);
        system.debug ('execute');
        if(setting.Disable_RollupTrades__c != true) {
            //Map<Id, Account> accounts = new Map<Id, Account>();
            for(Id accountId:accountIds) {
                system.debug(accountid);
                accounts.put(accountId,
                   new Account(
                       Id=accountId,
                       YTD_NIOR_I_Sales__c = 0,         YTD_NIOR_I_Shares__c = 0,         QTD_NIOR_I_Sales__c = 0,         QTD_NIOR_I_Shares__c = 0,
                       MTD_NIOR_I_Sales__c = 0,         MTD_NIOR_I_Shares__c = 0,         PY_NIOR_I_Sales__c = 0,          PY_NIOR_I_Shares__c = 0,
                       Total_NIOR_I_Sales__c = 0,       Total_NIOR_I_Shares__c = 0,       YTD_NS_Income_Sales__c = 0,      YTD_NS_Income_Shares__c = 0,
                       QTD_NS_Income_Sales__c = 0,      QTD_NS_Income_Shares__c = 0,      MTD_NS_Income_Sales__c = 0,      MTD_NS_Income_Shares__c = 0,
                       PY_NS_Income_Sales__c = 0,       PY_NS_Income_Shares__c = 0,       Total_NS_Income_Sales__c = 0,    Total_NS_Income_Shares__c = 0,
                       Total_NS_HI_Sales__c = 0,       Total_NS_HI_Shares__c = 0,       YTD_NS_HI_Sales__c = 0,         YTD_NS_HI_Shares__c = 0,
                       QTD_NS_HI_Sales__c = 0,         QTD_NS_HI_Shares__c = 0,         MTD_NS_HI_Sales__c = 0,         MTD_NS_HI_Shares__c = 0,
                       PY_NS_HI_Sales__c = 0,          PY_NS_HI_Shares__c = 0,          Total_NS_Income_II_Sales__c = 0, Total_NS_Income_II_Shares__c = 0,
                       YTD_NS_Income_II_Sales__c = 0,   YTD_NS_Income_II_Shares__c = 0,   QTD_NS_Income_II_Sales__c = 0,   QTD_NS_Income_II_Shares__c = 0,
                       MTD_NS_Income_II_Sales__c = 0,   MTD_NS_Income_II_Shares__c = 0,   PY_NS_Income_II_Sales__c = 0,    PY_NS_Income_II_Shares__c = 0,
                       Rollup_Trades__c = DateTime.now()
                   )
                            );
            }
            Map<String, SObjectField[]>
                ytd = new map<string, sobjectfield[]> {
                    '3910' => new sobjectfield[] { account.YTD_NIOR_I_Sales__c , account.YTD_NIOR_I_Shares__c},
                    '3911' => new sobjectfield[] { account.YTD_NS_Income_Sales__c , account.YTD_NS_Income_Shares__c },
                    '3912' => new sobjectfield[] { account.YTD_NS_HI_Sales__c , account.YTD_NS_HI_Shares__c },
                    '3915' => new sobjectfield[] { account.YTD_NS_Income_II_Sales__c , account.YTD_NS_Income_II_Shares__c }    
                },
                qtd = new map<string, sobjectfield[]> {
                    '3910' => new sobjectfield[] { account.QTD_NIOR_I_Sales__c , account.QTD_NIOR_I_Shares__c},
                    '3911' => new sobjectfield[] { account.QTD_NS_Income_Sales__c , account.QTD_NS_Income_Shares__c },
                    '3912' => new sobjectfield[] { account.QTD_NS_HI_Sales__c , account.QTD_NS_HI_Shares__c },
                    '3915' => new sobjectfield[] { account.QTD_NS_Income_II_Sales__c , account.QTD_NS_Income_II_Shares__c }
                },
                mtd = new map<string, sobjectfield[]> {
                    '3910' => new sobjectfield[] { account.MTD_NIOR_I_Sales__c , account.MTD_NIOR_I_Shares__c},
                    '3911' => new sobjectfield[] { account.MTD_NS_Income_Sales__c , account.MTD_NS_Income_Shares__c },
                    '3912' => new sobjectfield[] { account.MTD_NS_HI_Sales__c , account.MTD_NS_HI_Shares__c },
                    '3915' => new sobjectfield[] { account.MTD_NS_Income_II_Sales__c , account.MTD_NS_Income_II_Shares__c }
                },
                py = new map<string, sobjectfield[]> {
                    '3910' => new sobjectfield[] { account.PY_NIOR_I_Sales__c , account.PY_NIOR_I_Shares__c},
                    '3911' => new sobjectfield[] { account.PY_NS_Income_Sales__c , account.PY_NS_Income_Shares__c },
                    '3912' => new sobjectfield[] { account.PY_NS_HI_Sales__c , account.PY_NS_HI_Shares__c },
                    '3915' => new sobjectfield[] { account.PY_NS_Income_II_Sales__c , account.PY_NS_Income_II_Shares__c }
                },
                total = new map<string, sobjectfield[]> {
                    '3910' => new sobjectfield[] { account.Total_NIOR_I_Sales__c , account.Total_NIOR_I_Shares__c},
                    '3911' => new sobjectfield[] { account.Total_NS_Income_Sales__c , account.Total_NS_Income_Shares__c },
                    '3912' => new sobjectfield[] { account.Total_NS_HI_Sales__c , account.Total_NS_HI_Shares__c },
                    '3915' => new sobjectfield[] { account.Total_NS_Income_II_Sales__c , account.Total_NS_Income_II_Shares__c }
                };
	
	// We make the select in a "for" so instead of selecting to many records at once hitting the heap size limit the for it will take only 200 records to work with at each iteration.
	for(Trades__c[] tradesList : [select Dollar_Amount_of_the_transaction__c, Fund_Number__c, Number_of_Shares_of_the_transaction__c, Resolved_Firm_Trading_ID__c, Resolved_Firm_Trading_IDs__c, Trade_Date__c from Trades__c where Resolved_Firm_Trading_ID__c in :accountIds and Fund_Number__c in ('3910', '3911', '3912', '3915') and Dollar_Amount_of_the_transaction__c != null and Number_of_Shares_of_the_transaction__c != null and Trade_Date__c != null and Dollar_Amount_of_the_transaction__c >= 0 and Number_of_Shares_of_the_transaction__c >= 0]){
        for(trades__c trade: tradesList) {
            
            if(date.today().year() == trade.trade_date__c.year()) {
                system.debug(ytd);
                accounts.get(trade.Resolved_Firm_Trading_ID__c).put(ytd.get(trade.fund_number__c)[0], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(ytd.get(trade.fund_number__c)[0]))+trade.Dollar_Amount_of_The_Transaction__c);
                accounts.get(trade.Resolved_Firm_Trading_ID__c).put(ytd.get(trade.fund_number__c)[1], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(ytd.get(trade.fund_number__c)[1]))+trade.Number_of_Shares_of_the_transaction__c);
                
                system.debug(qtd);
                //( (date.ValueOf(date.today().month()).divide(3, 0) == date.ValueOf(trade.trade_date__c.month()).divide(3, 0)) )
                if((((date.today().month() - 1) / 3) + 1) == (((trade.Trade_Date__c.month() - 1) / 3) + 1))   {
                    accounts.get(trade.Resolved_Firm_Trading_ID__c).put(qtd.get(trade.fund_number__c)[0], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(qtd.get(trade.fund_number__c)[0]))+trade.Dollar_Amount_of_The_Transaction__c);
                    accounts.get(trade.Resolved_Firm_Trading_ID__c).put(qtd.get(trade.fund_number__c)[1], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(qtd.get(trade.fund_number__c)[1]))+trade.Number_of_Shares_of_the_transaction__c);
                    
                    system.debug(mtd);
                    if(date.today().month()==trade.trade_date__c.month()) {
                        accounts.get(trade.Resolved_Firm_Trading_ID__c).put(mtd.get(trade.fund_number__c)[0], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(mtd.get(trade.fund_number__c)[0]))+trade.Dollar_Amount_of_The_Transaction__c);
                        accounts.get(trade.Resolved_Firm_Trading_ID__c).put(mtd.get(trade.fund_number__c)[1], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(mtd.get(trade.fund_number__c)[1]))+trade.Number_of_Shares_of_the_transaction__c);
                    }
                }
            } else if(date.today().year()-1==trade.trade_date__c.year()) {
                accounts.get(trade.Resolved_Firm_Trading_ID__c).put(py.get(trade.fund_number__c)[0], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(py.get(trade.fund_number__c)[0]))+trade.Dollar_Amount_of_The_Transaction__c);
                accounts.get(trade.Resolved_Firm_Trading_ID__c).put(py.get(trade.fund_number__c)[1], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(py.get(trade.fund_number__c)[1]))+trade.Number_of_Shares_of_the_transaction__c);
            }
            
            accounts.get(trade.Resolved_Firm_Trading_ID__c).put(total.get(trade.fund_number__c)[0], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(total.get(trade.fund_number__c)[0]))+trade.Dollar_Amount_of_The_Transaction__c);
            accounts.get(trade.Resolved_Firm_Trading_ID__c).put(total.get(trade.fund_number__c)[1], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(total.get(trade.fund_number__c)[1]))+trade.Number_of_Shares_of_the_transaction__c);
        }
            }
        }
        inprog = true;
        update accounts.values();
        inprog = false;
    }
}



 
All,
We have a few national accounts with large trade volumes. Each National Account has a sales summary consisting of YTD, MTD, QTD, PYTD, etc. When we post new trades every morning, through a batch job, our system is starting to hit a CPU Limit Error. I was able to recreate this error in the sandbox by loading 5000 trades into 1 National Account and on 1 Contact record. I feel like my code is written pretty efficiently, but every time a trade is inserted, it recalculates the summary, so national accounts or contact records with large trade volumes is causing our system to blow up when the volume is near 200 trades. Can someone look at my code and see if there's a more efficient way to write it? Or does the trade process need to just load 50 at a time? There are also about 5 workflow rules running if a Contact hits a 1st trade in any fund, or a threshold of $250K, $500K, or $1MM.

Debug Logs
14:12:16:000 FATAL_ERROR Class.Contact_RollupTrades.execute: line 81, column 1
14:12:16:000 FATAL_ERROR Trigger.Contact_RollupTrades: line 4, column 1

14:38:37:000 FATAL_ERROR Class.Account_RollupTrades.execute: line 88, column 1
14:38:37:000 FATAL_ERROR Trigger.Account_RollupTrades: line 4, column 1

14:44:37:000 FATAL_ERROR Class.Account_RollupTrades.execute: line 74, column 1
14:44:37:000 FATAL_ERROR Trigger.Account_RollupTrades: line 4, column 1

14:48:51:000 FATAL_ERROR Class.Account_RollupTrades.execute: line 77, column 1
14:47:29:000 FATAL_ERROR Trigger.Account_RollupTrades: line 4, column 1

14:47:29:000 FATAL_ERROR Class.Account_RollupTrades.execute: line 78, column 1
14:47:29:000 FATAL_ERROR Trigger.Account_RollupTrades: line 4, column 1

14:46:06:000 FATAL_ERROR Class.Account_RollupTrades.execute: line 87, column 1
14:46:06:000 FATAL_ERROR Trigger.Account_RollupTrades: line 4, column 1

14:54:45:000 FATAL_ERROR Class.Account_RollupTrades.execute: line 67, column 1
14:54:45:000 FATAL_ERROR Trigger.Account_RollupTrades: line 4, column 1

15:02:01:000 FATAL_ERROR Class.Contact_RollupTrades.execute: line 83, column 1
15:02:01:000 FATAL_ERROR Trigger.Contact_RollupTrades: line 4, column 1

15:03:00:809 CODE_UNIT_FINISHED Trades_CascadeContacts on Trades trigger event AfterInsert for [a08L0000006xNw4, a08L0000006xNw5, a08L0000006xNw6, a08L0000006xNw7, a08L0000006xNw8, a08L0000006xNw9, a08L0000006xNwA, a08L0000006xNwB, a08L0000006xNwC, a08L0000006xNwD, a08L0000006xNwE, a08L0000006xNwF, a08L0000006xNwG, a08L0000006xNwH, a08L0000006xNwI, a08L0000006xNwJ, a08L0000006xNwK, a08L0000006xNwL, a08L0000006xNwM, a08L0000006xNwN, a08L0000006xNwO, a08L0000006xNwP, a08L0000006xNwQ, a08L0000006xNwR, a08L0000006xNwS, a08L0000006xNwT, a08L0000006xNwU, a08L0000006xNwV, a08L0000006xNwW, a08L0000006xNwX, a08L0000006xNwY, a08L0000006xNwZ, a08L0000006xNwa, a08L0000006xNwb, a08L0000006xNwc, a08L0000006xNwd, a08L0000006xNwe, a08L0000006xNwf, a08L0000006xNwg, a08L0000006xNwh, a08L0000006xNwi, a08L0000006xNwj, a08L0000006xNwk, a08L0000006xNwl, a08L0000006xNwm, a08L0000006xNwn, a08L0000006xNwo, a08L0000006xNwp, a08L0000006xNwq, a08L0000006xNwr, a08L0000006xNws, a08L0000006xNwt, a08L0000006xNwu, a08L0000006xNwv, a08L0000006xNww, a08L0000006xNwx, a08L0000006xNwy, a08L0000006xNwz, a08L0000006xNx0, a08L0000006xNx1, a08L0000006xNx2, a08L0000006xNx3, a08L0000006xNx4, a08L0000006xNx5, a08L0000006xNx6, a08L0000006xNx7, a08L0000006xNx8, a08L0000006xNx9, a08L0000006xNxA, a08L0000006xNxB, a08L0000006xNxC, a08L0000006xNxD, a08L0000006xNxE, a08L0000006xNxF, a08L0000006xNxG, a08L0000006xNxH, a08L0000006xNxI, a08L0000006xNxJ, a08L0000006xNxK, a08L0000006xNxL, a08L0000006xNxM, a08L0000006xNxN, a08L0000006xNxO, a08L0000006xNxP, a08L0000006xNxQ, a08L0000006xNxR, a08L0000006xNxS, a08L0000006xNxT, a08L0000006xNxU, a08L0000006xNxV, a08L0000006xNxW, a08L0000006xNxX, a08L0000006xNxY, a08L0000006xNxZ, a08L0000006xNxa, a08L0000006xNxb, a08L0000006xNxc, a08L0000006xNxd, a08L0000006xNxe]

Account Class
public class Account_RollupTrades {
    public Static Account_Setting__c setting = Account_Setting__c.getInstance();
    public Static boolean inprog = false;
    
    public static void execute (Set<Id> accountIds, List<Account> accountsList) {
        Map<Id, Account> accounts = new Map<Id, Account> (AccountsList);
        system.debug ('execute');
        if(setting.Disable_RollupTrades__c != true) {
            //Map<Id, Account> accounts = new Map<Id, Account>();
            for(Id accountId:accountIds) {
                system.debug(accountid);
                accounts.put(accountId,
                   new Account(
                       Id=accountId,
                       YTD_NIOR_I_Sales__c = 0,         YTD_NIOR_I_Shares__c = 0,         QTD_NIOR_I_Sales__c = 0,         QTD_NIOR_I_Shares__c = 0,
                       MTD_NIOR_I_Sales__c = 0,         MTD_NIOR_I_Shares__c = 0,         PY_NIOR_I_Sales__c = 0,          PY_NIOR_I_Shares__c = 0,
                       Total_NIOR_I_Sales__c = 0,       Total_NIOR_I_Shares__c = 0,       YTD_NS_Income_Sales__c = 0,      YTD_NS_Income_Shares__c = 0,
                       QTD_NS_Income_Sales__c = 0,      QTD_NS_Income_Shares__c = 0,      MTD_NS_Income_Sales__c = 0,      MTD_NS_Income_Shares__c = 0,
                       PY_NS_Income_Sales__c = 0,       PY_NS_Income_Shares__c = 0,       Total_NS_Income_Sales__c = 0,    Total_NS_Income_Shares__c = 0,
                       Total_NS_HI_Sales__c = 0,       Total_NS_HI_Shares__c = 0,       YTD_NS_HI_Sales__c = 0,         YTD_NS_HI_Shares__c = 0,
                       QTD_NS_HI_Sales__c = 0,         QTD_NS_HI_Shares__c = 0,         MTD_NS_HI_Sales__c = 0,         MTD_NS_HI_Shares__c = 0,
                       PY_NS_HI_Sales__c = 0,          PY_NS_HI_Shares__c = 0,          Total_NS_Income_II_Sales__c = 0, Total_NS_Income_II_Shares__c = 0,
                       YTD_NS_Income_II_Sales__c = 0,   YTD_NS_Income_II_Shares__c = 0,   QTD_NS_Income_II_Sales__c = 0,   QTD_NS_Income_II_Shares__c = 0,
                       MTD_NS_Income_II_Sales__c = 0,   MTD_NS_Income_II_Shares__c = 0,   PY_NS_Income_II_Sales__c = 0,    PY_NS_Income_II_Shares__c = 0,
                       Rollup_Trades__c = DateTime.now()
                   )
                            );
            }
            Map<String, SObjectField[]>
                ytd = new map<string, sobjectfield[]> {
                    '3910' => new sobjectfield[] { account.YTD_NIOR_I_Sales__c , account.YTD_NIOR_I_Shares__c},
                    '3911' => new sobjectfield[] { account.YTD_NS_Income_Sales__c , account.YTD_NS_Income_Shares__c },
                    '3912' => new sobjectfield[] { account.YTD_NS_HI_Sales__c , account.YTD_NS_HI_Shares__c },
                    '3915' => new sobjectfield[] { account.YTD_NS_Income_II_Sales__c , account.YTD_NS_Income_II_Shares__c }    
                },
                qtd = new map<string, sobjectfield[]> {
                    '3910' => new sobjectfield[] { account.QTD_NIOR_I_Sales__c , account.QTD_NIOR_I_Shares__c},
                    '3911' => new sobjectfield[] { account.QTD_NS_Income_Sales__c , account.QTD_NS_Income_Shares__c },
                    '3912' => new sobjectfield[] { account.QTD_NS_HI_Sales__c , account.QTD_NS_HI_Shares__c },
                    '3915' => new sobjectfield[] { account.QTD_NS_Income_II_Sales__c , account.QTD_NS_Income_II_Shares__c }
                },
                mtd = new map<string, sobjectfield[]> {
                    '3910' => new sobjectfield[] { account.MTD_NIOR_I_Sales__c , account.MTD_NIOR_I_Shares__c},
                    '3911' => new sobjectfield[] { account.MTD_NS_Income_Sales__c , account.MTD_NS_Income_Shares__c },
                    '3912' => new sobjectfield[] { account.MTD_NS_HI_Sales__c , account.MTD_NS_HI_Shares__c },
                    '3915' => new sobjectfield[] { account.MTD_NS_Income_II_Sales__c , account.MTD_NS_Income_II_Shares__c }
                },
                py = new map<string, sobjectfield[]> {
                    '3910' => new sobjectfield[] { account.PY_NIOR_I_Sales__c , account.PY_NIOR_I_Shares__c},
                    '3911' => new sobjectfield[] { account.PY_NS_Income_Sales__c , account.PY_NS_Income_Shares__c },
                    '3912' => new sobjectfield[] { account.PY_NS_HI_Sales__c , account.PY_NS_HI_Shares__c },
                    '3915' => new sobjectfield[] { account.PY_NS_Income_II_Sales__c , account.PY_NS_Income_II_Shares__c }
                },
                total = new map<string, sobjectfield[]> {
                    '3910' => new sobjectfield[] { account.Total_NIOR_I_Sales__c , account.Total_NIOR_I_Shares__c},
                    '3911' => new sobjectfield[] { account.Total_NS_Income_Sales__c , account.Total_NS_Income_Shares__c },
                    '3912' => new sobjectfield[] { account.Total_NS_HI_Sales__c , account.Total_NS_HI_Shares__c },
                    '3915' => new sobjectfield[] { account.Total_NS_Income_II_Sales__c , account.Total_NS_Income_II_Shares__c }
                };
	
	// We make the select in a "for" so instead of selecting to many records at once hitting the heap size limit the for it will take only 200 records to work with at each iteration.
	for(Trades__c[] tradesList : [select Dollar_Amount_of_the_transaction__c, Fund_Number__c, Number_of_Shares_of_the_transaction__c, Resolved_Firm_Trading_ID__c, Resolved_Firm_Trading_IDs__c, Trade_Date__c from Trades__c where Resolved_Firm_Trading_ID__c in :accountIds and Fund_Number__c in ('3910', '3911', '3912', '3915') and Dollar_Amount_of_the_transaction__c != null and Number_of_Shares_of_the_transaction__c != null and Trade_Date__c != null and Dollar_Amount_of_the_transaction__c >= 0 and Number_of_Shares_of_the_transaction__c >= 0]){
        for(trades__c trade: tradesList) {
            
            if(date.today().year() == trade.trade_date__c.year()) {
                system.debug(ytd);
                accounts.get(trade.Resolved_Firm_Trading_ID__c).put(ytd.get(trade.fund_number__c)[0], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(ytd.get(trade.fund_number__c)[0]))+trade.Dollar_Amount_of_The_Transaction__c);
                accounts.get(trade.Resolved_Firm_Trading_ID__c).put(ytd.get(trade.fund_number__c)[1], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(ytd.get(trade.fund_number__c)[1]))+trade.Number_of_Shares_of_the_transaction__c);
                
                system.debug(qtd);
                //( (date.ValueOf(date.today().month()).divide(3, 0) == date.ValueOf(trade.trade_date__c.month()).divide(3, 0)) )
                if((((date.today().month() - 1) / 3) + 1) == (((trade.Trade_Date__c.month() - 1) / 3) + 1))   {
                    accounts.get(trade.Resolved_Firm_Trading_ID__c).put(qtd.get(trade.fund_number__c)[0], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(qtd.get(trade.fund_number__c)[0]))+trade.Dollar_Amount_of_The_Transaction__c);
                    accounts.get(trade.Resolved_Firm_Trading_ID__c).put(qtd.get(trade.fund_number__c)[1], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(qtd.get(trade.fund_number__c)[1]))+trade.Number_of_Shares_of_the_transaction__c);
                    
                    system.debug(mtd);
                    if(date.today().month()==trade.trade_date__c.month()) {
                        accounts.get(trade.Resolved_Firm_Trading_ID__c).put(mtd.get(trade.fund_number__c)[0], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(mtd.get(trade.fund_number__c)[0]))+trade.Dollar_Amount_of_The_Transaction__c);
                        accounts.get(trade.Resolved_Firm_Trading_ID__c).put(mtd.get(trade.fund_number__c)[1], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(mtd.get(trade.fund_number__c)[1]))+trade.Number_of_Shares_of_the_transaction__c);
                    }
                }
            } else if(date.today().year()-1==trade.trade_date__c.year()) {
                accounts.get(trade.Resolved_Firm_Trading_ID__c).put(py.get(trade.fund_number__c)[0], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(py.get(trade.fund_number__c)[0]))+trade.Dollar_Amount_of_The_Transaction__c);
                accounts.get(trade.Resolved_Firm_Trading_ID__c).put(py.get(trade.fund_number__c)[1], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(py.get(trade.fund_number__c)[1]))+trade.Number_of_Shares_of_the_transaction__c);
            }
            
            accounts.get(trade.Resolved_Firm_Trading_ID__c).put(total.get(trade.fund_number__c)[0], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(total.get(trade.fund_number__c)[0]))+trade.Dollar_Amount_of_The_Transaction__c);
            accounts.get(trade.Resolved_Firm_Trading_ID__c).put(total.get(trade.fund_number__c)[1], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(total.get(trade.fund_number__c)[1]))+trade.Number_of_Shares_of_the_transaction__c);
        }
            }
        }
        inprog = true;
        update accounts.values();
        inprog = false;
    }
}

Account Trigger
trigger Account_RollupTrades on Account (after update) {
    if(Account_RollupTrades.inprog == false) {
        //set<ID> sID = new set<ID> (trigger.newMap.keySet());
        Account_RollupTrades.execute(trigger.newMap.keySet(), trigger.new);
    }
}

Contact Class
public class Contact_RollupTrades {
    public Static Contact_Setting__c setting = Contact_Setting__c.getInstance();
	public static boolean inprog = false;

    public static void execute(Set<Id> contactIds, List<Contact> contactsList) {
        Map<Id, Contact> contacts = new Map<Id, Contact>(ContactsList);
        system.debug('execute');
        if(setting.Disable_Contact_Rollup__c != true) {
            //Map<Id, Contact> contacts = new Map<Id, Contact>();
            for(Id contactId:contactIds) {
                system.debug(contactid);
                contacts.put(contactId,
                    new Contact(
                        Id=contactId,
                        YTD_NIOR_I_Sales__c = 0,       YTD_NIOR_I_Shares__c = 0,       QTD_NIOR_I_Sales__c = 0,         QTD_NIOR_I_Shares__c = 0,
                        MTD_NIOR_I_Sales__c = 0,       MTD_NIOR_I_Shares__c = 0,       PY_NIOR_I_Sales__c = 0,          PY_NIOR_I_Shares__c = 0,
                        Total_NIOR_I_Sales__c = 0,     Total_NIOR_I_Shares__c = 0,     YTD_NS_Income_Sales__c = 0,      YTD_NS_Income_Shares__c = 0,
                        QTD_NS_Income_Sales__c = 0,    QTD_NS_Income_Shares__c = 0,    MTD_NS_Income_Sales__c = 0,      MTD_NS_Income_Shares__c = 0,
                        PY_NS_Income_Sales__c = 0,     PY_NS_Income_Shares__c = 0,     Total_NS_Income_Sales__c = 0,    Total_NS_Income_Shares__c = 0,
                        Total_NS_HI_Sales__c = 0,     Total_NS_HI_Shares__c = 0,     YTD_NS_HI_Sales__c = 0,         YTD_NS_HI_Shares__c = 0,
                        QTD_NS_HI_Sales__c = 0,       QTD_NS_HI_Shares__c = 0,       MTD_NS_HI_Sales__c = 0,         MTD_NS_HI_Shares__c = 0,
                        PY_NS_HI_Sales__c = 0,        PY_NS_HI_Shares__c = 0,        Total_NS_Income_II_Sales__c = 0, Total_NS_Income_II_Shares__c = 0,
                        YTD_NS_Income_II_Sales__c = 0, YTD_NS_Income_II_Shares__c = 0, QTD_NS_Income_II_Sales__c = 0,   QTD_NS_Income_II_Shares__c = 0,
                        MTD_NS_Income_II_Sales__c = 0, MTD_NS_Income_II_Shares__c = 0, PY_NS_Income_II_Sales__c = 0,    PY_NS_Income_II_Shares__c = 0,
                        YES_NIOR_I_Sales__c = 0,       YES_NIOR_I_Shares__c = 0,       YES_NS_HI_Sales__c = 0,          YES_NS_HI_Shares__c=0,
                        YES_NS_Income_II_Sales__c = 0, YES_NS_Income_II_Shares__c = 0, YES_NS_Income_Sales__c = 0,      YES_NS_Income_Shares__c = 0,
                        Rollup_Trades__c = DateTime.now()
                    )
                            );
            }
            Map<String, SObjectField[]>
                ytd = new map<string, sobjectfield[]> {
                    '3910' => new sobjectfield[] { contact.YTD_NIOR_I_Sales__c , contact.YTD_NIOR_I_Shares__c},
                    '3911' => new sobjectfield[] { contact.YTD_NS_Income_Sales__c , contact.YTD_NS_Income_Shares__c },
                    '3912' => new sobjectfield[] { contact.YTD_NS_HI_Sales__c , contact.YTD_NS_HI_Shares__c },
                    '3915' => new sobjectfield[] { contact.YTD_NS_Income_II_Sales__c , contact.YTD_NS_Income_II_Shares__c }    
                },
                qtd = new map<string, sobjectfield[]> {
                    '3910' => new sobjectfield[] { contact.QTD_NIOR_I_Sales__c , contact.QTD_NIOR_I_Shares__c},
                    '3911' => new sobjectfield[] { contact.QTD_NS_Income_Sales__c , contact.QTD_NS_Income_Shares__c },
                    '3912' => new sobjectfield[] { contact.QTD_NS_HI_Sales__c , contact.QTD_NS_HI_Shares__c },
                    '3915' => new sobjectfield[] { contact.QTD_NS_Income_II_Sales__c , contact.QTD_NS_Income_II_Shares__c }
                },
                mtd = new map<string, sobjectfield[]> {
                    '3910' => new sobjectfield[] { contact.MTD_NIOR_I_Sales__c , contact.MTD_NIOR_I_Shares__c},
                    '3911' => new sobjectfield[] { contact.MTD_NS_Income_Sales__c , contact.MTD_NS_Income_Shares__c },
                    '3912' => new sobjectfield[] { contact.MTD_NS_HI_Sales__c , contact.MTD_NS_HI_Shares__c },
                    '3915' => new sobjectfield[] { contact.MTD_NS_Income_II_Sales__c , contact.MTD_NS_Income_II_Shares__c }
                },
                yes = new map<string, sobjectfield[]> {
                    '3910' => new sobjectfield[] { contact.YES_NIOR_I_Sales__c , contact.YES_NIOR_I_Shares__c},
                    '3911' => new sobjectfield[] { contact.YES_NS_Income_Sales__c , contact.YES_NS_Income_Shares__c },
                    '3912' => new sobjectfield[] { contact.YES_NS_HI_Sales__c , contact.YES_NS_HI_Shares__c },
                    '3915' => new sobjectfield[] { contact.YES_NS_Income_II_Sales__c , contact.YES_NS_Income_II_Shares__c }
                },
                py = new map<string, sobjectfield[]> {
                    '3910' => new sobjectfield[] { contact.PY_NIOR_I_Sales__c , contact.PY_NIOR_I_Shares__c},
                    '3911' => new sobjectfield[] { contact.PY_NS_Income_Sales__c , contact.PY_NS_Income_Shares__c },
                    '3912' => new sobjectfield[] { contact.PY_NS_HI_Sales__c , contact.PY_NS_HI_Shares__c },
                    '3915' => new sobjectfield[] { contact.PY_NS_Income_II_Sales__c , contact.PY_NS_Income_II_Shares__c }
                },
                total = new map<string, sobjectfield[]> {
                    '3910' => new sobjectfield[] { contact.Total_NIOR_I_Sales__c , contact.Total_NIOR_I_Shares__c},
                    '3911' => new sobjectfield[] { contact.Total_NS_Income_Sales__c , contact.Total_NS_Income_Shares__c },
                    '3912' => new sobjectfield[] { contact.Total_NS_HI_Sales__c , contact.Total_NS_HI_Shares__c },
                    '3915' => new sobjectfield[] { contact.Total_NS_Income_II_Sales__c , contact.Total_NS_Income_II_Shares__c }
                };
	// We make the select in a "for" so instead of selecting to many records at once hitting the heap size limit the for it will take only 200 records to work with at each iteration.
	for(Trades__c[] tradesList : [select Dollar_Amount_of_the_transaction__c, Fund_Number__c, Number_of_Shares_of_the_transaction__c, Resolved_to_Rep_Trading_ID__c, Trade_Date__c from Trades__c where Resolved_to_Rep_Trading_ID__c in :contactIds and Fund_Number__c in ('3910', '3911','3912', '3915') and Dollar_Amount_of_the_transaction__c != null and Number_of_Shares_of_the_transaction__c != null and Trade_Date__c != null and Dollar_Amount_of_the_transaction__c >= 0 and Number_of_Shares_of_the_transaction__c >= 0]){
        for(trades__c trade:tradesList) {
            
            system.debug(ytd);
            if(date.today().year() == trade.trade_date__c.year()) {
                contacts.get(trade.Resolved_to_Rep_Trading_Id__c).put(ytd.get(trade.fund_number__c)[0], ((Decimal)contacts.get(trade.Resolved_to_Rep_Trading_Id__c).get(ytd.get(trade.fund_number__c)[0]))+trade.Dollar_Amount_of_The_Transaction__c);
                contacts.get(trade.Resolved_to_Rep_Trading_Id__c).put(ytd.get(trade.fund_number__c)[1], ((Decimal)contacts.get(trade.Resolved_to_Rep_Trading_Id__c).get(ytd.get(trade.fund_number__c)[1]))+trade.Number_of_Shares_of_the_transaction__c);
                
                system.debug(qtd);
                //( (date.ValueOf(date.today().month()).divide(3, 0) == date.ValueOf(trade.trade_date__c.month()).divide(3, 0)) )
                if((((date.today().month() - 1) / 3) + 1) == (((trade.Trade_Date__c.month() - 1) / 3) + 1))   {
                    contacts.get(trade.Resolved_to_Rep_Trading_Id__c).put(qtd.get(trade.fund_number__c)[0], ((Decimal)contacts.get(trade.Resolved_to_Rep_Trading_Id__c).get(qtd.get(trade.fund_number__c)[0]))+trade.Dollar_Amount_of_The_Transaction__c);
                    contacts.get(trade.Resolved_to_Rep_Trading_Id__c).put(qtd.get(trade.fund_number__c)[1], ((Decimal)contacts.get(trade.Resolved_to_Rep_Trading_Id__c).get(qtd.get(trade.fund_number__c)[1]))+trade.Number_of_Shares_of_the_transaction__c);
                    
                    system.debug(mtd);
                    if(date.today().month()==trade.trade_date__c.month()) {
                        contacts.get(trade.Resolved_to_Rep_Trading_Id__c).put(mtd.get(trade.fund_number__c)[0], ((Decimal)contacts.get(trade.Resolved_to_Rep_Trading_Id__c).get(mtd.get(trade.fund_number__c)[0]))+trade.Dollar_Amount_of_The_Transaction__c);
                        contacts.get(trade.Resolved_to_Rep_Trading_Id__c).put(mtd.get(trade.fund_number__c)[1], ((Decimal)contacts.get(trade.Resolved_to_Rep_Trading_Id__c).get(mtd.get(trade.fund_number__c)[1]))+trade.Number_of_Shares_of_the_transaction__c);
                        
                        system.debug(yes);
                        if(date.today().day()-1==trade.trade_date__c.day()) {
                            contacts.get(trade.Resolved_to_Rep_Trading_Id__c).put(yes.get(trade.fund_number__c)[0], ((Decimal)contacts.get(trade.Resolved_to_Rep_Trading_Id__c).get(yes.get(trade.fund_number__c)[0]))+trade.Dollar_Amount_of_The_Transaction__c);
                            contacts.get(trade.Resolved_to_Rep_Trading_Id__c).put(yes.get(trade.fund_number__c)[1], ((Decimal)contacts.get(trade.Resolved_to_Rep_Trading_Id__c).get(yes.get(trade.fund_number__c)[1]))+trade.Number_of_Shares_of_the_transaction__c);
                        }
                    }
                }
            }else if(date.today().year()-1==trade.trade_date__c.year()) {
                contacts.get(trade.Resolved_to_Rep_Trading_Id__c).put(py.get(trade.fund_number__c)[0], ((Decimal)contacts.get(trade.Resolved_to_Rep_Trading_Id__c).get(py.get(trade.fund_number__c)[0]))+trade.Dollar_Amount_of_The_Transaction__c);
                contacts.get(trade.Resolved_to_Rep_Trading_Id__c).put(py.get(trade.fund_number__c)[1], ((Decimal)contacts.get(trade.Resolved_to_Rep_Trading_Id__c).get(py.get(trade.fund_number__c)[1]))+trade.Number_of_Shares_of_the_transaction__c);
            }
            
            contacts.get(trade.Resolved_to_Rep_Trading_Id__c).put(total.get(trade.fund_number__c)[0], ((Decimal)contacts.get(trade.Resolved_to_Rep_Trading_Id__c).get(total.get(trade.fund_number__c)[0]))+trade.Dollar_Amount_of_The_Transaction__c);
            contacts.get(trade.Resolved_to_Rep_Trading_Id__c).put(total.get(trade.fund_number__c)[1], ((Decimal)contacts.get(trade.Resolved_to_Rep_Trading_Id__c).get(total.get(trade.fund_number__c)[1]))+trade.Number_of_Shares_of_the_transaction__c);

        }
            }
        }
        inprog = true;
        update contacts.values();
        inprog = false;
    }
}

Contact Trigger
trigger Contact_RollupTrades on Contact (after update) {
    if(Contact_RollupTrades.inprog == false) {
        //Set<ID> sID = new Set<ID>(trigger.newMap.keySet());
        Contact_RollupTrades.execute (trigger.newMap.keySet(), trigger.new);
    }
}

 
This should be a simple fix, but I'm not sure how to do it. My footer only displays the calculated total if I make a change to the picklist in the column. Once I hit save or reopen the record, the total is gone until I make a change again (using onchange of course). Is there a way to always have the total rendered? Like have it say 0% before any selections, then show the total even after a save?

I've tried using rendered and adding the calculation the save button, still not displaying the total. Here's what it looks like after a save and I revisit the record, the Total value is blank.

User-added image

Here's my code if that helps.
<apex:actionFunction name="calculateAllocation" action="{!calculateAllocation}" reRender="Split, totalsPanel"/>
        <apex:actionFunction name="calculateSplit" action="{!calculateSplit}" reRender="totalsSplit" />         


   <apex:pageBlockSection id="Allocation" title="Allocate Expenses" Columns="1"  collapsible="false" rendered="{!(expenseLineItem.AllocationCheckbox__c == true)}">
                <apex:outputLabel value="Please select the Managed Company and the percentage amount you wish to allocate to it. Make sure it sums to 100%. Press Save in order to see the Allocation Split value." />
                <apex:variable var="rowNumber" value="{!0}"/>
                <apex:pageBlockTable id="allocationTable" var="allocation" columns="4" value="{!expenseLineItemAllocationList}">
                    <apex:column headerValue="Managed Company">
                        <apex:inputField value="{!allocation.Product__c}" required="{!IF(expenseLineItem.AllocationCheckbox__c == true, True, False)}"/>
                        <apex:facet name="footer">
                            <apex:outputPanel layout="block" style="text-align: right;" >
                                <apex:outputText value="Total" />
                            </apex:outputPanel>
						</apex:facet>
                    </apex:column>
                    <apex:column headerValue="Allocation %">
                        <apex:inputField value="{!allocation.Allocation__c}" onchange="calculateAllocation(); calculateSplit();" required="{!IF(expenseLineItem.AllocationCheckbox__c == true, True, False)}"/>
                        <apex:facet name="footer">
                            <apex:outputPanel layout="block" id="totalsPanel">
                                <apex:outputText value="{!totalAllocation}" rendered="{!IF(expenseLineItem.AllocationCheckbox__c == true, True, False)}" />
                            </apex:outputPanel>
						</apex:facet>
                    </apex:column>
                    <apex:column headerValue="Allocation Split">
                        <apex:outputField value="{!allocation.Allocation_Split__c}" />
                        <apex:facet name="footer2">
                            <apex:outputPanel layout="block" id="totalsSplit"  >
                                <apex:outputText value="{!totalSplit}" />
                            </apex:outputPanel>
                        </apex:facet>
                    </apex:column>
                    <apex:column headerValue="Action">
                        <apex:commandButton value="Delete" action="{!deleteRow}" rerender="Allocation, footer, totalsPanel" oncomplete="calculateAllocation(); calculateSplit();" >
                            <apex:param name="Allocation" value="{!FLOOR(rowNumber)}" assignTo="{!rowIndex}"/>
                            <apex:param name="deleteId" value="{!allocation.Id}" assignTo="{!deleteId}"/>
                        </apex:commandButton>
                        <apex:variable var="rowNumber" value="{!rowNumber+1}" />
                    </apex:column>
                </apex:pageBlockTable>
                <apex:commandButton value="Add Row" action="{!addRow}" rerender="allocationTable"/>
            </apex:pageBlockSection>
//New Object For Custom Allocation
    public Expense_Line_Item_Allocation__c expenseLineItemAllocation {get; set;} //insert field from allocation
    public List<Expense_Line_Item_Allocation__c> expenseLineItemAllocationList {get {
        if (ExpenseLineItemAllocationList != null)
            return ExpenseLineItemAllocationList;
        if (controller.getId() != null) try {
            ExpenseLineItemAllocationList = [
                select Allocation__c
                , Product__c
                , Expense_Split_Amount__c
                , Expense_Line_Item_Detail__c
                , Share_Of_Total_Allocation__c
                , Allocation_Split__c
                
                from Expense_Line_Item_Allocation__c
                where Expense_Line_Item_Detail__c = :expenseLineItem.Id
                order by Product__c desc
            ];
            
        } catch (System.DmlException dmlException) {
            ApexPages.addMessages(dmlException);
        }
        if (ExpenseLineItemAllocationList == null || ExpenseLineItemAllocationList.size() == 0) {
            ExpenseLineItemAllocationList = new List<Expense_Line_Item_Allocation__c>();
            if(expenseLineItem != null && !String.isBlank(expenseLineItem.Managed_Company__c)) {
                string[] parsedCompanies = expenseLineItem.Managed_Company__c.split(';');
                for(string s: parsedCompanies) {
                    ExpenseLineItemAllocationList.add(new Expense_Line_Item_Allocation__c(product__c = s));
                }
            }
        }
        return ExpenseLineItemAllocationList;
    } set;} //insert list of fields in allocation
    
    public void calculateAllocation() {
        Decimal dTotAllocation = 0;
        for(Expense_Line_Item_Allocation__c elia : expenseLineItemAllocationList) {
            if(!String.isBlank(elia.Allocation__c)) {
                dTotAllocation += Decimal.valueOf(elia.Allocation__c.replace('%',''));
            }
        }
        totalAllocation = dTotAllocation + '%';
    }
    public void calculateSplit() {
        Integer SplitTotal = 0;
        for(Expense_Line_Item_Allocation__c elia : expenseLineItemAllocationList) {
            if((elia.Allocation_Split__c) != null) {
                SplitTotal += Integer.valueOf(elia.Allocation_Split__c);
            }
        }
        totalSplit = '$' + SplitTotal;
    }
    
    public void saveCompany(){
        for(Expense_Line_Item_Allocation__c ela: expenseLineItemAllocationList){ 
            ela.Expense_Line_Item_Detail__c = expenseLineItem.Id;
            if(expenseLineItem.AllocationCheckbox__c == True) {
                if(!String.isBlank(totalAllocation)) {
                    if(Decimal.valueOf(totalAllocation.replace('%','')) != 100) {
                        addMessage(ApexPages.Severity.ERROR,'Please ensure the percentages add to 100%.');
                    }
                }
            }
            upsert ela;
        }
    }
    
    public void addRow(){
        expenseLineItemAllocationList.add(new Expense_Line_Item_Allocation__c());
        calculateAllocation();
        calculateSplit();
    }
    
    public integer rowIndex {get; set;}
    public Expense_Line_Item_Allocation__c del;
    public String deleteId {get; set;}
    public String totalAllocation {get; set;}
    public String totalSplit {get; set;}
    //public List<Id> deleteItems {get;set;}
    public void deleteRow(){
        calculateAllocation();
        calculateSplit();
        del = new Expense_Line_Item_Allocation__c();
        del = expenseLineItemAllocationList.remove(rowIndex);
        if(deleteId != null){
            try{
                Expense_Line_Item_Allocation__c elia = new Expense_Line_Item_Allocation__c(id=deleteId);
                delete elia;
            }catch(exception e){
                system.debug(string.valueof(e));//unable to be deleted
            }
        }
    }



 
Using the one trigger per object best practice, my trigger is not updating the results back to old values when an update (that would NOT be counted in the SOQL query) or delete occurs. Please see code below:

Class:
public with sharing class CompletedEvents {
    protected final Event[] eventOldList;
    protected final Event[] eventNewList;
    Set<Id> contIds = new Set<Id>();

    public CompletedEvents(Event[] eventOldList, Event[] eventNewList) {
        this.eventOldList = eventOldList;
        this.eventNewList = eventNewList;
    }

    public CompletedEvents(List<Event> events){
        this.eventNewList = events;
    }
   
 public void executeTotalConferenceCalls(){
        for(Event e : eventNewList){
            if(e.WhoId != null){
                contIds.add(e.WhoId);
            }
        }

        AggregateResult [] ars = [Select WhoId eventId, count(id) ConfCount
                                  From Event
                                  Where WhoId in :contIds
                                  AND EndDateTime < :date.today()
                                  AND isDeleted = False
                                  AND Subject = 'Conference Call'
                                  GROUP BY WhoId All Rows];

        List<Contact> updCon = new List<Contact>();
        for(AggregateResult ar : ars){
            Contact c = new Contact();
            c.Id = (Id)ar.get('eventId');
            c.Total_Conference_Calls__c = Integer.ValueOf(ar.get('ConfCount'));
            updCon.Add(c);
        }

        if(updCon.size()>0){
            update updCon;
        }
    }

    public void executeLastCompletedEvent(){
        for(Event e : eventNewList){
            if(e.WhoId != null){
                contIds.add(e.WhoId);
            }
        }

        Event[] eventList = [Select WhoId, Subject, EndDateTime, ActivityDateTime, ActivityDate
                             From Event
                             Where WhoId in :contIds
                             AND EndDateTime < :date.today()
                             AND isDeleted = False
                             AND Subject != 'B/D-Conference'
                             AND Subject != 'Cancel/No Show'
                             AND Subject != 'DD Meeting'
                             AND Subject != 'NRS-Conference'
                             AND Subject != 'Other'
                             AND Subject != 'Drop-In'
                             AND Subject != 'Business Review'
                             AND Subject != 'One-On-One'
                             AND Subject != 'Travel'
                             AND Subject != 'Professional Association Event'
                             ORDER BY EndDateTime ASC All Rows];

        Map<Id, Contact> cMap = new Map<Id, Contact>();
        for(Event e : eventList){
            Contact c = new Contact(Id = e.WhoId);
            if(c.Id != null){
                c.Last_Completed_Event__c = e.EndDateTime;
                cMap.put(c.Id, c);
            }
        }

        update cMap.values();
    }
}

Trigger
trigger MasterEventTrigger on Event (
    before insert, after insert,
    before update, after update,
    before delete, after delete){
    Event[] eventOldList = trigger.IsDelete ? null : trigger.old;
    Event[] eventNewList = trigger.IsDelete ? trigger.old : trigger.new;
        
    if (Trigger.isBefore) {
        if (Trigger.isInsert) {
                new CompletedEvents(eventOldList, eventNewList).executeTotalConferenceCalls();
                new CompletedEvents(eventOldList, eventNewList).executeLastCompletedEvent();
        }

        if (Trigger.isUpdate) {
                new CompletedEvents(eventOldList, eventNewList).executeTotalConferenceCalls();
                new CompletedEvents(eventOldList, eventNewList).executeLastCompletedEvent();
        }

        if (Trigger.isDelete) {
                new CompletedEvents(eventOldList, eventNewList).executeTotalConferenceCalls();
                new CompletedEvents(eventOldList, eventNewList).executeLastCompletedEvent();
        }
    }
    
    if (Trigger.IsAfter) {
        if (Trigger.isInsert) {
        }
        if (Trigger.isUpdate) {
        }
        if (Trigger.isDelete) {
        }
    }
}

 
All,
I need to make my sales summary code more efficient. Once we hit 9,000 trades on a single Account, the system hits the CPU Limit governor limit, even in a batch job. Anybody have any ideas on the code below? Perhaps moving each calculation in the For loop under each  corresponding map? I'm not sure the best way to change this code, but any help would be greatly appreciated.

Debug log shows errors at random at lines 73, 79, or 92 in the Class and every time on line 4 in the trigger.
CPU Time varies on the number of trades inserted at a time, but even at 1 trade I can get up to 25000 out of 10000 (more than double).

Class:
public class Account_RollupTrades {
    public Static Account_Setting__c setting = Account_Setting__c.getInstance();
    public Static boolean inprog = false;

    public static void execute (Set<Id> accountIds, List<Account> accountsList) {
        Map<Id, Account> accounts = new Map<Id, Account> (AccountsList);
        system.debug ('execute');
        if(setting.Disable_RollupTrades__c != true) {
            //Map<Id, Account> accounts = new Map<Id, Account>();
            for(Id accountId:accountIds) {
                system.debug(accountid);
                accounts.put(accountId,
                   new Account(
                       Id=accountId,
                       /**YTD_NIOR_I_Sales__c = 0,         YTD_NIOR_I_Shares__c = 0,         QTD_NIOR_I_Sales__c = 0,         QTD_NIOR_I_Shares__c = 0,
                       MTD_NIOR_I_Sales__c = 0,         MTD_NIOR_I_Shares__c = 0,         PY_NIOR_I_Sales__c = 0,          PY_NIOR_I_Shares__c = 0,
                       Total_NIOR_I_Sales__c = 0,       Total_NIOR_I_Shares__c = 0,       YTD_NS_Income_Sales__c = 0,      YTD_NS_Income_Shares__c = 0,
                       QTD_NS_Income_Sales__c = 0,      QTD_NS_Income_Shares__c = 0,      MTD_NS_Income_Sales__c = 0,      MTD_NS_Income_Shares__c = 0,
                       PY_NS_Income_Sales__c = 0,       PY_NS_Income_Shares__c = 0,       Total_NS_Income_Sales__c = 0,    Total_NS_Income_Shares__c = 0,**/
                       Total_NS_HI_Sales__c = 0,       Total_NS_HI_Shares__c = 0,       YTD_NS_HI_Sales__c = 0,         YTD_NS_HI_Shares__c = 0,
                       QTD_NS_HI_Sales__c = 0,         QTD_NS_HI_Shares__c = 0,         MTD_NS_HI_Sales__c = 0,         MTD_NS_HI_Shares__c = 0,
                       PY_NS_HI_Sales__c = 0,          PY_NS_HI_Shares__c = 0,          Total_NS_Income_II_Sales__c = 0, Total_NS_Income_II_Shares__c = 0,
                       YTD_NS_Income_II_Sales__c = 0,   YTD_NS_Income_II_Shares__c = 0,   QTD_NS_Income_II_Sales__c = 0,   QTD_NS_Income_II_Shares__c = 0,
                       MTD_NS_Income_II_Sales__c = 0,   MTD_NS_Income_II_Shares__c = 0,   PY_NS_Income_II_Sales__c = 0,    PY_NS_Income_II_Shares__c = 0,
                       Rollup_Trades__c = DateTime.now()
                   )
                            );
            }
            Map<String, SObjectField[]>
                ytd = new map<string, sobjectfield[]> {
                    //'3910' => new sobjectfield[] { account.YTD_NIOR_I_Sales__c , account.YTD_NIOR_I_Shares__c},
                    //'3911' => new sobjectfield[] { account.YTD_NS_Income_Sales__c , account.YTD_NS_Income_Shares__c },
                    '3912' => new sobjectfield[] { account.YTD_NS_HI_Sales__c , account.YTD_NS_HI_Shares__c },
                    '3915' => new sobjectfield[] { account.YTD_NS_Income_II_Sales__c , account.YTD_NS_Income_II_Shares__c }    
                },
                qtd = new map<string, sobjectfield[]> {
                    //'3910' => new sobjectfield[] { account.QTD_NIOR_I_Sales__c , account.QTD_NIOR_I_Shares__c},
                    //'3911' => new sobjectfield[] { account.QTD_NS_Income_Sales__c , account.QTD_NS_Income_Shares__c },
                    '3912' => new sobjectfield[] { account.QTD_NS_HI_Sales__c , account.QTD_NS_HI_Shares__c },
                    '3915' => new sobjectfield[] { account.QTD_NS_Income_II_Sales__c , account.QTD_NS_Income_II_Shares__c }
                },
                mtd = new map<string, sobjectfield[]> {
                    //'3910' => new sobjectfield[] { account.MTD_NIOR_I_Sales__c , account.MTD_NIOR_I_Shares__c},
                    //'3911' => new sobjectfield[] { account.MTD_NS_Income_Sales__c , account.MTD_NS_Income_Shares__c },
                    '3912' => new sobjectfield[] { account.MTD_NS_HI_Sales__c , account.MTD_NS_HI_Shares__c },
                    '3915' => new sobjectfield[] { account.MTD_NS_Income_II_Sales__c , account.MTD_NS_Income_II_Shares__c }
                },
                py = new map<string, sobjectfield[]> {
                    //'3910' => new sobjectfield[] { account.PY_NIOR_I_Sales__c , account.PY_NIOR_I_Shares__c},
                    //'3911' => new sobjectfield[] { account.PY_NS_Income_Sales__c , account.PY_NS_Income_Shares__c },
                    '3912' => new sobjectfield[] { account.PY_NS_HI_Sales__c , account.PY_NS_HI_Shares__c },
                    '3915' => new sobjectfield[] { account.PY_NS_Income_II_Sales__c , account.PY_NS_Income_II_Shares__c }
                },
                total = new map<string, sobjectfield[]> {
                    //'3910' => new sobjectfield[] { account.Total_NIOR_I_Sales__c , account.Total_NIOR_I_Shares__c},
                    //'3911' => new sobjectfield[] { account.Total_NS_Income_Sales__c , account.Total_NS_Income_Shares__c },
                    '3912' => new sobjectfield[] { account.Total_NS_HI_Sales__c , account.Total_NS_HI_Shares__c },
                    '3915' => new sobjectfield[] { account.Total_NS_Income_II_Sales__c , account.Total_NS_Income_II_Shares__c }
                };
    
    // We make the select in a "for" so instead of selecting to many records at once hitting the heap size limit the for it will take only 200 records to work with at each iteration.
    for(Trades__c[] tradesList : [select Dollar_Amount_of_the_transaction__c, Fund_Number__c, Number_of_Shares_of_the_transaction__c, Resolved_Firm_Trading_ID__c, Resolved_Firm_Trading_IDs__c, Trade_Date__c from Trades__c where Resolved_Firm_Trading_ID__c in :accountIds and Fund_Number__c in (/**'3910', '3911',**/ '3912', '3915') and Dollar_Amount_of_the_transaction__c != null and Number_of_Shares_of_the_transaction__c != null and Trade_Date__c != null and Dollar_Amount_of_the_transaction__c >= 0 and Number_of_Shares_of_the_transaction__c >= 0 FOR UPDATE]){
        for(trades__c trade: tradesList) {
            
            if(date.today().year() == trade.trade_date__c.year()) {
                accounts.get(trade.Resolved_Firm_Trading_ID__c).put(ytd.get(trade.fund_number__c)[0], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(ytd.get(trade.fund_number__c)[0]))+trade.Dollar_Amount_of_The_Transaction__c);
                accounts.get(trade.Resolved_Firm_Trading_ID__c).put(ytd.get(trade.fund_number__c)[1], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(ytd.get(trade.fund_number__c)[1]))+trade.Number_of_Shares_of_the_transaction__c);
                //system.debug(ytd);
                //system.debug(LoggingLevel.DEBUG, + Limits.getCpuTime() + '/' + Limits.getLimitCpuTime());
                
                //( (date.ValueOf(date.today().month()).divide(3, 0) == date.ValueOf(trade.trade_date__c.month()).divide(3, 0)) )
                if((((date.today().month() - 1) / 3) + 1) == (((trade.Trade_Date__c.month() - 1) / 3) + 1))   {
                    accounts.get(trade.Resolved_Firm_Trading_ID__c).put(qtd.get(trade.fund_number__c)[0], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(qtd.get(trade.fund_number__c)[0]))+trade.Dollar_Amount_of_The_Transaction__c);
                    accounts.get(trade.Resolved_Firm_Trading_ID__c).put(qtd.get(trade.fund_number__c)[1], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(qtd.get(trade.fund_number__c)[1]))+trade.Number_of_Shares_of_the_transaction__c);
                    //system.debug(qtd);
                    //system.debug(LoggingLevel.DEBUG, + Limits.getCpuTime() + '/' + Limits.getLimitCpuTime());
                    
                    if(date.today().month()==trade.trade_date__c.month()) {
                        accounts.get(trade.Resolved_Firm_Trading_ID__c).put(mtd.get(trade.fund_number__c)[0], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(mtd.get(trade.fund_number__c)[0]))+trade.Dollar_Amount_of_The_Transaction__c);
                        accounts.get(trade.Resolved_Firm_Trading_ID__c).put(mtd.get(trade.fund_number__c)[1], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(mtd.get(trade.fund_number__c)[1]))+trade.Number_of_Shares_of_the_transaction__c);
                        //system.debug(mtd);
                        //system.debug(LoggingLevel.DEBUG, + Limits.getCpuTime() + '/' + Limits.getLimitCpuTime());
                    }
                }
            } 
            else if(date.today().year()-1==trade.trade_date__c.year()) {
                accounts.get(trade.Resolved_Firm_Trading_ID__c).put(py.get(trade.fund_number__c)[0], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(py.get(trade.fund_number__c)[0]))+trade.Dollar_Amount_of_The_Transaction__c);
                accounts.get(trade.Resolved_Firm_Trading_ID__c).put(py.get(trade.fund_number__c)[1], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(py.get(trade.fund_number__c)[1]))+trade.Number_of_Shares_of_the_transaction__c);
                //system.debug(py);
                //system.debug(LoggingLevel.DEBUG, + Limits.getCpuTime() + '/' + Limits.getLimitCpuTime());
            }
            accounts.get(trade.Resolved_Firm_Trading_ID__c).put(total.get(trade.fund_number__c)[0], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(total.get(trade.fund_number__c)[0]))+trade.Dollar_Amount_of_The_Transaction__c);
            accounts.get(trade.Resolved_Firm_Trading_ID__c).put(total.get(trade.fund_number__c)[1], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(total.get(trade.fund_number__c)[1]))+trade.Number_of_Shares_of_the_transaction__c);
            //system.debug(total);
            //system.debug(LoggingLevel.DEBUG, + Limits.getCpuTime() + '/' + Limits.getLimitCpuTime());
        }
            }
        }
        inprog = true;
        update accounts.values();
        inprog = false;
    }
}
Trigger:
trigger Account_RollupTrades on Account (after update) {
    if(Account_RollupTrades.inprog == false) {
        //set<ID> sID = new set<ID> (trigger.newMap.keySet());
        Account_RollupTrades.execute(trigger.newMap.keySet(), trigger.new);
    }
}



 
Using the one trigger per object best practice, my trigger is not updating the results back to old values when an update (that would NOT be counted in the SOQL query) or delete occurs. Please see code below:

Class:
public with sharing class CompletedEvents {
    protected final Event[] eventOldList;
    protected final Event[] eventNewList;
    Set<Id> contIds = new Set<Id>();

    public CompletedEvents(Event[] eventOldList, Event[] eventNewList) {
        this.eventOldList = eventOldList;
        this.eventNewList = eventNewList;
    }

    public CompletedEvents(List<Event> events){
        this.eventNewList = events;
    }
   
 public void executeTotalConferenceCalls(){
        for(Event e : eventNewList){
            if(e.WhoId != null){
                contIds.add(e.WhoId);
            }
        }

        AggregateResult [] ars = [Select WhoId eventId, count(id) ConfCount
                                  From Event
                                  Where WhoId in :contIds
                                  AND EndDateTime < :date.today()
                                  AND isDeleted = False
                                  AND Subject = 'Conference Call'
                                  GROUP BY WhoId All Rows];

        List<Contact> updCon = new List<Contact>();
        for(AggregateResult ar : ars){
            Contact c = new Contact();
            c.Id = (Id)ar.get('eventId');
            c.Total_Conference_Calls__c = Integer.ValueOf(ar.get('ConfCount'));
            updCon.Add(c);
        }

        if(updCon.size()>0){
            update updCon;
        }
    }

    public void executeLastCompletedEvent(){
        for(Event e : eventNewList){
            if(e.WhoId != null){
                contIds.add(e.WhoId);
            }
        }

        Event[] eventList = [Select WhoId, Subject, EndDateTime, ActivityDateTime, ActivityDate
                             From Event
                             Where WhoId in :contIds
                             AND EndDateTime < :date.today()
                             AND isDeleted = False
                             AND Subject != 'B/D-Conference'
                             AND Subject != 'Cancel/No Show'
                             AND Subject != 'DD Meeting'
                             AND Subject != 'NRS-Conference'
                             AND Subject != 'Other'
                             AND Subject != 'Drop-In'
                             AND Subject != 'Business Review'
                             AND Subject != 'One-On-One'
                             AND Subject != 'Travel'
                             AND Subject != 'Professional Association Event'
                             ORDER BY EndDateTime ASC All Rows];

        Map<Id, Contact> cMap = new Map<Id, Contact>();
        for(Event e : eventList){
            Contact c = new Contact(Id = e.WhoId);
            if(c.Id != null){
                c.Last_Completed_Event__c = e.EndDateTime;
                cMap.put(c.Id, c);
            }
        }

        update cMap.values();
    }
}

Trigger
trigger MasterEventTrigger on Event (
    before insert, after insert,
    before update, after update,
    before delete, after delete){
    Event[] eventOldList = trigger.IsDelete ? null : trigger.old;
    Event[] eventNewList = trigger.IsDelete ? trigger.old : trigger.new;
        
    if (Trigger.isBefore) {
        if (Trigger.isInsert) {
                new CompletedEvents(eventOldList, eventNewList).executeTotalConferenceCalls();
                new CompletedEvents(eventOldList, eventNewList).executeLastCompletedEvent();
        }

        if (Trigger.isUpdate) {
                new CompletedEvents(eventOldList, eventNewList).executeTotalConferenceCalls();
                new CompletedEvents(eventOldList, eventNewList).executeLastCompletedEvent();
        }

        if (Trigger.isDelete) {
                new CompletedEvents(eventOldList, eventNewList).executeTotalConferenceCalls();
                new CompletedEvents(eventOldList, eventNewList).executeLastCompletedEvent();
        }
    }
    
    if (Trigger.IsAfter) {
        if (Trigger.isInsert) {
        }
        if (Trigger.isUpdate) {
        }
        if (Trigger.isDelete) {
        }
    }
}

 
All,
I'm trying to refactor my trigger code to a batch. How can I execute my class to fire within the batch?

Class
public class Account_RollupProductInterest {
    protected final Account[] accountNewList;
    protected final Account[] accountOldList;
    Set<Id> acctIds = new Set<Id>();
    Decimal RXRsum = 0;
    Decimal A40Actsum = 0;
    Decimal DSTsum = 0;
    Decimal PPsum = 0;
    Decimal ITSum = 0;
    Decimal ActiveRepsSum = 0;
    Decimal NSTickets = 0;

    public Account_RollupProductInterest(Account[] accountOldList, Account[] accountNewList) {
        this.accountNewList = accountNewList;
        this.accountOldList = accountOldList;
    }

    public Account_RollupProductInterest(){
        new Account_RollupProductInterest().executeTableRollup();
    }

    //Update Numbers Table
    public void executeTableRollup(){
        for(Account a : accountNewList){
            if(a.ParentId != null){
                acctIds.add(a.ParentId);
            }
        }

        List<Account> updAcc = new List<Account>();
        List<Account> childAccts = new List<Account>([Select Id, Number_of_NS_RXR_Propects__c,
                                                        Number_of_40_Act_Fund_Prospects__c,
                                                        Number_of_DST_Prospects__c,
                                                        Number_of_Private_Placement_Prospects__c,
                                                        Number_of_Investor_Tickets__c,
                                                        Number_Of_Active_Reps__c,
                                                        Number_of_NorthStar_Tickets__c,
                                                   (Select Id, Number_of_NS_RXR_Propects__c,
                                                        Number_of_40_Act_Fund_Prospects__c,
                                                        Number_of_DST_Prospects__c,
                                                        Number_of_Private_Placement_Prospects__c,
                                                        Number_of_Investor_Tickets__c,
                                                        Number_Of_Active_Reps__c,
                                                        Number_of_NorthStar_Tickets__c
                                                From ChildAccounts)
                                                  From Account
                                                  Where Id in :acctIds]);
        for(Account acc : childAccts){
            for(Account child : acc.ChildAccounts){
                    RXRsum += (child.Number_of_NS_RXR_Propects__c != null ? RXRsum + child.Number_of_NS_RXR_Propects__c : 0);
                    acc.Number_of_NS_RXR_Propects__c = RXRsum;

                    A40Actsum += (child.Number_of_40_Act_Fund_Prospects__c != null ? A40Actsum + child.Number_of_40_Act_Fund_Prospects__c : 0);
                    acc.Number_of_40_Act_Fund_Prospects__c = A40Actsum;

                    DSTsum += (child.Number_of_DST_Prospects__c != null ? DSTsum + child.Number_of_DST_Prospects__c : 0);
                    acc.Number_of_DST_Prospects__c = DSTsum;

                    PPsum += (child.Number_of_Private_Placement_Prospects__c != null ? PPsum + child.Number_of_Private_Placement_Prospects__c : 0);
                    acc.Number_of_Private_Placement_Prospects__c = PPsum;

                    ITSum += (child.Number_of_Investor_Tickets__c != null ? ITSum + child.Number_of_Investor_Tickets__c : 0);
                    acc.Number_of_Investor_Tickets__c = ITSum;

                    ActiveRepsSum += (child.Number_Of_Active_Reps__c != null ? ActiveRepsSum + child.Number_Of_Active_Reps__c : 0);
                    acc.Number_Of_Active_Reps__c = ActiveRepsSum;

                    NSTickets += (child.Number_Of_NorthStar_Tickets__c != null ? NSTickets + child.Number_Of_NorthStar_Tickets__c : 0);
                    acc.Number_Of_NorthStar_Tickets__c = NSTickets;
            }
            
            updAcc.add(acc);
        }

        try {
            update updAcc;
        }
        Catch (Exception e) {
            System.debug('Exception : '+e.getMessage());
        }
    }
}

Batch:
Batch:
global class Contact_RollupProductInterestBatchable implements Database.Batchable<sObject> {
     global Database.QueryLocator start(Database.BatchableContext batchableContext){
	 	        return Database.getQueryLocator('Select Id From Account');

         /**String query = 'Select Id, Number_of_NS_RXR_Propects__c,'
                                 + 'Number_of_40_Act_Fund_Prospects__c,'
                                 + 'Number_of_DST_Prospects__c,'
                                 + 'Number_of_Private_Placement_Prospects__c,'
                                 + 'Number_of_Investor_Tickets__c,'
                                 + 'Number_Of_Active_Reps__c,'
                                 + 'Number_of_NorthStar_Tickets__c,'
                                 + '(Select Id, Number_of_NS_RXR_Propects__c,'
                                             + 'Number_of_40_Act_Fund_Prospects__c,'
                                             + 'Number_of_DST_Prospects__c,'
                                             + 'Number_of_Private_Placement_Prospects__c,'
                                             + 'Number_of_Investor_Tickets__c,'
                                             + 'Number_Of_Active_Reps__c,'
                                             + 'Number_of_NorthStar_Tickets__c'
                                             + 'From ChildAccounts)'
                                  + 'From Account';
         return Database.getQueryLocator(query);**/

    }

    global void execute(Database.BatchableContext batchableContext, Account[] accountNewList) {
        // Execute the rollup. It will auto-update the branch accounts once complete
        for(Account a : accountNewList){
        	a.Number_of_NS_RXR_Propects__c = a.ChildAccounts.Number_of_NS_RXR_Propects__c;
        	a.Number_of_40_Act_Fund_Prospects__c = a.ChildAccounts.Number_of_40_Act_Fund_Prospects__c;
        	a.Number_of_DST_Prospects__c = a.ChildAccounts.Number_of_DST_Prospects__c;
        	a.Number_of_Private_Placement_Prospects__c = a.ChildAccounts.Number_of_Private_Placement_Prospects__c;
        	a.Number_of_Investor_Tickets__c = a.ChildAccounts.Number_of_Investor_Tickets__c;
        	a.Number_Of_Active_Reps__c = a.ChildAccounts.Number_Of_Active_Reps__c;
        	a.Number_of_NorthStar_Tickets__c = a.ChildAccounts.Number_of_NorthStar_Tickets__c;
        }

        update accountNewList
    }

    global void finish(Database.BatchableContext batchableContext) {

    }
}

 
All,
I'm trying to display a pageBlockSection based on the value of a picklist. But when I make the selection in the picklist, the pageBlockSection is not displayed. I have also tried wrapping it in an outputPanel container as well. Is my syntax incorrect in the rendered attribute? Here is a snippet of my code:
<apex:pageBlockSection title="Pre-Approval Form Required?" columns="2" rendered="{!NOT(ISBLANK(marketingReimbursementForm))}" collapsible="True">
        		<apex:pageBlockSectionItem >
        			<apex:outputLabel value="{!$ObjectType.Marketing_Reimbursement__c.Fields.Pre_Approval_Required__c.Label}" />
        			<apex:outputPanel layout="block" styleClass="requiredBlock">
        				<apex:actionRegion>
        					<apex:inputField value="{!MarketingReimbursement.Pre_Approval_Required__c}" required="true">
        						<apex:actionSupport event="onchange" rerender="preApprovalFormContainer" />
        					</apex:inputField>
        				</apex:actionRegion>
        			</apex:outputPanel>
        		</apex:pageBlockSectionItem>
        	</apex:pageBlockSection>
        	
        	<apex:outputPanel id="preApprovalFormContainer">
        	<apex:pageBlockSection id="preApprovalForm" title="Pre-Approval Form" columns="2" rendered="{!(marketingReimbursement.Pre_Approval_Required__c =='Yes')}" collapsible="False">
        		<apex:pageBlockSectionItem   >
        			<apex:outputLabel value="{!$ObjectType.Marketing_Reimbursement_Forms__c.Fields.Northstar_Registered_Representative__c.Label}" />
        			<apex:outputPanel layout="block" styleClass="requiredInput">
        				<apex:inputField value="{!marketingReimbursementForm.Northstar_Registered_Representative__c}" required="true"/>
        			</apex:outputPanel>
        		</apex:pageBlockSectionItem>

 
All,
I have a requirement to update a trigger to include Trigger.OldMap so that if a user edits a completed task, it doesn't fire the trigger again. Once I added Trigger.OldMap to the trigger, my test coverage went from 95% to 0%. Adding an Update to the inserted Task in the test code does not seem to help either. Below is my code:

Trigger:
trigger SalesBlitzProcess on Task (after insert, after update) {
    if(!RecursiveTriggerHelper.isAlreadyModified()){
        RecursiveTriggerHelper.setAlreadyModified();{
            Task[] taskOldList = trigger.IsDelete ? null : trigger.old;
            Task[] taskNewList = trigger.IsDelete ? trigger.old : trigger.new;
            if(trigger.oldMap != null) {
                for(task tsk: trigger.new) {
                    if(tsk.isClosed && trigger.oldMap.get(tsk.Id).isClosed == false){
                        new SalesBlitzProcess(trigger.Old, trigger.New).executeLeftMessage();
                        new SalesBlitzProcess(trigger.Old, trigger.New).executeContinueProcess();
                        new SalesBlitzProcess(trigger.Old, trigger.New).executeNotNow();
                        new SalesBlitzProcess(trigger.Old, trigger.New).executeHardNo();
                    }
                }
            }
        }
    }
}



Class
public class SalesBlitzProcess {
    //Grab List of tasks
    protected final Task[] taskNewList;
    protected final Task[] taskOldList;
    
    public SalesBlitzProcess (Task[] taskOldList, Task[] taskNewList){
        this.taskNewList = taskNewList;
        this.taskOldList = taskOldList;
    }
    
    List<Task> taskList = new List<Task>();
    List<Opportunity> oppList = new List<Opportunity>();
    Task t;
    Opportunity o;
    Contact c;
    Account a;
    
    //Left Message - Create new Tasks if the following Outcomes == 'Left Message' || 'No Answer'
    Set<Contact> cSet = new Set<Contact>();
    public void executeLeftMessage(){
        for(Task tsk : taskNewList){
            if(tsk.Status =='Completed' && tsk.Subject == 'Sales Blitz Call - Day 1' && (tsk.Outcome__c == 'Left Message' || tsk.Outcome__c == 'No Answer')){
                //Set c.Nurture_Paused__c = True; and c.Send_Day_1_Follow_Up_Email__c = true;
                if(tsk.WhoId != null && String.valueOf(tsk.whoId).substring(0,3) == '003') {
                    c = new Contact(Id = tsk.whoId);
                    c.Nurture_Paused__c = true;
                    c.Send_Day_1_Follow_Up_Email__c = true;
                    cSet.add(c);
                }
                t = new Task();
                t.OwnerId = tsk.OwnerId;
                t.WhoId = tsk.WhoId;
                t.Subject = 'Sales Blitz Call - Day 3';
                t.Status = 'Not Started';
                t.ActivityDate = System.Today().addDays(2);
                taskList.add(t);
                
            } else if (tsk.Status =='Completed' && tsk.Subject == 'Sales Blitz Call - Day 3' && (tsk.Outcome__c == 'Left Message' || tsk.Outcome__c == 'No Answer')){
                t = new Task();
                t.OwnerId = tsk.OwnerId;
                t.WhoId = tsk.WhoId;
                t.Subject = 'Sales Blitz Call - Day 5';
                t.Status = 'Not Started';
                t.ActivityDate = System.Today().addDays(2);
                taskList.add(t);
                
            } else if (tsk.Status =='Completed' && tsk.Subject == 'Sales Blitz Call - Day 5' && (tsk.Outcome__c == 'Left Message' || tsk.Outcome__c == 'No Answer')){
                //c.Send_Day_1_Follow_Up_Email__c = true;
                if(tsk.WhoId != null && String.valueOf(tsk.whoId).substring(0,3) == '003') {
                    c = new Contact(Id = tsk.whoId);
                    c.Send_Day_5_Follow_Up_Email__c = true;
                    cSet.add(c);
                }
                t = new Task();
                t.OwnerId = tsk.OwnerId;
                t.WhoId = tsk.WhoId;
                t.Subject = 'Sales Blitz Call - Day 8';
                t.Status = 'Not Started';
                t.ActivityDate = System.Today().addDays(3);
                taskList.add(t);
                
            } else if (tsk.Status =='Completed' && tsk.Subject == 'Sales Blitz Call - Day 8' && (tsk.Outcome__c == 'Left Message' || tsk.Outcome__c == 'No Answer')){
                //Set c.Nurture_Paused__c = False;
                if(tsk.WhoId != null && String.valueOf(tsk.whoId).substring(0,3) == '003') {
                    c = new Contact(Id = tsk.whoId);
                    c.Nurture_Paused__c = false;
                    c.Send_Day_1_Follow_Up_Email__c = false;
                    c.Send_Day_5_Follow_Up_Email__c = false;
                    cSet.add(c);
                }
            }
        }
        
        If(!taskList.isEmpty()){
            insert taskList;
        }
        If(!cSet.isEmpty()){
            update new List <Contact>(cSet);
        }
    }
    
    //Continue Process - Create Opportunity if Task has the following outcomes
    Set<Id> ContactIds = new Set<Id>();
    public void executeContinueProcess(){
        for(Task tsk : taskNewList){
            if(tsk.Status =='Completed' && (tsk.Outcome__c == 'Set First Advisor Briefing'
                                            || tsk.Outcome__c == 'Set Qualified Meeting'
                                            || tsk.Outcome__c == 'Set Existing Producer Meeting'
                                            || tsk.Outcome__c == 'Set Touch Base Meeting'
                                            || tsk.Outcome__c == 'Proposal Needed'
                                            || tsk.Outcome__c == 'Verbal Commitment')){
                                                String tId = tsk.WhoId;
                                                if(String.ValueOf(tsk.WhoId).substring(0,3) == '003'){
                                                    ContactIds.add(tsk.WhoId);
                                                }
                                            }
        }
        if(!ContactIds.isEmpty())
        {
            Map<Id, Contact> cIdMap = new Map<Id, Contact>([Select Id, AccountId, Account.Name, Nurture_Paused__c FROM Contact Where Id in:ContactIds]);
            Set<Id> accountIds=new Set<Id>();
            for(Task tsk : taskNewList)
            {
                if(tsk.WhoId != null && cIdMap.get(tsk.WhoId) != null){
                    //o.AccountId = cIdMap.get(tsk.WhoId).AccountId;
                    accountIds.add(cIdMap.get(tsk.WhoId).AccountId);
                }
            }
            
            if(!accountIds.isEmpty())
            {
                Map<Id,Account> mapAccount=new Map<Id,Account>([SELECT Id, (SELECT Id FROM Opportunities) FROM Account where Id IN : accountIds]);
                for(Id accId:accountIds)
                {
                    if(mapAccount.containsKey(accId))
                    {
                        if(mapAccount.get(accId).Opportunities.size() == 0)
                        {
                            Opportunity opp=new Opportunity();
                            opp.Name = 'New Sales Blitz Opportunity';
                            opp.AccountId = accId;
                            opp.StageName = 'New';
                            opp.Opportunity_Potential__c = 0.00;
                            opp.CloseDate = Date.today();
                            opp.OriginalOpportunitySource__c = 'Sales Blitz';
                            oppList.add(opp);
                        }
                    }
                }
                
            }
        }
        If(!oppList.isEmpty()){
            insert oppList;
        }
    }
    
    //Not Now - Check Nurture Paused for 3 weeks if Outcome__c == Follow Up Or TBD, then unpause.
    public void executeNotNow(){
        for(Task tsk : taskNewList){
            if(tsk.Status =='Completed' && (tsk.Outcome__c == 'Follow Up' || tsk.Outcome__c == 'TBD')){
                //Set c.Nurture_Paused__c = True;
                if(tsk.WhoId != null && String.valueOf(tsk.whoId).substring(0,3) == '003') {
                    c = new Contact(Id = tsk.whoId);
                    c.Nurture_Paused__c = true;
                    cSet.add(c);
                }
                t = new Task();
                t.OwnerId = '005F0000004E8iS';
                t.WhoId = tsk.WhoId;
                t.Subject = 'Unpause Nurture - 3 Weeks';
                t.Status = 'Not Started';
                t.Outcome__c = 'Unpause Nurture';
                t.ActivityDate = System.Today().addDays(21);
                taskList.add(t);
            }
            //After 3 weeks, unpause nurture
            //Once closed, uncheck checkbox
            else if (tsk.Status =='Completed' && tsk.Subject == 'Unpause Nurture - 3 Weeks' && tsk.Outcome__c == 'Unpause Nurture'){
                //Set c.Nurture_Paused__c = False;
                if(tsk.WhoId != null && String.valueOf(tsk.whoId).substring(0,3) == '003') {
                    c = new Contact(Id = tsk.whoId);
                    c.Nurture_Paused__c = false;
                    cSet.add(c);
                }
            }
        }
        If(!taskList.isEmpty()){
            insert t;
        }
        if(!cSet.isEmpty()){
            update new List <Contact>(cSet);
        }
    }
    //Hard No - Create reminder task to close in 90 days to unpause nurture
    public void executeHardNo(){
        for(Task tsk : taskNewList){
            if(tsk.Status =='Completed' && tsk.Outcome__c == 'Not Interested' && tsk.Subject.contains('Sales Blitz')){
                //Set c.Nurture_Paused__c = True;
                if(tsk.WhoId != null && String.valueOf(tsk.whoId).substring(0,3) == '003') {
                    c = new Contact(Id = tsk.whoId);
                    c.Nurture_Paused__c = true;
                    cSet.add(c);
                }
                t = new Task();
                t.OwnerId = '005F0000004E8iS';
                t.WhoId = tsk.WhoId;
                t.Subject = 'Unpause Nurture - 3 Months';
                t.Status = 'Not Started';
                t.Outcome__c = 'Unpause Nurture';
                t.ActivityDate = System.Today().addDays(90);
                taskList.add(t);
            }
            //After 3 months, unpause nurture
            //Once closed, uncheck checkbox
            else if (tsk.Status =='Completed' && tsk.Subject == 'Unpause Nurture - 3 Months' && tsk.Outcome__c == 'Unpause Nurture'){
                //Set c.Nurture_Paused__c = False;
                if(tsk.WhoId != null && String.valueOf(tsk.whoId).substring(0,3) == '003') {
                    c = new Contact(Id = tsk.whoId);
                    c.Nurture_Paused__c = false;
                    cSet.add(c);
                }
            }
        }
        If(!taskList.isEmpty()){
            insert t;
        }
        if(!cSet.isEmpty()){
            update new List <Contact>(cSet);
        }
    }
}

Test Class
@isTest
private class testSalesBlitzProcess {
    
    static testMethod void LeftMessage1(){
        Profile p=[SELECT Id From Profile WHERE Name='Standard User'];
        User u =new User(Alias = 'newUser' , Email ='testuser@361capital.com' , EmailEncodingKey = 'UTF-8' , LastName = 'Testing',
                         LanguageLocaleKey='en_US', LocaleSidKey='en_US', TimeZoneSidKey = 'GMT', UserName='testuser@361capital.com',ProfileId=p.Id);
        insert u;
        
        Account testAcct = new Account (Name = 'My Test Account');
        insert testAcct;
        
        Contact testCont = new Contact();
        testCont.FirstName = 'Test';
        testCont.LastName = 'User';
        testCont.AccountId = testAcct.Id;
        insert testCont;
        
        Task tsk = new Task();
        tsk.OwnerId = u.id;
        tsk.WhoId = testCont.Id;
        tsk.Subject = 'Sales Blitz Call - Day 1';
        tsk.Outcome__c = 'Left Message';
        tsk.Status = 'Completed';
        tsk.ActivityDate = System.Today().addDays(1);
        insert tsk;
    }
    
        static testMethod void LeftMessage1TESTNULL(){
        Profile p=[SELECT Id From Profile WHERE Name='Standard User'];
        User u =new User(Alias = 'newUser' , Email ='testuser@361capital.com' , EmailEncodingKey = 'UTF-8' , LastName = 'Testing',
                         LanguageLocaleKey='en_US', LocaleSidKey='en_US', TimeZoneSidKey = 'GMT', UserName='testuser@361capital.com',ProfileId=p.Id);
        insert u;
        
        Account testAcct = new Account (Name = 'My Test Account');
        insert testAcct;
        
        Contact testCont = new Contact();
        testCont.FirstName = 'Test';
        testCont.LastName = 'User';
        testCont.AccountId = testAcct.Id;
        insert testCont;
        
        Task tsk = new Task();
        tsk.OwnerId = u.id;
        tsk.WhoId = testCont.Id;
        tsk.Subject = 'Sales Blitz Call - Day 1';
        tsk.Outcome__c = 'Left Message';
        tsk.Status = null;
        tsk.ActivityDate = System.Today().addDays(1);
        insert tsk;
        
        test.startTest();
        tsk.Status='Completed';
        update tsk;
        test.stopTest();
        
         System.assertEquals(tsk.Status = 'Completed', null);
    }
    
    static testMethod void LeftMessage2(){
        Profile p=[SELECT Id From Profile WHERE Name='Standard User'];
        User u =new User(Alias = 'newUser' , Email ='testuser@361capital.com' , EmailEncodingKey = 'UTF-8' , LastName = 'Testing',
                         LanguageLocaleKey='en_US', LocaleSidKey='en_US', TimeZoneSidKey = 'GMT', UserName='testuser@361capital.com',ProfileId=p.Id);
        insert u;
        
        Account testAcct = new Account (Name = 'My Test Account');
        insert testAcct;
        
        Contact testCont = new Contact();
        testCont.FirstName = 'Test';
        testCont.LastName = 'User';
        testCont.AccountId = testAcct.Id;
        insert testCont;
        
        Task tsk = new Task();
        tsk.OwnerId = u.id;
        tsk.WhoId = testCont.Id;
        tsk.Subject = 'Sales Blitz Call - Day 3';
        tsk.Outcome__c = 'Left Message';
        tsk.Status = 'Completed';
        tsk.ActivityDate = System.Today().addDays(1);
        insert tsk;
    }
    
    static testMethod void LeftMessage3(){
        Profile p=[SELECT Id From Profile WHERE Name='Standard User'];
        User u =new User(Alias = 'newUser' , Email ='testuser@361capital.com' , EmailEncodingKey = 'UTF-8' , LastName = 'Testing',
                         LanguageLocaleKey='en_US', LocaleSidKey='en_US', TimeZoneSidKey = 'GMT', UserName='testuser@361capital.com',ProfileId=p.Id);
        insert u;
        
        Account testAcct = new Account (Name = 'My Test Account');
        insert testAcct;
        
        Contact testCont = new Contact();
        testCont.FirstName = 'Test';
        testCont.LastName = 'User';
        testCont.AccountId = testAcct.Id;
        insert testCont;
        
        Task tsk = new Task();
        tsk.OwnerId = u.id;
        tsk.WhoId = testCont.Id;
        tsk.Subject = 'Sales Blitz Call - Day 5';
        tsk.Outcome__c = 'Left Message';
        tsk.Status = 'Completed';
        tsk.ActivityDate = System.Today().addDays(1);
        insert tsk;
    }
    
    static testMethod void LeftMessage4(){
        Profile p=[SELECT Id From Profile WHERE Name='Standard User'];
        User u =new User(Alias = 'newUser' , Email ='testuser@361capital.com' , EmailEncodingKey = 'UTF-8' , LastName = 'Testing',
                         LanguageLocaleKey='en_US', LocaleSidKey='en_US', TimeZoneSidKey = 'GMT', UserName='testuser@361capital.com',ProfileId=p.Id);
        insert u;
        
        Account testAcct = new Account (Name = 'My Test Account');
        insert testAcct;
        
        Contact testCont = new Contact();
        testCont.FirstName = 'Test';
        testCont.LastName = 'User';
        testCont.AccountId = testAcct.Id;
        insert testCont;
        
        Task tsk = new Task();
        tsk.OwnerId = u.id;
        tsk.WhoId = testCont.Id;
        tsk.Subject = 'Sales Blitz Call - Day 8';
        tsk.Outcome__c = 'Left Message';
        tsk.Status = 'Completed';
        tsk.ActivityDate = System.Today().addDays(1);
        insert tsk;
    }
    
    static testMethod void notNow1(){
        Profile p=[SELECT Id From Profile WHERE Name='Standard User'];
        User u =new User(Alias = 'newUser' , Email ='testuser@361capital.com' , EmailEncodingKey = 'UTF-8' , LastName = 'Testing',
                         LanguageLocaleKey='en_US', LocaleSidKey='en_US', TimeZoneSidKey = 'GMT', UserName='testuser@361capital.com',ProfileId=p.Id);
        insert u;
        
        Account testAcct = new Account (Name = 'My Test Account');
        insert testAcct;
        
        Contact testCont = new Contact();
        testCont.FirstName = 'Test';
        testCont.LastName = 'User';
        testCont.AccountId = testAcct.Id;
        insert testCont;
        
        Task tsk = new Task();
        tsk.OwnerId = u.id;
        tsk.WhoId = testCont.Id;
        tsk.Subject = 'Unpause Nurture - 3 Weeks';
        tsk.Outcome__c = 'Follow Up';
        tsk.Status = 'Completed';
        tsk.ActivityDate = System.Today().addDays(21);
        insert tsk;
    }
    
    static testMethod void notNow2(){
        Profile p=[SELECT Id From Profile WHERE Name='Standard User'];
        User u =new User(Alias = 'newUser' , Email ='testuser@361capital.com' , EmailEncodingKey = 'UTF-8' , LastName = 'Testing',
                         LanguageLocaleKey='en_US', LocaleSidKey='en_US', TimeZoneSidKey = 'GMT', UserName='testuser@361capital.com',ProfileId=p.Id);
        insert u;
        
        Account testAcct = new Account (Name = 'My Test Account');
        insert testAcct;
        
        Contact testCont = new Contact();
        testCont.FirstName = 'Test';
        testCont.LastName = 'User';
        testCont.AccountId = testAcct.Id;
        insert testCont;
        
        Task tsk = new Task();
        tsk.OwnerId = u.id;
        tsk.WhoId = testCont.Id;
        tsk.Subject = 'Unpause Nurture - 3 Weeks';
        tsk.Outcome__c = 'TBD';
        tsk.Status = 'Completed';
        tsk.ActivityDate = System.Today().addDays(21);
        insert tsk;
    }
    
    static testMethod void notNow3(){
        Profile p=[SELECT Id From Profile WHERE Name='Standard User'];
        User u =new User(Alias = 'newUser' , Email ='testuser@361capital.com' , EmailEncodingKey = 'UTF-8' , LastName = 'Testing',
                         LanguageLocaleKey='en_US', LocaleSidKey='en_US', TimeZoneSidKey = 'GMT', UserName='testuser@361capital.com',ProfileId=p.Id);
        insert u;
        
        Account testAcct = new Account (Name = 'My Test Account');
        insert testAcct;
        
        Contact testCont = new Contact();
        testCont.FirstName = 'Test';
        testCont.LastName = 'User';
        testCont.AccountId = testAcct.Id;
        insert testCont;
        
        Task tsk = new Task();
        tsk.OwnerId = u.id;
        tsk.WhoId = testCont.Id;
        tsk.Subject = 'Unpause Nurture - 3 Weeks';
        tsk.Outcome__c = 'Unpause Nurture';
        tsk.Status = 'Completed';
        tsk.ActivityDate = System.Today().addDays(21);
        insert tsk;
    }
    
    static testMethod void HardNo1(){
        Profile p=[SELECT Id From Profile WHERE Name='Standard User'];
        User u =new User(Alias = 'newUser' , Email ='testuser@361capital.com' , EmailEncodingKey = 'UTF-8' , LastName = 'Testing',
                         LanguageLocaleKey='en_US', LocaleSidKey='en_US', TimeZoneSidKey = 'GMT', UserName='testuser@361capital.com',ProfileId=p.Id);
        insert u;
        
        Account testAcct = new Account (Name = 'My Test Account');
        insert testAcct;
        
        Contact testCont = new Contact();
        testCont.FirstName = 'Test';
        testCont.LastName = 'User';
        testCont.AccountId = testAcct.Id;
        insert testCont;
        
        Task tsk = new Task();
        tsk.OwnerId = u.id;
        tsk.WhoId = testCont.Id;
        tsk.Subject = 'Unpause Nurture - 3 Months';
        tsk.Outcome__c = 'Not Interested';
        tsk.Status = 'Completed';
        tsk.ActivityDate = System.Today().addDays(21);
        insert tsk;
    }
        static testMethod void HardNo2(){
        Profile p=[SELECT Id From Profile WHERE Name='Standard User'];
        User u =new User(Alias = 'newUser' , Email ='testuser@361capital.com' , EmailEncodingKey = 'UTF-8' , LastName = 'Testing',
                         LanguageLocaleKey='en_US', LocaleSidKey='en_US', TimeZoneSidKey = 'GMT', UserName='testuser@361capital.com',ProfileId=p.Id);
        insert u;
        
        Account testAcct = new Account (Name = 'My Test Account');
        insert testAcct;
        
        Contact testCont = new Contact();
        testCont.FirstName = 'Test';
        testCont.LastName = 'User';
        testCont.AccountId = testAcct.Id;
        insert testCont;
        
        Task tsk = new Task();
        tsk.OwnerId = u.id;
        tsk.WhoId = testCont.Id;
        tsk.Subject = 'Unpause Nurture - 3 Months';
        tsk.Outcome__c = 'Unpause Nurture';
        tsk.Status = 'Completed';
        tsk.ActivityDate = System.Today().addDays(21);
        insert tsk;
    }
    
    static testMethod void testOpportunity1(){
        //Create Account
        Account testAcct = new Account (Name = 'My Test Account');
        insert testAcct;
        
        Contact testCont = new Contact();
        testCont.FirstName = 'Test';
        testCont.LastName = 'User';
        testCont.AccountId = testAcct.Id;
        insert testCont;
        
        Task tsk = new Task();
        tsk.OwnerId = '005F0000003KmQ0';
        tsk.WhoId = testCont.Id;
        tsk.Subject = 'Create Opportunity';
        tsk.Outcome__c = 'Set First Advisor Briefing';
        tsk.Status = 'Completed';
        tsk.ActivityDate = System.Today().addDays(1);
        insert tsk;
        
        //Create Opportunity
        Opportunity oppt = new Opportunity();
        oppt.AccountId = testAcct.Id;
        oppt.Name = 'New Opportunity Name';
        oppt.Opportunity_Potential__c = 100.00;
        oppt.StageName = 'New';
        oppt.Amount = 5000;
        oppt.CloseDate = System.Today();
        insert oppt;
    }
    
    static testMethod void testOpportunity2(){
        //Create Account
        Account testAcct = new Account (Name = 'My Test Account');
        insert testAcct;
        
        Contact testCont = new Contact();
        testCont.FirstName = 'Test';
        testCont.LastName = 'User';
        testCont.AccountId = testAcct.Id;
        insert testCont;
        
        Task tsk = new Task();
        tsk.OwnerId = '005F0000003KmQ0';
        tsk.WhoId = testCont.Id;
        tsk.Subject = 'Create Opportunity';
        tsk.Outcome__c = 'Set Qualified Meeting';
        tsk.Status = 'Completed';
        tsk.ActivityDate = System.Today().addDays(1);
        insert tsk;
        
        //Create Opportunity
        Opportunity oppt = new Opportunity();
        oppt.AccountId = testAcct.Id;
        oppt.Name = 'New Opportunity Name';
        oppt.Opportunity_Potential__c = 100.00;
        oppt.StageName = 'New';
        oppt.Amount = 5000;
        oppt.CloseDate = System.Today();
        insert oppt;
    }
    
    static testMethod void testOpportunity3(){
        //Create Account
        Account testAcct = new Account (Name = 'My Test Account');
        insert testAcct;
        
        Contact testCont = new Contact();
        testCont.FirstName = 'Test';
        testCont.LastName = 'User';
        testCont.AccountId = testAcct.Id;
        insert testCont;
        
        Task tsk = new Task();
        tsk.OwnerId = '005F0000003KmQ0';
        tsk.WhoId = testCont.Id;
        tsk.Subject = 'Create Opportunity';
        tsk.Outcome__c = 'Set Existing Producer Meeting';
        tsk.Status = 'Completed';
        tsk.ActivityDate = System.Today().addDays(1);
        insert tsk;
        
        //Create Opportunity
        Opportunity oppt = new Opportunity();
        oppt.AccountId = testAcct.Id;
        oppt.Name = 'New Opportunity Name';
        oppt.Opportunity_Potential__c = 100.00;
        oppt.StageName = 'New';
        oppt.Amount = 5000;
        oppt.CloseDate = System.Today();
        insert oppt;
    }
    
    static testMethod void testOpportunity4(){
        //Create Account
        Account testAcct = new Account (Name = 'My Test Account');
        insert testAcct;
        
        Contact testCont = new Contact();
        testCont.FirstName = 'Test';
        testCont.LastName = 'User';
        testCont.AccountId = testAcct.Id;
        insert testCont;
        
        Task tsk = new Task();
        tsk.OwnerId = '005F0000003KmQ0';
        tsk.WhoId = testCont.Id;
        tsk.Subject = 'Create Opportunity';
        tsk.Outcome__c = 'Set Touch Base Meeting';
        tsk.Status = 'Completed';
        tsk.ActivityDate = System.Today().addDays(1);
        insert tsk;
        
        //Create Opportunity
        Opportunity oppt = new Opportunity();
        oppt.AccountId = testAcct.Id;
        oppt.Name = 'New Opportunity Name';
        oppt.Opportunity_Potential__c = 100.00;
        oppt.StageName = 'New';
        oppt.Amount = 5000;
        oppt.CloseDate = System.Today();
        insert oppt;
    }
    
    static testMethod void testOpportunity5(){
        //Create Account
        Account testAcct = new Account (Name = 'My Test Account');
        insert testAcct;
        
        Contact testCont = new Contact();
        testCont.FirstName = 'Test';
        testCont.LastName = 'User';
        testCont.AccountId = testAcct.Id;
        insert testCont;
        
        Task tsk = new Task();
        tsk.OwnerId = '005F0000003KmQ0';
        tsk.WhoId = testCont.Id;
        tsk.Subject = 'Create Opportunity';
        tsk.Outcome__c = 'Proposal Needed';
        tsk.Status = 'Completed';
        tsk.ActivityDate = System.Today().addDays(1);
        insert tsk;
        
        //Create Opportunity
        Opportunity oppt = new Opportunity();
        oppt.AccountId = testAcct.Id;
        oppt.Name = 'New Opportunity Name';
        oppt.Opportunity_Potential__c = 100.00;
        oppt.StageName = 'New';
        oppt.Amount = 5000;
        oppt.CloseDate = System.Today();
        insert oppt;
    }
    
    static testMethod void testOpportunity6(){
        //Create Account
        Account testAcct = new Account (Name = 'My Test Account');
        insert testAcct;
        
        Contact testCont = new Contact();
        testCont.FirstName = 'Test';
        testCont.LastName = 'User';
        testCont.AccountId = testAcct.Id;
        insert testCont;
        
        Task tsk = new Task();
        tsk.OwnerId = '005F0000003KmQ0';
        tsk.WhoId = testCont.Id;
        tsk.Subject = 'Create Opportunity';
        tsk.Outcome__c = 'Verbal Commitment';
        tsk.Status = 'Completed';
        tsk.ActivityDate = System.Today().addDays(1);
        insert tsk;
        
        //Create Opportunity
        Opportunity oppt = new Opportunity();
        oppt.AccountId = testAcct.Id;
        oppt.Name = 'New Opportunity Name';
        oppt.Opportunity_Potential__c = 100.00;
        oppt.StageName = 'New';
        oppt.Amount = 5000;
        oppt.CloseDate = System.Today();
        insert oppt;
    }
}
All,
I was asked to update some code so that instead of always inserting an Opportunity based on the Task insertion criteria, it only inserts an Opportunity if the related Account doesn't already have one. Usually I think this would be solved using Account.Opportunities.Size()==0, but I'm inserting the Opportunity based off a Task creation and finding the Account associated to the Contact using AccountId. And
​ cIdMap.get(tsk.whoId).AccountId.Opportunities.Size()==0
throws an Invalid foreign key relationship: Contact.AccountId error.

Does anyone know how I could solve this?

Here is the full code. The method is on lines 82-118.
public class SalesBlitzProcess {
    //Grab Lst of tasks
    protected final Task[] taskNewList;
    protected final Task[] taskOldList;
    
    public SalesBlitzProcess (Task[] taskOldList, Task[] taskNewList){
        this.taskNewList = taskNewList;
        this.taskOldList = taskOldList;
    }
    
    List<Task> taskList = new List<Task>();
    List<Opportunity> oppList = new List<Opportunity>();
    Task t;
    Opportunity o;
    Contact c;
    Account a;
    
    //Left Message - Create new Tasks if the following Outcomes == 'Left Message' || 'No Answer'
    Set<Contact> cSet = new Set<Contact>();
    public void executeLeftMessage(){
        for(Task tsk : taskNewList){
            if(tsk.Status =='Completed' && tsk.Subject == 'Sales Blitz Call - Day 1' && (tsk.Outcome__c == 'Left Message' || tsk.Outcome__c == 'No Answer')){
                //Set c.Nurture_Paused__c = True; and c.Send_Day_1_Follow_Up_Email__c = true;
                if(tsk.WhoId != null && String.valueOf(tsk.whoId).substring(0,3) == '003') {
                    c = new Contact(Id = tsk.whoId);
                    c.Nurture_Paused__c = true;
                    c.Send_Day_1_Follow_Up_Email__c = true;
                    cSet.add(c);
                }
                t = new Task();
                t.OwnerId = tsk.OwnerId;
                t.WhoId = tsk.WhoId;
                t.Subject = 'Sales Blitz Call - Day 3';
                t.Status = 'Not Started';
                t.ActivityDate = System.Today().addDays(2);
                taskList.add(t);
                
            } else if (tsk.Status =='Completed' && tsk.Subject == 'Sales Blitz Call - Day 3' && (tsk.Outcome__c == 'Left Message' || tsk.Outcome__c == 'No Answer')){
                t = new Task();
                t.OwnerId = tsk.OwnerId;
                t.WhoId = tsk.WhoId;
                t.Subject = 'Sales Blitz Call - Day 5';
                t.Status = 'Not Started';
                t.ActivityDate = System.Today().addDays(2);
                taskList.add(t);
                
            } else if (tsk.Status =='Completed' && tsk.Subject == 'Sales Blitz Call - Day 5' && (tsk.Outcome__c == 'Left Message' || tsk.Outcome__c == 'No Answer')){
                //c.Send_Day_1_Follow_Up_Email__c = true;
                if(tsk.WhoId != null && String.valueOf(tsk.whoId).substring(0,3) == '003') {
                    c = new Contact(Id = tsk.whoId);
                    c.Send_Day_5_Follow_Up_Email__c = true;
                    cSet.add(c);
                }
                t = new Task();
                t.OwnerId = tsk.OwnerId;
                t.WhoId = tsk.WhoId;
                t.Subject = 'Sales Blitz Call - Day 8';
                t.Status = 'Not Started';
                t.ActivityDate = System.Today().addDays(3);
                taskList.add(t);
                
            } else if (tsk.Status =='Completed' && tsk.Subject == 'Sales Blitz Call - Day 8' && (tsk.Outcome__c == 'Left Message' || tsk.Outcome__c == 'No Answer')){
                //Set c.Nurture_Paused__c = False;
                if(tsk.WhoId != null && String.valueOf(tsk.whoId).substring(0,3) == '003') {
                    c = new Contact(Id = tsk.whoId);
                    c.Nurture_Paused__c = false;
                    c.Send_Day_1_Follow_Up_Email__c = false;
                    c.Send_Day_5_Follow_Up_Email__c = false;
                    cSet.add(c);
                }
            }
        }
        
        If(!taskList.isEmpty()){
            insert taskList;
        }
        If(!cSet.isEmpty()){
            update new List <Contact>(cSet);
        }
    }
    
    //Continue Process - Create Opportunity if Task has the following outcomes
    Set<Id> ContactIds = new Set<Id>();
    public void executeContinueProcess(){
        for(Task tsk : taskNewList){
            if(tsk.Status =='Completed' && (tsk.Outcome__c == 'Set First Advisor Briefing'
                || tsk.Outcome__c == 'Set Qualified Meeting'
                || tsk.Outcome__c == 'Set Existing Producer Meeting'
                || tsk.Outcome__c == 'Set Touch Base Meeting'
                || tsk.Outcome__c == 'Proposal Needed'
                || tsk.Outcome__c == 'Verbal Commitment')){
                    String tId = tsk.WhoId;
                    if(String.ValueOf(tsk.WhoId).substring(0,3) == '003'){
                        ContactIds.add(tsk.WhoId);
                    }
                    
                    List<Contact> taskContacts = [Select Id, AccountId, Account.Name, Nurture_Paused__c FROM Contact Where Id in:ContactIds];
                    Map<Id, Contact> cIdMap = new Map<Id, Contact>(taskContacts);
                    //Create Opportunity if Task has the outcome above
                    o = new Opportunity();
                    //system.debug('==========Contact Id ========'+tsk.WhoId);
                    //system.debug('==========Contact record ========'+cIdMap.get(tsk.WhoId));
                    //system.debug('==========account Id ========'+cIdMap.get(tsk.WhoId).AccountId);
                    if(tsk.WhoId != null && cIdMap.get(tsk.WhoId) != null){
                        o.AccountId = cIdMap.get(tsk.WhoId).AccountId;
                    }
                    o.Name = 'New Sales Blitz Opportunity';
                    o.StageName = 'New';
                    o.Opportunity_Potential__c = 0.00;
                    o.CloseDate = Date.today();
                    o.OriginalOpportunitySource__c = 'Sales Blitz';
                    oppList.add(o);
                }
        }
        If(!oppList.isEmpty()){
            insert oppList;
        }
    }
    
    //Not Now - Check Nurture Paused for 3 weeks if Outcome__c == Follow Up Or TBD, then unpause.
    public void executeNotNow(){
        for(Task tsk : taskNewList){
            if(tsk.Status =='Completed' && (tsk.Outcome__c == 'Follow Up' || tsk.Outcome__c == 'TBD')){
                //Set c.Nurture_Paused__c = True;
                if(tsk.WhoId != null && String.valueOf(tsk.whoId).substring(0,3) == '003') {
                    c = new Contact(Id = tsk.whoId);
                    c.Nurture_Paused__c = true;
                    cSet.add(c);
                }
                t = new Task();
                t.OwnerId = tsk.OwnerId;
                t.WhoId = tsk.WhoId;
                t.Subject = 'Unpause Nurture - 3 Weeks';
                t.Status = 'Not Started';
                t.Outcome__c = 'Unpause Nurture';
                t.ActivityDate = System.Today().addDays(21);
                taskList.add(t);
            }
            //After 3 weeks, unpause nurture
            //Once closed, uncheck checkbox
            else if (tsk.Status =='Completed' && tsk.Subject == 'Unpause Nurture - 3 Weeks' && tsk.Outcome__c == 'Unpause Nurture'){
                //Set c.Nurture_Paused__c = False;
                if(tsk.WhoId != null && String.valueOf(tsk.whoId).substring(0,3) == '003') {
                    c = new Contact(Id = tsk.whoId);
                    c.Nurture_Paused__c = false;
                    cSet.add(c);
                }
            }
        }
        If(!taskList.isEmpty()){
            insert t;
        }
        if(!cSet.isEmpty()){
            update new List <Contact>(cSet);
        }
    }
    //Hard No - Create reminder task to close in 90 days to unpause nurture
    public void executeHardNo(){
        for(Task tsk : taskNewList){
            if(tsk.Status =='Completed' && tsk.Outcome__c == 'Not Interested' && tsk.Subject.contains('Sales Blitz')){
                //Set c.Nurture_Paused__c = True;
                if(tsk.WhoId != null && String.valueOf(tsk.whoId).substring(0,3) == '003') {
                    c = new Contact(Id = tsk.whoId);
                    c.Nurture_Paused__c = true;
                    cSet.add(c);
                }
                t = new Task();
                t.OwnerId = tsk.OwnerId;
                t.WhoId = tsk.WhoId;
                t.Subject = 'Unpause Nurture - 3 Months';
                t.Status = 'Not Started';
                t.Outcome__c = 'Unpause Nurture';
                t.ActivityDate = System.Today().addDays(90);
                taskList.add(t);
            }
            //After 3 months, unpause nurture
            //Once closed, uncheck checkbox
            else if (tsk.Status =='Completed' && tsk.Subject == 'Unpause Nurture - 3 Months' && tsk.Outcome__c == 'Unpause Nurture'){
                //Set c.Nurture_Paused__c = False;
                if(tsk.WhoId != null && String.valueOf(tsk.whoId).substring(0,3) == '003') {
                    c = new Contact(Id = tsk.whoId);
                    c.Nurture_Paused__c = false;
                    cSet.add(c);
                }
            }
        }
        If(!taskList.isEmpty()){
            insert t;
        }
        if(!cSet.isEmpty()){
            update new List <Contact>(cSet);
        }
    }
}

 

All,
I have two problems I'm trying to resolve in my trigger. FYI I'm using the design pattern of one trigger per object, so the class holds the code, and then execute the methods in the trigger. 

1.) Method executeLeftMesssage:
Line 42, updates the checkbox to true given the conditions, which is working perfectly. But at the end of this method (Line 74)  I'm trying to update the checkbox to false given Line 71 evaluates to true, but it's not updating the field in the list. What am I missing here?

2.) Method executeContinueProcess:
Line 104, when creating the new opportunity, I'm trying to grab the AccountId, but it keeps returning blank. How can I get this populate in the new opportunity?
 

public class SalesBlitzProcess {
    //Grab List of tasks
    protected final Task[] taskNewList;
    protected final Task[] taskOldList;
    
    public SalesBlitzProcess (Task[] taskOldList, Task[] taskNewList){
        this.taskNewList = taskNewList;
        this.taskOldList = taskOldList;
    }
    
    Set<Id> ContactIds = new Set<Id>();
    List<Contact> taskContacts = [Select Id, AccountId, Account.Name, Nurture_Paused__c FROM Contact Where Id in:ContactIds];
    Map<Id, Contact> cIdMap = new Map<Id, Contact>(taskContacts);
    
    List<Task> taskList = new List<Task>();
    List<Opportunity> oppList = new List<Opportunity>();
    Task t;
    Opportunity o;
    Contact c;
    Account a;
      
     //TODO: Create method to Check and Uncheck Nurture_Paused__c Checkbox within the below methods
    public void executeCheckNP(){
        for(Task t :taskNewList){
            String tId = t.WhoId;
            if(String.valueOf(t.whoId).substring(0,3) == '003'){
                ContactIds.add(t.WhoId);
            }
        }
    }

    
    //Left Message Sales Blitz Process
    private static set<Contact> cSet = new set<Contact>();
     public void executeLeftMessage(){
         if(!RecursiveTriggerHelper.isAlreadyModified()){
             RecursiveTriggerHelper.setAlreadyModified();
             for(Task tsk : taskNewList){
                 if(tsk.Status =='Completed' && tsk.Subject == 'Sales Blitz Call - Day 1' && tsk.Outcome__c == 'Left Message'){
                     //TODO: c.Nurture_Paused__c = True;
                     if(tsk.WhoId != null && String.valueOf(tsk.whoId).substring(0,3) == '003') {
                         c = new Contact(Id = tsk.whoId, Nurture_Paused__c = true);
                         cSet.add(c);
                     }
                     t = new Task();
                     t.OwnerId = tsk.OwnerId;
                     t.WhoId = tsk.WhoId;
                     t.Subject = 'Sales Blitz Call - Day 3';
                     t.Status = 'Not Started';
                     t.ActivityDate = System.Today().addDays(2);
                     taskList.add(t);
                     
                 } else if (tsk.Status =='Completed' && tsk.Subject == 'Sales Blitz Call - Day 3' && tsk.Outcome__c == 'Left Message'){
                     t = new Task();
                     t.OwnerId = tsk.OwnerId;
                     t.WhoId = tsk.WhoId;
                     t.Subject = 'Sales Blitz Call - Day 5';
                     t.Status = 'Not Started';
                     t.ActivityDate = System.Today().addDays(2);
                     taskList.add(t);
                     
                 } else if (tsk.Status =='Completed' && tsk.Subject == 'Sales Blitz Call - Day 5' && tsk.Outcome__c == 'Left Message'){
                     t = new Task();
                     t.OwnerId = tsk.OwnerId;
                     t.WhoId = tsk.WhoId;
                     t.Subject = 'Sales Blitz Call - Day 8';
                     t.Status = 'Not Started';
                     t.ActivityDate = System.Today().addDays(3);
                     taskList.add(t);
                     
                 } else if (tsk.Status =='Completed' && tsk.Subject == 'Sales Blitz Call - Day 8' && tsk.Outcome__c == 'Left Message'){
                     //TODO: c.Nurture_Paused__c = False;
                     if(tsk.WhoId != null && String.valueOf(tsk.whoId).substring(0,3) == '003') {
                         c = new Contact(Id = tsk.whoId, Nurture_Paused__c = false);
                         cSet.add(c);
                     }
                 }
             }
         }
         If(!taskList.isEmpty()){
             insert taskList;
             update new List <Contact>(cSet);
         }
     }
    
    //Create Opportunity if Task has the following outcome
    public void executeContinueProcess(){
        for(Task tsk : taskNewList){
            if(tsk.Status =='Completed' && tsk.Subject == 'Create Opportunity' &&
               (tsk.Outcome__c == 'Set First Advisor Briefing'
                || tsk.Outcome__c == 'Set Qualified Meeting'
                || tsk.Outcome__c == 'Set Existing Producer Meeting'
                || tsk.Outcome__c == 'Set Touch Base Meeting'
                || tsk.Outcome__c == 'Proposal Needed'
                || tsk.Outcome__c == 'Verbal Commitment')){
                    //TODO: c.Nurture_Paused__c = True;
                    if(tsk.WhoId != null && String.valueOf(tsk.whoId).substring(0,3) == '003') {
                        c = new Contact(Id = tsk.whoId, Nurture_Paused__c = true);
                        cSet.add(c);
                    }
                    //TODO Create Opportunity if Task has the following outcome
                    //executeCheckNP();
                    o = new Opportunity();
                    if(tsk.WhoId != null && cIdMap.get(tsk.WhoId) != null){
                        o.AccountId = cIdMap.get(tsk.WhoId).AccountId;
                    }
                    o.Name = 'Temp Opp Name';
                    o.StageName = 'New';
                    o.Opportunity_Potential__c = 0.00;
                    o.CloseDate = Date.today();
                    oppList.add(o);
                }
            //What is the deciding factor for unpausing Nurture here?
            /**if (tsk.WhoId != null && tsk.Status =='Completed' && tsk.Subject == 'Closed Opportunity' && tsk.Outcome__c == 'Closed'){
            //TODO: c.Nurture_Paused__c = False;
            }**/
        }
        If(!oppList.isEmpty()){
            insert oppList;
            update new List <Contact>(cSet);
        }
    }
}



 
trigger SalesBlitzProcess on Task (after insert, after update) {
    Task[] taskOldList = trigger.IsDelete ? null : trigger.old;
    Task[] taskNewList = trigger.IsDelete ? trigger.old : trigger.new;
    new SalesBlitzProcess(trigger.Old, trigger.New).executeLeftMessage();
    new SalesBlitzProcess(trigger.Old, trigger.New).executeContinueProcess();
    //new SalesBlitzProcess(trigger.Old, trigger.New).executeHardNo();
    //new SalesBlitzProcess(trigger.Old, trigger.New).executeNotNow();
}
In an attempt to clean up my org and remove some fields, I'm trying to modify code that grabs Trade totals from one specific Fund Number and applies to them to the corresponding fields, and instead combine Fund Numbers and sums them to one field. Here is my example with code snippets:
public static final Set<String> FUND_NUMBERS = new Set<String> {
        '3915',
        '3917',
    };

    // All amounts/shares
    public static final Map<String, SObjectField[]> FIELDMAP_TOTAL = new Map<String, SObjectField[]>  {
        '3915' => new SobjectField[] { Account.Total_NS_Income_II_Sales__c , Account.Total_NS_Income_II_Shares__c },
'3917' => new SobjectField[] { Account.Total_NS_Income_II_T_Share_Sales__c, Account.Total_NS_Income_II_T_Shares__c },
    };
        // Fetch all the trades for these accounts
        Trades__c[] tradesList = [
            SELECT Name
                 , Dollar_Amount_of_the_transaction__c
                 , Fund_Number__c
                 , Number_of_Shares_of_the_transaction__c
                 , Resolved_Firm_Trading_ID__c
                 , Trade_Date__c
              FROM Trades__c
             WHERE Resolved_Firm_Trading_ID__c IN :accountIds
               AND Resolved_Firm_Trading_ID__c <> NULL
               AND Fund_Number__c IN :FUND_NUMBERS
               AND Trade_Date__c != NULL
               AND Dollar_Amount_of_the_transaction__c >= 0
               AND Number_of_Shares_of_the_transaction__c >= 0
        ];

            Decimal amount = trade.Dollar_Amount_of_The_Transaction__c;
            Decimal shares = trade.Number_of_Shares_of_the_transaction__c;
            String fn = trade.Fund_Number__c;
            SobjectField f0, f1;

            // Always apply to totals
            if (true) {
                f0 = FIELDMAP_TOTAL.get(fn)[0];
                f1 = FIELDMAP_TOTAL.get(fn)[1];

                account.put(f0, (Decimal) account.get(f0) + amount);
                account.put(f1, (Decimal) account.get(f1) + shares);
            }
        }

        // Done, try to update
        update accountMap.values();
    }
Now if I want to combine Fund Numbers 3915 & 3917 to be summed into the same fields, like so:
'3915' + '3917' => new SobjectField[] { Account.Test_Total_Sales__c, Account.Test_Total_Shares__c}
I get thrown an "Attempt to de-reference a null object" error on line 36 (in first snippet), the f1 = FIELDMAP_TOTAL.get(fn)[1];.

What is the proper way to structure this map to combine Fund Numbers?
All,
Due to the Winter '16 update, my approval process submission started throwing an error for our expense reports. I have corrected most of the code so that the approval goes through, but I can't seem to get the redirect to work. What do I need to add to my code in order for the browser to redirect to main object page after the user clicks "I agree" or how can I provide a success message to the users?

Line 55:
//redirect page after submitted
        if(result.isSuccess()){
            new pageReference.getParameters().put('retURL', '/' +  controller.getId());
        }
Full Class:
public with sharing class ExpenseReport_ValidateBeforeSubmit {
    private ApexPages.StandardController controller;
    public Boolean isValidated { set; get; }
    
    public ExpenseReport_ValidateBeforeSubmit(ApexPages.StandardController controller) {
        this.controller = controller;
        this.isValidated = false;
    }
    
    public PageReference validateBeforeSubmit() {
        ExpenseReport expenseReport = new ExpenseReport(controller);
        
        if (expenseReport.getExpenseLineItemListSize() == 0) {
            expenseReport.addMessage(ApexPages.Severity.Error, 'Unable to submit: '
                + 'An expense report requires at least one expense line item.');
        }
        
        for(Expense_Line_Items__c expenseLineItem : expenseReport.getExpenseLineItemList()) {
            expenseReport.setExpenseLineItem(expenseLineItem);
            
            if (expenseReport.getIsAttendeeRequiredButMissing()) {
                expenseReport.addMessage(ApexPages.Severity.Error, 'Unable to submit: '
                    + 'The expense line item categorized as "' + expenseLineItem.Category__c + '" '
                    + 'dated "' + expenseLineItem.Date_of_Expense_Item__c.format() + '" '
                    + 'and in the amount of $' + expenseLineItem.Expense_line_Item_Amount__c + ' '
                    + 'requires at least one non-owner attendee.');
            }
        }
        
        if (ApexPages.hasMessages(ApexPages.Severity.Error))
            return null;
        
        // Update the expense report to a draft status if a status is missing
        if (expenseReport.getExpenseReport().Approval_Status__c == null) try {
            update new Expense_Record__c(Id = expenseReport.getExpenseReport().Id, Approval_Status__c = 'Draft');
        } catch (System.Exception pException) {
            ApexPages.addMessages(pException);
        }
        
        isValidated = ApexPages.hasMessages(ApexPages.Severity.Error) == false;
        return null;
    }
    
    //NEW CODE
    public void confirmCertificationStatement() {
        // Create an approval request for the Expense Report
        Approval.ProcessSubmitRequest req1 = new Approval.ProcessSubmitRequest();
        req1.setComments('Submitting request for approval.');
        req1.setObjectId(controller.getId());
        
        // Submit the approval request for the Expense Report
        Approval.ProcessResult result = Approval.process(req1);
        
        //redirect page after submitted
        if(result.isSuccess()){
            new pageReference.getParameters().put('retURL', '/' +  controller.getId());
        }
        
        //Verify the result
        System.assert(result.isSuccess());
        
        System.assertEquals(
        'Pending', result.getInstanceStatus(),
        'Instance Status'+result.getInstanceStatus());
        
        //OLD CODE
        //public pageReference confirmCertificationStatement() {
        //PageReference pageReference = new PageReference('/p/process/Submit');
        //pageReference.setRedirect(true);
        //pageReference.getParameters().put('id',  controller.getId());
        //pageReference.getParameters().put('retURL', '/' +  controller.getId());
        //return pageReference;
        //}
    }
}

Visualforce
<apex:page standardController="Expense_Record__c" extensions="ExpenseReport_ValidateBeforeSubmit" action="{!validateBeforeSubmit}">
    <apex:includeScript value="https://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" />
    <apex:includeScript value="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.1/jquery-ui.min.js" />
    <apex:sectionHeader title="Submit for Approval: {!$ObjectType.Expense_Record__c.Label}" subtitle="{!Expense_Record__c.Name}" />

    <apex:pageMessages />

    <apex:form style="padding: 1.5em;" styleClass="certificationStatement" rendered="{!AND(isValidated)}">
        <div style="font-size: 130%; font-weight: bold; padding-bottom: 1em;"><apex:outputText value="Certification Statement" /></div>
        <div><apex:outputText value="By submitting this report, I certify that all expenses were incurred while performing firm business and are true and correct. All listed expenses are allowable as described in the firms travel and entertainment and business expense policies. Any expenses not business related or in compliance with firm policy that do not have prior management approval may result in disciplinary action from the firm." /></div>
        <div>&nbsp;</div>
        <apex:commandButton action="{!confirmCertificationStatement}" value="I agree" />
        <apex:commandButton action="{!$Page.ExpenseReport}?id={!Expense_Record__c.Id}" value="I do not agree" />
    </apex:form>

    <apex:form style="padding: 1.5em;" rendered="{!NOT(isValidated)}">
        <apex:commandButton action="{!$Page.ExpenseReport}?id={!Expense_Record__c.Id}" value="Return to Expense Report" />
    </apex:form>
</apex:page>


 

How to make apex:inputfile as required?

i have used the following code,

<apex:inputFile value="{!objAttachment1.body}" filename="{!objAttachment1.name}" required="true">
</apex:inputFile>

It dint workout. Any help on how to achieve this?

Thanks.

 

All,

I have written code that finds the Last Completed Event Date, but I'm hoping someone can help me figure out how to add a method to find the First Completed Event Date. The trouble is I don't think there's a way to write a comparison argument to solve it as there is not standard date field in Salesforce that would represent the inception date of an org.

Here is my code thus far:
public class LastCompletedEventDate{
    //Grab list of contacts
    protected final Contact[] contactNewList = new Contact[] {};
    protected final Contact[] contactOldList = new Contact[] {};
    
    public LastCompletedEventDate(Contact[] contactOldList, Contact[] contactNewList) {
        this.contactNewList.addAll(contactNewList == null ? new Contact[] {} : contactNewList);
        this.contactOldList.addAll(contactOldList == null ? new Contact[] {} : contactOldList);
    }
    
    public void execute() {
        // Find all events associated to contacts
        Event[] eventList = [select ActivityDate, WhoId, EndDateTime, Subject, ActivityDateTime from Event where WhoId in :contactNewList];
        
        Map<Id, Contact> contactMap = new Map<Id, Contact>(contactNewList);
                for(Contact contact : contactNewList) {
                    contact.Last_Completed_Event__c = null;
        }
        
        //create if else statement to display most current completed event date
        for(Event event : eventList) {
            Contact contact = contactMap.get(event.WhoId);
            if(Contact == null)
                continue;
            if(Event.EndDateTime < Date.Today())
                Contact.Last_Completed_Event__c = Event.EndDateTime;
        }
    }
}
 
trigger LastCompletedEventDate on Contact (before update) {
    if(Contact_RollupTrades.inprog != true) {
        Set<ID> sID = new Set<ID>(trigger.newMap.keySet());
        new LastCompletedEventDate(trigger.old, trigger.new).execute();
    }
}
Hey guys,

I'm trying to do a date range to grab all trades from past 12 months, from yesterday's date. For some reason the following 2 formulas will not work. Any help would be greatly appreciated!

Returns nothing:
if(trade.trade_date__c < date.today().addDays(-1) && trade.trade_date__c > date.today().addDays(-366)) {
                            accounts.get(trade.Resolved_Firm_Trading_ID__c).put(prior12MOS.get(trade.fund_number__c)[0], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(prior12MOS.get(trade.fund_number__c)[0]))+trade.Dollar_Amount_of_The_Transaction__c);
                            accounts.get(trade.Resolved_Firm_Trading_ID__c).put(prior12MOS.get(trade.fund_number__c)[1], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(prior12MOS.get(trade.fund_number__c)[1]))+trade.Number_of_Shares_of_the_transaction__c);
                            system.debug(prior12MOS);
                            system.debug(LoggingLevel.DEBUG, + Limits.getCpuTime() + '/' + Limits.getLimitCpuTime());

Returns only dates within the past month:
if(trade.trade_date__c < date.today().addDays(-1) && trade.trade_date__c > date.today().addYears(-1)) {
                            

 
All,
I need to make my sales summary code more efficient. Once we hit 9,000 trades on a single Account, the system hits the CPU Limit governor limit, even in a batch job. Anybody have any ideas on the code below? Perhaps moving each calculation in the For loop under each  corresponding map? I'm not sure the best way to change this code, but any help would be greatly appreciated.

Debug log shows errors at random at lines 73, 79, or 92 in the Class and every time on line 4 in the trigger.
CPU Time varies on the number of trades inserted at a time, but even at 1 trade I can get up to 25000 out of 10000 (more than double).

Class:
public class Account_RollupTrades {
    public Static Account_Setting__c setting = Account_Setting__c.getInstance();
    public Static boolean inprog = false;

    public static void execute (Set<Id> accountIds, List<Account> accountsList) {
        Map<Id, Account> accounts = new Map<Id, Account> (AccountsList);
        system.debug ('execute');
        if(setting.Disable_RollupTrades__c != true) {
            //Map<Id, Account> accounts = new Map<Id, Account>();
            for(Id accountId:accountIds) {
                system.debug(accountid);
                accounts.put(accountId,
                   new Account(
                       Id=accountId,
                       /**YTD_NIOR_I_Sales__c = 0,         YTD_NIOR_I_Shares__c = 0,         QTD_NIOR_I_Sales__c = 0,         QTD_NIOR_I_Shares__c = 0,
                       MTD_NIOR_I_Sales__c = 0,         MTD_NIOR_I_Shares__c = 0,         PY_NIOR_I_Sales__c = 0,          PY_NIOR_I_Shares__c = 0,
                       Total_NIOR_I_Sales__c = 0,       Total_NIOR_I_Shares__c = 0,       YTD_NS_Income_Sales__c = 0,      YTD_NS_Income_Shares__c = 0,
                       QTD_NS_Income_Sales__c = 0,      QTD_NS_Income_Shares__c = 0,      MTD_NS_Income_Sales__c = 0,      MTD_NS_Income_Shares__c = 0,
                       PY_NS_Income_Sales__c = 0,       PY_NS_Income_Shares__c = 0,       Total_NS_Income_Sales__c = 0,    Total_NS_Income_Shares__c = 0,**/
                       Total_NS_HI_Sales__c = 0,       Total_NS_HI_Shares__c = 0,       YTD_NS_HI_Sales__c = 0,         YTD_NS_HI_Shares__c = 0,
                       QTD_NS_HI_Sales__c = 0,         QTD_NS_HI_Shares__c = 0,         MTD_NS_HI_Sales__c = 0,         MTD_NS_HI_Shares__c = 0,
                       PY_NS_HI_Sales__c = 0,          PY_NS_HI_Shares__c = 0,          Total_NS_Income_II_Sales__c = 0, Total_NS_Income_II_Shares__c = 0,
                       YTD_NS_Income_II_Sales__c = 0,   YTD_NS_Income_II_Shares__c = 0,   QTD_NS_Income_II_Sales__c = 0,   QTD_NS_Income_II_Shares__c = 0,
                       MTD_NS_Income_II_Sales__c = 0,   MTD_NS_Income_II_Shares__c = 0,   PY_NS_Income_II_Sales__c = 0,    PY_NS_Income_II_Shares__c = 0,
                       Rollup_Trades__c = DateTime.now()
                   )
                            );
            }
            Map<String, SObjectField[]>
                ytd = new map<string, sobjectfield[]> {
                    //'3910' => new sobjectfield[] { account.YTD_NIOR_I_Sales__c , account.YTD_NIOR_I_Shares__c},
                    //'3911' => new sobjectfield[] { account.YTD_NS_Income_Sales__c , account.YTD_NS_Income_Shares__c },
                    '3912' => new sobjectfield[] { account.YTD_NS_HI_Sales__c , account.YTD_NS_HI_Shares__c },
                    '3915' => new sobjectfield[] { account.YTD_NS_Income_II_Sales__c , account.YTD_NS_Income_II_Shares__c }    
                },
                qtd = new map<string, sobjectfield[]> {
                    //'3910' => new sobjectfield[] { account.QTD_NIOR_I_Sales__c , account.QTD_NIOR_I_Shares__c},
                    //'3911' => new sobjectfield[] { account.QTD_NS_Income_Sales__c , account.QTD_NS_Income_Shares__c },
                    '3912' => new sobjectfield[] { account.QTD_NS_HI_Sales__c , account.QTD_NS_HI_Shares__c },
                    '3915' => new sobjectfield[] { account.QTD_NS_Income_II_Sales__c , account.QTD_NS_Income_II_Shares__c }
                },
                mtd = new map<string, sobjectfield[]> {
                    //'3910' => new sobjectfield[] { account.MTD_NIOR_I_Sales__c , account.MTD_NIOR_I_Shares__c},
                    //'3911' => new sobjectfield[] { account.MTD_NS_Income_Sales__c , account.MTD_NS_Income_Shares__c },
                    '3912' => new sobjectfield[] { account.MTD_NS_HI_Sales__c , account.MTD_NS_HI_Shares__c },
                    '3915' => new sobjectfield[] { account.MTD_NS_Income_II_Sales__c , account.MTD_NS_Income_II_Shares__c }
                },
                py = new map<string, sobjectfield[]> {
                    //'3910' => new sobjectfield[] { account.PY_NIOR_I_Sales__c , account.PY_NIOR_I_Shares__c},
                    //'3911' => new sobjectfield[] { account.PY_NS_Income_Sales__c , account.PY_NS_Income_Shares__c },
                    '3912' => new sobjectfield[] { account.PY_NS_HI_Sales__c , account.PY_NS_HI_Shares__c },
                    '3915' => new sobjectfield[] { account.PY_NS_Income_II_Sales__c , account.PY_NS_Income_II_Shares__c }
                },
                total = new map<string, sobjectfield[]> {
                    //'3910' => new sobjectfield[] { account.Total_NIOR_I_Sales__c , account.Total_NIOR_I_Shares__c},
                    //'3911' => new sobjectfield[] { account.Total_NS_Income_Sales__c , account.Total_NS_Income_Shares__c },
                    '3912' => new sobjectfield[] { account.Total_NS_HI_Sales__c , account.Total_NS_HI_Shares__c },
                    '3915' => new sobjectfield[] { account.Total_NS_Income_II_Sales__c , account.Total_NS_Income_II_Shares__c }
                };
    
    // We make the select in a "for" so instead of selecting to many records at once hitting the heap size limit the for it will take only 200 records to work with at each iteration.
    for(Trades__c[] tradesList : [select Dollar_Amount_of_the_transaction__c, Fund_Number__c, Number_of_Shares_of_the_transaction__c, Resolved_Firm_Trading_ID__c, Resolved_Firm_Trading_IDs__c, Trade_Date__c from Trades__c where Resolved_Firm_Trading_ID__c in :accountIds and Fund_Number__c in (/**'3910', '3911',**/ '3912', '3915') and Dollar_Amount_of_the_transaction__c != null and Number_of_Shares_of_the_transaction__c != null and Trade_Date__c != null and Dollar_Amount_of_the_transaction__c >= 0 and Number_of_Shares_of_the_transaction__c >= 0 FOR UPDATE]){
        for(trades__c trade: tradesList) {
            
            if(date.today().year() == trade.trade_date__c.year()) {
                accounts.get(trade.Resolved_Firm_Trading_ID__c).put(ytd.get(trade.fund_number__c)[0], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(ytd.get(trade.fund_number__c)[0]))+trade.Dollar_Amount_of_The_Transaction__c);
                accounts.get(trade.Resolved_Firm_Trading_ID__c).put(ytd.get(trade.fund_number__c)[1], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(ytd.get(trade.fund_number__c)[1]))+trade.Number_of_Shares_of_the_transaction__c);
                //system.debug(ytd);
                //system.debug(LoggingLevel.DEBUG, + Limits.getCpuTime() + '/' + Limits.getLimitCpuTime());
                
                //( (date.ValueOf(date.today().month()).divide(3, 0) == date.ValueOf(trade.trade_date__c.month()).divide(3, 0)) )
                if((((date.today().month() - 1) / 3) + 1) == (((trade.Trade_Date__c.month() - 1) / 3) + 1))   {
                    accounts.get(trade.Resolved_Firm_Trading_ID__c).put(qtd.get(trade.fund_number__c)[0], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(qtd.get(trade.fund_number__c)[0]))+trade.Dollar_Amount_of_The_Transaction__c);
                    accounts.get(trade.Resolved_Firm_Trading_ID__c).put(qtd.get(trade.fund_number__c)[1], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(qtd.get(trade.fund_number__c)[1]))+trade.Number_of_Shares_of_the_transaction__c);
                    //system.debug(qtd);
                    //system.debug(LoggingLevel.DEBUG, + Limits.getCpuTime() + '/' + Limits.getLimitCpuTime());
                    
                    if(date.today().month()==trade.trade_date__c.month()) {
                        accounts.get(trade.Resolved_Firm_Trading_ID__c).put(mtd.get(trade.fund_number__c)[0], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(mtd.get(trade.fund_number__c)[0]))+trade.Dollar_Amount_of_The_Transaction__c);
                        accounts.get(trade.Resolved_Firm_Trading_ID__c).put(mtd.get(trade.fund_number__c)[1], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(mtd.get(trade.fund_number__c)[1]))+trade.Number_of_Shares_of_the_transaction__c);
                        //system.debug(mtd);
                        //system.debug(LoggingLevel.DEBUG, + Limits.getCpuTime() + '/' + Limits.getLimitCpuTime());
                    }
                }
            } 
            else if(date.today().year()-1==trade.trade_date__c.year()) {
                accounts.get(trade.Resolved_Firm_Trading_ID__c).put(py.get(trade.fund_number__c)[0], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(py.get(trade.fund_number__c)[0]))+trade.Dollar_Amount_of_The_Transaction__c);
                accounts.get(trade.Resolved_Firm_Trading_ID__c).put(py.get(trade.fund_number__c)[1], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(py.get(trade.fund_number__c)[1]))+trade.Number_of_Shares_of_the_transaction__c);
                //system.debug(py);
                //system.debug(LoggingLevel.DEBUG, + Limits.getCpuTime() + '/' + Limits.getLimitCpuTime());
            }
            accounts.get(trade.Resolved_Firm_Trading_ID__c).put(total.get(trade.fund_number__c)[0], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(total.get(trade.fund_number__c)[0]))+trade.Dollar_Amount_of_The_Transaction__c);
            accounts.get(trade.Resolved_Firm_Trading_ID__c).put(total.get(trade.fund_number__c)[1], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(total.get(trade.fund_number__c)[1]))+trade.Number_of_Shares_of_the_transaction__c);
            //system.debug(total);
            //system.debug(LoggingLevel.DEBUG, + Limits.getCpuTime() + '/' + Limits.getLimitCpuTime());
        }
            }
        }
        inprog = true;
        update accounts.values();
        inprog = false;
    }
}
Trigger:
trigger Account_RollupTrades on Account (after update) {
    if(Account_RollupTrades.inprog == false) {
        //set<ID> sID = new set<ID> (trigger.newMap.keySet());
        Account_RollupTrades.execute(trigger.newMap.keySet(), trigger.new);
    }
}