using HH.WCS.Mobox3.WeiLi.util; using HH.WCS.Mobox3.WeiLi.wms; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; namespace HH.WCS.Mobox3.WeiLi.core { internal class WMSCore { /// /// 遍历定版的发货单,生产分拣单主表和子表(也可以手动调接口触发) /// internal static void CheckShippingOrder() { //1.0、获取已经定版的发货单,生产分拣单子表和主表,设置【发货单】的业务状态 N_B_STATE = 1(待分拣) //2.0、如果发货单C_AUTO_SORTING=Y,则自动将分拣单状态设置为开始配货 } /// /// 开始配货创建分拣单明细(改成调接口触发) /// internal static void CheckSortingOrder() { //new SortingOrder().N_B_STATE //1.0、获取 N_B_STATE = 1 (开始配货)状态的分拣单 //2.0、遍历分拣单子表,创建分拣单明细,更新分拣单子表的明细汇总F_ACC_S_QTY //3.0、全部分拣单子表的明细创建完毕,子表明细汇总和子表数量一致,更新分拣单状态,N_B_STATE = 2配货完成 //4.0、如果分拣单是自动作业,就直接更新到 N_B_STATE = 3开始作业 //WMSHelper.GetWaitingSortingOrderList(); } /// /// 遍历分拣单明细创建出库作业 /// internal static void CheckSortingTask() { LogHelper.Info($"开始查询配盘单明细 获取托盘"); var db = new SqlHelper().GetInstance(); //new SortingOrder().N_B_STATE //遍历N_B_STATE = 3的分拣单创建作业 //或 遍历分拣单明细创建分拣作业,因为一个分拣单里面的明细都是批量生成的 var list = WMSHelper.GetWaitingSortingOperationList(); LogHelper.Info($"获取配盘数量 {list.Count}"); if (list.Count > 0) { list.ForEach(a => { var cntrInfo = db.Queryable().Where(it => it.S_CNTR_CODE == a.S_CNTR_CODE).First(); if (cntrInfo != null) { a.S_LOC_CODE = cntrInfo.S_LOC_CODE; var startloc = db.Queryable().Where(it => it.S_CODE == a.S_LOC_CODE).First(); if (startloc != null && startloc.S_LOCK_STATE == "其它锁") { LogHelper.Info($"托盘{a.S_CNTR_CODE} 绑定位置{a.S_LOC_CODE} 锁状态{startloc.S_LOCK_STATE}"); if (Settings.LKCodes.Where(it => it.LiKuCode == startloc.S_AREA_CODE).FirstOrDefault() != null) { string taskType = ""; Location endbit = null; if (a.S_SORT_TYPE == "整托") { LogHelper.Info($"托盘{a.S_CNTR_CODE} 分拣类型为整托 直接出到外部库区 无需分拣"); endbit = db.Queryable().Where(it => it.S_CODE == "Z03").First(); taskType = "分拣出"; } else if (a.S_SORT_TYPE != "整托备料") { LogHelper.Info($"托盘{a.S_CNTR_CODE} 分拣类型为{a.S_SORT_TYPE} 出到分拣位进行分拣"); taskType = a.S_BS_TYPE; var endList = Settings.ConnetAreas.Where(it => it.LineArea == a.S_EXIT_AREA_CODE && it.Station == a.S_OUT_TO).ToList(); if (endList.Count > 0) { foreach (var endlist in endList) { for (int i = 0; i < endlist.FullList.Length; i++) { var endloc = endlist.FullList[i]; var end = db.Queryable().Where(it => it.S_CODE == endloc && it.N_LOCK_STATE == 0 && it.N_CURRENT_NUM == 0).First(); if (end != null) { endbit = end; break; } else LogHelper.Info($"配盘 货位{endloc} 不可用"); } if (endbit != null) break; } } else LogHelper.Info($"配盘 未找到出库口库区编码{a.S_EXIT_AREA_CODE} 对应的配置文件"); } if (endbit != null) { var optask = new WMSTask { S_CODE = WMSHelper.GenerateTaskNo(), S_START_LOC = a.S_LOC_CODE, S_START_AREA = startloc.S_AREA_CODE, S_START_WH = startloc.S_WH_CODE, S_END_LOC = endbit.S_CODE, S_END_AREA = endbit.S_AREA_CODE, S_END_WH = endbit.S_WH_CODE, S_STATION_LOC = a.S_OUT_TO, S_TYPE = "出库", N_TYPE = 2, N_B_STATE = 0, S_CNTR_CODE = a.S_CNTR_CODE, S_OP_DEF_NAME = taskType, S_BS_NO = a.S_ZT_NO }; var note = Settings.Tasktypes.Where(it => it.StartArea == optask.S_START_AREA && it.EndArea == optask.S_END_AREA).FirstOrDefault(); if (note != null) { optask.S_NOTE = note.TaskType; } var res = db.Insertable(optask).ExecuteCommand() > 0; if (res) { LogHelper.Info($"修改配盘单状态及出库锁"); startloc.N_LOCK_STATE = 2; startloc.S_LOCK_STATE = "出库锁"; db.Updateable(startloc).UpdateColumns(it => new { it.S_LOCK_STATE, it.N_LOCK_STATE }).ExecuteCommand(); LocationHelper.LockLoc(endbit.S_CODE, 1); a.N_B_STATE = 2; a.S_B_STATE = "作业启动"; db.Updateable(a).UpdateColumns(it => new { it.S_B_STATE, it.N_B_STATE }).ExecuteCommand(); LogHelper.Info($"修改成功"); } } else LogHelper.Info($"配盘 未找到可用分拣货位"); } else { LogHelper.Info($"托盘{a.S_CNTR_CODE} 不在立库中 无法出库"); } } else LogHelper.Info($"配盘 托盘号{a.S_CNTR_CODE} 货位{a.S_LOC_CODE} 锁定状态异常"); } }); } } /// /// 遍历分拣单明细创建出库作业 /// internal static void CheckPlanInventoryTask() { LogHelper.Info($"开始查询盘点单明细 获取托盘"); var db = new SqlHelper().GetInstance(); //new SortingOrder().N_B_STATE //遍历N_B_STATE = 3的分拣单创建作业 //或 遍历分拣单明细创建分拣作业,因为一个分拣单里面的明细都是批量生成的 var list = WMSHelper.GetWaitingPlanInventoryList(); LogHelper.Info($"获取盘点数量 {list.Count}"); if (list.Count > 0) { list.ForEach(a => { var cntrInfo = db.Queryable().Where(it => it.S_CNTR_CODE == a.S_CNTR_CODE).First(); if (cntrInfo != null) { a.S_LOC_CODE = cntrInfo.S_LOC_CODE; var startloc = db.Queryable().Where(it => it.S_CODE == a.S_LOC_CODE).First(); if (startloc != null) { LogHelper.Info($"托盘{a.S_CNTR_CODE} 绑定位置{a.S_LOC_CODE} 锁状态{startloc.S_LOCK_STATE}"); if (a.N_B_STATE == 0 && startloc.S_LOCK_STATE == "其它锁") { if (Settings.LKCodes.Where(it => it.LiKuCode == startloc.S_AREA_CODE).FirstOrDefault() != null) { string taskType = ""; Location endbit = null; LogHelper.Info($"托盘{a.S_CNTR_CODE} 分拣区域{a.S_STATION_NO} 出库方向{a.S_OUT_TO} 出到分拣位进行分拣"); taskType = "盘点出"; var endList = Settings.ConnetAreas.Where(it => it.LineArea == a.S_STATION_NO.Trim() && it.Station == a.S_OUT_TO.Trim()).ToList(); if (endList.Count > 0) { foreach (var endlist in endList) { for (int i = 0; i < endlist.FullList.Length; i++) { var endloc = endlist.FullList[i]; var end = db.Queryable().Where(it => it.S_CODE == endloc && it.N_LOCK_STATE == 0 && it.N_CURRENT_NUM == 0).First(); if (end != null) { endbit = end; break; } else LogHelper.Info($"盘点 货位{endloc} 不可用"); } if (endbit != null) break; } } else LogHelper.Info($"盘点 未找到出库口库区编码{a.S_STATION_NO} 对应的配置文件"); if (endbit != null) { var optask = new WMSTask { S_CODE = WMSHelper.GenerateTaskNo(), S_START_LOC = a.S_LOC_CODE, S_START_AREA = startloc.S_AREA_CODE, S_START_WH = startloc.S_WH_CODE, S_END_LOC = endbit.S_CODE, S_END_AREA = endbit.S_AREA_CODE, S_END_WH = endbit.S_WH_CODE, S_STATION_LOC = a.S_OUT_TO, S_TYPE = "出库", N_TYPE = 2, N_B_STATE = 0, S_CNTR_CODE = a.S_CNTR_CODE, S_OP_DEF_NAME = taskType, S_BS_NO = a.S_COUNT_NO }; var note = Settings.Tasktypes.Where(it => it.StartArea == optask.S_START_AREA && it.EndArea == optask.S_END_AREA).FirstOrDefault(); if (note != null) { optask.S_NOTE = note.TaskType; } var res = db.Insertable(optask).ExecuteCommand() > 0; if (res) { LogHelper.Info($"修改盘点单状态及出库锁"); startloc.N_LOCK_STATE = 2; startloc.S_LOCK_STATE = "出库锁"; db.Updateable(startloc).UpdateColumns(it => new { it.S_LOCK_STATE, it.N_LOCK_STATE }).ExecuteCommand(); LocationHelper.LockLoc(endbit.S_CODE, 1); a.N_B_STATE = 1; db.Updateable(a).UpdateColumns(it => new { it.N_B_STATE }).ExecuteCommand(); LogHelper.Info($"修改成功"); } } else LogHelper.Info($"盘点 未找到可用分拣货位"); } else { LogHelper.Info($"托盘{a.S_CNTR_CODE} 不在立库中 无法出库"); } } else if (a.N_B_STATE == 3 && startloc.N_LOCK_STATE == 0) { var optask = new WMSTask { S_CODE = WMSHelper.GenerateTaskNo(), S_START_LOC = a.S_LOC_CODE, S_START_AREA = startloc.S_AREA_CODE, S_START_WH = startloc.S_WH_CODE, S_END_LOC = "", S_END_AREA = a.S_AREA_CODE, S_END_WH = a.S_WH_CODE, S_STATION_LOC = a.S_OUT_TO, S_TYPE = "入库", N_TYPE = 1, N_B_STATE = 0, S_CNTR_CODE = a.S_CNTR_CODE, S_OP_DEF_NAME = "盘点回", S_BS_NO = a.S_COUNT_NO }; var note = Settings.Tasktypes.Where(it => it.StartArea == optask.S_START_AREA && it.EndArea == optask.S_END_AREA).FirstOrDefault(); if (note != null) { optask.S_NOTE = note.TaskType; } var res = db.Insertable(optask).ExecuteCommand() > 0; if (res) { LogHelper.Info($"修改盘点单状态及出库锁"); startloc.N_LOCK_STATE = 2; startloc.S_LOCK_STATE = "出库锁"; db.Updateable(startloc).UpdateColumns(it => new { it.S_LOCK_STATE, it.N_LOCK_STATE }).ExecuteCommand(); a.N_B_STATE = 4; db.Updateable(a).UpdateColumns(it => new { it.N_B_STATE }).ExecuteCommand(); LogHelper.Info($"修改成功"); } } } else LogHelper.Info($"盘点 托盘号{a.S_CNTR_CODE} 货位{a.S_LOC_CODE} 锁定状态异常"); } }); } } /// /// 作业启动,创建子任务 /// internal static void Start() { LogHelper.Info($"作业启动 创建子任务"); var db = new SqlHelper().GetInstance(); List list = WMSHelper.GetWaitingOperationList(); LogHelper.Info($"获取任务数据 数量{list.Count}"); if (list.Count > 0) { //如果是出库的作业锁定托盘的时候已经明确起点了,如果发货单或分拣单指定了终点, //如果没有作业、任务的顺序限制就可以启动,创建子任务了 foreach (var a in list) { try { if (a.N_TYPE == 1) { //入库有终点就可以执行 var cntrinfo = db.Queryable().Where(it => it.S_CNTR_CODE == a.S_CNTR_CODE).First(); if (cntrinfo != null) { LocationHelper.LockLoc(cntrinfo.S_LOC_CODE, 2); //查询托盘所在位置 //计算终点 Location end = WMSHelper.GetEnd(a); if (end != null) { LogHelper.Info($"作业{a.S_CODE} 获取终点成功 任务终点{end.S_CODE}"); WMSHelper.UpdateTaskEnd(a); LocationHelper.LockLoc(a.S_END_LOC, 1); LocationHelper.LockLoc(end.S_CODE, 1); a.S_START_LOC = cntrinfo.S_LOC_CODE; if (!string.IsNullOrEmpty(a.S_END_LOC)) { var type = "NDC"; var startinfo = db.Queryable().Where(it => it.S_CODE == a.S_START_LOC).First(); var endinfo = db.Queryable().Where(it => it.S_CODE == end.S_CODE).First(); if (startinfo != null && endinfo != null) { //起点或终点在立库中 类型为杭奥 var bol = Settings.LKCodes.Where(it => it.LiKuCode == startinfo.S_AREA_CODE).FirstOrDefault() != null || Settings.LKCodes.Where(it => it.LiKuCode == endinfo.S_AREA_CODE).FirstOrDefault() != null; if (bol) type = "WCS"; } //创建wcs任务 var wcsTask = new WCSTask { S_OP_CODE = a.S_CODE, S_OP_NAME = "入库", S_CODE = WCSHelper.GenerateTaskNo(), S_TYPE = a.S_OP_DEF_NAME, S_START_LOC = a.S_START_LOC, S_START_AREA = startinfo.S_AREA_CODE, S_START_WH = startinfo.S_WH_CODE, S_END_LOC = end.S_CODE, S_END_AREA = endinfo.S_AREA_CODE, S_END_WH = endinfo.S_WH_CODE, S_SCHEDULE_TYPE = type, N_CNTR_COUNT = 1, S_CNTR_CODE = a.S_CNTR_CODE, }; if (WCSHelper.CreateTask(wcsTask)) { //更新作业状态为执行 a.N_B_STATE = 1; a.S_B_STATE = "执行"; WMSHelper.UpdateTaskState(a); } } else { LogHelper.Info($"作业{a.S_CODE} 获取终点失败"); } } } } else if (a.N_TYPE == 2) { //通过托盘获取到对应的分拣单 通过分拣单查找发货单上的终点库区 如果是备货出库的话 从配置文件中找一个空闲的点位 //计算终点 var cntrinfo = db.Queryable().Where(it => it.S_CNTR_CODE == a.S_CNTR_CODE).First(); if (cntrinfo != null) { LocationHelper.LockLoc(cntrinfo.S_LOC_CODE, 2); Location end = WMSHelper.GetEnd(a); if (end != null) { LogHelper.Info($"查询到可用货位{end.S_CODE} 准备上锁"); WMSHelper.UpdateTaskEnd(a); LocationHelper.LockLoc(a.S_END_LOC, 1); LocationHelper.LockLoc(end.S_CODE, 1); a.S_START_LOC = cntrinfo.S_LOC_CODE; if (!string.IsNullOrEmpty(a.S_END_LOC)) { var type = "NDC"; var startinfo = db.Queryable().Where(it => it.S_CODE == a.S_START_LOC).First(); var endinfo = db.Queryable().Where(it => it.S_CODE == end.S_CODE).First(); if (startinfo != null && endinfo != null) { //起点或终点在立库中 类型为杭奥 var bol = (Settings.LKCodes.Where(it => it.LiKuCode == startinfo.S_AREA_CODE).FirstOrDefault() != null || Settings.LKCodes.Where(it => it.LiKuCode == endinfo.S_AREA_CODE).FirstOrDefault() != null) || (Settings.ConnetAreas.Where(it => it.AreaCode == startinfo.S_AREA_CODE).FirstOrDefault() != null && Settings.ConnetAreas.Where(it => it.OutLocList.Contains(startinfo.S_CODE)).FirstOrDefault() == null); if (bol) { type = "WCS"; } } //创建wcs任务 var wcsTask = new WCSTask { S_OP_CODE = a.S_CODE, S_OP_NAME = "出库", S_CODE = WCSHelper.GenerateTaskNo(), S_TYPE = a.S_OP_DEF_NAME, S_START_LOC = a.S_START_LOC, S_START_AREA = startinfo.S_AREA_CODE, S_START_WH = startinfo.S_WH_CODE, S_END_LOC = end.S_CODE, S_END_AREA = endinfo.S_AREA_CODE, S_END_WH = endinfo.S_WH_CODE, S_SCHEDULE_TYPE = type, N_CNTR_COUNT = 1, S_CNTR_CODE = a.S_CNTR_CODE, }; if (type == "NDC" && (a.S_OP_DEF_NAME == "出库" || a.S_OP_DEF_NAME == "分拣出" || a.S_OP_DEF_NAME == "空框出库")) { string workNo = ""; if (a.S_OP_DEF_NAME == "分拣出") { workNo = a.S_BS_NO; } else { workNo = a.S_CODE; } //调接口 var endbit = WMSHelper.OutState(wcsTask, workNo); if (!string.IsNullOrEmpty(endbit)) { //替换终点 原终点解锁 var NewEndinfo = db.Queryable().Where(it => it.S_CODE == endbit).First(); if (NewEndinfo != null) { //替换终点 wcsTask.S_END_LOC = endbit; wcsTask.S_END_AREA = NewEndinfo.S_AREA_CODE; wcsTask.S_END_WH = NewEndinfo.S_WH_CODE; //解锁原终点 LocationHelper.UnLockLoc(a.S_END_LOC); //作业终点替换 a.S_END_LOC = endbit; WMSHelper.UpdateTaskEnd(a); LocationHelper.LockLoc(a.S_END_LOC, 1); } else { LogHelper.Info($"中台返回终点{endbit} 不存在货位信息"); LocationHelper.UnLockLoc(end.S_CODE); break; } } else { LogHelper.Info($"中台并未返回终点"); LocationHelper.UnLockLoc(end.S_CODE); break; } } if (WCSHelper.CreateTask(wcsTask)) { //更新作业状态为执行 a.N_B_STATE = 1; a.S_B_STATE = "执行"; WMSHelper.UpdateTaskState(a); } } } } } else if (a.N_TYPE == 3) { //agv转运任务 if (!string.IsNullOrEmpty(a.S_END_LOC)) { var startinfo = db.Queryable().Where(it => it.S_CODE == a.S_START_LOC).First(); var endinfo = db.Queryable().Where(it => it.S_CODE == a.S_END_LOC).First(); var type = "NDC"; if (startinfo != null && endinfo != null) { //起点或终点在立库中 类型为杭奥 var bol = Settings.LKCodes.Where(it => it.LiKuCode == startinfo.S_AREA_CODE).FirstOrDefault() != null || Settings.LKCodes.Where(it => it.LiKuCode == endinfo.S_AREA_CODE).FirstOrDefault() != null; if (bol) type = "WCS"; } //创建wcs任务 var wcsTask = new WCSTask { S_OP_CODE = a.S_CODE, S_OP_NAME = "转运", S_CODE = WCSHelper.GenerateTaskNo(), S_TYPE = a.S_OP_DEF_NAME, S_START_LOC = a.S_START_LOC, S_START_AREA = startinfo.S_AREA_CODE, S_START_WH = startinfo.S_WH_CODE, S_END_LOC = a.S_END_LOC, S_END_AREA = endinfo.S_AREA_CODE, S_END_WH = endinfo.S_WH_CODE, S_SCHEDULE_TYPE = type, N_CNTR_COUNT = 1, S_CNTR_CODE = a.S_CNTR_CODE, }; if (WCSHelper.CreateTask(wcsTask)) { //更新作业状态为执行 a.N_B_STATE = 1; a.S_B_STATE = "执行"; WMSHelper.UpdateTaskState(a); } } } } catch (Exception ex) { LogHelper.Error($"作业启动异常 异常信息={ex.Message}", ex); } } } } } }