MRP干预下层需求数据解决方案

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

MRP干预下层需求数据解决方案

【应用场景】

在一些特殊场景下,MRP运算生成计划订单及其计划BOM表体的标准业务逻辑并不能满足业务需求,因此需要在MRP运算过程中进行干预,之前有一个文章讲述了如何在MRP中干预计划订单(详见文章:MRP运算过程添加数据策略干预计划订单信息),但该方案有一定局限性,就是只是针对计划订单自身进行干预,当遇到干预之后需要往下层需求传递时,则该方案不适用。本知识贴主要介绍这类场景的解决方案,即添加MRP数据模型策略实现类,实现干预计划订单或计划BOM的信息,并且将更改后的信息往下层需求传递。



【注意事项】

该实现方案涉及到MRP数据模型添加数据策略并替换标准的数据策略,有较高的开发要求非最佳实践,不推荐使用,仅限于特殊场景下的特殊应用。实际场景中尽可能使用业务上的变通方案或沿用标准MRP相关逻辑,非必要不采用本方案干预MRP中间过程的数据传递逻辑。



【案例演示】

本方案演示的是MRP运算生成的计划订单的计划BOM相关需求数量字段向上取整。



【实现步骤】

<1>,本方案默认阅读者已经掌握二开添加MRP数据模型实现策略的方法(若尚未掌握,详见知识贴:MRP如何二开数据模型策略实现类)。但要是注意,本案要编辑策略实现类的MRP数据数据模型编码是MRP_DP_NC_TransferDemand,在系统前端修改编码为MRP_DP_NC_TransferDemand的MRP数据模型的策略实现类(路径:生产制造》计划管理》MRP建模》MRP数据模型),注意策略实现类文本框填对插件的命名空间和类名,结构是(命名空间.类名,组件名),如图。


<2>经过上一步掌握了添加MRP数据策略实现类之后,再二开实现本案示例业务场景的数据策略功能,示例代码如下。 

using Kingdee.BOS.Orm.DataEntity;

using Kingdee.BOS.Util;

using Kingdee.BOS;

using Kingdee.BOS.App.Data;

using Kingdee.K3.Core.MFG.EntityHelper;

using Kingdee.K3.MFG.PLN.App.MrpModel;

using Kingdee.K3.MFG.PLN.App.MrpModel.PolicyImpl.NetCalc;

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.ComponentModel;


namespace CustMrpModel_23231206

{

    [Kingdee.BOS.Util.HotUpdate]

    [Description("MRP插件:(传递净需求数据策略)")]

    public class MyTransferDSDataPolicy : Kingdee.K3.MFG.PLN.App.MrpModel.PolicyImpl.NetCalc.TransferDSDataPolicy

    {

        protected override void OnExecuteDataPolicy()

        {

            base.OnExecuteDataPolicy(); //首先处理标准逻辑

            //Kingdee.K3.MFG.PLN.App.MrpModel.PolicyImpl.NetCalc.TransferDSDataPolicy,Kingdee.K3.MFG.PLN.App.MrpModel

            if (this.MrpGlobalDataContext.TransferDemandRows.IsEmpty() || this.MrpDemandDimContext.MrpNetDemandContextGroup.PlanOrderItem == null) return;


            Dictionary<long, DynamicObject> plbomEntryDct = new Dictionary<long, DynamicObject>();

            DynamicObject planOrderData = this.MrpDemandDimContext.MrpNetDemandContextGroup.PlanOrderItem;

            DynamicObjectCollection plEntrys = planOrderData["PLBOMENTRY"] as DynamicObjectCollection;

            foreach (DynamicObject plEntry in plEntrys)

            {

                decimal stdQty = plEntry.GetDynamicValue<decimal>("StdQty");

                stdQty = Math.Ceiling(stdQty); //数量向上取整

                plEntry.SetDynamicObjectItemValue("StdQty", stdQty);

                plEntry.SetDynamicObjectItemValue("BaseStdQty", stdQty); //注意若基本单位与业务单位不一致,此处须换算


                decimal needQty = plEntry.GetDynamicValue<decimal>("NeedQty");

                needQty = Math.Ceiling(needQty); //数量向上取整

                plEntry.SetDynamicObjectItemValue("NeedQty", needQty);

                plEntry.SetDynamicObjectItemValue("BaseNeedQty", needQty); //注意若基本单位与业务单位不一致,此处须换算


                decimal mustQty = plEntry.GetDynamicValue<decimal>("MustQty");

                mustQty = Math.Ceiling(mustQty); //数量向上取整                    

                plEntry.SetDynamicObjectItemValue("MustQty", mustQty);

                plEntry.SetDynamicObjectItemValue("BaseMustQty", mustQty); //注意若基本单位与业务单位不一致,此处须换算


                //注意因为更改了需求数量,要重算并更新分子,才能正确计算需求数量等

                decimal baseNumerator = plEntry.GetDynamicValue<decimal>("BaseNumerator"); //分子

                decimal Individual = mustQty / baseNumerator;

                baseNumerator = this.CalcNumerator(Individual, mustQty);

                plEntry.SetDynamicObjectItemValue("BaseNumerator", baseNumerator);

                plEntry.SetDynamicObjectItemValue("Numerator", baseNumerator); //注意若基本单位与业务单位不一致,此处须换算


                //收集已处理的计划BOM数据,用于后面更新需求数据

                long plbomEntryId = plEntry.GetDynamicValue<long>("Id");

                plbomEntryDct[plbomEntryId] = plEntry;

            }


            //给计划BOM数量取整之后,还要对其对应的需求数据也要进行更新

            foreach (DynamicObject demandRow in this.MrpGlobalDataContext.TransferDemandRows)

            {

                string demandFormId = demandRow.GetDynamicValue<string>("RelationFormId_Id");

                if (!demandFormId.EqualsIgnoreCase("PLN_PLANORDER")) continue;


                string demandEntryIdStr = demandRow.GetDynamicValue<string>("RelationEntryId");

                long demandEntryId = 0;

                if (demandEntryIdStr.IsNullOrEmptyOrWhiteSpace() || !long.TryParse(demandEntryIdStr, out demandEntryId)) continue;


                DynamicObject plbomEntry;

                if (plbomEntryDct.TryGetValue(demandEntryId, out plbomEntry))

                {

                    demandRow["BASEDEMANDQTY"] = plbomEntry["BaseMustQty"];

                    demandRow["BASEGROSSQTY"] = plbomEntry["BaseMustQty"];

                    demandRow["BASEORDERQTY"] = plbomEntry["BaseMustQty"];

                    demandRow["BASEQTY"] = plbomEntry["BaseMustQty"];

                    demandRow["BaseNumerator"] = plbomEntry["BaseNumerator"];

                }

            }

        }


        private decimal CalcNumerator(decimal individual, decimal mustQty)

        {

            string numString = (mustQty / individual).ToString();

            int decimalIndex = numString.IndexOf('.') + 4;

            if (decimalIndex < numString.Length)

            {

                int fourthDecimal = int.Parse(numString[decimalIndex - 1].ToString());

                int newValue = fourthDecimal + 1;

                numString = numString.Remove(decimalIndex - 1, 1).Insert(decimalIndex - 1, newValue.ToString());

            }

            return decimal.Parse(numString.Substring(0, decimalIndex));

        }


    }

}


【功能验证】

<1>通过本案开发干预后,MRP运算生成的订单订单的计划BOM需求相关数量都是向上取整的整数,且预留也是整数,在一些单位精度因为关联业务偶合或历史原因无法更改为0,且又需要整领整发的场景中适用。

MRP干预下层需求数据解决方案

【应用场景】在一些特殊场景下,MRP运算生成计划订单及其计划BOM表体的标准业务逻辑并不能满足业务需求,因此需要在MRP运算过程中进行干预...
点击下载文档
确认删除?
回到顶部
客服QQ
  • 客服QQ点击这里给我发消息