You need to sign in to do that
Don't have an account?
Patrick G. Brown
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,
I suspect the if block below may not be executing because of the conditions not being satisfied. Have you tried printing the values of the following fields before line # 34 from your trigger code using Debug Logs? If not, please do so which should give you a perspective about the reason of the if block not executing.
- oli.UG_Event_Inventory__c
- associatedEventInv.Available__c
- li.Swap_for_Credit__c == FALSE
The other thing I would recommend checking the logical conditions i.e. the AND is appropriate. Hope that helps.Is this issue resolved for you?