From c9f7131f047071a08b550b1d7f10dc86717894fc Mon Sep 17 00:00:00 2001 From: Joshi <3040996759@qq.com> Date: Thu, 26 Jun 2025 13:56:07 +0800 Subject: [PATCH] =?UTF-8?q?=E8=96=AA=E8=B5=84=E6=8E=A5=E5=8F=A3=E7=9A=84?= =?UTF-8?q?=E6=96=B0=E8=A6=81=E6=B1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../OaEmployeeTemplateBindingController.java | 12 +- .../oa/domain/OaEmployeeTemplateBinding.java | 21 +- .../ruoyi/oa/domain/OaInsuranceTemplate.java | 4 + .../com/ruoyi/oa/domain/SysOaFinance.java | 1 + .../bo/OaEmployeeTemplateBindingBo.java | 19 +- .../oa/domain/bo/OaInsuranceTemplateBo.java | 4 + .../vo/OaEmployeeTemplateBindingVo.java | 20 +- .../oa/domain/vo/OaInsuranceTemplateVo.java | 5 + .../ruoyi/oa/domain/vo/SysOaFinanceVo.java | 2 + .../IOaEmployeeTemplateBindingService.java | 2 +- .../OaEmployeeTemplateBindingServiceImpl.java | 232 +++++++++++++++--- .../oa/OaEmployeeTemplateBindingMapper.xml | 8 +- .../mapper/oa/OaInsuranceTemplateMapper.xml | 1 + 13 files changed, 272 insertions(+), 59 deletions(-) diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/controller/OaEmployeeTemplateBindingController.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/controller/OaEmployeeTemplateBindingController.java index ed76c9f..6a8ce33 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/controller/OaEmployeeTemplateBindingController.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/controller/OaEmployeeTemplateBindingController.java @@ -117,10 +117,18 @@ public class OaEmployeeTemplateBindingController extends BaseController { if (bo.getPayYear() == null || bo.getPayMonth() == null) { return R.fail("请选择发薪年月"); } - if (bo.getDefaultInsuranceTemplateId() == null || bo.getDefaultSalaryTemplateId() == null) { + if (bo.getDefaultPersonalInsuranceTemplateId() == null || bo.getDefaultSalaryTemplateId() == null || bo.getDefaultCompanyInsuranceTemplateId() == null) { return R.fail("请选择默认模板"); } - return toAjax(iOaEmployeeTemplateBindingService.calculateSalary(bo.getEmployeeIds(), bo.getPayYear(), bo.getPayMonth(), bo.getDefaultInsuranceTemplateId(), bo.getDefaultSalaryTemplateId())); + + return toAjax(iOaEmployeeTemplateBindingService.calculateSalary( + bo.getEmployeeIds(), + bo.getPayYear(), + bo.getPayMonth(), + bo.getDefaultPersonalInsuranceTemplateId(), // 个人 + bo.getDefaultCompanyInsuranceTemplateId(), // 企业 + bo.getDefaultSalaryTemplateId() + )); } // 7. 批量确认发放 @PostMapping("/finalize") diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/OaEmployeeTemplateBinding.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/OaEmployeeTemplateBinding.java index 5af79e9..26356e1 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/OaEmployeeTemplateBinding.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/OaEmployeeTemplateBinding.java @@ -1,14 +1,13 @@ package com.ruoyi.oa.domain; -import com.baomidou.mybatisplus.annotation.*; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableLogic; +import com.baomidou.mybatisplus.annotation.TableName; +import com.ruoyi.common.core.domain.BaseEntity; import lombok.Data; import lombok.EqualsAndHashCode; -import java.io.Serializable; -import java.util.Date; -import java.math.BigDecimal; import java.math.BigDecimal; -import com.ruoyi.common.core.domain.BaseEntity; /** * 员工模板绑定及月度发放记录对象 oa_employee_template_binding @@ -21,7 +20,7 @@ import com.ruoyi.common.core.domain.BaseEntity; @TableName("oa_employee_template_binding") public class OaEmployeeTemplateBinding extends BaseEntity { - private static final long serialVersionUID=1L; + private static final long serialVersionUID = 1L; /** * 记录ID @@ -32,10 +31,12 @@ public class OaEmployeeTemplateBinding extends BaseEntity { * 员工ID → oa_employee.employee_id */ private Long employeeId; - /** - * 保险模板ID → oa_insurance_template.insurance_template_id - */ - private Long insuranceTemplateId; + // /** +// * 保险模板ID → oa_insurance_template.insurance_template_id +// */ +// private Long insuranceTemplateId; + private Long personalInsuranceTemplateId; + private Long companyInsuranceTemplateId; /** * 薪资模板ID → oa_salary_template.salary_template_id */ diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/OaInsuranceTemplate.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/OaInsuranceTemplate.java index 75ecddf..2bae655 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/OaInsuranceTemplate.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/OaInsuranceTemplate.java @@ -31,6 +31,10 @@ public class OaInsuranceTemplate extends BaseEntity { * 模板名称 */ private String templateName; + /** + * 模板类型'0个税1企业' + */ + private int type; /** * 删除标志 0=未删,1=已删 */ diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/SysOaFinance.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/SysOaFinance.java index c87f1c1..72f8af4 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/SysOaFinance.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/SysOaFinance.java @@ -89,6 +89,7 @@ public class SysOaFinance extends BaseEntity { /** * 一对一关联项目表 */ + @TableField(exist = false) private SysOaProject project; /** diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/bo/OaEmployeeTemplateBindingBo.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/bo/OaEmployeeTemplateBindingBo.java index 1c3da87..87071ba 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/bo/OaEmployeeTemplateBindingBo.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/bo/OaEmployeeTemplateBindingBo.java @@ -35,11 +35,20 @@ public class OaEmployeeTemplateBindingBo extends BaseEntity { */ private Long employeeId; private List employeeIds; - +// +// /** +// * 保险模板ID → oa_insurance_template.insurance_template_id +// */ +// private Long insuranceTemplateId; /** - * 保险模板ID → oa_insurance_template.insurance_template_id + * personal_insurance_template_id bigint not null comment '个人保险模板ID → oa_insurance_template.insurance_template_id', */ - private Long insuranceTemplateId; + private Long personalInsuranceTemplateId; + /* + * company_insurance_template_id bigint not null comment '企业保险模板ID → oa_insurance_temp + * */ + private Long companyInsuranceTemplateId; + /** * 薪资模板ID → oa_salary_template.salary_template_id @@ -75,7 +84,9 @@ public class OaEmployeeTemplateBindingBo extends BaseEntity { * 备注 */ private String remark; - private Long defaultInsuranceTemplateId; // 新增:默认社保模板ID +// private Long defaultInsuranceTemplateId; // 新增:默认社保模板ID + private Long defaultPersonalInsuranceTemplateId; + private Long defaultCompanyInsuranceTemplateId; private Long defaultSalaryTemplateId; // 新增:默认薪资模板ID diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/bo/OaInsuranceTemplateBo.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/bo/OaInsuranceTemplateBo.java index afd9651..932c487 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/bo/OaInsuranceTemplateBo.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/bo/OaInsuranceTemplateBo.java @@ -35,6 +35,10 @@ public class OaInsuranceTemplateBo extends BaseEntity { * 备注 */ private String remark; + /** + * 模板类型type'0个税1企业', + */ + private int type; } diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/OaEmployeeTemplateBindingVo.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/OaEmployeeTemplateBindingVo.java index 81df061..80e00dc 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/OaEmployeeTemplateBindingVo.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/OaEmployeeTemplateBindingVo.java @@ -34,11 +34,15 @@ public class OaEmployeeTemplateBindingVo { @ExcelProperty(value = "员工ID → oa_employee.employee_id") private Long employeeId; - /** - * 保险模板ID → oa_insurance_template.insurance_template_id - */ - @ExcelProperty(value = "保险模板ID → oa_insurance_template.insurance_template_id") - private Long insuranceTemplateId; +// /** +// * 保险模板ID → oa_insurance_template.insurance_template_id +// */ +// @ExcelProperty(value = "保险模板ID → oa_insurance_template.insurance_template_id") +// private Long insuranceTemplateId; + @ExcelProperty(value = "个人保险模板ID") + private Long personalInsuranceTemplateId; + @ExcelProperty(value = "企业保险模板ID") + private Long companyInsuranceTemplateId; /** * 薪资模板ID → oa_salary_template.salary_template_id @@ -61,7 +65,7 @@ public class OaEmployeeTemplateBindingVo { /** * 实发工资 */ - @ExcelProperty(value = "实发工资") + @ExcelProperty(value = "预计发放工资") private BigDecimal netSalary; /** @@ -85,5 +89,9 @@ public class OaEmployeeTemplateBindingVo { @ExcelProperty(value = "实发工资") private BigDecimal totalSalary; + private BigDecimal totalPersonalInsurance; + private BigDecimal totalCompanyInsurance; + private String company; // 所属公司 + private String deptName; // 所属部门名称 } diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/OaInsuranceTemplateVo.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/OaInsuranceTemplateVo.java index ae64597..85bb72d 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/OaInsuranceTemplateVo.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/OaInsuranceTemplateVo.java @@ -38,6 +38,11 @@ public class OaInsuranceTemplateVo { */ @ExcelProperty(value = "备注") private String remark; + /** + * 模板类型type'0个税1企业', + */ + @ExcelProperty(value = "模板类型'0个税1企业'") + private int type; } diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/SysOaFinanceVo.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/SysOaFinanceVo.java index fc9f201..da62bb9 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/SysOaFinanceVo.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/SysOaFinanceVo.java @@ -2,6 +2,7 @@ package com.ruoyi.oa.domain.vo; import java.util.Date; +import com.baomidou.mybatisplus.annotation.TableField; import com.fasterxml.jackson.annotation.JsonFormat; import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import com.alibaba.excel.annotation.ExcelProperty; @@ -118,6 +119,7 @@ public class SysOaFinanceVo extends SysOaFinance { /** * 一对一关联项目表 */ + @TableField(exist = false) private SysOaProject project; /** diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/IOaEmployeeTemplateBindingService.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/IOaEmployeeTemplateBindingService.java index a4c41c6..d2586e0 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/IOaEmployeeTemplateBindingService.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/IOaEmployeeTemplateBindingService.java @@ -48,7 +48,7 @@ public interface IOaEmployeeTemplateBindingService { */ Boolean deleteWithValidByIds(Collection ids, Boolean isValid); - Boolean calculateSalary(List employeeIds, Long payYear, Long payMonth,Long defaultInsuranceTemplateId, Long defaultSalaryTemplateId); + Boolean calculateSalary(List employeeIds, Long payYear, Long payMonth, Long defaultPersonalInsuranceTemplateId, Long defaultCompanyInsuranceTemplateId, Long defaultSalaryTemplateId); Boolean finalizeSalary(List bindingIds); List querySalaryHistory(Long employeeId); } diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/OaEmployeeTemplateBindingServiceImpl.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/OaEmployeeTemplateBindingServiceImpl.java index 60ab84f..b048a22 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/OaEmployeeTemplateBindingServiceImpl.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/OaEmployeeTemplateBindingServiceImpl.java @@ -2,6 +2,7 @@ package com.ruoyi.oa.service.impl; import cn.hutool.core.bean.BeanUtil; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.ruoyi.common.core.domain.entity.SysDept; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.core.domain.PageQuery; @@ -12,6 +13,7 @@ import com.ruoyi.oa.domain.*; import com.ruoyi.oa.domain.vo.EmployeeSalaryRecordVo; import com.ruoyi.oa.domain.vo.OaBindingItemDetailVo; import com.ruoyi.oa.mapper.*; +import com.ruoyi.system.mapper.SysDeptMapper; import lombok.RequiredArgsConstructor; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -21,10 +23,7 @@ import com.ruoyi.oa.domain.vo.OaEmployeeTemplateBindingVo; import com.ruoyi.oa.service.IOaEmployeeTemplateBindingService; import java.math.BigDecimal; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Collection; +import java.util.*; import java.util.stream.Collectors; /** @@ -45,7 +44,11 @@ public class OaEmployeeTemplateBindingServiceImpl implements IOaEmployeeTemplate @Autowired private final OaSalaryTemplateDetailMapper salaryDetailMapper; @Autowired + private final OaInsuranceTemplateMapper insuranceTemplateMapper; + @Autowired private final OaInsuranceTemplateDetailMapper insuranceDetailMapper; + @Autowired + private final SysDeptMapper deptMapper; /** @@ -63,24 +66,150 @@ public class OaEmployeeTemplateBindingServiceImpl implements IOaEmployeeTemplate public TableDataInfo queryPageList(OaEmployeeTemplateBindingBo bo, PageQuery pageQuery) { LambdaQueryWrapper lqw = buildQueryWrapper(bo); Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); - // 根据bindingid和template_type(salary)去求和paid_amount字段 + if (CollectionUtils.isNotEmpty(result.getRecords())) { + // 1. 批量查员工 + List employeeIds = result.getRecords().stream() + .map(OaEmployeeTemplateBindingVo::getEmployeeId) + .filter(Objects::nonNull) + .distinct() + .collect(Collectors.toList()); + Map employeeMap = new HashMap<>(); + if (!employeeIds.isEmpty()) { + List employees = employeeMapper.selectBatchIds(employeeIds); + employeeMap = employees.stream().collect(Collectors.toMap(OaEmployee::getEmployeeId, e -> e)); + } + + // 2. 批量查部门 + Set deptIds = employeeMap.values().stream() + .map(OaEmployee::getDeptId) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + Map deptMap = new HashMap<>(); + if (!deptIds.isEmpty()) { + List depts = deptMapper.selectBatchIds(deptIds); + deptMap = depts.stream().collect(Collectors.toMap(SysDept::getDeptId, d -> d)); + } + + // 3. 封装到VO + for (OaEmployeeTemplateBindingVo vo : result.getRecords()) { + OaEmployee emp = employeeMap.get(vo.getEmployeeId()); + if (emp != null) { + vo.setCompany(emp.getCompany()); + SysDept dept = deptMap.get(emp.getDeptId()); + vo.setDeptName(dept != null ? dept.getDeptName() : null); + } + } // 提取所有bindingId List bindingIds = result.getRecords().stream() .map(OaEmployeeTemplateBindingVo::getBindingId) .collect(Collectors.toList()); - // 批量查询每个bindingId对应的薪资总额 - Map salaryTotalMap = calculateSalaryTotalByBindingIds(bindingIds); + // 批量查询每个bindingId对应的各项金额 + Map calculationMap = calculateSalaryDetailsByBindingIds(bindingIds); // 将计算结果设置到对应的VO对象中 for (OaEmployeeTemplateBindingVo vo : result.getRecords()) { - vo.setTotalSalary(salaryTotalMap.getOrDefault(vo.getBindingId(), BigDecimal.ZERO)); + SalaryCalculationResult calc = calculationMap.getOrDefault(vo.getBindingId(), new SalaryCalculationResult()); + vo.setNetSalary(calc.getTotalSalary()); // 薪资总额 + vo.setTotalPersonalInsurance(calc.getTotalPersonalInsurance()); // 个人社保总额 + vo.setTotalCompanyInsurance(calc.getTotalCompanyInsurance()); // 企业社保总额 + vo.setTotalSalary(calc.getNetSalary()); // 实发工资 + vo.setTotalCompanyCost(calc.getTotalCompanyCost()); // 公司总成本 } } return TableDataInfo.build(result); } + + /** + * 薪资计算结果内部类 + */ + private static class SalaryCalculationResult { + private BigDecimal totalSalary = BigDecimal.ZERO; // 薪资总额 + private BigDecimal totalPersonalInsurance = BigDecimal.ZERO; // 个人社保总额 + private BigDecimal totalCompanyInsurance = BigDecimal.ZERO; // 企业社保总额 + private BigDecimal netSalary = BigDecimal.ZERO; // 实发工资 + private BigDecimal totalCompanyCost = BigDecimal.ZERO; // 公司总成本 + + // getters and setters + public BigDecimal getTotalSalary() { return totalSalary; } + public void setTotalSalary(BigDecimal totalSalary) { this.totalSalary = totalSalary; } + + public BigDecimal getTotalPersonalInsurance() { return totalPersonalInsurance; } + public void setTotalPersonalInsurance(BigDecimal totalPersonalInsurance) { this.totalPersonalInsurance = totalPersonalInsurance; } + + public BigDecimal getTotalCompanyInsurance() { return totalCompanyInsurance; } + public void setTotalCompanyInsurance(BigDecimal totalCompanyInsurance) { this.totalCompanyInsurance = totalCompanyInsurance; } + + public BigDecimal getNetSalary() { return netSalary; } + public void setNetSalary(BigDecimal netSalary) { this.netSalary = netSalary; } + + public BigDecimal getTotalCompanyCost() { return totalCompanyCost; } + public void setTotalCompanyCost(BigDecimal totalCompanyCost) { this.totalCompanyCost = totalCompanyCost; } + } + + /** + * 根据绑定记录ID集合批量计算薪资明细 + */ + private Map calculateSalaryDetailsByBindingIds(List bindingIds) { + if (CollectionUtils.isEmpty(bindingIds)) { + return Collections.emptyMap(); + } + + Map resultMap = new HashMap<>(); + + // 查询所有明细记录 + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.in(OaBindingItemDetail::getBindingId, bindingIds) + .eq(OaBindingItemDetail::getDelFlag, 0); + + List allDetails = bindingItemDetailMapper.selectList(queryWrapper); + + // 按bindingId分组处理 + Map> detailsByBindingId = allDetails.stream() + .collect(Collectors.groupingBy(OaBindingItemDetail::getBindingId)); + + for (Long bindingId : bindingIds) { + SalaryCalculationResult calc = new SalaryCalculationResult(); + List details = detailsByBindingId.getOrDefault(bindingId, Collections.emptyList()); + + for (OaBindingItemDetail detail : details) { + if (detail.getPaidAmount() != null) { + if ("salary".equals(detail.getTemplateType())) { + // 薪资项目 + calc.setTotalSalary(calc.getTotalSalary().add(detail.getPaidAmount())); + } else if ("insurance".equals(detail.getTemplateType())) { + // 社保项目 - 需要区分个人还是企业 + OaInsuranceTemplateDetail insuranceDetail = insuranceDetailMapper.selectById(detail.getItemDetailId()); + if (insuranceDetail != null) { + OaInsuranceTemplate template = insuranceTemplateMapper.selectById(insuranceDetail.getInsuranceTemplateId()); + if (template != null) { + if (template.getType() == 0) { + // 个人社保 + calc.setTotalPersonalInsurance(calc.getTotalPersonalInsurance().add(detail.getPaidAmount())); + } else if (template.getType() == 1) { + // 企业社保 + calc.setTotalCompanyInsurance(calc.getTotalCompanyInsurance().add(detail.getPaidAmount())); + } + } + } + } + } + + } + // 计算实发工资和公司总成本 + BigDecimal personalInsurance = calc.getTotalPersonalInsurance(); + if (personalInsurance.compareTo(BigDecimal.ZERO) < 0) { + personalInsurance = personalInsurance.abs(); // 或直接设为0 + } + calc.setNetSalary(calc.getTotalSalary().subtract(personalInsurance)); + calc.setTotalCompanyCost(calc.getTotalSalary().add(calc.getTotalCompanyInsurance())); + resultMap.put(bindingId, calc); + } + + return resultMap; + } /** * 根据绑定记录ID集合批量计算薪资总额 * @param bindingIds 绑定记录ID集合 @@ -124,7 +253,8 @@ public class OaEmployeeTemplateBindingServiceImpl implements IOaEmployeeTemplate Map params = bo.getParams(); LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); lqw.eq(bo.getEmployeeId() != null, OaEmployeeTemplateBinding::getEmployeeId, bo.getEmployeeId()); - lqw.eq(bo.getInsuranceTemplateId() != null, OaEmployeeTemplateBinding::getInsuranceTemplateId, bo.getInsuranceTemplateId()); + lqw.eq(bo.getPersonalInsuranceTemplateId() != null, OaEmployeeTemplateBinding::getPersonalInsuranceTemplateId, bo.getPersonalInsuranceTemplateId()); + lqw.eq(bo.getCompanyInsuranceTemplateId() != null, OaEmployeeTemplateBinding::getCompanyInsuranceTemplateId, bo.getCompanyInsuranceTemplateId()); lqw.eq(bo.getSalaryTemplateId() != null, OaEmployeeTemplateBinding::getSalaryTemplateId, bo.getSalaryTemplateId()); lqw.eq(bo.getPayYear() != null, OaEmployeeTemplateBinding::getPayYear, bo.getPayYear()); lqw.eq(bo.getPayMonth() != null, OaEmployeeTemplateBinding::getPayMonth, bo.getPayMonth()); @@ -178,9 +308,9 @@ public class OaEmployeeTemplateBindingServiceImpl implements IOaEmployeeTemplate @Override public Boolean calculateSalary(List employeeIds, Long payYear, Long payMonth, - Long defaultInsuranceTemplateId, Long defaultSalaryTemplateId) { + Long defaultPersonalInsuranceTemplateId, Long defaultCompanyInsuranceTemplateId, Long defaultSalaryTemplateId) { // 参数校验 - if (defaultInsuranceTemplateId == null || defaultSalaryTemplateId == null) { + if (defaultPersonalInsuranceTemplateId == null || defaultCompanyInsuranceTemplateId == null || defaultSalaryTemplateId == null) { throw new RuntimeException("请选择默认的薪资模板和社保模板"); } @@ -206,11 +336,13 @@ public class OaEmployeeTemplateBindingServiceImpl implements IOaEmployeeTemplate if (lastBinding != null) { // 存在上月记录,复制上月的模板ID - binding.setInsuranceTemplateId(lastBinding.getInsuranceTemplateId()); + binding.setPersonalInsuranceTemplateId(lastBinding.getPersonalInsuranceTemplateId()); + binding.setCompanyInsuranceTemplateId(lastBinding.getCompanyInsuranceTemplateId()); binding.setSalaryTemplateId(lastBinding.getSalaryTemplateId()); } else { // 首次配置,使用默认模板 - binding.setInsuranceTemplateId(defaultInsuranceTemplateId); + binding.setPersonalInsuranceTemplateId(defaultPersonalInsuranceTemplateId); + binding.setCompanyInsuranceTemplateId(defaultCompanyInsuranceTemplateId); binding.setSalaryTemplateId(defaultSalaryTemplateId); } @@ -224,7 +356,7 @@ public class OaEmployeeTemplateBindingServiceImpl implements IOaEmployeeTemplate } else { // 首次配置,使用模板默认金额 createNewDetails(binding.getBindingId(), binding.getSalaryTemplateId(), - binding.getInsuranceTemplateId()); + binding.getPersonalInsuranceTemplateId(), binding.getCompanyInsuranceTemplateId()); } // 5. 更新主表的汇总金额 @@ -253,7 +385,7 @@ public class OaEmployeeTemplateBindingServiceImpl implements IOaEmployeeTemplate /** * 创建新的明细记录(使用模板默认值) */ - private void createNewDetails(Long bindingId, Long salaryTemplateId, Long insuranceTemplateId) { + private void createNewDetails(Long bindingId, Long salaryTemplateId, Long personalInsuranceTemplateId, Long companyInsuranceTemplateId) { // 薪资明细 List salaryDetails = salaryDetailMapper.findByTemplateId(salaryTemplateId); for (OaSalaryTemplateDetail detail : salaryDetails) { @@ -265,42 +397,76 @@ public class OaEmployeeTemplateBindingServiceImpl implements IOaEmployeeTemplate bindingItemDetailMapper.insert(item); } - // 社保明细 - List insuranceDetails = insuranceDetailMapper.findByTemplateId(insuranceTemplateId); - for (OaInsuranceTemplateDetail detail : insuranceDetails) { - OaBindingItemDetail item = new OaBindingItemDetail(); - item.setBindingId(bindingId); - item.setTemplateType("insurance"); - item.setItemDetailId(detail.getInsuranceDetailId()); - item.setPaidAmount(detail.getAmount() != null ? detail.getAmount() : BigDecimal.ZERO); - bindingItemDetailMapper.insert(item); + // 个人社保明细 + List personalDetails = insuranceDetailMapper.findByTemplateId(personalInsuranceTemplateId); + for (OaInsuranceTemplateDetail detail : personalDetails) { + // 只处理主表type=0的模板 + OaInsuranceTemplate template = insuranceTemplateMapper.selectById(detail.getInsuranceTemplateId()); + if (template != null && template.getType() == 0) { + OaBindingItemDetail item = new OaBindingItemDetail(); + item.setBindingId(bindingId); + item.setTemplateType("insurance"); + item.setItemDetailId(detail.getInsuranceDetailId()); + item.setPaidAmount(detail.getAmount() != null ? detail.getAmount() : BigDecimal.ZERO); + bindingItemDetailMapper.insert(item); + } + } + + // 企业社保明细 + List companyDetails = insuranceDetailMapper.findByTemplateId(companyInsuranceTemplateId); + for (OaInsuranceTemplateDetail detail : companyDetails) { + // 只处理主表type=1的模板 + OaInsuranceTemplate template = insuranceTemplateMapper.selectById(detail.getInsuranceTemplateId()); + if (template != null && template.getType() == 1) { + OaBindingItemDetail item = new OaBindingItemDetail(); + item.setBindingId(bindingId); + item.setTemplateType("insurance"); + item.setItemDetailId(detail.getInsuranceDetailId()); + item.setPaidAmount(detail.getAmount() != null ? detail.getAmount() : BigDecimal.ZERO); + bindingItemDetailMapper.insert(item); + } } } - /** - * 更新主表的汇总金额 - */ private void updateBindingTotals(Long bindingId) { - // 查询该binding下所有明细 List details = bindingItemDetailMapper.findByBindingId(bindingId); BigDecimal totalSalary = BigDecimal.ZERO; - BigDecimal totalCost = BigDecimal.ZERO; + BigDecimal totalPersonalInsurance = BigDecimal.ZERO; + BigDecimal totalCompanyInsurance = BigDecimal.ZERO; for (OaBindingItemDetail detail : details) { if (detail.getPaidAmount() != null) { if ("salary".equals(detail.getTemplateType())) { totalSalary = totalSalary.add(detail.getPaidAmount()); + } else if ("insurance".equals(detail.getTemplateType())) { + // 通过明细的 insuranceTemplateId 查主表 type + OaInsuranceTemplateDetail insuranceDetail = insuranceDetailMapper.selectById(detail.getItemDetailId()); + if (insuranceDetail != null) { + OaInsuranceTemplate template = insuranceTemplateMapper.selectById(insuranceDetail.getInsuranceTemplateId()); + if (template != null) { + // 强制社保金额为正数 + BigDecimal paid = detail.getPaidAmount().abs(); + if (template.getType() == 0) { + totalPersonalInsurance = totalPersonalInsurance.add(paid); + } else if (template.getType() == 1) { + totalCompanyInsurance = totalCompanyInsurance.add(paid); + } + } + } } - totalCost = totalCost.add(detail.getPaidAmount()); } } - // 更新主表 + // 实发工资 = 薪资合计 - 个人社保 + BigDecimal netSalary = totalSalary.subtract(totalPersonalInsurance); + // 单位总支出 = 薪资合计 + 企业社保 + BigDecimal totalCompanyCost = totalSalary.add(totalCompanyInsurance); + OaEmployeeTemplateBinding binding = new OaEmployeeTemplateBinding(); binding.setBindingId(bindingId); - binding.setNetSalary(totalSalary); - binding.setTotalCompanyCost(totalCost); + binding.setNetSalary(netSalary); + binding.setTotalCompanyCost(totalCompanyCost); baseMapper.updateById(binding); } diff --git a/ruoyi-oa/src/main/resources/mapper/oa/OaEmployeeTemplateBindingMapper.xml b/ruoyi-oa/src/main/resources/mapper/oa/OaEmployeeTemplateBindingMapper.xml index 7041067..b6cc54d 100644 --- a/ruoyi-oa/src/main/resources/mapper/oa/OaEmployeeTemplateBindingMapper.xml +++ b/ruoyi-oa/src/main/resources/mapper/oa/OaEmployeeTemplateBindingMapper.xml @@ -7,7 +7,8 @@ - + + @@ -23,14 +24,15 @@ INSERT INTO oa_employee_template_binding - (employee_id, insurance_template_id, salary_template_id, pay_year, pay_month, net_salary, total_company_cost, status) - VALUES (#{employeeId}, #{insuranceTemplateId}, #{salaryTemplateId}, #{payYear}, #{payMonth}, #{netSalary}, #{totalCompanyCost}, #{status}) + (employee_id,personal_insurance_template_id,company_insurance_template_id, salary_template_id, pay_year, pay_month, net_salary, total_company_cost, status) + VALUES (#{employeeId}, #{personalInsuranceTemplateId},#{companyInsuranceTemplateId}, #{salaryTemplateId}, #{payYear}, #{payMonth}, #{netSalary}, #{totalCompanyCost}, #{status}) diff --git a/ruoyi-oa/src/main/resources/mapper/oa/OaInsuranceTemplateMapper.xml b/ruoyi-oa/src/main/resources/mapper/oa/OaInsuranceTemplateMapper.xml index ee04641..587acd4 100644 --- a/ruoyi-oa/src/main/resources/mapper/oa/OaInsuranceTemplateMapper.xml +++ b/ruoyi-oa/src/main/resources/mapper/oa/OaInsuranceTemplateMapper.xml @@ -7,6 +7,7 @@ +