业务流程.二开案例.插件建立关联、删除关联

栏目:云星空知识作者:金蝶来源:金蝶云社区发布:2024-09-16浏览:1

业务流程.二开案例.插件建立关联、删除关联

【场景】一般的业务单据指定了link实体,如果下推的时候跟link无关,则无法关联。 针对这种场景目前标准产品无法实现 【案例】采购申请单下推采购订单,而后采购订单通过选单建立自定义关系 <0>数据准备 已经跟采购申请单关联的采购订单 ![Image_20230111202138.webp](/download/0100fb97523435ad47af84821cc760a57083.webp) <1>第二个关系建立准备 ![Image_20230111202229.webp](/download/010086b77b5fbcce4ad59de46ea1a1e669b7.webp) ![Image_20230111202250.webp](/download/010062d6c182c698417f872a4c4796581f99.webp) ![Image_20230111202311.webp](/download/0100cc8c6ac47b584843b4a1297e7e43cab7.webp) <2>支持选单选择其他单据填入到另外的实体;但是不会关联(仅携带) ![Image_20230111202845.webp](/download/0100f85551db55564a8091f37165e260a10d.webp) <3>通过操作服务插件保存时,保存自定义关联 ```csharp using Kingdee.BOS; using Kingdee.BOS.Core.DynamicForm.PlugIn; using Kingdee.BOS.Core.DynamicForm.PlugIn.Args; using Kingdee.BOS.ServiceHelper; using System; using System.Collections.Generic; namespace DynamicFormPlugIn.BillConvert { [Kingdee.BOS.Util.HotUpdate] [System.ComponentModel.Description("手动创建关联")] public class CreateBusinessFlowNodePlugIn : AbstractOperationServicePlugIn { public class KeyConst { public static string SrcForm = "k85eec12fa5f24be7800779a5cfa22efd"; public static string TgtForm = "PUR_PurchaseOrder"; public static string Field_SBillId = "F_BHR_Integer"; public static string Entity = "F_BHR_Entity"; } public override void OnPreparePropertys(PreparePropertysEventArgs e) { e.FieldKeys.Add(KeyConst.Field_SBillId); } /* * 手动创建关联关系 * 操作逻辑:每次比对历史数据和本次修改后数据包的关联记录 * 历史的没有则为新增,数据包没有的则为删除 * * 注意:由于业务流程有归档,因此本插件仅建议尽可能在归档业务前完成此逻辑, * 获取历史数据比对支持归档查询:https://wenku.my7c.com/article/71661049120113152?productLineId=1 * 删除不支持归档删除,仅支持在当前表删除;一般的保存操作会将归档数据激活还原到当前表,但是部分场景不会 * 因此如果需要长时间后还需要调整关联关系的话,只能将业务流程的归档时间调大 */ public override void EndOperationTransaction(EndOperationTransactionArgs e) { const string HeadKey = "FBillHead"; var srcTableDefine = BusinessFlowServiceHelper.LoadTableDefine(Context, KeyConst.SrcForm, HeadKey, true); var tgtTableDefine = BusinessFlowServiceHelper.LoadTableDefine(Context, KeyConst.TgtForm, HeadKey, true); Kingdee.BOS.Core.Metadata.EntityElement.Entity entity = this.BusinessInfo.GetEntity(KeyConst.Entity); Kingdee.BOS.Core.Metadata.FieldElement.Field field = this.BusinessInfo.GetField(KeyConst.Field_SBillId); foreach(var dataObj in e.DataEntitys) { int billId = Kingdee.BOS.Util.ObjectUtils.Object2Int(dataObj[0]); var entityRows = dataObj[entity.EntryName] as Kingdee.BOS.Orm.DataEntity.DynamicObjectCollection; if (entityRows.Count == 0) continue; Dictionary<int, List<string>> linkBillIds = SelectAllLinkNodes(srcTableDefine, tgtTableDefine, billId); HashSet<int> curLinkIds = new HashSet<int>(); foreach (var entityRow in entityRows) { int srcBillId = Kingdee.BOS.Util.ObjectUtils.Object2Int(entityRow[field.PropertyName]); curLinkIds.Add(srcBillId); if(linkBillIds.ContainsKey(srcBillId)) { continue; } CreateNode(srcTableDefine, srcBillId, tgtTableDefine, billId); } foreach(var hisBillId in linkBillIds) { if(curLinkIds.Contains(hisBillId.Key)) { continue; } foreach(var instId in hisBillId.Value) { DeleteNode(instId); } } } } /// <summary> /// 创建关联节点 /// </summary> /// <param name="srcForm"></param> /// <param name="srcBillId"></param> /// <param name="tgtForm"></param> /// <param name="tgtBillId"></param> private void CreateNode(Kingdee.BOS.BusinessEntity.BusinessFlow.TableDefine srcTd, int srcBillId, Kingdee.BOS.BusinessEntity.BusinessFlow.TableDefine tgtTd, int tgtBillId) { /* * 创建关联逻辑 * https://wenku.my7c.com/article/162633?productLineId=1 */ string instId = Guid.NewGuid().ToString(); string rootId = Guid.NewGuid().ToString(); string nodeId = Guid.NewGuid().ToString(); Kingdee.BOS.App.Data.SqlObject sqlInst, sqlRoot, sqlNode; List<Kingdee.BOS.App.Data.SqlObject> sqlObjList = new List<Kingdee.BOS.App.Data.SqlObject>(); { string strCreateInst = string.Format(@"INSERT INTO T_BF_INSTANCE (FINSTANCEID,FFLOWID,FSOURCEID,FMASTERID,FSTATUS,FFIRSTFORMID,FFIRSTBILLID,FFIRSTBILLNO,FSTARTTIME) VALUES (@InstId, '','',@InstId,'A',@SrcForm, @SrcBillId,'',GETDATE())"); List<SqlParam> paramInst = new List<SqlParam>(); paramInst.Add(new SqlParam("@InstId", KDDbType.AnsiString, instId)); paramInst.Add(new SqlParam("@SrcForm", KDDbType.AnsiString, srcTd.TableNumber)); paramInst.Add(new SqlParam("@SrcBillId", KDDbType.Int32, srcBillId)); sqlInst = new Kingdee.BOS.App.Data.SqlObject(strCreateInst, paramInst); sqlObjList.Add(sqlInst); } { string strCreateRoot = string.Format(@"INSERT INTO T_BF_INSTANCEENTRY (FROUTEID, FINSTANCEID, FLINEID, FSTABLENAME, FSID, FTTABLENAME, FTID, FFIRSTNODE, FCREATETIME) VALUES (@RouteId, @InstId, '', '', '', @SrcForm, @SrcBillId, 1, GETDATE())"); List<SqlParam> paramRoot = new List<SqlParam>(); paramRoot.Add(new SqlParam("@RouteId", KDDbType.AnsiString, rootId)); paramRoot.Add(new SqlParam("@InstId", KDDbType.AnsiString, instId)); paramRoot.Add(new SqlParam("@SrcForm", KDDbType.AnsiString, srcTd.TableNumber)); paramRoot.Add(new SqlParam("@SrcBillId", KDDbType.Int32, srcBillId)); sqlRoot = new Kingdee.BOS.App.Data.SqlObject(strCreateRoot, paramRoot); sqlObjList.Add(sqlRoot); } { string strCreateNode = string.Format(@"INSERT INTO T_BF_INSTANCEENTRY (FROUTEID, FINSTANCEID, FLINEID, FSTABLENAME, FSID, FTTABLENAME, FTID, FFIRSTNODE, FCREATETIME) VALUES (@RouteId, @InstId, '', @SrcForm, @SrcBillId, @TgtForm, @TgtBillId, 0, GETDATE())"); List<SqlParam> paramRoot = new List<SqlParam>(); paramRoot.Add(new SqlParam("@RouteId", KDDbType.AnsiString, nodeId)); paramRoot.Add(new SqlParam("@InstId", KDDbType.AnsiString, instId)); paramRoot.Add(new SqlParam("@SrcForm", KDDbType.AnsiString, srcTd.TableNumber)); paramRoot.Add(new SqlParam("@SrcBillId", KDDbType.Int32, srcBillId)); paramRoot.Add(new SqlParam("@TgtForm", KDDbType.AnsiString, tgtTd.TableNumber)); paramRoot.Add(new SqlParam("@TgtBillId", KDDbType.Int32, tgtBillId)); sqlNode = new Kingdee.BOS.App.Data.SqlObject(strCreateNode, paramRoot); sqlObjList.Add(sqlNode); } Kingdee.BOS.App.Data.DBUtils.ExecuteBatch(Context, sqlObjList); } /// <summary> /// 查询所有关联节点 /// </summary> /// <param name="srcTd"></param> /// <param name="tgtTd"></param> /// <param name="tgtBillId"></param> /// <returns></returns> private Dictionary<int, List<string>> SelectAllLinkNodes(Kingdee.BOS.BusinessEntity.BusinessFlow.TableDefine srcTd, Kingdee.BOS.BusinessEntity.BusinessFlow.TableDefine tgtTd, int tgtBillId) { Dictionary<int, List<string>> srcBillIds = new Dictionary<int, List<string>>(); string strSelectNodes = "SELECT FSID,FINSTANCEID FROM T_BF_INSTANCEENTRY WHERE FSTABLENAME = @FSTABLENAME AND FTTABLENAME = @FTTABLENAME AND FTID = @FTID"; List<SqlParam> paramLists = new List<SqlParam>(); paramLists.Add(new SqlParam("@FSTABLENAME", KDDbType.AnsiString, srcTd.TableNumber)); paramLists.Add(new SqlParam("@FTTABLENAME", KDDbType.AnsiString, tgtTd.TableNumber)); paramLists.Add(new SqlParam("@FTID", KDDbType.Int32, tgtBillId)); using (var dr = Kingdee.BOS.App.Data.DBUtils.ExecuteReader(this.Context, strSelectNodes, paramLists)) { while(dr.Read()) { int sid = Kingdee.BOS.Util.ObjectUtils.Object2Int(dr["FSID"]); string instId = Kingdee.BOS.Util.ObjectUtils.Object2String(dr["FINSTANCEID"]); if (srcBillIds.ContainsKey(sid)) { srcBillIds[sid].Add(instId); } else { srcBillIds.Add(sid, new List<string>() { instId }); } } } return srcBillIds; } /// <summary> /// 仅删除当前表的关联节点 /// 注意:由于这里使用的是自创建的流程,那么就直接根据实例ID整个删除; /// 如果存在往历史流程插入节点的,则应该按照示例ID加上节点ID删除 /// 注意2:由于是整个流程删除,一般的对应也不应该存在下游节点(而且就算下游还存在,删除上游的关联关系依然流程图是有问题的,根节点系统不会重置) /// </summary> private void DeleteNode(string instanceId) { string strDeleInst = "DELETE T_BF_INSTANCE WHERE FINSTANCEID = @FINSTANCEID "; List<SqlParam> paramInst = new List<SqlParam>(); paramInst.Add(new SqlParam("@FINSTANCEID", KDDbType.AnsiString, instanceId)); var sqlInst = new Kingdee.BOS.App.Data.SqlObject(strDeleInst, paramInst); string strDeleNode = "DELETE T_BF_INSTANCEENTRY WHERE FINSTANCEID = @FINSTANCEID "; List<SqlParam> paramNode = new List<SqlParam>(); paramNode.Add(new SqlParam("@FINSTANCEID", KDDbType.AnsiString, instanceId)); var sqlNode = new Kingdee.BOS.App.Data.SqlObject(strDeleNode, paramNode); List<Kingdee.BOS.App.Data.SqlObject> sqlObjList = new List<Kingdee.BOS.App.Data.SqlObject>() { sqlInst, sqlNode }; Kingdee.BOS.App.Data.DBUtils.ExecuteBatch(Context, sqlObjList); } } } ``` 【效果】 手动关联,删除关联正常 ![Image_20230111203737.webp](/download/01003c9e501572f74ea1aaa284ef54ab3504.webp) 【备注】开发方案的缺陷代码已注明

业务流程.二开案例.插件建立关联、删除关联

【场景】一般的业务单据指定了link实体,如果下推的时候跟link无关,则无法关联。针对这种场景目前标准产品无法实现【案例】采购申请单下推...
点击下载文档
确认删除?
回到顶部
客服QQ
  • 客服QQ点击这里给我发消息