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

450 lines
20 KiB
Java

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.SalaryStatisticsReportPO;
import com.engine.salary.report.service.SalaryStatisticsDimensionService;
import com.engine.salary.report.service.SalaryStatisticsItemService;
import com.engine.salary.report.service.SalaryStatisticsReportService;
import com.engine.salary.report.service.SubTableExportService;
import com.engine.salary.report.service.impl.SalaryStatisticsDimensionServiceImpl;
import com.engine.salary.report.service.impl.SalaryStatisticsItemServiceImpl;
import com.engine.salary.report.service.impl.SalaryStatisticsReportServiceImpl;
import com.engine.salary.report.service.impl.SubTableExportServiceImpl;
import com.engine.salary.service.SalaryAcctEmployeeService;
import com.engine.salary.service.SalaryAcctResultService;
import com.engine.salary.service.SalaryCacheService;
import com.engine.salary.service.SalaryItemService;
import com.engine.salary.service.impl.SalaryAcctEmployeeServiceImpl;
import com.engine.salary.service.impl.SalaryAcctResultServiceImpl;
import com.engine.salary.service.impl.SalaryCacheServiceImpl;
import com.engine.salary.service.impl.SalaryItemServiceImpl;
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.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);
}
/**
* 报表列表
*
* @param queryParam
* @return
*/
public List<Map<String, Object>> list(SalaryStatisticsReportQueryParam queryParam) {
// 初始化
getSalaryStatisticsDimensionService(user).init((long) user.getUID());
List<SalaryStatisticsReportPO> reportList = getSalaryStatisticsReportService(user).list();
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<>();
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());
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
* @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, "统计维度不存在"));
}
// weaTable对象
Map<String, Object> weaTable = new HashMap<>();
// 查询报表配置
SalaryStatisticsReportPO po = this.getSalaryStatisticsReportService(user).getById(id);
if (po == null) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(161845, "薪酬统计报表不存在"));
}
// 参数转换
SalaryStatisticsReportBO.poToQueryParam(param, po);
String paramMd5 = SecureUtil.md5(param.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);
}
}
// 查询自定义统计项目
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());
// 列表columns
List<WeaTableColumnGroup> weaTableColumns = SalaryStatisticsReportBO.buildReportColumns(dimension.getDimName(), 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, "统计维度不存在"));
}
// 参数转换
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.getDimName(), 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, "统计维度不存在"));
}
// 查询自定义统计项目中所有薪资项目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;
}
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;
}
}