目录
1、个人所得税计算器
1.1、名词解释
税前月收入:即税前工资,指交纳个人所得税之前的总工资
应纳税所得额:指按照税法规定确定纳税人在一定期间所获得的所有应税收入减除在该纳税期间依法允许减除的各种支出后的余额
税率:是对征税对象的征收比例或征收额度
速算扣除数:指为解决超额累进税率分级计算税额的复杂技术问题,而预先计算出的一个数据,可以简化计算过程
扣税额:是指实际缴纳的税额
税后工资:是指扣完税后实际到手的工资收入
1.2、计算规则
要实现个人所得税计算器,需要了解如下计算规则:
规则编号 | 名称 | 描述 |
---|---|---|
1 | 计算应纳税所得额 | 应纳税所得额为税前工资减去3500 |
2 | 设置税率,应纳税所得额<=1500 | 税率为0.03,速算扣除数为0 |
3 | 设置税率,应纳税所得额在1500至4500之间 | 税率为0.1,速算扣除数为105 |
4 | 设置税率,应纳税所得额在4500志9000之间 | 税率为0.2,速算扣除数为555 |
5 | 设置税率,应纳税所得额在9000志35000之间 | 税率为0.25,速算扣除数为1005 |
6 | 设置税率,应纳税所得额在35000至55000之间 | 税率为0.3,速算扣除数为2755 |
7 | 设置税率,应纳税所得额在55000至80000之间 | 税率为0.35,速算扣除数为5505 |
8 | 设置税率,应纳税所得额在80000以上 | 税率为0.45,速算扣除数为13505 |
9 | 计算税后工资 | 扣税额=应纳税所得额*税率-速算扣除数 税后工资=税前工资-扣税额 |
例子:
税前工资:10000
应缴纳所得额:10000-3500 = 6500
税率:0.2
速算扣除数:555
扣税额:6500 * 0.2 - 555 = 745
税后工资:10000 - 745 = 9255
1.3、实现步骤
基于Spring Boot整合Drools的方式来实现。
第一步:创建maven工程calculation并配置pom.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starters</artifactId>
<version>2.0.6.RELEASE</version>
</parent>
<groupId>org.example</groupId>
<artifactId>calculation</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<!--drools规则引擎-->
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-core</artifactId>
<version>7.6.0.Final</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-compiler</artifactId>
<version>7.6.0.Final</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-templates</artifactId>
<version>7.6.0.Final</version>
</dependency>
<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-api</artifactId>
<version>7.6.0.Final</version>
</dependency>
<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-spring</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</exclusion>
</exclusions>
<version>7.6.0.Final</version>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
第二步:创建/resources/application.yml文件
server:
port: 8080
spring:
application:
name: calculation
第三步:编写配置类DroolsConfig
package com.itheima.drools.config;
import org.kie.api.KieBase;
import org.kie.api.KieServices;
import org.kie.api.builder.KieBuilder;
import org.kie.api.builder.KieFileSystem;
import org.kie.api.builder.KieRepository;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.kie.internal.io.ResourceFactory;
import org.kie.spring.KModuleBeanFactoryPostProcessor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.io.Resource;
import java.io.IOException;
/**
* 规则引擎配置类
*/
@Configuration
public class DroolsConfig {
//指定规则文件存放的目录
private static final String RULES_PATH = "rules/";
private final KieServices kieServices = KieServices.Factory.get();
@Bean
@ConditionalOnMissingBean
public KieFileSystem kieFileSystem() throws IOException {
System.setProperty("drools.dateformat","yyyy-MM-dd");
KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
ResourcePatternResolver resourcePatternResolver =
new PathMatchingResourcePatternResolver();
Resource[] files =
resourcePatternResolver.getResources("classpath*:" + RULES_PATH + "*.*");
String path = null;
for (Resource file : files) {
path = RULES_PATH + file.getFilename();
kieFileSystem.write(ResourceFactory.newClassPathResource(path, "UTF-8"));
}
return kieFileSystem;
}
@Bean
@ConditionalOnMissingBean
public KieContainer kieContainer() throws IOException {
KieRepository kieRepository = kieServices.getRepository();
kieRepository.addKieModule(kieRepository::getDefaultReleaseId);
KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem());
kieBuilder.buildAll();
return kieServices.newKieContainer(kieRepository.getDefaultReleaseId());
}
@Bean
@ConditionalOnMissingBean
public KieBase kieBase() throws IOException {
return kieContainer().getKieBase();
}
@Bean
@ConditionalOnMissingBean
public KModuleBeanFactoryPostProcessor kiePostProcessor() {
return new KModuleBeanFactoryPostProcessor();
}
}
第四步:编写实体类Calculation
package com.itheima.drools.entity;
public class Calculation
{
private double wage;//税前工资
private double wagemore;//应纳税所得额
private double cess;//税率
private double preminus;//速算扣除数
private double wageminus;//扣税额
private double actualwage;//税后工资
public double getWage()
{
return wage;
}
public void setWage(double wage)
{
this.wage = wage;
}
public double getActualwage()
{
return actualwage;
}
public void setActualwage(double actualwage)
{
this.actualwage = actualwage;
}
public double getWagemore()
{
return wagemore;
}
public void setWagemore(double wagemore)
{
this.wagemore = wagemore;
}
public double getCess()
{
return cess;
}
public void setCess(double cess)
{
this.cess = cess;
}
public double getPreminus()
{
return preminus;
}
public void setPreminus(double preminus)
{
this.preminus = preminus;
}
public double getWageminus()
{
return wageminus;
}
public void setWageminus(double wageminus)
{
this.wageminus = wageminus;
}
@Override
public String toString()
{
return "Calculation{" +
"wage=" + wage +
", actualwage=" + actualwage +
", wagemore=" + wagemore +
", cess=" + cess +
", preminus=" + preminus +
", wageminus=" + wageminus +
'}';
}
}
第五步:在resources/rules下创建规则文件calculation.drl文件
//当前规则文件用于计算个人所得税
package calculation
import com.itheima.drools.entity.Calculation
/**
当前规则文件中的规划主要分为三类
1、计算应纳税所得额
2、设置税率、速算扣除数
3、计算税后工资
*/
//计算应缴税所得额
rule "计算应缴纳所得额"
salience 100
date-effective "2011-09-01"
no-loop true
when
$cal:Calculation(wage > 0)
then
double wagemore = $cal.getWage() - 3500;
$cal.setWagemore(wagemore);
update($cal)
end
//设置税率、速算扣除数
rule "设置税率,应纳税所得额<=1500"
salience 3
no-loop true
when
$cal:Calculation(wagemore <= 1500)
then
$cal.setCess(0.03); //税率
$cal.setPreminus(0); //速算扣除数
update($cal)
end
//设置税率、速算扣除数
rule "设置税率,应纳税所得额在1500至4500之间"
salience 2
no-loop true
activation-group "SETCess_Group"
when
$cal:Calculation(wagemore > 1500 && wagemore <= 4500 )
then
$cal.setCess(0.1); //税率
$cal.setPreminus(105); //速算扣除数
update($cal)
end
rule "个人所得税:设置税率-->>应纳税所得额在4500志9000之间"
salience 2
no-loop true
activation-group "SETCess_Group"
when
$cal : Calculation(wagemore > 4500 && wagemore <= 9000)
then
$cal.setCess(0.2);
$cal.setPreminus(555);
update($cal);
end
rule "个人所得税:设置税率-->>应纳税所得额在9000志35000之间"
salience 2
no-loop true
activation-group "SETCess_Group"
when
$cal : Calculation(wagemore > 9000 && wagemore <= 35000)
then
$cal.setCess(0.25);
$cal.setPreminus(1005);
update($cal);
end
rule "个人所得税:设置税率-->>应纳税所得额在35000至55000之间"
salience 2
no-loop true
activation-group "SETCess_Group"
when
$cal : Calculation(wagemore > 35000 && wagemore <= 55000)
then
$cal.setCess(0.3);
$cal.setPreminus(2755);
update($cal);
end
rule "个人所得税:设置税率-->>应纳税所得额在55000至80000之间"
salience 2
no-loop true
activation-group "SETCess_Group"
when
$cal : Calculation(wagemore > 55000 && wagemore <= 80000)
then
$cal.setCess(0.35);
$cal.setPreminus(5505);
update($cal);
end
rule "个人所得税:设置税率-->>应纳税所得额在80000以上"
salience 2
no-loop true
activation-group "SETCess_Group"
when
$cal : Calculation(wagemore > 80000)
then
$cal.setCess(0.45);
$cal.setPreminus(13505);
update($cal);
end
rule "个人所得税:计算税后工资"
salience 1
when
$cal : Calculation(wage > 0 && wagemore > 0 && wagemore > 0 && cess > 0)
then
$cal.setWageminus($cal.getWagemore()*$cal.getCess()-$cal.getPreminus());
$cal.setActualwage($cal.getWage()-$cal.getWageminus());
System.out.println("-----税前工资:"+$cal.getWage());
System.out.println("-----应纳税所得额:"+$cal.getWagemore());
System.out.println("-----税率:" + $cal.getCess());
System.out.println("-----速算扣除数:" + $cal.getPreminus());
System.out.println("-----扣税额:" + $cal.getWageminus());
System.out.println("-----税后工资:" + $cal.getActualwage());
end
第六步:创建RuleService
package com.itheima.drools.service;
import com.itheima.drools.entity.Calculation;
import org.kie.api.KieBase;
import org.kie.api.runtime.KieSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class RuleService
{
@Autowired
private KieBase kieBase;
//调用Drools规则引擎实现个人所得税计算
public Calculation calculation(Calculation calculation)
{
KieSession session = kieBase.newKieSession(); //获得session
session.insert(calculation); //加入到规则内存
session.fireAllRules(); //启动所有规则
session.dispose(); //销毁session
return calculation; //返回经历过规则的calculation
}
}
第七步:创建RuleController
package com.itheima.drools.controller;
import com.itheima.drools.entity.Calculation;
import com.itheima.drools.service.RuleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/rule")
public class RuleController
{
@Autowired
private RuleService ruleService;
@RequestMapping("/calculate")
public Calculation calculation(double wage)
{
Calculation calculation = new Calculation();
calculation.setWage(wage);
calculation = ruleService.calculate(calculation);
System.out.println(calculation);
return calculation;
}
}
第八步:创建启动类DroolsApplication
package com.itheima.drools;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* 启动类
*/
@SpringBootApplication
public class DroolsApplication
{
public static void main(String[] args)
{
SpringApplication.run(DroolsApplication.class);
}
}
第九步:导入静态资源文件到resources/static目录下
calculation.html
<!DOCTYPE html>
<html>
<head>
<!-- 页面meta -->
<meta charset="utf-8">
<title>个人所得税计算</title>
<meta name="description" content="个人所得税计算">
<meta name="keywords" content="个人所得税计算">
<meta content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no" name="viewport">
</head>
<body class="mainBg">
<div id="app">
<h3 align="center">个人所得税计算器(2011版)</h3>
<table align="center" width="25%" border="0">
<tr>
<td>税前月收入</td>
<td>
<input type="text" v-model="cal.wage">
</td>
</tr>
<tr>
<td colspan="2">
<input type="button" value="计 算" @click="calculate()">
</td>
</tr>
<tr>
<td colspan="2" align="center">
</td>
</tr>
<tr>
<td>应纳税所得额</td>
<td>
<input type="text" v-model="cal.wagemore">
</td>
</tr>
<tr>
<td>税率</td>
<td>
<input type="text" v-model="cal.cess">
</td>
</tr>
<tr>
<td>速算扣除数</td>
<td>
<input type="text" v-model="cal.preminus">
</td>
</tr>
<tr>
<td>扣税额</td>
<td>
<input type="text" v-model="cal.wageminus">
</td>
</tr>
<tr>
<td>税后工资</td>
<td>
<input type="text" v-model="cal.actualwage">
</td>
</tr>
</table>
</div>
</body>
<!-- 引入组件库 -->
<script src="js/vue.js"></script>
<script src="js/axios.js"></script>
<script>
new Vue({
el: '#app',
data:{
cal:{}
},
methods: {
calculate(){
if(this.cal.wage <= 3500){
alert("税前月收入需要大于3500!");
return;
}
axios.get("/rule/calculate?wage=" + this.cal.wage).then((res) => {
console.log(res);
this.cal = res.data;
});
}
}
});
</script>
</html>
@@@@@@@@@@@@@@@@@@@@@@
测试:http://127.0.0.1:8080/calculation.html
大功告成 / 主要内容就在规则文件中