package com.engine.salary.entity.salaryacct.bo; import cn.hutool.core.util.NumberUtil; import com.engine.kq.service.KQGroupService; import com.engine.salary.annotation.SalaryFormulaVar; import com.engine.salary.common.LocalDateRange; import com.engine.salary.constant.SalaryFormulaFieldConstant; import com.engine.salary.constant.SalaryItemConstant; import com.engine.salary.entity.datacollection.AddUpDeduction; import com.engine.salary.entity.datacollection.AddUpSituation; import com.engine.salary.entity.datacollection.DataCollectionEmployee; import com.engine.salary.entity.datacollection.dto.AttendQuoteDataDTO; import com.engine.salary.entity.datacollection.dto.AttendQuoteDataValueDTO; import com.engine.salary.entity.datacollection.dto.AttendQuoteFieldListDTO; import com.engine.salary.entity.datacollection.po.OtherDeductionPO; import com.engine.salary.entity.salaryacct.po.SalaryAcctEmployeePO; import com.engine.salary.entity.salaryacct.po.SalaryAcctResultPO; import com.engine.salary.entity.salaryarchive.dto.SalaryArchiveDataDTO; import com.engine.salary.entity.salaryarchive.dto.SalaryArchiveItemDataDTO; import com.engine.salary.entity.salaryarchive.dto.SalaryArchiveTaxAgentDataDTO; import com.engine.salary.entity.salaryitem.po.SalaryItemPO; import com.engine.salary.entity.salarysob.dto.SalarySobCycleDTO; import com.engine.salary.entity.salarysob.po.SalarySobAdjustRulePO; import com.engine.salary.enums.SalaryCycleTypeEnum; import com.engine.salary.enums.UserStatusEnum; import com.engine.salary.enums.salaryformula.SalaryFormulaReferenceEnum; import com.engine.salary.enums.salaryformula.SalarySQLReferenceEnum; import com.engine.salary.enums.salarysob.SalarySobAdjustRuleTypeEnum; import com.engine.salary.mapper.SQLMapper; import com.engine.salary.util.JsonUtil; import com.engine.salary.util.SalaryDateUtil; import com.engine.salary.util.SalaryEntityUtil; import com.engine.salary.util.db.MapperProxyFactory; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import lombok.Data; import lombok.experimental.Accessors; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.math.NumberUtils; import weaver.conn.RecordSet; import weaver.general.BaseBean; import weaver.general.Util; import weaver.hrm.User; import java.lang.reflect.Field; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.*; import java.util.stream.Collectors; import static com.engine.salary.util.SalaryDateUtil.DATE_TIME_FORMATTER_PATTERN; /** * 薪资核算-将数据转换成公式中的变量 *

Copyright: Copyright (c) 2022

*

Company: 泛微软件

* * @author qiantao * @version 1.0 **/ @Data @Accessors(chain = true) public class CalculateFormulaVarBO { BaseBean bb = new BaseBean(); String salaryDateFormat = bb.getPropValue("hrmSalaryCustom", "salaryDateFormat"); /** * 员工信息 */ private List simpleEmployees; /** * 薪资档案 */ private List salaryArchiveData; /** * 累计情况 */ private List addUpSituationPOS; /** * 累计专项附加扣除 */ private List addUpDeductionPOS; /** * 其他扣除 */ private List otherDeductionPOS; /** * 社保福利 */ private List> welfareData; /** * 考勤数据 */ private List attendQuoteDataDTOS; /** * 薪资核算结果(输入/导入的值) */ private List salaryAcctResultPOS; /** * 浮动薪资档案 */ private List> variableArchiveList; /** * 上月核算结果 */ List lastMonthResultPOS; public CalculateFormulaVarBO(List simpleEmployees, List salaryArchiveData, List addUpSituationPOS, List addUpDeductionPOS, List otherDeductionPOS, List> welfareData, List attendQuoteDataDTOS, List salaryAcctResultPOS, List> variableArchiveList, List lastMonthResultPOS) { this.simpleEmployees = simpleEmployees; this.salaryArchiveData = salaryArchiveData; this.addUpSituationPOS = addUpSituationPOS; this.addUpDeductionPOS = addUpDeductionPOS; this.otherDeductionPOS = otherDeductionPOS; this.welfareData = welfareData; this.attendQuoteDataDTOS = attendQuoteDataDTOS; this.salaryAcctResultPOS = salaryAcctResultPOS; this.variableArchiveList = variableArchiveList; this.lastMonthResultPOS = lastMonthResultPOS; } /** * 将查询到的数据转换成公式变量 * * @param salaryAcctCalculateBO 核算参数 * @return */ public Map> convert2FormulaVar(SalaryAcctCalculateBO salaryAcctCalculateBO, KQGroupService kqGroupService, Integer attendCycleType) { Map> resultMap = Maps.newHashMapWithExpectedSize(salaryAcctCalculateBO.getSalaryAcctEmployeePOS().size()); // 处理薪资核算结果 handleSalaryAcctResult(salaryAcctCalculateBO, resultMap); // 处理薪资档案 handleSalaryArchiveData(salaryAcctCalculateBO, resultMap, kqGroupService, attendCycleType); // 处理浮动薪资档案 handleVariableArchiveData(salaryAcctCalculateBO, resultMap); // 处理往期累计情况 handleAddUpSituation(resultMap); // 处理累计专项附加扣除 handleAddUpDeduction(resultMap); // 处理其他扣除 handleOtherDeduction(resultMap); // 处理社保福利 handleWelfareData(salaryAcctCalculateBO, resultMap); // 处理考勤数据 handleAttendQuoteData(salaryAcctCalculateBO, resultMap); //处理核算人员信息 handleSalaryAcctEmployee(salaryAcctCalculateBO, resultMap); //处理人员信息 handleSimpleEmployees(resultMap); //处理上月薪资核算结果 handleLastMonthResult(salaryAcctCalculateBO, resultMap); return resultMap; } /** * 处理核算日期相关信息 */ private List handleSalarySobCycleDTO(SalaryAcctCalculateBO salaryAcctCalculateBO) { SalarySobCycleDTO salarySobCycleDTO = salaryAcctCalculateBO.getSalarySobCycleDTO(); salarySobCycleDTO.setSalaryDate(SalaryDateUtil.toDate(salarySobCycleDTO.getSalaryMonth(), 1)); salarySobCycleDTO.setTaxDate(SalaryDateUtil.toDate(salarySobCycleDTO.getTaxCycle(), 1)); salarySobCycleDTO.setSocialSecurityDate(SalaryDateUtil.toDate(salarySobCycleDTO.getSocialSecurityCycle(), 1)); LocalDateRange salaryCycle = salarySobCycleDTO.getSalaryCycle(); salarySobCycleDTO.setSalaryCycleFromDate(salaryCycle.getFromDate()); salarySobCycleDTO.setSalaryCycleEndDate(salaryCycle.getEndDate()); LocalDateRange attendCycle = salarySobCycleDTO.getAttendCycle(); salarySobCycleDTO.setAttendCycleFromDate(attendCycle.getFromDate()); salarySobCycleDTO.setAttendCycleEndDate(attendCycle.getEndDate()); Map map = JsonUtil.parseMap(salarySobCycleDTO, String.class); List formulaVarValues = Lists.newArrayList(); Field[] declaredFields = SalarySobCycleDTO.class.getDeclaredFields(); for (Field declaredField : declaredFields) { if (declaredField.isAnnotationPresent(SalaryFormulaVar.class)) { String fieldName = declaredField.getName(); String fieldId = SalarySQLReferenceEnum.SALARY_CYCLE.getValue() + SalaryFormulaFieldConstant.FIELD_ID_SEPARATOR + fieldName; String fieldValue = map.getOrDefault(fieldName, StringUtils.EMPTY); //日期值取yyyy-MM-dd if (StringUtils.isNotBlank(fieldValue) && fieldValue.length() > 10 && SalaryDateUtil.parse(fieldValue, DATE_TIME_FORMATTER_PATTERN) != null) { fieldValue = fieldValue.substring(0, 10); } formulaVarValues.add(new FormulaVarValue().setFieldId(fieldId).setFieldValue(fieldValue)); } } return formulaVarValues; } /** * 处理薪资核算结果 * * @param salaryAcctCalculateBO 薪资核算参数 * @param resultMap 返回结果集 */ private void handleSalaryAcctResult(SalaryAcctCalculateBO salaryAcctCalculateBO, Map> resultMap) { // key:薪资项目的id、value:薪资项目的code Map salaryItemCodeMap = SalaryEntityUtil.convert2Map(salaryAcctCalculateBO.getSalaryItemPOS(), SalaryItemPO::getId, SalaryItemPO::getCode); // key:薪资项目的code、value:薪资项目的id Map salaryCodeItemMap = SalaryEntityUtil.convert2Map(salaryAcctCalculateBO.getSalaryItemPOS(), SalaryItemPO::getCode, SalaryItemPO::getId); // key:employeeId_taxAgentId、value:薪资核算结果集合 Map> salaryAcctResultMap = SalaryEntityUtil.group2Map(salaryAcctResultPOS, salaryAcctResultPO -> salaryAcctResultPO.getEmployeeId() + "_" + salaryAcctResultPO.getTaxAgentId()); // // List expressFormulas = salaryAcctCalculateBO.getExpressFormulas(); // 填充到返回结果集中 salaryAcctResultMap.forEach((key, salaryAcctResultPOS) -> { List formulaVarValues = resultMap.computeIfAbsent(key, k -> Lists.newArrayList()); formulaVarValues.addAll(salaryAcctResultPOS.stream() .map(salaryAcctResultPO -> { String fieldId = SalaryFormulaReferenceEnum.SALARY_ITEM.getValue() + SalaryFormulaFieldConstant.FIELD_ID_SEPARATOR + salaryItemCodeMap.getOrDefault(salaryAcctResultPO.getSalaryItemId(), StringUtils.EMPTY); return new FormulaVarValue().setFieldId(fieldId).setFieldValue(salaryAcctResultPO.getResultValue()); }) .collect(Collectors.toList())); Map salaryAcctResultPOMap = SalaryEntityUtil.convert2Map(salaryAcctResultPOS, SalaryAcctResultPO::getSalaryItemId); formulaVarValues.addAll(salaryAcctCalculateBO.getIssuedFieldIds().stream() .map(fieldId -> { String originResultValue = salaryAcctResultPOMap.getOrDefault( salaryCodeItemMap.get(fieldId), SalaryAcctResultPO.builder().originResultValue("").build()) .getOriginResultValue(); String fieldId2 = SalaryFormulaReferenceEnum.ISSUED.getValue() + SalaryFormulaFieldConstant.FIELD_ID_SEPARATOR + fieldId; return new FormulaVarValue().setFieldId(fieldId2).setFieldValue(originResultValue); }).collect(Collectors.toList())); }); } private void handleLastMonthResult(SalaryAcctCalculateBO salaryAcctCalculateBO, Map> resultMap) { // key:薪资项目的id、value:薪资项目的code Map salaryItemCodeMap = SalaryEntityUtil.convert2Map(salaryAcctCalculateBO.getSalaryItemPOS(), SalaryItemPO::getId, SalaryItemPO::getCode); // key:employeeId_taxAgentId、value:薪资核算结果集合 Map> salaryAcctResultMap = SalaryEntityUtil.group2Map(lastMonthResultPOS, salaryAcctResultPO -> salaryAcctResultPO.getEmployeeId() + "_" + salaryAcctResultPO.getTaxAgentId()); // 填充到返回结果集中 salaryAcctResultMap.forEach((key, salaryAcctResultPOS) -> { List formulaVarValues = resultMap.computeIfAbsent(key, k -> Lists.newArrayList()); formulaVarValues.addAll(salaryAcctResultPOS.stream() .map(salaryAcctResultPO -> { String fieldId = SalaryFormulaReferenceEnum.LAST_MONTH_CALC.getValue() + SalaryFormulaFieldConstant.FIELD_ID_SEPARATOR + salaryItemCodeMap.getOrDefault(salaryAcctResultPO.getSalaryItemId(), StringUtils.EMPTY); return new FormulaVarValue().setFieldId(fieldId).setFieldValue(salaryAcctResultPO.getResultValue()); }) .collect(Collectors.toList())); }); } /** * 处理薪资档案(会涉及调薪计薪规则)+处理核算日期 * * @param salaryAcctCalculateBO 薪资核算参数 * @param resultMap 返回结果集 */ private void handleSalaryArchiveData(SalaryAcctCalculateBO salaryAcctCalculateBO, Map> resultMap, KQGroupService kqGroupService,Integer attendCycleType) { // 调薪计薪规则 Map salarySobAdjustRulePOMap = SalaryEntityUtil.convert2Map(salaryAcctCalculateBO.getSalarySobAdjustRulePOS(), SalarySobAdjustRulePO::getSalaryItemId); boolean isSeasonSob = false; if (attendCycleType != null && (attendCycleType.equals(SalaryCycleTypeEnum.THIS_SEASON.getValue()) || attendCycleType.equals(SalaryCycleTypeEnum.LAST_SEASON.getValue()) )) { // 联特 是季度账套 isSeasonSob = true; } for (SalaryArchiveDataDTO salaryArchiveDataDTO : salaryArchiveData) { for (SalaryArchiveTaxAgentDataDTO salaryArchiveTaxAgentDataDTO : salaryArchiveDataDTO.getTaxAgents()) { String key = salaryArchiveDataDTO.getEmployeeId() + "_" + salaryArchiveTaxAgentDataDTO.getTaxAgentId(); List formulaVarValues = resultMap.computeIfAbsent(key, k -> Lists.newArrayList()); // 将薪资档案的值转换成公式中的变量,填充到返回结果集中 formulaVarValues.addAll(handleSalaryArchiveItemVal(salaryAcctCalculateBO, salaryArchiveTaxAgentDataDTO.getSalaryItemValues(), salarySobAdjustRulePOMap, kqGroupService, salaryArchiveDataDTO.getEmployeeId(), isSeasonSob)); } } } private void handleVariableArchiveData(SalaryAcctCalculateBO salaryAcctCalculateBO, Map> resultMap) { Map> variableArchiveMap = SalaryEntityUtil.convert2Map(variableArchiveList, map -> map.getOrDefault("taxAgentIds", "").toString() + "-" + map.getOrDefault("employeeId", "").toString()); // 填充到返回结果集中 for (SalaryAcctEmployeePO salaryAcctEmployeePO : salaryAcctCalculateBO.getSalaryAcctEmployeePOS()) { List formulaVarValues = resultMap.computeIfAbsent(salaryAcctEmployeePO.getEmployeeId() + "_" + salaryAcctEmployeePO.getTaxAgentId(), k -> Lists.newArrayList()); String key = salaryAcctEmployeePO.getTaxAgentId().toString() + "-" + salaryAcctEmployeePO.getEmployeeId().toString(); Map map = variableArchiveMap.getOrDefault(key, Collections.emptyMap()); formulaVarValues.addAll(salaryAcctCalculateBO.getVariableItems().stream().map(field -> { String fieldId = SalaryFormulaReferenceEnum.VARIABLE_ITEM.getValue() + SalaryFormulaFieldConstant.FIELD_ID_SEPARATOR + field.getCode(); String value = map.getOrDefault(field.getId() + SalaryItemConstant.VARIABLE_ITEM_DYNAMIC_SUFFIX, StringUtils.EMPTY) == null ? StringUtils.EMPTY : map.getOrDefault(field.getId() + SalaryItemConstant.VARIABLE_ITEM_DYNAMIC_SUFFIX, StringUtils.EMPTY).toString(); return new FormulaVarValue().setFieldId(fieldId).setFieldValue(value); }).collect(Collectors.toList())); } } /** * 根据调薪计薪规则处理薪资档案的调薪,转换成公式编辑器中的变量 * * @param salaryAcctCalculateBO * @param salaryArchiveItemDataList * @param salarySobAdjustRulePOMap * @return */ private List handleSalaryArchiveItemVal(SalaryAcctCalculateBO salaryAcctCalculateBO, List salaryArchiveItemDataList, Map salarySobAdjustRulePOMap, KQGroupService kqGroupService, Long employeeId, boolean isSeasonSob) { // 薪资周期 LocalDateRange salaryCycle = salaryAcctCalculateBO.getSalarySobCycleDTO().getSalaryCycle(); // key:薪资项目的id、value:薪资项目的code Map salaryItemCodeMap = SalaryEntityUtil.convert2Map(salaryAcctCalculateBO.getSalaryItemPOS(), SalaryItemPO::getId, SalaryItemPO::getCode); // 将薪资档案的调薪记录按照薪资项目id聚合(同一个薪资项目可能存在多次调薪,按照生效日期对调薪记录排序) Map> dataMap = salaryArchiveItemDataList.stream() .collect(Collectors.groupingBy(SalaryArchiveItemDataDTO::getSalaryItemId, Collectors.collectingAndThen(Collectors.toList(), salaryArchiveItemDataDTOS -> salaryArchiveItemDataDTOS.stream() .sorted(Comparator.comparing(salaryArchiveItemDataDTO -> salaryArchiveItemDataDTO.getEffectiveDateRange().getFromDate())) .collect(Collectors.toList())))); // 将薪资档案的值转换成公式编辑器中的变量 List formulaVarValues = Lists.newArrayListWithExpectedSize(dataMap.size()); for (Map.Entry> entry : dataMap.entrySet()) { String value; // 获取薪资项目的调薪规则 SalarySobAdjustRulePO salaryAdjustmentRulePO = salarySobAdjustRulePOMap.get(entry.getKey()); List valueList = entry.getValue(); if (CollectionUtils.isNotEmpty(valueList)) { String firstDateStr = SalaryDateUtil.getFormatLocalDate(valueList.get(0).getEffectiveDateRange().getFromDate()); String salaryCycleFirstStr = SalaryDateUtil.getFormatLocalDate(salaryCycle.getFromDate()); if (isSeasonSob) { salaryCycleFirstStr = SalaryDateUtil.getFormatLocalDate(salaryAcctCalculateBO.getSalarySobCycleDTO().getAttendCycleFromDate()); } if (!firstDateStr.equals(salaryCycleFirstStr)) { LocalDateRange dateRange = LocalDateRange.builder() .fromDate(isSeasonSob ? salaryAcctCalculateBO.getSalarySobCycleDTO().getAttendCycleFromDate() : salaryCycle.getFromDate()) .endDate(valueList.get(0).getEffectiveDateRange().getFromDate()).build(); SalaryArchiveItemDataDTO zeroDTO = SalaryArchiveItemDataDTO.builder().effectiveDateRange(dateRange).salaryItemId(valueList.get(0).getSalaryItemId()).value("0").build(); valueList.add(0, zeroDTO); } } if (entry.getValue().size() > 2) { // 如果薪资项目在薪资周期内经历了多次调薪,则默认分段计薪 value = calculateBySalarySobAdjustRule(salaryCycle, SalarySobAdjustRuleTypeEnum.PARTITION, entry.getValue(), kqGroupService, employeeId, isSeasonSob); } else if (salaryAdjustmentRulePO == null || entry.getValue().size() < 2) { // 如果薪资项目没有设置调薪计薪规则,默认取薪资周期内薪资档案中最新的值 // 如果薪资项目在薪资周期内没有调薪,默认取薪资周期内薪资档案中最新的值 value = calculateBySalarySobAdjustRule(salaryCycle, SalarySobAdjustRuleTypeEnum.USE_AFTER_ADJUSTMENT, entry.getValue(), kqGroupService, employeeId, isSeasonSob); } else { // 如果薪资项目在薪资周期内只有一次调薪,则根据调薪计薪规则处理 SalarySobAdjustRuleTypeEnum adjustRuleTypeEnum = salaryAdjustmentRulePO.getDayOfMonth() < SalaryDateUtil.dateToLocalDate(entry.getValue().get(0).getEffectiveDateRange().getEndDate()).getDayOfMonth() ? SalarySobAdjustRuleTypeEnum.parseByValue(salaryAdjustmentRulePO.getAfterAdjustmentType()) : SalarySobAdjustRuleTypeEnum.parseByValue(salaryAdjustmentRulePO.getBeforeAdjustmentType()); // 根据调薪计薪规则处理薪资档案的调薪 value = calculateBySalarySobAdjustRule(salaryCycle, adjustRuleTypeEnum, entry.getValue(), kqGroupService, employeeId, isSeasonSob); } String fieldId = SalaryFormulaReferenceEnum.SALARY_ARCHIVES.getValue() + SalaryFormulaFieldConstant.FIELD_ID_SEPARATOR + salaryItemCodeMap.getOrDefault(entry.getKey(), StringUtils.EMPTY); formulaVarValues.add(new FormulaVarValue().setFieldId(fieldId).setFieldValue(value)); } return formulaVarValues; } /** * 根据调薪计薪规则计算调薪后的值 * * @param adjustRuleTypeEnum * @param salaryArchiveItemDataDTOS * @return */ private String calculateBySalarySobAdjustRule(LocalDateRange salaryCycle, SalarySobAdjustRuleTypeEnum adjustRuleTypeEnum, List salaryArchiveItemDataDTOS, KQGroupService kqGroupService, Long employeeId, boolean isSeasonSob) { if (Objects.isNull(adjustRuleTypeEnum)) { return StringUtils.EMPTY; } String value; switch (adjustRuleTypeEnum) { case AVERAGE: // 可能存在多次调薪 // = (第一段的值+第二段的值+……)/n value = String.valueOf(salaryArchiveItemDataDTOS.stream() .mapToDouble(salaryArchiveItemDataDTO -> SalaryEntityUtil.empty2Zero(salaryArchiveItemDataDTO.getValue()).doubleValue()) .average().orElse(NumberUtils.DOUBLE_ZERO)); break; case PARTITION: // 可能存在多次调薪 // = (第一段的值*第一段的自然日+第二段的值*第二段的自然日+……)/薪资所属月自然日 // BigDecimal valueSum = BigDecimal.ZERO; BigDecimal firstValue = BigDecimal.ZERO; BigDecimal baseValue = new BigDecimal("21.75"); if (isSeasonSob) { baseValue = baseValue.multiply(new BigDecimal(3)); } // 调薪补差金额 BigDecimal needAddValue = new BigDecimal(0); if (CollectionUtils.isNotEmpty(salaryArchiveItemDataDTOS)) { firstValue = SalaryEntityUtil.empty2Zero(salaryArchiveItemDataDTOS.get(0).getValue()); } BaseBean baseBean = new BaseBean(); baseBean.writeLog("ltsize"+salaryArchiveItemDataDTOS.size()); for (int i = 1; i < salaryArchiveItemDataDTOS.size(); i++) { // 联特二开:调薪前工资+(调薪后工资-调薪前工资)/21.75*(调薪后的应出勤天数+调薪后的法定节假日天数) SalaryArchiveItemDataDTO dataDTO = salaryArchiveItemDataDTOS.get(i); // 获取应出勤日期+法定节假日 Double ycq = new Double(0); String fdjjr = "0"; if (Objects.equals(i, salaryArchiveItemDataDTOS.size() - 1)) { ycq = getKQYcq(dataDTO.getEffectiveDateRange().getFromDate(), dataDTO.getEffectiveDateRange().getEndDate(), employeeId); fdjjr = getFdjjr(SalaryDateUtil.getFormatDate(dataDTO.getEffectiveDateRange().getFromDate()), SalaryDateUtil.getFormatDate(dataDTO.getEffectiveDateRange().getEndDate()), employeeId.toString(), kqGroupService); } else { // 不是最后一个,需要往前挪1天 Date endDate = SalaryDateUtil.localDateToDate(SalaryDateUtil.dateToLocalDate(dataDTO.getEffectiveDateRange().getEndDate()).minusDays(1)); ycq = getKQYcq(dataDTO.getEffectiveDateRange().getFromDate(), endDate, employeeId); fdjjr = getFdjjr(SalaryDateUtil.getFormatDate(dataDTO.getEffectiveDateRange().getFromDate()), SalaryDateUtil.getFormatDate(endDate), employeeId.toString(), kqGroupService); } baseBean.writeLog("lt-ycq" +ycq); double days = ycq + (NumberUtils.isCreatable(fdjjr) ? Double.valueOf(fdjjr) : 0); needAddValue = needAddValue.add(SalaryEntityUtil.empty2Zero(dataDTO.getValue()).subtract(firstValue).divide(baseValue, 15, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(days))); // // BigDecimal dayDiff = new BigDecimal(SalaryDateUtil.dateToLocalDate(dataDTO.getEffectiveDateRange().getFromDate()).until(SalaryDateUtil.dateToLocalDate(dataDTO.getEffectiveDateRange().getEndDate()), ChronoUnit.DAYS)); // // 最后一段日期范围需要加一 // if (Objects.equals(i, salaryArchiveItemDataDTOS.size() - 1)) { // dayDiff = dayDiff.add(BigDecimal.ONE); // } // valueSum = valueSum.add(SalaryEntityUtil.empty2Zero(dataDTO.getValue()).multiply(dayDiff)); } // value = valueSum.divide(new BigDecimal(SalaryDateUtil.dateToLocalDate(salaryCycle.getFromDate()).until(SalaryDateUtil.dateToLocalDate(salaryCycle.getEndDate()), ChronoUnit.DAYS)).add(BigDecimal.ONE), 2, RoundingMode.HALF_UP).toPlainString(); baseBean.writeLog("lt-ycq" +needAddValue); value = firstValue.add(needAddValue).toPlainString(); break; case USE_BEFORE_ADJUSTMENT: // = 调薪前工资 value = salaryArchiveItemDataDTOS.get(0).getValue(); break; case USE_AFTER_ADJUSTMENT: // = 调薪后工资 value = salaryArchiveItemDataDTOS.get(salaryArchiveItemDataDTOS.size() - 1).getValue(); break; default: value = "0"; break; } return value; } private SQLMapper getSQLMapper() { return MapperProxyFactory.getProxy(SQLMapper.class); } /** * 获取应出勤时数 * @param fromDate * @param endDate * @param userId */ private Double getKQYcq(Date fromDate, Date endDate, Long userId) { BaseBean baseBean = new BaseBean(); double ycq = 0.00; try { String sql = "SELECT sum(workdays) as a,sum(attendancemins) FROM kq_format_total WHERE workdays is not null and resourceid = "+userId+" and kqdate >= '" +SalaryDateUtil.getFormatDate(fromDate)+"' and kqdate <= '"+ SalaryDateUtil.getFormatDate(endDate)+"'"; baseBean.writeLog("lt-1" + sql); List list = getSQLMapper().runSQL(sql); baseBean.writeLog("lt-list" +list); if (CollectionUtils.isNotEmpty(list) && list.get(0) != null) { Object value = list.get(0).get("a"); if (value != null) { baseBean.writeLog("lt-value" +value); ycq = NumberUtils.isCreatable(value.toString()) ? Double.valueOf(value.toString()) : Double.valueOf("0"); } } } catch (Exception e) { baseBean.writeLog("获取应出勤时数出错" + e.getMessage()); return 0.00; } return ycq; } /** * 获取法定节假日天数 */ public String getFdjjr(String fromDate, String toDate, String userId, KQGroupService kqGroupService) { BaseBean baseBean = new BaseBean(); if (StringUtils.isEmpty(userId) || StringUtils.isEmpty(fromDate) || StringUtils.isEmpty(toDate)) { baseBean.writeLog("userId or fromDate or toDate is null!" + fromDate + toDate + userId); return "0"; } try { Map params = new HashMap<>(); params.put("viewScope", 3); params.put("resourceId", userId); params.put("groupType", 0); params.put("pageSize", 10); params.put("pageIndex", 1); User tmpUser = new User(); tmpUser.setUid(1); tmpUser.setLoginid("sysadmin"); //获取当前人员的生效考勤组 String activeGroupId = null; List> dataSource = null; Map groupInfo = kqGroupService.getGroupMemberList(params, tmpUser); if (groupInfo != null && groupInfo.size() > 0) { if (groupInfo.get("dataSource") != null) { dataSource = (List>) groupInfo.get("dataSource"); if (dataSource != null && dataSource.size() > 0) { Map dataMap = dataSource.get(0); activeGroupId = dataMap.get("activeGroupId") + ""; } } } if (activeGroupId == null && activeGroupId.length() > 0) { baseBean.writeLog("activeGroupId is null:" + params + dataSource); return "0"; } // 计算公共假期 RecordSet rs = new RecordSet(); String sql ="select count(1) from kq_HolidaySet where changeType =1 and holidayDate>= '"+ fromDate + "' and holidayDate<= '"+toDate+"' and groupId = "+ activeGroupId; rs.execute(sql); int jq =0; if(rs.next()){ jq = rs.getInt(1); } if(jq == -1) { jq = 0; } return String.valueOf(jq); } catch (Exception e) { baseBean.writeLog("获取法定节假日天数错误"+e.getMessage()); return "0"; } } /** * 处理累计情况(工资、薪金) * * @param resultMap 返回结果集 */ private void handleAddUpSituation(Map> resultMap) { // key:employeeId_taxAgentId、value:累计情况(工资、薪金)的数据 Map addUpSituationPOMap = SalaryEntityUtil.convert2Map(addUpSituationPOS, addUpSituationPO -> addUpSituationPO.getEmployeeId() + "_" + addUpSituationPO.getTaxAgentId()); // 累计情况(工资、薪金)可选字段 List fieldNames = Lists.newArrayList(); Field[] declaredFields = AddUpSituation.class.getDeclaredFields(); for (Field declaredField : declaredFields) { if (declaredField.isAnnotationPresent(SalaryFormulaVar.class)) { fieldNames.add(declaredField.getName()); } } // 填充到返回结果集中 addUpSituationPOMap.forEach((key, addUpSituationPO) -> { List formulaVarValues = resultMap.computeIfAbsent(key, k -> Lists.newArrayList()); Map map = JsonUtil.parseMap(addUpSituationPO, String.class); formulaVarValues.addAll(fieldNames.stream().map(fieldName -> { String fieldId = SalaryFormulaReferenceEnum.ADD_UP_SITUATION.getValue() + SalaryFormulaFieldConstant.FIELD_ID_SEPARATOR + fieldName; return new FormulaVarValue().setFieldId(fieldId).setFieldValue(map.getOrDefault(fieldName, StringUtils.EMPTY)); }).collect(Collectors.toList())); }); } /** * 处理累计专项附加扣除 * * @param resultMap 返回结果集 */ private void handleAddUpDeduction(Map> resultMap) { // key:employeeId_taxAgentId、value:累计专项附加扣除的数据 Map addUpDeductionPOMap = SalaryEntityUtil.convert2Map(addUpDeductionPOS, addUpDeductionPO -> addUpDeductionPO.getEmployeeId() + "_" + addUpDeductionPO.getTaxAgentId()); // 累计专项附加扣除可选字段 List fieldNames = Lists.newArrayList(); Field[] declaredFields = AddUpDeduction.class.getDeclaredFields(); for (Field declaredField : declaredFields) { if (declaredField.isAnnotationPresent(SalaryFormulaVar.class)) { fieldNames.add(declaredField.getName()); } } // 填充到返回结果集中 addUpDeductionPOMap.forEach((key, addUpDeductionPO) -> { List formulaVarValues = resultMap.computeIfAbsent(key, k -> Lists.newArrayList()); Map map = JsonUtil.parseMap(addUpDeductionPO, String.class); formulaVarValues.addAll(fieldNames.stream().map(fieldName -> { String fieldId = SalaryFormulaReferenceEnum.ADD_UP_DEDUCTIONS.getValue() + SalaryFormulaFieldConstant.FIELD_ID_SEPARATOR + fieldName; return new FormulaVarValue().setFieldId(fieldId).setFieldValue(map.getOrDefault(fieldName, StringUtils.EMPTY)); }).collect(Collectors.toList())); }); } /** * 处理其他扣除 * * @param resultMap 返回结果集 */ private void handleOtherDeduction(Map> resultMap) { // key:employeeId_taxAgentId、value:累计专项附加扣除的数据 Map otherDeductionPOMap = SalaryEntityUtil.convert2Map(otherDeductionPOS, otherDeductionPO -> otherDeductionPO.getEmployeeId() + "_" + otherDeductionPO.getTaxAgentId()); // 累计专项附加扣除可选字段 List fieldNames = Lists.newArrayList(); Field[] declaredFields = OtherDeductionPO.class.getDeclaredFields(); for (Field declaredField : declaredFields) { if (declaredField.isAnnotationPresent(SalaryFormulaVar.class)) { fieldNames.add(declaredField.getName()); } } // 填充到返回结果集中 otherDeductionPOMap.forEach((key, otherDeductionPO) -> { List formulaVarValues = resultMap.computeIfAbsent(key, k -> Lists.newArrayList()); Map map = JsonUtil.parseMap(otherDeductionPO, String.class); formulaVarValues.addAll(fieldNames.stream().map(fieldName -> { String fieldId = SalaryFormulaReferenceEnum.OTHER_DEDUCTION.getValue() + SalaryFormulaFieldConstant.FIELD_ID_SEPARATOR + fieldName; return new FormulaVarValue().setFieldId(fieldId).setFieldValue(map.getOrDefault(fieldName, StringUtils.EMPTY)); }).collect(Collectors.toList())); }); } /** * 处理社保福利数据 * * @param resultMap 返回结果集 */ private void handleWelfareData(SalaryAcctCalculateBO salaryAcctCalculateBO, Map> resultMap) { // 社保福利可选字段 List fieldNames = Lists.newArrayList(salaryAcctCalculateBO.getWelfareColumns().values()); // 社保福利数据 Map> tempMap = new HashMap<>(); welfareData.forEach(map -> { String key = map.getOrDefault("employeeId", StringUtils.EMPTY) + "_" + map.getOrDefault("taxAgentId", StringUtils.EMPTY); List formulaVarValues = tempMap.computeIfAbsent(key, k -> Lists.newArrayList()); formulaVarValues.addAll(fieldNames.stream().map(fieldName -> { String fieldId = SalaryFormulaReferenceEnum.WELFARE.getValue() + SalaryFormulaFieldConstant.FIELD_ID_SEPARATOR + fieldName; return new FormulaVarValue().setFieldId(fieldId).setFieldValue(String.valueOf(map.getOrDefault(fieldName, StringUtils.EMPTY))); }).collect(Collectors.toList())); }); // 填充到返回结果集中 for (SalaryAcctEmployeePO salaryAcctEmployeePO : salaryAcctCalculateBO.getSalaryAcctEmployeePOS()) { List formulaVarValues = resultMap.computeIfAbsent(salaryAcctEmployeePO.getEmployeeId() + "_" + salaryAcctEmployeePO.getTaxAgentId(), k -> Lists.newArrayList()); formulaVarValues.addAll(tempMap.getOrDefault(salaryAcctEmployeePO.getEmployeeId() + "_" + salaryAcctEmployeePO.getTaxAgentId(), Collections.emptyList())); } } /** * 处理考勤引用数据 * * @param salaryAcctCalculateBO * @param resultMap */ private void handleAttendQuoteData(SalaryAcctCalculateBO salaryAcctCalculateBO, Map> resultMap) { // 考勤引用可选字段 Set fieldNames = SalaryEntityUtil.properties(salaryAcctCalculateBO.getAttendQuoteFieldListDTOS(), AttendQuoteFieldListDTO::getId); // 考勤引用数据 Map> tempMap = Maps.newHashMapWithExpectedSize(attendQuoteDataDTOS.size()); attendQuoteDataDTOS.forEach(attendQuoteDataDTO -> { Map attendQuoteDataValueMap = SalaryEntityUtil.convert2Map(attendQuoteDataDTO.getDataValues(), AttendQuoteDataValueDTO::getAttendQuoteFieldId, AttendQuoteDataValueDTO::getDataValue); Long key = attendQuoteDataDTO.getEmployeeId(); List formulaVarValues = tempMap.computeIfAbsent(key, k -> Lists.newArrayList()); formulaVarValues.addAll(fieldNames.stream().map(fieldName -> { String fieldId = SalaryFormulaReferenceEnum.ATTEND.getValue() + SalaryFormulaFieldConstant.FIELD_ID_SEPARATOR + fieldName; return new FormulaVarValue().setFieldId(fieldId).setFieldValue(attendQuoteDataValueMap.getOrDefault(fieldName, StringUtils.EMPTY)); }).collect(Collectors.toList())); }); // 填充到返回结果集中 for (SalaryAcctEmployeePO salaryAcctEmployeePO : salaryAcctCalculateBO.getSalaryAcctEmployeePOS()) { List formulaVarValues = resultMap.computeIfAbsent(salaryAcctEmployeePO.getEmployeeId() + "_" + salaryAcctEmployeePO.getTaxAgentId(), k -> Lists.newArrayList()); formulaVarValues.addAll(tempMap.getOrDefault(salaryAcctEmployeePO.getEmployeeId(), Collections.emptyList())); } } /** * 处理核算人员信息 * * @param salaryAcctCalculateBO * @param resultMap */ private void handleSalaryAcctEmployee(SalaryAcctCalculateBO salaryAcctCalculateBO, Map> resultMap) { List salaryAcctEmployeePOS = salaryAcctCalculateBO.getSalaryAcctEmployeePOS(); // key:employeeId_taxAgentId、value:核算人员信息 Map salaryAcctEmployeeMap = SalaryEntityUtil.convert2Map(salaryAcctEmployeePOS, po -> po.getEmployeeId() + "_" + po.getTaxAgentId()); // 核算人员信息可选字段 List fieldNames = Lists.newArrayList(); Field[] declaredFields = SalaryAcctEmployeePO.class.getDeclaredFields(); for (Field declaredField : declaredFields) { if (declaredField.isAnnotationPresent(SalaryFormulaVar.class)) { fieldNames.add(declaredField.getName()); } } // 填充到返回结果集中 salaryAcctEmployeeMap.forEach((key, po) -> { List formulaVarValues = resultMap.computeIfAbsent(key, k -> Lists.newArrayList()); Map map = JsonUtil.parseMap(po, String.class); formulaVarValues.addAll(fieldNames.stream().map(fieldName -> { String fieldId = SalarySQLReferenceEnum.SALARY_ACCT_EMPLOYEE.getValue() + SalaryFormulaFieldConstant.FIELD_ID_SEPARATOR + fieldName; String fieldValue = map.getOrDefault(fieldName, StringUtils.EMPTY); //判断是否是日期,日期值取yyyy-MM-dd if (StringUtils.isNotBlank(fieldValue) && fieldValue.length() > 10 && SalaryDateUtil.parse(fieldValue, DATE_TIME_FORMATTER_PATTERN) != null) { fieldValue = fieldValue.substring(0, 10); } return new FormulaVarValue().setFieldId(fieldId).setFieldValue(fieldValue); }).collect(Collectors.toList())); //将薪资周期转换成公式中的变量,填充到返回结果集中 formulaVarValues.addAll(handleSalarySobCycleDTO(salaryAcctCalculateBO)); }); } /** * 处理员工基本信息 * * @param resultMap */ private void handleSimpleEmployees(Map> resultMap) { // key:employeeId_taxAgentId、value:员工信息 Map employeeMap = SalaryEntityUtil.convert2Map(simpleEmployees, po -> po.getEmployeeId() + ""); // 核算人员信息可选字段 List fieldNames = Lists.newArrayList(); Field[] declaredFields = DataCollectionEmployee.class.getDeclaredFields(); for (Field declaredField : declaredFields) { if (declaredField.isAnnotationPresent(SalaryFormulaVar.class)) { fieldNames.add(declaredField.getName()); } } // 填充到返回结果集中 employeeMap.forEach((key, po) -> { // 获取po的状态 if (po.getStatus() != null && NumberUtil.isNumber(po.getStatus())) { po.setStatusName(UserStatusEnum.getDefaultLabelByValue(new Integer(Util.null2s(po.getStatus(), "1")))); } List formulaVarValues = resultMap.computeIfAbsent(key, k -> Lists.newArrayList()); Map map = JsonUtil.parseMap(po, String.class); formulaVarValues.addAll(fieldNames.stream().map(fieldName -> { String fieldId = SalarySQLReferenceEnum.EMPLOYEE_INFO.getValue() + SalaryFormulaFieldConstant.FIELD_ID_SEPARATOR + fieldName; return new FormulaVarValue().setFieldId(fieldId).setFieldValue(map.getOrDefault(fieldName, StringUtils.EMPTY)); }).collect(Collectors.toList())); }); } @Data @Accessors(chain = true) public static class FormulaVarValue { /** * 公式变量id */ private String fieldId; /** * 公式变量的值 */ private String fieldValue; } }