こんにちは。いろいろ試したのですが、うまくいかないためこちらで相談させてください。
1. 想定の動作(図1)
「請求書アプリ」に請求情報(テーブル内の各行)を登録すると、「工事費用アプリ」のテーブルに集計表ができあがる。
このとき「工事費用アプリ」では「工事番号」ごとにレコードを作っています。
<図1>
2. 実際の動作(図2)
「請求書アプリ」に例えば4件(4行)分の請求情報を入力すると、「工事費用アプリ」側では 2件分しか集計されない。
再現性は90%程度で、残り10%は1件分しか(つまり、工事費用アプリ側で金額欄が1円となる)集計されない場合もあります。
3件以上集計できたことはありません。
<図2>
3. 説明用テスト入力(図3、図4)
説明を簡単にするため、「工事費用アプリ」にはあらかじめ「工事番号 001」「日付 2016-08-15」「支払先 A社」「金額 0円」を入力しておきました(図3)。「明細書」は「工事費用アプリ」内のテーブルのフィールドコードです。
<図3>
その次に、「請求書アプリ」に4件分登録してみました(図4)。「payTable」は請求書アプリ内のテーブルのフィールドコードです。
<図4>
4. ソースの説明
ソースを以下に示します。長くてすみません。これでもだいぶ簡略化して本質的な箇所を抜き出しています。
- (function() {
- “use strict”;
- //請求書アプリの操作
- var billApp = {};
- billApp.APP_ID = kintone.app.getId();
- billApp.APP_NAME = “請求書アプリ”;
- //工事費用アプリの操作
- var costApp = {};
- costApp.APP_ID = 73;
- costApp.APP_NAME = “工事費用アプリ”;
- //
- //請求書アプリのレコード追加画面(保存実行前)で、
- //工事費用アプリに情報を追加する
- //
- kintone.events.on(“app.record.create.submit”, function(e) {
-
//追加しようとしているレコードのテーブル値取得 -
var newTable = e.record['payTable'].value; -
billApp.insert(newTable).then(function(resp) { -
if (resp === false) { -
alert('\* NG \* 追加失敗'); -
} -
return e; -
}).catch(function(resp) { -
e.error = '\*\*\* NG \*\*\* ' + costApp.APP\_NAME + 'に登録できませんでした。'; -
return e; -
}); - });
- //--------------------------------------
- // 請求書アプリでの操作
- //--------------------------------------
- //
- //テーブル各行(請求情報)ごとに、
- //工事費用アプリへの登録する/しないを判定し、
- //登録する場合は登録処理を行う
- // @param array table 請求情報テーブル(payTable)
- // @param integer nextRow テーブルの行番号(初期値は0)
- // @return array/boolean [true, false,…]の配列(処理失敗時はarrayではなくfalseを返す)
- //
- billApp.insert = function(table, nextRow) {
-
var row = nextRow || 0; -
// (工事番号が同じ)工事費用レコードを取得 -
return costApp.get(table[row]['value']['工事番号'].value).then(function(resp) { -
// -
//工事費用アプリに、同じ工事番号のレコードが、既に存在するという条件下でのテスト -
// -
var costRecord = resp['records']; -
// -
//工事費用アプリに、同じ[日付, 支払先]の行が、既に存在するという条件下でのテスト -
// -
return costApp.increaseRow(costRecord, table[row].value, 0).then(function(resp4) { -
//金額加算成功 -
//----- recursive processing ----- -
row++; //1. 行を進める(次の支払情報へ) -
if (row \< table.length) { //2. 全ての行(支払情報)を処理したか -
return billApp.insert(table, row); //3. まだの場合、次の行(支払情報)の処理へ -
} -
return true; -
//-------------------------------- -
}, function(resp4) { -
//金額加算失敗 -
//----- recursive processing ----- -
row++; //1. 行を進める(次の支払情報へ) -
if (row \< table.length) { //2. 全ての行(支払情報)を処理したか -
return billApp.insert(table, row); //3. まだの場合、次の行(支払情報)の処理へ -
} -
return false; -
//-------------------------------- -
}); -
}, function(resp) { -
return false; //存在確認不能 -
}); //costApp.get - }; //billApp.insert
- // -----------------------------------
- // 工事費用アプリへの操作
- // -----------------------------------
- //
- // [工事番号]を指定して、工事費用アプリのレコードを取得
- // @param object kojiNo 工事番号
- // @return Promise ‘GET’
- //
- costApp.get = function(kojiNo) {
-
var params = { -
// 工事費用アプリ番号 -
"app": costApp.APP\_ID, -
// 検索条件 -
"query": '工事番号 ="' + kojiNo + '"', -
// 取得項目 -
"fields": ['$id', '$revision', '工事番号', '明細書'] -
}; -
return kintone.api(kintone.api.url('/k/v1/records', true), 'GET', params); - };
- //
- // テーブル内の1行を更新する(加算)
- // @param exsitedInf 工事費用アプリのレコード
- // @param newInf 請求書アプリの支払情報1件
- // @param rowIndex 更新する行を示す数(配列の添え字)
- // @return Promise
- //
- costApp.increaseRow = function(existedInf, newInf, rowIndex) {
-
var costTable = existedInf[0]['明細書'].value; -
//支払金額を加算する -
var tmpValue = Number(costTable[rowIndex]['value']['金額'].value); -
costTable[rowIndex]['value']['金額'].value = tmpValue + Number(newInf['金額'].value); -
var params = { -
"app": costApp.APP\_ID, -
"id": existedInf[0]['$id'].value, -
"revision": existedInf[0]['$revision'].value, -
"record": { -
"明細書": { "value": costTable } -
} -
}; -
// 更新 -
return kintone.api(kintone.api.url('/k/v1/record', true), 'PUT', params); - };
- })(); //----- function
「請求書アプリ」に4行分のデータを入力し、「保存」ボタンをクリックした時点以降を、GoogleChromeのディベロッパーツールで調べてみました。
ブレークポイントを適宜設定して実行してみますと、payTable 1行目の1円の行は正常に動作していました。しかし、payTable 2行目の10円の処理に入ったところで、(ソースコード42行目の)costApp.get関数がエラーを返し、ソースコード70行目のエラー処理にジャンプしてしまっていました。
(ソースコード81行目)costApp.get関数はシンプルな処理で、単に工事番号を受け取り、該当するレコードを「工事費用アプリ」から取得するだけのものです。
costApp.get関数がエラーを返す直前の処理でも、paramsの値は正常にセットされてていましたので、なぜ (ソースコード90行目の)return kinton.api(…); がエラーを返すのか理解できません。
請求書アプリの各行を処理する際に、Promiseを使い、再帰的に処理しているのですが、ここら辺でPromiseに関して私が何か誤解しているのかもしれません。
なお、GoogleChromeのディベロッパーツールでブレークポイント設置後に実行させると、payTable 1行目(1円の行)の処理は必ずうまくいくけども、payTable 2行目の10円の行は必ず失敗する、というように動作します。(この場合、工事費用アプリ側の(集計結果である)金額欄は 1円となります)
ブレークポイント無しで実行させ、リアルタイムで処理を流した場合は、たいてい payTable 2行目までは正常で payTable 3行目の100円の行で失敗します。(この場合、工事費用アプリの金額欄は 11円となります)
以上なのですが、何かヒントになるようなことでもよろしいですので教えていただけますでしょうか。よろしくお願いいたします。