薪资计算相关调整

This commit is contained in:
andy 2026-06-01 11:22:50 +08:00
parent 0a87b28282
commit 8e7d331c65
11 changed files with 139 additions and 116 deletions

View File

@ -3,11 +3,7 @@ package com.evo.finance.controller;
import java.util.List;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import com.evo.common.annotation.Log;
import com.evo.common.core.controller.BaseController;
import com.evo.common.core.domain.AjaxResult;
@ -51,4 +47,15 @@ public class RzSalaryStatisticsController extends BaseController
{
return rzSalaryStatisticsService.deleteRzSalaryStatisticsById(id);
}
/**
* 确认发放工资
*/
@PreAuthorize("@ss.hasPermi('finance:financeStatistics:confirm')")
@Log(title = "工资统计", businessType = BusinessType.UPDATE)
@PutMapping("/{id}")
public AjaxResult confirm(@PathVariable Long id)
{
return rzSalaryStatisticsService.confirmRzSalaryStatisticsById(id);
}
}

View File

@ -5,6 +5,7 @@ import java.util.Date;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.evo.common.annotation.Excel;
@ -16,6 +17,7 @@ import com.evo.common.core.domain.BaseEntity;
* @author evo
* @date 2024-11-26
*/
@Data
public class RzSalaryStatistics extends BaseEntity
{
private static final long serialVersionUID = 1L;
@ -43,61 +45,12 @@ public class RzSalaryStatistics extends BaseEntity
/** 删除标识 */
private String delFlag;
/***
* 发放信息
*/
private String salaryInfo;
public void setId(Long id)
{
this.id = id;
}
public Long getId()
{
return id;
}
public void setMonth(Date month)
{
this.month = month;
}
public Date getMonth()
{
return month;
}
public void setNumber(int number)
{
this.number = number;
}
public int getNumber()
{
return number;
}
public void setStatus(String status)
{
this.status = status;
}
public String getStatus()
{
return status;
}
public void setRemarks(String remarks)
{
this.remarks = remarks;
}
public String getRemarks()
{
return remarks;
}
public void setDelFlag(String delFlag)
{
this.delFlag = delFlag;
}
public String getDelFlag()
{
return delFlag;
}
@Override
public String toString() {

View File

@ -62,6 +62,14 @@ public interface RzSalaryDetailMapper extends BaseMapper<RzSalaryDetail>
* @return 工资详情集合
*/
public List<RzSalaryDetail> selectRzSalaryDetailByMonth(Date month);
/**
* 根据月份删除工资详情列表
*
* @param month 工资详情
* @return 工资详情集合
*/
public int deleteRzSalaryDetailByMonth(Date month);
/**
* 根据部门查询工资单
* @return

View File

@ -21,6 +21,8 @@ import java.math.RoundingMode;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
@ -78,7 +80,7 @@ public interface SalaryCalculationStrategyExchangeProcessor {
* 计算新薪资
* @return
*/
void exchangeSalaryCalculation(SysStaff sysStaff, SysStaffDetail detail, RzSalaryDetail rzSalaryDetail, RzAttendanceStatistical attendanceStatistical, Map<Long, Boolean> overTimeMap);
void exchangeSalaryCalculation(SysStaff sysStaff, SysStaffDetail detail, RzSalaryDetail rzSalaryDetail, RzAttendanceStatistical attendanceStatistical, Map<Long, Boolean> overTimeMap, List<Map<String,Object>> salaryInfoMapList);
void monthSalary(Date limitMonth, Date month, Date limitDate ,SysStaff sysStaff, SysStaffDetail sysStaffDetail, RzSalaryDetail rzSalaryDetail, RzAttendanceStatistical attendanceStatistical);
@ -222,7 +224,7 @@ public interface SalaryCalculationStrategyExchangeProcessor {
* 开始计算薪资
*/
default void calculation(SysStaff sysStaff, SysStaffDetail detail, RzSalaryDetail rzSalaryDetail){
default void calculation(SysStaff sysStaff, SysStaffDetail detail, RzSalaryDetail rzSalaryDetail, List<Map<String,Object>> salaryInfoMapList){
RzSalaryDetailMapper rzSalaryDetailMapper = SpringUtils.getBean(RzSalaryDetailMapper.class);
SysStaffDetailMapper sysStaffDetailMapper = SpringUtils.getBean(SysStaffDetailMapper.class);
@ -360,29 +362,50 @@ public interface SalaryCalculationStrategyExchangeProcessor {
if(rzSalaryDetailMapper.insert(rzSalaryDetail)< 0){
throw new RuntimeException("生成员工考勤详情失败");
}
//判断统计月缴费公司和上一次是否一个公司
Map<String, Object> salaryInfoMap = Collections.asMap("detailId", detail.getId());
if(StringUtils.isNull(old_rzSalary)
|| !old_rzSalary.getWbFlag().equals(sysStaff.getCompanyName())
//判断12月, 是个税系统, 每年12月更新, 开始累计次年1月数据
|| curr_month == 12){
// 把本年累计已缴个税保存到员工信息表中
detail.setAggregatePersonalIncomeTax(rzSalaryDetail.getTaxPayable());
// 把本年累计专项扣除保存到员工信息表中
detail.setSpecialDeduction(kouChu);
// 把本年累计已发工资保存到员工信息表中
detail.setTotalWages(rzSalaryDetail.getSalaryBeforeTax());
// 把本年累计已缴个税保存到员工信息表中
salaryInfoMap.put("aggregatePersonalIncomeTax", rzSalaryDetail.getTaxPayable());
// 把本年累计专项扣除保存到员工信息表中
salaryInfoMap.put("specialDeduction", kouChu);
// 把本年累计已发工资保存到员工信息表中
salaryInfoMap.put("totalWages", rzSalaryDetail.getSalaryBeforeTax());
}else{
// 把本年累计已缴个税保存到员工信息表中
salaryInfoMap.put("aggregatePersonalIncomeTax", rzSalaryDetail.getAggregatePersonalIncomeTax());
// 把本年累计专项扣除保存到员工信息表中
salaryInfoMap.put("specialDeduction", detail.getSpecialDeduction().add(kouChu));
// 把本年累计已发工资保存到员工信息表中
salaryInfoMap.put("totalWages", rzSalaryDetail.getTotalWages());
}
salaryInfoMapList.add(salaryInfoMap);
}else{
// 把本年累计个税
detail.setAggregatePersonalIncomeTax(rzSalaryDetail.getAggregatePersonalIncomeTax());
// 把本年累计专项扣除保存到员工信息表中
detail.setSpecialDeduction(detail.getSpecialDeduction().add(kouChu));
// 把本年累计已发工资保存到员工信息表中
detail.setTotalWages(rzSalaryDetail.getTotalWages());
}
if(sysStaffDetailMapper.updateSysStaffDetail(detail)< 0){
throw new RuntimeException("更新员工详情信息异常");
}
//判断统计月缴费公司和上一次是否一个公司
// if(StringUtils.isNull(old_rzSalary)
// || !old_rzSalary.getWbFlag().equals(sysStaff.getCompanyName())
// //判断12月, 是个税系统, 每年12月更新, 开始累计次年1月数据
// || curr_month == 12){
// // 把本年累计已缴个税保存到员工信息表中
// detail.setAggregatePersonalIncomeTax(rzSalaryDetail.getTaxPayable());
// // 把本年累计专项扣除保存到员工信息表中
// detail.setSpecialDeduction(kouChu);
// // 把本年累计已发工资保存到员工信息表中
// detail.setTotalWages(rzSalaryDetail.getSalaryBeforeTax());
//
// }else{
// // 把本年累计个税
// detail.setAggregatePersonalIncomeTax(rzSalaryDetail.getAggregatePersonalIncomeTax());
// // 把本年累计专项扣除保存到员工信息表中
// detail.setSpecialDeduction(detail.getSpecialDeduction().add(kouChu));
// // 把本年累计已发工资保存到员工信息表中
// detail.setTotalWages(rzSalaryDetail.getTotalWages());
// }
// if(sysStaffDetailMapper.updateSysStaffDetail(detail)< 0){
// throw new RuntimeException("更新员工详情信息异常");
// }
}

View File

@ -46,7 +46,7 @@ public class DailyWageStrategyExchangeProcessor implements SalaryCalculationStra
}
@Override
public void exchangeSalaryCalculation(SysStaff sysStaff, SysStaffDetail sysStaffDetail, RzSalaryDetail rzSalaryDetail, RzAttendanceStatistical attendanceStatistical, Map<Long, Boolean> overTimeMap) {
public void exchangeSalaryCalculation(SysStaff sysStaff, SysStaffDetail sysStaffDetail, RzSalaryDetail rzSalaryDetail, RzAttendanceStatistical attendanceStatistical, Map<Long, Boolean> overTimeMap, List<Map<String,Object>> salaryInfoMapList) {
// //计算社保
// socialSecurity(sysStaff,sysStaffDetail, attendanceStatistical);
@ -54,7 +54,7 @@ public class DailyWageStrategyExchangeProcessor implements SalaryCalculationStra
buildRzSalaryDetail(false, sysStaff, sysStaffDetail,rzSalaryDetail, attendanceStatistical);
//计算薪资
calculation(sysStaff, sysStaffDetail,rzSalaryDetail);
calculation(sysStaff, sysStaffDetail,rzSalaryDetail, salaryInfoMapList);
}

View File

@ -56,13 +56,13 @@ public class MonthlySalaryStrategyExchangeProcessor implements SalaryCalculation
* @param overTimeMap
*/
@Override
public void exchangeSalaryCalculation(SysStaff sysStaff, SysStaffDetail sysStaffDetail, RzSalaryDetail rzSalaryDetail, RzAttendanceStatistical attendanceStatistical, Map<Long, Boolean> overTimeMap) {
public void exchangeSalaryCalculation(SysStaff sysStaff, SysStaffDetail sysStaffDetail, RzSalaryDetail rzSalaryDetail, RzAttendanceStatistical attendanceStatistical, Map<Long, Boolean> overTimeMap, List<Map<String,Object>> salaryInfoMapList) {
//计算社保
//socialSecurity(sysStaff,sysStaffDetail, attendanceStatistical);
//组件基础数据
buildRzSalaryDetail(true, sysStaff, sysStaffDetail,rzSalaryDetail, attendanceStatistical);
//计算薪资
calculation(sysStaff, sysStaffDetail,rzSalaryDetail);
calculation(sysStaff, sysStaffDetail,rzSalaryDetail, salaryInfoMapList);
}
@Override

View File

@ -35,4 +35,6 @@ public interface IRzSalaryStatisticsService extends IService<RzSalaryStatistics>
* @return 结果
*/
public AjaxResult deleteRzSalaryStatisticsById(Long id);
public AjaxResult confirmRzSalaryStatisticsById(Long id);
}

View File

@ -1,5 +1,6 @@
package com.evo.finance.service.impl;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.evo.attendance.domain.RzAttendanceStatistical;
@ -139,7 +140,7 @@ public class RzSalaryDetailServiceImpl extends ServiceImpl<RzSalaryDetailMapper,
e.printStackTrace();
}
Map<Long, Boolean> overTimeMap = deptMapper.selectList(new LambdaQueryWrapper<SysDept>().eq(SysDept::getDelFlag, Constants.DELETE_FLAG_0).select(SysDept::getIsOverTime, SysDept::getDeptId)).stream().collect(Collectors.toMap(SysDept::getDeptId,d->"0".equals(d.getIsOverTime())));
List<Map<String,Object>> salaryInfoMapList = Collections.emptyList();
for (SysStaff sysStaff : st_list) {
RzSalaryDetail newRzSalaryDetail = new RzSalaryDetail();
newRzSalaryDetail.setMonth(rzSalaryDetail.getMonth());
@ -152,14 +153,15 @@ public class RzSalaryDetailServiceImpl extends ServiceImpl<RzSalaryDetailMapper,
RzAttendanceStatistical attendanceStatistical = rzAttendanceStatisticalMapper.getRzAttendanceStatisticalByDateAndName(sysStaff.getUserId(), rzSalaryDetail.getMonth());
//查询员工详情
SysStaffDetail sysStaffDetail = sysStaffDetailMapper.selectSysStaffDetailByStaffId(sysStaff.getUserId());
Map<String, SalaryCalculationStrategyExchangeProcessor> salaryCalculationExchangeProcessorMap = applicationContext.getBeansOfType(SalaryCalculationStrategyExchangeProcessor.class);
for (SalaryCalculationStrategyExchangeProcessor processor : salaryCalculationExchangeProcessorMap.values()) {
if (processor.accept(sysStaffDetail)) {
processor.exchangeSalaryCalculation(sysStaff, sysStaffDetail, newRzSalaryDetail, attendanceStatistical, overTimeMap);
processor.exchangeSalaryCalculation(sysStaff, sysStaffDetail, newRzSalaryDetail, attendanceStatistical, overTimeMap, salaryInfoMapList);
}
}
}
rzSalaryStatistics.setSalaryInfo(JSON.toJSONString(salaryInfoMapList));
rzSalaryStatisticsMapper.updateById(rzSalaryStatistics);
//关闭日志记录
ParamUtils.updateLogOperation(false);
return AjaxResult.success();

View File

@ -4,12 +4,17 @@ import java.text.SimpleDateFormat;
import java.util.List;
import java.util.stream.Collectors;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.evo.common.constant.Constants;
import com.evo.common.core.domain.AjaxResult;
import com.evo.common.utils.Collections;
import com.evo.common.utils.DateUtils;
import com.evo.common.utils.SecurityUtils;
import com.evo.common.utils.StringUtils;
import com.evo.finance.domain.RzSalaryDetail;
import com.evo.finance.mapper.RzSalaryDetailMapper;
import com.evo.system.domain.SysStaffDetail;
@ -64,38 +69,53 @@ public class RzSalaryStatisticsServiceImpl extends ServiceImpl<RzSalaryStatistic
*/
@Override
@Transactional
public AjaxResult deleteRzSalaryStatisticsById(Long id)
{
public AjaxResult deleteRzSalaryStatisticsById(Long id){
RzSalaryStatistics rzSalaryStatistics = rzSalaryStatisticsMapper.selectRzSalaryStatisticsById(id);
//根据月份查询员工的工资统计
List<RzSalaryDetail> gz_list = rzSalaryDetailMapper.selectRzSalaryDetailByMonth(rzSalaryStatistics.getMonth());
for (RzSalaryDetail rzSalaryDetail : gz_list) {
//根据员工ID查询员工详情修改员工详情
SysStaffDetail sysStaffDetail = sysStaffDetailMapper.selectSysStaffDetailByStaffId(rzSalaryDetail.getStaffId());
//修改个人详情
sysStaffDetail.setAggregatePersonalIncomeTax(sysStaffDetail.getAggregatePersonalIncomeTax().subtract(rzSalaryDetail.getTaxPayable()));
sysStaffDetail.setSpecialDeduction(sysStaffDetail.getSpecialDeduction().subtract(sysStaffDetail.getSpecialDeduction().subtract(rzSalaryDetail.getSpecialDeduction())));
sysStaffDetail.setTotalWages(sysStaffDetail.getTotalWages().subtract(rzSalaryDetail.getSalaryBeforeTax()));
int i = sysStaffDetailMapper.updateSysStaffDetail(sysStaffDetail);
if(i < 1){
return AjaxResult.error();
}
//删除个人员工工资详情
rzSalaryDetail.setDelFlag(Constants.DELETE_FLAG_1);
rzSalaryDetail.setUpdateBy(SecurityUtils.getUsername());
rzSalaryDetail.setUpdateTime(DateUtils.getNowDate());
i = rzSalaryDetailMapper.updateRzSalaryDetail(rzSalaryDetail);
if(i < 1){
return AjaxResult.error();
}
}
rzSalaryStatistics.setDelFlag(Constants.DELETE_FLAG_1);
rzSalaryStatistics.setUpdateTime(DateUtils.getNowDate());
rzSalaryStatistics.setUpdateBy(SecurityUtils.getUsername());
int p = rzSalaryStatisticsMapper.updateRzSalaryStatistics(rzSalaryStatistics);
if(p< 1){
return AjaxResult.error();
}
//根据月份直接物理删除
rzSalaryDetailMapper.deleteRzSalaryDetailByMonth(rzSalaryStatistics.getMonth());
rzSalaryStatisticsMapper.deleteById(rzSalaryStatistics);
// if(rzSalaryDetailMapper.deleteRzSalaryDetailByMonth(rzSalaryStatistics.getMonth()) < 1 || rzSalaryStatisticsMapper.deleteById(rzSalaryStatistics)< 1){
// return AjaxResult.error();
// }
return AjaxResult.success();
}
@Override
public AjaxResult confirmRzSalaryStatisticsById(Long id) {
RzSalaryStatistics rzSalaryStatistics = rzSalaryStatisticsMapper.selectById(id);
if(rzSalaryStatistics == null){
return AjaxResult.error("未找到统计信息");
}
if("已确认".equals(rzSalaryStatistics.getStatus())){
return AjaxResult.error("当前信息已确认发放");
}
if(StringUtils.isEmpty(rzSalaryStatistics.getSalaryInfo())){
return AjaxResult.error("未找到当前月份的薪资详情");
}
List<Long> detailIds = Collections.emptyList();
JSONArray jsonArray = JSON.parseArray(rzSalaryStatistics.getSalaryInfo());
for (int i = 0; i <jsonArray.size(); i++) {
JSONObject jb = jsonArray.getJSONObject(i);
if(jb != null){
SysStaffDetail detail = sysStaffDetailMapper.selectSysStaffDetailById(jb.getLong("detailId"));
if(detail != null){
detail.setAggregatePersonalIncomeTax(jb.getBigDecimal("aggregatePersonalIncomeTax"));
detail.setSpecialDeduction(jb.getBigDecimal("specialDeduction"));
detail.setTotalWages(jb.getBigDecimal("totalWages"));
sysStaffDetailMapper.updateById(detail);
}else{
detailIds.add(jb.getLong("detailId"));
}
}
}
if(Collections.isNotEmpty(detailIds)){
return AjaxResult.error("部分员工详情未找到: 未找到的员工详情Id为: " + String.format(",", detailIds));
}
rzSalaryStatistics.setStatus("已确认");
rzSalaryStatisticsMapper.updateById(rzSalaryStatistics);
return AjaxResult.success();
}
}

View File

@ -77,6 +77,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="month != null "> and DATE_FORMAT( month, '%Y%m' ) = DATE_FORMAT( #{month} , '%Y%m' )</if>
<if test="deptId != null "> and dept_id = #{deptId}</if>
</where>
order by month desc
</select>
<select id="selectRzSalaryDetailById" parameterType="Long" resultMap="RzSalaryDetailResult">
@ -256,6 +257,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<include refid="selectRzSalaryDetailVo"/>
where del_flag = '0' and DATE_FORMAT( month, '%Y%m' ) = DATE_FORMAT( #{month} , '%Y%m' )
</select>
<delete id="deleteRzSalaryDetailByMonth">
delete from rz_salary_detail where DATE_FORMAT( month, '%Y%m' ) = DATE_FORMAT( #{month} , '%Y%m' )
</delete>
<!-- 根据部门查询员工工资情况 -->
<select id="selectSalaryDetailByDeptId" resultMap="RzSalaryDetailResult">
<include refid="selectRzSalaryDetailVo"/>

View File

@ -27,6 +27,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
del_flag = '0'
<if test="month != null "> and month = #{month}</if>
</where>
order by month desc
</select>
<select id="selectRzSalaryStatisticsById" parameterType="Long" resultMap="RzSalaryStatisticsResult">