1116 lines
40 KiB
JavaScript
1116 lines
40 KiB
JavaScript
/**
|
||
* 勤怠申請入力_内勤者用 - 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<kintone.AppRecord__システムコントロール | null>}
|
||
*/
|
||
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<boolean>}
|
||
*/
|
||
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<kintone.AppRecord__祝祭日マスタ[]>}
|
||
*/
|
||
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<void>}
|
||
*/
|
||
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<kintone.AppRecord__印影マスタ | null>}
|
||
*/
|
||
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;
|
||
});
|
||
}
|
||
})();
|