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;
}
})();