业务:
请假申请流程需要根据员工的班次、实际填写的请假开始时间以及请假结束时间、休假类型,计算出请假时长;
班次:班次根据配置不同可以分为两笔卡、四笔卡的班次
两笔卡:
C015:P10:8:00[上班卡]|P20:17:00[下班卡]
四笔卡:
C005:P10:8:00[上午上班卡]|P20:12:00[上午下班卡]|P10:13:00[下午上班卡]|P20:17:00[下午下班卡]
休假类型:包含事假,病假,婚假等可以根据实际业务进行配置
通过休假类型获取配置表中的休假计算规则:
select KQZY from BO_JACK_RLMK_KQCS_M where type = '休假类型' AND CODE = '"+qjdm+"'
KQZY在此业务场景表示:1表示工作日,0或者空表示日历日
calQJWorkTime方法表示通过请假代码、请假开始时间以及请假结束时间进行获取对应的时间区间中的依照休假类型的休假计算规则(工作日规则或日历日规则)
public Long calQJWorkTime(String qjdm,String timeFrom, String timeTo) throws ParseException {
WorkTimeService ws = new WorkTimeService();
String workDayStr = DBUtil.getValuefromDB("KQZY"," select KQZY from BO_JACK_RLMK_KQCS_M where type = '休假类型' AND CODE = '"+qjdm+"' ");
Boolean workDay = "1".equals(workDayStr);
return ws.getQJWorkTime(uc.getUID(), timeFrom, timeTo,workDay)/1000;
}
getQJWorkTime表示:通过员工工号获取具体班次信息
public Long getQJWorkTime(String gh,String start,String end,Boolean workDay) throws ParseException {
String start_date=DateUtil.formatDateString(start);//start.split(" ")[0];
String start_time=DateUtil.formatTime(DateUtil.parseToDate(start));//start.split(" ")[1];
String end_date=DateUtil.formatDateString(end);//end.split(" ")[0];
String end_time=DateUtil.formatTime(DateUtil.parseToDate(end));//end.split(" ")[1];
List<Date> dateList = new ArrayList<Date>();
SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss");
String zbc = DBUtil.getValuefromDB("ZBC","select ZBC from BO_JACK_RLMK_RYXX_M WHERE GH ='"+gh+"'");
//格式 CODE[数值1-数值2] 案例: C017[14400-14400] C018[14400-14400]
//CODE BPM->人力资源->考勤参数视图->科室工作时间->代码
//数值1 表示两笔班次 第一笔卡 增加毫秒数,数值2 表示两笔班次 第二笔卡 减少毫秒数
String zbc_name = ConstantDao.getInstance().getCanstantValueByName("RLMK_GCSJ_WORK_TIME_ZBC", "C017 C018");
int firstTime_s = 60 * 60 * 4,secondTime_s = -60 * 60 * 4;
if(!StringUtils.isEmpty(zbc) && zbc_name.contains(zbc)){
String[] zbc_name_new = zbc_name.split(" ");
for (String s : zbc_name_new) {
if(s.contains(zbc) && s.contains("[")){
firstTime_s = Integer.valueOf(s.substring(s.indexOf("[")+1,s.indexOf("-")));
secondTime_s = -Integer.valueOf(s.substring(s.indexOf("-")+1,s.indexOf("]")));
break;
}
}
}
/*Boolean zbc_flag = false;//判断 人员班次是不是两笔卡打卡班次
if(!StringUtils.isEmpty(zbc) && !zbc_name.contains(zbc)){
zbc_flag = true;
}*/
String name = DBUtil.getValuefromDB("name","select k.name from BO_JACK_RLMK_RYXX_M m LEFT JOIN BO_JACK_RLMK_KQCS_M k on m.ZBC=k.CODE WHERE GH='"+gh+"' and k.type='科室工作时间'");
String namenew = null;
if(StringUtils.isNotEmpty(name)){
namenew = name.replace("P10:","").replace("P20:","");
}else{//默认班次
namenew = ConstantDao.getInstance().getCanstantValueByName("RLMK_GCSJ_WORK_TIME", "08:00|12:00|13:00|17:00");
}
String times[] = namenew.split("\\|");
for (int i = 0; i < times.length; i++) {
if(times[i].contains("[")){
dateList.add(timeFormat.parse(times[i].substring(0,times[i].indexOf("["))+":00"));
}else{
dateList.add(timeFormat.parse(times[i]+":00"));
}
}
//判断 两笔卡逻辑:由于一天上班8小时,所以按照第一笔增加4小时,第二笔卡退后4小时计算
if (times.length == 2 ){
//获取中午休息时间 开始时间
String firstTime = DateUtil.addSecondStr(timeFormat.format(dateList.get(0)), firstTime_s);
//获取中午休息时间 结束时间
String secondTime = DateUtil.addSecondStr(timeFormat.format(dateList.get(1)), secondTime_s);
dateList.add(timeFormat.parse(firstTime));
dateList.add(timeFormat.parse(secondTime));
//排序 正序
Collections.sort(dateList);
}
Date start_time_d=timeFormat.parse(start_time),end_time_d=timeFormat.parse(end_time);
Long start_time_t=start_time_d.getTime(),end_time_t=end_time_d.getTime();
if(start_time_t <= dateList.get(0).getTime()){
start_time_t = dateList.get(0).getTime();
}
if(end_time_t >= dateList.get(3).getTime()){
end_time_t = dateList.get(3).getTime();
}
if(start_date.equals(end_date)){//同天
//计算 小时数
//如果时间包含中午休息时间去除
if(start_time_t <= dateList.get(1).getTime() && end_time_t >= dateList.get(2).getTime()){
return end_time_t-start_time_t-(dateList.get(2).getTime()-dateList.get(1).getTime());
//请勿删除 保留有用 2020年03月25日 14点05分 13526 计算 开始时间 结束时间 其中一个在中午休息时间之间
/* }else if(start_time_t > dateList.get(1).getTime() && end_time_t >= dateList.get(2).getTime()){
return end_time_t-dateList.get(2).getTime();
}else if(start_time_t <= dateList.get(1).getTime() && end_time_t < dateList.get(2).getTime()){
return dateList.get(1).getTime()-start_time_t;*/
}else{
return end_time_t-start_time_t;
}
}else{//不同天
//获取天数集合
List<String> rq = DateUtil.getDateList(start_date,end_date);
int holiday = 0;
if(workDay){// true:工作日 false:日历日
Map<String,String> resultMap = isDateOutOfWork("假期通知表");
for (String s : rq) {
if(resultMap.containsKey(s)){
holiday++;
}
}
}
int day = rq.size() - 2 - holiday;
Long day_time_l = day * 8 * 60 * 60 * 1000L,start_time_l = 0L,end_time_l = 0L;
if(start_time_t <= dateList.get(1).getTime()){
start_time_l=dateList.get(3).getTime()-(dateList.get(2).getTime()-dateList.get(1).getTime())-start_time_t;
}else{
start_time_l=dateList.get(3).getTime()-start_time_t;
}
if(end_time_t >= dateList.get(2).getTime()){
end_time_l=end_time_t-(dateList.get(2).getTime()-dateList.get(1).getTime())-dateList.get(0).getTime();
}else{
end_time_l=end_time_t-dateList.get(0).getTime();
}
return day_time_l+start_time_l+end_time_l;
}
}
isDateOutOfWork方法表示获取配置放假日日期表
public Map<String,String> isDateOutOfWork(String company) {
String cdate = (DateUtil.getCurrentYear()-1)+"-01-01";
String sql ="select CONVERT(varchar(100), s.RQ, 23) as RQ from BO_JACK_RLMK_FJRQWH_S s,BO_JACK_RLMK_FJRQWH_M m where s.BINDID = m.BINDID and m.GSMC ='"+
company + "' and s.rq >= '"+cdate+"'";
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
Map<String,String> resultMap = new HashMap<String,String>();
try {
conn = DBSql.open();
stmt = conn.createStatement();
rs = stmt.executeQuery(sql);
while(rs.next()){
resultMap.put(rs.getString("RQ"),rs.getString("RQ"));
}
} catch (SQLException e) {
Logger.error(e.getMessage());
}finally{
DBSql.close(conn, stmt, rs);
}
return resultMap;
}