Merge branch 'feature/acc' into develop

This commit is contained in:
钱涛 2022-04-11 20:46:44 +08:00
commit 4d674bdd37
58 changed files with 3140 additions and 1420 deletions

View File

@ -0,0 +1,27 @@
package com.engine.salary.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 薪资公式计算器-变量
* <p>Copyright: Copyright (c) 2022</p>
* <p>Company: 泛微软件</p>
*
* @author qiantao
* @version 1.0
**/
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface SalaryFormulaVar {
int labelId();
String defaultLabel();
String dataType();
String fieldId() default "";
}

View File

@ -297,4 +297,13 @@ public class AddUpSituationBiz extends BaseBean {
}
public void deleteSome(AddUpSituation params) {
SqlSession sqlSession = MyBatisFactory.sqlSessionFactory.openSession();
try {
AddUpSituationMapper mapper = sqlSession.getMapper(AddUpSituationMapper.class);
mapper.deleteSome(params);
} finally {
sqlSession.close();
}
}
}

View File

@ -2,7 +2,7 @@ package com.engine.salary.biz;
import com.engine.salary.entity.salarysob.po.SalarySobPO;
import com.engine.salary.mapper.salarysob.SalarySobMapper;
import com.engine.salary.util.db.SqlProxyHandle;
import com.engine.salary.util.db.MapperProxyFactory;
import org.apache.ibatis.session.SqlSession;
import weaver.conn.mybatis.MyBatisFactory;
@ -11,7 +11,7 @@ import java.util.List;
public class SalarySobBiz {
public SalarySobPO getById(Long id) {
SalarySobMapper mapper = SqlProxyHandle.getProxy(SalarySobMapper.class);
SalarySobMapper mapper = MapperProxyFactory.getProxy(SalarySobMapper.class);
return mapper.getById(id);
}

View File

@ -0,0 +1,224 @@
package com.engine.salary.constant;
public class TaxDeclarationDataIndexConstant {
/**
* 本期收入
*/
public static final String INCOME = "income";
/**
* 累计收入
*/
public static final String ADD_UP_INCOME = "addUpIncome";
/**
* 本期免税收入
*/
public static final String TAX_FREE_INCOME = "taxFreeIncome";
/**
* 累计免税收入
*/
public static final String ADD_UP_TAX_FREE_INCOME = "addUpTaxFreeIncome";
/**
* 基本养老保险费
*/
public static final String ENDOWMENT_INSURANCE = "endowmentInsurance";
/**
* 基本医疗保险费
*/
public static final String MEDICAL_INSURANCE = "medicalInsurance";
/**
* 失业保险费
*/
public static final String UNEMPLOYMENT_INSURANCE = "unemploymentInsurance";
/**
* 住房公积金
*/
public static final String HOUSING_PROVIDENT_FUND = "housingProvidentFund";
/**
* 社保个人合计
*/
public static final String SOCIAL_SECURITY_TOTAL = "socialSecurityTotal";
/**
* 公积金个人合计
*/
public static final String ACCUMULATION_FUND_TOTAL = "accumulationFundTotal";
/**
* 当前累计社保个人合计
*/
public static final String ADD_UP_SOCIAL_SECURITY_TOTAL = "addUpSocialSecurityTotal";
/**
* 当前累计公积金个人合计
*/
public static final String ADD_UP_ACCUMULATION_FUND_TOTAL = "addUpAccumulationFundTotal";
/**
* 当前累计企业职业年金及其他福利个人合计
*/
public static final String ADD_UP_ENTERPRISE_AND_OTHER = "addUpEnterpriseAndOther";
/**
* 本月专项扣除合计
*/
public static final String SPECIAL_DEDUCTION = "specialDeduction";
/**
* 累计专项扣除
*/
public static final String ADD_UP_SPECIAL_DEDUCTION = "addUpSpecialDeduction";
/**
* 累计子女教育
*/
public static final String ADD_UP_CHILD_EDUCATION = "addUpChildEducation";
/**
* 累计住房贷款利息
*/
public static final String ADD_UP_HOUSING_LOAN_INTEREST = "addUpHousingLoanInterest";
/**
* 累计住房租金
*/
public static final String ADD_UP_HOUSING_RENT = "addUpHousingRent";
/**
* 累计继续教育
*/
public static final String ADD_UP_CONTINUING_EDUCATION = "addUpContinuingEducation";
/**
* 累计赡养老人
*/
public static final String ADD_UP_SUPPORT_ELDERLY = "addUpSupportElderly";
/**
* 累计大病医疗
*/
public static final String ADD_UP_ILLNESS_MEDICAL = "addUpIllnessMedical";
/**
* 累计专项附加扣除
*/
public static final String ADD_UP_SPE_ADDI_DEDUCTION = "addUpSpeAddiDeduction";
/**
* 减除费用
*/
public static final String SUBTRACTION = "subtraction";
/**
* 累计减除费用
*/
public static final String ADD_UP_SUBTRACTION = "addUpSubtraction";
/**
* 企业职业年金
*/
public static final String ANNUITY = "annuity";
/**
* 商业健康保险
*/
public static final String COMMERCIAL_HEALTH_INSURANCE = "commercialHealthInsurance";
/**
* 税延养老保险
*/
public static final String TAX_DEFERRED_ENDOWMENT_INSURANCE = "taxDeferredEndowmentInsurance";
/**
* 其他
*/
public static final String OTHER = "other";
/**
* 本次其他扣除合计
*/
public static final String OTHER_DEDUCTION = "otherDeduction";
/**
* 累计其他扣除
*/
public static final String ADD_UP_OTHER_DEDUCTION = "addUpOtherDeduction";
/**
* 准允扣除的捐赠额
*/
public static final String ALLOWED_DONATION = "allowedDonation";
/**
* 累计准允扣除的捐赠额
*/
public static final String ADD_UP_ALLOWED_DONATION = "addUpAllowedDonation";
/**
* 累计应纳税所得额
*/
public static final String ADD_UP_TAXABLE_INCOME = "addUpTaxableIncome";
/**
* 税率
*/
public static final String TAX_RATE = "taxRate";
/**
* 速算扣除数
*/
public static final String QUICK_DEDUCTION_FACTOR = "quickDeductionFactor";
/**
* 累计应纳税额
*/
public static final String ADD_UP_TAX_PAYABLE = "addUpTaxPayable";
/**
* 累计已纳税额
*/
public static final String ADD_UP_ADVANCE_TAX = "addUpAdvanceTax";
/**
* 减免税额
*/
public static final String TAX_DEDUCTION = "taxDeduction";
/**
* 累计减免税额
*/
public static final String ADD_UP_TAX_DEDUCTION = "addUpTaxDeduction";
/**
* 应补退税额
*/
public static final String REFUNDED_OR_SUPPLEMENTED_TAX = "refundedOrSupplementedTax";
/**
* 劳务收入
*/
public static final String LABOR_INCOME = "laborIncome";
/**
* 劳务免税收入
*/
public static final String LABOR_TAX_FREE_INCOME = "laborTaxFreeIncome";
/**
* 所得项目
*/
public static final String INCOME_ITEMS = "incomeItems";
/**
* 备注
*/
public static final String DESCRIPTION = "description";
}

View File

@ -5,6 +5,7 @@ import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Collection;
import java.util.Date;
/**
@ -72,4 +73,6 @@ public class AddUpDeduction {
*/
private Date updateTime;
Collection<Long> employeeIds;
}

View File

@ -7,6 +7,7 @@ import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Collection;
import java.util.Date;
/**
@ -115,4 +116,8 @@ public class AddUpSituation {
*/
private Integer year;
//条件
Collection<Long> employeeIds;
}

View File

@ -0,0 +1,11 @@
package com.engine.salary.entity.formula;
public class DataType {
public static final String STRING = "string";
public static final String NUMBER = "number";
public static final String DATE = "date";
public static final String OPTION = "option";
public static final String BOOL = "boolean";
public static final String FORM = "form";
public static final String DATASOURCE = "dataSource";
}

View File

@ -0,0 +1,46 @@
package com.engine.salary.entity.formula;
import com.engine.salary.entity.datacollection.DataCollectionEmployee;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.weaver.excel.formula.api.entity.ExpressFormulaSourceLink;
import com.weaver.excel.formula.api.entity.FormulaVar;
import lombok.Data;
import java.util.Date;
import java.util.List;
@Data
public class ExpressFormula {
@JsonSerialize(
using = ToStringSerializer.class
)
private Long id;
//名称
private String name;
private String module;
private String parameter;
private Long userId;
private Integer status;
private String msgFormula;
private String msgParameter;
private Date addTime;
private Date lastUpdate;
private Integer isDelete;
private Long formId;
private int type;
private String tenantKey;
private DataCollectionEmployee creator;
private List<ExpressFormulaSourceLink> sourceLinks;
//引用类型
private String referenceType;
//返回类型
private String returnType;
//公式内容
private String formula;
private boolean showInLibrary;
private String codeFormula;
private String msgCodeFormula;
private List<FormulaVar> parameters;
private List<FormulaVar> msgParameters;
}

View File

@ -1,442 +1,443 @@
//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<SimpleEmployee> simpleEmployees;
//
// /**
// * 薪资档案
// */
// private List<SalaryArchiveDataDTO> salaryArchiveData;
//
// /**
// * 累计情况
// */
// private List<AddUpSituationPO> addUpSituationPOS;
//
// /**
// * 累计专项附加扣除
// */
// private List<AddUpDeductionPO> addUpDeductionPOS;
//
// /**
// * 其他扣除
// */
// private List<OtherDeductionPO> otherDeductionPOS;
//
// /**
// * 社保福利
// */
// private List<Map<String, Object>> welfareData;
//
// /**
// * 考勤数据
// */
// private List<AttendQuoteDataDTO> attendQuoteDataDTOS;
//
// /**
// * 薪资核算结果输入/导入的值
// */
// private List<SalaryAcctResultPO> salaryAcctResultPOS;
//
// public CalculateFormulaVarBO(List<SimpleEmployee> simpleEmployees,
// List<SalaryArchiveDataDTO> salaryArchiveData,
// List<AddUpSituationPO> addUpSituationPOS,
// List<AddUpDeductionPO> addUpDeductionPOS,
// List<OtherDeductionPO> otherDeductionPOS,
// List<Map<String, Object>> welfareData,
// List<AttendQuoteDataDTO> attendQuoteDataDTOS,
// List<SalaryAcctResultPO> 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<String, List<FormulaVarValue>> convert2FormulaVar(SalaryAcctCalculateBO salaryAcctCalculateBO) {
// Map<String, List<FormulaVarValue>> 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<String, List<FormulaVarValue>> resultMap) {
// // key:薪资项目的idvalue:薪资项目的code
// Map<Long, String> salaryItemCodeMap = SalaryEntityUtil.convert2Map(salaryAcctCalculateBO.getSalaryItemPOS(), SalaryItemPO::getId, SalaryItemPO::getCode);
// // key:employeeId_taxAgentIdvalue:薪资核算结果集合
// Map<String, List<SalaryAcctResultPO>> salaryAcctResultMap = SalaryEntityUtil.group2Map(salaryAcctResultPOS,
// salaryAcctResultPO -> salaryAcctResultPO.getEmployeeId() + "_" + salaryAcctResultPO.getTaxAgentId());
// // 填充到返回结果集中
// salaryAcctResultMap.forEach((key, salaryAcctResultPOS) -> {
// List<FormulaVarValue> 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<String, List<FormulaVarValue>> resultMap) {
// // 调薪计薪规则
// Map<Long, SalarySobAdjustRulePO> salarySobAdjustRulePOMap = SalaryEntityUtil.convert2Map(salaryAcctCalculateBO.getSalarySobAdjustRulePOS(),
// SalarySobAdjustRulePO::getSalaryItemId);
// for (SalaryArchiveDataDTO salaryArchiveDataDTO : salaryArchiveData) {
// for (SalaryArchiveTaxAgentDataDTO salaryArchiveTaxAgentDataDTO : salaryArchiveDataDTO.getTaxAgents()) {
// String key = salaryArchiveDataDTO.getEmployeeId() + "_" + salaryArchiveTaxAgentDataDTO.getTaxAgentId();
// List<FormulaVarValue> formulaVarValues = resultMap.computeIfAbsent(key, k -> Lists.newArrayList());
// // 将薪资档案的值转换成公式中的变量填充到返回结果集中
// formulaVarValues.addAll(handleSalaryArchiveItemVal(salaryAcctCalculateBO, salaryArchiveTaxAgentDataDTO.getSalaryItemValues(), salarySobAdjustRulePOMap));
// }
// }
// }
//
// /**
// * 根据调薪计薪规则处理薪资档案的调薪转换成公式编辑器中的变量
// *
// * @param salaryAcctCalculateBO
// * @param salaryArchiveItemDataList
// * @param salarySobAdjustRulePOMap
// * @return
// */
// private List<FormulaVarValue> handleSalaryArchiveItemVal(SalaryAcctCalculateBO salaryAcctCalculateBO,
// List<SalaryArchiveItemDataDTO> salaryArchiveItemDataList,
// Map<Long, SalarySobAdjustRulePO> salarySobAdjustRulePOMap) {
// // 薪资周期
// LocalDateRange salaryCycle = salaryAcctCalculateBO.getSalarySobCycleDTO().getSalaryCycle();
// // key:薪资项目的idvalue:薪资项目的code
// Map<Long, String> salaryItemCodeMap = SalaryEntityUtil.convert2Map(salaryAcctCalculateBO.getSalaryItemPOS(), SalaryItemPO::getId, SalaryItemPO::getCode);
// // 将薪资档案的调薪记录按照薪资项目id聚合(同一个薪资项目可能存在多次调薪按照生效日期对调薪记录排序)
// Map<Long, List<SalaryArchiveItemDataDTO>> 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<FormulaVarValue> formulaVarValues = Lists.newArrayListWithExpectedSize(dataMap.size());
// for (Map.Entry<Long, List<SalaryArchiveItemDataDTO>> 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<SalaryArchiveItemDataDTO> 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<String, List<FormulaVarValue>> resultMap) {
// // key:employeeId_taxAgentIdvalue:累计情况工资薪金的数据
// Map<String, AddUpSituationPO> addUpSituationPOMap = SalaryEntityUtil.convert2Map(addUpSituationPOS,
// addUpSituationPO -> addUpSituationPO.getEmployeeId() + "_" + addUpSituationPO.getTaxAgentId());
// // 累计情况工资薪金可选字段
// List<String> 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<FormulaVarValue> formulaVarValues = resultMap.computeIfAbsent(key, k -> Lists.newArrayList());
// Map<String, String> 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<String, List<FormulaVarValue>> resultMap) {
// // key:employeeId_taxAgentIdvalue:累计专项附加扣除的数据
// Map<String, AddUpDeductionPO> addUpDeductionPOMap = SalaryEntityUtil.convert2Map(addUpDeductionPOS,
// addUpDeductionPO -> addUpDeductionPO.getEmployeeId() + "_" + addUpDeductionPO.getTaxAgentId());
// // 累计专项附加扣除可选字段
// List<String> 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<FormulaVarValue> formulaVarValues = resultMap.computeIfAbsent(key, k -> Lists.newArrayList());
// Map<String, String> 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<String, List<FormulaVarValue>> resultMap) {
// // key:employeeId_taxAgentIdvalue:累计专项附加扣除的数据
// Map<String, OtherDeductionPO> otherDeductionPOMap = SalaryEntityUtil.convert2Map(otherDeductionPOS,
// otherDeductionPO -> otherDeductionPO.getEmployeeId() + "_" + otherDeductionPO.getTaxAgentId());
// // 累计专项附加扣除可选字段
// List<String> 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<FormulaVarValue> formulaVarValues = resultMap.computeIfAbsent(key, k -> Lists.newArrayList());
// Map<String, String> 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<String, List<FormulaVarValue>> resultMap) {
// // 社保福利可选字段
// List<String> fieldNames = Lists.newArrayList(salaryAcctCalculateBO.getWelfareColumns().values());
// // 社保福利数据
// Map<String, List<FormulaVarValue>> tempMap = Maps.newHashMapWithExpectedSize(welfareData.size());
// welfareData.forEach(map -> {
// String key = String.valueOf(map.getOrDefault("employeeId", StringUtils.EMPTY));
// List<FormulaVarValue> 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<FormulaVarValue> 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<String, List<FormulaVarValue>> resultMap) {
// // 考勤引用可选字段
// Set<Long> fieldNames = SalaryEntityUtil.properties(salaryAcctCalculateBO.getAttendQuoteFieldListDTOS(), AttendQuoteFieldListDTO::getId);
// // 考勤引用数据
// Map<Long, List<FormulaVarValue>> tempMap = Maps.newHashMapWithExpectedSize(attendQuoteDataDTOS.size());
// attendQuoteDataDTOS.forEach(attendQuoteDataDTO -> {
// Map<Long, String> attendQuoteDataValueMap = SalaryEntityUtil.convert2Map(attendQuoteDataDTO.getDataValues(), AttendQuoteDataValueDTO::getAttendQuoteFieldId, AttendQuoteDataValueDTO::getDataValue);
// Long key = attendQuoteDataDTO.getEmployeeId();
// List<FormulaVarValue> 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<FormulaVarValue> 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;
// }
//}
package com.engine.salary.entity.salaryacct.bo;
import com.engine.salary.annotation.SalaryFormulaVar;
import com.engine.salary.common.LocalDateRange;
import com.engine.salary.constant.SalaryFormulaFieldConstant;
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.po.SalarySobAdjustRulePO;
import com.engine.salary.enums.SalaryFormulaReferenceEnum;
import com.engine.salary.enums.salarysob.SalarySobAdjustRuleTypeEnum;
import com.engine.salary.util.JsonUtil;
import com.engine.salary.util.SalaryDateUtil;
import com.engine.salary.util.SalaryEntityUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
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<DataCollectionEmployee> simpleEmployees;
/**
* 薪资档案
*/
private List<SalaryArchiveDataDTO> salaryArchiveData;
/**
* 累计情况
*/
private List<AddUpSituation> addUpSituationPOS;
/**
* 累计专项附加扣除
*/
private List<AddUpDeduction> addUpDeductionPOS;
/**
* 其他扣除
*/
private List<OtherDeductionPO> otherDeductionPOS;
/**
* 社保福利
*/
private List<Map<String, Object>> welfareData;
/**
* 考勤数据
*/
private List<AttendQuoteDataDTO> attendQuoteDataDTOS;
/**
* 薪资核算结果输入/导入的值
*/
private List<SalaryAcctResultPO> salaryAcctResultPOS;
public CalculateFormulaVarBO(List<DataCollectionEmployee> simpleEmployees,
List<SalaryArchiveDataDTO> salaryArchiveData,
List<AddUpSituation> addUpSituationPOS,
List<AddUpDeduction> addUpDeductionPOS,
List<OtherDeductionPO> otherDeductionPOS,
List<Map<String, Object>> welfareData,
List<AttendQuoteDataDTO> attendQuoteDataDTOS,
List<SalaryAcctResultPO> 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<String, List<FormulaVarValue>> convert2FormulaVar(SalaryAcctCalculateBO salaryAcctCalculateBO) {
Map<String, List<FormulaVarValue>> 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<String, List<FormulaVarValue>> resultMap) {
// key:薪资项目的idvalue:薪资项目的code
Map<Long, String> salaryItemCodeMap = SalaryEntityUtil.convert2Map(salaryAcctCalculateBO.getSalaryItemPOS(), SalaryItemPO::getId, SalaryItemPO::getCode);
// key:employeeId_taxAgentIdvalue:薪资核算结果集合
Map<String, List<SalaryAcctResultPO>> salaryAcctResultMap = SalaryEntityUtil.group2Map(salaryAcctResultPOS,
salaryAcctResultPO -> salaryAcctResultPO.getEmployeeId() + "_" + salaryAcctResultPO.getTaxAgentId());
// 填充到返回结果集中
salaryAcctResultMap.forEach((key, salaryAcctResultPOS) -> {
List<FormulaVarValue> 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<String, List<FormulaVarValue>> resultMap) {
// 调薪计薪规则
Map<Long, SalarySobAdjustRulePO> salarySobAdjustRulePOMap = SalaryEntityUtil.convert2Map(salaryAcctCalculateBO.getSalarySobAdjustRulePOS(),
SalarySobAdjustRulePO::getSalaryItemId);
for (SalaryArchiveDataDTO salaryArchiveDataDTO : salaryArchiveData) {
for (SalaryArchiveTaxAgentDataDTO salaryArchiveTaxAgentDataDTO : salaryArchiveDataDTO.getTaxAgents()) {
String key = salaryArchiveDataDTO.getEmployeeId() + "_" + salaryArchiveTaxAgentDataDTO.getTaxAgentId();
List<FormulaVarValue> formulaVarValues = resultMap.computeIfAbsent(key, k -> Lists.newArrayList());
// 将薪资档案的值转换成公式中的变量填充到返回结果集中
formulaVarValues.addAll(handleSalaryArchiveItemVal(salaryAcctCalculateBO, salaryArchiveTaxAgentDataDTO.getSalaryItemValues(), salarySobAdjustRulePOMap));
}
}
}
/**
* 根据调薪计薪规则处理薪资档案的调薪转换成公式编辑器中的变量
*
* @param salaryAcctCalculateBO
* @param salaryArchiveItemDataList
* @param salarySobAdjustRulePOMap
* @return
*/
private List<FormulaVarValue> handleSalaryArchiveItemVal(SalaryAcctCalculateBO salaryAcctCalculateBO,
List<SalaryArchiveItemDataDTO> salaryArchiveItemDataList,
Map<Long, SalarySobAdjustRulePO> salarySobAdjustRulePOMap) {
// 薪资周期
LocalDateRange salaryCycle = salaryAcctCalculateBO.getSalarySobCycleDTO().getSalaryCycle();
// key:薪资项目的idvalue:薪资项目的code
Map<Long, String> salaryItemCodeMap = SalaryEntityUtil.convert2Map(salaryAcctCalculateBO.getSalaryItemPOS(), SalaryItemPO::getId, SalaryItemPO::getCode);
// 将薪资档案的调薪记录按照薪资项目id聚合(同一个薪资项目可能存在多次调薪按照生效日期对调薪记录排序)
Map<Long, List<SalaryArchiveItemDataDTO>> 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<FormulaVarValue> formulaVarValues = Lists.newArrayListWithExpectedSize(dataMap.size());
for (Map.Entry<Long, List<SalaryArchiveItemDataDTO>> 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() < SalaryDateUtil.dateToLocalDate(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<SalaryArchiveItemDataDTO> 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(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();
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<String, List<FormulaVarValue>> resultMap) {
// key:employeeId_taxAgentIdvalue:累计情况工资薪金的数据
Map<String, AddUpSituation> addUpSituationPOMap = SalaryEntityUtil.convert2Map(addUpSituationPOS,
addUpSituationPO -> addUpSituationPO.getEmployeeId() + "_" + addUpSituationPO.getTaxAgentId());
// 累计情况工资薪金可选字段
List<String> 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<FormulaVarValue> formulaVarValues = resultMap.computeIfAbsent(key, k -> Lists.newArrayList());
Map<String, String> 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<String, List<FormulaVarValue>> resultMap) {
// key:employeeId_taxAgentIdvalue:累计专项附加扣除的数据
Map<String, AddUpDeduction> addUpDeductionPOMap = SalaryEntityUtil.convert2Map(addUpDeductionPOS,
addUpDeductionPO -> addUpDeductionPO.getEmployeeId() + "_" + addUpDeductionPO.getTaxAgentId());
// 累计专项附加扣除可选字段
List<String> 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<FormulaVarValue> formulaVarValues = resultMap.computeIfAbsent(key, k -> Lists.newArrayList());
Map<String, String> 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<String, List<FormulaVarValue>> resultMap) {
// key:employeeId_taxAgentIdvalue:累计专项附加扣除的数据
Map<String, OtherDeductionPO> otherDeductionPOMap = SalaryEntityUtil.convert2Map(otherDeductionPOS,
otherDeductionPO -> otherDeductionPO.getEmployeeId() + "_" + otherDeductionPO.getTaxAgentId());
// 累计专项附加扣除可选字段
List<String> 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<FormulaVarValue> formulaVarValues = resultMap.computeIfAbsent(key, k -> Lists.newArrayList());
Map<String, String> 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<String, List<FormulaVarValue>> resultMap) {
// 社保福利可选字段
List<String> fieldNames = Lists.newArrayList(salaryAcctCalculateBO.getWelfareColumns().values());
// 社保福利数据
Map<String, List<FormulaVarValue>> tempMap = Maps.newHashMapWithExpectedSize(welfareData.size());
welfareData.forEach(map -> {
String key = String.valueOf(map.getOrDefault("employeeId", StringUtils.EMPTY));
List<FormulaVarValue> 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<FormulaVarValue> 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<String, List<FormulaVarValue>> resultMap) {
// 考勤引用可选字段
Set<Long> fieldNames = SalaryEntityUtil.properties(salaryAcctCalculateBO.getAttendQuoteFieldListDTOS(), AttendQuoteFieldListDTO::getId);
// 考勤引用数据
Map<Long, List<FormulaVarValue>> tempMap = Maps.newHashMapWithExpectedSize(attendQuoteDataDTOS.size());
attendQuoteDataDTOS.forEach(attendQuoteDataDTO -> {
Map<Long, String> attendQuoteDataValueMap = SalaryEntityUtil.convert2Map(attendQuoteDataDTO.getDataValues(), AttendQuoteDataValueDTO::getAttendQuoteFieldId, AttendQuoteDataValueDTO::getDataValue);
Long key = attendQuoteDataDTO.getEmployeeId();
List<FormulaVarValue> 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<FormulaVarValue> 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;
}
}

View File

@ -1,131 +1,131 @@
//package com.engine.salary.entity.salaryacct.bo;
//
//import com.alibaba.fastjson.JSON;
//import com.alibaba.fastjson.JSONArray;
//import com.alibaba.fastjson.JSONObject;
//import com.weaver.excel.formula.api.entity.ExpressFormula;
//import com.weaver.excel.formula.api.entity.FormulaVar;
//import com.weaver.hrm.salary.constant.SalaryFormulaFieldConstant;
//import com.weaver.hrm.salary.entity.salaryacct.po.SalaryAcctResultPO;
//import com.weaver.hrm.salary.entity.salaryitem.po.SalaryItemPO;
//import com.weaver.hrm.salary.enums.SalaryFormulaReferenceEnum;
//import com.weaver.hrm.salary.util.SalaryEntityUtil;
//import org.apache.commons.collections4.CollectionUtils;
//import org.apache.commons.lang3.StringUtils;
//import org.apache.curator.shaded.com.google.common.collect.Maps;
//
//import java.math.BigDecimal;
//import java.util.Collections;
//import java.util.List;
//import java.util.Map;
//import java.util.Objects;
//import java.util.regex.Matcher;
//import java.util.regex.Pattern;
//
///**
// * @description: 薪资核算公式
// * @author: xiajun
// * @modified By: xiajun
// * @date: Created in 6/2/22 10:33 PM
// * @version:v1.0
// */
//public class ExpressFormulaBO {
//
// /**
// * 公式中变量的fieldId的正则表达式
// */
// private static final String SALARY_REGEX = "(\\w+)" + SalaryFormulaFieldConstant.FIELD_ID_SEPARATOR + "(\\w+)";
//
// /**
// * 解析公式中变量的fieldId的正则表达式
// */
// private static final Pattern SALARY_PATTERN = Pattern.compile(SALARY_REGEX);
//
// /**
// * 解析公式中的变量
// *
// * @param expressFormulas 公式详情
// * @return
// */
// public static Map<Long, List<FormulaVar>> buildFormulaVar(List<ExpressFormula> expressFormulas) {
// if (CollectionUtils.isEmpty(expressFormulas)) {
// return Collections.emptyMap();
// }
// Map<Long, List<FormulaVar>> resultMap = Maps.newHashMapWithExpectedSize(expressFormulas.size());
// for (ExpressFormula expressFormula : expressFormulas) {
// if (StringUtils.isEmpty(expressFormula.getParameter())) {
// continue;
// }
// JSONObject paramJson = JSON.parseObject(expressFormula.getParameter());
// if (paramJson != null) {
// JSONArray paramArray = paramJson.getJSONArray("formulavars");
// if (paramArray != null) {
// List<FormulaVar> formulaVars = paramArray.toJavaList(FormulaVar.class);
// resultMap.put(expressFormula.getId(), formulaVars);
// }
// }
// }
// return resultMap;
// }
//
// /**
// * 给公式中的变量填入值
// *
// * @param expressFormulas
// * @param salaryItems
// * @param acctResults
// * @return
// */
// public static Map<Long, List<FormulaVar>> buildFormulaVar4Check(List<ExpressFormula> expressFormulas, List<SalaryItemPO> salaryItems, List<SalaryAcctResultPO> acctResults) {
// if (CollectionUtils.isEmpty(expressFormulas)) {
// return Collections.emptyMap();
// }
// Map<Long, String> salaryItemCodeMap = SalaryEntityUtil.convert2Map(salaryItems, SalaryItemPO::getId, SalaryItemPO::getCode);
// Map<String, String> acctResultMap = SalaryEntityUtil.convert2Map(acctResults, e -> salaryItemCodeMap.getOrDefault(e.getSalaryItemId(), ""), SalaryAcctResultPO::getResultValue);
// Map<Long, List<FormulaVar>> formulaVarMap = buildFormulaVar(expressFormulas);
// formulaVarMap.forEach((k, v) -> {
// for (FormulaVar formulaVar : v) {
// Matcher matcher = SALARY_PATTERN.matcher(formulaVar.getFieldId());
// if (matcher.find()) {
// SalaryFormulaReferenceEnum referenceEnum = SalaryFormulaReferenceEnum.parseByValue(matcher.group(1));
// if (referenceEnum == SalaryFormulaReferenceEnum.SALARY_ITEM) {
// formulaVar.setContent(acctResultMap.getOrDefault(matcher.group(2), ""));
// }
// }
// }
// });
// return formulaVarMap;
// }
//
// /**
// * 给公式中的变量填入值
// *
// * @param expressFormula 公式
// * @param formulaVarValueMap 公式变量的值
// * @return
// */
// public static List<FormulaVar> buildFormulaVar4Accounting(ExpressFormula expressFormula, Map<String, String> formulaVarValueMap) {
// List<FormulaVar> formulaVars = Collections.emptyList();
// // 公式异常
// if (Objects.isNull(expressFormula) || StringUtils.isEmpty(expressFormula.getParameter())) {
// return Collections.emptyList();
// }
// JSONObject paramJson = JSON.parseObject(expressFormula.getParameter());
// if (paramJson != null) {
// JSONArray paramArray = paramJson.getJSONArray("formulavars");
// if (paramArray != null) {
// formulaVars = paramArray.toJavaList(FormulaVar.class);
// for (FormulaVar formulaVar : formulaVars) {
// // 公式变量的值
// String formulaVarValue = formulaVarValueMap.getOrDefault(formulaVar.getFieldId(), StringUtils.EMPTY);
// // 如果公式的返回值类型为number公式中的变量的值如果为空公式运行的时候会报错所以需要替换成0
// if (StringUtils.isEmpty(formulaVarValue) && "number".equals(expressFormula.getReturnType())) {
// formulaVarValue = BigDecimal.ZERO.toPlainString();
// }
// formulaVar.setContent(formulaVarValue);
// }
// }
// }
// return formulaVars;
// }
//}
package com.engine.salary.entity.salaryacct.bo;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.engine.salary.constant.SalaryFormulaFieldConstant;
import com.engine.salary.entity.salaryacct.po.SalaryAcctResultPO;
import com.engine.salary.entity.salaryitem.po.SalaryItemPO;
import com.engine.salary.enums.SalaryFormulaReferenceEnum;
import com.engine.salary.util.SalaryEntityUtil;
import com.google.common.collect.Maps;
import com.weaver.excel.formula.api.entity.ExpressFormula;
import com.weaver.excel.formula.api.entity.FormulaVar;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @description: 薪资核算公式
* @author: xiajun
* @modified By: xiajun
* @date: Created in 6/2/22 10:33 PM
* @version:v1.0
*/
public class ExpressFormulaBO {
/**
* 公式中变量的fieldId的正则表达式
*/
private static final String SALARY_REGEX = "(\\w+)" + SalaryFormulaFieldConstant.FIELD_ID_SEPARATOR + "(\\w+)";
/**
* 解析公式中变量的fieldId的正则表达式
*/
private static final Pattern SALARY_PATTERN = Pattern.compile(SALARY_REGEX);
/**
* 解析公式中的变量
*
* @param expressFormulas 公式详情
* @return
*/
public static Map<Long, List<FormulaVar>> buildFormulaVar(List<ExpressFormula> expressFormulas) {
if (CollectionUtils.isEmpty(expressFormulas)) {
return Collections.emptyMap();
}
Map<Long, List<FormulaVar>> resultMap = Maps.newHashMapWithExpectedSize(expressFormulas.size());
for (ExpressFormula expressFormula : expressFormulas) {
if (StringUtils.isEmpty(expressFormula.getParameter())) {
continue;
}
JSONObject paramJson = JSON.parseObject(expressFormula.getParameter());
if (paramJson != null) {
JSONArray paramArray = paramJson.getJSONArray("formulavars");
if (paramArray != null) {
List<FormulaVar> formulaVars = paramArray.toJavaList(FormulaVar.class);
resultMap.put(expressFormula.getId(), formulaVars);
}
}
}
return resultMap;
}
/**
* 给公式中的变量填入值
*
* @param expressFormulas
* @param salaryItems
* @param acctResults
* @return
*/
public static Map<Long, List<FormulaVar>> buildFormulaVar4Check(List<ExpressFormula> expressFormulas, List<SalaryItemPO> salaryItems, List<SalaryAcctResultPO> acctResults) {
if (CollectionUtils.isEmpty(expressFormulas)) {
return Collections.emptyMap();
}
Map<Long, String> salaryItemCodeMap = SalaryEntityUtil.convert2Map(salaryItems, SalaryItemPO::getId, SalaryItemPO::getCode);
Map<String, String> acctResultMap = SalaryEntityUtil.convert2Map(acctResults, e -> salaryItemCodeMap.getOrDefault(e.getSalaryItemId(), ""), SalaryAcctResultPO::getResultValue);
Map<Long, List<FormulaVar>> formulaVarMap = buildFormulaVar(expressFormulas);
formulaVarMap.forEach((k, v) -> {
for (FormulaVar formulaVar : v) {
Matcher matcher = SALARY_PATTERN.matcher(formulaVar.getFieldId());
if (matcher.find()) {
SalaryFormulaReferenceEnum referenceEnum = SalaryFormulaReferenceEnum.parseByValue(matcher.group(1));
if (referenceEnum == SalaryFormulaReferenceEnum.SALARY_ITEM) {
formulaVar.setContent(acctResultMap.getOrDefault(matcher.group(2), ""));
}
}
}
});
return formulaVarMap;
}
/**
* 给公式中的变量填入值
*
* @param expressFormula 公式
* @param formulaVarValueMap 公式变量的值
* @return
*/
public static List<FormulaVar> buildFormulaVar4Accounting(ExpressFormula expressFormula, Map<String, String> formulaVarValueMap) {
List<FormulaVar> formulaVars = Collections.emptyList();
// 公式异常
if (Objects.isNull(expressFormula) || StringUtils.isEmpty(expressFormula.getParameter())) {
return Collections.emptyList();
}
JSONObject paramJson = JSON.parseObject(expressFormula.getParameter());
if (paramJson != null) {
JSONArray paramArray = paramJson.getJSONArray("formulavars");
if (paramArray != null) {
formulaVars = paramArray.toJavaList(FormulaVar.class);
for (FormulaVar formulaVar : formulaVars) {
// 公式变量的值
String formulaVarValue = formulaVarValueMap.getOrDefault(formulaVar.getFieldId(), StringUtils.EMPTY);
// 如果公式的返回值类型为number公式中的变量的值如果为空公式运行的时候会报错所以需要替换成0
if (StringUtils.isEmpty(formulaVarValue) && "number".equals(expressFormula.getReturnType())) {
formulaVarValue = BigDecimal.ZERO.toPlainString();
}
formulaVar.setContent(formulaVarValue);
}
}
}
return formulaVars;
}
}

View File

@ -1,115 +1,116 @@
//package com.engine.salary.entity.salaryacct.bo;
//
//import com.weaver.excel.formula.api.entity.ExpressFormula;
//import com.weaver.hrm.salary.entity.datacollection.dto.AttendQuoteFieldListDTO;
//import com.weaver.hrm.salary.entity.salaryacct.po.SalaryAcctEmployeePO;
//import com.weaver.hrm.salary.entity.salaryacct.po.SalaryAcctRecordPO;
//import com.weaver.hrm.salary.entity.salaryitem.po.SalaryItemPO;
//import com.weaver.hrm.salary.entity.salarysob.dto.SalarySobCycleDTO;
//import com.weaver.hrm.salary.entity.salarysob.po.SalarySobAdjustRulePO;
//import com.weaver.hrm.salary.entity.salarysob.po.SalarySobItemPO;
//import lombok.AllArgsConstructor;
//import lombok.Data;
//import lombok.experimental.Accessors;
//
//import java.util.List;
//import java.util.Map;
//import java.util.concurrent.BlockingDeque;
//import java.util.concurrent.CountDownLatch;
//
///**
// * @description: 薪资核算
// * @author: xiajun
// * @modified By: xiajun
// * @date: Created in 1/25/22 6:03 PM
// * @version:v1.0
// */
//@Data
//@Accessors(chain = true)
//public class SalaryAcctCalculateBO {
//
// /**
// * 当前薪资核算记录
// */
// private SalaryAcctRecordPO salaryAcctRecordPO;
//
// /**
// * 当前薪资核算记录的薪资周期考勤周期
// */
// private SalarySobCycleDTO salarySobCycleDTO;
//
// /**
// * 相同税款所属期内其他薪资核算记录薪资类型为工资薪金的账套的
// */
// private List<SalaryAcctRecordPO> otherSalaryAcctRecordPOS;
//
// /**
// * 当前薪资核算记录所用的薪资账套下的薪资项目
// */
// private List<SalarySobItemPO> salarySobItemPOS;
//
// /**
// * 本次运算的薪资项目已排好运算优先级
// */
// private List<List<Long>> salaryItemIdWithPriorityList;
//
// /**
// * 本次运算涉及的所有公式
// */
// private List<ExpressFormula> expressFormulas;
//
// /**
// * 租户下所有的薪资项目
// */
// private List<SalaryItemPO> salaryItemPOS;
//
// /**
// * 当前薪资核算所用账套设置的调薪计薪规则
// */
// private List<SalarySobAdjustRulePO> salarySobAdjustRulePOS;
//
// /**
// * 社保福利字段
// */
// private Map<String, String> welfareColumns;
//
// /**
// * 考勤引用字段
// */
// private List<AttendQuoteFieldListDTO> attendQuoteFieldListDTOS;
//
// /**
// * 本次运算的薪资核算人员
// */
// private List<SalaryAcctEmployeePO> salaryAcctEmployeePOS;
//
// /**
// * 核算结果临时表中的key
// */
// private String calculateKey;
//
// /**
// * 监视子线程运算结果
// */
// private CountDownLatch childMonitor;
//
// /**
// * 所有子线程的运算结果
// */
// private BlockingDeque<Result> results;
//
// @Data
// @AllArgsConstructor
// public static class Result {
//
// /**
// * 子线程是否运算成功
// */
// private boolean status;
//
// /**
// * 子线程元算失败的错误信息
// */
// private String errMsg;
// }
//}
package com.engine.salary.entity.salaryacct.bo;
import com.engine.salary.entity.datacollection.dto.AttendQuoteFieldListDTO;
import com.engine.salary.entity.salaryacct.po.SalaryAcctEmployeePO;
import com.engine.salary.entity.salaryacct.po.SalaryAcctRecordPO;
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.entity.salarysob.po.SalarySobItemPO;
import com.weaver.excel.formula.api.entity.ExpressFormula;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.List;
import java.util.Map;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.CountDownLatch;
/**
* 薪资核算
* <p>Copyright: Copyright (c) 2022</p>
* <p>Company: 泛微软件</p>
*
* @author qiantao
* @version 1.0
**/
@Data
@Accessors(chain = true)
public class SalaryAcctCalculateBO {
/**
* 当前薪资核算记录
*/
private SalaryAcctRecordPO salaryAcctRecordPO;
/**
* 当前薪资核算记录的薪资周期考勤周期
*/
private SalarySobCycleDTO salarySobCycleDTO;
/**
* 相同税款所属期内其他薪资核算记录薪资类型为工资薪金的账套的
*/
private List<SalaryAcctRecordPO> otherSalaryAcctRecordPOS;
/**
* 当前薪资核算记录所用的薪资账套下的薪资项目
*/
private List<SalarySobItemPO> salarySobItemPOS;
/**
* 本次运算的薪资项目已排好运算优先级
*/
private List<List<Long>> salaryItemIdWithPriorityList;
/**
* 本次运算涉及的所有公式
*/
private List<ExpressFormula> expressFormulas;
/**
* 租户下所有的薪资项目
*/
private List<SalaryItemPO> salaryItemPOS;
/**
* 当前薪资核算所用账套设置的调薪计薪规则
*/
private List<SalarySobAdjustRulePO> salarySobAdjustRulePOS;
/**
* 社保福利字段
*/
private Map<String, String> welfareColumns;
/**
* 考勤引用字段
*/
private List<AttendQuoteFieldListDTO> attendQuoteFieldListDTOS;
/**
* 本次运算的薪资核算人员
*/
private List<SalaryAcctEmployeePO> salaryAcctEmployeePOS;
/**
* 核算结果临时表中的key
*/
private String calculateKey;
/**
* 监视子线程运算结果
*/
private CountDownLatch childMonitor;
/**
* 所有子线程的运算结果
*/
private BlockingDeque<Result> results;
@Data
@AllArgsConstructor
public static class Result {
/**
* 子线程是否运算成功
*/
private boolean status;
/**
* 子线程元算失败的错误信息
*/
private String errMsg;
}
}

View File

@ -1,225 +1,225 @@
//package com.engine.salary.entity.salaryacct.bo;
//
//import com.google.common.collect.Lists;
//import com.weaver.excel.formula.api.entity.ExpressFormula;
//import com.weaver.excel.formula.api.entity.FormulaVar;
//import com.weaver.hrm.salary.constant.SalaryFormulaFieldConstant;
//import com.weaver.hrm.salary.entity.salaryitem.po.SalaryItemPO;
//import com.weaver.hrm.salary.entity.salarysob.po.SalarySobItemPO;
//import com.weaver.hrm.salary.enums.SalaryFormulaReferenceEnum;
//import com.weaver.hrm.salary.exception.SalaryRunTimeException;
//import com.weaver.hrm.salary.util.SalaryEntityUtil;
//import com.weaver.hrm.salary.util.SalaryI18nUtil;
//import lombok.AllArgsConstructor;
//import lombok.Builder;
//import lombok.Data;
//import lombok.NoArgsConstructor;
//import org.apache.commons.collections4.CollectionUtils;
//import org.apache.commons.lang3.StringUtils;
//import org.apache.curator.shaded.com.google.common.collect.Maps;
//
//import java.util.*;
//import java.util.regex.Matcher;
//import java.util.regex.Pattern;
//import java.util.stream.Collectors;
//
///**
// * @description: 薪资核算-薪资项目运算优先级
// * @author: xiajun
// * @modified By: xiajun
// * @date: Created in 2/7/22 2:49 PM
// * @version:v1.0
// */
//public class SalaryAcctCalculatePriorityBO {
//
// /**
// * 公式中变量的fieldId的正则表达式
// */
// private static final String SALARY_REGEX = "(\\w+)" + SalaryFormulaFieldConstant.FIELD_ID_SEPARATOR + "(\\w+)";
//
// /**
// * 解析公式中变量的fieldId的正则表达式
// */
// private static final Pattern SALARY_PATTERN = Pattern.compile(SALARY_REGEX);
//
// /**
// * 计算优先级
// *
// * @param salarySobItems
// * @param salaryItems
// * @param expressFormulas
// * @return 根据计算优先级已经排好序集合中是薪资账套中的薪资项目
// */
// public static List<List<Long>> calculatePriority(List<SalarySobItemPO> salarySobItems,
// List<SalaryItemPO> salaryItems,
// List<ExpressFormula> expressFormulas) {
// // 公式详情
// Map<Long, List<FormulaVar>> formulaIdKeyMap = ExpressFormulaBO.buildFormulaVar(expressFormulas);
// // key薪资项目的idvalue薪资项目的po
// Map<Long, SalaryItemPO> salaryItemPOMap = SalaryEntityUtil.convert2Map(salaryItems, SalaryItemPO::getId);
// // key薪资项目的codevalue薪资项目的po
// Map<String, SalaryItemPO> codeKeySalaryItemPOMap = SalaryEntityUtil.convert2Map(salaryItems, SalaryItemPO::getCode);
// // key薪资项目的idvalue薪资账套下的薪资项目副本的po
// Map<Long, SalarySobItemPO> salaryItemIdKeySalarySobItemPOMap = SalaryEntityUtil.convert2Map(salarySobItems, SalarySobItemPO::getSalaryItemId);
// Map<Long, SalaryItemIdWithPriority> salaryItemIdWithPriorityMap = Maps.newHashMapWithExpectedSize(salarySobItems.size());
// for (SalarySobItemPO salarySobItem : salarySobItems) {
// calculate(salarySobItem.getSalaryItemId(), salaryItemPOMap, codeKeySalaryItemPOMap, salaryItemIdKeySalarySobItemPOMap, formulaIdKeyMap, salaryItemIdWithPriorityMap, null);
// }
// return SalaryEntityUtil.group2Map(salaryItemIdWithPriorityMap.values(), SalaryItemIdWithPriority::getPriority).values().stream()
// .sorted(Comparator.comparingInt(list -> list.get(0).getPriority()))
// .map(list -> SalaryEntityUtil.properties(list, SalaryItemIdWithPriority::getSalaryItemId, Collectors.toList()))
// .collect(Collectors.toList());
// }
//
//
// /**
// * 计算薪资账套中的薪资项目的计算优先级
// *
// * @param currentSalaryItemId
// * @param salaryItemPOMap
// * @param salaryItemIdKeySalarySobItemPOMap
// * @param codeKeySalaryItemPOMap
// * @param formulaIdKeyMap
// * @param salaryItemIdWithPriorityMap
// * @param pre
// */
// private static void calculate(Long currentSalaryItemId,
// Map<Long, SalaryItemPO> salaryItemPOMap,
// Map<String, SalaryItemPO> codeKeySalaryItemPOMap,
// Map<Long, SalarySobItemPO> salaryItemIdKeySalarySobItemPOMap,
// Map<Long, List<FormulaVar>> formulaIdKeyMap,
// Map<Long, SalaryItemIdWithPriority> salaryItemIdWithPriorityMap,
// SalaryItemIdWithPriority pre) {
// List<Long> salaryItemIds = Lists.newArrayList();
// // 获取公式详情
// List<FormulaVar> formulaVars;
// if (salaryItemIdKeySalarySobItemPOMap.containsKey(currentSalaryItemId)) {
// // 如果薪资项目在薪资账套中有副本则取薪资账套中设置的公式
// SalarySobItemPO salarySobItemPO = salaryItemIdKeySalarySobItemPOMap.get(currentSalaryItemId);
// formulaVars = formulaIdKeyMap.getOrDefault(salarySobItemPO.getFormulaId(), Collections.emptyList());
// } else {
// // 如果薪资项目在薪资账套中没有有副本则取薪资项目中设置的公式
// SalaryItemPO salaryItemPO = salaryItemPOMap.get(currentSalaryItemId);
// formulaVars = formulaIdKeyMap.getOrDefault(salaryItemPO.getFormulaId(), Collections.emptyList());
// }
// // 解析公式详情中的变量找出引用了哪些其他的薪资项目需要先计算出引用的薪资项目才能计算当前的薪资项目
// for (FormulaVar formulaVar : formulaVars) {
// String fieldId = formulaVar.getFieldId();
// if (StringUtils.isEmpty(fieldId)) {
// continue;
// }
// Matcher matcher = SALARY_PATTERN.matcher(fieldId);
// if (matcher.find()) {
// SalaryFormulaReferenceEnum referenceEnum = SalaryFormulaReferenceEnum.parseByValue(matcher.group(1));
// if (referenceEnum == SalaryFormulaReferenceEnum.SALARY_ITEM) {
// SalaryItemPO salaryItemPO = codeKeySalaryItemPOMap.get(matcher.group(2));
// if (salaryItemPO == null) {
// continue;
// }
// salaryItemIds.add(salaryItemPO.getId());
// }
// }
// }
// if (CollectionUtils.isEmpty(salaryItemIds)) {
// SalaryItemIdWithPriority current = salaryItemIdWithPriorityMap.computeIfAbsent(currentSalaryItemId, k -> SalaryItemIdWithPriority.builder()
// .priority(0)
// .salaryItemId(currentSalaryItemId)
// .preList(Collections.emptyList())
// .build());
// addPre(current, pre, salaryItemPOMap);
// updatePriority(current);
// return;
// }
// for (Long salaryItemId : salaryItemIds) {
// SalaryItemIdWithPriority current = salaryItemIdWithPriorityMap.computeIfAbsent(currentSalaryItemId, k -> SalaryItemIdWithPriority.builder()
// .priority(1)
// .salaryItemId(currentSalaryItemId)
// .preList(Collections.emptyList())
// .build());
// addPre(current, pre, salaryItemPOMap);
// updatePriority(current);
// calculate(salaryItemId, salaryItemPOMap, codeKeySalaryItemPOMap, salaryItemIdKeySalarySobItemPOMap, formulaIdKeyMap, salaryItemIdWithPriorityMap, current);
// }
// }
//
// /**
// * 薪资项目被哪些薪资项目引用
// *
// * @param current
// * @param pre
// */
// private static void addPre(SalaryItemIdWithPriority current, SalaryItemIdWithPriority pre, Map<Long, SalaryItemPO> salaryItemPOMap) {
// if (pre == null) {
// return;
// }
// checkLoop(current, pre, salaryItemPOMap);
// if (CollectionUtils.isEmpty(current.getPreList())) {
// current.setPreList(Lists.newArrayList(pre));
// } else {
// boolean isExist = current.getPreList().stream().anyMatch(e -> Objects.equals(e.getSalaryItemId(), pre.getSalaryItemId()));
// if (!isExist) {
// current.getPreList().add(pre);
// }
// }
// }
//
// /**
// * 检查薪资项目之间是否存在相互引用
// *
// * @param current
// */
// private static void checkLoop(SalaryItemIdWithPriority current, SalaryItemIdWithPriority pre, Map<Long, SalaryItemPO> salaryItemPOMap) {
// if (Objects.equals(pre.getSalaryItemId(), current.getSalaryItemId())) {
// SalaryItemPO preSalaryItemPO = salaryItemPOMap.get(pre.getSalaryItemId());
// SalaryItemPO currentSalaryItemPO = salaryItemPOMap.get(current.getSalaryItemId());
// String errMsg = SalaryI18nUtil.getI18nLabel(101426, "{0}和{1}的公式中存在相互引用")
// .replace("{0}", Optional.ofNullable(preSalaryItemPO).map(SalaryItemPO::getName).orElse(StringUtils.EMPTY))
// .replace("{1}", Optional.ofNullable(currentSalaryItemPO).map(SalaryItemPO::getName).orElse(StringUtils.EMPTY));
// throw new SalaryRunTimeException(errMsg);
// }
// if (CollectionUtils.isEmpty(pre.getPreList())) {
// return;
// }
// for (SalaryItemIdWithPriority salaryItemIdWithPriority : pre.getPreList()) {
// checkLoop(current, salaryItemIdWithPriority, salaryItemPOMap);
// }
// }
//
// /**
// * 更新薪资账套中的薪资项目的计算优先级
// *
// * @param current
// */
// private static void updatePriority(SalaryItemIdWithPriority current) {
// List<SalaryItemIdWithPriority> preList = current.getPreList();
// if (CollectionUtils.isEmpty(preList)) {
// return;
// }
// preList.stream()
// .filter(e -> e.getPriority() <= current.getPriority())
// .forEach(e -> e.setPriority(current.getPriority() + 1));
// }
//
//
// @Data
// @Builder
// @NoArgsConstructor
// @AllArgsConstructor
// private static class SalaryItemIdWithPriority {
//
// /**
// * 薪资账套中的薪资项目的计算优先级数字越小计算优先级越高从0开始计算
// */
// private Integer priority;
//
// /**
// * 薪资项目的id
// */
// private Long salaryItemId;
//
// /**
// * 当前层级中的上层
// */
// private List<SalaryItemIdWithPriority> preList;
// }
//}
package com.engine.salary.entity.salaryacct.bo;
import com.engine.salary.constant.SalaryFormulaFieldConstant;
import com.engine.salary.entity.salaryitem.po.SalaryItemPO;
import com.engine.salary.entity.salarysob.po.SalarySobItemPO;
import com.engine.salary.enums.SalaryFormulaReferenceEnum;
import com.engine.salary.exception.SalaryRunTimeException;
import com.engine.salary.util.SalaryEntityUtil;
import com.engine.salary.util.SalaryI18nUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.weaver.excel.formula.api.entity.ExpressFormula;
import com.weaver.excel.formula.api.entity.FormulaVar;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/**
* @description: 薪资核算-薪资项目运算优先级
* @author: xiajun
* @modified By: xiajun
* @date: Created in 2/7/22 2:49 PM
* @version:v1.0
*/
public class SalaryAcctCalculatePriorityBO {
/**
* 公式中变量的fieldId的正则表达式
*/
private static final String SALARY_REGEX = "(\\w+)" + SalaryFormulaFieldConstant.FIELD_ID_SEPARATOR + "(\\w+)";
/**
* 解析公式中变量的fieldId的正则表达式
*/
private static final Pattern SALARY_PATTERN = Pattern.compile(SALARY_REGEX);
/**
* 计算优先级
*
* @param salarySobItems
* @param salaryItems
* @param expressFormulas
* @return 根据计算优先级已经排好序集合中是薪资账套中的薪资项目
*/
public static List<List<Long>> calculatePriority(List<SalarySobItemPO> salarySobItems,
List<SalaryItemPO> salaryItems,
List<ExpressFormula> expressFormulas) {
// 公式详情
Map<Long, List<FormulaVar>> formulaIdKeyMap = ExpressFormulaBO.buildFormulaVar(expressFormulas);
// key薪资项目的idvalue薪资项目的po
Map<Long, SalaryItemPO> salaryItemPOMap = SalaryEntityUtil.convert2Map(salaryItems, SalaryItemPO::getId);
// key薪资项目的codevalue薪资项目的po
Map<String, SalaryItemPO> codeKeySalaryItemPOMap = SalaryEntityUtil.convert2Map(salaryItems, SalaryItemPO::getCode);
// key薪资项目的idvalue薪资账套下的薪资项目副本的po
Map<Long, SalarySobItemPO> salaryItemIdKeySalarySobItemPOMap = SalaryEntityUtil.convert2Map(salarySobItems, SalarySobItemPO::getSalaryItemId);
Map<Long, SalaryItemIdWithPriority> salaryItemIdWithPriorityMap = Maps.newHashMapWithExpectedSize(salarySobItems.size());
for (SalarySobItemPO salarySobItem : salarySobItems) {
calculate(salarySobItem.getSalaryItemId(), salaryItemPOMap, codeKeySalaryItemPOMap, salaryItemIdKeySalarySobItemPOMap, formulaIdKeyMap, salaryItemIdWithPriorityMap, null);
}
return SalaryEntityUtil.group2Map(salaryItemIdWithPriorityMap.values(), SalaryItemIdWithPriority::getPriority).values().stream()
.sorted(Comparator.comparingInt(list -> list.get(0).getPriority()))
.map(list -> SalaryEntityUtil.properties(list, SalaryItemIdWithPriority::getSalaryItemId, Collectors.toList()))
.collect(Collectors.toList());
}
/**
* 计算薪资账套中的薪资项目的计算优先级
*
* @param currentSalaryItemId
* @param salaryItemPOMap
* @param salaryItemIdKeySalarySobItemPOMap
* @param codeKeySalaryItemPOMap
* @param formulaIdKeyMap
* @param salaryItemIdWithPriorityMap
* @param pre
*/
private static void calculate(Long currentSalaryItemId,
Map<Long, SalaryItemPO> salaryItemPOMap,
Map<String, SalaryItemPO> codeKeySalaryItemPOMap,
Map<Long, SalarySobItemPO> salaryItemIdKeySalarySobItemPOMap,
Map<Long, List<FormulaVar>> formulaIdKeyMap,
Map<Long, SalaryItemIdWithPriority> salaryItemIdWithPriorityMap,
SalaryItemIdWithPriority pre) {
List<Long> salaryItemIds = Lists.newArrayList();
// 获取公式详情
List<FormulaVar> formulaVars;
if (salaryItemIdKeySalarySobItemPOMap.containsKey(currentSalaryItemId)) {
// 如果薪资项目在薪资账套中有副本则取薪资账套中设置的公式
SalarySobItemPO salarySobItemPO = salaryItemIdKeySalarySobItemPOMap.get(currentSalaryItemId);
formulaVars = formulaIdKeyMap.getOrDefault(salarySobItemPO.getFormulaId(), Collections.emptyList());
} else {
// 如果薪资项目在薪资账套中没有有副本则取薪资项目中设置的公式
SalaryItemPO salaryItemPO = salaryItemPOMap.get(currentSalaryItemId);
formulaVars = formulaIdKeyMap.getOrDefault(salaryItemPO.getFormulaId(), Collections.emptyList());
}
// 解析公式详情中的变量找出引用了哪些其他的薪资项目需要先计算出引用的薪资项目才能计算当前的薪资项目
for (FormulaVar formulaVar : formulaVars) {
String fieldId = formulaVar.getFieldId();
if (StringUtils.isEmpty(fieldId)) {
continue;
}
Matcher matcher = SALARY_PATTERN.matcher(fieldId);
if (matcher.find()) {
SalaryFormulaReferenceEnum referenceEnum = SalaryFormulaReferenceEnum.parseByValue(matcher.group(1));
if (referenceEnum == SalaryFormulaReferenceEnum.SALARY_ITEM) {
SalaryItemPO salaryItemPO = codeKeySalaryItemPOMap.get(matcher.group(2));
if (salaryItemPO == null) {
continue;
}
salaryItemIds.add(salaryItemPO.getId());
}
}
}
if (CollectionUtils.isEmpty(salaryItemIds)) {
SalaryItemIdWithPriority current = salaryItemIdWithPriorityMap.computeIfAbsent(currentSalaryItemId, k -> SalaryItemIdWithPriority.builder()
.priority(0)
.salaryItemId(currentSalaryItemId)
.preList(Collections.emptyList())
.build());
addPre(current, pre, salaryItemPOMap);
updatePriority(current);
return;
}
for (Long salaryItemId : salaryItemIds) {
SalaryItemIdWithPriority current = salaryItemIdWithPriorityMap.computeIfAbsent(currentSalaryItemId, k -> SalaryItemIdWithPriority.builder()
.priority(1)
.salaryItemId(currentSalaryItemId)
.preList(Collections.emptyList())
.build());
addPre(current, pre, salaryItemPOMap);
updatePriority(current);
calculate(salaryItemId, salaryItemPOMap, codeKeySalaryItemPOMap, salaryItemIdKeySalarySobItemPOMap, formulaIdKeyMap, salaryItemIdWithPriorityMap, current);
}
}
/**
* 薪资项目被哪些薪资项目引用
*
* @param current
* @param pre
*/
private static void addPre(SalaryItemIdWithPriority current, SalaryItemIdWithPriority pre, Map<Long, SalaryItemPO> salaryItemPOMap) {
if (pre == null) {
return;
}
checkLoop(current, pre, salaryItemPOMap);
if (CollectionUtils.isEmpty(current.getPreList())) {
current.setPreList(Lists.newArrayList(pre));
} else {
boolean isExist = current.getPreList().stream().anyMatch(e -> Objects.equals(e.getSalaryItemId(), pre.getSalaryItemId()));
if (!isExist) {
current.getPreList().add(pre);
}
}
}
/**
* 检查薪资项目之间是否存在相互引用
*
* @param current
*/
private static void checkLoop(SalaryItemIdWithPriority current, SalaryItemIdWithPriority pre, Map<Long, SalaryItemPO> salaryItemPOMap) {
if (Objects.equals(pre.getSalaryItemId(), current.getSalaryItemId())) {
SalaryItemPO preSalaryItemPO = salaryItemPOMap.get(pre.getSalaryItemId());
SalaryItemPO currentSalaryItemPO = salaryItemPOMap.get(current.getSalaryItemId());
String errMsg = SalaryI18nUtil.getI18nLabel(101426, "{0}和{1}的公式中存在相互引用")
.replace("{0}", Optional.ofNullable(preSalaryItemPO).map(SalaryItemPO::getName).orElse(StringUtils.EMPTY))
.replace("{1}", Optional.ofNullable(currentSalaryItemPO).map(SalaryItemPO::getName).orElse(StringUtils.EMPTY));
throw new SalaryRunTimeException(errMsg);
}
if (CollectionUtils.isEmpty(pre.getPreList())) {
return;
}
for (SalaryItemIdWithPriority salaryItemIdWithPriority : pre.getPreList()) {
checkLoop(current, salaryItemIdWithPriority, salaryItemPOMap);
}
}
/**
* 更新薪资账套中的薪资项目的计算优先级
*
* @param current
*/
private static void updatePriority(SalaryItemIdWithPriority current) {
List<SalaryItemIdWithPriority> preList = current.getPreList();
if (CollectionUtils.isEmpty(preList)) {
return;
}
preList.stream()
.filter(e -> e.getPriority() <= current.getPriority())
.forEach(e -> e.setPriority(current.getPriority() + 1));
}
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
private static class SalaryItemIdWithPriority {
/**
* 薪资账套中的薪资项目的计算优先级数字越小计算优先级越高从0开始计算
*/
private Integer priority;
/**
* 薪资项目的id
*/
private Long salaryItemId;
/**
* 当前层级中的上层
*/
private List<SalaryItemIdWithPriority> preList;
}
}

View File

@ -1,91 +1,91 @@
//package com.engine.salary.entity.salaryacct.bo;
//
//import com.google.common.collect.Lists;
//import com.weaver.hrm.salary.constant.TaxDeclarationDataIndexConstant;
//import com.weaver.hrm.salary.entity.salaryacct.po.SalaryAcctResultPO;
//import com.weaver.hrm.salary.entity.salaryitem.po.SalaryItemPO;
//import com.weaver.hrm.salary.util.SalaryEntityUtil;
//import org.apache.commons.lang3.StringUtils;
//
//import java.math.BigDecimal;
//import java.util.List;
//import java.util.Objects;
//import java.util.Optional;
//
//public class SalaryAcctConsolidatedTaxBO {
//
// /**
// * 处理合并计税的字段的值
// *
// * @param resultValue 本次薪资核算的结果
// * @param salaryItem 当前正在核算的薪资项目
// * @param salaryItems 系统内所有的薪资项目
// * @param salaryAcctResults 其他设计合并计税的薪资核算结果
// * @return
// */
// public static String handleConsolidatedTaxValue(String resultValue,
// SalaryItemPO salaryItem,
// List<SalaryItemPO> salaryItems,
// List<SalaryAcctResultPO> salaryAcctResults) {
// // 社保福利的当月值都是0
// List<String> welfareDataIndexList = Lists.newArrayList(TaxDeclarationDataIndexConstant.ENDOWMENT_INSURANCE,
// TaxDeclarationDataIndexConstant.MEDICAL_INSURANCE,
// TaxDeclarationDataIndexConstant.UNEMPLOYMENT_INSURANCE,
// TaxDeclarationDataIndexConstant.HOUSING_PROVIDENT_FUND,
// TaxDeclarationDataIndexConstant.SOCIAL_SECURITY_TOTAL,
// TaxDeclarationDataIndexConstant.ACCUMULATION_FUND_TOTAL,
// TaxDeclarationDataIndexConstant.SPECIAL_DEDUCTION);
// if (welfareDataIndexList.contains(salaryItem.getCode())) {
// return BigDecimal.ZERO.toPlainString();
// }
// // 专项附加扣除的当月值都是0
// List<String> speAddiDeductionDataIndexList = Lists.newArrayList(TaxDeclarationDataIndexConstant.ADD_UP_CHILD_EDUCATION,
// TaxDeclarationDataIndexConstant.ADD_UP_HOUSING_LOAN_INTEREST,
// TaxDeclarationDataIndexConstant.ADD_UP_HOUSING_RENT,
// TaxDeclarationDataIndexConstant.ADD_UP_CONTINUING_EDUCATION,
// TaxDeclarationDataIndexConstant.ADD_UP_SUPPORT_ELDERLY,
// TaxDeclarationDataIndexConstant.ADD_UP_ILLNESS_MEDICAL);
// if (speAddiDeductionDataIndexList.contains(salaryItem.getCode())) {
// return BigDecimal.ZERO.toPlainString();
// }
// // 本月减除费用也是0
// if (TaxDeclarationDataIndexConstant.SUBTRACTION.equals(salaryItem.getCode())) {
// return BigDecimal.ZERO.toPlainString();
// }
// // 当前累计减除费用当前累计专项扣除合计当前累计专项附加扣除合计
// if (TaxDeclarationDataIndexConstant.ADD_UP_SUBTRACTION.equals(salaryItem.getCode())
// || TaxDeclarationDataIndexConstant.ADD_UP_SPECIAL_DEDUCTION.equals(salaryItem.getCode())
// || TaxDeclarationDataIndexConstant.ADD_UP_SPE_ADDI_DEDUCTION.equals(salaryItem.getCode())) {
// return salaryAcctResults.stream()
// .filter(e -> Objects.equals(e.getSalaryItemId(), salaryItem.getId()))
// .map(SalaryAcctResultPO::getResultValue)
// .findFirst()
// .orElse("");
// }
// // 当前累计收入 = 累计值 + 本次收入 + 上几次收入
// if (TaxDeclarationDataIndexConstant.ADD_UP_INCOME.equals(salaryItem.getCode())) {
// Optional<Long> optional = salaryItems.stream().filter(e -> StringUtils.equals(e.getCode(), "income")).map(SalaryItemPO::getId).findAny();
// if (!optional.isPresent()) {
// return "";
// }
// BigDecimal income = salaryAcctResults.stream()
// .filter(e -> Objects.equals(e.getSalaryItemId(), optional.get()))
// .map(e -> SalaryEntityUtil.empty2Zero(e.getResultValue()))
// .reduce(BigDecimal.ZERO, BigDecimal::add);
// return new BigDecimal(resultValue).add(income).toPlainString();
// }
// // 当前累计已扣缴税额合计 = 累计值 + 上几次预扣预缴个税
// if (TaxDeclarationDataIndexConstant.ADD_UP_ADVANCE_TAX.equals(salaryItem.getCode())) {
// Optional<Long> optional = salaryItems.stream().filter(e -> StringUtils.equals(e.getCode(), "refundedOrSupplementedTax")).map(SalaryItemPO::getId).findAny();
// if (!optional.isPresent()) {
// return "";
// }
// BigDecimal refundedOrSupplementedTax = salaryAcctResults.stream()
// .filter(e -> Objects.equals(e.getSalaryItemId(), optional.get()))
// .map(e -> SalaryEntityUtil.empty2Zero(e.getResultValue()))
// .reduce(BigDecimal.ZERO, BigDecimal::add);
// return new BigDecimal(resultValue).add(refundedOrSupplementedTax).toPlainString();
// }
// return resultValue;
// }
//}
package com.engine.salary.entity.salaryacct.bo;
import com.engine.salary.constant.TaxDeclarationDataIndexConstant;
import com.engine.salary.entity.salaryacct.po.SalaryAcctResultPO;
import com.engine.salary.entity.salaryitem.po.SalaryItemPO;
import com.engine.salary.util.SalaryEntityUtil;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import java.math.BigDecimal;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
public class SalaryAcctConsolidatedTaxBO {
/**
* 处理合并计税的字段的值
*
* @param resultValue 本次薪资核算的结果
* @param salaryItem 当前正在核算的薪资项目
* @param salaryItems 系统内所有的薪资项目
* @param salaryAcctResults 其他设计合并计税的薪资核算结果
* @return
*/
public static String handleConsolidatedTaxValue(String resultValue,
SalaryItemPO salaryItem,
List<SalaryItemPO> salaryItems,
List<SalaryAcctResultPO> salaryAcctResults) {
// 社保福利的当月值都是0
List<String> welfareDataIndexList = Lists.newArrayList(TaxDeclarationDataIndexConstant.ENDOWMENT_INSURANCE,
TaxDeclarationDataIndexConstant.MEDICAL_INSURANCE,
TaxDeclarationDataIndexConstant.UNEMPLOYMENT_INSURANCE,
TaxDeclarationDataIndexConstant.HOUSING_PROVIDENT_FUND,
TaxDeclarationDataIndexConstant.SOCIAL_SECURITY_TOTAL,
TaxDeclarationDataIndexConstant.ACCUMULATION_FUND_TOTAL,
TaxDeclarationDataIndexConstant.SPECIAL_DEDUCTION);
if (welfareDataIndexList.contains(salaryItem.getCode())) {
return BigDecimal.ZERO.toPlainString();
}
// 专项附加扣除的当月值都是0
List<String> speAddiDeductionDataIndexList = Lists.newArrayList(TaxDeclarationDataIndexConstant.ADD_UP_CHILD_EDUCATION,
TaxDeclarationDataIndexConstant.ADD_UP_HOUSING_LOAN_INTEREST,
TaxDeclarationDataIndexConstant.ADD_UP_HOUSING_RENT,
TaxDeclarationDataIndexConstant.ADD_UP_CONTINUING_EDUCATION,
TaxDeclarationDataIndexConstant.ADD_UP_SUPPORT_ELDERLY,
TaxDeclarationDataIndexConstant.ADD_UP_ILLNESS_MEDICAL);
if (speAddiDeductionDataIndexList.contains(salaryItem.getCode())) {
return BigDecimal.ZERO.toPlainString();
}
// 本月减除费用也是0
if (TaxDeclarationDataIndexConstant.SUBTRACTION.equals(salaryItem.getCode())) {
return BigDecimal.ZERO.toPlainString();
}
// 当前累计减除费用当前累计专项扣除合计当前累计专项附加扣除合计
if (TaxDeclarationDataIndexConstant.ADD_UP_SUBTRACTION.equals(salaryItem.getCode())
|| TaxDeclarationDataIndexConstant.ADD_UP_SPECIAL_DEDUCTION.equals(salaryItem.getCode())
|| TaxDeclarationDataIndexConstant.ADD_UP_SPE_ADDI_DEDUCTION.equals(salaryItem.getCode())) {
return salaryAcctResults.stream()
.filter(e -> Objects.equals(e.getSalaryItemId(), salaryItem.getId()))
.map(SalaryAcctResultPO::getResultValue)
.findFirst()
.orElse("");
}
// 当前累计收入 = 累计值 + 本次收入 + 上几次收入
if (TaxDeclarationDataIndexConstant.ADD_UP_INCOME.equals(salaryItem.getCode())) {
Optional<Long> optional = salaryItems.stream().filter(e -> StringUtils.equals(e.getCode(), "income")).map(SalaryItemPO::getId).findAny();
if (!optional.isPresent()) {
return "";
}
BigDecimal income = salaryAcctResults.stream()
.filter(e -> Objects.equals(e.getSalaryItemId(), optional.get()))
.map(e -> SalaryEntityUtil.empty2Zero(e.getResultValue()))
.reduce(BigDecimal.ZERO, BigDecimal::add);
return new BigDecimal(resultValue).add(income).toPlainString();
}
// 当前累计已扣缴税额合计 = 累计值 + 上几次预扣预缴个税
if (TaxDeclarationDataIndexConstant.ADD_UP_ADVANCE_TAX.equals(salaryItem.getCode())) {
Optional<Long> optional = salaryItems.stream().filter(e -> StringUtils.equals(e.getCode(), "refundedOrSupplementedTax")).map(SalaryItemPO::getId).findAny();
if (!optional.isPresent()) {
return "";
}
BigDecimal refundedOrSupplementedTax = salaryAcctResults.stream()
.filter(e -> Objects.equals(e.getSalaryItemId(), optional.get()))
.map(e -> SalaryEntityUtil.empty2Zero(e.getResultValue()))
.reduce(BigDecimal.ZERO, BigDecimal::add);
return new BigDecimal(resultValue).add(refundedOrSupplementedTax).toPlainString();
}
return resultValue;
}
}

View File

@ -6,7 +6,8 @@ import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.Date;
/**
* @description: 薪资核算结果临时存储
@ -86,10 +87,14 @@ public class SalaryAcctResultTempPO {
/**
* 创建时间
*/
private LocalDateTime createTime;
private Date createTime;
/**
* 更新时间
*/
private LocalDateTime updateTime;
private Date updateTime;
//条件
Collection<Long> ids;
}

View File

@ -6,12 +6,13 @@ import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @description: 薪资公式计算器-员工基本信息
* @author: xiajun
* @modified By: xiajun
* @date: Created in 11/19/21 1:46 PM
* @version:v1.0
*/
* 薪资公式计算器-员工基本信息
* <p>Copyright: Copyright (c) 2022</p>
* <p>Company: 泛微软件</p>
*
* @author qiantao
* @version 1.0
**/
@Data
@Builder
@NoArgsConstructor

View File

@ -0,0 +1,109 @@
package com.engine.salary.entity.taxrate;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.Date;
/**
* 系统默认的税率表明细
* <p>Copyright: Copyright (c) 2022</p>
* <p>Company: 泛微软件</p>
*
* @author qiantao
* @version 1.0
**/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
//hrsa_sys_tax_rate_detail
public class SysTaxRateDetailPO {
/**
* 主键id
*/
private Long id;
/**
* 税率主表的id
*/
private Long baseId;
/**
* 序号
*/
private Integer indexNum;
/**
* 收入上限
*/
private BigDecimal incomeUpperLimit;
/**
* 收入下限不含
*/
private BigDecimal incomeLowerLimit;
/**
* 免税标准-固定值
*/
private BigDecimal dutyFreeValue;
/**
* 免税标准-比例
*/
private BigDecimal dutyFreeRate;
/**
* 应纳税所得额上限
*/
private BigDecimal taxableIncomeULimit;
/**
* 应纳税所得额下限不含
*/
private BigDecimal taxableIncomeLLimit;
/**
* 税率
*/
private BigDecimal taxRate;
/**
* 速算扣除数
*/
private BigDecimal taxDeduction;
/**
* 租户key
*/
private String tenantKey;
/**
* 创建人id
*/
private Long creator;
/**
* 是否删除
*/
private Integer deleteType;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新时间
*/
private Date updateTime;
//条件
Collection<Long> ids;
}

View File

@ -1,13 +1,13 @@
package com.engine.salary.entity.taxrate;
import java.util.Date;
import java.math.BigDecimal;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
import java.util.Date;
/**
* 税率明细表
*/

View File

@ -14,12 +14,13 @@ import java.util.*;
import java.util.stream.Collectors;
/**
* @description: 税率表业务方法
* @author: xiajun
* @modified By: xiajun
* @date: Created in 10/19/21 4:14 PM
* @version:v1.0
*/
* 税率表业务方法
* <p>Copyright: Copyright (c) 2022</p>
* <p>Company: 泛微软件</p>
*
* @author qiantao
* @version 1.0
**/
public class TaxRateBO {
private TaxRateBO() {
@ -134,52 +135,4 @@ public class TaxRateBO {
.collect(Collectors.toList());
}
// /**
// * 个税税率表明细表的前端表格的表头
// *
// * @return
// */
// public static List<WeaTableColumn> buildRecordTableColumns() {
// List<WeaTableColumn> result = Lists.newArrayListWithExpectedSize(9);
// result.add(new WeaTableColumnWapper(SalaryI18nUtil.getI18nLabel(84162, "序号"), TaxRateDataIndexConstant.INDEX_NUM, "150",
// WeaAlignEnum.LEFT.getStringVal(), WeaAlignEnum.LEFT.getStringVal(), TaxRateDataIndexConstant.INDEX_NUM));
// result.add(new WeaTableColumnWapper(SalaryI18nUtil.getI18nLabel(91070, "下限(不含)"), TaxRateDataIndexConstant.INCOME_LOWER_LIMIT, "150",
// WeaAlignEnum.LEFT.getStringVal(), WeaAlignEnum.LEFT.getStringVal(), TaxRateDataIndexConstant.INCOME_LOWER_LIMIT));
// result.add(new WeaTableColumnWapper(SalaryI18nUtil.getI18nLabel(91071, "上限(含)"), TaxRateDataIndexConstant.INCOME_UPPER_LIMIT, "150",
// WeaAlignEnum.LEFT.getStringVal(), WeaAlignEnum.LEFT.getStringVal(), TaxRateDataIndexConstant.INCOME_UPPER_LIMIT));
// result.add(new WeaTableColumnWapper(SalaryI18nUtil.getI18nLabel(91072, "固定值"), TaxRateDataIndexConstant.DUTY_FREE_VALUE, "150",
// WeaAlignEnum.LEFT.getStringVal(), WeaAlignEnum.LEFT.getStringVal(), TaxRateDataIndexConstant.DUTY_FREE_VALUE));
// result.add(new WeaTableColumnWapper(SalaryI18nUtil.getI18nLabel(91073, "比例"), TaxRateDataIndexConstant.DUTY_FREE_RATE, "150",
// WeaAlignEnum.LEFT.getStringVal(), WeaAlignEnum.LEFT.getStringVal(), TaxRateDataIndexConstant.DUTY_FREE_RATE));
// result.add(new WeaTableColumnWapper(SalaryI18nUtil.getI18nLabel(91070, "下限(不含)"), TaxRateDataIndexConstant.TAXABLE_INCOME_LOWER_LIMIT, "150",
// WeaAlignEnum.LEFT.getStringVal(), WeaAlignEnum.LEFT.getStringVal(), TaxRateDataIndexConstant.TAXABLE_INCOME_LOWER_LIMIT));
// result.add(new WeaTableColumnWapper(SalaryI18nUtil.getI18nLabel(91071, "上限(含)"), TaxRateDataIndexConstant.TAXABLE_INCOME_UPPER_LIMIT, "150",
// WeaAlignEnum.LEFT.getStringVal(), WeaAlignEnum.LEFT.getStringVal(), TaxRateDataIndexConstant.TAXABLE_INCOME_UPPER_LIMIT));
// result.add(new WeaTableColumnWapper(SalaryI18nUtil.getI18nLabel(84227, "税率"), TaxRateDataIndexConstant.TAX_RATE, "150",
// WeaAlignEnum.LEFT.getStringVal(), WeaAlignEnum.LEFT.getStringVal(), TaxRateDataIndexConstant.TAX_RATE));
// result.add(new WeaTableColumnWapper(SalaryI18nUtil.getI18nLabel(84228, "速算扣除数"), TaxRateDataIndexConstant.TAX_DEDUCTION, "150",
// WeaAlignEnum.LEFT.getStringVal(), WeaAlignEnum.LEFT.getStringVal(), TaxRateDataIndexConstant.TAX_DEDUCTION));
// return result;
// }
//
// /**
// * 新建个税税率表时明细会默认自带一条空数据
// *
// * @param systemType
// * @return
// */
// public static Map<String, EditableTableItem> buildEditableTableItemMap(SalarySystemTypeEnum systemType) {
// boolean readOnly = systemType == SalarySystemTypeEnum.SYSTEM;
// Map<String, EditableTableItem> resultMap = Maps.newHashMapWithExpectedSize(9);
// resultMap.put(TaxRateDataIndexConstant.INDEX_NUM, new EditableTableItem(EditableTableItemType.INPUTNUMBER, "", true));
// resultMap.put(TaxRateDataIndexConstant.INCOME_LOWER_LIMIT, new EditableTableItem(EditableTableItemType.INPUTNUMBER, "", readOnly, null, false, 9999999999L, 2, true));
// resultMap.put(TaxRateDataIndexConstant.INCOME_UPPER_LIMIT, new EditableTableItem(EditableTableItemType.INPUTNUMBER, "", readOnly, null, false, 9999999999L, 2, true));
// resultMap.put(TaxRateDataIndexConstant.DUTY_FREE_VALUE, new EditableTableItem(EditableTableItemType.INPUTNUMBER, "", readOnly, null, false, 9999999999L, 2, true));
// resultMap.put(TaxRateDataIndexConstant.DUTY_FREE_RATE, new EditableTableItem(EditableTableItemType.INPUTNUMBER, "", readOnly, null, false, 9999999999L, 2, true));
// resultMap.put(TaxRateDataIndexConstant.TAXABLE_INCOME_LOWER_LIMIT, new EditableTableItem(EditableTableItemType.INPUTNUMBER, "", readOnly, null, false, 9999999999L, 2, true));
// resultMap.put(TaxRateDataIndexConstant.TAXABLE_INCOME_UPPER_LIMIT, new EditableTableItem(EditableTableItemType.INPUTNUMBER, "", readOnly, null, false, 9999999999L, 2, true));
// resultMap.put(TaxRateDataIndexConstant.TAX_RATE, new EditableTableItem(EditableTableItemType.INPUTNUMBER, "", readOnly, null, false, 1L, 2, true));
// resultMap.put(TaxRateDataIndexConstant.TAX_DEDUCTION, new EditableTableItem(EditableTableItemType.INPUTNUMBER, "", readOnly, null, false, 9999999999L, 2, true));
// return resultMap;
// }
}

View File

@ -1,22 +1,24 @@
package com.engine.salary.entity.taxrate.bo;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
* @description: 税率表明细
* @author: xiajun
* @modified By: xiajun
* @date: Created in 2/18/22 2:07 PM
* @version:v1.0
*/
public class TaxRateDetailBO {
//package com.engine.salary.entity.taxrate.bo;
//
//import com.engine.salary.entity.taxrate.TaxRateDetail;
//import com.engine.salary.util.JsonUtil;
//import org.apache.commons.collections4.CollectionUtils;
//import org.apache.commons.lang3.StringUtils;
//
//import java.util.Collection;
//import java.util.List;
//import java.util.Map;
//import java.util.Objects;
//
///**
// * @description: 税率表明细
// * @author: xiajun
// * @modified By: xiajun
// * @date: Created in 2/18/22 2:07 PM
// * @version:v1.0
// */
//public class TaxRateDetailBO {
//
// /**
// * 根据公式条件获取对应的税率
// *
@ -25,7 +27,7 @@ public class TaxRateDetailBO {
// * @param formulaFilterDataList
// * @return
// */
// public static TaxRateDetailPO filter(List<TaxRateDetailPO> taxRateDetailPOS, boolean isOr, Collection<FormulaFilterData> formulaFilterDataList) {
// public static TaxRateDetail filter(List<TaxRateDetail> taxRateDetailPOS, boolean isOr, Collection<FormulaFilterData> formulaFilterDataList) {
// if (CollectionUtils.isEmpty(taxRateDetailPOS)) {
// return null;
// }
@ -57,7 +59,7 @@ public class TaxRateDetailBO {
// * @param formulaFilterData
// * @return
// */
// private static boolean filterByFormulaFilterData(TaxRateDetailPO taxRateDetailPO, FormulaFilterData formulaFilterData) {
// private static boolean filterByFormulaFilterData(TaxRateDetail taxRateDetailPO, FormulaFilterData formulaFilterData) {
// Map<String, Object> map = JsonUtil.parseMap(taxRateDetailPO, Object.class);
// switch (formulaFilterData.getTerm()) {
// case FormulaFilterData.TERM_EQ:
@ -88,4 +90,4 @@ public class TaxRateDetailBO {
// return false;
// }
// }
}
//}

View File

@ -17,12 +17,11 @@ public enum SalaryFormulaReferenceEnum implements BaseEnum<Integer> {
EMPLOYEE_INFO(3, "员工基本信息", 85366),
SALARY_ARCHIVES(4, "薪资档案", 85368),
ATTEND(5, "考勤引用", 85367),
CUMULATIVE_SITUATION(6, "累计情况(工资、薪金)", 87521),
SPECIAL_EXPENSE_DEDUCTIONS(7, "累计专项附加扣除", 85380),
SOCIAL_SECURITY(8, "社保福利", 87522),
ADD_UP_SITUATION(6, "往期累计情况", 104412),
ADD_UP_DEDUCTIONS(7, "累计专项附加扣除", 85380),
WELFARE(8, "社保福利", 87522),
OTHER_DEDUCTION(9, "其他免税扣除", 93849),
;
private int value;
private String defaultLabel;

View File

@ -0,0 +1,20 @@
package com.engine.salary.mapper;
import com.engine.salary.entity.taxrate.SysTaxRateDetailPO;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface SysTaxRateDetailMapper {
/**
* 查询所有记录
*
* @return 返回集合没有返回空List
*/
List<SysTaxRateDetailPO> listByBaseId(Long baseId);
}

View File

@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.engine.salary.mapper.SysTaxRateDetailMapper">
<resultMap id="BaseResultMap" type="com.engine.salary.entity.taxrate.SysTaxRateDetailPO">
<result column="id" property="id"/>
<result column="base_id" property="baseId"/>
<result column="index_num" property="indexNum"/>
<result column="income_lower_limit" property="incomeLowerLimit"/>
<result column="income_upper_limit" property="incomeUpperLimit"/>
<result column="duty_free_value" property="dutyFreeValue"/>
<result column="duty_free_rate" property="dutyFreeRate"/>
<result column="taxable_income_ll" property="incomeLowerLimit"/>
<result column="taxable_income_ul" property="taxableIncomeULimit"/>
<result column="tax_rate" property="taxRate"/>
<result column="tax_deduction" property="taxDeduction"/>
<result column="create_time" property="createTime"/>
<result column="update_time" property="updateTime"/>
<result column="creator" property="creator"/>
<result column="delete_type" property="deleteType"/>
<result column="tenant_key" property="tenantKey"/>
</resultMap>
<!-- 表字段 -->
<sql id="baseColumns">
t
.
id
, t.base_id
, t.index_num
, t.income_lower_limit
, t.income_upper_limit
, t.duty_free_value
, t.duty_free_rate
, t.taxable_income_ll
, t.taxable_income_ul
, t.tax_rate
, t.tax_deduction
, t.create_time
, t.update_time
, t.creator
, t.delete_type
, t.tenant_key
</sql>
<!-- 查询全部 -->
<select id="listByBaseId" resultMap="BaseResultMap">
SELECT
<include refid="baseColumns"/>
FROM hrsa_sys_tax_rate_detail t
WHERE delete_type = 0
and base_id =#{baseId}
</select>
</mapper>

View File

@ -523,7 +523,13 @@
FROM hrsa_add_up_deduction t
WHERE delete_type = 0
<if test="param.declareMonth != null">
and declare_month = #{param.declareMonth}
and declare_month = #{param.declareMonth}
</if>
<if test="param.employeeIds != null and param.employeeIds.size()>0">
AND employee_id IN
<foreach collection="param.employeeIds" open="(" item="employeeId" separator="," close=")">
#{employeeId}
</foreach>
</if>
</select>

View File

@ -96,5 +96,6 @@ public interface AddUpSituationMapper {
* @param updateList
*/
void updateData(@Param("collection") List<AddUpSituation> updateList);
void deleteSome(@Param("param") AddUpSituation params);
}

View File

@ -963,7 +963,26 @@
<if test="param.taxYearMonth != null">
and tax_year_month = #{param.taxYearMonth}
</if>
<if test="param.employeeIds != null and param.employeeIds.size()>0">
AND employee_id IN
<foreach collection="param.employeeIds" open="(" item="employeeId" separator="," close=")">
#{employeeId}
</foreach>
</if>
</select>
<delete id="deleteSome">
UPDATE hrsa_add_up_situation
SET delete_type=1
WHERE id = #{id} AND delete_type = 0
AND tax_year_month = #{param.taxYearMonth}
<if test="param.employeeIds != null and param.employeeIds.size()>0">
AND employee_id IN
<foreach collection="param.employeeIds" open="(" item="employeeId" separator="," close=")">
#{employeeId}
</foreach>
</if>
</delete>
</mapper>

View File

@ -0,0 +1,54 @@
package com.engine.salary.mapper.salaryacct;
import com.engine.salary.entity.salaryacct.po.SalaryAcctResultTempPO;
import org.apache.ibatis.annotations.Param;
import java.util.Collection;
import java.util.List;
/**
* 薪资核算结果临时存储
* <p>Copyright: Copyright (c) 2022</p>
* <p>Company: 泛微软件</p>
*
* @author qiantao
* @version 1.0
**/
public interface SalaryAcctResultTempMapper {
/**
* 批量插入
*
* @param salaryAcctResultTemps
*/
void batchInsert(@Param("collection") Collection<SalaryAcctResultTempPO> salaryAcctResultTemps);
/**
* 根据薪资核算记录id删除薪资核算结果
*
* @param salaryAcctRecordIds
*/
void deleteBySalaryAcctRecordIds(@Param("salaryAcctRecordIds") Collection<Long> salaryAcctRecordIds);
/**
* 根据薪资核算人员id删除薪资核算结果
*
* @param salaryAcctEmpIds
*/
void deleteBySalaryAcctEmpIds(@Param("salaryAcctEmpIds") Collection<Long> salaryAcctEmpIds);
/**
* 根据key删除薪资核算结果
*
* @param calculateKey
*/
void deleteByCalculateKey(@Param("calculateKey") String calculateKey);
/**
* 条件查询
*
* @return 返回集合没有返回空List
*/
List<SalaryAcctResultTempPO> listSome(SalaryAcctResultTempPO acctResultTemp);
}

View File

@ -0,0 +1,194 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.engine.salary.mapper.salaryacct.SalaryAcctResultTempMapper">
<insert id="batchInsert">
INSERT INTO hrsa_acct_result_temp(salary_sob_id, salary_acct_emp_id, salary_acct_record_id, employee_id,
tax_agent_id, salary_item_id, result_value, calculate_key, creator, create_time, update_time, delete_type,
tenant_key)
VALUES
<foreach collection="collection" item="item" separator=",">
(
#{item.salarySobId},
#{item.salaryAcctEmpId},
#{item.salaryAcctRecordId},
#{item.employeeId},
#{item.taxAgentId},
#{item.salaryItemId},
#{item.resultValue},
#{item.calculateKey},
#{item.creator},
#{item.createTime},
#{item.updateTime},
#{item.deleteType},
#{item.tenantKey}
)
</foreach>
</insert>
<insert id="batchInsert" databaseId="oracle">
INSERT INTO hrsa_acct_result_temp(salary_sob_id, salary_acct_emp_id, salary_acct_record_id, employee_id,
tax_agent_id, salary_item_id, result_value, calculate_key, creator, create_time, update_time, delete_type,
tenant_key)
<foreach collection="collection" item="item" separator="union all">
select
#{item.salarySobId},
#{item.salaryAcctEmpId},
#{item.salaryAcctRecordId},
#{item.employeeId},
#{item.taxAgentId},
#{item.salaryItemId},
#{item.resultValue},
#{item.calculateKey},
#{item.creator},
#{item.createTime},
#{item.updateTime},
#{item.deleteType},
#{item.tenantKey}
from dual
</foreach>
</insert>
<insert id="batchInsert" databaseId="sqlserver">
INSERT INTO hrsa_acct_result_temp( salary_sob_id, salary_acct_emp_id, salary_acct_record_id, employee_id,
tax_agent_id, salary_item_id, result_value, calculate_key, creator, create_time, update_time, delete_type,
tenant_key)
VALUES
<foreach collection="collection" item="item" separator=",">
(
#{item.salarySobId},
#{item.salaryAcctEmpId},
#{item.salaryAcctRecordId},
#{item.employeeId},
#{item.taxAgentId},
#{item.salaryItemId},
#{item.resultValue},
#{item.calculateKey},
#{item.creator},
#{item.createTime},
#{item.updateTime},
#{item.deleteType},
#{item.tenantKey}
)
</foreach>
</insert>
<delete id="deleteBySalaryAcctRecordIds">
DELETE FROM hrsa_acct_result_temp
WHERE AND delete_type = 0
AND salary_acct_record_id IN
<foreach collection="salaryAcctRecordIds" open="(" item="salaryAcctRecordId" separator="," close=")">
#{salaryAcctRecordId}
</foreach>
</delete>
<delete id="deleteBySalaryAcctEmpIds">
DELETE FROM hrsa_acct_result_temp
WHERE delete_type = 0
AND salary_acct_emp_id IN
<foreach collection="salaryAcctEmpIds" open="(" item="salaryAcctEmpId" separator="," close=")">
#{salaryAcctEmpId}
</foreach>
</delete>
<delete id="deleteByCalculateKey">
DELETE FROM hrsa_acct_result_temp
WHERE delete_type = 0
AND calculate_key = #{calculateKey}
</delete>
<resultMap id="BaseResultMap" type="com.engine.salary.entity.salaryacct.po.SalaryAcctResultTempPO">
<result column="id" property="id" />
<result column="calculate_key" property="calculateKey" />
<result column="salary_sob_id" property="salarySobId" />
<result column="salary_acct_emp_id" property="salaryAcctEmpId" />
<result column="salary_acct_record_id" property="salaryAcctRecordId" />
<result column="employee_id" property="employeeId" />
<result column="tax_agent_id" property="taxAgentId" />
<result column="salary_item_id" property="salaryItemId" />
<result column="result_value" property="resultValue" />
<result column="creator" property="creator" />
<result column="create_time" property="createTime" />
<result column="update_time" property="updateTime" />
<result column="delete_type" property="deleteType" />
<result column="tenant_key" property="tenantKey" />
</resultMap>
<!-- 表字段 -->
<sql id="baseColumns">
t.id
, t.calculate_key
, t.salary_sob_id
, t.salary_acct_emp_id
, t.salary_acct_record_id
, t.employee_id
, t.tax_agent_id
, t.salary_item_id
, t.result_value
, t.creator
, t.create_time
, t.update_time
, t.delete_type
, t.tenant_key
</sql>
<!-- 条件查询 -->
<select id="listSome" resultMap="BaseResultMap" parameterType="com.engine.salary.entity.salaryacct.po.SalaryAcctResultTempPO">
SELECT
<include refid="baseColumns" />
FROM hrsa_acct_result_temp t
WHERE delete_type = 0
<if test="id != null">
AND id = #{id}
</if>
<if test="calculateKey != null">
AND calculate_key = #{calculateKey}
</if>
<if test="salarySobId != null">
AND salary_sob_id = #{salarySobId}
</if>
<if test="salaryAcctEmpId != null">
AND salary_acct_emp_id = #{salaryAcctEmpId}
</if>
<if test="salaryAcctRecordId != null">
AND salary_acct_record_id = #{salaryAcctRecordId}
</if>
<if test="employeeId != null">
AND employee_id = #{employeeId}
</if>
<if test="taxAgentId != null">
AND tax_agent_id = #{taxAgentId}
</if>
<if test="salaryItemId != null">
AND salary_item_id = #{salaryItemId}
</if>
<if test="resultValue != null">
AND result_value = #{resultValue}
</if>
<if test="creator != null">
AND creator = #{creator}
</if>
<if test="createTime != null">
AND create_time = #{createTime}
</if>
<if test="updateTime != null">
AND update_time = #{updateTime}
</if>
<if test="deleteType != null">
AND delete_type = #{deleteType}
</if>
<if test="tenantKey != null">
AND tenant_key = #{tenantKey}
</if>
<if test="ids != null and ids.size()>0">
AND id IN
<foreach collection="ids" open="(" item="id" separator="," close=")">
#{id}
</foreach>
</if>
ORDER BY id DESC
</select>
</mapper>

View File

@ -1,7 +1,10 @@
package com.engine.salary.service;
import com.engine.salary.entity.datacollection.AddUpDeduction;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.time.YearMonth;
import java.util.List;
import java.util.Map;
public interface AddUpDeductionService {
@ -19,4 +22,13 @@ public interface AddUpDeductionService {
Map<String, Object> preview(Map<String, Object> params);
XSSFWorkbook exportDetail(Map<String, Object> map);
/**
* 获取累计专项附加扣除数据
*
* @param declareMonth
* @param employeeIds
* @return
*/
List<AddUpDeduction> getAddUpDeductionList(YearMonth declareMonth, List<Long> employeeIds);
}

View File

@ -1,7 +1,10 @@
package com.engine.salary.service;
import com.engine.salary.entity.datacollection.AddUpSituation;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.time.YearMonth;
import java.util.List;
import java.util.Map;
public interface AddUpSituationService {
@ -19,4 +22,21 @@ public interface AddUpSituationService {
Map<String, Object> getDetailList(Map<String, Object> params);
Map<String, Object> preview(Map<String, Object> params);
/**
* 获取累计情况
*
* @param taxYearMonth
* @param employeeIds
* @return
*/
List<AddUpSituation> getAddUpSituationList(YearMonth taxYearMonth, List<Long> employeeIds);
/**
* 删除累计情况
* @param taxYearMonth
* @param employeeIds
* @return
*/
boolean deleteAddUpSituationList(YearMonth taxYearMonth, List<Long> employeeIds);
}

View File

@ -71,16 +71,14 @@ public interface AttendQuoteFieldService {
/**
* 同步考勤模块字段
*
* @param currentEmployeeId
* @return
*/
String syncAttendFields(Long currentEmployeeId);
String syncAttendFields();
/**
* 获取当前租户下所有的考勤引用字段
*
* @param tenantKey
* @return
*/
List<AttendQuoteFieldListDTO> listAll(String tenantKey);
List<AttendQuoteFieldListDTO> listAll();
}

View File

@ -1,7 +1,10 @@
package com.engine.salary.service;
import com.engine.salary.entity.datacollection.po.OtherDeductionPO;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.time.YearMonth;
import java.util.List;
import java.util.Map;
/**
@ -50,4 +53,5 @@ public interface OtherDeductionService {
*/
XSSFWorkbook exportDetail(Map<String, Object> params);
List<OtherDeductionPO> getOtherDeductionList(YearMonth taxCycle, List<Long> employeeIds);
}

View File

@ -0,0 +1,24 @@
package com.engine.salary.service;
import com.weaver.excel.formula.api.entity.FormulaVar;
import java.util.List;
import java.util.Map;
public interface RemoteExcelService {
// ExcelResult aggregation(AggFunc func, String sourceId, String fieldId, List<FormulaFilterData> filterFormDataList, Map<String, Object> extendParam, SimpleEmployee employee);
//
// ExcelPage<FormulaCategory> categoryList(ExcelPage<FormulaCategory> page, Map<String, Object> extendParam, SimpleEmployee employee);
List<FormulaVar> fieldList(String sourceId, Map<String, Object> extendParam);
// ExcelPage<FormulaDataSource> dataSourceList(String categoryId, ExcelPage<FormulaDataSource> page, Map<String, Object> extendParam, SimpleEmployee employee);
//
// List<FormulaVar> findProperData(String dataId, String fieldId, String fieldType, Map<String, Object> extendParam, SimpleEmployee employee);
//
// List<DataType> choose(String sourceId, List<FormulaFilterData> filterFormDataList, Map<String, Object> extendParam, SimpleEmployee employee);
//
// List<DataType> vlookups(String sourceId, List<FormulaFilterData> filterFormDataList, List<String> returnFields, Map<String, Object> extendParam, SimpleEmployee employee);
//
// Map<String, SimpleExcelEntity> findSourceName(String Module, List<String> idList, Map<String, Object> extendParam, SimpleEmployee employee);
}

View File

@ -0,0 +1,22 @@
package com.engine.salary.service;
import com.engine.salary.entity.datacollection.DataCollectionEmployee;
import com.engine.salary.entity.salaryacct.bo.SalaryAcctCalculateBO;
/**
* 薪资核算-核算
* <p>Copyright: Copyright (c) 2022</p>
* <p>Company: 泛微软件</p>
*
* @author qiantao
* @version 1.0
**/
public interface SalaryAcctCalculateService {
/**
* 薪资核算
*
* @param salaryAcctCalculateBO
*/
void calculate(SalaryAcctCalculateBO salaryAcctCalculateBO, DataCollectionEmployee simpleEmploye);
}

View File

@ -0,0 +1,61 @@
package com.engine.salary.service;
import com.engine.salary.entity.salaryacct.dto.SalaryAcctProgressDTO;
/**
* 核算进度
* <p>Copyright: Copyright (c) 2022</p>
* <p>Company: 泛微软件</p>
*
* @author qiantao
* @version 1.0
**/
public interface SalaryAcctProgressService {
/**
* 初始化核算进度条
*
* @param salaryAcctProgress
* @return
*/
String initProgress(String cacheKey, SalaryAcctProgressDTO salaryAcctProgress);
/**
* 更新进度条
*
* @param calculatedQuantity
* @return
*/
void getAndAddCalculatedQty(String cacheKey, Integer calculatedQuantity);
/**
* 计算失败
*
* @param cacheKey
* @param message
* @return
*/
void fail(String cacheKey, String message);
/**
* 完成
*
* @param cacheKey
*/
void finish(String cacheKey, boolean checkStatus);
/**
* 获取进度条
* @return
*/
SalaryAcctProgressDTO getProgress(String cacheKey);
/**
* 删除redis中的缓存
*
* @param cacheKey
* @param employeeId
* @return
*/
SalaryAcctProgressDTO del(String cacheKey, Long employeeId);
}

View File

@ -1,7 +1,9 @@
package com.engine.salary.service;
import com.engine.salary.entity.datacollection.DataCollectionEmployee;
import com.engine.salary.entity.salaryacct.dto.ConsolidatedTaxDetailDTO;
import com.engine.salary.entity.salaryacct.dto.SalaryAcctResultDetailDTO;
import com.engine.salary.entity.salaryacct.param.SalaryAcctCalculateParam;
import com.engine.salary.entity.salaryacct.param.SalaryAcctResultQueryParam;
import com.engine.salary.entity.salaryacct.param.SalaryAcctResultSaveParam;
import com.engine.salary.entity.salaryacct.po.SalaryAcctResultPO;
@ -122,11 +124,11 @@ public interface SalaryAcctResultService {
*/
void deleteBySalaryAcctRecordIds(Collection<Long> salaryAcctRecordIds);
// /**
// * 薪资核算
// *
// * @param calculateParam
// * @param simpleEmployee
// */
// void calculate(SalaryAcctCalculateParam calculateParam, DataCollectionEmployee simpleEmployee);
/**
* 薪资核算
*
* @param calculateParam
* @param simpleEmployee
*/
void calculate(SalaryAcctCalculateParam calculateParam, DataCollectionEmployee simpleEmployee);
}

View File

@ -0,0 +1,39 @@
package com.engine.salary.service;
import com.engine.salary.entity.salaryacct.po.SalaryAcctResultTempPO;
import java.util.Collection;
import java.util.List;
/**
* 薪资核算结果临时存储
* <p>Copyright: Copyright (c) 2022</p>
* <p>Company: 泛微软件</p>
*
* @author qiantao
* @version 1.0
**/
public interface SalaryAcctResultTempService {
/**
* 根据key获取薪资核算结果临时存储
*
* @param calculateKey
* @return
*/
List<SalaryAcctResultTempPO> listByCalculateKey(String calculateKey);
/**
* 批量保存
*
* @param salaryAcctResultTempPOS
*/
void batchSave(Collection<SalaryAcctResultTempPO> salaryAcctResultTempPOS);
/**
* 根据key删除薪资核算结果临时存储
*
* @param calculateKey
*/
void deleteByCalculateKey(String calculateKey);
}

View File

@ -29,12 +29,6 @@ public interface SalaryEmployeeService {
*/
List<DataCollectionEmployee> listBySalarySobId(Long salarySobId);
/**
* 根据薪资账套id查询人员
*
* @param ids
* @return
*/
List<DataCollectionEmployee> listByIds(List<Long> ids);
DataCollectionEmployee getEmployeeById(Long employeeId);

View File

@ -1,5 +1,8 @@
package com.engine.salary.service;
import com.engine.salary.entity.taxrate.TaxRateBase;
import java.util.List;
import java.util.Map;
public interface TaxRateBaseService {
@ -15,4 +18,11 @@ public interface TaxRateBaseService {
Map<String, Object> update(Map<String, Object> params);
Map<String, Object> getForm(Map<String, Object> params);
/**
* 获取所有的个税税率表
*
* @return
*/
List<TaxRateBase> list();
}

View File

@ -0,0 +1,43 @@
package com.engine.salary.service;
import com.engine.salary.entity.taxrate.TaxRateDetail;
import java.util.Collection;
import java.util.List;
/**
* 个税税率表明细表
* <p>Copyright: Copyright (c) 2022</p>
* <p>Company: 泛微软件</p>
*
* @author qiantao
* @version 1.0
**/
public interface TaxRateDetailService {
/**
* 根据公式条件获取对应的税率
*
* @param taxRateBaseId
* @param isOr
* @param formulaFilterDataList
* @param tenantKey
* @return
*/
// TaxRateDetail getByFormulaFilterData(Long taxRateBaseId, boolean isOr, Collection<FormulaFilterData> formulaFilterDataList);
/**
* 根据主表id获取明细表
*
* @param taxRateBaseId
* @return
*/
List<TaxRateDetail> listByBaseId(Long taxRateBaseId);
/**
* 根据主表id批量删除明细表
*
* @param taxRateBaseIds
*/
void deleteByBaseIds(Collection<Long> taxRateBaseIds);
}

View File

@ -1,14 +1,17 @@
package com.engine.salary.service.impl;
import com.engine.core.impl.Service;
import com.engine.salary.cmd.datacollection.AddUpDeductionExportCmd;
import com.engine.salary.cmd.datacollection.AddUpDeductionGetSearchConditionCmd;
import com.engine.salary.cmd.datacollection.AddUpDeductionImportCmd;
import com.engine.salary.cmd.datacollection.AddUpDeductionListCmd;
import com.engine.salary.biz.AddUpDeductionBiz;
import com.engine.salary.cmd.datacollection.*;
import com.engine.salary.entity.datacollection.AddUpDeduction;
import com.engine.salary.exception.SalaryRunTimeException;
import com.engine.salary.service.AddUpDeductionService;
import com.engine.salary.util.SalaryDateUtil;
import com.engine.salary.util.SalaryI18nUtil;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.time.YearMonth;
import java.util.List;
import java.util.Map;
public class AddUpDeductionServiceImpl extends Service implements AddUpDeductionService {
@ -47,4 +50,13 @@ public class AddUpDeductionServiceImpl extends Service implements AddUpDeduction
public XSSFWorkbook exportDetail(Map<String, Object> params) {
return commandExecutor.execute(new AddUpDeductionExportDetailCmd(params, user));
}
@Override
public List<AddUpDeduction> getAddUpDeductionList(YearMonth declareMonth, List<Long> employeeIds) {
AddUpDeductionBiz addUpDeductionBiz = new AddUpDeductionBiz();
if (declareMonth == null) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100342, "参数有误申报月份、租户key必传"));
}
return addUpDeductionBiz.listSome(AddUpDeduction.builder().declareMonth(SalaryDateUtil.toDateStartOfMonth(declareMonth)).employeeIds(employeeIds).build());
}
}

View File

@ -1,14 +1,23 @@
package com.engine.salary.service.impl;
import com.engine.core.impl.Service;
import com.engine.salary.biz.AddUpSituationBiz;
import com.engine.salary.cmd.datacollection.*;
import com.engine.salary.entity.datacollection.AddUpSituation;
import com.engine.salary.exception.SalaryRunTimeException;
import com.engine.salary.service.AddUpSituationService;
import com.engine.salary.util.SalaryDateUtil;
import com.engine.salary.util.SalaryI18nUtil;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.time.YearMonth;
import java.util.List;
import java.util.Map;
public class AddUpSituationServiceImpl extends Service implements AddUpSituationService {
@Override
public Map<String, Object> list(Map<String, Object> params) {
return commandExecutor.execute(new AddUpSituationListCmd(params, user));
@ -43,4 +52,23 @@ public class AddUpSituationServiceImpl extends Service implements AddUpSituation
public Map<String, Object> preview(Map<String, Object> params) {
return commandExecutor.execute(new AddUpSituationPreviewCmd(params, user));
}
@Override
public List<AddUpSituation> getAddUpSituationList(YearMonth taxYearMonth, List<Long> employeeIds) {
if (taxYearMonth == null) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100353, "参数有误:税款所属期必传"));
}
AddUpSituationBiz biz = new AddUpSituationBiz();
return biz.listSome(AddUpSituation.builder().taxYearMonth(SalaryDateUtil.toDateStartOfMonth(taxYearMonth)).employeeIds(employeeIds).build());
}
@Override
public boolean deleteAddUpSituationList(YearMonth taxYearMonth, List<Long> employeeIds) {
if (taxYearMonth == null) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100353, "参数有误:税款所属期必传"));
}
AddUpSituationBiz biz = new AddUpSituationBiz();
biz.deleteSome(AddUpSituation.builder().employeeIds(employeeIds).taxYearMonth(SalaryDateUtil.toDateStartOfMonth(taxYearMonth)).build());
return Boolean.TRUE;
}
}

View File

@ -44,7 +44,7 @@ public class AttendQuoteFieldServiceImpl extends Service implements AttendQuoteF
@Override
public Map<String, Object> list(AttendQuoteFieldQueryParam queryParam) {
// todo 同步字段
// syncAttendFields(employeeId, tenantKey);
syncAttendFields();
String fields = " t1.id," +
" t1.field_name as fieldName," +
@ -192,7 +192,7 @@ public class AttendQuoteFieldServiceImpl extends Service implements AttendQuoteF
}
@Override
public String syncAttendFields(Long currentEmployeeId) {
public String syncAttendFields() {
// 所有字段管理的考勤模块引用字段
List<AttendQuoteFieldPO> attendQuoteFields = biz.listSome(AttendQuoteFieldPO.builder().sourceType(AttendQuoteFieldSourceTypeEnum.ATTEND.getValue()).build());
// 1.本地字段
@ -262,7 +262,7 @@ public class AttendQuoteFieldServiceImpl extends Service implements AttendQuoteF
// 3.新增
List<AttendQuoteFieldPO> saves = new ArrayList<>();
saves.addAll(attendFixedFieldCodes.stream().filter(e -> saveCodes.contains(e.get("code"))).map(m ->
buildAttendQuoteField(m.get("code"), m.get("name"), currentEmployeeId)
buildAttendQuoteField(m.get("code"), m.get("name"), (long)user.getUID())
).collect(Collectors.toList()));
// saveCodes.forEach(e -> {
// Optional<AttendVacationType> optionalHour = CollectionUtils.emptyIfNull(attendVacationTypes).stream().filter(m -> (m.getId() + "_leave_hour").equals(e)).findFirst();
@ -308,7 +308,7 @@ public class AttendQuoteFieldServiceImpl extends Service implements AttendQuoteF
}
@Override
public List<AttendQuoteFieldListDTO> listAll(String tenantKey) {
public List<AttendQuoteFieldListDTO> listAll() {
return biz.list(AttendQuoteFieldQueryParam.builder().build());
}
}

View File

@ -1,10 +1,17 @@
package com.engine.salary.service.impl;
import com.engine.core.impl.Service;
import com.engine.salary.biz.OtherDeductionBiz;
import com.engine.salary.cmd.datacollection.*;
import com.engine.salary.entity.datacollection.po.OtherDeductionPO;
import com.engine.salary.exception.SalaryRunTimeException;
import com.engine.salary.service.OtherDeductionService;
import com.engine.salary.util.SalaryDateUtil;
import com.engine.salary.util.SalaryI18nUtil;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.time.YearMonth;
import java.util.List;
import java.util.Map;
public class OtherDeductionServiceImpl extends Service implements OtherDeductionService {
@ -47,5 +54,12 @@ public class OtherDeductionServiceImpl extends Service implements OtherDeduction
return commandExecutor.execute(new OtherDeductionGetDetailListCmd(params, user));
}
@Override
public List<OtherDeductionPO> getOtherDeductionList(YearMonth declareMonth, List<Long> employeeIds) {
if (declareMonth == null) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100342, "参数有误:申报月份必传"));
}
OtherDeductionBiz OtherDeductionBiz = new OtherDeductionBiz();
return OtherDeductionBiz.listSome(OtherDeductionPO.builder().declareMonth(SalaryDateUtil.toDateStartOfMonth(declareMonth)).employeeIds(employeeIds).build());
}
}

View File

@ -0,0 +1,310 @@
package com.engine.salary.service.impl;
import com.engine.common.util.ServiceUtil;
import com.engine.core.impl.Service;
import com.engine.salary.annotation.SalaryFormulaVar;
import com.engine.salary.constant.SalaryFormulaFieldConstant;
import com.engine.salary.entity.datacollection.AddUpDeduction;
import com.engine.salary.entity.datacollection.AddUpSituation;
import com.engine.salary.entity.datacollection.dto.AttendQuoteFieldListDTO;
import com.engine.salary.entity.datacollection.param.AttendQuoteFieldQueryParam;
import com.engine.salary.entity.datacollection.po.OtherDeductionPO;
import com.engine.salary.entity.formula.DataType;
import com.engine.salary.entity.salaryformula.dto.SalaryFormulaEmployeeDTO;
import com.engine.salary.entity.salaryformula.dto.SalaryFormulaTaxRateDTO;
import com.engine.salary.entity.salaryitem.po.SalaryItemPO;
import com.engine.salary.entity.salarysob.po.SalarySobItemPO;
import com.engine.salary.entity.taxrate.TaxRateBase;
import com.engine.salary.enums.SalaryFormulaReferenceEnum;
import com.engine.salary.mapper.datacollection.AttendQuoteFieldMapper;
import com.engine.salary.service.*;
import com.engine.salary.util.SalaryEntityUtil;
import com.engine.salary.util.SalaryI18nUtil;
import com.engine.salary.util.db.MapperProxyFactory;
import com.google.common.collect.Lists;
import com.weaver.excel.formula.api.entity.FormulaVar;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import weaver.hrm.User;
import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;
public class RemoteExcelServiceImpl extends Service implements RemoteExcelService {
private static final Logger log = LoggerFactory.getLogger(RemoteExcelServiceImpl.class);
// private SIAccountService siAccountService;
private AttendQuoteFieldMapper getAttendQuoteFieldMapper() {
return MapperProxyFactory.getProxy(AttendQuoteFieldMapper.class);
}
private TaxRateBaseService getTaxRateBaseService(User user) {
return (TaxRateBaseService) ServiceUtil.getService(TaxRateBaseServiceImpl.class, user);
}
private TaxRateDetailService getTaxRateDetailService(User user) {
return (TaxRateDetailService) ServiceUtil.getService(TaxRateDetailServiceImpl.class, user);
}
private SalaryItemService getSalaryItemService(User user) {
return (SalaryItemService) ServiceUtil.getService(SalaryItemServiceImpl.class, user);
}
private SalarySobItemService getSalarySobItemService(User user) {
return (SalarySobItemService) ServiceUtil.getService(SalarySobItemServiceImpl.class, user);
}
// @Override
// public ExcelResult aggregation(AggFunc func, String sourceId, String fieldId, List<FormulaFilterData> filterFormDataList, Map<String, Object> extendParam,
// SimpleEmployee employee) {
// return null;
// }
// @Override
// public ExcelPage<FormulaCategory> categoryList(ExcelPage<FormulaCategory> page, Map<String, Object> extendParam, SimpleEmployee employee) {
// log.info("page: {}", JsonUtil.toJsonString(page));
// List<FormulaCategory> categories = Lists.newArrayList();
// FormulaCategory category = new FormulaCategory();
// category.setId("TAX_RATE");
// category.setName(SalaryI18nUtil.getI18nLabel(employee.getTenantKey(), employee.getEmployeeId(), 85370, "个税税率表"));
// category.setModule(SalaryFormulaFieldConstant.MODULE);
// category.setType(SalaryFormulaFieldConstant.MODULE);
// categories.add(category);
// page.setCount(1);
// page.setPageResult(categories);
// log.info("page: {}", JsonUtil.toJsonString(page));
// return page;
// }
@Override
public List<FormulaVar> fieldList(String sourceId, Map<String, Object> extendParam) {
List<FormulaVar> vars = new ArrayList<>();
// 如果是其他数据源
SalaryFormulaReferenceEnum referenceEnum = SalaryFormulaReferenceEnum.parseByValue(sourceId);
if (referenceEnum != null) {
switch (referenceEnum) {
case SALARY_ITEM:
case SALARY_ARCHIVES:
vars = salaryItem2FormulaVar(referenceEnum, extendParam);
break;
case ADD_UP_SITUATION:
vars = convert2FormulaVar(AddUpSituation.class, referenceEnum.getValue() + "");
break;
case ADD_UP_DEDUCTIONS:
vars = convert2FormulaVar(AddUpDeduction.class, referenceEnum.getValue() + "");
break;
case EMPLOYEE_INFO:
vars = convert2FormulaVar(SalaryFormulaEmployeeDTO.class, referenceEnum.getValue() + "");
break;
case OTHER_DEDUCTION:
vars = convert2FormulaVar(OtherDeductionPO.class, referenceEnum.getValue() + "");
break;
case WELFARE:
vars = welfare2FormulaVar(referenceEnum);
break;
case ATTEND:
vars = attendData2FormulaVar(referenceEnum);
break;
default:
break;
}
return vars;
}
// 如果是个税税率表的数据源
List<TaxRateBase> taxRateBatches = getTaxRateBaseService(user).list();
boolean isTaxRate = taxRateBatches.stream().anyMatch(e -> StringUtils.equals(sourceId, e.getId() + ""));
if (isTaxRate) {
vars = convert2FormulaVar(SalaryFormulaTaxRateDTO.class, sourceId);
}
return vars;
}
// @Override
// public ExcelPage<FormulaDataSource> dataSourceList(String categoryId, ExcelPage<FormulaDataSource> page, Map<String, Object> extendParam, SimpleEmployee employee) {
// log.info("categoryId: {}, page: {}", categoryId, JsonUtil.toJsonString(page));
// if (StringUtils.equals("TAX_RATE", categoryId)) {
// taxRate2FormulaDataSource(page, employee.getTenantKey());
// }
// log.info("page: {}", JsonUtil.toJsonString(page));
// return page;
// }
//
// @Override
// public List<FormulaVar> findProperData(String dataId, String fieldId, String fieldType, Map<String, Object> extendParam, SimpleEmployee employee) {
// return null;
// }
//
// @Override
// public List<DataType> choose(String sourceId, List<FormulaFilterData> filterFormDataList, Map<String, Object> extendParam, SimpleEmployee employee) {
// return null;
// }
//
//// @Override
// public List<DataType> vlookups(String sourceId, List<FormulaFilterData> filterFormDataList, List<String> returnFields, Map<String, Object> extendParam,
// SimpleEmployee employee) {
// log.info("sourceId: {}, filterFormDataList: {}, returnFields: {}", sourceId, JsonUtil.toJsonString(filterFormDataList), JsonUtil.toJsonString(returnFields));
// Map<String, String> columnMap = Maps.newHashMap();
// for (Field declaredField : SalaryFormulaTaxRateDTO.class.getDeclaredFields()) {
// if (!declaredField.isAnnotationPresent(SalaryFormulaVar.class)) {
// continue;
// }
// SalaryFormulaVar annotation = declaredField.getAnnotation(SalaryFormulaVar.class);
// columnMap.put(annotation.fieldId(), declaredField.getName());
// }
// List<DataType> resultList = Lists.newArrayList();
// Long taxRateBatchId = Long.valueOf(sourceId);
// boolean isOr = filterFormDataList.stream().anyMatch(e -> StringUtils.equals(e.getCondition(), FormulaFilterData.CONDITION_OR));
// TaxRateDetailPO taxRateRecord = taxRateDetailService.getByFormulaFilterData(taxRateBatchId, isOr, filterFormDataList, employee.getTenantKey());
// if (taxRateRecord == null) {
// return Collections.emptyList();
// }
// Map<String, String> valueMap = JsonUtil.parseMap(JsonUtil.toJsonString(taxRateRecord), String.class);
// for (String returnField : returnFields) {
// DataType dataType = new DataType();
// dataType.setFieldId(returnField);
// dataType.setFormId(0L);
// dataType.setSubFormId(0L);
// dataType.setName("");
// dataType.setContent(valueMap.getOrDefault(columnMap.get(returnField), "0"));
// dataType.setDataType(DataType.NUMBER);
// dataType.setComponentKey("NumberComponent");
// dataType.setModule(SalaryFormulaFieldConstant.MODULE);
// resultList.add(dataType);
// }
// log.info("resultList: {}", JsonUtil.toJsonString(resultList));
// return resultList;
// }
//
// @Override
// public Map<String, SimpleExcelEntity> findSourceName(String Module, List<String> idList, Map<String, Object> extendParam, SimpleEmployee employee) {
// return null;
// }
//
//// @Override
//// public List<DataType> getFieldData(String dataId, List<String> fieldIds, SimpleEmployee employee) {
//// return null;
//// }
//
// private void taxRate2FormulaDataSource(ExcelPage<FormulaDataSource> resultPage, String tenantKey) {
// List<TaxRateBasePO> taxRateBatches = taxRateBaseService.list(tenantKey);
// List<TaxRateBasePO> subList = SalaryPageUtil.subList(resultPage.getPageNo(), resultPage.getPageSize(), taxRateBatches);
// if (CollectionUtils.isEmpty(subList)) {
// resultPage.setPageResult(Collections.emptyList());
// return;
// }
// List<FormulaDataSource> formulaDataSources = subList.stream()
// .map(e -> {
// FormulaDataSource formulaDataSource = new FormulaDataSource();
// formulaDataSource.setTitle(e.getName());
// formulaDataSource.setDataId("" + e.getId());
// formulaDataSource.setModule(SalaryFormulaFieldConstant.MODULE);
// return formulaDataSource;
// })
// .collect(Collectors.toList());
// resultPage.setCount(taxRateBatches.size());
// resultPage.setPageResult(formulaDataSources);
// }
private List<FormulaVar> salaryItem2FormulaVar(SalaryFormulaReferenceEnum referenceEnum, Map<String, Object> extendParam) {
Set<Long> salaryItemIds = Collections.emptySet();
Object salarySobId = extendParam.get("salarySobId");
if (Objects.nonNull(salarySobId)) {
List<SalarySobItemPO> salarySobItems = getSalarySobItemService(user).listBySalarySobId(Long.valueOf(String.valueOf(salarySobId)));
salaryItemIds = SalaryEntityUtil.properties(salarySobItems, SalarySobItemPO::getSalaryItemId);
}
List<SalaryItemPO> salaryItems;
if (CollectionUtils.isEmpty(salaryItemIds)) {
salaryItems = getSalaryItemService(user).listAll();
} else {
salaryItems = getSalaryItemService(user).listByIds(salaryItemIds);
}
return salaryItems.stream()
.map(e -> {
FormulaVar formulaVar = new FormulaVar();
formulaVar.setFieldId(referenceEnum.getValue() + SalaryFormulaFieldConstant.FIELD_ID_SEPARATOR + e.getCode());
formulaVar.setTitle(e.getName());
formulaVar.setFormId("" + referenceEnum.getValue());
formulaVar.setDataType(DataType.NUMBER);
formulaVar.setModule(SalaryFormulaFieldConstant.MODULE);
formulaVar.setProperKey(DataType.NUMBER);
formulaVar.setProperKey(e.getDataType());
return formulaVar;
}).collect(Collectors.toList());
}
private <T> List<FormulaVar> convert2FormulaVar(Class<T> clazz, String formId) {
Field[] declaredFields = clazz.getDeclaredFields();
List<FormulaVar> formulaVars = Lists.newArrayListWithExpectedSize(declaredFields.length);
for (Field declaredField : declaredFields) {
if (!declaredField.isAnnotationPresent(SalaryFormulaVar.class)) {
continue;
}
SalaryFormulaVar annotation = declaredField.getAnnotation(SalaryFormulaVar.class);
FormulaVar formulaVar = new FormulaVar();
if (StringUtils.isEmpty(annotation.fieldId())) {
formulaVar.setFieldId(formId + SalaryFormulaFieldConstant.FIELD_ID_SEPARATOR + declaredField.getName());
} else {
formulaVar.setFieldId(annotation.fieldId());
}
formulaVar.setModule(SalaryFormulaFieldConstant.MODULE);
formulaVar.setTitle(SalaryI18nUtil.getI18nLabel(annotation.labelId(), annotation.defaultLabel()));
formulaVar.setFormId(formId);
formulaVar.setDataType(annotation.dataType());
formulaVar.setProperKey(DataType.NUMBER);
if (StringUtils.equals(formId, "" + SalaryFormulaReferenceEnum.EMPLOYEE_INFO.getValue())) {
formulaVar.setProperKey(DataType.STRING);
}
formulaVars.add(formulaVar);
}
return formulaVars;
}
private List<FormulaVar> welfare2FormulaVar(SalaryFormulaReferenceEnum referenceEnum) {
Map<String, String> welfareColumns = null;//siAccountService.welfareColumns();
if (MapUtils.isEmpty(welfareColumns)) {
return null;
}
List<FormulaVar> formulaVars = Lists.newArrayListWithExpectedSize(welfareColumns.size());
welfareColumns.forEach((k, v) -> {
FormulaVar formulaVar = new FormulaVar();
formulaVar.setFieldId(referenceEnum.getValue() + SalaryFormulaFieldConstant.FIELD_ID_SEPARATOR + v);
formulaVar.setModule(SalaryFormulaFieldConstant.MODULE);
formulaVar.setTitle(k);
formulaVar.setFormId("" + referenceEnum.getValue());
formulaVar.setDataType(DataType.NUMBER);
formulaVar.setProperKey(DataType.NUMBER);
formulaVars.add(formulaVar);
});
return formulaVars;
}
private List<FormulaVar> attendData2FormulaVar(SalaryFormulaReferenceEnum referenceEnum) {
List<AttendQuoteFieldListDTO> fields = getAttendQuoteFieldMapper().list(AttendQuoteFieldQueryParam.builder().build());
if (CollectionUtils.isEmpty(fields)) {
return null;
}
List<FormulaVar> formulaVars = fields.stream().map(e -> {
FormulaVar formulaVar = new FormulaVar();
formulaVar.setFieldId(referenceEnum.getValue() + SalaryFormulaFieldConstant.FIELD_ID_SEPARATOR + e.getId());
formulaVar.setModule(SalaryFormulaFieldConstant.MODULE);
formulaVar.setTitle(e.getFieldName());
formulaVar.setFormId("" + referenceEnum.getValue());
formulaVar.setDataType(DataType.NUMBER);
formulaVar.setProperKey(DataType.NUMBER);
return formulaVar;
}).collect(Collectors.toList());
return formulaVars;
}
}

View File

@ -0,0 +1,277 @@
package com.engine.salary.service.impl;
import com.engine.common.util.ServiceUtil;
import com.engine.core.impl.Service;
import com.engine.salary.constant.SalaryDefaultTenantConstant;
import com.engine.salary.constant.SalaryFormulaFieldConstant;
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.po.OtherDeductionPO;
import com.engine.salary.entity.salaryacct.bo.*;
import com.engine.salary.entity.salaryacct.po.SalaryAcctEmployeePO;
import com.engine.salary.entity.salaryacct.po.SalaryAcctRecordPO;
import com.engine.salary.entity.salaryacct.po.SalaryAcctResultPO;
import com.engine.salary.entity.salaryacct.po.SalaryAcctResultTempPO;
import com.engine.salary.entity.salaryarchive.dto.SalaryArchiveDataDTO;
import com.engine.salary.entity.salaryitem.po.SalaryItemPO;
import com.engine.salary.entity.salarysob.dto.SalarySobCycleDTO;
import com.engine.salary.entity.salarysob.po.SalarySobItemPO;
import com.engine.salary.enums.SalaryFormulaReferenceEnum;
import com.engine.salary.service.*;
import com.engine.salary.util.SalaryEntityUtil;
import com.google.common.collect.Lists;
import com.weaver.excel.formula.api.entity.ExpressFormula;
import com.weaver.excel.formula.api.entity.FormulaVar;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import weaver.hrm.User;
import java.time.Month;
import java.util.*;
import java.util.stream.Collectors;
/**
* 薪资核算-核算
* <p>Copyright: Copyright (c) 2022</p>
* <p>Company: 泛微软件</p>
*
* @author qiantao
* @version 1.0
**/
@Slf4j
public class SalaryAcctCalculateServiceImpl extends Service implements SalaryAcctCalculateService {
private SalaryAcctResultService getSalaryAcctResultService(User user) {
return (SalaryAcctResultService) ServiceUtil.getService(SalaryAcctResultServiceImpl.class, user);
}
private SalaryEmployeeService getSalaryEmployeeService(User user) {
return (SalaryEmployeeService) ServiceUtil.getService(SalaryEmployeeServiceImpl.class, user);
}
private SalaryArchiveService getSalaryArchiveService(User user) {
return (SalaryArchiveService) ServiceUtil.getService(SalaryArchiveServiceImpl.class, user);
}
private AddUpSituationService getAddUpSituationService(User user) {
return (AddUpSituationService) ServiceUtil.getService(AddUpSituationServiceImpl.class, user);
}
private AddUpDeductionService getAddUpDeductionService(User user) {
return (AddUpDeductionService) ServiceUtil.getService(AddUpDeductionServiceImpl.class, user);
}
private OtherDeductionService getOtherDeductionService(User user) {
return (OtherDeductionService) ServiceUtil.getService(OtherDeductionServiceImpl.class, user);
}
// private SIAccountService siAccountService;
private AttendQuoteDataService getAttendQuoteDataService(User user) {
return (AttendQuoteDataService) ServiceUtil.getService(AttendQuoteDataServiceImpl.class, user);
}
// private ExcelRunService excelRunService;
private SalaryAcctResultTempService getSalaryAcctResultTempService(User user) {
return (SalaryAcctResultTempService) ServiceUtil.getService(SalaryAcctResultTempServiceImpl.class, user);
}
private SalaryAcctProgressService salaryAcctProgressService;
private SalaryAcctEmployeeService salaryAcctEmployeeService;
@Override
public void calculate(SalaryAcctCalculateBO salaryAcctCalculateBO, DataCollectionEmployee simpleEmployee) {
Date now = new Date();
try {
// 数据库字段加密用
// 1查询人员信息
List<Long> employeeIds = SalaryEntityUtil.properties(salaryAcctCalculateBO.getSalaryAcctEmployeePOS(), SalaryAcctEmployeePO::getEmployeeId, Collectors.toList());
List<DataCollectionEmployee> simpleEmployees = getSalaryEmployeeService(user).listByIds(employeeIds);
SalarySobCycleDTO salarySobCycleDTO = salaryAcctCalculateBO.getSalarySobCycleDTO();
// 2查询薪资档案的数据
List<SalaryArchiveDataDTO> salaryArchiveData = getSalaryArchiveService(user).getSalaryArchiveData(salarySobCycleDTO.getSalaryCycle(), employeeIds);
// 3查询往期累计情况(查询的是上个税款所属期的的累计情况)
List<AddUpSituation> addUpSituationPOS;
if (salarySobCycleDTO.getTaxCycle().getMonth() == Month.JANUARY) {
// 3.1如果当前税款所属期是本年度第一个税款所属期就不需要查询往期累计情况
addUpSituationPOS = Collections.emptyList();
} else {
addUpSituationPOS = getAddUpSituationService(user).getAddUpSituationList(salarySobCycleDTO.getTaxCycle().plusMonths(-1), employeeIds);
}
// 4查询累计专项附加扣除
List<AddUpDeduction> addUpDeductionPOS = getAddUpDeductionService(user).getAddUpDeductionList(salarySobCycleDTO.getTaxCycle(), employeeIds);
// 5查询其他免税扣除
List<OtherDeductionPO> otherDeductionPOS = getOtherDeductionService(user).getOtherDeductionList(salarySobCycleDTO.getTaxCycle(), employeeIds);
//todo 6查询社保福利
List<Map<String, Object>> welfareData = null;//siAccountService.welfareData(salarySobCycleDTO.getSocialSecurityCycle().toString(), employeeIds);
// 7查询考勤数据
List<AttendQuoteDataDTO> attendQuoteDataDTOS = getAttendQuoteDataService(user).getAttendQuoteData(salarySobCycleDTO.getSalaryMonth(), salarySobCycleDTO.getSalarySobId(), employeeIds);
// 8查询薪资核算人员的薪资核算结果
Set<Long> salaryAcctEmployeeIds = SalaryEntityUtil.properties(salaryAcctCalculateBO.getSalaryAcctEmployeePOS(), SalaryAcctEmployeePO::getId);
List<SalaryAcctResultPO> salaryAcctResultPOS = getSalaryAcctResultService(user).listBySalaryAcctEmployeeIds(salaryAcctEmployeeIds);
// 9查询相同税款所属期内涉及合并计税的其他薪资核算结果
Set<Long> otherSalaryAcctRecordIds = SalaryEntityUtil.properties(salaryAcctCalculateBO.getOtherSalaryAcctRecordPOS(), SalaryAcctRecordPO::getId);
List<SalaryAcctResultPO> otherSalaryAcctResultPOS = getSalaryAcctResultService(user).listBySalaryAcctRecordIdsAndEmployeeIds(otherSalaryAcctRecordIds, employeeIds);
Map<String, List<SalaryAcctResultPO>> otherSalaryAcctResultPOMap = SalaryEntityUtil.group2Map(otherSalaryAcctResultPOS, e -> e.getEmployeeId() + "_" + e.getTaxAgentId());
// 9.1查询相同税款所属期内设计合并计税的其他薪资核算人员
List<SalaryAcctEmployeePO> otherSalaryAcctEmployeePOS = salaryAcctEmployeeService.listBySalaryAcctRecordIdsAndEmployeeIds(otherSalaryAcctRecordIds, employeeIds);
Map<String, List<SalaryAcctEmployeePO>> otherSalaryAcctEmployeePOMap = SalaryEntityUtil.group2Map(otherSalaryAcctEmployeePOS, salaryAcctEmployeePO -> salaryAcctEmployeePO.getEmployeeId() + "_" + salaryAcctEmployeePO.getTaxAgentId());
// 10转换成公式编辑器中的变量
CalculateFormulaVarBO calculateFormulaVarBO = new CalculateFormulaVarBO(simpleEmployees, salaryArchiveData, addUpSituationPOS, addUpDeductionPOS, otherDeductionPOS,
welfareData, attendQuoteDataDTOS, salaryAcctResultPOS);
Map<String, List<CalculateFormulaVarBO.FormulaVarValue>> formulaVarMap = calculateFormulaVarBO.convert2FormulaVar(salaryAcctCalculateBO);
// 本次薪资核算所用的薪资账套下的薪资项目
Map<Long, SalarySobItemPO> salaryItemIdKeySalarySobItemPOMap = SalaryEntityUtil.convert2Map(salaryAcctCalculateBO.getSalarySobItemPOS(), SalarySobItemPO::getSalaryItemId);
// 本次薪资核算所用的公式
Map<Long, ExpressFormula> expressFormulaMap = SalaryEntityUtil.convert2Map(salaryAcctCalculateBO.getExpressFormulas(), ExpressFormula::getId);
// 系统内的薪资项目
Map<Long, SalaryItemPO> salaryItemMap = SalaryEntityUtil.convert2Map(salaryAcctCalculateBO.getSalaryItemPOS(), SalaryItemPO::getId);
List<SalaryAcctResultTempPO> salaryAcctResultTempPOS = Lists.newArrayList();
// 开始核算
for (SalaryAcctEmployeePO salaryAcctEmployeePO : salaryAcctCalculateBO.getSalaryAcctEmployeePOS()) {
// 获取当前薪资核算人员的公式中的变量的值
List<CalculateFormulaVarBO.FormulaVarValue> formulaVarValues = formulaVarMap.get(salaryAcctEmployeePO.getEmployeeId() + "_" + salaryAcctEmployeePO.getTaxAgentId());
Map<String, String> formulaVarValueMap = SalaryEntityUtil.convert2Map(formulaVarValues, CalculateFormulaVarBO.FormulaVarValue::getFieldId, CalculateFormulaVarBO.FormulaVarValue::getFieldValue);
// 按照计算好的优先级计算薪资项目的值
for (List<Long> salaryItemIds : salaryAcctCalculateBO.getSalaryItemIdWithPriorityList()) {
// 同一运算优先级下的薪资项目逐个独立运算
for (Long salaryItemId : salaryItemIds) {
String resultValue;
SalaryItemPO salaryItemPO = salaryItemMap.get(salaryItemId);
ExpressFormula expressFormula;
// 如果薪资账套下重新定义了薪资项目的公式则使用薪资账套下的公式否则使用薪资项目本身的公式
if (salaryItemIdKeySalarySobItemPOMap.containsKey(salaryItemId)) {
SalarySobItemPO salarySobItemPO = salaryItemIdKeySalarySobItemPOMap.get(salaryItemId);
expressFormula = expressFormulaMap.get(salarySobItemPO.getFormulaId());
} else {
expressFormula = expressFormulaMap.get(salaryItemPO.getFormulaId());
}
if (Objects.nonNull(expressFormula)) {
// 运行公式
resultValue = runExpressFormula(expressFormula, formulaVarValueMap, simpleEmployee);
} else {
// 处理取值类型为输入/导入的薪资项目
String key = SalaryFormulaReferenceEnum.SALARY_ITEM.getValue()
+ SalaryFormulaFieldConstant.FIELD_ID_SEPARATOR
+ salaryItemPO.getCode();
resultValue = formulaVarValueMap.getOrDefault(key, StringUtils.EMPTY);
}
// 处理薪资档案
if (Objects.equals(salaryItemPO.getUseInEmployeeSalary(), NumberUtils.INTEGER_ONE)) {
String key = SalaryFormulaReferenceEnum.SALARY_ARCHIVES.getValue()
+ SalaryFormulaFieldConstant.FIELD_ID_SEPARATOR
+ salaryItemPO.getCode();
resultValue = formulaVarValueMap.getOrDefault(key, StringUtils.EMPTY);
}
// 处理合并计税
resultValue = handleConsolidatedTax(resultValue, salaryItemPO, salaryAcctCalculateBO,
otherSalaryAcctEmployeePOMap.get(salaryAcctEmployeePO.getEmployeeId() + "_" + salaryAcctEmployeePO.getTaxAgentId()),
otherSalaryAcctResultPOMap.get(salaryAcctEmployeePO.getEmployeeId() + "_" + salaryAcctEmployeePO.getTaxAgentId()));
// 处理小数点
resultValue = SalaryAcctFormulaBO.roundResultValue(resultValue, salaryItemPO);
// 将已经计算过的薪资项目的值转换成公式变量的值添加到集合中
String key = SalaryFormulaReferenceEnum.SALARY_ITEM.getValue()
+ SalaryFormulaFieldConstant.FIELD_ID_SEPARATOR
+ salaryItemPO.getCode();
formulaVarValueMap.put(key, resultValue);
// 值保存薪资账套下的薪资项目的核算结果
if (salaryItemIdKeySalarySobItemPOMap.containsKey(salaryItemId)) {
// 转换成薪资核算结果po
SalaryAcctResultTempPO salaryAcctResultTempPO = new SalaryAcctResultTempPO()
// .setId(IdGenerator.generate())
.setSalaryAcctRecordId(salaryAcctEmployeePO.getSalaryAcctRecordId())
.setSalaryAcctEmpId(salaryAcctEmployeePO.getId())
.setEmployeeId(salaryAcctEmployeePO.getEmployeeId())
.setTaxAgentId(salaryAcctEmployeePO.getTaxAgentId())
.setSalarySobId(salaryAcctEmployeePO.getSalarySobId())
.setSalaryItemId(salaryItemPO.getId())
.setResultValue(resultValue)
.setCalculateKey(salaryAcctCalculateBO.getCalculateKey())
.setCreator(simpleEmployee.getEmployeeId())
.setCreateTime(now)
.setUpdateTime(now)
.setTenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY)
.setDeleteType(0);
salaryAcctResultTempPOS.add(salaryAcctResultTempPO);
}
}
}
}
// 保存新的薪资核算结果临时存储
getSalaryAcctResultTempService(user).batchSave(salaryAcctResultTempPOS);
// 更新薪资核算进度
salaryAcctProgressService.getAndAddCalculatedQty("" + salaryAcctCalculateBO.getSalaryAcctRecordPO().getId(),
salaryAcctCalculateBO.getSalaryAcctEmployeePOS().size());
// 记录子线程执行结果
salaryAcctCalculateBO.getResults().add(new SalaryAcctCalculateBO.Result(true, StringUtils.EMPTY));
} catch (Exception e) {
log.info("薪资核算失败:{}", e.getMessage(), e);
salaryAcctCalculateBO.getResults().add(new SalaryAcctCalculateBO.Result(false, e.getMessage()));
} finally {
// 数据库字段加密用
// DSTenantKeyThreadVar.tenantKey.remove();
// 子线程执行完毕
salaryAcctCalculateBO.getChildMonitor().countDown();
}
}
/**
* 运行公式
*
* @param expressFormula
* @param formulaVarValueMap
* @return
*/
private String runExpressFormula(ExpressFormula expressFormula, Map<String, String> formulaVarValueMap, DataCollectionEmployee simpleEmployee) {
// 给公式中的变量填入值
List<FormulaVar> formulaVars = ExpressFormulaBO.buildFormulaVar4Accounting(expressFormula, formulaVarValueMap);
// todo 运行公式
// ExcelResult excelResult = excelRunService.run(expressFormula, formulaVars, simpleEmployee);
// if (excelResult.isStatus()) {
// return excelResult.getStringData();
// }
return StringUtils.EMPTY;
}
/**
* 处理合并计税
*
* @return
*/
private String handleConsolidatedTax(String resultValue, SalaryItemPO salaryItemPO, SalaryAcctCalculateBO salaryAcctCalculateBO, List<SalaryAcctEmployeePO> otherSalaryAcctEmployeePOS, List<SalaryAcctResultPO> otherSalaryAcctResultPOS) {
// 如果相同税款所属期内没有其他薪资核算人员就不存在合并计税
if (CollectionUtils.isEmpty(otherSalaryAcctEmployeePOS)) {
return resultValue;
}
// 相同税款所属期内其他薪资核算记录
Set<Long> otherSalaryAcctRecordIds = SalaryEntityUtil.properties(otherSalaryAcctEmployeePOS, SalaryAcctEmployeePO::getSalaryAcctRecordId);
List<SalaryAcctRecordPO> otherSalaryAcctRecordPOS = salaryAcctCalculateBO.getOtherSalaryAcctRecordPOS().stream()
.filter(e -> otherSalaryAcctRecordIds.contains(e.getId()))
.collect(Collectors.toList());
// 相同税款所属期内同一个个税扣缴义务人下的同一个人存在多次工资薪金类型的薪资核算记录那么只有最早创建的薪资核算记录可以扣减如下数据减除费用专项扣除专项附加扣除其他扣除
// 根据薪资核算记录的创建时间判断是否需要做合并计税处理
boolean needConsolidatedTax = otherSalaryAcctRecordPOS.stream().anyMatch(salaryAcctRecordPO -> salaryAcctCalculateBO.getSalaryAcctRecordPO().getCreateTime().compareTo(salaryAcctRecordPO.getCreateTime()) > 0);
if (!needConsolidatedTax) {
return resultValue;
}
// 合并计税处理
return SalaryAcctConsolidatedTaxBO.handleConsolidatedTaxValue(resultValue, salaryItemPO, salaryAcctCalculateBO.getSalaryItemPOS(), otherSalaryAcctResultPOS);
}
}

View File

@ -19,7 +19,7 @@ import com.engine.salary.service.*;
import com.engine.salary.util.SalaryDateUtil;
import com.engine.salary.util.SalaryEntityUtil;
import com.engine.salary.util.SalaryI18nUtil;
import com.engine.salary.util.db.SqlProxyHandle;
import com.engine.salary.util.db.MapperProxyFactory;
import com.engine.salary.util.page.PageInfo;
import com.engine.salary.util.page.PageUtil;
import com.engine.salary.util.valid.ValidUtil;
@ -45,7 +45,7 @@ public class SalaryAcctEmployeeServiceImpl extends Service implements SalaryAcct
private SalaryAcctEmployeeMapper salaryAcctEmployeeMapper;
private SalaryAcctEmployeeMapper getSalaryAcctEmployeeMapper() {
return SqlProxyHandle.getProxy(SalaryAcctEmployeeMapper.class);
return MapperProxyFactory.getProxy(SalaryAcctEmployeeMapper.class);
}
private SalaryAcctRecordService getSalaryAcctRecordService(User user) {

View File

@ -21,7 +21,7 @@ import com.engine.salary.service.SalarySobService;
import com.engine.salary.util.SalaryDateUtil;
import com.engine.salary.util.SalaryEntityUtil;
import com.engine.salary.util.SalaryI18nUtil;
import com.engine.salary.util.db.SqlProxyHandle;
import com.engine.salary.util.db.MapperProxyFactory;
import com.engine.salary.util.page.PageInfo;
import com.engine.salary.util.page.PageUtil;
import com.engine.salary.util.valid.ValidUtil;
@ -46,7 +46,7 @@ public class SalaryAcctRecordServiceImpl extends Service implements SalaryAcctRe
private SalaryAcctRecordMapper getSalaryAcctRecordMapper() {
return SqlProxyHandle.getProxy(SalaryAcctRecordMapper.class);
return MapperProxyFactory.getProxy(SalaryAcctRecordMapper.class);
}
private SalarySobService getSalarySobService(User user) {

View File

@ -4,20 +4,29 @@ import com.engine.core.impl.Service;
import com.engine.salary.biz.TaxAgentBiz;
import com.engine.salary.common.LocalDateRange;
import com.engine.salary.entity.datacollection.DataCollectionEmployee;
import com.engine.salary.entity.datacollection.dto.AttendQuoteFieldListDTO;
import com.engine.salary.entity.salaryacct.bo.SalaryAcctCalculateBO;
import com.engine.salary.entity.salaryacct.bo.SalaryAcctCalculatePriorityBO;
import com.engine.salary.entity.salaryacct.bo.SalaryAcctResultBO;
import com.engine.salary.entity.salaryacct.dto.ConsolidatedTaxDetailDTO;
import com.engine.salary.entity.salaryacct.dto.SalaryAcctProgressDTO;
import com.engine.salary.entity.salaryacct.dto.SalaryAcctResultDetailDTO;
import com.engine.salary.entity.salaryacct.param.SalaryAcctCalculateParam;
import com.engine.salary.entity.salaryacct.param.SalaryAcctEmployeeQueryParam;
import com.engine.salary.entity.salaryacct.param.SalaryAcctResultQueryParam;
import com.engine.salary.entity.salaryacct.param.SalaryAcctResultSaveParam;
import com.engine.salary.entity.salaryacct.po.SalaryAcctEmployeePO;
import com.engine.salary.entity.salaryacct.po.SalaryAcctRecordPO;
import com.engine.salary.entity.salaryacct.po.SalaryAcctResultPO;
import com.engine.salary.entity.salaryacct.po.SalaryAcctResultTempPO;
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.entity.salarysob.po.SalarySobEmpFieldPO;
import com.engine.salary.entity.salarysob.po.SalarySobItemPO;
import com.engine.salary.entity.salarysob.po.SalarySobPO;
import com.engine.salary.entity.taxrate.TaxAgent;
import com.engine.salary.enums.salaryaccounting.SalaryAcctRecordStatusEnum;
import com.engine.salary.enums.salarysob.IncomeCategoryEnum;
import com.engine.salary.exception.SalaryRunTimeException;
import com.engine.salary.mapper.salaryacct.SalaryAcctResultMapper;
@ -26,13 +35,24 @@ import com.engine.salary.util.SalaryDateUtil;
import com.engine.salary.util.SalaryEntityUtil;
import com.engine.salary.util.SalaryI18nUtil;
import com.engine.salary.util.page.PageInfo;
import com.google.common.collect.Lists;
import com.weaver.excel.formula.api.entity.ExpressFormula;
import com.weaver.util.threadPool.ThreadPoolUtil;
import com.weaver.util.threadPool.constant.ModulePoolEnum;
import com.weaver.util.threadPool.entity.LocalRunnable;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.stream.Collectors;
/**
@ -66,13 +86,13 @@ public class SalaryAcctResultServiceImpl extends Service implements SalaryAcctRe
private SalarySobAdjustRuleService salarySobAdjustRuleService;
// private SalaryAcctCalculateService salaryAcctCalculateService;
private SalaryAcctCalculateService salaryAcctCalculateService;
// private SalaryAcctProgressService salaryAcctProgressService;
private DataSourceTransactionManager dataSourceTransactionManager;
// private SalaryAcctResultTempService salaryAcctResultTempService;
private SalaryAcctResultTempService salaryAcctResultTempService;
// private LoggerTemplate salaryAcctRecordLoggerTemplate;
@ -321,120 +341,118 @@ public class SalaryAcctResultServiceImpl extends Service implements SalaryAcctRe
salaryAcctResultMapper.deleteBySalaryAcctRecordIds(salaryAcctRecordIds);
}
// @Override
// public void calculate(SalaryAcctCalculateParam calculateParam, DataCollectionEmployee simpleEmployee) {
// try {
// // 数据库字段加密用
// DSTenantKeyThreadVar.tenantKey.set();
// // 1查询薪资核算记录
// SalaryAcctRecordPO salaryAcctRecordPO = salaryAcctRecordService.getById(calculateParam.getSalaryAcctRecordId());
// if (Objects.isNull(salaryAcctRecordPO)) {
// throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98747, "薪资核算记录不存在或已被删除"));
// }
// // 1.1如果薪资核算记录已经归档了就不能继续核算
// if (!Objects.equals(salaryAcctRecordPO.getStatus(), SalaryAcctRecordStatusEnum.NOT_ARCHIVED.getValue())) {
// throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(99148, "当前薪资核算记录已归档,请重新打开后再进行核算"));
// }
// // 2查询薪资核算记录的薪资周期考勤周期等
// SalarySobCycleDTO salarySobCycleDTO = salaryAcctRecordService.getSalarySobCycleById(calculateParam.getSalaryAcctRecordId());
// // 3查询薪资核算记录所用薪资账套的薪资项目副本
// List<SalarySobItemPO> salarySobItemPOS = salarySobItemService.listBySalarySobId(salaryAcctRecordPO.getSalarySobId());
// if (CollectionUtils.isEmpty(salarySobItemPOS)) {
// throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(99151, "当前所用的薪资账套未选择任何薪资项目,无法核算"));
// }
// // 4查询当前租户的所有薪资项目
// List<SalaryItemPO> salaryItemPOS = salaryItemService.listAll(tenantKey);
// // 5查询薪资核算记录所用薪资账套的调薪计薪规则
// List<SalarySobAdjustRulePO> salarySobAdjustRulePOS = salarySobAdjustRuleService.listBySalarySobId(salaryAcctRecordPO.getSalarySobId());
// // 6查询社保福利的所有字段
// Map<String, String> welfareColumns = siAccountService.welfareColumns(tenantKey);
// // 7查询考勤引用的所有字段
// List<AttendQuoteFieldListDTO> attendQuoteFieldListDTOS = attendQuoteFieldService.listAll(tenantKey);
// // 8查询公式详情
// Set<Long> formulaIds = SalaryEntityUtil.properties(salarySobItemPOS, SalarySobItemPO::getFormulaId);
// formulaIds.addAll(SalaryEntityUtil.properties(salaryItemPOS, SalaryItemPO::getFormulaId));
// List<ExpressFormula> expressFormulas = salaryFormulaService.listExpressFormula(formulaIds);
// // 9计算薪资项目的运算优先级
// List<List<Long>> salarySobItemsWithPriority = SalaryAcctCalculatePriorityBO.calculatePriority(salarySobItemPOS, salaryItemPOS, expressFormulas);
// // 10根据id查询其他合并计税的薪资核算记录
// List<SalaryAcctRecordPO> otherSalaryAcctRecordPOS = salaryAcctRecordService.listById4OtherConsolidatedTax(salaryAcctRecordPO.getId());
// // 11查询本次核算人员
// List<SalaryAcctEmployeePO> salaryAcctEmployeePOS;
// if (CollectionUtils.isEmpty(calculateParam.getIds())) {
// salaryAcctEmployeePOS = salaryAcctEmployeeService.listBySalaryAcctRecordId(salaryAcctRecordPO.getId());
// } else {
// salaryAcctEmployeePOS = salaryAcctEmployeeService.listByIds(calculateParam.getIds());
// }
// if (CollectionUtils.isEmpty(salaryAcctEmployeePOS)) {
// throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(103378, "薪资核算人员不能为空"));
// }
// // 11.1初始化进度
// SalaryAcctProgressDTO initProgress = new SalaryAcctProgressDTO()
// .setTitle(SalaryI18nUtil.getI18nLabel(97515, "核算中"))
// .setTitleLabelId(97515L)
// .setTotalQuantity(salaryAcctEmployeePOS.size() * 2 + 1)
// .setCalculatedQuantity(0)
// .setProgress(BigDecimal.ZERO)
// .setStatus(true)
// .setMessage(StringUtils.EMPTY);
@Override
public void calculate(SalaryAcctCalculateParam calculateParam, DataCollectionEmployee simpleEmployee) {
try {
// 1查询薪资核算记录
SalaryAcctRecordPO salaryAcctRecordPO = salaryAcctRecordService.getById(calculateParam.getSalaryAcctRecordId());
if (Objects.isNull(salaryAcctRecordPO)) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98747, "薪资核算记录不存在或已被删除"));
}
// 1.1如果薪资核算记录已经归档了就不能继续核算
if (!Objects.equals(salaryAcctRecordPO.getStatus(), SalaryAcctRecordStatusEnum.NOT_ARCHIVED.getValue())) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(99148, "当前薪资核算记录已归档,请重新打开后再进行核算"));
}
// 2查询薪资核算记录的薪资周期考勤周期等
SalarySobCycleDTO salarySobCycleDTO = salaryAcctRecordService.getSalarySobCycleById(calculateParam.getSalaryAcctRecordId());
// 3查询薪资核算记录所用薪资账套的薪资项目副本
List<SalarySobItemPO> salarySobItemPOS = salarySobItemService.listBySalarySobId(salaryAcctRecordPO.getSalarySobId());
if (CollectionUtils.isEmpty(salarySobItemPOS)) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(99151, "当前所用的薪资账套未选择任何薪资项目,无法核算"));
}
// 4查询当前租户的所有薪资项目
List<SalaryItemPO> salaryItemPOS = salaryItemService.listAll();
// 5查询薪资核算记录所用薪资账套的调薪计薪规则
List<SalarySobAdjustRulePO> salarySobAdjustRulePOS = salarySobAdjustRuleService.listBySalarySobId(salaryAcctRecordPO.getSalarySobId());
// todo 6查询社保福利的所有字段
Map<String, String> welfareColumns = null;//siAccountService.welfareColumns(tenantKey);
// 7查询考勤引用的所有字段
List<AttendQuoteFieldListDTO> attendQuoteFieldListDTOS = attendQuoteFieldService.listAll();
// 8查询公式详情
Set<Long> formulaIds = SalaryEntityUtil.properties(salarySobItemPOS, SalarySobItemPO::getFormulaId);
formulaIds.addAll(SalaryEntityUtil.properties(salaryItemPOS, SalaryItemPO::getFormulaId));
List<ExpressFormula> expressFormulas = salaryFormulaService.listExpressFormula(formulaIds);
// 9计算薪资项目的运算优先级
List<List<Long>> salarySobItemsWithPriority = SalaryAcctCalculatePriorityBO.calculatePriority(salarySobItemPOS, salaryItemPOS, expressFormulas);
// 10根据id查询其他合并计税的薪资核算记录
List<SalaryAcctRecordPO> otherSalaryAcctRecordPOS = salaryAcctRecordService.listById4OtherConsolidatedTax(salaryAcctRecordPO.getId());
// 11查询本次核算人员
List<SalaryAcctEmployeePO> salaryAcctEmployeePOS;
if (CollectionUtils.isEmpty(calculateParam.getIds())) {
salaryAcctEmployeePOS = salaryAcctEmployeeService.listBySalaryAcctRecordId(salaryAcctRecordPO.getId());
} else {
salaryAcctEmployeePOS = salaryAcctEmployeeService.listByIds(calculateParam.getIds());
}
if (CollectionUtils.isEmpty(salaryAcctEmployeePOS)) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(103378, "薪资核算人员不能为空"));
}
// 11.1初始化进度
SalaryAcctProgressDTO initProgress = new SalaryAcctProgressDTO()
.setTitle(SalaryI18nUtil.getI18nLabel(97515, "核算中"))
.setTitleLabelId(97515L)
.setTotalQuantity(salaryAcctEmployeePOS.size() * 2 + 1)
.setCalculatedQuantity(0)
.setProgress(BigDecimal.ZERO)
.setStatus(true)
.setMessage(StringUtils.EMPTY);
// salaryAcctProgressService.initProgress("" + calculateParam.getSalaryAcctRecordId(), initProgress, simpleEmployee.getEmployeeId());
// // 12对薪资核算人员进行拆分
// List<List<SalaryAcctEmployeePO>> partition = Lists.partition(salaryAcctEmployeePOS, 100);
// // 12.1监控子线程的任务执行
// CountDownLatch childMonitor = new CountDownLatch(partition.size());
// // 12.2记录子线程的执行结果
// BlockingDeque<SalaryAcctCalculateBO.Result> calculateResults = new LinkedBlockingDeque<>(partition.size());
// // 12.3生成本次运算的key
// String calculateKey = UUID.randomUUID().toString();
// // 12.4多线程运算运算结果存放在临时表中
// for (List<SalaryAcctEmployeePO> acctEmployeePOS : partition) {
// SalaryAcctCalculateBO salaryAcctCalculateBO = new SalaryAcctCalculateBO()
// .setSalaryAcctRecordPO(salaryAcctRecordPO)
// .setSalarySobCycleDTO(salarySobCycleDTO)
// .setOtherSalaryAcctRecordPOS(otherSalaryAcctRecordPOS)
// .setSalarySobItemPOS(salarySobItemPOS)
// .setSalaryItemIdWithPriorityList(salarySobItemsWithPriority)
// .setExpressFormulas(expressFormulas)
// .setSalaryItemPOS(salaryItemPOS)
// .setSalarySobAdjustRulePOS(salarySobAdjustRulePOS)
// .setWelfareColumns(MapUtils.emptyIfNull(welfareColumns))
// .setAttendQuoteFieldListDTOS(attendQuoteFieldListDTOS)
// .setSalaryAcctEmployeePOS(acctEmployeePOS)
// .setChildMonitor(childMonitor)
// .setResults(calculateResults)
// .setCalculateKey(calculateKey);
// LocalRunnable localRunnable = new LocalRunnable() {
// @Override
// public void execute() {
// salaryAcctCalculateService.calculate(salaryAcctCalculateBO, simpleEmployee);
// }
// };
// ThreadPoolUtil.fixedPoolExecute(ModulePoolEnum.OTHER, "salaryAcctCalculate", localRunnable);
// }
// // 13等待所有子线程执行完毕
// childMonitor.await();
// // 14判断子线程执行结果
// boolean allSuccess = calculateResults.stream().allMatch(SalaryAcctCalculateBO.Result::isStatus);
// if (!allSuccess) {
// // 薪资核算实现的线程的错误信息
// String errorMsg = calculateResults.stream()
// .filter(result -> !result.isStatus())
// .map(SalaryAcctCalculateBO.Result::getErrMsg)
// .collect(Collectors.joining("|"));
// 12对薪资核算人员进行拆分
List<List<SalaryAcctEmployeePO>> partition = Lists.partition(salaryAcctEmployeePOS, 100);
// 12.1监控子线程的任务执行
CountDownLatch childMonitor = new CountDownLatch(partition.size());
// 12.2记录子线程的执行结果
BlockingDeque<SalaryAcctCalculateBO.Result> calculateResults = new LinkedBlockingDeque<>(partition.size());
// 12.3生成本次运算的key
String calculateKey = UUID.randomUUID().toString();
// 12.4多线程运算运算结果存放在临时表中
for (List<SalaryAcctEmployeePO> acctEmployeePOS : partition) {
SalaryAcctCalculateBO salaryAcctCalculateBO = new SalaryAcctCalculateBO()
.setSalaryAcctRecordPO(salaryAcctRecordPO)
.setSalarySobCycleDTO(salarySobCycleDTO)
.setOtherSalaryAcctRecordPOS(otherSalaryAcctRecordPOS)
.setSalarySobItemPOS(salarySobItemPOS)
.setSalaryItemIdWithPriorityList(salarySobItemsWithPriority)
.setExpressFormulas(expressFormulas)
.setSalaryItemPOS(salaryItemPOS)
.setSalarySobAdjustRulePOS(salarySobAdjustRulePOS)
.setWelfareColumns(MapUtils.emptyIfNull(welfareColumns))
.setAttendQuoteFieldListDTOS(attendQuoteFieldListDTOS)
.setSalaryAcctEmployeePOS(acctEmployeePOS)
.setChildMonitor(childMonitor)
.setResults(calculateResults)
.setCalculateKey(calculateKey);
LocalRunnable localRunnable = new LocalRunnable() {
@Override
public void execute() {
salaryAcctCalculateService.calculate(salaryAcctCalculateBO, simpleEmployee);
}
};
ThreadPoolUtil.fixedPoolExecute(ModulePoolEnum.OTHER, "salaryAcctCalculate", localRunnable);
}
// 13等待所有子线程执行完毕
childMonitor.await();
// 14判断子线程执行结果
boolean allSuccess = calculateResults.stream().allMatch(SalaryAcctCalculateBO.Result::isStatus);
if (!allSuccess) {
// 薪资核算实现的线程的错误信息
String errorMsg = calculateResults.stream()
.filter(result -> !result.isStatus())
.map(SalaryAcctCalculateBO.Result::getErrMsg)
.collect(Collectors.joining("|"));
// salaryAcctProgressService.fail("" + calculateParam.getSalaryAcctRecordId(), errorMsg);
// // 删除薪资核算临时存储表中的数据
// salaryAcctResultTempService.deleteByCalculateKey(calculateKey);
// return;
// }
// // 15处理核算结果临时表数据
// handleSalaryAcctResultTemp(calculateParam, calculateKey);
// // 16开始运行校验规则
// 删除薪资核算临时存储表中的数据
salaryAcctResultTempService.deleteByCalculateKey(calculateKey);
return;
}
// 15处理核算结果临时表数据
handleSalaryAcctResultTemp(calculateParam, calculateKey);
// 16开始运行校验规则
// SalaryAcctCheckParam salaryAcctCheckParam = new SalaryAcctCheckParam()
// .setSalaryAcctRecordId(calculateParam.getSalaryAcctRecordId())
// .setIds(calculateParam.getIds());
// salaryCheckResultService.check(salaryAcctCheckParam, true, simpleEmployee);
// // 记录日志
// // 查询操作日志的targetName
// 记录日志
// 查询操作日志的targetName
// String targetName = salaryAcctRecordService.getLogTargetNameById(calculateParam.getSalaryAcctRecordId());
// LoggerContext<SalaryCheckResultPO> loggerContext = new LoggerContext<>();
// loggerContext.setTargetId(String.valueOf(calculateParam.getSalaryAcctRecordId()));
@ -443,14 +461,13 @@ public class SalaryAcctResultServiceImpl extends Service implements SalaryAcctRe
// loggerContext.setOperateTypeName(SalaryI18nUtil.getI18nLabel(95783, "薪资核算"));
// loggerContext.setOperatedesc(SalaryI18nUtil.getI18nLabel(95783, "薪资核算"));
// salaryAcctRecordLoggerTemplate.write(loggerContext);
// } catch (Exception e) {
// log.info("薪资核算出错:{}", e.getMessage(), e);
} catch (Exception e) {
log.info("薪资核算出错:{}", e.getMessage(), e);
// salaryAcctProgressService.fail("" + calculateParam.getSalaryAcctRecordId(), SalaryI18nUtil.getI18nLabel(99642, "薪资核算出错") + ": " + e.getMessage());
// } finally {
// // 数据库字段加密用
// DSTenantKeyThreadVar.tenantKey.remove();
// }
// }
} finally {
// 数据库字段加密用
}
}
/**
* 处理薪资核算临时存储表中的数据
@ -458,27 +475,27 @@ public class SalaryAcctResultServiceImpl extends Service implements SalaryAcctRe
* @param calculateParam
* @param calculateKey
*/
// private void handleSalaryAcctResultTemp(SalaryAcctCalculateParam calculateParam, String calculateKey, String tenantKey) {
// TransactionStatus status = dataSourceTransactionManager.getTransaction(new DefaultTransactionDefinition());
// try {
// // 查询薪资核算结果的临时存储
// List<SalaryAcctResultTempPO> salaryAcctResultTempPOS = salaryAcctResultTempService.listByCalculateKey(calculateKey);
// // 删除原来的薪资核算结果
// if (CollectionUtils.isNotEmpty(calculateParam.getIds())) {
// salaryAcctResultMapper.deleteBySalaryAcctEmpIds(calculateParam.getIds());
// } else {
// salaryAcctResultMapper.deleteBySalaryAcctRecordIds(Collections.singleton(calculateParam.getSalaryAcctRecordId()));
// }
// // 保存薪资的薪资核算结果
// List<SalaryAcctResultPO> salaryAcctResultPOS = SalaryAcctResultBO.convert2ResultPO(salaryAcctResultTempPOS);
// batchSave(salaryAcctResultPOS);
// // 删除薪资核算临时存储表中的数据
// salaryAcctResultTempService.deleteByCalculateKey(calculateKey);
// // 提交事务
// dataSourceTransactionManager.commit(status);
// } catch (Exception e) {
// dataSourceTransactionManager.rollback(status);
// throw e;
// }
// }
private void handleSalaryAcctResultTemp(SalaryAcctCalculateParam calculateParam, String calculateKey) {
TransactionStatus status = dataSourceTransactionManager.getTransaction(new DefaultTransactionDefinition());
try {
// 查询薪资核算结果的临时存储
List<SalaryAcctResultTempPO> salaryAcctResultTempPOS = salaryAcctResultTempService.listByCalculateKey(calculateKey);
// 删除原来的薪资核算结果
if (CollectionUtils.isNotEmpty(calculateParam.getIds())) {
salaryAcctResultMapper.deleteBySalaryAcctEmpIds(calculateParam.getIds());
} else {
salaryAcctResultMapper.deleteBySalaryAcctRecordIds(Collections.singleton(calculateParam.getSalaryAcctRecordId()));
}
// 保存薪资的薪资核算结果
List<SalaryAcctResultPO> salaryAcctResultPOS = SalaryAcctResultBO.convert2ResultPO(salaryAcctResultTempPOS);
batchSave(salaryAcctResultPOS);
// 删除薪资核算临时存储表中的数据
salaryAcctResultTempService.deleteByCalculateKey(calculateKey);
// 提交事务
dataSourceTransactionManager.commit(status);
} catch (Exception e) {
dataSourceTransactionManager.rollback(status);
throw e;
}
}
}

View File

@ -0,0 +1,53 @@
package com.engine.salary.service.impl;
import com.engine.core.impl.Service;
import com.engine.salary.entity.salaryacct.po.SalaryAcctResultTempPO;
import com.engine.salary.mapper.salaryacct.SalaryAcctResultTempMapper;
import com.engine.salary.service.SalaryAcctResultTempService;
import com.engine.salary.util.db.MapperProxyFactory;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import java.util.Collection;
import java.util.List;
/**
* 薪资核算结果临时存储
* <p>Copyright: Copyright (c) 2022</p>
* <p>Company: 泛微软件</p>
*
* @author qiantao
* @version 1.0
**/
public class SalaryAcctResultTempServiceImpl extends Service implements SalaryAcctResultTempService {
private SalaryAcctResultTempMapper getSalaryAcctResultTempMapper(){
return MapperProxyFactory.getProxy(SalaryAcctResultTempMapper.class);
}
@Override
public List<SalaryAcctResultTempPO> listByCalculateKey(String calculateKey) {
if (StringUtils.isBlank(calculateKey)){
return Lists.newArrayList();
}
return getSalaryAcctResultTempMapper().listSome(SalaryAcctResultTempPO.builder().calculateKey(calculateKey).build());
}
@Override
public void batchSave(Collection<SalaryAcctResultTempPO> salaryAcctResultTempPOS) {
if (CollectionUtils.isNotEmpty(salaryAcctResultTempPOS)) {
getSalaryAcctResultTempMapper().batchInsert(salaryAcctResultTempPOS);
}
}
@Override
public void deleteByCalculateKey(String calculateKey) {
getSalaryAcctResultTempMapper().deleteByCalculateKey(calculateKey);
}
}

View File

@ -17,7 +17,7 @@ import com.engine.salary.mapper.archive.SalaryArchiveMapper;
import com.engine.salary.mapper.archive.SalaryArchiveTaxAgentMapper;
import com.engine.salary.service.SalaryArchiveTaxAgentService;
import com.engine.salary.util.SalaryI18nUtil;
import com.engine.salary.util.db.SqlProxyHandle;
import com.engine.salary.util.db.MapperProxyFactory;
import com.engine.salary.util.excel.ExcelUtil;
import com.engine.salary.util.page.PageInfo;
import com.engine.salary.util.page.PageUtil;
@ -43,7 +43,7 @@ public class SalaryArchiveTaxAgentServiceImpl extends Service implements SalaryA
private static final Logger log = LoggerFactory.getLogger(SalaryArchiveTaxAgentServiceImpl.class);
private SalaryArchiveTaxAgentMapper getSalaryArchiveTaxAgentMapper() {
return SqlProxyHandle.getProxy(SalaryArchiveTaxAgentMapper.class);
return MapperProxyFactory.getProxy(SalaryArchiveTaxAgentMapper.class);
}
private TaxAgentBiz taxAgentService = new TaxAgentBiz();
@ -97,7 +97,7 @@ public class SalaryArchiveTaxAgentServiceImpl extends Service implements SalaryA
SalaryArchiveTaxAgentSaveParam.checkParam(saveParam);
// 薪资档案
SalaryArchiveMapper salaryArchiveMapper = SqlProxyHandle.getProxy(SalaryArchiveMapper.class);
SalaryArchiveMapper salaryArchiveMapper = MapperProxyFactory.getProxy(SalaryArchiveMapper.class);
SalaryArchivePO salaryArchive = salaryArchiveMapper.getById(saveParam.getSalaryArchiveId());
// 获取当前已生效
SalaryArchiveTaxAgentPO effectiveTaxAgent = getEffectiveTaxAgent(saveParam.getSalaryArchiveId());

View File

@ -11,7 +11,7 @@ import com.engine.salary.mapper.salarysob.SalarySobAdjustRuleMapper;
import com.engine.salary.mapper.salarysob.SalarySobMapper;
import com.engine.salary.service.SalarySobAdjustRuleService;
import com.engine.salary.util.SalaryI18nUtil;
import com.engine.salary.util.db.SalarySqlProxyHandle;
import com.engine.salary.util.db.MapperProxyFactory;
import com.engine.salary.util.valid.ValidUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.ibatis.session.SqlSession;
@ -54,7 +54,7 @@ public class SalarySobAdjustRuleServiceImpl extends Service implements SalarySob
//开启事务
SqlSession sqlSession = MyBatisFactory.sqlSessionFactory.openSession();
try {
SalarySobMapper salarySobMapper = SalarySqlProxyHandle.getProxy(SalarySobMapper.class, sqlSession);
SalarySobMapper salarySobMapper = MapperProxyFactory.getProxy(SalarySobMapper.class);
// 查询薪资账套
SalarySobPO salarySobPO = salarySobMapper.getById(saveParam.getSalarySobId());
@ -62,7 +62,7 @@ public class SalarySobAdjustRuleServiceImpl extends Service implements SalarySob
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98379, "参数错误,薪资账套不存在或者已被删除"));
}
// 删除之前的调薪计薪规则
SalarySobAdjustRuleMapper salarySobAdjustRuleMapper = SalarySqlProxyHandle.getProxy(SalarySobAdjustRuleMapper.class, sqlSession);
SalarySobAdjustRuleMapper salarySobAdjustRuleMapper = MapperProxyFactory.getProxy(SalarySobAdjustRuleMapper.class);
salarySobAdjustRuleMapper.deleteBySalarySobIds(Collections.singleton(saveParam.getSalarySobId()));
// 保存参数转换成薪资账套的调薪计薪规则po
List<SalarySobAdjustRulePO> salarySobAdjustRulePOS = SalarySobAdjustRuleBO.convert2PO(saveParam, (long)user.getUID());

View File

@ -2,13 +2,32 @@ package com.engine.salary.service.impl;
import com.engine.core.impl.Service;
import com.engine.salary.cmd.TaxRate.*;
import com.engine.salary.entity.taxrate.SysTaxRateBase;
import com.engine.salary.entity.taxrate.TaxRateBase;
import com.engine.salary.mapper.SysTaxRateBaseMapper;
import com.engine.salary.mapper.TaxRateBaseMapper;
import com.engine.salary.service.TaxRateBaseService;
import com.engine.salary.util.db.MapperProxyFactory;
import com.google.common.collect.Lists;
import org.springframework.beans.BeanUtils;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class TaxRateBaseServiceImpl extends Service implements TaxRateBaseService {
private SysTaxRateBaseMapper getSysTaxRateBaseMapper(){
return MapperProxyFactory.getProxy(SysTaxRateBaseMapper.class);
}
private TaxRateBaseMapper getTaxRateBaseMapper(){
return MapperProxyFactory.getProxy(TaxRateBaseMapper.class);
}
@Override
public Map<String, Object> listPage(Map<String, Object> params) {
return commandExecutor.execute(new TaxRateListCmd(params, user));
@ -36,5 +55,24 @@ public class TaxRateBaseServiceImpl extends Service implements TaxRateBaseServic
return commandExecutor.execute(new TaxRateDeleteCmd(params, user));
}
@Override
public List<TaxRateBase> list() {
List<TaxRateBase> resultList = Lists.newArrayList();
// 查询系统默认的税率表
List<SysTaxRateBase> sysTaxRateBasePOS = getSysTaxRateBaseMapper().listAll();
List<TaxRateBase> taxRateBasePOS4Sys = sysTaxRateBasePOS.stream()
.map(sysTaxRateBasePO -> {
TaxRateBase taxRateBasePO = new TaxRateBase();
BeanUtils.copyProperties(sysTaxRateBasePO, taxRateBasePO);
return taxRateBasePO;
})
.collect(Collectors.toList());
resultList.addAll(taxRateBasePOS4Sys);
// 查询自定义税率表
List<TaxRateBase> taxRateBasePOS = getTaxRateBaseMapper().listAll();
resultList.addAll(taxRateBasePOS);
return resultList;
}
}

View File

@ -0,0 +1,67 @@
package com.engine.salary.service.impl;
import com.engine.core.impl.Service;
import com.engine.salary.entity.taxrate.SysTaxRateDetailPO;
import com.engine.salary.entity.taxrate.TaxRateDetail;
import com.engine.salary.mapper.SysTaxRateDetailMapper;
import com.engine.salary.mapper.TaxRateDetailMapper;
import com.engine.salary.service.TaxRateDetailService;
import com.engine.salary.util.db.MapperProxyFactory;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
/**
* 个税税率表明细表
* <p>Copyright: Copyright (c) 2022</p>
* <p>Company: 泛微软件</p>
*
* @author qiantao
* @version 1.0
**/
public class TaxRateDetailServiceImpl extends Service implements TaxRateDetailService {
private TaxRateDetailMapper getTaxRateDetailMapper(){
return MapperProxyFactory.getProxy(TaxRateDetailMapper.class);
}
private SysTaxRateDetailMapper getSysTaxRateDetailMapper(){
return MapperProxyFactory.getProxy(SysTaxRateDetailMapper.class);
}
// @Override
// public TaxRateDetail getByFormulaFilterData(Long taxRateBaseId, boolean isOr, Collection<FormulaFilterData> formulaFilterDataList, String tenantKey) {
// List<TaxRateDetail> taxRateDetailPOS = listByBaseId(taxRateBaseId);
// if (CollectionUtils.isEmpty(taxRateDetailPOS)) {
// return null;
// }
// // 根据公式中的条件过滤出个税税率表明细
// return TaxRateDetailBO.filter(taxRateDetailPOS, isOr, formulaFilterDataList);
// }
@Override
public List<TaxRateDetail> listByBaseId(Long taxRateBaseId) {
// 查询系统默认税率表的明细
List<SysTaxRateDetailPO> sysTaxRateDetailPOS = getSysTaxRateDetailMapper().listByBaseId(taxRateBaseId);
if (CollectionUtils.isNotEmpty(sysTaxRateDetailPOS)) {
return sysTaxRateDetailPOS.stream()
.map(sysTaxRateDetailPO -> {
TaxRateDetail taxRateDetailPO = new TaxRateDetail();
BeanUtils.copyProperties(sysTaxRateDetailPO, taxRateDetailPO);
return taxRateDetailPO;
}).collect(Collectors.toList());
}
// 查询自定义税率表的明细
return getTaxRateDetailMapper().listByBaseId(taxRateBaseId);
}
@Override
public void deleteByBaseIds(Collection<Long> taxRateBaseIds) {
getTaxRateDetailMapper().deleteByBatchIds(taxRateBaseIds);
}
}

View File

@ -154,6 +154,10 @@ public class SalaryDateUtil {
return LocalDateTime.ofInstant(instant, zone);
}
public static LocalDate dateToLocalDate(Date date) {
return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
}
public static Date localDateToDate(LocalDate localDate) {
if (null == localDate) {
return null;

View File

@ -10,16 +10,13 @@ import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* @author zhangjian
* @date 2017-8-25 下午5:41:17
*/
public class SqlProxyHandle implements InvocationHandler {
public class MapperProxyFactory implements InvocationHandler {
private Class clazz;
private boolean isAutoCommit = true;
private boolean enableTransactions = false;
private SqlSession session;
public SqlProxyHandle(Class clazz) {
public MapperProxyFactory(Class clazz) {
this.clazz = clazz;
}
@ -28,12 +25,11 @@ public class SqlProxyHandle implements InvocationHandler {
if (this.session == null) {
this.session = MyBatisFactory.sqlSessionFactory.openSession();
}
// System.out.println(MyBatisFactory.getSql(this.clazz, method.getName(), args[0]));
try {
Object target = session.getMapper(clazz);
return method.invoke(target, args);
} finally {
if (isAutoCommit) {
if (!enableTransactions) {
session.commit();
session.close();
}
@ -41,7 +37,7 @@ public class SqlProxyHandle implements InvocationHandler {
}
public Object getProxy() {
if (!isAutoCommit)
if (enableTransactions)
this.session = MyBatisFactory.sqlSessionFactory.openSession();
ClassLoader loader = Thread.currentThread().getContextClassLoader();
Class<?>[] interfaces = new Class<?>[1];
@ -50,7 +46,7 @@ public class SqlProxyHandle implements InvocationHandler {
}
public Object getProxy(boolean isAutoCommit) {
this.isAutoCommit = isAutoCommit;
this.enableTransactions = isAutoCommit;
return this.getProxy();
}
@ -69,12 +65,12 @@ public class SqlProxyHandle implements InvocationHandler {
}
public static <T> T getProxy(Class<T> clazz) {
SqlProxyHandle handle = new SqlProxyHandle(clazz);
MapperProxyFactory handle = new MapperProxyFactory(clazz);
return (T) handle.getProxy();
}
public static <T> T getProxy(Class<T> clazz, boolean isAutoSubmit) {
SqlProxyHandle handle = new SqlProxyHandle(clazz);
return (T) handle.getProxy(isAutoSubmit);
public static <T> T getProxy(Class<T> clazz, boolean enableTransactions) {
MapperProxyFactory handle = new MapperProxyFactory(clazz);
return (T) handle.getProxy(enableTransactions);
}
}

View File

@ -1,83 +0,0 @@
package com.engine.salary.util.db;
import org.apache.ibatis.session.SqlSession;
import weaver.conn.mybatis.MyBatisFactory;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class SalarySqlProxyHandle implements InvocationHandler {
private Class clazz;
private boolean enableTransactions = false;
private SqlSession session;
public SalarySqlProxyHandle() {
}
public SalarySqlProxyHandle(Class clazz) {
this.clazz = clazz;
}
public SalarySqlProxyHandle(Class clazz, boolean enableTransactions) {
this.clazz = clazz;
this.enableTransactions = enableTransactions;
}
public SalarySqlProxyHandle(Class clazz, boolean enableTransactions, SqlSession session) {
this.clazz = clazz;
this.enableTransactions = enableTransactions;
this.session = session;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Exception {
if (this.session == null) {
this.session = MyBatisFactory.sqlSessionFactory.openSession();
}
try {
Object target = session.getMapper(clazz);
Object invoke = method.invoke(target, args);
if (!enableTransactions) {
session.commit();
}
return invoke;
} finally {
if (!enableTransactions) {
this.session.close();
}
}
}
public Object getProxy() {
ClassLoader loader = Thread.currentThread().getContextClassLoader();
Class<?>[] interfaces = new Class<?>[1];
interfaces[0] = this.clazz;
return Proxy.newProxyInstance(loader, interfaces, this);
}
public void commit() {
if (this.session != null) {
this.session.commit();
this.session.close();
}
}
public void rollback() {
if (this.session != null) {
this.session.rollback();
this.session.close();
}
}
public static <T> T getProxy(Class<T> clazz) {
SalarySqlProxyHandle handle = new SalarySqlProxyHandle(clazz);
return (T) handle.getProxy();
}
public static <T> T getProxy(Class<T> clazz, SqlSession sqlSession) {
SalarySqlProxyHandle handle = new SalarySqlProxyHandle(clazz, true, sqlSession);
return (T) handle.getProxy();
}
}

View File

@ -247,7 +247,7 @@ public class AttendQuoteController {
@Produces(MediaType.APPLICATION_JSON)
public String syncAttendFields(@Context HttpServletRequest request, @Context HttpServletResponse response) {
User user = HrmUserVarify.getUser(request, response);
return new ResponseResult<Long, String>().run(getFieldService(user)::syncAttendFields, (long) user.getUID());
return new ResponseResult<Long, String>().run(getFieldService(user)::syncAttendFields);
}
/**

View File

@ -1,19 +1,34 @@
package com.engine.salary.wrapper;
import com.cloudstore.eccom.pc.table.WeaTableColumn;
import com.cloudstore.eccom.result.WeaResultMsg;
import com.engine.core.impl.Service;
import com.engine.salary.component.SalaryWeaTable;
import com.engine.salary.entity.datacollection.DataCollectionEmployee;
import com.engine.salary.entity.salaryacct.bo.SalaryAcctResultBO;
import com.engine.salary.entity.salaryacct.dto.ConsolidatedTaxDetailDTO;
import com.engine.salary.entity.salaryacct.dto.SalaryAcctResultDetailDTO;
import com.engine.salary.entity.salaryacct.param.SalaryAcctCalculateParam;
import com.engine.salary.entity.salaryacct.param.SalaryAcctResultQueryParam;
import com.engine.salary.entity.salaryacct.param.SalaryAcctResultSaveParam;
import com.engine.salary.entity.salaryacct.po.SalaryAcctRecordPO;
import com.engine.salary.entity.salaryarchive.dto.SalaryArchiveListDTO;
import com.engine.salary.entity.salarysob.dto.SalarySobItemAggregateDTO;
import com.engine.salary.exception.SalaryRunTimeException;
import com.engine.salary.service.SalaryAcctRecordService;
import com.engine.salary.service.SalaryAcctResultService;
import com.engine.salary.service.SalarySobItemService;
import com.engine.salary.service.TaxAgentService;
import org.springframework.stereotype.Component;
import com.engine.salary.util.SalaryI18nUtil;
import com.engine.salary.util.page.PageInfo;
import com.weaver.util.threadPool.ThreadPoolUtil;
import com.weaver.util.threadPool.constant.ModulePoolEnum;
import com.weaver.util.threadPool.entity.LocalRunnable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
* 薪资核算结果
@ -23,8 +38,7 @@ import java.util.List;
* @author qiantao
* @version 1.0
**/
@Component
public class SalaryAcctResultWrapper {
public class SalaryAcctResultWrapper extends Service {
private SalaryAcctResultService salaryAcctResultService;
@ -48,41 +62,41 @@ public class SalaryAcctResultWrapper {
* @param tenantKey 租户key
* @return
*/
// public WeaTable<Map<String, Object>> listPage(SalaryAcctResultQueryParam queryParam, String tenantKey) {
// // 查询薪资核算记录
// SalaryAcctRecordPO salaryAcctRecordPO = salaryAcctRecordService.getById(queryParam.getSalaryAcctRecordId());
// if (Objects.isNull(salaryAcctRecordPO)) {
// throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98747, "薪资核算记录不存在或已被删除"));
// }
// // 构建薪资核算结果列表的表头
// List<WeaTableColumn> weaTableColumns = listWeaTableColumn(salaryAcctRecordPO, tenantKey);
// // 查询薪资核算结果分页
// Page<Map<String, Object>> page = salaryAcctResultService.listPageByParam(queryParam, tenantKey);
// // 转换成前端所需的数据格式
// WeaTable<Map<String, Object>> weaTable = new WeaTable<>();
// weaTable.setColumns(weaTableColumns);
// weaTable.setPage(page);
// weaTable.setData(page.getRecords());
// weaTable.setDisplayData(page.getRecords());
// weaTable.setPageUid("salaryAcctResultList");
// weaTable.setModule("hrmsalary");
// // 列表操作列
// if (Objects.equals(salaryAcctRecordPO.getStatus(), SalaryAcctRecordStatusEnum.NOT_ARCHIVED.getValue())) {
// weaTable.setOperates(Collections.singletonList(new WeaTableOperate("edit", SalaryI18nUtil.getI18nLabel(87058, "编辑"), 0, true, true)));
// List<List<Permission>> operatesPermission = page.getRecords().stream().map(e -> Collections.singletonList(new Permission())).collect(Collectors.toList());
// weaTable.setOperatesPermission(operatesPermission);
// }
// return weaTable;
// }
public Map<String,Object> listPage(SalaryAcctResultQueryParam queryParam, String tenantKey) {
// 查询薪资核算记录
SalaryAcctRecordPO salaryAcctRecordPO = salaryAcctRecordService.getById(queryParam.getSalaryAcctRecordId());
if (Objects.isNull(salaryAcctRecordPO)) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98747, "薪资核算记录不存在或已被删除"));
}
// 查询薪资核算结果分页
PageInfo<Map<String, Object>> page = salaryAcctResultService.listPageByParam(queryParam);
// 构建薪资核算结果列表的表头
List<WeaTableColumn> columns = listWeaTableColumn(salaryAcctRecordPO);
SalaryWeaTable<SalaryArchiveListDTO> table = new SalaryWeaTable<SalaryArchiveListDTO>(user, SalaryArchiveListDTO.class);
table.setColumns(columns);
WeaResultMsg result = new WeaResultMsg(false);
result.putAll(table.makeDataResult());
result.success();
Map<String,Object> datas = new HashMap<>();
datas.put("pageInfo", page);
datas.put("dataKey",result.getResultMap());
return datas;
}
/**
* 构建薪资核算结果列表的表头
*
* @param salaryAcctRecordPO 薪资核算记录
* @param tenantKey 租户key
* @return
*/
public List<WeaTableColumn> listWeaTableColumn(SalaryAcctRecordPO salaryAcctRecordPO, String tenantKey) {
public List<WeaTableColumn> listWeaTableColumn(SalaryAcctRecordPO salaryAcctRecordPO) {
// 查询薪资账套下的薪资项目+员工信息字段
SalarySobItemAggregateDTO salarySobItemAggregateDTO = salarySobItemService.getAggregateBySalarySobId(salaryAcctRecordPO.getSalarySobId());
// 构建薪资核算结果列表表头
@ -150,12 +164,11 @@ public class SalaryAcctResultWrapper {
*
* @param calculateParam 薪资核算的参数
* @param simpleEmployee 当前登陆人员
* @param tenantKey 租户key
*/
// public void calculate(SalaryAcctCalculateParam calculateParam, DataCollectionEmployee simpleEmployee) {
// // 检查薪资核算人员的个税扣缴义务人
// salaryAcctEmployeeWrapper.checkTaxAgent(calculateParam.getSalaryAcctRecordId());
// // 检查是否正在核算中
public void calculate(SalaryAcctCalculateParam calculateParam, DataCollectionEmployee simpleEmployee) {
// 检查薪资核算人员的个税扣缴义务人
salaryAcctEmployeeWrapper.checkTaxAgent(calculateParam.getSalaryAcctRecordId());
// 检查是否正在核算中
// SalaryAcctProgressDTO salaryAcctProgressDTO = salaryAcctProgressService.getProgress("" + calculateParam.getSalaryAcctRecordId(), simpleEmployee.getEmployeeId(), tenantKey);
// if (Objects.nonNull(salaryAcctProgressDTO) && salaryAcctProgressDTO.isStatus() && Optional.ofNullable(salaryAcctProgressDTO.getProgress()).orElse(BigDecimal.ZERO).compareTo(BigDecimal.ONE) < 0) {
// return;
@ -170,15 +183,15 @@ public class SalaryAcctResultWrapper {
// .setStatus(true)
// .setMessage(StringUtils.EMPTY);
// salaryAcctProgressService.initProgress("" + calculateParam.getSalaryAcctRecordId(), initProgress, simpleEmployee.getEmployeeId(), tenantKey);
// // 异步执行薪资核算
// LocalRunnable localRunnable = new LocalRunnable() {
// @Override
// public void execute() {
// salaryAcctResultService.calculate(calculateParam, simpleEmployee, tenantKey);
// }
// };
// ThreadPoolUtil.fixedPoolExecute(ModulePoolEnum.OTHER, "salaryAcctCalculate", localRunnable);
// }
// 异步执行薪资核算
LocalRunnable localRunnable = new LocalRunnable() {
@Override
public void execute() {
salaryAcctResultService.calculate(calculateParam, simpleEmployee);
}
};
ThreadPoolUtil.fixedPoolExecute(ModulePoolEnum.OTHER, "salaryAcctCalculate", localRunnable);
}
/**
* 薪资核算-校验