suitescript将项目子列表添加到itempricing子列表 - 提高性能

时间:2016-10-03 15:43:39

标签: javascript optimization transactions netsuite suitescript

我正在NetSuite的javascript SuiteScript中编写一个脚本,该脚本从报价单或销售订单中获取项目子列表,并在客户记录上的项目定价子列表中编辑或创建,添加或更新这些项目。 / p>

所以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循环,但似乎其他一切都是必要的......

谢谢大家,感谢任何帮助。

2 个答案:

答案 0 :(得分:0)

您可以在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
}

如果您需要补充说明,请与我们联系。

答案 1 :(得分:0)

我认为您的主要问题是您在for循环中使用selectNewLineItemcommitLineItem和&#39; selectLineItem`。这些操作依赖于相对较慢的DOM操作和ajax传输。通常,这是不可避免的。

实现所需内容的唯一更快的方法是使用后端事件脚本,该脚本可以在没有所有DOM / GUI操作的情况下操作子列表。这是一种稍微不同的方法,因为脚本仅在GUI呈现之前运行,或者在中间保存之前运行。

P.S。要获得较小的潜在速度增益,请尝试在setCurrentLineItemValue上禁用事件触发器。要禁用,您需要将其中一个方法参数设置为false