I have a context for QuoteLineItems pricing that uses the list price from the current Pricebook and applies a series of factors (defined in custom fields of both Quote and QuoteLineItems) to compose different pricing stages of the item. I have this scenario implemented via WFR + Field Updates, but trying to migrate this to triggers, since I need more control of execution order for later improvements. This is the scenario I'm trying with triggers:

  1. QuoteLineItem has a Formula field Effective_Unit_Price__c, which is a really long formula field;
  2. QuoteLineItem has a Number Field Effective_Unit_Price_2__c which is updated via before update trigger with contents from Effective_Unit_Price__c, so we can use this new one on other formulas ahead in this pricing stages I mentioned. I need this because the previous field was already too long; (this update was being done by field update)
  3. QuoteLineItem has a Formula field Total_Price__c which is a formula field referencing that Effective_Unit_Price_2__c plus some Quote's field (cross-object reference).
  4. QuoteLineItem has another Number field called Total_Price_2__c which is updated via before update trigger:
item.put('Total_Price_2__c', item.get('Total_Price__c'));
  1. Quote has a roll-up summary field which sums up this Total_Price_2__c (that is the reason I make that copy, because there is a restriction of roll-up for cross-object formula fields);

So, basically I want this propagation of values:

QLI.Effective_Unit_Price__c -> Qli.Effective_Unit_Price_2__c -> QLI.Total_Price__c -> QLI.Total_Price_2__c

The order of those before update triggers in QuoteLineItem (it is a single trigger, using methods from a handler class):

  trigger QuoteLineItemTrigger on QuoteLineItem (before insert, before update, after delete) {

  if (trigger.isBefore && trigger.isUpdate) {
      Map<Id, PricebookEntry> entries = new Map<Id, PricebookEntry>([... QUERY ...]);
      List<QuoteLineItem> new_items = trigger.new;

      // Updating some long-formula fields of QuoteLineItems
      QuoteLineItemTriggerHandler.UpdateWkFields(new_items, entries);

      // Copies calculated values from formula fields with cross-object formula to new fields, to be used in roll-up summary fields

However, my desired output is not being achieved. Here is an example:

  1. Before running triggers, Effective_Unit_Price__c is 1000 and all other fields are 0;
  2. First trigger runs (Effective Unit Price fields), populates Effective_Unit_Price_2__c with 1000; Both Total_Price__c and Total_Price_2__c are still 0;
  3. Second trigger runs (Total_Price fields) but since the source value is still 0, target field remains as 0;

What I am doing wrong? Is there some other better solution to get this desired propagation of values? Or shouldn't I be moving to triggers? Any advice is very appreciated.

  • Are there 2 before update triggers for the same object ? If so as per docs(additional considerations) : developer.salesforce.com/docs/atlas.en-us.apexcode.meta/… order of execution isn’t guaranteed when having multiple triggers for the same object due to the same event. For example, if you have two before insert triggers for Case, and a new Case record is inserted that fires the two triggers, the order in which these triggers fire isn’t guaranteed. – Rao Jul 12 '17 at 19:11
  • It is one single trigger, calling a trigger handler class methods in that order, I added some extra code in the original post to make that clearer. – Mauricio Oliveira Jul 12 '17 at 19:17
  • Are you querying the formula field Effective_Unit_Price__c in your before update trigger? the formula field value may not be accessible in your before trigger context. – Rao Jul 12 '17 at 19:28
  • I'm not making any query in any step, I'm just using trigger.new objects. – Mauricio Oliveira Jul 12 '17 at 19:39
  • Im asking you to modify your logic to include the Effective_Unit_Price__c from QuoteLineItems [Select Effective_Unit_Price__c from QuoteLineItems where Id IN:Trigger.new ] and see what comes out – Rao Jul 12 '17 at 20:37

Your Answer

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

Browse other questions tagged or ask your own question.