薪资分析
This commit is contained in:
@@ -3,6 +3,9 @@ package com.ruoyi.oa.mapper;
|
||||
import com.ruoyi.oa.domain.OaBindingItemDetail;
|
||||
import com.ruoyi.oa.domain.vo.OaBindingItemDetailVo;
|
||||
import com.ruoyi.common.core.mapper.BaseMapperPlus;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 绑定记录明细Mapper接口
|
||||
@@ -11,5 +14,5 @@ import com.ruoyi.common.core.mapper.BaseMapperPlus;
|
||||
* @date 2025-06-23
|
||||
*/
|
||||
public interface OaBindingItemDetailMapper extends BaseMapperPlus<OaBindingItemDetailMapper, OaBindingItemDetail, OaBindingItemDetailVo> {
|
||||
|
||||
List<OaBindingItemDetail> findByBindingId(@Param("bindingId") Long bindingId);
|
||||
}
|
||||
|
||||
@@ -177,7 +177,8 @@ public class OaEmployeeTemplateBindingServiceImpl implements IOaEmployeeTemplate
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean calculateSalary(List<Long> employeeIds, Long payYear, Long payMonth,Long defaultInsuranceTemplateId, Long defaultSalaryTemplateId) {
|
||||
public Boolean calculateSalary(List<Long> employeeIds, Long payYear, Long payMonth,
|
||||
Long defaultInsuranceTemplateId, Long defaultSalaryTemplateId) {
|
||||
// 参数校验
|
||||
if (defaultInsuranceTemplateId == null || defaultSalaryTemplateId == null) {
|
||||
throw new RuntimeException("请选择默认的薪资模板和社保模板");
|
||||
@@ -187,92 +188,122 @@ public class OaEmployeeTemplateBindingServiceImpl implements IOaEmployeeTemplate
|
||||
// 1. 检查本月是否已存在记录
|
||||
OaEmployeeTemplateBinding exist = baseMapper.findByEmployeeAndMonth(employeeId, payYear, payMonth);
|
||||
if (exist != null) {
|
||||
// 已存在,跳过或更新
|
||||
// 已存在,跳过
|
||||
continue;
|
||||
}
|
||||
|
||||
// 2. 获取上月的模板ID(支持一键复制)
|
||||
// 2. 获取上月记录
|
||||
Long lastMonth = (payMonth == 1) ? 12 : payMonth - 1;
|
||||
Long lastYear = (payMonth == 1) ? payYear - 1 : payYear;
|
||||
OaEmployeeTemplateBinding lastBinding = baseMapper.findByEmployeeAndMonth(employeeId, lastYear, lastMonth);
|
||||
|
||||
Long insuranceTemplateId;
|
||||
Long salaryTemplateId;
|
||||
if (lastBinding != null) {
|
||||
// 存在上月记录,使用上月的模板
|
||||
insuranceTemplateId = lastBinding.getInsuranceTemplateId();
|
||||
salaryTemplateId = lastBinding.getSalaryTemplateId();
|
||||
} else {
|
||||
// 首次配置,使用前端传入的默认模板
|
||||
insuranceTemplateId = defaultInsuranceTemplateId;
|
||||
salaryTemplateId = defaultSalaryTemplateId;
|
||||
|
||||
// 将默认模板ID保存到员工表
|
||||
// OaEmployeeTemplateBinding employee = new OaEmployeeTemplateBinding();
|
||||
// employee.setEmployeeId(employeeId);
|
||||
// employee.setInsuranceTemplateId(defaultInsuranceTemplateId);
|
||||
// employee.setSalaryTemplateId(defaultSalaryTemplateId);
|
||||
// baseMapper.updateById(employee);
|
||||
}
|
||||
|
||||
// 3. 新建本月主表记录
|
||||
OaEmployeeTemplateBinding binding = new OaEmployeeTemplateBinding();
|
||||
binding.setEmployeeId(employeeId);
|
||||
binding.setInsuranceTemplateId(insuranceTemplateId);
|
||||
binding.setSalaryTemplateId(salaryTemplateId);
|
||||
binding.setPayYear(payYear);
|
||||
binding.setPayMonth(payMonth);
|
||||
binding.setStatus("待发");
|
||||
// binding.setNetSalary(BigDecimal.ZERO); // 确保设置默认值
|
||||
// binding.setTotalCompanyCost(BigDecimal.ZERO);
|
||||
|
||||
if (lastBinding != null) {
|
||||
// 存在上月记录,复制上月的模板ID
|
||||
binding.setInsuranceTemplateId(lastBinding.getInsuranceTemplateId());
|
||||
binding.setSalaryTemplateId(lastBinding.getSalaryTemplateId());
|
||||
} else {
|
||||
// 首次配置,使用默认模板
|
||||
binding.setInsuranceTemplateId(defaultInsuranceTemplateId);
|
||||
binding.setSalaryTemplateId(defaultSalaryTemplateId);
|
||||
}
|
||||
|
||||
// 插入主表记录
|
||||
baseMapper.insert(binding);
|
||||
|
||||
// 4. 生成明细快照
|
||||
List<OaSalaryTemplateDetail> salaryDetails = salaryDetailMapper.findByTemplateId(salaryTemplateId);
|
||||
List<OaInsuranceTemplateDetail> insuranceDetails = insuranceDetailMapper.findByTemplateId(insuranceTemplateId);
|
||||
|
||||
BigDecimal totalSalary = BigDecimal.ZERO;
|
||||
BigDecimal totalCompanyInsurance = BigDecimal.ZERO;
|
||||
|
||||
// 薪资明细
|
||||
for (OaSalaryTemplateDetail detail : salaryDetails) {
|
||||
BigDecimal paidAmount = detail.getAmount() != null ? detail.getAmount() : BigDecimal.ZERO;
|
||||
totalSalary = totalSalary.add(paidAmount);
|
||||
|
||||
OaBindingItemDetail item = new OaBindingItemDetail();
|
||||
item.setBindingId(binding.getBindingId());
|
||||
item.setTemplateType("salary");
|
||||
item.setItemDetailId(detail.getSalaryDetailId());
|
||||
item.setPaidAmount(paidAmount);
|
||||
//打印item
|
||||
System.out.println("item:"+item);
|
||||
bindingItemDetailMapper.insert(item);
|
||||
if (lastBinding != null) {
|
||||
// 如果存在上月记录,复制上月的实际支付金额
|
||||
copyLastMonthDetails(lastBinding.getBindingId(), binding.getBindingId());
|
||||
} else {
|
||||
// 首次配置,使用模板默认金额
|
||||
createNewDetails(binding.getBindingId(), binding.getSalaryTemplateId(),
|
||||
binding.getInsuranceTemplateId());
|
||||
}
|
||||
|
||||
// 社保明细
|
||||
for (OaInsuranceTemplateDetail detail : insuranceDetails) {
|
||||
BigDecimal paidAmount = detail.getAmount() != null ? detail.getAmount() : BigDecimal.ZERO;
|
||||
totalCompanyInsurance = totalCompanyInsurance.add(paidAmount);
|
||||
|
||||
OaBindingItemDetail item = new OaBindingItemDetail();
|
||||
item.setBindingId(binding.getBindingId());
|
||||
item.setTemplateType("insurance");
|
||||
item.setItemDetailId(detail.getInsuranceDetailId());
|
||||
item.setPaidAmount(paidAmount);
|
||||
bindingItemDetailMapper.insert(item);
|
||||
}
|
||||
|
||||
// 5. 计算实发工资和单位总支出
|
||||
BigDecimal netSalary = totalSalary;
|
||||
//TODO 可扩展:减去个税、个人社保等
|
||||
BigDecimal totalCompanyCost = netSalary.add(totalCompanyInsurance);
|
||||
binding.setNetSalary(netSalary);
|
||||
binding.setTotalCompanyCost(totalCompanyCost);
|
||||
baseMapper.updateById(binding);
|
||||
// 5. 更新主表的汇总金额
|
||||
updateBindingTotals(binding.getBindingId());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 复制上月明细记录
|
||||
*/
|
||||
private void copyLastMonthDetails(Long lastBindingId, Long newBindingId) {
|
||||
// 查询上月所有明细
|
||||
List<OaBindingItemDetail> lastDetails = bindingItemDetailMapper.findByBindingId(lastBindingId);
|
||||
|
||||
for (OaBindingItemDetail lastDetail : lastDetails) {
|
||||
OaBindingItemDetail newDetail = new OaBindingItemDetail();
|
||||
newDetail.setBindingId(newBindingId);
|
||||
newDetail.setTemplateType(lastDetail.getTemplateType());
|
||||
newDetail.setItemDetailId(lastDetail.getItemDetailId());
|
||||
newDetail.setPaidAmount(lastDetail.getPaidAmount()); // 复制实际支付金额
|
||||
bindingItemDetailMapper.insert(newDetail);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建新的明细记录(使用模板默认值)
|
||||
*/
|
||||
private void createNewDetails(Long bindingId, Long salaryTemplateId, Long insuranceTemplateId) {
|
||||
// 薪资明细
|
||||
List<OaSalaryTemplateDetail> salaryDetails = salaryDetailMapper.findByTemplateId(salaryTemplateId);
|
||||
for (OaSalaryTemplateDetail detail : salaryDetails) {
|
||||
OaBindingItemDetail item = new OaBindingItemDetail();
|
||||
item.setBindingId(bindingId);
|
||||
item.setTemplateType("salary");
|
||||
item.setItemDetailId(detail.getSalaryDetailId());
|
||||
item.setPaidAmount(detail.getAmount() != null ? detail.getAmount() : BigDecimal.ZERO);
|
||||
bindingItemDetailMapper.insert(item);
|
||||
}
|
||||
|
||||
// 社保明细
|
||||
List<OaInsuranceTemplateDetail> 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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新主表的汇总金额
|
||||
*/
|
||||
private void updateBindingTotals(Long bindingId) {
|
||||
// 查询该binding下所有明细
|
||||
List<OaBindingItemDetail> details = bindingItemDetailMapper.findByBindingId(bindingId);
|
||||
|
||||
BigDecimal totalSalary = BigDecimal.ZERO;
|
||||
BigDecimal totalCost = BigDecimal.ZERO;
|
||||
|
||||
for (OaBindingItemDetail detail : details) {
|
||||
if (detail.getPaidAmount() != null) {
|
||||
if ("salary".equals(detail.getTemplateType())) {
|
||||
totalSalary = totalSalary.add(detail.getPaidAmount());
|
||||
}
|
||||
totalCost = totalCost.add(detail.getPaidAmount());
|
||||
}
|
||||
}
|
||||
|
||||
// 更新主表
|
||||
OaEmployeeTemplateBinding binding = new OaEmployeeTemplateBinding();
|
||||
binding.setBindingId(bindingId);
|
||||
binding.setNetSalary(totalSalary);
|
||||
binding.setTotalCompanyCost(totalCost);
|
||||
baseMapper.updateById(binding);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Boolean finalizeSalary(List<String> bindingIds) {
|
||||
|
||||
@@ -17,6 +17,12 @@
|
||||
<result property="updateBy" column="update_by"/>
|
||||
<result property="updateTime" column="update_time"/>
|
||||
</resultMap>
|
||||
<select id="findByBindingId" resultType="com.ruoyi.oa.domain.OaBindingItemDetail">
|
||||
SELECT *
|
||||
FROM oa_binding_item_detail
|
||||
WHERE binding_id = #{bindingId}
|
||||
AND del_flag = 0
|
||||
</select>
|
||||
|
||||
|
||||
</mapper>
|
||||
|
||||
Reference in New Issue
Block a user