+ Start a Discussion
Patrick G. BrownPatrick 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.
 
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);

}
}


 
jigarshahjigarshah

Patrick,

I suspect the if block below may not be executing because of the conditions not being satisfied.
if (oli.UG_Event_Inventory__c == NULL && associatedEventInv.Available__c == TRUE && oli.Swap_for_Credit__c == FALSE){

     //Code that does not execute
}
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.
jigarshahjigarshah
Patrick,

Is this issue resolved for you?
Patrick G. BrownPatrick G. Brown
Unfortunately no, Jigarshah.  All of my logic is sound.  The issue, from what I can tell, is that at save, the value of the lookup field has been removed, therefore the system can no longer find the fields to update on the related record.  I created a workaround that I'm not really happy with.  I was able to get my code to work by implementing a checkbox called "remove associated event inventory" and when checked, this trigger works fine and removed the related information as well as the value in the lookup field.  I don't like this solution because I should be able to make this work by simply unrelating the related event inventory item.