| using System; | 
| using System.Collections.Generic; | 
| using Kingdee.BOS.Util; | 
| using Kingdee.BOS.Core.Metadata; | 
| using Kingdee.BOS.Core.Metadata.EntityElement; | 
| using Kingdee.BOS.Core.DynamicForm.PlugIn; | 
| using Kingdee.BOS.Core.DynamicForm.PlugIn.Args; | 
| using Kingdee.BOS.Orm.DataEntity; | 
| using Kingdee.BOS.Contracts; | 
| using Kingdee.BOS.App; | 
| using Kingdee.BOS.Core.Metadata.FieldElement; | 
| using System.ComponentModel; | 
| using Kingdee.BOS.ServiceHelper; | 
| using Kingdee.K3.SCM.App; | 
|   | 
| namespace Demo.DynamicForm.PRD | 
| { | 
|     /// <summary> | 
|     /// 插件示例:引入销售出库单,建立与销售订单的关联 | 
|     /// </summary> | 
|     /// <remarks> | 
|     /// 要求: | 
|     /// 1. 需要引入单据体的源单类型、源单编号字段 | 
|     /// 2. 本插件挂在销售出库单的保存操作上 | 
|     /// 出库关联销售订单 | 
|     /// </remarks> | 
|     [Description("引入生产领料单,建立与生产订单的关联")] | 
|     [HotUpdate] | 
|     public class Pro_MaterialRequisitionAudit : AbstractOperationServicePlugIn | 
|     { | 
|         public override void OnPreparePropertys(PreparePropertysEventArgs e) | 
|         { | 
|             base.OnPreparePropertys(e); | 
|             e.FieldKeys.Add("FSrcBillType"); | 
|             e.FieldKeys.Add("FSrcBillNo"); | 
|             e.FieldKeys.Add("FID"); | 
|             e.FieldKeys.Add("FTreeEntity_FEntryID"); | 
|             e.FieldKeys.Add("FBillNo"); | 
|             e.FieldKeys.Add("FBFLowId"); | 
|             e.FieldKeys.Add("FMaterialId"); | 
|             e.FieldKeys.Add("FBaseUnitQty"); | 
|             e.FieldKeys.Add("FBaseJoinQty"); | 
|         } | 
|         private const string POFormId = "PRD_PPBOM"; | 
|         public override void BeforeExecuteOperationTransaction(BeforeExecuteOperationTransaction e) | 
|         { | 
|             base.BeforeExecuteOperationTransaction(e); | 
|             HashSet<string> poBillNos = new HashSet<string>(); | 
|             Entity entity = this.BusinessInfo.GetEntity("FEntity");//获取明细信息 | 
|             Entity linkEntry = this.BusinessInfo.GetEntity("FEntity_Link"); | 
|             Field fldSrcFormId = this.BusinessInfo.GetField("FSrcBillType"); | 
|             Field fldSrcBillNo = this.BusinessInfo.GetField("FSrcBillNo"); | 
|             // 对单据体进行循环,取关联的源单编号 | 
|             foreach (var billObj in e.SelectedRows) | 
|             { | 
|                 DynamicObjectCollection entryRows = entity.DynamicProperty.GetValue(billObj.DataEntity) | 
|                             as DynamicObjectCollection; | 
|                 foreach (var entryRow in entryRows) | 
|                 { | 
|                     string srcFormId = ""; | 
|                     string srcSrcBillNo = ""; | 
|                     try | 
|                     { | 
|                         srcFormId = "PRD_PPBOM"; | 
|                         srcSrcBillNo = fldSrcBillNo.DynamicProperty.GetValue<string>(entryRow); | 
|                         srcSrcBillNo = DBServiceHelper.ExecuteScalar<string>(Context, $" select distinct FPPBOMBILLNO from T_PRD_PICKMTRLDATA where FSRCBILLNO = '{srcSrcBillNo}' ", srcSrcBillNo); | 
|   | 
|                     } | 
|                     catch (Exception) | 
|                     { | 
|                     } | 
|                     if (string.IsNullOrWhiteSpace(srcFormId) | 
|                         || string.IsNullOrWhiteSpace(srcSrcBillNo) | 
|                         ) | 
|                     {// 源单不是采购订单,略过 | 
|                         continue; | 
|                     } | 
|                     // 源单编号已经登记,不再重复记录,略过 | 
|                     if (poBillNos.Contains(srcSrcBillNo)) continue; | 
|                     // Link已经记录了源单信息,略过 | 
|                     //DynamicObjectCollection linkRows = linkEntry.DynamicProperty.GetValue(entryRow) | 
|                     //        as DynamicObjectCollection; | 
|                     //if (linkRows.Count > 0) continue; | 
|                     bool Ret = SourceVerification(Convert.ToString(entryRow["Id"])); | 
|                     if (!Ret) continue; | 
|   | 
|                     poBillNos.Add(srcSrcBillNo); | 
|                 } | 
|             } | 
|             if (poBillNos.Count == 0) return; | 
|             DynamicObject[] poObjs = this.LoadPurchaseOrder(poBillNos); | 
|             if (poObjs == null || poObjs.Length == 0) return; | 
|             Dictionary<string, Dictionary<string, DynamicObject>> dctAllBills = this.BuildDictionary(poObjs); | 
|             string srcTableNumber = this.GetPOEntryTableNumber(); | 
|             List<DynamicObject> allNewLinkRows = new List<DynamicObject>(); | 
|             // 循环单据体,为单据体,建立起源单关联信息: | 
|             foreach (var billObj in e.SelectedRows) | 
|             { | 
|                 DynamicObjectCollection entryRows = entity.DynamicProperty.GetValue(billObj.DataEntity) | 
|                             as DynamicObjectCollection; | 
|                 foreach (var entryRow in entryRows) | 
|                 { | 
|                     string srcSrcBillNo = fldSrcBillNo.DynamicProperty.GetValue<string>(entryRow); | 
|                     string srcFormId = "PRD_PPBOM"; | 
|                     srcSrcBillNo = DBServiceHelper.ExecuteScalar<string>(Context, $" select distinct FPPBOMBILLNO from T_PRD_PICKMTRLDATA where FSRCBILLNO = '{srcSrcBillNo}' ", srcSrcBillNo); | 
|   | 
|   | 
|                     if (string.IsNullOrWhiteSpace(srcFormId) | 
|                         || string.IsNullOrWhiteSpace(srcSrcBillNo) | 
|                       ) | 
|                     {// 源单不是销售订单,略过 | 
|                         continue; | 
|                     } | 
|                     Dictionary<string, DynamicObject> dctOneBill = null; | 
|                     if (dctAllBills.TryGetValue(srcSrcBillNo, out dctOneBill) == false) continue; | 
|                     DynamicObject materialObj = entryRow["MaterialId"] as DynamicObject; | 
|                     if (materialObj == null) continue; | 
|                     string materialNumber = Convert.ToString(materialObj["number"]); | 
|                     DynamicObject srcRow = null; | 
|                     if (dctOneBill.TryGetValue(materialNumber, out srcRow) == false) continue; | 
|                     // Link已经记录了源单信息,略过 | 
|                     bool Ret = SourceVerification(Convert.ToString(entryRow["Id"])); | 
|                     if (!Ret) continue; | 
|   | 
|                     DynamicObjectCollection linkRows = linkEntry.DynamicProperty.GetValue(entryRow) | 
|                             as DynamicObjectCollection; | 
|                     | 
|                     DynamicObject linkRow = new DynamicObject(linkEntry.DynamicObjectType); | 
|                     linkRow["STableName"] = srcTableNumber; | 
|                     this.FillLinkRow(srcRow, entryRow, linkRow); | 
|                     linkRows.Add(linkRow); | 
|                     allNewLinkRows.Add(linkRow); | 
|                 } | 
|             } | 
|             // 为新建的源单关联信息,设置内码 | 
|             IDBService dbService = ServiceHelper.GetService<IDBService>(); | 
|             dbService.AutoSetPrimaryKey(this.Context, allNewLinkRows.ToArray(), linkEntry.DynamicObjectType); | 
|         } | 
|   | 
|         /// <summary> | 
|         /// 加载相关的销售订单数据 | 
|         /// </summary> | 
|         /// <param name="poBillNos"></param> | 
|         /// <returns></returns> | 
|         private DynamicObject[] LoadPurchaseOrder(HashSet<string> poBillNos) | 
|         { | 
|             IViewService viewService = ServiceHelper.GetService<IViewService>(); | 
|             string formId = "PRD_PPBOM"; | 
|   | 
|             // 指定需要加载的销售订单字段 | 
|             List<SelectorItemInfo> fields = new List<SelectorItemInfo>(); | 
|             fields.Add(new SelectorItemInfo("FID"));        // 单据主键 | 
|             fields.Add(new SelectorItemInfo("FTreeEntity_FEntryID"));     // 单据体主键 | 
|             fields.Add(new SelectorItemInfo("FBillNo"));    // 单据编号 | 
|             fields.Add(new SelectorItemInfo("FBFLowId"));    // 业务流程 | 
|             fields.Add(new SelectorItemInfo("FMaterialId"));    // 物料 | 
|             fields.Add(new SelectorItemInfo("FMaterialID2"));    // 物料 | 
|             fields.Add(new SelectorItemInfo("FBASENEEDQTY"));           // 基本单位数量 | 
|             fields.Add(new SelectorItemInfo("FBASEPICKEDQTY"));           // 基本单位关联数量 | 
|             fields.Add(new SelectorItemInfo("FBFLOWID"));           //   | 
|   | 
|             // 指定过滤条件 | 
|             string filter = string.Format(" FBillNo IN ('{0}') ", string.Join("','", poBillNos)); | 
|             OQLFilter ofilter = OQLFilter.CreateHeadEntityFilter(filter); | 
|             var objs = viewService.Load(this.Context, formId, fields, ofilter); | 
|             return objs; | 
|         } | 
|         /// <summary> | 
|         /// 把销售订单单据体行构建为字典:Dictionary(单据编号, Dictionary(物料编码, 源单行)); | 
|         /// </summary> | 
|         /// <param name="poObjs"></param> | 
|         /// <returns></returns> | 
|         private Dictionary<string, Dictionary<string, DynamicObject>> BuildDictionary(DynamicObject[] poObjs) | 
|         { | 
|             Dictionary<string, Dictionary<string, DynamicObject>> dctAllBills = | 
|                 new Dictionary<string, Dictionary<string, DynamicObject>>(); | 
|             foreach (var poObj in poObjs) | 
|             { | 
|                 string billNo = Convert.ToString(poObj["BillNo"]); | 
|                 Dictionary<string, DynamicObject> dctOneBill = new Dictionary<string, DynamicObject>(); | 
|                 DynamicObjectCollection entryRows = poObj["PPBomEntry"] as DynamicObjectCollection; | 
|                 foreach (var entryRow in entryRows) | 
|                 { | 
|                     DynamicObject materialObj = entryRow["MaterialId"] as DynamicObject; | 
|                     if (materialObj == null) continue; | 
|                     string materialNumber = Convert.ToString(materialObj["number"]); | 
|                     dctOneBill[materialNumber] = entryRow; | 
|                 } | 
|                 dctAllBills.Add(billNo, dctOneBill); | 
|             } | 
|             return dctAllBills; | 
|         } | 
|         /// <summary> | 
|         /// 获取销售订单关联主实体表格编码 | 
|         /// </summary> | 
|         /// <returns></returns> | 
|         private string GetPOEntryTableNumber() | 
|         { | 
|             IBusinessFlowService bfMetaService = ServiceHelper.GetService<IBusinessFlowService>(); | 
|             var tableDefine = bfMetaService.LoadTableDefine(this.Context, POFormId, "FEntity"); | 
|             return tableDefine.TableNumber; | 
|         } | 
|         /// <summary> | 
|         /// 填写源单信息 | 
|         /// </summary> | 
|         /// <param name="srcRow">源单行</param> | 
|         /// <param name="toRow">目标单行</param> | 
|         /// <param name="linkRow">关联行</param> | 
|         private void FillLinkRow(DynamicObject srcRow, DynamicObject toRow, DynamicObject linkRow) | 
|         { | 
|             linkRow["FlowId"] = srcRow["BFLowId_Id"]; | 
|             linkRow["FlowLineId"] = 0; | 
|             linkRow["RuleId"] = "PRD_PPBOM2PICKMTRL_NORMAL"; | 
|             linkRow["SBillId"] = ((DynamicObject)srcRow.Parent)[0]; | 
|             linkRow["SId"] = srcRow[0]; | 
|             // 原始携带量 | 
|             decimal baseUnitQty = Convert.ToDecimal(srcRow["BaseNeedQty"]);//用料清单单位数量 | 
|             decimal joinUnitQty = Convert.ToDecimal(srcRow["BasePickedQty"]);//用料清单单位领料数量 | 
|             linkRow["BaseActualQtyOld"] = baseUnitQty - joinUnitQty; | 
|             linkRow["BaseActualQty"] = toRow["BASEACTUALQTY"]; //基本单位实发数量 | 
|         } | 
|   | 
|         /// <summary> | 
|         /// 验证是否生成过生产用料清单对应的源单 | 
|         /// </summary> | 
|         /// <returns></returns> | 
|         public bool SourceVerification(string FTID) | 
|         { | 
|             string sql = $" select count(*) from T_BF_INSTANCEENTRY where FSTABLENAME= 'T_PRD_PPBOMENTRY' and FTID = '{FTID}'"; | 
|             int count = DBServiceHelper.ExecuteScalar<int>(Context, sql, 0); | 
|             if (count == 0) | 
|                 return true; | 
|             else | 
|                 return false; | 
|         } | 
|   | 
|     } | 
| } |