+ Start a Discussion
Blake TanonBlake Tanon 

Bulkify this Trigger?

I've tried to bulkify this trigger but with no success, below is the code that works for single updates.  We use an object other than Opportunities to track our sales and I'm trying to build out a better way to track our ROI on campaigns.  This triggers goal is to get a sum of all sales for the 90 days after a campaign has ended on each campaign member record.  Any pointers?





trigger CMPostSales on CampaignMember (before update) {

Integer i = 0;

CampaignMember cm = Trigger.new[i];

// Current CampaignMember and Contact ID
String intCm = Trigger.new[i].Id;
CampaignMember cmm = [Select Contact.id, End_Date__c, Post_Sales__c from CampaignMember where id =: intCm];

//Step 2. Create a list of Transactions who are children of Contact record.
List<Transaction__c> t = [Select Transaction__c.Gross_Amount__c From Transaction__c WHERE Transaction__c.Rep__c =: cmm.Contact.id AND Transaction__c.Trade_Date__c >: cmm.End_Date__c AND Transaction__c.Trade_Date__c <: cmm.End_Date__c + 90];

/* Update Sales within the range of the campaign */
// Loop through the filtered Transactions and sum up their amounts.
    Double a = 0;
        for(Transaction__c tr : t)
            if(tr.gross_Amount__c != Null)
                a += tr.Gross_Amount__c;
        cm.Post_Sales__c  = a;



Manos SpanoudakisManos Spanoudakis

My approach would be to go with a Batch Job which runs every day and checks for all Campaigns that have ended 90 ago...


But if you insist,


List <CampaignMember> lCMs =  [Select Contact.id, End_Date__c, Post_Sales__c from CampaignMember where id IN :Trigger.New];


Set <Id> sContactIDs = new Set<Id>();

Date dMin = system.now().date().addDays(-90); // Use this as your min date

for (CampaignMember cm:cmm)




    if (cmm.End_Date__c < dMin)

        dMin = cmm.End_Date__c;



//Then Select All Transactions from the Min Date till now and in the Loop select those of interest


List <Transaction__c> lts = [Select Transaction__c.Gross_Amount__c From Transaction__c WHERE Transaction__c.Rep__c  IN : sContactIDs AND Transaction__c.Trade_Date__c >:dMin];


//Build a Map ContactId -> Transaction List !!

Map <Id,List<Transaction__c>> mContactToTransaction = new Map<Id,List<Transaction__c>>();

for (Transactino__c t:lts)


    if map has the contact add the transaction to the respective contact List otherwise create a new entry for the map




//Loop the CampaignMember Map


for (CampaignMember cm:lCMs)


   //Fetch All Transactions Usign the map ContactId -> Transaction List and calculate :)




Sorry about any typos didn't test it ;-)

What about the limits though ? How many transactions / Campaign Member ? how many CMembers/Campaign ?


hope it helps :)

Blake TanonBlake Tanon

In most cases there won't be more than 10 transactions per member - most will have 0.  We would only run this on campaigns with less than 1000 members most likely.  I supposed the real issue will come with trying to do this with activities, if this isn't the best approach I can look into other solutions.

Blake TanonBlake Tanon

How would I run this as batch apex, if it's not difficult?