forEachを使用した別アプリへの値更新

お世話になっております。

レコード一覧画面上に設置したボタンを押した時、表示されているレコードの該当フィールドの値が、在庫アプリにある該当レコードのフィールドに加減されて更新されるというイベントを書いています。

しかし反復処理が順に行われているにも関わらず、在庫アプリの値がうまく更新されません。

以下ソースコードのどういったところが「エラー情報」にて記載させていただきました、

結果のようになってしまっているのか、ご指摘いただけますと幸いです。

よろしくお願いいたします。

 

背景・実現したいこと

「データ確定」ボタン押下時の在庫データ連携

《詳細》

以下の条件で在庫アプリの「未検査在庫」の値を更新
<更新元対象>
・ボタン押下時の一覧に表示されている(もしくは一覧と同じ条件で絞込)レコード
<更新先対象>
・機材コードが等しいレコード
・「機材在庫データ」の「月末日」と「バーコード読込データ」の「入出荷日」の月が等しい
<条件>
・「連携フラグ」が”連携済”ではない
・「状態」が”在庫”
・「データ区分」が”入荷”
・「目的」が以下のどれか
交換 / 減少 / 閉店 / 入替 / その他
・「検査フラグ」が”要検査”
<加減>
・「数量」を加算

 

エラー情報 (開発者ツールのコンソール)

 該当レコード数分加算されるはずが加算されない。

 

利用したソースコード

 //イベントが発生するタイミング
  const eventFields = [
      'app.record.index.show',
      'app.record.index.edit.submit.success'
    ];

  kintone.events.on(eventFields,event => {
     confirm_btn();
     return event;
    });

function confirm_btn() {
  if(document.getElementById('confirm_button') !== null) {
      return;
  }
  const createButton = document.createElement('button');
  createButton.id = 'confirm_button';
  createButton.classList.add('gaia-ui-actionmenu-save');
  createButton.innerHTML = 'データ確定';
  createButton.style.width = '180px';
  createButton.style .height = '0 16px';
  createButton.onclick = () => {
      if(createButton.innerHTML === 'データ確定') {
          if(window.confirm('表示されているデータを確定データとして登録します。')) {
              //ボタンの表示切替(データ処理実行中)
              createButton.innerHTML = '実行中';

              //イベント発生用関数
              toConfirm();
           }
       } else {
           alert(`${createButton.innerHTML}です。`)
       }
      createButton.innerHTML = 'データ確定';
  }
  kintone.app.getHeaderMenuSpaceElement().appendChild(createButton);
}


async function toConfirm() {
      //条件に該当する「バーコード読込データ」の取得パラメ
      const getBarcode = {
          'app': kintone.app.getId(),
      }
      //「バーコード読込データ」一覧のレコードを取得
      const getRecords =  await kintone.api(kintone.api.url('/k/v1/records', true), 'GET', getBarcode);
      const grRecords = getRecords.records;
    await uninspected(grRecords); //未検査在庫の更新
}


async function uninspected(grRecords) {

   //条件に該当する「バーコード読込データ」の取得
  const grUninspectedRecords = grRecords.filter(value => {
      return value.連携フラグ.value === '-' &&
             value.状態.value === '在庫' &&
             value.データ区分.value === '入荷' &&
             (value.目的.value === '交換' || value.目的.value === '減少' ||value.目的.value === '閉店' ||
              value.目的.value === '入替' || value.目的.value === 'その他') &&
             value.検査フラグ_0.value === '要検査'
    });

  if(grUninspectedRecords.length === 0) {
      return;
    }

  grUninspectedRecords.forEach(async record => {
      //入出荷日の月末日算出
      const dt = new Date(record.入出荷日.value);
      const ldt = new Date(dt.getFullYear(), dt.getMonth() + 1, 0);
      //取得した月末日のフォーマットを形成
      const y = ldt.getFullYear();
      const m = ("00" + (ldt.getMonth()+1)).slice(-2);
      const d = ('00' + ldt.getDate()).slice(-2);
        const eom = `${y}-${m}-${d}`;

      //機材コード
      const equipmentCode_repair = record.機材コード.value;

      //条件に該当する「未検査在庫」の取得パラメ
      const getStock_uninspected = {
          'app': squipmentStocksAppId,
          'query': `機材コード = "${equipmentCode_repair}" and 月末日 = "${eom}"`
      }

      //「機材在庫データ」取得
      const getStockRecords_uninspected = await kintone.api(kintone.api.url('/k/v1/records', true), 'GET', getStock_uninspected);
      const gstUninspectedRecords = getStockRecords_uninspected.records;
        console.log(gstUninspectedRecords);

      if(gstUninspectedRecords.length === 0) {
          return;
        }

      //未検査在庫 + 数量
      const addStocks_un = Number(gstUninspectedRecords[0].未検査在庫.value) + Number(record.数量.value);
        console.log(`未検査在庫:${addStocks_un}`);

      //「未検査在庫」入荷更新用パラメ
      const putAddStock_uninspected = {
          'app': squipmentStocksAppId,
          'id': gstUninspectedRecords[0].$id.value,
          'record': { '未検査在庫': {value: addStocks_un} }
        }

      //「未検査在庫」の更新
      try {
          await kintone.api(kintone.api.url('/k/v1/record', true), 'PUT', putAddStock_uninspected);
      } catch (error) {
          alert(error);
          console.log(error);
        }

    });

    return grRecords;

}

全て見たわけではありませんが、forEachによるループでasync/awaitをそのまま使うことはできません。

使用できるようにする方法 もありますが、簡単な方法だとforループに変えるか、Promise.allを使う方法が良いと思います(参考 )。

mls-hashimoto 様

いつも大変お世話になっております。

forEachでasync/awatを使うには少し工夫が必要だったんですね。

参考資料、アドバイス共に大変勉強になりました。

今回はforを使って実装してみたところスムーズに理想通りに動きました。

本当にありがとうございます。

今回もとても助かりました!!