Update of Opportunity Line Items

edited May 24, 2018 in Questions
When updating Opportunity Line items recaclulation of the total and unit price is done if only the quantity is changed. However if updating is done in a table component and the unitprice is displayed on the same row this is not very logical. I think this is because SKUID only updates changed values. If both unitprice and quantityt is changed the update works as expected but it only quantity is changed this means that unitprice is recalculated based on total price. There should be an option to force SKUID to always send both Quantity and Unitprice in the update. Is there a way to do this?

Comments

  • Zach McElrathZach McElrath Principal Software Engineer Chattanooga, TN 💎💎💎
    edited May 24, 2018
    UPDATE as of 9/1/2015 and the Banzai release of Skuid: This approach is now discouraged in favor of a Model Action / Ui-only field approach described in the "Official" answer to this question.

    Yes, there is a way to do this: all it takes is a custom field renderer on the Quantity field, which forces a simultaneous update of the UnitPrice/SalesPrice field whenever Quantity is updated. So suppose you have a table on Opportunity Products looking something like this: image Go into the page's builder, to the table component, and click on the "Quantity" field: image Set the "Field Renderer" to "Custom" and the "Render Snippet" to "quantityRenderer": image This makes it so that the Quantity field will be rendered by a custom Snippet (named JavaScript function). To define this Snippet, go to the Resources tab, and create a new JavaScript Resource of type "Inline (Snippet)": image image Enter the following for the body of the snippet: image Here's a Gist containing the code for the snippet as well.
  • edited February 16, 2015
    exellent, thanks
  • edited February 20, 2015
    Hi Zach, this is extremely helpful, thank you!

    I'm working on a very similar use case on a custom object, only differences are that my table is already in edit mode, and the field I am entering in is a reference field. 

    The destination however is also unit price, and is meant to be updated with a value brought in via the reference field. 

    Input field (reference, autocomplete): Product_For_Sale__c
    Source value from field: Product_For_Sale__r.Price__c
    Destination to update: Unit_Price__c

    The delay input callback seems to be "too quick" to wait for the autocomplete value in the input field to "stick", so 'undefined' gets passed on to Unit_Price__c.

    I assured the Product_For_Sale__r.Price__c is brought in on the model and that it has data in it.

    Here is my code:
    var field = arguments[0],    value = arguments[1],
        row = field.row,
    $ = skuid.$;
    skuid.ui.fieldRenderers[field.metadata.displaytype].edit( field, value);
    skuid.utils.delayInputCallback(
            field.element.find('input'),
            function(newValue) {
                field.model.updateRow(row, {Unit_Price__c: field.Price__c});
                                        }
                );
    How would I need to modify this to run after the autocomplete on the reference field is selected by the user?

    Thank you in advance!

    Regards, 

    Robin
  • Zach McElrathZach McElrath Principal Software Engineer Chattanooga, TN 💎💎💎
    edited December 21, 2016
    Robin, I think the error is actually in field.Price__c, change it to be row.Product_For_Sale__r.Price__c like this:

    field.model.updateRow(row, {Unit_Price__c: row.Product_For_Sale__r.Price__c});
  • edited February 20, 2015
    Zach, thank you for the quick response!

    I kept fiddling with it and yes, it is updating now, so that's awesome. Can get it to work both using the syntax from your sample code as well as what you suggested just now! 

    However: I am starting the row blank, so there is no value in the Product_For_Sale__c input field. First time I pick it with autocomplete, the value in Unit Price does NOT update. 

    If I change the value in the input field a second time, the value updates correctly.

    Anything I need to do to modify this if I'm starting with the field blank?

    Thank you!!!
  • Zach McElrathZach McElrath Principal Software Engineer Chattanooga, TN 💎💎💎
    edited December 21, 2016
    That's strange, I would think that it should work, can you do a console.log to check what the price is?

    var newPrice = row.Product_For_Sale__r.Price__c;
    console.log('new price: ' + newPrice);
    field.model.updateRow(row, {Unit_Price__c: newPrice});

    Also just noticed this, but it is now highly recommended for Custom Field Renderers that you add an initiatorId parameter when making updateRow() calls, like this:

    field.model.updateRow(row, {Unit_Price__c: newPrice}, {initiatorId: field._GUID});
  • edited July 1, 2015
    Hi Zach, 

    I have tried your solution, however the unit price is still being changed. I'm trying to make it so that the total price is updated when the quantity is changed. Below is a link to the XML. Let me know what I should do. 

    Thanks in advance

    https://gist.github.com/djjordan87/460949a266e2a590a38e
  • Zach McElrathZach McElrath Principal Software Engineer Chattanooga, TN 💎💎💎
    edited March 2, 2017
    As of Skuid's Banzai release (7.0+), there is a highly recommended alternative approach that does not require any JavaScript / Custom Field Renderers. 

    In a nutshell, the approach is to add Model Actions. The first listens for changes to the Quantity field, and then runs a series of actions which have the effect of forcing an update to the UnitPrice field as well, even if it was not actually changed. The second listens for changes to a "TotalPriceFormula" Ui-Only Field, and when this is changed, the actual TotalPrice field is updated. All this rigamarole is necessary because if you only tell Salesforce to changes about one of these fields, then Salesforce tries to be "smart" and adjusts the other field values based on which field you changed. The only way to be absolutely sure that Salesforce will not "mess things up" is to tell it exactly which values to set for every field. 

    To see exactly how this is done, I recommend examining the latest version of our OpportunityDetail sample page XML from the Skuid Sample Pages repository on Github.

    This approach also has the benefit of being extensible, allowing you to incorporate additional fields into the "SalesPriceFormula" or "TotalPriceFormula" fields to accommodate more complex calculations. What's crucial to understand is that at the end of the day, to use the OpportunityLineItem you have only 4 fields to work with: Quantity, UnitPrice, Discount, TotalPrice. Salesforce has baked-in logic around these fields that you can't change --- TotalPrice = Quantity * UnitPrice * ((100 - Discount) / 100) . You can't really get around Salesforce's hard-coded formula --- all you can do is to adjust what values you pass to each of the component fields.

    For instance, take the issue of pro-rating prices. We deal with this internally at Skuid. A company buys 1000 Skuid licenses in January, but then in June wants to add 500 more. To keep things on an annual schedule, we pro-rate the UnitPrice for these "Adds" Opportunities. However, to track this in OpportunityLineItems, we can't just inject a percentage field into Salesforce's hardcoded formula. What we can do, and what we do at Skuid, is to adjust the UnitPrice field to be a pro-rated percentage of the original UnitPrice based on how many months are remaining until the end of the year. To accomplish this using the framework set forth in the OpportunityDetail sample page given above, we add a Picklist field with values 1-12 to our OpportunityLineItem object, and then we adjust the SalesPriceFormula UI-only Formula Field so that it decreased the UnitPrice by the number of months remaining till annual renewal. 
Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!