suitescript 将项目子列表添加到项目定价子列表 - 提高性能
suitescript adding item sublist to itempricing sublist - improve performance
我正在 NetSuite 的 javascript SuiteScript 中编写一个脚本,该脚本从报价单或销售订单中获取项目子列表,并在编辑或创建、添加或更新客户记录的项目定价子列表中的这些项目.
所以我正在比较 2 个列表(rec.itempricing 和 newSoQuote.item),然后更新 rec.itempricing
我的问题:我在使用三重 for 循环时遇到了性能问题(很明显);如何组合 for 循环中的某些行以减少执行时间?
代码如下:
function userEventBeforeSubmit(type){
var currentUserRole = nlapiGetRole();
if (type != 'create' && type != 'edit')
return;
if (currentUserRole != 1037 && currentUserRole != 1064)
return;
var newSoQuote = nlapiGetNewRecord();
var custInternalId = newSoQuote.getFieldValue('entity');
var soItemsCount = newSoQuote.getLineItemCount('item');
var rec = nlapiLoadRecord('customer',custInternalId); //load customer record
var quotedPrice, duplicate, itemType;
var itemPricingCount;
for (var i = 1; i <= soItemsCount; i++) {
duplicate = false;
itemType = newSoQuote.getLineItemValue('item', 'itemtype', i);
if(itemType == 'InvtPart') {
itemPricingCount = rec.getLineItemCount('itempricing');
//get the rate (unit price)
quotedPrice = newSoQuote.getLineItemValue('item', 'rate', i);
//check for duplicate
for (var j = 1; j <= itemPricingCount; j++) {
//if we find a match on itempricing list
if (newSoQuote.getLineItemValue('item','item',i) == rec.getLineItemValue('itempricing', 'item', j)){
rec.selectLineItem('itempricing', j);
rec.setCurrentLineItemValue('itempricing', 'price', quotedPrice); //update price
rec.commitLineItem('itempricing'); //commit the line item
j = itemPricingCount + 1;
duplicate = true;
}
}
for (var k = 1; k < i; k++) {
if (newSoQuote.getLineItemValue('item', 'item', i) == newSoQuote.getLineItemValue('item', 'item', k))
duplicate = true;
}
if (!duplicate) { //if not on the itempricing sublist adding new item
rec.selectNewLineItem('itempricing'); //select a new line on the item price sublist
rec.setCurrentLineItemValue('itempricing', 'item', newSoQuote.getLineItemValue('item', 'item', i)); //select an item
rec.setCurrentLineItemValue('itempricing', 'level', -1); //select 'custom' level
rec.setCurrentLineItemValue('itempricing', 'currency', 1); //select currency
rec.setCurrentLineItemValue('itempricing', 'price', quotedPrice); //input price
rec.commitLineItem('itempricing'); //commit the line item
}
}
}
nlapiSubmitRecord(rec); //submit the record
}
我已经将所有变量声明移出 for 循环,但似乎其他一切都是必要的...
谢谢大家,感谢任何帮助。
您可以对 rec 对象使用 findLineItemValue 方法。它将按如下方式工作:
var lookForItem = newSoQuote.getLineItemValue('item','item',i);
var foundIndex = rec.findLineItemValue('itempricing','item',lookForItem);
/* if foundIndex is -1, the item was not found, exlist it would be the row index in sublist */
if(foundIndex==-1) {
rec.selectNewLineItem('itempricing');
//... and set the rest of your sublist values.
rec.commitLineItem('itempricing'); //commit the line item
}
如果您需要进一步说明,请告诉我。
我认为您的主要问题是您在 for 循环中使用了 selectNewLineItem
、commitLineItem
和“selectLineItem”。这些操作依赖于相对较慢的 DOM 操作和 ajax 传输。通常,这是不可避免的。
完成您需要的唯一更快的方法是使用后端事件脚本,它可以在没有所有 DOM/GUI 操作的情况下操作子列表。这是一种有点不同的方法,因为脚本只在 GUI 呈现之前 运行,或者在保存之间。
P.S。对于小的潜在速度增益,请尝试在 setCurrentLineItemValue
上禁用事件触发器。要禁用,您需要将方法参数之一设置为 false
我正在 NetSuite 的 javascript SuiteScript 中编写一个脚本,该脚本从报价单或销售订单中获取项目子列表,并在编辑或创建、添加或更新客户记录的项目定价子列表中的这些项目.
所以我正在比较 2 个列表(rec.itempricing 和 newSoQuote.item),然后更新 rec.itempricing
我的问题:我在使用三重 for 循环时遇到了性能问题(很明显);如何组合 for 循环中的某些行以减少执行时间?
代码如下:
function userEventBeforeSubmit(type){
var currentUserRole = nlapiGetRole();
if (type != 'create' && type != 'edit')
return;
if (currentUserRole != 1037 && currentUserRole != 1064)
return;
var newSoQuote = nlapiGetNewRecord();
var custInternalId = newSoQuote.getFieldValue('entity');
var soItemsCount = newSoQuote.getLineItemCount('item');
var rec = nlapiLoadRecord('customer',custInternalId); //load customer record
var quotedPrice, duplicate, itemType;
var itemPricingCount;
for (var i = 1; i <= soItemsCount; i++) {
duplicate = false;
itemType = newSoQuote.getLineItemValue('item', 'itemtype', i);
if(itemType == 'InvtPart') {
itemPricingCount = rec.getLineItemCount('itempricing');
//get the rate (unit price)
quotedPrice = newSoQuote.getLineItemValue('item', 'rate', i);
//check for duplicate
for (var j = 1; j <= itemPricingCount; j++) {
//if we find a match on itempricing list
if (newSoQuote.getLineItemValue('item','item',i) == rec.getLineItemValue('itempricing', 'item', j)){
rec.selectLineItem('itempricing', j);
rec.setCurrentLineItemValue('itempricing', 'price', quotedPrice); //update price
rec.commitLineItem('itempricing'); //commit the line item
j = itemPricingCount + 1;
duplicate = true;
}
}
for (var k = 1; k < i; k++) {
if (newSoQuote.getLineItemValue('item', 'item', i) == newSoQuote.getLineItemValue('item', 'item', k))
duplicate = true;
}
if (!duplicate) { //if not on the itempricing sublist adding new item
rec.selectNewLineItem('itempricing'); //select a new line on the item price sublist
rec.setCurrentLineItemValue('itempricing', 'item', newSoQuote.getLineItemValue('item', 'item', i)); //select an item
rec.setCurrentLineItemValue('itempricing', 'level', -1); //select 'custom' level
rec.setCurrentLineItemValue('itempricing', 'currency', 1); //select currency
rec.setCurrentLineItemValue('itempricing', 'price', quotedPrice); //input price
rec.commitLineItem('itempricing'); //commit the line item
}
}
}
nlapiSubmitRecord(rec); //submit the record
}
我已经将所有变量声明移出 for 循环,但似乎其他一切都是必要的...
谢谢大家,感谢任何帮助。
您可以对 rec 对象使用 findLineItemValue 方法。它将按如下方式工作:
var lookForItem = newSoQuote.getLineItemValue('item','item',i);
var foundIndex = rec.findLineItemValue('itempricing','item',lookForItem);
/* if foundIndex is -1, the item was not found, exlist it would be the row index in sublist */
if(foundIndex==-1) {
rec.selectNewLineItem('itempricing');
//... and set the rest of your sublist values.
rec.commitLineItem('itempricing'); //commit the line item
}
如果您需要进一步说明,请告诉我。
我认为您的主要问题是您在 for 循环中使用了 selectNewLineItem
、commitLineItem
和“selectLineItem”。这些操作依赖于相对较慢的 DOM 操作和 ajax 传输。通常,这是不可避免的。
完成您需要的唯一更快的方法是使用后端事件脚本,它可以在没有所有 DOM/GUI 操作的情况下操作子列表。这是一种有点不同的方法,因为脚本只在 GUI 呈现之前 运行,或者在保存之间。
P.S。对于小的潜在速度增益,请尝试在 setCurrentLineItemValue
上禁用事件触发器。要禁用,您需要将方法参数之一设置为 false