BOTP 应用场景开发介绍原创
金蝶云社区-MiLai
MiLai
8人赞赏了该文章 1,944次浏览 未经作者许可,禁止转载编辑于2021年04月02日 09:27:12

BOTP是Business Object TransformPlatform的缩写,是基于业务对象(Business Object)技术的数据转换平台。

本文以具体场景入手,介绍如何通过开发来解决BOTP应用中遇到的业务问题。

本文的读者是业务开发、二次开发人员,需要掌握java语言,熟悉单据、操作插件开发,了解BOTP业务。

场景:后台自动下推

需求背景

源单需要在审核通过后自动生成下游单据。

这个需求,正常情况下,可以通过配置实现,无需开发代码,配置方法: 修改源单的审核操作,配置操作服务,添加自动下推服务。

某些特殊情况,无法通过配置实现自动下推,那么就得自行开发代码,调用单据转换服务,实现下推。

本章介绍如何调用下推服务,下推并保存目标单,然后获取下推生成的目标单,执行提交、审核操作;

案例设计

假设有源单,标识为demo_bill1;有两条数据,内码为10001、10002;

需要自动生成目标单,标识demo_bill2;

源单和目标单之间,已经建立并启用了转换规则,关联主实体设为单据体1(entryentity),并配置好了字段映射关系。

相关知识点

实现上述需求,需要用到如下类:

  • PushArg:下推参数,允许指定好源单、目标单标识,源单需要下推的数据行,以及下推时采用的转换规则等;

  • ConvertServiceHelper:单据转换帮助类,提供push,pushAndSave方法实现下推;

  • ConvertOperateResult:下推服务返回的结果,包含生成的目标单数据包,或目标单内码,以及下推失败的错误信息;

  • OperateionServiceHelper:操作服务帮助类,可以完成目标单的提交、审核等操作;

示例代码

示例代码逻辑思路:

  • 包装下推参数PushArgs

  • 调用下推引擎,下推并保存目标单,获取下推结果

  • 判断下推结果

  • 调用提交操作服务,提交目标单;获取提交结果

  • 判断提交结果

示例代码(仅用于演示如何调用下推、保存、提交等服务,未实际跑通)


package kd.bos.plugin.sample.bill.billconvert.bizcase;
import java.util.ArrayList;
import java.util.List;
import kd.bos.data.BusinessDataReader;
import kd.bos.dataentity.OperateOption;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.metadata.IDataEntityType;
import kd.bos.entity.EntityMetadataCache;
import kd.bos.entity.MainEntityType;
import kd.bos.entity.botp.runtime.ConvertOperationResult;
import kd.bos.entity.botp.runtime.PushArgs;
import kd.bos.entity.botp.runtime.SourceBillReport;
import kd.bos.entity.datamodel.IRefrencedataProvider;
import kd.bos.entity.datamodel.ListSelectedRow;
import kd.bos.entity.operate.OperateOptionConst;
import kd.bos.entity.operate.result.IOperateInfo;
import kd.bos.entity.operate.result.OperationResult;
import kd.bos.exception.KDBizException;
import kd.bos.servicehelper.botp.ConvertServiceHelper;
import kd.bos.servicehelper.operation.OperationServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;
/**
 * 示例代码:自动生成目标单
 *
 * @author rd_johnnyding
 *
 */
public class AutoPushSample {
    private final static String DEMO_BILL1 = "demo_bill1";
    private final static String DEMO_BILL2 = "demo_bill2";
    /**
     * 演示自动生成并提交目标单
     */
    @SuppressWarnings("unused")
    public void autoPushAndSubmit() {
        // 创建下推参数,把源单demo_bill1的两张单据10001, 10002,下推生成目标单demo_bill2
        PushArgs pushArgs = new PushArgs();
        pushArgs.setSourceEntityNumber(DEMO_BILL1);        // 必选,源单标识
        pushArgs.setTargetEntityNumber(DEMO_BILL2);        // 必选,目标单标识
        pushArgs.setHasRight(false);        // 可选,传入true,不检查目标单新增权
        pushArgs.setAppId("");                // 可选,传入目标单验权使用的应用编码
        pushArgs.setDefOrgId(0L);            // 可选,传入目标单主组织默认值
        pushArgs.setRuleId("");                // 可选,传入本次下推使用的转换规则id;传入空值,由系统自动寻找合适的转换规则
        pushArgs.setBuildConvReport(true);    // 是否输出详细错误报告
        // 设置需要下推的单据,或分录行
        List<ListSelectedRow> selectedRows = new ArrayList<>();
        ListSelectedRow srcBill1 = new ListSelectedRow(10001L);
        srcBill1.setEntryEntityKey("");            // 可选,如按分录行下推必填:填单据体标识如entryentity
        srcBill1.setEntryPrimaryKeyValue(0L);    // 可选,如按分录行下推必填:填分录行内码如10001
        selectedRows.add(srcBill1);
        ListSelectedRow srcBill2 = new ListSelectedRow(10002L);
        selectedRows.add(srcBill2);
        pushArgs.setSelectedRows(selectedRows);        // 必选,设置需要下推的源单及分录内码
        // 调用下推引擎,下推目标单
        ConvertOperationResult pushResult = ConvertServiceHelper.push(pushArgs);
        // 判断下推是否成功,如果失败,提炼失败消息输出
        if (!pushResult.isSuccess()) {
            String errMessage = pushResult.getMessage();    // 错误摘要
            for(SourceBillReport billReport : pushResult.getBillReports()) {
                // 演示如何提取各单错误报告
                if (!billReport.isSuccess()) {
                    String billMessage = billReport.getFailMessage();
                }
            }
            throw new KDBizException("下推失败:" + errMessage);
        }
        // 获取生成的目标单数据包
        MainEntityType targetMainType = EntityMetadataCache.getDataEntityType(DEMO_BILL2);
        List<DynamicObject> targetBillObjs = pushResult.loadTargetDataObjects(new IRefrencedataProvider() {
            @Override
            public void fillReferenceData(Object[] objs, IDataEntityType dType) {
                BusinessDataReader.loadRefence(objs, dType);
            }
        },     targetMainType);
        // 设置保存参数,调用目标单保存服务,保存目标单(保存时自动反写源单)
        OperateOption saveOption = OperateOption.create();
        saveOption.setVariableValue(OperateOptionConst.IGNOREWARN, String.valueOf(true));    // 不执行警告级别校验器
        saveOption.setVariableValue(OperateOptionConst.IGNOREINTERACTION, String.valueOf(true));    // 不显示交互提示,自动执行到底
        saveOption.setVariableValue(OperateOptionConst.STRICTVALIDATION, String.valueOf(true));        // 全部校验通过才保存
        OperationResult saveResult = SaveServiceHelper.saveOperate(
                DEMO_BILL2,
                targetBillObjs.toArray(new DynamicObject[0]),
                saveOption);
        // 判断保存结果
        if (!saveResult.isSuccess()) {
            String errMessage = saveResult.getMessage();    // 错误摘要
            // 演示提取保存详细错误
            for(IOperateInfo errInfo: saveResult.getAllErrorOrValidateInfo()) {
                String detailMessage = errInfo.getMessage();
            }
            throw new KDBizException("保存失败:" + errMessage);
        }
        // 设置提交操作,调用目标单提交服务
        OperateOption submitOption = OperateOption.create();
        submitOption.setVariableValue(OperateOptionConst.IGNOREWARN, String.valueOf(true));    // 不执行警告级别校验器
        submitOption.setVariableValue(OperateOptionConst.IGNOREINTERACTION, String.valueOf(true));    // 不显示交互提示,自动执行到底
        submitOption.setVariableValue(OperateOptionConst.STRICTVALIDATION, String.valueOf(true));        // 全部校验通过才保存
        OperationResult submitResult = OperationServiceHelper.executeOperate(
                "submit",
                DEMO_BILL2,
                saveResult.getSuccessPkIds().toArray(),
                submitOption);
        // 判断提交结果
        if (!submitResult.isSuccess()) {
            String errMessage = submitResult.getMessage();    // 错误摘要
            // 演示提取提交详细错误
            for(IOperateInfo errInfo: submitResult.getAllErrorOrValidateInfo()) {
                String detailMessage = errInfo.getMessage();
            }
            throw new KDBizException("提交失败:" + errMessage);
        }
    }
}


赞 8