9. Drools实战

全套代码及资料全部完整提供,点此处下载

9.1 个人所得税计算器

本小节我们需要通过Drools规则引擎来根据规则计算个人所得税,最终数据效果如下:

9.1.1 名词解释

税前月收入:即税前工资,指交纳个人所得税之前的总工资

应纳税所得额:指按照税法规定确定纳税人在一定期间所获得的所有应税收入减除在该纳税期间依法允许减除的各种支出后的余额

税率:是对征税对象的征收比例或征收额度

速算扣除数:指为解决超额累进税率分级计算税额的复杂技术问题,而预先计算出的一个数据,可以简化计算过程

扣税额:是指实际缴纳的税额

税后工资:是指扣完税后实际到手的工资收入

9.1.2 计算规则

要实现个人所得税计算器,需要了解2019个税扣缴变化:

应纳税所得额=(月收入-五险一金-起征点-依法确定的其他扣除-专项附加扣除)*适用税率

9.1.2.1 新税制主要有哪些变化?
  1. 扣缴义务人在支付居民个人工资、薪金所得时,需按照“累计预扣法”核算预扣个人所得税。较之前按月的税率表变化成按年计税,适用个人所得税预扣率表
  2. 首次设立了子女教育、继续教育、大病医疗、住房贷款利息或住房租金、赡养老人六项专项附加扣除。(在税前工资扣除相应额度后核算个税)
9.1.2.2 资较高人员本次个税较少,可能到年底扣税增加?

〔例1〕某职员2015年入职,2019年每月应发工资均为10000元,每月减除费用5000元,“三险一金”等专项扣除为1500元,从1月起享受子女教育专项附加扣除1000元,没有减免收入及减免税额等情况,以前三个月为例,应当按照以下方法计算预扣预缴税额:

1月份:(10000-5000-1500-1000)×3% =75元;

2月份:(10000×2-5000×2-1500×2-1000×2)×3%-75 =75元;

3月份:(10000×3-5000×3-1500×3-1000×3)×3%-75-75 =75元;

进一步计算可知,该纳税人全年累计预扣预缴应纳税所得额为30000元,一直适用3%的税率,因此各月应预扣预缴的税款相同

〔例2〕某职员2015年入职,2019年每月应发工资均为30000元,每月减除费用5000元,“三险一金”等专项扣除为4500元,享受子女教育、赡养老人两项专项附加扣除共计2000元,没有减免收入及减免税额等情况,以前三个月为例,应当按照以下方法计算各月应预扣预缴税额:

1月份:(30000–5000-4500-2000)×3% = 555元;

2月份:(30000×2-5000×2-4500×2-2000×2)×10% -2520 -555 =625元;

3月份:(30000×3-5000×3-4500×3-2000×3)×10% -2520 -555-625 =1850元;

按照上述算法,每一个月应纳个税额:

项目 1月 2月 3月 4月 5月 6月 7月 8月 9月 10月 11月 12月
每月税前工资 30000 30000 30000 30000 30000 30000 30000 30000 30000 30000 30000 30000
扣除各项减免额后应对税率 3% 10% 10% 10% 10% 10% 10% 20% 20% 20% 20% 20%
月应预扣预缴个税 555 625 1850 1850 1850 1850 1850 2250 3700 3700 3700 3700

上述计算结果表明,由于2月份累计预扣预缴应纳税所得额为37000元,已适用10%的税率,因此2月份和3月份应预扣预缴有所增高。8月份已适用于20%的税率。根据上述计算结果表明,虽每月工资薪金额和相关扣除额相同,年度内越往后,应纳税所得额越大适用税率越高,则预扣预缴税款可能会越大,会出现类似“12月取得工资10000元预扣预缴的个税税款,比1月份取得工资薪金30000元预扣预缴的个税税款多的”现象。

〔例3〕某职员2022年每月应发工资均为15000元,每月减除费用5000元,养老保险个人缴纳8%,为15000×8%=1200元,失业保险个人缴纳0.5%,为15000×0.5%=75元,医疗保险个人缴纳2%+3元,为15000×2%+3=303元,住房公积金个人缴纳比例12%,为15000×12%=1800元,享受住房租金专项附加扣除1500元,没有减免收入及减免税额等情况,以前三个月的计算为例,应当按照以下方法计算各月应预扣预缴税额:

应纳税所得额=月收入-五险一金-起征点-依法确定的其他扣除-专项附加扣除

1月应纳税所得额=15000–5000-1200-75-303-1800-1500=5122元

1月份:1月应纳税所得额 × 3% = 153.66元;

2月份:1月应纳税所得额 × 2 × 3% -153.66 =153.66元;

3月份:1月应纳税所得额 × 3 × 3% -153.66 - 153.66=153.66元;

按照上述算法,每一个月应纳个税额:

项目 1月 2月 3月 4月 5月 6月 7月 8月 9月 10月 11月 12月
每月税前工资 15000 15000 15000 15000 15000 15000 15000 15000 15000 15000 15000 15000
扣除各项减免额后应对税率 3% 3% 3% 3% 3% 3% 3% 10% 10% 10% 10% 10%
月应预扣预缴个税 153.66 153.66 153.66 153.66 153.66 153.66 153.66 501.98 512.2 512.2 512.2 512.2

上述计算结果表明,由于8月份累计预扣预缴应纳税所得额为40976元,已适用10%的税率,因此8月份应预扣预缴有所增高。

9.1.2.3 关于年度汇算清缴

一般来讲,有以下情形之一的,您可以选择在次年3月1日至6月30日内,自行向汇缴地主管税务机关办理汇算清缴申报时进行专项附加扣除,税款多退少补;(1)不愿意通过单位办理扣除,未将相关专项附加扣除信息报送给任职受雇单位的;

(2)在同一纳税年度涉及有两处工资薪金所得或涉及劳务报酬所得的;

(3)有大病医疗支出项目的;

(4)纳税年度内未享受或未足额享受专项附加扣除等情形。  

9.1.2.4 个人所得税预扣率表(居民个人工资、薪金所得预扣预缴适用)
级数 全年累计预扣预缴应纳税所得额 税率(%) 速算扣除数
1 不超过36,000元的部分 3 0
2 超过36,000元至144,000元的部分 10 2520
3 超过144,000元至300,000元的部分 20 16920
4 超过300,000元至420,000元的部分 25 31920
5 超过420,000元至660,000元的部分 30 52920
6 超过660,000元至960,000元的部分 35 85920
7 超过960,000元的部分 45 181920
9.1.2.5 五险一金缴费比例

五险一金缴费比例:养老保险单位21%,个人8%;医疗保险单位9%,个人2%+3元;失业保险单位0.5%,个人0.5%;工伤保险和生育保险由单位缴纳,劳动者不用缴;住房公积金根据企业的实际情况,选择住房公积金缴费比例,下限为5%,最高不超12%。

9.1.3 实现步骤

本实战案例我们基于Spring Boot整合Drools的方式来实现。

目录结构

9.1.3.1 创建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>cn.itcast</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>
9.1.3.2 创建/resources/application.yml文件
server:
port: 8080
spring:
application:
name: calculation
9.1.3.3 编写配置类DroolsConfig
package com.guohaowei.drools.config;
import cn.hutool.core.date.DatePattern;
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.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.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver; 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", DatePattern.NORM_DATE_PATTERN);
KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
ResourcePatternResolver resourcePatternResolver =
new PathMatchingResourcePatternResolver();
Resource[] files =
resourcePatternResolver.getResources("classpath*:" + RULES_PATH + "*.*");
String path;
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();
}
}
9.1.3.4 编写各种实体类
  • 编写实体类CalculationDto
package com.guohaowei.drools.domain.dto;

import com.guohaowei.drools.domain.vo.CalculationVo;
import lombok.Data; import java.math.BigDecimal;
import java.util.List; /**
* @author guohaowei
*/
@Data
public class CalculationDto {
/**
* 12个月的工资缴税额等信息
*/
private List<CalculationVo> calculationVoList;
//--------------------------------重复字段用于计算start--------------------------------------------------------
/**
* 税前工资
*/
private BigDecimal wageBeforeTax;
/**
* 预扣预缴应纳税所得额
*/
private BigDecimal taxableIncome;
/**
* 累计预扣预缴应纳税所得额
*/
private BigDecimal taxableIncomeCount;
/**
* 月税后工资
*/
private BigDecimal wageDeductedTax;
//--------------------------------重复字段用于计算end----------------------------------------------------------
/**
* 个人所得税起征点
*/
private BigDecimal threshold;
/**
* 养老保险个人缴纳比例,默认8%
*/
private BigDecimal oldAgeInsuranceRatio;
/**
* 失业保险个人缴纳比例,默认0.5%
*/
private BigDecimal unemploymentInsuranceRatio;
/**
* 医疗保险个人缴纳比例,默认2% + 3元
*/
private BigDecimal medicalInsuranceRatio = BigDecimal.valueOf(0.02);
/**
* 医疗保险个人缴纳比例,默认2% + 3元
*/
private BigDecimal medicalInsuranceAdd = BigDecimal.valueOf(3);
/**
* 住房公积金个人缴纳比例,默认12%
*/
private BigDecimal housingFundRatio;
/**
* 住房租金专项附加扣除,默认1500元
* 其他专项附加扣除同理,此处省略
*/
private BigDecimal specialAdditionalDeductionRent; }
  • 编写实体类CalculationVo
package com.guohaowei.drools.domain.vo;

import lombok.Builder;
import lombok.Data; import java.math.BigDecimal; /**
* @author guohaowei
*/
@Data
@Builder
public class CalculationVo {
/**
* 月税前工资
*/
private BigDecimal wageBeforeTax;
/**
* 月预扣预缴应纳税所得额
*/
private BigDecimal taxableIncome;
/**
* 月税率
*/
private BigDecimal taxRate;
/**
* 月速算扣除数
*/
private BigDecimal quickDeduction;
/**
* 月扣税额
*/
private BigDecimal taxRebate;
/**
* 月税后工资
*/
private BigDecimal wageDeductedTax;
/**
* 月份
*/
private Integer month;
}
  • 编写枚举类WithholdingTaxRateEnum
package com.guohaowei.drools.enums;

import lombok.AllArgsConstructor;
import lombok.Getter; import java.math.BigDecimal; /**
* @Author: 郭浩伟 qq:912161367
* @Date: 2022/11/17 0017 7:18
* @Description: 个人所得税预扣率表(居民个人工资、薪金所得预扣预缴适用)
*/
@AllArgsConstructor
@Getter
public enum WithholdingTaxRateEnum {
/**
* 级数
*/
one(36_000, "0.03", 0),
two(144_000, "0.10", 2520),
three(300_000, "0.20", 16920),
four(420_000, "0.25", 31920),
five(660_000, "0.30", 52920),
six(960_000, "0.35", 85920),
seven(960_000, "0.45", 181920),
; /**
* 全年累计预扣预缴应纳税所得额
*/
private Integer taxableIncome;
/**
* 税率,如0.03
*/
private String taxRate;
/**
* 速算扣除数
*/
private Integer quickDeduction; /**
* 根据【应纳税所得额】得到含对应的【税率】和【速算扣除数】的枚举值
*
* @param actualTaxableIncome
* @return
*/
public static WithholdingTaxRateEnum getInfoByIncome(BigDecimal actualTaxableIncome) {
if(null == actualTaxableIncome){
return null;
}
for (WithholdingTaxRateEnum value : WithholdingTaxRateEnum.values()) {
if(actualTaxableIncome.compareTo(BigDecimal.valueOf(value.getTaxableIncome())) <= 0){
return value;
}
}
return seven;
}
}
  • 编写实体类CalculationReq
package com.guohaowei.drools.domain.req;

import lombok.Data;

import java.math.BigDecimal;

/**
* @Author: 郭浩伟 qq:912161367
* @Date: 2022/11/16 0016 23:31
* @Description:
*/
@Data
public class CalculationReq {
/**
* 税前工资
*/
private BigDecimal wageBeforeTax;
/**
* 个人所得税起征点,默认5000元
*/
private BigDecimal threshold = BigDecimal.valueOf(5000);
/**
* 养老保险个人缴纳比例,默认8%
*/
private BigDecimal oldAgeInsuranceRatio = BigDecimal.valueOf(0.08);
/**
* 失业保险个人缴纳比例,默认0.5%
*/
private BigDecimal unemploymentInsuranceRatio = BigDecimal.valueOf(0.005);
/**
* 医疗保险个人缴纳比例,默认2% + 3元
*/
private BigDecimal medicalInsuranceRatio = BigDecimal.valueOf(0.02);
/**
* 医疗保险个人缴纳比例,默认2% + 3元
*/
private BigDecimal medicalInsuranceAdd = BigDecimal.valueOf(3);
/**
* 住房公积金个人缴纳比例,默认12%
*/
private BigDecimal housingFundRatio = BigDecimal.valueOf(0.12);
/**
* 住房租金专项附加扣除,默认1500元
* 其他专项附加扣除同理,此处省略
*/
private BigDecimal specialAdditionalDeductionRent = BigDecimal.valueOf(1500); }
9.1.3.5 在resources/rules下创建规则文件calculation.drl文件
//当前规则文件用于计算个人所得税
package calculation
import java.math.BigDecimal
import com.guohaowei.drools.domain.dto.CalculationDto
import com.guohaowei.drools.enums.WithholdingTaxRateEnum
import java.util.ArrayList
import com.guohaowei.drools.domain.vo.CalculationVo
import java.util.List
global com.guohaowei.drools.domain.dto.CalculationDto calculationGlobalDto
/**
当前规则文件中的规则主要分为三类
1、计算应纳税所得额有1个规则
2、设置税率、速算扣除数有7个规则
3、计算税后工资有1个规则
**/ //计算应纳税所得额
rule "计算应纳税所得额-减去个税起征点"
salience 100
date-effective "2019-01-01"
no-loop true
when
then
//税前工资
BigDecimal wageBeforeTax = calculationGlobalDto.getWageBeforeTax();
BigDecimal taxableIncome = wageBeforeTax.subtract(calculationGlobalDto.getThreshold()); calculationGlobalDto.setWageBeforeTax(wageBeforeTax);
calculationGlobalDto.setWageDeductedTax(wageBeforeTax);
calculationGlobalDto.setTaxableIncome(BigDecimal.ZERO);
if(taxableIncome.compareTo(BigDecimal.valueOf(0)) > 0){
calculationGlobalDto.setTaxableIncome(taxableIncome);
} end rule "计算应纳税所得额-减去养老保险个人缴纳金额"
salience 99
date-effective "2019-01-01"
no-loop true
when
then
//养老保险个人缴纳额
BigDecimal oldAgeInsurance = calculationGlobalDto.getWageBeforeTax().multiply(calculationGlobalDto.getOldAgeInsuranceRatio());
//预扣预缴应纳税所得额
BigDecimal taxableIncome = calculationGlobalDto.getTaxableIncome();
//应纳税所得额如果小于0即不需要缴税也就不需要计算了
if(taxableIncome.compareTo(BigDecimal.valueOf(0)) > 0){
taxableIncome = taxableIncome.subtract(oldAgeInsurance);
calculationGlobalDto.setTaxableIncome(taxableIncome);
}
//税后工资
calculationGlobalDto.setWageDeductedTax(calculationGlobalDto.getWageBeforeTax().subtract(oldAgeInsurance));
end rule "计算应纳税所得额-减去失业保险个人缴纳金额"
salience 98
date-effective "2019-01-01"
no-loop true
when
then
//失业保险个人缴纳额
BigDecimal unemploymentInsurance = calculationGlobalDto.getWageBeforeTax().multiply(calculationGlobalDto.getUnemploymentInsuranceRatio());
//应纳税所得额如果小于0即不需要缴税也就不需要计算了
if(calculationGlobalDto.getTaxableIncome().compareTo(BigDecimal.valueOf(0)) > 0){
BigDecimal taxableIncome = calculationGlobalDto.getTaxableIncome().subtract(unemploymentInsurance);
calculationGlobalDto.setTaxableIncome(taxableIncome);
}
//税后工资
calculationGlobalDto.setWageDeductedTax(calculationGlobalDto.getWageDeductedTax().subtract(unemploymentInsurance));
end rule "计算应纳税所得额-减去医疗保险个人缴纳金额"
salience 97
date-effective "2019-01-01"
no-loop true
when
then
//医疗保险个人缴纳额
BigDecimal medicalInsurance = calculationGlobalDto.getWageBeforeTax().multiply(calculationGlobalDto.getMedicalInsuranceRatio()).add(calculationGlobalDto.getMedicalInsuranceAdd());
//应纳税所得额如果小于0即不需要缴税也就不需要计算了
if(calculationGlobalDto.getTaxableIncome().compareTo(BigDecimal.valueOf(0)) > 0){
BigDecimal taxableIncome = calculationGlobalDto.getTaxableIncome().subtract(medicalInsurance);
calculationGlobalDto.setTaxableIncome(taxableIncome);
}
//税后工资
calculationGlobalDto.setWageDeductedTax(calculationGlobalDto.getWageDeductedTax().subtract(medicalInsurance));
end rule "计算应纳税所得额-减去住房公积金个人缴纳金额"
salience 96
date-effective "2019-01-01"
no-loop true
when
then
//住房公积金个人缴纳额
BigDecimal housingFund = calculationGlobalDto.getWageBeforeTax().multiply(calculationGlobalDto.getHousingFundRatio());
//应纳税所得额如果小于0即不需要缴税也就不需要计算了
if(calculationGlobalDto.getTaxableIncome().compareTo(BigDecimal.valueOf(0)) > 0){
BigDecimal taxableIncome = calculationGlobalDto.getTaxableIncome().subtract(housingFund);
calculationGlobalDto.setTaxableIncome(taxableIncome);
}
//税后工资
calculationGlobalDto.setWageDeductedTax(calculationGlobalDto.getWageDeductedTax().subtract(housingFund));
end rule "计算应纳税所得额-减去住房租金专项附加扣除金额"
salience 95
date-effective "2019-01-01"
no-loop true
when
then
//应纳税所得额如果小于0即不需要缴税也就不需要计算了
if(calculationGlobalDto.getTaxableIncome().compareTo(BigDecimal.valueOf(0)) > 0){
BigDecimal taxableIncome = calculationGlobalDto.getTaxableIncome().subtract(calculationGlobalDto.getSpecialAdditionalDeductionRent());
calculationGlobalDto.setTaxableIncome(taxableIncome);
}
end rule "计算出最终的统计结果"
salience 94
date-effective "2019-01-01"
no-loop true
when
then
List<CalculationVo> calculationVoList = new ArrayList<>();
BigDecimal taxRebateCount = BigDecimal.ZERO;
//当月扣税额=应纳税所得额x月份数x税率-速算扣除数-累计扣税额
for(int i = 1; i <= 12 ; i++) {
//累计应纳税所得额
BigDecimal taxableIncomeCount = calculationGlobalDto.getTaxableIncome().multiply(BigDecimal.valueOf(i));
WithholdingTaxRateEnum withholdingTaxRateEnum = WithholdingTaxRateEnum.getInfoByIncome(taxableIncomeCount);
//月税率
BigDecimal taxRate = new BigDecimal(withholdingTaxRateEnum.getTaxRate());
//月速算扣除数
BigDecimal quickDeduction = BigDecimal.valueOf(withholdingTaxRateEnum.getQuickDeduction());
//月扣税额
BigDecimal taxRebate =taxableIncomeCount.multiply(taxRate).subtract(quickDeduction).subtract(taxRebateCount);
//累计扣税额
taxRebateCount = taxRebateCount.add(taxRebate);
//组装vo
CalculationVo calculationVo = CalculationVo.builder().wageBeforeTax(calculationGlobalDto.getWageBeforeTax()).taxableIncome(calculationGlobalDto.getTaxableIncome()).
taxRate(taxRate).quickDeduction(quickDeduction).taxRebate(taxRebate).wageDeductedTax(calculationGlobalDto.getWageDeductedTax().subtract(taxRebate)).month(i).build();
calculationVoList.add(calculationVo);
}
calculationGlobalDto.setCalculationVoList(calculationVoList);
end
9.1.3.6 创建RuleServiceImpl
package com.guohaowei.drools.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.guohaowei.drools.domain.dto.CalculationDto;
import com.guohaowei.drools.domain.req.CalculationReq;
import com.guohaowei.drools.domain.vo.CalculationVo;
import com.guohaowei.drools.service.RuleService;
import org.kie.api.KieBase;
import org.kie.api.runtime.KieSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import java.util.List;
/**
* @Author: 郭浩伟 qq:912161367
* @Date: 2022/11/18 0018 19:41
* @Description:
*/
@Service
public class RuleServiceImpl implements RuleService {
@Autowired
private KieBase kieBase; /**
* 调用Drools规则引擎实现个人所得税计算
*
* @param req
* @return
*/
@Override
public List<CalculationVo> calculate(CalculationReq req) {
KieSession session = kieBase.newKieSession();
CalculationDto calculationDto = BeanUtil.copyProperties(req, CalculationDto.class);
//初始化税后工资=税前工资
calculationDto.setWageDeductedTax(calculationDto.getWageBeforeTax());
//设置全局变量,名称和类型必须和规则文件中定义的全局变量名称对应
session.setGlobal("calculationGlobalDto",calculationDto);
session.fireAllRules();
session.dispose();
return calculationDto.getCalculationVoList();
}
}
9.1.3.7 创建RuleController
package com.guohaowei.drools.controller;

import com.guohaowei.drools.domain.req.CalculationReq;
import com.guohaowei.drools.domain.vo.CalculationVo;
import com.guohaowei.drools.service.impl.RuleServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import java.util.List; @RestController
@RequestMapping("/rule")
public class RuleController {
@Autowired
private RuleServiceImpl ruleService; @RequestMapping("/calculate")
public List<CalculationVo> calculate(@RequestBody CalculationReq req){
return ruleService.calculate(req);
}
}
9.1.3.8 创建启动类DroolsApplication
package com.guohaowei.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);
}
}

全套代码及资料全部完整提供,点此处下载

第2-4-8章 规则引擎Drools实战(1)-个人所得税计算器的更多相关文章

  1. 开源规则引擎 drools

    java语言开发的开源业务规则引擎 DROOLS(JBOSS RULES )具有一个易于访问企业策略.易于调整以及易于管理的开源业务规则引擎,符合业内标准,速度快.效率高.业务分析师或审核人员可以利用 ...

  2. 规则引擎drools封装

    一.前言 网上规则引擎drools介绍很多,并且有很多细致的说明,作者也不敢托大说自己的好用,但作者经过2个项目使用过规则引擎后,自己对规则引擎的理解并进行封装,对规则内容及如何使用,有自己的一番实践 ...

  3. 开源规则引擎 Drools 学习笔记 之 -- 1 cannot be cast to org.drools.compiler.kie.builder.impl.InternalKieModule

    直接进入正题 我们在使用开源规则引擎 Drools 的时候, 启动的时候可能会抛出如下异常: Caused by: java.lang.ClassCastException: cn.com.cheng ...

  4. [Drools]JAVA规则引擎 -- Drools 2

    上一篇文章 http://blog.csdn.net/quzishen/archive/2011/01/25/6163012.aspx 描述了一些常用的drools的语法标签和一个模拟实例即发送积分的 ...

  5. 使用规则引擎Drools计算圆周率PI

    实际上是使用规则引擎能够更新工作内存区重新匹配规则实现迭代功能. 使用了策略模式实现. <规则引擎与RETE算法介绍> PPT : http://files.cnblogs.com/lov ...

  6. JAVA规则引擎 -- Drools

    Drools是一个基于java的规则引擎,开源的,可以将复杂多变的规则从硬编码中解放出来,以规则脚本的形式存放在文件中,使得规则的变更不需要修正代码重启机器就可以立即在线上环境生效. 本文所使用的de ...

  7. [Drools]JAVA规则引擎 -- Drools

    Drools是一个基于Java的规则引擎,开源的,可以将复杂多变的规则从硬编码中解放出来,以规则脚本的形式存放在文件中,使得规则的变更不需要修正代码重启机器就可以立即在线上环境生效. 本文所使用的de ...

  8. 小明历险记:规则引擎drools教程一

    小明是一家互联网公司的软件工程师,他们公司为了吸引新用户经常会搞活动,小明常常为了做活动加班加点很烦躁,这不今天呀又来了一个活动需求,我们大家一起帮他看看. 小明的烦恼 活动规则是根据用户购买订单的金 ...

  9. 规则引擎 drools

    https://www.jianshu.com/p/725811f420db 深入了解Drools 简单介绍 笔者正在做风控系统,风控系统里边存在非常多的规则(比如:age < 16 || ag ...

  10. 规则引擎drools的简单使用

    规则引擎适用于有复杂多变的规则,如商品满减.积分赠送.考勤规则等 一.引入maven依赖 <dependency> <groupId>org.drools</groupI ...

随机推荐

  1. Openstack Neutron : 安全

    目录 - iptable:起源 - tables - chains - rules - 方向 - Security group 安全组: - Firewall 防火墙: - 更高的安全 - 无处安放的 ...

  2. 发布日志- kratos v2.1.4 发布!

    v2.1.4 release https://github.com/go-kratos/kratos/releases/tag/v2.1.4 New Features feat(registry/co ...

  3. fastdfs-zyc管理FastDFS的web界面

    俩压缩包根据大小重命名以下,按图片所示 把1_fastdfs-zyc.7z重命名为fastdfs-zyc.7z.001 把2_fastdfs-zyc.7z重命名为fastdfs-zyc.7z.002 ...

  4. Prometheus监控Nginx

    转载自:https://www.cnblogs.com/you-men/p/13173245.html CentOS7.3 prometheus-2.2.1.linux-amd64.tar.gz ng ...

  5. Nginx配置中一个不起眼字符"/"的巨大作用

    文章转载自:https://mp.weixin.qq.com/s/QwsbuNIqLpxi_FhQ5pSV3w Nginx作为一个轻量级的,高性能的web服务软件,因其占有内存少,并发能力强的特点,而 ...

  6. 通过js实现随机生成图片

    这次给大家分享一个通过js向HTML添加便签,实现随机代码生成的案例,代码已经放在下方,这里我在下面准备了50张图片,但是没有放在博文中,如果读者想要练习,可以自己下载一些图片,建议下载的多一些. & ...

  7. 使用 HammerDB 对 Citus 和 Postgres 进行 Benchmark,每分钟200万新订单处理测试(官方博客)

    在为 Postgres 运行性能基准测试时,主要建议是:"自动化!" 如果您正在测量数据库性能,您可能不得不一遍又一遍地运行相同的基准测试. 要么是因为你想要一个稍微不同的配置,要 ...

  8. Python实验报告(第四周

    一.实验目的和要求 学会应用列表.元组.字典等序列: 二.实验环境 软件版本:Python 3.10 64_bit 三.实验过程 1.实例1:输出每日一贴 (1)在IDLE中创建一个名称为tips.p ...

  9. oracle中的行转列,列转行

    行转列:源表: 方法1:case when select y,sum(case when q=1 then amt end) q1,sum(case when q=2 then amt end) q2 ...

  10. RNN自学理解(一)

    RNN对具有序列特性的数据非常有效,它能挖掘数据中的时序信息以及语义信息,利用了RNN的这种能力,使深度学习模型在解决语音识别.语言模型.机器翻译以及时序分析等NLP领域的问题时有所突破. 参考文献1 ...