diff --git a/src/com/engine/kq/biz/KQScheduleSignBiz.java b/src/com/engine/kq/biz/KQScheduleSignBiz.java new file mode 100644 index 0000000..d4cbecb --- /dev/null +++ b/src/com/engine/kq/biz/KQScheduleSignBiz.java @@ -0,0 +1,542 @@ +package com.engine.kq.biz; + +import com.engine.kq.bean.KQHrmScheduleSign; +import com.engine.kq.log.KQLog; +import com.engine.kq.wfset.util.KQSignUtil; +import weaver.conn.RecordSet; +import weaver.general.Util; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 签到签退数据处理类 + */ +public class KQScheduleSignBiz { + + private KQLog kqLog = new KQLog(); + private String resourceid; + private String userType; + private String signDate; + private String signTime; + private String worksection; + /** + * 考勤数据所属日期 因为班次可能跨天 + */ + private String belongdate; + private String signtype; + private String signDateTimeSql; + /** + * 上班开始打卡时间 + */ + private String signSectionTime; + + /** + * 上班结束打卡时间 + */ + private String signSectionEndTime; + /** + * 下班开始打卡时间 + */ + private String signSectionBeginTime; + + /** + * 下班结束打卡时间 + */ + private String offSignSectionTime; + + private int shiftCount; + + private int shiftI; + + private String count4NoonStartDateTime; + + private String count4NoonEndDateTime; + + private KQScheduleSignBiz(KQScheduleSignParamBuilder build){ + this.resourceid = build.resourceid; + this.userType = build.userType; + this.signDate = build.signDate; + this.signTime = build.signTime; + this.belongdate = build.belongdate; + this.signtype = build.signtype; + this.worksection = build.worksection; + this.signDateTimeSql = build.signDateTimeSql; + this.signSectionTime = build.signSectionTime; + this.signSectionEndTime = build.signSectionEndTime; + this.signSectionBeginTime = build.signSectionBeginTime; + this.offSignSectionTime = build.offSignSectionTime; + this.shiftCount = build.shiftCount; + this.shiftI = build.shiftI; + this.count4NoonStartDateTime = build.count4NoonStartDateTime; + this.count4NoonEndDateTime = build.count4NoonEndDateTime; + } + + /** + * 自由班制的签到签退数据 + * @return + */ + public List getFreeScheduleSignInfo() { + + RecordSet rs = new RecordSet(); + String signSql = "select * from hrmschedulesign where 1=1 and isInCom='1' "; + String sqlWhere = sqlParamWhere(); + if(sqlWhere.length() > 0){ + signSql += sqlWhere; + } + signSql += " order by signdate,signtime"; + List kqHrmScheduleSigns = new ArrayList<>(); + + try{ + rs.execute(signSql); + while (rs.next()){ + KQHrmScheduleSign kqHrmScheduleSign = getSignBean(rs); + + kqHrmScheduleSigns.add(kqHrmScheduleSign); + } + }catch (Exception e){ + e.printStackTrace(); + } + return kqHrmScheduleSigns; + } + /** + * 非自由班制的考勤数据 + * 针对设置了打卡开始范围,结束范围的数据,即可以出现,只签退没有签到的数据的处理 + * @return + */ + public Map getScheduleSignInfoWithCardRange(){ + + String signSql = ""; + Map signMap = new HashMap<>(); + RecordSet rs = new RecordSet(); + String dbtype = rs.getDBType(); + String baseSql = "select * from hrmschedulesign where 1=1 and isInCom='1' "; + String sqlWhere = sqlParamWhere(); + if(sqlWhere.length() > 0){ + baseSql += sqlWhere; + } + if(signSectionEndTime.length() == 0 && signSectionBeginTime.length() == 0){ + //如果没设置上班后,下班前打卡 + String signTimeSql = KQSignUtil.buildSignSql(signSectionTime,offSignSectionTime); + if(signTimeSql.length() > 0){ + baseSql += " and "+signTimeSql; + } + if(baseSql.length() > 0){ + signSql = baseSql; + signSql += " order by signdate,signtime"; + kqLog.info("signSql:"+signSql); + try{ + rs.execute(signSql); + while (rs.next()){ + getScheduleSignBean(rs,signMap); + } + }catch (Exception e){ + e.printStackTrace(); + } + } + }else { + if(shiftCount == 4 && shiftI==2) { + String signSectionEndTime2 = count4NoonStartDateTime.substring(0, count4NoonStartDateTime.length() - 2) + "00"; + String noonSignTimeSql = KQSignUtil.buildSignSql(signSectionEndTime2, count4NoonEndDateTime); + String sql = baseSql; + if (sqlWhere.length() > 0) { + sql += sqlWhere + " and " + noonSignTimeSql + " order by signdate, signtime"; + } + rs.executeQuery(sql); + int count = 0; + while (rs.next()) { + if(count == 0) { + count ++; + continue; + } + // 午休时段如果有打卡的话,取第二次打卡算作下午第一次签到 + KQHrmScheduleSign kqHrmScheduleSign = getSignBean(rs); + signMap.put("signin", kqHrmScheduleSign); + signMap.put("signinNoon", kqHrmScheduleSign); + if (count == 1) { + break; + } + } + } + String onSignTimeSql = ""; + if(shiftCount == 4 && shiftI==2) { + onSignTimeSql = KQSignUtil.buildSignSql(count4NoonEndDateTime,signSectionEndTime); + } else { + onSignTimeSql = KQSignUtil.buildSignSql(signSectionTime,signSectionEndTime); + } + String offSignTimeSql = KQSignUtil.buildSignSql(signSectionBeginTime,offSignSectionTime); + String onSql = ""; + String orderSql = ""; + if(onSignTimeSql.length() > 0){ + orderSql = " order by signdate asc, signtime asc "; + onSql += "select 'on' as belongtype,t.* from ("+baseSql+" and "+onSignTimeSql+") t"; + if("oracle".equalsIgnoreCase(dbtype)){ + onSql = "select * from ("+onSql+" "+orderSql+" ) a where rownum=1"; + }else if("mysql".equalsIgnoreCase(dbtype)){ + onSql = "select * from (select * from ("+onSql+" "+orderSql+" ) a limit 0,1) a "; + } + else if("postgresql".equalsIgnoreCase(dbtype)){ + onSql = "select * from (select * from ("+onSql+" "+orderSql+" ) a limit 1 offset 0) a "; + } + else if("sqlserver".equalsIgnoreCase(dbtype)){ + onSql = "select top 1 * from ("+onSql+" ) a "+" "+orderSql ; + } + } + String offSql = ""; + if(offSignTimeSql.length() > 0){ + orderSql = " order by signdate desc, signtime desc "; + offSql += "select 'off' as belongtype,t.* from ("+baseSql+" and "+offSignTimeSql+") t"; + if("oracle".equalsIgnoreCase(dbtype)){ + offSql = "select * from ("+offSql+" "+orderSql+" ) a where rownum=1"; + }else if("mysql".equalsIgnoreCase(dbtype)){ + offSql = "select * from (select * from ("+offSql+" "+orderSql+" ) a limit 0,1) a "; + } + else if("postgresql".equalsIgnoreCase(dbtype)){ + offSql = "select * from (select * from ("+offSql+" "+orderSql+" ) a limit 1 offset 0) a "; + } + else if("sqlserver".equalsIgnoreCase(dbtype)){ + offSql = "select top 1 * from ("+offSql+" ) a "+" "+orderSql ; + } + } + if(onSql.length() > 0 && offSql.length() > 0){ + signSql = "select * from ("+onSql+" UNION ALL "+offSql+") s "; + kqLog.info("signSql:"+signSql); + try{ + Map checkMap = new HashMap<>(); + rs.execute(signSql); + while (rs.next()){ + getScheduleSignCardRangeBean(rs,signMap,checkMap); + } + }catch (Exception e){ + e.printStackTrace(); + } + } + if(shiftCount == 4 && shiftI==0) { // 一天4次卡的上午签退卡的统计 + String signSectionEndTime2 = signSectionEndTime.substring(0, signSectionEndTime.length()-2)+"00"; + String noonSignTimeSql = KQSignUtil.buildSignSql(signSectionEndTime2,offSignSectionTime); + String sql = baseSql; + if(sqlWhere.length() > 0){ + sql += sqlWhere+" and "+noonSignTimeSql + " order by signdate, signtime"; + } + rs.executeQuery(sql); + if (rs.next()) { + String signTime = rs.getString("signtime"); + KQHrmScheduleSign kqHrmScheduleSignOut = signMap.get("signout"); + String oldSignTime = kqHrmScheduleSignOut.getSigntime(); + // 午休时段如果有打卡的话,取第一次打卡算作签退 + if(signTime.compareTo(oldSignTime) < 0) { + kqHrmScheduleSignOut.setSigntime(signTime); + } + } + } + } + + return signMap; + } + + /** + * 如果签到和签退可以独立出来,用这个方法 + * @param rs + * @param signMap + * @param checkMap + */ + public void getScheduleSignCardRangeBean(RecordSet rs, Map signMap, + Map checkMap){ + String belongtype =Util.null2String(rs.getString("belongtype")); + if(shiftCount == 4 && shiftI==2) { + if(!signMap.isEmpty()) { + KQHrmScheduleSign kqHrmScheduleSignNoon = signMap.get("signinNoon"); + KQHrmScheduleSign kqHrmScheduleSignOn = signMap.get("signin"); + if(kqHrmScheduleSignNoon != null) { + if("on".equalsIgnoreCase(belongtype)) { + return; + } else { + KQHrmScheduleSign kqHrmScheduleSign = getSignBean(rs); + if(kqHrmScheduleSign != null && kqHrmScheduleSignOn.equals(kqHrmScheduleSign)) { + return; + } + signMap.put("signout",kqHrmScheduleSign); + return; + } + } + } + } + KQHrmScheduleSign kqHrmScheduleSign = getSignBean(rs); + if("on".equalsIgnoreCase(belongtype)){ + if(!checkMap.containsKey("on")){ + signMap.put("signin",kqHrmScheduleSign); + } + }else{ + KQHrmScheduleSign kqHrmScheduleSignOn = signMap.get("signin"); + if(kqHrmScheduleSignOn != null && kqHrmScheduleSign != null && kqHrmScheduleSignOn.equals(kqHrmScheduleSign)) { + return; + } + signMap.put("signout",kqHrmScheduleSign); + } + } + + + /** + * 原始的获取最早时间作为签到,最晚时间作为签退的方法 + * @param rs + * @param signMap + */ + public void getScheduleSignBean(RecordSet rs,Map signMap){ + KQHrmScheduleSign kqHrmScheduleSign = getSignBean(rs); + if(signMap.isEmpty()){ + signMap.put("signin",kqHrmScheduleSign); + }else { + signMap.put("signout",kqHrmScheduleSign); + } + } + + public KQHrmScheduleSign getSignBean(RecordSet rs){ + + KQHrmScheduleSign kqHrmScheduleSign = new KQHrmScheduleSign(); + String id=Util.null2String(rs.getString("id")); + String userid=Util.null2String(rs.getString("userid")); + String usertype =Util.null2String(rs.getString("usertype")); + String signtype=Util.null2String(rs.getString("signtype")); + String signdate=Util.null2String(rs.getString("signdate")); + String signtime=Util.null2String(rs.getString("signtime")); + String clientaddress=Util.null2String(rs.getString("clientaddress")); + String signfrom=Util.null2String(rs.getString("signfrom")); + String longitude=Util.null2String(rs.getString("longitude")); + String latitude=Util.null2String(rs.getString("latitude")); + String addr=Util.null2String(rs.getString("addr")); + String isincom=Util.null2String(rs.getString("isincom")); + String isimport=Util.null2String(rs.getString("isimport")); + String importsql=Util.null2String(rs.getString("importsql")); + String belongdate=Util.null2String(rs.getString("belongdate")); + String serialid=Util.null2String(rs.getString("serialid")); + String worksections=Util.null2String(rs.getString("worksection")); + String signstatus=Util.null2String(rs.getString("signstatus")); + + kqHrmScheduleSign.setId(id); + kqHrmScheduleSign.setUserid(userid); + kqHrmScheduleSign.setUsertype(usertype); + kqHrmScheduleSign.setSigntype(signtype); + kqHrmScheduleSign.setSigndate(signdate); + kqHrmScheduleSign.setSigntime(signtime); + kqHrmScheduleSign.setClientaddress(clientaddress); + kqHrmScheduleSign.setSignfrom(signfrom); + kqHrmScheduleSign.setLongitude(longitude); + kqHrmScheduleSign.setLatitude(latitude); + kqHrmScheduleSign.setAddr(addr); + kqHrmScheduleSign.setIsincom(isincom); + kqHrmScheduleSign.setIsimport(isimport); + kqHrmScheduleSign.setImportsql(importsql); + kqHrmScheduleSign.setBelongdate(belongdate); + kqHrmScheduleSign.setSerialid(serialid); + kqHrmScheduleSign.setWorksections(worksections); + kqHrmScheduleSign.setSignstatus(signstatus); + + return kqHrmScheduleSign; + } + + /** + * 非自由班制的考勤数据 + * @return + */ + public Map getScheduleSignInfo(){ + + RecordSet rs = new RecordSet(); + String signSql = "select * from hrmschedulesign where 1=1 and isInCom='1' "; + String sqlWhere = sqlParamWhere(); + if(sqlWhere.length() > 0){ + signSql += sqlWhere; + } + signSql += " order by signdate,signtime"; + Map signMap = new HashMap<>(); + + try{ + kqLog.info("signSql:"+signSql); + rs.execute(signSql); + while (rs.next()){ + getScheduleSignBean(rs,signMap); + } + }catch (Exception e){ + e.printStackTrace(); + } + return signMap; + } + + /** + * 生成相应的查询条件 + * @return + */ + private String sqlParamWhere() { + String sqlWhere = ""; + if(resourceid.length() > 0){ + sqlWhere += " and userid in ( "+resourceid+" )"; + } + if(signDate.length() > 0){ + sqlWhere += " and signDate = '"+signDate+"' "; + } + if(signTime.length() > 0){ + sqlWhere += " and signTime = '"+signTime+"' "; + } + if(signDateTimeSql.length() > 0){ + sqlWhere += " and "+signDateTimeSql; + } + if(belongdate.length() > 0){ + sqlWhere += " and belongdate = '"+belongdate+"' "; + } + if(signtype.length() > 0){ + sqlWhere += " and signtype = '"+signtype+"' "; + } + //不需要userType,没啥用 +// if(userType.length() > 0){ +// sqlWhere += " and userType = '"+userType+"' "; +// } + if(worksection.length() > 0){ + sqlWhere += " and worksection = '"+worksection+"' "; + } + return sqlWhere; + } + + public static class KQScheduleSignParamBuilder{ + private String resourceid; + private String userType; + private String signDate; + private String signTime; + private String belongdate; + private String signtype; + private String worksection; + private int shiftCount; + private int shiftI; + private String count4NoonStartDateTime; + private String count4NoonEndDateTime; + /** + * 自定义sql + */ + private String signDateTimeSql; + /** + * 上班开始打卡时间 + */ + private String signSectionTime; + + /** + * 上班结束打卡时间 + */ + private String signSectionEndTime; + /** + * 下班开始打卡时间 + */ + private String signSectionBeginTime; + + /** + * 下班结束打卡时间 + */ + private String offSignSectionTime; + + public KQScheduleSignParamBuilder() { + this.resourceid = resourceid; + //初始化的时候需要把其他参数先清空下 + this.userType = ""; + this.signDate = ""; + this.signTime = ""; + this.belongdate = ""; + this.signtype = ""; + this.worksection = ""; + this.signDateTimeSql = ""; + this.signSectionTime = ""; + this.signSectionEndTime = ""; + this.signSectionBeginTime = ""; + this.offSignSectionTime = ""; + this.shiftCount = 0; + this.shiftI = 0; + this.count4NoonStartDateTime = ""; + this.count4NoonEndDateTime = ""; + } + //成员方法返回其自身,所以可以链式调用 + public KQScheduleSignParamBuilder resourceidParam(final String resourceid) { + this.resourceid = resourceid; + return this; + } + + public KQScheduleSignParamBuilder userTypeParam(final String userType) { + this.userType = userType; + return this; + } + + public KQScheduleSignParamBuilder shiftCountParam(final int shiftCount) { + this.shiftCount = shiftCount; + return this; + } + + public KQScheduleSignParamBuilder count4NoonStartDateTimeParam(final String count4NoonStartDateTime) { + this.count4NoonStartDateTime = count4NoonStartDateTime; + return this; + } + + public KQScheduleSignParamBuilder count4NoonEndDateTimeParam(final String count4NoonEndDateTime) { + this.count4NoonEndDateTime = count4NoonEndDateTime; + return this; + } + + public KQScheduleSignParamBuilder shiftIParam(final int shiftI) { + this.shiftI = shiftI; + return this; + } + + public KQScheduleSignParamBuilder signDateParam(final String signDate) { + this.signDate = signDate; + return this; + } + + public KQScheduleSignParamBuilder signTimeParam(final String signTime) { + this.signTime = signTime; + return this; + } + + public KQScheduleSignParamBuilder belongDateParam(final String belongdate) { + this.belongdate = belongdate; + return this; + } + + public KQScheduleSignParamBuilder signtypeParam(final String signtype) { + this.signtype = signtype; + return this; + } + + public KQScheduleSignParamBuilder worksectionParam(final String worksection) { + this.worksection = worksection; + return this; + } + + public KQScheduleSignParamBuilder signDateTimeSqlParam(final String signDateTimeSql) { + this.signDateTimeSql = signDateTimeSql; + return this; + } + + public KQScheduleSignParamBuilder signSectionTimeParam(final String signSectionTime) { + this.signSectionTime = signSectionTime; + return this; + } + + public KQScheduleSignParamBuilder signSectionEndTimeParam(final String signSectionEndTime) { + this.signSectionEndTime = signSectionEndTime; + return this; + } + + public KQScheduleSignParamBuilder signSectionBeginTimeParam(final String signSectionBeginTime) { + this.signSectionBeginTime = signSectionBeginTime; + return this; + } + + public KQScheduleSignParamBuilder offSignSectionTimeParam(final String offSignSectionTime) { + this.offSignSectionTime = offSignSectionTime; + return this; + } + //Builder的build方法,返回外部类的实例 + public KQScheduleSignBiz build() { + return new KQScheduleSignBiz(this); + } + + } + + +} diff --git a/src/com/engine/kq/cmd/report/ExportDailyExcelCmd.java b/src/com/engine/kq/cmd/report/ExportDailyExcelCmd.java index 8af4fd0..02a9b65 100644 --- a/src/com/engine/kq/cmd/report/ExportDailyExcelCmd.java +++ b/src/com/engine/kq/cmd/report/ExportDailyExcelCmd.java @@ -188,7 +188,7 @@ public class ExportDailyExcelCmd extends AbstractCommonCommand0){ diff --git a/src/com/engine/kq/cmd/report/ExportExcelCmd.java b/src/com/engine/kq/cmd/report/ExportExcelCmd.java index 15e9edf..f928092 100644 --- a/src/com/engine/kq/cmd/report/ExportExcelCmd.java +++ b/src/com/engine/kq/cmd/report/ExportExcelCmd.java @@ -213,7 +213,7 @@ public class ExportExcelCmd extends AbstractCommonCommand> { " sum(b.leaveEarlyMins) as leaveEarlyMins, sum(b.graveLeaveEarly) as graveLeaveEarly, " + " sum(b.graveLeaveEarlyMins) as graveLeaveEarlyMins,sum(b.absenteeism) as absenteeism, " + " sum(b.signdays) as signdays,sum(b.signmins) as signmins, "+ - " sum(b.absenteeismMins) as absenteeismMins, sum(b.forgotCheck)+"+forgotBeginWorkCheck_field+" as forgotCheck "+(definedFieldSum.length()>0?","+definedFieldSum+"":""); + " sum(FLOOR( (b.absenteeismMins / 60 ) /0.5 ) * 0.5 * 60 AS absenteeismMins) as absenteeismMins, sum(b.forgotCheck)+"+forgotBeginWorkCheck_field+" as forgotCheck "+(definedFieldSum.length()>0?","+definedFieldSum+"":""); if(rs.getDBType().equals("oracle")){ backFields = "/*+ index(kq_format_total IDX_KQ_FORMAT_TOTAL_KQDATE) */ "+backFields; } diff --git a/src/com/engine/kq/cmd/report/GetKQDailyReportCmd.java b/src/com/engine/kq/cmd/report/GetKQDailyReportCmd.java index 35b3926..1450b80 100644 --- a/src/com/engine/kq/cmd/report/GetKQDailyReportCmd.java +++ b/src/com/engine/kq/cmd/report/GetKQDailyReportCmd.java @@ -147,7 +147,7 @@ public class GetKQDailyReportCmd extends AbstractCommonCommand0){ diff --git a/src/com/engine/kq/cmd/report/GetKQReportCmd.java b/src/com/engine/kq/cmd/report/GetKQReportCmd.java index 5d25fd5..1cd7c69 100644 --- a/src/com/engine/kq/cmd/report/GetKQReportCmd.java +++ b/src/com/engine/kq/cmd/report/GetKQReportCmd.java @@ -179,7 +179,7 @@ public class GetKQReportCmd extends AbstractCommonCommand> { " sum(b.leaveEarlyMins) as leaveEarlyMins, sum(b.graveLeaveEarly) as graveLeaveEarly, " + " sum(b.graveLeaveEarlyMins) as graveLeaveEarlyMins,sum(b.absenteeism) as absenteeism, " + " sum(b.signdays) as signdays,sum(b.signmins) as signmins, "+ - " sum(b.absenteeismMins) as absenteeismMins, sum(b.forgotCheck)+"+forgotBeginWorkCheck_field+" as forgotCheck "+(definedFieldSum.length()>0?","+definedFieldSum+"":""); + " sum(FLOOR( (b.absenteeismMins / 60 ) /0.5 ) * 0.5 * 60 AS absenteeismMins) as absenteeismMins, sum(b.forgotCheck)+"+forgotBeginWorkCheck_field+" as forgotCheck "+(definedFieldSum.length()>0?","+definedFieldSum+"":""); if(rs.getDBType().equals("oracle")){ backFields = "/*+ index(kq_format_total IDX_KQ_FORMAT_TOTAL_KQDATE) */ "+backFields;