From 9c0c6e7f4f5eb267e576fae33e5332a712c1e4e2 Mon Sep 17 00:00:00 2001 From: Harryxzy Date: Thu, 3 Jul 2025 13:57:54 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BE=8E=E4=B9=8B=E9=AB=98=E6=A0=B8=E7=AE=97?= =?UTF-8?q?=E5=AE=A1=E6=89=B9=E6=B5=81=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../salaryacct/bo/SalaryAcctResultBO.java | 1 + .../impl/SalaryAcctExcelServiceImpl.java | 12 +++- .../impl/SalaryAcctResultServiceImpl.java | 59 +++++++++++++++++-- .../salary/util/excel/ExcelUtilPlus.java | 9 ++- .../salary/web/SalarySobController.java | 15 +++++ .../salary/wrapper/SalaryApprovalWrapper.java | 52 ++++++++++++++-- 6 files changed, 136 insertions(+), 12 deletions(-) diff --git a/src/com/engine/salary/entity/salaryacct/bo/SalaryAcctResultBO.java b/src/com/engine/salary/entity/salaryacct/bo/SalaryAcctResultBO.java index b906a6a37..8a24008cd 100644 --- a/src/com/engine/salary/entity/salaryacct/bo/SalaryAcctResultBO.java +++ b/src/com/engine/salary/entity/salaryacct/bo/SalaryAcctResultBO.java @@ -335,6 +335,7 @@ public class SalaryAcctResultBO { // 个税扣缴义务人 String taxAgentName = taxAgentNameMap.getOrDefault(e.getTaxAgentId(), StringUtils.EMPTY); map.put("taxAgentName", taxAgentName); + map.put("taxAgentId", e.getTaxAgentId()); // 是否属于"合并计税"的标记 map.put("consolidatedTaxation", StringUtils.isNotEmpty(taxAgentName) && consolidatedTaxSalaryAcctEmpIds.contains(e.getId())); // 个税扣缴义务人的字段类型 diff --git a/src/com/engine/salary/service/impl/SalaryAcctExcelServiceImpl.java b/src/com/engine/salary/service/impl/SalaryAcctExcelServiceImpl.java index 67aff3ecd..00347662f 100644 --- a/src/com/engine/salary/service/impl/SalaryAcctExcelServiceImpl.java +++ b/src/com/engine/salary/service/impl/SalaryAcctExcelServiceImpl.java @@ -420,10 +420,16 @@ public class SalaryAcctExcelServiceImpl extends Service implements SalaryAcctExc String DATA_TYPE_SUFFIX = "_type"; List> rows = new ArrayList<>(); rows.add(headerList); - for (Map map : resultMapList) { + List redIndex = new ArrayList<>(); + for (int i =0; i < resultMapList.size(); i++) { + Map map = resultMapList.get(i); List row = Lists.newArrayListWithExpectedSize(headerColumnGroup.size()); - for (WeaTableColumnGroup weaTableColumn : headerColumnGroup) { + for (int j =0; j < headerColumnGroup.size(); j++) { + WeaTableColumnGroup weaTableColumn = headerColumnGroup.get(j); String fieldType = (String) map.getOrDefault(weaTableColumn.getColumn().toString() + DATA_TYPE_SUFFIX, StringUtils.EMPTY); + if (map.get(weaTableColumn.getColumn().toString() + "_color") != null) { + redIndex.add((i+1) + ":" + j); + } if (StringUtils.equals("number", fieldType) && map.get(weaTableColumn.getColumn()) != null && NumberUtil.isNumber(map.get(weaTableColumn.getColumn()).toString())) { row.add(new BigDecimal(StringUtils.isBlank(map.get(weaTableColumn.getColumn()).toString()) ? "0" : map.get(weaTableColumn.getColumn()).toString())); } else { @@ -448,7 +454,7 @@ public class SalaryAcctExcelServiceImpl extends Service implements SalaryAcctExc String sheetName = "薪资核算结果"; // return ExcelUtil.genWorkbookV2(rows, sheetName, total); - return ExcelUtilPlus.genWorkbookWithChildTitleColumnWithExcelFormat(rows, sheetName, total); + return ExcelUtilPlus.genWorkbookWithChildTitleColumnWithExcelFormat(rows, sheetName, total, redIndex); } diff --git a/src/com/engine/salary/service/impl/SalaryAcctResultServiceImpl.java b/src/com/engine/salary/service/impl/SalaryAcctResultServiceImpl.java index 41f1317e1..c45a9c0ef 100644 --- a/src/com/engine/salary/service/impl/SalaryAcctResultServiceImpl.java +++ b/src/com/engine/salary/service/impl/SalaryAcctResultServiceImpl.java @@ -364,7 +364,7 @@ public class SalaryAcctResultServiceImpl extends Service implements SalaryAcctRe // 查询薪资核算结果 - List> data = listBySalaryAcctEmployees(page.getList(), queryParam); + List> data = listBySalaryAcctEmployees(page.getList(), queryParam, true); // 薪资核算结果的分页结果 PageInfo> resultPage = new PageInfo<>(); resultPage.setList(data); @@ -439,7 +439,7 @@ public class SalaryAcctResultServiceImpl extends Service implements SalaryAcctRe // 查询薪资核算人员 List salaryAcctEmployeePOS = getSalaryAcctEmployeeService(user).listByResultQueryParam(queryParam); // 查询薪资核算结果 - return listBySalaryAcctEmployees(salaryAcctEmployeePOS, queryParam); + return listBySalaryAcctEmployees(salaryAcctEmployeePOS, queryParam,true); } /** @@ -449,7 +449,7 @@ public class SalaryAcctResultServiceImpl extends Service implements SalaryAcctRe * @param queryParam 列表查询条件 * @return */ - private List> listBySalaryAcctEmployees(List salaryAcctEmployeePOS, SalaryAcctResultQueryParam queryParam) { + private List> listBySalaryAcctEmployees(List salaryAcctEmployeePOS, SalaryAcctResultQueryParam queryParam, boolean compareWithLastMonth) { if (CollectionUtils.isEmpty(salaryAcctEmployeePOS)) { return Collections.emptyList(); } @@ -523,8 +523,59 @@ public class SalaryAcctResultServiceImpl extends Service implements SalaryAcctRe return expressFormulaMap.getOrDefault(salarySobBackItemPO.getFormulaId(), StringUtils.EMPTY); }); + if (CollectionUtils.isNotEmpty(queryParam.getSalaryItemIds())) { + salaryItemPOS = salaryItemPOS.stream().filter(salaryItemPO -> queryParam.getSalaryItemIds().contains(salaryItemPO.getId())).collect(Collectors.toList()); + } + List> result = SalaryAcctResultBO.buildTableData(salaryItemPOS, salarySobEmpFieldPOS, simpleEmployees, salaryAcctEmployeePOS, salaryAcctResultPOS, taxAgentPOS, salaryAcctEmployeeIds4ConsolidatedTax, customParameters, customBackCalcParameters, queryParam.isDynamicEmpInfo()); + + + if (compareWithLastMonth) { + // 获取需要对比的薪资项目id + BaseBean baseBean = new BaseBean(); + List needCompareItemIds = Arrays.stream(baseBean.getPropValue("mzgSalaryReport", "need_compare_salary_item_ids").split(",")) + .filter(NumberUtils::isCreatable) + .map(Long::valueOf) + .collect(Collectors.toList()); + + // 获取这些员工上月薪资核算结果 + Date lastMonthDate = SalaryDateUtil.localDateToDate(SalaryDateUtil.dateToLocalDate(salaryAcctRecordPO.getSalaryMonth()).minusMonths(1)); + LocalDateRange dateRange = LocalDateRange.builder().fromDate(lastMonthDate).endDate(lastMonthDate).build(); + List salaryAcctRecordPOS = getSalaryAcctRecordService(user).listBySalarySobIdsAndSalaryMonth(Collections.singletonList(salaryAcctRecordPO.getSalarySobId()), dateRange); + if (CollectionUtils.isNotEmpty(salaryAcctRecordPOS)) { + SalaryAcctRecordPO lastMonthSalaryAcctRecordPO = salaryAcctRecordPOS.get(0); + // 获取上月薪资核算人员 + List lastMonthAcctEmpList = getSalaryAcctEmployeeService(user).listBySalaryAcctRecordIdAndEmployeeIds(lastMonthSalaryAcctRecordPO.getId(), employeeIds); + List salaryAcctEmpIds = SalaryEntityUtil.properties(lastMonthAcctEmpList, SalaryAcctEmployeePO::getId, Collectors.toList()); + + // 获取上月薪资核算结果 + List lastMonthAcctResultList = listByAcctEmployeeIdsAndSalaryItemIds(salaryAcctEmpIds, needCompareItemIds); + Map> lastMonthResultMap = SalaryEntityUtil.group2Map(lastMonthAcctResultList, r -> r.getTaxAgentId() + "_" + r.getEmployeeId()); + for (Map map : result) { + String taxAgentId = Utils.null2String(map.get("taxAgentId")); + String employeeId = Utils.null2String(map.get("employeeId")); + List lastMonthResult = lastMonthResultMap.get(taxAgentId + "_" + employeeId); + lastMonthResult = lastMonthResult == null ? Collections.emptyList() : lastMonthResult; + Map lastMonthMap = SalaryEntityUtil.convert2Map(lastMonthResult, po -> po.getSalaryItemId().toString(), SalaryAcctResultPO::getResultValue); + for (Long compareItem : needCompareItemIds) { + String thisValue = Utils.null2String(map.get(compareItem.toString())); + String lastValue = Utils.null2String(lastMonthMap.get(compareItem.toString())); + if (map.containsKey(compareItem.toString()) && !thisValue.equals(lastValue)) { + map.put(compareItem + "_color", "red"); + } + } + } + } else { + for (Map map : result) { + for (Long compareItem : needCompareItemIds) { + if (map.containsKey(compareItem.toString())) { + map.put(compareItem + "_color", "red"); + } + } + } + } + } // 转换成薪资核算结果列表 - return SalaryAcctResultBO.buildTableData(salaryItemPOS, salarySobEmpFieldPOS, simpleEmployees, salaryAcctEmployeePOS, salaryAcctResultPOS, taxAgentPOS, salaryAcctEmployeeIds4ConsolidatedTax, customParameters, customBackCalcParameters, queryParam.isDynamicEmpInfo()); + return result; } diff --git a/src/com/engine/salary/util/excel/ExcelUtilPlus.java b/src/com/engine/salary/util/excel/ExcelUtilPlus.java index 9da402ce7..d347568a8 100644 --- a/src/com/engine/salary/util/excel/ExcelUtilPlus.java +++ b/src/com/engine/salary/util/excel/ExcelUtilPlus.java @@ -502,7 +502,7 @@ public class ExcelUtilPlus { } // 数值项目修改excel单元格格式为数值 - public static XSSFWorkbook genWorkbookWithChildTitleColumnWithExcelFormat(List> rowList, String sheetName, boolean lastRowRed) { + public static XSSFWorkbook genWorkbookWithChildTitleColumnWithExcelFormat(List> rowList, String sheetName, boolean lastRowRed, List redIndex) { XSSFWorkbook workbook = new XSSFWorkbook(); // 设置title样式 @@ -672,6 +672,10 @@ public class ExcelUtilPlus { cell.setCellStyle(cellStyle); } } + + if (redIndex.contains(rowIndex + ":" + cellIndex)) { + cell.setCellStyle(redCellStyle); + } Object o = infoList.get(cellIndex); if (o instanceof String) { cell.setCellType(CellType.STRING); @@ -682,6 +686,9 @@ public class ExcelUtilPlus { } else { cell.setCellStyle(numberCellStyleMap.get(patternList.get(cellIndex))); } + if (redIndex.contains(rowIndex + ":" + cellIndex)) { + cell.setCellStyle(numberRedCellStyleMap.get(patternList.get(cellIndex))); + } cell.setCellType(CellType.NUMERIC); double value = o == null ? 0 : ((BigDecimal) o).doubleValue(); cell.setCellValue(value); diff --git a/src/com/engine/salary/web/SalarySobController.java b/src/com/engine/salary/web/SalarySobController.java index 50da5a073..ee4a98ac7 100644 --- a/src/com/engine/salary/web/SalarySobController.java +++ b/src/com/engine/salary/web/SalarySobController.java @@ -658,6 +658,21 @@ public class SalarySobController { return new ResponseResult>(user).run(getSalaryApprovalWrapper(user)::listSalaryApprovalAcctResult, param); } + /** + * 美之高获取审批时薪资核算结果 + * @param request + * @param response + * @param param + * @return + */ + @POST + @Path("/salaryApproval/acctresult/list4detail") + @Produces(MediaType.APPLICATION_JSON) + public String listSalaryApprovalAcctResult4Detail(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody SalaryAcctResultQueryParam param) { + User user = HrmUserVarify.getUser(request, response); + return new ResponseResult>(user).run(getSalaryApprovalWrapper(user)::listSalaryApprovalAcctResult4Detail, param); + } + /** * 美之高 - 统计需要渲染到流程字段中的值 * @param request diff --git a/src/com/engine/salary/wrapper/SalaryApprovalWrapper.java b/src/com/engine/salary/wrapper/SalaryApprovalWrapper.java index edd5a5526..513f68452 100644 --- a/src/com/engine/salary/wrapper/SalaryApprovalWrapper.java +++ b/src/com/engine/salary/wrapper/SalaryApprovalWrapper.java @@ -26,12 +26,12 @@ import com.engine.salary.util.page.SalaryPageUtil; import com.engine.salary.util.valid.ValidUtil; import com.google.common.collect.Lists; import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.math.NumberUtils; +import weaver.general.BaseBean; import weaver.hrm.User; +import weaver.wechat.util.Utils; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; +import java.util.*; import java.util.stream.Collectors; /** @@ -161,6 +161,50 @@ public class SalaryApprovalWrapper extends Service { return datas; } + + public Map listSalaryApprovalAcctResult4Detail(SalaryAcctResultQueryParam queryParam) { + ValidUtil.doValidator(queryParam); + // 获取需要赋值的列和的薪资项目信息 + BaseBean baseBean = new BaseBean(); + List columnList = Arrays.stream(baseBean.getPropValue("mzgSalaryReport", "need_rendering_columns").split(",")).collect(Collectors.toList()); + Map columnItemMap = new HashMap<>(); + for (String col : columnList) { + String itemIdStr = baseBean.getPropValue("mzgSalaryReport", col + "_detail_item_id"); + Long itemId = NumberUtils.isCreatable(itemIdStr) ? Long.valueOf(itemIdStr) : 0L; + columnItemMap.put(col, itemId); + } + queryParam.setSalaryItemIds(columnItemMap.values()); + + // 查询薪资核算记录 + SalaryAcctRecordPO salaryAcctRecordPO = getSalaryAcctRecordService(user).getById(queryParam.getSalaryAcctRecordId()); + if (Objects.isNull(salaryAcctRecordPO)) { + throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98747, "薪资核算记录不存在或已被删除")); + } + + // 查询薪资核算结果(分页) + List> acctResultList = getSalaryAcctResultService(user).listByParam(queryParam); + List> resultList = new ArrayList<>(); + for (Map map : acctResultList) { + Map resultMap = new HashMap<>(); + for (String col : columnList) { + Long itemId = columnItemMap.get(col); + String value = Utils.null2String(map.get(itemId == null ? "" : itemId.toString())); + resultMap.put(col, value); + Object color = map.get(itemId == null ? "" : itemId.toString()+"_color"); + if (color != null) { + resultMap.put(col+"_color", color); + } + } + resultList.add(resultMap); + } + + Map datas = new HashMap<>(); + datas.put("result", resultList); + datas.put("columns", columnItemMap.keySet()); + + return datas; + } + /** * 保存审批流程id * @param saveParam