package com.ruoyi.staff.controller;
|
|
import java.math.BigDecimal;
|
import java.math.RoundingMode;
|
import java.util.ArrayList;
|
import java.util.List;
|
|
/**
|
* 月度个税计算工具类(仅需月度收入、社保个人、公积金个人三个参数)
|
*/
|
public class TaxCalculator {
|
// 月度免征额(5000元)
|
private static final BigDecimal MONTHLY_EXEMPTION = new BigDecimal("5000");
|
|
// 月度个税税率表:[应纳税所得额上限, 税率, 速算扣除数]
|
private static final List<TaxBracket> MONTHLY_TAX_BRACKETS = new ArrayList<>();
|
|
// 静态初始化税率表(按月度换算,对应全年表/12)
|
static {
|
MONTHLY_TAX_BRACKETS.add(new TaxBracket(new BigDecimal("3000"), new BigDecimal("0.03"), new BigDecimal("0")));
|
MONTHLY_TAX_BRACKETS.add(new TaxBracket(new BigDecimal("12000"), new BigDecimal("0.10"), new BigDecimal("210")));
|
MONTHLY_TAX_BRACKETS.add(new TaxBracket(new BigDecimal("25000"), new BigDecimal("0.20"), new BigDecimal("1410")));
|
MONTHLY_TAX_BRACKETS.add(new TaxBracket(new BigDecimal("35000"), new BigDecimal("0.25"), new BigDecimal("2660")));
|
MONTHLY_TAX_BRACKETS.add(new TaxBracket(new BigDecimal("55000"), new BigDecimal("0.30"), new BigDecimal("4410")));
|
MONTHLY_TAX_BRACKETS.add(new TaxBracket(new BigDecimal("80000"), new BigDecimal("0.35"), new BigDecimal("7160")));
|
MONTHLY_TAX_BRACKETS.add(new TaxBracket(new BigDecimal("999999"), new BigDecimal("0.45"), new BigDecimal("15160")));
|
}
|
|
// 税率表内部类
|
private static class TaxBracket {
|
final BigDecimal max; // 该档位应纳税所得额上限
|
final BigDecimal rate; // 税率
|
final BigDecimal deduction; // 速算扣除数
|
|
TaxBracket(BigDecimal max, BigDecimal rate, BigDecimal deduction) {
|
this.max = max;
|
this.rate = rate;
|
this.deduction = deduction;
|
}
|
}
|
|
/**
|
* 计算单月个人所得税(仅需三个参数)
|
* @param monthlyIncome 月度收入(税前)
|
* @param socialSecurity 社保个人缴纳金额
|
* @param fund 公积金个人缴纳金额
|
* @return 月度应缴个税(保留2位小数)
|
*/
|
public static BigDecimal calculateMonthlyTax(
|
BigDecimal monthlyIncome,
|
BigDecimal socialSecurity,
|
BigDecimal fund
|
) {
|
// 1. 空值/负数处理:参数为null或负数时按0计算
|
monthlyIncome = (monthlyIncome == null || monthlyIncome.compareTo(BigDecimal.ZERO) < 0) ? BigDecimal.ZERO : monthlyIncome;
|
socialSecurity = (socialSecurity == null || socialSecurity.compareTo(BigDecimal.ZERO) < 0) ? BigDecimal.ZERO : socialSecurity;
|
fund = (fund == null || fund.compareTo(BigDecimal.ZERO) < 0) ? BigDecimal.ZERO : fund;
|
|
// 2. 计算月度应纳税所得额 = 月度收入 - 5000免征额 - 社保个人 - 公积金个人
|
BigDecimal taxableIncome = monthlyIncome
|
.subtract(MONTHLY_EXEMPTION)
|
.subtract(socialSecurity)
|
.subtract(fund);
|
|
// 3. 应纳税所得额≤0时,个税为0
|
if (taxableIncome.compareTo(BigDecimal.ZERO) <= 0) {
|
return BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
|
}
|
|
// 4. 匹配税率档位计算个税
|
for (TaxBracket bracket : MONTHLY_TAX_BRACKETS) {
|
if (taxableIncome.compareTo(bracket.max) <= 0) {
|
return taxableIncome.multiply(bracket.rate)
|
.subtract(bracket.deduction)
|
.setScale(2, RoundingMode.HALF_UP);
|
}
|
}
|
|
// 5. 超过最高档位(80000元)的情况
|
TaxBracket lastBracket = MONTHLY_TAX_BRACKETS.get(MONTHLY_TAX_BRACKETS.size() - 1);
|
return taxableIncome.multiply(lastBracket.rate)
|
.subtract(lastBracket.deduction)
|
.setScale(2, RoundingMode.HALF_UP);
|
}
|
|
// 测试示例
|
public static void main(String[] args) {
|
// 示例1:月收入10000,社保个人800,公积金个人500
|
BigDecimal income1 = new BigDecimal("10000");
|
BigDecimal social1 = new BigDecimal("800");
|
BigDecimal fund1 = new BigDecimal("500");
|
BigDecimal tax1 = calculateMonthlyTax(income1, social1, fund1);
|
System.out.println("月收入10000,社保800,公积金500,个税:" + tax1 + " 元"); // 计算结果:111.00 元
|
|
// 示例2:月收入5000,社保500,公积金200
|
BigDecimal income2 = new BigDecimal("5000");
|
BigDecimal social2 = new BigDecimal("500");
|
BigDecimal fund2 = new BigDecimal("200");
|
BigDecimal tax2 = calculateMonthlyTax(income2, social2, fund2);
|
System.out.println("月收入5000,社保500,公积金200,个税:" + tax2 + " 元"); // 计算结果:0.00 元
|
}
|
}
|