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で動作を確認しています。