Tips「安全に在庫管理を行うテクニック」で紹介されている様な別アプリへの登録/更新処理を真似て、
サブテーブルのデータ件数分、登録/更新を繰り返す処理を作成していますが、以下の点で困っています。
皆様のお知恵を拝借できれば幸いです。よろしくお願いします。
・アプリの構成
入力アプリ
・サブテーブル(”明細”)に”商品名”と”数量”を持つ。
・プロセス管理のあるステータス実行時に更新処理を実行。
・更新処理にて、サブテーブルの”商品名”、”数量”を使い、
商品マスタの”在庫数”を更新、在庫アプリにレコードを追加する。
商品マスタ
・”商品名”と”在庫数”を持つ
在庫アプリ
・”変更種別”、”商品名”、”数量”を持つ
・課題
サブテーブルに同一商品があった場合に、409 Conflictエラーを回避したい。
またはエラーが発生した際に、更新処理を再実行させたい。
・現状
待ち処理(sleep関数)を作り、更新処理(zaikoUpdate)を順番に一定間隔で実行しようとしていますが、
更新処理(zaikoUpdate)は一定間隔で実行されるものの、データ更新処理(bulkRequest)はほぼ同じタイミングで実行されてしまう。
・作成中のソース
(function() {
'use strict';
// 在庫アプリのアプリID
var zaikoAppId = 92; //在庫AP
// 商品マスタアプリのアプリID
var itemAppId = kintone.app.getLookupTargetAppId('商品名'); //商品マスタAP
function zaikoUpdate(tableRecord){
// 商品マスタから在庫数を取得
var itemCode = tableRecord.value['商品名'].value;
var getParams = {
app: itemAppId,
query: '商品名 = "' + itemCode + '"'
};
console.log(itemCode + '登録処理開始');
kintone.api(
kintone.api.url('/k/v1/records', true),
'GET',
getParams
).then(function(getRes) {
// データがあれば更新
var recordId = getRes.records[0].$id.value;
var revision = getRes.records[0].$revision.value;
var itemCode = tableRecord.value['商品名'].value;
var pickingNum = Number(tableRecord.value['数量'].value);
// 在庫数
var stockNum = Number(getRes.records[0].在庫数.value);
// 出庫後の在庫数
var newStockNum = stockNum - pickingNum;
// 商品マスタの在庫数を更新し、在庫アプリに出庫データを追加する。
var requestParams = {
'requests':[
{
// 商品マスタアプリの在庫数を更新
'method': 'PUT',
'api': '/k/v1/record.json',
'payload': {
'app': itemAppId,
'id': recordId,
// 商品マスタのデータ取得時と更新時でrevisionが異なる場合はエラーにする
'revision': revision,
'record': {
'在庫数': {
'value': newStockNum
}
}
}
},
{
// 在庫アプリに出庫情報を追加登録
'method': 'POST',
'api': '/k/v1/record.json',
'payload': {
'app': zaikoAppId,
'record': {
'変更種別': {
'value': '出庫'
},
'商品名': {
'value': itemCode
},
'数量': {
'value': pickingNum * -1
}
}
}
}
]
};
kintone.api(
kintone.api.url('/k/v1/bulkRequest', true),
'POST',
requestParams
).then(function(postRes) {
console.log(itemCode + 'を登録しました');
return;
}).catch(function(error) {
console.log(error);
console.log(itemCode + 'の登録に失敗しました');
event.error= '出庫に失敗しました。';
return event;
});
}).catch(function(error) {
console.log(error);
event.error = 'データ未登録';
return event;
});
}
function sleep(msec){
var d1 = new Date();
while (true) {
var d2 = new Date();
if (d2 - d1 > msec) {
break;
}
}
}
function zaikoUpdateWait(val){
zaikoUpdate(val);
sleep(3000);
}
// 配列を順番に処理する
function sequential(array) {
// .reduce で順番に処理。初期値は第二引数の Promise.resolve()
return array.reduce((promise, val) => {
// promise が常に前回の戻り値であることを利用して
// Promise を連鎖させるのがポイント
return promise.then(res => zaikoUpdateWait(val));
}, Promise.resolve());
}
kintone.events.on(['app.record.detail.process.proceed'], function(event) {
if(event.action.value == '出庫する'){
var record = event.record;
// 明細
var tableRecords = record.明細.value;
sequential(tableRecords);
}
return event;
});
})();