开发案例分享-单据转换之子单据体转换
一、问题描述:
如下图,配置子单据体转换时会报错(目前7.6、7.7版本已经修复了这个,老版本会存在),如果出现这个报错,可以通过插件的形式进行处理
二、解决方法:可通过单据转换插件进行处理,
2.1、插件代码如下:
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、将插件注册到单据转换中:
2.3、启用单据转换规则:
2.4、实现效果:
如有帮助,请点个赞呗
你好,子单据体中的数据确实可以带过来,可是审核后,在重新打开这个子单据,子单据体里面的基础资料是空的,请问有解决方法嘛
这个能支持多张订单一起下推么
填写好对应的标识、字段、ORM直接可用,我把格式化代码整理放压缩包了
大侠,复制成功,谢谢分享
学习了。
最后的方法,感觉注释不太好理解,newrows应该是目标子单数据包,newrow是目标子单的行数据包吧 这个插件只获取第一个原单,对于多个原单分组合并的怎么在插件里获取原单和目标单的对应关系?
【emoji】
真棒【emoji】
单据转换插件之子单据体携带【emoji】
共同交流学习
开发案例分享-单据转换之子单据体转换
本文2024-09-16 17:23:39发表“云星空知识”栏目。
本文链接:https://wenku.my7c.com/article/kingdee-k3cloud-15429.html