• Dave Blumenfeld
  • NEWBIE
  • 0 Points
  • Member since 2015

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 2
    Questions
  • 1
    Replies

Hey All,

I am hoping someone might be able to help me diagnose a code issue.  The following are a trigger and class used to reassign leads using the assignment rules if a lead checkbox field called "Reassign__c" is checked off.  To cover the most common issues...both trigger, class, (and also test class) are active in prod and sandbox.  The other two caveats that are confusing is that previously this trigger did work, and also I have a similar trigger/class for contacts (does not use DMLOptions, but does use Database.Update(contacts)) that works fine in both prod and sandbox.  I have recently been experimenting with new sharing settings & permission set stuff, could this affect it?  Any thoughts or suggestions would be greatly appreciated.

Trigger:

trigger reassignLeads on Lead (after update){
    if (ReassignLeads.futureMethodAlreadyCalled == FALSE){
        Set<Id> leadIds=new Set<Id>();
        for(Lead l:trigger.new){
           leadIds.add(l.id);    
        }//for
        ReassignLeads.reassignLeads(leadIds);
    }//if
}//trigger

Class:
public class ReassignLeads {

    public static Boolean futureMethodAlreadyCalled = FALSE;//prevent infinite loops 
   
    @future
    public static void reassignLeads(Set<Id> ids){
        futureMethodAlreadyCalled = TRUE; //prevent infinite loops
        List<Lead> leads = [SELECT id, Reassign__c FROM Lead WHERE Id IN: ids];
        Database.DMLOptions dmo=new Database.DMLOptions();
        dmo.assignmentRuleHeader.UseDefaultRule=True;

        for (Lead l: leads){
            if(l.Reassign__c == TRUE){
              l.Reassign__c = False; //set it to false to avoid continually reassigning this lead
              l.setOptions(dmo);
            }
        }//for
       try {
           Database.Update(leads);
       }catch (DMLException e){
           system.debug('Something went wrong with the reassignLeads method: ' + e);
       }//try
    }//reassignLeads
}//class

 
Hi All.  I am trying to write an apex trigger that writes a few fields that serve as "last touch attribution" on a lead or contact onto a campaign member so that on any given campaign we can track things like what the source channel that particular campaign response is from.  I wrote a trigger that seems to be working great for both individual and bulk updates, but am having trouble with the Test Class.  (a bit of background..I am actually a digital marketer who got lassooed into being the Salesforce guy, and have little to no coding experience and am a newbie so if this looks stupid try and use small words to help me understand haha. )

I am running into an issue with the error below:

System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, AppendLastTouchCampaignMembers: execution of BeforeInsert

caused by: System.NullPointerException: Attempt to de-reference a null object

Trigger.AppendLastTouchCampaignMembers: line 26, column 1: []

First it was appearing in line twenty five (the "if" statement which said if( cm.contactId == null).  When I changed it to string.isBlank(cm.ContactId) it moved down to line 26.

Trigger:
trigger AppendLastTouchCampaignMembers on CampaignMember (before insert) {
    
    Map<ID, Lead> myLead = new Map<ID, Lead>();
    Map<ID, Contact> myContact = new Map<ID, Contact>();
    Set<Id> leadIds = new Set<Id>();
    Set<Id> contactIds = new Set<Id>();
    

    for (CampaignMember cm : Trigger.new) {

        if (cm.ContactId == null){
            leadIds.add(cm.LeadId);
        }
        else{
            contactIds.add(cm.ContactId);
        }
    }
    
    myLead = new Map<ID, Lead>([SELECT id, utm_source__c, utm_medium__c, utm_term__c FROM Lead WHERE ID IN :leadIds]);
    myContact = new Map<Id, Contact>([SELECT id, utm_source__c, utm_medium__c, utm_term__c FROM Contact WHERE ID IN :contactIds]);
    
    
    for (CampaignMember cm : Trigger.new){
        if (String.isBlank(cm.ContactId)) {
            Lead myCM = myLead.get(cm.LeadId);
            cm.Last_Touch_Source__c = myCM.utm_source__c;
            cm.Last_Touch_Medium__c = myCM.utm_medium__c;
            cm.Last_Touch_Term__c = myCM.utm_term__c;
        }
        else{
            Contact myCM = myContact.get(cm.ContactId);
            cm.Last_Touch_Source__c = myCM.utm_source__c;
            cm.Last_Touch_Medium__c = myCM.utm_medium__c;
            cm.Last_Touch_Term__c = myCM.utm_term__c;
        }
    }
}

Test Class
@isTest 

public class TestCampaignAttributionTrigger {
    static testMethod void TestCampaignMember (){

        Test.startTest();

        //Creates Contact to be linked to Campaign Member
        Contact testContact = new Contact(FirstName = 'TestContactF', LastName = 'TestContactL', Email = 'none@navinet.net', utm_source__c = 'discover', utm_medium__c = 'bought database', utm_term__c = 'test');
        Lead testLead = new Lead(FirstName = 'Dave', LastName = 'Blum', Company = 'DaveCorp', Email = 'dblum@xl.com', utm_source__c = 'discover', utm_medium__c = 'bought database', utm_term__c = 'test');
        insert testContact;
        insert testLead;



        //Creates a new campaign
        Campaign c = new Campaign(Name='Test', Status='In Progress');
        insert c;
        
        //Assign Lead & Contact to campaign
        CampaignMember newMember2 = 
        new CampaignMember(Campaign = [SELECT Id FROM Campaign WHERE Status = 'In Progress' LIMIT 5], Lead = testLead);
        insert newMember2;
        
        CampaignMember newMember = 
        new CampaignMember(Campaign = [SELECT Id FROM Campaign WHERE Name = 'Test' LIMIT 5], Contact = testContact);
        insert newMember;

        Test.stopTest();

    }
}

 
Hi All.  I am trying to write an apex trigger that writes a few fields that serve as "last touch attribution" on a lead or contact onto a campaign member so that on any given campaign we can track things like what the source channel that particular campaign response is from.  I wrote a trigger that seems to be working great for both individual and bulk updates, but am having trouble with the Test Class.  (a bit of background..I am actually a digital marketer who got lassooed into being the Salesforce guy, and have little to no coding experience and am a newbie so if this looks stupid try and use small words to help me understand haha. )

I am running into an issue with the error below:

System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, AppendLastTouchCampaignMembers: execution of BeforeInsert

caused by: System.NullPointerException: Attempt to de-reference a null object

Trigger.AppendLastTouchCampaignMembers: line 26, column 1: []

First it was appearing in line twenty five (the "if" statement which said if( cm.contactId == null).  When I changed it to string.isBlank(cm.ContactId) it moved down to line 26.

Trigger:
trigger AppendLastTouchCampaignMembers on CampaignMember (before insert) {
    
    Map<ID, Lead> myLead = new Map<ID, Lead>();
    Map<ID, Contact> myContact = new Map<ID, Contact>();
    Set<Id> leadIds = new Set<Id>();
    Set<Id> contactIds = new Set<Id>();
    

    for (CampaignMember cm : Trigger.new) {

        if (cm.ContactId == null){
            leadIds.add(cm.LeadId);
        }
        else{
            contactIds.add(cm.ContactId);
        }
    }
    
    myLead = new Map<ID, Lead>([SELECT id, utm_source__c, utm_medium__c, utm_term__c FROM Lead WHERE ID IN :leadIds]);
    myContact = new Map<Id, Contact>([SELECT id, utm_source__c, utm_medium__c, utm_term__c FROM Contact WHERE ID IN :contactIds]);
    
    
    for (CampaignMember cm : Trigger.new){
        if (String.isBlank(cm.ContactId)) {
            Lead myCM = myLead.get(cm.LeadId);
            cm.Last_Touch_Source__c = myCM.utm_source__c;
            cm.Last_Touch_Medium__c = myCM.utm_medium__c;
            cm.Last_Touch_Term__c = myCM.utm_term__c;
        }
        else{
            Contact myCM = myContact.get(cm.ContactId);
            cm.Last_Touch_Source__c = myCM.utm_source__c;
            cm.Last_Touch_Medium__c = myCM.utm_medium__c;
            cm.Last_Touch_Term__c = myCM.utm_term__c;
        }
    }
}

Test Class
@isTest 

public class TestCampaignAttributionTrigger {
    static testMethod void TestCampaignMember (){

        Test.startTest();

        //Creates Contact to be linked to Campaign Member
        Contact testContact = new Contact(FirstName = 'TestContactF', LastName = 'TestContactL', Email = 'none@navinet.net', utm_source__c = 'discover', utm_medium__c = 'bought database', utm_term__c = 'test');
        Lead testLead = new Lead(FirstName = 'Dave', LastName = 'Blum', Company = 'DaveCorp', Email = 'dblum@xl.com', utm_source__c = 'discover', utm_medium__c = 'bought database', utm_term__c = 'test');
        insert testContact;
        insert testLead;



        //Creates a new campaign
        Campaign c = new Campaign(Name='Test', Status='In Progress');
        insert c;
        
        //Assign Lead & Contact to campaign
        CampaignMember newMember2 = 
        new CampaignMember(Campaign = [SELECT Id FROM Campaign WHERE Status = 'In Progress' LIMIT 5], Lead = testLead);
        insert newMember2;
        
        CampaignMember newMember = 
        new CampaignMember(Campaign = [SELECT Id FROM Campaign WHERE Name = 'Test' LIMIT 5], Contact = testContact);
        insert newMember;

        Test.stopTest();

    }
}