weaver-hrm-salary/src/com/engine/salary/report/wrapper/SalaryStatisticsReportWrapp...

521 lines
24 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.report.wrapper;
import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSONArray;
import com.cloudstore.eccom.pc.table.WeaTable;
import com.cloudstore.eccom.pc.table.WeaTableColumn;
import com.cloudstore.eccom.result.WeaResultMsg;
import com.engine.common.util.ServiceUtil;
import com.engine.core.impl.Service;
import com.engine.salary.cache.SalaryCacheKey;
import com.engine.salary.component.WeaFormOption;
import com.engine.salary.component.WeaTableColumnGroup;
import com.engine.salary.entity.salaryitem.po.SalaryItemPO;
import com.engine.salary.exception.SalaryRunTimeException;
import com.engine.salary.report.common.constant.SalaryConstant;
import com.engine.salary.report.entity.bo.SalaryStatisticsReportBO;
import com.engine.salary.report.entity.param.*;
import com.engine.salary.report.entity.po.SalaryStatisticsDimensionPO;
import com.engine.salary.report.entity.po.SalaryStatisticsItemPO;
import com.engine.salary.report.entity.po.SalaryStatisticsPushPO;
import com.engine.salary.report.entity.po.SalaryStatisticsReportPO;
import com.engine.salary.report.service.*;
import com.engine.salary.report.service.impl.*;
import com.engine.salary.service.*;
import com.engine.salary.service.impl.*;
import com.engine.salary.util.*;
import com.engine.salary.util.excel.ExcelUtilPlus;
import com.engine.salary.util.page.PageInfo;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import weaver.general.PageIdConst;
import weaver.hrm.User;
import weaver.wechat.util.Utils;
import java.util.*;
import java.util.stream.Collectors;
/**
* 薪酬统计维度
* <p>Copyright: Copyright (c) 2022</p>
* <p>Company: 泛微软件</p>
*
* @author qiantao
* @version 1.0
**/
public class SalaryStatisticsReportWrapper extends Service {
private static final String conditionId = "salaryStatisticsReportSearchCondition";
private SalaryStatisticsReportService getSalaryStatisticsReportService(User user) {
return ServiceUtil.getService(SalaryStatisticsReportServiceImpl.class, user);
}
private SalaryStatisticsItemService getSalaryStatisticsItemService(User user) {
return ServiceUtil.getService(SalaryStatisticsItemServiceImpl.class, user);
}
private SalaryStatisticsDimensionService getSalaryStatisticsDimensionService(User user) {
return ServiceUtil.getService(SalaryStatisticsDimensionServiceImpl.class, user);
}
private SubTableExportService getSubTableExportService(User user) {
return ServiceUtil.getService(SubTableExportServiceImpl.class, user);
}
private SalaryAcctEmployeeService getSalaryAcctEmployeeService(User user) {
return ServiceUtil.getService(SalaryAcctEmployeeServiceImpl.class, user);
}
private SalaryAcctResultService getSalaryAcctResultService(User user) {
return ServiceUtil.getService(SalaryAcctResultServiceImpl.class, user);
}
private SalaryItemService getSalaryItemService(User user) {
return ServiceUtil.getService(SalaryItemServiceImpl.class, user);
}
private SalaryCacheService getSalaryCacheService(User user) {
return ServiceUtil.getService(SalaryCacheServiceImpl.class, user);
}
private SalaryStatisticsPushService getSalaryStatisticsPushService(User user) {
return ServiceUtil.getService(SalaryStatisticsPushServiceImpl.class, user);
}
private SalaryStatisticsPushDetailService getSalaryStatisticsPushDetailService(User user) {
return ServiceUtil.getService(SalaryStatisticsPushDetailServiceImpl.class, user);
}
private TaxAgentService getTaxAgentService(User user) {
return ServiceUtil.getService(TaxAgentServiceImpl.class, user);
}
/**
* 报表列表
*
* @param queryParam
* @return
*/
public List<Map<String, Object>> list(SalaryStatisticsReportQueryParam queryParam) {
Long uid = Long.valueOf(user.getUID());
// 初始化
getSalaryStatisticsDimensionService(user).init(uid);
// 所有人能够看到自己创建的报表,薪酬总管理员能够查看所有报表
List<SalaryStatisticsReportPO> reportList = getSalaryStatisticsReportService(user).listByCreator(uid);
List<Long> reportIds = reportList.stream().map(SalaryStatisticsReportPO::getId).collect(Collectors.toList());
// 获取所有没有撤回没有过期的报表ID不包含过期失效的
List<SalaryStatisticsPushPO> pushList = getSalaryStatisticsPushService(user).getSuccessPushListByReceiver(uid);
List<Long> sharedReportIds = pushList.stream().map(po -> Arrays.asList(StringUtils.split(po.getReportIds(), ",")))
.flatMap(Collection::stream).distinct().map(Long::valueOf).collect(Collectors.toList());
sharedReportIds = sharedReportIds.stream().filter(id -> !reportIds.contains(id)).collect(Collectors.toList());
reportList.addAll(getSalaryStatisticsReportService(user).getByIds(sharedReportIds));
if (StringUtils.isNotEmpty(queryParam.getReportName())) {
reportList = reportList.stream().filter(rp -> rp.getReportName().contains(queryParam.getReportName())).collect(Collectors.toList());
}
List<SalaryStatisticsDimensionPO> salaryStatisticsDimensionList = this.getSalaryStatisticsDimensionService(user).listAll();
Map<String, String> salaryStatisticsDimensionMap = SalaryEntityUtil.convert2Map(salaryStatisticsDimensionList, k -> k.getId().toString(), SalaryStatisticsDimensionPO::getDimName);
List<Map<String, Object>> result = new ArrayList<>();
List<Long> finalSharedReportIds = sharedReportIds;
reportList.forEach(po -> {
Map<String, Object> temp = new HashMap<>();
temp.put("id", po.getId().toString());
temp.put("reportName", po.getReportName());
List<String> dimNames = Arrays.stream(po.getDimension().split(",")).map(dim -> Optional.ofNullable(salaryStatisticsDimensionMap.get(dim)).orElse("")).collect(Collectors.toList());
temp.put("dimension", StringUtils.join(dimNames, ","));
temp.put("dimensionId", po.getDimension());
temp.put("isShare", finalSharedReportIds.contains(po.getId()));
result.add(temp);
});
return result;
}
/**
* 获取薪酬统计报表表单
*
* @param id
* @param
* @return
*/
public Map<String, Object> getFrom(Long id) {
List<SalaryStatisticsDimensionPO> salaryStatisticsDimensions = getSalaryStatisticsDimensionService(user).listAll();
List<WeaFormOption> statsDimOptions = salaryStatisticsDimensions.stream().map(sd -> new WeaFormOption(sd.getId().toString(), sd.getDimName())).collect(Collectors.toList());
// 获取默认维度统计
List<SalaryStatisticsDimensionPO> defaultSalaryStatisticsDimensions = getSalaryStatisticsDimensionService(user).listAllDefaultDimension();
List<Long> defaultDimensionIds = defaultSalaryStatisticsDimensions.stream().map(SalaryStatisticsDimensionPO::getId).collect(Collectors.toList());
// 获取有薪资统计报表引用的统计维度
Set<String> haveUsedDimIds = new HashSet<>();
List<SalaryStatisticsReportPO> salaryStatisticsReports = getSalaryStatisticsReportService(user).listAll();
salaryStatisticsReports.stream().forEach(report -> Collections.addAll(haveUsedDimIds, report.getDimension().split(",")));
statsDimOptions.stream().forEach(option -> {
if (defaultDimensionIds.contains(Long.valueOf(option.getId()))) {
// 默认维度不允许修改、删除
option.setCanDelete(false);
option.setCanEdit(false);
} else if (haveUsedDimIds.contains(option.getId())) {
// 被薪资统计报表引用的不能删除
option.setCanEdit(true);
option.setCanDelete(false);
}
});
// 1.构建基础信息表单
Map<String, Object> weaForm = new HashMap<>();
weaForm.put("statsDimOptions", statsDimOptions);
if (id != null) {
SalaryStatisticsReportPO po = this.getSalaryStatisticsReportService(user).getById(id);
if (po == null) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(161845, "薪酬统计报表不存在"));
}
Map<String, Object> dataMap = JsonUtil.parseMap(po, Object.class);
dataMap.put("dimension", Arrays.asList(po.getDimension().split(",")));
weaForm.put("data", dataMap);
}
return weaForm;
}
/**
* 保存薪酬统计报表
*
* @param saveParam
* @param
* @return
*/
public String save(SalaryStatisticsReportSaveParam saveParam) {
return getSalaryStatisticsReportService(user).save(saveParam);
}
/**
* 删除薪酬统计报表
*
* @param ids
* @param
* @return
*/
public Map<String, Object> delete(Collection<Long> ids) {
return getSalaryStatisticsReportService(user).delete(ids);
}
/**
* 复制薪资账套
* @param id
*/
public void duplicate(Long id) {
if (id == null) {
throw new SalaryRunTimeException("id为空");
}
getSalaryStatisticsReportService(user).duplicate(id);
}
/**
* 获取统计条件
*
* @param id
* @return
*/
public Map<String, Object> getSearchCondition(Long id) {
// 高级搜索实例
Map<String, Object> map = new HashMap<>();
if (id != null) {
SalaryStatisticsReportPO po = getSalaryStatisticsReportService(user).getById(id);
SalaryAssert.notNull(po, SalaryI18nUtil.getI18nLabel(152563, "报表不存在"));
Map<String, Object> data = new HashMap<>();
data.put("salaryStartMonth", SalaryDateUtil.getFormatYearMonth(po.getSalaryStartMonth()));
data.put("salaryEndMonth", SalaryDateUtil.getFormatYearMonth(po.getSalaryEndMonth()));
data.put("taxAgent", JSONArray.parseArray(po.getTaxAgentSetting()));
data.put("incomeCategory", JSONArray.parseArray(po.getIncomeCategorySetting()));
data.put("subCompany", JSONArray.parseArray(po.getSubCompanySetting()));
data.put("department", JSONArray.parseArray(po.getDepartSetting()));
data.put("grade", JSONArray.parseArray(po.getGradeSetting()));
data.put("position", JSONArray.parseArray(po.getPositionSetting()));
data.put("status", JSONArray.parseArray(po.getStatusSetting()));
data.put("employee", JSONArray.parseArray(po.getEmployeeSetting()));
data.put("hiredate", JSONArray.parseArray(po.getHiredateSetting()));
// data.put("leavedate", JSONArray.parseArray(po.getLeavedateSetting()));
map.put("data", data);
}
return map;
}
public String saveSearchCondition(SalaryStatisticsSearchConditionSaveParam param) {
return this.getSalaryStatisticsReportService(user).saveSearchCondition(param);
}
/**
* 获取报表数据
*
* @param param
* @return
*/
public Map<String, Object> getData(SalaryStatisticsReportDataQueryParam param) {
Long id = param.getId();
if (id == null || param.getDimensionId() == null) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(84026, "参数错误"));
}
SalaryStatisticsDimensionPO dimension = getSalaryStatisticsDimensionService(user).getById(param.getDimensionId());
if (dimension == null) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(161300, "统计维度不存在"));
}
// 查询报表配置
SalaryStatisticsReportPO po = this.getSalaryStatisticsReportService(user).getById(id);
if (po == null) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(161845, "薪酬统计报表不存在"));
}
if (param.isShare()) {
// 是被分享的报表
Long uid = Long.valueOf(user.getUID());
// 校验查看权限,获取有效的分享记录
List<SalaryStatisticsPushPO> pushList = getSalaryStatisticsPushService(user).shareReportValid(param.getId(), uid);
List<Long> batchIds = pushList.stream().map(SalaryStatisticsPushPO::getId).collect(Collectors.toList());
getSalaryStatisticsPushService(user).updateReportViewStatus(batchIds, uid);
// salaryStatisticsPushService.sendViewedMsg(param.getBatchId(), param.getId(), employeeId, tenantKey);
// 如果是被分享的报表校验分享权限通过后将user赋值为报表创建人
User creator = new User();
creator.setUid(po.getCreator().intValue());
user = creator;
} else {
// 判断报表是否是登陆人创建的,或薪酬总管理员
Boolean needAuth = getTaxAgentService(user).isNeedAuth((long) user.getUID());
if (needAuth && NumberUtils.compare(po.getCreator().intValue(), user.getUID()) != 0) {
throw new SalaryRunTimeException("无权限查看该报表!");
}
}
// weaTable对象
Map<String, Object> weaTable = new HashMap<>();
// 查询自定义统计项目
List<SalaryStatisticsItemPO> salaryStatisticsItemList = this.getSalaryStatisticsItemService(user).listByStatisticsReportId(po.getId());
// 参数转换
SalaryStatisticsReportBO.poToQueryParam(param, po);
String paramMd5 = SecureUtil.md5(param + salaryStatisticsItemList.toString());
//已缓存的报表id
String salaryReportIds = Utils.null2String(getSalaryCacheService(user).get(SalaryCacheKey.SALARY_REPORT_IDS));
String salaryReportConditions = "";
if (StringUtils.isNotBlank(salaryReportIds) && salaryReportIds.contains(id + "")) {
//报表中缓存的条件
salaryReportConditions = Utils.null2String(getSalaryCacheService(user).get(SalaryCacheKey.SALARY_REPORT_CONDITIONS + id));
if (StringUtils.isNotBlank(salaryReportConditions) && salaryReportConditions.contains(paramMd5)) {
return getSalaryCacheService(user).get(SalaryCacheKey.SALARY_REPORT_DATA + paramMd5);
}
}
// 列表data
PageInfo<Map<String, Object>> page = this.getSalaryStatisticsReportService(user).buildReportRecords(dimension, param, salaryStatisticsItemList);
// 组装合计
Map<String, Object> countResultMap = SalaryStatisticsReportBO.buildTotal(page, salaryStatisticsItemList, (long) user.getUID());
// 列表columns
List<WeaTableColumnGroup> weaTableColumns = SalaryStatisticsReportBO.buildReportColumns(dimension, salaryStatisticsItemList);
Map<String, Object> resultMap = Maps.newHashMap();
resultMap.putAll(JsonUtil.parseMap(weaTable, Object.class));
resultMap.put("columns", weaTableColumns);
resultMap.put("pageInfo", page);
resultMap.put("countResult", countResultMap);
resultMap.put("reportId", id);
getSalaryCacheService(user).set(SalaryCacheKey.SALARY_REPORT_IDS, salaryReportIds + "," + id);
getSalaryCacheService(user).set(SalaryCacheKey.SALARY_REPORT_CONDITIONS + id, salaryReportConditions + "," + paramMd5);
getSalaryCacheService(user).set(SalaryCacheKey.SALARY_REPORT_DATA + paramMd5, resultMap);
return resultMap;
}
/**
* 导出报表数据
*
* @param param
* @return
*/
public Map<String, Object> exportData(SalaryStatisticsReportDataQueryParam param) {
if (param.getId() == null || param.getDimensionId() == null) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(84026, "参数错误"));
}
SalaryStatisticsReportPO po = this.getSalaryStatisticsReportService(user).getById(param.getId());
if (po == null) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(161845, "薪酬统计报表不存在"));
}
SalaryStatisticsDimensionPO dimension = getSalaryStatisticsDimensionService(user).getById(param.getDimensionId());
if (dimension == null) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(161300, "统计维度不存在"));
}
sharedReportCheck(param.isShare(), po);
// 参数转换
SalaryStatisticsReportBO.poToQueryParam(param, po);
// 查询自定义统计项目
List<SalaryStatisticsItemPO> salaryStatisticsItemList = this.getSalaryStatisticsItemService(user).listByStatisticsReportId(po.getId());
// 列表data
PageInfo<Map<String, Object>> page = this.getSalaryStatisticsReportService(user).buildReportRecords(dimension, param, salaryStatisticsItemList);
// 组装合计
Map<String, Object> countResultMap = SalaryStatisticsReportBO.buildTotal(page, salaryStatisticsItemList, (long) user.getUID());
List<Map<String, Object>> list = page.getList();
if (CollectionUtils.isNotEmpty(list) && MapUtils.isNotEmpty(countResultMap)) {
list.add(countResultMap);
}
// 获取数据
List<Map<String, String>> records = list.stream().map(m -> m.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue() + StringUtils.EMPTY))).collect(Collectors.toList());
// 获取列头
List<WeaTableColumnGroup> weaTableColumns = SalaryStatisticsReportBO.buildReportColumns(dimension, salaryStatisticsItemList);
// 组装导出参数
// ExportCommonParam exportParam = SalaryStatisticsReportBO.buildExportParam(dimension.getDimName(), weaTableColumns, records);
// exportParam.setSheetName(SalaryI18nUtil.getI18nLabel(179263, "薪酬统计报表") + "-" + exportParam.getDimensionName());
//
List rows = new ArrayList<>();
rows.add(weaTableColumns);
List<String> head = new ArrayList<>();
weaTableColumns.forEach(weaTableColumn -> {
String column = weaTableColumn.getColumn();
if (CollectionUtils.isEmpty(weaTableColumn.getChildren())) {
head.add(column);
} else {
weaTableColumn.getChildren().forEach(children -> {
head.add(children.getColumn());
});
}
});
for (Map<String, String> map : records) {
List<Object> row = Lists.newArrayListWithExpectedSize(records.size());
head.forEach(k -> {
row.add(map.getOrDefault(k, StringUtils.EMPTY));
});
rows.add(row);
}
String sheetName = SalaryI18nUtil.getI18nLabel(179263, "薪酬统计报表") + "-" + dimension.getDimName();
XSSFWorkbook book = ExcelUtilPlus.genWorkbookWithChildTitleColumn(rows, sheetName, true);
Map<String, Object> map = new HashMap<>();
map.put("workbook", book);
map.put("fileName", sheetName);
return map;
}
/**
* 获取报表透视数据
*
* @param param
* @return
*/
public Map<String, Object> getDataPerspective(SalaryStatisticsDataPerspectiveQueryParam param) {
if (param.getId() == null || param.getDimensionId() == null) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(84026, "参数错误"));
}
SalaryStatisticsReportPO po = this.getSalaryStatisticsReportService(user).getById(param.getId());
if (po == null) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(161845, "薪酬统计报表不存在"));
}
SalaryStatisticsDimensionPO dimension = getSalaryStatisticsDimensionService(user).getById(param.getDimensionId());
if (dimension == null) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(161300, "统计维度不存在"));
}
// 校验报表权限如果是被分享报表修改User
sharedReportCheck(param.isShare(), po);
// 查询自定义统计项目中所有薪资项目id
List<SalaryStatisticsItemPO> salaryStatisticsItemPOS = getSalaryStatisticsItemService(user).listByStatisticsReportId(param.getId());
List<Long> salaryItemIds = salaryStatisticsItemPOS.stream().filter(item -> StringUtils.isNotBlank(item.getItemValue())).map(p -> p.getItemValue().split(","))
.flatMap(Arrays::stream).map(Long::valueOf).collect(Collectors.toList());
PageInfo<Map<String, Object>> pageInfo = getSalaryStatisticsReportService(user).buildDataPerspectiveRecords(param, po, dimension, salaryStatisticsItemPOS);
List<SalaryItemPO> itemList = getSalaryItemService(user).listByIds(salaryItemIds);
// 列表columns
List<WeaTableColumn> weaTableColumns = buildDataPerspectiveTableColumns(itemList);
WeaTable table = new WeaTable();
String pageId = "a4f85an7-9576-4125-adn9-7d06e7sy69f2";
table.setPageID(pageId);
table.setPageUID(pageId + user.getUID());
table.setPagesize(PageIdConst.getPageSize(pageId, user.getUID()));
table.setBackfields("");
table.setColumns(weaTableColumns);
WeaResultMsg result = new WeaResultMsg(false);
result.putAll(table.makeDataResult());
result.success();
// 结果
Map<String, Object> resultMap = Maps.newHashMap();
resultMap.put("dataKey", result.getResultMap());
resultMap.put("pageInfo", pageInfo);
return resultMap;
}
/**
* 权限校验
*
* @param isShared 是否是被分享的报表
* @param po 报表po
*/
private void sharedReportCheck(boolean isShared, SalaryStatisticsReportPO po) {
if (isShared) {
// 是被分享的报表
Long uid = Long.valueOf(user.getUID());
// 校验分享查看权限
getSalaryStatisticsPushService(user).shareReportValid(po.getId(), uid);
// 如果是被分享的报表校验分享权限通过后将user赋值为报表创建人
User creator = new User();
creator.setUid(po.getCreator().intValue());
user = creator;
} else {
// 判断报表是否是登陆人创建的,或薪酬总管理员
Boolean needAuth = getTaxAgentService(user).isNeedAuth((long) user.getUID());
if (needAuth && NumberUtils.compare(po.getCreator().intValue(), user.getUID()) != 0) {
throw new SalaryRunTimeException("无权限查看该报表!");
}
}
}
private List<WeaTableColumn> buildDataPerspectiveTableColumns(List<SalaryItemPO> salaryItems) {
// 表格表头
List<WeaTableColumn> columns = new ArrayList<>();
columns.add(new WeaTableColumn("100px", SalaryI18nUtil.getI18nLabel(87614, "姓名"), "userName"));
columns.add(new WeaTableColumn("100px", SalaryI18nUtil.getI18nLabel(87614, "部门"), "departmentName"));
columns.add(new WeaTableColumn("100px", SalaryI18nUtil.getI18nLabel(87614, "薪资所属月"), "salaryMonth"));
columns.add(new WeaTableColumn("100px", SalaryI18nUtil.getI18nLabel(86184, "个税扣缴义务人"), "taxAgent"));
columns.add(new WeaTableColumn("100px", SalaryI18nUtil.getI18nLabel(86184, "账套"), "salarySob"));
// columns.add(new WeaTableColumn("100px", SalaryI18nUtil.getI18nLabel(86184, "次数"), "acctTimes").setDisplay(WeaBoolAttr.FALSE));
salaryItems.forEach(item -> {
columns.add(new WeaTableColumn("100px", item.getName(), item.getId() + SalaryConstant.DYNAMIC_SUFFIX));
});
return columns;
}
}