【API下推接口】---实现一行拆成多行原创
金蝶云社区-eris
eris
25人赞赏了该文章 6,659次浏览 未经作者许可,禁止转载编辑于2022年06月14日 11:16:03
summary-icon摘要由AI智能服务提供

本文档描述了通过调用API下推接口,在单据转换过程中根据自定义数据对单据行进行拆分的实现方法。要点包括:传入自定义数据作为拆分行依据,在转换插件的OnAfterCreateLink事件中获取并处理这些自定义数据,注意拆分行的依据、被拆分的字段及关联字段,以及创建和更新关联数据包时的特殊情况处理。示例中展示了如何通过webapi下推接口,并携带自定义参数(如基本单位数量),实现单据A下推单据B时按指定数量拆分单据体的具体实现代码。

实现说明

        调用API下推接口,根据传入的自定义数据,实现单据在转换过程中对行进行拆分。

要点:

      1. 下推接口传入自定义数据,作为拆分行依据。

      2. 在转换插件OnAfterCreateLink事件中取到自定义数据。

      3. 并在2中的事件处理相关的业务逻辑。

      4. 注意拆分行的依据和被拆分的字段以及被拆分的关联字段。

      5. 注意创建和更新关联数据包,如果被拆分的字段是控制字段,则需要更新关联数据包中的携带和反写。

示例参考

      通过webapi下推接口,并带自定义参数,实现单据A下推单据B,按基本单位数量10来拆分,基本单位数量字段在单据体中。

  1. 注册转换插件

    image.png

  2. 调用webapi下推接口

    image.png

  3. 查看下推结果

    image.png


转换插件代码参考

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using Kingdee.BOS;
using Kingdee.BOS.Core;
using Kingdee.BOS.DataEntity;
using Kingdee.BOS.Core.Bill;
using Kingdee.BOS.Contracts;
using Kingdee.BOS.ServiceHelper;
using Kingdee.BOS.Util;
using Kingdee.BOS.JSON;
using Kingdee.BOS.Orm.DataEntity;
using Kingdee.BOS.Core.DynamicForm;
using Kingdee.BOS.Core.Metadata;
using Kingdee.BOS.Core.DynamicForm.PlugIn;
using Kingdee.BOS.Core.Metadata.FieldElement;
using Kingdee.BOS.Core.Metadata.FormElement;
using Kingdee.BOS.Core.Metadata.EntityElement;
using Kingdee.BOS.Core.Metadata.ConvertElement.PlugIn;
using Kingdee.BOS.Core.Metadata.ConvertElement.PlugIn.Args;
using Kingdee.BOS.Orm.Metadata.DataEntity;
namespace Kingdee.BOS.TestPlugIn
{
    [Kingdee.BOS.Util.HotUpdate]
    [Description("单据A到单据B单转换插件")]
    public class BillAConvertBillBPlugIn : AbstractConvertPlugIn
    {
        //控制字段Key和属性集合
        private List<DynamicProperty> _lstProperys = null;
        /// <summary>
        /// 单据转换之后事件
        /// </summary>
        /// <param name="e"></param>
        public override void AfterConvert(AfterConvertEventArgs e)
        {
            //行拆分依据
            long splitNumber = 0;
         //  webapi下推接口中的自定义参数,CustomParams={"FBaseQty":10}
            this.Option.TryGetVariableValue<long>("FBaseQty", out splitNumber);
            if (splitNumber == 0) return; //分录行拆分数量
            var field = e.TargetBusinessInfo.GetField("FBaseQty"); //基本单据数量字段
            var entryEntity = field.Entity; //字段所在的单据体
            //得到单据数据包扩展集合
            var billDynObjExs = e.Result.FindByEntityKey("FBillHead");
            var tView = CreateView(e.TargetBusinessInfo.GetForm().Id); //创建目标单据视图
            var targetLinkSet = e.TargetBusinessInfo.GetForm().LinkSet;
            var targetLinConfig= targetLinkSet.LinkEntitys[0]; //平台只支持一个关联实体,故取第一个关联设置就可以
            var targetLinkEntity = e.TargetBusinessInfo.GetEntity(targetLinConfig.Key); //关联实体
            this.InitLinkFieldProperty(targetLinkEntity, targetLinConfig, e.TargetBusinessInfo); //初始化关联字段属性
            foreach (var billDynObjEx in billDynObjExs) //循环数据包扩展集合
            {
                var billDynObj = billDynObjEx.DataEntity; //单个单据数据包
                tView.Model.DataObject = billDynObj; //给模型设置数据包
                var entryDynObjs = entryEntity.DynamicProperty.GetValue(billDynObj) as DynamicObjectCollection; //得到字段所在实体的数据包
                int rowIndex = 0; //分录行索引
               //拆分信息;原分录行索引,新增拆分的行数,最后一行值,来源单内码,来源单分录内码
                              Dictionary<int, Tuple<int, decimal, long, long>> dicSplitInfo = new Dictionary<int, Tuple<int, decimal, long, long>>();
                foreach (var rowObj in entryDynObjs) //循环分录
                {
                        var linkObjs=  rowObj[targetLinkEntity.Key] as DynamicObjectCollection;
                                        long sBillId = Int64.Parse(linkObjs[0]["SBillId"].ToString()); //来源单据内码
                                        long sId = Int64.Parse(linkObjs[0]["SId"].ToString());//来源分录内码
                    var sRealQty = decimal.Parse(Convert.ToString(field.DynamicProperty.GetValue(rowObj ))); //得到字段在此分录下的值
                    if (sRealQty > splitNumber) //如果值大于行拆分值
                    {
                        var rowCount = (int)(sRealQty % splitNumber > 0 ? sRealQty / splitNumber : sRealQty / splitNumber - 1); //需要新增拆分的行数
                        decimal leaveValue = sRealQty - splitNumber * rowCount; //剩余值
                        dicSplitInfo.Add(rowIndex, Tuple.Create(rowCount, leaveValue, sBillId, sId));
                }
                //复制拆分行,并设置拆分值
                int offsetRow = 0; //偏移数
                foreach (var item in dicSplitInfo)
                {
                    rowIndex = item.Key + offsetRow; //原分录行索引加偏移量在变动的数据包中的索引
                    var dynObj = entryDynObjs[rowIndex]; //原原分录行数据包
                    tView.Model.SetValue(field, dynObj, splitNumber); //这字段值并且会触发值更新事件
                    tView.InvokeFieldUpdateService(field.Key, rowIndex); //调用实体服务规则
                    offsetRow = 0; //偏移量重置
                   for (int i = 0; i < item.Value.Item1; i++)
                    {
                        tView.Model.CopyEntryRowFollowCurrent(field.Entity.Key, rowIndex + offsetRow, rowIndex, true); //rowIndex + offsetRow+1插入的位置;rowIndex复制行的位置;true,复制关联关系
                        int newRowIndex = rowIndex + offsetRow + 1; //新分录行索引
                        var fValue = i == item.Value.Item1 - 1 ? (item.Value.Item2 == 0 ? splitNumber : item.Value.Item2) : splitNumber;
                        //对单据体进行赋值
                        tView.Model.SetValue(field, entryDynObjs[newRowIndex], fValue); //这字段值并且会触发值更新事件
                        tView.InvokeFieldUpdateService(field.Key, newRowIndex); //调用实体服务规则
                        //关联数据包的处理
                        //处理关联数据包
                        var linkObjs = targetLinkEntity.DynamicProperty.GetValueFast(entryDynObjs[newRowIndex]) as DynamicObjectCollection;
                        // 控制字段处理
                        foreach (var fieldProperty in this._lstProperys)
                        {
                            foreach (var linkObj in linkObjs)
                            {
                               fieldProperty .SetValue(linkObj, fValue);
                               linkObj["SBillId"] = item.Value.Item3;
                               linkObj["SId"] = item.Value.Item4;
                            }
                        }
                        offsetRow++;
                    }
                }
            }
        }
        /// <summary>
        /// 初始化关联字段属性
        /// </summary>
        /// <param name="targetLinkEntity"></param>
        private void InitLinkFieldProperty(Entity targetLinkEntity, LinkEntity targetLinkEntitySet, BusinessInfo targetBInfo)
        {
            // 关联实体的字段属性
            DynamicObjectType linkEntityDT = targetLinkEntity.DynamicObjectType;
            this._lstProperys= new List<DynamicProperty>();
            foreach (var key in targetLinkEntitySet.WriteBackFieldKeys)
            {
                if (!this._lstProperys.ContainsKey(key))
                {
                    var field= targetBInfo.GetField(key);
                    this._lstProperys.Add(linkEntityDT.Properties[field.PropertyName]);
                }
            }
        }
        /// <summary>
        /// 创建单据视图  
        /// </summary>
        /// <param name="ctx"></param>
        /// <param name="metaData"></param>
        /// <returns></returns>
        public IDynamicFormView CreateView(string formId)
        {
            FormMetadata metadata = FormMetaDataCache.GetCachedFormMetaData(this.Context, formId);
            var OpenParameter = CreateOpenParameter(this.Context, metadata);
            var Provider = metadata.BusinessInfo.GetForm().GetFormServiceProvider(true);
            string importViewClass = "Kingdee.BOS.Web.Import.ImportBillView,Kingdee.BOS.Web";
            Type type = Type.GetType(importViewClass);
            IDynamicFormView view = (IDynamicFormView)Activator.CreateInstance(type);
            ((IDynamicFormViewService)view).Initialize(OpenParameter, Provider);
            return view;
        }
         /// <summary>
        /// 创建输入参数
        /// </summary>
        /// <param name="ctx"></param>
        /// <param name="metaData"></param>
        /// <returns></returns>
        private BillOpenParameter CreateOpenParameter(Context ctx, FormMetadata metaData)
        {
            Form form = metaData.BusinessInfo.GetForm();
            BillOpenParameter openPara = new BillOpenParameter(form.Id, metaData.GetLayoutInfo().Id);
            openPara = new BillOpenParameter(form.Id, string.Empty);
            openPara.C = ctx;
            openPara.ServiceName = form.FormServiceName;
            openPara.PageId = Guid.NewGuid().ToString();
            // 单据
            openPara.FormMetaData = metaData;
            openPara.LayoutId = metaData.GetLayoutInfo().Id;
            // 操作相关参数
            openPara.Status = OperationStatus.ADDNEW;
            openPara.PkValue = null;
            openPara.CreateFrom = CreateFrom.Default;
            openPara.ParentId = 0;
            openPara.GroupId = "";
            openPara.DefaultBillTypeId = null;
            openPara.DefaultBusinessFlowId = null;
            // 修改主业务组织无须用户确认
            openPara.SetCustomParameter("ShowConfirmDialogWhenChangeOrg", false);
            // 插件
            List<AbstractDynamicFormPlugIn> plugins = form.CreateFormPlugIns();
            openPara.SetCustomParameter(FormConst.PlugIns, plugins);
            return openPara;
        }
    }
}


图标赞 25
25人点赞
还没有人点赞,快来当第一个点赞的人吧!
图标打赏
0人打赏
还没有人打赏,快来当第一个打赏的人吧!