如何在 Suitelet 打印输出(Netsuite)中使用高阶函数而不是 FOR 循环来处理订单项?

How to use higher order functions instead of FOR Loop for Line items in Suitelet printouts (Netsuite)?

我的上级指派我使用高阶函数 (.filter/.map/.reject/.reduce) 打印订单项的值。我很困惑如何编写高阶函数而不是 for 循环(用于在发票打印输出中打印行值)。我只需要在数量超过 3 时打印该行。我是一名实习生,我不知道它是如何工作的,请帮忙。

Link 到代码段:https://drive.google.com/file/d/1uVQQb0dsg_bo53fT3vk9f0G8WwZomgQg/view?usp=sharing

我总是使用 if 条件仅当数量字段的值大于 3 时才打印行。我什至知道如何 .filter 但我不知道如何调用它以及在哪里调用它。请帮助

通常这是一项直接的任务,但由于您正在获取长度并基于此进行迭代,因此您可以使用 Array.from。它的签名是:

Array.from(ArrayLikeObject, mapFunction);

var tableData = Array.from({ length: countItem}, function(index) {
  vendorBillRec.selectLineItem('item', index);
  var item = vendorBillRec.getCurrentLineItemText('item', 'item');
  var description = nlapiEscapeXML(vendorBillRec.getCurrentLineItemValue('item', 'description'));
  var quantity = parseFloat(nullNumber(vendorBillRec.getCurrentLineItemValue('item', 'quantity')));
  return { item, description, quantity}
});

var htmlData = tableData.filter(...).map(getRowMarkup).join('');

function getRowMarkup(data) {
const { itemName, descript, quantity } = data;
return  '<tr>' +
          '<td colspan="6">' +
            '<p>' + itemName + ' ' + descript + '</p>'+
          '</td>' +
          '<td colspan="2" align="right">' + quantity + '</td>' +
        '</tr>';
}


或者如果您想使用更实用的方法:

  • 创建一个函数,以数组格式读取并提供所有数据。您可以将此数据用于任何任务。
  • 创建一个将接受指定属性的对象和 returns 标记的函数。
  • 在任何筛选条件后将数据传递到此标记。

想法是隔离这两个任务: - 获取需要处理的数据 - 呈现逻辑和样式相关代码

var htmlString = Array.from({ length: countItem}, function(index) {
  vendorBillRec.selectLineItem('item', index);
  var item = vendorBillRec.getCurrentLineItemText('item', 'item');
  var description = nlapiEscapeXML(vendorBillRec.getCurrentLineItemValue('item', 'description'));
  var qty = parseFloat(nullNumber(vendorBillRec.getCurrentLineItemValue('item', 'quantity')));
  return getRowMarkup(item, description, qty)
}).join('');

function getRowMarkup(itemName, descript, quantity) {
return  '<tr>' +
          '<td colspan="6">' +
            '<p>' + itemName + ' ' + descript + '</p>'+
          '</td>' +
          '<td colspan="2" align="right">' + quantity + '</td>' +
        '</tr>';
}

我不相信 Array.from 在服务器端代码中有效。如果确实如此,则使用它。我一直在使用的是以下功能。它们不符合指定的高阶函数,但它们使用 Netsuite 语法并在简化子列表处理和封装代码方面大有帮助:

//SS2.x
//I have this as a snippet that can be included in server side scripts
function iter(rec, listName, cb){
    var lim = rec.getLineCount({sublistId:listName});
    var i = 0;
    var getV = function (fld){
        return rec.getSublistValue({sublistId:listName, fieldId:fld, line:i});
    };
    for(; i< lim; i++){
        cb(i, getV);
    }
}
// to use it:
iter(ctx.newRecord, 'item', function(idx, getV){
  if(parseInt(getV('quantity')) >3){
   ...
  }
});

或者对于 SS1 脚本,我有以下允许在 UserEvent 和 Scheduled 脚本或 Suitelets 之间共享代码的代码

function forRecordLines(rec, machName, op, doReverse) {
    var i, pred, incr;
    var getVal = rec ? function(fld) {
            return rec.getLineItemValue(machName, fld, i);
        } : function(fld) {
            return nlapiGetLineItemValue(machName, fld, i);
        };
    var getText = rec ? function(fld) {
            return rec.getLineItemText(machName, fld, i);
        } : function(fld) {
            return nlapiGetLineItemText(machName, fld, i);
        };
    var setVal = rec ? function(fld, val) {
            rec.setLineItemValue(machName, fld, i, val);
        } : function(fld, val) {
            nlapiSetLineItemValue(machName, fld, i, val);
        };
    var machCount = rec ? rec.getLineItemCount(machName) : nlapiGetLineItemCount(machName);

    if(!doReverse){
        i = 1;
        pred = function(){ return i<= machCount;};
        incr = function(){ i++;};
    }else{
        i = machCount;
        pred = function(){ return i>0;};
        incr = function(){ i--;};
    }

    while(pred()){
        var ret = op(i, getVal, getText, setVal);
        incr();
        if (typeof ret != 'undefined' && !ret) break;
    }

}

// User Event Script:
forRecordLines(null, 'item', function(idx, getV, getT, setV){
  if(parseInt(getV('quantity')) >3){
   ...
  } 
});

// in a Scheduled Script:
forRecordLines(nlapiLoadRecord('salesorder', id), 'item', function(idx, getV, getT, setV){
  if(parseInt(getV('quantity')) >3){
   ...
  } 
});