0

I am developing a batch Apex process to assign an 'engagement score' to Account based on event/ campaign attendance.

We use Campaigns to track events and event guests.

What I would like this batch process to do is select all Accounts that are associated with a CampaignMember object that has attended an event in the last year.

global class UpdateEventScore implements Database.Batchable<sObject> {

    global Database.QueryLocator start(Database.BatchableContext bc) {
        // collect the batches of records or objects to be passed to execute
        return Database.getQueryLocator(
             'Select Contact.Account.ID' +
             'from CampaignMember' +
             'WHERE Campaign.StartDate = LAST_N_DAYS:365' +
             'AND status = \'Attended\' ORDER BY Campaign.StartDate'
        )
    }
    global void execute(Database.BatchableContext bc, List<P> records){
        // process each batch of records
    }    
    global void finish(Database.BatchableContext bc){
        // execute any post-processing operations
    }    
}

Is there a best practice/ most efficient way to query only distinct Account IDs, assuming some accounts with have attended multiple events?

I'm new to Apex so any help is appreciated. Thanks

1 Answer 1

1

There's no direct way to do this without a bit of extra setup, but it is possible. First, you need to create a new Account Lookup field on Campaign Member. Next, you would want to write a trigger or Process Builder to update this field with the Contact's Account. After that, you need to just update the records once so the new field is populated.

Here's the modified version you could use as a starting point:

global class UpdateEventScore implements Database.Batchable<sObject> {

    global Database.QueryLocator start(Database.BatchableContext bc) {
        // collect the batches of records or objects to be passed to execute
        return Database.getQueryLocator([
          SELECT Id FROM Account WHERE Id IN (
            SELECT Account__c 
            FROM CampaignMember 
            WHERE Campaign.StartDate = LAST_N_DAYS:365 AND
                  Status = 'Attended'
        ]);
    }
    global void execute(Database.BatchableContext bc, List<Account> records){
        // process each batch of records
    }    
    global void finish(Database.BatchableContext bc){
        // execute any post-processing operations
    }    
}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .