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

背景说明:
目前单据转换只支持单据头,一个单据体,一个子单据体的携带(可以配置多个子单据体携带,但只能携带一行)。
单据关联关系,源单可以是单据头,单据体,子单据体, 目标单据是关联配置中的单据实体(只能是单据头或单据体)
默认关联关系是:单据头--》单据头, 单据体--》单据体;可以使用插件干预使子单据体--》单据体,但无法干预为单据体--》子单据体,因为目标单只会用关联主实体去关联。
实现方式:
方式1、 通过转换插件,取原单另外一个实体数据包,自行解析赋值到目标单据实体
方式2、配置转换规则,调用下推转换,得到另外一个目标数据包,然后合并数据包
示例概况:
两个单据:单据A简称A,有单据体1,单据体2 ,子单据体1; 单据B简称B,有单据体1,单据体2 ,子单据体1,关联配置实体为单据体1
单据转换:A单据体1携带数据到B单据体1,并注册了单据A到单据B的转换插件
3. 两个反写规则:B单据体1中的基本单位数量反写A单据体1的基本单位数量, B单据体1中的基本单位数量反写A单据体2的基本单位数量
4. 目标:实现A单据体1和A单据体2同时携带数据到B单据体1,并分别创建关联关系。
示例过程说明:
A单据体1包含1条数据,A单据体2包含条数据

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

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

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

插件源码:
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格式
声明:除非特别标注,否则均为本站原创文章,转载时请以链接形式注明文章出处。如若本站内容侵犯了原著者的合法权益,可联系本站删除。
上一篇
已经是第一篇



