BOTP场景:搜索源单原创
金蝶云社区-MiLai
MiLai
18人赞赏了该文章 896次浏览 未经作者许可,禁止转载编辑于2021年04月06日 08:32:49

需求背景

业务代码在对下游单据进行处理时,常常需要找到源头的核心单据(例如订单),根据核心单据的数据状态等信息,决定业务逻辑。

核心单据和下游单据之间,经过了多次的单据转换(如A -> B -> C -> D ->…)。很不幸,在当前需要处理的下游单据上,并没有冗余字段记录源头核心单据的信息,无法通过本单上的字段值找到源单。

每次执行单据转换时,平台都会在后台自动记录单据之间的关联关系,并提供了相应的服务接口,查询各单之间的关系。上述需求,可以通过平台提供的服务接口实现。

说明:正因为平台会在后台自动记录单据之间的关联关系,在设计下游单据时,其实不需要考虑冗余太多字段,一层层携带、记录源头核心单据信息。

本章介绍如何使用平台提供的服务接口,搜索源单。

案例设计

假设源头核心单据是demo_botp1,当前处理的下游单据是demo_botp3:

  • demo_botp1 下推生成 demo_botp2;

  • demo_botp2 接着下推生成 demo_botp3;

  • 当前正在审核demo_botp3,需要找到源头的demo_botp1;

相关知识点

  • BFTrackerServiceHelper:平台封装的单据关联关系追踪服务,可以搜索源单、搜索目标单、搜索分录行的关联追溯树;

示例代码

案例实现思路:

  • 开发单据demo_botp3的审核操作插件,派生自AbstractOperationServicePlugIn;

  • 重写beforeExecuteOperationTransaction方法,此方法在操作校验通过,开启事务保护前触发,可以在此事件中,检查、整理数据;

  • 调用BFTrackerServiceHelper服务方法,传入本单主实体编码和单据内码,搜索本单的全部源单;从中获取需要查找的源单demo_botp1;

  • 根据取到的源头demo_botp1单据内码,进行后续处理。

特别说明:

本示例使用的BFTrackerServiceHelper.findSourceBills只是整体搜索出所有源单,未区分各单直接的对应关系,这在批量处理时会有限制。如果需要准确区分各单对应关系,需要使用BFTrackerServiceHelper.loadLinkUpNodes获取行级追溯树,然后从其中寻找源单,详细过程,请参阅另外一个场景、示例。


package kd.bos.plugin.sample.bill.billconvert.bizcase;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import kd.bos.entity.ExtendedDataEntity;
import kd.bos.entity.plugin.AbstractOperationServicePlugIn;
import kd.bos.entity.plugin.args.BeforeOperationArgs;
import kd.bos.servicehelper.botp.BFTrackerServiceHelper;
/**
 * 示例:在单据审核时,搜索源头单据
 * 
 * @author rd_johnnyding
 *
 */
public class FindSourceBillOpPlugin extends AbstractOperationServicePlugIn {
    /**
     * 开启事务保护前,触发本事件:对数据进行检查、整理
     */
    @Override
    public void beforeExecuteOperationTransaction(BeforeOperationArgs e) {
        if (e.getValidExtDataEntities().isEmpty()) {
            return;
        }
        // 获取当前单据(下游单据)的主实体编码、单据内码
        String targetEntityNumber = this.billEntityType.getName();
        Set<Object> billIds = new HashSet<>();
        for(ExtendedDataEntity dataEntity : e.getValidExtDataEntities()) {
            billIds.add(dataEntity.getBillPkId());
        }
        // 调用平台的服务,获取所有源单及其内码
        Map<String, HashSet<Long>> sourceBillIds = BFTrackerServiceHelper.findSourceBills(targetEntityNumber, billIds.toArray(new Long[0]));
        // 从所有源单中寻找需要的demo_botpbill1
        HashSet<Long> botpbill1_Ids = new HashSet<>();
        String botpbill1_EntityNumber = "demo_botp1";
        if (sourceBillIds.containsKey(botpbill1_EntityNumber)) {
            botpbill1_Ids = sourceBillIds.get(botpbill1_EntityNumber);
        }
        if (!botpbill1_Ids.isEmpty()) {
            // TODO 已经获取到了源头的demo_botpbill1单据内码,可以进行后续处理
        }
    }
}



赞 18