薪资计算逻辑完善
This commit is contained in:
@@ -124,7 +124,7 @@ public class OaEmployeeTemplateBindingController extends BaseController {
|
||||
}
|
||||
// 7. 批量确认发放
|
||||
@PostMapping("/finalize")
|
||||
public R<Void> finalizeSalary(@RequestBody List<Long> bindingIds) {
|
||||
public R<Void> finalizeSalary(@RequestBody List<String> bindingIds ) {
|
||||
return toAjax(iOaEmployeeTemplateBindingService.finalizeSalary(bindingIds));
|
||||
}
|
||||
// 8. 查询单员工历史发放记录
|
||||
|
||||
@@ -83,6 +83,7 @@ public class OaEmployeeTemplateBindingVo {
|
||||
@ExcelProperty(value = "备注")
|
||||
private String remark;
|
||||
|
||||
|
||||
@ExcelProperty(value = "实发工资")
|
||||
private BigDecimal totalSalary;
|
||||
|
||||
}
|
||||
|
||||
@@ -12,6 +12,5 @@ import org.springframework.data.repository.query.Param;
|
||||
* @date 2025-06-23
|
||||
*/
|
||||
public interface OaEmployeeMapper extends BaseMapperPlus<OaEmployeeMapper, OaEmployee, OaEmployeeVo> {
|
||||
Long getDefaultInsuranceTemplateId(@Param("employeeId") Long employeeId);
|
||||
Long getDefaultSalaryTemplateId(@Param("employeeId") Long employeeId);
|
||||
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package com.ruoyi.oa.mapper;
|
||||
import com.ruoyi.oa.domain.OaEmployeeTemplateBinding;
|
||||
import com.ruoyi.oa.domain.vo.OaEmployeeTemplateBindingVo;
|
||||
import com.ruoyi.common.core.mapper.BaseMapperPlus;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
/**
|
||||
* 员工模板绑定及月度发放记录Mapper接口
|
||||
|
||||
@@ -3,7 +3,7 @@ package com.ruoyi.oa.mapper;
|
||||
import com.ruoyi.oa.domain.OaInsuranceTemplateDetail;
|
||||
import com.ruoyi.oa.domain.vo.OaInsuranceTemplateDetailVo;
|
||||
import com.ruoyi.common.core.mapper.BaseMapperPlus;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ package com.ruoyi.oa.mapper;
|
||||
import com.ruoyi.oa.domain.OaSalaryTemplateDetail;
|
||||
import com.ruoyi.oa.domain.vo.OaSalaryTemplateDetailVo;
|
||||
import com.ruoyi.common.core.mapper.BaseMapperPlus;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@@ -49,6 +49,6 @@ public interface IOaEmployeeTemplateBindingService {
|
||||
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||
|
||||
Boolean calculateSalary(List<Long> employeeIds, Long payYear, Long payMonth,Long defaultInsuranceTemplateId, Long defaultSalaryTemplateId);
|
||||
Boolean finalizeSalary(List<Long> bindingIds);
|
||||
Boolean finalizeSalary(List<String> bindingIds);
|
||||
List<EmployeeSalaryRecordVo> querySalaryHistory(Long employeeId);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.ruoyi.oa.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
import com.ruoyi.common.core.domain.PageQuery;
|
||||
@@ -20,6 +21,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;
|
||||
@@ -61,9 +63,54 @@ public class OaEmployeeTemplateBindingServiceImpl implements IOaEmployeeTemplate
|
||||
public TableDataInfo<OaEmployeeTemplateBindingVo> queryPageList(OaEmployeeTemplateBindingBo bo, PageQuery pageQuery) {
|
||||
LambdaQueryWrapper<OaEmployeeTemplateBinding> lqw = buildQueryWrapper(bo);
|
||||
Page<OaEmployeeTemplateBindingVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
||||
// 根据bindingid和template_type(salary)去求和paid_amount字段
|
||||
if (CollectionUtils.isNotEmpty(result.getRecords())) {
|
||||
// 提取所有bindingId
|
||||
List<Long> bindingIds = result.getRecords().stream()
|
||||
.map(OaEmployeeTemplateBindingVo::getBindingId)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 批量查询每个bindingId对应的薪资总额
|
||||
Map<Long, BigDecimal> salaryTotalMap = calculateSalaryTotalByBindingIds(bindingIds);
|
||||
|
||||
// 将计算结果设置到对应的VO对象中
|
||||
for (OaEmployeeTemplateBindingVo vo : result.getRecords()) {
|
||||
vo.setTotalSalary(salaryTotalMap.getOrDefault(vo.getBindingId(), BigDecimal.ZERO));
|
||||
}
|
||||
}
|
||||
|
||||
return TableDataInfo.build(result);
|
||||
}
|
||||
/**
|
||||
* 根据绑定记录ID集合批量计算薪资总额
|
||||
* @param bindingIds 绑定记录ID集合
|
||||
* @return 绑定记录ID与薪资总额的映射关系
|
||||
*/
|
||||
private Map<Long, BigDecimal> calculateSalaryTotalByBindingIds(List<Long> bindingIds) {
|
||||
if (CollectionUtils.isEmpty(bindingIds)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
// 创建查询条件
|
||||
LambdaQueryWrapper<OaBindingItemDetail> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.in(OaBindingItemDetail::getBindingId, bindingIds)
|
||||
.eq(OaBindingItemDetail::getTemplateType, "salary") // 只查询薪资类型
|
||||
.eq(OaBindingItemDetail::getDelFlag, 0); // 只查询未删除的记录
|
||||
|
||||
// 查询所有符合条件的明细记录
|
||||
List<OaBindingItemDetail> details = bindingItemDetailMapper.selectList(queryWrapper);
|
||||
|
||||
// 使用流处理按bindingId分组并计算总额
|
||||
return details.stream()
|
||||
.collect(Collectors.groupingBy(
|
||||
OaBindingItemDetail::getBindingId,
|
||||
Collectors.reducing(
|
||||
BigDecimal.ZERO,
|
||||
OaBindingItemDetail::getPaidAmount,
|
||||
BigDecimal::add
|
||||
)
|
||||
));
|
||||
}
|
||||
/**
|
||||
* 查询员工模板绑定及月度发放记录列表
|
||||
*/
|
||||
@@ -135,6 +182,7 @@ public class OaEmployeeTemplateBindingServiceImpl implements IOaEmployeeTemplate
|
||||
if (defaultInsuranceTemplateId == null || defaultSalaryTemplateId == null) {
|
||||
throw new RuntimeException("请选择默认的薪资模板和社保模板");
|
||||
}
|
||||
|
||||
for (Long employeeId : employeeIds) {
|
||||
// 1. 检查本月是否已存在记录
|
||||
OaEmployeeTemplateBinding exist = baseMapper.findByEmployeeAndMonth(employeeId, payYear, payMonth);
|
||||
@@ -175,6 +223,8 @@ public class OaEmployeeTemplateBindingServiceImpl implements IOaEmployeeTemplate
|
||||
binding.setPayYear(payYear);
|
||||
binding.setPayMonth(payMonth);
|
||||
binding.setStatus("待发");
|
||||
// binding.setNetSalary(BigDecimal.ZERO); // 确保设置默认值
|
||||
// binding.setTotalCompanyCost(BigDecimal.ZERO);
|
||||
baseMapper.insert(binding);
|
||||
|
||||
// 4. 生成明细快照
|
||||
@@ -194,6 +244,8 @@ public class OaEmployeeTemplateBindingServiceImpl implements IOaEmployeeTemplate
|
||||
item.setTemplateType("salary");
|
||||
item.setItemDetailId(detail.getSalaryDetailId());
|
||||
item.setPaidAmount(paidAmount);
|
||||
//打印item
|
||||
System.out.println("item:"+item);
|
||||
bindingItemDetailMapper.insert(item);
|
||||
}
|
||||
|
||||
@@ -214,7 +266,6 @@ public class OaEmployeeTemplateBindingServiceImpl implements IOaEmployeeTemplate
|
||||
BigDecimal netSalary = totalSalary;
|
||||
//TODO 可扩展:减去个税、个人社保等
|
||||
BigDecimal totalCompanyCost = netSalary.add(totalCompanyInsurance);
|
||||
|
||||
binding.setNetSalary(netSalary);
|
||||
binding.setTotalCompanyCost(totalCompanyCost);
|
||||
baseMapper.updateById(binding);
|
||||
@@ -224,11 +275,12 @@ public class OaEmployeeTemplateBindingServiceImpl implements IOaEmployeeTemplate
|
||||
|
||||
|
||||
@Override
|
||||
public Boolean finalizeSalary(List<Long> bindingIds) {
|
||||
for (Long id : bindingIds) {
|
||||
public Boolean finalizeSalary(List<String> bindingIds) {
|
||||
for (String id : bindingIds) {
|
||||
OaEmployeeTemplateBinding binding = baseMapper.selectById(id);
|
||||
if (binding != null && !"已发".equals(binding.getStatus())) {
|
||||
binding.setStatus("已发");
|
||||
//TODO 这里可以算到财务支出等逻辑
|
||||
baseMapper.updateById(binding);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user