2024-11-08
221次
網站運營
某客戶企業為上市公司,公司員工規模800人左右,根據公司企業發展需要,后續公司員工規模還會持續性增長。因客戶沒有人力資源管理系統,所有的考勤、薪資、計件都是人工手動計算,同時客戶班次分類較多、較雜,當每個月每個事業部的考勤文員在核算員工的考勤時都比較痛苦,其中有一個加班補貼的核算場景,文員都是人工根據打卡數據以及紙質單據識別出來的加班餐補補貼。現客戶使用東寶人力資源管理系統,希望此需求能通過系統自動計算,減少人工成本。規則如下:

①加班需要打卡,并且提交加班單才計算加班餐補補貼。
②滿足以下場景,才計算加班餐補補貼。
③日報統計加班餐補補貼次數,薪資核算加班餐補補貼。
通過在東寶DHG系統配置的自定義過程實現,系統自動根據員工的打卡或加班單來統計不同的餐次次數。考勤匯總餐補次數,薪酬核算餐補費用。



以下是自定義識別加班場景來計算餐補的代碼實現部分:
/* 加班統計餐次
腳本執行的標識:工時日報-工時計算最后處理
1. 根據日報班段時間,將其中加班段處理為 "找餐時間段"
- 如果員工的考勤制度勾選了加班需申請,那餐補次數的統計需要根據員工的加班單結合打卡時間來計算餐補次數。否則,只需要根據打卡來計算加班餐補的次數。
- 無需特殊處理:該控制會影響日報的班段結果,直接按日報班段結果處理即可
2. 固定的餐補應上下班時間、餐補
3. 匹配就餐
- “找餐時間段” 匹配 “就餐應上下班時間段”,計加班餐次
*/
var debug = type.new("java.lang.StringBuilder");
try {
// 處理前置空(保障更新原本算出來,現在算不出來的數據)
// 早餐
workHourDayDTO.attWorkHourDay.extField['c_overtime_breakfast'] = 0;
// 中餐
workHourDayDTO.attWorkHourDay.extField['c_overtime_lunch'] = 0;
// 晚餐
workHourDayDTO.attWorkHourDay.extField['c_overtime_dinner'] = 0;
// 夜宵
workHourDayDTO.attWorkHourDay.extField['c_overtime_night_snack'] = 0;
// 1. 根據日報班段時間,將其中加班段處理為 "找餐時間段"
var workBucketDTOList = workHourDayDTO.workShiftDTO.workBucketDTOList;
// 4-請假 6-停工 7-曠工 8-休假
// 1-正班 3-休息
// 5-出差正班 51-出差加班 52-出差其他加班 62-出差推后加班 61-出差提前加班
// 11-正班提前加班 12-正班推后加班 2-正班加班
// 81-休假加班 82-休假其他加班
var overtimeBucketType = @com.google.common.collect.Sets.newHashSet(5, 51, 52, 61, 62, 11, 12, 2, 81, 82);
var currFindRepastRange = null;
var findRepastRangeList = [];
for (var workBucketDTO in workBucketDTOList) {
for (var workHourDayBucketDTO in workBucketDTO.workHourDayBucketDTOList) {
@debug.append("
[").append(workHourDayBucketDTO.workBucketType).append("]");
@debug.append(workHourDayBucketDTO.workTimeBegin).append(" - ").append(workHourDayBucketDTO.workTimeEnd);
if (workHourDayBucketDTO.effectiveWorkHour && @overtimeBucketType.contains(workHourDayBucketDTO.workBucketType)) {
@debug.append("
有效加班段");
if (currFindRepastRange == null) {
var begin = workHourDayBucketDTO.cardTimeBegin != null
? workHourDayBucketDTO.cardTimeBegin
: workHourDayBucketDTO.workTimeBegin;
var end = workHourDayBucketDTO.cardTimeEnd != null
? workHourDayBucketDTO.cardTimeEnd
: workHourDayBucketDTO.workTimeEnd;
currFindRepastRange = {
begin: begin,
end: end
};
@debug.append("
初始找餐時間段:").append(currFindRepastRange.begin).append(" - ").append(currFindRepastRange.end);
} else {
currFindRepastRange.end = workHourDayBucketDTO.cardTimeEnd != null
? workHourDayBucketDTO.cardTimeEnd
: workHourDayBucketDTO.workTimeEnd;
@debug.append("
合并緊鄰的有效加班段:~ ").append(currFindRepastRange.end);
}
} else {
@debug.append(workHourDayBucketDTO.effectiveWorkHour ? "
非加班段" : "
無效時段");
if (currFindRepastRange != null) {
@debug.append("
記錄當前的找餐時間段:");
@debug.append(currFindRepastRange.begin).append(" - ").append(currFindRepastRange.end);
@findRepastRangeList.add(currFindRepastRange);
currFindRepastRange = null;
}
}
}
}
if (currFindRepastRange != null) {
@debug.append("
記錄最后的找餐時間段:");
@debug.append(currFindRepastRange.begin).append(" - ").append(currFindRepastRange.end);
@findRepastRangeList.add(currFindRepastRange);
}
// 2. 固定的餐補應上下班時間、餐補
var repastTimeConfList = [
// 早餐:6元/次,打卡時間為7:00前(含7點整);
{ flag: "breakfast", begin: "07:00", end: "07:00", cnt: 0 },
// 中餐:15元/次,上班打卡時間為10:00前(含10點整)并加班餐補下班打卡時間為14:00后(含14點整);
{ flag: "lunch", begin: "10:00", end: "14:00", cnt: 0 },
// 晚餐:15元/次,打卡時間為20:00后(含20點整);
{ flag:"dinner", begin: "20:00", end: "20:00", cnt: 0 },
// 夜宵:6元/次,打卡時間為24:00后(含24點整)。
{ flag: "night_snack", begin: "00:00", end: "00:00", cnt: 0 }
//
];
// 取進三天就餐具體時間
var repastDateTimeRangeList = [];
var attendanceDate = workHourDayDTO.attWorkHourDay.attendanceDate;
for (var i = -1; i <= 1; i++) {
var date = @com.dongbao.core.util.DateUtil.dayOffset(attendanceDate, i);
for (var repastTimeConf in repastTimeConfList) {
@repastDateTimeRangeList.add({
conf: repastTimeConf,
begin: @com.dongbao.core.util.DateUtil.getDateTime(date, repastTimeConf.begin),
end: @com.dongbao.core.util.DateUtil.getDateTime(date, repastTimeConf.end)
});
}
}
// 3. 匹配就餐
var i = 0;
var j = 0;
while (i < @findRepastRangeList.size() && j < @repastDateTimeRangeList.size()) {
var findRepastRange = findRepastRangeList[i];
var repastDateTimeRange = repastDateTimeRangeList[j];
var isLater = repastDateTimeRange.begin < findRepastRange.begin;
var isEarly = repastDateTimeRange.end > findRepastRange.end;
if (isLater) {
// 飯點過了——就餐時間早于找餐時間,接著找下段就餐時間
j++;
} else if (isEarly) {
// 飯點沒到——就餐時間晚于找餐時間,接著找下一段加班時間
i++;
} else {
// 包含飯點——匹配,計對應加班餐次,接著找下段就餐時間
@debug.append("
匹配到餐點:");
@debug.append(repastDateTimeRange.begin).append(" - ").append(repastDateTimeRange.end);
@debug.append("
加班時間段:");
@debug.append(findRepastRange.begin).append(" - ").append(findRepastRange.end);
var conf = repastDateTimeRange.conf;
conf.cnt = conf.cnt + 1;
@debug.append("
餐補次數 - ").append(conf.flag).append(": ").append(conf.cnt);
j++;
}
}
// 4. 自定義字段賦值
for (var conf in repastTimeConfList) {
workHourDayDTO.attWorkHourDay.extField["c_overtime_" + conf.flag] = conf.cnt;
}
} catch (e) {
var writer = type.new("StringWriter");
var printer = @org.codehaus.groovy.runtime.IOGroovyMethods.newPrintWriter(writer);
@e.printStackTrace(printer);
@debug.append("
").append(writer);
}①系統自動根據班次、打卡、加班單識別不同類型的加班餐次,考勤文員由原來每月人工識別,縮短為系統實時數據更新,省時省力。
②日考勤機準確率提升至100%,同時每月能快速高效完結考勤月報。
上一篇:員工參加培訓后的效果評估功能