• K3 cloud 老版本 建立单据关联关系


    业务背景:
    某些单据需要通过引入工具(Excel引入、Web API保存、WebService保存等)引入到K/3 Cloud中。
    引入这些数据时,仅仅能够保存单据本身,其与源单的关联关系则不能同步引入进来,导致没有反写,不支持上下查等。

    解决思路:
    这个功能,需要写被引入单据的保存插件实现,并配合修改单据的引入模板(或者Web API Json参数):
    1.引入模板中,单据体字段 - 源单类型、源单编号,必须引入;
    2. 编写单据的保存操作插件(AbstractOperationServicePlugIn),重载BeforeExecuteOperationTransaction事件:
    2.1 对单据体行进行循环,取每单据体行的源单类型、源单编号;
    2.2 根据源单类型、源单编号,批量读取源单;
    2.3 对源单单据体行进行循环,按照源单编号、物料进行分组,方便随后能够快速的根据源单编号、物料,取到源单单据体行内码;
    2.4 重新对目标单单据体行进行循环,判断目标单单据体行"xxxx_Link"子单据体是否有数据;
    2.5 如果"xxxx_Link"子单据体没有数据,则插件新建数据包,并填写源单信息,追加到目标单单据体中。

    依赖原理:单据保存时,会根据单据体的"xxxx_Link"子单据体记录的源单信息,与源单进行关联、反写。

    案例背景:
    演示引入采购收料单时,如何与采购订单建立关联

    示例代码:
    //*************************************************
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    using System.ComponentModel;

    using Kingdee.BOS;
    using Kingdee.BOS.Util;
    using Kingdee.BOS.Core;
    using Kingdee.BOS.Core.Metadata;
    using Kingdee.BOS.Core.Metadata.EntityElement;
    using Kingdee.BOS.Core.DynamicForm;
    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;
    namespace JDSample.ServicePlugIn.Operation
    {
        /// <summary>
        /// 插件示例:演示引入采购收料单时,如何与采购订单建立关联
        /// </summary>
        /// <remarks>
        /// 要求:
        /// 1. 需要引入单据体的源单类型、源单编号字段
        /// 2. 本插件挂在采购收料单的保存操作上
        /// </remarks>
        [Description("引入采购收料单,建立与采购订单的关联")]
        public class CreateLinkEntryForImport : AbstractOperationServicePlugIn
        {
            private const string POFormId = "PUR_PurchaseOrder";

            public override void BeforeExecuteOperationTransaction(BeforeExecuteOperationTransaction e)
            {
                base.BeforeExecuteOperationTransaction(e);

                HashSet<string> poBillNos = new HashSet<string>();
                Entity entity = this.BusinessInfo.GetEntity("FDetailEntity");
                Entity linkEntry = this.BusinessInfo.GetEntity("FDetailEntity_Link");
                Field fldSrcFormId = this.BusinessInfo.GetField("FSrcFormId");
                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 = fldSrcFormId.DynamicProperty.GetValue<string>(entryRow);
                        string srcSrcBillNo = fldSrcBillNo.DynamicProperty.GetValue<string>(entryRow);

                        if (string.IsNullOrWhiteSpace(srcFormId)
                            || string.IsNullOrWhiteSpace(srcSrcBillNo)
                            || !srcFormId.EqualsIgnoreCase(POFormId))
                        {// 源单不是采购订单,略过
                            continue;
                        }

                        // 源单编号已经登记,不再重复记录,略过
                        if (poBillNos.Contains(srcSrcBillNo)) continue;

                        // Link已经记录了源单信息,略过
                        DynamicObjectCollection linkRows = linkEntry.DynamicProperty.GetValue(entryRow)
                                as DynamicObjectCollection;
                        if (linkRows.Count > 0) 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 srcFormId = fldSrcFormId.DynamicProperty.GetValue<string>(entryRow);
                        string srcSrcBillNo = fldSrcBillNo.DynamicProperty.GetValue<string>(entryRow);

                        if (string.IsNullOrWhiteSpace(srcFormId)
                            || string.IsNullOrWhiteSpace(srcSrcBillNo)
                            || !srcFormId.EqualsIgnoreCase(POFormId))
                        {// 源单不是采购订单,略过
                            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已经记录了源单信息,略过
                        DynamicObjectCollection linkRows = linkEntry.DynamicProperty.GetValue(entryRow)
                                as DynamicObjectCollection;
                        if (linkRows.Count > 0) continue;

                        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 = "PUR_PurchaseOrder";
                
                // 指定需要加载的采购订单字段
                List<SelectorItemInfo> fields = new List<SelectorItemInfo>();
                fields.Add(new SelectorItemInfo("FID"));        // 单据主键
                fields.Add(new SelectorItemInfo("FPOOrderEntry_FEntryID"));     // 单据体主键
                fields.Add(new SelectorItemInfo("FBillNo"));    // 单据编号
                fields.Add(new SelectorItemInfo("FBFLowId"));    // 业务流程
                fields.Add(new SelectorItemInfo("FMaterialId"));    // 物料
                fields.Add(new SelectorItemInfo(" FBaseUnitQty"));           // 基本单位数量
                fields.Add(new SelectorItemInfo("FBaseJoinQty"));           // 基本单位关联数量

                // 指定过滤条件
                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["POOrderEntry"] 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, "FPOOrderEntry");

                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["FBFLowId_Id"];
                linkRow["FlowLineId"] = 0;
                linkRow["RuleId"] = "PUR_PurchaseOrder-PUR_ReceiveBill";
                linkRow["SBillId"] = ((DynamicObject)srcRow.Parent)[0];
                linkRow["SId"] = srcRow[0];

                // 原始携带量
                decimal baseUnitQty = Convert.ToDecimal(srcRow["BaseUnitQty"]);
                decimal joinUnitQty = Convert.ToDecimal(srcRow["BaseJoinQty"]);
                linkRow["BaseUnitQtyOld"] = baseUnitQty - joinUnitQty;
                linkRow["BaseUnitQty"] = toRow["BaseUnitQty"];
            }
        }
    }

  • 相关阅读:
    SugarCRM SupPanel删除键不好用
    SugarCRM 一个页面控制两个模块(editview.php)
    使用组策略去除每次打开IE7的”自定义您的设置”
    SugarCRM SupPanel表头显示不正确
    SugarCRM 去掉 模块标题左边的 问号 和 帮助
    SugarCRM 在Html中增加超连接按钮
    C#中设置状态栏(statusStrip)的布局
    poj2418 Hardwood Species *
    算法导论15.54
    算法导论9.37
  • 原文地址:https://www.cnblogs.com/liangyuwen/p/13197162.html
Copyright © 2020-2023  润新知