Exemple #1
0
        public void CheckOrder(OrderMaster orderMaster)
        {
            BusinessException ex = new BusinessException();
            if (orderMaster.Type == com.Sconit.CodeMaster.OrderType.CustomerGoods
                || orderMaster.Type == com.Sconit.CodeMaster.OrderType.Procurement)
            {
                ex.AddMessage("订单" + orderMaster.OrderNo + "无需检查库存");
            }
            else
            {
                var paramList = new List<object>();
                string sql = string.Empty;
                paramList.Add(orderMaster.LocationFrom);

                var itemQtyDic = new Dictionary<string, decimal>();
                if (orderMaster.Type == CodeMaster.OrderType.Production)
                {
                    TryLoadOrderBomDetails(orderMaster);
                    if (orderMaster.OrderDetails != null)
                    {
                        itemQtyDic = orderMaster.OrderDetails
                            .SelectMany(p => p.OrderBomDetails)
                            .GroupBy(p => p.Item).ToDictionary(d => d.Key, d => d.Sum(q => q.OrderedQty));
                    }

                    string hql = @"select distinct(isnull(d.LocFrom,f.LocFrom)) from Scm_FlowDet as d 
                               join SCM_FlowMstr f on d.Flow = f.Code
                               where f.IsActive = ? and (d.LocTo =? or (d.LocTo is null and f.LocTo = ? ))
                               and d.Item in(?  ";
                    var locations = genericMgr.FindAllWithNativeSqlIn<string>
                        (hql, itemQtyDic.Select(p => p.Key), new object[] { true, orderMaster.LocationFrom, orderMaster.LocationFrom });

                    foreach (var location in locations)
                    {
                        if (sql == string.Empty)
                        {
                            sql = @" select l.* from VIEW_LocationDet as l with(nolock) where l.ATPQty>0 and l.Location in(?,? ";
                        }
                        else
                        {
                            sql += ",?";
                        }
                    }
                    paramList.AddRange(locations);
                }
                else
                {
                    TryLoadOrderDetails(orderMaster);
                    if (orderMaster.OrderDetails != null)
                    {
                        itemQtyDic = orderMaster.OrderDetails
                            .GroupBy(p => p.Item).ToDictionary(d => d.Key, d => d.Sum(q => q.OrderedQty));
                    }
                    sql = @" select l.* from VIEW_LocationDet as l with(nolock) where l.ATPQty>0 and (l.Location =? ";
                }
                sql += @" ) and l.Item in(? ";

                IList<LocationDetailView> locationDetailViewList = this.genericMgr.FindEntityWithNativeSqlIn<LocationDetailView>
                    (sql, itemQtyDic.Select(p => p.Key), paramList);

                var invDic = (from p in locationDetailViewList
                              group p by p.Item into g
                              select new
                              {
                                  Item = g.Key,
                                  Qty = g.Sum(q => q.ATPQty)
                              }).ToDictionary(d => d.Item, d => d.Qty);
                foreach (var itemQty in itemQtyDic)
                {
                    var diffQty = itemQty.Value - invDic.ValueOrDefault(itemQty.Key);
                    if (diffQty > 0)
                    {
                        ex.AddMessage(string.Format("物料:{0}[{1}]没有足够的库存,缺口:{2}",
                            itemQty.Key, itemMgr.GetCacheItem(itemQty.Key).FullDescription, diffQty.ToString("0.##")));
                    }
                }
            }
            if (ex.GetMessages() != null && ex.GetMessages().Count > 0)
            {
                throw ex;
            }
        }
        public void RunRccp(DateTime planVersion, DateTime snapTime, CodeMaster.TimeUnit dateType, string dateIndex, User user)
        {
            lock(RunRccpLock)
            {
                planVersion = DateTime.Parse(planVersion.ToString("yyyy-MM-dd HH:mm:ss"));
                SecurityContextHolder.Set(user);
                log.Info(string.Format("---**------ SnapTime:{0} PlanVersion:{1} - 开始执行预测计划 ---", snapTime, planVersion));
                BusinessException businessException = new BusinessException();
                int rccpPlanVersion = 0;
                try
                {
                    #region 获取RccpPlan
                    log.Info(string.Format("--- SnapTime:{0} PlanVersion:{1} - 开始获取RccpPlan ---", snapTime, planVersion));
                    var rccpPlans = this.genericMgr.FindAll<RccpPlan>
                        (@"from RccpPlan as m where m.DateIndex >= ? and DateType=? ", new object[] { dateIndex, dateType });
                    log.Info(string.Format("--- SnapTime:{0} PlanVersion:{1} - 结束获取RccpPlan ---", snapTime, planVersion));
                    rccpPlanVersion = rccpPlans.Max(p => p.PlanVersion);
                    #endregion

                    #region 获取路线
                    log.Info(string.Format("--- SnapTime:{0} PlanVersion:{1} - 开始获取路线 ---", snapTime, planVersion));
                    var mrpFlowDetailList = this.genericMgr.FindAll<MrpFlowDetail>
                        (@"from MrpFlowDetail as m where m.SnapTime = ?", new object[] { snapTime });
                    log.Info(string.Format("--- SnapTime:{0} PlanVersion:{1} - 结束获取路线 ---", snapTime, planVersion));
                    #endregion

                    #region 分解BOM
                    log.Info(string.Format("--- SnapTime:{0} PlanVersion:{1} - 开始分解Bom ---", snapTime, planVersion));
                    var rccpTransList = GetRccpTrans(planVersion, rccpPlans, businessException);

                    var rccpTransGroupList = (from r in rccpTransList
                                              group r by new
                                              {
                                                  Item = r.Item,
                                                  DateIndex = r.DateIndex,
                                                  IsLastLevel = r.IsLastLevel,
                                                  DateType = r.DateType
                                              } into g
                                              select new RccpTransGroup
                                              {
                                                  PlanVersion = planVersion,
                                                  DateType = g.Key.DateType,
                                                  Item = g.Key.Item,
                                                  DateIndex = g.Key.DateIndex,
                                                  IsLastLevel = g.Key.IsLastLevel,
                                                  Qty = g.Sum(r => r.Qty),
                                                  ScrapPercentage = g.Sum(s => s.Qty) > 0 ? g.Sum(r => r.ScrapPercentage * (r.Qty / g.Sum(s => s.Qty))) : 0
                                              }).ToList();

                    log.Info(string.Format("--- SnapTime:{0} PlanVersion:{1} - 结束分解Bom ---", snapTime, planVersion));
                    #endregion

                    #region 后加工
                    log.Info(string.Format("--- SnapTime:{0} PlanVersion:{1} - 开始执行后加工计划 ---", snapTime, planVersion));
                    GenFiRccp(planVersion, dateType, mrpFlowDetailList, rccpTransList, businessException);
                    log.Info(string.Format("--- SnapTime:{0} PlanVersion:{1} - 结束执行后加工计划 ---", snapTime, planVersion));
                    #endregion 后加工

                    #region 炼胶 委外
                    log.Info(string.Format("--- SnapTime:{0} PlanVersion:{1} - 开始执行炼胶计划 ---", snapTime, planVersion));
                    GenMiRccp(planVersion, dateType, dateIndex, mrpFlowDetailList, rccpTransGroupList, businessException);
                    log.Info(string.Format("--- SnapTime:{0} PlanVersion:{1} - 结束执行炼胶计划 ---", snapTime, planVersion));
                    #endregion 炼胶

                    #region 采购/委外等
                    log.Info(string.Format("--- SnapTime:{0} PlanVersion:{1} - 开始执行采购/委外计划 ---", snapTime, planVersion));
                    GenPurchaseRccp(planVersion, dateType, businessException, mrpFlowDetailList, rccpTransGroupList, snapTime, user);
                    log.Info(string.Format("--- SnapTime:{0} PlanVersion:{1} - 结束执行采购/委外计划 ---", snapTime, planVersion));
                    #endregion 采购/委外等

                    #region Create RccpTransGroup
                    log.Info(string.Format("--- SnapTime:{0} PlanVersion:{1} - 开始记录RccpTrans/Group ---", snapTime, planVersion));
                    this.genericMgr.BulkInsert<RccpTransGroup>(rccpTransGroupList);
                    log.Info(string.Format("--- SnapTime:{0} PlanVersion:{1} - 结束记录RccpTrans/Group ---", snapTime, planVersion));
                    #endregion
                }
                catch(Exception ex)
                {
                    businessException.AddMessage(new Message(CodeMaster.MessageType.Error, ex.StackTrace));
                    log.Error(ex);
                }

                List<RccpLog> rccpLogs = new List<RccpLog>();
                CodeMaster.MessageType status = CodeMaster.MessageType.Info;
                if(businessException.HasMessage)
                {
                    var messages = businessException.GetMessages().GroupBy(p =>
                                     new { Message = p.GetMessageString(), MessageType = p.MessageType },
                                     (k, g) => new { k.Message, k.MessageType });
                    foreach(var message in messages)
                    {
                        RccpLog rccpLog = new RccpLog();
                        rccpLog.ErrorLevel = message.MessageType.ToString();
                        rccpLog.Message = message.Message;
                        rccpLog.Logger = "RunRccp";
                        rccpLog.PlanVersion = planVersion;
                        rccpLogs.Add(rccpLog);
                        //this.genericMgr.Create(rccpLog);

                        if(message.MessageType == CodeMaster.MessageType.Warning)
                        {
                            log.Warn(rccpLog.Message);
                        }
                        else if(message.MessageType == CodeMaster.MessageType.Error)
                        {
                            log.Error(rccpLog.Message);
                        }
                        else
                        {
                            log.Info(rccpLog.Message);
                        }
                    }
                    if(messages.Count(f => f.MessageType == CodeMaster.MessageType.Error) > 0)
                    {
                        status = CodeMaster.MessageType.Error;
                    }
                    else if(messages.Count(f => f.MessageType == CodeMaster.MessageType.Warning) > 0)
                    {
                        status = CodeMaster.MessageType.Warning;
                    }
                }

                #region 记录RccpPlanMaster
                RccpPlanMaster rccpPlanMaster = new RccpPlanMaster();
                rccpPlanMaster.DateType = dateType;
                rccpPlanMaster.SnapTime = snapTime;
                rccpPlanMaster.PlanVersion = planVersion;
                rccpPlanMaster.Status = status;
                rccpPlanMaster.RccpPlanVersion = rccpPlanVersion;

                rccpPlanMaster.CreateUserId = user.Id;
                rccpPlanMaster.CreateUserName = user.FullName;
                rccpPlanMaster.CreateDate = DateTime.Now;
                rccpPlanMaster.LastModifyUserId = user.Id;
                rccpPlanMaster.LastModifyUserName = user.FullName;
                rccpPlanMaster.LastModifyDate = DateTime.Now;

                this.genericMgr.Create(rccpPlanMaster);
                #endregion

                double timetick = 1001 - (rccpPlanMaster.CreateDate - planVersion).TotalMilliseconds;
                timetick = timetick > 0 ? timetick : 0;
                Thread.Sleep((int)timetick);

                string infoMessage = string.Format("完成预测计划时间:{0},时间总计:{1}秒", DateTime.Now.ToLocalTime(), (DateTime.Now - planVersion).TotalSeconds);
                log.Info(infoMessage);
                RccpLog infoLog = new RccpLog();
                infoLog.ErrorLevel = CodeMaster.MessageType.Info.ToString();
                infoLog.Message = infoMessage;
                infoLog.Logger = "RunRccp";
                infoLog.PlanVersion = planVersion;
                rccpLogs.Add(infoLog);
                this.genericMgr.BulkInsert<RccpLog>(rccpLogs);
            }
        }
 private string GetBusinessExMessage(BusinessException ex)
 {
     string messageString = "";
     IList<Message> messages = ex.GetMessages();
     foreach (Message message in messages)
     {
         messageString += message.GetMessageString();
     }
     return messageString;
 }
        private void GenPurchaseRccp(DateTime planVersion, CodeMaster.TimeUnit dateType, BusinessException businessException,
            IList<MrpFlowDetail> mrpFlowDetailList, IEnumerable<RccpTransGroup> rccpTransGroupList, DateTime snapTime, User user)
        {
            if(businessException.GetMessages().Where(p => p.MessageType == CodeMaster.MessageType.Error).Count() > 0)
            {
                //如果有错误,退出,不产生采购物料需求
                return;
            }

            var flowDetails = mrpFlowDetailList
                  .Where(p => p.Type == CodeMaster.OrderType.Procurement || p.Type == CodeMaster.OrderType.CustomerGoods
                   || p.Type == CodeMaster.OrderType.SubContract || p.Type == CodeMaster.OrderType.ScheduleLine);

            var purchasePlanList = new List<PurchasePlan>();
            var rccpTransGroupByIndexList = (from p in rccpTransGroupList
                                             group p by p.DateIndex into g
                                             select new
                                             {
                                                 DateIndex = g.Key,
                                                 List = g
                                             }).OrderBy(p => p.DateIndex).ToList();

            foreach(var rccpTransGroupByIndex in rccpTransGroupByIndexList)
            {
                DateTime windowTime = DateTime.Now;
                if(dateType == CodeMaster.TimeUnit.Week)
                {
                    windowTime = DateTimeHelper.GetWeekIndexDateFrom(rccpTransGroupByIndex.DateIndex);
                }
                else if(dateType == CodeMaster.TimeUnit.Month)
                {
                    windowTime = DateTime.Parse(rccpTransGroupByIndex.DateIndex + "-01");
                }
                var mrpFlowDetailDic = flowDetails.Where(p => p.StartDate <= windowTime && p.EndDate > windowTime)
                    .GroupBy(p => p.Item, (k, g) => new { k, g })
                    .ToDictionary(d => d.k, d => d.g);

                foreach(var groupRccpTrans in rccpTransGroupByIndex.List)
                {
                    var mrpFlowDetails = mrpFlowDetailDic.ValueOrDefault(groupRccpTrans.Item);
                    if(mrpFlowDetails != null)
                    {
                        foreach(var mrpFlowDetail in mrpFlowDetails)
                        {
                            var purchasePlan = new PurchasePlan();
                            purchasePlan.Item = groupRccpTrans.Item;
                            //purchasePlan.Sequence = mrpFlowDetail.Sequence;
                            purchasePlan.Flow = mrpFlowDetail.Flow;
                            purchasePlan.LocationTo = mrpFlowDetail.LocationTo;
                            purchasePlan.OrderType = mrpFlowDetail.Type;
                            purchasePlan.WindowTime = windowTime;
                            var leadDay = Utility.DateTimeHelper.TimeTranfer((decimal)mrpFlowDetail.LeadTime, CodeMaster.TimeUnit.Hour, CodeMaster.TimeUnit.Day);
                            if(dateType == CodeMaster.TimeUnit.Week)
                            {
                                purchasePlan.StartTime = purchasePlan.WindowTime.AddDays(3).AddDays(-leadDay);
                                purchasePlan.StartTime = Utility.DateTimeHelper.GetWeekStart(purchasePlan.StartTime);
                            }
                            else
                            {
                                purchasePlan.StartTime = purchasePlan.WindowTime.AddDays(15).AddDays(-leadDay);
                                purchasePlan.StartTime = Utility.DateTimeHelper.GetStartTime(CodeMaster.TimeUnit.Month, purchasePlan.StartTime);
                            }

                            purchasePlan.Qty = (mrpFlowDetail.MrpWeight / mrpFlowDetails.Sum(p => p.MrpWeight)) * groupRccpTrans.Qty;
                            purchasePlan.PlanQty = purchasePlan.Qty;
                            purchasePlan.DateType = dateType;
                            purchasePlan.PlanVersion = planVersion;
                            purchasePlanList.Add(purchasePlan);
                        }
                    }
                    else
                    {
                        if(groupRccpTrans.IsLastLevel)
                        {
                            businessException.AddMessage(new Message(CodeMaster.MessageType.Warning, "没有找到物料{0}的采购路线", groupRccpTrans.Item));
                        }
                    }
                }
            }

            string hql = string.Empty;
            if(dateType == CodeMaster.TimeUnit.Week)
            {
                hql = "from FlowStrategy where IsCheckMrpWeeklyPlan =? and Flow in(?";
            }
            else if(dateType == CodeMaster.TimeUnit.Month)
            {
                hql = "from FlowStrategy where IsCheckMrpMonthlyPlan =? and Flow in(?";
            }

            var flowStategys = this.genericMgr.FindAllIn<FlowStrategy>
                (hql, purchasePlanList.Select(p => p.Flow).Where(p => !string.IsNullOrWhiteSpace(p)).Distinct(),
                new object[] { true });
            var flowMasterDic = this.genericMgr.FindAllIn<FlowMaster>
             ("from FlowMaster where Code in(?", flowStategys.Select(p => p.Flow).Distinct())
             .GroupBy(p => p.Code, (k, g) => new { k, g.First().Description })
             .ToDictionary(d => d.k, d => d.Description);
            foreach(var flowStategy in flowStategys)
            {
                PurchasePlanMaster purchasePlanMaster = new PurchasePlanMaster();
                purchasePlanMaster.DateType = dateType;
                purchasePlanMaster.Flow = flowStategy.Flow;
                purchasePlanMaster.FlowDescription = flowMasterDic[flowStategy.Flow];
                purchasePlanMaster.PlanVersion = planVersion;
                purchasePlanMaster.SnapTime = snapTime;
                purchasePlanMaster.SourcePlanVersion = snapTime;

                purchasePlanMaster.CreateUserId = user.Id;
                purchasePlanMaster.CreateUserName = user.FullName;
                purchasePlanMaster.CreateDate = DateTime.Now;
                purchasePlanMaster.LastModifyUserId = user.Id;
                purchasePlanMaster.LastModifyUserName = user.FullName;
                purchasePlanMaster.LastModifyDate = DateTime.Now;

                this.genericMgr.Create(purchasePlanMaster);
            }

            purchasePlanList = purchasePlanList.Where(p => flowStategys.Select(q => q.Flow).Contains(p.Flow)).ToList();
            this.genericMgr.BulkInsert<PurchasePlan>(purchasePlanList);
        }
Exemple #5
0
        public void CheckOrder(OrderMaster orderMaster)
        {
            BusinessException ex = new BusinessException();
            if (orderMaster.Type != com.Sconit.CodeMaster.OrderType.Production)
            {
                ex.AddMessage("订单" + orderMaster.OrderNo + "不是生产单");
            }
            else
            {
                TryLoadOrderBomDetails(orderMaster);
                if (orderMaster.OrderDetails != null && orderMaster.OrderDetails.Count > 0)
                {
                    foreach (OrderDetail orderDetail in orderMaster.OrderDetails)
                    {
                        if (orderDetail.OrderBomDetails != null && orderDetail.OrderBomDetails.Count > 0)
                        {
                            //循环检查太慢了,先检查一层,而且只查有明细的
                            var locationList = orderDetail.OrderBomDetails.Select(b => b.Location).Distinct().ToList();
                            foreach (string location in locationList)
                            {

                                FlowDetail transferFlowDetail = null;

                                string hql = "from FlowDetail as d where exists (select 1 from FlowMaster as f where f.Code = d.Flow and f.IsActive = ? and (d.LocationTo = ? or (d.LocationTo is null and f.LocationTo = ?)))";
                                IList<FlowDetail> transferFlowDetailList = genericMgr.FindAll<FlowDetail>(hql, new object[] { true, location, location });

                                var lob = orderDetail.OrderBomDetails.Where(p => p.Location == location).ToList(); //发到此库位的bom明细

                                #region 找到有路线明细的
                                foreach (OrderBomDetail orderBomDetail in lob)
                                {
                                    transferFlowDetail = transferFlowDetailList.Where(f => f.Item == orderBomDetail.Item).ToList().FirstOrDefault();
                                    if (transferFlowDetail == null)
                                    {
                                        ex.AddMessage("物料" + orderBomDetail.Item + "没有找到对应的" + orderBomDetail.Location + "库位的路线");
                                        continue;
                                    }
                                }
                                #endregion
                            }
                        }
                    }
                    if (ex.GetMessages() != null && ex.GetMessages().Count > 0)
                    {
                        throw ex;
                    }
                }
            }
        }