カスタマイズ kintone 初心者向け:初めての JavaScript プログラムの作成(パート2)

パート1では、標準のkintoneが対応できない経費予測の問題を提起し、JavaScriptを使用してその問題を処理しました。
本記事では、使用したJavaScriptによる処理方法の詳細について説明します。
前回記事;カスタマイズ kintone 初心者向け:kintone で初めての JavaScript プログラムの作成(パート1)

以下は、使用した経費予測の計算式です。
標準のkintoneでは、今月経過した日数月の合計日数の2つの値を計算することができません。


JavaScriptのソースコードの詳細
ソースコードには、即時関数内に含まれる2つの主要な部分があります。
この記事では、経費予測の計算処理部分を説明します。月末に予算を超過する値を強調表示する部分は別の記事で説明します。


(() => {
  // 経費予測の計算処理。
  kintone.events.on([
    'app.record.create.change.経費',
    'app.record.create.change.年',
    'app.record.create.change.月',
    'app.record.edit.change.経費',
    'app.record.edit.change.年',
    'app.record.edit.change.月'
  ], (event) => {
    let record = event.record;
    let campaigns = record['リストキャンペーン'].value;
    let date = new Date().getDate();
    let year = record['年'].value;
    let month = record['月'].value;
    if (!year || !month) return event;
    let numberOfDaysInMonth = new Date(year, month, 0).getDate();
    for (let item of campaigns){
      let campaign = item.value;
      if (!campaign['経費'].value) continue;
      let estimates = Math.ceil(campaign['経費'].value * numberOfDaysInMonth / date);
      campaign['経費予測'].value = estimates;
    }
    return event;
  });
  // 月末に予算を超過する値を強調表示する。
  kintone.events.on([
      'app.record.detail.show'
  ], () => {
    let elementCampaigns = kintone.app.record.getFieldElement("リストキャンペーン");
    let tableBody = elementCampaigns.querySelector('tbody');
    let observer = new MutationObserver(function() {
      let record = kintone.app.record.get().record;
      let campaigns = record['リストキャンペーン'].value;
      let trTags = tableBody.querySelectorAll('tr');
      for (let [index, item] of campaigns.entries()){
        let campaign = item.value;
        if (+campaign['経費予測'].value > +campaign['予算'].value){
          let currentRow = trTags[index];
          let expenseForecastingElement = currentRow.querySelectorAll('td')[3].querySelector('.control-value-gaia')
        	expenseForecastingElement.style.color = 'red';
        }
      } 
    });
    let observerConfig = { childList: true };
    observer.observe(tableBody, observerConfig);
 });


経費予測の計算処理
経費予測の計算結果は、「経費予測」というデータフィールドに保存されます。計算プロセスでは、「経費」、「年」、「月」のデータフィールドからデータが使用されます。
最初に、kintone.events.on()関数を使用して、レコードの追加または編集時に、「経費」、「年」、「月」のデータフィールドの値が変更されたイベントを捕捉します。

'app.record.create.change.{fieldcode}' → レコード追加画面で、{fieldcode}の値が変更されたときに、イベントがトリガーされます。
'app.record.edit.change.{fieldcode}'   → レコード編集画面で、{fieldcode}の値が変更されたときに、イベントがトリガーされます。


その後、「経費」、「年」、「月」のフィールドの変更された値を取得し、計算を処理します。

// レコードのデータを格納するために、「record」変数を初期化します。
let record = event.record;

// キャンペーのンデータを格納するために、「campaigns」変数を初期化します。
//「campaigns」変数の各要素は、広告キャンペーンのテーブルの1行に対応します。
let campaigns = record['リストキャンペーン'].value;

// 現在の日付を格納するために、「date」変数を初期化します。
let date = new Date().getDate();
    
//レコード内の「」フィールドの値を格納するために、「year」変数を初期化します。
let year = record['年'].value;

// レコード内の「」フィールドの値を格納するために、「month」変数を初期化します。
let month = record['月'].value;

//「year 」と「month」の値が未定義の場合、計算は行われません。

if (!year || !month) return event;

// 月の合計日数を格納するために、「numberOfDaysInMonth」変数を初期化します。
let numberOfDaysInMonth = new Date(year, month, 0).getDate();

// それぞれの広告キャンペーンをループして、キャンペーンの経費予測を計算します。
for (let item of campaigns){

    // 現在ループしている広告キャンペーンのデータを格納するために、「campaign」変数を初期化します。
    let campaign = item.value;
      
    // もし広告キャンペーンに経費データがない場合、計算を行わず、次の広告キャンペーンに進みます。
    if (!campaign['経費'].value) continue;

    // 月末の広告キャンペーンの経費予測を計算するために、「estimates」変数を初期化します。結果は最も近い整数を切り上げ。
    let estimates = Math.ceil(campaign['経費'].value * numberOfDaysInMonth / date );

    // 計算された「estimates」の値をレコード内の「経費予測」データフィールドに格納します。
    campaign['経費予測'].value = estimates;
}

// レコードの計算後の経費予測値を返します。
return event;


以下は、JavaScriptのエラーがないかどうか確認するデバッグ方法を例示します。
ここではブラウザーのデバッグ機能を利用します。
キーボードのF12を押し、「Sources」 画面を開きます。
参照 ; kintone JavaScriptカスタマイズデバッグまとめ


記事を読んでいただきありがとうございます。
次の記事をお楽しみにお待ちください !