
## 问题描述
缺料分析如何在完成分析后,附加统计计算相关的采购订单的未入库数量
## 实现方案
本插件的目的主要是基于缺料分析的分析功能完成后,按照缺料分析加载的供应表获取采购订单类型的供应,获取相关联的未审核采购入库单统计数量。原理是:在分析完成后自动调用的保存事件中加入二开插件执行客户化逻辑。注:本方案仅支持补丁号 PT-149006([8.1.0.20230608] 发布时间:2023/6/8)以后的版本,往前的历史版本获取不到每个子项分配的供应条目。
## 插件样例
扩展缺料分析单,在保存操作上注册新插件,源码参考以下:
其中,detailItems包含的属性可以参考表单【缺料分析子项明细】业务对象,需要加属性可以扩展该表单进行添加
供应表PrepareMtrlCalcBillView.SupplyData可以参考表单【备料运算单据】业务对象的页签分录【供给数据信息】,判定供应是什么类型按照一下属性
RelationFormId//供应单类型
BaseTotalQty;//该供应条目的总供应数量统计
RelationBillNo;//供应的单据编号
RelationInterId;//供应的单据内码
RelationEntryId;//单据分录内码
RelationFormId_Id;//供应单据的FORMID,如即时库存为STK_INVENTORY,采购订单为PUR_PurchaseOrder...
```csharp
using Kingdee.BOS;
using Kingdee.BOS.Core.DynamicForm.PlugIn;
using Kingdee.BOS.Core.DynamicForm.PlugIn.Args;
using Kingdee.BOS.Core.Metadata;
using Kingdee.BOS.Core.SqlBuilder;
using Kingdee.BOS.Orm.DataEntity;
using Kingdee.BOS.ServiceHelper;
using Kingdee.BOS.Util;
using Kingdee.K3.Core.MFG;
using Kingdee.K3.Core.MFG.EntityHelper;
using Kingdee.K3.MFG.Common.BusinessEntity.PRD;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SampleAppPlugIn
{
public class LackSaveGetNonAuditStocks : AbstractOperationServicePlugIn
{
//每个子项分配到的供应
Dictionary<string, List<PrepareMtrlCalcBillView.SupplyData>> dicSupplyDatas = new Dictionary<string, List<PrepareMtrlCalcBillView.SupplyData>>();
//每个子项现有的非库存预留关系
Dictionary<string, List<PrepareMtrlCalcBillView.SupplyData>> dicReserveLinkDatas = new Dictionary<string, List<PrepareMtrlCalcBillView.SupplyData>>();
Dictionary<long, DynamicObject> dicPPBOMEntrys = new Dictionary<long, DynamicObject>();
Dictionary<long, DynamicObject> dicSUBPPBOMEntrys = new Dictionary<long, DynamicObject>();
public override void BeginOperationTransaction(BeginOperationTransactionArgs e)
{
if (!this.Option.ContainsVariable("taskId"))
return;
if (!this.Option.ContainsVariable("CalModelData"))
return;
DynamicObject calModelData = this.Option.GetVariableValue<DynamicObject>("CalModelData");
if (calModelData == null)
{
return;
}
//全部自由匹配的供应
DynamicObjectCollection supplyDatas = calModelData.GetDynamicValue<DynamicObjectCollection>("SupplyData");
if (supplyDatas.IsEmpty())
{
return;
}
//按照子项明细分配的供应记录,包含:Item1子项明细数据包,Item2自由匹配的供应记录,Item3当前供应给当前子项明细的分配数量。
var supplyDetails = this.Option.GetVariableValue<List<Tuple<DynamicObject, PrepareMtrlCalcBillView.SupplyData, decimal>>>("SubSupplyDetails");
//还原已经按照标准产品逻辑摊分的供应数量
foreach (var supplyDetail in supplyDetails)
{
supplyDetail.Item2.BaseQty = supplyDetail.Item2.BaseSupplyQty = supplyDetail.Item2.BaseTotalQty;
}
dicSupplyDatas = supplyDetails.GroupBy(x => x.Item1.GetDynamicValue<string>("RowId")).ToDictionary(x => x.Key, v => v.Select(x => x.Item2).OrderBy(x => x.Priority).ToList());
//按照子项明细收集的非库存预留关系,包含:Item1子项明细数据包,Item2当次计算加载的预留关系,Item3当前预留供应给当前子项明细的分配数量
var reserveLinkSupplys = this.Option.GetVariableValue<List<Tuple<DynamicObject, PrepareMtrlCalcBillView.SupplyData, decimal>>>("ReserveLinkSupplys");
dicReserveLinkDatas = reserveLinkSupplys.GroupBy(x => x.Item1.GetDynamicValue<string>("RowId")).ToDictionary(x => x.Key, v => v.Select(x => x.Item2).ToList());
var MoEntrys = e.DataEntitys[0]["Entity"] as DynamicObjectCollection;
var dicMoEntrys = MoEntrys.GroupBy(x => string.Format("{0}_{1}_{2}_{3}", x.GetDynamicValue<string>("MoBillNo"), x.GetDynamicValue<long>("MoEntrySeq"), x.GetDynamicValue<long>("MoId"),
x.GetDynamicValue<long>("MoEntryId"))).ToDictionary(x => x.Key);
long fid = e.DataEntitys[0].GetDynamicValue<long>("Id");
var matchItemMeta = MetaDataServiceHelper.Load(this.Context, "PRD_PMPPBOMENTRY") as FormMetadata;
var qp = new QueryBuilderParemeter()
{
FormId = "PRD_PMPPBOMENTRY",
};
qp.FilterClauseWihtKey = string.Format("FID={0}", fid);
qp.SelectItems = SelectorItemInfo.CreateItems("FENTRYID");
var detailItems = BusinessDataServiceHelper.Load(this.Context, matchItemMeta.BusinessInfo.GetDynamicObjectType(), qp);//缺料子项明细
//收集采购类供应的采购订单内码
List<long> poIds = supplyDatas.Where(x => x.GetDynamicValue<string>("RelationFormId_Id")
== MFGFormIdConst.SubSys_SCM.PUR_PurchaseOrder).Select(x => x.GetDynamicValue<long>("RelationInterId")).ToList();
if (poIds.IsEmpty()) return;
var purchaseStockInDatas = G