| | |
| | | BigDecimal socialSecurityBase = (socialSecurity != null && socialSecurity.getSocialSecurityBase() != null) |
| | | ? socialSecurity.getSocialSecurityBase() : baseSalary; |
| | | |
| | | // 获取公积金基数:员工社保档案 > 员工基本工资 |
| | | BigDecimal housingFundBase = (socialSecurity != null && socialSecurity.getHousingFundBase() != null) |
| | | ? socialSecurity.getHousingFundBase() : baseSalary; |
| | | |
| | | // 从方案中获取缴纳比例(优先使用方案中的比例,否则使用默认比例) |
| | | // 从方案中获取社保缴纳比例(方案未配置时回退默认比例) |
| | | BigDecimal pensionPersonalRatio = (scheme != null && scheme.getPensionPersonalRatio() != null) |
| | | ? scheme.getPensionPersonalRatio() : DEFAULT_PENSION_PERSONAL_RATIO; |
| | | BigDecimal medicalPersonalRatio = (scheme != null && scheme.getMedicalPersonalRatio() != null) |
| | | ? scheme.getMedicalPersonalRatio() : DEFAULT_MEDICAL_PERSONAL_RATIO; |
| | | BigDecimal unemploymentPersonalRatio = (scheme != null && scheme.getUnemploymentPersonalRatio() != null) |
| | | ? scheme.getUnemploymentPersonalRatio() : DEFAULT_UNEMPLOYMENT_PERSONAL_RATIO; |
| | | BigDecimal housingFundPersonalRatio = (scheme != null && scheme.getHousingFundPersonalRatio() != null) |
| | | ? scheme.getHousingFundPersonalRatio() : DEFAULT_HOUSING_FUND_PERSONAL_RATIO; |
| | | |
| | | // 公积金个人比例:只取方案配置值,不再回退默认比例。 |
| | | // 否则「公司没配公积金方案」时会被按默认 12% 扣款(这就是客户反馈的问题)。 |
| | | BigDecimal housingFundPersonalRatio = scheme != null ? scheme.getHousingFundPersonalRatio() : null; |
| | | |
| | | // 社保扣除 = 基数 × (养老个人比例 + 医疗个人比例 + 失业个人比例) |
| | | BigDecimal socialSecurityDeduction = socialSecurityBase |
| | |
| | | .add(socialSecurityBase.multiply(unemploymentPersonalRatio)) |
| | | .setScale(2, RoundingMode.HALF_UP); |
| | | |
| | | // 公积金扣除 = 基数 × 公积金个人比例 |
| | | BigDecimal housingFundDeduction = housingFundBase.multiply(housingFundPersonalRatio).setScale(2, RoundingMode.HALF_UP); |
| | | // 公积金扣除:必须同时满足「方案配置了公积金比例 > 0」且「员工档案配置了公积金基数 > 0」才扣款, |
| | | // 任一不满足都视为公司未缴纳公积金,扣款为 0。 |
| | | BigDecimal housingFundDeduction = BigDecimal.ZERO; |
| | | BigDecimal housingFundBase = socialSecurity != null ? socialSecurity.getHousingFundBase() : null; |
| | | if (housingFundPersonalRatio != null && housingFundPersonalRatio.signum() > 0 |
| | | && housingFundBase != null && housingFundBase.signum() > 0) { |
| | | housingFundDeduction = housingFundBase.multiply(housingFundPersonalRatio) |
| | | .setScale(2, RoundingMode.HALF_UP); |
| | | } |
| | | |
| | | // 计算请假扣款 |
| | | BigDecimal leaveDeduction = calculateLeaveDeduction(employee, period, baseSalary); |
| | |
| | | salaryCalculationMapper.deleteById(id); |
| | | } |
| | | |
| | | /** |
| | | * 批量删除核算记录(全选后一键删除) |
| | | * |
| | | * 说明:按业务要求,批量删除不限制状态,勾选即删。 |
| | | * 不存在的 ID 直接跳过,不报错(避免前端勾选列表与库不一致时整体失败)。 |
| | | */ |
| | | @Override |
| | | public Integer deleteSalaryCalculationList(List<Long> ids) { |
| | | if (CollUtil.isEmpty(ids)) { |
| | | return 0; |
| | | } |
| | | List<Long> existIds = salaryCalculationMapper.selectBatchIds(ids).stream() |
| | | .map(HrmSalaryCalculationDO::getId) |
| | | .collect(Collectors.toList()); |
| | | if (CollUtil.isEmpty(existIds)) { |
| | | return 0; |
| | | } |
| | | salaryCalculationMapper.deleteByIds(existIds); |
| | | return existIds.size(); |
| | | } |
| | | |
| | | } |