开发案例分享-单据转换之子单据体转换原创
金蝶云社区-Dave身份
Dave
34人赞赏了该文章 4,553次浏览 未经作者许可,禁止转载编辑于2021年11月24日 15:59:19
summary-icon摘要由AI智能服务提供

本文描述了在金蝶系统中配置子单据体转换时可能遇到的错误问题,特别是在旧版本中。为解决这个问题,提供了使用插件的方法。插件代码示例展示了如何在单据转换过程中通过插件获取源单数据,并在下推过程中处理数据转换,包括从源单据体中获取数据并赋值到目标单据体的相应位置。通过重写`OnGetSourceData`和`AfterConvert`方法,插件能够实现对单据转换过程的精确控制。

一、问题描述:


如下图,配置子单据体转换时会报错(目前7.6、7.7版本已经修复了这个,老版本会存在),如果出现这个报错,可以通过插件的形式进行处理

3.png

4.png


二、解决方法:可通过单据转换插件进行处理,

2.1、插件代码如下:

using Kingdee.BOS.App;

using Kingdee.BOS.Contracts;

using Kingdee.BOS.Core.Metadata.EntityElement;

using Kingdee.BOS.Orm.DataEntity;

using System;

using System.Linq;

using Kingdee.BOS.Core.Metadata;

using Kingdee.BOS.Core.Metadata.ConvertElement.PlugIn;

using Kingdee.BOS.Core.Metadata.ConvertElement.PlugIn.Args;

using System.ComponentModel;

 

 

namespace Dave.ConvertDemo.ServicePlugIn

{

    /// <summary>

    /// 按顺序输出单据转换-下推过程的插件事件

    /// </summary>

    [Kingdee.BOS.Util.HotUpdate]

    [Description("子单据体单据转换插件")]

    public class SubEntity : AbstractConvertPlugIn

    {

        private DynamicObject sourceBill = null;

        object fid;

        //获取源单数据

        public override void OnGetSourceData(GetSourceDataEventArgs e)

        {

            base.OnGetSourceData(e);

            fid = e.SourceData[0]["FId"];

            if (fid != null && !"".Equals(fid))

            {

                string sfilter = string.Format("FID = {0} ", fid.ToString());

                OQLFilter filter = OQLFilter.CreateHeadEntityFilter(sfilter);

                if (null == sourceBill)

                {

                    IViewService viewService = ServiceHelper.GetService<IViewService>();

                    sourceBill = viewService.Load(this.Context, e.SourceBusinessInfo.GetForm().Id, null, filter).FirstOrDefault();

                }

            }

        }

 

        // 下推携带

        public override void AfterConvert(Kingdee.BOS.Core.Metadata.ConvertElement.PlugIn.Args.AfterConvertEventArgs e)

        {

            base.AfterConvert(e);

            var headEntity = e.Result.FindByEntityKey("FBillHead");

            foreach (var extendedDataEntity in headEntity)

            {

                // 声明选中单据体集合数据

                DynamicObjectCollection entryCollection = null;

 

                // 目标的父单据体实体(标识)

                Entity entity = e.TargetBusinessInfo.GetEntity("FEntity");

 

                //目标父单据体的数据包(orm)

                entryCollection = extendedDataEntity.DataEntity["Entity"] as DynamicObjectCollection;

 

                // 源单父单据体数据包(orm)

                DynamicObjectCollection sourceObjCollection = sourceBill["TreeEntity"] as DynamicObjectCollection;

 

                //父单据体行数差值,计算此差值是针对:目标单上已录入几行父单据体之后再去选单。

                int difCount = entryCollection.Count;

 

                if (sourceBill != null)

                {

                    difCount -= sourceObjCollection.Count;

                }

 

                //从源单上获取每一条父单据体的子单据体集合,并赋值到目标单上对应的父单据体中。

                for (int i = 0; i < entryCollection.Count; i++)

                {

                    // 销售订单明细====父单据体实体

                    var entityData = entryCollection[i];

                    // 对应的订单明细索引

                    int index = entryCollection.IndexOf(entityData);

 

                    // 目标子单据体的实体(标识)

                    Entity FSubEntity = e.TargetBusinessInfo.GetEntity("F_QYGN_SubEntity");

                    // 目标子单据体的数据包(orm)

                    DynamicObjectCollection subCollection = entityData["F_QYGN_SubEntity"] as DynamicObjectCollection;

 

                    String[] SourceFeild = { "F_QYGN_SubText", "F_QYGN_SubDecimal", "F_QYGN_SubBase"  };

                    String[] GoalFeild = { "F_QYGN_SubText", "F_QYGN_SubDecimal", "F_QYGN_SubBase" };

                    // 调用公共方法

                    // 参数1:目标子单据体标识           参数2:目标父单据体的当前行的实体     参数3:源单父单据体的实体名 

                    // 参数4:源单子单据体实体名     参数5:要转换的字段名             参数6:当前行号

                    DynamicObjectCollection newRows = getSourceSubEntity(FSubEntity, entityData, "TreeEntity", "F_QYGN_SubEntity",

                        SourceFeild, GoalFeild, index - difCount);

                    if (subCollection == null)

                    {

                        subCollection = new DynamicObjectCollection(FSubEntity.DynamicObjectType, entityData);

                    }

                    else

                    {

                        subCollection.Clear();

                    }

                    int x = 1;

                    foreach (DynamicObject newRow in newRows)

                    {

                        newRow["Seq"] = x;

                        subCollection.Add(newRow);

                        x++;

                    }

                }

 

 

            }

        }

        /// <summary>

        /// 从源单中获取单据体当前行对应的子单据体的数据集合

        /// </summary>

        /// <param name="FSubEntity">子单据体标识</param>

        /// <param name="entityData">父单据体的当前行的实体</param>

        /// <param name="entityName">源单父单据体的实体名</param>

        /// <param name="subName">源单子单据体实体名</param>

        /// <param name="fieldNames">要转换的字段名(目标单需要与源单字段名完全一致。另外不要遗漏序号字段-标识为Seq)</param>

        /// <param name="index">当前行号</param>

        /// <returns></returns>

        private DynamicObjectCollection getSourceSubEntity(Entity FSubEntity, DynamicObject entityData, string entityName, string subName, string[] source, string[] goal, int index)

        {

            //创建一个目标单据体(包括父子单据体)

            DynamicObjectCollection newRows = new DynamicObjectCollection(FSubEntity.DynamicObjectType, entityData);

            //源单数据

            if (sourceBill != null)

            {

                //获取原单的父单据体数据包

                DynamicObjectCollection sourceObjCollection = sourceBill[entityName] as DynamicObjectCollection;

 

                if (sourceObjCollection != null)

                {//获取源子单据体的数据包集合

                    //  DynamicObject s = sourceObjCollection[index] as DynamicObject;

 

                    DynamicObjectCollection sourceSubCollection = (sourceObjCollection[index] as DynamicObject)[subName] as DynamicObjectCollection;

 

                    //循环元数据包

                    foreach (var sourceSubEntityData in sourceSubCollection)

                    {

                        //创建一个目标子单据体的数据包

                        DynamicObject newRow = new DynamicObject(FSubEntity.DynamicObjectType);

 

                        for (int i = 0; i < source.Length; i++)

                        {

                            newRow[goal[i]] = sourceSubEntityData[source[i]];

                        }

                        newRows.Add(newRow);

                    }

                }

            }

            return newRows;

        }

 

    }

}

 

2.2、将插件注册到单据转换中:

1.png

2.3、启用单据转换规则:

2.png

2.4、实现效果:

3.png

4.png


如有帮助,请点个赞呗

发布于 金蝶云星空BOS开发交流圈 社群

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