
【场景】由于反写是App层服务,不会创建源单视图模型,因此不会触发源单的值更新事件、实体服务规则等;
部分客户想通过反写修改单据体的字段的时候,同时触发该字段的值更新修改其他字段
【案例】采购订单反写采购申请单,触发值更新的案例分享
<1>变通案例1:通过复制多个反写规则同时反写
此场景适用于反写单据体的数量字段,同时汇总更新到单据头的数量字段
假定我们有一个反写规则是反写到单据体的数量

复制此规则,将反写上游单据字段修改为【汇总单据头字段】(通过反写变通实现单据体的汇总重新计算),如果存在超额判断,则把超额判断去掉,只保留反写

<2>变通案例2:通过插件代码,自行通过sql实现数据更新的逻辑,进行模拟值更新的更新逻辑,手动更新数据
这个案例不详细解析,可参考下
[保存成功后,手工反写](https://vip.kingdee.com/article/66164742058270464?productLineId=1)
<3>案例3:通过创建源单视图,进行值更新,并手工保存
a)数据准备:配置实体服务规则,单据体文本汇总到单据头
参考:[实体服务规则汇总](https://vip.kingdee.com/article/128865436997123328?productLineId=1&isKnowledge=2)

b)通过采购订单 保存的操作服务插件,将下游单据编号反写到明细,并触发值更新

```csharp
using Kingdee.BOS;
using Kingdee.BOS.Core.Bill;
using Kingdee.BOS.Core.DynamicForm;
using Kingdee.BOS.Core.DynamicForm.PlugIn;
using Kingdee.BOS.Core.DynamicForm.PlugIn.Args;
using Kingdee.BOS.Core.Metadata;
using Kingdee.BOS.Core.Metadata.EntityElement;
using Kingdee.BOS.Core.Metadata.FieldElement;
using Kingdee.BOS.Orm.DataEntity;
using Kingdee.BOS.ServiceHelper;
using System;
namespace DynamicFormPlugIn.Operation
{
[Kingdee.BOS.Util.HotUpdate]
public class ServicePlugIn_DataChanged : AbstractOperationServicePlugIn
{
public class KeyConst
{
public static string EntityKey = "FPOOrderEntry";//采购订单的明细
public static string LinkKey = "FPOOrderEntry_Link";
public static string Link_STableName = "STableName";
public static string Link_FSBillId = "SBillId";
public static string Link_FSId = "SId";
public static string SrcEntityKey = "FEntity";//申请单的明细
public static string SrcEntityField = "F_BHR_TextEntity";
}
/*
* 案例:采购订单反写采购申请单,反写的同时需要触发值更新事件的场景
*
*/
public override void BeginOperationTransaction(BeginOperationTransactionArgs e)
{
Entity entity = this.BusinessInfo.GetEntity(KeyConst.EntityKey);
Entity linkEntity = this.BusinessInfo.GetEntity(KeyConst.LinkKey);
foreach (var dataObj in e.DataEntitys)
{
/*
* <0>找到反写的源单内码
* 如果是直接上游可以通过link查找,如果是跨级可以通过携带源单内码进行查找
*
* 此案例:通过link实体处理
*/
if (dataObj == null)
continue;
if (!dataObj.DynamicObjectType.Properties.ContainsKey(entity.EntryName))
continue;
DynamicObjectCollection rowColl = dataObj[entity.EntryName] as DynamicObjectCollection;
if (rowColl == null || rowColl.Count <= 0)
continue;
if (!rowColl.DynamicCollectionItemPropertyType.Properties.ContainsKey(linkEntity.EntryName))
continue;
foreach (var rowObj in rowColl)
{
if (rowObj == null)
continue;
DynamicObjectCollection linkColl = rowObj[linkEntity.EntryName] as DynamicObjectCollection;
if (linkColl == null || linkColl.Count <= 0)
continue;
foreach (var linkObj in linkColl)
{
//仅处理采购申请单
string srcTableName = Kingdee.BOS.Util.ObjectUtils.Object2String(linkObj[KeyConst.Link_STableName]);
if (!string.Equals(srcTableName, "T_PUR_ReqEntry", StringComparison.OrdinalIgnoreCase))
continue;
int sbillId = Kingdee.BOS.Util.ObjectUtils.Object2Int(linkObj[KeyConst.Link_FSBillId]);
if (sbillId <= 0)
continue;
int sentryId = Kingdee.BOS.Util.ObjectUtils.Object2Int(linkObj[KeyConst.Link_FSId]);
if (sentryId <= 0)
continue;
//<1>根据源单内码,创建目标视图,调用字段更新并触发值更新事件
UpdateReq(sbillId, sentryId, Kingdee.BOS.Util.ObjectUtils.Object2String(dataObj["BillNo"]));
}
}
}
}
private void UpdateReq(int billId, int entryId, string updateVal)
{
IDynamicFormView dynamicFormView = CreateBillView(this.Context, "PUR_Requisition", billId.ToString());
if (dynamicFormView == null)
return;
Entity entity = dynamicFormView.BillBusinessInfo.GetEntity(KeyConst.SrcEnti