BOTP场景:搜索下游单原创
金蝶云社区-MiLai
MiLai
12人赞赏了该文章 541次浏览 未经作者许可,禁止转载编辑于2021年4月6日 08:33:47

需求背景

业务代码在对上游单据进行处理时,需要联查到某种特定的下游单据,一起做相关处理(如同步删除等)。

平台会在后台自动记录单据间的关联关系,并提供了服务接口,查询单据间关联关系。

本章介绍如何如何使用平台提供的服务接口,搜索特定的下游单据。

案例设计

假设源头核心单据是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("同步删除下游单据失败!");
            }
        }        
    }
}


12