Drools实战-个人所得税计算器
1、个人所得税计算器
1.1、名词解释
税前月收入:即税前工资,指交纳个人所得税之前的总工资
应纳税所得额:指按照税法规定确定纳税人在一定期间所获得的所有应税收入减除在该纳税期间依法允许减除的各种支出后的余额
税率:是对征税对象的征收比例或征收额度
速算扣除数:指为解决超额累进税率分级计算税额的复杂技术问题,而预先计算出的一个数据,可以简化计算过程
扣税额:是指实际缴纳的税额
税后工资:是指扣完税后实际到手的工资收入
1.2、计算规则
要实现个人所得税计算器,需要了解如下计算规则:
例子:
税前工资: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"?>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"> 4.0.0 org.springframework.boot spring-boot-starters 2.0.6.RELEASE org.example calculation 1.0-SNAPSHOT org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-aop org.springframework.boot spring-boot-starter-test commons-lang commons-lang 2.6 org.drools drools-core 7.6.0.Final org.drools drools-compiler 7.6.0.Final org.drools drools-templates 7.6.0.Final org.kie kie-api 7.6.0.Final org.kie kie-spring org.springframework spring-tx org.springframework spring-beans org.springframework spring-core org.springframework spring-context 7.6.0.Final ${project.artifactId} src/main/java **/*.xml false src/main/resources **/*.* false org.apache.maven.plugins maven-compiler-plugin 2.3.2 1.8
第二步:创建/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
个人所得税计算 class="mainBg">个人所得税计算器(2011版)
税前月收入 应纳税所得额 税率 速算扣除数 扣税额 税后工资
第十步:测试:http://127.0.0.1:8080/calculation.html