using HH.WCS.Mobox3.pinggao.api; using HH.WCS.Mobox3.pinggao.models; using HH.WCS.Mobox3.pinggao.util; using HH.WCS.Mobox3.pinggao.wms; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; using static HH.WCS.Mobox3.pinggao.api.ApiModel; namespace HH.WCS.Mobox3.pinggao.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 async Task SendSap() //{ // var result = new SimpleResult(); // LogHelper.Info($"下发sap "); // var db = new SqlHelper().GetInstance(); // //获取配盘单 // var list = db.Queryable().Where(a => a.S_CNTR_CODE == model.cntr_code).First(); ; // try // { // foreach (var po in list) { // if (po.S_OUT_TYPE == "冲销出库") // { // result = await WmsSpaHelper.CXAddOutboundOrder(db, model.MaterList, model.arrival_no, model.cntr_code, start); // } // else // if (po.S_OUT_TYPE == "出库")//普通出库 // { // LogHelper.Info($"S_OUT_TYPE{po.S_OUT_TYPE}"); // result = await AddOutboundOrder(db, model.MaterList, model.arrival_no, model.cntr_code, start); // } // else if (po.S_OUT_TYPE == "计划外发料出库") // { // result = await jhwtlAddOutboundOrder(db, model.MaterList, model.arrival_no, model.cntr_code, start); // } // else if (po.S_OUT_TYPE == "成本中心出库") // { // result = await CBAddOutboundOrder(db, model.MaterList, model.arrival_no, model.cntr_code, start); // } // } // } // catch (Exception ex) // { // LogHelper.Info($"配盘生成作业错误 {ex.Message}"); // throw; // } // LogHelper.Info($"获取配盘数量 {list.Count}"); //} internal static void CheckDistributionCNTROrder() { LogHelper.Info($"配盘生成作业 "); var db = new SqlHelper().GetInstance(); //获取配盘单 var list = WMSHelper.GetWaitingSortingOperationList(); try { foreach (var item in list) { var lcr = db.Queryable().Where(c => c.S_CNTR_CODE == item.S_CNTR_CODE).First(); if (lcr != null) { var yxj = db.Queryable().Where(it => it.S_NO == item.S_BS_NO).First(); //起始库位 var startloc = db.Queryable().Where(it => it.S_CODE == lcr.S_LOC_CODE).First(); if (startloc != null)//&& { //终点货位 var endloc = db.Queryable().Where(it => it.S_AREA_CODE == "AGVXHQ" && it.N_LOCK_STATE == 0 && it.N_CURRENT_NUM == 0).First(); // var endloc = db.Queryable().Where(it => it.S_CODE == item.S_END_LOC).First(); if (endloc != null) { var optask = new WMSTask { S_CODE = WMSHelper.GenerateTaskNo(), S_START_LOC = item.S_LOC_CODE, S_START_AREA = startloc.S_AREA_CODE, N_PRIORITY = yxj.N_PRIORITY, S_START_WH = startloc.S_WH_CODE, S_END_LOC = endloc.S_CODE, S_END_AREA = endloc.S_AREA_CODE, S_END_WH = endloc.S_WH_CODE, S_TYPE = "出库", N_TYPE = 2, N_B_STATE = 0, S_BS_NO = item.S_DC_NO, S_CNTR_CODE = item.S_CNTR_CODE, S_OP_DEF_NAME = item.S_BS_TYPE }; var res = db.Insertable(optask).ExecuteCommand() > 0; if (res) { 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(endloc.S_CODE, 1); item.N_B_STATE = 2; item.S_B_STATE = "作业启动"; item.S_SORT_TYPE = "待分拣"; db.Updateable(item).UpdateColumns(it => new { it.S_B_STATE, it.N_B_STATE, it.S_SORT_TYPE }).ExecuteCommand(); } } else { LogHelper.Info($"{item.S_BS_NO}配盘 库区AGVXHQ无空货位"); } } else { LogHelper.Info($"{item.S_BS_NO}配盘 库区{item.S_AREA_CODE}无货位"); } } else { LogHelper.Info($"配盘生成作业容器未绑定货位"); } } } catch (Exception ex) { LogHelper.Info($"配盘生成作业错误 {ex.Message}"); throw; } LogHelper.Info($"获取配盘数量 {list.Count}"); } internal static void podetailSend() { LogHelper.Info($"自动生成出库任务 "); var db = new SqlHelper().GetInstance(); //获取入库明细单 var list = db.Queryable().ToList(); try { foreach (var item in list) { bool idadd = true; var S_CNTR_CODE = ""; var lcr = db.Queryable() .InnerJoin((l, c) => l.S_CNTR_CODE == c.S_CNTR_CODE) .Where((l, c) => c.S_ITEM_CODE == item.S_ITEM_CODE && c.S_CNTR_TYPE == "半托") .OrderByDescending((l, c) => l.T_CREATE) .Select((l, c) => l).ToList() .FirstOrDefault(); S_CNTR_CODE = lcr.S_CNTR_CODE; if (lcr != null) { //起始库位 var startloc = db.Queryable().Where(it => it.S_CODE == lcr.S_LOC_CODE).First(); var wsc = db.Queryable().Where(it => it.S_CNTR_CODE == S_CNTR_CODE && it.S_TYPE.Contains("出库") && it.N_B_STATE < 3).First(); if (wsc != null) { item.N_B_STATE = 2; db.Updateable(item).UpdateColumns(it => new { it.N_B_STATE }).ExecuteCommand(); } else { if (startloc != null)//&& { //终点货位 var endloc = db.Queryable().Where(it => it.S_AREA_CODE == "QYQXHQ" && it.N_LOCK_STATE == 0 && it.N_CURRENT_NUM == 0).First(); if (endloc != null) { var optask = new WMSTask { S_CODE = WMSHelper.GenerateTaskNo(), S_START_LOC = startloc.S_CODE, S_START_AREA = startloc.S_AREA_CODE, S_START_WH = startloc.S_WH_CODE, S_END_LOC = endloc.S_CODE, S_END_AREA = endloc.S_AREA_CODE, S_END_WH = endloc.S_WH_CODE, N_PRIORITY = 1, S_TYPE = "半托出库", N_TYPE = 2, N_B_STATE = 0, S_BS_NO = "", S_CNTR_CODE = S_CNTR_CODE, S_OP_DEF_NAME = item.S_BS_TYPE }; var res = db.Insertable(optask).ExecuteCommand() > 0; if (res) { startloc.N_LOCK_STATE = 2; startloc.S_LOCK_STATE = "出库锁"; db.Updateable(startloc).UpdateColumns(it => new { it.S_LOCK_STATE, it.N_LOCK_STATE }).ExecuteCommand(); var models = db.Queryable().Where(a => a.S_CODE == endloc.S_CODE).First(); if (models != null && models.N_LOCK_STATE == 0) { models.N_LOCK_STATE = 1; models.S_LOCK_STATE = Location.GetLockStateStr(1); res = db.Updateable(models).UpdateColumns(it => new { it.N_LOCK_STATE, it.S_LOCK_STATE }).ExecuteCommand() > 0; } item.N_B_STATE = 2; db.Updateable(item).UpdateColumns(it => new { it.N_B_STATE }).ExecuteCommand(); } LocationHelper.LockLoc(endloc.S_CODE, 1); } else { idadd = false; LogHelper.Info($" 库区AGVXHQ无空货位"); } } else { idadd = false; LogHelper.Info($" 库区无货位"); } } } else { idadd = false; LogHelper.Info($"物料{item.S_ITEM_CODE}未找到容器对应的货位信息,请联系人工绑定关系"); } if (idadd) { db.Deleteable(item).ExecuteCommand(); } } } catch (Exception ex) { LogHelper.Info($"自动生成出库任务 {ex.Message}"); throw; } LogHelper.Info($"自动生成人物 {list.Count}"); } /// /// 遍历分拣单明细创建出库作业 /// internal static void CheckSortingTask() { 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 startloc = db.Queryable().Where(it => it.S_CODE == a.S_LOC_CODE).First(); if (startloc != null && startloc.S_LOCK_STATE == "其它锁") { Location endbit = null; //计算托盘进行出库 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 = a.S_BS_TYPE }; 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) { 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(); } } else LogHelper.Info($"配盘 未找到可用分拣货位"); } else LogHelper.Info($"配盘 未找到出库口库区编码{a.S_EXIT_AREA_CODE} 对应的配置文件"); }); } } internal static void TransportTask() { var db = new SqlHelper().GetInstance(); var transportInfos = Settings.transportInfos.Where(a => a.enable == 1).ToList(); transportInfos.ForEach(it => { try { LogHelper.Info($"转运"); var startItemCode = ""; //起点物料编码 为空则为空框 废料转运到废料区 var startDeviceName = "";//产线号 var trayNo = ""; Location startLoc = null; Location endLoc = null; if (it.startAreaRowLock == "0") { //起点不为密集型库区 LogHelper.Info($"转运起点不为密集型库区"); startLoc = db.Queryable() .Where(a => a.S_AREA_CODE == it.startArea && //a.S_ATTRIBUTE == it.startLocAttribute && a.N_LOCK_STATE == 0 && a.N_CURRENT_NUM > 0) .Includes(a => a.LocCntrRel) .First(); LogHelper.Info($"转运数据{it.startArea},{it.startLocAttribute}"); if (startLoc != null) { if ( startLoc.LocCntrRel != null) { trayNo = startLoc.LocCntrRel.S_CNTR_CODE; var itemInfo = db.Queryable().Where(a => a.S_CNTR_CODE == trayNo).First(); if (itemInfo != null) { startItemCode = itemInfo.S_ITEM_CODE; startDeviceName = itemInfo.S_BP_CODE; } } else { LogHelper.Info($"判断调试{startLoc.S_CODE}未找到绑定托盘"); } } } else { LogHelper.Info($"转运起点为密集型库区"); var startList = db.Queryable() .Where(a => a.S_AREA_CODE == it.startArea && //a.S_ATTRIBUTE == it.startLocAttribute && a.N_LOCK_STATE == 0 && a.N_CURRENT_NUM > 0) .PartitionBy(a => a.N_ROW) .OrderByDescending(a => a.N_COL) .Includes(a => a.LocCntrRel) .Take(1) .ToList(); LogHelper.Info($"转运数据{it.startArea},{it.startLocAttribute},{it.startLocCreatTime}"); if (it.startLocCreatTime == "1") { //按创建时间出 var item = startList.OrderBy(a => a.LocCntrRel.T_CREATE).FirstOrDefault(); LogHelper.Info($"按创建时间出{item.S_AREA_CODE},{item.N_ROW}"); if (item != null) { var startLock = db.Queryable() .Where(a => a.S_AREA_CODE == item.S_AREA_CODE && a.N_ROW == item.N_ROW && a.N_LOCK_STATE != 0) .First(); if (startLock == null && item.LocCntrRel != null) { startLoc = item; trayNo = item.LocCntrRel.S_CNTR_CODE; } } else { LogHelper.Info($"搭建框无空框数据"); } } else { LogHelper.Info($"不按创建时间出"); foreach (var item in startList) { LogHelper.Info($"不按创建时间出{item.S_AREA_CODE},{item.N_ROW}"); //排除这一排是否有锁定的货位 如果没有选取最外面的货位 var startLock = db.Queryable() .Where(a => a.S_AREA_CODE == item.S_AREA_CODE && a.N_ROW == item.N_ROW && a.N_LOCK_STATE != 0) .First(); if (startLock == null && item.LocCntrRel != null) { startLoc = item; trayNo = item.LocCntrRel.S_CNTR_CODE; break; } } } } LogHelper.Info($"判断{trayNo}"); if (startLoc != null && !string.IsNullOrEmpty(trayNo)) { //可增加废料流程自动转运 //满框流程自动转运 //获取终点 if (it.endAreaRowLock == "0") { //终点非密集型 endLoc = db.Queryable() .Where(a => a.S_AREA_CODE == it.endArea && //a.S_ATTRIBUTE == it.endLocAttribute && a.N_CURRENT_NUM == 0 && a.N_LOCK_STATE == 0) .First(); LogHelper.Info($"终点非密集型{it.endArea},{it.endLocAttribute}"); } else { LogHelper.Info($"终点密集型{it.endArea},{it.endLocAttribute}"); if (!string.IsNullOrEmpty(startItemCode) && !string.IsNullOrEmpty(startDeviceName)) { //转运到满框库区 var endList = db.Queryable() .Where(a => a.S_AREA_CODE == it.endArea && a.N_CURRENT_NUM > 0 //a.S_ATTRIBUTE == it.endLocAttribute ) .PartitionBy(a => a.N_ROW) .OrderByDescending(a => a.N_COL) .Includes(a => a.LocCntrRel) .Take(1) .ToList(); bool ass = endList.Count > 0; LogHelper.Info($"终点密集型{ass},{startItemCode},{startDeviceName}"); foreach (var item in endList) { var endLock = db.Queryable() .Where(a => a.S_AREA_CODE == item.S_AREA_CODE && a.N_ROW == item.N_ROW && a.N_LOCK_STATE != 0) .First(); if (endLock == null) { var ssss = item.LocCntrRel == null; LogHelper.Info($"匹配物料是否和这一排的物料相同{ssss}"); //匹配物料是否和这一排的物料相同 if (item.LocCntrRel != null) { var cntr = item.LocCntrRel.S_CNTR_CODE; var isUse = db.Queryable() .Where(a => a.S_CNTR_CODE == cntr && a.S_ITEM_CODE == startItemCode && a.S_BP_CODE == startDeviceName) .First(); var ssss1 = isUse == null; LogHelper.Info($"匹配isUse相同{ssss1},{cntr},{startItemCode},{startDeviceName}"); if (isUse != null) { //该排可用 endLoc = db.Queryable() .Where(a => a.S_AREA_CODE == item.S_AREA_CODE && a.N_ROW == item.N_ROW && a.N_CURRENT_NUM == 0) .OrderBy(a => a.N_COL) .First(); if (endLoc != null) break; } } else { LogHelper.Info($"匹配物料和这一排的物料不相同"); } } } if (endLoc == null) { //寻找空排进行存放 var RowList = db.Queryable() .Where(a => a.S_AREA_CODE == it.endArea && a.N_CURRENT_NUM == 0) .PartitionBy(a => a.N_ROW) .OrderBy(a => a.N_COL) .Take(1) .ToList(); endLoc = RowList.Where(a => a.N_COL == 1 && a.N_LOCK_STATE == 0).FirstOrDefault(); } } else { LogHelper.Info($"容器编码{trayNo} 物料编码{startItemCode},产线号{startDeviceName}为空"); } } if (endLoc != null) { LogHelper.Info($"创建作业"); //创建作业 WMSHelper.CreatOpenation(startLoc, endLoc, trayNo, "自动转运", 3); } } } catch (Exception ex) { LogHelper.Error($"自动转运流程异常 起点库区{it.startArea} 终点库区{it.endArea} 异常信息{ex.Message}", ex); } }); } /// /// 作业启动,创建子任务 /// 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 { LogHelper.Info($"获取任务状态 {a.N_B_STATE}"); var WCSTasks = db.Queryable().Where(it => it.S_OP_CODE == a.S_CODE).First(); if (WCSTasks!=null) { continue; } if (a.N_TYPE == 1) { //查询托盘所在位置 //计算终点 Location end = WMSHelper.GetEnd(a); if (end != null) { LogHelper.Info($"作业{a.S_CODE} 获取终点成功 任务终点{end.S_CODE}"); WMSHelper.UpdateTaskEnd(a); LocationHelper.LockLoc(end.S_CODE, 1); 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(); var wcsTask = new WCSTask { S_OP_CODE = a.S_CODE, S_OP_NAME = a.S_OP_DEF_NAME, S_CODE = WCSHelper.GenerateTaskNo(), S_TYPE = a.S_TYPE, N_TYPE = a.N_TYPE, 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_BS_NO = a.S_BS_NO, S_END_AREA = endinfo.S_AREA_CODE, S_END_WH = endinfo.S_WH_CODE, S_SCHEDULE_TYPE = "NDC", N_PRIORITY = a.N_PRIORITY, //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) { //通过托盘获取到对应的分拣单 通过分拣单查找发货单上的终点库区 如果是备货出库的话 从配置文件中找一个空闲的点位 //计算终点 Location end = WMSHelper.GetEnd(a); if (end != null) { WMSHelper.UpdateTaskEnd(a); LocationHelper.LockLoc(end.S_CODE, 1); 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(); //创建wcs任务 var wcsTask = new WCSTask { S_OP_CODE = a.S_CODE, S_OP_NAME = a.S_OP_DEF_NAME, S_CODE = WCSHelper.GenerateTaskNo(), S_TYPE = a.S_TYPE, N_TYPE = a.N_TYPE, 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_BS_NO = a.S_BS_NO, S_END_AREA = endinfo.S_AREA_CODE, S_END_WH = endinfo.S_WH_CODE, S_SCHEDULE_TYPE = "NDC", //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); } var detail = db.Queryable().Where(s => s.S_DC_NO == a.S_BS_NO).ToList(); List listdp=new List(); foreach (var item in detail) { TN_DPRECORD tN_DPRECORD = new TN_DPRECORD(); tN_DPRECORD.S_WLBM=item.S_ITEM_CODE; tN_DPRECORD.S_WLMC = item.S_ITEM_NAME; tN_DPRECORD.S_NO= wcsTask.S_CODE; tN_DPRECORD.N_COUNT= item.F_QTY; tN_DPRECORD.S_LOCATION= end.S_CODE; listdp.Add(tN_DPRECORD); } if (listdp.Count()>0) { db.Insertable(listdp).ExecuteCommand(); } } else { LogHelper.Info($"作业{a.S_CODE} 获取终点失败"); } } else if (a.N_TYPE == 3) { 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(); //创建wcs任务 var wcsTask = new WCSTask { S_OP_CODE = a.S_CODE, S_OP_NAME = a.S_OP_DEF_NAME, S_CODE = WCSHelper.GenerateTaskNo(), S_TYPE = a.S_TYPE, S_START_LOC = a.S_START_LOC, S_START_AREA = startinfo.S_AREA_CODE, S_START_WH = startinfo.S_WH_CODE, S_END_LOC = endinfo.S_CODE, S_END_AREA = endinfo.S_AREA_CODE, S_END_WH = endinfo.S_WH_CODE, S_SCHEDULE_TYPE = "NDC", //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); } } } } } }