小技巧 - 如何实现第三方下推
金蝶云社区-JANE
JANE
12人赞赏了该文章 1783次浏览 未经作者许可,禁止转载编辑于2018年05月16日 10:07:22

实际业务中,常常需要在单据A列表(表面上的源单)上,点击下推时,实际要由单据B(真实源单)下推生成单据C(真实目标单),此需求K/3 Cloud BOS称之为第三方下推。

典型的应用场景,如生产订单(表面上的源单)下推生产领料单,实际上是由生产用料清单(真实源单)下推生产领料单(真实目标单);

如下示例代码,以采购订单单据维护插件为例,演示第三方下推JDB(实际由JDA下推到JDB);以及第三方上查(实际由采购申请上查生产订单):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using Kingdee.BOS;
using Kingdee.BOS.Util;
using Kingdee.BOS.Core;
using Kingdee.BOS.Core.DynamicForm;
using Kingdee.BOS.Core.DynamicForm.PlugIn.Args;
using Kingdee.BOS.Core.Bill.PlugIn;
using Kingdee.BOS.Core.Bill.PlugIn.Args;
using Kingdee.BOS.Core.List;
using Kingdee.BOS.Core.List.PlugIn.Args;
using Kingdee.BOS.Core.Metadata.ConvertElement;
using Kingdee.BOS.BusinessEntity.BillTrack;
namespace JDSample.FormPlugIn.Bill
{
    /// <summary>
    /// 演示利用插件实现第三方下推
    /// </summary>
    /// <remarks>
    /// 第三方下推:在单据A列表(表面上的源单)上,点击下推,实际是要用单据B(真实源单)下推生成单据C(真实目标单);
    /// 关键点:
    /// 1. 要在单据A的下推界面上,添加单据C;
    /// 2. 要自行根据单据A的内码,找到单据B的内码,以此替换掉下推参数中的源单内码集合;
    /// 3. 要在单据A的下查界面,添加单据C;(要在单据C的上查界面,添加单据A);
    /// 4. 要在单据A下查界面,找到单据B的内码,然后找到单据C的内码,据此构建出单据C列表过滤条件;
    ///
    /// 本示例代码,要实现:
    /// 1. 在采购订单列表下推,实现自定义单据JDA到JDB的下推
    /// 2. 在采购订单列表下查,实现下查到JDB的数据
    /// </remarks>
    [Description("演示利用插件实现第三方下推")]
    public class ThirdPushEdit : AbstractBillPlugIn
    {
        /// <summary>
        /// JDA单据的FormId
        /// </summary>
        private const string JDAFormId = "0964b538-feea-46df-8e48-c7a78b6ca992";
        /// <summary>
        /// JDB单据的FormId
        /// </summary>
        private const string JDBFormId = "7f0e9b0e-915b-4b8d-84af-d175685ca1f6";
        /// <summary>
        /// 点击下推、上下查菜单之后,显示下推界面、联查界面之前触发
        /// </summary>
        /// <param name="e"></param>
        /// <remarks>
        /// 可以利用此事件,为下推界面添加目标单据
        /// </remarks>
        public override void OnShowConvertOpForm(ShowConvertOpFormEventArgs e)
        {
            base.OnShowConvertOpForm(e);
            if (e.ConvertOperation == FormOperationEnum.Push)
            {// 下推
                // 把 采购订单 -> JDB,替换为 JDA -> JDB
                this.DoPush(e);
            }
            else if (e.ConvertOperation == FormOperationEnum.Draw)
            {// 选单
                // 选单,把采购订单选采购申请单,替换为采购订单选生产订单
                this.DoDraw(e);
            }
            else if (e.ConvertOperation == FormOperationEnum.TrackDown)
            {// 下查
                // 采购订单 (表面上的源单) -> JDA (真实源单) -> JDB (真实目标单)
                this.DoTrackDown(e);
            }
            else if (e.ConvertOperation == FormOperationEnum.TrackUp)
            {// 上查
                // 采购订单 (真实目标单) -> 采购申请单 (真实源单) -> 生产订单 (表面上的源单)
                this.DoTrackUp(e);
            }
        }
        /// <summary>
        /// 在下推界面,确定好目标单,点击确定,开始下推后触发
        /// </summary>
        /// <param name="e"></param>
        /// <remarks>
        /// 可以利用此事件,调整源单内码;
        ///
        /// 本演示代码,本事件仅用于下推,
        /// 把采购订单的内码,替换为真实源单JDA单据内码
        /// </remarks>
        public override void OnGetConvertRule(GetConvertRuleEventArgs e)
        {
            base.OnGetConvertRule(e);
            if (e.ConvertOperation == FormOperationEnum.Push
                && e.TargetFormId.EqualsIgnoreCase(JDBFormId))
            {// 用户选择下推到JDB,采用的是第三方下推,需要把源单内码调整为JDA的内码
                // 根据实际业务关系,由当前选择的采购订单找到关联的JDA单据
                // 演示代码并没有这种关系,略过,直接填写具体的JDA单据内码
                List<ListSelectedRow> JDARows = new List<ListSelectedRow>();
                JDARows.Add(new ListSelectedRow("100019", "100019", 0, JDAFormId));
                // 把源单内码替换为JDA的内码
                e.SelectedRows = JDARows.ToArray();
            }
        }
        /// <summary>
        /// 联查界面,用户点击关联单据之后,触发本事件
        /// </summary>
        /// <param name="e"></param>
        /// <remarks>
        /// 可以利用此事件,调整关联单据内码,以控制关联单据列表的显示内容
        ///
        /// 本演示代码,本事件仅用于上查,
        /// 把真实源单采购申请单,替换为表面上的生产订单内码
        /// </remarks>
        public override void OnShowTrackResult(ShowTrackResultEventArgs e)
        {
            base.OnShowTrackResult(e);
            if (e.TrackOperation == FormOperationEnum.TrackUp)
            {// 上查
                if (e.TargetFormKey.EqualsIgnoreCase("PRD_MO"))
                {// 需要上查生产订单
                    // e.TrackResult 中存储了真实源单的信息,需要替换为表面上源单
                    // TODO: 根据e.TrackResult中的真实源单,寻找对应的表面上的源单
                    // 本演示代码,忽略上述寻找过程,直接替换为生产订单单据体内码100003
                    BillNode trackResult = BillNode.Create("PRD_MO", "", null);
                    trackResult.AddLinkCopyData(new List<string>() { "100003" });
                    
                    // 替换源单内码:由真实源单(采购申请单),替换为表面上的源单(生产订单)
                    e.TrackResult = trackResult;
                    // 替换之后,系统将显示上面指定的生产订单单据体行
                }
            }
        }
        /// <summary>
        /// 把 采购订单 -> JDB,替换为 JDA -> JDB
        /// </summary>
        /// <param name="e"></param>
        private void DoPush(ShowConvertOpFormEventArgs e)
        {
            // 把真实目标单(JDB),添加到可选下游单据列表
            ConvertBillElement JDBInfo = new ConvertBillElement();
            JDBInfo.FormID = JDBFormId;
            JDBInfo.Name = new LocaleValue("JD单据转换B");
            e.BillList.Add(JDBInfo);
            // 标记目标单(JDB)为第三方下推,其真实源单为JDA
            // 下推操作,ReplaceRelation构造参数说明:
            // ReplaceRelation(真实源单FormId, 真实目标单FormId);
            ReplaceRelation JDAToJDB = new ReplaceRelation(JDAFormId, JDBFormId);
            e.ReplaceRelations.Add(JDAToJDB);
        }
        /// <summary>
        /// 选单,把采购订单选采购申请单,替换为采购订单选生产订单
        /// </summary>
        /// <param name="e"></param>
        private void DoDraw(ShowConvertOpFormEventArgs e)
        {
        }
        /// <summary>
        /// 在采购订单上查生产订单,实际上由采购订单 (真实目标单) -> 采购申请单 (真实源单) -> 生产订单 (表面上的源单)
        /// </summary>
        /// <param name="e"></param>
        private void DoTrackUp(ShowConvertOpFormEventArgs e)
        {
            if (e.ConvertOperation == FormOperationEnum.TrackUp)
            {// 上查
                // 在上游单据列表中,增加生产订单:供用户双击查询生产订单
                ConvertBillElement PRD_MOInfo = new ConvertBillElement();
                PRD_MOInfo.FormID = "PRD_MO";
                PRD_MOInfo .Name = new LocaleValue("生产订单");
                e.BillList.Add(PRD_MOInfo );
                // 因为本单与生产订单并没有直接关系,需要借助真实源单(采购申请单)搭一个桥
                // 上查操作ReplaceRelation参数说明:
                // e.AddReplaceRelation(真实源单FormId(采购申请), 表面上的源单FormId(生产订单));
                // 用户双击生产订单时,系统会先找到真实的源单(采购申请)单,
                // 然后插件在OnShowTrackResult事件中,替换源单
                e.AddReplaceRelation("PUR_Requisition", "PRD_MO");
            }
        }
        /// <summary>
        /// 在采购订单上下查JDB,实际上由采购订单 (表面上的源单) -> JDA (真实源单) -> JDB (真实目标单)
        /// </summary>
        /// <param name="e"></param>
        private void DoTrackDown(ShowConvertOpFormEventArgs e)
        {
            // 把真实目标单(JDB),添加到可选下游单据列表
            ConvertBillElement JDBInfo = new ConvertBillElement();
            JDBInfo.FormID = JDBFormId;
            JDBInfo.Name = new LocaleValue("JD单据转换B");
            e.BillList.Add(JDBInfo);
            // 标记目标单(JDB)为第三方下推,其真实源单为JDA
            // 下推、选单操作,ReplaceRelation构造参数说明:ReplaceRelation(真实源单FormId, 真实目标单FormId);
            // 上查操作,ReplaceRelation构造参数说明:ReplaceRelation(真实源单FormId, 表面上的源单FormId);
            // 下查操作,ReplaceRelation构造参数说明:ReplaceRelation(真实源单FormId, 正式目标单FormId);
            ReplaceRelation JDAToJDB = new ReplaceRelation(JDAFormId, JDBFormId);
            // 当前采购订单分录内码
            JDAToJDB.TargetLinkId = new List<string>();
            JDAToJDB.TargetLinkId.Add("100047"); // 100047仅用于演示,实际运行时,需要取e.SelectedRows中的单据体内码
            // 对应的JDA单据体内码,联查时,将以此内码作为源单内码,搜索JDA下推的JDB单据
            JDAToJDB.SourceLinkId = new List<string>();
            JDAToJDB.SourceLinkId.Add("100017"); // 100017仅用于演示,实际运行时,需根据关系自行查找第三方源单的内码
            e.ReplaceRelations.Add(JDAToJDB);
        }
    }
}

赞 12