見出し画像

Kintoneアプリで月末日をセットしたい

Kintoneのカスタマイズ要望のお話です。
よくある相談事に「本日を基準に月末日、翌月末日をセットしたい」という要望があります。
これは、月末日を基準に納品や請求の締日処理を行うためです。
各レコードに月末締日があれば、一覧表の検索条件等に利用できます。
月末日は年や月の条件(うるう年の2月、大の月の1,3,5,7,8,10,12月など)によって変化するので、計算フィールドのIF関数や日付の計算式だけでは全てのパターンを処理できません。
Excelなら「=EOMONTH (開始日 , 月)」で簡単に計算できるのですが、Kintoneには、その様な関数は未実装です(2023年9月10日現在)

【結論】
Kintoneの標準機能だけでは実現するのが困難です。
日付の計算条件が複雑になる上、計算結果をDATE_FORMA関数を用いて整形すると文字列として扱われるので、日付の計算や検索条件に使えません。
しかし、Javascriptによるカスタマイズ機能で「実現可能」です。

上記のデモ画面では、日付フィールドの値を基準に、前月末日、当月末日、翌月末日を計算しています。「うるう年」の2月末日も正しく計算します。
2020年の3月は、前月末日を「2020-02-29」と計算しています
2022年の3月は、前月末日を「2022-02-28」と計算しています

前提条件として、以下の準備が必要です。

アプリのフォームの日付型フィールドに「フィールドコード」を設定する
アプリのフォームに各月末日の日付型フィールドと「フィールドコード」を設定する
CDNにある日付処理ライブラリ(Luxon)のURLを利用する

https://cybozu.dev/ja/kintone/sdk/library/cybozu-cdn/

CDNライブラリのluxonを使用する方法は、以下のページをご覧ください。

月末日を計算するJavascriptコード

/*
 * 月末日を計算 Luxonライブラリを利用
 */

(function() {
    "use strict";
    
    // Kintoneフォームのフィールドコードをセット
    const DATE_FIELD_CODE 	 = '日付';
    const PREV_MONTH_END_CODE 	 = '前月末日';
    const CURRENT_MONTH_END_CODE = '当月末日';
    const NEXT_MONTH_END_CODE 	 = '来月末日';

    // Luxonのライブラリを読み込む前提
    const { DateTime } = luxon;

   //日付フィールドの値で、先月末日、今月末日、来月末日を計算
    const calculateDates = (record) => {

	//日付が空白ならリターン
        if (!record[DATE_FIELD_CODE].value) return; 

	//レコードの「日付」フィールドの値を変数にセット
        const inputDate = DateTime.fromISO(record[DATE_FIELD_CODE].value);
        
	//先月末日の計算
        const prevMonthEnd = inputDate.minus({ days: inputDate.day }).toISODate();
	//今月末日の計算
        const currentMonthEnd = inputDate.endOf('month').toISODate();
	//来月末日の計算
        const nextMonthEnd = inputDate.plus({ months: 1 }).endOf('month').toISODate();

        return {
            [PREV_MONTH_END_CODE]: prevMonthEnd,
            [CURRENT_MONTH_END_CODE]: currentMonthEnd,
            [NEXT_MONTH_END_CODE]: nextMonthEnd
        };
    };

   // 指定のフィールドコードに計算結果の日付をセット
    const setCalculatedDates = (event) => {
        const record = event.record;
        const calculatedDates = calculateDates(record);
        
        if (calculatedDates) {
	    //先月末日のセット
            record[PREV_MONTH_END_CODE].value = calculatedDates[PREV_MONTH_END_CODE];
	    //当月末日のセット
            record[CURRENT_MONTH_END_CODE].value = calculatedDates[CURRENT_MONTH_END_CODE];
	    //来月末日のセット
            record[NEXT_MONTH_END_CODE].value = calculatedDates[NEXT_MONTH_END_CODE];
        }

        return event;
    };

    // 新規登録&編集画面で日付フィールドが変更されたときのイベントハンドラ
    kintone.events.on(`app.record.create.change.${DATE_FIELD_CODE}`, setCalculatedDates);
    kintone.events.on(`app.record.edit.change.${DATE_FIELD_CODE}`  , setCalculatedDates);

})();

上記のコードでは、新規登録画面と編集画面で、日付フィールドの値が変更されたときに月末日を計算する関数が動作する様に設定しています。
月末日をセットしたい際のご参考にしてください。

前月末日、当月末日、翌月末日のうち、自社の運用上不必要なフィールドはグループフィールドに放り込んで非表示にしておけば、運用面で大きな弊害はありません。
不必要なフィールドコードの処理部分を削除して利用して頂いてもいいのですが、編集ミスでエラーが出る可能性がありますので、Javascriptカスタマイズ未経験者には非推奨です。

よろしければサポートお願いします! いただいたサポートは、note記事制作の活動費に使わせていただきます!