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

# はじめにの前に

> [10連休向けアドベントカレンダーシステムを作った【個人開発】](https://qiita.com/wicket/items/f2aa70ac9cd734a01c7d)

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

[kintoneでなんかやってやる](https://gw-advent.9wick.com/calendars/19)

今回はそれの#1です！

# はじめに

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

[関連レコードの項目を条件付きで集計
](https://developer.cybozu.io/hc/ja/articles/203030394)

をちょっとアレンジしてみました。
(条件はなしにして、関連レコードの項目をただただ集計した感じです)

# そもそもの仕組み

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

関連レコード一覧の参照元に対して、
レコードの取得APIで該当レコードを取得して、計算して表示するって感じです。

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

# アレンジ箇所

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

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

です。

<br/><br/>

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

# 改修方法

関連レコード一覧で 「どんな条件で取得しているか」は **フォームの設定の取得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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153051/e7a6c78d-21cd-7fc9-1136-b890ba88802d.png)

![image2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153051/78c05c3a-8bb0-cad1-e833-8493613228c0.png)

なので、
関連レコード一覧の設定で ```対象フィールド = 参照先フィールド``` となっているやつを、
レコードの取得APIのクエリでは ```参照先フィールド = 対象フィールド(の値)``` にしてあげる必要があります。

# 実装

## 流れ

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

1. **フォームの設定の取得API** で設定を取得する
1. 関連レコード一覧部分のオブジェクトを探す 
1. **参照先アプリID** を見つける
    - `関連レコード一覧.referenceTable.app`
1. **対象フィールド** を見つける
    - `関連レコード一覧.condition.field`
1. **参照先フィールド** を見つける
    - `関連レコード一覧.condition.relatedField`
1. **ソート条件** を見つける
    - `関連レコード一覧.sort`
1. **表示件数** を見つける
    - `関連レコード一覧.size`
1. **表示する(取得する)フィールド** を見つける
    - `関連レコード一覧.displayFields`
1. これらをクエリにはめる

## コード

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

ちなみに、API実行部分は、[kinton JS SDK](https://developer.cybozu.io/hc/ja/articles/360025484571) を使っています！
(パラメータが省略できたり、便利です)

```javascript

(() => {
  '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);
    });
  });
})();

```

# おわりに

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

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

<br/><br/>

・・・。

<br/><br/>

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

それでは！≧(+･` ཀ･´)≦