NetSuite 开发日记:如何管理多环境自定义列表值

发布时间 2023-12-14 10:48:54作者: 橙噫i

在 NetSuite 中可以创建自定义列表,列表可用于为其他(自定义)记录上的下拉选项列表值。

var rec = record.create({
    type: 'customrecord_xx'
});

rec.setValue({
    fieldId: 'custrecord_xx_fld',
    value: '1' 
});
 
rec.save();

我们设置自定义列表值,需要使用该值的内部 ID。但是,内部 ID 是特定于环境的。这意味着,对于相同的自定义列表值,生产中的内部 ID 可能与沙盒中的内部 ID 不同。
image

那么,我们如何管理多个环境中同一自定义列表的内部 ID 不同的情况呢?

方式一:使用SuiteScript查询(N/search模块、N/query模块)
前提设置:

  1. 启用在子列表上显示 ID 字段
    image
  2. 为每个自定义列表值分配唯一且有意义的脚本 ID
    image
function getListValueId(list, listValueScriptId) {
    var listValueId = null;
     
    search.create({
        type: list,
        columns: [
            'internalid',
            'scriptid'
        ]
    }).run().each(function(result) {
        // Note: From tests, the script ID from the search results are always uppercase.
        if (result.getValue("scriptid") === listValueScriptId.toUpperCase()) {
            listValueId = result.getValue('internalid');
        }
        // Stop iterating when we find the target ID.
        return (listValueId === null);
    });
  
    return listValueId;
}
function getListValueId(listType, listValueScriptId) {
    var listValueId;
    
    const sql = "SELECT ID FROM ? WHERE scriptid = ?";
    var resultSet = query.runSuiteQL({ query: sql, params: [listType, listValueScriptId.toUpperCase()] }).asMappedResults();
 
    return listValueId = (resultSet.length === 1 ? resultSet[0].id : null);
}

但这种方式有个显而易见的缺点,查询需要消耗Usage(Usage是NetSuite管理API的一种方式)

方式二:将自定义列表值配置在javaScript文件

SuiteScript
    └─ src
        ├─ constant
        │      ├─ 123456
        │      │     └─ const.js
        │      ├─ 123456_SB1
        │      │     └─ const.js
        │      └─ const.js
        └─ suitelet
              └─ test_sl.js

SuiteScript/src/constant/123456/const.jsSuiteScript/src/constant/123456_SB1/const.js文件内容

// 123456/const.js
define([], function () {
  return {
    TASK_LEVEL: {
      LOW: 1,
      Medium: 2,
      High: 3
    }
  };
});

// 123456_SB1/const.js
define([], function () {
  return {
    TASK_LEVEL: {
      LOW: 4,
      Medium: 5,
      High: 6
    }
  };
});

SuiteScript/src/constant/const.js文件内容

/**
 * @NApiVersion 2.x
 */
define(['N/runtime', './123456/const', './123456_SB1/const'], function (runtime, prodConst, sandboxConst) {
	var constJSON = {};
	var accountId = runtime.accountId;
	switch (accountId) {
		case '123456':
			// 生产环境
			constJSON = prodConst;
			break;
		case '123456_SB1':
			// 沙盒环境
			constJSON = sandboxConst;
			break;
	}
	return constJSON;
});

SuiteScript/src/client/test_cs.js文件内容

/**
 * @NApiVersion 2.x
 * @NScriptType Suitelet
 * @NModuleScope SameAccount
 */
define(['../constant/const'], function (cuxConst) {
  /**
   * Definition of the Suitelet script trigger point.
   * @param {Object} context
   * @param {ServerRequest} context.request - Encapsulation of the incoming request
   * @param {ServerResponse} context.response - Encapsulation of the Suitelet response
   * @Since 2015.2
   */
  function onRequest(context) {
    var response = context.response;
    response.wirte(cuxConst.TASK_LEVEL.LOW);
  }

  return {
    onRequest: onRequest
  };
});