单据转换.二开案例.选单界面过滤已经选过的行

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

单据转换.二开案例.选单界面过滤已经选过的行

【场景】选单界面,过滤掉已经选单使用过的行,避免重复选择 如在采购订单中,选单采购申请单分录,确认后,继续选单,依然能够看到已选单的分录 ![image.webp](/download/0100b2c4c61f670d48e6ae1806bbfc627ba3.webp) 最终如果没有允许超额的会保存报错,而允许超额的可能会导致反写翻倍的场景 【案例】采购订单选单采购申请单,在采购申请单选单界面,针对已选单的分录,选单界面不再显示 <1>在上游的采购申请单,增加列表插件 实现思路 a)根据下游单据的数据包,通过link实体获取已经选中的源行,记录分录内码 b)根据已选源行分录内码过滤,使用not in 或者not exists ![image.webp](/download/0100191db44a94e24726a76748f0409c5c2f.webp) ```csharp using Kingdee.BOS.BusinessEntity.BusinessFlow; using Kingdee.BOS.Core.DynamicForm.PlugIn.Args; using Kingdee.BOS.Core.List.PlugIn; using Kingdee.BOS.Core.List.PlugIn.Args; using Kingdee.BOS.Core.Metadata; using Kingdee.BOS.Core.Metadata.EntityElement; using Kingdee.BOS.Orm.DataEntity; using Kingdee.BOS.Util; using System; using System.Collections.Generic; using System.Linq; namespace DynamicFormPlugIn.List { [Kingdee.BOS.Util.HotUpdate] [System.ComponentModel.Description("源单列表插件 - 选单控制可选数据过滤")] public class SelBillListPlugIn_FilterSelRow : AbstractListPlugIn { /* * 挂在源单列表插件 * 针对特定目标单据单据选单时, 过滤源单的主业务组织逻辑 */ /// <summary> /// 目标单 表单标识 /// </summary> string tgtFormId = "PUR_PurchaseOrder"; /// <summary> /// 是否选单界面 /// </summary> bool isSelBillSpec = false; /// <summary> /// 下游单据,关联的已选源单内码 /// </summary> Dictionary<string, List<int>> srcFormBillIds = new Dictionary<string, List<int>>(); public override void OnInitialize(InitializeEventArgs e) { if (this.ListView.OpenParameter.ListType == (int)Kingdee.BOS.Core.Enums.BOSEnums.Enu_ListType.SelBill) { if (this.View.ParentFormView == null) return; string parentFormId = this.View.ParentFormView.BillBusinessInfo.GetForm().Id; if (string.Equals(tgtFormId, parentFormId, StringComparison.OrdinalIgnoreCase)) { isSelBillSpec = true; // 根据 父视图单据界面的link实体,收集已经使用的源单行数据 CollectUseSrcRows(this.View.ParentFormView.BillBusinessInfo, this.View.ParentFormView.Model.DataObject, srcFormBillIds); } } } /// <summary> /// 收集已使用的源单行号 /// </summary> private static void CollectUseSrcRows(BusinessInfo businessInfo, DynamicObject billObj, Dictionary<string, List<int>> srcFormBillIds) { var billForm = businessInfo.GetForm(); if (billForm.LinkSet == null || billForm.LinkSet.LinkEntitys.Count == 0) return; // <0>收集关联源单对象和单据内码 foreach (var linkEntity in billForm.LinkSet.LinkEntitys) { if (linkEntity == null) continue; string entityKey = linkEntity.ParentEntityKey; var entity = businessInfo.GetEntryEntity(entityKey); if (entity == null) continue; var billData = billObj; if (billData == null) continue; // <1>获取link 实体的父实体数据包 var entityObjColl = GetEntityDynamicObject(businessInfo, billData, entity); for (int rowIdx = 0, rowCnt = entityObjColl.Count; rowIdx < rowCnt; ++rowIdx) { var entityRow = entityObjColl[rowIdx]; if (entityRow == null) continue; if (!entityRow.DynamicObjectType.Properties.ContainsKey(linkEntity.Key)) continue; // <2>根据link实体 收集 源单内码 源单对象 var linkObjCol = entityRow[linkEntity.Key] as DynamicObjectCollection; if (linkObjCol == null || linkObjCol.Count <= 0) continue; foreach (var linkObj in linkObjCol) { if (linkObj == null) continue; var linkSTableName = ObjectUtils.Object2String(linkObj["STableName"]); var linkSBillid = ObjectUtils.Object2Int(linkObj["SBillId"]); var linkSEntryid = ObjectUtils.Object2Int(linkObj["SId"]); if (linkSTableName.IsNullOrEmptyOrWhiteSpace()) continue; if (linkSEntryid == 0) continue; if (!srcFormBillIds.ContainsKey(linkSTableName)) srcFormBillIds[linkSTableName] = new List<int>(); srcFormBillIds[linkSTableName].Add(linkSEntryid); } } } } /// <summary> /// 获取目标实体的数据 /// </summary> /// <param name="billObj"></param> /// <param name="targetEntity"></param> /// <returns></returns> private static List<DynamicObject> GetEntityDynamicObject(BusinessInfo businessInfo, DynamicObject billObj, Entity targetEntity) { if (billObj == null) return null; List<DynamicObject> result = new List<DynamicObject>(); if (targetEntity is HeadEntity) { result.Add(billObj); return result; } if (targetEntity is SubHeadEntity) { if (billObj.DynamicObjectType.Properties.ContainsKey(targetEntity.EntryName)) { DynamicObjectCollection subHeadObj = billObj[targetEntity.EntryName] as DynamicObjectCollection; if (subHeadObj == null || subHeadObj.Count <= 0) return null; foreach (var subHeadObjItem in subHeadObj) { result.Add(subHeadObjItem); } return result; } return null; } Entity headEntity = businessInfo.Entrys.FirstOrDefault(x => x is HeadEntity); if (headEntity == null) return null; SubEntryEntity targetSubEntryEntity = targetEntity as SubEntryEntity; string parentEntityKey = targetSubEntryEntity == null ? headEntity.Key : targetSubEntryEntity.ParentEntityKey; ///实现思路,假设 A(单据头) B(单据体) C(子单据体) D(子子单据体)四级关系 ///从单据数据包 目标实体 和目标实体父实体的内码 获取 目标实体的所有数据 ///第一步获取搜索路径,第二步根据搜索路径存入所有目标实体的父实体数据包,将父实体数据包的所有子分录收集 EntryEntity entryEntity = targetEntity as EntryEntity;//先获取对应的搜索路径 Stack<EntryEntity> pathEntity = new Stack<EntryEntity>(); while ((entryEntity as SubEntryEntity) != null)//递归子单据体 { entryEntity = (entryEntity as SubEntryEntity).ParentEntity; pathEntity.Push(entryEntity); } List<DynamicObjectCollection> lastEntityCollection = new List<DynamicObjectCollection>(); DynamicObjectCollection billObjCollection = new DynamicObjectCollection(billObj.DynamicObjectType); billObjCollection.Add(billObj); lastEntityCollection.Add(billObjCollection); DynamicObjectCollection tempCollection = null; while (pathEntity.Count != 0) { EntryEntity tempEntity = pathEntity.Pop(); //递归BFS List<DynamicObjectCollection> tempEntityCollection = new List<DynamicObjectCollection>(); foreach (var lastEntityObjs in lastEntityCollection) { if (!lastEntityObjs.DynamicCollectionItemPropertyType.Properties.ContainsKey(tempEntity.EntryName)) continue; foreach (var lastEntityObj in lastEntityObjs) { tempCollection = lastEntityObj[tempEntity.EntryName] as DynamicObjectCollection; if (tempCollection == null || tempCollection.Count == 0) continue; tempEntityCollection.Add(tempCollection); } } lastEntityCollection = tempEntityCollection; } //这里是目标实体的父实体数据包集合,兼容了目标实体是单据体 foreach (var lastEntityObjs in lastEntityCollection) { if (!lastEntityObjs.DynamicCollectionItemPropertyType.Properties.ContainsKey(targetEntity.EntryName)) continue; foreach (var lastEntityObj in lastEntityObjs) { DynamicObjectCollection objColl = lastEntityObj[targetEntity.EntryName] as DynamicObjectCollection; if (objColl == null) continue; foreach (var obj in objColl) { result.Add(obj); } } } return result; } /// <summary> /// 追加过滤 /// </summary> /// <param name="e"></param> public override void AfterCreateSqlBuilderParameter(SqlBuilderParameterArgs e) { if (!isSelBillSpec) return; /* * 假定过滤实体为明细,这里与转换规则有关系,如果是明细下推就是明细关联 * 当然你也可以全部实体扫描,这里没有这个必要 */ Entity filterEntity = this.View.BillBusinessInfo.GetEntity("FEntity"); if (filterEntity == null) return; TableDefine tableDefine = Kingdee.BOS.ServiceHelper.BusinessFlowServiceHelper.LoadTableDefine(this.Context, this.View.BillBusinessInfo.GetForm().Id, filterEntity.Key); if (tableDefine == null) return; if (srcFormBillIds.ContainsKey(tableDefine.TableNumber)) { //todo 如果分录少的话可以这么写,直接not in,分录多的话这个地方会有些性能损耗 string sourceEntryPkKey = string.Concat(filterEntity.Key, "_", filterEntity.EntryPkFieldName); string filter = string.Format("{0} NOT IN ({1})", sourceEntryPkKey, string.Join(",", srcFormBillIds[tableDefine.TableNumber])); e.sqlBuilderParameter.FilterClauseWihtKey = e.sqlBuilderParameter.FilterClauseWihtKey.JoinFilterString(filter); } } } } ``` 【效果】选单界面过滤已选择行 ![image.webp](/download/0100d0f5dae94f584c3d9019629afd0b6fb2.webp)

单据转换.二开案例.选单界面过滤已经选过的行

【场景】选单界面,过滤掉已经选单使用过的行,避免重复选择如在采购订单中,选单采购申请单分录,确认后,继续选单,依然能够看到已选单的...
点击下载文档
确认删除?
回到顶部
客服QQ
  • 客服QQ点击这里给我发消息