Drools实战-个人所得税计算器

目录

1、个人所得税计算器

1.1、名词解释

1.2、计算规则

1.3、实现步骤


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

大功告成 / 主要内容就在规则文件中

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值