You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从对象数组设置发票行项目数据并避免重复加载发票

解决重复加载发票并批量处理行数据的问题

问题背景

使用定时脚本处理多张发票行级数据时,由于JEIDArray中存在重复的发票ID(invId),导致同一张发票被重复加载、处理和保存,既浪费资源又降低效率。需要优化逻辑,实现同一发票仅加载一次,同时正确为对应行设置数据。

原始数据与代码

原始数据数组

var JEIDArray = [ 
  { item: "663", amount: "3000.00", JE: 13026407, invId: "13020561" }, 
  { item: "663", amount: "100.00", JE: 13026408, invId: "13020561" }, 
  { item: "663", amount: "111.00", JE: 13026409, invId: "13026406" }, 
  { item: "663", amount: "222.00", JE: 13026410, invId: "13026406" }, 
  { item: "373", amount: "444.00", JE: 13026411, invId: "13026406" } 
];

原始处理函数

function updateInvoice(JEIDArray) {
  try {
    for (var r=0;r<JEIDArray.length;r++) {
      var getRecId=JEIDArray[r].invId;
      log.debug("getRecId",getRecId);
      
      var invoice = record.load({
          type: record.Type.INVOICE,
          id: getRecId,
          isDynamic: false
      })
  
      // 获取发票行数
      var lineCount = invoice.getLineCount({
          sublistId: 'item'
      });
      log.debug("lineCount", lineCount);

      // 遍历发票行
      for (var i = 0; i < lineCount; i++) {
          var currentItemId = invoice.getSublistValue({
              sublistId: 'item',
              fieldId: 'item',
              line: i
          });
          var currentItemAmount = invoice.getSublistValue({
              sublistId: 'item',
              fieldId: 'custcol_ay_cts_allocation_amount',
              line: i
          });

          // 遍历JEIDArray找匹配项
          var flag = false;
          for (var j = 0; j < JEIDArray.length; j++) {
              var jeItem = JEIDArray[j];
              if (currentItemId == jeItem.item && currentItemAmount == jeItem.amount) {
                  flag = true;
                  invoice.setSublistValue({
                      sublistId: 'item',
                      fieldId: 'custcol_ay_cts_assoc_ic', // 自定义字段
                      line: i,
                      value: jeItem.JE
                  });
                  break;
              }
          }
      }
      // 保存发票
      var invoiceId=invoice.save();
      log.debug('Invoice Updated', `Invoice ID: ${invoiceId}`);
    }
  } catch(e) {
    log.error('Error updating invoice', e);
  }
}

优化方案

核心思路是先按发票ID分组数据,将同一发票的所有行级数据聚合到一起,之后每个发票仅加载一次,一次性处理完所有对应行再保存。

优化步骤

  • 分组数据:将JEIDArray转换为以invId为键的对象,每个键对应该发票的所有行数据数组。
  • 单发票单加载:遍历分组后的每个发票ID,仅加载一次发票记录。
  • 精准匹配行数据:处理发票行时,直接从当前发票的分组数据中查找匹配的item和amount,避免全局遍历整个数组。
  • 单发票单保存:处理完当前发票的所有目标行后,仅保存一次。

优化后的代码

function updateInvoice(JEIDArray) {
  try {
    // 按invId分组数据,减少重复遍历
    const groupedByInvId = {};
    JEIDArray.forEach(item => {
      const invId = item.invId;
      if (!groupedByInvId[invId]) {
        groupedByInvId[invId] = [];
      }
      groupedByInvId[invId].push(item);
    });

    // 遍历每个分组的发票,仅加载一次
    Object.keys(groupedByInvId).forEach(invId => {
      log.debug("Processing Invoice", invId);
      
      // 加载发票(单发票仅一次)
      const invoice = record.load({
        type: record.Type.INVOICE,
        id: invId,
        isDynamic: false
      });

      const lineCount = invoice.getLineCount({ sublistId: 'item' });
      log.debug("Invoice Line Count", lineCount);

      // 获取当前发票对应的所有行数据
      const invoiceItems = groupedByInvId[invId];

      // 处理发票行,匹配分组后的数据
      for (let i = 0; i < lineCount; i++) {
        const currentItemId = invoice.getSublistValue({
          sublistId: 'item',
          fieldId: 'item',
          line: i
        });
        const currentItemAmount = invoice.getSublistValue({
          sublistId: 'item',
          fieldId: 'custcol_ay_cts_allocation_amount',
          line: i
        });

        // 从当前发票的分组数据中找匹配项,无需遍历整个JEIDArray
        const matchedItem = invoiceItems.find(jeItem => 
          jeItem.item === currentItemId && jeItem.amount === currentItemAmount
        );

        if (matchedItem) {
          invoice.setSublistValue({
            sublistId: 'item',
            fieldId: 'custcol_ay_cts_assoc_ic',
            line: i,
            value: matchedItem.JE
          });
          log.debug(`Set JE ${matchedItem.JE} for line ${i} of invoice ${invId}`);
        }
      }

      // 单发票仅保存一次
      const savedInvoiceId = invoice.save();
      log.debug('Invoice Updated', `Invoice ID: ${savedInvoiceId}`);
    });
  } catch(e) {
    log.error('Error updating invoices', e);
  }
}

优化效果

  • 避免重复加载同一发票,减少API调用次数(原逻辑中invId为13020561的发票会被加载2次,优化后仅1次)。
  • 减少嵌套遍历次数,提升处理效率(原逻辑复杂度为O(n*m),优化后为O(n + m),n为总数据行数,m为发票总行数)。
  • 每个发票仅保存一次,降低数据冲突风险。

内容的提问来源于stack exchange,提问作者Maira S

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 16:25:23