反写插件手册
# 反写插件手册
## 1.场景
BOTP反写规则可以应用在一对已绑定关联关系的单据上,通过配置反写规则使下游目标单在保存或审核时进行反写操作,将目标单的指定字段按一定计算规则反写到源单关联行的那个字段上,并根据反写结果改变源单的状态,实现下游单据向上游单据的自动数据转换,节省人力,提高效率。下游目标单据反写源单过程中,会触发反写插件事件,允许自定义插件进行干预。
## 2.适用版本
金蝶云苍穹 4.0.004以上
## 3.反写步骤
- 根据相应的操作和单据状态进行分组,分别执行不同的逻辑
- 执行业务跟踪、反写主干逻辑,生成待保存数据
- 分析数据包,是否有需要处理关联关系的数据行,以及需要分页执行的数据行
- 单线程同步执行反写
- 构建分批反写执行类
- 执行分批反写类
- 执行反写逻辑
- 构建关联勾稽行
- 基于当前数据,构建单据级追踪记录
- 对比历史记录,生成分录行级追踪记录
- 执行反写前,加载当前操作需要用到的反写规则
- 构建源单追溯树
- 基于最新反写规则,构建反写需求
- 读取历史反写快照中用到的反写规则版本
- 对比历史快照,计算本次实际需要反写的数量
- 执行反写逻辑单元
- 反写快照日志处理逻辑单元
- 判断当前操作的单据,有没有读取到历史快照
- 对比差异:生成待存储的单据级跟踪数据
- 分析分批执行结果
## 4.反写插件各事件的触发时机及用途
### 4.1.插件接口及基类
1. #### 反写插件接口
```java
package kd.bos.entity.botp.plugin;
import kd.sdk.annotation.SdkPublic;
import kd.bos.entity.BillEntityType;
import kd.bos.entity.LinkSetItemElement;
import kd.bos.entity.botp.plugin.args.AfterCalcWriteValueEventArgs;
import kd.bos.entity.botp.plugin.args.AfterCloseRowEventArgs;
import kd.bos.entity.botp.plugin.args.AfterCommitAmountEventArgs;
import kd.bos.entity.botp.plugin.args.AfterExcessCheckEventArgs;
import kd.bos.entity.botp.plugin.args.AfterReadSourceBillEventArgs;
import kd.bos.entity.botp.plugin.args.AfterSaveSourceBillEventArgs;
import kd.bos.entity.botp.plugin.args.BeforeCloseRowEventArgs;
import kd.bos.entity.botp.plugin.args.BeforeCreateArticulationRowEventArgs;
import kd.bos.entity.botp.plugin.args.BeforeExcessCheckEventArgs;
import kd.bos.entity.botp.plugin.args.BeforeExecWriteBackRuleEventArgs;
import kd.bos.entity.botp.plugin.args.BeforeReadSourceBillEventArgs;
import kd.bos.entity.botp.plugin.args.BeforeSaveSourceBillEventArgs;
import kd.bos.entity.botp.plugin.args.BeforeSaveTransEventArgs;
import kd.bos.entity.botp.plugin.args.BeforeTrackEventArgs;
import kd.bos.entity.botp.plugin.args.FinishWriteBackEventArgs;
import kd.bos.entity.botp.plugin.args.PreparePropertysEventArgs;
import kd.bos.entity.botp.plugin.args.RollbackSaveEventArgs;
/**
* 反写插件:控制反写过程,需要注册到下游单据的关联配置属性中
*
* @author rd_johnnyding
*
*/
@SdkPublic
public interface IWriteBackPlugIn {
/**
* 下游目标单主实体,仅包含了需要的字段,与单据数据包一致
* @return
*/
BillEntityType getTargetSubMainType();
/**
* 当前操作类型:Draft,Save,Audit,UnAudit,Delete,Cancel,UnCancel,Unknown
* @return
*/
String getOpType();
/**
* 当前处理的关联主实体
*
* @return
*/
LinkSetItemElement getCurrLinkSetItem();
/**
* 在读取下游目标单数据之前,触发此事件:用于添加需要加载的目标单字段
* @param e
* @remark
* 这个事件比设置上下文方法,更早执行,在此事件中,只能依赖事件参数获取上下文信息
*/
void preparePropertys(PreparePropertysEventArgs e);
/**
* 设置当前上下文
*
* @param targetMainType 下游目标单主实体,仅包含了需要的字段
* @param opType 操作类型
* @param linkSetItem 关联主实体
*/
void setContext(BillEntityType targetSubMainType, String opType, LinkSetItemElement linkSetItem);
/**
* 构建本关联主实体全部关联记录前,触发此事件:用于取消关联、反写
*
* @param e
*/
void beforeTrack(BeforeTrackEventArgs e);
/**
* 构建本关联主实体,单行数据与源单的关联记录前,触发此事件:用于取消本行的关联、反写
* @param e
*/
void beforeCreateArticulationRow(BeforeCreateArticulationRowEventArgs e);
/**
* 开始分析反写规则,计算反写量前触发此事件:用于取消当前反写规则的执行
*
* @param e
* @remark
* 升级版本后,系统预置插件,可以通过此事件,强制禁用系统预置的反写规则
*/
void beforeExecWriteBackRule(BeforeExecWriteBackRuleEventArgs e);
/**
* 基于下游单据当前行,反写值计算完毕后,触发此事件:用于修正反写量,调整对各源单行的分配量
* @param e
*/
void afterCalcWriteValue(AfterCalcWriteValueEventArgs e);
/**
* 读取源单数据之前,触发此事件:用于添加需要加载的源单字段
* @param e
*/
void beforeReadSourceBill(BeforeReadSourceBillEventArgs e);
/**
* 读取源单数据之后,触发此事件:供插件读取相关的第三方单据
* @param e
*/
default void afterReadSourceBill(AfterReadSourceBillEventArgs e) {}
/**
* 执行反写规则,把当前反写量,写到源单行之后,触发此事件:用于对源单行,进行连锁更新
* @param e
*/
void afterCommitAmount(AfterCommitAmountEventArgs e);
/**
* 对源单行反写执行完毕,超额检查前,触发此事件:用于取消超额检查
* @param e
*/
void beforeExcessCheck(BeforeExcessCheckEventArgs e);
/**
* 对源单行反写执行完毕,超额检查完毕后,触发此事件:用于控制是否中止反写、提示超额,修正提示内容
* @param e
*/
void afterExcessCheck(AfterExcessCheckEventArgs e);
/**
* 关闭上游行前调用,IsCancelCheck==true,则不再做关闭条件检查
* @param e
*/
default void beforeCloseRow(BeforeCloseRowEventArgs e) {}
/**
* 对上游行进行了关闭状态填写后调用
* @param e
*/
default void afterCloseRow(AfterCloseRowEventArgs e) {}
/**
* 反写逻辑处理完毕,开始开启事务,保存反写数据前触发此事件,供插件在事务前读取并处理第三方数据,以便在随后开启的事务中一并保存
* @param e
*/
default void beforeSaveTrans(BeforeSaveTransEventArgs e) {}
/**
* 反写规则执行完毕后,源单数据保存到数据库之前调用
* @param e
*/
default void beforeSaveSourceBill(BeforeSaveSourceBillEventArgs e) {}
/**
* 源单数据保存到数据库后调用
* @param e
*/
default void afterSaveSourceBill(AfterSaveSourceBillEventArgs e) {}
/**
* 保存失败,触发此事件,通知插件回滚数据
* @param e
*/
default void rollbackSave(RollbackSaveEventArgs e) {}
/**
* 反写所有逻辑已经执行完毕后触发,用于通知插件释放资源,如插件申请的网控
* @param e
*/
default void finishWriteBack(FinishWriteBackEventArgs e) {}
}
```
2. #### 单据转换插件基类`AbstractWriteBackPlugIn`,实现了反写插件接口`IWriteBackPlugIn`
```java
public class AbstractWriteBackPlugIn implements IWriteBackPlugIn {
}
```
3. #### 创建并注册插件
自定义反写插件,必须扩展插件基类AbstractWriteBackPlugIn,注册到下游单据的关联配置属性中:
![downloadfile.webp](/download/01004095cc0104d94dde9c931355d097cd18.webp)
### 4.2.插件事件
反写插件,提供如下插件事件:
| 事件 | 触发时机 |
| --------------------------- | -------------------------------------------------------- |
| preparePropertys | 在读取下游目标单数据之前,触发此事件 |
| beforeTrack | 构建本关联主实体全部关联记录前,触发此事件 |
| beforeCreateArticulationRow | 构建本关联主实体,单行数据与源单的关联记录前,触发此事件 |
| beforeExecWriteBackRule | 开始分析反写规则,计算反写量前触发此事件 |
| afterCalcWriteValue | 基于下游单据当前行,反写值计算完毕后,触发此事件 |
| beforeReadSourceBill | 读取源单数据之前,触发此事件 |
| afterReadSourceBill | 取源单数据之后,触发此事件 |
| afterCommitAmount | 执行反写规则,把当前反写量,写到源单行之后,触发此事件 |
| beforeExcessCheck | 源单行反写执行完毕,超额检查前,触发此事件 |
| afterExcessCheck | 对源单行反写执行完毕,超额检查完毕后,触发此事件 |
| beforeCloseRow | 关闭上游行前调用 |
| afterCloseRow | 对上游行进行了关闭状态填写后调用 |
| beforeSaveTrans | 反写逻辑处理完毕,开始开启事务,保存反写数据前触发此事件 |
| beforeSaveSourceBill | 反写规则执行完毕后,源单数据保存到数据库之前调用 |
| afterSaveSourceBill | 源单数据保存到数据库后调用 |
| rollbackSave | 保存失败,触发此事件,通知插件回滚数据 |
| finishWriteBack | 反写所有逻辑已经执行完毕后触发 |
1. preparePropertys事件
- 事件触发时机
- 在读取下游目标单数据之前,即触发此事件。插件可以在此事件中,添加需要加载的目标单字段。
- 这个事件比设置上下文方法,更早执行,在此事件中,只能依赖事件参数获取上下文信息。
- 插件可以利用如下方法,获取到目标单、当前操作类型、当前处理的关联主实体:
```java
private void getContext(){
// 目标单主实体
BillEntityType targetSubMainType = this.getTargetSubMainType();
// 当前操作类型
String opType = this.getOpType();
// 当前处理的关联主实体
LinkSetItemElement linkSetItemEle = this.getCurrLinkSetItem();
}
```
- 代码模板
```java
public class PreparePropertys extends AbstractWriteBackPlugIn {
@Override
public void preparePropertys(PreparePropertysEventArgs e) {
// TODO 在此添加业务逻辑
}
}
```
- 事件参数
```java
public class PreparePropertysEventArgs extends WriteBackEventArgs {
BillEntityType mainType;
List<String> fieldKeys;
/**
* 构造函数
* @param mainType 目标单实体类型
* @param fieldKeys 需要加载的目标单字段
*/
public PreparePropertysEventArgs(BillEntityType mainType, List<String> fieldKeys) {
this.mainType = mainType;
this.fieldKeys = fieldKeys;
}
/**
* 目标单实体类型
* @return
*/
@KSMethod
public BillEntityType getMainType() {
return mainType;
}
/**
* 需要加载的目标单字段
* @return
*/
@KSMethod
public List<String> getFieldKeys() {
return fieldKeys;
}
}
```
- 示例
暂无示例。
2. beforeTrack事件
- 事件触发时机
- 构建本关联主实体全部关联记录前,触发此事件,用于取消关联、反写。
- 插件可以在此事件中,增加需要加载的源单字段,调整源单行取数条件。
- 代码模板
```java
public class BeforeTrack extends AbstractWriteBackPlugIn {
@Override
public void beforeTrack(BeforeTrackEventArgs e) {
// TODO 在此添加业务逻辑
}
}
```
- 事件参数
```java
public class BeforeTrackEventArgs extends WriteBackEventArgs {
private DynamicObject dataEntity;
private boolean cancel;
/**
* 构造函数
* @param dataEntity 当前单据数据包
*/
public BeforeTrackEventArgs(DynamicObject dataEntity) {
this.dataEntity = dataEntity;
}
/**
* 当前单据数据包
* @return
*/
@KSMethod
public DynamicObject getDataEntity() {
return dataEntity;
}
/**
* 插件取消关联、反写
* @return
*/
@KSMethod
public boolean isCancel() {
return cancel;
}
/**
* 设置插件取消关联、反写
* @param cancel
*/
@KSMethod
public void setCancel(boolean cancel) {
this.cancel = cancel;
}
}
```
- 示例
暂无示例
3. beforeCreateArticulationRow事件
- 事件触发时机
- 构建本关联主实体,单行数据与源单的关联记录前,触发此事件。
- 用于取消本行的关联、反写;
- 代码模板
```java
public class BeforeCreateArticulationRow extends AbstractWriteBackPlugIn {
@Override
public void beforeCreateArticulationRow(BeforeCreateArticulationRowEventArgs e) {
// TODO 在此添加业务逻辑
}
}
```
- 事件参数
```java
public class BeforeCreateArticulationRowEventArgs extends WriteBackEventArgs {
private EntityType entity;
private DynamicObject activeRow;
private DynamicObjectCollection linkRows;
private boolean cancel;
private boolean cancelReDistributeAmount;
/**
* 构造函数
* @param entity 当前关联主实体
* @param activeRow 关联主实体当前行
* @param linkRows 关联主实体行下属的关联子实体行,包含了来源单据行信息
*/
public BeforeCreateArticulationRowEventArgs(EntityType entity, DynamicObject activeRow, DynamicObjectCollection linkRows) {
this.entity = entity;
this.activeRow = activeRow;
this.linkRows = linkRows;
}
/**
* 当前关联主实体
* @return
*/
@KSMethod
public EntityType getEntity() {
return entity;
}
/**
* 关联主实体当前行
* @return
*/
@KSMethod
public DynamicObject getActiveRow() {
return activeRow;
}
/**
* 关联主实体行下属的关联子实体行,包含了来源单据行信息
* @return
*/
@KSMethod
public DynamicObjectCollection getLinkRows() {
return linkRows;
}
/**
* 是否取消创建本行的关联记录:
* 取消后,相当于本行无源单,不会记录业务流程路线记录与反写源单
* @return
*/
@KSMethod
public boolean isCancel() {
return cancel;
}
/**
* 设置是否取消创建本行的关联记录
* @param cancel
*/
@KSMethod
public void setCancel(boolean cancel) {
this.cancel = cancel;
}
/**
* 由插件自行调整控制字段对各源单行的分配量,取消系统的自动分配处理;
* @return
*/
@KSMethod
public boolean isCancelReDistributeAmount() {
return cancelReDistributeAmount;
}
/**
* 设置由插件自行调整控制字段对各源单行的分配量,取消系统的自动分配处理
* @param cancelReDistributeAmount
*/
@KSMethod
public void setCancelReDistributeAmount(boolean cancelReDistributeAmount) {
this.cancelReDistributeAmount = cancelReDistributeAmount;
}
}
```
- 示例
暂无示例
4. beforeExecWriteBackRule事件
- 事件触发时机
- 开始分析反写规则,计算反写量前,触发此事件。
- 插件可以用于取消当前反写规则的执行。
- 升级版本后,系统预置插件,可以通过此事件,强制禁用系统预置的反写规则
- 代码模板
```java
public class BeforeExecWriteBackRule extends AbstractWriteBackPlugIn {
@Override
public void beforeExecWriteBackRule(BeforeExecWriteBackRuleEventArgs e) {
// TODO 在此添加业务逻辑
}
}
```
- 事件参数
```java
public class BeforeExecWriteBackRuleEventArgs extends WriteBackEventArgs {
private WriteBackRuleElement rule;
private WriteBackFormula ruleItem;
private boolean cancel;
/**
* 构造函数
*/
public BeforeExecWriteBackRuleEventArgs() {
//empty method
}
/**
* 调整当前反写规则、反写条目
* @param rule
* @param ruleItem
*/
@KSMethod
public void setContext(WriteBackRuleElement rule, WriteBackFormula ruleItem) {
this.rule = rule;
this.ruleItem = ruleItem;
this.cancel = false;
}
/**
* 当前准备执行的反写规则
*
* @return
*/
@KSMethod
public WriteBackRuleElement getRule() {
return rule;
}
/**
* 当前准备执行的反写公式
*
* @return
*/
@KSMethod
public WriteBackFormula getRuleItem() {
return ruleItem;
}
/**
* 是否取消本反写公式的执行
* @return
*/
@KSMethod
public boolean isCancel() {
return cancel;
}
/**
* 设置是否取消本反写公式的执行
* @param cancel
*/
@KSMethod
public void setCancel(boolean cancel) {
this.cancel = cancel;
}
}
```
- 示例
暂无示例。
5. afterCalcWriteValue事件
- 事件触发时机
- 基于下游单据当前行,反写值计算完毕后,触发此事件。
- 用于修正反写量,调整对各源单行的分配量。
- 代码模板
```java
public class AfterCalcWriteValue extends AbstractWriteBackPlugIn {
@Override
public void afterCalcWriteValue(AfterCalcWriteValueEventArgs e) {
// TODO 在此添加业务逻辑
}
}
```
- 事件参数
```java
public class AfterCalcWriteValueEventArgs extends WriteBackEventArgs {
private EntityType entity;
private DynamicObject activeRow;
private WriteBackRuleElement rule;
private WriteBackFormula ruleItem;
private BigDecimal val;
private Object cVal;
private Map<BFRowId, BigDecimal> srcRowVal = new HashMap<>();
/**
* 构造函数
* @param entity 关联主实体
* @param activeRow 关联主实体当前行
* @param rule 反写规则
* @param ruleItem 反写公式
* @param val 根据反写公式,算出的反写量
* @param cVal 覆盖反写模式,根据反写公式算出的覆盖值
*/
public AfterCalcWriteValueEventArgs(EntityType entity, DynamicObject activeRow,
WriteBackRuleElement rule, WriteBackFormula ruleItem,
BigDecimal val, Object cVal) {
this.entity = entity;
this.activeRow = activeRow;
this.rule = rule;
this.ruleItem = ruleItem;
this.val = val;
this.cVal = cVal;
}
/**
* 关联主实体
* @return
*/
@KSMethod
public EntityType getEntity() {
return entity;
}
/**
* 关联主实体当前行
* @return
*/
@KSMethod
public DynamicObject getActiveRow() {
return activeRow;
}
/**
* 反写规则
* @return
*/
@KSMethod
public WriteBackRuleElement getRule() {
return rule;
}
/**
* 反写公式
*/
@KSMethod
public WriteBackFormula getRuleItem() {
return ruleItem;
}
/**
* 根据反写公式,算出的反写量
* @return
*/
@KSMethod
public BigDecimal getVal() {
return val;
}
/**
* 覆盖反写模式,根据反写公式算出的覆盖值
*/
@KSMethod
public Object getCVal() {
return cVal;
}
/**
* 搜索出的源单行,以及其分配的反写量:
* 如果有多个源单行,默认每行的反写量为0;需要插件自行给各源单行分配反写量;
* 如果插件不处理,则不反写
* @return
*/
@KSMethod
public Map<BFRowId, BigDecimal> getSrcRowVal() {
return srcRowVal;
}
}
```
- 示例
暂无示例。
6. beforeReadSourceBill 事件
- 事件触发时机
- 读取源单数据之前,触发此事件。
- 用于添加需要加载的源单字段
- 代码模板
```java
public class BeforeReadSourceBill extends AbstractWriteBackPlugIn {
@Override
public void beforeReadSourceBill(BeforeReadSourceBillEventArgs e) {
// TODO 在此添加业务逻辑
}
}
```
- 事件参数
```java
public class BeforeReadSourceBillEventArgs extends WriteBackEventArgs {
private BillEntityType srcMainType;
private List<WriteBackRuleElement> rules = new ArrayList<>();
private List<String> fieldKeys = new ArrayList<>();
private Set<Long> srcBillIds = new HashSet<>();
/**
* 构造函数
* @param srcMainType 上游源单主实体,包含了完整字段
* @param rules 反写上游源单的全部反写规则
*/
public BeforeReadSourceBillEventArgs(BillEntityType srcMainType, List<WriteBackRuleElement> rules) {
this.srcMainType = srcMainType;
this.rules.addAll(rules);
}
/**
* 上游源单主实体,包含了完整字段
* @return
*/
@KSMethod
public BillEntityType getSrcMainType() {
return srcMainType;
}
/**
* 反写上游源单的全部反写规则
* @return
*/
@KSMethod
public List<WriteBackRuleElement> getRules() {
return rules;
}
/**
* 插件需要用到的源单字段
* @return
*/
@KSMethod
public List<String> getFieldKeys() {
return fieldKeys;
}
/**
* 需要读取的源单内码:插件可以反写前,根据源单内码,读取第三方单据数据
* @return
*/
public Set<Long> getSrcBillIds() {
return srcBillIds;
}
/**
* 传入源单内码
* @param srcBillIds
*/
public void setSrcBillIds(Set<Long> srcBillIds) {
this.srcBillIds.clear();
if (srcBillIds != null) {
this.srcBillIds.addAll(srcBillIds);
}
}
}
```
- 示例
暂无示例。
7. afterReadSourceBill 事件
- 事件触发时机
- 读取源单数据之后,触发此事件
- 供插件读取相关的第三方单据
- 代码模板
```java
public class AfterReadSourceBill extends AbstractWriteBackPlugIn {
@Override
public void afterReadSourceBill(AfterReadSourceBillEventArgs e) {
// TODO 在此添加业务逻辑
}
}
```
- 事件参数
```java
public class AfterReadSourceBillEventArgs extends WriteBackEventArgs {
private BillEntityType srcSubMainType;
private DynamicObject[] srcDataEntities;
/**
* 构造函数
* @param srcSubMainType 源单主实体,只包含了部分用到的字段
* @param srcDataEntities 源单数据包,只包含了部分用到的字段
*/
public AfterReadSourceBillEventArgs(BillEntityType srcSubMainType, DynamicObject[] srcDataEntities) {
this.srcSubMainType = srcSubMainType;
this.srcDataEntities = srcDataEntities;
}
/**
* 源单主实体,只包含了部分用到的字段
* @return
*/
@KSMethod
public BillEntityType getSrcSubMainType() {
return srcSubMainType;
}
/**
* 源单数据包,只包含了部分用到的字段
* @return
*/
@KSMethod
public DynamicObject[] getSrcDataEntities() {
return srcDataEntities;
}
}
```
- 示例
暂无示例
8. afterCommitAmount事件
- 事件触发时机
- 执行反写规则,把当前反写量,写到源单行之后,触发此事件;
- 用于对源单行,进行连锁更新
- 代码模板
```java
public class AfterCommitAmount extends AbstractWriteBackPlugIn {
@Override
public void afterCommitAmount(AfterCommitAmountEventArgs e) {
// TODO 在此添加业务逻辑
}
}
```
- 事件参数
```java
public class AfterCommitAmountEventArgs extends WriteBackEventArgs {
private WriteBackRuleElement rule;
private WriteBackFormula ruleItem;
private BillEntityType srcSubMainType;
private EntityType srcEntity;
private DynamicObject srcActiveRow;
private String srcFieldKey;
private BigDecimal currVal;
private BigDecimal realVal;
private Object currCVal;
private EntityType targetEntity;
private DynamicObject targetActiveRow;
private BFRowId targetRowId;
/**
* 构造函数
* @param rule 反写规则
* @param ruleItem 反写公式
* @param srcSubMainType 上游源单主实体,仅包含需要用到的字段
* @param srcEntity 上游源单,关联主实体
* @param srcActiveRow 上游源单,关联主实体数据行
* @param srcFieldKey 上游源单反写字段
* @param currVal 本次操作,对源单行执行的反写差量
* @param realVal 本次操作执行完毕完后,对源单行的反写总量
* @param currCVal 覆盖反写值
* @param targetEntity 下游目标单关联主实体
* @param targetActiveRow 下游目标单关联主实体,当前数据行
*/
public AfterCommitAmountEventArgs(WriteBackRuleElement rule, WriteBackFormula ruleItem,
BillEntityType srcSubMainType, EntityType srcEntity, DynamicObject srcActiveRow,
String srcFieldKey, BigDecimal currVal, BigDecimal realVal, Object currCVal,
EntityType targetEntity, DynamicObject targetActiveRow) {
this.rule = rule;
this.ruleItem = ruleItem;
this.srcSubMainType = srcSubMainType;
this.srcEntity = srcEntity;
this.srcActiveRow = srcActiveRow;
this.srcFieldKey = srcFieldKey;
this.currVal = currVal;
this.realVal = realVal;
this.currCVal = currCVal;
this.targetEntity = targetEntity;
this.targetActiveRow = targetActiveRow;
}
/**
* 反写规则
* @return
*/
@KSMethod
public WriteBackRuleElement getRule() {
return rule;
}
/**
* 反写公式
* @return
*/
@KSMethod
public WriteBackFormula getRuleItem() {
return ruleItem;
}
/**
* 上游源单主实体,仅包含需要用到的字段
* @return
*/
@KSMethod
public BillEntityType getSrcSubMainType() {
return srcSubMainType;
}
/**
* 上游源单,关联主实体
* @return
*/
@KSMethod
public EntityType getSrcEntity() {
return srcEntity;
}
/**
* 上游源单,关联主实体数据行
* @return
*/
@KSMethod
public DynamicObject getSrcActiveRow() {
return srcActiveRow;
}
/**
* 上游源单反写字段
* @return
*/
@KSMethod
public String getSrcFieldKey() {
return srcFieldKey;
}
/**
* 本次操作,对源单行执行的反写差量:公式计算出的反写量 - 上一次保存已执行的反写量;如果是删除行,反冲历史量
* @return
*/
@KSMethod
public BigDecimal getCurrVal() {
return currVal;
}
/**
* 本次操作执行完毕完后,对源单行的反写总量;如果是删除行,反写总量 = 0;
* @return
*/
@KSMethod
public BigDecimal getRealVal() {
return realVal;
}
/**
* 覆盖反写值
* @return
*/
@KSMethod
public Object getCurrCVal() {
return currCVal;
}
/**
* 下游目标单关联主实体
* @return
*/
@KSMethod
public EntityType getTargetEntity() {
return targetEntity;
}
/**
* 下游目标单关联主实体,当前数据行;删除行时,这个属性可能没值
* @return
*/
@KSMethod
public DynamicObject getTargetActiveRow() {
return targetActiveRow;
}
/**
* 下游目标单关联行信息:删除操作,可以据此从数据库取到删除前的行数据
* @return
*/
@KSMethod
public BFRowId getTargetRowId() {
return targetRowId;
}
/**
* 设置下游目标单关联行
* @param targetRowId 目标单关联行
*/
@KSMethod
public void setTargetRowId(BFRowId targetRowId) {
this.targetRowId = targetRowId;
}
}
```
- 示例
暂无示例。
9. beforeExcessCheck事件
- 事件触发时机
- 对源单行反写执行完毕,超额检查前,触发此事件。
- 用于取消超额检查
- 代码模板
```java
public class BeforeExcessCheck extends AbstractWriteBackPlugIn {
@Override
public void beforeExcessCheck(BeforeExcessCheckEventArgs e) {
// TODO 在此添加业务逻辑
}
}
```
- 事件参数
```java
public class BeforeExcessCheckEventArgs extends WriteBackEventArgs {
private WriteBackRuleElement rule;
private BillEntityType srcSubMainType;
private EntityType srcEntity;
private DynamicObject srcActiveRow;
private EntityType targetEntity;
private DynamicObject targetActiveRow;
private boolean cancel;
/**
* 构造函数
* @param rule 反写规则
* @param srcSubMainType 上游源单主实体,仅包含需要用到的字段
* @param srcEntity 上游源单,关联主实体
* @param srcActiveRow 上游源单,关联主实体数据行
* @param targetEntity 下游目标单关联主实体
* @param targetActiveRow 下游目标单关联主实体,当前数据行
*/
public BeforeExcessCheckEventArgs(WriteBackRuleElement rule,
BillEntityType srcSubMainType, EntityType srcEntity, DynamicObject srcActiveRow,
EntityType targetEntity, DynamicObject targetActiveRow) {
this.rule = rule;
this.srcSubMainType = srcSubMainType;
this.srcEntity = srcEntity;
this.srcActiveRow = srcActiveRow;
this.targetEntity = targetEntity;
this.targetActiveRow = targetActiveRow;
}
/**
* 反写规则
* @return
*/
@KSMethod
public WriteBackRuleElement getRule() {
return rule;
}
/**
* 上游源单主实体,仅包含需要用到的字段
* @return
*/
@KSMethod
public BillEntityType getSrcSubMainType() {
return srcSubMainType;
}
/**
* 上游源单,关联主实体
* @return
*/
@KSMethod
public EntityType getSrcEntity() {
return srcEntity;
}
/**
* 上游源单,关联主实体数据行
* @return
*/
@KSMethod
public DynamicObject getSrcActiveRow() {
return srcActiveRow;
}
/**
* 下游目标单关联主实体
* @return
*/
@KSMethod
public EntityType getTargetEntity() {
return targetEntity;
}
/**
* 下游目标单关联主实体,当前数据行;删除行时,这个属性可能没值
* @return
*/
@KSMethod
public DynamicObject getTargetActiveRow() {
return targetActiveRow;
}
/**
* 插件是否要求略过超额检查
* @return
*/
@KSMethod
public boolean isCancel() {
return cancel;
}
/**
* 设置插件是否要求略过超额检查
* @param cancel
*/
@KSMethod
public void setCancel(boolean cancel) {
this.cancel = cancel;
}
}
```
- 示例
暂无示例
10. afterExcessCheck事件
- 事件触发时机
- 对源单行反写执行完毕,超额检查完毕后,触发此事件。
- 用于控制是否中止反写、提示超额,修正提示内容。
- 代码模板
```java
public class AfterExcessCheck extends AbstractWriteBackPlugIn {
@Override
public void afterExcessCheck(AfterExcessCheckEventArgs e) {
// TODO 在此添加业务逻辑
}
}
```
- 事件参数
```java
public class AfterExcessCheckEventArgs {
private WriteBackRuleElement rule;
private BillEntityType srcSubMainType;
private EntityType srcEntity;
private DynamicObject srcActiveRow;
private EntityType targetEntity;
private DynamicObject targetActiveRow;
private boolean excess;
private String message;
public AfterExcessCheckEventArgs(WriteBackRuleElement rule,
BillEntityType srcSubMainType, EntityType srcEntity, DynamicObject srcActiveRow,
EntityType targetEntity, DynamicObject targetActiveRow) {
this.rule = rule;
this.srcSubMainType = srcSubMainType;
this.srcEntity = srcEntity;
this.srcActiveRow = srcActiveRow;
this.targetEntity = targetEntity;
this.targetActiveRow = targetActiveRow;
}
/**
* 反写规则
* @return
*/
@KSMethod
public WriteBackRuleElement getRule() {
return rule;
}
/**
* 上游源单主实体,仅包含需要用到的字段
* @return
*/
@KSMethod
public BillEntityType getSrcSubMainType() {
return srcSubMainType;
}
/**
* 上游源单,关联主实体
* @return
*/
@KSMethod
public EntityType getSrcEntity() {
return srcEntity;
}
/**
* 上游源单,关联主实体数据行
* @return
*/
@KSMethod
public DynamicObject getSrcActiveRow() {
return srcActiveRow;
}
/**
* 下游目标单关联主实体
* @return
*/
@KSMethod
public EntityType getTargetEntity() {
return targetEntity;
}
/**
* 下游目标单关联主实体,当前数据行;删除行时,这个属性可能没值
* @return
*/
@KSMethod
public DynamicObject getTargetActiveRow() {
return targetActiveRow;
}
/**
* 是否超额;插件可以调整此属性值,决定是否显示超额提示
* @return
*/
@KSMethod
public boolean isExcess() {
return excess;
}
/**
* 设置是否超额
* @param excess 是否超额
*/
@KSMethod
public void setExcess(boolean excess) {
this.excess = excess;
}
/**
* 超额提示
* @return
*/
@KSMethod
public String getMessage() {
return message;
}
/**
* 设置超额提示
* @param message 超额提示
*/
@KSMethod
public void setMessage(String message) {
this.message = message;
}
}
```
- 示例
暂无示例
11. beforeCloseRow事件
- 事件触发时机
- 关闭上游行前,触发此事件。
- IsCancelCheck==true,则不再做关闭条件检查。
- 代码模板
```java
public class BeforeCloseRow extends AbstractWriteBackPlugIn {
@Override
public void beforeCloseRow(BeforeCloseRowEventArgs e) {
// TODO 在此添加业务逻辑
}
}
```
- 事件参数
```java
public class BeforeCloseRowEventArgs extends WriteBackEventArgs {
private WriteBackRuleElement rule;
private BillEntityType srcSubMainType;
private EntityType srcEntity;
private DynamicObject srcActiveRow;
private EntityType targetEntity;
private DynamicObject targetActiveRow;
private boolean cancel;
/**
* 构造函数
* @param rule 反写规则
* @param srcSubMainType 上游源单主实体,仅包含需要用到的字段
* @param srcEntity 上游源单,关联主实体
* @param srcActiveRow 上游源单,关联主实体数据行
* @param targetEntity 下游目标单关联主实体
* @param targetActiveRow 下游目标单关联主实体,当前数据行
*/
public BeforeCloseRowEventArgs(WriteBackRuleElement rule,
BillEntityType srcSubMainType, EntityType srcEntity, DynamicObject srcActiveRow,
EntityType targetEntity, DynamicObject targetActiveRow) {
this.rule = rule;
this.srcSubMainType = srcSubMainType;
this.srcEntity = srcEntity;
this.srcActiveRow = srcActiveRow;
this.targetEntity = targetEntity;
this.targetActiveRow = targetActiveRow;
}
/**
* 反写规则
* @return
*/
@KSMethod
public WriteBackRuleElement getRule() {
return rule;
}
/**
* 上游源单主实体,仅包含需要用到的字段
* @return
*/
@KSMethod
public BillEntityType getSrcSubMainType() {
return srcSubMainType;
}
/**
* 上游源单,关联主实体
* @return
*/
@KSMethod
public EntityType getSrcEntity() {
return srcEntity;
}
/**
* 上游源单,关联主实体数据行
* @return
*/
@KSMethod
public DynamicObject getSrcActiveRow() {
return srcActiveRow;
}
/**
* 下游目标单关联主实体
* @return
*/
@KSMethod
public EntityType getTargetEntity() {
return targetEntity;
}
/**
* 下游目标单关联主实体,当前数据行;删除行时,这个属性可能没值
* @return
*/
@KSMethod
public DynamicObject getTargetActiveRow() {
return targetActiveRow;
}
/**
* 插件是否要求略过超额检查
* @return
*/
@KSMethod
public boolean isCancel() {
return cancel;
}
/**
* 设置插件是否要求略过超额检查
* @param cancel
*/
@KSMethod
public void setCancel(boolean cancel) {
this.cancel = cancel;
}
}
```
- 示例
暂无示例。
12. afterCloseRow事件
- 事件触发时机
对上游行进行了关闭状态填写后,触发此事件。
- 代码模板
```java
public class AfterCloseRow extends AbstractWriteBackPlugIn {
@Override
public void afterCloseRow(AfterCloseRowEventArgs e) {
// TODO 在此添加业务逻辑
}
}
```
- 事件参数
```java
public class AfterCloseRowEventArgs extends WriteBackEventArgs {
private WriteBackRuleElement rule;
private BillEntityType srcSubMainType;
private EntityType srcEntity;
private DynamicObject srcActiveRow;
private EntityType targetEntity;
private DynamicObject targetActiveRow;
private boolean closeRow;
/**
* 构造函数
* @param rule 反写规则
* @param srcSubMainType 上游源单主实体,仅包含需要用到的字段
* @param srcEntity 上游源单,关联主实体
* @param srcActiveRow 上游源单,关联主实体数据行
* @param targetEntity 下游目标单关联主实体
* @param targetActiveRow 下游目标单关联主实体,当前数据行
*/
public AfterCloseRowEventArgs(WriteBackRuleElement rule,
BillEntityType srcSubMainType, EntityType srcEntity, DynamicObject srcActiveRow,
EntityType targetEntity, DynamicObject targetActiveRow) {
this.rule = rule;
this.srcSubMainType = srcSubMainType;
this.srcEntity = srcEntity;
this.srcActiveRow = srcActiveRow;
this.targetEntity = targetEntity;
this.targetActiveRow = targetActiveRow;
}
/**
* 反写规则
* @return
*/
@KSMethod
public WriteBackRuleElement getRule() {
return rule;
}
/**
* 上游源单主实体,仅包含需要用到的字段
* @return
*/
@KSMethod
public BillEntityType getSrcSubMainType() {
return srcSubMainType;
}
/**
* 上游源单,关联主实体
* @return
*/
@KSMethod
public EntityType getSrcEntity() {
return srcEntity;
}
/**
* 上游源单,关联主实体数据行
* @return
*/
@KSMethod
public DynamicObject getSrcActiveRow() {
return srcActiveRow;
}
/**
* 下游目标单关联主实体
* @return
*/
@KSMethod
public EntityType getTargetEntity() {
return targetEntity;
}
/**
* 下游目标单关联主实体,当前数据行;删除行时,这个属性可能没值
* @return
*/
@KSMethod
public DynamicObject getTargetActiveRow() {
return targetActiveRow;
}
/**
* 是否达成行关闭条件
* @return
*/
@KSMethod
public boolean isCloseRow() {
return closeRow;
}
/**
* 设置中是否达成行关闭条件
* @param closeRow 是否达成行关闭条件
*/
@KSMethod
public void setCloseRow(boolean closeRow) {
this.closeRow = closeRow;
}
}
```
- 示例
暂无示例
13. beforeSaveTrans事件
- 事件触发时机
- 反写逻辑处理完毕,开始开启事务,保存反写数据前,触发此事件。
- 供插件在事务前读取并处理第三方数据,以便在随后开启的事务中一并保存
- 代码模板
```java
public class BeforeSaveTrans extends AbstractWriteBackPlugIn {
@Override
public void beforeSaveTrans(BeforeSaveTransEventArgs e) {
// TODO 在此添加业务逻辑
}
}
```
- 事件参数
```java
public class BeforeSaveTransEventArgs extends WriteBackEventArgs {
}
```
- 示例
暂无示例
14. beforeSaveSourceBill事件
- 事件触发时机
- 反写规则执行完毕后,源单数据保存到数据库之前,触发此事件。
- 代码模板
```java
public class BeforeSaveSourceBill extends AbstractWriteBackPlugIn {
@Override
public void beforeSaveSourceBill(BeforeSaveSourceBillEventArgs e) {
// TODO 在此添加业务逻辑
}
}
```
- 事件参数
```java
ublic class BeforeSaveSourceBillEventArgs extends WriteBackEventArgs {
private BillEntityType srcSubMainType;
private DynamicObject[] srcDataEntities;
private boolean newThread;
/**
* 构造函数
* @param srcSubMainType 源单主实体,只包含了部分用到的字段
* @param srcDataEntities 源单数据包,只包含了部分用到的字段
*/
public BeforeSaveSourceBillEventArgs(BillEntityType srcSubMainType, DynamicObject[] srcDataEntities) {
this.srcSubMainType = srcSubMainType;
this.srcDataEntities = srcDataEntities;
}
/**
* 源单主实体,只包含了部分用到的字段
* @return
*/
@KSMethod
public BillEntityType getSrcSubMainType() {
return srcSubMainType;
}
/**
* 源单数据包,只包含了部分用到的字段
* @return
*/
@KSMethod
public DynamicObject[] getSrcDataEntities() {
return srcDataEntities;
}
/**
* 当前事件是否由异步线程触发,不在事务内:跨库反写时,会启动一个异步线程,在事务外单独的保存源单反写结果,没有事务保护,不能回滚数据。
* 此时插件抛出异常并不能取消反写,回滚数据。因此,此场景下插件要确保不抛出异常
* @return
*/
public boolean isNewThread() {
return newThread;
}
public void setNewThread(boolean newThread) {
this.newThread = newThread;
}
}
```
- 示例
暂无示例
15. afterSaveSourceBill事件
- 事件触发时机
- 源单数据保存到数据库后,触发此事件。
- 代码模板
```java
public class AfterSaveSourceBill extends AbstractWriteBackPlugIn {
@Override
public void afterSaveSourceBill(AfterSaveSourceBillEventArgs e) {
// TODO 在此添加业务逻辑
}
}
```
- 事件参数
```java
public class AfterSaveSourceBillEventArgs extends WriteBackEventArgs {
private BillEntityType srcSubMainType;
private DynamicObject[] srcDataEntities;
private boolean newThread;
/**
* 构造函数
* @param srcSubMainType 源单主实体,只包含了部分用到的字段
* @param srcDataEntities 源单数据包,只包含了部分用到的字段
*/
public AfterSaveSourceBillEventArgs(BillEntityType srcSubMainType, DynamicObject[] srcDataEntities) {
this.srcSubMainType = srcSubMainType;
this.srcDataEntities = srcDataEntities;
}
/**
* 源单主实体,只包含了部分用到的字段
* @return
*/
@KSMethod
public BillEntityType getSrcSubMainType() {
return srcSubMainType;
}
/**
* 源单数据包,只包含了部分用到的字段
* @return
*/
@KSMethod
public DynamicObject[] getSrcDataEntities() {
return srcDataEntities;
}
/**
* 当前事件是否由异步线程触发,不在事务内:跨库反写时,会启动一个异步线程,在事务外单独的保存源单反写结果,没有事务保护,不能回滚数据。
* 此时插件抛出异常并不能取消反写,回滚数据。因此,此场景下插件要确保不抛出异常
* @return
*/
public boolean isNewThread() {
return newThread;
}
/**
* 设置当前事件是否由异步线程触发,不在事务内:跨库反写时,会启动一个异步线程,在事务外单独的保存源单反写结果,没有事务保护,不能回滚数据。
* @param newThread
*/
public void setNewThread(boolean newThread) {
this.newThread = newThread;
}
}
```
- 示例
暂无示例
16. rollbackSave事件
- 事件触发时机
- 保存失败,触发此事件
- 通知插件回滚数据
- 代码模板
```java
public class RollbackSave extends AbstractWriteBackPlugIn {
@Override
public void rollbackSave(RollbackSaveEventArgs e) {
// TODO 在此添加业务逻辑
}
}
```
- 示例
暂无示例
17. finishWriteBack事件
- 事件触发时机
- 反写所有逻辑已经执行完毕后,触发此事件
- 用于通知插件释放资源,如插件申请的网控
- 代码模板
```java
public class RollbackSave extends AbstractWriteBackPlugIn {
@Override
public void rollbackSave(RollbackSaveEventArgs e) {
// TODO 在此添加业务逻辑
}
}
```
- 示例
暂无示例
反写插件手册
# 反写插件手册## 1.场景BOTP反写规则可以应用在一对已绑定关联关系的单据上,通过配置反写规则使下游目标单在保存或审核时进行反写操作...
点击下载文档
上一篇:单据转换操作说明-反写规则配置 下一篇:反写规则说明
本文2024-09-23 00:25:02发表“云苍穹知识”栏目。
本文链接:https://wenku.my7c.com/article/kingdee-cangqiong-139320.html
您需要登录后才可以发表评论, 登录登录 或者 注册
最新文档
热门文章