Kintone API で組織情報一覧を取得してツリー構造化する

## 組織情報の取得

cybozu.com 共通設定で設定されている、組織情報を一覧で取得するには以下のように書けば良い。JSONで取得できる。

```javascript
async function getOrganizationInfo() {
    try {
        const response = await kintone.api('/v1/organizations', 'GET', {});
        return response.organizations;
    } catch (error) {
        throw error;
    }
}
```

レスポンスの中身は以下のようなオブジェクトとなる。ちなみに一番親にあたる組織の場合、'parentCode === null' となる。

```json
{
	"organizations": [
	    {
		"id": 5,
		"name": "org1",
		"code": "org1",
		"parentCode": "org3",
		"localName": "ln1",
		"localNameLocale": "en",
		"description": "desc1",
	    },
	    {
		"id": 6,
		"name": "org2",
		"code": "org2",
		"parentCode": "org3",
		"localName": "ln2",
		"localNameLocale": "zh",
		"description": "desc2",
	    },
	    {
		"id": 7,
		"name": "org3",
		"code": "org3",
		"parentCode": null,
		"localName": "ln3",
		"localNameLocale": "zh",
		"description": "desc3",
	    }
    ]
}
```

[参考：KintoneAPI公式ページ](https://developer.cybozu.io/hc/ja/articles/202124754-%E7%B5%84%E7%B9%94%E3%82%A8%E3%82%AF%E3%82%B9%E3%83%9D%E3%83%BC%E3%83%88API)


## 組織階層をツリー構造のデータに格納する

以前に私が書いた記事、[「Javascript でツリー階層をデータで持たせる」](https://qiita.com/es-row/items/4d654d4272564f8c5528)　で使ったアイディアを応用して組織情報をツリー構造のクラスインスタンスに持たせるようにすれば諸々カスタマイズの際に融通が効く。

### クラスの準備

```javascript

class Group {
    
    constructor(code, name) {
        this.code = code;
        this.name = name;
        this.parent = null;
        this.children = [];
    }

    addChild(child) {
        this.children.push(child);
        child.parent = this;
    }

    addChildren(childrenArray) {
        for (let i = 0; i < childrenArray.length; i++) {
            this.addChild(childrenArray[i]);
        }
    }

}
```

### 組織情報のツリー化

```javascript
async function createOrganizationTree() {

    try {

        // KintoneAPIで組織情報の取得
        const groups = await getOrganizationInfo();
    
        // APIのレスポンスから Groupクラスインスタンスを生成、parentCodeとセットにする
        // この時点では親子関係は構築されていない
        const arrayTmp = groups.map(eachGroup => {
            return {
            groupInstance : new Group(eachGroup.code, eachGroup.name), 
            parentCode : eachGroup.parentCode
            };
        });

        // parentCode の値が指定のものになっているGroupクラスインスタンスの配列を取得
        const searchInstanceByParentCode = function(code) {
            const returnArray = [];
            for (let i = 0; i < arrayTmp.length; i++) {
                const instance = arrayTmp[i].groupInstance;
                const parentCode = arrayTmp[i].parentCode;
                if (parentCode === code) {
                    returnArray.push(instance);
                }
             }
             return returnArray;
        }

        // 仮想のROOTを作ってすべてを配下におく
        const ROOT = new Group(null, 'ROOT');

        // 親子関係の構築
        for (let i = 0; i < arrayTmp.length; i++) {

            const eachGroup = arrayTmp[i].groupInstance;
            const childrenGroups = searchInstanceByParentCode(eachGroup.code);
            eachGroup.addChildren(childrenGroups);
            
            // 最上層組織はROOT直下に
            if (arrayTmp[i].parentCode === null) {
                ROOT.addChild(eachGroup);
            }
        }

        console.log(ROOT);
        return ROOT;

    } catch (e) {
        throw e;
    }

}
```

以上の処理をKintoneの何かしらのイベント処理の際に呼び出せば、ROOT配下にすべての組織がツリー構造になって格納される。