一些特殊字段,比如多选基础资料字段在反写规则配置中是不支持反写的,需要支持一般有两种方式:
一是使用反写引擎,配置一个反写规则,确保会走反写引擎,但没有实际意义,就像空操作一样,这样就不用去分析关联
关系和取上游数据,直接在相关的反写插件事件中处理自定义逻辑。
二是不走反写引擎,直接在单据操作事件中解析关联数据,根据关联数据取到上游数据包,在对上游数据包进行修改,
使用此逻辑一般使用操作插件来处理。
第二种方式需要考虑的操作场景比较多。建议用第一种方式。
下面介绍第一种方式,来反写多选基础资料字段。(上游单据A,下游单据B)
1. 扩展上下游单据。
2. 在上下游单据中分别加入一个整数字段,把下游单据的缺省值设置为100,并把所有的可见性去掉。
注:这里使用整数字段是因为只有累加和累减模式的反写规则在一起版本才会在任何操作走反写引擎,而覆盖模式在反向操作是不会走反写引擎的。
3.创建反写规则,把扩展的整数字段配置为上下游反写字段,操作选择保存,条件不填,模式为累加。
4. 编写反写插件代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.ComponentModel;
using Kingdee.BOS;
using Kingdee.BOS.Core;
using Kingdee.BOS.Util;
using Kingdee.BOS.Core.Metadata;
using Kingdee.BOS.Orm.DataEntity;
using Kingdee.BOS.BusinessEntity;
using Kingdee.BOS.Core.BusinessFlow;
using Kingdee.BOS.Core.BusinessFlow.PlugIn;
using Kingdee.BOS.Core.Metadata.FieldElement;
using Kingdee.BOS.Core.BusinessFlow.PlugIn.Args;
using Kingdee.BOS.BusinessEntity.BusinessFlow;
using Kingdee.BOS.App.Core;
namespace Kingdee.BOS.TestPlugIn.BillABillB
{
[Description("单据B反写插件")]
[Kingdee.BOS.Util.HotUpdate]
public class BillBWriteBackPlugIn : AbstractBusinessFlowServicePlugIn
{
//需要干预的反写规则
private bool _isNeedHandleRule = false;
/// <summary>
/// 反写前事件,每个反写规则走一次,得到需要干预反写规则
/// </summary>
/// <param name="e"></param>
public override void BeforeWriteBack(BeforeWriteBackEventArgs e)
{
this._isNeedHandleRule = false;
var ruleName = e.Rule.Name.ToString();
if (ruleName.EqualsIgnoreCase("单据B反写单据A-隐藏的整数字段"))
{
this._isNeedHandleRule = true;
}
}
/// <summary>
/// 加入需要反写的上游字段,反写取的是上游部分数据包,需要通过插件加入自定义需要处理的字段
/// </summary>
/// <param name="e"></param>
public override void AfterCustomReadFields(AfterCustomReadFieldsEventArgs e)
{
if (this._isNeedHandleRule)
{
e.AddFieldKey("F_PKMX_MulBase");//多选基础资料字段
}
}
/// <summary>
///反写条目反写后事件,每一行都会走
/// </summary>
/// <param name="e"></param>
public override void AfterCommitAmount(AfterCommitAmountEventArgs e)
{
base.AfterCommitAmount(e);
if (this._isNeedHandleRule)
{
//保存操作
if (this.OperationNumber.EqualsIgnoreCase("Save"))
{
var wbRule = e.WriteBackRuleRow as WRule<Id>;//反写条目
var tCurrDynObj = wbRule.Row.DataEntity;//下游单据当前行数据包
var tMaseField = this.BusinessInfo.GetField("F_PKMX_MulBase") as MulBaseDataField;//下游单据多选基础资料
var tPName = tMaseField.DynamicProperty.Name;
var tMObjs = tMaseField.DynamicProperty.GetValue(tCurrDynObj) as DynamicObjectCollection;//下游单据多选基础资料值
var sMBaseField = e.SourceBusinessInfo.GetField("F_PKMX_MulBase") as MulBaseDataField;//上游单据多选基础资料
var sPName = sMBaseField.DynamicProperty.Name;
var smObjs = sMBaseField.RefEntityDynamicProperty.GetValue(e.SourceActiveRow) as DynamicObjectCollection;
smObjs.Clear();
SequenceReader sr = new SequenceReader(this.Context); //取内码
var pkIds = sr.GetSequence("PKMX_T_Cust_WorkerEntry", tMObjs.Count).ToArray();
int index = 0;
foreach (var obj in tMObjs)
{
var sDynObj = new DynamicObject(sMBaseField.RefEntityDynamicObjectType);
sDynObj[0] = pkIds[index];
sDynObj[sPName] = obj[tPName];
sDynObj[sPName + "_Id"] = obj[tPName + "_Id"];
smObjs.Add(sDynObj);
index++;
}
}
//删除操作
else if (this.OperationNumber.EqualsIgnoreCase("Delete"))
{
//上游单据多选基础资料
var sourceMulBaseField = e.SourceBusinessInfo.GetField("F_PKMX_MulBase") as MulBaseDataField;/
var sourceRow = e.SourceActiveRow;
var mulDynObjs = sourceMulBaseField.RefEntityDynamicProperty.GetValue(sourceRow) as DynamicObjectCollection;
//清空上游单据多选基础资料值
mulDynObjs.Clear();
}
}
}
}
}
推荐阅读