kintoneでの在庫管理方法について

kintoneで安全に在庫管理を行うテクニック(下記)にて設定を行い、出来るようになりました。

出庫の商品コード・商品名・出庫数をテーブルで複数入力を行って、在庫に反映させることはできないでしょうか。
ご教示よろしくお願いいたします。
kintoneで安全に在庫管理を行うテクニック - cybozu developer network

テーブルのデータをループさせて処理すればよいのだと思うのですが

たとえば
注文が
商品A 30個
商品B 20個
だったときに
在庫は
商品A 500個
商品B 10個
だったとき

商品Aは問題なしですが、商品Bは在庫が足りません。
この場合、
・注文全体をキャンセルしますか?
・商品Aのみは完了しますか?
・商品Bの在庫限界まで在庫を割り当てますか?
・在庫がなかった10個の情報はどこに記録しますか?

ご連絡ありがとうございます。
どちらかの在庫が無い場合は、登録できないようになれば問題ありません。
よろしくお願いいたします。

もし、
商品Aを出庫処理したあとに
商品Bの在庫が足りないとわかったときに
商品Aの出庫を巻き戻す必要があって
これが10行だったら

それなら、先に
在庫チェックを先にして
とおもっていたら、
ほかの誰かが在庫を動かしていて

というわけで、
在庫管理は専用ソフトを使うこともご検討ください。

kintoneで出勤簿や在庫管理を作るよりも
市販のサービスを使った方が便利でトータルでみて安価だと思います。

ご連絡ありがとうございます。
今のところ、在庫がある分しか出庫させる運用と出庫させる場所も1箇所のみで考えています。
よろしくお願いいたします。

テーブルのフィールドコードは「テーブル」にしています。
「商品コード・商品名・出庫数をテーブルで複数入力を行って」とあるので、これに含まれない出庫先はテーブル外に置いています。
前回トピックに倣って、出庫先はルックアップにしています。
一か所でも在庫より多く出庫しようとしている行があったら、エラーを出して何もしません。
在庫不足エラーは複数出る可能性があるので、出し方を画面上部にエラーを表示するから フィールドにエラーを表示するに変えています。

(() => {
  'use strict';

  // レコード追加時のイベント
  kintone.events.on('app.record.create.submit', async (event) => {
    // 出庫アプリのレコードを取得
    const outBoundRecord = event.record;

    // 参照するアプリのIDを取得
    const stockAppId = kintone.app.getLookupTargetAppId('itemCode'); // 在庫アプリID
    const outBoundAppId = kintone.app.getId(); // 出庫アプリID

    // 出庫先とテーブルのレコードを取得
    const destination = outBoundRecord.destination.value; // 出庫先
    const tableRecords = outBoundRecord.テーブル.value; // テーブルのレコード

    try {
      // Kintone APIクライアントのインスタンスを生成
      const client = new KintoneRestAPIClient();
      const requests = []; // 一括リクエスト用の配列
      let hasError = false; // エラーフラグ

      // テーブル内の各行を処理
      for (const row of tableRecords) {
        const itemCode = row.value.itemCode.value; // 商品コード
        const pickNum = Number(row.value.pickNum.value); // 出庫数

        // 在庫アプリから該当商品の在庫情報を取得
        const { records: stockRecords } = await client.record.getRecords({
          app: stockAppId,
          query: 'itemCode = "' + itemCode + '"', // 商品コードで検索
          fields: ['$id', '$revision', 'stockNum'] // レコード番号、リビジョン、在庫数を取得
        });

        // 商品コードでの検索結果が1件でなかった場合はエラーを返す
        if (stockRecords.length !== 1) {
          row.value.itemCode.error = `商品が特定できません: ${itemCode}`; // エラーメッセージ設定
          hasError = true; // エラーフラグを立てる
          continue; // 次の行へ
        }

        const stockNum = Number(stockRecords[0].stockNum.value); // 現在の在庫数
        const newStockNum = stockNum - pickNum; // 出庫後の在庫数を計算

        // 在庫不足の場合のエラーハンドリング
        if (newStockNum < 0) {
          row.value.pickNum.error = `在庫が足りません。${itemCode} の現在の在庫数は ${stockNum} です。`;
          hasError = true; // エラーフラグを立てる
          continue; // 次の行へ
        }

        // 在庫更新のリクエストを一括リクエストに追加
        requests.push({
          method: 'PUT',
          api: '/k/v1/record.json',
          payload: {
            app: stockAppId,
            id: stockRecords[0].$id.value, // 更新するレコードのレコード番号
            record: {
              stockNum: { value: newStockNum } // 出庫後の在庫数
            },
            revision: stockRecords[0].$revision.value // リビジョン番号
          }
        });
      }

      // エラーがある場合は処理を中断
      if (hasError) {
        return event;
      }

      // 出庫アプリのレコード追加リクエストを一括リクエストに追加
      requests.push({
        method: 'POST',
        api: '/k/v1/record.json',
        payload: {
          app: outBoundAppId,
          record: {
            destination: { value: destination }, // 出庫先
            テーブル: { value: tableRecords } // テーブルのデータ
          }
        }
      });

      try {
        // 一括リクエストを実行
        const bulkResp = await client.bulkRequest({ requests });

        // 正常に処理が完了した場合、追加したレコードのレコード詳細画面にリダイレクト
        location.href = '/k/' + outBoundAppId + '/show#record=' + bulkResp.results[requests.length - 1].id;
        return false; // レコード追加はbulkRequest内で実行済みなので、デフォルトの追加イベントはキャンセル
      } catch (err) {
        // 在庫数の確認時と在庫数の変更時のリビジョンが違ってたらエラー
        console.log(err); // エラーをコンソールに出力
        event.error = '出庫に失敗しました。'; // エラーメッセージ設定
        return event;
      }
    } catch (err) {
      // 在庫アプリからのレコード取得に失敗したらエラー
      console.log(err); // エラーをコンソールに出力
      event.error = '商品を取得できませんでした。'; // エラーメッセージ設定
      return event;
    }
  });
})();
1 Like

ご連絡ありがとうございます。
いただいた内容に変更してみたのですが、テーブルデータは保存できました。
在庫アプリの方の在庫数が減りません。
どうすればいいでしょうか。
よろしくお願いいたします。

前提として、各アプリのフィールドは下図のような状態ですよね?
(赤文字はフィールドコード)
自分の環境では、これで在庫アプリの在庫数減少も起こってます。

ご連絡ありがとうございます。
てんそさんと同じに設定をしましたが、在庫数が減少しません。
よろしくお願いいたします。
image

出庫アプリの設定はこうなっていますか?

プラグインや、他のJavaScript/CSSファイルを適用していたら、それらを全部無効化して私のコードと競合してないか確かめましたか?

ブラウザのキャッシュクリアは試しましたか?

出庫アプリのレコード追加後に、在庫アプリはリロードしましたか?

このあたりをチェックしても駄目なら、こちらでは既に以下のgifのように出庫アプリのレコード追加時に在庫が減っているので、これ以上は助言のしようがありません。
Animation

ありがとうございます。
何度か試しても上手くいかなかったのですが、アプリを作り直しをしましたら、できました。
お手数をおかけしました。

このトピックはベストアンサーに選ばれた返信から 3 日が経過したので自動的にクローズされました。新たに返信することはできません。