using HH.WCS.Mobox3.SXJK.device; using HH.WCS.Mobox3.SXJK.dispatch; using HH.WCS.Mobox3.SXJK.models; using HH.WCS.Mobox3.SXJK.process; using HH.WCS.Mobox3.SXJK.util; using HH.WCS.Mobox3.SXJK.wms; using Newtonsoft.Json; using NLog.Filters; using SqlSugar; using System; using System.Collections.Generic; using System.Linq; using System.Net.NetworkInformation; using System.Security.Cryptography; using System.Web.Http.Tracing; using static EasyModbus.ModbusServer; using static HH.WCS.Mobox3.SXJK.api.ApiHelper; using static HH.WCS.Mobox3.SXJK.api.ApiModel; using static HH.WCS.Mobox3.SXJK.dispatch.WMSDispatch; using static HH.WCS.Mobox3.SXJK.util.Settings; using static HH.WCS.Mobox3.SXJK.wms.WCSHelper; namespace HH.WCS.Mobox3.SXJK.core { internal class WCSCore { public static void OperateAgvTaskStatus(AgvTaskState model) { if (string.IsNullOrEmpty(model.No)) { //无任务号请求(交管) //DeviceProcess.Traffic(model.ForkliftNo, model.LockNo, model.State==1023); } else { var TN_Task = WCSHelper.GetTask(model.No); if (TN_Task != null) { if (model.State <= 7) { //有任务号请求 switch (model.State) { case 1: WCSHelper.Begin(TN_Task); break; #region MyRegion case 3: WCSHelper.UpdateStatus(TN_Task, "开始取货"); break; case 4: WCSHelper.UpdateStatus(TN_Task, "取货完成"); TaskProcess.OperateStatus(TN_Task, 4); break; case 5: WCSHelper.UpdateStatus(TN_Task, "开始卸货"); break; case 6: WCSHelper.UpdateStatus(TN_Task, "卸货完成"); TaskProcess.OperateStatus(TN_Task, 6); break; #endregion case 2: WCSHelper.End(TN_Task); break; case 7: TaskProcess.OperateStatus(TN_Task, 7); WCSHelper.Fail(TN_Task); break; } WCSHelper.AddActionRecord(model.No, model.State, model.ForkliftNo, model.ExtData); //调用第三方接口(如果有)TaskProcess.ReportStatus } else { //安全请求等 TaskProcess.OperateReq(model.No, model.State, model.ForkliftNo, model.ExtData); } } } } /// /// 任务分发,根据调度类型发给不同的调度系统 /// internal static void Dispatch() { //查询任务 //获取所有等待的任务 var list = WCSHelper.GetWaitingTaskList(); if (list.Count > 0) { list.ForEach(task => { if (!TaskProcess.Intercept(task)) { //使用自定义任务推送 TaskProcess.SendTask(task); } }); } } /// /// 杭奥堆垛机信号反馈 /// /// internal static void OperateHATaskStatus(HanAo.TaskStateInfoModel model) { var wcsTask = WCSHelper.GetTask(model.requestPk); if (wcsTask != null) { if (model.code == "0") { // if (wcsTask.S_TYPE == "堆垛机入库") { //终点托盘绑定 if (LocationHelper.BindingLoc(wcsTask.S_END_LOC, new List { wcsTask.S_CNTR_CODE })) { //修改托盘状态为可用,增加库存量表,后面分拣出可以计算到 ContainerHelper.Enable(wcsTask.S_CNTR_CODE, wcsTask.S_END_LOC); } } else if (wcsTask.S_TYPE == "堆垛机出库") { //起点托盘解绑 LocationHelper.UnBindingLoc(wcsTask.S_START_LOC, new List { wcsTask.S_CNTR_CODE }); } //标记任务完成 //标记作业完成 wcsTask.N_B_STATE = 3; WCSHelper.UpdateStatus(wcsTask); var wmsTask = WMSHelper.GetWmsTask(wcsTask.S_OP_CODE); if (wmsTask != null) { wmsTask.N_B_STATE = 2; WMSHelper.UpdateTaskState(wmsTask); } } } } internal static object finish_lock = new object(); /// /// 国自AGV信号反馈 /// state 0等待 1执行中 3开始取货 4取货完成 5开始卸货 6卸货完成 2完成 7取消 /// /// internal static void OperateGZTaskStatus(GZAgvTaskState model) { int state = 0; var TN_Task = wms.WCSHelper.GetTaskByEQTaskNo(model.OrderID.ToString()); if (TN_Task != null) { if (model.errorCode == 0) { if (model.OrderStatus != null && model.OrderStatus != "") { var cntrCodes = TN_Task.S_CNTR_CODE.Split(',').ToList(); switch (model.OrderStatus) { case "waiting": wms.WCSHelper.Begin(TN_Task); wms.WCSHelper.UpdateStatus(TN_Task, "等待处理"); break; case "active": wms.WCSHelper.UpdateStatus(TN_Task, "正在处理"); state = 1; // 执行中 break; case "dispatched": wms.WCSHelper.UpdateStatus(TN_Task, "AGV调度中"); state = 3; // 取货中 break; case "source_finish": wms.WCSHelper.UpdateStatus(TN_Task, "起点完成"); LocationHelper.UnBindingLoc(TN_Task.S_START_LOC, cntrCodes); LocationHelper.UnLockLoc(TN_Task.S_START_LOC); state = 4; // 取货完成 break; case "dest_finish": wms.WCSHelper.UpdateStatus(TN_Task, "卸货完成"); LocationHelper.BindingLoc(TN_Task.S_END_LOC, cntrCodes); LocationHelper.UnLockLoc(TN_Task.S_END_LOC); state = 6; // 卸货完成 break; case "finish": wms.WCSHelper.End(TN_Task); state = 2; // 完成 break; case "error": cancelTask(TN_Task, cntrCodes); state = 7; // 取消 break; case "cancel_finish": cancelTask(TN_Task, cntrCodes); state = 7; // 取消 break; case "manually_finish": wms.WCSHelper.End(TN_Task); wms.WCSHelper.UpdateStatus(TN_Task, "手动完成"); LocationHelper.UnBindingLoc(TN_Task.S_START_LOC, cntrCodes); LocationHelper.UnLockLoc(TN_Task.S_START_LOC); LocationHelper.BindingLoc(TN_Task.S_END_LOC, cntrCodes); LocationHelper.UnLockLoc(TN_Task.S_END_LOC); state = 2; // 完成 break; } wms.WCSHelper.AddActionRecord(TN_Task.S_CODE, state, model.agvIDList.Split(',').ToList().First(), model.extraInfo1, model.OrderStatus); // 任务完成反馈WMS WMSTask wst = WMSHelper.GetWmsTask(TN_Task.S_OP_CODE); if (model.OrderStatus == "finish" || model.OrderStatus == "manually_finish") { lock (finish_lock) { if (wst != null) { if (TN_Task.S_END_LOC == wst.S_END_LOC) { wst.N_B_STATE = 2; wst.T_END_TIME = DateTime.Now; WMSHelper.UpdateTaskState(wst); var endLoc = LocationHelper.GetLoc(wst.S_END_LOC); var fuller = LocationHelper.getFullerLocCode(endLoc.S_AREA_CODE, endLoc.N_ROW); if (wst.S_TYPE == "入库任务") { LogHelper.Info("OperateGZTaskStatus: 1", "WMS"); // 入库任务生成后,则调 收货回传接口 ,反馈信息给WMS foreach (var cntrCode in cntrCodes) { var cntrItemRels = ContainerHelper.GetCntrItemRel(cntrCode); if (cntrItemRels != null && cntrItemRels.Count > 0) { LogHelper.Info($"OperateGZTaskStatus: 2 ,cntrCode:{cntrCode},S_ASN_NO ={cntrItemRels[0].S_ASN_NO},", "WMS"); var inStockListChilds = WMSHelper.getInstockListChild(cntrCode, cntrItemRels[0].S_ASN_NO); LogHelper.Info($"OperateGZTaskStatus: 2 ,inStockListChilds.count:{inStockListChilds.Count}", "WMS"); if (inStockListChilds != null && inStockListChilds.Count > 0) { LogHelper.Info("OperateGZTaskStatus: 3", "WMS"); receiveGoodsFeedback(inStockListChilds, cntrItemRels[0].F_NET_WEIGHT.ToString(), cntrCode, TN_Task.S_END_LOC); } } } } else if (wst.S_TYPE == "出库任务") { // 完成出库任务 WMSHelper.completedOutstockTask(TN_Task, wst.S_OP_DEF_CODE); // 托盘出库回报 trayOutStockFeedback(TN_Task, wst.S_OP_DEF_CODE); } else if (wst.S_TYPE == "移库任务") { shiftFeedback(fuller, wst, cntrCodes); } else if (wst.S_TYPE == "抽检任务") { var spotCheckList = WMSHelper.GetShopCheckList(wst.S_OP_DEF_CODE, wst.S_CNTR_CODE); spotCheckList.S_STATUS = "待检验"; spotCheckList.N_STATUS = 2; WMSHelper.updateSpotCheckList(spotCheckList); /* List feedbackDatas = new List(); ShiftingStockOrderFeedbackData.FeedbackData feedbackData = new ShiftingStockOrderFeedbackData.FeedbackData() { organizationId = Settings.orgInfo.organizationId, warehouseId = Settings.orgInfo.warehouseId, customerId = Settings.orgInfo.customerId, mdocNo = wst.S_OP_DEF_CODE, mdocType = "AGV", traceId = wst.S_CNTR_CODE, toLocationId = fuller.FULLER_CODE, }; feedbackDatas.Add(feedbackData); WMSDispatch.ShiftingStockOrderFeedback(feedbackDatas);*/ } } } } } if (model.OrderStatus == "error" || model.OrderStatus == "cancel_finish") { if (wst.S_TYPE == "出库任务") { } } } } } } /// /// 取消任务 /// 1.卸货完成的任务无法取消 /// /// /// public static void cancelTask(WCSTask cst,List cntrCodes) { var exist = WCSHelper.CheckActionRecordExist(cst.S_CODE, 6); if (cst.N_B_STATE <= 2 && !exist) { LocationHelper.UnLockLoc(cst.S_START_LOC); LocationHelper.UnLockLoc(cst.S_END_LOC); cst.N_B_STATE = 4; WCSHelper.UpdateStatus(cst, "取消"); WMSTask wst = WMSHelper.GetWmsTask(cst.S_OP_CODE); if (wst != null) { wst.N_B_STATE = 3; wst.T_END_TIME = DateTime.Now; WMSHelper.UpdateTaskState(wst); if (wst.S_TYPE == "入库任务") { foreach (var cntrCode in cntrCodes) { ContainerHelper.deleteCntrItem(cntrCode); } } } } } public static int safetyInteraction(SafetyInfo model) { bool result = false; PipelineSignalInfo lineSignalInfo = null; LineDeviceInfo lineDeviceInfo = Settings.lineDeviceInfos.Where(a => a.localtion == model.station_name && a.type == 2).First(); if (lineDeviceInfo != null) { lineSignalInfo = WCSHelper.readPipelineInfo(lineDeviceInfo); LogHelper.Info("安全交互: " + JsonConvert.SerializeObject(lineSignalInfo), "输送线"); } if (model.station_name != null) { switch (model.apply_code) { case 1: if (lineSignalInfo != null && lineSignalInfo.agvInfo == 2 && (lineSignalInfo.faultMessage == 0 || lineSignalInfo.faultMessage == 1)) { LogHelper.Info("向输送线下发AGV安全信号【9】 ", "输送线"); S7Helper.WriteInt(lineDeviceInfo.deviceNo, 101, lineDeviceInfo.writeAddr + 16, 9); result = true; } break; case 2: break; case 4: S7Helper.WriteInt(lineDeviceInfo.deviceNo, 101, lineDeviceInfo.writeAddr + 14, 1); // AGV 取货完成 1 LogHelper.Info("AGV取货完成,并向输送线下发AGV任务反馈", "输送线"); LogHelper.Info("安全退出【0】 ", "输送线"); S7Helper.WriteInt(lineDeviceInfo.deviceNo, 101, lineDeviceInfo.writeAddr + 16, 0); result = true; break; } } return result ? 0 : 1; } public static List> shiftFeedbackDatas = new List>(); public static List> outStockFeedbackDatas = new List>(); /// /// 托盘出库回报 /// /// /// public static void trayOutStockFeedback(WCSTask cst ,string orderNo) { var outStockListChild = WMSHelper.getOutstockListChildBySeqNo(orderNo , cst.S_DATA); if (outStockListChild != null) { List cntrCodeList = new List(); cntrCodeList = cst.S_CNTR_CODE.Split(',').ToList(); if (cntrCodeList != null && cntrCodeList.Count > 0) { foreach (var cntrCode in cntrCodeList) { LocCntrRel locCntrRel = LocationHelper.GetLocCntrRelByCntr(cntrCode); var cntrItemRels = ContainerHelper.GetCntrItemRel(cntrCode); if (cntrItemRels.Count > 0 ) { var endLoc = LocationHelper.GetLoc(cst.S_END_LOC); var fuller = LocationHelper.getFullerLocCode(endLoc.S_AREA_CODE, endLoc.N_ROW); if (fuller != null) { if (outStockListChild.COMPLETED_QTY > outStockListChild.N_QTY) { float outNum = outStockListChild.COMPLETED_QTY - outStockListChild.N_QTY; if (locCntrRel.N_BIND_ORDER == 1) { if (outNum > cntrItemRels[0].F_QTY) { // 出库多于托盘则需要调用 “移库单移库反馈接口” 反馈 List feedbackDatas = new List(); ShiftingStockOrderFeedbackData.FeedbackData feedbackData = new ShiftingStockOrderFeedbackData.FeedbackData() { organizationId = Settings.orgInfo.organizationId, warehouseId = Settings.orgInfo.warehouseId, customerId = Settings.orgInfo.customerId, mdocType = "AGV", traceId = cntrCode, toLocation = fuller.FULLER_CODE, }; if (!WMSDispatch.ShiftingStockOrderFeedback(feedbackDatas)) { shiftFeedbackDatas.Add(feedbackDatas); } } } } // 出库任务完成后,则 发货托盘回传WMS接口,进行反馈 List feedbackDatas1 = new List(); ShipmentsTrayFeedbackData.FeedbackData feedbackData1 = new ShipmentsTrayFeedbackData.FeedbackData() { organizationId = Settings.orgInfo.organizationId, warehouseId = Settings.orgInfo.warehouseId, customerId = Settings.orgInfo.customerId, orderNo = orderNo, sku = outStockListChild.S_SKU, qty = cntrItemRels[0].F_QTY.ToString(), weighQty = cntrItemRels[0].F_NET_WEIGHT.ToString(), traceId = cntrCode, serialNo = cntrItemRels[0].S_SERIAL_NO, toLocationId = fuller.FULLER_CODE, completedFlag = "N", }; feedbackDatas1.Add(feedbackData1); if (!WMSDispatch.ShipmentsTrayFeedback(feedbackDatas1)) { outStockFeedbackDatas.Add(feedbackDatas1); } var result = WMSHelper.isCompletedOutstockOrder(orderNo); if (result) { List feedbackDatas2 = new List(); var feedbackData2 = new ShipmentsTrayFeedbackData.FeedbackData() { organizationId = Settings.orgInfo.organizationId, warehouseId = Settings.orgInfo.warehouseId, customerId = Settings.orgInfo.customerId, orderNo = orderNo, sku = outStockListChild.S_SKU, qty = cntrItemRels[0].F_QTY.ToString(), weighQty = cntrItemRels[0].F_NET_WEIGHT.ToString(), traceId = cntrCode, serialNo = cntrItemRels[0].S_SERIAL_NO, toLocationId = fuller.FULLER_CODE, completedFlag = "Y" }; feedbackDatas2.Add(feedbackData2); if (!WMSDispatch.ShipmentsTrayFeedback(feedbackDatas2)) { outStockFeedbackDatas.Add(feedbackDatas2); } } } } } } } } public static List> inStockFeedbackDatas = new List>(); /// /// 物料入库反馈 /// /// /// /// /// public static void receiveGoodsFeedback(List inStockListChilds, string weight, string trayCode, string endLocCode) { LogHelper.Info("receiveGoodsFeedback: 1", "WMS"); // 1.入库完成,更新状态 WMSHelper.instockCompleted(inStockListChilds); LogHelper.Info("receiveGoodsFeedback: 2", "WMS"); // 2.预期入库单全部入库完成后,对最后两托物料进行抽检 var result = WMSHelper.isCompletedInstockOrder(inStockListChilds[0].S_ASN_NO); if (result) { putCheckSign(inStockListChilds[0].S_ASN_NO); } LogHelper.Info("receiveGoodsFeedback: 3", "WMS"); // 3.收货反馈WMS List feedbackDatas = new List(); foreach (var item in inStockListChilds) { var endLoc = LocationHelper.GetLoc(endLocCode); var fuller = LocationHelper.getFullerLocCode(endLoc.S_AREA_CODE, endLoc.N_ROW); if (fuller != null) { ReceiveGoodsFeedbackData.FeedbackData feedbackData = new ReceiveGoodsFeedbackData.FeedbackData() { organizationId = Settings.orgInfo.organizationId, warehouseId = Settings.orgInfo.warehouseId, customerId = Settings.orgInfo.customerId, ASNNo = item.S_ASN_NO, sku = item.S_SKU, qty = item.N_QTY.ToString(), weighQty = weight, traceId = trayCode, serialNo = item.S_SERIAL_NO, locationId = fuller.FULLER_CODE, completedFlag = "N", }; feedbackDatas.Add(feedbackData); } else { LogHelper.Info("收货反馈WMS,查询富乐库区失败", "Mobox"); } } LogHelper.Info("receiveGoodsFeedback: 4", "WMS"); if (feedbackDatas.Count > 0) { var feedbackResult = WMSDispatch.ReceiveGoodsFeedback(feedbackDatas); if (!feedbackResult) { inStockFeedbackDatas.Add(feedbackDatas); } } if (result) { List feedbackDatas1 = new List(); ReceiveGoodsFeedbackData.FeedbackData feedbackData = new ReceiveGoodsFeedbackData.FeedbackData() { organizationId = Settings.orgInfo.organizationId, warehouseId = Settings.orgInfo.warehouseId, customerId = Settings.orgInfo.customerId, ASNNo = inStockListChilds[0].S_ASN_NO, sku = inStockListChilds[0].S_SKU, serialNo = inStockListChilds[0].S_SERIAL_NO, completedFlag = "Y", }; feedbackDatas1.Add(feedbackData); var feedbackResult = WMSDispatch.ReceiveGoodsFeedback(feedbackDatas1); if (!feedbackResult) { inStockFeedbackDatas.Add(feedbackDatas1); } } } /// /// 抽取该批次最外侧物料打上抽检标记,等待抽检 /// /// public static void putCheckSign(string asnNo) { var db = new SqlHelper().GetInstance(); var loc = db.Queryable() .LeftJoin((a, b) => a.S_CODE == b.S_LOC_CODE) .LeftJoin((a, b, c) => b.S_CNTR_CODE == c.S_CNTR_CODE) .Where((a, b, c) => a.N_CURRENT_NUM > 0 && c.S_ASN_NO == asnNo) .OrderByDescending((a, b, c) => a.N_COL) .OrderBy((a, b, c) => a.N_CURRENT_NUM ) .First(); LocCntrRel locCntrRel = LocationHelper.GetLocCntr(loc.S_CODE).OrderByDescending(a => a.N_BIND_ORDER).FirstOrDefault(); if (locCntrRel != null) { var cntrItems = ContainerHelper.GetCntrItemRel(locCntrRel.S_CNTR_CODE); if (cntrItems != null && cntrItems.Count > 0) { cntrItems[0].S_CHECK_FLAG = "Y"; ContainerHelper.UpdateCntrItemRel(cntrItems[0]); SpotCheckList spotCheckList = new SpotCheckList() { S_ASN_NO = asnNo, S_SKU = cntrItems[0].S_ITEM_CODE, S_TRACE_ID = locCntrRel.S_CNTR_CODE, N_STATUS = 1, S_STATUS = "待出库", S_LOC_CODE = locCntrRel.S_LOC_CODE }; WMSHelper.addSpotCheckList(spotCheckList); } } } /// /// 移库反馈上游 /// /// /// /// public static void shiftFeedback(TN_Fuller fuller, WMSTask wst, List cntrCodes) { if (fuller != null) { // 移库任务完成后, 则需要 调移库单移库反馈接口 List feedbackDatas = new List(); if (wst.S_OP_DEF_NAME == "创建抽检品回库任务") { var spotCheckList = WMSHelper.GetShopCheckList(wst.S_OP_DEF_CODE, wst.S_CNTR_CODE); spotCheckList.S_STATUS = "已回库"; spotCheckList.N_STATUS = 4; WMSHelper.updateSpotCheckList(spotCheckList); } else { string mdocType = "AGV"; if (wst.S_OP_DEF_NAME == "移库同步单") { mdocType = "WMS"; } // 入库任务生成后,则调 收货回传接口 ,反馈信息给WMS foreach (var cntrCode in cntrCodes) { if (mdocType == "WMS") { var shiftStockListChild = WMSHelper.getShiftstockListChild(wst.S_OP_DEF_CODE, cntrCode); if (shiftStockListChild != null) { WMSHelper.shiftstockListCompleted(shiftStockListChild); } else { LogHelper.Info("WMS移库任务反馈,未查询到移库单", "Mobox"); } } ShiftingStockOrderFeedbackData.FeedbackData feedbackData = new ShiftingStockOrderFeedbackData.FeedbackData() { organizationId = Settings.orgInfo.organizationId, warehouseId = Settings.orgInfo.warehouseId, customerId = Settings.orgInfo.customerId, mdocNo = wst.S_OP_DEF_CODE, mdocType = mdocType, traceId = cntrCode, toLocation = fuller.FULLER_CODE, }; feedbackDatas.Add(feedbackData); } } if (!WMSDispatch.ShiftingStockOrderFeedback(feedbackDatas)) { shiftFeedbackDatas.Add(feedbackDatas); } } } } }