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. Jan 11 '20 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
    Jan 11 '20 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. Jan 11 '20 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
    Jan 11 '20 at 12:19
  • I didnt notice its a before insert. My bad. See if this helps: salesforce.stackexchange.com/questions/173607/… Jan 11 '20 at 12:27
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. Jan 11 '20 at 20:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.