I'm trying to create a client side script that pop...
# suitescript
n
I'm trying to create a client side script that populates a custom column field with a calculated value when one of the other transaction column field is changed. Right now I am using sublistChanged as the entry point and it is looping forever. @User I think I saw you answered a similar question on a forum
Copy code
/*******************************************************************
 *
 *
 * Name: MMO_CUE_rateCard.js
 * @NApiVersion 2.x
 * @NScriptType ClientScript
 * Version: 0.0.1
 *
 *
 * Author: MMO_CUE_rateCard.js
 * Purpose: Sets correct rate based on the project, item, currency, location
 * Script: The script record id
 * Deploy: The script deployment record id
 *
 *
 * ******************************************************************* */

define(['N/currentRecord', 'N/search', 'N/ui/dialog'], function(currentRecord, search, dialog) {

  function sublistChanged(context) {
    var currentRecord = context.currentRecord;
    var sublistName = context.sublistId;
    var index = currentRecord.getCurrentSublistIndex({sublistId:sublistName});
    log.debug('index', index);

    if (sublistName = 'item') {


      var project = currentRecord.getCurrentSublistValue({
        sublistId: sublistName,
        fieldId: 'job'
      });
      log.debug('project', project);
      var item = currentRecord.getCurrentSublistValue({
        sublistId: sublistName,
        fieldId: 'item'
      });
      log.debug('item', item);
      var location = currentRecord.getCurrentSublistValue({
        sublistId: sublistName,
        fieldId: 'location'
      });
      log.debug('location', location);
      var currency = currentRecord.getValue({
        fieldId: 'currency'
      });
      log.debug('location', location);

      try {

        if (project != null && item != null && location != null && currency != null) {
          var rate = rateLookup(item, location);
          log.debug('rate', rate);
          var fxrate = fxLookup(project, currency);
          log.debug('fxrate', fxrate);
          currentRecord.selectLine({sublistId:sublistName,line:index});
          currentRecord.setCurrentSublistValue({sublistId:sublistName,fieldId:'custcolmdlz_rate_usd',value:rate});
          currentRecord.setCurrentSublistValue({sublistId:sublistName,fieldId:'rate',value:rate*fxrate});
          currentRecord.commitLine({sublistId:sublistName});
        }

      } catch (e) {
        log.debug('Error reads: ', e.name + e.message);
      }

      return true;

    }
  }

  function rateLookup(item, location) {
    var customrecordrate_card_matrixSearchObj = search.create({
      type: "customrecordrate_card_matrix",
      filters: [
        ["custrecordlocation", "anyof", location],
        "AND",
        ["custrecordservice_item", "anyof", item]
      ],
      columns: [
        search.createColumn({
          name: "custrecordlocation",
          label: "Location"
        }),
        search.createColumn({
          name: "custrecordcurrency",
          label: "Currency"
        }),
        search.createColumn({
          name: "custrecordrate",
          label: "Rate"
        })
      ]
    });
    var tempres = customrecordrate_card_matrixSearchObj.run().getRange(0, 1);
    log.debug('tempres', tempres);

    var temprate = tempres[0].getValue({
      name: 'custrecordrate'
    });
    log.debug('temprate', temprate)
    return temprate;
  }

  function fxLookup(project, currency) {
    var customrecordfw_proj_fx_rateSearchObj = search.create({
      type: "customrecordfw_proj_fx_rate",
      filters: [
        ["custrecordfw_proj_fx_rate_proj", "anyof", project],
        "AND",
        ["custrecordfw_proj_fx_rate_currency", "anyof", currency]
      ],
      columns: [
        search.createColumn({
          name: "custrecordfw_proj_fx_rate_proj",
          label: "Project"
        }),
        search.createColumn({
          name: "custrecordfw_proj_fx_rate_period",
          label: "Period"
        }),
        search.createColumn({
          name: "custrecordfw_proj_fx_rate_currency",
          label: "Currency"
        }),
        search.createColumn({
          name: "custrecordfw_proj_fx_rate_fx_rate",
          label: "Exchange Rate"
        })
      ]
    });
    var tempres = customrecordfw_proj_fx_rateSearchObj.run().getRange(0, 1);
    log.debug('tempres', tempres);

    var temprate = tempres[0].getValue({
      name: 'custrecordfw_proj_fx_rate_fx_rate'
    });
    log.debug('temprate', temprate)
    return temprate;
  }

  return {
    sublistChanged: sublistChanged
  };
});
b
your sublistChanged entrypoint triggers itself when it updates the line again
n
yeah, how can I prevent that?
b
fix your code so that it doesnt always run is the general answer
usually by adding a guard in the beginning that returns early
n
yeah what I mean is how do I add that filter/guard? I assume there's a way to check what has changed
b
pick your favored technique
you can use a boolean variable to indicate that you should not run
you can use a field that you set, and potentially unset
n
yeah that makes sense but how do I return what has changed? I couldn't find it anywhere
context. somethign
b
you can only set fields with changed values instead of always
though thats kinda expensive since you dont cache lookups
dont expect netsuite to implement this functionality for you, you have to write it yourself
n
oh really.. ok now I really have no idea how to check that lol
b
pure code approach is to have a variable
thats true when you want to not run your logic
and false when you should (or the opposite, your choice)
you declare the variable in your module's closure so that you have access to it from all your entry points
field based approach is to have a field that you set true when you update your other fields and return early when that field is true
set that field false in another entrypoint when a field that affects your rate calculation changes
n
man
maybe its easier if I changed to validateLine
b
thats also an option, its generally better for performance to not commit the line twice
though you may run into issues if you didnt want your code to run if a validateLine returns false