- Patrick G. Brown
- NEWBIE
- 65 Points
- Member since 2015
- Patrick Brown
-
ChatterFeed
-
0Best Answers
-
0Likes Received
-
0Likes Given
-
17Questions
-
17Replies
Null Pointer Exception - Only on Bulk Insert
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?
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; } } } } } }
- Patrick G. Brown
- December 20, 2017
- Like
- 0
Stumped - Trigger not executing on basic criteria
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.
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); } }
- Patrick G. Brown
- December 12, 2017
- Like
- 0
Need Help with System.NoSuchElementException: Iterator has no more elements Error Message
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:
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"
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); } }
- Patrick G. Brown
- November 20, 2017
- Like
- 0
Interesting Duplicate ID In List Scenario - Need Help
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?
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
- Patrick G. Brown
- October 23, 2017
- Like
- 0
Trigger with two updates not working
I have a trigger on Campaigns that is doing two things.
Any help would be most appreciated. Thanks so much.
- When the Campaign IsActive is flipped to FALSE, I am updating related Campaign Members
- 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).
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.
- Patrick G. Brown
- October 14, 2017
- Like
- 0
Update Campaign Member from Campaign
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.
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); } } } } }
- Patrick G. Brown
- October 13, 2017
- Like
- 0
Two trigger variables inside one for loop
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?
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; } } }
- Patrick G. Brown
- October 11, 2017
- Like
- 0
Basic After Insert trigger not working
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:
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?
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?
- Patrick G. Brown
- October 09, 2017
- Like
- 0
Too Many DML Statements 151 Campaign Member Import
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; } }
- Patrick G. Brown
- October 08, 2017
- Like
- 0
Need a little assistance with Null Pointer Exception
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:
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'); } } }
- Patrick G. Brown
- October 08, 2017
- Like
- 0
Help with Test Class to test Trigger Validation on Delete
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:
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:
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?
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?
- Patrick G. Brown
- October 04, 2017
- Like
- 0
Receiving an Invalid Foreign Key Error with Custom Object
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?
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 } } }
- Patrick G. Brown
- August 28, 2017
- Like
- 0
Need help with simple before trigger
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'; } } } }
- Patrick G. Brown
- August 28, 2017
- Like
- 0
Help with error "Variable does not exist: Id" when trying to default an Account on Contact
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; } } } }
- Patrick G. Brown
- July 17, 2017
- Like
- 0
Need assistance with System.QueryException: List has no rows for assignment to SObject
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; } }
- Patrick G. Brown
- July 23, 2016
- Like
- 0
Trigger to add master record id based on values from detail record 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:
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:
Here is my trigger:
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?
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:
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?
- Patrick G. Brown
- April 02, 2016
- Like
- 0
Simple trigger getting List index out of bounds error
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:
Here is my test class. Again, very basic:
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); } }
- Patrick G. Brown
- February 09, 2016
- Like
- 0
Stumped - Trigger not executing on basic criteria
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.
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); } }
- Patrick G. Brown
- December 12, 2017
- Like
- 0
Need Help with System.NoSuchElementException: Iterator has no more elements Error Message
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:
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"
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); } }
- Patrick G. Brown
- November 20, 2017
- Like
- 0
Trigger with two updates not working
I have a trigger on Campaigns that is doing two things.
Any help would be most appreciated. Thanks so much.
- When the Campaign IsActive is flipped to FALSE, I am updating related Campaign Members
- 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).
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.
- Patrick G. Brown
- October 14, 2017
- Like
- 0
Two trigger variables inside one for loop
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?
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; } } }
- Patrick G. Brown
- October 11, 2017
- Like
- 0
Too Many DML Statements 151 Campaign Member Import
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; } }
- Patrick G. Brown
- October 08, 2017
- Like
- 0
Need a little assistance with Null Pointer Exception
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:
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'); } } }
- Patrick G. Brown
- October 08, 2017
- Like
- 0
Receiving an Invalid Foreign Key Error with Custom Object
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?
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 } } }
- Patrick G. Brown
- August 28, 2017
- Like
- 0
Need help with simple before trigger
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'; } } } }
- Patrick G. Brown
- August 28, 2017
- Like
- 0
Help with error "Variable does not exist: Id" when trying to default an Account on Contact
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; } } } }
- Patrick G. Brown
- July 17, 2017
- Like
- 0
Need assistance with System.QueryException: List has no rows for assignment to SObject
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; } }
- Patrick G. Brown
- July 23, 2016
- Like
- 0
Trigger to add master record id based on values from detail record 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:
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:
Here is my trigger:
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?
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:
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?
- Patrick G. Brown
- April 02, 2016
- Like
- 0
Simple trigger getting List index out of bounds error
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:
Here is my test class. Again, very basic:
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); } }
- Patrick G. Brown
- February 09, 2016
- Like
- 0