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
                    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