开发案例分享-单据转换之多单据体转换原创
金蝶云社区-Dave身份
Dave
51人赞赏了该文章 8218次浏览 未经作者许可,禁止转载编辑于2021年11月24日 15:59:44

一、问题描述:


如下图,标准系统仅支持一个单据体的字段映射,配置多个单据体映射保存时报错

1.png

2.png


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


2.1、插件代码如下:

using System;

using System.Collections.Generic;

using System.ComponentModel;

using Kingdee.BOS.Core;

using Kingdee.BOS.Core.Metadata;

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

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

using Kingdee.BOS.Core.Metadata.EntityElement;

using Kingdee.BOS.Core.Metadata.FormElement;

using Kingdee.BOS.Orm.DataEntity;

using Kingdee.BOS.Contracts;

using Kingdee.BOS.App;

namespace Dave.ConvertDemo.ServicePlugIn

{

    /// <summary>

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

    /// </summary>

    [Kingdee.BOS.Util.HotUpdate]

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

    public class MulEntity : AbstractConvertPlugIn

    {

 

        //// <summary>

        /// 主单据体的字段携带完毕,与源单的关联关系创建好之后,触发此事件

        /// </summary>

        /// <param name="e"></param>

        public override void OnAfterCreateLink(CreateLinkEventArgs e)

        {

            // 预先获取一些必要的元数据,后续代码要用到:

            // 源单第二单据体

            Entity srcSecondEntity = e.SourceBusinessInfo.GetEntity("F_QYGN_Entity");

 

            // 目标单第一单据体

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

 

            // 目标单第二单据体

            Entity secondEntity = e.TargetBusinessInfo.GetEntity("F_QYGN_Entity");

 

            // 目标单关联子单据体

            Entity linkEntity = null;

            Form form = e.TargetBusinessInfo.GetForm();

            if (form.LinkSet != null

                && form.LinkSet.LinkEntitys != null

                && form.LinkSet.LinkEntitys.Count != 0)

            {

                linkEntity = e.TargetBusinessInfo.GetEntity(

                    form.LinkSet.LinkEntitys[0].Key);

            }

 

            if (linkEntity == null)

            {

                return;

            }

 

            // 获取生成的全部下游单据

            ExtendedDataEntity[] billDataEntitys = e.TargetExtendedDataEntities.FindByEntityKey("FBillHead");

 

 

            // 对下游单据,逐张单据进行处理

            foreach (var item in billDataEntitys)

            {

                DynamicObject dataObject = item.DataEntity;

 

                // 定义一个集合,用于收集本单对应的源单内码

                HashSet<long> srcBillIds = new HashSet<long>();

 

                // 开始到主单据体中,读取关联的源单内码

                DynamicObjectCollection mainEntryRows =

                    mainEntity.DynamicProperty.GetValue(dataObject) as DynamicObjectCollection;

                foreach (var mainEntityRow in mainEntryRows)

                {

                    DynamicObjectCollection linkRows =

                        linkEntity.DynamicProperty.GetValue(mainEntityRow) as DynamicObjectCollection;

                    foreach (var linkRow in linkRows)

                    {

                        long srcBillId = Convert.ToInt64(linkRow["SBillId"]);

                        if (srcBillId != 0

                            && srcBillIds.Contains(srcBillId) == false)

                        {

                            srcBillIds.Add(srcBillId);

                        }

                    }

                }

                if (srcBillIds.Count == 0)

                {

                    continue;

                }

                // 开始加载源单第二单据体上的字段

 

                // 确定需要加载的源单字段(仅加载需要携带的字段)

                List<SelectorItemInfo> selector = new List<SelectorItemInfo>();

                selector.Add(new SelectorItemInfo("F_QYGN_TestText"));

                selector.Add(new SelectorItemInfo("F_QYGN_TestDecimal"));

                selector.Add(new SelectorItemInfo("F_QYGN_TestDepartment"));

               

 

                // TODO: 继续添加其他需要携带的字段,示例代码略

                // 设置过滤条件

                string filter = string.Format(" {0} IN ({1}) ",

                    e.SourceBusinessInfo.GetForm().PkFieldName,

                    string.Join(",", srcBillIds));

                OQLFilter filterObj = OQLFilter.CreateHeadEntityFilter(filter);

 

                // 读取源单

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

                var srcBillObjs = viewService.Load(this.Context,

                    e.SourceBusinessInfo.GetForm().Id,

                    selector,

                    filterObj);

 

                // 开始把源单单据体数据,填写到目标单上

                DynamicObjectCollection secondEntryRows =

                    secondEntity.DynamicProperty.GetValue(dataObject) as DynamicObjectCollection;

                secondEntryRows.Clear();    // 删除空行

 

                foreach (var srcBillObj in srcBillObjs)

                {

                    DynamicObjectCollection srcEntryRows =

                        srcSecondEntity.DynamicProperty.GetValue(srcBillObj) as DynamicObjectCollection;

 

                    int i = 1;

                    foreach (var srcEntryRow in srcEntryRows)

                    {

                        // 目标单添加新行,并接受源单字段值

                        DynamicObject newRow = new DynamicObject(secondEntity.DynamicObjectType);

                        secondEntryRows.Add(newRow);

                        // 填写字段值

                        //序号

                        newRow["Seq"] = i;

                        //测试文本

                        newRow["F_QYGN_TestText"] = srcEntryRow["F_QYGN_TestText"];                     

                        //测试小数

                        newRow["F_QYGN_TestDepartment"] = srcEntryRow["F_QYGN_TestDepartment"];

                        //测试部门

                        newRow["F_QYGN_TestDecimal"] = srcEntryRow["F_QYGN_TestDecimal"];

                        i++;

                    }

 

                }

            }

        }

 

    }

}

 

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

1.png

 

2.3、启用单据转换规则:

2.png

2.4、实现效果:

3.png

4.png

5.png


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

赞 51