package com.engine.salary.entity.salaryacct.bo;
import com.engine.salary.constant.SalaryFormulaFieldConstant;
import com.engine.salary.entity.salaryacct.po.SalaryAcctResultPO;
import com.engine.salary.entity.salaryformula.ExpressFormula;
import com.engine.salary.entity.salaryformula.po.FormulaVar;
import com.engine.salary.entity.salaryitem.po.SalaryItemPO;
import com.engine.salary.enums.salaryformula.SalaryFormulaReferenceEnum;
import com.engine.salary.util.SalaryEntityUtil;
import com.google.common.collect.Maps;
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.regex.Matcher;
import java.util.regex.Pattern;
/**
* 薪资核算公式
*
Copyright: Copyright (c) 2022
* Company: 泛微软件
*
* @author qiantao
* @version 1.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> buildFormulaVar(List expressFormulas) {
if (CollectionUtils.isEmpty(expressFormulas)) {
return Collections.emptyMap();
}
Map> resultMap = Maps.newHashMapWithExpectedSize(expressFormulas.size());
for (ExpressFormula expressFormula : expressFormulas) {
resultMap.put(expressFormula.getId(), expressFormula.getParameters());
}
return resultMap;
}
/**
* 给公式中的变量填入值
*
* @param expressFormulas
* @param salaryItems
* @param acctResults
* @return
*/
public static Map> buildFormulaVar4Check(List expressFormulas, List salaryItems, List acctResults) {
if (CollectionUtils.isEmpty(expressFormulas)) {
return Collections.emptyMap();
}
Map salaryItemCodeMap = SalaryEntityUtil.convert2Map(salaryItems, SalaryItemPO::getId, SalaryItemPO::getCode);
Map acctResultMap = SalaryEntityUtil.convert2Map(acctResults, e -> salaryItemCodeMap.getOrDefault(e.getSalaryItemId(), ""), SalaryAcctResultPO::getResultValue);
Map> 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 buildFormulaVar4Accounting(ExpressFormula expressFormula, Map formulaVarValueMap) {
List formulaVars = Collections.emptyList();
formulaVars = expressFormula.getParameters();
for (FormulaVar formulaVar : formulaVars) {
// 公式变量的值
String formulaVarValue = formulaVarValueMap.getOrDefault(formulaVar.getFieldId(), StringUtils.EMPTY);
// 如果公式的返回值类型为number,公式中的变量的值如果为空,公式运行的时候会报错,所以需要替换成0
if (StringUtils.isEmpty(formulaVarValue) && "number".equals(formulaVar.getFieldType())) {
formulaVarValue = BigDecimal.ZERO.toPlainString();
} else if (StringUtils.isEmpty(formulaVarValue) && "string".equals(formulaVar.getFieldType())) {
formulaVarValue = "";
}
formulaVar.setContent(formulaVarValue);
}
return formulaVars;
}
}