Posted at

kintoneの関連レコード一覧を集計してみた


はじめにの前に


10連休向けアドベントカレンダーシステムを作った【個人開発】


こちらの記事がバズっていたので、kintone版で作ってみました。

kintoneでなんかやってやる

今回はそれの#1です!


はじめに

cybozu developer networkでも良く読まれている、

関連レコードの項目を条件付きで集計

をちょっとアレンジしてみました。

(条件はなしにして、関連レコードの項目をただただ集計した感じです)


そもそもの仕組み

devnetの記事では 関連レコード一覧に表示されている数値の合計を表示 ということをしています。

関連レコード一覧の参照元に対して、

レコードの取得APIで該当レコードを取得して、計算して表示するって感じです。

需要はそこそこありそうです


アレンジ箇所

記事を読んでアレンジできそうって思ったのは、サンプルコードのL17部分、

var query = '顧客管理レコード番号_関連レコード紐付け用="' + clientRecordId + '" and 提案プラン in ("Aプラン")';

です。



条件がコードに直書きされてるやん!


改修方法

関連レコード一覧で 「どんな条件で取得しているか」は フォームの設定の取得API で取得できます。

"関連レコード一覧": {

"type": "REFERENCE_TABLE",
"code": "関連レコード一覧",
"label": "関連レコード一覧",
"noLabel": true,
"referenceTable": {
"relatedApp": {
"app": "3",
"code": "参照先アプリ"
},
"condition": {
"field": "このアプリのフィールド",
"relatedField": "参照するアプリのフィールド"
},
"filterCond": "数値 > 10 and 数値2 > 20",
"displayFields": [
"表示するフィールド1",
"表示するフィールド2"
],
"sort": "ソートフィールド1 desc, ソートフィールド2 asc",
"size": 5
}
}

じゃあこれをクエリにしたらいけるのでは!!って魂胆です。


ちょっと小難しい話

すんなりできるかと思ったけど、意外と頭をつかうことがありました^^;

まぁ日本語の問題なのですが、フォームの設定の取得API と レコードの取得APIは 主語 が違いました。

image1.png

image2.png

なので、

関連レコード一覧の設定で 対象フィールド = 参照先フィールド となっているやつを、

レコードの取得APIのクエリでは 参照先フィールド = 対象フィールド(の値) にしてあげる必要があります。


実装


流れ

流れとしては以下みたいな感じです。



  1. フォームの設定の取得API で設定を取得する

  2. 関連レコード一覧部分のオブジェクトを探す


  3. 参照先アプリID を見つける


    • 関連レコード一覧.referenceTable.app




  4. 対象フィールド を見つける


    • 関連レコード一覧.condition.field




  5. 参照先フィールド を見つける


    • 関連レコード一覧.condition.relatedField




  6. ソート条件 を見つける


    • 関連レコード一覧.sort




  7. 表示件数 を見つける


    • 関連レコード一覧.size




  8. 表示する(取得する)フィールド を見つける


    • 関連レコード一覧.displayFields



  9. これらをクエリにはめる


コード

こんなかんじのコードにしてみました

ちなみに、API実行部分は、kinton JS SDK を使っています!

(パラメータが省略できたり、便利です)


(() => {
'use strict';

// フィールドコードとか
const common = {
app: kintone.app.getId(),
relatedRecordCode: '案件一覧',
spaceCode: 'スペース',
related_TotalFee: '合計費用'
};

// JS SDKのコネクションとか
const conn = new kintoneJSSDK.Connection();
const kintoneApp = new kintoneJSSDK.App(conn);
const kintoneRecord = new kintoneJSSDK.Record(conn);

// 詳細画面表示・編集画面表示イベントで発火
kintone.events.on(['app.record.detail.show', 'app.record.edit.show'], event => {
const promise = Promise.resolve();
promise.then(() => {
return kintoneApp.getFormFields(common.app, 'JA');
}).then(resp => {
return resp.properties[common.relatedRecordCode].referenceTable;
}).then(resp2 => {
const params = {
'app': resp2.relatedApp.app,
'query': resp2.condition.relatedField + '="' + event.record[resp2.condition.field].value
+ '" order by ' + resp2.sort + ' limit ' + resp2.size,
'fields': resp2.displayFields
};
return kintoneRecord.getRecords(params.app, params.query, params.fields, true);
}).then(resp3 => {
// 1件以下なら何もしない(計算いらない)
if (resp3.records.length < 1) {return; }

// 金額フィールドの値を配列に格納する
const numArray = resp3.records.map(index => {
return Number(index[common.related_TotalFee].value);
});

// 格納した配列の中身を集計する
const sum = numArray.reduce((pre, cur) => {
return pre + cur;
});

// カンマ区切り
const total = sum.toFixed(0).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1,');

// スペースフィールドに表示
kintone.app.record.getSpaceElement(common.spaceCode).textContent = total;
}).catch(err => {
console.log(err);
});
});
})();


おわりに

とりあえず、設定に応じて可変できるようにはなったけど、作ってる中で思ったのが

「あれ?設定変えるってことは、そもそも集計したいフィールドも変わって結局コード修正必要なのでは・・・」



・・・。



(まぁその時はその時ですね^^;)

それでは!≧(+・` ཀ・´)≦