別アプリからのレコード情報の取得

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

類似投稿を読み、いろいろ試してきましたが解決に至らず、投稿いたしました。

 

やりたいこと

アプリA

アプリID 67

申請者名 文字列1行

勤務形態 ドロップダウン(”出勤”、”有休”)

残業時間 数値(分単位で記入しています)

アプリB

社員名 ユーザ選択

出勤日数 数値

残業時間 数値

があります。

このとき、アプリB:社員名=アプリA:申請者名である

アプリAのレコードを取得し、

アプリA:勤務形態=”出勤”のレコードの数をアプリB:出勤日数に、

アプリA:残業時間の総和をアプリB:残業時間に出力したいと考えております。

 

まずは出勤日数だけ出力してみようと

下記Scriptを作成しましたが、うまくいきません。

お手数をおかけいたしますが、どこを修正すればいいか教えていただけないでしょうか。

コードからお察しいただけるかと思いますが、Kintone、JavaScriptともに初心者です。

 

(function() {
    “use strict”;
    var events = [
        “app.record.create.show”, “app.record.edit.show”, “app.record.index.edit.show”
    ];
    kintone.events.on(events, function(event) {
        var record = event.record;
        var appId = 67;
        var recordId = record[‘対象社員’].value[0].name;
        
        
        kintone.api(‘/k/v1/records’, ‘GET’, {
            app: appId,
            query: ‘申請者1 = "’ + recordId + ‘"’,
            fields: [‘勤務形態’,‘残業時間’],
        },
        function(resp) {
            var iDayCnt = 0;
            
            for (var i = 0; i < resp.totalCount; i++) {
                if(resp[‘records’][i][‘勤務形態’][‘value’] === “出勤”){
                    iDayCnt++;
                }
            }
            
             record[‘出勤日数’][‘value’]=iDayCnt;
           
        });
        
        return event;
    });
})();
       

 

aki さん

気になったところを上げてみます。

・アプリA タイムカード、 アプリB 月次勤務管理

アプリ名があると理解しやすく、処理もイメージしやすくなります。

勤務管理であれば、たぶん月の管理が必要だと思います。

・アプリB(月次勤務管理)に申請月(日付項目)を追加

勤務の締め日によって、対象月の範囲が変わりますが申請月単位で管理します。

・アプリA(タイムカード) 申請者名(文字列1行)を 申請者(ユーザー選択)に変更(規定値をログインユーザー)

アプリA(タイムカード)とアプリB(月次勤務管理)で、社員を扱う項目は同じ形式にしましょう。

申請者名だと、同姓同名問題が発生します。 文字列だと、入力ミスもあります。

 

・変数名は、中身にあったものをつけましょう。

var recordId = record[‘対象社員’].value[0].name;

社員名なら、recordId ではなく、employeeName 等の中身をあらわす名称にしましょう。

英語にこだわらずに、ローマ字でもいいと思います。

・配列の長さチェック

record[‘対象社員’].value[0]

配列の要素を参照する場合は、要素が存在するかチェックしましょう。

ユーザー選択であれば、マニュアルで選択を解除することもできます。

 

・ resp.totalCount について

for (var i = 0; i < resp.totalCount; i++) {

resp.totalCount は、kintone のアプリ上の対象レコード件数をあらわします。

API 呼び出し時、totalCount: true オプションを指定しないと値が設定されません。

実際に取得したレコード数を示すのは、resp.records.length になります。

API の規定値で レコード取得した場合は、最大 100 レコードになります。

対象レコード件数が 100 以上の場合、 resp.totalCount と resp.records.length が異なります。

今回は、社員別の勤務レコードなので、どちらでも同じ数値になると思いますが、意味が異なりますので使い分けましょう。

・ レコードの更新処理

record[‘出勤日数’][‘value’]=iDayCnt;

kintone.api は、非同期処理ですので、api が完了した時点では イベント処理が完了しています。

そのため、 event.record を書き換えても 実際の画面表示には反映されません。

"app.record.create.show"等は、Promise 非対応なので、api の完了を待ってからイベント処理を終了することもできません。

対応としては、kintone.app.record.set 関数を使って、画面表示を変更します。

 

・サンプルアプリイメージです。

勝手なイメージですので、運用に合わせてカスタマイズしてください。

 

 

 

・サンプルコード

勤務日数部分だけ実装してみました。

日付処理のため、moment.js を使っています。

参考 Moment.js を利用して、日時フィールドのフォーマットをカスタマイズする

 

/*
* 勤務管理集計サンプル
*/
(function() {
"use strict";

const TIMECARD_APPID = 281; // タイムカードアプリ

var events = [
"app.record.create.show", "app.record.edit.show", "app.record.index.edit.show",
"app.record.create.change.対象社員",
"app.record.edit.change.対象社員",
"app.record.index.edit.change.対象社員",
"app.record.create.change.申請月",
"app.record.edit.change.申請月",
"app.record.index.edit.change.申請月",
];
kintone.events.on(events, function(event) {
var record = event.record;
record['出勤日数']['disabled'] = true;
record['出勤日数']['value'] = 0;

moment.locale('ja');

// 勤務集計処理
if (!errCheck(record)) {
var employees  = record['対象社員'].value[0].code
var startOfDate = moment(record['申請月'].value).startOf('month').format('YYYY-MM-DD');
var endOfDate = moment(record['申請月'].value).endOf('month').format('YYYY-MM-DD');
var query = '申請者 in (" USER", "' + employees + '")';
query += ' and 日付 >= "' + startOfDate + '"';
query += ' and 日付 <= "' + endOfDate + '"';
var param = {
app: TIMECARD_APPID,
query: query,
fields: ['勤務形態', '残業時間'],
};
kintone.api('/k/v1/records', 'GET', param).then(function(resp) {
var iDayCnt = 0;
for (var i = 0; i < resp.records.length; i++) {
if (resp['records'][i]['勤務形態']['value'] === "出勤") {
iDayCnt++;
}
}
record['出勤日数']['value'] = iDayCnt;
kintone.app.record.set({ record: record });
}).catch(function(error) {
console.log('record get err', error);
alert('タイムカードレコード取得エラー');
});
}

return event;
});

// レコードエラーチェック
function errCheck(record) {
var err = false;
if (record['対象社員'].value.length !== 1) {
record['出勤日数']['value'] = 0;
record['対象社員'].error = '1申請者を指定します';
err = true;
}
else {
record['対象社員'].error = null;
}
if (!record['申請月'].value) {
record['申請月'].error = '必須';
err = true;
}
else {
record['申請月'].error = null;
}
return err;
}
})();

rex0220様

コードの間違いの指摘にとどまらず、

アプリ作成のノウハウまで教えていただきありがとうございます。

また、昨日まで出張だったため、返信が遅くなったことお詫び申し上げます。

 

さっそく、いただいた情報をもとにアプリを作成しなおしたいと思います。

作成する中で、またご相談させていただく場合もあるかもしれませんが、

その際はお時間の許す範囲でご支援いただけますと幸いです。

 

ひとまず、いただいた情報を用いて自力で頑張ってみます。

 

以上、よろしくお願いいたします。