فهرست منبع

资源检查替代料计算处理。

tangdi 3 سال پیش
والد
کامیت
940467065a

+ 50 - 3
MicroServices/Business/Business.Application.Contracts/ResourceExamineManagement/Dto/BomChildExamineDto.cs

@@ -19,6 +19,11 @@ namespace Business.ResourceExamineManagement.Dto
         /// </summary>
         public long? parent_id { get; set; }
 
+        /// <summary>
+        /// bom明细主键
+        /// </summary>
+        public long? bom_child_id { get; set; }
+
         /// <summary>
         /// level
         /// </summary>
@@ -75,7 +80,7 @@ namespace Business.ResourceExamineManagement.Dto
         public string unit { get; set; }
 
         /// <summary>
-        /// 物料属性
+        /// 物料属性 0.配置类 1.自制 2.委外加工 3.外购 4.虚拟件
         /// </summary>
         public int erp_cls { get; set; }
 
@@ -137,12 +142,12 @@ namespace Business.ResourceExamineManagement.Dto
         /// <summary>
         /// 齐套时间
         /// </summary>
-        public DateTime kitting_time { get; set; }
+        public DateTime? kitting_time { get; set; }
 
         /// <summary>
         /// 满足时间
         /// </summary>
-        public DateTime satisfy_time { get; set; }
+        public DateTime? satisfy_time { get; set; }
 
         /// <summary>
         /// 计划员
@@ -183,6 +188,12 @@ namespace Business.ResourceExamineManagement.Dto
         /// 群组ids
         /// </summary>
         public string icitem_ids { get; set; }
+
+        /// <summary>
+        /// 群组优先级
+        /// </summary>
+        public int substitute_all_num { get; set; }
+
         /// <summary>
         /// 替代数量
         /// </summary>
@@ -197,5 +208,41 @@ namespace Business.ResourceExamineManagement.Dto
         /// 替代方式
         /// </summary>
         public int substitute_mode { get; set; }
+
+        /// <summary>
+        /// 物料状态--0.充足 1.缺料 2.可制,时间满足 3.可制,时间不满足 4.无需求
+        /// </summary>
+        public int stock_state { get; set; }
+
+        /// <summary>
+        /// 满足量
+        /// </summary>
+        public decimal satisfyNum { get; set; }
+
+        /// <summary>
+        /// 库存可制
+        /// </summary>
+        public decimal kz { get; set; }
+
+        /*/// <summary>
+        /// 产品缺量
+        /// </summary>
+        public decimal lack { get; set; }*/
+
+        /// <summary>
+        /// 单个产品总需要用量
+        /// </summary>
+        public decimal needCount { get; set; }
+
+        /// <summary>
+        /// 使用数量
+        /// </summary>
+        public decimal use_qty { get; set; }
+
+        /// <summary>
+        /// 是否显示
+        /// </summary>
+        public bool is_show { get; set; }
+
     }
 }

+ 191 - 27
MicroServices/Business/Business.Application/ResourceExamineManagement/ResourceExamineAppService.cs

@@ -35,6 +35,7 @@ using System.ComponentModel.Design;
 using Volo.Abp.Validation.StringValues;
 using System.Runtime.CompilerServices;
 using MongoDB.Driver;
+using Hangfire.Annotations;
 
 namespace Business.ResourceExamineManagement
 {
@@ -600,28 +601,26 @@ namespace Business.ResourceExamineManagement
             {
                 string childNum = dto.num + "." + idx.ToString();
                 var icitem = icitemlist.WhereIf(true, a => a.Id == c.icitem_id).FirstOrDefault();
+                var childBom = bomlist.WhereIf(true, a => a.icitem_id == c.icitem_id).FirstOrDefault();
                 //如果此明细查的到BOM信息,则代表此child是一个子BOM。
-                if (c.is_bom == 1)
+                if (childBom != null)
                 {
-                    var childBom = bomlist.WhereIf(true, a => a.icitem_id == c.icitem_id).FirstOrDefault();
-                    if (childBom != null)
-                    {
-                        var cdto = new BomChildExamineDto();
-                        cdto.id = help.NextId();
-                        cdto.level = level;
-                        cdto.parent_id = dto.id;
-                        cdto.qty = c.qty.Value;
-                        cdto.backflush = c.backflush;
-                        cdto.num = childNum;
-                        cdto.isbom = 1;
-                        cdto.is_replace = c.is_replace;
-                        cdto.haveicsubs = c.haveicsubs;
-                        cdto.substitute_code = c.substitute_code;
-                        cdto.icitem_ids = c.icitem_ids;
-                        cdto.type = type;
-                        //递归寻找子级
-                        GetBomList(bomlist, bomchildlist, icitemlist, cdto, returnlist, type);
-                    }
+                    var cdto = new BomChildExamineDto();
+                    cdto.id = help.NextId();
+                    cdto.level = level;
+                    cdto.parent_id = dto.id;
+                    cdto.bom_child_id = c.Id;
+                    cdto.qty = c.qty.Value;
+                    cdto.backflush = c.backflush;
+                    cdto.num = childNum;
+                    cdto.isbom = 1;
+                    cdto.is_replace = c.is_replace;
+                    cdto.haveicsubs = c.haveicsubs;
+                    cdto.substitute_code = c.substitute_code;
+                    cdto.icitem_ids = c.icitem_ids;
+                    cdto.type = type;
+                    //递归寻找子级
+                    GetBomList(bomlist, bomchildlist, icitemlist, cdto, returnlist, type);
                 }
                 else
                 {
@@ -630,6 +629,7 @@ namespace Business.ResourceExamineManagement
                         var childDto = new BomChildExamineDto();
                         childDto.level = level++;
                         childDto.bom_id = dto.bom_id;
+                        childDto.bom_child_id = c.Id;
                         childDto.id = help.NextId();
                         childDto.parent_id = dto.id;
                         childDto.item_id = icitem.Id;
@@ -665,19 +665,32 @@ namespace Business.ResourceExamineManagement
             var sublist = _ic_substitute.GetManyByCondition(s => s.substitute_code.IsIn(returnlist.Select(c => c.substitute_code))).Result.ToList();
             var suballlist = _ic_substitute_all.GetManyByCondition(s => s.substitute_id.IsIn(sublist.Select(c => c.Id))).Result.ToList();
             var subdtllist = _ic_substitute_all_dtl.GetManyByCondition(s => s.substitute_allid.IsIn(suballlist.Select(c => c.Id))).Result.ToList();
-
-            List<long> dicIds = new List<long>();
+            List<long> childidList = new List<long>();
             var help = new SnowFlake();
             int type = 1;
             //除顶级外,其他层级关系全带出来。生成平铺
             foreach (var item in returnlist)
             {
                 //最顶级、虚拟件
-                if (item.level != 1 && item.erp_cls != 4)
+                if (item.level != 1 && item.erp_cls != 4 && !childidList.Contains(item.bom_child_id.GetValueOrDefault()))
                 {
                     //有替代关系
                     if (item.haveicsubs == 1)
                     {
+                        if (!string.IsNullOrEmpty(item.icitem_ids))
+                        {
+                            long cid = 1;
+                            var cids = item.icitem_ids.Split(',');
+                            foreach (var c in cids)
+                            {
+                                if (long.TryParse(c, out cid))
+                                {
+                                    childidList.Add(cid);
+                                }
+                            }
+                        }
+
+
                         //找到当前物料的替代群组关系集
                         var sl = sublist.Find(s => s.substitute_code == item.substitute_code);
                         if (sl != null)
@@ -688,8 +701,11 @@ namespace Business.ResourceExamineManagement
                                 var sadl = subdtllist.Where(s => s.substitute_allid == sal.Id).ToList();
                                 foreach (var dtl in sadl)
                                 {
-                                    //递归将替代关系组装出来。
-                                    SubstitutePretreatment(sl, sal, dtl, item, returnlist, icitemlist, bomlist, bomchildlist,type);
+                                    if (dtl.ismain == 0)
+                                    {
+                                        //递归将替代关系组装出来。
+                                        SubstitutePretreatment(sl, sal, dtl, item, returnlist, icitemlist, bomlist, bomchildlist, type);
+                                    }
                                 }
                             }
                         }
@@ -740,9 +756,10 @@ namespace Business.ResourceExamineManagement
             dto.haveicsubs = 0;
             dto.substitute_code = "";
             dto.icitem_ids = "";
-            dto.substitute_strategy = sl.substitute_strategy.Value;
-            dto.substitute_mode = sl.substitute_mode.Value;
+            dto.substitute_strategy = sl.substitute_strategy.Value;//替代策略
+            dto.substitute_mode = sl.substitute_mode.Value;//替代方式
             dto.type = type;
+            dto.substitute_all_num = sal.order_num;//群组优先级
             if (bom != null)
             {
                 dto.bom_id = bom.Id;
@@ -786,5 +803,152 @@ namespace Business.ResourceExamineManagement
                 }
             }
         }
+
+        /// <summary>
+        /// 替代关系检查计算
+        /// </summary>
+        public void CalcIcitemSubstitute(List<BomChildExamineDto> returnlist,int count)
+        {
+            returnlist = returnlist.OrderBy(s => s.num).ToList();
+            //1.如果主料够的时候,不需要显示替代料的平铺视图,如果主料不够,显示替代料的平铺视图。
+            //2.替代策略和替代方式,影响到的是甲乙组概念,替代按主料有限,取代按组的优先级。A与B的替代,则A和B各自会存在一个组。
+            List<long> calcIds = new List<long>();
+            //先处理下最顶级的产品需要数量
+            returnlist[0].needCount = returnlist[0].qty * count;
+            returnlist[0].satisfyNum = returnlist[0].sqty;
+            returnlist[0].lack_qty = returnlist[0].needCount - returnlist[0].satisfyNum;
+            returnlist[0].is_show = true;
+            foreach (var item in returnlist)
+            {
+                //循环平铺整个资源检查的物料库存情况、缺料情况
+                CaclMaterialShortage(returnlist,item, count);
+            }
+            foreach (var item in returnlist)
+            {
+                //替代件不计算,替代件通过标准件的替代关系,去计算需要使用哪些物料
+                if (item.type == 1)
+                {
+                    continue;
+                }
+                CaclBomChildUseShortage(returnlist, item);
+            }
+        }
+
+        /// <summary>
+        /// 物料计算
+        /// </summary>
+        /// <param name="returnlist"></param>
+        /// <param name="item"></param>
+        /// <param name="count"></param>
+        public void CaclBomChildUseShortage(List<BomChildExamineDto> returnlist, BomChildExamineDto item)
+        {
+            //判断是否是BOM,如果是BOM,还需要向下展开
+            var bomchild = returnlist.Where(s => s.parent_id == item.id && s.type == 0).ToList();
+            if (bomchild.Count > 0)
+            {
+                foreach (var child in bomchild)
+                {
+                    CaclBomChildUseShortage(returnlist, item);
+                }
+            }
+            var tolist = returnlist.Where(s => s.parent_id == item.parent_id && s.num == item.num).ToList();
+            //有替代关系
+            if (item.haveicsubs == 1)
+            {
+                //首先判断标准件库存是否满足。
+                //如果是BOM,也需要向下展开,看子物料是否满足。
+                //不满足的情况下,则需要展开替代关系,根据替代策略和替代方式,来判定替代件的库存。
+                //假设子BOM有替代关系,则子BOM的子物料,也是有替代关系存在的,需要展开来看。
+                //1.假设标准件库存满足,则不计算替代件关系。
+                //2.如果标准件不满足,则替代件开始计算并展示。
+                //注意:不管是否需要替代件,标准件都需要展开。
+                var sublist = returnlist.Where(s => s.parent_id == item.parent_id && s.num == item.num && s.level == item.level).OrderBy(c => c.substitute_all_num).ToList();
+                //sublist找出当前含替代关系的标准件和替代件。
+
+                
+
+
+                if (item.substitute_mode == 0)
+                {
+                    //替代
+                }
+                else { 
+                    //取代
+
+                }
+            }
+            else
+            {
+                //无替代关系
+                if (item.stock_state==0)
+                {
+                    item.use_qty = item.needCount;
+                    item.is_show = true;
+                    item.stock_state = 0;
+                }
+                else if (item.stock_state == 1)
+                {
+                    // 缺料数量 item.lack_qty
+                    // 使用数量将库存全部使用了 item.use_qty = item.sqty;
+                    if (item.erp_cls == 2 || item.erp_cls == 3)
+                    {
+                        //委外、外购
+                        //生成委外工单、采购申请单
+                        //得到单据到货时间。
+                        //todo:初步设置为7天到货期,后期根据实际业务来补充修改。
+                        item.kitting_time = DateTime.Now.AddDays(7);
+                    }
+                    else if (item.erp_cls == 1)
+                    {
+                        //自制
+                        //调用产能计算,得到物料自制后的齐套时间。
+                        //todo:初步设置为7天完成,等沟通调用方法,来修改此处。
+                        item.kitting_time = DateTime.Now.AddDays(7);
+                    }
+                }
+            }
+        }
+
+        /// <summary>
+        /// 平铺物料缺料情况,展示所有主料+替代料的库存情况、缺料情况
+        /// </summary>
+        /// <param name="returnlist"></param>
+        /// <param name="item"></param>
+        /// <param name="count"></param>
+        public void CaclMaterialShortage(List<BomChildExamineDto> returnlist, BomChildExamineDto item, int count)
+        {
+            var parent = returnlist.Find(s => s.id == item.parent_id);
+            //当前物料总共需要数量
+            item.needCount = parent.needCount * item.qty;
+            item.satisfyNum = item.sqty;//5
+            item.lack_qty = item.needCount - item.satisfyNum;
+
+            //如果不满足,计算子物料,或者计算替代料
+            if (item.lack_qty < 0)
+            {
+                //库存满足
+                item.stock_state = 0;
+                item.lack_qty = 0;
+            }
+            else
+            {
+                //找出自己的子集,存在子集则是BOM,不存在子集,则自己非BOM。
+                var childList = returnlist.Where(s => s.parent_id == item.id && s.type == item.type).ToList();
+                if (childList.Count > 0)
+                {
+                    //自己是BOM
+                    foreach (var child in childList)
+                    {
+                        //循环子集判断库存
+                        CaclMaterialShortage(returnlist, child, count);
+                    }
+                }
+                else
+                {
+                    item.stock_state = 1;
+                }
+            }
+        }
+
     }
 }