|
|
|
|
import com.engine.attendance.attendanceanalysis.wrapper.AttendanceAnalysisWrapper;
|
|
|
|
|
import com.engine.attendance.enums.CheckBoxEnum;
|
|
|
|
|
import com.engine.attendance.enums.ClockPointEnum;
|
|
|
|
|
import com.engine.common.util.DateUtil;
|
|
|
|
|
import com.engine.common.util.Utils;
|
|
|
|
|
import com.google.common.collect.Lists;
|
|
|
|
|
import com.google.common.collect.Maps;
|
|
|
|
|
import weaver.general.Util;
|
|
|
|
|
|
|
|
|
|
import java.util.HashMap;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
|
|
|
|
|
public class TestGetClockInPoint {
|
|
|
|
|
public static void main(String[] args) {
|
|
|
|
|
|
|
|
|
|
List<Map<String,Object>> schedulingList = Lists.newArrayList();
|
|
|
|
|
schedulingList.add(new HashMap(){{
|
|
|
|
|
put("edsc","9.50");
|
|
|
|
|
put("bdlx","0");
|
|
|
|
|
put("jsdk","1");
|
|
|
|
|
put("tqdkfzs","60");
|
|
|
|
|
put("sfkt","1");
|
|
|
|
|
put("dtjssj","13:00");
|
|
|
|
|
put("zddxfz","30");
|
|
|
|
|
put("bcxx","25");
|
|
|
|
|
put("dxhs","5");
|
|
|
|
|
put("bcsdxx","09:00-13:00|13:00-18:30");
|
|
|
|
|
put("sfdx","0");
|
|
|
|
|
put("dtkssj","09:00");
|
|
|
|
|
put("thdkfzs","60");
|
|
|
|
|
put("ksdk","1");
|
|
|
|
|
put("rqlx","11");
|
|
|
|
|
}});
|
|
|
|
|
schedulingList.add(new HashMap(){{
|
|
|
|
|
put("edsc","9.50");
|
|
|
|
|
put("bdlx","0");
|
|
|
|
|
put("jsdk","1");
|
|
|
|
|
put("tqdkfzs","60");
|
|
|
|
|
put("sfkt","1");
|
|
|
|
|
put("dtjssj","18:00");
|
|
|
|
|
put("zddxfz","30");
|
|
|
|
|
put("bcxx","25");
|
|
|
|
|
put("dxhs","5");
|
|
|
|
|
put("bcsdxx","09:00-13:00|13:00-18:30");
|
|
|
|
|
put("sfdx","0");
|
|
|
|
|
put("dtkssj","03:00");
|
|
|
|
|
put("thdkfzs","60");
|
|
|
|
|
put("ksdk","0");
|
|
|
|
|
put("rqlx","11");
|
|
|
|
|
}});
|
|
|
|
|
|
|
|
|
|
List<Map<String,Object>> dataList = Lists.newArrayList();
|
|
|
|
|
dataList.add(new HashMap(){{
|
|
|
|
|
put("signtime","08:45:00");
|
|
|
|
|
put("id","48");
|
|
|
|
|
put("userid","53");
|
|
|
|
|
put("signdate","2023-11-12");
|
|
|
|
|
}});
|
|
|
|
|
dataList.add(new HashMap(){{
|
|
|
|
|
put("signtime","09:15:00");
|
|
|
|
|
put("id","48");
|
|
|
|
|
put("userid","53");
|
|
|
|
|
put("signdate","2023-11-12");
|
|
|
|
|
}});
|
|
|
|
|
dataList.add(new HashMap(){{
|
|
|
|
|
put("signtime","10:15:00");
|
|
|
|
|
put("id","48");
|
|
|
|
|
put("userid","53");
|
|
|
|
|
put("signdate","2023-11-12");
|
|
|
|
|
}});
|
|
|
|
|
dataList.add(new HashMap(){{
|
|
|
|
|
put("signtime","13:01:00");
|
|
|
|
|
put("id","48");
|
|
|
|
|
put("userid","53");
|
|
|
|
|
put("signdate","2023-11-12");
|
|
|
|
|
}});
|
|
|
|
|
dataList.add(new HashMap(){{
|
|
|
|
|
put("signtime","15:30:00");
|
|
|
|
|
put("id","48");
|
|
|
|
|
put("userid","53");
|
|
|
|
|
put("signdate","2023-11-12");
|
|
|
|
|
}});
|
|
|
|
|
// dataList.add(new HashMap(){{
|
|
|
|
|
// put("signtime","18:15:00");
|
|
|
|
|
// put("id","48");
|
|
|
|
|
// put("userid","53");
|
|
|
|
|
// put("signdate","2023-11-12");
|
|
|
|
|
// }});
|
|
|
|
|
System.out.println(getClockInPoint("2023-11-12",schedulingList,dataList));
|
|
|
|
|
}
|
|
|
|
|
public static List<Map<String, Map<String,Object>>> getClockInPoint(String analysisDate, List<Map<String, Object>> needClockInSchedule, List<Map<String, Object>> clockInTimeList){
|
|
|
|
|
List<Map<String,Map<String,Object>>> clcokInTimeData = Lists.newArrayList();
|
|
|
|
|
|
|
|
|
|
for (Map<String, Object> needClockIn :needClockInSchedule){
|
|
|
|
|
if (CheckBoxEnum.CHECKED.getKey().equals(needClockIn.get("ksdk"))){
|
|
|
|
|
String dtkssj = analysisDate+" "+needClockIn.get("dtkssj");
|
|
|
|
|
String dtjssj = analysisDate+" "+needClockIn.get("dtjssj");
|
|
|
|
|
if (DateUtil.getTime(dtkssj).compareTo(DateUtil.getTime(dtjssj)) > 0){
|
|
|
|
|
dtjssj = DateUtil.AfterDay(analysisDate,1) +" "+needClockIn.get("dtjssj");
|
|
|
|
|
}
|
|
|
|
|
int tqdkfzs = Integer.valueOf(Util.null2String(needClockIn.get("tqdkfzs")));
|
|
|
|
|
Map<String,Map<String,Object>> ksdkNearestClcokInTime = Utils.getNearestClcokInTimeCmd(dtkssj,clockInTimeList);
|
|
|
|
|
String timeType = ClockPointEnum.EMPTY.getKey();
|
|
|
|
|
Map<String,Map<String,Object>> clcokInTimeMap = Maps.newHashMap();
|
|
|
|
|
if (ksdkNearestClcokInTime.get(ClockPointEnum.EQUAL.getKey()) != null){
|
|
|
|
|
timeType=ClockPointEnum.EQUAL.getKey();
|
|
|
|
|
}
|
|
|
|
|
if (ClockPointEnum.EMPTY.getKey().equals(timeType) && ksdkNearestClcokInTime.get(ClockPointEnum.BEFORE.getKey()) != null){
|
|
|
|
|
String clockInTime = ksdkNearestClcokInTime.get(ClockPointEnum.BEFORE.getKey()).get("signdate") +" "+ksdkNearestClcokInTime.get(ClockPointEnum.BEFORE.getKey()).get("signtime");
|
|
|
|
|
if (DateUtil.getTime(clockInTime).compareTo(DateUtil.getTime(DateUtil.beforeMinutes(dtkssj,tqdkfzs))) >=0){
|
|
|
|
|
//打卡时间大于等于最早打卡时间
|
|
|
|
|
timeType=ClockPointEnum.BEFORE.getKey();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (ClockPointEnum.EMPTY.getKey().equals(timeType) && ksdkNearestClcokInTime.get(ClockPointEnum.AFTER.getKey()) != null){
|
|
|
|
|
String clockInTime = ksdkNearestClcokInTime.get(ClockPointEnum.AFTER.getKey()).get("signdate") +" "+ksdkNearestClcokInTime.get(ClockPointEnum.AFTER.getKey()).get("signtime");
|
|
|
|
|
if (DateUtil.getTime(clockInTime).compareTo(DateUtil.getTime(dtjssj)) < 0){
|
|
|
|
|
//打卡时间小于结束时间
|
|
|
|
|
timeType=ClockPointEnum.AFTER.getKey();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
clcokInTimeMap.put(dtkssj+"|"+ClockPointEnum.START.getKey()+"|"+timeType,ksdkNearestClcokInTime.get(timeType));
|
|
|
|
|
clcokInTimeData.add(clcokInTimeMap);
|
|
|
|
|
}
|
|
|
|
|
if (CheckBoxEnum.CHECKED.getKey().equals(needClockIn.get("jsdk"))){
|
|
|
|
|
String dtkssj = analysisDate+" "+needClockIn.get("dtkssj");
|
|
|
|
|
String dtjssj = analysisDate+" "+needClockIn.get("dtjssj");
|
|
|
|
|
int thdkfzs = Integer.valueOf(Util.null2String(needClockIn.get("thdkfzs")));
|
|
|
|
|
if (DateUtil.getTime(dtkssj).compareTo(DateUtil.getTime(dtjssj)) > 0){
|
|
|
|
|
dtjssj = DateUtil.AfterDay(analysisDate,1) +" "+needClockIn.get("dtjssj");
|
|
|
|
|
}
|
|
|
|
|
Map<String,Map<String,Object>> jsdkNearestClcokInTime = Utils.getNearestClcokInTimeCmd(dtjssj,clockInTimeList);
|
|
|
|
|
|
|
|
|
|
String timeType = ClockPointEnum.EMPTY.getKey();
|
|
|
|
|
Map<String,Map<String,Object>> clcokInTimeMap = Maps.newHashMap();
|
|
|
|
|
if (jsdkNearestClcokInTime.get(ClockPointEnum.EQUAL.getKey()) != null){
|
|
|
|
|
timeType=ClockPointEnum.EQUAL.getKey();
|
|
|
|
|
}
|
|
|
|
|
if (ClockPointEnum.EMPTY.getKey().equals(timeType) && jsdkNearestClcokInTime.get(ClockPointEnum.AFTER.getKey()) != null){
|
|
|
|
|
String clockInTime = jsdkNearestClcokInTime.get(ClockPointEnum.AFTER.getKey()).get("signdate") +" "+jsdkNearestClcokInTime.get(ClockPointEnum.AFTER.getKey()).get("signtime");
|
|
|
|
|
if (DateUtil.getTime(clockInTime).compareTo(DateUtil.getTime(DateUtil.AfterMinutes(dtjssj,thdkfzs))) <=0){
|
|
|
|
|
timeType=ClockPointEnum.AFTER.getKey();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (ClockPointEnum.EMPTY.getKey().equals(timeType) && jsdkNearestClcokInTime.get(ClockPointEnum.BEFORE.getKey()) != null){
|
|
|
|
|
String clockInTime = jsdkNearestClcokInTime.get(ClockPointEnum.BEFORE.getKey()).get("signdate") +" "+jsdkNearestClcokInTime.get(ClockPointEnum.BEFORE.getKey()).get("signtime");
|
|
|
|
|
if (DateUtil.getTime(clockInTime).compareTo(DateUtil.getTime(dtkssj)) >0){
|
|
|
|
|
timeType=ClockPointEnum.BEFORE.getKey();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
clcokInTimeMap.put(dtjssj+"|"+ClockPointEnum.END.getKey()+"|"+timeType,jsdkNearestClcokInTime.get(timeType));
|
|
|
|
|
clcokInTimeData.add(clcokInTimeMap);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//当有2笔需要打卡时,可能会有打卡歧义的情况,歧义情况取2个时间点的中间值,当打卡时间小于中间值归属前一个打卡,大于则相反
|
|
|
|
|
if (clcokInTimeData.size() >1){
|
|
|
|
|
for (int i=0;i<clcokInTimeData.size()-1;i++){
|
|
|
|
|
Map<String,Map<String,Object>> beforeClcokInTimeData = clcokInTimeData.get(i);
|
|
|
|
|
Map<String,Map<String,Object>> afterClcokInTimeData = clcokInTimeData.get(i+1);
|
|
|
|
|
Map<String,Object> beforeClcokInTimeMap = null;
|
|
|
|
|
String beforeClcokInTime = "";
|
|
|
|
|
String afterClcokInTime = "";
|
|
|
|
|
Map<String,Object> afterClcokInTimeMap = null;
|
|
|
|
|
for (Map.Entry<String,Map<String,Object>> beforeEntry :beforeClcokInTimeData.entrySet()){
|
|
|
|
|
beforeClcokInTimeMap = beforeEntry.getValue();
|
|
|
|
|
beforeClcokInTime = beforeEntry.getKey();
|
|
|
|
|
}
|
|
|
|
|
for (Map.Entry<String,Map<String,Object>> afterEntry :afterClcokInTimeData.entrySet()){
|
|
|
|
|
afterClcokInTimeMap = afterEntry.getValue();
|
|
|
|
|
afterClcokInTime = afterEntry.getKey();
|
|
|
|
|
}
|
|
|
|
|
//重复
|
|
|
|
|
if (beforeClcokInTimeMap != null && beforeClcokInTimeMap == afterClcokInTimeMap ){
|
|
|
|
|
String beforeTime = beforeClcokInTime.split("\\|")[0];
|
|
|
|
|
String afterTime = afterClcokInTime.split("\\|")[0];
|
|
|
|
|
long betWeenMinutes = DateUtil.getBetWeenMinutes(beforeTime,afterTime);
|
|
|
|
|
|
|
|
|
|
String middileTime = DateUtil.AfterMinutes(beforeTime,betWeenMinutes/2);
|
|
|
|
|
|
|
|
|
|
String signdateTime = beforeClcokInTimeMap.get("signdate") +" "+beforeClcokInTimeMap.get("signtime");
|
|
|
|
|
|
|
|
|
|
if (DateUtil.getTime(signdateTime).compareTo(DateUtil.getTime(middileTime)) <=0){
|
|
|
|
|
//该打卡归属前一个打卡点
|
|
|
|
|
afterClcokInTimeData.put(afterClcokInTime,null);
|
|
|
|
|
}else if (DateUtil.getTime(signdateTime).compareTo(DateUtil.getTime(middileTime)) >0){
|
|
|
|
|
//该打卡归属后一个打卡点
|
|
|
|
|
beforeClcokInTimeData.put(beforeClcokInTime,null);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return clcokInTimeData;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|