From 2ab7049fa0e5bfe5756c87f2419fbba5f7ddf296 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=92=B1=E6=B6=9B?= <15850646081@163.com> Date: Wed, 23 Nov 2022 18:30:53 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8D=95=E4=B8=AA=E6=A0=B8=E7=AE=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../salaryacct/bo/SalaryAcctEmployeeBO.java | 24 + .../salaryacct/bo/SalaryCalcContext.java | 46 ++ .../bo/SalaryCalcEmployeeContext.java | 41 ++ .../salaryacct/bo/SalaryCalcFormula.java | 53 ++ .../bo/SalaryCalcFormulaContext.java | 105 +++ .../salaryacct/bo/SalaryCalcResult.java | 34 + .../salaryacct/dto/SalaryAcctRateDTO.java | 41 ++ .../salary/service/SalaryAcctCalcService.java | 31 + .../service/SalaryAcctEmployeeService.java | 1 - .../salary/service/SalaryCacheService.java | 69 ++ .../salary/service/SalaryEmployeeService.java | 2 +- .../salary/service/SalaryFormulaService.java | 6 + .../service/impl/SISchemeServiceImpl.java | 2 - .../impl/SalaryAcctCalcServiceImpl.java | 648 ++++++++++++++++++ .../service/impl/SalaryCacheServiceImpl.java | 50 ++ .../impl/SalaryFormulaServiceImpl.java | 5 + .../salary/wrapper/TaxDeclarationWrapper.java | 4 - 17 files changed, 1154 insertions(+), 8 deletions(-) create mode 100644 src/com/engine/salary/entity/salaryacct/bo/SalaryCalcContext.java create mode 100644 src/com/engine/salary/entity/salaryacct/bo/SalaryCalcEmployeeContext.java create mode 100644 src/com/engine/salary/entity/salaryacct/bo/SalaryCalcFormula.java create mode 100644 src/com/engine/salary/entity/salaryacct/bo/SalaryCalcFormulaContext.java create mode 100644 src/com/engine/salary/entity/salaryacct/bo/SalaryCalcResult.java create mode 100644 src/com/engine/salary/entity/salaryacct/dto/SalaryAcctRateDTO.java create mode 100644 src/com/engine/salary/service/SalaryAcctCalcService.java create mode 100644 src/com/engine/salary/service/SalaryCacheService.java create mode 100644 src/com/engine/salary/service/impl/SalaryAcctCalcServiceImpl.java create mode 100644 src/com/engine/salary/service/impl/SalaryCacheServiceImpl.java diff --git a/src/com/engine/salary/entity/salaryacct/bo/SalaryAcctEmployeeBO.java b/src/com/engine/salary/entity/salaryacct/bo/SalaryAcctEmployeeBO.java index 67a99329b..6ce040fed 100644 --- a/src/com/engine/salary/entity/salaryacct/bo/SalaryAcctEmployeeBO.java +++ b/src/com/engine/salary/entity/salaryacct/bo/SalaryAcctEmployeeBO.java @@ -119,4 +119,28 @@ public class SalaryAcctEmployeeBO { } return resultList; } + + + public static List> partitionByEmployeeId(List salaryAcctEmployees) { + if (CollectionUtils.isEmpty(salaryAcctEmployees)) { + return Collections.emptyList(); + } + List employeeIdList = salaryAcctEmployees.stream() + .map(SalaryAcctEmployeePO::getEmployeeId) + .distinct() + .collect(Collectors.toList()); + // 每个线程处理多少个人员(一个线程最多处理10个人员) + int size = 100; + List> partition = Lists.partition(employeeIdList, size); + List> resultList = new ArrayList<>(); + Map> salaryAcctEmployeeMap = SalaryEntityUtil.group2Map(salaryAcctEmployees, SalaryAcctEmployeePO::getEmployeeId); + for (List employeeIds : partition) { + List temp = new ArrayList<>(); + for (Long employeeId : employeeIds) { + temp.addAll(salaryAcctEmployeeMap.getOrDefault(employeeId, Collections.emptyList())); + } + resultList.add(temp); + } + return resultList; + } } diff --git a/src/com/engine/salary/entity/salaryacct/bo/SalaryCalcContext.java b/src/com/engine/salary/entity/salaryacct/bo/SalaryCalcContext.java new file mode 100644 index 000000000..c1a88ba6a --- /dev/null +++ b/src/com/engine/salary/entity/salaryacct/bo/SalaryCalcContext.java @@ -0,0 +1,46 @@ +package com.engine.salary.entity.salaryacct.bo; + +import com.engine.salary.entity.datacollection.DataCollectionEmployee; +import com.engine.salary.entity.salaryacct.po.SalaryAcctRecordPO; +import com.engine.salary.entity.salarysob.dto.SalarySobCycleDTO; +import com.engine.salary.entity.salarysob.po.SalarySobAdjustRulePO; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @description: 薪资核算上下文 + * @author: xiajun + * @modified By: xiajun + * @date: Created in 8/22/22 3:26 PM + * @version:v1.0 + */ +@Data +public class SalaryCalcContext { + + /** + * 当前核算人员 + */ + private DataCollectionEmployee simpleEmployee; + /** + * 员工状态 + */ + private Map hrmStatusMap; + /** + * 薪资核算记录 + */ + private SalaryAcctRecordPO salaryAcctRecord; + /** + * 考勤周期、薪资周期、税款所属期、社保福利台账月份 + */ + private SalarySobCycleDTO salarySobCycle; + /** + * 调薪计薪规则 + */ + private List salaryAdjustmentRules; + /** + * 本次薪资核算所涉及的公式 + */ + private SalaryCalcFormulaContext salaryCalcFormulaContext; +} diff --git a/src/com/engine/salary/entity/salaryacct/bo/SalaryCalcEmployeeContext.java b/src/com/engine/salary/entity/salaryacct/bo/SalaryCalcEmployeeContext.java new file mode 100644 index 000000000..fa07e673e --- /dev/null +++ b/src/com/engine/salary/entity/salaryacct/bo/SalaryCalcEmployeeContext.java @@ -0,0 +1,41 @@ +package 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 lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @description: + * @author: xiajun + * @modified By: xiajun + * @date: Created in 8/23/22 3:45 PM + * @version:v1.0 + */ +@Data +public class SalaryCalcEmployeeContext { + + /** + * key:formulaId、value:公式变量的值 + */ + private Map> formulaVarValueMap; + /** + * key:salaryAcctEmployeeId、value:薪资核算结果 + */ + private Map noDecryptAcctResultValueMap; + /** + * key:salaryAcctRecordId、value:薪资核算记录 + */ + private Map sameTaxCycleRecordMap; + /** + * key:employee-taxAgentId、value:薪资核算人员 + */ + private Map> sameTaxCycleEmployeeMap; + /** + * key:salaryAcctEmployeeId、value:薪资核算结果 + */ + private Map sameTaxCycleResultValueMap; +} diff --git a/src/com/engine/salary/entity/salaryacct/bo/SalaryCalcFormula.java b/src/com/engine/salary/entity/salaryacct/bo/SalaryCalcFormula.java new file mode 100644 index 000000000..937bffdc7 --- /dev/null +++ b/src/com/engine/salary/entity/salaryacct/bo/SalaryCalcFormula.java @@ -0,0 +1,53 @@ +package com.engine.salary.entity.salaryacct.bo; + +import com.engine.salary.enums.SalaryRoundingModeEnum; +import com.engine.salary.enums.salaryitem.SalaryDataTypeEnum; +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * @description: 薪资核算计算优先级 + * @author: xiajun + * @modified By: xiajun + * @date: Created in 8/23/22 11:52 AM + * @version:v1.0 + */ +@Data +@Accessors(chain = true) +public class SalaryCalcFormula { + + /** + * 薪资项目id + */ + private Long salaryItemId; + /** + * 薪资项目的code + */ + private String salaryItemCode; + /** + * 薪资类型 + */ + private String incomeCategory; + /** + * 薪资档案引用。0:薪资档案未引用、1:薪资档案引用 + * 为处理历史数据而留,不再使用 + */ + @Deprecated + private Integer useInEmployeeSalary; + /** + * 字段类型 + */ + private SalaryDataTypeEnum dataType; + /** + * 舍入规则 + */ + private SalaryRoundingModeEnum roundingMode; + /** + * 小数位数 + */ + private Integer pattern; + /** + * 公式id + */ + private Long formulaId; +} diff --git a/src/com/engine/salary/entity/salaryacct/bo/SalaryCalcFormulaContext.java b/src/com/engine/salary/entity/salaryacct/bo/SalaryCalcFormulaContext.java new file mode 100644 index 000000000..bd8a60387 --- /dev/null +++ b/src/com/engine/salary/entity/salaryacct/bo/SalaryCalcFormulaContext.java @@ -0,0 +1,105 @@ +package com.engine.salary.entity.salaryacct.bo; + +import com.engine.salary.entity.salaryformula.ExpressFormula; +import com.engine.salary.entity.salaryitem.po.SalaryItemPO; +import com.googlecode.aviator.Expression; +import lombok.Data; + +import java.util.*; + +/** + * @description: 薪资核算公式 + * @author: xiajun + * @modified By: xiajun + * @date: Created in 8/22/22 3:33 PM + * @version:v1.0 + */ +@Data +public class SalaryCalcFormulaContext { + + /** + * 薪资核算所包含的薪资项目 + */ + private Map salaryItemMap; + + /** + * 本次薪资核算所涉及的公式编译后的对象 + */ + private Map expressionMap; + + /** + * 薪资核算所包含的公式 + */ + private Map expressFormulaMap; + + /** + * 薪资核算所包含的薪资项目id(按计算顺序排序好了) + */ + private List> salaryCalcFormulas; + + /** + * 所有公式中是否包含薪资档案 + */ + private Set salaryArchiveFieldIds; + + /** + * 所有公式中是否包含其他扣除 + */ + private Set otherDeductionFieldIds; + + /** + * 所有公式中是否包含专项附加扣除 + */ + private Set addUpDeductionFieldIds; + + /** + * 所有公式中是否包含往期累计情况 + */ + private Set addUpSituationFieldIds; + + /** + * 所有公式中是否包含考勤 + */ + private Set attendFieldIds; + + /** + * 所有公式中是否包含社保福利 + */ + private Set welfareFieldIds; + + /** + * 所有公式中是否包含人员信息 + */ + private Set employeeInfoFieldIds; + + /** + * 所有公式中是否包含外部人员 + */ + private Set extEmployeeFieldIds; + + /** + * 所有公式中包含的自定义业务数据表 + */ + private Map> customDataFieldIdMap; + + /** + * 所有公式中包含的已发 + */ + private Set issuedFieldIds; + + public SalaryCalcFormulaContext() { + this.salaryItemMap = new HashMap<>(); + this.expressFormulaMap = new HashMap<>(); + this.salaryCalcFormulas = new ArrayList<>(); + this.salaryArchiveFieldIds = new HashSet<>(); + this.otherDeductionFieldIds = new HashSet<>(); + this.addUpDeductionFieldIds = new HashSet<>(); + this.addUpSituationFieldIds = new HashSet<>(); + this.attendFieldIds = new HashSet<>(); + this.welfareFieldIds = new HashSet<>(); + this.employeeInfoFieldIds = new HashSet<>(); + this.extEmployeeFieldIds = new HashSet<>(); + this.customDataFieldIdMap = new HashMap<>(); + this.issuedFieldIds = new HashSet<>(); + } +} diff --git a/src/com/engine/salary/entity/salaryacct/bo/SalaryCalcResult.java b/src/com/engine/salary/entity/salaryacct/bo/SalaryCalcResult.java new file mode 100644 index 000000000..3b658c769 --- /dev/null +++ b/src/com/engine/salary/entity/salaryacct/bo/SalaryCalcResult.java @@ -0,0 +1,34 @@ +package com.engine.salary.entity.salaryacct.bo; + +import com.engine.salary.entity.salaryacct.po.SalaryAcctResultPO; +import lombok.AllArgsConstructor; +import lombok.Data; + +import java.util.List; + +/** + * @description: + * @author: xiajun + * @modified By: xiajun + * @date: 2022/8/22 20:45 + * @version:v1.0 + */ +@Data +@AllArgsConstructor +public class SalaryCalcResult { + + /** + * 子线程是否运算成功 + */ + private boolean status; + + /** + * 子线程元算失败的错误信息 + */ + private String errMsg; + + /** + * 计算结果 + */ + private List salaryAcctResultValues; +} diff --git a/src/com/engine/salary/entity/salaryacct/dto/SalaryAcctRateDTO.java b/src/com/engine/salary/entity/salaryacct/dto/SalaryAcctRateDTO.java new file mode 100644 index 000000000..8044bed9e --- /dev/null +++ b/src/com/engine/salary/entity/salaryacct/dto/SalaryAcctRateDTO.java @@ -0,0 +1,41 @@ +package com.engine.salary.entity.salaryacct.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.math.BigDecimal; + +@Data +@Accessors(chain = true) +@AllArgsConstructor +public class SalaryAcctRateDTO { + + //"缓存索引") + private String index; + //"提示信息") + private String msg; + //"状态") + private boolean status; + //"是否已经完成") + private boolean finish; + //"总数") + private Integer totalQty; + //"已经计算的数量") + private Integer calcQty; + //"进度") + private BigDecimal rate; + //"校验异常") + private boolean checkStatus; + + public SalaryAcctRateDTO(String index) { + this.index = index; + this.msg = ""; + this.status = true; + this.finish = false; + this.totalQty = 1; + this.calcQty = 0; + this.rate = BigDecimal.ZERO; + this.checkStatus = true; + } +} diff --git a/src/com/engine/salary/service/SalaryAcctCalcService.java b/src/com/engine/salary/service/SalaryAcctCalcService.java new file mode 100644 index 000000000..842622b3c --- /dev/null +++ b/src/com/engine/salary/service/SalaryAcctCalcService.java @@ -0,0 +1,31 @@ +//package com.engine.salary.service; +// +//import com.engine.salary.entity.datacollection.DataCollectionEmployee; +// +//import java.util.Collection; +// +///** +// * @description: 薪资核算 +// * @author: xiajun +// * @modified By: xiajun +// * @date: Created in 8/22/22 3:15 PM +// * @version:v1.0 +// */ +//public interface SalaryAcctCalcService { +// +// /** +// * 按薪资核算记录id进行核算 +// * +// * @param salaryAcctRecordId +// * @param simpleEmployee +// */ +// void calcByRecordId(Long salaryAcctRecordId, DataCollectionEmployee simpleEmployee) throws Exception; +// +// /** +// * 按薪资核算人员id进行核算 +// * +// * @param salaryAcctEmployeeIds +// * @param simpleEmployee +// */ +// void calcByEmployeeIds(Long salaryAcctRecordId, Collection salaryAcctEmployeeIds, DataCollectionEmployee simpleEmployee) throws Exception; +//} diff --git a/src/com/engine/salary/service/SalaryAcctEmployeeService.java b/src/com/engine/salary/service/SalaryAcctEmployeeService.java index 325cb7b1f..44f9f38f7 100644 --- a/src/com/engine/salary/service/SalaryAcctEmployeeService.java +++ b/src/com/engine/salary/service/SalaryAcctEmployeeService.java @@ -1,6 +1,5 @@ package com.engine.salary.service; -import com.engine.salary.entity.datacollection.DataCollectionEmployee; import com.engine.salary.entity.salaryacct.dto.SalaryAcctEmployeeCountDTO; import com.engine.salary.entity.salaryacct.param.*; import com.engine.salary.entity.salaryacct.po.SalaryAcctEmployeePO; diff --git a/src/com/engine/salary/service/SalaryCacheService.java b/src/com/engine/salary/service/SalaryCacheService.java new file mode 100644 index 000000000..2c01c1466 --- /dev/null +++ b/src/com/engine/salary/service/SalaryCacheService.java @@ -0,0 +1,69 @@ +package com.engine.salary.service; + +public interface SalaryCacheService { + + /** + * 添加缓存 + * + * @param key + * @param value + * @param + * @return + */ + void set(String key, T value); + + /** + * 添加缓存,有过期时间 + * + * @param key + * @param value + * @param time + * @return + */ + void set(String key, T value, int time); + + /** + * 将对象转为json字符串缓存 + * @param key + * @param value + * @param + */ + void setJson(String key, T value); + + /** + * 将对象转为json字符串缓存,有过期时间 + * @param key + * @param value + * @param time + * @param + */ + void setJson(String key, T value, int time); + + + /** + * 获取缓存 + * @param key + * @param + * @return + */ + T get(String key); + + + /** + * 获取缓存对象 + * @param key + * @param clazz + * @param + * @return + */ + T getJson(String key, Class clazz); + + /** + * 清除缓存 + * + * @param key + */ + void remove(String key); + + +} diff --git a/src/com/engine/salary/service/SalaryEmployeeService.java b/src/com/engine/salary/service/SalaryEmployeeService.java index 1acc05e9b..a31b12692 100644 --- a/src/com/engine/salary/service/SalaryEmployeeService.java +++ b/src/com/engine/salary/service/SalaryEmployeeService.java @@ -72,5 +72,5 @@ public interface SalaryEmployeeService { * @param workcode 工号 * @param uid 人员id */ - List matchImportEmployee(List employeeList, String userName, String deparmentName, String mobile, String workcode,Long uid); + List matchImportEmployee(List employeeList, String userName, String deparmentName, String mobile, String workcode, Long uid); } diff --git a/src/com/engine/salary/service/SalaryFormulaService.java b/src/com/engine/salary/service/SalaryFormulaService.java index 591e83caa..5bc9223f0 100644 --- a/src/com/engine/salary/service/SalaryFormulaService.java +++ b/src/com/engine/salary/service/SalaryFormulaService.java @@ -36,4 +36,10 @@ public interface SalaryFormulaService { FormulaPO save(SalaryFormulaSaveParam salaryFormulaSaveParam); FormulaPO update(SalaryFormulaSaveParam salaryFormulaSaveParam); + + + /** + * 初始化函数 + */ + void initFunction(); } diff --git a/src/com/engine/salary/service/impl/SISchemeServiceImpl.java b/src/com/engine/salary/service/impl/SISchemeServiceImpl.java index 1a1ab9cdc..6cbbd9b5f 100644 --- a/src/com/engine/salary/service/impl/SISchemeServiceImpl.java +++ b/src/com/engine/salary/service/impl/SISchemeServiceImpl.java @@ -17,7 +17,6 @@ import com.engine.salary.encrypt.siarchives.InsuranceArchivesOtherSchemePOEncryp import com.engine.salary.encrypt.siarchives.InsuranceArchivesSocialSchemePOEncrypt; import com.engine.salary.encrypt.sischeme.InsuranceSchemeDetailPOEncrypt; import com.engine.salary.entity.datacollection.DataCollectionEmployee; -import com.engine.salary.entity.salaryarchive.po.SalaryArchivePO; import com.engine.salary.entity.siarchives.param.InsuranceArchivesListParam; import com.engine.salary.entity.siarchives.po.*; import com.engine.salary.entity.sicategory.po.ICategoryPO; @@ -64,7 +63,6 @@ import org.apache.commons.lang3.math.NumberUtils; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.util.IOUtils; import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.apache.xpath.operations.Bool; import weaver.file.ImageFileManager; import weaver.hrm.User; diff --git a/src/com/engine/salary/service/impl/SalaryAcctCalcServiceImpl.java b/src/com/engine/salary/service/impl/SalaryAcctCalcServiceImpl.java new file mode 100644 index 000000000..c48450772 --- /dev/null +++ b/src/com/engine/salary/service/impl/SalaryAcctCalcServiceImpl.java @@ -0,0 +1,648 @@ +//package com.engine.salary.service.impl; +// +//import com.engine.salary.cache.SalaryCacheKey; +//import com.engine.salary.constant.SalaryDefaultTenantConstant; +//import com.engine.salary.entity.datacollection.DataCollectionEmployee; +//import com.engine.salary.entity.salaryacct.bo.*; +//import com.engine.salary.entity.salaryacct.dto.SalaryAcctRateDTO; +//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.salaryformula.ExpressFormula; +//import com.engine.salary.entity.salaryitem.po.SalaryItemPO; +//import com.engine.salary.service.*; +//import com.engine.salary.util.SalaryEntityUtil; +//import com.google.common.collect.Lists; +//import com.google.common.collect.Maps; +//import com.googlecode.aviator.Expression; +//import com.weaver.common.distribution.genid.IdGenerator; +//import com.weaver.common.elog.dto.LoggerContext; +//import com.weaver.common.elog.util.Util; +//import com.weaver.common.hrm.domain.employee.HrmStatus; +//import com.weaver.datasecurity.interceptor.DSTenantKeyThreadVar; +//import com.weaver.excel.formula.api.entity.FormulaVar; +//import com.weaver.excel.formula.entity.parameter.standard.ExcelResult; +//import com.weaver.framework.util.JsonUtil; +//import com.weaver.hrm.salary.common.LocalDateRange; +//import com.weaver.hrm.salary.constant.SalaryFormulaFieldConstant; +//import com.weaver.hrm.salary.entity.customdata.param.CustomDataEmployeeQueryParam; +//import com.weaver.hrm.salary.entity.customdata.po.CustomDataEmployeePO; +//import com.weaver.hrm.salary.entity.customdata.po.CustomDataRecordPO; +//import com.weaver.hrm.salary.entity.datacollection.dto.AttendQuoteDataDTO; +//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.extemployee.po.ExtEmployeePO; +//import com.weaver.hrm.salary.entity.salaryacct.bo.*; +//import com.weaver.hrm.salary.entity.salaryacct.po.*; +//import com.weaver.hrm.salary.entity.salaryarchive.dto.SalaryArchiveDataDTO; +//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.SalarySobBackItemPO; +//import com.weaver.hrm.salary.entity.salarysob.po.SalarySobItemPO; +//import com.weaver.hrm.salary.entity.salarysob.po.SalarySobPO; +//import com.weaver.hrm.salary.enums.OperateTypeEnum; +//import com.weaver.hrm.salary.enums.salaryaccounting.EmployeeTypeEnum; +//import com.weaver.hrm.salary.enums.salaryaccounting.SalaryAcctRecordStatusEnum; +//import com.weaver.hrm.salary.enums.salaryitem.SalaryDataTypeEnum; +//import com.weaver.hrm.salary.enums.salaryitem.SalaryFormulaReferenceEnum; +//import com.weaver.hrm.salary.enums.salaryitem.SalaryRoundingModeEnum; +//import com.weaver.hrm.salary.enums.salarysob.IncomeCategoryEnum; +//import com.weaver.hrm.salary.enums.sicategory.DeleteTypeEnum; +//import com.weaver.hrm.salary.exception.SalaryRunTimeException; +//import com.weaver.hrm.salary.service.*; +//import com.weaver.hrm.salary.util.SalaryI18nUtil; +//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.apache.commons.lang3.math.NumberUtils; +//import org.springframework.transaction.annotation.Transactional; +// +//import java.math.BigDecimal; +//import java.math.RoundingMode; +//import java.time.LocalDateTime; +//import java.time.Month; +//import java.util.*; +//import java.util.concurrent.BlockingDeque; +//import java.util.concurrent.CountDownLatch; +//import java.util.concurrent.LinkedBlockingDeque; +//import java.util.stream.Collectors; +// +///** +// * 薪资核算 +// * +// *

Copyright: Copyright (c) 2022

+// *

Company: 泛微软件

+// * +// * @author qiantao +// * @version 1.0 +// **/ +//@Slf4j +//public class SalaryAcctCalcServiceImpl implements SalaryAcctCalcService { +// +// +// private SalaryAcctRecordService salaryAcctRecordService; +// +// private SalarySobItemService salarySobItemService; +// +//// private SalarySobBackItemService salarySobBackItemService; +// +// private SalarySobAdjustRuleService salarySobAdjustRuleService; +// +// private SalaryFormulaService salaryFormulaService; +// +// private SalaryItemService salaryItemService; +// +// private SalaryAcctEmployeeService salaryAcctEmployeeService; +// +// private SalaryArchiveService salaryArchiveService; +// +// private AddUpSituationService addUpSituationService; +// +// private AddUpDeductionService addUpDeductionService; +// +// private OtherDeductionService otherDeductionService; +// +// private AttendQuoteDataService attendQuoteDataService; +// +// private SIAccountService siAccountService; +// +// private SalaryCacheService salaryCacheService; +// +//// private CustomDataRecordService customDataRecordService; +// +//// private CustomDataEmployeeService customDataEmployeeService; +// +//// private HrmCommonEmployeeService hrmCommonEmployeeService; +// +//// private ExtEmployeeService extEmployeeService; +// +//// private SalaryAcctResultValueService salaryAcctResultValueService; +// +// +// private SalarySobService salarySobService; +// +//// private SalaryAcctSobConfigService salaryAcctSobConfigService; +// +// +// @Override +// public void calcByRecordId(Long salaryAcctRecordId, DataCollectionEmployee simpleEmployee) throws Exception { +// calcByEmployeeIds(salaryAcctRecordId, Collections.emptyList(), simpleEmployee); +// } +// +// @Override +// @Transactional(rollbackFor = Exception.class) +// public void calcByEmployeeIds(Long salaryAcctRecordId, Collection salaryAcctEmployeeIds, DataCollectionEmployee simpleEmployee) throws Exception { +// SalaryAcctRateDTO salaryAcctRate = new SalaryAcctRateDTO("" + salaryAcctRecordId); +// try { +// String tenantKey = SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY; +// // 查询本次核算的薪资核算人员 +// List salaryAcctEmployees; +// if (CollectionUtils.isEmpty(salaryAcctEmployeeIds)) { +// salaryAcctEmployees = salaryAcctEmployeeService.listBySalaryAcctRecordId(salaryAcctRecordId); +// } else { +// salaryAcctEmployees = salaryAcctEmployeeService.listByIds(salaryAcctEmployeeIds); +// } +// // 初始化核算进度(总数+1是因为所有人员核算完成后,数据保存入库还需要一定的时间) +// salaryAcctRate.setTotalQty(salaryAcctEmployees.size() + 1); +// salaryCacheService.set(SalaryCacheKey.ACCT_PROGRESS + salaryAcctRate.getIndex(), salaryAcctRate); +// // 查询薪资核算记录 +// SalaryAcctRecordPO salaryAcctRecord = salaryAcctRecordService.getById(salaryAcctRecordId); +// // 检查是否能够核算 +// checkBeforeCalc(salaryAcctRecord, salaryAcctEmployees); +// // 加载函数 +//// salaryFormulaService.initFunction(); +// // 构建核算上下文 +// SalaryCalcContext salaryCalcContext = loadContext(salaryAcctRecord, simpleEmployee); +// // 分批核算 +// List> salaryAcctEmployeePartition = SalaryAcctEmployeeBO.partitionByEmployeeId(salaryAcctEmployees); +// // 监控子线程的任务执行 +// CountDownLatch childMonitor = new CountDownLatch(salaryAcctEmployeePartition.size()); +// // 记录子线程的执行结果 +// BlockingDeque blockingDeque = new LinkedBlockingDeque<>(salaryAcctEmployeePartition.size()); +// for (List partSalaryAcctEmployees : salaryAcctEmployeePartition) { +// LocalRunnable localRunnable = new LocalRunnable() { +// @Override +// public void execute() { +// calc(salaryCalcContext, partSalaryAcctEmployees, childMonitor, blockingDeque, simpleEmployee); +// } +// }; +// ThreadPoolUtil.fixedPoolExecute(ModulePoolEnum.OTHER, "salaryAcctCalculate", localRunnable); +// } +// // 等待核算结束 +// childMonitor.await(); +// // 处理核算结果 +// handleCalcResult(blockingDeque, salaryAcctRecordId, salaryAcctEmployeeIds, tenantKey); +// // 记录日志 +// writeLog(salaryAcctRecordId, tenantKey); +// // 核算结束,更新进度 +// salaryAcctRate.setFinish(true).setCalcQty(salaryAcctEmployees.size()).setRate(BigDecimal.ONE); +// } finally { +// // 更新进度 +// salaryCacheService.set(SalaryCacheKey.ACCT_PROGRESS + salaryAcctRate.getIndex(), salaryAcctRate); +// } +// } +// +// private void calc(SalaryCalcContext salaryCalcContext, +// List salaryAcctEmployees, +// CountDownLatch childMonitor, +// BlockingDeque blockingDeque, +// DataCollectionEmployee simpleEmployee) { +// try { +// // 数据库字段加密用 +// LocalDateTime now = LocalDateTime.now(); +// // 加载公式计算时所需要的变量 +// SalaryCalcEmployeeContext salaryCalcEmployeeContext = loadEmployeeContext(salaryCalcContext, salaryAcctEmployees, simpleEmployee.getTenantKey()); +// // 对薪资核算人员进行分组,如果是合并计算(工资薪金、劳务一起计算)的话,会存在工资薪金和劳务费用的项目存在相互引用,所以相关联的人员要在同一组进行核算 +// Map> salaryAcctEmployeeMap = SalaryEntityUtil.group2Map(salaryAcctEmployees, SalaryAcctEmployeePO::getId); +//// if (salaryCalcContext.getSalarySobCycle().getIncomeCategories().size() > 1) { +//// salaryAcctEmployeeMap = SalaryEntityUtil.group2Map(salaryAcctEmployees, SalaryAcctEmployeePO::getEmployeeId); +//// } +// // 计算公式 +// int calcQty = 0; +// List newSalaryAcctResultValues = Lists.newArrayListWithExpectedSize(salaryAcctEmployees.size()); +// for (Map.Entry> entry : salaryAcctEmployeeMap.entrySet()) { +// // 获取锁定的薪资项目 +// Set lockSalaryItemIds = new HashSet<>(Collections.emptySet()); +// for (SalaryAcctEmployeePO salaryAcctEmployee : entry.getValue()) { +// SalaryAcctResultPO noDecryptSalaryAcctResultValue = salaryCalcEmployeeContext.getNoDecryptAcctResultValueMap().get(salaryAcctEmployee.getId()); +//// if (noDecryptSalaryAcctResultValue != null) { +//// lockSalaryItemIds.addAll(noDecryptSalaryAcctResultValue.getLockSalaryItemIds()); +//// } +// } +// Map> incomeCategoryResultValueMap = Maps.newHashMap(); +// Map incomeCategoryAcctEmployeeMap = SalaryEntityUtil.convert2Map(entry.getValue(), SalaryAcctEmployeePO::getIncomeCategory); +// // 根据解析好的公式计算优先级计算公式 +// for (List formulaPriority : salaryCalcContext.getSalaryCalcFormulaContext().getSalaryCalcFormulas()) { +// for (SalaryCalcFormula salaryCalcFormula : formulaPriority) { +// SalaryAcctEmployeePO salaryAcctEmployee; +// if (Objects.equals(salaryCalcFormula.getIncomeCategory(), "0")) { +// salaryAcctEmployee = SalaryEntityUtil.findFirst(entry.getValue()); +// } else { +// salaryAcctEmployee = incomeCategoryAcctEmployeeMap.get(salaryCalcFormula.getIncomeCategory()); +// } +// if (salaryAcctEmployee == null) { +// continue; +// } +// // 找出需要计算的公式 +// SalaryItemPO salaryItem = salaryCalcContext.getSalaryCalcFormulaContext().getSalaryItemMap().get(salaryCalcFormula.getSalaryItemId()); +// ExpressFormula expressFormula = salaryCalcContext.getSalaryCalcFormulaContext().getExpressFormulaMap().get(salaryCalcFormula.getFormulaId()); +// Expression expression = salaryCalcContext.getSalaryCalcFormulaContext().getExpressionMap().get(salaryCalcFormula.getFormulaId()); +// // 获取变量的值 +// Map formulaVarValueMap = salaryCalcEmployeeContext.getFormulaVarValueMap().computeIfAbsent(salaryAcctEmployee.getId(), k -> new HashMap<>()); +// // 运行公式获取结果 +// String resultValue = calcResultValue(salaryCalcFormula, expressFormula, expression, formulaVarValueMap, lockSalaryItemIds, salaryCalcContext.getSimpleEmployee()); +// // 处理合并计税 +// resultValue = handleConsolidatedTax(salaryCalcContext, salaryCalcEmployeeContext, salaryAcctEmployee, resultValue, salaryItem); +// // 处理小数位数 +// resultValue = roundResultValue(resultValue, salaryCalcFormula); +// // 将公式计算结果回填到变量map中 +// formulaVarValueMap.put(SalaryFormulaReferenceEnum.SALARY_ITEM.getValue() +// + SalaryFormulaFieldConstant.FIELD_ID_SEPARATOR + salaryItem.getCode(), resultValue); +// // 合并计算时工资薪金和劳务费用的项目存在相互引用,所以需要将公式计算结果回填到另一个相关联的薪资核算人员的变量map中 +// for (SalaryAcctEmployeePO relationSalaryAcctEmployee : entry.getValue()) { +// if (!Objects.equals(relationSalaryAcctEmployee.getId(), salaryAcctEmployee.getId())) { +// Map relationFormulaVarValueMap = salaryCalcEmployeeContext.getFormulaVarValueMap().computeIfAbsent(relationSalaryAcctEmployee.getId(), k -> new HashMap<>()); +// relationFormulaVarValueMap.put(SalaryFormulaReferenceEnum.SALARY_ITEM.getValue() +// + SalaryFormulaFieldConstant.FIELD_ID_SEPARATOR + salaryItem.getCode(), resultValue); +// } +// } +// // 计算结果 +// Map resultValueMap = incomeCategoryResultValueMap.computeIfAbsent(salaryCalcFormula.getIncomeCategory(), k -> Maps.newHashMap()); +// resultValueMap.put("" + salaryCalcFormula.getSalaryItemId(), resultValue); +// } +// } +// for (SalaryAcctEmployeePO salaryAcctEmployee : entry.getValue()) { +// Map resultValueMap = Maps.newHashMap(); +// // 根据薪资核算人员的收入所得项目(工资薪金或者劳务),获取对应的薪资核算结果 +// resultValueMap.putAll(incomeCategoryResultValueMap.getOrDefault(salaryAcctEmployee.getIncomeCategory(), Collections.emptyMap())); +// // 回算薪资项目既不属于工资薪金也不属于劳务,但是也要保存到人员的薪资核算结果中 +// resultValueMap.putAll(incomeCategoryResultValueMap.getOrDefault("0", Collections.emptyMap())); +// SalaryAcctResultValuePO noDecryptSalaryAcctResultValue = salaryCalcEmployeeContext.getNoDecryptAcctResultValueMap().get(salaryAcctEmployee.getId()); +// SalaryAcctResultValuePO newSalaryAcctResultValue = new SalaryAcctResultValuePO() +// .setId(IdGenerator.generate()) +// .setSalaryAcctRecordId(salaryAcctEmployee.getSalaryAcctRecordId()) +// .setSalaryAcctEmployeeId(salaryAcctEmployee.getId()) +// .setResultValue(resultValueMap) +// .setOriginResultValueJson(noDecryptSalaryAcctResultValue == null +// ? StringUtils.EMPTY : noDecryptSalaryAcctResultValue.getOriginResultValueJson()) +// .setLockSalaryItemIds(lockSalaryItemIds) +// .setDeleteType(DeleteTypeEnum.NOT_DELETED.getValue()) +// .setTenantKey(simpleEmployee.getTenantKey()) +// .setCreator(simpleEmployee.getEmployeeId()) +// .setCreateTime(now) +// .setUpdateTime(now); +// newSalaryAcctResultValues.add(newSalaryAcctResultValue); +// // 更新计算进度 +// updateRate(salaryCalcContext.getSalaryAcctRecord().getId(), ++calcQty, salaryAcctEmployees.size()); +// } +// } +// blockingDeque.add(new SalaryCalcResult(true, "", newSalaryAcctResultValues)); +// } catch (Exception e) { +// log.info("薪资核算失败:{}", e.getMessage(), e); +// blockingDeque.add(new SalaryCalcResult(false, e.getMessage(), Collections.emptyList())); +// } finally { +// // 子线程执行完毕 +// childMonitor.countDown(); +// // 数据库字段加密用 +// DSTenantKeyThreadVar.tenantKey.remove(); +// } +// } +// +// private void checkBeforeCalc(SalaryAcctRecordPO salaryAcctRecordPO, List salaryAcctEmployees) { +// if (Objects.isNull(salaryAcctRecordPO)) { +// throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(145221, "薪资核算记录不存在或已被删除")); +// } +// // 归档状态或已申报状态下不能核算 +// if (!Objects.equals(salaryAcctRecordPO.getStatus(), SalaryAcctRecordStatusEnum.NOT_ARCHIVED.getValue())) { +// throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(145222, "薪资核算记录已经归档,不能再核算")); +// } +// // 没有薪资核算人员不能核算 +// if (CollectionUtils.isEmpty(salaryAcctEmployees)) { +// throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(0, "当前核算人员为空,请先确认要核算的人员")); +// } +// } +// +// private SalaryCalcContext loadContext(SalaryAcctRecordPO salaryAcctRecord, DataCollectionEmployee simpleEmployee) { +// String tenantKey = simpleEmployee.getTenantKey(); +// // 查询考勤周期、薪资周期、税款所属期、社保福利台账月份 +// SalarySobCycleDTO salarySobCycle = salaryAcctRecordService.getSalarySobCycleById(salaryAcctRecord.getId(), tenantKey); +// // 查询薪资核算记录的账套配置 +// SalaryAcctSobConfigPO salaryAcctSobConfig = salaryAcctSobConfigService.getBySalaryAcctRecordId(salaryAcctRecord.getId(), tenantKey); +// // 薪资项目 +// List salarySobItems = JsonUtil.parseList(salaryAcctSobConfig.getItemConfig(), SalarySobItemPO.class); +// // 回算薪资项目 +// List salarySobBackItems = !Objects.equals(salaryAcctRecord.getBackCalcStatus(), 1) ? Collections.emptyList() +// : JsonUtil.parseList(salaryAcctSobConfig.getBackItemConfig(), SalarySobBackItemPO.class); +// // 查询薪资项目所用的公式id +// Set formulaIds = new HashSet<>(); +// formulaIds.addAll(SalaryEntityUtil.properties(salarySobItems, SalarySobItemPO::getFormulaId)); +// formulaIds.addAll(SalaryEntityUtil.properties(salarySobBackItems, SalarySobBackItemPO::getFormulaId)); +// List expressFormulas = salaryFormulaService.listOriginExpressFormula(formulaIds, tenantKey); +// // 查询薪资项目 +// Set salaryItemIds = new HashSet<>(); +// salaryItemIds.addAll(SalaryEntityUtil.properties(salarySobItems, SalarySobItemPO::getSalaryItemId)); +// salaryItemIds.addAll(SalaryEntityUtil.properties(salarySobBackItems, SalarySobBackItemPO::getSalaryItemId)); +// List salaryItems = salaryItemService.listByIds(salaryItemIds, tenantKey); +// // 计算薪资项目的计算优先级 +// SalaryCalcPriority salaryCalcPriority = new SalaryCalcPriority(salaryItems, salarySobItems, salarySobBackItems, expressFormulas); +// SalaryCalcFormulaContext salaryCalcFormulaContext = salaryCalcPriority.calc(); +// // 查询薪资核算所用的调薪计薪规则 +// List salarySobAdjustRules = salarySobAdjustRuleService.listBySalarySobId(salaryAcctRecord.getSalarySobId(), tenantKey); +// // 查询员工状态 +// List hrmStatusList = hrmCommonHrmStatusService.list(tenantKey); +// Map hrmStatusMap = SalaryEntityUtil.convert2Map(hrmStatusList, hrmStatus -> "" + hrmStatus.getCodeId(), HrmStatus::getName); +// +// // 构建上下文 +// SalaryCalcContext salaryCalcContext = new SalaryCalcContext(); +// salaryCalcContext.setSimpleEmployee(simpleEmployee); +// salaryCalcContext.setHrmStatusMap(hrmStatusMap); +// salaryCalcContext.setSalaryAcctRecord(salaryAcctRecord); +// salaryCalcContext.setSalarySobCycle(salarySobCycle); +// salaryCalcContext.setSalaryAdjustmentRules(salarySobAdjustRules); +// salaryCalcContext.setSalaryCalcFormulaContext(salaryCalcFormulaContext); +// return salaryCalcContext; +// } +// +// private SalaryCalcEmployeeContext loadEmployeeContext(SalaryCalcContext salaryCalcContext, List salaryAcctEmployees, String tenantKey) { +// // 查询合并计税的薪资核算记录 +// LocalDateRange localDateRange = LocalDateRange.builder() +// .fromDate(salaryCalcContext.getSalarySobCycle().getTaxCycle().atDay(1)) +// .endDate(salaryCalcContext.getSalarySobCycle().getTaxCycle().atEndOfMonth()) +// .build(); +// List salaryAcctRecords = salaryAcctRecordService.listByTaxCycle(localDateRange, tenantKey); +// Map salaryAcctRecordMap = SalaryEntityUtil.convert2Map(salaryAcctRecords, SalaryAcctRecordPO::getId); +// // 查询合并计税的薪资核算人员 +// List sameTaxCycleSalaryAcctEmployees = salaryAcctEmployeeService.listSameTaxCycle(salaryAcctEmployees, salaryCalcContext.getSalarySobCycle().getTaxCycle().toString(), tenantKey); +// Map> sameTaxCycleEmployeeMap = SalaryEntityUtil.group2Map(sameTaxCycleSalaryAcctEmployees, o -> o.getEmployeeId() + "-" + o.getTaxAgentId()); +// Set sameTaxCycleSalaryAcctEmployeeIds = SalaryEntityUtil.properties(sameTaxCycleSalaryAcctEmployees, SalaryAcctEmployeePO::getId); +// List sameTaxCycleResultValues = salaryAcctResultValueService +// .listBySalaryAcctEmployeeIds(sameTaxCycleSalaryAcctEmployeeIds, tenantKey); +// Map sameTaxCycleResultValueMap = SalaryEntityUtil.convert2Map(sameTaxCycleResultValues, SalaryAcctResultValuePO::getSalaryAcctEmployeeId); +// +// SalaryCalcEmployeeContext salaryCalcEmployeeContext = new SalaryCalcEmployeeContext(); +// salaryCalcEmployeeContext.setSameTaxCycleRecordMap(salaryAcctRecordMap); +// salaryCalcEmployeeContext.setSameTaxCycleEmployeeMap(sameTaxCycleEmployeeMap); +// salaryCalcEmployeeContext.setSameTaxCycleResultValueMap(sameTaxCycleResultValueMap); +// // 加载公式变量 +// loadFormulaVar(salaryCalcContext, salaryCalcEmployeeContext, salaryAcctEmployees); +// return salaryCalcEmployeeContext; +// } +// +// private void loadFormulaVar(SalaryCalcContext salaryCalcContext, SalaryCalcEmployeeContext salaryCalcEmployeeContext, List salaryAcctEmployees) { +// String tenantKey = salaryCalcContext.getSimpleEmployee().getTenantKey(); +// // 薪资核算人员中的组织架构人员 +// List employeeIds = SalaryEntityUtil.properties(salaryAcctEmployees, SalaryAcctEmployeePO::getEmployeeId, Collectors.toList()); +// // 查询薪资档案 +// List salaryArchiveDataList = Collections.emptyList(); +// if (CollectionUtils.isNotEmpty(salaryCalcContext.getSalaryCalcFormulaContext().getSalaryArchiveFieldIds()) +// && CollectionUtils.isNotEmpty(employeeIds)) { +// salaryArchiveDataList = salaryArchiveService.getSalaryArchiveData(salaryCalcContext.getSalarySobCycle().getSalaryCycle(), employeeIds, tenantKey); +// } +// // 查询往期累计情况 +// List addUpSituations = Collections.emptyList(); +// if (CollectionUtils.isNotEmpty(salaryCalcContext.getSalaryCalcFormulaContext().getAddUpSituationFieldIds()) +// && salaryCalcContext.getSalarySobCycle().getTaxCycle().getMonth() != Month.JANUARY +// && CollectionUtils.isNotEmpty(employeeIds)) { +// addUpSituations = addUpSituationService.getAddUpSituationList(salaryCalcContext.getSalarySobCycle().getTaxCycle().plusMonths(-1), employeeIds, tenantKey); +// } +// // 查询累计专项附加扣除 +// List addUpDeductions = Collections.emptyList(); +// if (CollectionUtils.isNotEmpty(salaryCalcContext.getSalaryCalcFormulaContext().getAddUpDeductionFieldIds()) +// && CollectionUtils.isNotEmpty(employeeIds)) { +// addUpDeductions = addUpDeductionService.getAddUpDeductionList(salaryCalcContext.getSalarySobCycle().getTaxCycle(), employeeIds, tenantKey); +// } +// // 查询其他扣除 +// List otherDeductions = Collections.emptyList(); +// if (CollectionUtils.isNotEmpty(salaryCalcContext.getSalaryCalcFormulaContext().getOtherDeductionFieldIds()) +// && CollectionUtils.isNotEmpty(employeeIds)) { +// otherDeductions = otherDeductionService.getOtherDeductionList(salaryCalcContext.getSalarySobCycle().getTaxCycle(), employeeIds, tenantKey); +// } +// // 查询考勤 +// List attendQuoteDataList = Collections.emptyList(); +// if (CollectionUtils.isNotEmpty(salaryCalcContext.getSalaryCalcFormulaContext().getAttendFieldIds()) +// && CollectionUtils.isNotEmpty(employeeIds)) { +// SalarySobPO salarySob = salarySobService.getById(salaryCalcContext.getSalaryAcctRecord().getSalarySobId(), tenantKey); +// attendQuoteDataList = attendQuoteDataService.getAttendQuoteData(salaryCalcContext.getSalarySobCycle().getSalaryMonth(), salarySob.getOriginSalarySobId(), employeeIds, tenantKey); +// } +// // 查询社保福利 +// List> welfareMapList = Collections.emptyList(); +// if (CollectionUtils.isNotEmpty(salaryCalcContext.getSalaryCalcFormulaContext().getWelfareFieldIds()) +// && CollectionUtils.isNotEmpty(employeeIds)) { +// welfareMapList = siAccountService.welfareData(salaryCalcContext.getSalarySobCycle().getSocialSecurityCycle().toString(), employeeIds, tenantKey); +// } +// // 查询自定义业务数据 +// List customDataEmployees = Collections.emptyList(); +// if (MapUtils.isNotEmpty(salaryCalcContext.getSalaryCalcFormulaContext().getCustomDataFieldIdMap()) +// && CollectionUtils.isNotEmpty(employeeIds)) { +// Set customFieldIds = salaryCalcContext.getSalaryCalcFormulaContext().getCustomDataFieldIdMap().values().stream() +// .flatMap(Collection::stream) +// .map(fieldId -> Util.getLongValue(fieldId, 0L)) +// .collect(Collectors.toSet()); +// List customDataRecords = customDataRecordService.listByCustomFormIdsAndSalaryMonth( +// salaryCalcContext.getSalaryCalcFormulaContext().getCustomDataFieldIdMap().keySet(), +// salaryCalcContext.getSalarySobCycle().getSalaryMonth(), +// salaryCalcContext.getSimpleEmployee().getEmployeeId(), tenantKey); +// CustomDataEmployeeQueryParam param = new CustomDataEmployeeQueryParam() +// .setCustomDataRecordIds(SalaryEntityUtil.properties(customDataRecords, CustomDataRecordPO::getId)) +// .setEmployeeIds(employeeIds) +// .setCustomFieldIds(customFieldIds); +// customDataEmployees = customDataEmployeeService.listByParam(param, tenantKey); +// } +// // 查询人员信息 +// List simpleEmployees = Collections.emptyList(); +// if (CollectionUtils.isNotEmpty(salaryCalcContext.getSalaryCalcFormulaContext().getEmployeeInfoFieldIds()) +// && CollectionUtils.isNotEmpty(employeeIds)) { +// simpleEmployees = hrmCommonEmployeeService.getEmployeeByIds(employeeIds, tenantKey); +// } +// // 查询外部人员 +// List extEmployeeIds = salaryAcctEmployees.stream() +// .filter(salaryAcctEmployee -> Objects.equals(salaryAcctEmployee.getEmployeeType(), EmployeeTypeEnum.EXT_EMPLOYEE.getValue())) +// .map(SalaryAcctEmployeePO::getEmployeeId) +// .distinct() +// .collect(Collectors.toList()); +// List extEmployees = Collections.emptyList(); +// if (CollectionUtils.isNotEmpty(salaryCalcContext.getSalaryCalcFormulaContext().getExtEmployeeFieldIds()) +// && CollectionUtils.isNotEmpty(extEmployeeIds)) { +// extEmployees = extEmployeeService.listByIdsWithDeleted(extEmployeeIds, tenantKey); +// } +// // 查询薪资核算结果(不解密) +// Set salaryAcctEmployeeIds = SalaryEntityUtil.properties(salaryAcctEmployees, SalaryAcctEmployeePO::getId); +// List noDecryptSalaryAcctResultValues = salaryAcctResultValueService.listNoDecryptBySalaryAcctEmployeeIds(salaryAcctEmployeeIds, tenantKey); +// Map noDecryptSalaryAcctResultValueMap = SalaryEntityUtil.convert2Map(noDecryptSalaryAcctResultValues, SalaryAcctResultValuePO::getSalaryAcctEmployeeId); +// salaryCalcEmployeeContext.setNoDecryptAcctResultValueMap(noDecryptSalaryAcctResultValueMap); +// // 查询薪资核算结果(解密) +// List salaryAcctResultValues = salaryAcctResultValueService.listBySalaryAcctEmployeeIds(salaryAcctEmployeeIds, tenantKey); +// +// SalaryCalcFormulaVar salaryCalcFormulaVar = new SalaryCalcFormulaVar(salaryArchiveDataList, addUpSituations, +// addUpDeductions, otherDeductions, attendQuoteDataList, welfareMapList, customDataEmployees, simpleEmployees, extEmployees, salaryAcctResultValues); +// Map> resultMap = salaryCalcFormulaVar.handleSalaryCalcFormulaVar(salaryCalcContext, salaryAcctEmployees); +// Map> formulaVarValueMap = Maps.newHashMapWithExpectedSize(resultMap.size()); +// resultMap.forEach((k, v) -> { +// Map map = SalaryEntityUtil.convert2Map(v, SalaryCalcFormulaVarValue::getFieldId, SalaryCalcFormulaVarValue::getFieldValue); +// formulaVarValueMap.put(k, map); +// }); +// salaryCalcEmployeeContext.setFormulaVarValueMap(formulaVarValueMap); +// } +// +// private String calcResultValue(SalaryCalcFormula salaryCalcFormula, +// ExpressFormula expressFormula, +// Expression expression, +// Map formulaVarValueMap, +// Set lockSalaryItemIds, +// DataCollectionEmployee simpleEmployee) { +// String originValue = formulaVarValueMap.getOrDefault(SalaryFormulaReferenceEnum.SALARY_ITEM.getValue() +// + SalaryFormulaFieldConstant.FIELD_ID_SEPARATOR + salaryCalcFormula.getSalaryItemCode(), ""); +// if (Objects.isNull(expressFormula) || lockSalaryItemIds.contains(salaryCalcFormula.getSalaryItemId())) { +// if (Objects.equals(salaryCalcFormula.getUseInEmployeeSalary(), NumberUtils.INTEGER_ONE) && !lockSalaryItemIds.contains(salaryCalcFormula.getSalaryItemId())) { +// return formulaVarValueMap.getOrDefault(SalaryFormulaReferenceEnum.SALARY_ARCHIVES.getValue() +// + SalaryFormulaFieldConstant.FIELD_ID_SEPARATOR + salaryCalcFormula.getSalaryItemId(), ""); +// } +// return originValue; +// } +// // 如果只包含了优化的函数,走本模块的计算,否则走公式模块提供的公共方法计算 +// if (expression != null) { +// try { +// // 填充变量的值 +// Map envMap = ExpressFormulaBO.fillExpressionEnvMap(expressFormula, formulaVarValueMap); +// // 运行公式 +// return Util.null2String(expression.execute(envMap)); +// } catch (Exception e) { +// log.info("公式计算错误:{}", expressFormula.getFormula(), e); +// return StringUtils.EMPTY; +// } +// } +// // 填充变量的值 +// List formulaVars = ExpressFormulaBO.fillFormulaVarContent(expressFormula, formulaVarValueMap); +// // 运行公式 +// ExcelResult excelResult = excelRunService.run(expressFormula, formulaVars, simpleEmployee); +// if (excelResult.isStatus()) { +// return excelResult.getStringData(); +// } else { +// log.info("公式计算错误:{}, 错误原因:{}", expressFormula.getFormula(), excelResult.getErrorMsg()); +// return StringUtils.EMPTY; +// } +// } +// +// private String handleConsolidatedTax(SalaryCalcContext salaryCalcContext, +// SalaryCalcEmployeeContext salaryCalcEmployeeContext, +// SalaryAcctEmployeePO salaryAcctEmployee, +// String resultValue, +// SalaryItemPO salaryItem) { +// // 只有正常工资薪金所得才需要合并计税处理 +// if (!Objects.equals(salaryAcctEmployee.getIncomeCategory(), "" + IncomeCategoryEnum.WAGES_AND_SALARIES.getValue())) { +// return resultValue; +// } +// List sameTaxCycleSalaryAcctEmployees = salaryCalcEmployeeContext.getSameTaxCycleEmployeeMap() +// .get(salaryAcctEmployee.getEmployeeId() + "-" + salaryAcctEmployee.getTaxAgentId()); +// if (CollectionUtils.isEmpty(sameTaxCycleSalaryAcctEmployees)) { +// return resultValue; +// } +// // 第一次计算时不需要合并计税处理 +// boolean needConsolidatedTax = needConsolidatedTax(salaryCalcEmployeeContext, salaryAcctEmployee, sameTaxCycleSalaryAcctEmployees); +// if (!needConsolidatedTax) { +// return resultValue; +// } +// List salaryAcctResultValues = Lists.newArrayList(); +// for (SalaryAcctEmployeePO sameTaxCycleSalaryAcctEmployee : sameTaxCycleSalaryAcctEmployees) { +// SalaryAcctResultValuePO salaryAcctResultValue = salaryCalcEmployeeContext.getSameTaxCycleResultValueMap().get(sameTaxCycleSalaryAcctEmployee.getId()); +// if (salaryAcctResultValue != null) { +// salaryAcctResultValues.add(salaryAcctResultValue); +// } +// } +// List salaryItems = Lists.newArrayList(salaryCalcContext.getSalaryCalcFormulaContext().getSalaryItemMap().values()); +// return SalaryAcctConsolidatedTax.handleConsolidatedTaxValue(resultValue, salaryItem, salaryItems, salaryAcctResultValues); +// } +// +// /** +// * 判断是否需要进行合并计税 +// * +// * @param salaryCalcEmployeeContext +// * @param salaryAcctEmployee +// * @param sameTaxCycleSalaryAcctEmployees +// * @return +// */ +// private boolean needConsolidatedTax(SalaryCalcEmployeeContext salaryCalcEmployeeContext, +// SalaryAcctEmployeePO salaryAcctEmployee, +// List sameTaxCycleSalaryAcctEmployees) { +// SalaryAcctRecordPO salaryAcctRecord = salaryCalcEmployeeContext.getSameTaxCycleRecordMap().get(salaryAcctEmployee.getSalaryAcctRecordId()); +// if (salaryAcctRecord == null) { +// return false; +// } +// for (SalaryAcctEmployeePO sameTaxCycleSalaryAcctEmployee : sameTaxCycleSalaryAcctEmployees) { +// SalaryAcctRecordPO otherSalaryAcctRecord = salaryCalcEmployeeContext.getSameTaxCycleRecordMap() +// .get(sameTaxCycleSalaryAcctEmployee.getSalaryAcctRecordId()); +// if (otherSalaryAcctRecord == null) { +// continue; +// } +// if (otherSalaryAcctRecord.getCreateTime().compareTo(salaryAcctRecord.getCreateTime()) < 0) { +// return true; +// } +// } +// return false; +// } +// +// private String roundResultValue(String resultValue, SalaryCalcFormula salaryCalcFormula) { +// // 值为空,不需要四舍五入 +// if (StringUtils.isEmpty(resultValue)) { +// return StringUtils.EMPTY; +// } +// // 薪资项目字段类型为string,无需四舍五入 +// SalaryDataTypeEnum dataTypeEnum = salaryCalcFormula.getDataType(); +// if (dataTypeEnum == SalaryDataTypeEnum.STRING) { +// return resultValue; +// } +// BigDecimal bigDecimalValue = SalaryEntityUtil.empty2Zero(resultValue); +// RoundingMode roundingMode = RoundingMode.HALF_UP; +// if (salaryCalcFormula.getRoundingMode() == SalaryRoundingModeEnum.ROUND_UP) { +// roundingMode = RoundingMode.UP; +// } +// if (salaryCalcFormula.getRoundingMode() == SalaryRoundingModeEnum.ROUND_DOWN) { +// roundingMode = RoundingMode.DOWN; +// } +// return bigDecimalValue.setScale(salaryCalcFormula.getPattern(), roundingMode).toPlainString(); +// } +// +// /** +// * 更新核算进度 +// * +// * @param salaryAcctRecordId +// * @param calcQty +// */ +// private synchronized void updateRate(Long salaryAcctRecordId, int calcQty, int salaryAcctEmployeeSize) { +// int addQty = 0; +// if (calcQty % 10 == 0) { +// addQty = 10; +// } else if (Objects.equals(calcQty, salaryAcctEmployeeSize)) { +// addQty = calcQty % 10; +// } +// if (addQty > 0) { +// SalaryAcctRateDTO salaryAcctRate = salaryCacheService +// .get(SalaryCacheKey.ACCT_PROGRESS, "" + salaryAcctRecordId, SalaryAcctRateDTO.class); +// salaryAcctRate.setCalcQty(salaryAcctRate.getCalcQty() + addQty); +// salaryCacheService.set(SalaryCacheKey.ACCT_PROGRESS, "" + salaryAcctRecordId, salaryAcctRate); +// } +// } +// +// private void handleCalcResult(BlockingDeque blockingDeque, +// Long salaryAcctRecordId, Collection salaryAcctEmployeeIds, +// String tenantKey) { +// boolean allSuccess = blockingDeque.stream().allMatch(SalaryCalcResult::isStatus); +// if (!allSuccess) { +// // 薪资核算实现的线程的错误信息 +// String errorMsg = blockingDeque.stream() +// .filter(result -> !result.isStatus()) +// .map(SalaryCalcResult::getErrMsg) +// .collect(Collectors.joining("|")); +// // 返回错误信息 +// throw new SalaryRunTimeException("薪资核算失败:" + errorMsg); +// } +// // 删除历史数据 +// if (CollectionUtils.isNotEmpty(salaryAcctEmployeeIds)) { +// salaryAcctResultValueService.deleteBySalaryAcctEmployeeIds(salaryAcctEmployeeIds, tenantKey); +// } else { +// salaryAcctResultValueService.deleteBySalaryAcctRecordIds(Collections.singleton(salaryAcctRecordId), tenantKey); +// } +// // 保存新数据 +// List salaryAcctResultValues = Lists.newArrayList(); +// for (SalaryCalcResult salaryCalcResult : blockingDeque) { +// salaryAcctResultValues.addAll(salaryCalcResult.getSalaryAcctResultValues()); +// } +// salaryAcctResultValueService.batchSave(salaryAcctResultValues, tenantKey); +// } +// +// private void writeLog(Long salaryAcctRecordId, String tenantKey) { +// String targetName = salaryAcctRecordService.getLogTargetNameById(salaryAcctRecordId, tenantKey); +// LoggerContext loggerContext = new LoggerContext<>(); +// loggerContext.setTargetId(String.valueOf(salaryAcctRecordId)); +// loggerContext.setTargetName(targetName); +// loggerContext.setOperateType(OperateTypeEnum.UPDATE.getValue()); +// loggerContext.setOperateTypeName(SalaryI18nUtil.getI18nLabel(95783, "薪资核算")); +// loggerContext.setOperatedesc(SalaryI18nUtil.getI18nLabel(95783, "薪资核算")); +// salaryAcctRecordLoggerTemplate.write(loggerContext); +// } +//} diff --git a/src/com/engine/salary/service/impl/SalaryCacheServiceImpl.java b/src/com/engine/salary/service/impl/SalaryCacheServiceImpl.java new file mode 100644 index 000000000..0ec845af4 --- /dev/null +++ b/src/com/engine/salary/service/impl/SalaryCacheServiceImpl.java @@ -0,0 +1,50 @@ +package com.engine.salary.service.impl; + +import com.cloudstore.dev.api.util.Util_DataCache; +import com.engine.salary.service.SalaryCacheService; +import com.engine.salary.util.JsonUtil; +import org.apache.commons.lang3.StringUtils; +import weaver.general.Util; + +public class SalaryCacheServiceImpl implements SalaryCacheService { + + + @Override + public void set(String key, T value) { + Util_DataCache.setObjVal(key, value); + } + + @Override + public void set(String key, T value, int time) { + Util_DataCache.setObjVal(key, value, time); + } + + @Override + public void setJson(String key, T value) { + Util_DataCache.setObjVal(key, JsonUtil.toJsonString(value)); + } + + @Override + public void setJson(String key, T value, int time) { + Util_DataCache.setObjVal(key, JsonUtil.toJsonString(value), time); + } + + @Override + public T get(String key) { + return (T) Util_DataCache.getObjVal(key); + } + + @Override + public T getJson(String key, Class clazz) { + String value = Util.null2String(Util_DataCache.getObjVal(key)); + if (StringUtils.isEmpty(value)) { + return null; + } + return JsonUtil.parseObject(value, clazz); + } + + @Override + public void remove(String key) { + Util_DataCache.clearVal(key); + } +} diff --git a/src/com/engine/salary/service/impl/SalaryFormulaServiceImpl.java b/src/com/engine/salary/service/impl/SalaryFormulaServiceImpl.java index cba68be38..65cb918c8 100644 --- a/src/com/engine/salary/service/impl/SalaryFormulaServiceImpl.java +++ b/src/com/engine/salary/service/impl/SalaryFormulaServiceImpl.java @@ -292,4 +292,9 @@ public class SalaryFormulaServiceImpl extends Service implements SalaryFormulaSe return formulaPO; } + @Override + public void initFunction() { + + } + } diff --git a/src/com/engine/salary/wrapper/TaxDeclarationWrapper.java b/src/com/engine/salary/wrapper/TaxDeclarationWrapper.java index 2b4a75e9b..df7acfb9a 100644 --- a/src/com/engine/salary/wrapper/TaxDeclarationWrapper.java +++ b/src/com/engine/salary/wrapper/TaxDeclarationWrapper.java @@ -4,9 +4,6 @@ import com.engine.common.util.ServiceUtil; import com.engine.core.impl.Service; import com.engine.salary.biz.EmployBiz; import com.engine.salary.component.WeaFormOption; -import com.engine.salary.encrypt.datacollection.AddUpSituationEncrypt; -import com.engine.salary.encrypt.taxdeclaration.TaxDeclarationDetailPOEncrypt; -import com.engine.salary.entity.datacollection.AddUpSituation; import com.engine.salary.entity.datacollection.DataCollectionEmployee; import com.engine.salary.entity.taxagent.po.TaxAgentPO; import com.engine.salary.entity.taxdeclaration.bo.TaxDeclarationBO; @@ -15,7 +12,6 @@ import com.engine.salary.entity.taxdeclaration.dto.TaxDeclarationInfoDTO; import com.engine.salary.entity.taxdeclaration.dto.TaxDeclarationListDTO; import com.engine.salary.entity.taxdeclaration.param.TaxDeclarationListQueryParam; import com.engine.salary.entity.taxdeclaration.param.TaxDeclarationSaveParam; -import com.engine.salary.entity.taxdeclaration.po.TaxDeclarationDetailPO; import com.engine.salary.entity.taxdeclaration.po.TaxDeclarationPO; import com.engine.salary.exception.SalaryRunTimeException; import com.engine.salary.service.TaxAgentService;