Browse Source

增加环形库分流交互点关于直接码垛的执行流程

林豪 左 3 months ago
parent
commit
2a172e1b37
1 changed files with 242 additions and 85 deletions
  1. 242 85
      YWGC/FJK/WCS.WorkEngineering/Systems/分拣支线/环形库分流点.cs

+ 242 - 85
YWGC/FJK/WCS.WorkEngineering/Systems/分拣支线/环形库分流点.cs

@@ -27,42 +27,32 @@ namespace WCS.WorkEngineering.Systems
 
         public override void Do(Device<IStation520, IStation521, IStation523, IStation91> obj)
         {
-            if (obj.Data.VoucherNo != obj.Data2.VoucherNo)
-            {
-                if (obj.Data2.TaskNumber != 0 && obj.Data2.TaskNumber != 2)
-                {
-                    obj.Data.TaskNumber = obj.Data2.TaskNumber;
-                    World.Log($"复写:{obj.Data.TaskNumber}");
-                }
-                World.Log($"凭证号不一致,DB520:{obj.Data.VoucherNo}-DB521:{obj.Data2.VoucherNo}", LogLevelEnum.Mid);
-                return;
-            }
+            #region 执行条件检查
 
+            if (CheckVoucherNoMismatch(obj)) return;
             if (obj.Data3.Status.HasFlag(StationStatus.Run))
             {
                 World.Log("设备运行中");
                 return;
             }
-
-            ;
             if (!obj.Data3.Status.HasFlag(StationStatus.OT_Status))
             {
                 World.Log("站台货物信息与实际占用不一致", LogLevelEnum.Mid);
                 return;
             }
-
             if (!obj.Data3.Status.HasFlag(StationStatus.PH_Status))
             {
                 World.Log("站台无光电信息", LogLevelEnum.Mid);
                 return;
             }
-            ;
             if (obj.Data2.Request != 1)
             {
                 World.Log("无请求", LogLevelEnum.Mid);
                 return;
             }
 
+            #endregion 执行条件检查
+
             var isPut = false;
             var nextAdd = GetNext(obj);
             if (nextAdd == 9999) return;
@@ -72,43 +62,17 @@ namespace WCS.WorkEngineering.Systems
             {
                 var db = _db.Default;
 
-                WCS_TaskInfo? taskInfo;
-                if (obj.Data2.TaskNumber == 1 || obj.Data2.TaskNumber == 3 || obj.Data2.TaskNumber == 2)
-                {
-                    var type = goodsType.ToString();
-                    //找到一条起点是当前位置且状态小于2的任务
-                    taskInfo = db.Queryable<WCS_TaskInfo>().NoLock().OrderBy(x => x.AddTime).First(x => x.Status < TaskStatus.FinishOfShunt && x.AddrFrom == obj.Entity.Code && x.BarCode.Contains("Error") && x.AddrNext == null && x.GoodsType == goodsType);
-                    if (taskInfo == null)
-                    {
-                        switch (obj.Data2.TaskNumber)
-                        {
-                            case 1:
-                                WmsApi.PalletizingCreateseErrorTasks(obj.Entity.Code, type);
-                                break;
+                WCS_TaskInfo? taskInfo = null;
 
-                            case 3: //bc质量
-                                WmsApi.PalletizingCreateseErrorTasks(obj.Entity.Code, type, 3);
-                                break;
-
-                            case 2: //南北流错
-                                WmsApi.PalletizingCreateseErrorTasks(obj.Entity.Code, type, 2);
-                                break;
-                        }
+                #region 处理异常任务
 
-                        return;
-                    }
-                    if (taskInfo.Status == TaskStatus.NewBuild)
-                    {
-                        //更新任务状态
-                        taskInfo.Status = TaskStatus.WaitingToExecute;
-                        taskInfo.EditTime = DateTime.Now;
-                        taskInfo.EditWho = "WCS";
-                        db.UpdateableRowLock(taskInfo).ExecuteCommand();
-                        taskInfo.AddWCS_TASK_DTL(db, obj.Entity.Code, $"初始化异常轮入库任务信息");
-                        return;
-                    }
+                if (obj.Data2.TaskNumber == 1 || obj.Data2.TaskNumber == 3 || obj.Data2.TaskNumber == 2)
+                {
+                    if (HandleExceptionTask(db, taskInfo, obj.Entity.Code, obj.Data2.TaskNumber, goodsType)) return;
                 }
 
+                #endregion 处理异常任务
+
                 taskInfo = db.Queryable<WCS_TaskInfo>().NoLock().First(v => v.ID == obj.Data2.TaskNumber && v.Status < TaskStatus.FinishOfShunt);
                 if (taskInfo == null)
                 {
@@ -164,7 +128,6 @@ namespace WCS.WorkEngineering.Systems
                     case "418":
                         if (taskInfo.WarehouseCode != "1N")
                         {
-                            //throw new KnownException($"当前任务应该当前往{taskInfo.WarehouseCode}库", LogLevelEnum.Mid);
                             if (taskInfo.WarehouseCode.Contains("N"))
                             {
                                 EditFlow(taskInfo, "1N", db, obj.Entity.Code);
@@ -180,7 +143,6 @@ namespace WCS.WorkEngineering.Systems
                     case "618":
                         if (taskInfo.WarehouseCode != "1S")
                         {
-                            //throw new KnownException($"当前任务应该当前往{taskInfo.WarehouseCode}库", LogLevelEnum.Mid);
                             if (taskInfo.WarehouseCode.Contains("S"))
                             {
                                 EditFlow(taskInfo, "1S", db, obj.Entity.Code);
@@ -196,7 +158,6 @@ namespace WCS.WorkEngineering.Systems
                     case "818":
                         if (taskInfo.WarehouseCode != "2N")
                         {
-                            //throw new KnownException($"当前任务应该当前往{taskInfo.WarehouseCode}库", LogLevelEnum.Mid);
                             if (taskInfo.WarehouseCode.Contains("N"))
                             {
                                 EditFlow(taskInfo, "2N", db, obj.Entity.Code);
@@ -211,7 +172,6 @@ namespace WCS.WorkEngineering.Systems
                     case "1018":
                         if (taskInfo.WarehouseCode != "2S")
                         {
-                            //throw new KnownException($"当前任务应该当前往{taskInfo.WarehouseCode}库", LogLevelEnum.Mid);
                             if (taskInfo.WarehouseCode.Contains("S"))
                             {
                                 EditFlow(taskInfo, "2S", db, obj.Entity.Code);
@@ -227,7 +187,6 @@ namespace WCS.WorkEngineering.Systems
                     case "1218":
                         if (taskInfo.WarehouseCode != "3N")
                         {
-                            //throw new KnownException($"当前任务应该当前往{taskInfo.WarehouseCode}库", LogLevelEnum.Mid);
                             if (taskInfo.WarehouseCode.Contains("N"))
                             {
                                 EditFlow(taskInfo, "3N", db, obj.Entity.Code);
@@ -243,7 +202,6 @@ namespace WCS.WorkEngineering.Systems
                     case "1418":
                         if (taskInfo.WarehouseCode != "3S")
                         {
-                            //throw new KnownException($"当前任务应该当前往{taskInfo.WarehouseCode}库", LogLevelEnum.Mid);
                             if (taskInfo.WarehouseCode.Contains("S"))
                             {
                                 EditFlow(taskInfo, "3S", db, obj.Entity.Code);
@@ -306,6 +264,8 @@ namespace WCS.WorkEngineering.Systems
                     }
                     if (robot.GetIsDirectPalletizing(db)) //是直接码垛
                     {
+                        var warehouseCode = taskInfo.WarehouseCode.Contains("R") ? taskInfo.WarehouseCode : taskInfo.WarehouseCode + "R";
+                        var wareHouse = db.Queryable<BaseWarehouse>().First(x => x.Code == warehouseCode);
                         //获取两个对应的环形库码垛工位
                         List<string> maDuoZhanTaiList = new List<string>();
                         switch (robot.Code)
@@ -341,45 +301,139 @@ namespace WCS.WorkEngineering.Systems
                                 break;
                         }
 
-                        //判断两个位置是否都有码垛信息,为没有的创建码垛信息
-                        var maDuoXinXiList = db.Queryable<BillRingPalletizingInfo>().NoLock().Where(x => maDuoZhanTaiList.Contains(x.MaDuoGongWei) && x.Out == false).ToList();
+                        #region 判断两个位置是否都有码垛信息,为没有的创建码垛信息
+
+                        var maDuoXinXiList = db.Queryable<BillRingPalletizingInfo>().Where(x => maDuoZhanTaiList.Contains(x.MaDuoGongWei) && x.Out == false).ToList();
 
                         foreach (var maDuoZhanTai in maDuoZhanTaiList)
                         {
                             if (!maDuoXinXiList.Any(x => x.MaDuoGongWei == maDuoZhanTai))
                             {
-                                ////如果没有码垛信息
-                                //var bomsetGrp =
-                                //    _billBomsetgrpRepository.GetFirst(x => x.IsStop == 0 && x.BomCode.Contains(wcsTask.MatCode));
-                                //if (bomsetGrp == null)
-                                //{
-                                //    res.ResCode = ResponseStatusCodeEnum.Fail.GetHashCode();
-                                //    res.ResMsg = "未找到对应垛型信息,请确认是否被禁用";
-                                //    return res;
-                                //}
-                                //var xyNo = _billBomsetinfoRepository.GetList(x => x.BomSetHdrId == bomsetGrp.Id && x.IsEmpty == 0)
-                                //    .ToList().Select(x => Convert.ToInt32(x.XYNo)).OrderByDescending(x => x).First();
-                                ////跟据垛形信息生成
-                                //ringPalletizingInfo = new BillRingPalletizingInfo
-                                //{
-                                //    Id = IdFactory.NewId(),
-                                //    WareHouseId = wareHouse.Id,
-                                //    BomSetGrpId = bomsetGrp.Id,
-                                //    HWCountQty = bomsetGrp.HWCountQty,
-                                //    BomCode = bomsetGrp.BomCode,
-                                //    HaveQty = 0,
-                                //    Out = false,
-                                //    LastXYNO = wareHouse.Code.Contains("N") ? xyNo + 1 : 0
-                                //};
-
-                                //if (!_billRingPalletizingInfo.Insert(ringPalletizingInfo))
-                                //{
-                                //    res.ResCode = ResponseStatusCodeEnum.DataSaveErr.GetHashCode();
-                                //    res.ResMsg = "环形库满轮码垛信息存储失败";
-                                //    return res;
-                                //}
+                                if (CreateStackingInfo(db, taskInfo, wareHouse, maDuoZhanTai)) continue;
                             }
                         }
+
+                        #endregion 判断两个位置是否都有码垛信息,为没有的创建码垛信息
+
+                        #region 选取创建事件已分分配任务数量较多、或者创建事件较早的码垛信息,默认一个库就跑一个垛型,多个垛型会混料
+
+                        maDuoXinXiList = db.Queryable<BillRingPalletizingInfo>().Where(x => maDuoZhanTaiList.Contains(x.MaDuoGongWei) && x.Out == false).ToList().OrderByDescending(x => x.HaveQty).ThenBy(x => x.AddTime).ToList();
+                        if (maDuoXinXiList.Any(x => x.HWCountQty != x.HaveQty))
+                        {
+                            var maDuoXinXi = maDuoXinXiList.Where(x => x.HWCountQty != x.HaveQty).First(); //获取一个应该分配目标
+
+                            //分配当前轮子在垛形中的位置
+                            if (wareHouse.Code.Contains("N")) //北侧由大到小,出的时候刚好可用反过来;
+                            {
+                                //取当前任务SKU在任务中已有的信息
+                                var taksList = db.Queryable<WCS_TaskInfo>().Where(x => x.TaskGroupKey == maDuoXinXi.Id.ToString()).ToList();
+
+                                if (taksList.Count != maDuoXinXi.HaveQty)
+                                {
+                                    World.Log($"码垛信息组【{maDuoXinXi.Id}】记录已有【{maDuoXinXi.HaveQty}】个轮子,但对应的任务信息有【{taksList.Count}】,请在WMS检查对应的任务信息", LogLevelEnum.High);
+                                    return;
+                                }
+
+                                var cellMatCodeList = taksList.Where(x => x.MatCode == taskInfo.MatCode);
+                                //取当前SKU在垛形明细中所有的信息
+                                var bomSetInfos = db.Queryable<BillBomsetinfo>().Where(x =>
+                                     x.BomSetHdrId == maDuoXinXi.BomSetGrpId && x.IsEmpty == 0 &&
+                                     x.MatCode == taskInfo.MatCode).ToList();
+                                //取当前SKU在垛形明细中最大的一个坐标号,初始化时默认取第一个
+                                var lastXYNO = Convert.ToInt32(bomSetInfos.Select(x => Convert.ToInt32(x.XYNo))
+                                    .OrderByDescending(x => x).First());
+                                if (cellMatCodeList.Any()) //货位中已有当前SKU的产品,取最小数,最小数表示最近入库的
+                                {
+                                    lastXYNO = cellMatCodeList.OrderBy(x => x.WmsTask).First().WmsTask;
+                                    var xyNo = bomSetInfos.Select(x => Convert.ToInt32(x.XYNo)).Where(x => x < lastXYNO).OrderByDescending(x => x).First();
+                                    maDuoXinXi.LastXYNO = xyNo;
+                                }
+                                else
+                                {
+                                    maDuoXinXi.LastXYNO = lastXYNO;
+                                }
+                            }
+                            else //南侧小到大,出的时候刚好可用反过来;
+                            {
+                                //取当前任务SKU在任务中已有的信息
+                                var taksList = db.Queryable<WCS_TaskInfo>().Where(x => x.TaskGroupKey == maDuoXinXi.Id.ToString()).ToList();
+                                if (taksList.Count != maDuoXinXi.HaveQty)
+                                {
+                                    World.Log($"码垛信息组【{maDuoXinXi.Id}】记录已有【{maDuoXinXi.HaveQty}】个轮子,但对应的任务信息有【{taksList.Count}】,请在WMS检查对应的任务信息", LogLevelEnum.High);
+                                    return;
+                                }
+
+                                var cellMatCodeList = taksList.Where(x => x.MatCode == taskInfo.MatCode);
+                                //取当前SKU在垛形明细中所有的信息
+                                var bomSetInfos = db.Queryable<BillBomsetinfo>().Where(x =>
+                                    x.BomSetHdrId == maDuoXinXi.BomSetGrpId && x.IsEmpty == 0 &&
+                                    x.MatCode == taskInfo.MatCode).ToList();
+                                //取当前SKU在垛形明细中最小的一个坐标号 ,初始化时默认取第一个
+                                var lastXYNO = Convert.ToInt32(bomSetInfos.Select(x => Convert.ToInt32(x.XYNo)).OrderBy(x => x).First());
+
+                                if (cellMatCodeList.Any()) //货位中已有当前SKU的产品,取最大数 最大数表示最近入库的
+                                {
+                                    lastXYNO = cellMatCodeList.OrderByDescending(x => x.WmsTask).First().WmsTask;
+                                    var xyNo = bomSetInfos.Select(x => Convert.ToInt32(x.XYNo)).Where(x => x > lastXYNO)
+                                        .OrderBy(x => x).First();
+                                    maDuoXinXi.LastXYNO = xyNo;
+                                }
+                                else
+                                {
+                                    maDuoXinXi.LastXYNO = lastXYNO;
+                                }
+                            }
+
+                            //检查分配位置是否已经分配过
+                            if (db.Queryable<WCS_TaskInfo>().NoLock().Any(x => x.TaskGroupKey == maDuoXinXi.Id.ToString() && x.WmsTask == maDuoXinXi.LastXYNO))
+                            {
+                                World.Log($"当前位置已经被分配过了,请检查异常码垛信息{maDuoXinXi.Id}-{maDuoXinXi.LastXYNO}", LogLevelEnum.High);
+                                return;
+                            }
+
+                            #region 更新码垛、任务相关信息
+
+                            // 获取下一个地址
+                            nextAdd = maDuoXinXi.MaDuoGongWei switch
+                            {
+                                "1661" => 433,
+                                "1666" => 442,
+                                "1676" => 633,
+                                "1681" => 642,
+                                "1691" => 833,
+                                "1696" => 842,
+                                "1706" => 1033,
+                                "1711" => 1042,
+                                "1721" => 1233,
+                                "1726" => 1242,
+                                "1736" => 1433,
+                                "1741" => 1442,
+                                _ => 9999
+                            };
+
+                            maDuoXinXi.HaveQty += 1;
+                            taskInfo.AddrNext = nextAdd.ToString();
+                            taskInfo.Status = TaskStatus.FinishOfShunt;
+                            taskInfo.EditTime = DateTime.Now;
+                            taskInfo.WarehouseCode = taskInfo.WarehouseCode.Contains("R") ? taskInfo.WarehouseCode : taskInfo.WarehouseCode + "R";
+                            taskInfo.AddrTo = "Robot";
+                            taskInfo.WmsTask = maDuoXinXi.LastXYNO;
+                            taskInfo.TaskGroupKey = maDuoXinXi.Id.ToString();
+                            taskInfo.GoodsType = goodsType;
+                            db.UpdateableRowLock(taskInfo).UpdateColumns(x => new { x.AddrNext, x.Status, x.EditTime, x.WarehouseCode, x.AddrTo, x.GoodsType, x.WmsTask, x.TaskGroupKey }).ExecuteCommand();
+                            taskInfo.AddWCS_TASK_DTL(db, obj.Entity.Code, nextAdd.ToString(), "工字轮完成环形库分流");
+                            db.Updateable(maDuoXinXi).UpdateColumns(x => new { x.LastXYNO, x.HaveQty }).ExecuteCommand();
+
+                            #endregion 更新码垛、任务相关信息
+                        }
+                        else //创建一个码垛信息
+                        {
+                            var maDuoXinXi = maDuoXinXiList.Where(x => x.HWCountQty == x.HaveQty).OrderBy(x => x.AddTime).First(); //获取一个已分配完成,但未码垛结束的目标
+                            CreateStackingInfo(db, taskInfo, wareHouse, maDuoXinXi.MaDuoGongWei);
+                            return;
+                        }
+
+                        #endregion 选取创建事件已分分配任务数量较多、或者创建事件较早的码垛信息,默认一个库就跑一个垛型,多个垛型会混料
                     }
                     else
                     {
@@ -438,6 +492,109 @@ namespace WCS.WorkEngineering.Systems
             return dev.Code is "418" or "618" or "818" or "1018" or "1218" or "1418";
         }
 
+        /// <summary>
+        ///  检查凭证号是否满足条件
+        /// </summary>
+        /// <param name="obj"></param>
+        /// <returns></returns>
+        private bool CheckVoucherNoMismatch(Device<IStation520, IStation521, IStation523, IStation91> obj)
+        {
+            if (obj.Data.VoucherNo != obj.Data2.VoucherNo)
+            {
+                if (obj.Data2.TaskNumber != 0 && obj.Data2.TaskNumber != 2)
+                {
+                    obj.Data.TaskNumber = obj.Data2.TaskNumber;
+                    World.Log($"复写:{obj.Data.TaskNumber}");
+                }
+                World.Log($"凭证号不一致,DB520:{obj.Data.VoucherNo}-DB521:{obj.Data2.VoucherNo}", LogLevelEnum.Mid);
+                return true;
+            }
+            return false;
+        }
+
+        /// <summary>
+        ///  处理异常任务
+        /// </summary>
+        /// <param name="db">数据库连接</param>
+        /// <param name="taskInfo">任务信息</param>
+        /// <param name="addrFrom">异常任务起始地址,即当前设备号</param>
+        /// <param name="devTaskNumber">设备中的任务号</param>
+        /// <param name="goodsType">产品类型,即外检结果</param>
+        /// <returns></returns>
+        private bool HandleExceptionTask(SqlSugarScopeProvider db, WCS_TaskInfo? taskInfo, string addrFrom, int devTaskNumber, int goodsType)
+        {
+            var type = goodsType.ToString();
+            //找到一条起点是当前位置且状态小于2的任务
+            taskInfo = db.Queryable<WCS_TaskInfo>().NoLock().OrderBy(x => x.AddTime).First(x => x.Status < TaskStatus.FinishOfShunt && x.AddrFrom == addrFrom && x.BarCode.Contains("Error") && x.AddrNext == null && x.GoodsType == goodsType);
+            if (taskInfo == null)
+            {
+                switch (devTaskNumber)
+                {
+                    case 1:
+                        WmsApi.PalletizingCreateseErrorTasks(addrFrom, type);
+                        break;
+
+                    case 3: //bc质量
+                        WmsApi.PalletizingCreateseErrorTasks(addrFrom, type, 3);
+                        break;
+
+                    case 2: //南北流错
+                        WmsApi.PalletizingCreateseErrorTasks(addrFrom, type, 2);
+                        break;
+                }
+
+                return true;
+            }
+            if (taskInfo.Status == TaskStatus.NewBuild)
+            {
+                //更新任务状态
+                taskInfo.Status = TaskStatus.WaitingToExecute;
+                taskInfo.EditTime = DateTime.Now;
+                taskInfo.EditWho = "WCS";
+                db.UpdateableRowLock(taskInfo).ExecuteCommand();
+                taskInfo.AddWCS_TASK_DTL(db, addrFrom, $"初始化异常轮入库任务信息");
+                return true;
+            }
+            return false;
+        }
+
+        /// <summary>
+        ///  创建一条码垛信息
+        /// </summary>
+        /// <param name="db">数据库连接</param>
+        /// <param name="taskInfo">任务信息</param>
+        /// <param name="wareHouse">仓库信息</param>
+        /// <param name="maDuoGongWei">码垛工位</param>
+        /// <returns></returns>
+        private bool CreateStackingInfo(SqlSugarScopeProvider db, WCS_TaskInfo taskInfo, BaseWarehouse wareHouse, string maDuoGongWei)
+        {
+            var bomsetGrp = db.Queryable<BillBomsetgrp>().NoLock().First(x => x.IsStop == 0 && x.BomCode.Contains(taskInfo.MatCode));
+            if (bomsetGrp == null)
+            {
+                World.Log($"未找到对应垛型信息,请确认是否被禁用", LogLevelEnum.High);
+                return true;
+            }
+            var xyNo = db.Queryable<BillBomsetinfo>().NoLock().Where(x => x.BomSetHdrId == bomsetGrp.Id && x.IsEmpty == 0)
+                .ToList().Select(x => Convert.ToInt32(x.XYNo)).OrderByDescending(x => x).First();
+
+            //跟据垛形信息生成
+            var ringPalletizingInfo = new BillRingPalletizingInfo
+            {
+                Id = IdFactory.NewId(),
+                WareHouseId = wareHouse.Id,
+                BomSetGrpId = bomsetGrp.Id,
+                HWCountQty = bomsetGrp.HWCountQty,
+                BomCode = bomsetGrp.BomCode,
+                HaveQty = 0,
+                Out = false,
+                LastXYNO = wareHouse.Code.Contains("N") ? xyNo + 1 : 0,
+                MaDuoGongWei = maDuoGongWei
+            };
+
+            db.Insertable(ringPalletizingInfo);
+            return false;
+        }
+
         /// <summary>
         ///  计算非零九的去向
         /// </summary>