• Patrick G. Brown
  • NEWBIE
  • 65 Points
  • Member since 2015
  • Patrick Brown

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 17
    Questions
  • 17
    Replies
I have a trigger that looks to see if the lookup field AVSFQB__Primary_Contact__c (looks up to Contact) has changed on an Opportunity and if so, deletes all Contact Roles and adds the value from the AVSFQB__Primary_Contact__c field.

Everything works perfectly except when I try to fire the trigger via DataLoader.  I've handled null pointer issues before, but in this example, I'm checking for null on both the list of Opportunities as well as the field AVSFQB__Primary_Contact__c just to be sure.  When executing via the ui, it works great.  When trying to upload a set of records it fails.  

Can someone point me in the right direction?
 
trigger opportunityMaintenance on Opportunity (after insert, after update) {

    if(Trigger.isAfter){
        if(Trigger.isUpdate || Trigger.isInsert){
            set<Id> setOpportunityIds = new set<Id>() ;
            for(Opportunity opp : Trigger.new){
                if(opp != null){
                    //Error on the next line: execution of AfterInsert caused by: System.NullPointerException: Attempt to de-reference a null object
                    if((opp.AVSFQB__Primary_Contact__c != null) && (Trigger.oldMap.get(opp.Id).AVSFQB__Primary_Contact__c != Trigger.newMap.get(opp.Id).AVSFQB__Primary_Contact__c))
                    {
                    setOpportunityIds.add(opp.Id) ;
                    }
                }    
            }
            if(!setOpportunityIds.isEmpty())
            delete([SELECT Id from opportunityContactRole WHERE OpportunityID IN: setOpportunityIds]) ;

        List<Opportunity> oppList = new List<Opportunity>();
        oppList = [select Id, Name, AVSFQB__Primary_Contact__c from Opportunity where Id in :Trigger.New];
            for(Opportunity opp : oppList) {
                if (oppList.size()>0){
                    if(opp.AVSFQB__Primary_Contact__c != NULL){
                        opportunityContactRole ocr = new opportunityContactRole(
                        ContactId = opp.AVSFQB__Primary_Contact__c,
                        OpportunityId = opp.Id,
                        Role = 'Decision Maker',
                        IsPrimary = TRUE);
                        insert ocr;    
                    }    
                }
            }
        }   
    }
}

 
I am relating two objects - OpportunityLineItem (child) to UG_Event_Inventory__c (parent).  Some of the products that are added to an Opportunity may need to have a related Inventory Item and some may not.  When an UG_Event_Inventory__c record is related to the OpportunityLineItem record via a Lookup, I am updating several fields on the UG_Event_Inventory__c record.

I've written a trigger and everything in it seems to work except when I'm checking to see if the Lookup field is blank and if so, I need to mark the values of the previously related UG_Event_Inventory__c record to Null.  Everything else works fine...the addition of values, the deleting of values (if the OpportunityLineItem record is deleted).  I've commented in the trigger below where the section where it doesn't work. 

Does anyone have any ideas why this isn't working?

Things I've tried:

1. I've tried correctly taking these criteria and leveraging a before update trigger...both in this trigger and as a standalone trigger independently to validate it was this code an not something else.

2. I wrote a test class that will validate the null fields.  I have 100% coverage and no errors (test class below).  I use very similar test classes to test the rest of the functionality in this trigger and they all pass with flying colors.
 
trigger opportunityLineItemMaintenance on OpportunityLineItem (before update, after insert, after update, before delete) {

//This trigger is to check for changes to the OpportunityLineItem Object and make updates as necessary to the OpportunityLineItem
//record and/or the associated UG Event Inventory Record

    if(Trigger.isAfter){
        if(Trigger.isUpdate || Trigger.isInsert){
            Set<Id> UGEventInventoryIds = new Set<Id>();
            for (OpportunityLineItem oli: Trigger.new){
                UGEventInventoryIds.add(oli.UG_Event_Inventory__c);
            }
            
            Map<Id, UG_Event_Inventory__c> eventInvMap = new Map<Id, UG_Event_Inventory__c>
            ([SELECT Id, UG_Event__c, Available__c FROM UG_Event_Inventory__c WHERE Id IN :UGEventInventoryIds]);
            
            List<UG_Event_Inventory__c> eventInvToUpdate = new List<UG_Event_Inventory__c>();
            UG_Event_Inventory__c associatedEventInv;           

            //Query to get SWAP CREDIT Opportunity Product
            
            Product2 pswap = [SELECT Id, Name, ProductCode FROM Product2 WHERE ProductCode = 'sc' LIMIT 1];
            PricebookEntry pbeswap = [SELECT Id, ProductCode, Product2Id, Pricebook2Id FROM PricebookEntry WHERE ProductCode = 'sc' and Pricebook2.IsStandard = True LIMIT 1];
            
            //Loop through OpportuintyLineItems and check for criteria
            
            for (OpportunityLineItem oli: Trigger.new){
                
                if(eventInvMap.containsKey(oli.UG_Event_Inventory__c)){
                    associatedEventInv = eventInvMap.get(oli.UG_Event_Inventory__c);
                    
                    //THIS ISN'T WORKING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
                    //If the Event Inventory is REMOVED to the Product, The Event Inventory is UNAVAILABLE, Swap is FALSE
                    //Mark it available, Remove the Opportunity Id from the Event Inventory                   
                    if (oli.UG_Event_Inventory__c == NULL && associatedEventInv.Available__c == TRUE && oli.Swap_for_Credit__c == FALSE)
                    
                    {
                        associatedEventInv1.Available__c = TRUE;
                        associatedEventInv1.Associated_Opportunity__c = NULL;
                        associatedEventInv1.Associated_Account__c = NULL;
                        associatedEventInv1.Associated_Product_Code__c = NULL;
                        associatedEventInv1.Associated_Product_Description__c = NULL;
                        associatedEventInv1.Associated_Product_Discount__c = NULL;
                        associatedEventInv1.Associated_Product_List_Price__c = NULL;
                        associatedEventInv1.Associated_Product_Sales_Price__c = NULL;
                        associatedEventInv1.Associated_Product_Total_Price__c = NULL;
                        eventInvToUpdate1.add(associatedEventInv1);
                    }
                    //END THIS ISN'T WORKING - EVERYTHING AFTER THIS WORKS FINE//
                    
                    
                    //If the Event Inventory is ADDED to the Product and the associated Event Inventory is AVAILABLE, Swap is FALSE
                    //Mark it unavailable, Add the Opportunity Id to the Event Inventory
                    if(oli.UG_Event_Inventory__c != NULL && associatedEventInv.Available__c == TRUE && oli.Swap_for_Credit__c == FALSE)
                    {   
                        //Need to get Account Id - Check to see if this will create bulk issues.
                        Opportunity opp = [SELECT Id, Name, AccountId FROM Opportunity WHERE Id = :oli.OpportunityId LIMIT 1];
                        associatedEventInv.Available__c = FALSE;
                        associatedEventInv.Associated_Opportunity__c = oli.OpportunityId;
                        associatedEventInv.Associated_Account__c = opp.AccountId;
                        associatedEventInv.Associated_Product_Code__c = oli.ProductCode;
                        associatedEventInv.Associated_Product_Description__c = oli.Description;
                        associatedEventInv.Associated_Product_Discount__c = oli.Discount;
                        associatedEventInv.Associated_Product_List_Price__c = oli.ListPrice;
                        associatedEventInv.Associated_Product_Sales_Price__c = oli.UnitPrice;
                        associatedEventInv.Associated_Product_Total_Price__c = oli.TotalPrice;
                        eventInvToUpdate.add(associatedEventInv);
                    }
                    
                    //If the Event Inventory is ASSOCIATED to the Product, The Event Inventory is UNAVAILABLE, Swap is TRUE
                    //Mark it available, Remove the Opportunity Id from the Event Inventory
                    
                    if(oli.UG_Event_Inventory__c != NULL && associatedEventInv.Available__c == FALSE && oli.Swap_for_Credit__c == TRUE)
                    {
                        //Update Associated Event Inventory
                        associatedEventInv.Available__c = TRUE;
                        associatedEventInv.Associated_Opportunity__c = NULL;
                        associatedEventInv.Associated_Account__c = NULL;
                        associatedEventInv.Associated_Product_Code__c = NULL;
                        associatedEventInv.Associated_Product_Description__c = NULL;
                        associatedEventInv.Associated_Product_Discount__c = NULL;
                        associatedEventInv.Associated_Product_List_Price__c = NULL;
                        associatedEventInv.Associated_Product_Sales_Price__c = NULL;
                        associatedEventInv.Associated_Product_Total_Price__c = NULL;
                        eventInvToUpdate.add(associatedEventInv);
                        
                        //Create and Insert SWAP CREDIT OpportunityLineItem
                        OpportunityLineItem olicred = new OpportunityLineItem(Product2Id = pswap.Id, PricebookEntryId = pbeswap.Id, OpportunityId = oli.OpportunityId, Quantity = oli.Quantity, Discount = oli.Discount, TotalPrice = oli.TotalPrice, Previous_Product_SC__c = oli.Product2Id, Previous_Product_Code_SC__c = oli.ProductCode);
                        insert olicred;
                        
                        //Query to find Id of Opportuinty Product and Delete
                        for(OpportunityLineItem oli2del: Trigger.old)
                        {
                        oli2del = [Select Id, Swap_for_Credit__c from OpportunityLineItem WHERE id = :oli.Id];
                        delete oli2del;
                        }
                    }
                }//if
            }//for
            
            update eventInvToUpdate;
            
        }
    }
    

//If an OpportunityLineItem is deleted, this will remove the associated Event Inventory Item and clear the OLI fields on the EII   
    if(Trigger.IsBefore){
        if(Trigger.IsDelete){
            Set<Id> UGEventInventoryIds = new Set<Id>();
            for (OpportunityLineItem oli: Trigger.old){
            
                UGEventInventoryIds.add(oli.UG_Event_Inventory__c);
            }
            
            Map<Id, UG_Event_Inventory__c> eventInvMap = new Map<Id, UG_Event_Inventory__c>
            ([SELECT Id, Available__c FROM UG_Event_Inventory__c WHERE Id IN :UGEventInventoryIds]);
            
            List<UG_Event_Inventory__c> eventInvToUpdate = new List<UG_Event_Inventory__c>();
            UG_Event_Inventory__c associatedEventInv;
                    
            for (OpportunityLineItem oli: Trigger.old){
                
                if(eventInvMap.containsKey(oli.UG_Event_Inventory__c)){
                    associatedEventInv = eventInvMap.get(oli.UG_Event_Inventory__c);
                    if(oli.UG_Event_Inventory__c != NULL && associatedEventInv.Available__c == FALSE)
                    {
                        associatedEventInv.Available__c = TRUE;
                        associatedEventInv.Associated_Opportunity__c = NULL;
                        associatedEventInv.Associated_Account__c = NULL;
                        associatedEventInv.Associated_Product_Code__c = NULL;
                        associatedEventInv.Associated_Product_Description__c = NULL;
                        associatedEventInv.Associated_Product_Discount__c = NULL;
                        associatedEventInv.Associated_Product_List_Price__c = NULL;
                        associatedEventInv.Associated_Product_Sales_Price__c = NULL;
                        associatedEventInv.Associated_Product_Total_Price__c = NULL;
                        eventInvToUpdate.add(associatedEventInv);
                    }
                    
                }//if
            }//for
            
            update eventInvToUpdate;
        }
    
    }
}
Not sure if will help, but this test passed and I'm checking for null values on the previously related Event Inventory Item:
 
@istest
public class testOpptyLineItemRemoveUGEI{
@istest (seeAllData=true)
public static void runTestOpptyLineItemRemoveUGEI(){

//Define Account Fields
String accountName = 'Innovatis Test';
    
//Define UG Event Fields
String ugEventName = 'Test Event 1';
    
//Define UGEvent Inventory1 Fields
String ugEventInventoryName1 = 'Test Event Inventory 1';
String BoothID1 = '1234';
String Sponsorship1 = 'Gold';
String UGEventYear1 = '2017';

//Define Opportunity Fields
String OpportunityName = 'Test Opportunity';
Date OpportunityCloseDate = Date.newInstance(2017, 12, 31);
String OpportunityStage = 'Proposal';

//Define Pricebook Fields
String pbName = 'Test Pricebook';
Boolean Activepb = TRUE;

//Define Product1 Fields
String ProductName1 = 'Test Product 1';
Boolean Active1 = TRUE;
String ProductCode1 = 'tp1';

//Create Account
Account a = new Account(Name = accountName);
insert a;

//Query for Account
Account aNew = [SELECT Id, Name FROM Account WHERE Id = :a.Id LIMIT 1];

//Create Product 1
Product2 p1 = new Product2(Name = ProductName1, IsActive = Active1, ProductCode = ProductCode1);
insert p1;

//Query for Product to get Product Ids
Product2 p1New = [SELECT Id, Name FROM Product2 WHERE Id = :p1.Id LIMIT 1];

//Create Pricebook Entry
PricebookEntry pbe1 = new PricebookEntry(UnitPrice = 1000, UseStandardPrice = FALSE, IsActive = TRUE, Pricebook2Id = Test.getStandardPricebookId(), Product2Id = p1New.Id );
insert pbe1;

//Query Price Book Entry to get Ids
PricebookEntry pbeNew1 = [SELECT Id, Name FROM PricebookEntry WHERE Id = :pbe1.Id];

//Create Event
UG_Event__c uge = new UG_Event__c (Name = ugEventName);
insert uge;

//Query Event to get Id
UG_Event__c ugeNew = [SELECT Id, Name FROM UG_Event__c WHERE Id = :uge.Id LIMIT 1];

//Create Event Inventories
UG_Event_Inventory__c ugei1 = new UG_Event_Inventory__c (UG_Event__c = uge.Id, Name = ugEventInventoryName1, Booth_ID__c = BoothID1, Sponsorship__c = Sponsorship1, UG_Event_Year__c = UGEventYear1);
insert ugei1;

//Query Event Inventories to get Ids
UG_Event_Inventory__c ugei1New = [SELECT Id, Name, Available__c FROM UG_Event_Inventory__c WHERE Name = 'Test Event 1 - Gold - 1234' LIMIT 1];

//Create Opportunity
Opportunity opp = new Opportunity (AccountId = aNew.Id, Name = OpportunityName, CloseDate = OpportunityCloseDate, StageName = OpportunityStage, Pricebook2Id = Test.getStandardPricebookId());
insert opp;

//Query Opportunity to get Id
Opportunity oppNew = [SELECT Id, Name FROM Opportunity WHERE Id = :opp.Id LIMIT 1];

//Add Products to Opportunity and Link to Event

OpportunityLineItem opi1 = new OpportunityLineItem(Product2Id = p1New.Id, Swap_for_Credit__c = FALSE, PricebookEntryId = pbeNew1.Id, OpportunityId = oppNew.Id, Quantity = 1, TotalPrice = 1000, UG_Event_Inventory__c = ugei1New.Id);
insert opi1;

//Mark opi1 UG Event Inventory as blank for testing the Clearing of the Product fields on the UGEI

opi1.UG_Event_Inventory__c = NULL;
update opi1;


//Query Event Inventory and verify it's now active and the product fields are blank
UG_Event_Inventory__c ugei1Check = [SELECT Id, Name, Available__c, Associated_Account__c, Associated_Opportunity__c, Associated_Product_Code__c, Associated_Product_Description__c, Associated_Product_Discount__c, Associated_Product_List_Price__c, Associated_Product_Sales_Price__c, Associated_Product_Total_Price__c FROM UG_Event_Inventory__c WHERE Id = :ugei1New.Id LIMIT 1];
System.assertEquals(TRUE, ugei1Check.Available__c);
System.assertEquals(NULL, ugei1Check.Associated_Account__c);
System.assertEquals(NULL, ugei1Check.Associated_Opportunity__c);
System.assertEquals(NULL, ugei1Check.Associated_Product_Code__c);

}
}


 
I'm working on a test for my batch process.  The batch works fine, however, I'm getting an error message in my test class.  Can anyone help?

Here is the batch I'm executing:
 
/**
This batch process will be triggered when a Campaign is deactivated and will stamp the Campaign with the dateTime value.
This batch will kick off two processes that also update Leads and CampaignMembers with the appropriate values.

*/

global class batchDeactivateCampaignCM implements Database.Batchable<sObject>,Database.Stateful{  
   
  
   global final DateTime nowStamp;
   //global final Integer nowStamp;
   global final Integer currentNowDateTime;  
   global List<Campaign> recordsToUpdate;
   
   
   global batchDeactivateCampaignCM(Integer nowDateTime)  
   {  
     currentNowDateTime = nowDateTime;  
     nowStamp = datetime.now();  
     recordsToUpdate = new List<Campaign>();  
   }  
   global Database.QueryLocator start(Database.BatchableContext BC)  
   {  
    return Database.getQueryLocator('Select id, Name, IsActive, Deactivate_Date__c from Campaign WHERE IsActive = FALSE AND Deactivate_Date__c = NULL');
    //Patrick, add this Where clause back in WHERE IsActive = FALSE AND Deactivate_Date__c = NULL
   }  
   global void execute(Database.BatchableContext BC, List<Campaign> scope)  
   {  
    for(Campaign c: scope)  
    {  if(c.IsActive == False && c.Deactivate_Date__c ==NULL){
     c.Deactivate_Date__c = nowStamp;  
    }
    }
    recordsToUpdate.addAll(scope);   
    update scope;  
   }  
    global void finish(Database.BatchableContext BC)
    {
	// Get the ID of the AsyncApexJob representing this batch job
	// from Database.BatchableContext.
	// Query the AsyncApexJob object to retrieve the current job's information.
	AsyncApexJob a = [SELECT Id, 
							Status, 
							NumberOfErrors, 
							JobItemsProcessed,
							TotalJobItems, 
							CreatedBy.Email
							FROM AsyncApexJob 
							WHERE Id = :BC.getJobId()];
	// Send an email to the Apex job's submitter notifying of job completion.
	Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
	String[] toAddresses = new String[] {a.CreatedBy.Email};
	mail.setToAddresses(toAddresses);
	mail.setSubject('Batch Process to Deactivate Campaigns ' + a.Status);
	mail.setPlainTextBody
	('The batch Apex job batchDeactivateCampaignCM processed ' + a.TotalJobItems +
	' batches with '+ a.NumberOfErrors + ' failures.');
	Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
	
System.debug('DateTimeStamped : '+ nowStamp);
System.ScheduleBatch(new batchDeactivateCampaignMembers(recordsToUpdate),'Batch to Update CampaignMembers :'+String.valueOf(Datetime.now()),1,50);  
System.ScheduleBatch(new batchDeactivateLeads(recordsToUpdate),'Batch to Update Leads :'+String.valueOf(Datetime.now()),2,50);   
	
	}
}

My test class is below. 

I'm getting an error on line 18, col 1 stating ( campList.add((Campaign)QIT.next()); ).  The error reads: "System.NoSuchElementException: Iterator has no more elements
Class.Database.QueryLocatorIterator.next: line 52, column 1
Class.batchDeactivateCMLeadTest.testBatch: line 18, column 1"
 
@IsTest  
 class batchDeactivateCMLeadTest  
 {  
 static testMethod void testBatch()  
 {  
  Campaign c = new Campaign(Name='Test Batch Campaign');  
  insert c;  
  Lead l = new Lead(firstname ='Testbatchfirst', lastname = 'Testbatchlast', company = 'Testbatchcompany', National_Provider_Number_NPN__c = '12354868541');  
  insert l;
  CampaignMember cm = new CampaignMember(CampaignId = c.id, LeadId = l.id);
  insert cm;
  Database.BatchableContext BC;  
  batchDeactivateCampaignCM bdc = new batchDeactivateCampaignCM(50);  
  bdc.start(BC);  
  Database.QueryLocator QL = bdc.Start(BC);  
  List<Campaign> campList = new List<Campaign>();  
  Database.QueryLocatorIterator QIT = QL.iterator();  
  campList.add((Campaign)QIT.next());  
  bdc.execute(BC,campList);  
  bdc.finish(BC);  
//   System.assertEquals([Select 
//                         id,
//                         Name
//                         from Campaign
//                         where Name = 'Test Batch Campaign']);  
  Database.BatchableContext BC_new;  
  batchDeactivateCampaignMembers bdcm = new batchDeactivateCampaignMembers([Select Id from Campaign]);  
  bdcm.start(BC_new);  
  Database.QueryLocator QL_new = bdcm.Start(BC_new);  
  List<CampaignMember> campaignMem = new List<CampaignMember>();  
  Database.QueryLocatorIterator QIT_new = QL_new.iterator();  
  campaignMem.add((CampaignMember)QIT_new.next());  
  bdcm.execute(BC_new,campaignMem);  
  bdcm.finish(BC_new);  

  Database.BatchableContext BC_new2;  
  batchDeactivateLeads bdl = new batchDeactivateLeads([Select Id from Campaign]);  
  bdl.start(BC_new2);  
  Database.QueryLocator QL_new2 = bdl.Start(BC_new);  
  List<Lead> campaignLead = new List<Lead>();  
  Database.QueryLocatorIterator QIT_new2 = QL_new2.iterator();  
  campaignLead.add((Lead)QIT_new.next());  
  bdl.execute(BC_new,campaignLead);  
  bdl.finish(BC_new);

 }  
 }

 
I have an interesting scenario where I need to update a many-to-many record (Campaign Members) on Leads associated with Campaigns and I need the trigger to refer to values in both the Lead and Campaign objects.

Here's my scenario:  I need to maintain a status value on the Campaign Member record (Campaign_Lead_Status__c) and when the Campaign Member is updated, push this value to the Status field on the Lead.  This trigger should only fire when the Campaign is Active.  If the Campaign isn't active, I don't want this trigger to fire.

Here is what I think is happening, but I'm not sure:  To make this trigger work, I need to make one list of Campaign Members related to Leads (for my update) and another list of Campaign Members related to Campaigns (to check for IsActive).  

When I update one Campaign Member at a time, this trigger works perfectly.  But if I do any type of bulk process such as update Campaign Members via scheduled batch, use DataLoader or use the Bulk update/import process for Leads, I get the dreaded "caused by: System.ListException: Duplicate id in list:" error message.

Below is my code.  Does anyone have a good idea to solve for this?  Do I need to try to create only one list somehow?
 
//////////////////////START - CAMPAIGN MEMBER - SYNC LEAD STATUS//////////////////////


//Create Set of Leads and make list

    if(Trigger.IsAfter){
        if(Trigger.IsUpdate){
        
        Set<Id> leadIds = new Set<Id>();
        for (CampaignMember cml: Trigger.new){
            leadIds.add(cml.LeadId);
        }
            Map<Id, Lead> LeadMap = new Map<Id, Lead>([SELECT Id, Current_Campaign__c, Status 
                                                        FROM Lead 
                                                        WHERE Id IN :LeadIDs]);
            List<Lead> leadToUpdate = new List<Lead>();
            Lead associatedLead;
            
//End Create Set of Leads and make list            
            
//Below, create a list of Campaigns to look and see if IsActive == FALSE

//Create Set of Campaigns and make list 

        Set<Id> campaignIds = new Set<Id>();
        for (CampaignMember cmc: Trigger.new){
            campaignIds.add(cmc.CampaignId);
        }
        Map<Id, Campaign> CampaignMap = new Map<Id, Campaign>([SELECT Id, Name, IsActive 
                                                                FROM Campaign 
                                                                WHERE Id IN :campaignIds]);
        List<Campaign> campaignToCheck = new List<Campaign>();
        Campaign associatedCampaign;
    
            for (CampaignMember cmc: Trigger.new){
                if(CampaignMap.containsKey(cmc.CampaignId)){
                associatedCampaign = CampaignMap.get(cmc.CampaignId);
                    if(associatedCampaign.IsActive==FALSE){
                    //do nothing    
                    }
                    else if (associatedCampaign.IsActive==TRUE){
            
//End Create Set of Campaigns and make list

//For List of CampaignMembers, check CampaignLeadStatus and update Lead Status

            for (CampaignMember cml: Trigger.new){
                if(LeadMap.containsKey(cml.LeadId)){
                    associatedLead = LeadMap.get(cml.LeadId);
                
        
                    if(cml.Campaign_Lead_Status__c=='Resting'){
                        associatedLead.Status = 'Resting';
                        leadToUpdate.add(associatedLead);
                    }
                        
                    
                    if(cml.Campaign_Lead_Status__c=='In Campaign'){
                         associatedLead.Status = 'In Campaign';
                         leadToUpdate.add(associatedLead);
                    }
                         
                         
                    if(cml.Campaign_Lead_Status__c=='Untouched'){
                         associatedLead.Status = 'In Campaign';
                         leadToUpdate.add(associatedLead);
                    }

                    
                    if(cml.Campaign_Lead_Status__c=='24H Call Back'){
                         associatedLead.Status = '24H Call Back';
                         leadToUpdate.add(associatedLead);
                    }

                    
                    if(cml.Campaign_Lead_Status__c=='Qualifying'){
                         associatedLead.Status = 'Qualifying';
                         leadToUpdate.add(associatedLead);
                    }
                    
                    
                    if(cml.Campaign_Lead_Status__c=='Disqualified'){
                         associatedLead.Status = 'Disqualified';
                         leadToUpdate.add(associatedLead);
                    }

                    
                    if(cml.Campaign_Lead_Status__c=='Pre-Contracting'){
                         associatedLead.Status = 'Pre-Contracting';
                         leadToUpdate.add(associatedLead);
                    }

                    
                    if(cml.Campaign_Lead_Status__c=='Contracting'){
                         associatedLead.Status = 'Contracting';
                         leadToUpdate.add(associatedLead);
                    }

                } 
            
            }   
            update leadToUpdate;
                    }
                }
                
            }
        }
    
    }
    
//////////////////////END - CAMPAIGN MEMBER - SYNC LEAD STATUS//////////////////////

} //end trigger

//10-15-12:44 am
//Restore Point
//When trying to bulk update campaign members of any size via data loader, receiving error 
//campaignMemberControl: execution of AfterUpdate caused by: System.ListException: Duplicate id in list: 00Q1b000001OvMIEA0
//Trigger.campaignMemberControl: line 226, column 1

 
I have a trigger on Campaigns that is doing two things.
  1. When the Campaign IsActive is flipped to FALSE, I am updating related Campaign Members
  2. When the Campagin IsActive is flipped to FALSE, I am updating related Leads (Leads are related directly via a custom field called Current_Campaign_ID__c).
When the Campaign is deactivated, my Leads update no problem.  However, nothing happens to my Campaign Members.  If I remove the entire Leads update section, my Campaign Members work just fine.  Can I not do two different updates in one trigger?
 
trigger deactivateCampaignMember on Campaign (after update) {


//HANDLE UPDATING CAMPAIGN MEMBERS RELATED TO CAMPAIGN
    Set<ID> campids = new Set<ID>();
    for(Campaign camp : Trigger.new){
            campIds.add(camp.Id);
    }

    List<Campaign> updatedCampaigns = [SELECT Id, IsActive, (Select Id, Campaign_IsActive__c from CampaignMembers)  FROM Campaign WHERE Id in :campids];
    List<CampaignMember> campMemsToUpdate = new List<CampaignMember>();

    for (Campaign camp : updatedCampaigns){

        for(CampaignMember cm : camp.CampaignMembers){
            if(camp.IsActive == False){
            cm.Campaign_IsActive__c = False;
                if(cm.Campaign_Lead_Status__c == 'In Campaign'){
                    cm.Campaign_Lead_Status__c ='Resting';
                    campMemsToUpdate.add(cm);
                    
                }
            }
        }
    }
    
    
//HANDLE UPDATING LEADS RELATED TO CAMPAIGN    
        Set<ID> campids2 = new Set<ID>();
        for(Campaign camp2 : Trigger.new){
                campIds2.add(camp2.Id);
        }   
        List<Campaign> updatedCampaigns2 = [SELECT Id, IsActive, (Select Id, Current_Campaign__c, Current_Campaign_ID__c, Status from Leads__r)  FROM Campaign WHERE Id in :campids2];
        List<Lead> campLeadsToUpdate = new List<Lead>();
    
        for(Campaign camp2 : updatedCampaigns2){
        
            for(Lead ld : camp2.Leads__r){
                if(camp2.IsActive == False){
                    if(ld.Status == 'In Campaign'){
                        ld.Status = 'Resting';
                        ld.Current_Campaign__c = '';
                        ld.Current_Campaign_ID__c = NULL;
                        campLeadsToUpdate.add(ld);
                    }
                }    
            }
        }
    update campMemsToUpdate;
    update campLeadsToUpdate;
 }

Any help would be most appreciated.  Thanks so much. 
I have a checkbox field on my Campaign Member records called Campaign_IsActive__c.  Using a trigger, I'd like when my Campaign IsActive = FALSE, to update the Campagin_IsActive__c on my Campaign Member records.

I've been working on a trigger for a few days and continue to run into roadblocks.  I'm currently facing an error stating: Variable Does Not Exist: 'CampaignMember'.

Can anyone please point me in the right direction?  Once I can get the list, I'll be able to update the field.  But I have had the hardest time simply getting a list of CampaignMembers from Campaigns.
 
trigger deactivateCampaignMember on Campaign (after insert) {
    if(Trigger.isAfter){
        if(Trigger.isInsert){
        Map<id, list<CampaignMember>> campaignMemberMap = new Map<Id, List<CampaignMember>>();
        for(campaign camp : [SELECT Id, (SELECT LeadId,ContactId FROM CampaignMembers) FROM Campaign])
        
            {
            list<CampaignMember> campMemebersList = camp.CampaignMember;
            
            if(campMemebersList!= null)
                {
                campaignMemberMap.put(camp.Id, campMemebersList);
                }
            }

        }
    }
}



 
I have an interesting trigger on Campaign Member that needs to check a value on the associated Lead and associated Campaign and if both are TRUE, it should fire and update a few fields.  The challenge I'm having is that I can't figure out how to get both the Campaign and Lead variables inside of one for loop, without creating a loop inside of a loop, which will inevitably give me a DML insert error.  I create two Sets to get the IDs of the respective Leads and Campaigns, however, when I try to add the Campaign inside of my for loop I'm receiving a "variable doesn't exist" error.  I understand why...it's because I'm creating a "for"' on cml and not cmc (see below).  

I've commented out the code that is giving me issues.  How do I loop through two different objects that are related by a m2m (Campaign Member), relate them to each other, check for values in both Lead and Campaign, then update my Lead?  Any suggestions?
 
trigger deactivateCampaignSetToResting on CampaignMember (before Update) {
if(Trigger.IsBefore){
    if(Trigger.IsUpdate){
        Set<Id> leadIds = new Set<Id>();
        for (CampaignMember cml: Trigger.new){
            leadIds.add(cml.LeadId);
        }
        Set<Id> campaignIds = new Set<Id>();
        for (CampaignMember cmc: Trigger.New){
            campaignIds.add(cmc.CampaignId);
        }
        Map<Id, Lead> LeadMap2 = 
            new Map<Id, Lead>([SELECT Id, Current_Campaign__c, Status 
                              FROM Lead 
                              WHERE Id IN :LeadIDs]);
        List<Lead> leadToUpdate2 = new List<Lead>();
        Lead associatedLead2;
        
        Map<Id, Campaign> CampaignMap = 
            new Map<Id, Campaign>([SELECT Id, IsActive
                                    FROM Campaign
                                    WHERE Id IN :CampaignIds]);
        
        for (CampaignMember cml: Trigger.new){
            if(LeadMap2.containsKey(cml.LeadId)){
                associatedLead2 = LeadMap2.get(cml.LeadId);
                //if(CampaignMap.containsKey(cmc.LeadId)){
                //associatedCampaign = CampaignMap.get(cmc.CampaignId);    
                //    if( Trigger.oldMap.get(cmc.Id).IsActive != Trigger.newMap.get(cmc.Id).IsActive ){
                        if(associatedLead2.Current_Campaign__c!=NULL){
                            if(cml.Campaign_Lead_Status__c !='Pre-Contracting'){
                                if(cml.Campaign_Lead_Status__c !='Contracting'){
                                    if(cml.Campaign_Lead_Status__c !='Disqualified'){
                                        
                                        cml.Campaign_Lead_Status__c = 'Resting';
                                        associatedLead2.Status = 'Resting';
                                        associatedLead2.Current_Campaign__c = '';
                                        leadToUpdate2.add(associatedLead2);
                                    }
                                }
                            }
                            
                        } 
                        
                    //}
                    
                //}
                
            }
            
        }
        update leadToUpdate2;
    }
}
}

 
I have a trigger that I've been working on for a few days and worked through all of the errors (with a lot of help from this forum). However, it's simply not working and I can't figure out why.  This trigger is on Campaign Member and if the Current_Campaign__c value in my Lead is blank, it looks to add the Campaign_Name__c from my Campaign Member to the Current_Campaign__c field on my associated Lead record.  I've tried everything I know to do.   Here is my code:
 
trigger setLeadStatusandCurrentCampaign on CampaignMember (after insert) {
	if(Trigger.isAfter){
		if(Trigger.isInsert){
			/*Set<Id> leadIds = new Set<Id>();
			for (CampaignMember cml: Trigger.new){
				leadIds.add(cml.LeadId);
			}*/
			Map<Id, Lead> LeadMap2 = 
				new Map<Id, Lead>([SELECT Id, Current_Campaign__c, Status 
								   FROM Lead 
								   WHERE Id IN :Trigger.newMap.keyset()]);
			List<Lead> leadToUpdate2 = new List<Lead>();
			Lead associatedLead2;			
			//Loop through Campaign Member Leads and look for Current Campaign values
			for (CampaignMember cml: Trigger.new){
			
				if(LeadMap2.containsKey(cml.LeadId)){
					associatedLead2 = LeadMap2.get(cml.LeadId);
					if(associatedLead2.Current_Campaign__c == NULL)
					{
//This is not working
						associatedLead2.Status = 'In Campaign';
						associatedLead2.Current_Campaign__c = cml.Campaign_Name__c;
						leadToUpdate2.add(associatedLead2);
					}
				}//if
			}//for
			
			update leadToUpdate2;
		}
	}
}

I replaced "associatedLead2.Current_Campaign__c = cml.Campaign_Name__c;" with "associatedLead2.Current_Campaign__c = "text";" to make sure it wasn't the formula field that was causing the error.  For some reason, my update isn't working.  Any ideas?
I have a trigger that works fine up to about 100 Campaign Members on import, but once I hit around 100 I receive the Too Many DML Statements 151 Error.  Anyone have an idea how to fix?
 
trigger setLeadStatusandCurrentCampaign on CampaignMember (after insert) {

    Set<Id> leadIds = new Set<Id>();
    for (CampaignMember cml: Trigger.new){
        leadIds.add(cml.LeadId);
    }
    
    Map<Id, Lead> LeadMap2 = new Map<Id, Lead>([SELECT Id, Current_Campaign__c, Status FROM Lead WHERE Id IN :leadIds]);
        
        //Loop through Campaign Member Leads and look for Current Campaign values
    for (CampaignMember cml: Trigger.new){
        List<Lead> leadToUpdate2=new List<Lead>();
        Lead associatedLead2 = LeadMap2.get(cml.LeadId);
        if(associatedLead2.Current_Campaign__c==NULL)
                {
                    associatedLead2.Status = 'In Campaign';
                    associatedLead2.Current_Campaign__c = cml.Campaign_Name__c;
                    leadToUpdate2.add(associatedLead2);
                }
        
        update leadToUpdate2;
    }

}

 
I have a relatively simple trigger that looks through Campaign Members, finds the associated Lead records and checks to see if the Current_Campaign__c field is null on the Lead.  If that field is not null, I throw an error.  I thought I'd used best practices, however, I'm getting a null pointer exception on this line: if(associatedLead2.Current_Campaign__c!=NULL).  The full error reads: checkCurrentCampaign: execution of BeforeInsert caused by: System.NullPointerException: Attempt to de-reference a null object Trigger.checkCurrentCampaign: line 13, column 1

Can anyone see what I may have done?  I've tried to edit this a dozen or so different ways to ensure I'm not pulling null records, but I'm still receiving an error.  Any assistance would be most appreciated.

My trigger:
 
trigger checkCurrentCampaign on CampaignMember (before insert) {
    Set<Id> leadIds = new Set<Id>();
    for (CampaignMember cml: Trigger.new){    
            leadIds.add(cml.LeadId);
        }
    
        Map<Id, Lead> LeadMap2 = new Map<Id, Lead>([SELECT Id, Current_Campaign__c, Status FROM Lead WHERE Id IN :leadIds]);
    
    //Loop through Campaign Members and get Associated Lead ID
        for (CampaignMember cml: Trigger.new){
            Lead associatedLead2 = LeadMap2.get(cml.LeadId);
            //Still getting a dereference null error    
                if(associatedLead2.Current_Campaign__c!=NULL)
                {
            cml.adderror('Campaign Members can only be in one Campaign at a time.  If you are receiving this error, you are attempting to add one or more Leads to multiple active Campaigns');
                }
        }   
    }

 
I have a trigger that looks to see if a Campaign is Active and if so, throws an error when a user tries to delete it.  Here is my trigger:
 
trigger cannotDeleteCampaignMember on CampaignMember (before delete) {
    if(System.Trigger.IsDelete){
        Set<Id> leadIds = new Set<Id>();
        for (CampaignMember cm: Trigger.old){
            leadIds.add(cm.LeadId);
        }
        Map<Id, Lead> leadMap = new Map<Id, Lead>([SELECT Id, Current_Campaign__c, Status FROM Lead WHERE Id IN :leadIds]);
        List<Lead> leadToUpdate=new List<Lead>();
        for (CampaignMember cm: Trigger.old)
        {Lead associatedLead = leadMap.get(cm.LeadId);
         if(associatedLead.Current_Campaign__c!=null)
         {
             cm.adderror('Only the Marketing Team can delete Campaign Members.  If you are on the Marketing Team and would like to delete this Campaign Member, go to the Lead and remove the value from the "Current Campaign" field first.');
         }
         if(associatedLead.Current_Campaign__c==null)
         {
             associatedLead.Status = 'Resting';
             leadToUpdate.add(associatedLead);
         }
         
        } 
        update leadToUpdate;
    }   
}

I've written a test class that meets the threshold of passing, so I'm good to move my code to our Production org.  However, the way I would like to test this isn't working the way one would expect.  Here is my test class:
 
@isTest

public class testCannotDeleteCampaignMember {
    @isTest
    public static void runTestDelete(){
        String campName4 = 'Apex Test Campaign4';  
        String lead4firstName = 'Apex4';
        String lead4lastName = 'Test4';
        String lead4Company = 'Apex Test Company4';
        
        
        //Create Campaign1
        Campaign camp4 = new Campaign(Name=campName4, Isactive=True);
        insert camp4;
        
        
        // Create Lead 1
        Lead lead4 = new Lead(firstName=lead4firstName,
                              lastName=lead4lastName,
                              Company=lead4Company);
        insert lead4;
        
        
        //Grab Campaign ID for the Campaigns created above
        
        Campaign campid4 = [SELECT Id FROM Campaign WHERE Name = 'Apex Test Campaign4' LIMIT 1];
        
        // Associate Lead 1 to Campaign - You must deactivate Activate Campaign on Create WFR
        CampaignMember newMember4 = new CampaignMember(LeadID = lead4.Id, 
                                                       status='Sent',
                                                       campaignid = campid4.id);
        insert newMember4;
        
        
        CampaignMember deletedCM = [SELECT Id, IsDeleted FROM CampaignMember WHERE campaignid = :campid4.id ALL ROWS];
        //Try to delete the Campaign Member        
        try
        {
            
            delete newMember4;
        }
        
        //Validate error is thrown
        catch(Exception e)
        {
            System.Assert(e.getMessage().contains('Only the Marketing Team can delete Campaign Members. If you are on the Marketing Team and would like to delete this Campaign Member, go to the Lead and remove the value from the "Current Campaign" field first.'));
        }
    }
}

When I run this test class it fails every time in row 46, which is my "System.Assert(e.getMessage()...." line.  This seems pretty straightforward...I'm asking it to try to delete the record (which should throw an error due to my trigger) then catch the error and ensure it matches the error message in my trigger.

When I comment out line 46, my test case passes with 85% coverage.  Like it is, it simply fails.  The error message it gives me when it fails is: "Class.testCannotDeleteCampaignMember.runTestDelete: line 46, column 1".  Of course, it can't delete the record...that's what my trigger is designed to prevent.

Can anyone tell me why my test case is failing when I try to catch the error message in row 46?
I have a pretty straightforward relationship between two custom Salesforce objects: Agent Contract (child) and Hierarchy (parent).  There is a lookup field on the Agent Contract page that looks out to the Hierarchy object.  What I'm trying to do is maintain a list of static values for certain fields in the Hierarchy table so that when a new Agent Contract is created or edited, and a user adds a lookup value in the Hiearchy_Name__c field (only if the field was previously blank) on the Agent Contract,  the trigger will fire and will pull over some field values.

I am using a very similar trigger between Campaigns and Campaign Members and it works fine.  However, this trigger is throwing an Invalid foreign key relationship: Agent_Contract__c.Hierarchy__c.  Can anyone please tell me what I've done incorrectly?
 
trigger agentContractHierarchy on Agent_Contract__c (before update) {
    Set<Id> hierarchyIds = new Set<Id>();
    for (Agent_Contract__c ac: Trigger.new){
        hierarchyIds.add(ac.Hierarchy__c.Id);
    }
    Map<Id, Hierarchy__c> hierarchyMap = new Map<Id, Hierarchy__c>([SELECT Id, SGA__c FROM Hierarchy__c WHERE Id IN :hierarchyIds]);
    for (Agent_Contract__c ac: Trigger.new)
    {Hierarchy__c associatedHierarchy = hierarchyMap.get(ac.hierarchyId);
     if(associatedHierarchy.Id==NULL)
     {
         //Do my thing
     }
    }
}

 
I'm working with a simple before delete trigger and am stumped on one piece.  This trigger checks if a value is present on the Lead and if so, throws an error when trying to delete the Campaign Member.  What I would like to do is check the status of this field, if it is not null, throw the error.  If it is null, update the Lead Status to 'Resting".  The trigger works for the error but doesn't update the Lead Status field.  Any help would be most appreciated.

 
trigger cannotDeleteCampaignMember on CampaignMember (before delete) {
    if(System.Trigger.IsDelete){
        Set<Id> leadIds = new Set<Id>();
        for (CampaignMember cm: Trigger.old){
            leadIds.add(cm.LeadId);
        }
        Map<Id, Lead> leadMap = new Map<Id, Lead>([SELECT Id, Current_Campaign__c, Status FROM Lead WHERE Id IN :leadIds]); 
        for (CampaignMember cm: Trigger.old)
        {Lead associatedLead = leadMap.get(cm.LeadId);
         if(associatedLead.Current_Campaign__c!=null)
         {
             cm.adderror('Only the Marketing Team can delete Campaign Members.  If you are on the Marketing Team and would like to delete this Campaign Member, go to the Lead and remove the value from the "Current Campaign" field first.');
         }
         if(associatedLead.Current_Campaign__c==null)
         {
             associatedLead.Status = 'Resting';
         }
         
        }   
    }   
}

 
I'm writing a trigger to default the Account of a Contact each time a Contact is created.  The trigger is relatively simple.  I'm receiving an error that reads: Variable does not exist: Id.  Can anyone point me in the direction of what I'm doing wrong?
 
trigger setDefaultAcc on Contact (before insert){
    List<Contact> lstCon = new List<Contact>();
    // Find out and prepare list of Contacts
    for(Contact var : Trigger.new){
        if(var.AccountId == null){
            lstCon.add(var);
        }
    }
    // Fetch the Default account
    if(lstCon.size()>0){
        List<Account> acc = new List<Account>();
        acc = [SELECT Id, Name FROM Account WHERE Name = 'Strategic Market Advisors' LIMIT 1];
        if(acc != null){
            for(Contact var : lstCon){
                // Assign the id of the default account to the selected contacts
                var.AccountId = acc.Id;
            }
        }
    }
}

 
I have a very simple query that ls looking querying Accounts to find one particular Account, then assign that Account's ID to the Account field on my Contact record.  I continue to get the "System.QueryException: List has no rows for assignment to SObject" error, but when I run the query using Query Editor, it returns the appropriate record.  Can anyone please tell me what I'm doing wrong?
 
trigger assignAccounttoContact on Contact (before insert, before update) {
    
    Account a = [
        SELECT ID, Name 
        FROM Account 
        WHERE Name = 'TestAccount'
    ];
    
    for(Contact c: Trigger.new){
        
        c.AccountID = a.ID;
    }
    
}

 
I have a trigger to create a Monthly Outreach record that looks to be correct, but I continue to run into a required field error.  Here is an example of my error:

Image of error

I have a master record (Outreach Target) with two identical values (see below) that I'm manually adding to this child record for the purposes of matching.  Those two fields are Location ID and Year Submitted.  My trigger is attempting to add a parent Outreach Target record ID the child Monthly Outreach record by querying the Outreach Target object and searching for a record with matching criteria.  The criteria is unique, so my SOQL query will only find one record.

Here is the master record who's Id I'm attempting to add to my child Monthly Outreach record:

Master Record

Here is my trigger:
 
trigger SetOutreachTarget on Monthly_Outreaches__c (after insert, after update) {
    for (Monthly_Outreaches__c mo : Trigger.new) {
        String moy = mo.Year__c;
        String moa = mo.Location_ID__c;
        List<Outreach_Target__c> ot = [SELECT Id FROM Outreach_Target__c WHERE Outreach_Target_Year__c = :moy AND Location_ID__c = :moa];        
        if(ot.size()>0){
            mo.Outreach_Target__c = ot[0].Id;}
    }
}

I've even tried hard-coding the master record ID into the query to guarantee I'm finding the matching record, but I continue to get the required field error.  Can anyone please help me solve this issue?



 
Everyone, I have the most basic trigger and am getting a silly testing error that I can't shake.  Ironically, when I manually fire this trigger, it works perfectly.  But when I test it, I receive this error: "System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, SetAccountField: execution of BeforeInsert caused by: System.ListException: List index out of bounds: 0  Trigger.SetAccountField: line 6, column 1: []"  

This trigger simply looks at a "location_ID" field on my Monthly Outreach object, which coorelates to a "location_ID" field on my Account object, then associates the Account ID to my Monthly Outreach record.  I continue to get the dreaded List Out of Bounds error.  After much research, it appears that I'm supposed to be checking to see if my account variable is null.  I thought I was doing that by adding:"if(account != null)".  Can anyone tell me what I'm doing wrong?

My trigger:
trigger SetAccountField on Monthly_Outreaches__c (before insert, before update) {
    for (Monthly_Outreaches__c mo : Trigger.new) {
        String accid = mo.Location_ID__c;
        List<Account> account = [SELECT Id FROM Account WHERE Location_ID__c = :accid];
        if(account != null){
            account[0].Id = mo.Account__c;} else {
            }
    }
}

Here is my test class.  Again, very basic:
 
@isTest 
private class AddMonthlyOutreachesTestClass {
    static testMethod void validateMonthlyOutreaches() {
        Monthly_Outreaches__c m = new Monthly_Outreaches__c(
            LOCATION_ID__C='001', 
            Submitter_Email__c='rick.allen@xxx.com',
            MEDIA_INTERVIEWS_ARTICLES__C=100         
        );
        // Insert Monthly Outreaches
        insert m;
        
        ApexPages.StandardController sc = new ApexPages.standardController(m);
        MonthlyOutreachesRedirect e = new MonthlyOutreachesRedirect(sc);
        String nextPage = e.saveAndCongrat().getURL();
        
        // Verify that the Congratulations page displays
        System.assertEquals('/apex/congratulations', nextPage);
    }
}
I am relating two objects - OpportunityLineItem (child) to UG_Event_Inventory__c (parent).  Some of the products that are added to an Opportunity may need to have a related Inventory Item and some may not.  When an UG_Event_Inventory__c record is related to the OpportunityLineItem record via a Lookup, I am updating several fields on the UG_Event_Inventory__c record.

I've written a trigger and everything in it seems to work except when I'm checking to see if the Lookup field is blank and if so, I need to mark the values of the previously related UG_Event_Inventory__c record to Null.  Everything else works fine...the addition of values, the deleting of values (if the OpportunityLineItem record is deleted).  I've commented in the trigger below where the section where it doesn't work. 

Does anyone have any ideas why this isn't working?

Things I've tried:

1. I've tried correctly taking these criteria and leveraging a before update trigger...both in this trigger and as a standalone trigger independently to validate it was this code an not something else.

2. I wrote a test class that will validate the null fields.  I have 100% coverage and no errors (test class below).  I use very similar test classes to test the rest of the functionality in this trigger and they all pass with flying colors.
 
trigger opportunityLineItemMaintenance on OpportunityLineItem (before update, after insert, after update, before delete) {

//This trigger is to check for changes to the OpportunityLineItem Object and make updates as necessary to the OpportunityLineItem
//record and/or the associated UG Event Inventory Record

    if(Trigger.isAfter){
        if(Trigger.isUpdate || Trigger.isInsert){
            Set<Id> UGEventInventoryIds = new Set<Id>();
            for (OpportunityLineItem oli: Trigger.new){
                UGEventInventoryIds.add(oli.UG_Event_Inventory__c);
            }
            
            Map<Id, UG_Event_Inventory__c> eventInvMap = new Map<Id, UG_Event_Inventory__c>
            ([SELECT Id, UG_Event__c, Available__c FROM UG_Event_Inventory__c WHERE Id IN :UGEventInventoryIds]);
            
            List<UG_Event_Inventory__c> eventInvToUpdate = new List<UG_Event_Inventory__c>();
            UG_Event_Inventory__c associatedEventInv;           

            //Query to get SWAP CREDIT Opportunity Product
            
            Product2 pswap = [SELECT Id, Name, ProductCode FROM Product2 WHERE ProductCode = 'sc' LIMIT 1];
            PricebookEntry pbeswap = [SELECT Id, ProductCode, Product2Id, Pricebook2Id FROM PricebookEntry WHERE ProductCode = 'sc' and Pricebook2.IsStandard = True LIMIT 1];
            
            //Loop through OpportuintyLineItems and check for criteria
            
            for (OpportunityLineItem oli: Trigger.new){
                
                if(eventInvMap.containsKey(oli.UG_Event_Inventory__c)){
                    associatedEventInv = eventInvMap.get(oli.UG_Event_Inventory__c);
                    
                    //THIS ISN'T WORKING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
                    //If the Event Inventory is REMOVED to the Product, The Event Inventory is UNAVAILABLE, Swap is FALSE
                    //Mark it available, Remove the Opportunity Id from the Event Inventory                   
                    if (oli.UG_Event_Inventory__c == NULL && associatedEventInv.Available__c == TRUE && oli.Swap_for_Credit__c == FALSE)
                    
                    {
                        associatedEventInv1.Available__c = TRUE;
                        associatedEventInv1.Associated_Opportunity__c = NULL;
                        associatedEventInv1.Associated_Account__c = NULL;
                        associatedEventInv1.Associated_Product_Code__c = NULL;
                        associatedEventInv1.Associated_Product_Description__c = NULL;
                        associatedEventInv1.Associated_Product_Discount__c = NULL;
                        associatedEventInv1.Associated_Product_List_Price__c = NULL;
                        associatedEventInv1.Associated_Product_Sales_Price__c = NULL;
                        associatedEventInv1.Associated_Product_Total_Price__c = NULL;
                        eventInvToUpdate1.add(associatedEventInv1);
                    }
                    //END THIS ISN'T WORKING - EVERYTHING AFTER THIS WORKS FINE//
                    
                    
                    //If the Event Inventory is ADDED to the Product and the associated Event Inventory is AVAILABLE, Swap is FALSE
                    //Mark it unavailable, Add the Opportunity Id to the Event Inventory
                    if(oli.UG_Event_Inventory__c != NULL && associatedEventInv.Available__c == TRUE && oli.Swap_for_Credit__c == FALSE)
                    {   
                        //Need to get Account Id - Check to see if this will create bulk issues.
                        Opportunity opp = [SELECT Id, Name, AccountId FROM Opportunity WHERE Id = :oli.OpportunityId LIMIT 1];
                        associatedEventInv.Available__c = FALSE;
                        associatedEventInv.Associated_Opportunity__c = oli.OpportunityId;
                        associatedEventInv.Associated_Account__c = opp.AccountId;
                        associatedEventInv.Associated_Product_Code__c = oli.ProductCode;
                        associatedEventInv.Associated_Product_Description__c = oli.Description;
                        associatedEventInv.Associated_Product_Discount__c = oli.Discount;
                        associatedEventInv.Associated_Product_List_Price__c = oli.ListPrice;
                        associatedEventInv.Associated_Product_Sales_Price__c = oli.UnitPrice;
                        associatedEventInv.Associated_Product_Total_Price__c = oli.TotalPrice;
                        eventInvToUpdate.add(associatedEventInv);
                    }
                    
                    //If the Event Inventory is ASSOCIATED to the Product, The Event Inventory is UNAVAILABLE, Swap is TRUE
                    //Mark it available, Remove the Opportunity Id from the Event Inventory
                    
                    if(oli.UG_Event_Inventory__c != NULL && associatedEventInv.Available__c == FALSE && oli.Swap_for_Credit__c == TRUE)
                    {
                        //Update Associated Event Inventory
                        associatedEventInv.Available__c = TRUE;
                        associatedEventInv.Associated_Opportunity__c = NULL;
                        associatedEventInv.Associated_Account__c = NULL;
                        associatedEventInv.Associated_Product_Code__c = NULL;
                        associatedEventInv.Associated_Product_Description__c = NULL;
                        associatedEventInv.Associated_Product_Discount__c = NULL;
                        associatedEventInv.Associated_Product_List_Price__c = NULL;
                        associatedEventInv.Associated_Product_Sales_Price__c = NULL;
                        associatedEventInv.Associated_Product_Total_Price__c = NULL;
                        eventInvToUpdate.add(associatedEventInv);
                        
                        //Create and Insert SWAP CREDIT OpportunityLineItem
                        OpportunityLineItem olicred = new OpportunityLineItem(Product2Id = pswap.Id, PricebookEntryId = pbeswap.Id, OpportunityId = oli.OpportunityId, Quantity = oli.Quantity, Discount = oli.Discount, TotalPrice = oli.TotalPrice, Previous_Product_SC__c = oli.Product2Id, Previous_Product_Code_SC__c = oli.ProductCode);
                        insert olicred;
                        
                        //Query to find Id of Opportuinty Product and Delete
                        for(OpportunityLineItem oli2del: Trigger.old)
                        {
                        oli2del = [Select Id, Swap_for_Credit__c from OpportunityLineItem WHERE id = :oli.Id];
                        delete oli2del;
                        }
                    }
                }//if
            }//for
            
            update eventInvToUpdate;
            
        }
    }
    

//If an OpportunityLineItem is deleted, this will remove the associated Event Inventory Item and clear the OLI fields on the EII   
    if(Trigger.IsBefore){
        if(Trigger.IsDelete){
            Set<Id> UGEventInventoryIds = new Set<Id>();
            for (OpportunityLineItem oli: Trigger.old){
            
                UGEventInventoryIds.add(oli.UG_Event_Inventory__c);
            }
            
            Map<Id, UG_Event_Inventory__c> eventInvMap = new Map<Id, UG_Event_Inventory__c>
            ([SELECT Id, Available__c FROM UG_Event_Inventory__c WHERE Id IN :UGEventInventoryIds]);
            
            List<UG_Event_Inventory__c> eventInvToUpdate = new List<UG_Event_Inventory__c>();
            UG_Event_Inventory__c associatedEventInv;
                    
            for (OpportunityLineItem oli: Trigger.old){
                
                if(eventInvMap.containsKey(oli.UG_Event_Inventory__c)){
                    associatedEventInv = eventInvMap.get(oli.UG_Event_Inventory__c);
                    if(oli.UG_Event_Inventory__c != NULL && associatedEventInv.Available__c == FALSE)
                    {
                        associatedEventInv.Available__c = TRUE;
                        associatedEventInv.Associated_Opportunity__c = NULL;
                        associatedEventInv.Associated_Account__c = NULL;
                        associatedEventInv.Associated_Product_Code__c = NULL;
                        associatedEventInv.Associated_Product_Description__c = NULL;
                        associatedEventInv.Associated_Product_Discount__c = NULL;
                        associatedEventInv.Associated_Product_List_Price__c = NULL;
                        associatedEventInv.Associated_Product_Sales_Price__c = NULL;
                        associatedEventInv.Associated_Product_Total_Price__c = NULL;
                        eventInvToUpdate.add(associatedEventInv);
                    }
                    
                }//if
            }//for
            
            update eventInvToUpdate;
        }
    
    }
}
Not sure if will help, but this test passed and I'm checking for null values on the previously related Event Inventory Item:
 
@istest
public class testOpptyLineItemRemoveUGEI{
@istest (seeAllData=true)
public static void runTestOpptyLineItemRemoveUGEI(){

//Define Account Fields
String accountName = 'Innovatis Test';
    
//Define UG Event Fields
String ugEventName = 'Test Event 1';
    
//Define UGEvent Inventory1 Fields
String ugEventInventoryName1 = 'Test Event Inventory 1';
String BoothID1 = '1234';
String Sponsorship1 = 'Gold';
String UGEventYear1 = '2017';

//Define Opportunity Fields
String OpportunityName = 'Test Opportunity';
Date OpportunityCloseDate = Date.newInstance(2017, 12, 31);
String OpportunityStage = 'Proposal';

//Define Pricebook Fields
String pbName = 'Test Pricebook';
Boolean Activepb = TRUE;

//Define Product1 Fields
String ProductName1 = 'Test Product 1';
Boolean Active1 = TRUE;
String ProductCode1 = 'tp1';

//Create Account
Account a = new Account(Name = accountName);
insert a;

//Query for Account
Account aNew = [SELECT Id, Name FROM Account WHERE Id = :a.Id LIMIT 1];

//Create Product 1
Product2 p1 = new Product2(Name = ProductName1, IsActive = Active1, ProductCode = ProductCode1);
insert p1;

//Query for Product to get Product Ids
Product2 p1New = [SELECT Id, Name FROM Product2 WHERE Id = :p1.Id LIMIT 1];

//Create Pricebook Entry
PricebookEntry pbe1 = new PricebookEntry(UnitPrice = 1000, UseStandardPrice = FALSE, IsActive = TRUE, Pricebook2Id = Test.getStandardPricebookId(), Product2Id = p1New.Id );
insert pbe1;

//Query Price Book Entry to get Ids
PricebookEntry pbeNew1 = [SELECT Id, Name FROM PricebookEntry WHERE Id = :pbe1.Id];

//Create Event
UG_Event__c uge = new UG_Event__c (Name = ugEventName);
insert uge;

//Query Event to get Id
UG_Event__c ugeNew = [SELECT Id, Name FROM UG_Event__c WHERE Id = :uge.Id LIMIT 1];

//Create Event Inventories
UG_Event_Inventory__c ugei1 = new UG_Event_Inventory__c (UG_Event__c = uge.Id, Name = ugEventInventoryName1, Booth_ID__c = BoothID1, Sponsorship__c = Sponsorship1, UG_Event_Year__c = UGEventYear1);
insert ugei1;

//Query Event Inventories to get Ids
UG_Event_Inventory__c ugei1New = [SELECT Id, Name, Available__c FROM UG_Event_Inventory__c WHERE Name = 'Test Event 1 - Gold - 1234' LIMIT 1];

//Create Opportunity
Opportunity opp = new Opportunity (AccountId = aNew.Id, Name = OpportunityName, CloseDate = OpportunityCloseDate, StageName = OpportunityStage, Pricebook2Id = Test.getStandardPricebookId());
insert opp;

//Query Opportunity to get Id
Opportunity oppNew = [SELECT Id, Name FROM Opportunity WHERE Id = :opp.Id LIMIT 1];

//Add Products to Opportunity and Link to Event

OpportunityLineItem opi1 = new OpportunityLineItem(Product2Id = p1New.Id, Swap_for_Credit__c = FALSE, PricebookEntryId = pbeNew1.Id, OpportunityId = oppNew.Id, Quantity = 1, TotalPrice = 1000, UG_Event_Inventory__c = ugei1New.Id);
insert opi1;

//Mark opi1 UG Event Inventory as blank for testing the Clearing of the Product fields on the UGEI

opi1.UG_Event_Inventory__c = NULL;
update opi1;


//Query Event Inventory and verify it's now active and the product fields are blank
UG_Event_Inventory__c ugei1Check = [SELECT Id, Name, Available__c, Associated_Account__c, Associated_Opportunity__c, Associated_Product_Code__c, Associated_Product_Description__c, Associated_Product_Discount__c, Associated_Product_List_Price__c, Associated_Product_Sales_Price__c, Associated_Product_Total_Price__c FROM UG_Event_Inventory__c WHERE Id = :ugei1New.Id LIMIT 1];
System.assertEquals(TRUE, ugei1Check.Available__c);
System.assertEquals(NULL, ugei1Check.Associated_Account__c);
System.assertEquals(NULL, ugei1Check.Associated_Opportunity__c);
System.assertEquals(NULL, ugei1Check.Associated_Product_Code__c);

}
}


 
I'm working on a test for my batch process.  The batch works fine, however, I'm getting an error message in my test class.  Can anyone help?

Here is the batch I'm executing:
 
/**
This batch process will be triggered when a Campaign is deactivated and will stamp the Campaign with the dateTime value.
This batch will kick off two processes that also update Leads and CampaignMembers with the appropriate values.

*/

global class batchDeactivateCampaignCM implements Database.Batchable<sObject>,Database.Stateful{  
   
  
   global final DateTime nowStamp;
   //global final Integer nowStamp;
   global final Integer currentNowDateTime;  
   global List<Campaign> recordsToUpdate;
   
   
   global batchDeactivateCampaignCM(Integer nowDateTime)  
   {  
     currentNowDateTime = nowDateTime;  
     nowStamp = datetime.now();  
     recordsToUpdate = new List<Campaign>();  
   }  
   global Database.QueryLocator start(Database.BatchableContext BC)  
   {  
    return Database.getQueryLocator('Select id, Name, IsActive, Deactivate_Date__c from Campaign WHERE IsActive = FALSE AND Deactivate_Date__c = NULL');
    //Patrick, add this Where clause back in WHERE IsActive = FALSE AND Deactivate_Date__c = NULL
   }  
   global void execute(Database.BatchableContext BC, List<Campaign> scope)  
   {  
    for(Campaign c: scope)  
    {  if(c.IsActive == False && c.Deactivate_Date__c ==NULL){
     c.Deactivate_Date__c = nowStamp;  
    }
    }
    recordsToUpdate.addAll(scope);   
    update scope;  
   }  
    global void finish(Database.BatchableContext BC)
    {
	// Get the ID of the AsyncApexJob representing this batch job
	// from Database.BatchableContext.
	// Query the AsyncApexJob object to retrieve the current job's information.
	AsyncApexJob a = [SELECT Id, 
							Status, 
							NumberOfErrors, 
							JobItemsProcessed,
							TotalJobItems, 
							CreatedBy.Email
							FROM AsyncApexJob 
							WHERE Id = :BC.getJobId()];
	// Send an email to the Apex job's submitter notifying of job completion.
	Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
	String[] toAddresses = new String[] {a.CreatedBy.Email};
	mail.setToAddresses(toAddresses);
	mail.setSubject('Batch Process to Deactivate Campaigns ' + a.Status);
	mail.setPlainTextBody
	('The batch Apex job batchDeactivateCampaignCM processed ' + a.TotalJobItems +
	' batches with '+ a.NumberOfErrors + ' failures.');
	Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
	
System.debug('DateTimeStamped : '+ nowStamp);
System.ScheduleBatch(new batchDeactivateCampaignMembers(recordsToUpdate),'Batch to Update CampaignMembers :'+String.valueOf(Datetime.now()),1,50);  
System.ScheduleBatch(new batchDeactivateLeads(recordsToUpdate),'Batch to Update Leads :'+String.valueOf(Datetime.now()),2,50);   
	
	}
}

My test class is below. 

I'm getting an error on line 18, col 1 stating ( campList.add((Campaign)QIT.next()); ).  The error reads: "System.NoSuchElementException: Iterator has no more elements
Class.Database.QueryLocatorIterator.next: line 52, column 1
Class.batchDeactivateCMLeadTest.testBatch: line 18, column 1"
 
@IsTest  
 class batchDeactivateCMLeadTest  
 {  
 static testMethod void testBatch()  
 {  
  Campaign c = new Campaign(Name='Test Batch Campaign');  
  insert c;  
  Lead l = new Lead(firstname ='Testbatchfirst', lastname = 'Testbatchlast', company = 'Testbatchcompany', National_Provider_Number_NPN__c = '12354868541');  
  insert l;
  CampaignMember cm = new CampaignMember(CampaignId = c.id, LeadId = l.id);
  insert cm;
  Database.BatchableContext BC;  
  batchDeactivateCampaignCM bdc = new batchDeactivateCampaignCM(50);  
  bdc.start(BC);  
  Database.QueryLocator QL = bdc.Start(BC);  
  List<Campaign> campList = new List<Campaign>();  
  Database.QueryLocatorIterator QIT = QL.iterator();  
  campList.add((Campaign)QIT.next());  
  bdc.execute(BC,campList);  
  bdc.finish(BC);  
//   System.assertEquals([Select 
//                         id,
//                         Name
//                         from Campaign
//                         where Name = 'Test Batch Campaign']);  
  Database.BatchableContext BC_new;  
  batchDeactivateCampaignMembers bdcm = new batchDeactivateCampaignMembers([Select Id from Campaign]);  
  bdcm.start(BC_new);  
  Database.QueryLocator QL_new = bdcm.Start(BC_new);  
  List<CampaignMember> campaignMem = new List<CampaignMember>();  
  Database.QueryLocatorIterator QIT_new = QL_new.iterator();  
  campaignMem.add((CampaignMember)QIT_new.next());  
  bdcm.execute(BC_new,campaignMem);  
  bdcm.finish(BC_new);  

  Database.BatchableContext BC_new2;  
  batchDeactivateLeads bdl = new batchDeactivateLeads([Select Id from Campaign]);  
  bdl.start(BC_new2);  
  Database.QueryLocator QL_new2 = bdl.Start(BC_new);  
  List<Lead> campaignLead = new List<Lead>();  
  Database.QueryLocatorIterator QIT_new2 = QL_new2.iterator();  
  campaignLead.add((Lead)QIT_new.next());  
  bdl.execute(BC_new,campaignLead);  
  bdl.finish(BC_new);

 }  
 }

 
I have a trigger on Campaigns that is doing two things.
  1. When the Campaign IsActive is flipped to FALSE, I am updating related Campaign Members
  2. When the Campagin IsActive is flipped to FALSE, I am updating related Leads (Leads are related directly via a custom field called Current_Campaign_ID__c).
When the Campaign is deactivated, my Leads update no problem.  However, nothing happens to my Campaign Members.  If I remove the entire Leads update section, my Campaign Members work just fine.  Can I not do two different updates in one trigger?
 
trigger deactivateCampaignMember on Campaign (after update) {


//HANDLE UPDATING CAMPAIGN MEMBERS RELATED TO CAMPAIGN
    Set<ID> campids = new Set<ID>();
    for(Campaign camp : Trigger.new){
            campIds.add(camp.Id);
    }

    List<Campaign> updatedCampaigns = [SELECT Id, IsActive, (Select Id, Campaign_IsActive__c from CampaignMembers)  FROM Campaign WHERE Id in :campids];
    List<CampaignMember> campMemsToUpdate = new List<CampaignMember>();

    for (Campaign camp : updatedCampaigns){

        for(CampaignMember cm : camp.CampaignMembers){
            if(camp.IsActive == False){
            cm.Campaign_IsActive__c = False;
                if(cm.Campaign_Lead_Status__c == 'In Campaign'){
                    cm.Campaign_Lead_Status__c ='Resting';
                    campMemsToUpdate.add(cm);
                    
                }
            }
        }
    }
    
    
//HANDLE UPDATING LEADS RELATED TO CAMPAIGN    
        Set<ID> campids2 = new Set<ID>();
        for(Campaign camp2 : Trigger.new){
                campIds2.add(camp2.Id);
        }   
        List<Campaign> updatedCampaigns2 = [SELECT Id, IsActive, (Select Id, Current_Campaign__c, Current_Campaign_ID__c, Status from Leads__r)  FROM Campaign WHERE Id in :campids2];
        List<Lead> campLeadsToUpdate = new List<Lead>();
    
        for(Campaign camp2 : updatedCampaigns2){
        
            for(Lead ld : camp2.Leads__r){
                if(camp2.IsActive == False){
                    if(ld.Status == 'In Campaign'){
                        ld.Status = 'Resting';
                        ld.Current_Campaign__c = '';
                        ld.Current_Campaign_ID__c = NULL;
                        campLeadsToUpdate.add(ld);
                    }
                }    
            }
        }
    update campMemsToUpdate;
    update campLeadsToUpdate;
 }

Any help would be most appreciated.  Thanks so much. 
I have an interesting trigger on Campaign Member that needs to check a value on the associated Lead and associated Campaign and if both are TRUE, it should fire and update a few fields.  The challenge I'm having is that I can't figure out how to get both the Campaign and Lead variables inside of one for loop, without creating a loop inside of a loop, which will inevitably give me a DML insert error.  I create two Sets to get the IDs of the respective Leads and Campaigns, however, when I try to add the Campaign inside of my for loop I'm receiving a "variable doesn't exist" error.  I understand why...it's because I'm creating a "for"' on cml and not cmc (see below).  

I've commented out the code that is giving me issues.  How do I loop through two different objects that are related by a m2m (Campaign Member), relate them to each other, check for values in both Lead and Campaign, then update my Lead?  Any suggestions?
 
trigger deactivateCampaignSetToResting on CampaignMember (before Update) {
if(Trigger.IsBefore){
    if(Trigger.IsUpdate){
        Set<Id> leadIds = new Set<Id>();
        for (CampaignMember cml: Trigger.new){
            leadIds.add(cml.LeadId);
        }
        Set<Id> campaignIds = new Set<Id>();
        for (CampaignMember cmc: Trigger.New){
            campaignIds.add(cmc.CampaignId);
        }
        Map<Id, Lead> LeadMap2 = 
            new Map<Id, Lead>([SELECT Id, Current_Campaign__c, Status 
                              FROM Lead 
                              WHERE Id IN :LeadIDs]);
        List<Lead> leadToUpdate2 = new List<Lead>();
        Lead associatedLead2;
        
        Map<Id, Campaign> CampaignMap = 
            new Map<Id, Campaign>([SELECT Id, IsActive
                                    FROM Campaign
                                    WHERE Id IN :CampaignIds]);
        
        for (CampaignMember cml: Trigger.new){
            if(LeadMap2.containsKey(cml.LeadId)){
                associatedLead2 = LeadMap2.get(cml.LeadId);
                //if(CampaignMap.containsKey(cmc.LeadId)){
                //associatedCampaign = CampaignMap.get(cmc.CampaignId);    
                //    if( Trigger.oldMap.get(cmc.Id).IsActive != Trigger.newMap.get(cmc.Id).IsActive ){
                        if(associatedLead2.Current_Campaign__c!=NULL){
                            if(cml.Campaign_Lead_Status__c !='Pre-Contracting'){
                                if(cml.Campaign_Lead_Status__c !='Contracting'){
                                    if(cml.Campaign_Lead_Status__c !='Disqualified'){
                                        
                                        cml.Campaign_Lead_Status__c = 'Resting';
                                        associatedLead2.Status = 'Resting';
                                        associatedLead2.Current_Campaign__c = '';
                                        leadToUpdate2.add(associatedLead2);
                                    }
                                }
                            }
                            
                        } 
                        
                    //}
                    
                //}
                
            }
            
        }
        update leadToUpdate2;
    }
}
}

 
I have a trigger that works fine up to about 100 Campaign Members on import, but once I hit around 100 I receive the Too Many DML Statements 151 Error.  Anyone have an idea how to fix?
 
trigger setLeadStatusandCurrentCampaign on CampaignMember (after insert) {

    Set<Id> leadIds = new Set<Id>();
    for (CampaignMember cml: Trigger.new){
        leadIds.add(cml.LeadId);
    }
    
    Map<Id, Lead> LeadMap2 = new Map<Id, Lead>([SELECT Id, Current_Campaign__c, Status FROM Lead WHERE Id IN :leadIds]);
        
        //Loop through Campaign Member Leads and look for Current Campaign values
    for (CampaignMember cml: Trigger.new){
        List<Lead> leadToUpdate2=new List<Lead>();
        Lead associatedLead2 = LeadMap2.get(cml.LeadId);
        if(associatedLead2.Current_Campaign__c==NULL)
                {
                    associatedLead2.Status = 'In Campaign';
                    associatedLead2.Current_Campaign__c = cml.Campaign_Name__c;
                    leadToUpdate2.add(associatedLead2);
                }
        
        update leadToUpdate2;
    }

}

 
I have a relatively simple trigger that looks through Campaign Members, finds the associated Lead records and checks to see if the Current_Campaign__c field is null on the Lead.  If that field is not null, I throw an error.  I thought I'd used best practices, however, I'm getting a null pointer exception on this line: if(associatedLead2.Current_Campaign__c!=NULL).  The full error reads: checkCurrentCampaign: execution of BeforeInsert caused by: System.NullPointerException: Attempt to de-reference a null object Trigger.checkCurrentCampaign: line 13, column 1

Can anyone see what I may have done?  I've tried to edit this a dozen or so different ways to ensure I'm not pulling null records, but I'm still receiving an error.  Any assistance would be most appreciated.

My trigger:
 
trigger checkCurrentCampaign on CampaignMember (before insert) {
    Set<Id> leadIds = new Set<Id>();
    for (CampaignMember cml: Trigger.new){    
            leadIds.add(cml.LeadId);
        }
    
        Map<Id, Lead> LeadMap2 = new Map<Id, Lead>([SELECT Id, Current_Campaign__c, Status FROM Lead WHERE Id IN :leadIds]);
    
    //Loop through Campaign Members and get Associated Lead ID
        for (CampaignMember cml: Trigger.new){
            Lead associatedLead2 = LeadMap2.get(cml.LeadId);
            //Still getting a dereference null error    
                if(associatedLead2.Current_Campaign__c!=NULL)
                {
            cml.adderror('Campaign Members can only be in one Campaign at a time.  If you are receiving this error, you are attempting to add one or more Leads to multiple active Campaigns');
                }
        }   
    }

 
I have a pretty straightforward relationship between two custom Salesforce objects: Agent Contract (child) and Hierarchy (parent).  There is a lookup field on the Agent Contract page that looks out to the Hierarchy object.  What I'm trying to do is maintain a list of static values for certain fields in the Hierarchy table so that when a new Agent Contract is created or edited, and a user adds a lookup value in the Hiearchy_Name__c field (only if the field was previously blank) on the Agent Contract,  the trigger will fire and will pull over some field values.

I am using a very similar trigger between Campaigns and Campaign Members and it works fine.  However, this trigger is throwing an Invalid foreign key relationship: Agent_Contract__c.Hierarchy__c.  Can anyone please tell me what I've done incorrectly?
 
trigger agentContractHierarchy on Agent_Contract__c (before update) {
    Set<Id> hierarchyIds = new Set<Id>();
    for (Agent_Contract__c ac: Trigger.new){
        hierarchyIds.add(ac.Hierarchy__c.Id);
    }
    Map<Id, Hierarchy__c> hierarchyMap = new Map<Id, Hierarchy__c>([SELECT Id, SGA__c FROM Hierarchy__c WHERE Id IN :hierarchyIds]);
    for (Agent_Contract__c ac: Trigger.new)
    {Hierarchy__c associatedHierarchy = hierarchyMap.get(ac.hierarchyId);
     if(associatedHierarchy.Id==NULL)
     {
         //Do my thing
     }
    }
}

 
I'm working with a simple before delete trigger and am stumped on one piece.  This trigger checks if a value is present on the Lead and if so, throws an error when trying to delete the Campaign Member.  What I would like to do is check the status of this field, if it is not null, throw the error.  If it is null, update the Lead Status to 'Resting".  The trigger works for the error but doesn't update the Lead Status field.  Any help would be most appreciated.

 
trigger cannotDeleteCampaignMember on CampaignMember (before delete) {
    if(System.Trigger.IsDelete){
        Set<Id> leadIds = new Set<Id>();
        for (CampaignMember cm: Trigger.old){
            leadIds.add(cm.LeadId);
        }
        Map<Id, Lead> leadMap = new Map<Id, Lead>([SELECT Id, Current_Campaign__c, Status FROM Lead WHERE Id IN :leadIds]); 
        for (CampaignMember cm: Trigger.old)
        {Lead associatedLead = leadMap.get(cm.LeadId);
         if(associatedLead.Current_Campaign__c!=null)
         {
             cm.adderror('Only the Marketing Team can delete Campaign Members.  If you are on the Marketing Team and would like to delete this Campaign Member, go to the Lead and remove the value from the "Current Campaign" field first.');
         }
         if(associatedLead.Current_Campaign__c==null)
         {
             associatedLead.Status = 'Resting';
         }
         
        }   
    }   
}

 
I'm writing a trigger to default the Account of a Contact each time a Contact is created.  The trigger is relatively simple.  I'm receiving an error that reads: Variable does not exist: Id.  Can anyone point me in the direction of what I'm doing wrong?
 
trigger setDefaultAcc on Contact (before insert){
    List<Contact> lstCon = new List<Contact>();
    // Find out and prepare list of Contacts
    for(Contact var : Trigger.new){
        if(var.AccountId == null){
            lstCon.add(var);
        }
    }
    // Fetch the Default account
    if(lstCon.size()>0){
        List<Account> acc = new List<Account>();
        acc = [SELECT Id, Name FROM Account WHERE Name = 'Strategic Market Advisors' LIMIT 1];
        if(acc != null){
            for(Contact var : lstCon){
                // Assign the id of the default account to the selected contacts
                var.AccountId = acc.Id;
            }
        }
    }
}

 
I have a very simple query that ls looking querying Accounts to find one particular Account, then assign that Account's ID to the Account field on my Contact record.  I continue to get the "System.QueryException: List has no rows for assignment to SObject" error, but when I run the query using Query Editor, it returns the appropriate record.  Can anyone please tell me what I'm doing wrong?
 
trigger assignAccounttoContact on Contact (before insert, before update) {
    
    Account a = [
        SELECT ID, Name 
        FROM Account 
        WHERE Name = 'TestAccount'
    ];
    
    for(Contact c: Trigger.new){
        
        c.AccountID = a.ID;
    }
    
}

 
I have a trigger to create a Monthly Outreach record that looks to be correct, but I continue to run into a required field error.  Here is an example of my error:

Image of error

I have a master record (Outreach Target) with two identical values (see below) that I'm manually adding to this child record for the purposes of matching.  Those two fields are Location ID and Year Submitted.  My trigger is attempting to add a parent Outreach Target record ID the child Monthly Outreach record by querying the Outreach Target object and searching for a record with matching criteria.  The criteria is unique, so my SOQL query will only find one record.

Here is the master record who's Id I'm attempting to add to my child Monthly Outreach record:

Master Record

Here is my trigger:
 
trigger SetOutreachTarget on Monthly_Outreaches__c (after insert, after update) {
    for (Monthly_Outreaches__c mo : Trigger.new) {
        String moy = mo.Year__c;
        String moa = mo.Location_ID__c;
        List<Outreach_Target__c> ot = [SELECT Id FROM Outreach_Target__c WHERE Outreach_Target_Year__c = :moy AND Location_ID__c = :moa];        
        if(ot.size()>0){
            mo.Outreach_Target__c = ot[0].Id;}
    }
}

I've even tried hard-coding the master record ID into the query to guarantee I'm finding the matching record, but I continue to get the required field error.  Can anyone please help me solve this issue?



 
Everyone, I have the most basic trigger and am getting a silly testing error that I can't shake.  Ironically, when I manually fire this trigger, it works perfectly.  But when I test it, I receive this error: "System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, SetAccountField: execution of BeforeInsert caused by: System.ListException: List index out of bounds: 0  Trigger.SetAccountField: line 6, column 1: []"  

This trigger simply looks at a "location_ID" field on my Monthly Outreach object, which coorelates to a "location_ID" field on my Account object, then associates the Account ID to my Monthly Outreach record.  I continue to get the dreaded List Out of Bounds error.  After much research, it appears that I'm supposed to be checking to see if my account variable is null.  I thought I was doing that by adding:"if(account != null)".  Can anyone tell me what I'm doing wrong?

My trigger:
trigger SetAccountField on Monthly_Outreaches__c (before insert, before update) {
    for (Monthly_Outreaches__c mo : Trigger.new) {
        String accid = mo.Location_ID__c;
        List<Account> account = [SELECT Id FROM Account WHERE Location_ID__c = :accid];
        if(account != null){
            account[0].Id = mo.Account__c;} else {
            }
    }
}

Here is my test class.  Again, very basic:
 
@isTest 
private class AddMonthlyOutreachesTestClass {
    static testMethod void validateMonthlyOutreaches() {
        Monthly_Outreaches__c m = new Monthly_Outreaches__c(
            LOCATION_ID__C='001', 
            Submitter_Email__c='rick.allen@xxx.com',
            MEDIA_INTERVIEWS_ARTICLES__C=100         
        );
        // Insert Monthly Outreaches
        insert m;
        
        ApexPages.StandardController sc = new ApexPages.standardController(m);
        MonthlyOutreachesRedirect e = new MonthlyOutreachesRedirect(sc);
        String nextPage = e.saveAndCongrat().getURL();
        
        // Verify that the Congratulations page displays
        System.assertEquals('/apex/congratulations', nextPage);
    }
}