package com.ruoyi.staff.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.framework.web.domain.AjaxResult; import com.ruoyi.production.dto.UserAccountDto; import com.ruoyi.production.dto.UserProductionAccountingDto; import com.ruoyi.production.service.SalesLedgerProductionAccountingService; import com.ruoyi.project.system.domain.SysDept; import com.ruoyi.project.system.domain.SysUser; import com.ruoyi.project.system.domain.SysUserDept; import com.ruoyi.project.system.mapper.SysDeptMapper; import com.ruoyi.project.system.mapper.SysUserDeptMapper; import com.ruoyi.project.system.mapper.SysUserMapper; import com.ruoyi.staff.controller.TaxCalculator; import com.ruoyi.staff.dto.StaffOnJobDto; import com.ruoyi.staff.mapper.SchemeInsuranceDetailMapper; import com.ruoyi.staff.mapper.StaffOnJobMapper; import com.ruoyi.staff.pojo.SchemeApplicableStaff; import com.ruoyi.staff.mapper.SchemeApplicableStaffMapper; import com.ruoyi.staff.pojo.SchemeInsuranceDetail; import com.ruoyi.staff.pojo.StaffOnJob; import com.ruoyi.staff.service.IStaffOnJobService; import com.ruoyi.staff.service.SchemeApplicableStaffService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import javax.annotation.Resource; import java.math.BigDecimal; import java.util.*; import java.util.stream.Collectors; /** *

* 社保方案适用人员表 服务实现类 *

* * @author 芯导软件(江苏)有限公司 * @since 2026-03-05 11:50:17 */ @Service public class SchemeApplicableStaffServiceImpl extends ServiceImpl implements SchemeApplicableStaffService { @Autowired private SchemeApplicableStaffMapper schemeApplicableStaffMapper; @Autowired private SchemeInsuranceDetailMapper schemeInsuranceDetailMapper; @Autowired private SysUserDeptMapper sysUserDeptMapper; @Autowired private SysUserMapper sysUserMapper; @Autowired private SysDeptMapper sysDeptMapper; @Autowired private StaffOnJobMapper staffOnJobMapper; @Autowired private SalesLedgerProductionAccountingService salesLedgerProductionAccountingService; @Override public AjaxResult listPage(Page page, SchemeApplicableStaff schemeApplicableStaff) { LambdaQueryWrapper schemeApplicableStaffLambdaQueryWrapper = new LambdaQueryWrapper<>(); if(schemeApplicableStaff != null){ if(StringUtils.isNotEmpty(schemeApplicableStaff.getTitle())){ schemeApplicableStaffLambdaQueryWrapper.like(SchemeApplicableStaff::getTitle, schemeApplicableStaff.getTitle()); } } Page page1 = schemeApplicableStaffMapper.selectPage(page, schemeApplicableStaffLambdaQueryWrapper); List collect = page1.getRecords().stream().map(SchemeApplicableStaff::getId).collect(Collectors.toList()); if(CollectionUtils.isEmpty(collect)){ return AjaxResult.success(page1); } List schemeInsuranceDetails = schemeInsuranceDetailMapper .selectList(new LambdaQueryWrapper() .in(SchemeInsuranceDetail::getSchemeId, collect)); page1.getRecords().forEach(item -> { item.setSchemeInsuranceDetailList(schemeInsuranceDetails .stream() .filter(detail -> detail.getSchemeId().equals(item.getId())) .collect(Collectors.toList())); SysUser sysUser = sysUserMapper.selectUserById(item.getCreateUser().longValue()); item.setCreateUserName(sysUser == null ? "未知" : sysUser.getNickName()); // 获取部门信息 String[] split = item.getDeptIds().split(","); List sysDepts = sysDeptMapper.selectList(new LambdaQueryWrapper() .in(SysDept::getDeptId, Arrays.stream(split).map(Long::valueOf).collect(Collectors.toList()))); if(!CollectionUtils.isEmpty(sysDepts)){ item.setDeptNames(sysDepts.stream().map(SysDept::getDeptName).collect(Collectors.joining(","))); } }); return AjaxResult.success(page1); } public void setSchemeApplicableStaffUserInfo(SchemeApplicableStaff schemeApplicableStaff) { // 通过部门获取人员id String[] split = schemeApplicableStaff.getDeptIds().split(","); List staffOnJobs = staffOnJobMapper.selectList(new LambdaQueryWrapper() .in(StaffOnJob::getSysDeptId, Arrays.stream(split).map(Long::valueOf).collect(Collectors.toList()))); if(CollectionUtils.isEmpty(staffOnJobs)){ throw new IllegalArgumentException("部门下无员工"); } schemeApplicableStaff.setStaffIds(staffOnJobs .stream() .map(StaffOnJob::getId) .filter(Objects::nonNull) // 过滤掉 null 值 .map(String::valueOf) .collect(Collectors.joining( ","))); schemeApplicableStaff.setStaffNames(staffOnJobs.stream().map(StaffOnJob::getStaffName).collect(Collectors.joining(","))); } @Override public AjaxResult add(SchemeApplicableStaff schemeApplicableStaff) { if(schemeApplicableStaff == null){ return AjaxResult.error("参数错误"); } if(CollectionUtils.isEmpty(schemeApplicableStaff.getSchemeInsuranceDetailList())){ return AjaxResult.error("请选择方案明细"); } setSchemeApplicableStaffUserInfo(schemeApplicableStaff); //根据部门设置用户信息 int insert = schemeApplicableStaffMapper.insert(schemeApplicableStaff); schemeApplicableStaff.getSchemeInsuranceDetailList().forEach(item -> { item.setSchemeId(schemeApplicableStaff.getId()); schemeInsuranceDetailMapper.insert(item); }); return AjaxResult.success(insert); } @Override public AjaxResult updateSchemeApplicableStaff(SchemeApplicableStaff schemeApplicableStaff) { if(schemeApplicableStaff == null){ return AjaxResult.error("参数错误"); } setSchemeApplicableStaffUserInfo(schemeApplicableStaff); //根据部门设置用户信息 int update = schemeApplicableStaffMapper.updateById(schemeApplicableStaff); // 先删,重新绑定 schemeInsuranceDetailMapper.delete(new LambdaQueryWrapper() .eq(SchemeInsuranceDetail::getSchemeId, schemeApplicableStaff.getId())); schemeApplicableStaff.getSchemeInsuranceDetailList().forEach(item -> { item.setSchemeId(schemeApplicableStaff.getId()); schemeInsuranceDetailMapper.insert(item); }); return AjaxResult.success(update); } @Override public AjaxResult delete(List ids) { if (CollectionUtils.isEmpty(ids)) { return AjaxResult.error("参数错误"); } int delete = schemeApplicableStaffMapper.deleteBatchIds(ids); schemeInsuranceDetailMapper.delete(new LambdaQueryWrapper() .in(SchemeInsuranceDetail::getSchemeId, ids)); return AjaxResult.success(delete); } /** * 通过员工id计算社保方案 * @param id */ public void calculateByEmployeeId(Integer id,Map map,String date) { // 1. 入参校验 if (id == null) { return; // 或返回空列表,根据业务需求调整 } Long staffId = id.longValue(); // 社保金额 BigDecimal schemeAmount = new BigDecimal("0.00"); // 公积金金额 BigDecimal gjj = new BigDecimal("0.00"); // 基本工资 BigDecimal basicSalary = new BigDecimal("0.00"); map.put("gjj", gjj); // 公积金 map.put("schemeAmount", schemeAmount); // 社保金额 map.put("basicSalary", basicSalary); // 基本工资 // 个税金额 BigDecimal salaryTax = new BigDecimal("0.00"); map.put("salaryTax", salaryTax); // 计件工资 BigDecimal pieceSalary = new BigDecimal("0.00"); map.put("pieceSalary", pieceSalary); // 计时工资 BigDecimal hourlySalary = new BigDecimal("0.00"); map.put("hourlySalary", hourlySalary); // 其他收入 BigDecimal otherIncome = new BigDecimal("0.00"); map.put("otherIncome", otherIncome); // 其他支出 BigDecimal otherDeduct = new BigDecimal("0.00"); map.put("otherDeduct", otherDeduct); // 应发工资 BigDecimal grossSalary = new BigDecimal("0.00"); map.put("grossSalary", grossSalary); // 应扣工资 BigDecimal deductSalary = new BigDecimal("0.00"); map.put("deductSalary", deductSalary); // 实发工资 BigDecimal netSalary = new BigDecimal("0.00"); map.put("netSalary", netSalary); // 调用基本工资 StaffOnJob staffOnJobDto = staffOnJobMapper.selectById(staffId); if(staffOnJobDto == null){ return; } basicSalary = staffOnJobDto.getBasicSalary(); map.put("basicSalary", basicSalary); // 应发工资 map.put("grossSalary", basicSalary); // 个税金额(无社保版) BigDecimal bigDecimal = TaxCalculator.calculateMonthlyTax(basicSalary, schemeAmount, gjj); map.put("salaryTax", bigDecimal); // 计时工资 计件工资 UserProductionAccountingDto userProductionAccountingDto = new UserProductionAccountingDto(); userProductionAccountingDto.setUserId(getUidByStaffId(staffId)); userProductionAccountingDto.setDate(date); UserAccountDto byUserId = salesLedgerProductionAccountingService.getByUserId(userProductionAccountingDto); if(byUserId != null){ map.put("pieceSalary", byUserId.getAccountBalance()); map.put("hourlySalary", byUserId.getAccount()); // 应发 实发增加 grossSalary = grossSalary.add(byUserId.getAccountBalance()).add(byUserId.getAccount()); map.put("grossSalary", grossSalary); netSalary = netSalary.add(byUserId.getAccountBalance()).add(byUserId.getAccount()); map.put("netSalary", netSalary); } // 2. 查询该人员对应的社保方案 List schemeList = schemeApplicableStaffMapper.selectSchemeByStaffId(staffId); if (CollectionUtils.isEmpty(schemeList)) { return; // 无匹配方案,返回空列表 } // 3. 为每个方案关联明细列表 for (SchemeApplicableStaff scheme : schemeList) { List detailList = schemeApplicableStaffMapper.selectDetailBySchemeId(scheme.getId()); // 根据明细列表计算社保缴费金额 if(CollectionUtils.isEmpty(detailList)){ continue; } for (SchemeInsuranceDetail detail : detailList) { if("住房公积金".equals(detail.getInsuranceType())){ gjj = gjj.add(calculateByEmployeeIdType(detail.getInsuranceType(),gjj, staffOnJobDto, detail)); }else{ schemeAmount = schemeAmount.add(calculateByEmployeeIdType(detail.getInsuranceType(),schemeAmount, staffOnJobDto, detail)); } } } map.put("schemeAmount", schemeAmount); map.put("gjj", gjj); // 个税金额(社保版) bigDecimal = TaxCalculator.calculateMonthlyTax(basicSalary, schemeAmount, gjj); map.put("salaryTax", bigDecimal); // 应扣工资 map.put("deductSalary", bigDecimal.add(gjj).add(schemeAmount)); // 实发工资 map.put("netSalary", basicSalary.subtract(bigDecimal).subtract(gjj).subtract(schemeAmount)); } /** * 通过员工Id获取用户id * @param staffId * @return */ public Long getUidByStaffId(Long staffId){ StaffOnJob staffOnJob = staffOnJobMapper.selectById(staffId); if(staffOnJob == null){ return -1L; // 返回不存在Id } SysUser sysUser = sysUserMapper.selectOne(new LambdaQueryWrapper() .eq(SysUser::getUserName, staffOnJob.getStaffNo()) .eq(SysUser::getDelFlag, "0") .last("limit 1")); if(sysUser == null){ return -1L; // 返回不存在Id } return sysUser.getUserId(); } /** * 计算 * @param type * @param bigDecimal * @param staffOnJobDto * @param detail * @return */ public BigDecimal calculateByEmployeeIdType(String type,BigDecimal bigDecimal, StaffOnJob staffOnJobDto,SchemeInsuranceDetail detail) { // 判断是否调用基本工资 if (detail.getUseBasicSalary() == 1) { BigDecimal divide = detail.getPaymentBase().multiply(detail.getPersonalRatio()).divide(new BigDecimal("100"), 2); bigDecimal = bigDecimal.add(divide); }else{ // 调用基本工资 BigDecimal multiply = staffOnJobDto.getBasicSalary().multiply(detail.getPersonalRatio().divide(new BigDecimal("100"), 2)); bigDecimal = bigDecimal.add(multiply); } bigDecimal = bigDecimal.add(detail.getPersonalFixed()); return bigDecimal; } }