|
|
package com.engine.jucailinkq.common.util;
|
|
|
|
|
|
import com.engine.jucailinkq.attendance.attendanceanalysis.dto.clockpoint.ClockPointDTO;
|
|
|
import com.engine.jucailinkq.attendance.enums.*;
|
|
|
import com.google.common.collect.Lists;
|
|
|
import com.google.common.collect.Maps;
|
|
|
import com.google.common.collect.Sets;
|
|
|
import com.google.common.reflect.TypeToken;
|
|
|
import com.google.gson.Gson;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.jetbrains.annotations.NotNull;
|
|
|
import weaver.general.BaseBean;
|
|
|
import weaver.general.Util;
|
|
|
import weaver.hrm.company.SubCompanyComInfo;
|
|
|
|
|
|
import java.io.File;
|
|
|
import java.io.FileFilter;
|
|
|
import java.io.IOException;
|
|
|
import java.lang.reflect.Type;
|
|
|
import java.math.BigDecimal;
|
|
|
import java.math.MathContext;
|
|
|
import java.math.RoundingMode;
|
|
|
import java.net.JarURLConnection;
|
|
|
import java.net.URL;
|
|
|
import java.net.URLDecoder;
|
|
|
import java.time.ZoneOffset;
|
|
|
import java.util.*;
|
|
|
import java.util.jar.JarEntry;
|
|
|
import java.util.jar.JarFile;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
@Slf4j
|
|
|
public class Utils<T> {
|
|
|
public static Gson gson = new Gson();
|
|
|
public static Type list_map_type = new TypeToken<List<Map<String,String>>>(){}.getType();
|
|
|
public static Type map_type = new TypeToken<Map<String,Object>>(){}.getType();
|
|
|
public static BaseBean baseBean = new BaseBean();
|
|
|
/**
|
|
|
* 解析格式为[{a:b,c:d}]格式的json
|
|
|
* @param json
|
|
|
* @return
|
|
|
*/
|
|
|
public static List<Map<String,String>> resolveList_Map(String json){
|
|
|
List<Map<String,String>> list= gson.fromJson(json,list_map_type);
|
|
|
return list;
|
|
|
}
|
|
|
/**
|
|
|
* 解析格式为{a:b,c:d}格式的json
|
|
|
* @param json
|
|
|
* @return
|
|
|
*/
|
|
|
public static Map<String,Object> resolveMap(String json){
|
|
|
Map<String,Object> list= gson.fromJson(json,map_type);
|
|
|
return list;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 通过接口名取得某个接口下所有实现这个接口的类
|
|
|
*/
|
|
|
public List<T> getAllClassByInterface(Class<?> c) {
|
|
|
List<T> returnClassList = null;
|
|
|
if (c.isInterface()) {
|
|
|
try {
|
|
|
// 获取当前的包名
|
|
|
String packageName = c.getPackage().getName();
|
|
|
// 获取当前包下以及子包下所以的类
|
|
|
List<Class<?>> allClass = getClasses(packageName);
|
|
|
if (allClass != null) {
|
|
|
returnClassList = new ArrayList();
|
|
|
for (Class<?> cls : allClass) {
|
|
|
// 判断是否是同一个接口
|
|
|
if (c.isAssignableFrom(cls)) {
|
|
|
// 本身不加入进去
|
|
|
if (!c.equals(cls)) {
|
|
|
returnClassList.add((T)cls.newInstance());
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}catch (Exception e){
|
|
|
baseBean.writeLog(e);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return returnClassList;
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
* 从包package中获取所有的Class
|
|
|
*
|
|
|
* @param packageName
|
|
|
* @return
|
|
|
*/
|
|
|
@NotNull
|
|
|
public static List<Class<?>> getClasses(String packageName) {
|
|
|
// 第一个class类的集合
|
|
|
List<Class<?>> classes = new ArrayList<Class<?>>();
|
|
|
// 是否循环迭代
|
|
|
boolean recursive = true;
|
|
|
// 获取包的名字 并进行替换
|
|
|
String packageDirName = packageName.replace('.', '/');
|
|
|
// 定义一个枚举的集合 并进行循环来处理这个目录下的things
|
|
|
Enumeration<URL> dirs;
|
|
|
try {
|
|
|
dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName);
|
|
|
// 循环迭代下去
|
|
|
while (dirs.hasMoreElements()) {
|
|
|
// 获取下一个元素
|
|
|
URL url = dirs.nextElement();
|
|
|
// 得到协议的名称
|
|
|
String protocol = url.getProtocol();
|
|
|
// 如果是以文件的形式保存在服务器上
|
|
|
if ("file".equals(protocol)) {
|
|
|
// 获取包的物理路径
|
|
|
String filePath = URLDecoder.decode(url.getFile(), "UTF-8");
|
|
|
// 以文件的方式扫描整个包下的文件 并添加到集合中
|
|
|
findAndAddClassesInPackageByFile(packageName, filePath, recursive, classes);
|
|
|
} else if ("jar".equals(protocol)) {
|
|
|
// 如果是jar包文件
|
|
|
// 定义一个JarFile
|
|
|
JarFile jar;
|
|
|
try {
|
|
|
// 获取jar
|
|
|
jar = ((JarURLConnection) url.openConnection()).getJarFile();
|
|
|
// 从此jar包 得到一个枚举类
|
|
|
Enumeration<JarEntry> entries = jar.entries();
|
|
|
// 同样的进行循环迭代
|
|
|
while (entries.hasMoreElements()) {
|
|
|
// 获取jar里的一个实体 可以是目录 和一些jar包里的其他文件 如META-INF等文件
|
|
|
JarEntry entry = entries.nextElement();
|
|
|
String name = entry.getName();
|
|
|
// 如果是以/开头的
|
|
|
if (name.charAt(0) == '/') {
|
|
|
// 获取后面的字符串
|
|
|
name = name.substring(1);
|
|
|
}
|
|
|
// 如果前半部分和定义的包名相同
|
|
|
if (name.startsWith(packageDirName)) {
|
|
|
int idx = name.lastIndexOf('/');
|
|
|
// 如果以"/"结尾 是一个包
|
|
|
if (idx != -1) {
|
|
|
// 获取包名 把"/"替换成"."
|
|
|
packageName = name.substring(0, idx).replace('/', '.');
|
|
|
}
|
|
|
// 如果可以迭代下去 并且是一个包
|
|
|
if ((idx != -1) || recursive) {
|
|
|
// 如果是一个.class文件 而且不是目录
|
|
|
if (name.endsWith(".class") && !entry.isDirectory()) {
|
|
|
// 去掉后面的".class" 获取真正的类名
|
|
|
String className = name.substring(packageName.length() + 1, name.length() - 6);
|
|
|
try {
|
|
|
// 添加到classes
|
|
|
classes.add(Class.forName(packageName + '.' + className));
|
|
|
} catch (ClassNotFoundException e) {
|
|
|
baseBean.writeLog(e);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
} catch (IOException e) {
|
|
|
baseBean.writeLog(e);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
}
|
|
|
} catch (IOException e) {
|
|
|
baseBean.writeLog(e);
|
|
|
}
|
|
|
|
|
|
return classes;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 以文件的形式来获取包下的所有Class
|
|
|
*
|
|
|
* @param packageName
|
|
|
* @param packagePath
|
|
|
* @param recursive
|
|
|
* @param classes
|
|
|
*/
|
|
|
public static void findAndAddClassesInPackageByFile(String packageName, String packagePath, final boolean recursive, List<Class<?>> classes) {
|
|
|
// 获取此包的目录 建立一个File
|
|
|
File dir = new File(packagePath);
|
|
|
// 如果不存在或者 也不是目录就直接返回
|
|
|
if (!dir.exists() || !dir.isDirectory()) {
|
|
|
return;
|
|
|
}
|
|
|
// 如果存在 就获取包下的所有文件 包括目录
|
|
|
File[] dirfiles = dir.listFiles(new FileFilter() {
|
|
|
// 自定义过滤规则 如果可以循环(包含子目录) 或则是以.class结尾的文件(编译好的java类文件)
|
|
|
@Override
|
|
|
public boolean accept(File file) {
|
|
|
return (recursive && file.isDirectory()) || (file.getName().endsWith(".class"));
|
|
|
}
|
|
|
});
|
|
|
// 循环所有文件
|
|
|
for (File file : dirfiles) {
|
|
|
// 如果是目录 则继续扫描
|
|
|
if (file.isDirectory()) {
|
|
|
findAndAddClassesInPackageByFile(packageName + "." + file.getName(), file.getAbsolutePath(), recursive, classes);
|
|
|
} else {
|
|
|
// 如果是java类文件 去掉后面的.class 只留下类名
|
|
|
String className = file.getName().substring(0, file.getName().length() - 6);
|
|
|
try {
|
|
|
// 添加到集合中去
|
|
|
classes.add(Class.forName(packageName + '.' + className));
|
|
|
} catch (ClassNotFoundException e) {
|
|
|
e.printStackTrace();
|
|
|
baseBean.writeLog(e);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
/**
|
|
|
* 获得time时间内最近的前后打卡时间数据
|
|
|
* @param time
|
|
|
* @param clockInTimeList 打卡数据
|
|
|
* @return
|
|
|
*/
|
|
|
public static Map<ClockPointEnum,Map<String,Object>> getNearestClcokInTimeCmd(String time,List<Map<String, Object>> clockInTimeList){
|
|
|
Map<ClockPointEnum,Map<String,Object>> resultMap = Maps.newHashMap();
|
|
|
for (int i=0;i<clockInTimeList.size();i++){
|
|
|
String signDateTime = clockInTimeList.get(i).get("signdate") +" "+clockInTimeList.get(i).get("signtime");
|
|
|
int j=i+1;
|
|
|
if (j > clockInTimeList.size()-1){
|
|
|
j = clockInTimeList.size()-1;
|
|
|
}
|
|
|
String afterSignDateTime = clockInTimeList.get(j).get("signdate") +" "+clockInTimeList.get(j).get("signtime");
|
|
|
if (i==0 && DateUtil.getTime(time).compareTo(DateUtil.getTime(signDateTime)) <0){
|
|
|
resultMap.put(ClockPointEnum.AFTER,clockInTimeList.get(i));
|
|
|
}else if (i == clockInTimeList.size()-1 && DateUtil.getTime(time).compareTo(DateUtil.getTime(signDateTime)) >0){
|
|
|
resultMap.put(ClockPointEnum.BEFORE,clockInTimeList.get(i));
|
|
|
}else if (DateUtil.getTime(time).compareTo(DateUtil.getTime(signDateTime)) >0 && DateUtil.getTime(time).compareTo(DateUtil.getTime(afterSignDateTime)) <0){
|
|
|
resultMap.put(ClockPointEnum.BEFORE,clockInTimeList.get(i));
|
|
|
resultMap.put(ClockPointEnum.AFTER,clockInTimeList.get(j));
|
|
|
}else if (DateUtil.getTime(time).compareTo(DateUtil.getTime(signDateTime)) == 0){
|
|
|
resultMap.put(ClockPointEnum.EQUAL,clockInTimeList.get(i));
|
|
|
}
|
|
|
}
|
|
|
return resultMap;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 根据核算量、核算单位,计算出具体项目时长,向上核算
|
|
|
* @param hsl 核算量
|
|
|
* @param hsdw 核算单位
|
|
|
* @param duration 时间值
|
|
|
* @param unit 时间值单位
|
|
|
* @param edsc 班次额定时长
|
|
|
* @return
|
|
|
*/
|
|
|
public static double getItemduration(double hsl, String hsdw,double duration, AccountingUnitEnum unit,double edsc){
|
|
|
double itemDuration = 0.0;
|
|
|
BigDecimal durationBig = new BigDecimal(duration);
|
|
|
BigDecimal hslBig = new BigDecimal(hsl);
|
|
|
if (AccountingUnitEnum.DAY.getKey().equals(hsdw)){
|
|
|
double durationDay = 0;
|
|
|
if (unit.equals(AccountingUnitEnum.MINUTES)){
|
|
|
durationDay = Utils.divide(Utils.divide(duration,60),edsc);
|
|
|
|
|
|
}else if (unit.equals(AccountingUnitEnum.HOUR)){
|
|
|
durationDay = Utils.divide(duration,edsc);
|
|
|
}else if (unit.equals(AccountingUnitEnum.DAY)){
|
|
|
durationDay=duration;
|
|
|
}
|
|
|
durationBig = new BigDecimal(durationDay);
|
|
|
if (Double.compare(durationDay/hsl,Math.floor(durationDay/hsl)) > 0){
|
|
|
durationBig = new BigDecimal(Math.floor(durationDay/hsl));
|
|
|
itemDuration = durationBig.multiply(hslBig).add(hslBig,new MathContext(BigDecimal.ROUND_HALF_UP)).doubleValue();
|
|
|
}else {
|
|
|
itemDuration = durationBig.multiply(hslBig).divide(hslBig,BigDecimal.ROUND_DOWN).doubleValue();
|
|
|
}
|
|
|
}else if (AccountingUnitEnum.ONCE.getKey().equals(hsdw)){
|
|
|
itemDuration=hsl;
|
|
|
}else if (AccountingUnitEnum.HOUR.getKey().equals(hsdw)){
|
|
|
double durationHour = 0;
|
|
|
if (unit.equals(AccountingUnitEnum.MINUTES)){
|
|
|
durationHour = duration/60.0;
|
|
|
}else if (unit.equals(AccountingUnitEnum.HOUR)){
|
|
|
durationHour = duration;
|
|
|
}else if (unit.equals(AccountingUnitEnum.DAY)){
|
|
|
durationHour = duration*edsc;
|
|
|
}
|
|
|
durationBig = new BigDecimal(durationHour);
|
|
|
if ((durationHour/hsl) > Math.floor(durationHour/hsl)){
|
|
|
// (durationHour/hsl)*hsl+hsl
|
|
|
durationBig = new BigDecimal(Math.floor(durationHour/hsl));
|
|
|
itemDuration = durationBig.multiply(hslBig).add(hslBig,new MathContext(BigDecimal.ROUND_HALF_UP)).doubleValue();
|
|
|
}else {
|
|
|
itemDuration = durationBig.multiply(hslBig).divide(hslBig,BigDecimal.ROUND_DOWN).doubleValue();
|
|
|
}
|
|
|
}else if (AccountingUnitEnum.MINUTES.getKey().equals(hsdw)){
|
|
|
double durationMinute = 0;
|
|
|
if (unit.equals(AccountingUnitEnum.MINUTES)){
|
|
|
durationMinute = duration;
|
|
|
}else if (unit.equals(AccountingUnitEnum.HOUR)){
|
|
|
durationMinute = duration*60;
|
|
|
}else if (unit.equals(AccountingUnitEnum.DAY)){
|
|
|
durationMinute = duration*24*60;
|
|
|
}
|
|
|
durationBig = new BigDecimal(durationMinute);
|
|
|
if ((durationMinute/hsl) > Math.floor(durationMinute/hsl)){
|
|
|
durationBig = new BigDecimal(Math.floor(durationMinute/hsl));
|
|
|
itemDuration=durationBig.multiply(hslBig).add(hslBig,new MathContext(BigDecimal.ROUND_HALF_UP)).doubleValue();
|
|
|
}else {
|
|
|
itemDuration = durationBig.multiply(hslBig).divide(hslBig,BigDecimal.ROUND_DOWN).doubleValue();
|
|
|
}
|
|
|
}
|
|
|
return itemDuration;
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
* 根据核算量、核算单位,计算出具体项目时长,向下核算
|
|
|
* @param hsl 核算量
|
|
|
* @param hsdw 核算单位
|
|
|
* @param duration 时间值
|
|
|
* @param unit 时间值单位
|
|
|
* @return
|
|
|
*/
|
|
|
public static double getItemdurationDown(double hsl, String hsdw,int duration, AccountingUnitEnum unit){
|
|
|
double itemDuration = 0.0;
|
|
|
BigDecimal durationBig = new BigDecimal(duration);
|
|
|
BigDecimal hslBig = new BigDecimal(hsl);
|
|
|
if (AccountingUnitEnum.DAY.getKey().equals(hsdw) || AccountingUnitEnum.ONCE.getKey().equals(hsdw)){
|
|
|
itemDuration = hsl;
|
|
|
}else if (AccountingUnitEnum.HOUR.getKey().equals(hsdw)){
|
|
|
if (unit.equals(AccountingUnitEnum.MINUTES)){
|
|
|
double durationHour = duration/60.0;
|
|
|
// if (duration%60 > 0){
|
|
|
// durationHour = durationHour +1;
|
|
|
// }
|
|
|
durationBig = new BigDecimal(durationHour);
|
|
|
if ((durationHour/hsl) > Math.floor(durationHour/hsl)){
|
|
|
// (durationHour/hsl)*hsl+hsl
|
|
|
durationBig = new BigDecimal(Math.floor(durationHour/hsl));
|
|
|
itemDuration = durationBig.multiply(hslBig).doubleValue();
|
|
|
}else {
|
|
|
itemDuration = durationBig.multiply(hslBig).divide(hslBig,BigDecimal.ROUND_DOWN).doubleValue();
|
|
|
}
|
|
|
|
|
|
}else if (unit.equals(AccountingUnitEnum.HOUR)){
|
|
|
if ((duration/hsl) > Math.floor(duration/hsl)){
|
|
|
durationBig = new BigDecimal(Math.floor(duration/hsl));
|
|
|
itemDuration=durationBig.multiply(hslBig).doubleValue();
|
|
|
}else {
|
|
|
itemDuration = durationBig.multiply(hslBig).divide(hslBig,BigDecimal.ROUND_DOWN).doubleValue();
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}else if (AccountingUnitEnum.MINUTES.getKey().equals(hsdw)){
|
|
|
if (unit.equals(AccountingUnitEnum.MINUTES)){
|
|
|
if ((duration/hsl) > Math.floor(duration/hsl)){
|
|
|
durationBig = new BigDecimal(Math.floor(duration/hsl));
|
|
|
itemDuration=durationBig.multiply(hslBig).doubleValue();
|
|
|
}else {
|
|
|
itemDuration = durationBig.multiply(hslBig).divide(hslBig,BigDecimal.ROUND_DOWN).doubleValue();
|
|
|
}
|
|
|
|
|
|
}else if (unit.equals(AccountingUnitEnum.HOUR)){
|
|
|
int durationMinute = duration*60;
|
|
|
durationBig = new BigDecimal(durationMinute);
|
|
|
if ((durationMinute/hsl) > Math.floor(durationMinute/hsl)){
|
|
|
durationBig = new BigDecimal(Math.floor(durationMinute/hsl));
|
|
|
itemDuration=durationBig.multiply(hslBig).doubleValue();
|
|
|
}else {
|
|
|
itemDuration = durationBig.multiply(hslBig).divide(hslBig,BigDecimal.ROUND_DOWN).doubleValue();
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
return itemDuration;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 请假、外出时间扣出休息时间
|
|
|
* @param kssj 开始时间
|
|
|
* @param jssj 结束时间
|
|
|
* @param scheduleResult 班次
|
|
|
* @return
|
|
|
*/
|
|
|
public static int removeRestTime(String kssj,String jssj,List<Map<String, Object>> scheduleResult,String analysisDate){
|
|
|
scheduleResult = scheduleResult.stream().filter(e -> ClassSegmentTypeEnum.REST_AND_DINE.getKey().equals(e.get("bdlx")) ||
|
|
|
ClassSegmentTypeEnum.REST_PERIOD.getKey().equals(e.get("bdlx")) || ClassSegmentTypeEnum.DINING_PERIOD.getKey().equals(e.get("bdlx"))).collect(Collectors.toList());
|
|
|
int betweenMinutes = DateUtil.getBetWeenMinutes(kssj,jssj)-removeTime(kssj,jssj,scheduleResult,analysisDate);
|
|
|
if (betweenMinutes < 0){
|
|
|
betweenMinutes = 0;
|
|
|
}
|
|
|
return betweenMinutes;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 开始时间和结束时间在所给班次中的占比时间
|
|
|
* @param kssj
|
|
|
* @param jssj
|
|
|
* @param scheduleResult
|
|
|
* @param analysisDate
|
|
|
* @return
|
|
|
*/
|
|
|
public static int removeTime(String kssj,String jssj,List<Map<String, Object>> scheduleResult,String analysisDate){
|
|
|
int betweenMinutes = 0;
|
|
|
log.debug("removeTime scheduleResult : {}",scheduleResult);
|
|
|
for (Map<String, Object> restSchedule :scheduleResult){
|
|
|
String dtkssj = Utils.getkssjTime(restSchedule,analysisDate);
|
|
|
String dtjssj = Utils.getjssjTime(restSchedule,analysisDate);
|
|
|
|
|
|
if (DateUtil.getTime(kssj).compareTo(DateUtil.getTime(dtkssj)) <=0 && DateUtil.getTime(jssj).compareTo(DateUtil.getTime(dtjssj)) >=0){
|
|
|
|
|
|
betweenMinutes += DateUtil.getBetWeenMinutes(dtkssj,dtjssj);
|
|
|
|
|
|
}else if (DateUtil.getTime(kssj).compareTo(DateUtil.getTime(dtkssj)) <=0 && DateUtil.getTime(jssj).compareTo(DateUtil.getTime(dtjssj)) <=0 && DateUtil.getTime(jssj).compareTo(DateUtil.getTime(dtkssj)) >=0){
|
|
|
//休息时间在请假时间 右边
|
|
|
betweenMinutes += DateUtil.getBetWeenMinutes(dtkssj,jssj);
|
|
|
|
|
|
}else if (DateUtil.getTime(kssj).compareTo(DateUtil.getTime(dtkssj)) >=0 && DateUtil.getTime(jssj).compareTo(DateUtil.getTime(dtjssj)) >=0 && DateUtil.getTime(kssj).compareTo(DateUtil.getTime(dtjssj)) <=0){
|
|
|
//休息时间在请假时间 左边
|
|
|
betweenMinutes += DateUtil.getBetWeenMinutes(kssj,dtjssj);
|
|
|
|
|
|
}else if (DateUtil.getTime(kssj).compareTo(DateUtil.getTime(dtkssj)) >=0 && DateUtil.getTime(jssj).compareTo(DateUtil.getTime(dtjssj)) <=0){
|
|
|
//请假时间在休息时间中间
|
|
|
betweenMinutes += DateUtil.getBetWeenMinutes(kssj,jssj);;
|
|
|
|
|
|
}
|
|
|
}
|
|
|
return betweenMinutes;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 开始时间和结束时间在所给加班计划中的占比时间
|
|
|
* @param kssj
|
|
|
* @param jssj
|
|
|
* @param overtimePlanList
|
|
|
* @return
|
|
|
*/
|
|
|
public static int removeTimeWithOvertimePlan(String kssj,String jssj,List<Map<String, Object>> overtimePlanList){
|
|
|
int betweenMinutes = 0;
|
|
|
log.debug("removeTimeWithOvertimePlan overtimePlanList : {}", overtimePlanList);
|
|
|
for (Map<String, Object> overtimePlanItem : overtimePlanList){
|
|
|
String dtkssj = overtimePlanItem.get("ksrq") + " " + overtimePlanItem.get("kssj");
|
|
|
String dtjssj = overtimePlanItem.get("jsrq") + " " + overtimePlanItem.get("jssj");
|
|
|
|
|
|
if (DateUtil.getTime(kssj).compareTo(DateUtil.getTime(dtkssj)) <=0 && DateUtil.getTime(jssj).compareTo(DateUtil.getTime(dtjssj)) >=0){
|
|
|
|
|
|
betweenMinutes += DateUtil.getBetWeenMinutes(dtkssj,dtjssj);
|
|
|
|
|
|
}else if (DateUtil.getTime(kssj).compareTo(DateUtil.getTime(dtkssj)) <=0 && DateUtil.getTime(jssj).compareTo(DateUtil.getTime(dtjssj)) <=0 && DateUtil.getTime(jssj).compareTo(DateUtil.getTime(dtkssj)) >=0){
|
|
|
//休息时间在请假时间 右边
|
|
|
betweenMinutes += DateUtil.getBetWeenMinutes(dtkssj,jssj);
|
|
|
|
|
|
}else if (DateUtil.getTime(kssj).compareTo(DateUtil.getTime(dtkssj)) >=0 && DateUtil.getTime(jssj).compareTo(DateUtil.getTime(dtjssj)) >=0 && DateUtil.getTime(kssj).compareTo(DateUtil.getTime(dtjssj)) <=0){
|
|
|
//休息时间在请假时间 左边
|
|
|
betweenMinutes += DateUtil.getBetWeenMinutes(kssj,dtjssj);
|
|
|
|
|
|
}else if (DateUtil.getTime(kssj).compareTo(DateUtil.getTime(dtkssj)) >=0 && DateUtil.getTime(jssj).compareTo(DateUtil.getTime(dtjssj)) <=0){
|
|
|
//请假时间在休息时间中间
|
|
|
betweenMinutes += DateUtil.getBetWeenMinutes(kssj,jssj);;
|
|
|
|
|
|
}
|
|
|
}
|
|
|
return betweenMinutes;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 开始时间和结束时间在班段类型中所占的时间
|
|
|
* @param kssj
|
|
|
* @param jssj
|
|
|
* @param scheduleResult
|
|
|
* @param analysisDate
|
|
|
* @return
|
|
|
*/
|
|
|
public static Map<String,Object> getAskLeaveAndEvctionProportion(String kssj,String jssj,List<Map<String, Object>> scheduleResult,String analysisDate){
|
|
|
Map<String,Object> resultMap = Maps.newHashMap();
|
|
|
for (Map<String, Object> restSchedule :scheduleResult){
|
|
|
String dtkssj = Utils.getkssjTime(restSchedule,analysisDate);
|
|
|
String dtjssj = Utils.getjssjTime(restSchedule,analysisDate);
|
|
|
|
|
|
int betweenMinutes = 0;
|
|
|
if (DateUtil.getTime(kssj).compareTo(DateUtil.getTime(dtkssj)) <=0 && DateUtil.getTime(jssj).compareTo(DateUtil.getTime(dtjssj)) >=0){
|
|
|
//休息时间在请假时间中间
|
|
|
betweenMinutes = DateUtil.getBetWeenMinutes(dtkssj,dtjssj);
|
|
|
log.debug("休息时间在请假时间中间");
|
|
|
}else if (DateUtil.getTime(kssj).compareTo(DateUtil.getTime(dtkssj)) <=0 && DateUtil.getTime(jssj).compareTo(DateUtil.getTime(dtjssj)) <=0 && DateUtil.getTime(jssj).compareTo(DateUtil.getTime(dtkssj)) >=0){
|
|
|
//休息时间在请假时间 右边
|
|
|
betweenMinutes = DateUtil.getBetWeenMinutes(dtkssj,jssj);
|
|
|
log.debug("休息时间在请假时间 右边");
|
|
|
}else if (DateUtil.getTime(kssj).compareTo(DateUtil.getTime(dtkssj)) >=0 && DateUtil.getTime(jssj).compareTo(DateUtil.getTime(dtjssj)) >=0 && DateUtil.getTime(kssj).compareTo(DateUtil.getTime(dtjssj)) <=0){
|
|
|
//休息时间在请假时间 左边
|
|
|
betweenMinutes = DateUtil.getBetWeenMinutes(kssj,dtjssj);
|
|
|
log.debug("休息时间在请假时间 左边");
|
|
|
}else if (DateUtil.getTime(kssj).compareTo(DateUtil.getTime(dtkssj)) >=0 && DateUtil.getTime(jssj).compareTo(DateUtil.getTime(dtjssj)) <=0){
|
|
|
//请假时间在休息时间中间
|
|
|
betweenMinutes = 0;
|
|
|
log.debug("请假时间在休息时间中间");
|
|
|
}
|
|
|
if (betweenMinutes > 0){
|
|
|
if (resultMap.get(restSchedule.get("bdlx")) == null){
|
|
|
resultMap.put(restSchedule.get("bdlx").toString(),betweenMinutes);
|
|
|
}else {
|
|
|
betweenMinutes = betweenMinutes + Integer.valueOf(resultMap.get(restSchedule.get("bdlx")).toString());
|
|
|
resultMap.put(restSchedule.get("bdlx").toString(),betweenMinutes);
|
|
|
}
|
|
|
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return resultMap;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 统计各种类型班段所占时间,除请假和出差外
|
|
|
* @return
|
|
|
*/
|
|
|
public static Map<String,Object> getClassSegmentTimeProportion(List<Map<String,Object>> scheduleResult,String analysisDate){
|
|
|
Map<String,Object> resultMap = Maps.newHashMap();
|
|
|
for (Map<String,Object> schedule: scheduleResult){
|
|
|
String bdlx = Util.null2String(schedule.get("bdlx"));
|
|
|
int edfzs = Util.null2String(schedule.get("edfzs")).equals("")?0:Integer.valueOf(Util.null2String(schedule.get("edfzs")));
|
|
|
if (!bdlx.equals(ClassSegmentTypeEnum.ASK_FOR_LEAVE.getKey()) && !bdlx.equals(ClassSegmentTypeEnum.EVECTION.getKey())){
|
|
|
if (bdlx.equals(ClassSegmentTypeEnum.OVERTIME_PLAN.getKey())){
|
|
|
String kssj = getkssjTime(schedule,analysisDate);
|
|
|
String jssj = getjssjTime(schedule,analysisDate);
|
|
|
edfzs = DateUtil.getBetWeenMinutes(kssj,jssj);
|
|
|
}
|
|
|
if (resultMap.get(bdlx) != null){
|
|
|
edfzs = edfzs + Integer.valueOf(resultMap.get(bdlx).toString());
|
|
|
}
|
|
|
|
|
|
resultMap.put(bdlx,edfzs);
|
|
|
}
|
|
|
}
|
|
|
return resultMap;
|
|
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 扣除就餐时间
|
|
|
* @param kssj 开始时间
|
|
|
* @param jssj 结束时间
|
|
|
* @param scheduleResult 班次
|
|
|
* @return
|
|
|
*/
|
|
|
public static int dinnerTime(String kssj,String jssj,List<Map<String, Object>> scheduleResult,String analysisDate){
|
|
|
scheduleResult = scheduleResult.stream().filter(e ->ClassSegmentTypeEnum.DINING_PERIOD.getKey().equals(e.get("bdlx"))).collect(Collectors.toList());
|
|
|
int dinnerTime = removeTime(kssj,jssj,scheduleResult,analysisDate);
|
|
|
return dinnerTime;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 请假外出在加班中所占时间
|
|
|
* @return
|
|
|
*/
|
|
|
public static int getStartAndEndTime(String kssj,String jssj,Map<String, Object> leaveMap){
|
|
|
String leavekssj = leaveMap.get("ksrq") + " "+leaveMap.get("kssj");
|
|
|
String leavejssj = leaveMap.get("jsrq")+ " "+leaveMap.get("jssj");
|
|
|
int betweenMinutes=0;
|
|
|
if (DateUtil.getTime(kssj).compareTo(DateUtil.getTime(leavekssj)) <=0 && DateUtil.getTime(jssj).compareTo(DateUtil.getTime(leavejssj)) >=0){
|
|
|
//请假外出时间在中间
|
|
|
betweenMinutes = DateUtil.getBetWeenMinutes(leavekssj,leavejssj);
|
|
|
log.debug("请假外出时间在中间");
|
|
|
}else if (DateUtil.getTime(kssj).compareTo(DateUtil.getTime(leavekssj)) <=0 && DateUtil.getTime(jssj).compareTo(DateUtil.getTime(leavejssj)) <=0 && DateUtil.getTime(jssj).compareTo(DateUtil.getTime(leavekssj)) >=0){
|
|
|
//请假外出时间 右边
|
|
|
betweenMinutes = DateUtil.getBetWeenMinutes(leavekssj,jssj);
|
|
|
log.debug("请假外出时间 右边");
|
|
|
}else if (DateUtil.getTime(kssj).compareTo(DateUtil.getTime(leavekssj)) >=0 && DateUtil.getTime(jssj).compareTo(DateUtil.getTime(leavejssj)) >=0 && DateUtil.getTime(kssj).compareTo(DateUtil.getTime(leavejssj)) <=0){
|
|
|
//休请假外出时间 左边
|
|
|
betweenMinutes = DateUtil.getBetWeenMinutes(kssj,leavejssj);
|
|
|
log.debug("请假外出时间 左边");
|
|
|
}else if (DateUtil.getTime(kssj).compareTo(DateUtil.getTime(leavekssj)) >=0 && DateUtil.getTime(jssj).compareTo(DateUtil.getTime(leavejssj)) <=0){
|
|
|
//请假外出时间中间
|
|
|
betweenMinutes = DateUtil.getBetWeenMinutes(kssj,jssj);
|
|
|
log.debug("加班实际在请假外出时间中间");
|
|
|
}
|
|
|
return betweenMinutes;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* map中的开始时间和结束时间,在kssj和jssj中占据的分钟数
|
|
|
* @return
|
|
|
*/
|
|
|
public static int getIntersectionTime(String kssj,String jssj,Map<String, Object> map,List<Map<String, Object>> scheduleResult,String analysisDate){
|
|
|
String leavekssj = map.get("kssj").toString();
|
|
|
String leavejssj = map.get("jssj").toString();
|
|
|
int betweenMinutes=0;
|
|
|
if (DateUtil.getTime(kssj).compareTo(DateUtil.getTime(leavekssj)) <=0 && DateUtil.getTime(jssj).compareTo(DateUtil.getTime(leavejssj)) >=0){
|
|
|
//时间在中间
|
|
|
betweenMinutes = removeRestTime(leavekssj,leavejssj,scheduleResult,analysisDate);
|
|
|
log.debug("时间在中间,被包含");
|
|
|
}else if (DateUtil.getTime(kssj).compareTo(DateUtil.getTime(leavekssj)) <=0 && DateUtil.getTime(jssj).compareTo(DateUtil.getTime(leavejssj)) <=0 && DateUtil.getTime(jssj).compareTo(DateUtil.getTime(leavekssj)) >=0){
|
|
|
//时间 右边
|
|
|
betweenMinutes = removeRestTime(leavekssj,jssj,scheduleResult,analysisDate);
|
|
|
log.debug("时间 右边");
|
|
|
}else if (DateUtil.getTime(kssj).compareTo(DateUtil.getTime(leavekssj)) >=0 && DateUtil.getTime(jssj).compareTo(DateUtil.getTime(leavejssj)) >=0 && DateUtil.getTime(kssj).compareTo(DateUtil.getTime(leavejssj)) <=0){
|
|
|
//时间 左边
|
|
|
betweenMinutes = removeRestTime(kssj,leavejssj,scheduleResult,analysisDate);
|
|
|
log.debug("时间 左边");
|
|
|
}else if (DateUtil.getTime(kssj).compareTo(DateUtil.getTime(leavekssj)) >=0 && DateUtil.getTime(jssj).compareTo(DateUtil.getTime(leavejssj)) <=0){
|
|
|
//请假外出时间中间
|
|
|
betweenMinutes = removeRestTime(kssj,jssj,scheduleResult,analysisDate);
|
|
|
log.debug("时间在中间,包含");
|
|
|
}
|
|
|
return betweenMinutes;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获得建模表对应的模块ID
|
|
|
* @return
|
|
|
*/
|
|
|
public static Map<String,String> getFormmodeIdMap(){
|
|
|
String sql = "select c.id,b.tablename from uf_jcl_form_table a left join workflow_bill b on a.tablename=b.tablename left join modeinfo c on b.id=c.formid where (c.isDelete is null or c.isDelete <> '1')";
|
|
|
List<Map<String,Object>> dataList = DbTools.getSqlToList(sql);
|
|
|
return dataList.stream().collect(Collectors.toMap(e->e.get("tablename").toString(),e->e.get("id").toString()));
|
|
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 插入
|
|
|
* @param tableName
|
|
|
* @param dataMap
|
|
|
* @param formmodeIdMap
|
|
|
*/
|
|
|
public static boolean InsertFormTable(String tableName,Map<String,Object> dataMap,Map<String,String> formmodeIdMap){
|
|
|
String formmodeId = formmodeIdMap.get(tableName);
|
|
|
if (!tableName.contains("_dt")){
|
|
|
dataMap.put("formmodeid",formmodeId);
|
|
|
dataMap.put("modeuuid", UUID.randomUUID().toString());
|
|
|
dataMap.put("modedatacreater","1");
|
|
|
dataMap.put("modedatacreatertype","0");
|
|
|
dataMap.put("modedatacreatedate",DateUtil.getCurrentTime().split(" ")[0]);
|
|
|
dataMap.put("modedatacreatetime",DateUtil.getCurrentTime().split(" ")[1]);
|
|
|
}
|
|
|
return CommonUtil.makeInsertSql(tableName,dataMap);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 根据班段类型获得作用时段
|
|
|
* @param bdlx
|
|
|
* @return
|
|
|
*/
|
|
|
public static String getWorkFor(String bdlx){
|
|
|
String workFor="";
|
|
|
if (ClassSegmentTypeEnum.WORK_TIME.getKey().equals(bdlx)){
|
|
|
workFor = WorkForTimeEnum.WORK_TIME.getKey();
|
|
|
}else if (ClassSegmentTypeEnum.EXTENDED_OVERTIME.getKey().equals(bdlx)){
|
|
|
workFor = WorkForTimeEnum.DELAY_TO_WORK_OVERTIME.getKey();
|
|
|
}else if (ClassSegmentTypeEnum.EARLY_OVERTIME.getKey().equals(bdlx)){
|
|
|
workFor = WorkForTimeEnum.EARLY_TO_WORK_OVERTIME.getKey();
|
|
|
}else if (ClassSegmentTypeEnum.OVERTIME_PLAN.getKey().equals(bdlx)){
|
|
|
workFor = WorkForTimeEnum.PLAN_WORK_OVERTIME.getKey();
|
|
|
}else if (ClassSegmentTypeEnum.ASK_FOR_LEAVE.getKey().equals(bdlx)){
|
|
|
workFor = WorkForTimeEnum.LEAVE_TIME.getKey();
|
|
|
}else if (ClassSegmentTypeEnum.EVECTION.getKey().equals(bdlx)){
|
|
|
workFor = WorkForTimeEnum.EVECTION.getKey();
|
|
|
}else if (ClassSegmentTypeEnum.OVERTIME_IN_CLASS.getKey().equals(bdlx)){
|
|
|
workFor = WorkForTimeEnum.OVERTIME_IN_CLASS.getKey();
|
|
|
}
|
|
|
return workFor;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 根据作用时段获得班段类型
|
|
|
* @param workFor
|
|
|
* @return
|
|
|
*/
|
|
|
public static String getClassSegmenByWorkFor(String workFor){
|
|
|
String bdlx="";
|
|
|
if (WorkForTimeEnum.WORK_TIME.getKey().equals(workFor)){
|
|
|
bdlx = ClassSegmentTypeEnum.WORK_TIME.getKey();
|
|
|
}else if (WorkForTimeEnum.DELAY_TO_WORK_OVERTIME.getKey().equals(workFor)){
|
|
|
bdlx = ClassSegmentTypeEnum.EXTENDED_OVERTIME.getKey();
|
|
|
}else if (WorkForTimeEnum.EARLY_TO_WORK_OVERTIME.getKey().equals(workFor)){
|
|
|
bdlx = ClassSegmentTypeEnum.EARLY_OVERTIME.getKey();
|
|
|
}else if (WorkForTimeEnum.PLAN_WORK_OVERTIME.getKey().equals(workFor)){
|
|
|
bdlx = ClassSegmentTypeEnum.OVERTIME_PLAN.getKey();
|
|
|
}else if (WorkForTimeEnum.LEAVE_TIME.getKey().equals(workFor)){
|
|
|
bdlx = ClassSegmentTypeEnum.ASK_FOR_LEAVE.getKey();
|
|
|
}else if (WorkForTimeEnum.EVECTION.getKey().equals(workFor)){
|
|
|
bdlx = ClassSegmentTypeEnum.EVECTION.getKey();
|
|
|
}else if (WorkForTimeEnum.OVERTIME_IN_CLASS.getKey().equals(workFor)){
|
|
|
bdlx = ClassSegmentTypeEnum.OVERTIME_IN_CLASS.getKey();
|
|
|
}
|
|
|
return bdlx;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获得半天时间
|
|
|
* @param scheduleResult
|
|
|
* @return
|
|
|
*/
|
|
|
public double getHalfDay(List<Map<String, Object>> scheduleResult){
|
|
|
scheduleResult = scheduleResult.stream().filter(e -> !ClassSegmentTypeEnum.OVERTIME_PLAN.getKey().equals(e.get("bdlx")) &&
|
|
|
!ClassSegmentTypeEnum.ASK_FOR_LEAVE.getKey().equals(e.get("bdlx")) && !ClassSegmentTypeEnum.EVECTION.getKey().equals(e.get("bdlx"))).collect(Collectors.toList());
|
|
|
if (scheduleResult.size() > 0){
|
|
|
String btgz = Util.null2String(scheduleResult.get(0).get("btgz"));
|
|
|
String fgsjd = Util.null2String(scheduleResult.get(0).get("fgsjd"));
|
|
|
if (HalfDayRuleREnum.BY_CLASS_SET.getKey().equals(btgz)){
|
|
|
|
|
|
}else if (HalfDayRuleREnum.FIXED_DURATION.getKey().equals(btgz)){
|
|
|
|
|
|
}else if (HalfDayRuleREnum.HALF_TOTAL_DURATION.getKey().equals(btgz)){
|
|
|
|
|
|
}else if (HalfDayRuleREnum.HALF_RATED_DURATION.getKey().equals(btgz)){
|
|
|
|
|
|
}
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 重新获得排班
|
|
|
* @param dataList
|
|
|
* @return
|
|
|
*/
|
|
|
public static List<Map<String, Object>> getSchedulingList(List<Map<String, Object>> dataList){
|
|
|
Map<String,List<Map<String, Object>>> dataMaps = dataList.stream().collect(Collectors.groupingBy(e->Util.null2String(e.get("bcrq"))));
|
|
|
List<Map<String, Object>> resultList = Lists.newArrayList();
|
|
|
for (Map.Entry<String,List<Map<String, Object>>> entry:dataMaps.entrySet()){
|
|
|
String bcrq = entry.getKey();
|
|
|
List<Map<String, Object>> classList = entry.getValue();
|
|
|
if (classList.size() > 1){
|
|
|
classList = classList.stream().filter(e->!e.get("pbtj").equals(RegularScheduleTypeEnum.REGULAR.getKey())).collect(Collectors.toList());
|
|
|
classList = classList.stream().sorted(Comparator.comparing(e->DateUtil.getTime(e.get("modedatacreatedate")+" "+e.get("modedatacreatetime")).toInstant(ZoneOffset.of("+8")).toEpochMilli())).collect(Collectors.toList());
|
|
|
if (classList.size() > 0){
|
|
|
resultList.add(classList.get(classList.size()-1));
|
|
|
}else {
|
|
|
resultList.add(entry.getValue().get(0));
|
|
|
}
|
|
|
}else {
|
|
|
resultList.addAll(classList);
|
|
|
}
|
|
|
}
|
|
|
return resultList;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 相减
|
|
|
* @param value1
|
|
|
* @param value2
|
|
|
* @return
|
|
|
*/
|
|
|
public static double subtract(double value1,double value2){
|
|
|
|
|
|
return new BigDecimal(String.valueOf(value1)).subtract(new BigDecimal(String.valueOf(value2)),new MathContext(BigDecimal.ROUND_HALF_UP)).doubleValue();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 相加
|
|
|
* @param value1
|
|
|
* @param value2
|
|
|
* @return
|
|
|
*/
|
|
|
public static double add(double value1,double value2){
|
|
|
|
|
|
return new BigDecimal(String.valueOf(value1)).add(new BigDecimal(String.valueOf(value2)),new MathContext(BigDecimal.ROUND_HALF_UP)).doubleValue();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 相乘
|
|
|
* @param value1
|
|
|
* @param value2
|
|
|
* @return
|
|
|
*/
|
|
|
public static double multiply(double value1,double value2){
|
|
|
|
|
|
return new BigDecimal(String.valueOf(value1)).multiply(new BigDecimal(String.valueOf(value2)),new MathContext(BigDecimal.ROUND_HALF_UP)).doubleValue();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 相除
|
|
|
* @param value1
|
|
|
* @param value2
|
|
|
* @return
|
|
|
*/
|
|
|
public static double divide(double value1, double value2){
|
|
|
|
|
|
return new BigDecimal(String.valueOf(value1)).divide(new BigDecimal(String.valueOf(value2)), 2, RoundingMode.HALF_UP).doubleValue();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 根据日期和时间组装日期时间
|
|
|
* @param date
|
|
|
* @param time
|
|
|
* @return
|
|
|
*/
|
|
|
public static String installTime(String date ,String time){
|
|
|
return date+" "+time;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 开始时间大于结束时间
|
|
|
* @param beginTime
|
|
|
* @param endTime
|
|
|
* @return
|
|
|
*/
|
|
|
public static boolean dateGreaterThan(String beginTime,String endTime){
|
|
|
return DateUtil.getTime(beginTime).compareTo(DateUtil.getTime(endTime)) >0;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 根据日期,日历名称id,获得当前日期类型
|
|
|
* @param date
|
|
|
* @param rlmc
|
|
|
* @return
|
|
|
*/
|
|
|
public static String getDateType(String date,String rlmc){
|
|
|
String sql = "select rqlx from uf_jcl_kq_rlxx where rlmc=? and rq=?";
|
|
|
Map<String,Object> data = DbTools.getSqlToMap(sql,rlmc,date.split(" ")[0]);
|
|
|
return Util.null2String(data.get("rqlx"));
|
|
|
}
|
|
|
/**
|
|
|
* 根据日期,分部,获得该分部下的默认日历的当前日期类型
|
|
|
* @param subcompanyid1
|
|
|
* @param date
|
|
|
* @return
|
|
|
*/
|
|
|
public static String getDefaultDateType(String subcompanyid1,String date){
|
|
|
String rqlx = "";
|
|
|
String parentSubcompanyids = "";
|
|
|
try {
|
|
|
|
|
|
parentSubcompanyids = new SubCompanyComInfo().getAllParentSubcompanyId(subcompanyid1,parentSubcompanyids);
|
|
|
}catch (Exception e){
|
|
|
log.error("getDefaultDateType error:[{}]",e);
|
|
|
}
|
|
|
parentSubcompanyids = subcompanyid1+parentSubcompanyids;
|
|
|
String sql = "select b.szjg,a.rqlx from uf_jcl_kq_rlxx a left join uf_jcl_kq_rlmc b on a.rlmc=b.id where b.mrrl=1 and b.szjg in ("+parentSubcompanyids+") and a.rq=?";
|
|
|
List<Map<String,Object>> dataList = DbTools.getSqlToList(sql,date);
|
|
|
Map<String,Object> dataMap = dataList.stream().collect(Collectors.toMap(e->e.get("szjg").toString(),e->e.get("rqlx")));
|
|
|
for (int i=0;i<parentSubcompanyids.split(",").length;i++){
|
|
|
String subId = parentSubcompanyids.split(",")[i];
|
|
|
rqlx = Util.null2String(dataMap.get(subId));
|
|
|
if (!"".equals(rqlx)){
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
return rqlx;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获得默认周期
|
|
|
* @param subcompanyid1
|
|
|
* @return
|
|
|
*/
|
|
|
public static String getDefaultAttendanceCycle(String subcompanyid1){
|
|
|
String defaultCycle = "";
|
|
|
String parentSubcompanyids = "";
|
|
|
try {
|
|
|
|
|
|
parentSubcompanyids = new SubCompanyComInfo().getAllParentSubcompanyId(subcompanyid1,parentSubcompanyids);
|
|
|
}catch (Exception e){
|
|
|
log.error("getDefaultDateType error:[{}]",e);
|
|
|
}
|
|
|
parentSubcompanyids = subcompanyid1+parentSubcompanyids;
|
|
|
String sql = "select id,szjg from uf_jcl_kq_kqzqmc where szjg in ("+parentSubcompanyids+") and mrzq=1";
|
|
|
List<Map<String,Object>> dataList = DbTools.getSqlToList(sql);
|
|
|
Map<String,Object> dataMap = dataList.stream().collect(Collectors.toMap(e->e.get("szjg").toString(),e->e.get("id")));
|
|
|
|
|
|
for (int i=0;i<parentSubcompanyids.split(",").length;i++){
|
|
|
String subId = parentSubcompanyids.split(",")[i];
|
|
|
defaultCycle = Util.null2String(dataMap.get(subId));
|
|
|
if (!"".equals(defaultCycle)){
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
return defaultCycle;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获得人员分部对应年度的默认日历
|
|
|
* @param subcompanyid1
|
|
|
* @param year
|
|
|
* @return
|
|
|
*/
|
|
|
public static List<Map<String,Object>> getDefaultDateList(String subcompanyid1,String year){
|
|
|
List<Map<String,Object>> resultList=null;
|
|
|
String parentSubcompanyids = "";
|
|
|
try {
|
|
|
parentSubcompanyids = new SubCompanyComInfo().getAllParentSubcompanyId(subcompanyid1,parentSubcompanyids);
|
|
|
}catch (Exception e){
|
|
|
log.error("getDefaultDateType error:[{}]",e);
|
|
|
}
|
|
|
parentSubcompanyids = subcompanyid1+parentSubcompanyids;
|
|
|
String sql = "select a.nd,a.rq,a.nlrq,a.rqlx,a.xq,a.rlmc,b.szjg from uf_jcl_kq_rlxx a left join uf_jcl_kq_rlmc b on a.rlmc=b.id where b.mrrl=1 and b.szjg in ("+parentSubcompanyids+") and a.nd=?";
|
|
|
List<Map<String,Object>> dataList = DbTools.getSqlToList(sql,year);
|
|
|
Map<String,List<Map<String,Object>>> dataMap = dataList.stream().collect(Collectors.groupingBy(e->e.get("szjg").toString()));
|
|
|
for (int i=0;i<parentSubcompanyids.split(",").length;i++){
|
|
|
String subId = parentSubcompanyids.split(",")[i];
|
|
|
resultList = dataMap.get(subId);
|
|
|
if (resultList != null){
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
return resultList;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 根据核算单位、时间转换成分钟
|
|
|
* @param time 时间
|
|
|
* @param hsdw 核算单位
|
|
|
* @return
|
|
|
*/
|
|
|
public static double converTimeToMinute(double time,String hsdw){
|
|
|
if (AccountingUnitEnum.DAY.getKey().equals(hsdw)){
|
|
|
time = time*24*60;
|
|
|
}else if (AccountingUnitEnum.HOUR.getKey().equals(hsdw)){
|
|
|
time = time*60;
|
|
|
}
|
|
|
|
|
|
return time;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获得班次的开始时间的提前时间
|
|
|
* @param schedulingMap
|
|
|
* @param date
|
|
|
* @return
|
|
|
*/
|
|
|
public static String getkssjEarliestTime(Map<String,Object> schedulingMap,String date){
|
|
|
String tqdkfzs = Util.null2String(schedulingMap.get("tqdkfzs"));
|
|
|
if ("".equals(tqdkfzs)){
|
|
|
tqdkfzs = "60";
|
|
|
}
|
|
|
return DateUtil.beforeMinutes(getkssjTime(schedulingMap,date),Integer.valueOf(tqdkfzs));
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获得班次的开始时间
|
|
|
* @param schedulingMap 班次信息
|
|
|
* @param date 分析日期
|
|
|
* @return
|
|
|
*/
|
|
|
public static String getkssjTime(Map<String,Object> schedulingMap,String date){
|
|
|
if (ifAskforOrEvctionClassSegment(schedulingMap.get("bdlx").toString())){
|
|
|
return schedulingMap.get("dtkssj").toString();
|
|
|
}
|
|
|
String gsrq = Util.null2String(schedulingMap.get("gsrq"));
|
|
|
String kssj = Util.null2String(schedulingMap.get("dtkssj"));
|
|
|
if (gsrq.equals(ClassBelongToEnum.YESTERDAY.getKey())){
|
|
|
date = DateUtil.beforeDay(date,1);
|
|
|
}else if (gsrq.equals(ClassBelongToEnum.NEXTDAY.getKey())){
|
|
|
date = DateUtil.AfterDay(date,1);
|
|
|
}else if (gsrq.equals(ClassBelongToEnum.NOWDAY.getKey())){
|
|
|
date = date;
|
|
|
}
|
|
|
kssj = date+" "+kssj;
|
|
|
|
|
|
return kssj;
|
|
|
}
|
|
|
/**
|
|
|
* 获得班次的结束时间的退后时间
|
|
|
* @param schedulingMap
|
|
|
* @param date
|
|
|
* @return
|
|
|
*/
|
|
|
public static String getjssjLastestTime(Map<String,Object> schedulingMap,String date){
|
|
|
|
|
|
String thdkfzs = Util.null2String(schedulingMap.get("thdkfzs"));
|
|
|
if ("".equals(thdkfzs)){
|
|
|
thdkfzs = "60";
|
|
|
}
|
|
|
|
|
|
return DateUtil.AfterMinutes(getjssjTime(schedulingMap,date),Integer.valueOf(thdkfzs));
|
|
|
}
|
|
|
/**
|
|
|
* 获得班次的结束时间
|
|
|
* @param schedulingMap 班次信息
|
|
|
* @param date 分析日期
|
|
|
* @return
|
|
|
*/
|
|
|
public static String getjssjTime(Map<String,Object> schedulingMap,String date){
|
|
|
if (ifAskforOrEvctionClassSegment(schedulingMap.get("bdlx").toString())){
|
|
|
return schedulingMap.get("dtjssj").toString();
|
|
|
}
|
|
|
String gsrq = Util.null2String(schedulingMap.get("gsrq"));
|
|
|
String jssj = Util.null2String(schedulingMap.get("dtjssj"));
|
|
|
String kssj = Util.null2String(schedulingMap.get("dtkssj"));
|
|
|
if (gsrq.equals(ClassBelongToEnum.YESTERDAY.getKey())){
|
|
|
date = DateUtil.beforeDay(date,1);
|
|
|
}else if (gsrq.equals(ClassBelongToEnum.NEXTDAY.getKey())){
|
|
|
date = DateUtil.AfterDay(date,1);
|
|
|
}else if (gsrq.equals(ClassBelongToEnum.NOWDAY.getKey())){
|
|
|
date = date;
|
|
|
}
|
|
|
jssj = date+" "+jssj;
|
|
|
kssj = date+" "+kssj;
|
|
|
if (DateUtil.getTime(kssj).compareTo(DateUtil.getTime(jssj)) >= 0) {
|
|
|
jssj = DateUtil.AfterDay(date, 1) + " " + Util.null2String(schedulingMap.get("dtjssj"));
|
|
|
}
|
|
|
|
|
|
return jssj;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 判断是否是加班类型时段
|
|
|
* @param classSegmentType
|
|
|
* @return
|
|
|
*/
|
|
|
public static boolean ifOverTimeClassSegment(String classSegmentType){
|
|
|
if (classSegmentType.equals(ClassSegmentTypeEnum.EXTENDED_OVERTIME.getKey()) || classSegmentType.equals(ClassSegmentTypeEnum.EARLY_OVERTIME.getKey())
|
|
|
|| classSegmentType.equals(ClassSegmentTypeEnum.OVERTIME_IN_CLASS.getKey()) || classSegmentType.equals(ClassSegmentTypeEnum.OVERTIME_PLAN.getKey())){
|
|
|
return true;
|
|
|
}else {
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 判断是否是休息类型时段
|
|
|
* @param classSegmentType
|
|
|
* @return
|
|
|
*/
|
|
|
public static boolean ifRestClassSegment(String classSegmentType){
|
|
|
if (classSegmentType.equals(ClassSegmentTypeEnum.REST_AND_DINE.getKey()) || classSegmentType.equals(ClassSegmentTypeEnum.REST_PERIOD.getKey())
|
|
|
|| classSegmentType.equals(ClassSegmentTypeEnum.DINING_PERIOD.getKey())){
|
|
|
return true;
|
|
|
}else {
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
/**
|
|
|
* 判断是否是请假出差
|
|
|
* @param classSegmentType
|
|
|
* @return
|
|
|
*/
|
|
|
public static boolean ifAskforOrEvctionClassSegment(String classSegmentType){
|
|
|
if (classSegmentType.equals(ClassSegmentTypeEnum.ASK_FOR_LEAVE.getKey()) || classSegmentType.equals(ClassSegmentTypeEnum.EVECTION.getKey())){
|
|
|
return true;
|
|
|
}else {
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 转换成double
|
|
|
* @param num
|
|
|
* @return
|
|
|
*/
|
|
|
public static double convertDouble(Object num){
|
|
|
return Util.null2String(num).equals("")?0:Double.valueOf(Util.null2String(num));
|
|
|
}
|
|
|
public static ClockPointDTO getClockPointDTO(List<ClockPointDTO> clockPointDTOList,ClockPointEnum pointType,String time){
|
|
|
|
|
|
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 将班次转换成卡点并按照打卡时间从小到大排列
|
|
|
* @param scheduleResult
|
|
|
* @return
|
|
|
*/
|
|
|
public static List<ClockPointDTO> converToClockPointBySchedule(List<Map<String, Object>> scheduleResult,String analysisDate){
|
|
|
List<ClockPointDTO> clockPointDTOList = Lists.newArrayList();
|
|
|
for (Map<String, Object> schedule: scheduleResult){
|
|
|
ClockPointDTO startClockPointDTO = ClockPointDTO.builder().classTime(Utils.getkssjTime(schedule,analysisDate)).pointType(ClockPointEnum.START).classSegmentType(schedule.get("bdlx").toString()).build();
|
|
|
ClockPointDTO endClockPointDTO = ClockPointDTO.builder().classTime(Utils.getjssjTime(schedule,analysisDate)).pointType(ClockPointEnum.END).classSegmentType(schedule.get("bdlx").toString()).build();
|
|
|
if (ifAskforOrEvctionClassSegment(schedule.get("bdlx").toString())){
|
|
|
startClockPointDTO.setPointType(ClockPointEnum.END);
|
|
|
endClockPointDTO.setPointType(ClockPointEnum.START);
|
|
|
}
|
|
|
clockPointDTOList.add(startClockPointDTO);
|
|
|
clockPointDTOList.add(endClockPointDTO);
|
|
|
}
|
|
|
clockPointDTOList = clockPointDTOList.stream().sorted(Comparator.comparing(e->DateUtil.getTime(e.getClassTime()).toInstant(ZoneOffset.of("+8")).toEpochMilli())).collect(Collectors.toList());
|
|
|
return clockPointDTOList;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获得班段包含的异常集合
|
|
|
* @param scheduleMap 班段
|
|
|
* @param abnormalScheduleList 异常集合
|
|
|
* @return
|
|
|
*/
|
|
|
public static List<Map<String,Object>> getAbnormalListBySchedule(Map<String, Object> scheduleMap,List<Map<String,Object>> abnormalScheduleList,String analysisDate){
|
|
|
String kssj = getkssjTime(scheduleMap,analysisDate);
|
|
|
String jssj = getjssjTime(scheduleMap,analysisDate);
|
|
|
List<Map<String,Object>> resultList = abnormalScheduleList.stream().filter(e->{
|
|
|
ClockPointEnum pointType = (ClockPointEnum)e.get("pointType");
|
|
|
String time = "";
|
|
|
if (pointType == ClockPointEnum.END){
|
|
|
time = jssj;
|
|
|
}else if (pointType == ClockPointEnum.START){
|
|
|
time = kssj;
|
|
|
}
|
|
|
if (DateUtil.getTime(time).compareTo(DateUtil.getTime(e.get("pointTime").toString())) == 0){
|
|
|
return true;
|
|
|
}else if (DateUtil.getTime(kssj).compareTo(DateUtil.getTime(e.get("pointTime").toString())) <0 && DateUtil.getTime(jssj).compareTo(DateUtil.getTime(e.get("pointTime").toString())) >0){
|
|
|
return true;
|
|
|
}else {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
}).collect(Collectors.toList());
|
|
|
return resultList;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获得异常所处的班段集合
|
|
|
* @param scheduleMapList 班段
|
|
|
* @param abnormalList 异常集合
|
|
|
* @return
|
|
|
*/
|
|
|
public static Set<Map<String,Object>> getScheduleByAbnormalList(List<Map<String,Object>> scheduleMapList,List<Map<String,Object>> abnormalList,String analysisDate){
|
|
|
Set<Map<String,Object>> resultList = Sets.newHashSet();
|
|
|
for (Map<String,Object> abnormal:abnormalList){
|
|
|
ClockPointEnum pointType = (ClockPointEnum)abnormal.get("pointType");
|
|
|
String pointTime = abnormal.get("pointTime").toString();
|
|
|
for (Map<String,Object> scheduleMap:scheduleMapList){
|
|
|
String kssj = getkssjTime(scheduleMap,analysisDate);
|
|
|
String jssj = getjssjTime(scheduleMap,analysisDate);
|
|
|
String time = "";
|
|
|
if (pointType == ClockPointEnum.END){
|
|
|
time = jssj;
|
|
|
}else if (pointType == ClockPointEnum.START){
|
|
|
time = kssj;
|
|
|
}
|
|
|
if (DateUtil.getTime(time).compareTo(DateUtil.getTime(pointTime)) == 0){
|
|
|
resultList.add(scheduleMap);
|
|
|
}else if (DateUtil.getTime(kssj).compareTo(DateUtil.getTime(pointTime)) <0 && DateUtil.getTime(jssj).compareTo(DateUtil.getTime(pointTime)) >0){
|
|
|
resultList.add(scheduleMap);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
return resultList;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 合并一个班段上的异常
|
|
|
* @param scheduleMapList
|
|
|
* @param abnormalScheduleList
|
|
|
* @param analysisDate
|
|
|
* @return
|
|
|
*/
|
|
|
public static List<Map<String,Object>> mergeOneScheduleAbnormal(List<Map<String,Object>> scheduleMapList,List<Map<String,Object>> abnormalScheduleList,String analysisDate){
|
|
|
List<Map<String,Object>> resultList = Lists.newArrayList();
|
|
|
for (Map<String,Object> scheduleMap:scheduleMapList){
|
|
|
List<Map<String,Object>> abnormals = getAbnormalListBySchedule(scheduleMap,abnormalScheduleList,analysisDate);
|
|
|
if (abnormals.size() == 1){
|
|
|
resultList.add(abnormals.get(0));
|
|
|
}else if (abnormals.size() > 1){
|
|
|
String kssj = getkssjTime(scheduleMap,analysisDate);
|
|
|
String jssj = getjssjTime(scheduleMap,analysisDate);
|
|
|
int betweenMinute = DateUtil.getBetWeenMinutes(kssj,jssj);
|
|
|
List<Map<String,Object>> filterAbnormals = abnormals.stream().filter(e->e.get("itemType") == AttendanceItemTypeEnum.MISSE_CARD ||
|
|
|
Integer.valueOf(e.get("betweenMinutes") == null?"0":e.get("betweenMinutes").toString()) >= betweenMinute).collect(Collectors.toList());
|
|
|
if (filterAbnormals.size() > 0){
|
|
|
resultList.add(filterAbnormals.get(0));
|
|
|
}else {
|
|
|
resultList.addAll(abnormals);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return resultList;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 转换sql语句
|
|
|
* @param sqltj
|
|
|
* @return
|
|
|
*/
|
|
|
public static String converSQL(String sqltj){
|
|
|
sqltj = sqltj.replace("select","select");
|
|
|
sqltj = sqltj.replace("SELECT","select");
|
|
|
sqltj = sqltj.replace("and","and");
|
|
|
sqltj = sqltj.replace("AND","and");
|
|
|
sqltj = sqltj.replace("or","or");
|
|
|
sqltj = sqltj.replace("OR","or");
|
|
|
sqltj = sqltj.replace("join","join");
|
|
|
sqltj = sqltj.replace("JOIN","join");
|
|
|
sqltj = sqltj.replace("like","like");
|
|
|
sqltj = sqltj.replace("LIKE","like");
|
|
|
sqltj = sqltj.replace("in","in");
|
|
|
sqltj = sqltj.replace("IN","in");
|
|
|
sqltj = sqltj.replace("union","union");
|
|
|
return sqltj;
|
|
|
}
|
|
|
|
|
|
}
|