This topic contains 4 replies, has 0 voices, and was last updated by bradsimpson 7 years, 11 months ago.

  • Author
    Posts
  • #6125 Score: 0

    bradsimpson
    • Contributions: 0
    • Level 1

    I need some help determing where I should put the nlapiCommitLineItem in my pricing script. I have a client script that allows my sales reps to markup or markdown their line item pricing utilizing some custom integer fields on the Quote. So far, the only way for them to see what their pricing looks like is to save the quote so if they want to try different markups, they have to save and then re-edit the quote each time they want to change it. I so far have not been able to figure out how to get nlapiCommitLineItem to work properly to reflect the changes in the transaction without having to hit save. Should I put the Commit Line Item api within each If/Else If statement or should it be within the For loop? Code below. Any help is very much appreciated.

    Code:
    function cs_Markup() {
    alert(‘Item Markup Clicked’);
    console.log(‘cs_Markup invoked’);
    for (var x = 1; x < = nlapiGetLineItemCount("item"); x++) { var product = nlapiGetLineItemValue("item", "class", x); var initrate = nlapiGetLineItemValue("item", "costestimaterate", x); var hardware = nlapiGetFieldValue('custbody_hw_pricemod') / 100; var software = nlapiGetFieldValue('custbody_sw_pricemod') / 100; var supmaint = nlapiGetFieldValue('custbody_sm_pricemod') / 100; var services = nlapiGetFieldValue('custbody_sv_pricemod') / 100; var train = nlapiGetFieldValue('custbody_tr_pricemod') / 100; var freight = nlapiGetFieldValue('custbody_fr_pricemod') / 100; nlapiLogExecution('debug', 'Product Class', "Product " + x +"s class is " + product); nlapiLogExecution('debug', 'Init Rate', "Init Rate for item " + x + " is " + initrate); if (product == 8){ var ratecalchw = initrate / (1 - hardware); var ratecalchwp = ratecalchw.toFixed(2); nlapiSetLineItemValue("item", "rate", x, ratecalchwp); var qty = nlapiGetLineItemValue('item', 'quantity', x); var amount = nlapiGetLineItemValue('item', 'rate', x) * qty; nlapiSetLineItemValue('item', 'amount', x, amount); nlapiLogExecution('debug', 'amount', "Hardware item " + x + " total amount is " + amount); nlapiLogExecution('debug', 'ratecalc', 'Item '+ x + "'s ratecalc is " + ratecalchw); nlapiLogExecution('debug', 'Hardware Markup', "Hardware markup value is " + hardware); } else if (product == 9){ ... } else if (product == 10 || product == 12){ ... } else if (product == 15){ ... } else if (product == 17){ ... } else if (product == 5 || product == 11 || product == 15 || product == 18 || product == 19 || product == 20 || product == 21){ ... } else { continue; } } cs_CalcItemGP(); alert('Item Markup Finished'); }
    This is a cached copy. Click here to see the original post.

  • #6126 Score: 0

    david.smith
    • Contributions: 0
    • Level 1

    nlapiCommitLineItem is typically used to add lines. I think you might want to use the recalc client script event.

  • #6127 Score: 0

    bradsimpson
    • Contributions: 0
    • Level 1

    Hi david.smith, I’ve never used that script event. I guess my question is how would invoke a recalc for the whole transaction after the line items have been changed?

  • #6128 Score: 0

    erictgrubaugh
    • Contributions: 0
    • Level 1

    You only need to use nlapiCommitLine when you have also used nlapiSelectLine. It looks like you are using nlapiSetLineItemValue here, so nlapiCommitLine should be unnecessary.

    I also noticed 15 is listed in two of your if-branches; only the first one will ever get executed.

    On another note, I imagine all of your if-else blocks will look very similar. You can probably simplify this code quite a bit doing something like:

    Code:
    // Extract logic for calculating Rate and Amount out into reusable functions
    function calcRate(initialRate, markupFactor) {
    return (initialRate / (1 – markupFactor));
    }

    function calcAmount(quantity, rate) {
    return (quantity * rate);
    }

    // Map the Product Class ID to the correct pricemod field
    var markupByProduct = {
    “5”: “custbody_fr_pricemod”,
    “8”: “custbody_hw_pricemod”,
    “9”: “custbody_sw_pricemod”,
    “10”: “custbody_sm_pricemod”,
    “11”: “custbody_fr_pricemod”,
    “12”: “custbody_sm_pricemod”,
    “15”: “custbody_sv_pricemod”,
    “17”: “custbody_tr_pricemod”,
    “18”: “custbody_fr_pricemod”,
    “19”: “custbody_fr_pricemod”,
    “20”: “custbody_fr_pricemod”,
    “21”: “custbody_fr_pricemod”
    };

    function cs_Markup() {
    for (var x = 1; x <= nlapiGetLineItemCount("item"); x++) {
    var product = nlapiGetLineItemValue("item", "class", x);

    // If no markup field is specified for the Product Class, skip the line
    if (!markupByProduct[product]) {
    continue;
    }

    var qty = nlapiGetLineItemValue('item', 'quantity', x);
    var initrate = nlapiGetLineItemValue("item", "costestimaterate", x);

    // Use the markup map to retrieve the right pricemod value
    var markupFactor = nlapiGetFieldValue(markupByProduct[product]) / 100;
    var lineRate = calcRate(initrate, markupFactor).toFixed(2);

    nlapiSetLineItemValue("item", "rate", x, lineRate);
    nlapiSetLineItemValue("item", "amount", x, calcAmount(qty, lineRate));
    }

    // Move out of function, to click handler
    cs_CalcItemGP();
    }
    Giant if-else or switch structures are almost always avoidable in JS using Objects as maps and a few other patterns.

    I would also recommend moving your call to cs_CalcItemGP out of cs_Markup and into your click handler so that you have two separate, composable functions.


    david.smith replied on 10/05/2016, 08:42 AM: Great code review as always Eric. I suggested recalc because he wants the screen to update for the sales reps to be able to seen new values and calculations. I’m guessing there is something else that might be needed that might be happening after submit.

  • #6129 Score: 0

    bradsimpson
    • Contributions: 0
    • Level 1

    erictgrubaugh You are quite right, each “else if” statement is the same function as the hardware (product == 8) function, just a different input on the markup. I appreciate the advice on simplifying the script. This is one of the first scripts I’ve ever written so it’s wholly inefficient.


    erictgrubaugh replied on 10/05/2016, 08:04 AM: Any time! Helping new devs is my primary focus.

You must be logged in to reply to this topic.