Просмотр исходного кода

Merge branch 'dev' of http://123.60.180.165:4647/ZZYDOP/DOPCore into dev

tangdi 2 лет назад
Родитель
Сommit
ae78320343

+ 110 - 26
MicroServices/Business/Business.Application/ReplenishmentManagement/ReplenishmentAppService.cs

@@ -1140,13 +1140,17 @@ namespace Business.Replenishment
                                 }
                             }
                         }
-                        rop.monthl_avg_outstock = Math.Ceiling(SumOutQty / MonthCount);
-
+                        if(MonthCount==0)
+                        {
+                            rop.monthl_avg_outstock = 0;
+                        }else
+                        {
+                            rop.monthl_avg_outstock = Math.Ceiling(SumOutQty / MonthCount);
+                        }
                         rop.year = DateTime.Now.AddMonths(j).Year;
                         rop.month = DateTime.Now.AddMonths(j).Month;
                         rop.planmonth = $"{DateTime.Now.AddMonths(j).Year}-{DateTime.Now.AddMonths(j).Month.ToString("00")}";
                         //供应提前期,成品取物料主数据维护的,原材料从货源清单取取不到取物料维护的
-                        rop.supply_leadtime = 22;//默认
                         if(icItem.erp_cls==1)
                         {
                             rop.supply_leadtime = icItem.PurLT;//默认
@@ -1160,6 +1164,8 @@ namespace Business.Replenishment
                                 rop.supply_leadtime = icItem.PurLT;//默认
                             }
                         }
+                        if(rop.supply_leadtime==0)
+                            rop.supply_leadtime = 22;//默认
                         //存货周转率先取规格型号,没有再取产品系列,没有取产品线,再没有取物料配置的(主要是原材料),再没有就默认
                         if (turnOverlist.Find(t => t.Model == rop.model) != null)
                         {
@@ -1184,7 +1190,7 @@ namespace Business.Replenishment
                         CalcFMRAndABC(rop, replenishmentDto, shipList, pickbilllist, input);
                         rop.security_stock = Math.Ceiling((decimal)(mathtool.InverseCumulativeDistribution((double)rop.service_level_pct.Value) * (double)rop.monthl_avg_demand_variance));
 
-                        rop.eop = Math.Ceiling(rop.monthl_avg_demand.Value * rop.supply_leadtime.Value / DateTime.DaysInMonth(DateTime.Now.Year, DateTime.Now.Month));
+                        rop.eop = Math.Ceiling(rop.monthl_avg_demand.Value * rop.supply_leadtime.Value / DateTime.DaysInMonth(DateTime.Now.AddMonths(j).Year, DateTime.Now.AddMonths(months: j).Month));
                         rop.rop_computed = rop.security_stock + rop.eop;
                         rop.max_stock_level = rop.monthl_avg_outstock * (12 / rop.stock_turnover);
                         //瑞奇是ROP和最高库存值两者之间取较小的值,平台是取较大的值。
@@ -1198,14 +1204,14 @@ namespace Business.Replenishment
                         }
 
                         //存在上一个月补货
-                        if (updateList.Find(r => r.number == a.SAPItemNumber && r.planmonth == $"{DateTime.Now.AddMonths(j - 1).Year}-{DateTime.Now.AddMonths(j - 1).Month.ToString("00")}") != null)
+                        if (updateList.Find(r => r.number == a.SAPItemNumber && r.distributionchannel==a.DistributionChannel && r.planmonth == $"{DateTime.Now.AddMonths(j - 1).Year}-{DateTime.Now.AddMonths(j - 1).Month.ToString("00")}") != null)
                         {
-                            var avaItem = updateList.Find(r => r.number == a.SAPItemNumber && r.planmonth == $"{DateTime.Now.AddMonths(j - 1).Year}-{DateTime.Now.AddMonths(j - 1).Month.ToString("00")}");
+                            var avaItem = updateList.Find(r => r.number == a.SAPItemNumber && r.distributionchannel == a.DistributionChannel && r.planmonth == $"{DateTime.Now.AddMonths(j - 1).Year}-{DateTime.Now.AddMonths(j - 1).Month.ToString("00")}");
                             rop.avaStockQty = Math.Ceiling(avaItem.avaStockQty.GetValueOrDefault() + avaItem.montheop1.GetValueOrDefault() + avaItem.montheop2.GetValueOrDefault() - a.Qty);
                         }
-                        else if (addList.Find(r => r.number == a.SAPItemNumber && r.planmonth == $"{DateTime.Now.AddMonths(j - 1).Year}-{DateTime.Now.AddMonths(j - 1).Month.ToString("00")}") != null)
+                        else if (addList.Find(r => r.number == a.SAPItemNumber && r.distributionchannel == a.DistributionChannel && r.planmonth == $"{DateTime.Now.AddMonths(j - 1).Year}-{DateTime.Now.AddMonths(j - 1).Month.ToString("00")}") != null)
                         {
-                            var avaItem = addList.Find(r => r.number == a.SAPItemNumber && r.planmonth == $"{DateTime.Now.AddMonths(j - 1).Year}-{DateTime.Now.AddMonths(j - 1).Month.ToString("00")}");
+                            var avaItem = addList.Find(r => r.number == a.SAPItemNumber && r.distributionchannel == a.DistributionChannel && r.planmonth == $"{DateTime.Now.AddMonths(j - 1).Year}-{DateTime.Now.AddMonths(j - 1).Month.ToString("00")}");
                             rop.avaStockQty = Math.Ceiling(avaItem.avaStockQty.GetValueOrDefault() + avaItem.montheop1.GetValueOrDefault() + avaItem.montheop2.GetValueOrDefault() - a.Qty);
                         }
                         else
@@ -1240,8 +1246,8 @@ namespace Business.Replenishment
                                 rop.avaStockQty = dictItemStock[a.SAPItemNumber];
                             }
                         }
-                        rop.montheop1 = rop.rop_computed > rop.avaStockQty ? rop.eop : 0;
-                        rop.montheop2 = rop.security_stock > rop.avaStockQty ? rop.eop : 0;
+                        rop.montheop1 = rop.rop_computed > rop.avaStockQty.GetValueOrDefault() ? rop.eop : 0;
+                        rop.montheop2 = rop.security_stock > rop.avaStockQty.GetValueOrDefault() ? rop.eop : 0;
                         rop.ProdLine = a.ProdLine;
                         rop.ProdRange = a.ProdRange;
                         rop.Languages = a.Languages;
@@ -1303,7 +1309,6 @@ namespace Business.Replenishment
                             rop.month = DateTime.Now.AddMonths(j).Month;
                             rop.planmonth = $"{DateTime.Now.AddMonths(j).Year}-{DateTime.Now.AddMonths(j).Month.ToString("00")}";
                             //供应提前期,成品取物料主数据维护的,原材料从货源清单取取不到取物料维护的
-                            rop.supply_leadtime = 22;//默认
                             if (icItem.erp_cls == 1)
                             {
                                 rop.supply_leadtime = icItem.PurLT;//默认
@@ -1319,23 +1324,39 @@ namespace Business.Replenishment
                                     rop.supply_leadtime = icItem.PurLT;//默认
                                 }
                             }
+                            if(rop.supply_leadtime==0)
+                                rop.supply_leadtime = 22;//默认
                             //原材料周转率取物料
                             if (mesItemList.Find(s => s.ItemNum ==rop.number) != null)
                             {
                                 rop.stock_turnover = mesItemList.Find(s => s.ItemNum == rop.number).StockTurnOver;
+                                if(rop.stock_turnover==0)
+                                {
+                                    rop.stock_turnover = 4;
+                                }
                             }
                             else
                             {
                                 rop.stock_turnover = 4;
                             }
+                            if (rop.stock_turnover == 0)
+                                rop.stock_turnover = 4;
                             CalcFMRAndABC(rop, replenishmentDto, shipList, pickbilllist, input);
                             rop.security_stock = Math.Ceiling((decimal)(mathtool.InverseCumulativeDistribution((double)rop.service_level_pct.Value) * (double)rop.monthl_avg_demand_variance));
 
-                            rop.eop = Math.Ceiling(rop.monthl_avg_demand.Value * rop.supply_leadtime.Value / DateTime.DaysInMonth(DateTime.Now.Year, DateTime.Now.Month));
+                            rop.eop = Math.Ceiling(rop.monthl_avg_demand.Value * rop.supply_leadtime.Value / DateTime.DaysInMonth(DateTime.Now.AddMonths(j).Year, DateTime.Now.AddMonths(j).Month));
                             rop.rop_computed = rop.security_stock + rop.eop;
                             rop.max_stock_level = rop.monthl_avg_outstock * (12 / rop.stock_turnover);
                             //瑞奇是ROP和最高库存值两者之间取较小的值,平台是取较大的值。
-                             rop.rop_revised = Math.Min(rop.rop_computed.Value, rop.max_stock_level.Value);
+                            //瑞奇是ROP和最高库存值两者之间取较小的值,平台是取较大的值。
+                            if (a.DistributionChannel != "瑞奇")
+                            {
+                                rop.rop_revised = Math.Max(rop.rop_computed.Value, rop.max_stock_level.Value);
+                            }
+                            else
+                            {
+                                rop.rop_revised = Math.Min(rop.rop_computed.Value, rop.max_stock_level.Value);
+                            }
                      
 
                             //存在上一个月补货
@@ -1352,10 +1373,11 @@ namespace Business.Replenishment
                             else
                             {
                                 //取实际库存
-                                rop.avaStockQty = locations.Where(a=>a.ItemNum==rop.number).Sum(a=>a.QtyOnHand);
+                                //1开始的库位为原料仓
+                                rop.avaStockQty = locations.Where(a=>a.ItemNum==rop.number && a.Location.StartsWith("1")).Sum(a=>a.QtyOnHand);
                             }
-                            rop.montheop1 = rop.rop_computed > rop.avaStockQty ? rop.eop : 0;
-                            rop.montheop2 = rop.security_stock > rop.avaStockQty ? rop.eop : 0;
+                            rop.montheop1 = rop.rop_computed > rop.avaStockQty.GetValueOrDefault() ? rop.eop : 0;
+                            rop.montheop2 = rop.security_stock > rop.avaStockQty.GetValueOrDefault() ? rop.eop : 0;
                             rop.ProdLine = a.ProdLine;
                             rop.ProdRange = a.ProdRange;
                             rop.Languages = a.Languages;
@@ -1502,9 +1524,26 @@ namespace Business.Replenishment
             _workOrdMaster.Delete(a => workOrderDelete.Contains(a.WorkOrd) && a.Domain == input.factory_id.ToString());
             _workOrdRouting.Delete(a => workOrderDelete.Contains(a.WorkOrd) && a.Domain == input.factory_id.ToString());
             _workOrdDetail.Delete(a => workOrderDelete.Contains(a.WorkOrd) && a.Domain == input.factory_id.ToString());
-            await _mysql_mes_morder.DeleteAsync(a => workOrderDelete.Contains(a.morder_no) && a.factory_id == input.factory_id);
-            await _mysql_mes_moentry.DeleteAsync(a => workOrderDelete.Contains(a.moentry_mono) && a.factory_id == input.factory_id);
+            var deletedOrderList=_mysql_mes_morder.GetListAsync(a=>workOrderDelete.Contains(a.morder_no) && a.factory_id == input.factory_id).Result;
+            var deletedIds = deletedOrderList.Select(a => a.Id).ToList();
+            await _mysql_mes_morder.DeleteManyAsync(deletedOrderList);
+            var deletedEntryList= _mysql_mes_moentry.GetListAsync(a => workOrderDelete.Contains(a.moentry_mono) && a.factory_id == input.factory_id).Result;
+            await _mysql_mes_moentry.DeleteManyAsync(deletedEntryList);
             var examine_result = _mysql_examine_result.GetListAsync(a => workOrderDelete.Contains(a.morder_no) && a.factory_id == input.factory_id).Result;
+            List<srm_po_occupy> occupy = await _mysql_srm_po_occupy.GetListAsync(s => workOrderDelete.Contains(s.morder_mo));
+            _businessDbContext.BulkDelete(occupy);
+            //清理工单占用
+            List<mes_mooccupy> mooccupy = await _mysql_mes_mooccupy.GetListAsync(s => deletedIds.Contains(s.moo_id.GetValueOrDefault()));
+            if (mooccupy.Any())
+            {
+                _businessDbContext.BulkDelete(mooccupy);
+            }
+            //清理掉库存占用
+            var itemstockoccupy = _mysql_ic_item_stockoccupy.GetListAsync(s => workOrderDelete.Contains(s.morder_mo)).Result;
+            if (itemstockoccupy.Any())
+            {
+                _businessDbContext.BulkDelete(itemstockoccupy);
+            }
             await _mysql_bom_child_examine.DeleteAsync(a => examine_result.Select(b => b.Id).ToList().Contains(a.examine_id.Value) && a.factory_id == input.factory_id);
             await _mysql_examine_result.DeleteManyAsync(examine_result);
             await _replenishmentWeekPlan.HardDeleteAsync(weekPlanDelete);
@@ -1525,6 +1564,23 @@ namespace Business.Replenishment
             List<ReplenishmentWeekPlan> weekPlan = new List<ReplenishmentWeekPlan>();
             long bang_id = help.NextId();
 
+            //获取BOM用于分解到原材料
+            var boms = _ic_bom.GetListAsync(a => planItemList.Contains(a.item_number) && a.factory_id == input.factory_id).Result;
+            var pretreatments = _mysql_b_bom_pretreatment.GetListAsync(s => boms.Select(c => c.mysql_id).ToList().Contains(s.sourceid)).Result;
+            List<mo_ic_bom> autoCreates = new List<mo_ic_bom>();
+            boms.ForEach(p =>
+            {
+                if (!pretreatments.Where(s => s.sourceid == p.mysql_id).Any())
+                {
+                    autoCreates.Add(p);
+                }
+            });
+            if (autoCreates.Any())
+            {
+                AutoCreateBomBill(input.company_id.ToString(), autoCreates);
+                pretreatments = _mysql_b_bom_pretreatment.GetListAsync(s => boms.Select(c => c.mysql_id).ToList().Contains(s.sourceid)).Result;
+            }
+
             List<string> weeks = new List<string>();
             for (int k = 0; k < replenishmentDto.SaleFcstMonth; k++)
             {
@@ -1564,9 +1620,9 @@ namespace Business.Replenishment
                         {
                             ReplenishmentWeekPlan weekItemPlanAdd = new ReplenishmentWeekPlan();
                             weekItemPlanAdd.Area = item.area;
-                            weekItemPlanAdd.Week = $"WK{GetWeekOfYear(DateTime.Now.AddMonths(k).AddDays( 7 * (w))).ToString("00")}";
+                            weekItemPlanAdd.Week = $"WK{GetWeekOfYear(DateTime.Now.AddDays(1 - DateTime.Now.Day).AddMonths(k).AddDays( 7 * (w))).ToString("00")}";
                             weekItemPlanAdd.DistributionChannel = item.distributionchannel;
-                            weekItemPlanAdd.ProdLine = item.planmonth;
+                            weekItemPlanAdd.ProdLine = item.ProdLine;
                             weekItemPlanAdd.ProdRange = item.ProdRange;
                             weekItemPlanAdd.Model = item.model;
                             weekItemPlanAdd.ItemNumber = item.number;
@@ -1600,6 +1656,8 @@ namespace Business.Replenishment
                 kTime = kTime.AddDays(1 - kTime.Day);//某月第一天
                 var monthWeekPlan = planList.Where(a => a.planmonth == kMonth).ToList();
                 var ropList = planList.Select(t => t.number).Distinct().ToList();
+                //中间件汇总,比如A成品10、11、12月都需要中间件C,B成品11、12月都需要中间件C,那么中间件C需要每个月汇总平均分到4周
+                Dictionary<string, decimal?> subProductItem = new Dictionary<string, decimal?>();
                 foreach (var itemSeq in ropList)
                 {
                     if(shipPlanList.Select(s=>s.SAPItemNumber).ToList().Contains(itemSeq))
@@ -1609,7 +1667,7 @@ namespace Business.Replenishment
                         var monthPlanTotal = monthWeekPlan.Where(x => x.number == itemSeq).ToList();
                         var item = monthPlanTotal[0];
                         //瑞奇补货计划!Y5 + 瑞奇补货计划!Z5 + 国科补货计划!Y5 + 国科补货计划!Z5 + 海王补货计划!Y4 + 海王补货计划!Z4
-                        var itemQty = monthPlanTotal.Sum(a => a.montheop1) + monthPlanTotal.Sum(a => a.montheop1);
+                        var itemQty = monthPlanTotal.Sum(a => a.montheop1) + monthPlanTotal.Sum(a => a.montheop2);
                         //每次都是发布12周,每个月4周,不用判断存不存在(退市的可能没有)
                         int days = 15;
                         if (item.area != "国内" && item.area != "中国")
@@ -1726,6 +1784,28 @@ namespace Business.Replenishment
                                 moentryList.Add(mes_Moentry);
                             }
                         }
+
+                        var planBOM = boms.Find(b => b.item_number == itemSeq);
+                        var pretreament = pretreatments.Where(c => c.sourceid == planBOM.mysql_id).ToList();
+                        var returnlist = ObjectMapper.Map<List<b_bom_pretreatment>, List<BomChildExamineDto>>(pretreament);
+                        returnlist = returnlist.OrderBy(s => s.num_order).ToList();
+                        var level1Dto = returnlist[0];
+                        level1Dto.needCount = itemQty.GetValueOrDefault();
+                        CaclMaterialShortage(returnlist);
+                        foreach (var r in returnlist)
+                        {
+                            if(r.item_number!=itemSeq && r.erp_cls==1)
+                            {
+                                if (subProductItem.ContainsKey(r.item_number))
+                                {
+                                    subProductItem[r.item_number] += r.needCount;
+                                }
+                                else
+                                {
+                                    subProductItem.Add(r.item_number, r.needCount);
+                                }
+                            }
+                        }
                     }
                 }
             }
@@ -1739,13 +1819,16 @@ namespace Business.Replenishment
                 weekPlan[i].OrderNO = OrderNOList[i].NbrResult;
             }
             
-            await _mysql_mes_morder.InsertManyAsync(moList);
-            await _mysql_mes_moentry.InsertManyAsync(moentryList);
-
             await PlanOrderResourceCheck(moList, moentryList, bang_id, input);
 
-
             var examine_resultList = _mysql_examine_result.GetListAsync(a => a.bangid == bang_id).Result;
+            moList.ForEach(mo =>
+            {
+                var moItem = examine_resultList.Find(b => b.morder_no == mo.morder_no);
+                mo.moentry_sys_stime = moItem.kitting_times;
+            });
+            await _mysql_mes_morder.InsertManyAsync(moList);
+            await _mysql_mes_moentry.InsertManyAsync(moentryList);
 
             //批量保存 后期考虑子工单
             List<WorkOrdMaster> workOrdSave = new List<WorkOrdMaster>();
@@ -2302,6 +2385,7 @@ namespace Business.Replenishment
             var productStructureMs = _productStructureMaster.Select(x => morders.Select(c => c.morder_no).Contains(x.ParentItem) && x.Domain == param.factoryId.ToString());
             foreach (var item in morders)
             {
+                var moItem = exmResult.Find(b => b.morder_no ==item.morder_no);
                 //添加工单数据
                 workOrd = new WorkOrdMaster();
                 workOrd.Domain = item.factory_id.ToString();
@@ -3654,7 +3738,7 @@ namespace Business.Replenishment
             var bomList = _mysql_ic_bom.GetListAsync(a => itemList.Contains(a.item_number) && !a.IsDeleted && a.factory_id == input.factory_id).Result;
             List<mes_morder> moList=new List<mes_morder>();
             List<mes_moentry> moentryList = new List<mes_moentry>();
-            var list = _serialNumberAppService.GetBillNo(input.factory_id.ToString(), "MPO", productList.Count(), "", 1);
+            var list = _serialNumberAppService.GetBillNo(input.factory_id.ToString(), "M5", productList.Count(), "", 1);
             long bangid = help.NextId();
             for (int i = 0;i< productList.Count();i++)
             {

+ 6 - 5
MicroServices/Business/Business.Application/ResourceExamineManagement/ProductionScheduleAppService.cs

@@ -653,7 +653,7 @@ namespace Business.ResourceExamineManagement
                         entity.WorkOrd = item.WorkOrd;
                         entity.ItemNum = item.ItemNum;
                         entity.CreateTime = DateTime.Now;
-                        entity.Remark = "排产异常:工单的多个关键工序[" + string.Join("、",curLines.Select(p=>p.Op).ToList()) + "]对应同一条产线,请调整后再操作!";
+                        entity.Remark = "排产异常:工单的多个关键工序[" + string.Join("、",curLines.Select(p=>p.Op).ToList()) + "]对应同一条产线[" + curLines[0].Line +"],请调整后再操作!";
                         entity.Type = type == 1 ? "自动排产" : "手动排产";
                         entity.OptTime = optTime;
                         exceptions.Add(entity);
@@ -4188,12 +4188,13 @@ namespace Business.ResourceExamineManagement
 
             //计算上次报工到当前时间点的预估生产数量,如果没有报工记录,则计算产线准备时间完成到当前时间点的预估生产数量
             decimal planQty = 0m;
-            if (routing.Last == null && Math.Abs(restTime)>0)
+            if (routing.Last == null && restTime < 0)
             {
                 //工序没有报工,使用产线准备完成之后到当前时间点剩余时长计算预估生产数量
                 planQty = Math.Floor(Math.Abs(restTime) * rate);
             }
-            else {
+            else if(routing.Last != null)
+            {
                 //工序存在报工记录,计算报工时间点到当前时间点的有效生产时长,然后计算预估生产数量
                 sumTimes = CalcTimeMins(routing.Last.GetValueOrDefault(), lineStart.StartTime, lineStart.Line);
                 planQty = Math.Floor(sumTimes / 60 * rate);
@@ -4575,12 +4576,12 @@ namespace Business.ResourceExamineManagement
 
             //计算上次报工到当前时间点的预估生产数量,如果没有报工记录,则计算产线准备时间完成到当前时间点的预估生产数量
             decimal planQty = 0m;
-            if (routing.Last == null && Math.Abs(restTime) > 0)
+            if (routing.Last == null && restTime < 0)
             {
                 //工序没有报工,使用产线准备完成之后到当前时间点剩余时长计算预估生产数量
                 planQty = Math.Floor(Math.Abs(restTime) * rate);
             }
-            else
+            else if (routing.Last != null)
             {
                 //工序存在报工记录,计算报工时间点到当前时间点的有效生产时长,然后计算预估生产数量
                 sumTimes = CalcTimeMins(routing.Last.GetValueOrDefault(), startDto.StartTime, startDto.Line);