diff --git a/src/com/engine/salary/cache/SalaryCacheKey.java b/src/com/engine/salary/cache/SalaryCacheKey.java index 01f0747a9..549dccd31 100644 --- a/src/com/engine/salary/cache/SalaryCacheKey.java +++ b/src/com/engine/salary/cache/SalaryCacheKey.java @@ -9,15 +9,55 @@ package com.engine.salary.cache; */ public class SalaryCacheKey { + /** + * 人员范围同步 + */ + public final static String TAX_AGENT_MANAGE_RANGE_SYNC = "TAX_AGENT_MANAGE_RANGE_SYNC"; /** * 核算进度 */ public final static String ACCT_PROGRESS = "ACCT_PROGRESS_"; + /** + * 薪资核算的账套配置 + */ + public final static String ACCT_SOB_CONFIG = "ACCT_SOB_CONFIG"; + /** * 考勤进度 */ - public final static String ATTEND_PROGRESS = "ATTEND_PROGRESS_"; + public final static String ATTEND_PROGRESS = "ATTEND_PROGRESS"; + + /** + * 工资单发放进度 + */ + public final static String SALARY_GRANT_PROGRESS = "SALARY_GRANT_PROGRESS"; + + /** + * 工资单撤回进度 + */ + public final static String SALARY_WITHDRAW_PROGRESS = "SALARY_WITHDRAW_PROGRESS"; + + /** + * ecology系统的token + */ + public final static String ECOLOGY_TOKEN = "ECOLOGY_TOKEN"; + + /** + * 个税申报表 + */ + public final static String TAX_DECLARATION = "TAX_DECLARATION"; + + /** + * 人员报送 + */ + public final static String EMPLOYEE_DECLARE = "EMPLOYEE_DECLARE"; + + /** + * 自定义业务数据 + */ + public final static String CUSTOM_DATA = "CUSTOM_DATA"; + } diff --git a/src/com/engine/salary/entity/salaryacct/bo/CalculateFormulaVarBO.java b/src/com/engine/salary/entity/salaryacct/bo/CalculateFormulaVarBO.java index b2a9eb0e0..fc5dcc5cd 100644 --- a/src/com/engine/salary/entity/salaryacct/bo/CalculateFormulaVarBO.java +++ b/src/com/engine/salary/entity/salaryacct/bo/CalculateFormulaVarBO.java @@ -16,6 +16,7 @@ import com.engine.salary.entity.salaryarchive.dto.SalaryArchiveDataDTO; import com.engine.salary.entity.salaryarchive.dto.SalaryArchiveItemDataDTO; import com.engine.salary.entity.salaryarchive.dto.SalaryArchiveTaxAgentDataDTO; import com.engine.salary.entity.salaryitem.po.SalaryItemPO; +import com.engine.salary.entity.salarysob.dto.SalarySobCycleDTO; import com.engine.salary.entity.salarysob.po.SalarySobAdjustRulePO; import com.engine.salary.enums.salaryformula.SalaryFormulaReferenceEnum; import com.engine.salary.enums.salaryformula.SalarySQLReferenceEnum; @@ -136,6 +137,39 @@ public class CalculateFormulaVarBO { return resultMap; } + /** + * 处理核算日期相关信息 + */ + private List handleSalarySobCycleDTO(SalaryAcctCalculateBO salaryAcctCalculateBO) { + + SalarySobCycleDTO salarySobCycleDTO = salaryAcctCalculateBO.getSalarySobCycleDTO(); + + salarySobCycleDTO.setSalaryDate(SalaryDateUtil.toDate(salarySobCycleDTO.getSalaryMonth(), 1)); + salarySobCycleDTO.setTaxDate(SalaryDateUtil.toDate(salarySobCycleDTO.getTaxCycle(), 1)); + salarySobCycleDTO.setSocialSecurityDate(SalaryDateUtil.toDate(salarySobCycleDTO.getSocialSecurityCycle(), 1)); + LocalDateRange salaryCycle = salarySobCycleDTO.getSalaryCycle(); + salarySobCycleDTO.setSalaryCycleFromDate(salaryCycle.getFromDate()); + salarySobCycleDTO.setSalaryCycleEndDate(salaryCycle.getEndDate()); + LocalDateRange attendCycle = salarySobCycleDTO.getAttendCycle(); + salarySobCycleDTO.setAttendCycleFromDate(attendCycle.getFromDate()); + salarySobCycleDTO.setAttendCycleEndDate(attendCycle.getEndDate()); + + Map map = JsonUtil.parseMap(salarySobCycleDTO, String.class); + + List formulaVarValues = Lists.newArrayList(); + Field[] declaredFields = SalarySobCycleDTO.class.getDeclaredFields(); + for (Field declaredField : declaredFields) { + if (declaredField.isAnnotationPresent(SalaryFormulaVar.class)) { + String fieldName = declaredField.getName(); + String fieldId = SalarySQLReferenceEnum.SALARY_CYCLE.getValue() + + SalaryFormulaFieldConstant.FIELD_ID_SEPARATOR + + fieldName; + formulaVarValues.add(new FormulaVarValue().setFieldId(fieldId).setFieldValue(map.getOrDefault(fieldName, StringUtils.EMPTY))); + } + } + return formulaVarValues; + } + /** * 处理薪资核算结果 @@ -164,7 +198,7 @@ public class CalculateFormulaVarBO { } /** - * 处理薪资档案(会涉及调薪计薪规则) + * 处理薪资档案(会涉及调薪计薪规则)+处理核算日期 * * @param salaryAcctCalculateBO 薪资核算参数 * @param resultMap 返回结果集 @@ -179,6 +213,7 @@ public class CalculateFormulaVarBO { List formulaVarValues = resultMap.computeIfAbsent(key, k -> Lists.newArrayList()); // 将薪资档案的值转换成公式中的变量,填充到返回结果集中 formulaVarValues.addAll(handleSalaryArchiveItemVal(salaryAcctCalculateBO, salaryArchiveTaxAgentDataDTO.getSalaryItemValues(), salarySobAdjustRulePOMap)); + formulaVarValues.addAll(handleSalarySobCycleDTO(salaryAcctCalculateBO)); } } } 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/entity/salaryarchive/bo/SalaryArchiveExcelBO.java b/src/com/engine/salary/entity/salaryarchive/bo/SalaryArchiveExcelBO.java index 41bba094d..389f66a64 100644 --- a/src/com/engine/salary/entity/salaryarchive/bo/SalaryArchiveExcelBO.java +++ b/src/com/engine/salary/entity/salaryarchive/bo/SalaryArchiveExcelBO.java @@ -372,6 +372,7 @@ public class SalaryArchiveExcelBO extends Service { //员工id 流程定薪使用 String empId = Optional.ofNullable(map.get("员工id")).orElse("").toString(); if (StringUtils.isNotBlank(empId)) { + employeeSameIds.clear(); employeeSameIds.add(Long.valueOf(empId)); employeeId = Long.valueOf(empId); } diff --git a/src/com/engine/salary/entity/salarysob/dto/SalarySobCycleDTO.java b/src/com/engine/salary/entity/salarysob/dto/SalarySobCycleDTO.java index 65a482e20..70a688b10 100644 --- a/src/com/engine/salary/entity/salarysob/dto/SalarySobCycleDTO.java +++ b/src/com/engine/salary/entity/salarysob/dto/SalarySobCycleDTO.java @@ -1,5 +1,6 @@ package com.engine.salary.entity.salarysob.dto; +import com.engine.salary.annotation.SalaryFormulaVar; import com.engine.salary.common.LocalDateRange; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; @@ -9,6 +10,7 @@ import lombok.Data; import lombok.NoArgsConstructor; import java.time.YearMonth; +import java.util.Date; /** * 薪资账套的周期 @@ -24,24 +26,43 @@ import java.time.YearMonth; @AllArgsConstructor public class SalarySobCycleDTO { - //薪资账套id + //薪资账套id private Long salarySobId; - //薪资所属月 + //薪资所属月 @JsonSerialize(using = ToStringSerializer.class) private YearMonth salaryMonth; - //税款所属期 + //税款所属期 @JsonSerialize(using = ToStringSerializer.class) private YearMonth taxCycle; - //社保福利所属期 + //社保福利所属期 @JsonSerialize(using = ToStringSerializer.class) private YearMonth socialSecurityCycle; - //薪资周期") + //薪资周期") private LocalDateRange salaryCycle; - //考勤周期") + //考勤周期") private LocalDateRange attendCycle; + + + /** + * 公式变量 + */ + @SalaryFormulaVar(defaultLabel = "薪资所属月", labelId = 86321, dataType = "string") + private Date salaryDate; + @SalaryFormulaVar(defaultLabel = "税款所属期", labelId = 86321, dataType = "string") + private Date taxDate; + @SalaryFormulaVar(defaultLabel = "社保福利所属期", labelId = 86321, dataType = "string") + private Date socialSecurityDate; + @SalaryFormulaVar(defaultLabel = "薪资周期起始日期", labelId = 86321, dataType = "string") + private Date salaryCycleFromDate; + @SalaryFormulaVar(defaultLabel = "薪资周期结束日期", labelId = 86321, dataType = "string") + private Date salaryCycleEndDate; + @SalaryFormulaVar(defaultLabel = "考勤周期起始日期", labelId = 86321, dataType = "string") + private Date attendCycleFromDate; + @SalaryFormulaVar(defaultLabel = "考勤周期结束日期", labelId = 86321, dataType = "string") + private Date attendCycleEndDate; } diff --git a/src/com/engine/salary/enums/salaryformula/SalarySQLReferenceEnum.java b/src/com/engine/salary/enums/salaryformula/SalarySQLReferenceEnum.java index 16ba69a64..f08a583d2 100644 --- a/src/com/engine/salary/enums/salaryformula/SalarySQLReferenceEnum.java +++ b/src/com/engine/salary/enums/salaryformula/SalarySQLReferenceEnum.java @@ -16,7 +16,8 @@ import java.util.Objects; public enum SalarySQLReferenceEnum implements BaseEnum { EMPLOYEE_INFO("employeeInfo", "员工基本信息", 85366), - SALARY_ACCT_EMPLOYEE("salaryAcctEmployee", "核算基本信息", 85368); + SALARY_ACCT_EMPLOYEE("salaryAcctEmployee", "核算基本信息", 85368), + SALARY_CYCLE("SalaryCycle", "核算日期", 85368); private String value; private String defaultLabel; diff --git a/src/com/engine/salary/mapper/InsuranceExportMapper.xml b/src/com/engine/salary/mapper/InsuranceExportMapper.xml index 02e48fb98..517eb1672 100644 --- a/src/com/engine/salary/mapper/InsuranceExportMapper.xml +++ b/src/com/engine/salary/mapper/InsuranceExportMapper.xml @@ -129,6 +129,7 @@ AND bill_month = #{param.billMonth} AND payment_status = #{paymentStatus} AND creator = #{param.creator} + AND payment_organization = #{param.paymentOrganization} ) a LEFT JOIN hrmresource e ON e.ID = a.employee_id LEFT JOIN hrmdepartment d ON d.id = e.departmentid @@ -154,6 +155,7 @@ AND bill_month = #{param.billMonth} AND payment_status = #{paymentStatus} AND creator = #{param.creator} + AND payment_organization = #{param.paymentOrganization} ) a LEFT JOIN hrmresource e ON e.ID = a.employee_id LEFT JOIN hrmdepartment d ON d.id = e.departmentid @@ -179,6 +181,7 @@ AND bill_month = #{param.billMonth} AND payment_status = #{paymentStatus} AND creator = #{param.creator} + AND payment_organization = #{param.paymentOrganization} ) a LEFT JOIN hrmresource e ON e.ID = a.employee_id LEFT JOIN hrmdepartment d ON d.id = e.departmentid diff --git a/src/com/engine/salary/mapper/datacollection/EmployMapper.java b/src/com/engine/salary/mapper/datacollection/EmployMapper.java index 427ff6cd7..496f00ed0 100644 --- a/src/com/engine/salary/mapper/datacollection/EmployMapper.java +++ b/src/com/engine/salary/mapper/datacollection/EmployMapper.java @@ -53,5 +53,8 @@ public interface EmployMapper { List getSubCompanyInfoList(@Param("subDepartmentIds") List subDepartmentIds); + List listAll(); + + List listHrmInfoByIdAndName(@Param("param") HrmQueryParam param); } \ No newline at end of file diff --git a/src/com/engine/salary/mapper/datacollection/EmployMapper.xml b/src/com/engine/salary/mapper/datacollection/EmployMapper.xml index 874f28246..806a1bf2d 100644 --- a/src/com/engine/salary/mapper/datacollection/EmployMapper.xml +++ b/src/com/engine/salary/mapper/datacollection/EmployMapper.xml @@ -37,17 +37,23 @@ + +