自定义补贴规则
如何使用自定义补贴规则
- boss里开启补贴自动计算
- 点击【设置】-【角色与权限】,为需要设置补贴规则的管理员增加“补贴规则”权限‘补贴规则’
- 具有“补贴规则”权限的管理员,点击【设置】-【补贴规则】,可以新建并上传补贴规则代码(由于每家公司的补贴规则不同,规则代码通常需要联系每刻进行定制化开发,需要收费)
- 点击【设置】-【单据与流程】,在具体需要用到补贴自动计算的报销单中,选择补贴规则使用。
- 效果:员工填写对应的单据时,可以自动计算补贴(点击提单时如果未计算过会提示是否计算)
如何开发自定义补贴规则
对象信息
以下对象都在包com.maycur.sdk.rule.domain里
本地开发maven引用如下,具体版本见 http://s1.maycur.cc:5000/content/groups/public/com/maycur/ng-rule-sdk/
<dependency>
<groupId>com.maycur</groupId>
<artifactId>ng-rule-sdk</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
DateTime指org.joda.time.DateTime
Reimburse(单据)
参数名称 |
类型 |
描述 |
entCode |
String |
企业编码 |
formTypeBizCode |
String |
单据小类业务编码 |
|
subsidiaryBizCode |
String |
业务实体业务编码 |
legalEntityBizCode |
String |
公司抬头业务编码 |
reimEmployee |
Employee |
报销人信息 |
expenses |
List<Expense> 数组 |
费用信息 |
travelRoutes |
List<TravelRoute> 数组 |
行程信息 |
customFormValues |
List<CustomFormValue> 数组 |
自定义表单信息 |
collectionCcy |
String |
收款币种 |
baseCcy |
String |
本币 |
submittedAt |
DateTime |
最近提单时间 |
firstSubmittedAt |
DateTime |
第一次提单时间 |
travelPartnerInfo |
TravelPartnerInfo |
单据级参与人信息 |
ruleScheduleValue |
RuleScheduleValue |
节假日信息列表 |
|
Employee(员工)
参数名称 |
类型 |
描述 |
userCode |
String |
员工编码 |
name |
String |
员工姓名 |
|
employeeId |
String |
员工工号 |
residences |
List<Residence> 数组 |
常驻地 |
customFormValues |
List<CustomFormValue> 数组 |
自定义表单信息 |
classPositionBizCode |
String |
职级业务编码 |
hireDate |
DateTime |
入职日期 |
gender |
GenderEnum枚举 |
性别,值如下 MAN:男 WOMAN:女 |
rtRouteList |
List<RTRoute> |
部门信息 |
RTRoute(部门信息)
参数名称 |
类型 |
描述 |
departmentBizCode |
String |
部门业务编码 |
supervisorEmployeeId |
String |
直接上级工号 |
|
positionBizCode |
String |
职位业务编码 |
Residence(常驻地)
参数名称 |
类型 |
描述 |
placeFullCode |
String |
每刻地址编码 |
includeChildPlace |
String |
是否包含下级 |
参数名称 |
类型 |
描述 |
code |
String |
字段内码 |
name |
String |
字段名称(自定义组件名称) |
identifier |
String |
字段占位符(字段编码) |
|
bizCode |
String |
业务编码(自定义组件编码) |
type |
String |
字段类型,值如下 SingleTextInput //单行文本 MultiTextInput //多行文本 NumberInput //数字 OptionInput //选项 ... |
|
value |
String |
字段内容(如类型为单行文本/多行文本/数字时,则为填写的值;如类型为选项时,则为选择的选项的编码) |
Expense(费用)
参数名称 |
类型 |
描述 |
code |
String |
费用行编码(唯一编码) |
typeBizCode |
String |
费用类型业务编码 |
amount |
BigDecimal |
费用收款币种金额 |
collectionCcy |
String |
收款币种 |
|
baseCcy |
String |
本币 |
consumeLocation |
String |
消费城市(每刻地址编码) |
departure |
String |
出发地(每刻地址编码) |
|
destination |
String |
目的地(每刻地址编码) |
consumeDate |
DateTime |
消费时间 |
startDate |
DateTime |
开始时间 |
|
endDate |
DateTime |
结束时间 |
customFormValues |
List<CustomFormValue> 数组 |
自定义表单信息 |
|
allowanceStandardInfos |
List<AllowanceStandardInfo> 数组 |
补贴信息 |
containBreakfast |
int |
1-含早餐 2-不含 3-未知(默认值 |
|
expenseAllocations |
List<ExpenseAllocation> 数组 |
费用分摊信息 |
detailExecResultList |
List<DistDetailExecResult> 数组 |
对应的费控信息 |
ExpenseStandResult(按条件汇总后的费控标准信息)
参数名称 |
类型 |
描述 |
key |
String |
部门业务编码 |
finalStdActualAmt |
MonetaryAmount |
经过调整后的费用标准金额 |
|
finalStdOriginAmt |
MonetaryAmount |
原始的费用标准金额 |
DistDetailExecResult(费控标准明细信息)
参数名称 |
类型 |
描述 |
expenseCode |
String |
费用内码 |
expenseTypeCode |
MonetaryAmount |
费用类型编码 |
|
dateType |
MonetaryAmount |
日期类型,枚举值:TIME,YEAR,QUARTER,MONTH,DAY |
effectiveDate |
Integer |
生效日期yyyyMMdd |
|
amountUsage |
UserAmtVaryUsage |
金额 |
UserAmtVaryUsage(费控金额信息)
参数名称 |
类型 |
描述 |
finalUserCode |
String |
人员code |
finalStdActualAmt |
MonetaryAmount |
匹配到的费控格子标准金额 |
|
execAmt |
MonetaryAmount |
本次执行的金额 |
MonetaryAmount
参数名称 |
类型 |
描述 |
amount |
BigDecimal |
金额 |
currency |
String |
币种 |
ExpenseAllocation(费用分摊)
参数名称 |
类型 |
描述 |
code |
String |
分摊行唯一标识 |
expenseCode |
String |
费用行code(对应费用行code参数) |
|
coverUserCode |
String |
承担人编码 |
coverUserName |
String |
承担人用户名 |
coverDepartmentCode |
String |
承担部门编码 |
|
coverDepartmentName |
String |
承担部门名称 |
legalEntityCode |
String |
公司抬头编码 |
legalEntityName |
String |
公司抬头名称 |
|
allocatedAmount |
BigDecimal |
分摊金额 |
allocatedRatio |
BigDecimal |
分摊比例 |
approvedBaseAmount |
BigDecimal |
分摊本币金额 |
|
approvedAmount |
BigDecimal |
审批后金额 |
consumeCcy |
String |
消费币种 |
|
baseCcy |
String |
本币 |
collectionCcy |
String |
收款币种 |
|
customFormValues |
List<CustomFormValue>数组 |
表单自定义字段 |
AllowanceStandardInfo(补贴信息)
参数名称 |
类型 |
描述 |
sourceCode |
String |
资源编码(如费用上的补贴信息为费用编码,行程上为行程编码) |
hasDateDimension |
boolean |
是否有日期维度 |
ruleName |
String |
补贴标准名称 |
ruleBizCode |
String |
补贴标准业务编码 |
userCode |
String |
标准所属于的人员内码 |
standardMap |
Map |
补贴标准map,当没有日期维度时,key为补贴标准业务编码,当有日期维度时,key为补贴标准业务编码+yyyy-MM-dd格式。value为匹配的补贴标准。AllowanceService有提供方法获取对应补贴金额 |
AllowanceStandard(补贴标准)
参数名称 |
类型 |
描述 |
amount |
BigDecimal |
金额 |
currency |
String |
币种 |
TravelRoute(行程)
参数名称 |
类型 |
描述 |
departure |
String |
出发地(每刻地址编码) |
destination |
String |
目的地(每刻地址编码) |
startDate |
DateTime |
开始时间 |
endDate |
DateTime |
结束时间 |
tripWay |
TripWay枚举 |
行程类型,SINGLE(单程)ROUND_TRIP(往返) |
travelDays |
BigDecimal |
出差天数 |
customFormValues |
List<CustomFormValue> 数组 |
自定义表单信息 |
expenseCodeList |
List<String> 数组 |
行程关联的费用编码(对应费用行code参数) |
attendance |
Attendance |
考勤信息 |
allowanceStandardInfos |
List<AllowanceStandardInfo> 数组 |
报销人补贴标准信息 |
travelPartnerInfo |
TravelPartnerInfo |
参与人信息 |
partnerAllowanceStandardInfos |
List<AllowanceStandardInfo> 数组 |
参与人补贴标准信息(优先级:行程参与人标准信息>单据参与人标准信息;若行程有参与人信息,这里的标准为行程参与人标准,若无,这里的标准为单据参与人标准;单据、行程都无参与人,则为null) |
travelRouteCode |
String |
行程code,可用于申请单补贴费用在行程下显示 |
departureText |
String |
行程出发地名称(待发布) |
destinationText |
String |
行程目的地名称(待发布) |
TravelPartnerInfo(参与人信息组)
参数名称 |
类型 |
描述 |
code |
String |
参与人信息组编码 |
relationCode |
String |
关联编码 |
externalReferenceFormCode |
BigDecimal |
外部同行人表单编码 |
externalTravelPartnerTypeCode |
String |
外部同行人小类编码 |
externalPeopleNum |
int |
外部同行人人数 |
externalTravelPartner |
List<TravelPartner> 数组 |
外部同行人列表 |
internalReferenceFormCode |
String |
内部同行人表单编码 |
internalTravelPartnerTypeCode |
String |
内部同行人小类编码 |
internalPeopleNum |
BigDecimal |
内部同行人人数 |
internalTravelPartner |
List<TravelPartner> 数组 |
内部同行人列表 |
TravelPartner(参与人信息)
参数名称 |
类型 |
描述 |
code |
String |
参与人信息编码 |
externalUser |
boolean |
是否外部员工 |
userCode |
String |
内部员工编码 |
employeeId |
String |
员工工号 |
departmentCode |
String |
部门内部编码 |
departmentBizCode |
String |
部门业务编码 |
departmentName |
String |
部门名称 |
name |
String |
姓名 |
gender |
String |
性别 |
peopleNum |
int |
参与人人数 |
customObject |
String |
自定义对象 |
formDataCode |
String |
关联单据编码 |
classPosition |
ClassPosition |
职级(仅限返回单据级参与人组件的职级信息,其他(如行程)的参与人组件此字段暂时未返回) |
ClassPosition(职级信息)
参数名称 |
类型 |
描述 |
code |
String |
职级编码 |
userGroupCode |
String |
用户组编码 |
name |
String |
职级名称 |
businessCode |
String |
职级业务编码 |
description |
String |
职级描述 |
superiorCode |
String |
直接上级编码 |
Attendance(考勤信息)
参数名称 |
类型 |
描述 |
startDate |
DateTime |
开始时间 |
endDate |
DateTime |
结束时间 |
calcDaysMode |
CalcDaysMode枚举 |
时长计算方式,NATURAL_DAY(自然日)WORK_DAY(工作日) |
durationUnit |
AttendanceDurationUnit枚举 |
考勤统计单元DAY(天)HALF_DAY(半天)HOUR(小时) |
duration |
double |
考勤时长 |
RuleScheduleValue(节假日信息列表)
参数名称 |
类型 |
描述 |
scheduleMap |
Map |
节假日信息集合 |
ScheduleValue(节假日信息)
参数名称 |
类型 |
描述 |
scheduleOptionCode |
String |
节假日表code |
scheduleDate |
String |
日期,格式(yyyy-MM-dd) |
补贴结果
补贴结果存入AllowanceResult对象
AllowanceResult(补贴结果)
参数名称 |
类型 |
描述 |
bizCode |
String |
补贴类型业务编码 |
date |
DateTime |
消费时间 |
startDate |
DateTime |
开始时间 |
endDate |
DateTime |
结束时间 |
amount |
BigDecimal |
补贴金额 |
collectionCcy |
String |
收款币种(外币仅支持报销单) |
baseCcy |
String |
本币 |
customObject |
Map |
自定义字段 |
consumeLocation |
String |
消费城市(需传入每刻地址编码) |
departure |
String |
出发地(需传入每刻地址编码) |
destination |
String |
目的地(需传入每刻地址编码) |
备注:
1)如果费用表单的消费城市范围是区间,可以通过result.setDeparture(), result.setDestination 或者allowanceService.copyLocationFromTravelRoute()该方法设置补贴的消费地点
2)如果费用表单的消费城市范围不是区间,可以通过setConsumeLocation(), 或者下面一个参数的构造方法设置补贴消费地点的值
构造器
○ AllowanceResult(DateTime date, String bizCode, BigDecimal amount,String baseCcy, String collectionCcy)
○ AllowanceResult(DateTime date, String bizCode, BigDecimal amount,String baseCcy, String collectionCcy, String consumeLocation)
○ AllowanceResult(DateTime startDate, DateTime endDate, String bizCode, BigDecimal amount,String baseCcy, String collectionCcy)
○ AllowanceResult(DateTime startDate, DateTime endDate, String bizCode, BigDecimal amount,String baseCcy, String collectionCcy,String destination)
自定义字段相关赋值方法(bizCode填写字段对应的业务编码)
○ void setTextCustomObject(String bizCode, String value) 文本类型字段赋值
○ void setNumberCustomObject(String bizCode, BigDecimal value) 数字类型字段赋值
○ void setAmountCustomObject(String bizCode, MonetaryAmount monetaryAmount) 金额类型字段赋值
○ void setOptionCustomObject(String bizCode, String value) 选项类型字段赋值(选项值使用业务编码)
其他
//针对申请单申请明细配置为“需要在行程下填写申请明细”模式时,使用该方法支持将生成的补贴费用挂在对应行程下。
○ setTravelRouteCode($travelRouteCode); //&travelRouteCode:取值为行程code。
注:使用时间或时间区间对应的补贴类型要设置对应的消费时间格式,不然无法带入。
MonetaryAmount提供一个MonetaryAmount(BigDecimal amount, String currency)构造器
工作区里存在的对象
1、Reimburse 单据信息
drl可以使用的全局对象
1、AllowanceService 提供如下方法
/**
* 根据费用的开始结束时间计算出差天数(不考虑时分秒)
*/
List<DateTime> getTripDiffDays(Expense expense);
/**
* 根据行程的开始结束时间计算出差天数(不考虑时分秒)
*/
List<DateTime> getTripDiffDays(TravelRecord record)
/**
* 判断两个时间是否是同一天
*/
boolean isSameDay(DateTime startDate,DateTime endDate)
/**
* 根据补贴类型和日期汇总补贴
*/
List<AllowanceResult> getSumAllowancesGroupByAllowanceType(List<AllowanceResult> dailyAllowances)
/**
* 根据日期获取对应的补贴标准
*/
BigDecimal getAllowanceStandard(DateTime date, AllowanceStandardInfo standardInfo)
/**
* 根据日期获取对应的目的地补贴标准
*/
BigDecimal getDestinationAllowanceStandard(DateTime date, AllowanceStandardInfo standardInfo)
/**
* 根据日期获取对应的参与人出发地补贴标准
*/
BigDecimal getPartnerAllowanceStandard(DateTime date, List<AllowanceStandardInfo> standardInfos,TravelPartner travelPartner,String ruleBizCode)
/**
* 根据日期获取对应的参与人目的地补贴标准
*/
BigDecimal getDestinationPartnerAllowanceStandard(DateTime date, List<AllowanceStandardInfo> standardInfos,TravelPartner travelPartner,String ruleBizCode)
/**
* 根据日期获取对应的补贴标准币种
*/
String getAllowanceStandardCcy(DateTime date, AllowanceStandardInfo standardInfo)
/**
* 根据日期获取对应的目的地补贴标准币种
*/
String getDestinationAllowanceStandardCcy(DateTime date, AllowanceStandardInfo standardInfo)
/**
* 拷贝费用上的地址信息到补贴上
*/
void copyLocationFromExpense(Expense expense, AllowanceResult allowanceResult)
/**
* 拷贝行程上的地址信息到补贴上
*/
void copyLocationFromTravelRoute(TravelRoute travelRoute, AllowanceResult allowanceResult)
/**
* 获取员工的第一个常驻地编码
*/
String getEmployeePlaceFullCode(Employee employee)
/**
* 获取指定自定义字段的值
*/
String getCustomFormValue(List<CustomFormValue> customFormValues, String bizCode)
/**
* 获取指定rulBizCode的补贴标准金额
* @param standardInfos 补贴标准List
* @param dateTime 时间
* @param ruleBizCode 补贴标准
* @param isDestination 是否是目的地
* @return
*/
BigDecimal getAllowanceStandardAmountByCodeAndTime(List<AllowanceStandardInfo> standardInfos, DateTime dateTime, String ruleBizCode, boolean isDestination)
/**
* 取重复行程天数的就高或者就低标准
* @param dateTime 重复的日期
* @param ruleBiCode
* @param destination 是否取目的地的标准
* @param high 是否就高
* @return
*/
BigDecimal getAmountByDateTime(List<TravelRoute> travelRoutes, DateTime dateTime, String ruleBiCode, boolean destination, boolean high)
/**
* 判断出差地点是否是常驻地
* @param employee 员工信息
* @param travelRoute 行程信息
* @param isDestination 是否校验目的地
* @param isContain 是否完全检验 | 非完全校验 即地址编码 包含关系
* @return
*/
boolean isResidence(Employee employee, TravelRoute travelRoute, boolean isDestination, boolean isContain)
/**
* 判断指定日期是否是节假日
* @param optionCode 节假日表code
* @param dateTime yyyy-MM-dd
* @param ruleScheduleValue
* @return
*/
boolean isSchedule(String optionCode, String dateTime, RuleScheduleValue ruleScheduleValue)
/**
* 判断指定日期是否是周六周末
* @param dateTime yyyy-MM-dd
* @return
*/
public static boolean isDayOfWeek(String dateTime)
/**
* 按照人+日期+格子分组后的费控标准信息
* @param expenses
* @return
*/
public ExpenseStandResult getKeyByFinalDimCodes(List<Expense> expenses)
/**
* 按照人+日期+规则分组后的费控标准信息
* @param expenses
* @return
*/
public ExpenseStandResult getKeyByRuleCode(List<Expense> expenses)
2、Logger 日志 引用路径如下
import org.slf4j.Logger;
import com.maycur.sdk.rule.service.AllowanceService;
示例
根据员工住宿生成补贴,根据补贴标准配置生成对应金额的补贴,最后一天不产生补贴
package rules;
import com.maycur.sdk.rule.domain.Expense;
import com.maycur.sdk.rule.domain.Reimburse;
import com.maycur.sdk.rule.domain.AllowanceStandardInfo;
import com.maycur.sdk.rule.domain.MonetaryAmount;
import com.maycur.sdk.rule.domain.result.AllowanceResult;
import com.maycur.sdk.rule.service.AllowanceService;
import org.joda.time.DateTime;
import java.util.Map;
import java.util.List;
import java.math.BigDecimal;
global AllowanceService allowanceService;
dialect "mvel"
rule "default"
when
Reimburse($expenses:expenses)
$expense : Expense(typeCode=="2001_01",$baseCcy:baseCcy,$collectionCcy:collectionCcy,$endDate:endDate, $allowanceStandardInfos:allowanceStandardInfos) from $expenses
$allowanceStandardInfo: AllowanceStandardInfo() from $allowanceStandardInfos
$consumeTime : DateTime() from $expense.days()
not (eval($endDate == $consumeTime))
then
AllowanceResult result = new AllowanceResult($consumeTime,"2023_01",allowanceService.getAllowanceStandard($consumeTime,$allowanceStandardInfo),$baseCcy,$collectionCcy);
result.setTextCustomObject("C1","1");
result.setTextCustomObject("C2","2");
result.setNumberCustomObject("C3", new BigDecimal(3));
result.setAmountCustomObject("C4", new MonetaryAmount(new BigDecimal(4), "CNY"));
allowanceService.copyLocationFromExpense($expense, result);
insert(result);
end
使用时间区间的例子
package rules;
import com.maycur.sdk.rule.domain.Expense;
import com.maycur.sdk.rule.domain.Reimburse;
import com.maycur.sdk.rule.domain.result.AllowanceResult;
import org.joda.time.DateTime;
import java.util.Map;
import java.util.List;
import java.math.BigDecimal;
import com.maycur.sdk.rule.service.AllowanceService;
import com.maycur.sdk.rule.domain.TravelRoute;
import com.maycur.sdk.rule.domain.AllowanceStandardInfo;
import com.maycur.sdk.rule.domain.MonetaryAmount;
import org.joda.time.DateTime;
import org.slf4j.Logger;
global AllowanceService allowanceService;
dialect "mvel"
rule "default"
salience 2
when
Reimburse($travelRoutes:travelRoutes,$baseCcy:baseCcy,$collectionCcy:collectionCcy)
$travelRoute : TravelRoute($endDate:new DateTime(endDate.getYear(),endDate.getMonthOfYear(),endDate.getDayOfMonth(),0,0,0),$startDate:new DateTime(startDate.getYear(),startDate.getMonthOfYear(),startDate.getDayOfMonth(),0,0,0),$allowanceStandardInfos:allowanceStandardInfos) from $travelRoutes;
$consumeTime : DateTime() from allowanceService.getTripDiffDays($travelRoute);
$allowanceStandardInfo: AllowanceStandardInfo() from $allowanceStandardInfos
$result:AllowanceResult(bizCode == "2023_10")
not (eval($endDate == $consumeTime))
then
BigDecimal standard = allowanceService.getAllowanceStandard($consumeTime,$allowanceStandardInfo);
$result.setAmount($result.getAmount().add(standard));
update($result);
end
rule "生成补贴"
salience 10
when
Reimburse($travelRoutes:travelRoutes,$baseCcy:baseCcy,$collectionCcy:collectionCcy)
$travelRoute : TravelRoute($endDate:new DateTime(endDate.getYear(),endDate.getMonthOfYear(),endDate.getDayOfMonth(),0,0,0),$startDate:new DateTime(startDate.getYear(),startDate.getMonthOfYear(),startDate.getDayOfMonth(),0,0,0),$allowanceStandardInfos:allowanceStandardInfos) from $travelRoutes;
then
AllowanceResult result = new AllowanceResult($startDate,$endDate,"2023_10",BigDecimal.ZERO,$baseCcy,$collectionCcy);
allowanceService.copyLocationFromTravelRoute($travelRoute, result);
insert(result);
end
修改记录
2020-05-13:初稿
2020-07-03:员工对象增加一些字段,费用、行程上增加对应的补贴标准信息,补贴结果对象增删字段(构造器有变化),AllowanceService增加三个新方法
2020-08-05:补贴结果增加对选项类型的自定义字段的处理
2020-08-20:增加根据日期获取对应的目的地补贴标准
2020-09-01:补贴结果增加时间区间
2020-10-10:增加获取补贴标准币种的方法
2021-05-27:新增单据级参与人信息,新增申请单补贴,申请单补贴和报销单公用一个rule-sdk
2021-06-03:新增单据、行程参与人补贴标准信息,allowanceService新增获取参与人标准的方法,同时旧方法也可用于获取参与人标准(入参不同),更新rule-sdk版本到1.06
2021-06-09:补贴支持访问外部系统发起http请求HttpURLConnection
2021-08-30:新增allowanceResult,目的地构造方法;更新获取参与人补贴标准的方法;更新sdk版本到1.0.7
2021-11-04:补贴行程信息优化排序,优先按照行程开始日期进行排序
2022-01-12: sdk 增加一些常用方法抽取,更新sdk 版本到1.0.8
2022-01-25:费用增加是否含早字段
2022-02-11:费用新增分摊表单信息,更新sdk 版本到1.0.9
2022-05-13:行程增加travelRouteCode字段,用于申请单补贴单独在行程下显示
2022-06-09:行程新增出发地和目的地名称
2023-01-03:补贴新增节假日表信息,以及isSchedule 判断是否是节假日的方法, sdk版本到1.1.1
2023-04-01:补贴新增费控标准信息,sdk版本更新到1.1.2
2023-04-23:迁移openapi文档