+ Start a Discussion
jaw999jaw999 

Linking Campaign Member back to Account directly Trigger

Hi, users want to see all Campaign Members for Contacts at an Account on the Account page in a related list. Makes sense.

So I need to link the Campaign Member object directly to the Account.

Here's my code - am not sure why it isn't working.

Oddly the system debug tells me the field Contact on the Campaign member is Null even though the Member is linked to a Contact via it.

 

Any help appreciated thanks!

 

trigger AccountCampaignMember on CampaignMember (after insert, after update)
{
    
    for (CampaignMember t : Trigger.new)
    {
       system.debug('camp memb id================'+t.id);
       system.debug('camp memb Contact================'+t.Contact);
       system.debug('camp memb ContactAccount================'+t.Contact.Account);

            if (t.Contact<> null)
{
If (t.Account__c==null){

                t.Account__c= t.Contact.AccountId;
            }
        }
    //update t;
}}

 

Best Answer chosen by Admin (Salesforce Developers) 
Sfd developerSfd developer

Hi,

 

Try this,

 

trigger AccountCampaignMember on CampaignMember (before insert, before update){
    Set<Id> contactIds = new Set<Id>();
    
    for (CampaignMember t : Trigger.new){
        if (t.ContactId != null){
            contactIds.add(t.ContactId);
        }
    }
    
    Map<Id, Contact> mapContacts = new Map<Id, Contact>([SELECT AccountId FROM Contact WHERE Id IN:contactIds]);
    
    for (CampaignMember t : Trigger.new){
        if (t.ContactId != null){
            t.Account__c= mapContacts.get(t.ContactId).AccountId;
        }
    }
}

All Answers

jaw999jaw999
Updated code.
Sfd developerSfd developer

Hi,

 

Try this,

 

trigger AccountCampaignMember on CampaignMember (before insert, before update){
    Set<Id> contactIds = new Set<Id>();
    
    for (CampaignMember t : Trigger.new){
        if (t.ContactId != null){
            contactIds.add(t.ContactId);
        }
    }
    
    Map<Id, Contact> mapContacts = new Map<Id, Contact>([SELECT AccountId FROM Contact WHERE Id IN:contactIds]);
    
    for (CampaignMember t : Trigger.new){
        if (t.ContactId != null){
            t.Account__c= mapContacts.get(t.ContactId).AccountId;
        }
    }
}

This was selected as the best answer
jaw999jaw999

Ah, looking great! thanks

jaw999jaw999

Hello, I am having issue with testing, when deploying I get result:

 

AccountCampaignMemberTest.AccountCampaignMember() Class 17 1 Failure Message: "System.DmlException: Insert failed. First exception on row 0; first error: REQUIRED_FIELD_MISSING, Attempted to add a campaign member where either the member id 'null' or the campaign id 'null' is null.: []", Failure Stack Trace: "Class.AccountCampaignMemberTest.AccountCampaignMember: line 17, column 1"

 

I thought I specified the ids

Here is my test class:

 

@isTest
public class AccountCampaignMemberTest {

    static testMethod void AccountCampaignMember(){
    
        Campaign Camp = new Campaign(name='Camp', status='planned');
        
Account testA = new Account(name='testing Account', Aims_client_id__c='9999999999') ;
    insert testA;
       insert Camp;
       
Contact Dude = new Contact (lastname ='blotto', Account=testA);
insert Dude;



CampaignMember DudeAtCamp = new CampaignMember(Contact=dude, Campaign=Camp);
Insert  DudeAtCamp;





    }
}

 

 

 

jaw999jaw999
it also fails with the line:

CampaignMember DudeAtCamp = new CampaignMember(Contact=dude.id, Campaign=Camp.id);
Sfd developerSfd developer

Hi,

 

Try this,

 

@isTest
public class AccountCampaignMemberTest {

    static testMethod void AccountCampaignMember(){
    
        Campaign Camp = new Campaign(name='Camp', status='planned');
        
Account testA = new Account(name='testing Account', Aims_client_id__c='9999999999') ;
    insert testA;
       insert Camp;
       
Contact Dude = new Contact (lastname ='blotto', AccountId=testA.Id);
insert Dude;



CampaignMember DudeAtCamp = new CampaignMember(ContactId=Dude.Id, CampaignId=Camp.Id);
Insert  DudeAtCamp;





    }
}
jaw999jaw999

Thanks. I got this error on deployment:

 

Failure Message: "System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, AccountCampaignMember: execution of AfterInsert caused by: System.FinalException: Record is read-only Trigger.AccountCampaignMember: line 16, column 1: []", Failure Stack Trace: "Class.AccountCampa...

 

 

that line is:

 

  t.Account__c= mapContacts.get(t.ContactId).AccountId;

 

 

read only?

thanks

jaw999jaw999
Works when switched trigger to (before insert, before update)
Eva DeLoriolEva DeLoriol

This may be oversimplifying things, but I just added a formula field to the Campaign Member object called Account.  In my case, I'm using it as a hyperlink, but you could modify it to contain just the ID of the Account.  The formula is below:

 

HYPERLINK(Contact.Account.Id , Contact.Account.Name )

 

jaw999jaw999

Eva, this does not create a link between the objects. This formula doesn't create a related list on the Account page of all the Contacts in Campaigns the way the look-up field does.

jaw999jaw999

This has been great. I am now trying to have this Not fire on a particular Campaign type, Reference List.

making line 13 this isn't working:

 

 if (t.ContactId != null && t.id !=null && t.Campaign.Type != 'Reference List'){
system.debug('id and type======================='+t.id+t.Campaign.Type);

 Is it b/c I haven't grabbed the type yet? thanks

 the system debug tells me the Type is null

jaw999jaw999
Fixed in the intial for query loop