weaver-hrm-salary/src/com/engine/salary/service/impl/AttendQuoteDataServiceImpl....

874 lines
42 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.engine.salary.service.impl;
import com.alibaba.druid.support.json.JSONUtils;
import com.alibaba.fastjson.JSONObject;
import com.engine.common.util.ServiceUtil;
import com.engine.core.impl.Service;
import com.engine.salary.biz.*;
import com.engine.salary.common.LocalDateRange;
import com.engine.salary.constant.SalaryDefaultTenantConstant;
import com.engine.salary.entity.datacollection.DataCollectionEmployee;
import com.engine.salary.entity.datacollection.bo.AttendQuoteDataBO;
import com.engine.salary.entity.datacollection.dto.*;
import com.engine.salary.entity.datacollection.param.*;
import com.engine.salary.entity.datacollection.po.AttendQuoteDataPO;
import com.engine.salary.entity.datacollection.po.AttendQuoteDataValuePO;
import com.engine.salary.entity.datacollection.po.AttendQuoteFieldPO;
import com.engine.salary.entity.datacollection.po.AttendQuotePO;
import com.engine.salary.entity.salarysob.bo.SalarySobRangeBO;
import com.engine.salary.entity.salarysob.dto.SalarySobCycleDTO;
import com.engine.salary.entity.salarysob.param.SalarySobRangeEmpQueryParam;
import com.engine.salary.entity.salarysob.po.SalarySobPO;
import com.engine.salary.entity.salarysob.po.SalarySobRangePO;
import com.engine.salary.enums.UserStatusEnum;
import com.engine.salary.enums.datacollection.AttendQuoteSourceTypeEnum;
import com.engine.salary.exception.SalaryRunTimeException;
import com.engine.salary.mapper.datacollection.AttendQuoteDataMapper;
import com.engine.salary.mapper.salarysob.SalarySobMapper;
import com.engine.salary.mapper.salarysob.SalarySobRangeMapper;
import com.engine.salary.remote.attend.entity.Attend4Salary;
import com.engine.salary.remote.attend.service.RemoteAttend4SalaryService;
import com.engine.salary.remote.attend.service.impl.RemoteAttend4SalaryServiceImpl;
import com.engine.salary.service.AttendQuoteDataService;
import com.engine.salary.service.AttendQuoteFieldSettingService;
import com.engine.salary.service.SalarySobService;
import com.engine.salary.util.SalaryDateUtil;
import com.engine.salary.util.SalaryI18nUtil;
import com.engine.salary.util.db.MapperProxyFactory;
import com.engine.salary.util.excel.ExcelParseHelper;
import com.engine.salary.util.excel.ExcelSupport;
import com.engine.salary.util.excel.ExcelUtil;
import com.engine.salary.util.page.PageInfo;
import com.engine.salary.util.page.SalaryPageUtil;
import com.engine.salary.util.valid.ValidUtil;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import dm.jdbc.util.IdGenerator;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.util.IOUtils;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import weaver.file.ImageFileManager;
import weaver.hrm.User;
import weaver.wechat.util.Utils;
import java.io.InputStream;
import java.math.BigDecimal;
import java.time.YearMonth;
import java.util.*;
import java.util.stream.Collectors;
import static com.engine.salary.util.excel.ExcelSupport.EXCEL_TYPE_XLSX;
/**
* 数据采集-考勤引用数据
* <p>Copyright: Copyright (c) 2022</p>
* <p>Company: 泛微软件</p>
*
* @author qiantao
* @version 1.0
**/
@Slf4j
public class AttendQuoteDataServiceImpl extends Service implements AttendQuoteDataService {
private AttendQuoteBiz quoteBiz = new AttendQuoteBiz();
private AttendQuoteDataBiz dataBiz = new AttendQuoteDataBiz();
private AttendQuoteDataValueBiz dataValueBiz = new AttendQuoteDataValueBiz();
private AttendQuoteFieldBiz fieldBiz = new AttendQuoteFieldBiz();
private EmployBiz employeeBiz = new EmployBiz();
private AttendQuoteFieldSettingService getFieldSettingService(User user) {
return (AttendQuoteFieldSettingService) ServiceUtil.getService(AttendQuoteFieldSettingServiceImpl.class, user);
}
private SalarySobService getSalarySobService(User user) {
return (SalarySobService) ServiceUtil.getService(SalarySobServiceImpl.class, user);
}
private AttendQuoteDataMapper getAttendQuoteDataMapper() {
return MapperProxyFactory.getProxy(AttendQuoteDataMapper.class);
}
private SalarySobMapper getSalarySobMapper() {
return MapperProxyFactory.getProxy(SalarySobMapper.class);
}
private SalarySobRangeMapper getSalarySobRangeMapper() {
return MapperProxyFactory.getProxy(SalarySobRangeMapper.class);
}
private RemoteAttend4SalaryService getRemoteAttend4SalaryService(User user) {
return (RemoteAttend4SalaryService) ServiceUtil.getService(RemoteAttend4SalaryServiceImpl.class, user);
}
@Override
public PageInfo<AttendQuoteDataBaseDTO> listPage(AttendQuoteDataQueryParam queryParam) {
SalaryPageUtil.start(queryParam.getCurrent(), queryParam.getPageSize());
List<AttendQuoteDataBaseDTO> list = getAttendQuoteDataMapper().list(queryParam);
PageInfo<AttendQuoteDataBaseDTO> page = new PageInfo<AttendQuoteDataBaseDTO>(list);
return page;
}
/**
* 获取所有考勤字段
*
* @return
*/
private List<AttendQuoteFieldPO> getAllAttendQuoteFields() {
return fieldBiz.listSome(AttendQuoteFieldPO.builder().build());
}
/**
* 获取考勤数据结果
*
* @param attendQuoteDataBases
* @return
*/
public List<Map<String, Object>> getListMaps(List<AttendQuoteDataBaseDTO> attendQuoteDataBases) {
if (CollectionUtils.isEmpty(attendQuoteDataBases)) {
return new ArrayList<>();
}
// 考核数据值
List<AttendQuoteDataValuePO> attendQuoteDataValues = dataValueBiz.listSome(AttendQuoteDataValuePO.builder().attendQuoteId(attendQuoteDataBases.get(0).getAttendQuoteId()).build());
return attendQuoteDataBases.stream().map(m -> {
Map<String, Object> map = new LinkedHashMap<>();
map.put("id", m.getId());
map.put("username", m.getUsername());
map.put("departmentName", m.getDepartmentName());
map.put("mobile", m.getMobile());
map.put("jobNum", m.getJobNum());
// 考勤数据
attendQuoteDataValues.stream().filter(a -> a.getAttendQuoteDataId().equals(m.getId())).collect(Collectors.toList()).forEach(e -> {
map.put(e.getAttendQuoteFieldId() + "_attendQuoteData", e.getDataValue());
});
return map;
}).collect(Collectors.toList());
}
@Override
public List<AttendQuoteDataDTO> getAttendQuoteData(YearMonth salaryYearMonth, Long salarySobId, List<Long> employeeIds) {
if (salaryYearMonth == null || salarySobId == null) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100358, "参数有误薪资所属月、薪资账套id"));
}
List<AttendQuoteDataDTO> list = new ArrayList<>();
Date salaryYearMonthDay = SalaryDateUtil.localDateToDate(salaryYearMonth.atDay(1));
//查询引用主表
List<AttendQuotePO> attendQuotes = quoteBiz.listSome(AttendQuotePO.builder().salaryYearMonth(salaryYearMonthDay).salarySobId(salarySobId).build());
if (CollectionUtils.isEmpty(attendQuotes)) {
return Collections.emptyList();
}
AttendQuotePO attendQuote = attendQuotes.get(0);
//查询考勤数据值
List<AttendQuoteDataValuePO> attendQuoteDataValues = dataValueBiz.listSome(AttendQuoteDataValuePO.builder().attendQuoteId(attendQuote.getId()).employeeIds(employeeIds).build());
if (CollectionUtils.isEmpty(employeeIds)) {
employeeIds = attendQuoteDataValues.stream().map(AttendQuoteDataValuePO::getEmployeeId)
.distinct().collect(Collectors.toList());
}
employeeIds.forEach(e -> {
AttendQuoteDataDTO attendQuoteData = new AttendQuoteDataDTO();
attendQuoteData.setEmployeeId(e);
List<AttendQuoteDataValueDTO> dataValues = attendQuoteDataValues.stream().filter(v -> v.getEmployeeId().equals(e)).map(m ->
AttendQuoteDataValueDTO.builder()
.attendQuoteFieldId(m.getAttendQuoteFieldId())
.dataValue(m.getDataValue())
.build()).collect(Collectors.toList());
attendQuoteData.setDataValues(dataValues);
list.add(attendQuoteData);
});
return list;
}
@Override
public XSSFWorkbook export(AttendQuoteDataQueryParam queryParam) {
if (queryParam.getAttendQuoteId() == null) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100253, "考勤引用id不能为空"));
}
// 考勤数据分页主数据
List<AttendQuoteDataBaseDTO> attendQuoteDataBases = dataBiz.list(queryParam);
// 所有考勤字段
List<AttendQuoteFieldPO> attendQuoteFields = getAllAttendQuoteFields();
// 获取最终结果
List<Map<String, Object>> listMaps = getListMaps(attendQuoteDataBases);
// 1.工作簿名称
String sheetName = SalaryI18nUtil.getI18nLabel(93931, "考勤数据");
List<Object> header = new ArrayList<>();
header.add(SalaryI18nUtil.getI18nLabel(85429, "姓名"));
header.add(SalaryI18nUtil.getI18nLabel(86185, "部门"));
header.add(SalaryI18nUtil.getI18nLabel(86186, "手机号"));
header.add(SalaryI18nUtil.getI18nLabel(86317, "工号"));
// 动态列
if (CollectionUtils.isNotEmpty(listMaps)) {
Map<String, Object> mapColumn = listMaps.get(0);
for (AttendQuoteFieldPO attendQuoteField : attendQuoteFields) {
if (mapColumn.containsKey(attendQuoteField.getId() + "_attendQuoteData")) {
header.add(attendQuoteField.getFieldName());
}
}
}
List<List<Object>> rows = new ArrayList<>();
// 2.表头
rows.add(header);
// 3.表数据
for (Map<String, Object> dto : listMaps) {
List<Object> row = new ArrayList<>();
row.add(dto.get("username"));
row.add(dto.get("departmentName"));
row.add(dto.get("mobile"));
row.add(dto.get("jobNum"));
// 动态列
Map<String, Object> mapColumn = listMaps.get(0);
for (AttendQuoteFieldPO attendQuoteField : attendQuoteFields) {
if (mapColumn.containsKey(attendQuoteField.getId() + "_attendQuoteData")) {
row.add(dto.get(attendQuoteField.getId().toString() + "_attendQuoteData"));
}
}
rows.add(row);
}
return ExcelUtil.genWorkbookV2(rows, sheetName);
}
/**
* 获取表头设置字段
*
* @param sourceType
* @return
*/
private List<AttendQuoteFieldPO> getAttendQuoteSetFields(AttendQuoteSourceTypeEnum sourceType) {
List<AttendQuoteFieldPO> allAttendQuoteFields = getAllAttendQuoteFields();
List<AttendQuoteFieldSettingListDTO> attendQuoteFieldSettingList = getFieldSettingService(user).listNoSync(AttendQuoteFieldSettingQueryParam.builder().sourceType(sourceType).isViewChecked(Boolean.TRUE).build());
List<AttendQuoteFieldPO> attendQuoteFields = new ArrayList<>();
attendQuoteFieldSettingList.forEach(s -> {
List<AttendQuoteFieldSettingFieldListDTO> items = s.getItems();
if (CollectionUtils.isNotEmpty(items)) {
items.forEach(i -> {
Optional<AttendQuoteFieldPO> optional = allAttendQuoteFields.stream().filter(f -> f.getId().equals(i.getId())).findFirst();
optional.ifPresent(attendQuoteFields::add);
});
}
});
return attendQuoteFields;
}
@Override
public String syncAttendQuoteData(AttendQuoteDataSyncParam syncParam) {
AttendQuoteDataSyncParam.checkParam(syncParam);
String salaryYearMonth = syncParam.getSalaryYearMonth();
int year = Integer.parseInt(salaryYearMonth.split("-")[0]);
int month = Integer.parseInt(salaryYearMonth.split("-")[1]);
if (!SalaryDateUtil.checkYearMonth(salaryYearMonth)) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100365, "薪资所属月格式有误,正确格式示例为'2021-01'"));
}
// 1.获取已设置的可同步的考勤字段
List<AttendQuoteFieldPO> attendQuoteFields = getAttendQuoteSetFields(AttendQuoteSourceTypeEnum.QUOTE);
if (CollectionUtils.isEmpty(attendQuoteFields)) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100366, "请先设置同步字段"));
}
// 获取薪资账套
SalarySobCycleDTO salarySobCycle = getSalarySobService(user).getSalarySobCycle(syncParam.getSalarySobId(), YearMonth.of(year, month));
// 2.薪资账套人员
List<Long> employeeIds = new ArrayList<>();
// 获取薪资账套人员
List<SalarySobRangePO> salarySobRanges = getSalarySobRangeMapper().listSome(SalarySobRangePO.builder().includeType(1).salarySobId(salarySobCycle.getSalarySobId()).build());
List<SalarySobRangeEmpQueryParam> salarySobRangeEmpQueryParams = SalarySobRangeBO.convert2EmployeeQueryParam(salarySobRanges);
List<Long> employeeSalarySobIds = getSalarySobRangeMapper().listEmployeeIds(salarySobRangeEmpQueryParams);
if (CollectionUtils.isEmpty(employeeSalarySobIds) || CollectionUtils.isEmpty(salarySobRangeEmpQueryParams)) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100367, "薪资账套还没有人员"));
}
// 账套外人员
List<Long> employeeOtherIds = (List<Long>) syncParam.getEmployeeIds();
employeeIds.addAll(employeeSalarySobIds);
employeeIds.addAll(CollectionUtils.emptyIfNull(employeeOtherIds));
// 4.获取考勤模块数据
List<Map<String, Object>> attendQuoteSyncData = getAttendQuoteDataFromRemoteAttend(salarySobCycle.getAttendCycle(), employeeIds, attendQuoteFields);
List<AttendQuoteDataPO> pos = new ArrayList<>();
List<AttendQuoteDataValuePO> values = new ArrayList<>();
// 5.考勤引用数据处理
Date now = new Date();
if (CollectionUtils.isNotEmpty(attendQuoteSyncData)) {
// 3.生成考勤引用
AttendQuotePO attendQuote = getAttendQuote(AttendQuoteSourceTypeEnum.QUOTE, syncParam.getSalarySobId(), year, month, syncParam.getDescription());
for (Long employeeId : employeeIds) {
AttendQuoteDataPO po = new AttendQuoteDataPO();
po.setId(IdGenerator.generate());
po.setCreateTime(now);
po.setUpdateTime(now);
po.setCreator((long) user.getUID());
po.setTenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY);
// 考勤引用表的主键id
po.setAttendQuoteId(attendQuote.getId());
po.setEmployeeId(employeeId);
pos.add(po);
for (Map<String, Object> attendQuoteData : attendQuoteSyncData) {
if (!Objects.isNull(attendQuoteData.get("employeeId")) &&
!Objects.isNull(employeeId) &&
!Objects.isNull(attendQuoteData.get("attendQuoteFieldId")) &&
attendQuoteData.get("employeeId").toString().equals(employeeId.toString())) {
values.add(AttendQuoteDataValuePO.builder()
.createTime(now)
.updateTime(now)
.creator((long) user.getUID())
.tenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY)
.employeeId(employeeId)
.attendQuoteId(attendQuote.getId())
.attendQuoteDataId(po.getId())
.attendQuoteFieldId(Long.valueOf(attendQuoteData.get("attendQuoteFieldId").toString()))
.dataValue(Utils.null2String(attendQuoteData.get("dataValue")))
.build());
}
}
}
// 6.数据落库处理
handleDataToDB(attendQuote.getId(), pos, values);
} else {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100368, "暂无考勤数据可以同步"));
}
// todo 记录日志
// recordLog(attendQuote, currentEmployeeId, currentTenantKey, null);
return null;
}
/**
* 获取考勤引用
*
* @param salarySobId
* @param year
* @param month
* @return
*/
private AttendQuotePO getAttendQuote(AttendQuoteSourceTypeEnum sourceType, Long salarySobId, int year, int month, String description) {
SalarySobCycleDTO salarySobCycle = getSalarySobService(user).getSalarySobCycle(salarySobId, YearMonth.of(year, month));
Date salaryYearMonthDayDate = SalaryDateUtil.localDateToDate(YearMonth.of(year, month).atDay(1));
List<AttendQuotePO> attendQuotes = quoteBiz.listSome(AttendQuotePO.builder().salarySobId(salarySobId).salaryYearMonth(salaryYearMonthDayDate).build());
// 考勤引用
AttendQuotePO attendQuote = new AttendQuotePO();
if (CollectionUtils.isNotEmpty(attendQuotes)) {
attendQuote = attendQuotes.get(0);
}
attendQuote.setSalarySobId(salarySobCycle.getSalarySobId());
LocalDateRange salaryCycleRange = salarySobCycle.getSalaryCycle();
LocalDateRange attendCycleRange = salarySobCycle.getAttendCycle();
// 考勤周期
attendQuote.setAttendCycle(SalaryDateUtil.getFormatLocalDate(attendCycleRange.getFromDate()) + " ~ " + SalaryDateUtil.getFormatLocalDate(attendCycleRange.getEndDate()));
// 薪资周期
attendQuote.setSalaryCycle(SalaryDateUtil.getFormatLocalDate(salaryCycleRange.getFromDate()) + " ~ " + SalaryDateUtil.getFormatLocalDate(salaryCycleRange.getEndDate()));
attendQuote.setSalaryYearMonth(salaryYearMonthDayDate);
// 来源:导入
attendQuote.setSourceType(sourceType.getValue());
attendQuote.setDescription(description);
Date now = new Date();
attendQuote.setCreateTime(now);
attendQuote.setUpdateTime(now);
attendQuote.setCreator((long) user.getUID());
attendQuote.setTenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY);
// 新增或修改考勤引用
if (attendQuote.getId() != null) {
quoteBiz.updateById(attendQuote);
} else {
attendQuote.setId(IdGenerator.generate());
quoteBiz.insert(attendQuote);
}
return attendQuote;
}
/**
* 获取考勤模块数据
*
* @param attendCycleRange
* @param employeeIds
* @param attendQuoteFields
* @return
*/
private List<Map<String, Object>> getAttendQuoteDataFromRemoteAttend(LocalDateRange attendCycleRange, List<Long> employeeIds, List<AttendQuoteFieldPO> attendQuoteFields) {
List<Map<String, Object>> attendQuoteSyncData = new ArrayList<>();
Attend4Salary attend4Salary = new Attend4Salary();
try {
int partSize = 500;
List<List<Long>> partition = Lists.partition(employeeIds, partSize);
for (List<Long> part : partition) {
attend4Salary.setBeginDate(attendCycleRange.getFromDate());
attend4Salary.setEndDate(attendCycleRange.getEndDate());
attend4Salary.setOnlyEmpIds(part);
List<Map<String, String>> attendResult = getRemoteAttend4SalaryService(user).getDatas(attend4Salary);
log.info("考勤数据:{}", JSONUtils.toJSONString(attendResult));
AttendQuoteDataBO.buildAttendDataFromRemote(attendResult, attendQuoteFields, attendQuoteSyncData);
// attend4Salary.setUnit("day");
// attendResult = remoteAttend4SalaryService.getWorkTimeSummary(attend4Salary);
// log.info("考勤数据[按天]:{}", JSONUtils.toJSONString(attendResult.getData()));
// AttendQuoteDataBO.buildAttendDataFromRemote("day", attendResult.getData(), attendQuoteFields, attendQuoteSyncData);
}
} catch (Exception e) {
log.error("获取考勤数据错误失败:{}", String.format("参数:%s,错误信息:%s", JSONObject.toJSONString(attend4Salary), e.getMessage()), e);
return attendQuoteSyncData;
}
log.info("同步的考勤数据:{}", JSONUtils.toJSONString(attendQuoteSyncData));
return attendQuoteSyncData;
}
/**
* 引用同步或导入落库处理
*
* @param attendQuoteId
* @param pos
* @param values
*/
private void handleDataToDB(Long attendQuoteId, List<AttendQuoteDataPO> pos, List<AttendQuoteDataValuePO> values) {
// 数据落库处理
if (CollectionUtils.isEmpty(pos)) {
return;
}
// 多条相同人的则以第一条为准如果逆序排列用于重复的则以最后一条为准Collections.reverse(pos);
pos = pos.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(f -> f.getEmployeeId()))), ArrayList::new));
// 删除考勤数据
ArrayList<Long> quoteIds = new ArrayList<>();
quoteIds.add(attendQuoteId);
dataBiz.deleteByAttendQuoteIds(quoteIds);
// 新增考勤数据
dataBiz.insertData(pos);
// 删除考勤值数据
// dataValueBiz.deleteByAttendQuoteDataIds(pos.stream().map(AttendQuoteDataPO::getId).collect(Collectors.toList()));
dataValueBiz.deleteByAttendQuoteIds(quoteIds);
// 新增考勤值数据
if (CollectionUtils.isNotEmpty(values)) {
log.info("考勤数据:{}",values);
dataValueBiz.insertData(values);
}
}
@Override
public XSSFWorkbook downloadTemplate(AttendQuoteDataExportTemplateParam exportParam) {
try {
// 考勤主数据
Date salaryYearMonth = SalaryDateUtil.localDateToDate(exportParam.getSalaryYearMonth().atDay(1));
List<AttendQuotePO> attendQuotePOS = quoteBiz.listSome(AttendQuotePO.builder()
.salarySobId(exportParam.getSalarySobId())
.salaryYearMonth(salaryYearMonth)
.ids(exportParam.getIds()).build());
AttendQuotePO po = CollectionUtils.isNotEmpty(attendQuotePOS) ? attendQuotePOS.get(0) : null;
AttendQuoteDataQueryParam queryParam = AttendQuoteDataQueryParam.builder().attendQuoteId(po == null ? 0L : po.getId()).build();
List<AttendQuoteDataBaseDTO> attendQuoteDataBases = dataBiz.list(queryParam);
// 获取已设置的可同步的字段
List<AttendQuoteFieldPO> attendQuoteFields = getAttendQuoteSetFields(AttendQuoteSourceTypeEnum.IMPORT);
// 获取最终结果
List<Map<String, Object>> listMaps = getListMaps(attendQuoteDataBases);
// 1.工作簿名称
String sheetName = SalaryI18nUtil.getI18nLabel(101606, "考勤引用导入模板");
List<Object> header = new ArrayList<>();
header.add(SalaryI18nUtil.getI18nLabel(85429, "姓名"));
header.add(SalaryI18nUtil.getI18nLabel(86185, "部门"));
header.add(SalaryI18nUtil.getI18nLabel(86186, "手机号"));
header.add(SalaryI18nUtil.getI18nLabel(86317, "工号"));
// 动态列
for (AttendQuoteFieldPO attendQuoteField : attendQuoteFields) {
header.add(attendQuoteField.getFieldName());
}
List<List<Object>> rows = new ArrayList<>();
rows.add(header);
// for (Map<String, Object> dto : listMaps) {
// List<Object> row = new ArrayList<>();
// row.add(dto.get("username"));
// row.add(dto.get("departmentName"));
// row.add(dto.get("mobile"));
// row.add(dto.get("jobNum"));
//
// // 动态列
// Map<String, Object> map = listMaps.get(0);
// for (AttendQuoteFieldPO attendQuoteField : attendQuoteFields) {
// row.add(map.containsKey(attendQuoteField.getId() + "_attendQuoteData") ? dto.get(attendQuoteField.getId() + "_attendQuoteData") : "");
// }
// rows.add(row);
// }
return ExcelUtil.genWorkbookV2(rows, sheetName);
} catch (Exception e) {
log.error("下载模板失败", e);
}
return null;
}
/**
* 导入的数据插入到数据库中
*/
public Map<String, Object> preview(AttendQuoteDataImportParam param) {
ValidUtil.doValidator(param);
Long salarySobId = param.getSalarySobId();
SalarySobPO salarySobPO = getSalarySobService(user).getById(salarySobId);
if (salarySobPO == null) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100537, "薪资账套不存在"));
}
String salaryYearMonth = param.getSalaryYearMonth();
if (!SalaryDateUtil.checkYearMonth(salaryYearMonth)) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100365, "薪资所属月格式有误,正确格式示例为'2021-01'"));
}
InputStream fileInputStream = null;
try {
fileInputStream = ImageFileManager.getInputStreamById(Integer.parseInt(param.getImageId()));
Sheet sheet = ExcelSupport.parseFile(fileInputStream, 0, EXCEL_TYPE_XLSX);
Map<String, Object> apidatas = new HashMap<String, Object>();
apidatas.put("headers", ExcelSupport.getSheetHeader(sheet, 0));
apidatas.put("list", ExcelParseHelper.parse2List(sheet, 1));
return apidatas;
} finally {
IOUtils.closeQuietly(fileInputStream);
}
}
/**
* 导入的数据插入到数据库中
*/
public Map<String, Object> importAttendQuoteData(AttendQuoteDataImportParam param) {
ValidUtil.doValidator(param);
Long salarySobId = param.getSalarySobId();
SalarySobPO salarySobPO = getSalarySobService(user).getById(salarySobId);
if (salarySobPO == null) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100537, "薪资账套不存在"));
}
String salaryYearMonth = param.getSalaryYearMonth();
if (!SalaryDateUtil.checkYearMonth(salaryYearMonth)) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100365, "薪资所属月格式有误,正确格式示例为'2021-01'"));
}
int year = Integer.parseInt(salaryYearMonth.split("-")[0]);
int month = Integer.parseInt(salaryYearMonth.split("-")[1]);
// 获取租户下所有的人员
List<DataCollectionEmployee> employees = employeeBiz.listEmployee();
// 获取已设置的可同步的考勤字段
List<AttendQuoteFieldPO> attendQuoteFields = getAttendQuoteSetFields(AttendQuoteSourceTypeEnum.IMPORT);
// 生成获取考勤引用
AttendQuotePO attendQuote = getAttendQuote(AttendQuoteSourceTypeEnum.IMPORT, salarySobId, year, month, StringUtils.EMPTY);
int total = 0;
int index = 0;
int successCount = 0;
int errorCount = 0;
// 待导入数据
List<AttendQuoteDataPO> pos = new ArrayList<>();
List<AttendQuoteDataValuePO> values = new ArrayList<>();
String valI18n = SalaryI18nUtil.getI18nLabel(100581, "请输入数字");
InputStream fileInputStream = null;
try {
fileInputStream = ImageFileManager.getInputStreamById(Integer.parseInt(param.getImageId()));
Sheet sheet = ExcelSupport.parseFile(fileInputStream, 0, EXCEL_TYPE_XLSX);
// 表头
List<String> headers = ExcelSupport.getSheetHeader(sheet, 0);
// 错误sheet数据
List<Map<String, Object>> errorData = new ArrayList<>();
// 错误提示
List<Map<String, String>> excelComments = new ArrayList<>();
//验证字段是否缺失
String isValidHeader = checkHeaders(headers, attendQuoteFields);
if (StringUtils.isNotBlank(isValidHeader)) {
Map<String, Object> apidatas = new HashMap<String, Object>();
apidatas.put("successCount", successCount);
apidatas.put("errorCount", errorCount);
Map<String, String> errorMessageMap = Maps.newHashMap();
errorMessageMap.put("message", isValidHeader);
excelComments.add(errorMessageMap);
apidatas.put("errorData", excelComments);
return apidatas;
}
// 处理数值
List<Map<String, Object>> data = ExcelParseHelper.parse2Map(sheet, 1);
total = data.size();
Map<String, Object> map;
Date now = new Date();
AttendQuoteDataPO po;
for (int i = 0; i < data.size(); i++) {
index += 1;
map = data.get(i);
po = new AttendQuoteDataPO();
po.setId(IdGenerator.generate());
po.setCreateTime(now);
po.setUpdateTime(now);
po.setCreator((long) user.getUID());
po.setTenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY);
// 考勤引用表的主键id
po.setAttendQuoteId(attendQuote.getId());
int errorSum = 0;
String userName = Optional.ofNullable(map.get(SalaryI18nUtil.getI18nLabel(85429, "姓名"))).orElse("").toString();
String deparmentName = Optional.ofNullable(map.get(SalaryI18nUtil.getI18nLabel(86185, "部门"))).orElse("").toString();
String mobile = Optional.ofNullable(map.get(SalaryI18nUtil.getI18nLabel(86186, "手机号"))).orElse("").toString();
List<Long> employeeSameIds = new ArrayList<>();
List<DataCollectionEmployee> emps = employees.stream().filter(e -> (StringUtils.isBlank(userName) || Objects.equals(e.getUsername(), userName))
&& (StringUtils.isBlank(deparmentName) || Objects.equals(e.getDepartmentName(), deparmentName))
&& (StringUtils.isBlank(mobile) || Objects.equals(e.getMobile(), mobile)))
.collect(Collectors.toList());
//含在职和离职,选在职数据
if (CollectionUtils.isNotEmpty(emps) && emps.size() > 1) {
employeeSameIds = emps.stream()
.filter(e -> UserStatusEnum.getNormalStatus().contains(e.getStatus()))
.map(DataCollectionEmployee::getEmployeeId)
.collect(Collectors.toList());
}
if (CollectionUtils.isNotEmpty(emps) && emps.size() == 1) {
employeeSameIds = emps.stream()
.map(DataCollectionEmployee::getEmployeeId)
.collect(Collectors.toList());
}
for (int j = 0; j < headers.size(); j++) {
String key = headers.get(j);
if (key == null) {
continue;
}
String cellVal = Optional.ofNullable(map.get(key.toString())).orElse("").toString();
if (SalaryI18nUtil.getI18nLabel(85429, "姓名").equals(key.toString())) {
if (StringUtils.isEmpty(cellVal)) {
Map<String, String> errorMessageMap = Maps.newHashMap();
errorMessageMap.put("message", SalaryI18nUtil.getI18nLabel(100579, "姓名不能为空"));
excelComments.add(errorMessageMap);
errorSum += 1;
} else if (CollectionUtils.isEmpty(employeeSameIds) || employeeSameIds.size() > 1) {
Map<String, String> errorMessageMap = Maps.newHashMap();
errorMessageMap.put("message", SalaryI18nUtil.getI18nLabel(100579, "员工信息不存在或者存在多个员工"));
excelComments.add(errorMessageMap);
errorSum += 1;
} else {
Long employeeId = CollectionUtils.isNotEmpty(employeeSameIds) && employeeSameIds.size() == 1 ? employeeSameIds.get(0) : null;
if (employeeId != null && employeeId > 0) {
po.setEmployeeId(employeeId);
} else {
Map<String, String> errorMessageMap = Maps.newHashMap();
errorMessageMap.put("message", SalaryI18nUtil.getI18nLabel(100579, "姓名错误,系统内不存在该姓名"));
excelComments.add(errorMessageMap);
errorSum += 1;
}
}
}
String bigDecimalValue;
for (AttendQuoteFieldPO attendQuoteField : attendQuoteFields) {
if (attendQuoteField.getFieldName().equals(key)) {
if (1 == attendQuoteField.getFieldType()) {
bigDecimalValue = bigDecimalVal(cellVal, excelComments, valI18n, errorCount + 1, j);
errorSum += StringUtils.isEmpty(bigDecimalValue) ? 1 : 0;
if (StringUtils.isNotEmpty(bigDecimalValue)) {
values.add(AttendQuoteDataValuePO.builder()
.createTime(now)
.updateTime(now)
.creator((long) user.getUID())
.tenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY)
.employeeId(po.getEmployeeId())
.attendQuoteId(attendQuote.getId())
.attendQuoteDataId(po.getId())
.attendQuoteFieldId(attendQuoteField.getId())
.dataValue(Utils.null2String(bigDecimalValue))
.build());
}
} else {
values.add(AttendQuoteDataValuePO.builder()
.createTime(now)
.updateTime(now)
.creator((long) user.getUID())
.tenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY)
.employeeId(po.getEmployeeId())
.attendQuoteId(attendQuote.getId())
.attendQuoteDataId(po.getId())
.attendQuoteFieldId(attendQuoteField.getId())
.dataValue(Utils.null2String(cellVal))
.build());
}
break;
}
}
}
if (errorSum > 0) {
errorCount += 1;
// 添加错误数据
errorData.add(map);
} else {
successCount += 1;
// 成功一条就添加一条记录
pos.add(po);
}
// 导入进度
// salaryBatchService.sendImportRate(message.getBizId(), total, index);
}
// 数据入库处理
handleDataToDB(attendQuote.getId(), pos, values);
// todo 记录日志
// recordLog(attendQuote, message.getUserId(), message.getTenantKey(), message.getClientIp());
Map<String, Object> apidatas = new HashMap<String, Object>();
apidatas.put("successCount", successCount);
apidatas.put("errorCount", errorCount);
apidatas.put("errorData", excelComments);
return apidatas;
} finally {
IOUtils.closeQuietly(fileInputStream);
}
}
/**
* 获取金额数字值
*
* @param bigDecimalValStr
* @param excelComments
* @param i
* @param j
* @return
*/
private String bigDecimalVal(String bigDecimalValStr, List<Map<String, String>> excelComments, String valI18n, int i, int j) {
if (StringUtils.isBlank(bigDecimalValStr)) {
return BigDecimal.ZERO.toString();
}
BigDecimal bigDecimalVal = null;
try {
bigDecimalVal = new BigDecimal(bigDecimalValStr);
} catch (Exception e) {
Map<String, String> errorMessageMap = Maps.newHashMap();
errorMessageMap.put("message", valI18n);
excelComments.add(errorMessageMap);
// salaryBatchService.createExcelComment(excelComments, valI18n, i, i, j, j);
}
return bigDecimalVal == null ? "" : bigDecimalVal.toString();
}
// /**
// * 记录日志
// * @param attendQuote
// * @param currentEmployeeId
// * @param currentTenantKey
// * @param clientIp
// */
// private void recordLog(AttendQuotePO attendQuote, Long currentEmployeeId, String currentTenantKey, String clientIp) {
// List<SalarySobPO> salarySobs = new LambdaQueryChainWrapper<>(getSalarySobMapper())
// .eq(SalarySobPO::getTenantKey, TenantContext.getCurrentTenantKey())
// .eq(SalarySobPO::getDeleteType, 0)
// .eq(SalarySobPO::getId, attendQuote.getSalarySobId())
// .list();
// String sourceType = AttendQuoteSourceTypeEnum.getDefaultLabelByValue(attendQuote.getSourceType(), currentEmployeeId, currentTenantKey);
//
// LoggerContext loggerContext = new LoggerContext();
// loggerContext.setTargetId(String.valueOf(attendQuote.getId()));
// loggerContext.setTargetName(SalaryDateUtil.getFormatYearMonth(attendQuote.getSalaryYearMonth())+" "+(CollectionUtils.isNotEmpty(salarySobs)?salarySobs.get(0).getName():""));
// loggerContext.setOperateType(OperateTypeEnum.ADD.getValue());
// loggerContext.setOperateTypeName(sourceType+SalaryI18nUtil.getI18nLabel(93931, "考勤数据"));
// loggerContext.setOperatedesc(sourceType+SalaryI18nUtil.getI18nLabel( 93931, "考勤数据"));
// loggerContext.setNewValues(attendQuote);
// loggerContext.setTenant_key(currentTenantKey);
// loggerContext.setOperator(currentEmployeeId.toString());
// if (StringUtils.isNotEmpty(clientIp)) {
// loggerContext.setClientIp(clientIp);
// }
// attendQuoteLoggerTemplate.write(loggerContext);
// }
/**
* 检查参数
*
* @param message
* @param params
* @return
*/
// private boolean checkParams(BatchDocumentMessage message, Map<String, Object> params) {
// boolean isValid = true;
// String errorMsg = "";
// if (params == null) {
// errorMsg = SalaryI18nUtil.getI18nLabel(message.getTenantKey(), message.getUserId(), 100582, "参数必传");
// } else {
// if (!params.containsKey("salaryYearMonth")
// || !params.containsKey("salarySobId")
// || params.get("salaryYearMonth") == null
// || params.get("salarySobId") == null) {
// errorMsg = SalaryI18nUtil.getI18nLabel(message.getTenantKey(), message.getUserId(), 100588, "薪资所属月和薪资账套必传");
// } else {
// String salaryYearMonth = params.get("salaryYearMonth").toString();
// if (!SalaryDateUtil.checkYearMonth(salaryYearMonth)) {
// errorMsg = SalaryI18nUtil.getI18nLabel(message.getTenantKey(), message.getUserId(), 100365, "薪资所属月格式有误,正确格式示例为'2021-01'");
// } else {
// List<SalarySobPO> salarySobs = new LambdaQueryChainWrapper<>(getSalarySobMapper())
// .eq(SalarySobPO::getTenantKey, message.getTenantKey())
// .eq(SalarySobPO::getDeleteType, 0)
// .eq(SalarySobPO::getId, Long.valueOf(params.get("salarySobId").toString()))
// .list();
// if (CollectionUtils.isEmpty(salarySobs)) {
// errorMsg = SalaryI18nUtil.getI18nLabel(message.getTenantKey(), message.getUserId(), 100537, "薪资账套不存在");
// }
// }
// }
// }
// // 有错误信息发送
// if (StringUtils.isNotEmpty(errorMsg)) {
// // 发送导入回调信息
// salaryBatchService.sendImportCallBackInfo(message, errorMsg);
// isValid = false;
// }
// return isValid;
// }
/**
* 检查列头
*
* @return
*/
private String checkHeaders(List<String> headerList, List<AttendQuoteFieldPO> attendQuoteFields) {
boolean isValid = true;
String userNameI18n = SalaryI18nUtil.getI18nLabel(85429, "姓名");
List<String> mustHeaders = attendQuoteFields.stream().map(AttendQuoteFieldPO::getFieldName).collect(Collectors.toList());
mustHeaders.add(userNameI18n);
// 缺少的必须列
List<String> lackHeaders = mustHeaders.stream().filter(item -> !headerList.contains(item)).collect(Collectors.toList());
String errorMsg = "";
String checkHeaderI18n = SalaryI18nUtil.getI18nLabel(101850, "缺少如下列,请检查:");
if (CollectionUtils.isEmpty(attendQuoteFields)) {
errorMsg = SalaryI18nUtil.getI18nLabel(101849, "考勤字段列缺失,请补充");
} else if (CollectionUtils.isNotEmpty(lackHeaders)) {
errorMsg = checkHeaderI18n + Joiner.on(",").join((Iterable<?>) lackHeaders);
}
return errorMsg;
}
}