NetSuite 能否以编程方式克隆/复制 SuiteLet 中销售订单上的项目?

问题描述 投票:0回答:1

我想克隆/复制销售订单上的项目。我想从销售订单中复制项目子列表中的第一项。

我有一个

UserEventScript
,它添加了一个 SuiteLet' 按钮来克隆/复制该项目。

我想做的是

  1. 获取销售订单
  2. 从销售订单中获取项目子列表中的字段
  3. 然后我有一个包含排除字段的数组;我使用数组来逐出将这些字段添加到我将用来复制其他属性的辅助对象中
  4. 在复制值时,我有几个数组来指示字段类型
  5. 我使用
    salesOrder.selectNewLine({ sublistId: 'item' });
  6. 向项目添加新行
  7. 我迭代辅助对象来复制属性
  8. 我尝试提交新行

我收到以下错误

{"type":"error.SuiteScriptError","name":"USER_ERROR","message":"请选择要添加的项目","id":"","stack":["错误 在 RecordInvoker.commitLine (suitescript/resources/javascript/record/serverRecordService.js:278:5) 在 NetSuiteObject.thenableFunction() (suitescript/resources/javascript/record/proxy.js:115:24) 在 Object.onRequest (/SuiteScripts/Sales Orders/Suitelets/prepopulateLineItem.js:193:18)"],"原因":{"type":"内部错误","code":"USER_ERROR","详细信息": "请选择要添加的项目","userEvent":null,"stackTrace":["错误 在 RecordInvoker.commitLine (suitescript/resources/javascript/record/serverRecordService.js:278:5) 在 NetSuiteObject.thenableFunction() (suitescript/resources/javascript/record/proxy.js:115:24) 在 Object.onRequest (/SuiteScripts/销售订单/Suitelets/prepopulateLineItem.js:193:18)"],"notifyOff":false},"notifyOff":false,"userFacing":true}

这是我的套房

/**
 * @NApiVersion 2.1
 * @NScriptType Suitelet
 * @NModuleScope SameAccount
 */

define(['N/record', 'N/log', 'N/redirect'], function (record, log, redirect) {
  function onRequest(scriptContext) {
    try {
      const request = scriptContext.request;

      const salesOrderID = request.parameters.id;

      const salesOrder = record.load({
        type: record.Type.SALES_ORDER,
        id: salesOrderID,
        isDynamic: true
      });

      const itemFields = salesOrder.getSublistFields({ sublistId: 'item' });

      const excludeFields = [
        'commitinventory',
        'createpo',
        'custcol_rbs_date_auto_close',
        'custcol_ship_date_act',
        'custcolcust_linenum',
        'id',
        'item',
        'line',
        'linenumber',
        'lineuniquekey',
        'olditemid',
        'sys_id',
        'sys_parentid',
        'unitconversionrate',
        'units',
        'unitslist'
      ];

      var firstItemKeyValue = {};
      itemFields.forEach((fieldId) => {
        if (excludeFields.indexOf(fieldId) !== -1) return;
        const value = salesOrder.getSublistValue({
          sublistId: 'item',
          fieldId: fieldId,
          line: 0
        });
        if (value === null || value === undefined || value === '') return;
        log.debug({ title: 'fieldId - ' + fieldId, details: value });
        firstItemKeyValue[fieldId] = value;
      });

      const textFields = [
        'class',
        'class_display',
        'createdpo',
        'custcol_4601_witaxamount',
        'custcol_4601_witaxbaseamount',
        'custcol_category_salesforce_name',
        'custcol_item_type',
        'custcol_material_quality',
        'description',
        'item_display',
        'itemtype',
        'location_display',
        'pocurrency',
        'units_display'
      ];

      const dateFields = [
        'createddate',
        'ddistrib',
        'prevdate',
        'recordcreateddate',
        'saleseffectivedate'
      ];

      const booleanFields = [
        'amounthasbeenset',
        'backordered',
        'billvariancestatusallbook',
        'custcol_2663_isperson',
        'custcol_2663_isperson',
        'custcol_4601_witaxapplies',
        'dropshiporderhasbeenshiprecv',
        'dropshipwarningdisplayed',
        'fulfillable',
        'generateaccruals',
        'groupclosed',
        'includegroupwrapper',
        'isclosed',
        'isdropshiporderline',
        'islinefulfilled',
        'islinefulfilled',
        'isnoninventory',
        'isopen',
        'isposting',
        'isspecialorderline',
        'istaxable',
        'itempacked',
        'itempicked',
        'linked',
        'linked',
        'linkeddropship',
        'linkedordbill',
        'linkedshiprcpt',
        'noprint',
        'pomarginal',
        'povendor_display',
        'printitems'
      ];

      const integerFields = [
        'amount',
        'createdpo',
        'custcol_freight_estimate_amount',
        'custcol_material_form',
        'custcol_material_non_material',
        'custcol_material_quality',
        'custcol_material_type',
        'custcol_statistical_value_base_curr',
        'initquantity',
        'location',
        'onorder',
        'origlocation',
        'origquantity',
        'origunits',
        'poid',
        'povendor',
        'quantity',
        'quantityavailable',
        'quantitybilled',
        'quantityfulfilled',
        'rate'
      ];

      const floatFields = ['porate'];

      const filteredItemFields = Object.keys(firstItemKeyValue);
      salesOrder.selectNewLine({ sublistId: 'item' });
      salesOrder.setCurrentSublistValue({
        sublistId: 'item',
        fieldId: 'description',
        value: 'PLEASE UPDATE DESCRIPTION'
      });
      filteredItemFields.forEach((fieldId) => {
        if (textFields.indexOf(fieldId) !== -1) {
          salesOrder.setCurrentSublistValue({
            sublistId: 'item',
            fieldId: fieldId,
            value: firstItemKeyValue[fieldId]
          });
        } else if (dateFields.indexOf(fieldId) !== -1) {
          salesOrder.setCurrentSublistValue({
            sublistId: 'item',
            fieldId: fieldId,
            value: new Date(firstItemKeyValue[fieldId])
          });
        } else if (booleanFields.indexOf(fieldId) !== -1) {
          salesOrder.setCurrentSublistValue({
            sublistId: 'item',
            fieldId: fieldId,
            value:
              String(firstItemKeyValue[fieldId]).toLowerCase() === 'true' ||
              String(firstItemKeyValue[fieldId]).toLowerCase() === 't'
          });
        } else if (integerFields.indexOf(fieldId) !== -1) {
          salesOrder.setCurrentSublistValue({
            sublistId: 'item',
            fieldId: fieldId,
            value: parseInt(firstItemKeyValue[fieldId])
          });
        } else if (floatFields.indexOf(fieldId) !== -1) {
          salesOrder.setCurrentSublistValue({
            sublistId: 'item',
            fieldId: fieldId,
            value: parseFloat(firstItemKeyValue[fieldId])
          });
        } else {
          log.debug({
            title: 'without a type fieldId - ' + fieldId,
            details: "'" + firstItemKeyValue[fieldId] + "'"
          });
          salesOrder.setCurrentSublistValue({
            sublistId: 'item',
            fieldId: fieldId,
            value: "'" + firstItemKeyValue[fieldId] + "'"
          });
        }
      });
      log.debug({ title: 'salesOrder', details: salesOrder });
      salesOrder.commitLine({ sublistId: 'item' });
      salesOrder.save({
        enableSourcing: false,
        ignoreMandatoryFields: false
      });

      const lastItem = salesOrder.getSublistValue({
        sublistId: 'item',
        fieldId: 'item',
        line: salesOrder.getLineCount({ sublistId: 'item' }) - 1
      });

      redirect.redirect({
        url: '/app/common/item/item.nl?id=' + lastItem.id + '&e=T'
      });
    } catch (error) {
      log.debug({ title: 'error', details: JSON.stringify(error) });
    }
  }

  return { onRequest };
});
netsuite
1个回答
0
投票

我可以解决我想要的事情,但不是我最初的意图。 @bknights 的评论澄清了我对这个问题的理解以及为什么我无法实现我想要的。物料记录与销售订单上的物料列表记录不同。

我的解决方案是从销售订单列表中的项目中获取第一个元素,加载项目记录,复制并保存。

const salesOrder = record.load({
  type: record.Type.SALES_ORDER,
  id: salesOrderID,
  isDynamic: true
});

...

const firstLineItem = salesOrder.getSublistValue({
  sublistId: 'item',
  fieldId: 'item',
  line: 0
});

...

const copyItem = record.copy({
  type: record.Type.INVENTORY_ITEM,
  id: parseInt(firstLineItem)
});

...

copyItem.setValue({ fieldId: 'itemid', value: random.generateUUID() });
copyItem.setValue({ fieldId: 'displayname', value: 'Please update the description value' });
copyItem.save();

其中

record
random
来自 NetSuite SuiteScripts 2.x 模块

© www.soinside.com 2019 - 2024. All rights reserved.