0

I have built a trigger to update Opportunity Line Items discount based on quantity before insert/update. There are custom fields to define the quantity tiers and discount to be assigned.

The code is returning values on o.Quantity and o.Discount, but not for the discount and quantity tiers. I suspect this might have something to do with not being able to access them with dot notation in the way I have done. How should this be done?

trigger opportunityLineItemTrigger on OpportunityLineItem (Before Insert, before update) {

    if(Trigger.isExecuting && Trigger.isInsert && Trigger.isBefore){
        for (OpportunityLineItem oppItems: Trigger.New){
        ProductLineItemClass.updateLineItemDiscount(Trigger.new);
        }
    }  

    if(Trigger.isExecuting && Trigger.isUpdate && Trigger.isBefore){
        for (OpportunityLineItem oppItems: Trigger.New){
        ProductLineItemClass.updateLineItemDiscount(Trigger.new);
        }
    } 
}




public class ProductLineItemClass {
    public static void updateLineItemDiscount(List<OpportunityLineItem> oppItems ){

        for(OpportunityLineItem o: oppItems){

            If ((o.Quantity >= o.PriceBookEntry.Tier__c) && (o.Quantity<= o.PriceBookEntry.Tier_1_Upper_Quantity_Limit__c)){
                o.Discount = o.PriceBookEntry.Tier_1_Discount__c;
            } else If ((o.Quantity >= o.PriceBookEntry.Tier_2_Lower_Quantity_Limit__c) && (o.Quantity <= o.PriceBookEntry.Tier_2_Upper_Quantity_Limit__c)){
                o.Discount = o.PriceBookEntry.Tier_2_Discount__c;
            } else If ((o.Quantity >= o.PriceBookEntry.Tier_3_Lower_Quantity_Limit__c) && (o.Quantity <= o.PriceBookEntry.Tier_3_Upper_Quantity_Limit__c)){
                o.Discount = o.PriceBookEntry.Tier_3_Discount__c;
            }

        }
    }
}   
6
  • Parent object fields are not accessible in the trigger collections. You have to explicitely query those fields or create formula fields to populated the values and then use the formula fields. Commented Jan 11, 2020 at 10:24
  • @ShaileshPatil Thanks. Thats what i suspected. do you know how could I query these fields and map them so that the conditionals so that they comparing the correct fields to the correct OpportunityLineItems based on the product?
    – Jordan
    Commented Jan 11, 2020 at 11:10
  • You can do this in two ways.1) Create formula fields and use them directly 2) Query them. In the for loop you are iterating over oppItems list, you have to do something like: for(OLI o : [Select PricebookEntry.customfield, Priicebookentry.Cf2 From OLI Where ID in OppItems] and then use them the way you were using earlier. Commented Jan 11, 2020 at 11:16
  • The formula field (option 1) is a simple solution. But would rather not create more fields if I do not need too. Option 2 is preferred but I do not think it will work on to use WHERE Id IN :oppItems. Since the trigger is before insert the Id on oppItems has not been assigned yet.
    – Jordan
    Commented Jan 11, 2020 at 12:19
  • I didnt notice its a before insert. My bad. See if this helps: salesforce.stackexchange.com/questions/173607/… Commented Jan 11, 2020 at 12:27

1 Answer 1

0

Managed to accomplish this by doing the following:

trigger opportunityLineItemTrigger on OpportunityLineItem (Before Insert, before update) {

    if(Trigger.isExecuting && Trigger.isInsert && Trigger.isBefore){
        for (OpportunityLineItem oppItems: Trigger.New){
        ProductLineItemClass.updateLineItemDiscount(Trigger.new);
        }
    }  

    if(Trigger.isExecuting && Trigger.isUpdate && Trigger.isBefore){
        for (OpportunityLineItem oppItems: Trigger.New){
        ProductLineItemClass.updateLineItemDiscount(Trigger.new);
        }
    }   
}

public class ProductLineItemClass {
    public static void updateLineItemDiscount(List<OpportunityLineItem> oppItems ){

        Set<Id> pbeIds = new Set<Id>();
        for (OpportunityLineItem item : oppItems) pbeIds.add(item.PricebookEntryId);
        Map<Id, PricebookEntry> entries = new Map<Id, PricebookEntry>([
            SELECT Tier__c, Tier_1_Upper_Quantity_Limit__c, Tier_1_Discount__c, 
                   Tier_2_Lower_Quantity_Limit__c, Tier_2_Upper_Quantity_Limit__c, 
                   Tier_2_Discount__c, Tier_3_Lower_Quantity_Limit__c, Tier_3_Upper_Quantity_Limit__c, 
                   Tier_3_Discount__c 
            FROM PricebookEntry 
            WHERE Id IN :pbeIds
        ]);

        for (OpportunityLineItem item : oppItems)
        {
        PricebookEntry PBentry = entries.get(item.PricebookEntryId);

            If ((item.Quantity >= PBentry.Tier__c) && (item.Quantity<= PBentry.Tier_1_Upper_Quantity_Limit__c)){
                item.Discount = PBentry.Tier_1_Discount__c;
            } else If ((item.Quantity >= PBentry.Tier_2_Lower_Quantity_Limit__c) && (item.Quantity <= PBentry.Tier_2_Upper_Quantity_Limit__c)){
                item.Discount = PBentry.Tier_2_Discount__c;
            } else If ((item.Quantity >= PBentry.Tier_3_Lower_Quantity_Limit__c) && (item.Quantity <= PBentry.Tier_3_Upper_Quantity_Limit__c)){
                item.Discount = PBentry.Tier_3_Discount__c;
            } 
        } 
    }
}
1
  • As opposed to just showing the working code, it'd be helpful to understand what/why you changed it to help others looking at this question. Commented Jan 11, 2020 at 20:35

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .