package com.engine.kq.cmd.attendanceButton; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.cloudstore.dev.api.util.EMManager; import com.engine.common.biz.AbstractCommonCommand; import com.engine.common.entity.BizLogContext; import com.engine.core.interceptor.CommandContext; import com.engine.hostar.util.HostarUtil; import com.engine.kq.biz.*; import com.engine.kq.entity.KQGroupEntity; import com.engine.kq.entity.WorkTimeEntity; import com.engine.kq.log.KQLog; import com.engine.kq.wfset.util.SplitActionUtil; import com.google.common.collect.Maps; import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.lang3.StringUtils; import weaver.common.DateUtil; import weaver.conn.RecordSet; import weaver.dateformat.DateTransformer; import weaver.dateformat.TimeZoneVar; import weaver.general.BaseBean; import weaver.general.Util; import weaver.hrm.User; import weaver.systeminfo.SystemEnv; import javax.servlet.http.HttpServletRequest; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.*; import java.util.Map.Entry; /** * 外勤签到签退 */ public class PunchOutButtonCmd extends AbstractCommonCommand> { private HttpServletRequest request; public KQLog kqLog = new KQLog(); BaseBean bb = new BaseBean(); private Map logMap = Maps.newHashMap(); private Map workTimeEntityLogMap = Maps.newHashMap(); private final List LIST = Arrays.asList("1", "8", "14","15"); public PunchOutButtonCmd(HttpServletRequest request, Map params, User user) { this.request = request; this.user = user; this.params = params; } @Override public Map execute(CommandContext commandContext) { Map retmap = new HashMap(); try{ insertSign(retmap); }catch (Exception e) { retmap.put("status", "-1"); retmap.put("message", SystemEnv.getHtmlLabelName(382661,user.getLanguage())); writeLog(e); } KQCardLogBiz.logCardInfo(user.getUID()+"", logMap, workTimeEntityLogMap, "punchOutButton"); return retmap; } /** * 检验ip是否在考勤组设置的范围要求内 */ private boolean checkIsInIp() { KQGroupBiz kqGroupBiz = new KQGroupBiz(); String clientAddress = Util.getIpAddr(request); return kqGroupBiz.getIsInScope(user.getUID()+"", clientAddress); } private void insertSign(Map retmap) { logMap.put("lastname", user.getLastname()); logMap.put("params", params); // signSection: 2019-03-20 08:30#2019-03-20 18:30 RecordSet rs = new RecordSet(); RecordSet rs1 = new RecordSet(); String serialid = Util.null2String(params.get("serialid")); //应上班 工作时间点 String time = Util.null2String(params.get("time")); //应上班 工作时间 带日期 String datetime = Util.null2String(params.get("datetime")); //允许打卡时段 带日期 String signSectionTime = Util.null2String(params.get("signSectionTime")); //打卡所属worksection的对应的点 String type = Util.null2String(params.get("type")); //所属打卡日期 String belongdate = Util.null2String(params.get("belongdate")); boolean belongdateIsNull = belongdate.length()==0; String islastsign = Util.null2String(params.get("islastsign")); String isPunchOpen = Util.null2String(params.get("isPunchOpen")); String workmins = Util.null2String(params.get("workmins")); //针对非工作时段 签退的时候记录的签到数据 用于计算加班 String signInTime4Out = Util.null2String(params.get("signInTime4Out")); //允许打卡的范围 String signsection = Util.null2String(params.get("signSection")); //手机打卡部分 String longitude = Util.null2String(params.get("longitude")); String latitude = Util.null2String(params.get("latitude")); double d_longitude = Util.getDoubleValue(longitude); double d_latitude = Util.getDoubleValue(latitude); if(d_latitude <= 0){ latitude = ""; } if(d_longitude <= 0){ longitude = ""; } String address = Util.null2String(params.get("address")); String ismobile = Util.null2String(params.get("ismobile")); String remark = Util.null2String(params.get("remark")); String attachment = Util.null2String(params.get("fileids")); //区分是来自于钉钉还是EM7 String browser = Util.null2String(params.get("browser")); //客户 String crm = Util.null2String(params.get("crm")); //是否开启外勤签到转考勤 String outsidesign = ""; KQGroupMemberComInfo kqGroupMemberComInfo = new KQGroupMemberComInfo(); KQGroupEntity kqGroupEntity = kqGroupMemberComInfo.getUserKQGroupInfo(user.getUID()+""); String kqGroupEntityInfo = kqGroupEntity != null ? JSON.toJSONString(kqGroupEntity): ""; logMap.put("kqGroupEntityInfo", kqGroupEntityInfo); if (kqGroupEntity != null) { outsidesign = kqGroupEntity.getOutsidesign(); } kqLog.info(user.getLastname()+":params:"+params+":outsidesign:"+outsidesign); int userId = user.getUID(); String signfrom = "e9_mobile_out"; DateTimeFormatter allFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss"); LocalDateTime localTime = LocalDateTime.now(); String signTime =localTime.format(dateTimeFormatter); String signDate = localTime.format(dateFormatter); KQWorkTime kqWorkTime = new KQWorkTime(); WorkTimeEntity workTimeEntity = kqWorkTime.getWorkTime(user.getUID()+"", signDate); String userinfo = "#userid#"+user.getUID()+"#getUserSubCompany1#"+user.getUserSubCompany1()+"#getUserSubCompany1#"+user.getUserDepartment() +"#getJobtitle#"+user.getJobtitle(); workTimeEntityLogMap.put("resourceid", userinfo); workTimeEntityLogMap.put("splitDate", signDate); workTimeEntityLogMap.put("workTimeEntity", workTimeEntity); //处理多时区 String timeZoneConversion = Util.null2String(new weaver.general.BaseBean().getPropValue("weaver_timezone_conversion","timeZoneConversion")).trim(); logMap.put("timeZoneConversion", timeZoneConversion); if("1".equals(timeZoneConversion)) { DateTransformer dateTransformer=new DateTransformer(); String[] zone_localTime = dateTransformer.getLocaleDateAndTime(signDate,signTime); if(zone_localTime != null && zone_localTime.length == 2){ signDate = zone_localTime[0]; signTime = zone_localTime[1]; } } String timeZone = Util.null2String(TimeZoneVar.getTimeZone(),""); String signData = Util.null2String(params.get("signData")); String groupid = workTimeEntity.getGroupId(); String text ="wea"+ userId + groupid; kqLog.writeLog("PunchOutButtonCmd>text=" + text); String ma5Text = DigestUtils.md5Hex(text)+"ver"; kqLog.writeLog("PunchOutButtonCmd>ma5Text=" + ma5Text+";signData=" + signData); if(!signData.equals(ma5Text)){ retmap.put("status", "0"); retmap.put("message", SystemEnv.getHtmlLabelName(382661,user.getLanguage())); return ; } String mobile_sign_sql = "insert into mobile_sign(operater,operate_type,operate_date,operate_time,longitude,latitude,address,remark,attachment,crm,timezone) " + " values(?,?,?,?,?,?,?,?,?,?,?) "; rs1.executeUpdate(mobile_sign_sql, userId,signfrom,signDate,signTime,longitude,latitude,address,remark,attachment,crm,timeZone); logMap.put("outsidesign", outsidesign); if("1".equalsIgnoreCase(outsidesign)){ JSONObject jsonObject = null; String deviceInfo = Util.null2String(params.get("deviceInfo")); if(deviceInfo.length() > 0){ jsonObject = JSON.parseObject(deviceInfo); JSONObject jsonObject1 = new JSONObject(); Set> jsonSet = jsonObject.entrySet(); for(Entry js : jsonSet){ String key = js.getKey(); String value = Util.null2String(js.getValue()); jsonObject1.put(key, value); } if(!jsonObject1.isEmpty()){ deviceInfo = jsonObject1.toJSONString(); } } if("DingTalk".equalsIgnoreCase(browser)){ signfrom = "DingTalk_out"; }else if("Wechat".equalsIgnoreCase(browser)){ signfrom = "Wechat_out"; String weChat_deviceid = Util.null2String(request.getSession().getAttribute(EMManager.DeviceId)); kqLog.info("EMManager.DeviceId:"+EMManager.DeviceId+":weChat_deviceid:"+weChat_deviceid); logMap.put("weChat_deviceid", weChat_deviceid); if(weChat_deviceid.length() > 0){ //微信打卡的设备号需要单独处理 if(jsonObject != null){ jsonObject.put("deviceId", weChat_deviceid); }else{ jsonObject = new JSONObject(); jsonObject.put("deviceId", weChat_deviceid); } if(!jsonObject.isEmpty()){ deviceInfo = jsonObject.toJSONString(); } } } //自由班制处理 String isfree = Util.null2String(params.get("isfree")); String userType = user.getLogintype(); String signType = "on".equalsIgnoreCase(type) ? "1" : "2"; String clientAddress = Util.getIpAddr(request); boolean isInIp = true; String isInCom = isInIp ? "1" : "0"; String datetime_timezone = signDate+" "+signTime; LocalDateTime nowDateTime = LocalDateTime.parse(datetime_timezone,allFormatter); kqLog.info("timeZone:"+timeZone+":signDate:"+signDate+":signTime:"+signTime+":nowDateTime:"+nowDateTime); boolean isInScope = true; if(signsection != null && signsection.length() > 0){ List signsectionList = Util.TokenizerString(signsection, ","); for(int i = 0 ; i < signsectionList.size() ; i++){ String signsections = Util.null2String(signsectionList.get(i)); String[] signsection_arr = signsections.split("#"); if(signsection_arr != null && signsection_arr.length == 2){ String canStart = signsection_arr[0]; String canEnd = signsection_arr[1]; LocalDateTime startSignDateTime = LocalDateTime.parse(canStart,allFormatter); LocalDateTime endSignDateTime = LocalDateTime.parse(canEnd,allFormatter); if(nowDateTime.isBefore(startSignDateTime) || nowDateTime.isAfter(endSignDateTime)){ isInScope = false; }else{ isInScope = true; break; } } } } if(!isInScope){ //外勤的不在范围内也不管,全部计入考勤表 // retmap.put("status", "1"); // retmap.put("message", SystemEnv.getHtmlLabelName(503597 , user.getLanguage())); // return ; } if(belongdate.length() == 0){ belongdate = signDate; } deviceInfo = deviceInfo.replaceAll("\\?", ""); String punchSql = "insert into HrmScheduleSign(userId,userType,signType,signDate,signTime,clientAddress,isInCom,timeZone,belongdate,signfrom,longitude,latitude,addr,deviceInfo) "+ " values(?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; boolean isok = rs.executeUpdate(punchSql,userId,userType,signType,signDate,signTime,clientAddress,isInCom, timeZone,belongdate,signfrom,longitude,latitude,address,deviceInfo); logMap.put("punchSql", punchSql); logMap.put("punchSql_isok", isok); //同步更新考勤数据到考勤报表 if(belongdateIsNull){ //外勤签到没有归属日期,遇到跨天班次打卡可能归属前一天,需要格式化前一天考勤 kqLog.info("PunchOutButtonCmd:userId:"+userId+":belongdate:"+DateUtil.getYesterday()); new KQFormatBiz().formatDate(""+userId,DateUtil.getYesterday()); } kqLog.info("PunchOutButtonCmd:userId:"+userId+":belongdate:"+(belongdate.length() == 0 ? DateUtil.getCurrentDate() : belongdate)); if(belongdate.length()==0){ //外勤签到没有归属日期,遇到跨天班次打卡可能归属前一天,需要格式化前一天考勤 new KQFormatBiz().formatDate(""+userId,DateUtil.getYesterday()); } new KQFormatBiz().formatDate(""+userId,(belongdate.length() == 0 ? DateUtil.getCurrentDate() : belongdate)); //外勤签到转的考勤 处理加班规则 SplitActionUtil.pushOverTimeTasksAll(belongdate,belongdate,""+userId); } /*考勤二开--外出出差流程外勤打卡start*/ else { bb.writeLog("外勤打卡转考勤卡start"); bb.writeLog("params: " + params); bb.writeLog("signdate: " + signDate); //先判断是否有外出出差流程 String evectionTableName = Util.null2String(bb.getPropValue("project_hostar","evectionTableName")); String outTableName = Util.null2String(bb.getPropValue("project_hostar","outTableName")); if ( StringUtils.isNotBlank(evectionTableName) && StringUtils.isNotBlank(outTableName) ) { Integer number = -1; String sqlDate = ""; if (StringUtils.isNotBlank(belongdate)) { sqlDate = belongdate; } else { sqlDate = signDate; } String acqEvecAndOutSql = " select sum(a.number) as number " + " from ( " + " SELECT " + " count(*) as number " + " FROM " + " workflow_requestbase " + " WHERE " + " requestid IN ( SELECT requestid FROM " + evectionTableName + " WHERE sqr = '" + userId + "' and ksrq <='" + sqlDate + "' and yjjsrq >='" + sqlDate + "' ) " + // " AND currentnodetype = 3 " + " UNION all " + " SELECT " + " count(*) as number " + " FROM " + " workflow_requestbase " + " WHERE " + " requestid IN ( SELECT requestid FROM " + outTableName + " WHERE sqr = '" + userId + "' and ksrq <='" + sqlDate + "' and yjjsrq >='" + sqlDate + "') " + // " AND currentnodetype = 3 " + ") a "; rs.executeQuery(acqEvecAndOutSql); bb.writeLog("acqEvecAndOutSql: " + acqEvecAndOutSql); while (rs.next()) { number = Util.getIntValue(Util.null2String(rs.getString("number"))); } bb.writeLog("number: " + number); if (number > 0) { boolean isInIp = true; String userType = user.getLogintype(); String signType = "on".equalsIgnoreCase(type) ? "1" : "2"; String clientAddress = Util.getIpAddr(request); String isInCom = isInIp ? "1" : "0"; JSONObject jsonObject = null; String deviceInfo = Util.null2String(params.get("deviceInfo")); if(deviceInfo.length() > 0){ jsonObject = JSON.parseObject(deviceInfo); JSONObject jsonObject1 = new JSONObject(); Set> jsonSet = jsonObject.entrySet(); for(Entry js : jsonSet){ String key = js.getKey(); String value = Util.null2String(js.getValue()); jsonObject1.put(key, value); } if(!jsonObject1.isEmpty()){ deviceInfo = jsonObject1.toJSONString(); } } String punchSql = "insert into HrmScheduleSign(userId,userType,signType,signDate,signTime,clientAddress,isInCom,timeZone,belongdate,signfrom,longitude,latitude,addr,deviceInfo,isdev) "+ " values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; boolean isok = rs.executeUpdate(punchSql,userId,userType,signType,signDate,signTime,clientAddress,isInCom, timeZone,belongdate,signfrom,longitude,latitude,address,deviceInfo,"1"); bb.writeLog("isok: " + isok); //自动对班 kqLog.info("PunchOutButtonCmd.format in >>>>>userId" + userId + "kqDate==" + signDate+"format.groupId:"+groupid+"format.serialId:"+workTimeEntity.getSerialId()); if(LIST.contains(groupid)&&StringUtils.isBlank(workTimeEntity.getSerialId())) { RecordSet rt = new RecordSet(); boolean b; //休息日或节假日给休息班次 int changeType = KQOvertimeRulesBiz.getChangeType(Util.null2String(userId), signDate); kqLog.info("format.changeType:" + changeType); String sql = "insert into kq_shiftschedule(kqdate,serialid,resourceid,groupid,isdelete)values(?,?,?,?,?)"; //考勤当天是节假日或者休息日 if (changeType != 2) { //休息班 b = rt.executeUpdate(sql, signDate, "-1", Util.null2String(userId), groupid, "0"); kqLog.info("PunchOutButtonCmd.b1:" + b); }else{ //设置考勤班次为对应班次 b = rt.executeUpdate(sql, signDate, "9", Util.null2String(userId), groupid, "0"); kqLog.info("PunchOutButtonCmd.b2:"+b); } } //同步更新考勤数据到考勤报表 if(belongdateIsNull){ //外勤签到没有归属日期,遇到跨天班次打卡可能归属前一天,需要格式化前一天考勤 bb.writeLog("PunchOutButtonCmd:userId:"+userId+":belongdate:"+DateUtil.getYesterday()); new KQFormatBiz().formatDate(""+userId,DateUtil.getYesterday()); } bb.writeLog("PunchOutButtonCmd:userId:"+userId+":belongdate:"+(belongdate.length() == 0 ? DateUtil.getCurrentDate() : belongdate)); if(belongdate.length()==0){ //外勤签到没有归属日期,遇到跨天班次打卡可能归属前一天,需要格式化前一天考勤 new KQFormatBiz().formatDate(""+userId,DateUtil.getYesterday()); } new KQFormatBiz().formatDate(""+userId,(belongdate.length() == 0 ? DateUtil.getCurrentDate() : belongdate)); //外勤签到转的考勤 处理加班规则 SplitActionUtil.pushOverTimeTasksAll(belongdate,belongdate,""+userId); } else { String acqSql = "select id from mobile_sign where operater = ? and operate_date = ? and operate_time = ? "; rs.executeQuery(acqSql, userId, signDate, signTime); while (rs.next()) { String id = Util.null2String(rs.getString("id")); if (StringUtils.isNotBlank(id)) { //整理原始打卡信息 Map signInfo = new HashMap<>(); boolean isInIp = true; String userType = user.getLogintype(); String signType = "on".equalsIgnoreCase(type) ? "1" : "2"; String clientAddress = Util.getIpAddr(request); String isInCom = isInIp ? "1" : "0"; JSONObject jsonObject = null; String deviceInfo = Util.null2String(params.get("deviceInfo")); if(deviceInfo.length() > 0){ jsonObject = JSON.parseObject(deviceInfo); JSONObject jsonObject1 = new JSONObject(); Set> jsonSet = jsonObject.entrySet(); for(Entry js : jsonSet){ String key = js.getKey(); String value = Util.null2String(js.getValue()); jsonObject1.put(key, value); } if(!jsonObject1.isEmpty()){ deviceInfo = jsonObject1.toJSONString(); } } signInfo.put("userId", userId); signInfo.put("userType", userType); signInfo.put("signType", signType); signInfo.put("signDate", signDate); signInfo.put("signTime", signTime); signInfo.put("clientAddress", clientAddress); signInfo.put("isInCom", isInCom); signInfo.put("timeZone", timeZone); signInfo.put("belongdate", belongdate); signInfo.put("signfrom", signfrom); signInfo.put("longitude", longitude); signInfo.put("latitude", latitude); signInfo.put("address", address); signInfo.put("deviceInfo", deviceInfo); signInfo.put("isdev", "1"); signInfo.put("belongdateIsNull", belongdateIsNull); String signInfoString = signInfo.toString(); String outSignTypeModeId = bb.getPropValue("project_hostar", "outSignTypeModeId"); Integer modedatacreater = 1; Integer modedatacreatertype = 0; String modedatacreatedate = cn.hutool.core.date.DateUtil.format(new Date(), "yyyy-MM-dd"); String modedatacreatetime = cn.hutool.core.date.DateUtil.format(new Date(), "HH:mm:ss"); String abnUuid = UUID.randomUUID().toString(); String syncSql = "insert into uf_outsigntype (outsignid, signinfo, formmodeid, modedatacreater, " + "modedatacreatertype, modedatacreatedate, modedatacreatetime, MODEUUID) values (?, ?, ?, ?, ?, ?, ?, ?)"; boolean b = rs.executeUpdate(syncSql, id, signInfoString, outSignTypeModeId, modedatacreater, modedatacreatertype, modedatacreatedate, modedatacreatetime, abnUuid); if (b) { String billid = "-1"; String acqModeIdSql = "select id from uf_outsigntype where MODEUUID = ?"; rs.executeQuery(acqModeIdSql, abnUuid); while (rs.next()) { billid = Util.null2String(rs.getString("id")); } bb.writeLog("billid:" + billid); new HostarUtil().modePerRecon(modedatacreater, outSignTypeModeId, billid); } } } } } bb.writeLog("外勤打卡转考勤卡end"); } /*考勤二开--外出出差流程外勤打卡end*/ retmap.put("status", "1"); retmap.put("signdate", signDate); retmap.put("signtime", signTime); logMap.put("retmap", retmap); } @Override public BizLogContext getLogContext() { return null; } }