知识分享 - 如何通过插件携带第二个单据体到下游单据
金蝶云社区-JohnnyDing
JohnnyDing
3人赞赏了该文章 1.6万次浏览 未经作者许可,禁止转载编辑于2015年11月05日 16:18:38
summary-icon摘要由AI智能服务提供

本文介绍了在K/3 Cloud系统中,由于不支持同时携带两个单据体的数据下推,因此需要通过配置转换规则和编写插件来解决此问题。案例中设计了两张单据A和B,均包含主单据体FEntity和第二单据体FEntity2。主单据体字段已通过配置转换规则处理,而第二单据体(含文本字段F_JD_Text)需通过插件携带。文中给出了一个具体的插件代码示例,展示了如何在主单据体的字段携带完毕后,通过插件将源单的第二单据体数据加载并填写到目标单的第二单据体中。同时指出,该方法不适用于同一张源单同时下推为多张目标单的情况。

背景说明:
K/3 Cloud 不支持在下推时,同时携带两个单据体的数据;
因此,需要在转换规则上,配置好携带主单据体;
而辅助单据体的数据,需要在插件中自行携带;

案例说明:
本案例,设计了两张单据A和B,都有两个单据体,主单据体为FEntity,第二单据体为FEntity2;
主单据体的字段,已经配置的单据转换规则 - 字段映射关系;
而第二单据体,需要通过插件携带;
第二单据体仅有一个文本字段F_JD_Text;

特别说明:
本案例不适用于同一张源单同时下推为多张目标单的情况:
这样情况是分单了,而第二单据体,无法对应拆分;

示例代码:
//*********************************************
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;


using Kingdee.BOS;
using Kingdee.BOS.Util;
using Kingdee.BOS.Core;
using Kingdee.BOS.Core.Metadata;
using Kingdee.BOS.Core.Metadata.ConvertElement;
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.Core.SqlBuilder;
using Kingdee.BOS.Orm.DataEntity;
using Kingdee.BOS.Contracts;
using Kingdee.BOS.App;


namespace JDSample.ServicePlugIn.BillConvert
{
///


/// 携带其他单据体
///

[Description("携带其他单据体")]
public class S151105TakeOtherEntryConvPlug : AbstractConvertPlugIn
{
///
/// 主单据体的字段携带完毕,与源单的关联关系创建好之后,触发此事件
///

///
public override void OnAfterCreateLink(CreateLinkEventArgs e)
{
// 预先获取一些必要的元数据,后续代码要用到:
// 源单第二单据体
Entity srcSecondEntity = e.SourceBusinessInfo.GetEntity("FEntity2");

// 目标单第一单据体
Entity mainEntity = e.TargetBusinessInfo.GetEntity("FEntity");


// 目标单第二单据体
Entity secondEntity = e.TargetBusinessInfo.GetEntity("FEntity2");


// 目标单关联子单据体
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 srcBillIds = new HashSet();

// 开始到主单据体中,读取关联的源单内码
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 selector = new List();
selector.Add(new SelectorItemInfo("F_JD_Text"));
// TODO: 继续添加其他需要携带的字段,示例代码略

// 设置过滤条件
string filter = string.Format(" {0} IN ({1}) ",
e.SourceBusinessInfo.GetForm().PkFieldName,
string.Join(",", srcBillIds));
OQLFilter filterObj = OQLFilter.CreateHeadEntityFilter(filter);

// 读取源单
IViewService viewService = ServiceHelper.GetService();
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;

foreach (var srcEntryRow in srcEntryRows)
{
// 目标单添加新行,并接受源单字段值
DynamicObject newRow = new DynamicObject(secondEntity.DynamicObjectType);
secondEntryRows.Add(newRow);
// 填写字段值
newRow["F_JD_Text"] = srcEntryRow["F_JD_Text"];
// TODO: 逐个填写其他字段值,示例代码略
}
}
}
}
}
}