日月报表生成

This commit is contained in:
fl 2025-02-18 21:01:41 +08:00
parent 5f76423d4c
commit 01208754a4
7 changed files with 345 additions and 190 deletions

View File

@ -42,7 +42,7 @@ public interface AttSourceDataDao {
* 查询三天的每日考勤情况
* @return list bean
*/
List<AttDayReportBean> selectAttDayReport(@Param("pushDate")String pushDate, @Param("pushType")int pushType);
List<AttDayReportBean> selectAttDayReport(@Param("pushDate")String pushDate);
/**
* 新增日报表
@ -231,4 +231,19 @@ public interface AttSourceDataDao {
* @param v
*/
void updateLeaveData(AttDataBean v);
/**
* 查询月模版数据
* @param pushDate
* @return
*/
List<AttMonthReportBean> selectAttMonthReportTemp(String pushDate);
/**
* 生成月模版数据
* @param monthReportList
* @return
*/
void insertAttMonthReportTemp(List<AttMonthReportBean> monthReportList);
void updateAttMonthReport(List<AttMonthReportBean> monthReportList);
}

View File

@ -145,8 +145,6 @@ public class AttGroupBean {
*/
private String currentDay;
/**是否有法定节假日*/
private Integer isHaveHoliday;
public AttGroupBean(Long groupId, String attDay, String toWorkTime, String offWorkTime,
Long todayClockNum, Long lateMinute, Long leaveMinute,

View File

@ -54,4 +54,24 @@ public interface AttCalService {
* @param pushDate 时间
*/
void updateLeaveData(String pushDate);
/**
* 报表数据生成日报表
* 每次更新数据都要执行(跟随)
* @param pushDate 时间
*/
void insertDayReportData(String pushDate);
/**
* 月报表数据生成人员对应出月出勤
* 月初生成一次
* @param pushDate 时间
*/
void insertMonthReportTempData(String pushDate);
/**
* 月报表数据更新人员对应出月出勤
* 每次更新完数据要执行(跟随)
* @param pushDate 时间
*/
void updateMonthReportData(String pushDate);
}

View File

@ -237,6 +237,54 @@ public class AttCalServiceImpl implements AttCalService {
}
}
/**
* 报表数据生成日报表
* 每次更新数据都要执行(跟随)
* @param pushDate 时间
*/
@Override
public void insertDayReportData(String pushDate) {
//日报表查询
List<AttDayReportBean> dayReportList = attSourceDataDao.selectAttDayReport(pushDate);
//日报表新增
attSourceDataDao.insertAttDayReport(dayReportList);
}
/**
* 月报表模版生成人员对应出月出勤
* 月初生成一次
* @param pushDate 时间
*/
@Override
public void insertMonthReportTempData(String pushDate) {
List<AttMonthReportBean> monthReportList = attSourceDataDao.selectAttMonthReportTemp(pushDate);
//查出考勤组
List<AttGroupBean> groupList = getGroupData(pushDate);
//人员对应出月出勤天数
monthReportList.forEach(c ->
groupList.stream()
.filter(v -> c.getGroupId() != null && c.getGroupId().equals(v.getGroupId()))
.findFirst()
.ifPresent(v -> c.setRequiredDays(v.getAttWorkDayBean().getRequiredDays()))
);
//月报表模版生成
if(!monthReportList.isEmpty()){
attSourceDataDao.insertAttMonthReportTemp(monthReportList);
}
}
/**
* 月报表数据更新人员对应出月出勤
* 每次更新完数据要执行(跟随)
* @param pushDate 时间
*/
@Override
public void updateMonthReportData(String pushDate) {
List<AttMonthReportBean> monthReportList = attSourceDataDao.selectAttMonthReport(pushDate);
//月报表修改
attSourceDataDao.updateAttMonthReport(monthReportList);
}
/**
* 人员考勤模版数据默认是未打卡
* 每天早上0点30执行一次
@ -245,7 +293,7 @@ public class AttCalServiceImpl implements AttCalService {
*/
@Override
public void insertAttTempData(String pushDate, int pushType) {
//查询当天应考勤人员列表
//查询当天应考勤人员列表每个人分上下午生成2条
List<AttDataBean> listPerson = attSourceDataDao.getAttPerson(pushDate);
if (pushType == 1) {
//只会在凌晨执行一次
@ -365,7 +413,7 @@ public class AttCalServiceImpl implements AttCalService {
groupList.forEach(c -> {
//应考勤天
List<String> attDayList = WorkdayCalculator.getWorkDay(c.getAttDay(),
Integer.parseInt(c.getAttType()), holidays, pushDate);
c.getIsHaveHoliday(), holidays, pushDate);
c.setAttWorkDayBean(new PersonAttWorkDayBean(c.getGroupId(), attDayList.size(), attDayList));
});
return groupList;
@ -467,120 +515,6 @@ public class AttCalServiceImpl implements AttCalService {
return newList;
}
/**
* 上下班考勤计算
*
* @param list 考勤来源数据
* @param attGroupBean 考勤组数据
* @param tf 固定|自由
* @return 考勤数据
*/
private List<AttSourceDataBean> getDataList(List<AttSourceDataBean> list,
AttGroupBean attGroupBean,
Boolean tf) {
List<AttSourceDataBean> newList = new ArrayList<>();
//分组排序(将每个人每天在自己考勤组的数据分组)
Map<String, List<AttSourceDataBean>> groupedItems = list.stream()
.collect(Collectors.groupingBy(
c -> c.getUserId() + "|" + c.getAttCurrentDay(),
Collectors.collectingAndThen(
Collectors.toList(),
v -> {
v.sort(Comparator.comparing(AttSourceDataBean::getAttCurrentTime));
return v;
}
)
));
if (!tf) {
//固定打卡以最靠近上班打卡时间前的出闸机的时间为基准去除掉之前的所有打卡数据
AttTimeUtil.processGroupedItems(groupedItems, attGroupBean);
}
groupedItems.forEach((c, v) -> {
//第一次上班时间
AttSourceDataBean frontToWorkBean = v.stream()
.filter(a -> a.getAttType().equals("1"))
.collect(Collectors.toList())
.stream().min(Comparator.comparing(AttSourceDataBean::getAttCurrentTime)).orElse(null);
//最新一次下班时间
AttSourceDataBean backOffWorkBean = v.stream()
.filter(a -> a.getAttType().equals("2"))
.collect(Collectors.toList())
.stream().max(Comparator.comparing(AttSourceDataBean::getAttCurrentTime)).orElse(null);
if (tf) {
// if(!v.isEmpty() && v.get(0).getName().equals("任荣辉")){
// System.out.println("11111111111");
// }
//自由打卡不需要去除数据
getFreeAttData(newList, frontToWorkBean, backOffWorkBean, attGroupBean);
} else {
if (backOffWorkBean != null) {
//最新一次下班时间插入list
newList.add(backOffWorkBean);
}
//没有下班卡则添加第一次打卡数据
newList.add(frontToWorkBean);
//获取工作异常
LocalTime lastOutTime = null;
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss");
try {
//存储工作异常的list
List<AttSourceDataBean> longBreakRecords = new ArrayList<>();
for (int i = 0; i < v.size(); i++) {
AttSourceDataBean record = v.get(i);
// 如果是的记录保存时间
if ("2".equals(record.getAttType())) {
lastOutTime = LocalDateTime.parse(record.getAttCurrentTime(), dateTimeFormatter).toLocalTime();
if (lastOutTime.isAfter(LocalTime.parse(attGroupBean.getOffWorkTime(), timeFormatter))) {
//进在下班之后不考虑
break;
}
}
// 如果是的记录并且之前有的记录
else if ("1".equals(record.getAttType()) && lastOutTime != null) {
LocalTime inTime = LocalDateTime.parse(record.getAttCurrentTime(), dateTimeFormatter).toLocalTime();
// 计算实际工作时间不包括午休时间
// if(record.getName().equals("何波")){
// System.out.println("11111111111");
// }
// - 的时间在上班时间前去除
if (inTime.isBefore(LocalTime.parse(attGroupBean.getToWorkTime(), timeFormatter))) {
//进在上班之后不考虑
break;
}
Duration workDuration = AttTimeUtil.calculateWorkDuration(lastOutTime, inTime, attGroupBean);
// 如果工作时间外出超过了规定时间记录下这对
if (workDuration != null && !workDuration.isNegative() && workDuration.toMinutes() > attGroupBean.getWorkAbnormalMinute()) {
AttSourceDataBean longBreakRecord = new AttSourceDataBean();
longBreakRecord.setUserId(record.getUserId());
longBreakRecord.setName(record.getName());
longBreakRecord.setOrgId(attGroupBean.getOrgId());
longBreakRecord.setAttCurrentDay(record.getAttCurrentDay());
longBreakRecord.setAttCurrentTime(v.get(i - 1).getAttCurrentTime() + " " + record.getAttCurrentTime());
longBreakRecord.setAttAddress(v.get(i - 1).getAttAddress() + " " + record.getAttAddress());
longBreakRecords.add(longBreakRecord);
}
// 更新lastOutTime为null因为已经处理了这一对
lastOutTime = null;
}
}
//判断有没有临时外出请假等等
if (!longBreakRecords.isEmpty()) {
int x = attSourceDataDao.getLeaveDataByUserId(longBreakRecords.get(0));
if (x == 0) {
attSourceDataDao.insertWorkAbnormal(longBreakRecords);
}
}
} catch (Exception e) {
e.printStackTrace();
log.error("工作异常处理报错");
}
}
});
return newList;
}
/**
* 处理打卡状态
*

View File

@ -1162,7 +1162,7 @@ public class AttTasks {
*/
public void createReportData(List<AttGroupBean> groupList, String pushDate, int pushType) {
//日报表查询
List<AttDayReportBean> dayReportList = attSourceDataDao.selectAttDayReport(pushDate, pushType);
List<AttDayReportBean> dayReportList = attSourceDataDao.selectAttDayReport(pushDate);
//日报表新增
attSourceDataDao.insertAttDayReport(dayReportList);
List<AttMonthReportBean> monthReportList = attSourceDataDao.selectAttMonthReport(pushDate);

View File

@ -45,23 +45,155 @@ import java.util.stream.Collectors;
@EnableAsync
public class NewAttTask {
@Resource(name = "attSourceDataDao")
private AttSourceDataDao attSourceDataDao;
@Resource(name = "sqlSessionTemplate")
private SqlSessionTemplate sqlSessionTemplate;
@Resource(name = "AttCalService")
private AttCalService attCalService;
/**
* 考勤模版数据定时器 凌晨10分启动一次一天仅仅一次
*/
// @Scheduled(cron = "0 0/10 * * * ?")
@Scheduled(cron = "0 10 0 * * ?")
// @Scheduled(initialDelay = 60000, fixedDelay = 60000 * 10)
@Async
public void getAttTempDataTask() {
log.info("--------考勤模版数据定时器开启------");
String today = DateUtil.today();
insertAttDateHistory(today);
insertAttTempData(today,1);
log.info("--------考勤模版数据定时器完毕------");
}
/**
* 1.数据拉取考勤定时器 每隔1个小时获取一次数据
* 2.考勤数据应用步骤一考勤数据更新
*/
@Scheduled(cron = "0 0/50 * * * ?")
// @Scheduled(initialDelay = 60000, fixedDelay = 60000 * 10)
@Async
public void getAttDataPullTask() {
log.info("--------数据拉取(考勤)定时器开启------");
String today = DateUtil.today();
getAttendanceData(today,1);
updateAttData(today,1);
log.info("--------数据拉取(考勤)定时器完毕------");
}
/**
* 单独子流程不在主流程中
* 旷工判断
* 每天12点将当天未打卡考勤人员上班置为旷工
* 每天晚上22点将下班未打卡置为旷工
*/
@Scheduled(cron = "0 0 12,22 * * ?")
// @Scheduled(initialDelay = 60000, fixedDelay = 60000 * 10)
@Async
public void getAbsenteeismDataTask() {
log.info("--------旷工判断定时器开启------");
String today = DateUtil.today();
updateAbsenteeismData(today,1);
log.info("--------旷工判断定时器完毕------");
}
/**
* 单独子流程不在主流程中
* 昨日下班卡更新
* 每天7点将昨天数据更新一下
*/
@Scheduled(cron = "0 0 7 * * ?")
// @Scheduled(initialDelay = 60000, fixedDelay = 60000 * 10)
@Async
public void getYesterdayAttDataTask() {
log.info("--------昨日下班卡更新定时器开启------");
// 获取昨天日期
LocalDate yesterday = LocalDate.now().minusDays(1);
// 格式化输出
String yesterdayStr = yesterday.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
updateAttData(yesterdayStr,2);
//日报表更新 TODO
log.info("--------昨日下班卡更新定时器完毕------");
}
/**
* 请假数据应用--法假
* 每天更新一次一点更新
*/
@Scheduled(cron = "0 0 1 * * ?")
// @Scheduled(initialDelay = 60000, fixedDelay = 60000 * 10)
@Async
public void getLegalHolidayDataTask() {
log.info("--------请假数据应用--法假定时器开启------");
String today = DateUtil.today();
updateLegalHolidayData(today);
log.info("--------请假数据应用--法假定时器完毕------");
}
/**
* 请假数据应用--请假
* 每天更新两次上午8点下午18点45天前数据
*/
@Scheduled(cron = "0 0 8,18 * * ?")
// @Scheduled(initialDelay = 60000, fixedDelay = 60000 * 10)
@Async
public void getLeaveDataTask() {
log.info("--------请假数据应用--请假定时器开启------");
String today = DateUtil.today();
updateLeaveData(today);
log.info("--------请假数据应用--请假定时器完毕------");
}
/**
* 报表数据生成--日报表
* 一小时更新一次
*/
@Scheduled(cron = "0 0 8,18 * * ?")
// @Scheduled(initialDelay = 60000, fixedDelay = 60000 * 10)
@Async
public void getDayReportDataTask() {
log.info("--------报表数据生成--日报表定时器开启------");
String today = DateUtil.today();
insertDayReportDataTask(today);
log.info("--------报表数据生成--日报表定时器完毕------");
}
/**
* 报表数据生成--月报表
* 月初生成之后修改
*/
@Scheduled(cron = "0 15 1 1 * ?")
// @Scheduled(initialDelay = 60000, fixedDelay = 60000 * 10)
@Async
public void getMonthReportDataTempTask() {
log.info("--------报表数据生成--月报表定时器开启------");
String today = DateUtil.today();
insertMonthReportTempData(today);
log.info("--------报表数据生成--月报表定时器完毕------");
}
/**
* 报表数据生成--月报表
* 每日数据变化修改之后修改
*/
@Scheduled(cron = "0 0 8,10,17,19,23 * * ?")
// @Scheduled(initialDelay = 60000, fixedDelay = 60000 * 10)
@Async
public void getMonthReportDataTask() {
log.info("--------报表数据生成--月报表定时器开启------");
String today = DateUtil.today();
updateMonthReportData(today);
log.info("--------报表数据生成--月报表定时器完毕------");
}
/**
* 待考勤人员列表
* 在人员考勤模版数据之前生成
* @param pushDate 时间(可为空为空则推历史60天内没生成的数据不为空则推指定日期)
*/
private void insertAttDateHistory(String pushDate) {
public void insertAttDateHistory(String pushDate) {
//待考勤人员列表生成
attCalService.insertAttDateHistory(pushDate);
}
@ -73,7 +205,7 @@ public class NewAttTask {
* @param pushDate 时间
* @param pushType 1:自动推送当天 2:手动历史
*/
private void insertAttTempData(String pushDate, int pushType) {
public void insertAttTempData(String pushDate, int pushType) {
//获取考勤数据
attCalService.insertAttTempData(pushDate, pushType);
}
@ -84,18 +216,18 @@ public class NewAttTask {
* @param pushDate 时间
* @param pushType 1:自动推送当天 2:手动历史
*/
private void getAttendanceData(String pushDate, int pushType) {
public void getAttendanceData(String pushDate, int pushType) {
//获取考勤数据
attCalService.getAttendanceData(pushDate, pushType);
}
/**
* 考勤数据应用步骤一考勤数据更新
* 建议一小时一次
* 建议一小时一次,紧随数据拉取之后
* @param pushDate 时间
* @param pushType 1:自动推送当天 2:手动历史
*/
private void updateAttData(String pushDate, int pushType) {
public void updateAttData(String pushDate, int pushType) {
//获取考勤数据
attCalService.updateAttData(pushDate, pushType);
}
@ -107,7 +239,7 @@ public class NewAttTask {
* @param pushDate 时间
* @param pushType 1:自动推送当天 2:手动历史
*/
private void updateAbsenteeismData(String pushDate, int pushType) {
public void updateAbsenteeismData(String pushDate, int pushType) {
//旷工状态更新
attCalService.updateAbsenteeismData(pushDate, pushType);
}
@ -117,7 +249,7 @@ public class NewAttTask {
* 法定节假日不会随时间变化一天执行一次就可以了
* @param pushDate 时间
*/
private void updateLegalHolidayData(String pushDate) {
public void updateLegalHolidayData(String pushDate) {
//法假数据更新
attCalService.updateLegalHolidayData(pushDate);
}
@ -127,9 +259,39 @@ public class NewAttTask {
* 法定节假日不会随时间变化一天执行一次就可以了
* @param pushDate 时间
*/
private void updateLeaveData(String pushDate) {
public void updateLeaveData(String pushDate) {
//请假数据更新
attCalService.updateLeaveData(pushDate);
}
/**
* 报表数据生成日报表
* 每次更新数据都要执行(跟随)
* @param pushDate 时间
*/
public void insertDayReportDataTask(String pushDate) {
//日报表更新
attCalService.insertDayReportData(pushDate);
}
/**
* 月报表数据生成人员对应出月出勤
* 月初生成一次
* @param pushDate 时间
*/
public void insertMonthReportTempData(String pushDate) {
//月报表模版数据生成
attCalService.insertMonthReportTempData(pushDate);
}
/**
* 月报表数据更新人员对应出月出勤
* 每次更新完数据要执行(跟随)
* @param pushDate 时间
*/
public void updateMonthReportData(String pushDate) {
//月报表模版数据生成
attCalService.updateMonthReportData(pushDate);
}
}

View File

@ -80,6 +80,15 @@
</foreach>
;
</insert>
<insert id="insertAttMonthReportTemp">
insert into att_month_report(user_id, name, org_id, org_name, att_current_month,
required_days)
values
<foreach collection="list" item="params" separator=";">
(#{params.userId}, #{params.userName}, #{params.orgId}, #{params.orgName},
#{params.attCurrentMonth}, #{params.requiredDays})
</foreach>
</insert>
<update id="updateAttStatusData">
<foreach collection="list" item="params" separator=";">
@ -169,6 +178,27 @@
and att_type = #{v.attType}
and is_update = 0;
</update>
<update id="updateAttMonthReport">
<foreach collection="list" item="v" separator=";">
update att_month_report
set org_id = #{v.orgId},
org_name = #{v.orgName},
nomal_num = #{v.normalNum},
late_num = #{v.lateNum},
early_num = #{v.earlyNum},
skipping_num = #{v.skippingNum},
leave_num = #{v.leaveNum},
address_error_num = #{v.addressErrorNum},
ein_error_num = #{v.einErrorNum},
rest_num = #{v.restNum},
out_num = #{v.outNum},
business_trip_num = #{v.businessTripNum}
where
user_id = #{v.userId}
and att_current_month = #{v.attCurrentMonth}
</foreach>
</update>
<delete id="updateHisData">
delete
@ -242,7 +272,6 @@
<select id="selectAttDayReport" resultType="com.bonus.system.att.entity.AttDayReportBean">
select att_current_day,
org_id,
IFNULL(sum(toWorkAttStatus = 1 and offWorkAttStatus = 1), 0) as normalNum,
IFNULL(sum(toWorkAttStatus = 2 or offWorkAttStatus = 2), 0) as lateNum,
IFNULL(sum(toWorkAttStatus = 3 or offWorkAttStatus = 3), 0) as skippingNum,
@ -258,64 +287,42 @@
IFNULL(sum(toWorkAttStatus = 8 or offWorkAttStatus = 8), 0) as einErrorNum,
IFNULL(sum(toWorkAttStatus = 9 or offWorkAttStatus = 9), 0) as addressErrorNum
from v_att_update_data
where att_current_day
<if test=' pushType == "1" '>
>= #{pushDate}
</if>
<if test=' pushType == "2" '>
= #{pushDate}
</if>
GROUP BY att_current_day, org_id
where att_current_day = #{pushDate}
GROUP BY att_current_day
</select>
<!--att_setting_history 的处理是为了获取当月最后一天在哪个考勤规则,去计算他的当月考勤天数 -->
<select id="selectAttMonthReport" resultType="com.bonus.system.att.entity.AttMonthReportBean">
SELECT g.org_id,
SELECT
v.user_id,
su.user_name,
suo.org_id,
so.org_name,
g.group_id,
DATE_FORMAT(att_current_day, '%Y-%m') AS attCurrentMonth,
IFNULL(sum(IF(toWorkAttStatus = 1, 0.5, 0)), 0) +
IFNULL(sum(IF(offWorkAttStatus = 1, 0.5, 0)), 0) AS normalNum,
IFNULL(sum(IF(toWorkAttStatus = 2, 0.5, 0)), 0) +
IFNULL(sum(IF(offWorkAttStatus = 2, 0.5, 0)), 0) AS lateNum,
IFNULL(sum(IF(toWorkAttStatus = 3, 0.5, 0)), 0) +
IFNULL(sum(IF(offWorkAttStatus = 3, 0.5, 0)), 0) AS skippingNum,
IFNULL(sum(IF(toWorkAttStatus = 4, 0.5, 0)), 0) +
IFNULL(sum(IF(offWorkAttStatus = 4, 0.5, 0)), 0) AS earlyNum,
IFNULL(sum(IF(toWorkAttStatus = 5, 0.5, 0)), 0) +
IFNULL(sum(IF(offWorkAttStatus = 5, 0.5, 0)), 0) AS restNum,
DATE_FORMAT( att_current_day, '%Y-%m' ) AS attCurrentMonth,
IFNULL( sum( IF ( toWorkAttStatus = 1, 0.5, 0 )), 0 ) + IFNULL( sum( IF ( offWorkAttStatus = 1, 0.5, 0 )), 0 ) AS normalNum,
IFNULL( sum( IF ( toWorkAttStatus = 2, 0.5, 0 )), 0 ) + IFNULL( sum( IF ( offWorkAttStatus = 2, 0.5, 0 )), 0 ) AS lateNum,
IFNULL( sum( IF ( toWorkAttStatus = 3, 0.5, 0 )), 0 ) + IFNULL( sum( IF ( offWorkAttStatus = 3, 0.5, 0 )), 0 ) AS skippingNum,
IFNULL( sum( IF ( toWorkAttStatus = 4, 0.5, 0 )), 0 ) + IFNULL( sum( IF ( offWorkAttStatus = 4, 0.5, 0 )), 0 ) AS earlyNum,
IFNULL( sum( IF ( toWorkAttStatus = 5, 0.5, 0 )), 0 ) + IFNULL( sum( IF ( offWorkAttStatus = 5, 0.5, 0 )), 0 ) AS restNum,
sum(
IF
(toWorkAttStatus IN
(SELECT dict_value FROM sys_dict_data WHERE dict_type = 'att_status' AND is_leave = '1'), 0.5,
0)) + sum(
( toWorkAttStatus IN ( SELECT dict_value FROM sys_dict_data WHERE dict_type = 'att_status' AND is_leave = '1' ), 0.5, 0 )) + sum(
IF
(offWorkAttStatus IN
(SELECT dict_value FROM sys_dict_data WHERE dict_type = 'att_status' AND is_leave = '1'), 0.5,
0)) AS leaveNum,
IFNULL(sum(IF(toWorkAttStatus = 7, 0.5, 0)), 0) +
IFNULL(sum(IF(offWorkAttStatus = 7, 0.5, 0)), 0) AS outNum,
IFNULL(sum(IF(toWorkAttStatus = 8, 0.5, 0)), 0) +
IFNULL(sum(IF(offWorkAttStatus = 8, 0.5, 0)), 0) AS einErrorNum,
IFNULL(sum(IF(toWorkAttStatus = 9, 0.5, 0)), 0) +
IFNULL(sum(IF(offWorkAttStatus = 9, 0.5, 0)), 0) AS addressErrorNum,
IFNULL(sum(IF(toWorkAttStatus = 10, 0.5, 0)), 0) +
IFNULL(sum(IF(offWorkAttStatus = 10, 0.5, 0)), 0) AS businessTripNum
FROM v_att_update_data v
( offWorkAttStatus IN ( SELECT dict_value FROM sys_dict_data WHERE dict_type = 'att_status' AND is_leave = '1' ), 0.5, 0 )) AS leaveNum,
IFNULL( sum( IF ( toWorkAttStatus = 7, 0.5, 0 )), 0 ) + IFNULL( sum( IF ( offWorkAttStatus = 7, 0.5, 0 )), 0 ) AS outNum,
IFNULL( sum( IF ( toWorkAttStatus = 8, 0.5, 0 )), 0 ) + IFNULL( sum( IF ( offWorkAttStatus = 8, 0.5, 0 )), 0 ) AS einErrorNum,
IFNULL( sum( IF ( toWorkAttStatus = 9, 0.5, 0 )), 0 ) + IFNULL( sum( IF ( offWorkAttStatus = 9, 0.5, 0 )), 0 ) AS addressErrorNum,
IFNULL( sum( IF ( toWorkAttStatus = 10, 0.5, 0 )), 0 ) + IFNULL( sum( IF ( offWorkAttStatus = 10, 0.5, 0 )), 0 ) AS businessTripNum
FROM
v_att_update_data v
LEFT JOIN sys_user su ON su.user_id = v.user_id
LEFT JOIN (SELECT *
FROM (SELECT DISTINCT *
FROM att_setting_history
WHERE DATE_FORMAT(current_day, '%Y-%m') = DATE_FORMAT(#{pushDate}, '%Y-%m')
ORDER BY current_day DESC) a
GROUP BY user_id) g ON g.user_id = v.user_id
LEFT JOIN sys_organization so ON so.id = g.org_id
WHERE DATE_FORMAT(att_current_day, '%Y-%m') = DATE_FORMAT(#{pushDate}, '%Y-%m')
AND g.group_id IS NOT NULL
GROUP BY DATE_FORMAT(att_current_day, '%Y-%m'),
LEFT JOIN sys_user_org suo ON suo.user_id = v.user_id
LEFT JOIN sys_organization so ON so.id = suo.org_id
WHERE
DATE_FORMAT( att_current_day, '%Y-%m' ) = DATE_FORMAT( #{pushDate}, '%Y-%m' )
GROUP BY
DATE_FORMAT( att_current_day, '%Y-%m' ),
v.user_id
</select>
@ -517,4 +524,23 @@
AND type = '1'
</select>
<select id="selectAttMonthReportTemp" resultType="com.bonus.system.att.entity.AttMonthReportBean">
SELECT
su.user_id,
su.user_name,
suo.org_id,
so.org_name,
ash.group_id
FROM
att_setting_history ash
LEFT JOIN sys_user su ON su.user_id = ash.user_id
LEFT JOIN sys_user_org suo ON suo.user_id = su.user_id
LEFT JOIN sys_organization so ON so.id = suo.org_id
WHERE
DATE_FORMAT( ash.current_day, '%Y-%m' ) = DATE_FORMAT( #{pushDate}, '%Y-%m' )
GROUP BY
DATE_FORMAT( #{pushDate}, '%Y-%m' ),
su.user_id
</select>
</mapper>