kintone REST APIの絞り込みについて

お世話になります。

現在、スケジュールアプリの作成を行っています。

その中で、入力中のレコードの保存時(新規、修正どちらも)に、

過去レコードとのスケジュールの重複チェックを行う部分があります。

もしスケジュールの開始日時と終了日時の範囲が過去レコードと重なっていた場合、

保存処理のキャンセルを行います。

イメージとしては、

【登録OK】

レコード A: 開始8/21 9:00 ~ 終了8/21 10:00
レコード B: 開始8/21 10:00 ~ 終了8/21 11:00

【登録NG】

レコード A: 開始8/21 9:00 ~ 終了8/21 10:07
レコード B: 開始8/21 10:00 ~ 終了8/21 11:00

というような形です。

一応以下に記載している内容でも動きはするのですが、アプリ内にあるレコードを全件取得している現在の内容から、条件に該当するレコードのみを取得して重複チェックを行うように改善が可能であると知りました。

方法として、レコードの取得時にqueryを用いて絞り込みを行うのかと考えているのですが、なかなかうまくいきません。

ご教授いただければ幸いです。

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

(function(){

    "use strict";

    kintone.events.on(["app.record.create.submit","app.record.edit.submit"],function(event){

        //開始日時、終了日時の値とレコードIDを取得
        const start = new Date(event.record["開始日時"].value);
        const finish = new Date(event.record["終了日時"].value);
        const recordId = event.recordId;

        //定数startが定数finishを上回っていた場合、レコードの修正、保存をキャンセルする
        if(start > finish){
            alert("日付範囲に誤りがあります。");
            return false;
        };

        //---レコードの修正、保存時に他のレコードとスケジュールが重複していた場合、保存をキャンセルする。---

        //レコードの一括取得を行う際のリクエスト内容(パラメーター)
        let body = {
            "app":event.appId,
            "fields":["開始日時","終了日時","$id"]
        };

        //レコードの一括取得時の命令文
        return kintone.api(kintone.api.url("/k/v1/records", true), "GET", body).then(function(resp){

            //変数iがレコードのかすより少ない場合、+1を繰り返す
            for(let i = 0; i < resp.records.length; i++){

                const start_log = new Date(resp.records[i]["開始日時"].value);
                const finish_log = new Date(resp.records[i]["終了日時"].value);
                const record_log = resp.records[i].$id.value;

                //入力中のレコードの開始日時が過去レコードの終了時間よりも先で
                //終了日時が過去レコードの開始日時より後で、
                //レコードIDが同じではない場合、保存をキャンセルする。
                if(start < finish_log && finish > start_log && recordId != record_log){
                    alert("スケジュールがかぶっています。保存できません。");
                    return false;
                };

            };

            return event;

        });

    });

})();

 

 

マツさん

こんにちは。ひよこです。

改善前のコード、ありがとうございます!どんなことをやりたいかイメージ付きました!

 

クエリの書き方は、以下の記事が参考になるとおもいます。

 

また、マツさんが行いたい絞り込みの場合、ポイントが2つあると思っています。

  • 日時フィールドに対して絞り込みをするとき、比較する値には、event.record[‘開始日時’].value を使う
    つまり、new Date() で Date 型に変換した値を使わない。

  • event.type が app.record.edit.submit のときだけ、「自身のレコードではない」という条件を入れるようにする
    「app.record.create.submit」イベントでは、event.recordId(自分自身のレコードID)がありません。
    なので、不正なクエリになってしまい、kitnone.api() の実行結果がエラーとなります。

ひよこさん

コメントありがとうございます。

コメント頂いた内容を元に一括取得時のパラメータを書き換えてみたのですが、うまく動きません…。

 

        //レコードの一括取得を行う際のリクエスト内容(パラメーター)

        const start_ol = event.record["開始日時"].value;

        const finish_ol = event.record["終了日時"].value;

        let body = {

            "app":event.appId,

            "query":"開始日時 >= " + finish_ol,

            "fields":["開始日時","終了日時","$id"]

        };

また「event.type が app.record.edit.submit のときだけ、「自身のレコードではない」という条件を入れるようにする」

の点に関してですが、これはif文か何かで追加するということでいいのでしょうか…?

 

プログラム初心者なので、もし当たり前のことを聞いていたらご容赦ください…。

マツさん

ひよこです。

比較する値である finish_ol は "(ダブルクォート)でくくる必要があります。

なので、こんな感じにします。
元のクエリ部分はダブルクォートで囲っていましたが、文字としてのダブルクォートを使いたい場合は、シングルクォートで囲みます。

  "query":'開始日時&nbsp;\>= "' + finish_ol + '"',

とすると、「開始日時 >= “2020-09-10T07:58:00Z” 」のようになります。

> また「event.type が app.record.edit.submit のときだけ、「自身のレコードではない」という条件を入れるようにする」
> の点に関してですが、これはif文か何かで追加するということでいいのでしょうか…?

はい、そうです。
イメージとしては、こんな感じです。

if 文など、JavaScript の基本的な構文については、はじめよう JavaScript というチュートリアルが有るので、ぜひ見てみてください。

let query ='開始日時&nbsp;\>= "' + finish_ol + '"'; // 日時に関するクエリ
if (event.type === 'app.record.edit.submit') {
// event.type が app.record.edit.submit のときは、追加の条件を文字列結合する
query = query + ' and 自分のレコードではないという条件';
}
const body = {
"app":event.appId,
"query": query,
"field": ["開始日時","終了日時","$id"]
};

ひよこさん

コメントありがとうございます。

頂いたアドバイスを元に改めて試してみます。