电脑桌面
添加蚂蚁七词文库到电脑桌面
安装后可以在桌面快捷访问

单据转换实现多单据体到目标单的携带和关联

来源:金蝶云社区作者:金蝶2024-09-2332

单据转换实现多单据体到目标单的携带和关联

背景说明:

  1. 目前单据转换只支持单据头,一个单据体,一个子单据体的携带(可以配置多个子单据体携带,但只能携带一行)。

  2. 单据关联关系,源单可以是单据头,单据体,子单据体, 目标单据是关联配置中的单据实体(只能是单据头或单据体)

  3. 默认关联关系是:单据头--》单据头, 单据体--》单据体;可以使用插件干预使子单据体--》单据体,但无法干预为单据体--》子单据体,因为目标单只会用关联主实体去关联。

实现方式:

     方式1、 通过转换插件,取原单另外一个实体数据包,自行解析赋值到目标单据实体

     方式2、配置转换规则,调用下推转换,得到另外一个目标数据包,然后合并数据包


示例概况:

  1. 两个单据:单据A简称A,有单据体1,单据体2 ,子单据体1;  单据B简称B,有单据体1,单据体2 ,子单据体1,关联配置实体为单据体1

  2. 单据转换:A单据体1携带数据到B单据体1,并注册了单据A到单据B的转换插件

   3. 两个反写规则:B单据体1中的基本单位数量反写A单据体1的基本单位数量, B单据体1中的基本单位数量反写A单据体2的基本单位数量

   4. 目标:实现A单据体1和A单据体2同时携带数据到B单据体1,并分别创建关联关系。


示例过程说明:

  1.  A单据体1包含1条数据,A单据体2包含条数据

image.webp

2. 单据A下推单据B,合并成3条分录。

image.webp

3. 单据B保存,分别反写A单据体1基本单位数量,A单据体2基本单位单位数量。

image.webp

4. 单据A下查也能查询到3条数据,故三条数据都创建了关联关系。

image.webp


插件源码:


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.Core.Const;
using Kingdee.BOS.Core.SqlBuilder;
using Kingdee.BOS.Orm.Metadata.DataEntity;
using Kingdee.BOS.BusinessEntity.BusinessFlow;
using Kingdee.BOS.Core.Metadata.ConvertElement;
 namespace Kingdee.BOS.TestPlugIn
{
    /// <summary>
    /// 实现两个单据体携带,并跟目标关联父实体创建关联数据包
    /// </summary>
    [HotUpdate]
    [Description("单据A到单据B转换插件")]
    public class BillAToBillBConvertPlugIn : AbstractConvertPlugIn
    {
        //关联数据包相关字段的说明和示例可以参考:https://vip.kingdee.com/article/158703
        // 关联实体,流程图
        private DynamicProperty _linkFlowIdProperty = null;
        // 关联实体,流程路线
        private DynamicProperty _linkFlowLineIdProperty = null;
        // 关联实体,转换规则
        private DynamicProperty _linkRuleIdProperty = null;
        // 关联实体,源单表格编码
        private DynamicProperty _linkSTableNameProperty = null;
        // 关联实体,源单单据内码
        private DynamicProperty _linkSBillIdProperty = null;
        // 关联实体,源单被关联实体内码,一般为分录内码
        private DynamicProperty _linkSIdProperty = null;
        //控制字段Key和属性集合
        private Dictionary<string, Tuple<DynamicProperty, DynamicProperty>> _dicProperys = null;
        public override void OnAfterCreateLink(CreateLinkEventArgs e)
        {
            base.OnAfterCreateLink(e);
            ///检查下游单据是否存在关联配置
            var targetLinkSet =e.TargetBusinessInfo.GetForm().LinkSet ;
            if (targetLinkSet == null || targetLinkSet.LinkEntitys == null || targetLinkSet.LinkEntitys.Count == 0)
            {
                return;
            }
            ///得到需要携带的第二个源单单据体数据
            Entity srcEntity2 = e.SourceBusinessInfo.GetEntity("FEntity2"); //第二个来源单单据实体
            var srcPkFieldName = e.SourceBusinessInfo.GetForm().PkFieldName; //来源单据主键字段名
            List<long> lstSrcPkValues = new List<long>();  //源单主键集合(单据内码)
            List<DynamicObject> lstSrcObjs = new List<DynamicObject>();//源单数据包集合
            var targetExDatas = e.TargetExtendedDataEntities.FindByEntityKey("FBillHead");  //目标单数据包集合
            targetExDatas.ToList().ForEach(x => lstSrcObjs.AddRange(x[BOSConst.ConvSourceExtKey] as List<DynamicObject>));
            lstSrcObjs.ForEach(x => lstSrcPkValues.Add(ObjectUtils.Object2Int64(x[srcPkFieldName])));
            //来源单单据体2数据包
            var srcEntity2DynObjs = this.GetEntity2DynamicObjs(lstSrcPkValues, e.SourceBusinessInfo, srcEntity2);
            if (srcEntity2DynObjs.Count == 0) return;
            ///把源单第二个单据体数据付给关联父实体
            var targetLinConfig = targetLinkSet.LinkEntitys[0]; //平台只支持一个关联实体,故取第一个关联设置就可以
            var targetLinkEntity = e.TargetBusinessInfo.GetEntity(targetLinConfig.Key); //关联实体
            var targetParentEntityKey = targetLinConfig.ParentEntityKey;  //目标单据关联父实体Key
            var targeLinktParentEntity = e.TargetBusinessInfo.GetEntity(targetParentEntityKey);  //目标单据关联父实体
            var srcEntity2TableDefine = this.GetTableDefine(e.SourceBusinessInfo.GetForm().Id, srcEntity2.Key); //第二个源单单据体表定义
            this.InitLinkFieldProperty(targetLinkEntity, targetLinConfig, e.TargetBusinessInfo); //初始化关联字段属性
            var convertRule = this.Option.GetVariableValue<ConvertRuleElement>("Rule"); //得到转换规则
            var tMaterialField = e.TargetBusinessInfo.GetField("FMaterial") as BaseDataField;
            var materialObjs = this.GetMaterialObjs(e.TargetBusinessInfo, tMaterialField, srcEntity2DynObjs);//基础资料数据包需要单独赋值,这里先记录相关信息
            //对目标单数据包进行循环,把源单第二个单据体数据付给目标关联父实体并创建关联数据包
            foreach (var exTargetData in targetExDatas)
            {
                List<long> currSrcPks = new List<long>(); //目标数据包对应的来源单据内码集合
                var targetBillObj = exTargetData.DataEntity;  //目标单整单数据包
                var currSrcObjs = exTargetData[BOSConst.ConvSourceExtKey] as List<DynamicObject>; //目标单对应的源单数据包集合
                currSrcObjs.ForEach(x => currSrcPks.Add(ObjectUtils.Object2Int64(x[srcPkFieldName])));
                //当前对应的第二个单据体数据包
                var currSrcEntity2Objs = srcEntity2DynObjs.Where(x => currSrcPks.Contains(ObjectUtils.Object2Int64(x[srcPkFieldName]))).ToList();
                if (currSrcEntity2Objs.Count == 0) continue;
                //这里目标单据的关联父实体数据报集合
                var targetLinkParentObjs = targeLinktParentEntity.DynamicProperty.GetValue(targetBillObj) as DynamicObjectCollection;
                //对来源单第二个单据体数据包进行循环
                foreach (var currSrcObj in currSrcEntity2Objs)
                {
                    var tObj = new DynamicObject(targeLinktParentEntity.DynamicObjectType);
                    var materialId = ObjectUtils.Object2Int64(currSrcObj["FEntry2Material"]);
                    tObj["Material_Id"] = materialId;//基础资料的赋值不仅仅要赋值Id 还要给引用数据报赋值
                    tObj[tMaterialField.PropertyName] = materialObjs.First(x => ObjectUtils.Object2Int64(x["Id"]) == materialId);
                    tObj["BaseQty"] = currSrcObj["FEntry2BaseQty"];
                    tObj["Entry1Note"] = currSrcObj["FEntry2Note"];
                    targetLinkParentObjs.Add(tObj);
                    //处理关联数据包
                    var linkObjs = targetLinkEntity.DynamicProperty.GetValueFast(tObj) as DynamicObjectCollection;
                    var targetLinkObj = new DynamicObject(targetLinkEntity.DynamicObjectType);
                    this._linkFlowIdProperty.SetValueFast(targetLinkObj, ""); // 业务流程图内码
                    this._linkFlowLineIdProperty.SetValueFast(targetLinkObj, 0);//流程路线
                    this._linkRuleIdProperty.SetValueFast(targetLinkObj, convertRule.Id); //转换规则
                    this._linkSTableNameProperty.SetValueFast(targetLinkObj, srcEntity2TableDefine.TableNumber);  // 来源单据体表编码
                    this._linkSBillIdProperty.SetValueFast(targetLinkObj, currSrcObj[srcPkFieldName]);                    //源单单据ID
                    this._linkSIdProperty.SetValueFast(targetLinkObj, currSrcObj[srcEntity2.Key + "_" + srcEntity2.EntryPkFieldName]); //源单第二个单据体内码
                    // 控制字段处理
                    foreach (var item in this._dicProperys)
                    {
                        item.Value.Item1.SetValue(targetLinkObj, currSrcObj[item.Key]);
                        item.Value.Item2.SetValue(targetLinkObj, currSrcObj[item.Key]);
                    }
                    linkObjs.Add(targetLinkObj);
                }
            }
        }
        /// <summary>
        /// 得到物料数据包
       /// </summary>
       /// <param name="tBInfo"></param>
       /// <param name="tMaterialField"></param>
       /// <param name="srcEntity2Objs"></param>
       /// <returns></returns>
        private DynamicObject[] GetMaterialObjs(BusinessInfo tBInfo,BaseDataField tMaterialField,  DynamicObjectCollection srcEntity2Objs)
        {
            var lstMaterialIds = srcEntity2Objs.Select

单据转换实现多单据体到目标单的携带和关联

背景说明:目前单据转换只支持单据头,一个单据体,一个子单据体的携带(可以配置多个子单据体携带,但只能携带一行)。单据关联关系,源单...
点击下载文档文档为doc格式

声明:除非特别标注,否则均为本站原创文章,转载时请以链接形式注明文章出处。如若本站内容侵犯了原著者的合法权益,可联系本站删除。

已经是第一篇
确认删除?
回到顶部
客服QQ
  • 客服QQ点击这里给我发消息
QQ群
  • 答案:my7c点击这里加入QQ群
支持邮箱
微信
  • 微信