//package com.engine.salary.entity.salaryacct.bo; // //import com.google.common.collect.Lists; //import com.google.common.collect.Maps; //import com.weaver.framework.util.JsonUtil; //import com.weaver.hrm.salary.annotation.SalaryFormulaVar; //import com.weaver.hrm.salary.common.LocalDateRange; //import com.weaver.hrm.salary.constant.SalaryFormulaFieldConstant; //import com.weaver.hrm.salary.entity.datacollection.dto.AttendQuoteDataDTO; //import com.weaver.hrm.salary.entity.datacollection.dto.AttendQuoteDataValueDTO; //import com.weaver.hrm.salary.entity.datacollection.dto.AttendQuoteFieldListDTO; //import com.weaver.hrm.salary.entity.datacollection.po.AddUpDeductionPO; //import com.weaver.hrm.salary.entity.datacollection.po.AddUpSituationPO; //import com.weaver.hrm.salary.entity.datacollection.po.OtherDeductionPO; //import com.weaver.hrm.salary.entity.salaryacct.po.SalaryAcctEmployeePO; //import com.weaver.hrm.salary.entity.salaryacct.po.SalaryAcctResultPO; //import com.weaver.hrm.salary.entity.salaryarchive.dto.SalaryArchiveDataDTO; //import com.weaver.hrm.salary.entity.salaryarchive.dto.SalaryArchiveItemDataDTO; //import com.weaver.hrm.salary.entity.salaryarchive.dto.SalaryArchiveTaxAgentDataDTO; //import com.weaver.hrm.salary.entity.salaryitem.po.SalaryItemPO; //import com.weaver.hrm.salary.entity.salarysob.po.SalarySobAdjustRulePO; //import com.weaver.hrm.salary.enums.SalaryFormulaReferenceEnum; //import com.weaver.hrm.salary.enums.salarysob.SalarySobAdjustRuleTypeEnum; //import com.weaver.hrm.salary.util.SalaryEntityUtil; //import com.weaver.teams.domain.user.SimpleEmployee; //import lombok.Data; //import lombok.experimental.Accessors; //import org.apache.commons.lang3.StringUtils; //import org.apache.commons.lang3.math.NumberUtils; // //import java.lang.reflect.Field; //import java.math.BigDecimal; //import java.math.RoundingMode; //import java.time.temporal.ChronoUnit; //import java.util.*; //import java.util.stream.Collectors; // ///** // * @description: 薪资核算-将数据转换成公式中的变量 // * @author: xiajun // * @modified By: xiajun // * @date: Created in 1/25/22 7:29 PM // * @version:v1.0 // */ //@Data //@Accessors(chain = true) //public class CalculateFormulaVarBO { // // /** // * 员工信息 // */ // private List simpleEmployees; // // /** // * 薪资档案 // */ // private List salaryArchiveData; // // /** // * 累计情况 // */ // private List addUpSituationPOS; // // /** // * 累计专项附加扣除 // */ // private List addUpDeductionPOS; // // /** // * 其他扣除 // */ // private List otherDeductionPOS; // // /** // * 社保福利 // */ // private List> welfareData; // // /** // * 考勤数据 // */ // private List attendQuoteDataDTOS; // // /** // * 薪资核算结果(输入/导入的值) // */ // private List salaryAcctResultPOS; // // public CalculateFormulaVarBO(List simpleEmployees, // List salaryArchiveData, // List addUpSituationPOS, // List addUpDeductionPOS, // List otherDeductionPOS, // List> welfareData, // List attendQuoteDataDTOS, // List salaryAcctResultPOS) { // this.simpleEmployees = simpleEmployees; // this.salaryArchiveData = salaryArchiveData; // this.addUpSituationPOS = addUpSituationPOS; // this.addUpDeductionPOS = addUpDeductionPOS; // this.otherDeductionPOS = otherDeductionPOS; // this.welfareData = welfareData; // this.attendQuoteDataDTOS = attendQuoteDataDTOS; // this.salaryAcctResultPOS = salaryAcctResultPOS; // } // // /** // * 将查询到的数据转换成公式变量 // * // * @param salaryAcctCalculateBO 核算参数 // * @return // */ // public Map> convert2FormulaVar(SalaryAcctCalculateBO salaryAcctCalculateBO) { // Map> resultMap = Maps.newHashMapWithExpectedSize(salaryAcctCalculateBO.getSalaryAcctEmployeePOS().size()); // // 处理薪资核算结果 // handleSalaryAcctResult(salaryAcctCalculateBO, resultMap); // // 处理薪资档案 // handleSalaryArchiveData(salaryAcctCalculateBO, resultMap); // // 处理往期累计情况 // handleAddUpSituation(resultMap); // // 处理累计专项附加扣除 // handleAddUpDeduction(resultMap); // // 处理其他扣除 // handleOtherDeduction(resultMap); // // 处理社保福利 // handleWelfareData(salaryAcctCalculateBO, resultMap); // // 处理考勤数据 // handleAttendQuoteData(salaryAcctCalculateBO, resultMap); // return resultMap; // } // // /** // * 处理薪资核算结果 // * // * @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:employeeId_taxAgentId、value:薪资核算结果集合 // Map> salaryAcctResultMap = SalaryEntityUtil.group2Map(salaryAcctResultPOS, // 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.SALARY_ITEM.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) { // // 调薪计薪规则 // Map salarySobAdjustRulePOMap = SalaryEntityUtil.convert2Map(salaryAcctCalculateBO.getSalarySobAdjustRulePOS(), // SalarySobAdjustRulePO::getSalaryItemId); // 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)); // } // } // } // // /** // * 根据调薪计薪规则处理薪资档案的调薪,转换成公式编辑器中的变量 // * // * @param salaryAcctCalculateBO // * @param salaryArchiveItemDataList // * @param salarySobAdjustRulePOMap // * @return // */ // private List handleSalaryArchiveItemVal(SalaryAcctCalculateBO salaryAcctCalculateBO, // List salaryArchiveItemDataList, // Map salarySobAdjustRulePOMap) { // // 薪资周期 // 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()); // if (entry.getValue().size() > 2) { // // 如果薪资项目在薪资周期内经历了多次调薪,则默认分段计薪 // value = calculateBySalarySobAdjustRule(salaryCycle, SalarySobAdjustRuleTypeEnum.PARTITION, entry.getValue()); // } else if (salaryAdjustmentRulePO == null || entry.getValue().size() < 2) { // // 如果薪资项目没有设置调薪计薪规则,默认取薪资周期内薪资档案中最新的值 // // 如果薪资项目在薪资周期内没有调薪,默认取薪资周期内薪资档案中最新的值 // value = calculateBySalarySobAdjustRule(salaryCycle, SalarySobAdjustRuleTypeEnum.USE_AFTER_ADJUSTMENT, entry.getValue()); // } else { // // 如果薪资项目在薪资周期内只有一次调薪,则根据调薪计薪规则处理 // SalarySobAdjustRuleTypeEnum adjustRuleTypeEnum = salaryAdjustmentRulePO.getDayOfMonth() < entry.getValue().get(0).getEffectiveDateRange().getEndDate().getDayOfMonth() // ? SalarySobAdjustRuleTypeEnum.parseByValue(salaryAdjustmentRulePO.getAfterAdjustmentType()) // : SalarySobAdjustRuleTypeEnum.parseByValue(salaryAdjustmentRulePO.getBeforeAdjustmentType()); // // 根据调薪计薪规则处理薪资档案的调薪 // value = calculateBySalarySobAdjustRule(salaryCycle, adjustRuleTypeEnum, entry.getValue()); // } // 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) { // 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; // for (int i = 0; i < salaryArchiveItemDataDTOS.size(); i++) { // SalaryArchiveItemDataDTO dataDTO = salaryArchiveItemDataDTOS.get(i); // BigDecimal dayDiff = new BigDecimal(dataDTO.getEffectiveDateRange().getFromDate().until(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(salaryCycle.getFromDate().until(salaryCycle.getEndDate(), ChronoUnit.DAYS)).add(BigDecimal.ONE), 2, RoundingMode.HALF_UP).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; // } // // /** // * 处理累计情况(工资、薪金) // * // * @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 = AddUpSituationPO.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 = AddUpDeductionPO.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 = Maps.newHashMapWithExpectedSize(welfareData.size()); // welfareData.forEach(map -> { // String key = String.valueOf(map.getOrDefault("employeeId", 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(String.valueOf(salaryAcctEmployeePO.getEmployeeId()), 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())); // } // } // // @Data // @Accessors(chain = true) // public static class FormulaVarValue { // // /** // * 公式变量id // */ // private String fieldId; // // /** // * 公式变量的值 // */ // private String fieldValue; // } //}