使用 Ragic API 自動生成庫存扣減子表單實作筆記

前言

在庫存管理系統中,經常需要根據商品需求自動計算庫存扣減清單,並將結果保存於子表單中以便追蹤。本文針對使用 Ragic API 的場景,說明如何透過程式碼自動清空舊數據、遍歷需求商品、依序扣減庫存批次,並將扣減結果記錄到子表單,適合有程式基礎且想優化庫存流程的工程師或自學者。

功能概述

此程式碼主要包含以下功能:

  1. 清空目標子表單的舊有數據,避免重複記錄。
  2. 讀取需求子表單資料,判斷是否有待處理的需求。
  3. 依據 FIFO 原則,遍歷庫存批次並計算扣減數量。
  4. 將扣減結果逐筆寫入另一個子表單,完成自動化記錄。

代碼邏輯詳解

1. 初始化與清空子表單

首先,設定目標子表單 ID,並使用 deleteSubtableRowAll 方法清空該子表單的所有資料,確保後續寫入的是最新扣減結果。

var subtable_id = "1003384"; // 扣減結果子表單ID
entry.deleteSubtableRowAll(subtable_id);
entry.save();

2. 讀取需求子表單並檢查資料

接著,取得需求子表單的行數,若無資料則直接結束程序,避免不必要的運算。

var subtableSize = entry.getSubtableSize(1003391); // 需求子表單行數
if (subtableSize === 0) {
  log.println("子表單 1003391 沒有資料");
  return;
}

3. 遍歷需求商品並查詢庫存批次

對每筆需求商品,使用 Ragic API 的 getAPIQuery 方法查詢對應商品的庫存批次,並依創建時間排序以符合 FIFO 原則。

for (var i = 0; i < subtableSize; i++) {
  var productId = entry.getSubtableFieldValue(1003391, i, "1003389"); // 商品ID
  var productNumber = entry.getSubtableFieldValue(1003391, i, "1003390"); // 領用數量

  var batchQuery = db.getAPIQuery("/forms27/8");
  batchQuery.addFilter(1003353, '=', productId); // 篩選商品ID
  batchQuery.setOrder(1003372, 1); // 按創建時間排序
  var stockResults = batchQuery.getAPIResultList();

  // 後續扣減邏輯
}

4. 計算扣減並寫入扣減子表單

根據需求數量,逐批扣減庫存,並使用 setSubtableFieldValue 方法將扣減明細寫入目標子表單,確保每筆扣減數量與批次資訊完整記錄。

var accumulatedQuantity = 0;
var currentSubtableSize = entry.getSubtableSize('1003384');

for (var j = 0; j < stockResults.length; j++) {
  var stockEntry = stockResults[j];
  var batchQuantity = Number(stockEntry.getFieldValue("1003374")); // 庫存數量
  var remainingRequired = productNumber - accumulatedQuantity; // 尚需扣減數量
  var usedQuantity = Math.min(batchQuantity, remainingRequired); // 本批次扣減數量

  if (usedQuantity <= 0) break;

  entry.setSubtableFieldValue('1003384', currentSubtableSize, '1003392', stockEntry.getFieldValue('1003354')); // 商品名稱
  entry.setSubtableFieldValue('1003384', currentSubtableSize, '1003380', stockEntry.getFieldValue('1003355')); // 批次號
  entry.setSubtableFieldValue('1003384', currentSubtableSize, '1003381', usedQuantity); // 扣減數量
  entry.setSubtableFieldValue('1003384', currentSubtableSize, '1003382', stockEntry.getFieldValue('1003356')); // 成本

  accumulatedQuantity += usedQuantity;
  currentSubtableSize++;

  if (accumulatedQuantity >= productNumber) break;
}

小結

透過 Ragic API 的子表單操作與資料查詢功能,這段程式碼實現了從需求子表單到庫存扣減子表單的自動化流程,提升庫存管理效率與數據準確性。當庫存不足時,程式可擴充加入錯誤提示機制,避免錯誤記錄產生。此範例也可作為與其他系統整合的基礎,方便後續功能擴展。

完整程式碼

var subtable_id = "1003384"; // 扣減結果子表單ID
entry.deleteSubtableRowAll(subtable_id);
entry.save();

var subtableSize = entry.getSubtableSize(1003391); // 需求子表單行數
if (subtableSize === 0) {
  log.println("子表單 1003391 沒有資料");
  return;
}

for (var i = 0; i < subtableSize; i++) {
  var productId = entry.getSubtableFieldValue(1003391, i, "1003389"); // 商品ID
  var productNumber = entry.getSubtableFieldValue(1003391, i, "1003390"); // 領用數量

  var batchQuery = db.getAPIQuery("/forms27/8");
  batchQuery.addFilter(1003353, '=', productId); // 篩選商品ID
  batchQuery.setOrder(1003372, 1); // 按創建時間排序
  var stockResults = batchQuery.getAPIResultList();

  var accumulatedQuantity = 0;
  var currentSubtableSize = entry.getSubtableSize(subtable_id);

  for (var j = 0; j < stockResults.length; j++) {
    var stockEntry = stockResults[j];
    var batchQuantity = Number(stockEntry.getFieldValue("1003374")); // 庫存數量
    var remainingRequired = productNumber - accumulatedQuantity; // 尚需扣減數量
    var usedQuantity = Math.min(batchQuantity, remainingRequired); // 本批次扣減數量

    if (usedQuantity <= 0) break;

    entry.setSubtableFieldValue(subtable_id, currentSubtableSize, '1003392', stockEntry.getFieldValue('1003354')); // 商品名稱
    entry.setSubtableFieldValue(subtable_id, currentSubtableSize, '1003380', stockEntry.getFieldValue('1003355')); // 批次號
    entry.setSubtableFieldValue(subtable_id, currentSubtableSize, '1003381', usedQuantity); // 扣減數量
    entry.setSubtableFieldValue(subtable_id, currentSubtableSize, '1003382', stockEntry.getFieldValue('1003356')); // 成本

    accumulatedQuantity += usedQuantity;
    currentSubtableSize++;

    if (accumulatedQuantity >= productNumber) break;
  }
}
entry.save();