需求背景
业务代码在对上游单据进行处理时,需要联查到某种特定的下游单据,一起做相关处理(如同步删除等)。
平台会在后台自动记录单据间的关联关系,并提供了服务接口,查询单据间关联关系。
本章介绍如何如何使用平台提供的服务接口,搜索特定的下游单据。
案例设计
假设源头核心单据是demo_botp1,需要搜索下游单据demo_botp2:
demo_botp1 审核时,自动下推生成了 demo_botp2;
现在要在删除demo_botp1时,找到下游单据demo_botp2并自动删除;
特别说明:
正常情况下,源单反审核、删除,都会增加是否下推检查,如果已经下推了,不允许反审核和删除。本示例为了演示效果,去掉了是否下推检查。
相关知识点
IsPush函数:操作校验器上,可以使用IsPush函数,检查有没有下级单据,如果有,应该禁止反审核、删除。
示例代码
案例实现思路:
开发单据demo_botp1的删除操作插件,派生自AbstractOperationServicePlugIn;
重写beginExecuteOperationTransaction方法,此方法在操作校验通过后,已经开启了事务保护时触发,在此事件中修改数据库数据,受事务保护。本示例是需要同步删除下游单据,如果失败,需要自动回滚,因此,需要把删除下游单据的代码,放在本事件中,受事务保护;
调用BFTrackerServiceHelper服务方法,传入本单主实体编码和单据内码,搜索本单的全部下游单据;从中获取需要同步删除的下游单据demo_botp2
调用删除服务,删除下游单据demo_botp2;
特别说明:
在beginExecuteOperationTransaction事件中,不能通过调用微服务方法删除其他单据,即事务不允许跨越微服务,只能使用本地调用的方式实现。
package kd.bos.plugin.sample.bill.billconvert.bizcase; import java.util.HashSet; import java.util.Map; import java.util.Set; import kd.bos.dataentity.OperateOption; import kd.bos.dataentity.entity.DynamicObject; import kd.bos.entity.operate.result.OperationResult; import kd.bos.entity.plugin.AbstractOperationServicePlugIn; import kd.bos.entity.plugin.args.BeginOperationTransactionArgs; import kd.bos.exception.KDBizException; import kd.bos.service.operation.OperationServiceImpl; import kd.bos.servicehelper.botp.BFTrackerServiceHelper; /** * 示例:演示自动找到并删除下游单据 * * @author rd_johnnyding * */ public class FindTargetBillOpPlugin extends AbstractOperationServicePlugIn { /** * 数据检查通过,启动事务保护,准备删除数据时,触发此事件 */ @Override public void beginOperationTransaction(BeginOperationTransactionArgs e) { if (e.getDataEntities().length == 0) { return; } // 获取当前单据(上游单据)的主实体编码、单据内码 String sourceEntityNumber = this.billEntityType.getName(); Set<Object> billIds = new HashSet<>(); for(DynamicObject dataEntity : e.getDataEntities()) { billIds.add(dataEntity.getPkValue()); } // 调用平台的服务,获取所有目标单及内码 Map<String, HashSet<Long>> targetBillIds = BFTrackerServiceHelper.findTargetBills(sourceEntityNumber, billIds.toArray(new Long[0])); if (targetBillIds.size() > 1) { // 有多种下游单据:不允许删除 throw new KDBizException("单据已经下推,不允许删除!"); } String botpbill2_EntityNumber = "demo_botp2"; if (targetBillIds.size() == 1 && !targetBillIds.containsKey(botpbill2_EntityNumber)) { // 有其他下游单据:不允许删除 throw new KDBizException("单据已经下推,不允许删除!"); } // 获取需要同步删除的demo_botpbill2单据内码 HashSet<Long> botpbill2_Ids = new HashSet<>(); if (targetBillIds.containsKey(botpbill2_EntityNumber)) { botpbill2_Ids = targetBillIds.get(botpbill2_EntityNumber); } if (!botpbill2_Ids.isEmpty()) { // 删除下游单据(本方法是在事务中,如果删除失败,可以回滚) // 要在事务中同步删除其他单据,不能调用微服务,只能本地调用, OperationServiceImpl delService = new OperationServiceImpl(); //OperationResult delResult = OperationServiceHelper.executeOperate(// 微服务调用 OperationResult delResult = delService.localInvokeOperation( "delete", // 操作名:删除 botpbill2_EntityNumber, // 单据主实体编码 botpbill2_Ids.toArray(), // 单据内码 OperateOption.create()); // 操作自定义参数包:可以用其携带各种自定义参数 if (delResult.getSuccessPkIds().size() < botpbill2_Ids.size()) { throw new KDBizException("同步删除下游单据失败!"); } } } }
推荐阅读