kintone で安全に在庫管理を行うテクニック

著者名:竹内 能彦(サイボウズ株式会社)

目次

warning
注意

このカスタマイズで利用している kintone JS SDK は現在推奨されていません。
今後は kintone JavaScript Client (@kintone/rest-api-client) を利用するように書き換えてください。

はじめに

今回は以前紹介させていただいた「 bulkRequest で複数アプリの一括処理(在庫管理や予約申請など)」を kintone アプリに実装します。
理解しやすいように在庫アプリと出庫アプリの 2 つを利用します。
「出庫アプリから XX 個出庫すると在庫アプリの在庫が XX 個減る」というカスタマイズを行います。

また、 kintone JS SDK を使うことで REST API 部分のコードを簡素化しています。
非常に便利ですのでこれからコードを書く人はぜひ使ってくださいね。

デモ環境

デモ環境 (External link) で実際に動作を確認できます。
ログイン情報は cybozu developer network デモ環境 で確認してください。

完成イメージ

まずは、完成イメージからいきましょう!
在庫アプリはこのような状態です。

出庫アプリに出庫数を登録します。

すると、出庫アプリには出庫数が登録されます。

また、在庫アプリからは在庫数が減りました!

在庫が足りない場合は、このようなエラーを表示します。

①「在庫数の確認時」と②「在庫数の変更時」のリビジョンが異なる場合(①と②の間に在庫のデータが更新された場合)はこのようなエラーを表示します。

これで安全に在庫管理ができますね。

kintone の設定

「在庫」アプリの作成

フィールド名 フィールドタイプ フィールドコード 備考
商品コード 文字列(1 行) itemCode 必須項目にする
値の重複を禁止する
商品名 文字列(1 行) itemName 必須項目にする
在庫数 数値 stockNum 必須項目にする

「出庫」アプリの作成

フィールド名 フィールドタイプ フィールドコード 備考
出庫先 文字列(1 行) destination
商品コード ルックアップ itemCode 必須項目にする
関連付けるアプリ:在庫アプリ
コピー元のフィールド:商品コード
ほかのフィールドのコピー:「商品名」に「在庫アプリの商品名」
商品名 文字列(1 行) itemName
出庫数 数値 pickNum 必須項目にする

「出庫」アプリのJS/CSS設定

「アプリの設定 > JavaScript / CSS でカスタマイズ」の「PC 用の JavaScript ファイル」に以下の URL/ファイルを設定します。

  • kintone-js-sdk.min.js
    GitHub (External link) にアクセスして、zip ファイルをダウンロードします。
    v0.4.2 より前のバージョンを利用してください。
    ダウンロードした Zip ファイルを解凍して、dist 以下の kintone-js-sdk.min.js を利用してください。
  • 以下のサンプルコードをエディタにコピーして、ファイル名を「sample.js」、文字コードを「UTF-8N」で保存、アップロードします。
    ファイル名は任意ですが、ファイルの拡張子は「js」にしてください
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
/*
 * kintone で安全に在庫管理を行うサンプルプログラム
 * Copyright (c) 2017 Cybozu
 *
 * Licensed under the MIT License
 * https://opensource.org/license/mit/
*/
(() => {
  'use strict';

  kintone.events.on('app.record.create.submit', (event) => {
    const record = event.record;

    const pickNum = Number(record.pickNum.value); // 出庫数
    const destination = record.destination.value; // 出庫先
    const itemCode = record.itemCode.value; // 商品コード
    const itemAppId = kintone.app.getLookupTargetAppId('itemCode'); // 商品アプリのアプリID

    // kintone JS SDK
    const con = new kintoneJSSDK.Connection();
    const kintoneRecord = new kintoneJSSDK.Record(con);

    // 商品アプリから在庫数を取得
    return kintoneRecord
      .getRecords(itemAppId, 'itemCode = "' + record.itemCode.value + '"', ['$id', '$revision', 'stockNum'], false)
      .then((getRes) => {
        if (getRes.records.length !== 1) {
          event.error = '商品が特定できません。';
          return event;
        }

        const stockRecord = getRes.records[0];
        const recordId = stockRecord.$id.value;
        const recordRevision = stockRecord.$revision.value;
        const stockNum = Number(stockRecord.stockNum.value); // 現在の在庫数

        const newStockNum = stockNum - pickNum; // 出庫後の在庫数
        if (newStockNum < 0) {
          event.error = '在庫が足りません。今の在庫数は' + stockNum + 'です。';
          return event;
        }

        // 在庫アプリのアプリID
        const warehouseAppId = kintone.app.getId();
        // 商品アプリの在庫数を更新し、出庫アプリに出庫情報を登録
        const stock = {
          stockNum: {value: newStockNum}
        };
        const warehouse = {
          destination: {value: destination},
          itemCode: {value: itemCode},
          pickNum: {value: pickNum}
        };

        const kintoneBulkRequest = new kintoneJSSDK.BulkRequest(con);
        const responseBulkRequest = kintoneBulkRequest
          .updateRecordByID(itemAppId, recordId, stock, recordRevision)
          .addRecord(warehouseAppId, warehouse)
          .execute();

        // 実行
        return responseBulkRequest
          .then((postRes) => {
            // bulkRequestで登録した詳細ページに移動
            location.href = '/k/' + warehouseAppId + '/show#record=' + postRes.results[1].id;
            // 登録画面のレコードは保存しない
            return false;
          })
          .catch((error) => {
            console.log(error);
            event.error = '出庫に失敗しました。';
            return event;
          });
      })
      .catch((error) => {
        console.log(error);
        event.error = '商品を取得できませんでした。';
        return event;
      });
  });
})();

ポイントは以下の 3 つです!

  • bulkRequest(kintoneBulkRequest)を使って、2 つのアプリ(在庫、出庫)を同時に操作します。
  • bulkRequest による在庫アプリの更新時にはリビジョンを指定します。
  • bulkRequest が成功した場合は「return false」として、レコードの登録自体はキャンセルします。(67 行目)

終わりに

リビジョンの使い方わかりましたでしょうか。
サンプルコードはレコードの登録、出庫にしか対応していません。
ぜひレコードの編集や入庫にも対応させてみてください。

変更履歴

  • 2019/06/10
    • 利用ライブラリを kintone Utility Library for JavaScript から kintone JS SDK に変更
information

この Tips は、2019 年 5 月版 kintone で動作を確認しています。