/** * 勤怠申請入力_内勤者用 - pvc-desktop-main.js */ (function () { "use strict"; /** * システムコントロールの情報 */ const systemInfo = { 休憩時間: 0, 通常業務時間: 0, 深夜_開始時間: 0, 深夜_終了時間: 0, 昼食休憩時間_開始: 0, 昼食休憩時間_終了: 0, 午前半休: 0, 午後半休: 0, 祝休日の休憩時間算出用1: 0, 祝休日の休憩時間算出用2: 0, 祝休日の勤務時間が8時間以上の場合の休憩時間: 0, 祝休日の勤務時間が6時間以上8時間未満の場合の休憩時間: 0, }; /** * 詳細画面表示時の処理を行います。 */ kintone.events.on( ["app.record.detail.show"], function ( /** @type {kintone.AppEvent__勤怠申請入力_内勤者用} */ event ) { setHiddenField(); return event; } ); /** * 新規登録・編集画面表示時の処理を行います。 */ kintone.events.on( ["app.record.create.show", "app.record.edit.show"], function ( /** @type {kintone.AppEvent__勤怠申請入力_内勤者用} */ event ) { const record = event.record; setDisabledField(record); setHiddenField(); setHiddenTableRowButton(); pvc.util.ui.showSpinner(); return getSystemControlRecord() .then(function (systemRecord) { pvc.util.ui.hideSpinner(); if (systemRecord != null) { setSystemControlField(systemRecord, record); setSystemInfo(record); } return event; }) .catch(function (error) { pvc.util.ui.hideSpinner(); console.error(error); alert("システムエラーが発生しました"); return event; }); } ); /** * 「申請年月」「氏名」変更時の処理を行います。 */ kintone.events.on( [ "app.record.create.change.申請年月", "app.record.edit.change.申請年月", "app.record.create.change.氏名", "app.record.edit.change.氏名", ], function ( /** @type {kintone.AppEvent__勤怠申請入力_内勤者用} */ event ) { const record = event.record; const sinseiNengetu = pvc.util.obj.toNumber(record.申請年月.value) || 0; if (isNengetuNum(sinseiNengetu) && record.氏名.value.length > 0) { kintone.Promise.resolve().then(function () { pvc.util.ui.showSpinner(); /** @type {{ record: kintone.AppRecord__勤怠申請入力_内勤者用 }} */ const r = kintone.app.record.get(); return existsDuplicateData(r.record) .then(function (isExists) { if (isExists) { // 重複するデータが既に存在する場合 alert("既に登録済です。"); return; } // 就業届テーブルにデータを作成 return setSyuugyouTodokeTable(r.record).then(function () { // 使用不可を設定 setDisabledField(r.record); // レコードに値を設定 kintone.app.record.set(r); }); }) .then(function () { // スピナーを非表示 pvc.util.ui.hideSpinner(); }) .catch(function (error) { pvc.util.ui.hideSpinner(); console.error(error); alert("システムエラーが発生しました"); }); }); } return event; } ); /** * 「就業届_開始時間」「就業届_終了時間」変更時の処理を行います。 */ kintone.events.on( [ "app.record.create.change.就業届_開始時間", "app.record.edit.change.就業届_開始時間", "app.record.create.change.就業届_終了時間", "app.record.edit.change.就業届_終了時間", ], function ( /** @type {kintone.AppEvent__勤怠申請入力_内勤者用} */ event ) { const record = event.record; // 就業届の計算 // @ts-ignore calcSyuugyouTodokeRowValue(event.changes.row.value); calcSyuugyouTodokeJikanGoukei(record); return event; } ); /** * 「就業届_理由」変更時の処理を行います。 */ kintone.events.on( [ "app.record.create.change.就業届_理由", "app.record.edit.change.就業届_理由", ], function ( /** @type {kintone.AppEvent__勤怠申請入力_内勤者用} */ event ) { const record = event.record; // 就業届の計算 // @ts-ignore calcSyuugyouTodokeRowValue(event.changes.row.value); calcSyuugyouTodokeJikanGoukei(record); calcSyuugyouTodokeKyuukaGoukei(record); return event; } ); /** * 「就業届_区分」変更時の処理を行います。 */ kintone.events.on( [ "app.record.create.change.就業届_区分", "app.record.edit.change.就業届_区分", ], function ( /** @type {kintone.AppEvent__勤怠申請入力_内勤者用} */ event ) { /** @type {kintone.AppRecord__勤怠申請入力_内勤者用["就業届"]["value"][0]} */ const changeRow = event.changes.row; // 区分Noと区分Typeの設定 setSyuugyouTodokeKubunNoAndType(changeRow); if (changeRow.value.就業届_区分.value === "0:休暇") { // 区分が「0:休暇」の場合開始時間と終了時間に"00:00"を設定 changeRow.value.就業届_開始時間.value = "00:00"; changeRow.value.就業届_終了時間.value = "00:00"; } return event; } ); /** * 新規登録・編集画面保存前の処理を行います。 */ kintone.events.on( ["app.record.create.submit", "app.record.edit.submit"], function ( /** @type {kintone.AppEvent__勤怠申請入力_内勤者用} */ event ) { const record = event.record; const sinseiNengetu = pvc.util.obj.toNumber(record.申請年月.value) || 0; if (!isNengetuNum(sinseiNengetu)) { event.error = "申請年月にYYYYMM形式の数値を入力してください。"; return event; } // 帳票用申請年月にYYYY/MM形式の文字列を設定する。 record.帳票用申請年月.value = (record.申請年月.value || "").slice(0, 4) + "/" + (record.申請年月.value || "").slice(-2); if ( record.登録完了.value.indexOf("レ") !== -1 && record.就業届.value.some(function (row) { return pvc.util.obj.isEmpty(row.value.就業届_区分.value); }) ) { event.error = "就業届の区分に入力漏れがあります。"; return event; } pvc.util.ui.showSpinner(); return existsDuplicateData(record) .then(function (isExists) { if (isExists) { event.error = "この申請年月のデータは既に登録済みです。"; } else { return getInneiMasterRecord(record.氏名.value[0].code).then( function (inneiRecord) { if (inneiRecord != null) { record.社員番号.value = inneiRecord.社員番号.value; } } ); } }) .then(function () { pvc.util.ui.hideSpinner(); return event; }) .catch(function (error) { console.error(error); event.error = "システムエラーが発生しました"; pvc.util.ui.hideSpinner(); return event; }); } ); /** * プロセス管理のアクション実行時の処理を行います。 */ kintone.events.on( ["app.record.detail.process.proceed"], function ( /** @type {kintone.AppEvent__勤怠申請入力_内勤者用} */ event ) { const record = event.record; const processInfo = pvc.env.app.勤怠申請入力_内勤者用.process; if ( event.status.value === processInfo.status.未申請 && (event.nextStatus.value === processInfo.status.所属課長承認 || event.nextStatus.value === processInfo.status.営業部確認担当者承認 || event.nextStatus.value === processInfo.status.所属部長承認) ) { // ステータスが「未申請」から「所属課長承認」または「営業部確認担当者承認」または「所属部長承認」になった時 record.申請日.value = pvc.util.date.format(new Date(), "yyyy-MM-dd"); } else if ( (event.status.value === processInfo.status.営業部確認担当者承認 && event.nextStatus.value === processInfo.status.所属部長承認) || (event.status.value === processInfo.status.技術部確認担当者承認 && event.nextStatus.value === processInfo.status.財務管理担当承認) ) { // ステータスが「営業部確認担当者承認」から「所属部長承認」、または「技術部確認担当者承認」から「財務管理担当承認」になった時 record.確認者.value = [ { code: kintone.getLoginUser().code, }, ]; record.確認日.value = pvc.util.date.format(new Date(), "yyyy-MM-dd"); } else if ( event.status.value === processInfo.status.所属課長承認 && (event.nextStatus.value === processInfo.status.所属部長承認 || event.nextStatus.value === processInfo.status.財務管理担当承認) ) { // ステータスが「所属課長承認」から「所属部長承認」または「財務管理担当承認」になった時 record.所属課長.value = [ { code: kintone.getLoginUser().code, }, ]; record.所属課長承認日.value = pvc.util.date.format( new Date(), "yyyy-MM-dd" ); } else if ( event.status.value === processInfo.status.所属部長承認 && (event.nextStatus.value === processInfo.status.技術部確認担当者承認 || event.nextStatus.value === processInfo.status.財務管理担当承認) ) { // ステータスが「所属部長承認」から「技術部確認担当者」または「財務管理担当承認」になった時 record.所属部長.value = [ { code: kintone.getLoginUser().code, }, ]; record.所属部長承認日.value = pvc.util.date.format( new Date(), "yyyy-MM-dd" ); } else if ( event.status.value === processInfo.status.財務管理担当承認 && event.nextStatus.value === processInfo.status.承認完了 ) { // ステータスが「財務管理担当承認」から「承認完了」になった時 record.財務管理.value = [ { code: kintone.getLoginUser().code, }, ]; record.財務管理承認日.value = pvc.util.date.format( new Date(), "yyyy-MM-dd" ); } else if (event.nextStatus.value === processInfo.status.未申請) { // ステータスが「未申請」になった(差し戻し)時 record.申請日.value = null; record.確認者.value = []; record.確認日.value = null; record.所属課長.value = []; record.所属課長承認日.value = null; record.所属部長.value = []; record.所属部長承認日.value = null; record.財務管理.value = []; record.財務管理承認日.value = null; } return event; } ); /** * フィールドの使用不可を設定します。 * @param {kintone.AppRecord__勤怠申請入力_内勤者用} record */ function setDisabledField(record) { // 合計項目の編集不可 record.有給休暇.disabled = true; record.病気休暇.disabled = true; record.振休_代休.disabled = true; record.特別休暇.disabled = true; record.その他.disabled = true; record.勤務時間計_hm.disabled = true; record.残業時間計_hm.disabled = true; record.平日残業計_hm.disabled = true; record.平日深夜計_hm.disabled = true; record.休日残業計_hm.disabled = true; record.休日深夜計_hm.disabled = true; record.勤務時間計_h.disabled = true; record.残業時間計_h.disabled = true; record.平日残業計_h.disabled = true; record.平日深夜計_h.disabled = true; record.休日残業計_h.disabled = true; record.休日深夜計_h.disabled = true; // 承認項目の編集不可 record.申請日.disabled = true; record.確認者.disabled = true; record.確認日.disabled = true; record.所属課長.disabled = true; record.所属課長承認日.disabled = true; record.所属部長.disabled = true; record.所属部長承認日.disabled = true; record.財務管理.disabled = true; record.財務管理承認日.disabled = true; // 就業届テーブルの編集不可の設定 record.就業届.value.forEach(function (row) { row.value.就業届_日.disabled = true; row.value.就業届_曜日.disabled = true; row.value.就業届_勤務時間.disabled = true; row.value.就業届_残業時間.disabled = true; row.value.就業届_平日残業.disabled = true; row.value.就業届_平日深夜.disabled = true; row.value.就業届_休日残業.disabled = true; row.value.就業届_休日深夜.disabled = true; row.value.就業届_日付.disabled = true; row.value.就業届_祭日.disabled = true; row.value.就業届_区分No.disabled = true; row.value.就業届_区分Type.disabled = true; }); } /** * フィールドの非表示を設定します。 */ function setHiddenField() { setHiddenShown("就業届_日付", false); setHiddenShown("就業届_祭日", false); setHiddenShown("就業届_区分No", false); setHiddenShown("就業届_区分Type", false); setHiddenShown("システムグループ", false); /** * フィールドの表示・非表示を切り替える * @param {keyof kintone.AppRecord__勤怠申請入力_内勤者用 | keyof kintone.AppFieldRowValue_勤怠申請入力_内勤者用_就業届} fieldCode * @param {boolean} shown */ function setHiddenShown(fieldCode, shown) { kintone.app.record.setFieldShown(fieldCode, shown); } } /** * サブテーブルの行追加・行削除ボタンを非表示に設定する。 */ function setHiddenTableRowButton() { // 一番最初のサブテーブル(就業届テーブル) const table = document.querySelector(".subtable-gaia"); if (table != null) { table.classList.add("pvc-desktop-main__rowButtonHiddenTable"); } } /** * 就業届の行の勤務時間等を計算します。 * @param {kintone.AppFieldRowValue_勤怠申請入力_内勤者用_就業届} row */ function calcSyuugyouTodokeRowValue(row) { const timeInfo = { 開始時間: toMinutesNum(row.就業届_開始時間.value || "", null), /** @type {number | null} */ 終了時間: 0, 勤務時間: 0, 残業時間: 0, 平日残業: 0, 平日深夜: 0, 休日残業: 0, 休日深夜: 0, }; // 終了時間の設定 timeInfo.終了時間 = toMinutesNum( row.就業届_終了時間.value || "", timeInfo.開始時間 ); if ( timeInfo.開始時間 == null || timeInfo.終了時間 == null || timeInfo.開始時間 > timeInfo.終了時間 ) { // 開始時間または終了時間がブランク、または大小が逆の場合 row.就業届_勤務時間.value = "00:00"; row.就業届_残業時間.value = "00:00"; row.就業届_平日残業.value = "00:00"; row.就業届_平日深夜.value = "00:00"; row.就業届_休日残業.value = "00:00"; row.就業届_休日深夜.value = "00:00"; return; } // 各値を計算 ※残業時間の計算に勤務時間が必要になるため、この順番は変えないこと timeInfo.勤務時間 = getKinmuJikan(); timeInfo.残業時間 = getZangyouJikan(); timeInfo.平日残業 = getHeijituZangyou(); timeInfo.平日深夜 = getHaijituSinya(); timeInfo.休日残業 = getKyuujituZangyou(); timeInfo.休日深夜 = getKyuujituSinya(); // 計算結果の数値から時間文字列を設定 row.就業届_勤務時間.value = toTimeStr(timeInfo.勤務時間); row.就業届_残業時間.value = toTimeStr(timeInfo.残業時間); row.就業届_平日残業.value = toTimeStr(timeInfo.平日残業); row.就業届_平日深夜.value = toTimeStr(timeInfo.平日深夜); row.就業届_休日残業.value = toTimeStr(timeInfo.休日残業); row.就業届_休日深夜.value = toTimeStr(timeInfo.休日深夜); /** * 勤務時間を取得します。 * @returns {number} */ function getKinmuJikan() { if ( timeInfo.開始時間 == null || timeInfo.終了時間 == null || timeInfo.終了時間 === 0 || row.就業届_理由.value === "全休" ) { return 0; } else if (row.就業届_理由.value === "午前半休") { return timeInfo.終了時間 - systemInfo.昼食休憩時間_終了; } else if (row.就業届_理由.value === "午後半休") { return systemInfo.昼食休憩時間_開始 - timeInfo.開始時間; } else if ( row.就業届_曜日.value === "土" || row.就業届_曜日.value === "日" || row.就業届_祭日.value === "祭日" ) { if ( timeInfo.終了時間 - timeInfo.開始時間 < systemInfo.祝休日の休憩時間算出用1 ) { return timeInfo.終了時間 - timeInfo.開始時間; } else if ( timeInfo.終了時間 - timeInfo.開始時間 >= systemInfo.祝休日の休憩時間算出用1 && timeInfo.終了時間 - timeInfo.開始時間 < systemInfo.祝休日の休憩時間算出用2 ) { return ( timeInfo.終了時間 - timeInfo.開始時間 - systemInfo.祝休日の勤務時間が6時間以上8時間未満の場合の休憩時間 ); } else { return ( timeInfo.終了時間 - timeInfo.開始時間 - systemInfo.祝休日の勤務時間が8時間以上の場合の休憩時間 ); } } else if ( timeInfo.開始時間 <= systemInfo.昼食休憩時間_開始 && timeInfo.終了時間 >= systemInfo.昼食休憩時間_終了 ) { return timeInfo.終了時間 - timeInfo.開始時間 - systemInfo.休憩時間; } else { return timeInfo.終了時間 - timeInfo.開始時間; } } /** * 残業時間を取得します。 */ function getZangyouJikan() { if (timeInfo.開始時間 === 0) { return 0; } else if ( row.就業届_曜日.value === "土" || row.就業届_曜日.value === "日" || row.就業届_祭日.value === "祭日" ) { return timeInfo.勤務時間; } else if (row.就業届_理由.value === "全休") { return 0; } else if (row.就業届_理由.value === "午前半休") { return ( timeInfo.勤務時間 + systemInfo.午前半休 - systemInfo.通常業務時間 ); } else if (row.就業届_理由.value === "午後半休") { return ( timeInfo.勤務時間 + systemInfo.午後半休 - systemInfo.通常業務時間 ); } else { return timeInfo.勤務時間 - systemInfo.通常業務時間; } } /** * 平日残業を取得します。 * @returns {number} */ function getHeijituZangyou() { if (timeInfo.終了時間 == null || timeInfo.終了時間 === 0) { return 0; } else if ( row.就業届_曜日.value === "土" || row.就業届_曜日.value === "日" || row.就業届_祭日.value === "祭日" ) { return 0; } else if (timeInfo.終了時間 > systemInfo.深夜_開始時間) { return ( timeInfo.残業時間 - (timeInfo.終了時間 - systemInfo.深夜_開始時間) ); } else { return timeInfo.残業時間; } } /** * 平日深夜を取得します。 * @returns {number} */ function getHaijituSinya() { if (timeInfo.終了時間 == null || timeInfo.終了時間 === 0) { return 0; } else if ( row.就業届_曜日.value === "土" || row.就業届_曜日.value === "日" || row.就業届_祭日.value === "祭日" ) { return 0; } else if (timeInfo.終了時間 < systemInfo.深夜_開始時間) { return 0; } else { return timeInfo.終了時間 - systemInfo.深夜_開始時間; } } /** * 休日残業を取得します。 * @returns {number} */ function getKyuujituZangyou() { if (timeInfo.終了時間 == null || timeInfo.終了時間 === 0) { return 0; } else if ( row.就業届_曜日.value !== "土" && row.就業届_曜日.value !== "日" && row.就業届_祭日.value !== "祭日" ) { return 0; } else if (timeInfo.終了時間 <= systemInfo.深夜_開始時間) { return timeInfo.勤務時間; } else { return ( timeInfo.勤務時間 - (timeInfo.終了時間 - systemInfo.深夜_開始時間) ); } } /** * 休日深夜を取得します。 * @returns {number} */ function getKyuujituSinya() { if (timeInfo.終了時間 == null || timeInfo.終了時間 === 0) { return 0; } else if ( row.就業届_曜日.value === "土" || row.就業届_曜日.value === "日" || row.就業届_祭日.value === "祭日" ) { if (timeInfo.終了時間 < systemInfo.深夜_開始時間) { return 0; } else { return timeInfo.終了時間 - systemInfo.深夜_開始時間; } } else { return 0; } } } /** * HH:mm形式の文字列を分数に変換する。 * @param {string} strDate HH:mm形式の文字列 * @param {number | null} fromNum 終了時間の場合、開始時間の分数 * @returns {number | null} */ function toMinutesNum(strDate, fromNum) { if (!/-?\d+:\d{2}/.test(strDate)) { // 時刻形式(マイナスは可能)以外の場合 return null; } let isMinus = strDate[0] === "-"; const numArr = strDate.replace("-", "").split(":"); const hh = pvc.util.obj.toNumber(numArr[0]) || 0; const mm = pvc.util.obj.toNumber(numArr[1]) || 0; let result = hh * 60 + mm; if (fromNum != null && fromNum > result) { // 終了時間かつ、開始時間より終了時間が小さい場合、24:00を加算 result += 24 * 60; } return (isMinus ? -1 : 1) * result; } /** * 分数を元に、HH:mm形式の文字列に変換する。 * @param {number} minutesNum * @returns {string} */ function toTimeStr(minutesNum) { const absNum = Math.abs(minutesNum); const hh = pvc.util.str.padLeft(String(Math.floor(absNum / 60)), "0", 2); const mm = pvc.util.str.padLeft(String(absNum % 60), "0", 2); return (minutesNum < 0 ? "-" : "") + hh + ":" + mm; } /** * 分数を元に、小数2桁の時間数値に変換する。 * @param {number} minutesNum * @returns {number} */ function toHoursNum(minutesNum) { return Math.round((minutesNum * 100.0) / 60.0) / 100; } /** * YYYYMM形式の値かどうか * @param {number} nengetuNum * @returns {boolean} */ function isNengetuNum(nengetuNum) { const strValue = String(nengetuNum); const mm = nengetuNum % 100; return strValue.length === 6 && 1 <= mm && mm <= 12; } /** * システムコントロールのレコードを取得します。 * @returns {Promise} */ function getSystemControlRecord() { return new KintoneRestAPIClient().record .getRecords({ app: pvc.env.app.システムコントロール.appId, query: "limit 1", }) .then(function (resp) { return resp.records.length > 0 ? resp.records[0] : null; }); } /** * システムコントロール関連のフィールドに値を設定します。 * @param {kintone.AppRecord__システムコントロール} systemRecord * @param {kintone.AppRecord__勤怠申請入力_内勤者用} record */ function setSystemControlField(systemRecord, record) { record.システム_休憩時間.value = systemRecord.休憩時間.value || "00:00"; record.システム_通常業務時間.value = systemRecord.通常業務時間.value || "00:00"; record.システム_深夜_開始時間.value = systemRecord.深夜_開始時間.value || "00:00"; record.システム_深夜_終了時間.value = systemRecord.深夜_終了時間.value || "00:00"; record.システム_昼食休憩時間_開始.value = systemRecord.昼食休憩時間_開始.value || "00:00"; record.システム_昼食休憩時間_終了.value = systemRecord.昼食休憩時間_終了.value || "00:00"; record.システム_午前半休.value = systemRecord.午前半休.value || "00:00"; record.システム_午後半休.value = systemRecord.午後半休.value || "00:00"; record.システム_祝休日の休憩時間算出用1.value = systemRecord.祝休日の休憩時間算出用1.value || "00:00"; record.システム_祝休日の休憩時間算出用2.value = systemRecord.祝休日の休憩時間算出用2.value || "00:00"; record.システム_祝休日の勤務時間が8時間以上の場合の休憩時間.value = systemRecord.祝休日の勤務時間が8時間以上の場合の休憩時間.value || "00:00"; record.システム_祝休日の勤務時間が6時間以上8時間未満の場合の休憩時間.value = systemRecord.祝休日の勤務時間が6時間以上8時間未満の場合の休憩時間.value || "00:00"; } /** * システムコントロールフィールドからシステム時間情報を設定します。 * @param {kintone.AppRecord__勤怠申請入力_内勤者用} record */ function setSystemInfo(record) { systemInfo.休憩時間 = toMinutesNum(record.システム_休憩時間.value || "", null) || 0; systemInfo.通常業務時間 = toMinutesNum(record.システム_通常業務時間.value || "", null) || 0; systemInfo.深夜_開始時間 = toMinutesNum(record.システム_深夜_開始時間.value || "", null) || 0; systemInfo.深夜_終了時間 = toMinutesNum( record.システム_深夜_終了時間.value || "", systemInfo.深夜_開始時間 ) || 0; systemInfo.昼食休憩時間_開始 = toMinutesNum(record.システム_昼食休憩時間_開始.value || "", null) || 0; systemInfo.昼食休憩時間_終了 = toMinutesNum( record.システム_昼食休憩時間_終了.value || "", systemInfo.昼食休憩時間_開始 ) || 0; systemInfo.午前半休 = toMinutesNum(record.システム_午前半休.value || "", null) || 0; systemInfo.午後半休 = toMinutesNum(record.システム_午後半休.value || "", null) || 0; systemInfo.祝休日の休憩時間算出用1 = toMinutesNum(record.システム_祝休日の休憩時間算出用1.value || "", null) || 0; systemInfo.祝休日の休憩時間算出用2 = toMinutesNum(record.システム_祝休日の休憩時間算出用2.value || "", null) || 0; systemInfo.祝休日の勤務時間が8時間以上の場合の休憩時間 = toMinutesNum( record.システム_祝休日の勤務時間が8時間以上の場合の休憩時間.value || "", null ) || 0; systemInfo.祝休日の勤務時間が6時間以上8時間未満の場合の休憩時間 = toMinutesNum( record.システム_祝休日の勤務時間が6時間以上8時間未満の場合の休憩時間 .value || "", null ) || 0; } /** * 重複データが存在するかどうか * @param {kintone.AppRecord__勤怠申請入力_内勤者用} record * @returns {Promise} */ function existsDuplicateData(record) { return new KintoneRestAPIClient().record .getRecords({ app: pvc.env.app.勤怠申請入力_内勤者用.appId, query: pvc.util.kintone.makeQuery( "$id != (@id) and 申請年月 = (@申請年月) and 氏名 in ((@氏名))", { id: record.$id != null ? record.$id.value : "", 申請年月: record.申請年月.value || "", 氏名: record.氏名.value[0].code, } ), fields: ["$id"], }) .then(function (resp) { return resp.records.length > 0; }); } /** * 指定範囲の祝祭日マスタデータを取得します。 * @param {Date} fromDate * @param {Date} toDate * @returns {Promise} */ function getSyukusaijituMaster(fromDate, toDate) { return new KintoneRestAPIClient().record .getAllRecords({ app: pvc.env.app.祝祭日マスタ.appId, condition: pvc.util.kintone.makeQuery( "日付 >= (@fromDate) and 日付 <= (@toDate)", { fromDate: pvc.util.date.format(fromDate, "yyyy-MM-dd"), toDate: pvc.util.date.format(toDate, "yyyy-MM-dd"), } ), }) .then(function (records) { return records; }); } /** * 就業届テーブルに申請年月の値からデータを設定します。 * @param {kintone.AppRecord__勤怠申請入力_内勤者用} record * @returns {Promise} */ function setSyuugyouTodokeTable(record) { const sinseiNengetu = pvc.util.obj.toNumber(record.申請年月.value) || 0; const year = Math.floor(sinseiNengetu / 100); const month = sinseiNengetu % 100; // 前月26日が開始日 const fromDate = new Date(year, month - 2, 26); // 今月25日が終了日 const toDate = new Date(year, month - 1, 25); return getSyukusaijituMaster(fromDate, toDate).then(function ( syukusaijituRecords ) { // 祝祭日の日付数値リストを作成 const syukusaijituList = syukusaijituRecords.map(function ( syukusaijituRecord ) { return ( pvc.util.obj.toDate(syukusaijituRecord.日付.value) || new Date(0) ).getTime(); }); record.就業届.value = []; const rowDate = new Date(fromDate.getTime()); const youbiList = ["日", "月", "火", "水", "木", "金", "土"]; while (rowDate.getTime() <= toDate.getTime()) { const isSaijitu = syukusaijituList.indexOf(rowDate.getTime()) !== -1; const youbi = youbiList[rowDate.getDay()]; const isHoliday = isSaijitu || youbi === "土" || youbi === "日"; record.就業届.value.push({ value: { 就業届_日: { type: "NUMBER", value: String(rowDate.getDate()), }, 就業届_区分: { type: "DROP_DOWN", value: isHoliday ? "0:休暇" : null, }, 就業届_曜日: { type: "SINGLE_LINE_TEXT", value: youbi, }, 就業届_業務内容: { type: "SINGLE_LINE_TEXT", value: null, }, 就業届_開始時間: { type: "TIME", value: !isHoliday ? "09:00" : "00:00", }, 就業届_終了時間: { type: "TIME", value: !isHoliday ? "18:00" : "00:00", }, 就業届_勤務時間: { type: "SINGLE_LINE_TEXT", value: !isHoliday ? "08:00" : "00:00", }, 就業届_残業時間: { type: "SINGLE_LINE_TEXT", value: "00:00", }, 就業届_平日残業: { type: "SINGLE_LINE_TEXT", value: "00:00", }, 就業届_平日深夜: { type: "SINGLE_LINE_TEXT", value: "00:00", }, 就業届_休日残業: { type: "SINGLE_LINE_TEXT", value: "00:00", }, 就業届_休日深夜: { type: "SINGLE_LINE_TEXT", value: "00:00", }, 就業届_理由: { type: "DROP_DOWN", value: null, }, 就業届_日付: { type: "DATE", value: pvc.util.date.format(rowDate, "yyyy-MM-dd"), }, 就業届_祭日: { type: "DROP_DOWN", value: isSaijitu ? "祭日" : null, }, 就業届_区分No: { type: "SINGLE_LINE_TEXT", value: isHoliday ? "0" : null, }, 就業届_区分Type: { type: "SINGLE_LINE_TEXT", value: isHoliday ? "休暇" : null, }, }, }); // 行の日付に+1日 rowDate.setDate(rowDate.getDate() + 1); } // 全行の計算 record.就業届.value.forEach(function (row) { calcSyuugyouTodokeRowValue(row.value); }); // 時間合計を計算 calcSyuugyouTodokeJikanGoukei(record); // 休暇合計を全て0に設定 record.有給休暇.value = "0"; record.病気休暇.value = "0"; record.振休_代休.value = "0"; record.特別休暇.value = "0"; record.その他.value = "0"; }); } /** * 就業届テーブルの行の「区分」から「区分No」と「区分Type」を設定します。 * @param {kintone.AppRecord__勤怠申請入力_内勤者用["就業届"]["value"][0]} row */ function setSyuugyouTodokeKubunNoAndType(row) { const kubunSplit = (row.value.就業届_区分.value || "").split(":"); if (kubunSplit.length >= 2) { row.value.就業届_区分No.value = kubunSplit[0]; row.value.就業届_区分Type.value = kubunSplit[1]; } } /** * 就業届テーブルから休暇合計を計算します。 * @param {kintone.AppRecord__勤怠申請入力_内勤者用} record */ function calcSyuugyouTodokeKyuukaGoukei(record) { const totalInfo = { 有給休暇: 0, 病気休暇: 0, 振休_代休: 0, 特別休暇: 0, その他: 0, }; record.就業届.value.forEach(function (row) { switch (row.value.就業届_理由.value) { case "全休": totalInfo.有給休暇 += 1; break; case "午前半休": totalInfo.有給休暇 += 0.5; break; case "午後半休": totalInfo.有給休暇 += 0.5; break; case "病気休暇": totalInfo.病気休暇 += 1; break; case "振休": totalInfo.振休_代休 += 1; break; case "特別休暇": totalInfo.特別休暇 += 1; break; case "その他": totalInfo.その他 += 1; break; } }); record.有給休暇.value = String(totalInfo.有給休暇); record.病気休暇.value = String(totalInfo.病気休暇); record.振休_代休.value = String(totalInfo.振休_代休); record.特別休暇.value = String(totalInfo.特別休暇); record.その他.value = String(totalInfo.その他); } /** * 就業届テーブルから時間合計を計算します。 * @param {kintone.AppRecord__勤怠申請入力_内勤者用} record */ function calcSyuugyouTodokeJikanGoukei(record) { const totalInfo = { 勤務時間計: 0, 残業時間計: 0, 平日残業計: 0, 平日深夜計: 0, 休日残業計: 0, 休日深夜計: 0, }; record.就業届.value.forEach(function (row) { totalInfo.勤務時間計 += toMinutesNum(row.value.就業届_勤務時間.value || "", null) || 0; totalInfo.残業時間計 += toMinutesNum(row.value.就業届_残業時間.value || "", null) || 0; totalInfo.平日残業計 += toMinutesNum(row.value.就業届_平日残業.value || "", null) || 0; totalInfo.平日深夜計 += toMinutesNum(row.value.就業届_平日深夜.value || "", null) || 0; totalInfo.休日残業計 += toMinutesNum(row.value.就業届_休日残業.value || "", null) || 0; totalInfo.休日深夜計 += toMinutesNum(row.value.就業届_休日深夜.value || "", null) || 0; }); // 合計(h:m)の設定 record.勤務時間計_hm.value = toTimeStr(totalInfo.勤務時間計); record.残業時間計_hm.value = toTimeStr(totalInfo.残業時間計); record.平日残業計_hm.value = toTimeStr(totalInfo.平日残業計); record.平日深夜計_hm.value = toTimeStr(totalInfo.平日深夜計); record.休日残業計_hm.value = toTimeStr(totalInfo.休日残業計); record.休日深夜計_hm.value = toTimeStr(totalInfo.休日深夜計); // 合計(h)の設定 record.勤務時間計_h.value = String(toHoursNum(totalInfo.勤務時間計)); record.残業時間計_h.value = String(toHoursNum(totalInfo.残業時間計)); record.平日残業計_h.value = String(toHoursNum(totalInfo.平日残業計)); record.平日深夜計_h.value = String(toHoursNum(totalInfo.平日深夜計)); record.休日残業計_h.value = String(toHoursNum(totalInfo.休日残業計)); record.休日深夜計_h.value = String(toHoursNum(totalInfo.休日深夜計)); } /** * 指定されたユーザーコードから印影マスタの情報を取得します。 * @param {string} userCode * @returns {Promise} */ function getInneiMasterRecord(userCode) { return new KintoneRestAPIClient().record .getRecords({ app: pvc.env.app.印影マスタ.appId, query: pvc.util.kintone.makeQuery("担当者 in ((@担当者))", { 担当者: userCode, }), }) .then(function ( /** @type {{ records: kintone.AppRecord__印影マスタ[] }} */ resp ) { return resp.records.length > 0 ? resp.records[0] : null; }); } })();