2 文件已重命名
3个文件已添加
39个文件已修改
124个文件已删除
| | |
| | | <Compile Include="dispatch\NDC.cs" /> |
| | | <Compile Include="core\Monitor.cs" /> |
| | | <Compile Include="dispatch\NDCApi.cs" /> |
| | | <Compile Include="dispatch\WCSDispatch.cs" /> |
| | | <Compile Include="models\BaseModel.cs" /> |
| | | <Compile Include="models\Area.cs" /> |
| | | <Compile Include="models\ItemBarcodeInfo.cs" /> |
| | |
| | | { |
| | | foreach (var item in itemInfos) |
| | | { |
| | | // 将MES的物料状态转化成WMS可识别的物料状态 |
| | | if (item.jdge == "" || item.jdge == null) |
| | | { |
| | | item.jdge = "OK"; |
| | | } |
| | | else if(item.jdge != "OK") |
| | | { |
| | | item.jdge = "HOLD"; |
| | | } |
| | | |
| | | // 计算生效时间、失效时间 |
| | | var overage = WMSHelper.getOverage(item.bc_entried); |
| | | if (overage != null) |
| | | { |
| | |
| | | S_END_AREA = endLoc.S_AREA_CODE, |
| | | S_TYPE = model.taskType, |
| | | S_OP_DEF_CODE = model.taskNo, |
| | | S_OP_DEF_NAME = "半制品/余料/空托下发入库任务", |
| | | N_PRIORITY = model.priority, |
| | | T_START_TIME = DateTime.Now, |
| | | }; |
| | |
| | | S_END_AREA = endLoc.S_AREA_CODE, |
| | | S_TYPE = "空托出库任务", |
| | | S_OP_DEF_CODE = model.taskNo, |
| | | S_OP_DEF_NAME = "空托出库任务", |
| | | N_PRIORITY = model.priority, |
| | | T_START_TIME = DateTime.Now, |
| | | }; |
| | |
| | | else |
| | | { |
| | | result.ResultCode = 1; |
| | | result.ResultMsg = "库内没有查到此物料"; |
| | | result.ResultMsg = "库内没有满足条件的物料"; |
| | | return result; |
| | | } |
| | | |
| | |
| | | S_END_AREA = endLoc.S_AREA_CODE, |
| | | S_TYPE = "成型机叫料出库任务", |
| | | S_OP_DEF_CODE = model.taskNo, |
| | | S_OP_DEF_NAME = "成型机叫料出库任务", |
| | | N_PRIORITY = model.priority, |
| | | T_START_TIME = DateTime.Now, |
| | | }; |
| | |
| | | { |
| | | foreach (var item in model.itemInfo) |
| | | { |
| | | // 将MES的物料状态转化成WMS可识别的物料状态 |
| | | if (item.jdge == "" || item.jdge == null) |
| | | { |
| | | item.jdge = "OK"; |
| | | } |
| | | else if (item.jdge != "OK") |
| | | { |
| | | item.jdge = "HOLD"; |
| | | } |
| | | |
| | | var overage = WMSHelper.getOverage(item.bc_entried); |
| | | if (overage != null) |
| | | if (overage != null && overage.OVERAGE != 0) |
| | | { |
| | | DateTime txndate = DateTime.Parse(item.txndate); |
| | | DateTime minTime = txndate.AddHours(overage.MINHOUR); |
| | |
| | | S_END_AREA = endLoc.S_AREA_CODE, |
| | | S_TYPE = "人工入库任务", |
| | | S_OP_DEF_CODE = model.taskNo, |
| | | S_OP_DEF_NAME = "人工入库任务", |
| | | N_PRIORITY = model.priority, |
| | | T_START_TIME = DateTime.Now, |
| | | }; |
| | |
| | | S_END_AREA = endLoc.S_AREA_CODE, |
| | | S_TYPE = "人工出库任务", |
| | | S_OP_DEF_CODE = model.taskNo, |
| | | S_OP_DEF_NAME = "人工出库任务", |
| | | N_PRIORITY = model.priority, |
| | | T_START_TIME = DateTime.Now, |
| | | }; |
| | |
| | | else |
| | | { |
| | | result.ResultCode = 1; |
| | | result.ResultMsg = "库内没有此物料"; |
| | | result.ResultMsg = "库内没有满足条件的物料"; |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | |
| | | S_END_AREA = endLoc.S_AREA_CODE, |
| | | S_TYPE = "母拖入库任务", |
| | | S_OP_DEF_CODE = taskNo, |
| | | S_OP_DEF_NAME = "母拖入库任务", |
| | | N_PRIORITY = 1, |
| | | T_START_TIME = DateTime.Now, |
| | | }; |
| | |
| | | ReturnResult result = new ReturnResult(); |
| | | try |
| | | { |
| | | var mst = WMSHelper.GetWmsTask(wmsTaskNo); |
| | | if (mst != null && mst.N_B_STATE < 2) |
| | | var cst = WCSHelper.GetTaskByStart(loc); |
| | | if (cst == null) |
| | | { |
| | | Location startLoc = LocationHelper.GetLoc(loc); |
| | | Location endLoc = LocationHelper.GetLoc(Settings.baseTrayInBufferLoc); |
| | | if (!(endLoc != null && endLoc.N_CURRENT_NUM == 0)) |
| | | if (!(endLoc != null && endLoc.N_CURRENT_NUM == 0)) |
| | | { |
| | | endLoc = WMSHelper.GetInstockEndLoc(0, loc, 2); |
| | | } |
| | | } |
| | | |
| | | if (endLoc != null && startLoc != null) |
| | | { |
| | |
| | | // 创建一段入库任务 |
| | | WCSTask wcsTask = new WCSTask() |
| | | { |
| | | S_OP_NAME = mst.S_OP_DEF_NAME, |
| | | S_OP_CODE = mst.S_CODE, |
| | | S_OP_CODE = wmsTaskNo, |
| | | S_CODE = WCSHelper.GenerateTaskNo(), |
| | | S_CNTR_CODE = trayCode, |
| | | S_TYPE = "母拖入库任务", |
| | |
| | | /// <param name="loc"></param> |
| | | /// <param name="taskNo"></param> |
| | | /// <returns></returns> |
| | | public static ReturnResult baseTrayOutStock(string loc ,string taskNo) |
| | | public static ReturnResult baseTrayOutStock(string loc ,string taskNo ,int exclude = 1) |
| | | { |
| | | LogHelper.Info("【母拖出库任务】开始下发母拖出库任务", "WMS"); |
| | | ReturnResult result = new ReturnResult(); |
| | | try |
| | | { |
| | | Location startLoc = WMSHelper.GetEmptyTrayStartLoc(0, 1); |
| | | Location startLoc = WMSHelper.GetEmptyTrayStartLoc(0, exclude); |
| | | Location endLoc = LocationHelper.GetLoc(loc); |
| | | var agvJBLoc = Settings.getAgvJBLoc(loc); |
| | | |
| | |
| | | S_END_AREA = endLoc.S_AREA_CODE, |
| | | S_TYPE = "母拖出库任务", |
| | | S_OP_DEF_CODE = taskNo, |
| | | S_OP_DEF_NAME = "母拖出库任务", |
| | | N_PRIORITY = 1, |
| | | T_START_TIME = DateTime.Now, |
| | | }; |
| | |
| | | ReturnResult result = new ReturnResult(); |
| | | try |
| | | { |
| | | var mst = WMSHelper.GetWmsTask(wmsTaskNo); |
| | | if (mst != null && mst.N_B_STATE < 2) |
| | | var cst = WCSHelper.GetTaskByEnd(loc); |
| | | if (cst == null) |
| | | { |
| | | Location startLoc = WMSHelper.GetEmptyTrayStartLoc(0,0); |
| | | Location startLoc = WMSHelper.GetEmptyTrayStartLoc(0, 0); |
| | | Location endLoc = LocationHelper.GetLoc(loc); |
| | | |
| | | if (startLoc != null) |
| | |
| | | // 创建入库任务 |
| | | WCSTask wcsTask = new WCSTask() |
| | | { |
| | | S_OP_NAME = mst.S_OP_DEF_NAME, |
| | | S_OP_CODE = mst.S_CODE, |
| | | S_OP_CODE = wmsTaskNo, |
| | | S_CODE = WCSHelper.GenerateTaskNo(), |
| | | S_CNTR_CODE = trayCode, |
| | | S_TYPE = "母拖出库任务", |
| | |
| | | BOM3 = matl.bom3, |
| | | S_FOVRAGE = matl.fovrage, |
| | | S_JDGE = matl.jdge, |
| | | S_WMS_JDGE = matl.WMS_jdge, |
| | | EFFECTIVE_TIME = matl.effective_time, |
| | | EXPIRATION_TIME = matl.expiration_time, |
| | | LAST_MODIFY_TIME = matl.last_modify_time |
| | | }; |
| | | itemBarcodeInfos.Add(itemBarcodeInfo); |
| | |
| | | if (overages != null && overages.Count > 0) |
| | | { |
| | | List<Overage> overageList = new List<Overage>(); |
| | | |
| | | foreach (var item in overages) |
| | | { |
| | | Overage overage = new Overage |
| | |
| | | MCNGRP = item.mcngrp, |
| | | ITEMPATT = item.itempatt, |
| | | OVERAGE = item.overage, |
| | | MINHOUR = int.Parse(item.minhour.ToString()) , |
| | | MINHOUR = float.Parse(item.minhour.ToString()), |
| | | FLAG_STS = item.flag_sts, |
| | | RECID = item.recid, |
| | | }; |
| | | overageList.Add(overage); |
| | | } |
| | |
| | | if (!bo) |
| | | { |
| | | responseResult.ResultCode = 1; |
| | | responseResult.ResultMsg = "同步物料状态信息失败"; |
| | | responseResult.ResultMsg = "记录数据同步时间失败"; |
| | | } |
| | | return responseResult; |
| | | } |
| | |
| | | { |
| | | ReturnResult responseResult = new ReturnResult(); |
| | | var synDataTime = WMSHelper.getLastDataSynTime(recordTable); |
| | | responseResult.data = synDataTime; |
| | | if (synDataTime != null) |
| | | { |
| | | Dictionary<string, string> map = new Dictionary<string, string>(); |
| | | map.Add("S_SYN_TIME", synDataTime.S_SYN_TIME); |
| | | map.Add("RECORD_TABLE", synDataTime.RECORD_TABLE); |
| | | responseResult.data = map; |
| | | } |
| | | return responseResult; |
| | | } |
| | | |
| | |
| | | { |
| | | public int ResultCode { get; set; } = 0; |
| | | public string ResultMsg { get; set; } |
| | | |
| | | public object data { get; set; } |
| | | } |
| | | |
| | | public class ResponseResult |
| | | { |
| | | public int code { get; set; } = 200; |
| | | public string msg { get; set; } |
| | | public object data { get; set; } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// hosttoagv上报任务状态 |
| | | /// </summary> |
| | |
| | | public decimal minhour { get; set; } // 最小工作时间或条件 |
| | | public string flag_sts { get; set; } // 状态标记 |
| | | public int recid { get; set; } |
| | | public DateTime last_modify_time { get; set; } |
| | | public string last_modify_time { get; set; } |
| | | } |
| | | |
| | | public class RecordDataSynTimeModel |
| | |
| | | var cst = WCSHelper.GetTaskByStartAndEnd(endLoc.S_CODE); |
| | | if (cst == null) |
| | | { |
| | | ApiHelper.baseTrayOutStockAgv(endLoc.S_CODE, null); |
| | | ApiHelper.baseTrayOutStock(endLoc.S_CODE, null , 0); |
| | | } |
| | | } |
| | | } |
| | |
| | | namespace HH.WCS.Mobox3.YNJT_BZP.core { |
| | | internal class WCSCore { |
| | | public static void OperateAgvTaskStatus(AgvTaskState model) { |
| | | LogHelper.Info($"AGV任务状态反馈,入参:{JsonConvert.SerializeObject(model)}", "AGV"); |
| | | try |
| | | { |
| | | if (string.IsNullOrEmpty(model.No)) |
| | |
| | | break; |
| | | } |
| | | } |
| | | else if (model.State == 2001) |
| | | else if (model.State == 1002) |
| | | { |
| | | //申请新终点 |
| | | string endLoc = AGVApplyEndLoc(model.No); |
| | | //查询当前终点是等待区,则查询入库agv接驳位 |
| | | var waitLoc = Settings.getAgvWaitLoc(TN_Task.S_END_LOC); |
| | | if (waitLoc != null) |
| | | { |
| | | string endLoc = AGVApplyEndLoc(model.No); |
| | | |
| | | |
| | | } |
| | | |
| | | //如果不是等待区货位,则查询终点货位是否是入库接驳位 |
| | | var agvJBLoc = Settings.getAgvJBLoc(TN_Task.S_END_LOC); |
| | | if (agvJBLoc != null && agvJBLoc.type == 1 && agvJBLoc.action == 1) |
| | | { |
| | | //是则查询WCS的任务执行情况 |
| | | var wcsTask = WCSHelper.GetTaskBySrcNoAndScheduleType(TN_Task.S_OP_CODE ,"WCS"); |
| | | if (wcsTask != null) |
| | | { |
| | | bool existAction = WCSHelper.CheckActionRecordExist(wcsTask.S_CODE, 7); |
| | | if (existAction) |
| | | { |
| | | //如果WCS反馈7取消任务,则rfid校验失败,生成新任务到异常区,并变更agv任务号、起点、终点 |
| | | var mst = WMSHelper.GetWmsTask(TN_Task.S_OP_CODE); |
| | | var endLoc = WMSHelper.getErrorBufferAreaLoc(); |
| | | if (endLoc != null) |
| | | { |
| | | LocationHelper.UnLockLoc(mst.S_END_LOC); |
| | | mst.S_END_LOC = endLoc.S_CODE; |
| | | mst.S_END_AREA = endLoc.S_AREA_CODE; |
| | | |
| | | WMSHelper.UpdateTaskEnd(mst); |
| | | WCSCore.createLastTask(TN_Task.S_END_LOC, mst, 2); |
| | | } |
| | | else |
| | | { |
| | | LogHelper.Info("", "AGV"); |
| | | } |
| | | } |
| | | |
| | | existAction = WCSHelper.CheckActionRecordExist(wcsTask.S_CODE, 3); |
| | | if (existAction) |
| | | { |
| | | //WCS反馈3已取货,则agv任务正常结束 |
| | | |
| | | } |
| | | } |
| | | } |
| | | } |
| | | else |
| | | { |
| | |
| | | /// <param name="taskNo"></param> |
| | | public static string AGVApplyEndLoc(string taskNo) |
| | | { |
| | | LogHelper.Info("【agv申请终点】", "AGV"); |
| | | string endLocCode = null; |
| | | LogHelper.Info($"任务号:{taskNo},AGV等待区申请终点", "AGV"); |
| | | var cst = WCSHelper.GetTask(taskNo); |
| | | if (cst != null && cst.N_B_STATE < 3) |
| | | if (cst != null && cst.N_B_STATE < 3) |
| | | { |
| | | var mst = WMSHelper.GetWmsTask(cst.S_OP_CODE); |
| | | if (mst != null && mst.N_B_STATE < 2 && mst.S_END_LOC == "虚拟货位") |
| | | if (mst != null && mst.N_B_STATE < 2 && mst.S_END_LOC == "虚拟货位") |
| | | { |
| | | var container = ContainerHelper.GetCntr(cst.S_CNTR_CODE); |
| | | if (container != null) |
| | | if (container != null) |
| | | { |
| | | var endLoc = WMSHelper.GetInstockEndLoc(container.N_TYPE); |
| | | if (endLoc != null) |
| | | { |
| | | Location agvLoc = null; |
| | | var locCodes = Settings.getAgvJBLocList(1, endLoc.N_ROADWAY, 1); |
| | | if (locCodes.Count > 0) |
| | | if (locCodes.Count > 0) |
| | | { |
| | | agvLoc = LocationHelper.GetLoc(locCodes[0]); |
| | | } |
| | | |
| | | if (agvLoc != null && agvLoc.C_ENABLE == "Y") |
| | | { |
| | | var wcsTask = WCSHelper.GetTaskByStartAndEnd(agvLoc.S_CODE); |
| | | if (wcsTask == null && agvLoc.N_LOCK_STATE == 0) |
| | | foreach (var locCode in locCodes) |
| | | { |
| | | // 胎圈入库,下发母拖出库任务 \ 帘布、内衬入库,下发托盘回库任务 |
| | | if (mst.S_TYPE.Contains("入库")) |
| | | agvLoc = LocationHelper.GetLoc(locCode); |
| | | if (agvLoc != null && agvLoc.C_ENABLE == "Y") |
| | | { |
| | | if (agvLoc.N_CURRENT_NUM == 1) |
| | | { |
| | | var locCntrRels = LocationHelper.GetLocCntr(agvLoc.S_CODE); |
| | | if (locCntrRels.Count > 0) |
| | | { |
| | | var container1 = ContainerHelper.GetCntr(locCntrRels[0].S_CNTR_CODE); |
| | | if (container1.N_TYPE == 0) |
| | | { |
| | | if (container.N_TYPE == 4 || container.N_TYPE == 5) |
| | | { |
| | | ApiHelper.baseTrayInStockAgv(agvLoc.S_CODE, mst.S_CODE); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | LogHelper.Info($"接驳位:{agvLoc.S_CODE},存在非母拖容器", "AGV"); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | LogHelper.Info($"接驳位:{agvLoc.S_CODE}的当前数量与容器数量不匹配", "AGV"); |
| | | } |
| | | } |
| | | else if (agvLoc.N_CURRENT_NUM == 0) |
| | | { |
| | | if (container.N_TYPE == 6) |
| | | { |
| | | ApiHelper.baseTrayOutStockAgv(agvLoc.S_CODE, mst.S_CODE); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | return endLocCode; |
| | | } |
| | | cst.S_END_LOC = agvLoc.S_CODE; |
| | | cst.S_END_AREA = agvLoc.S_AREA_CODE; |
| | | WCSHelper.UpdateTaskEnd(cst); |
| | | |
| | | mst.S_END_LOC = endLoc.S_CODE; |
| | | mst.S_END_AREA = endLoc.S_AREA_CODE; |
| | | WMSHelper.UpdateTaskEnd(mst); |
| | | LocationHelper.LockLoc(endLoc.S_CODE, 1); |
| | | |
| | | LogHelper.Info($"任务号:{taskNo},AGV申请的终点:{agvLoc.S_CODE}", "AGV"); |
| | | return agvLoc.S_CODE; |
| | | } |
| | | cst.S_END_LOC = agvLoc.S_CODE; |
| | | cst.S_END_AREA = agvLoc.S_AREA_CODE; |
| | | WCSHelper.UpdateTaskEnd(cst); |
| | | |
| | | mst.S_END_LOC = endLoc.S_CODE; |
| | | mst.S_END_AREA = endLoc.S_AREA_CODE; |
| | | WMSHelper.UpdateTaskEnd(mst); |
| | | |
| | | LocationHelper.LockLoc(agvLoc.S_CODE, 1); |
| | | LocationHelper.LockLoc(endLoc.S_CODE, 1); |
| | | endLocCode = agvLoc.S_CODE; |
| | | } |
| | | else |
| | | { |
| | | LogHelper.Info("接驳位当前有任务未完成,请稍等", "AGV"); |
| | | } |
| | | |
| | | LogHelper.Info($"任务号:{taskNo},入库接驳位货位都已禁用", "AGV"); |
| | | } |
| | | else |
| | | else |
| | | { |
| | | LogHelper.Info("没有可用的入库接驳位", "AGV"); |
| | | LogHelper.Info($"任务号:{taskNo},没有配置立库接驳位", "AGV"); |
| | | } |
| | | } |
| | | else |
| | | else |
| | | { |
| | | LogHelper.Info("没有空余的货位", "AGV"); |
| | | LogHelper.Info($"任务号:{taskNo},立库没有满足条件的空货位", "AGV"); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | LogHelper.Info($"任务号:{taskNo},AGV任务的容器:{cst.S_CNTR_CODE}不存在", "AGV"); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | LogHelper.Info($"任务号:{taskNo},AGV任务已申请终点,请勿重复申请", "AGV"); |
| | | } |
| | | } |
| | | return endLocCode; |
| | | else |
| | | { |
| | | LogHelper.Info($"任务号:{taskNo},AGV任务已完成或取消", "AGV"); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | } |
File was renamed from HH.WCS.Mobox3/HH.WCS.Mobox3.FJJT/dispatch/WCSDispatch.cs |
| | |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | using HH.WCS.Mobox3.FJJT.util; |
| | | using HH.WCS.Mobox3.FJJT.wms; |
| | | using HH.WCS.Mobox3.YNJT_BZP.util; |
| | | using HH.WCS.Mobox3.YNJT_BZP.wms; |
| | | using Newtonsoft.Json; |
| | | using static HH.WCS.Mobox3.FJJT.api.ApiModel; |
| | | using static HH.WCS.Mobox3.FJJT.util.ExcetionHelper; |
| | | using static HH.WCS.Mobox3.YNJT_BZP.api.ApiModel; |
| | | |
| | | namespace HH.WCS.Mobox3.FJJT.dispatch |
| | | namespace HH.WCS.Mobox3.YNJT_BZP.dispatch |
| | | { |
| | | internal class WCSDispatch |
| | | { |
| | |
| | | { |
| | | result = true; |
| | | } |
| | | else |
| | | { |
| | | WMSHelper.addAlarmRecord("流程异常", "高", $"下发WCS任务失败,WCS反馈原因:{dataResult.msg}"); |
| | | throw new BusinessException($"下发WCS任务失败,WCS反馈原因:{dataResult.msg}"); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | WMSHelper.addAlarmRecord("流程异常", "高", $"下发WCS任务失败,WCS没有返回数据"); |
| | | throw new BusinessException($"下发WCS任务失败,WCS没有返回数据"); |
| | | |
| | | } |
| | | } |
| | | catch (BusinessException be) |
| | | { |
| | | throw be; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | WMSHelper.addAlarmRecord("系统异常", "高", $"下发WCS任务错误,错误原因:{ex.Message}"); |
| | | throw new BusinessException($"下发WCS任务错误,错误原因:{ex.Message}"); |
| | | |
| | | } |
| | | return result; |
| | | } |
| | |
| | | { |
| | | result = true; |
| | | } |
| | | else |
| | | { |
| | | WMSHelper.addAlarmRecord("流程异常", "高", $"取消WCS任务失败,WCS反馈原因:{dataResult.msg}"); |
| | | throw new BusinessException($"取消WCS任务失败,WCS反馈原因:{dataResult.msg}"); |
| | | } |
| | | |
| | | } |
| | | else |
| | | { |
| | | WMSHelper.addAlarmRecord("流程异常", "高", $"取消WCS任务失败,WCS没有返回数据"); |
| | | throw new BusinessException($"取消WCS任务失败,WCS没有返回数据"); |
| | | |
| | | } |
| | | } |
| | | catch (BusinessException be) |
| | | { |
| | | throw be; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | WMSHelper.addAlarmRecord("系统异常", "高", $"取消WCS任务错误,错误原因:{ex.Message}"); |
| | | throw new BusinessException($"取消WCS任务错误,错误原因:{ex.Message}"); |
| | | |
| | | } |
| | | return result; |
| | | } |
| | |
| | | { |
| | | deviceStatusDatas = JsonConvert.DeserializeObject<List<DeviceStatusData>>(response); |
| | | } |
| | | else |
| | | { |
| | | WMSHelper.addAlarmRecord("流程异常", "高", $"获取设备状态失败,WCS反馈原因:{dataResult.msg}"); |
| | | throw new BusinessException($"获取设备状态失败,WCS反馈原因:{dataResult.msg}"); |
| | | } |
| | | |
| | | } |
| | | else |
| | | { |
| | | WMSHelper.addAlarmRecord("流程异常", "高", $"获取设备状态失败,WCS没有返回数据"); |
| | | throw new BusinessException($"获取设备状态失败,WCS没有返回数据"); |
| | | |
| | | } |
| | | } |
| | | catch (BusinessException be) |
| | | { |
| | | throw be; |
| | | } |
| | | |
| | | catch (Exception ex) |
| | | { |
| | | WMSHelper.addAlarmRecord("系统异常", "高", $"获取设备状态错误,错误原因:{ex.Message}"); |
| | | throw new BusinessException($"获取设备状态错误,错误原因:{ex.Message}"); |
| | | |
| | | } |
| | | return deviceStatusDatas; |
| | | } |
| | |
| | | { |
| | | result = true; |
| | | } |
| | | else |
| | | { |
| | | WMSHelper.addAlarmRecord("流程异常", "高", $"修改任务优先级失败,WCS反馈原因:{dataResult.msg}"); |
| | | throw new BusinessException($"修改任务优先级失败,WCS反馈原因:{dataResult.msg}"); |
| | | } |
| | | |
| | | } |
| | | else |
| | | { |
| | | WMSHelper.addAlarmRecord("流程异常", "高", $"修改任务优先级失败,WCS没有返回数据"); |
| | | throw new BusinessException($"修改任务优先级失败,WCS没有返回数据"); |
| | | |
| | | } |
| | | } |
| | | catch (BusinessException be) |
| | | { |
| | | throw be; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | WMSHelper.addAlarmRecord("系统异常", "高", $"修改任务优先级错误,错误原因:{ex.Message}"); |
| | | throw new BusinessException($"修改任务优先级错误,错误原因:{ex.Message}"); |
| | | |
| | | } |
| | | return result; |
| | | } |
| | |
| | | { |
| | | result = true; |
| | | } |
| | | else |
| | | { |
| | | WMSHelper.addAlarmRecord("流程异常", "高", $"AGV安全交互请求失败,WCS反馈原因:{dataResult.msg}"); |
| | | throw new BusinessException($"AGV安全交互请求失败,WCS反馈原因:{dataResult.msg}"); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | WMSHelper.addAlarmRecord("流程异常", "高", $"AGV安全交互请求失败,WCS没有返回数据"); |
| | | throw new BusinessException($"AGV安全交互请求失败,WCS没有返回数据"); |
| | | LogHelper.Info("调用WCS安全请求接口失败", "AGV"); |
| | | } |
| | | } |
| | | catch (BusinessException be) |
| | | { |
| | | throw be; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | WMSHelper.addAlarmRecord("系统异常", "高", $"AGV安全交互请求错误,错误原因:{ex.Message}"); |
| | | throw new BusinessException($"AGV安全交互请求错误,错误原因:{ex.Message}"); |
| | | LogHelper.Info($"调用WCS安全请求接口错误,错误原因:{ex.Message}", "AGV"); |
| | | } |
| | | return result; |
| | | } |
| | |
| | | public string BOM3 { get; set; } |
| | | public string S_FOVRAGE { get; set; } // 是否过期 是否过期(null 或 空 默认 否) Y/N |
| | | public string S_JDGE { get; set; } // 质检状态 |
| | | public string S_WMS_JDGE { get; set; } // 反馈wms质检状态 |
| | | public DateTime EFFECTIVE_TIME { get; set; } // 生效时间 |
| | | public DateTime EXPIRATION_TIME { get; set; } // 失效时间 |
| | | public DateTime LAST_MODIFY_TIME { get; set; } // 最后修改时间 |
| | | public string LAST_MODIFY_TIME { get; set; } // 最后修改时间 |
| | | } |
| | | } |
| | |
| | | public string bom3 { get; set; } |
| | | public string fovrage { get; set; } // 是否过期 是否过期(null 或 空 默认 否) Y/N |
| | | public string jdge { get; set; } // 质检状态 |
| | | public string WMS_jdge { get; set; } // 反馈wms质检状态 |
| | | public DateTime effective_time { get; set; } // 生效时间 |
| | | public DateTime expiration_time { get; set; } // 失效时间 |
| | | public DateTime last_modify_time { get; set; } // 最后修改时间 |
| | | public string last_modify_time { get; set; } // 最后修改时间 |
| | | } |
| | | } |
| | |
| | | namespace HH.WCS.Mobox3.YNJT_BZP.models |
| | | { |
| | | [SugarTable("TN_standard_overage")] |
| | | internal class Overage |
| | | internal class Overage : BaseModel |
| | | { |
| | | public string MCNGRP { get; set; } //生产流程组 |
| | | public string ITEMPATT { get; set; } // 物料前缀 |
| | | public int OVERAGE { get; set; } // 最大保存时间 |
| | | public int MINHOUR { get; set; } // 多久后生效 |
| | | public float MINHOUR { get; set; } // 多久后生效 |
| | | public string FLAG_STS { get; set; } // 标记 |
| | | public int RECID { get; set; } // 标记 |
| | | } |
| | | } |
| | |
| | | { |
| | | public string S_SYN_TIME { get; set; } // 同步时间 |
| | | public int N_SYN_NUM { get; set; } // 同步数量 |
| | | public string RECORD_TABLE { get; set; } // 1.物料条码记录表 2.胚胎条码状态表 |
| | | public string RECORD_TABLE { get; set; } // 1.物料条码记录表 2.胚胎条码状态表 3.过期时间配置表 |
| | | |
| | | } |
| | | } |
| | |
| | | public string S_VALUE { get; set; } |
| | | public string S_STATE_PRE { get; set; } |
| | | public int N_REVIEW_RESULT { get; set; } |
| | | |
| | | public int N_S_STATUS { get; set; } = 0; |
| | | public int N_ACTION_CODE { get; set; } |
| | | } |
| | | } |
| | |
| | | using System.Linq; |
| | | using System.Reflection; |
| | | using System.Security.Cryptography; |
| | | using static HH.WCS.Mobox3.YNJT_BZP.util.Settings; |
| | | |
| | | namespace HH.WCS.Mobox3.YNJT_BZP.process { |
| | | internal class TaskProcess { |
| | |
| | | /// <param name="forkliftNo"></param> |
| | | /// <param name="extData"></param> |
| | | internal static void OperateReq(string no, int state, string forkliftNo, string extData) { |
| | | LogHelper.Info($"开始安全请求,任务号:{no},请求码:{state},小车号:{forkliftNo}", "AGV"); |
| | | var cst = WCSHelper.GetTask(no); |
| | | var mst = WMSHelper.GetWmsTask(cst.S_OP_CODE); |
| | | var endLoc = LocationHelper.GetLoc(cst.S_END_LOC); |
| | | if (state == 1101) { |
| | | //请求取货, |
| | | |
| | | } |
| | | if (state == 1102) { |
| | | //请求卸货, |
| | | bool isCan = false; |
| | | |
| | | |
| | | if (endLoc != null) |
| | | var taskAction = WCSHelper.getActionRecord(no, state); |
| | | if (taskAction != null) |
| | | { |
| | | LogHelper.Info($"再次安全请求,查询设备是否反馈", "AGV"); |
| | | if (taskAction.N_S_STATUS == 1) |
| | | { |
| | | // 1.查看终点货位放货条件是否满足 |
| | | var waitLoc = Settings.getAgvWaitLoc(endLoc.S_CODE); |
| | | if (waitLoc != null) |
| | | LogHelper.Info($"再次安全请求,设备已反馈", "AGV"); |
| | | NDCApi.ChangeOrderParam(no, 8, "1"); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | LogHelper.Info($"首次进行安全请求,任务号:{no},请求码:{state},小车号:{forkliftNo}", "AGV"); |
| | | bool result = false; |
| | | if (state == 1101) |
| | | { |
| | | result = WCSDispatch.safetyInteraction(cst.S_CODE, cst.S_START_LOC, "1"); //请求取货, |
| | | } |
| | | if (state == 1102) |
| | | { |
| | | //请求卸货, |
| | | var container = ContainerHelper.GetCntr(cst.S_CNTR_CODE); |
| | | // 胎圈入库,下发母拖出库任务 \ 帘布、内衬入库,下发托盘回库任务 |
| | | if (cst.S_TYPE.Contains("入库") && endLoc.N_LOCK_STATE == 0) |
| | | { |
| | | if (container.N_TYPE != 6 ) |
| | | { |
| | | if (endLoc.N_CURRENT_NUM == 1) |
| | | { |
| | | var locCntrRels = LocationHelper.GetLocCntr(endLoc.S_CODE); |
| | | if (locCntrRels != null && locCntrRels.Count > 0) |
| | | { |
| | | var container1 = ContainerHelper.GetCntr(locCntrRels[0].S_CNTR_CODE); |
| | | if (container1.N_TYPE == 0) |
| | | { |
| | | LogHelper.Info("非胎圈入库,接驳位存在母拖,下发母拖入库任务", "AGV"); |
| | | ApiHelper.baseTrayInStockAgv(endLoc.S_CODE, mst.S_CODE); |
| | | } |
| | | } |
| | | } |
| | | else |
| | | { |
| | | result = true; |
| | | } |
| | | } |
| | | |
| | | // 胎圈入库 |
| | | if (container.N_TYPE == 6 ) |
| | | { |
| | | if (endLoc.N_CURRENT_NUM == 0) |
| | | { |
| | | LogHelper.Info("胎圈入库,接驳位缺少母拖,下发母拖出库任务", "AGV"); |
| | | ApiHelper.baseTrayOutStockAgv(endLoc.S_CODE, mst.S_CODE); |
| | | } |
| | | else if (endLoc.N_CURRENT_NUM == 1) |
| | | { |
| | | var locCntrRels = LocationHelper.GetLocCntr(endLoc.S_CODE); |
| | | if (locCntrRels != null && locCntrRels.Count > 0) |
| | | { |
| | | var container1 = ContainerHelper.GetCntr(locCntrRels[0].S_CNTR_CODE); |
| | | if (container1.N_TYPE == 0) |
| | | { |
| | | result = true; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 请求WCS是否允许放货 |
| | | if (result) |
| | | { |
| | | result = WCSDispatch.safetyInteraction(cst.S_CODE, cst.S_START_LOC, "2"); // 请求放货 |
| | | } |
| | | |
| | | if (result) |
| | | { |
| | | //根据终点判断,是cb02的入口,判断内存中状态(要状态时间),允许卸货,通知agv改参数 |
| | | var dic = new Dictionary<string, string>(); |
| | |
| | | dic.Add("ParamNo", "8"); |
| | | dic.Add("Param1", "1"); |
| | | NDC.ChangeOrder(dic); |
| | | //改完参数车子就会自己卸货 |
| | | } |
| | | else |
| | | { |
| | | var container = ContainerHelper.GetCntr(cst.S_CNTR_CODE); |
| | | if (container != null && container.N_TYPE == 6) |
| | | { |
| | | isCan = false; |
| | | var locCntrs = LocationHelper.GetLocCntr(endLoc.S_CODE); |
| | | if (endLoc.N_CURRENT_NUM == 1 && locCntrs.Count > 0) |
| | | { |
| | | var container1 = ContainerHelper.GetCntr(locCntrs[0].S_CNTR_CODE); |
| | | if (container1.N_TYPE == 0) |
| | | { |
| | | isCan = true; |
| | | } |
| | | } |
| | | if (!isCan) |
| | | { |
| | | LogHelper.Info("胎圈请求放货失败,母拖没有到位", "AGV"); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 2.查询输送线 是否允许放货 |
| | | |
| | | } |
| | | |
| | | if (isCan) |
| | | if (state == 1103) |
| | | { |
| | | //根据终点判断,是cb02的入口,判断内存中状态(要状态时间),允许卸货,通知agv改参数 |
| | | var dic = new Dictionary<string, string>(); |
| | | //< Req >< Order No = 'TN2302020002' ParamNo = '18' Param1 = '12' /></ Req > |
| | | dic.Add("No", no); |
| | | dic.Add("ParamNo", "8"); |
| | | dic.Add("Param1", "1"); |
| | | NDC.ChangeOrder(dic); |
| | | //改完参数车子就会自己卸货 |
| | | result = WCSDispatch.safetyInteraction(cst.S_CODE, cst.S_START_LOC, "3"); //取货完成允许离开 |
| | | } |
| | | } |
| | | if (state == 1103) |
| | | { |
| | | // 取货完成请求离开 |
| | | // 安全退出 |
| | | // 胎圈出库,下发母拖回库任务 |
| | | var locCntrRels = LocationHelper.GetLocCntrRel(cst.S_START_LOC); |
| | | if (locCntrRels.Count > 0) |
| | | if (state == 1104) |
| | | { |
| | | var container = ContainerHelper.GetCntr(locCntrRels[0].S_CNTR_CODE); |
| | | if (container != null && container.N_TYPE == 0) |
| | | { |
| | | ApiHelper.baseTrayInStockAgv(cst.S_START_LOC, cst.S_OP_CODE); |
| | | } |
| | | result = WCSDispatch.safetyInteraction(cst.S_CODE, cst.S_START_LOC, "4"); //放货完成允许离开 |
| | | } |
| | | } |
| | | if (state == 1104) |
| | | { |
| | | // 放货完成请求离开 |
| | | |
| | | // 安全请求发送成功,添加任务动作记录 |
| | | if (result) |
| | | { |
| | | WCSHelper.AddActionRecord(no, state, forkliftNo, extData); |
| | | LogHelper.Info($"首次进行安全请求成功", "AGV"); |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | var task = db.Queryable<WCSTask>().Where(a => a.S_OP_CODE== no).First(); |
| | | return task; |
| | | } |
| | | internal static WCSTask GetTaskBySrcNoAndScheduleType(string no ,string scheduleType) |
| | | { |
| | | var db = new SqlHelper<WCSTask>().GetInstance(); |
| | | var task = db.Queryable<WCSTask>().Where(a => a.S_OP_CODE == no && a.S_SCHEDULE_TYPE == scheduleType && a.N_B_STATE < 3).First(); |
| | | return task; |
| | | } |
| | | internal static List<WCSTask> GetTaskListBySrcNo(string no) |
| | | { |
| | | var db = new SqlHelper<WCSTask>().GetInstance(); |
| | |
| | | return task; |
| | | } |
| | | |
| | | internal static List<WCSTask> GetTaskByStart(string bit) { |
| | | internal static WCSTask GetTaskByStart(string bit) { |
| | | var db = new SqlHelper<WCSTask>().GetInstance(); |
| | | var task = db.Queryable<WCSTask>().Where(a => a.S_START_LOC == bit.Trim()).ToList(); |
| | | var task = db.Queryable<WCSTask>().Where(a => a.S_START_LOC == bit.Trim() && a.N_B_STATE < 3).First(); |
| | | return task; |
| | | } |
| | | internal static List<WCSTask> GetTaskByEnd(string bit) { |
| | | internal static WCSTask GetTaskByEnd(string bit) { |
| | | var db = new SqlHelper<WCSTask>().GetInstance(); |
| | | var task = db.Queryable<WCSTask>().Where(a => a.S_END_LOC.Trim() == bit.Trim()).ToList(); |
| | | var task = db.Queryable<WCSTask>().Where(a => a.S_END_LOC.Trim() == bit.Trim() && a.N_B_STATE < 3).First(); |
| | | return task; |
| | | } |
| | | |
| | |
| | | var db = new SqlHelper<TaskAction>().GetInstance(); |
| | | return db.Queryable<TaskAction>().Count(a => a.S_TASK_CODE == no.Trim() && a.N_ACTION_CODE == code) > 0; |
| | | } |
| | | internal static TaskAction getActionRecord(string no, int code) |
| | | { |
| | | var db = new SqlHelper<TaskAction>().GetInstance(); |
| | | return db.Queryable<TaskAction>().Where(a => a.S_TASK_CODE == no.Trim() && a.N_ACTION_CODE == code).First(); |
| | | } |
| | | |
| | | internal static void Begin(WCSTask task) { |
| | | var db = new SqlHelper<WCSTask>().GetInstance(); |
| | | if (task != null) { |
| | |
| | | try |
| | | { |
| | | db.BeginTran(); |
| | | itemBarcodeInfos.ForEach(a => { |
| | | var bo = db.Insertable<ItemBarcodeInfo>(a).ExecuteCommand() > 0; |
| | | if (!bo) |
| | | itemBarcodeInfos.ForEach(item => { |
| | | var itemBarcodeInfo = db.Queryable<ItemBarcodeInfo>().Where(a => a.S_BC_ENTRIED == item.S_BC_ENTRIED).First(); |
| | | if (itemBarcodeInfo == null) |
| | | { |
| | | result = false; |
| | | LogHelper.Info($"添加物料条码信息失败,物料条码信息:{JsonConvert.SerializeObject(a)}", "GT"); |
| | | var bo = db.Insertable<ItemBarcodeInfo>(item).ExecuteCommand() > 0; |
| | | if (!bo) |
| | | { |
| | | result = false; |
| | | LogHelper.Info($"添加物料条码信息失败,物料条码信息:{JsonConvert.SerializeObject(item)}", "GT"); |
| | | } |
| | | } |
| | | }); |
| | | if (result) |
| | |
| | | { |
| | | db.BeginTran(); |
| | | updateMatlStatuses.ForEach(update => { |
| | | var bo = db.Updateable<CntrItemRel>().SetColumns(a => new CntrItemRel() { S_ITEM_STATE = update.jdge }).Where(a => a.S_CG_ID == update.bc_entried).ExecuteCommand() > 0; |
| | | if (!bo) |
| | | var itemBarcodeInfo = db.Queryable<ItemBarcodeInfo>().Where(a => a.S_BC_ENTRIED == update.bc_entried).First(); |
| | | if (itemBarcodeInfo != null) |
| | | { |
| | | result = false; |
| | | LogHelper.Info($"批量更新物料状态失败,物料条码信息:{JsonConvert.SerializeObject(update)}", "GT"); |
| | | itemBarcodeInfo.S_JDGE = update.jdge; |
| | | db.Updateable(itemBarcodeInfo).ExecuteCommand(); |
| | | var cntrItemRel = db.Queryable<CntrItemRel>().Where(a => a.S_CG_ID == update.bc_entried).First(); |
| | | if (cntrItemRel != null) |
| | | { |
| | | // 将MES的物料状态转化成WMS可识别的物料状态 |
| | | if (update.jdge == "" || update.jdge == null) |
| | | { |
| | | update.jdge = "OK"; |
| | | } |
| | | else if (update.jdge != "OK") |
| | | { |
| | | update.jdge = "HOLD"; |
| | | } |
| | | db.Updateable<CntrItemRel>().SetColumns(a => new CntrItemRel() { S_ITEM_STATE = update.jdge }).Where(a => a.S_CG_ID == update.bc_entried).ExecuteCommand(); |
| | | } |
| | | } |
| | | }); |
| | | if (result) |
| | | { |
| | | db.CommitTran(); |
| | | } |
| | | else |
| | | { |
| | | db.RollbackTran(); |
| | | } |
| | | db.CommitTran(); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | LogHelper.Info($"批量更新物料状态错误,错误信息:{ex.Message}", "GT"); |
| | | db.RollbackTran(); |
| | | result = false; |
| | | } |
| | | return result; |
| | | } |
| | |
| | | db.BeginTran(); |
| | | foreach (Overage overage in overages) |
| | | { |
| | | bool bo = false; |
| | | var overage1 = db.Queryable<Overage>().Where(a => a.MCNGRP == overage.MCNGRP && a.ITEMPATT == overage.ITEMPATT).First(); |
| | | var overage1 = db.Queryable<Overage>().Where(a => a.RECID == overage.RECID).First(); |
| | | if (overage1 != null) |
| | | { |
| | | overage1.MCNGRP = overage.MCNGRP; |
| | | overage1.ITEMPATT = overage.ITEMPATT; |
| | | overage1.OVERAGE = overage.OVERAGE; |
| | | overage1.MINHOUR = overage.MINHOUR; |
| | | overage1.FLAG_STS = overage.FLAG_STS; |
| | | bo = db.Updateable(overage1).ExecuteCommand() > 0; |
| | | db.Updateable(overage1).ExecuteCommand(); |
| | | } |
| | | else |
| | | { |
| | | overage1 = new Overage() |
| | | { |
| | | MCNGRP = overage.MCNGRP, |
| | | ITEMPATT = overage.ITEMPATT, |
| | | OVERAGE = overage.OVERAGE, |
| | | MINHOUR = overage.MINHOUR, |
| | | FLAG_STS = overage.FLAG_STS |
| | | }; |
| | | bo = db.Insertable(overage1).ExecuteCommand() > 0; |
| | | } |
| | | if (!bo) |
| | | { |
| | | result = false; |
| | | LogHelper.Info($"批量更新物料存放时间配置信息失败,配置信息:{JsonConvert.SerializeObject(overage)}", "GT"); |
| | | break; |
| | | db.Insertable(overage).ExecuteCommand(); |
| | | } |
| | | } |
| | | |
| | | if (result) |
| | | { |
| | | db.CommitTran(); |
| | | } |
| | | else |
| | | { |
| | | db.RollbackTran(); |
| | | } |
| | | db.CommitTran(); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | LogHelper.Info($"批量更新物料存放时间配置信息错误,错误信息:{ex.Message}", "GT"); |
| | | db.RollbackTran(); |
| | | result = false; |
| | | } |
| | | return result; |
| | | } |
| | |
| | | /// <returns></returns> |
| | | public static Overage getOverage(string bc_entried) |
| | | { |
| | | Overage overage = null; |
| | | |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | overage = db.Queryable<Overage>().Where(a => a.ITEMPATT == bc_entried && a.MCNGRP == "1").First(); |
| | | |
| | | if (overage == null) |
| | | { |
| | | string sub = bc_entried.Substring(0, 3); |
| | | overage = db.Queryable<Overage>().Where(a => a.ITEMPATT.Contains(sub) && a.MCNGRP == "1").First(); |
| | | } |
| | | // 直接执行 SQL(参数化查询) |
| | | var sql = "SELECT get_ovg_bar(@barcode, @mcngrp) AS overage_value"; |
| | | var sql1 = "SELECT get_minhour_bar(@barcode, @mcngrp) AS overage_value"; |
| | | |
| | | if (overage == null) |
| | | // 使用匿名对象传递参数 |
| | | var ovg_bar = db.Ado.SqlQuery<int>(sql, new { barcode = bc_entried, mcngrp = "1"}); |
| | | var minhour_bar = db.Ado.SqlQuery<float>(sql1, new { barcode = bc_entried, mcngrp = "1"}); |
| | | if (ovg_bar.Count > 0 && minhour_bar.Count > 0) |
| | | { |
| | | string sub = bc_entried.Substring(0, 7); |
| | | overage = db.Queryable<Overage>().Where(a => a.ITEMPATT.Contains(sub) && a.MCNGRP == "1").First(); |
| | | Overage overage = new Overage() |
| | | { |
| | | MINHOUR = minhour_bar[0], |
| | | OVERAGE = ovg_bar[0] |
| | | }; |
| | | return overage; |
| | | } |
| | | return overage; |
| | | return null; |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | try |
| | | { |
| | | db.BeginTran(); |
| | | result = db.Insertable(record).ExecuteCommand()> 0; |
| | | var synDataTimeRecord = db.Queryable<SynDataTimeRecord>().Where(a => a.S_SYN_TIME == record.S_SYN_TIME && a.RECORD_TABLE == record.RECORD_TABLE).First(); |
| | | if (synDataTimeRecord == null) |
| | | { |
| | | result = db.Insertable(record).ExecuteCommand() > 0; |
| | | } |
| | | else |
| | | { |
| | | synDataTimeRecord.N_SYN_NUM = record.N_SYN_NUM; |
| | | synDataTimeRecord.S_SYN_TIME = record.S_SYN_TIME; |
| | | result = db.Updateable(synDataTimeRecord).ExecuteCommand() > 0; |
| | | } |
| | | |
| | | if (result) |
| | | { |
| | | db.CommitTran(); |
| | |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | LogHelper.Info($"添加同步数据时间记录错误,错误信息:{ex.Message}", "GT"); |
| | | LogHelper.Info($"添加数据同步时间记录错误,错误信息:{ex.Message}", "GT"); |
| | | db.RollbackTran(); |
| | | } |
| | | return result; |
| | |
| | | |
| | | tasks.Add(GetTask(Monitor.MonitorMatlBarcode)); |
| | | tasks.Add(GetTask(Monitor.MonitorMatlStatus)); |
| | | tasks.Add(GetTask(Monitor.MonitorMatlTimeConfig)); |
| | | Task.WaitAll(tasks.ToArray()); |
| | | } |
| | | public void Stop() { Console.WriteLine("work stopped"); } |
| | | private Task GetTask(Action action) { |
| | | private Task GetTask(Action action ,int time = 3000) { |
| | | var task = Task.Run(() => { |
| | | while (true) { |
| | | try { |
| | |
| | | catch (Exception ex) { |
| | | LogHelper.Error(ex.Message, ex); |
| | | } |
| | | Thread.Sleep(3000); |
| | | Thread.Sleep(time); |
| | | } |
| | | }); |
| | | return task; |
| | |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | using static HH.WCS.Mobox3.YNJT_BZP_GT.dispatch.WMSDispatch; |
| | | |
| | | namespace HH.WCS.Mobox3.YNJT_BZP_GT.api { |
| | | /// <summary> |
| | |
| | | public class ReturnResult { |
| | | public int ResultCode { get; set; } |
| | | public string ResultMsg { get; set; } |
| | | public object data { get; set; } |
| | | public SynDataTimeRecord data { get; set; } |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | [RoutePrefix("api")] |
| | | public class WmsController : System.Web.Http.ApiController |
| | | { |
| | | |
| | | |
| | | } |
| | | } |
| | |
| | | if (synDataTimeRecord != null) |
| | | { |
| | | /* CultureInfo enGB = new CultureInfo("en-GB");*/ |
| | | var maltInformations = WMSHelper.getMaltInfoList(DateTime.Parse(synDataTimeRecord.RECORD_TABLE)); |
| | | var maltInformations = WMSHelper.getMaltInfoList(synDataTimeRecord.S_SYN_TIME); |
| | | if (maltInformations != null && maltInformations.Count > 0) |
| | | { |
| | | bool bo = WMSDispatch.synMatlInformation(new SynMatlInformationModel() { matlInformationList = maltInformations }); |
| | | if (bo) |
| | | { |
| | | WMSDispatch.recordDataSynTime(new RecordDataSynTimeModel() { sysTime = maltInformations[0].last_modify_time.ToString("yyyy-MM-dd HH:mm:ss:ff"), synNum = maltInformations.Count, recordTable = "1" }); |
| | | WMSDispatch.recordDataSynTime(new RecordDataSynTimeModel() { sysTime = maltInformations[0].last_modify_time, synNum = maltInformations.Count, recordTable = "1" }); |
| | | } |
| | | } |
| | | } |
| | |
| | | if (synDataTimeRecord != null) |
| | | { |
| | | /* CultureInfo enGB = new CultureInfo("en-GB");*/ |
| | | var barcodeStatuses = WMSHelper.getMaltStatusList(DateTime.Parse(synDataTimeRecord.RECORD_TABLE)); |
| | | var barcodeStatuses = WMSHelper.getMaltStatusList(synDataTimeRecord.S_SYN_TIME); |
| | | if (barcodeStatuses != null && barcodeStatuses.Count > 0) |
| | | { |
| | | var updateMatlStatuses = barcodeStatuses.Select(a => new UpdateMatlStatus {bc_entried = a.bc_entried ,jdge = a.jdge }).ToList(); |
| | | bool bo = WMSDispatch.synUpdateMatlStatus(new SynUpdateMatlStatusModel() { updateMatlStatuses = updateMatlStatuses }); |
| | | if (bo) |
| | | if (updateMatlStatuses.Count > 0) |
| | | { |
| | | WMSDispatch.recordDataSynTime(new RecordDataSynTimeModel() { sysTime = barcodeStatuses[0].last_modify_time.ToString("yyyy-MM-dd HH:mm:ss:ff"), synNum = barcodeStatuses.Count, recordTable = "2" }); |
| | | bool bo = WMSDispatch.synUpdateMatlStatus(new SynUpdateMatlStatusModel() { updateMatlStatuses = updateMatlStatuses }); |
| | | if (bo) |
| | | { |
| | | WMSDispatch.recordDataSynTime(new RecordDataSynTimeModel() { sysTime = barcodeStatuses[0].last_modify_time, synNum = barcodeStatuses.Count, recordTable = "2" }); |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 同步半制品物料状态 |
| | | /// 1.查询上次记录时间 |
| | | /// 2.根据记录时间,查询大于等于记录时间,且符合条件的物料状态信息 |
| | | /// 3.将物料条码信息同步到wms |
| | | /// 4.同步成功,记录最后一条数据的更新时间 |
| | | /// 同步半制品物料时间配置 |
| | | /// </summary> |
| | | internal static void MonitorMatlTimeConfig() |
| | | { |
| | |
| | | if (synDataTimeRecord != null) |
| | | { |
| | | /* CultureInfo enGB = new CultureInfo("en-GB");*/ |
| | | var overages = WMSHelper.getOverageList(DateTime.Parse(synDataTimeRecord.RECORD_TABLE)); |
| | | var overages = WMSHelper.getOverageList(synDataTimeRecord.S_SYN_TIME); |
| | | if (overages != null && overages.Count > 0) |
| | | { |
| | | bool bo = WMSDispatch.synUpdateMatlTimeConfig(new MatlTimeConfigModel() { overages = overages }); |
| | | if (bo) |
| | | { |
| | | WMSDispatch.recordDataSynTime(new RecordDataSynTimeModel() { sysTime = overages[0].last_modify_time.ToString("yyyy-MM-dd HH:mm:ss:ff"), synNum = overages.Count, recordTable = "3" }); |
| | | WMSDispatch.recordDataSynTime(new RecordDataSynTimeModel() { sysTime = overages[0].last_modify_time, synNum = overages.Count, recordTable = "3" }); |
| | | } |
| | | } |
| | | } |
| | |
| | | |
| | | namespace HH.WCS.Mobox3.YNJT_BZP_GT.dispatch |
| | | { |
| | | internal class WMSDispatch |
| | | public class WMSDispatch |
| | | { |
| | | private static readonly HttpHelper apiHelper = new HttpHelper(); |
| | | private static readonly string baseUrl = Settings.WMSSeverUrl; |
| | |
| | | var msg = ""; |
| | | bool bo = false; |
| | | var request = JsonConvert.SerializeObject(model); |
| | | var response = apiHelper.Post(baseUrl + "/api/Wms/recordDataSynTime", request); |
| | | var response = apiHelper.Post(baseUrl + "/api/Wms/synUpdateMatlTimeConfig", request); |
| | | msg = $"[synUpdateMatlTimeConfig] request={request} response={response}"; |
| | | Console.WriteLine(msg); |
| | | LogHelper.Info(msg, "WMS"); |
| | |
| | | public class SynDataTimeRecord |
| | | { |
| | | public string S_SYN_TIME { get; set; } // 同步时间 |
| | | public int N_SYN_NUM { get; set; } // 同步数量 |
| | | public string RECORD_TABLE { get; set; } // 1.物料条码记录表 2.胚胎条码状态表 |
| | | |
| | | } |
| | |
| | | |
| | | public class SynMatlInformationModel |
| | | { |
| | | public List<MaltInformation> matlInformationList { get; set; } |
| | | public List<MatlInformation> matlInformationList { get; set; } |
| | | } |
| | | } |
| | | } |
| | |
| | | /// <summary> |
| | | /// GT 中间表 |
| | | /// </summary> |
| | | [SugarTable("malt_information")] |
| | | public class MaltInformation |
| | | [SugarTable("matl_information")] |
| | | public class MatlInformation |
| | | { |
| | | public string item { get; set; } // 产品材料的物品代码(从条形码数字左侧起截取前10位) |
| | | public string bc_entried { get; set; } // 产品材料的条形码编号 |
| | |
| | | public string bom3 { get; set; } |
| | | public string fovrage { get; set; } // 是否过期 是否过期(null 或 空 默认 否) Y/N |
| | | public string jdge { get; set; } // 质检状态 |
| | | public DateTime last_modify_time { get; set; } // 最后修改时间 |
| | | public string last_modify_time { get; set; } // 最后修改时间 |
| | | } |
| | | } |
| | |
| | | /// GT 中间表(物料存放时间配置表) |
| | | /// </summary> |
| | | [SugarTable("overage")] |
| | | internal class Overage |
| | | public class Overage |
| | | { |
| | | public string mcngrp { get; set; } // 机器组代码 mcn字段 以 RTE 前缀=mcngrp字段=1;半制品 / mcn字段 以 RTB 前缀=mcngrp字段=0;硫化机 |
| | | public string itempatt { get; set; } // 物品模式(如条码匹配规则) |
| | |
| | | public decimal minhour { get; set; } // 最小工作时间或条件 |
| | | public string flag_sts { get; set; } // 状态标记 |
| | | public int recid { get; set; } |
| | | public DateTime last_modify_time { get; set; } |
| | | public string last_modify_time { get; set; } |
| | | } |
| | | } |
| | |
| | | { |
| | | public string bc_entried { get; set; } |
| | | public string descr { get; set; } |
| | | public DateTime bld_date { get; set; } |
| | | public string bld_date { get; set; } |
| | | public string bld_mcn01 { get; set; } |
| | | public string bld_mcn02 { get; set; } |
| | | public string bld_shift { get; set; } |
| | |
| | | public string bld_opr02 { get; set; } |
| | | public string bld_opr03 { get; set; } |
| | | public string bld_opr04 { get; set; } |
| | | public DateTime cur_in { get; set; } |
| | | public DateTime cur_out { get; set; } |
| | | public string cur_in { get; set; } |
| | | public string cur_out { get; set; } |
| | | public string cur_shift { get; set; } |
| | | public string cur_mcn { get; set; } |
| | | public string lr_mcn { get; set; } |
| | | public string cur_opr01 { get; set; } |
| | | public DateTime jdge_date { get; set; } |
| | | public string jdge_date { get; set; } |
| | | public string jdge { get; set; } |
| | | public string probcode { get; set; } |
| | | public DateTime last_modify_time { get; set; } |
| | | public string last_modify_time { get; set; } |
| | | } |
| | | } |
| | |
| | | /// </summary> |
| | | /// <param name="lastTime"></param> |
| | | /// <returns></returns> |
| | | public static List<MaltInformation> getMaltInfoList(DateTime lastTime) |
| | | public static List<MatlInformation> getMaltInfoList(string lastTime) |
| | | { |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | return db.Queryable<MaltInformation>().Where( a => a.last_modify_time >= lastTime).OrderByDescending( a => a.last_modify_time).ToList(); |
| | | return db.Queryable<MatlInformation>().Where( a => DateTime.Parse(a.last_modify_time) >= DateTime.Parse(lastTime)).OrderByDescending( a => a.last_modify_time).ToList(); |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | /// </summary> |
| | | /// <param name="lastTime"></param> |
| | | /// <returns></returns> |
| | | public static List<TableOfBarcodeStatus> getMaltStatusList(DateTime lastTime) |
| | | public static List<TableOfBarcodeStatus> getMaltStatusList(string lastTime) |
| | | { |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | return db.Queryable<TableOfBarcodeStatus>().Where(a => a.last_modify_time >= lastTime && a.bld_date == null).OrderByDescending(a => a.last_modify_time).ToList(); |
| | | return db.Queryable<TableOfBarcodeStatus>().Where(a => DateTime.Parse(a.last_modify_time) >= DateTime.Parse(lastTime) && a.bld_date == null).OrderByDescending(a => a.last_modify_time).ToList(); |
| | | } |
| | | |
| | | public static List<Overage> getOverageList(DateTime lastTime) |
| | | public static List<Overage> getOverageList(string lastTime) |
| | | { |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | return db.Queryable<Overage>().Where(a => a.last_modify_time >= lastTime ).OrderByDescending(a => a.last_modify_time).ToList(); |
| | | return db.Queryable<Overage>().Where(a => DateTime.Parse(a.last_modify_time) >= DateTime.Parse(lastTime) ).OrderByDescending(a => a.last_modify_time).ToList(); |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | <Compile Include="core\Monitor.cs" /> |
| | | <Compile Include="models\BaseModel.cs" /> |
| | | <Compile Include="models\Area.cs" /> |
| | | <Compile Include="models\GreenTireInformation.cs" /> |
| | | <Compile Include="models\OffLineRecord.cs" /> |
| | | <Compile Include="models\OI_WMS_OP_DEF.cs" /> |
| | | <Compile Include="models\OI_WMS_SCHEDULE_TYPE.cs" /> |
| | | <Compile Include="models\OI_WMS_TASK_TYPE.cs" /> |
| | | <Compile Include="models\other\DayuanIn.cs" /> |
| | | <Compile Include="models\other\DayuanOut.cs" /> |
| | | <Compile Include="models\Overage.cs" /> |
| | | <Compile Include="models\PutawayDetail.cs" /> |
| | | <Compile Include="models\PutawayOrder.cs" /> |
| | | <Compile Include="models\TN_ASN_Detail.cs" /> |
| | |
| | | <Compile Include="api\ApiHelper.cs" /> |
| | | <Compile Include="dispatch\HostToAGV.cs" /> |
| | | <Compile Include="process\TaskProcess.cs" /> |
| | | <Compile Include="util\ExcetionHelper.cs" /> |
| | | <Compile Include="util\LogHelper.cs" /> |
| | | <Compile Include="util\StrHelper.cs" /> |
| | | <Compile Include="util\STAttribute.cs" /> |
| | |
| | | }); |
| | | } |
| | | private static void StartTcp() { |
| | | Console.WriteLine("开启tcp:" + Settings.listenAddress); |
| | | new TcpServer(Settings.listenAddress); |
| | | /*var host = Dns.GetHostEntry(Dns.GetHostName()); |
| | | foreach (var ip in host.AddressList) { |
| | | if (ip.AddressFamily == AddressFamily.InterNetwork) { |
| | | /* Console.WriteLine("开启tcp:" + Settings.listenAddress); |
| | | new TcpServer(Settings.listenAddress);*/ |
| | | var host = Dns.GetHostEntry(Dns.GetHostName()); |
| | | foreach (var ip in host.AddressList) |
| | | { |
| | | if (ip.AddressFamily == AddressFamily.InterNetwork) |
| | | { |
| | | Console.WriteLine($"ip= {ip.ToString()}"); |
| | | new TcpServer(ip.ToString()); |
| | | } |
| | | }*/ |
| | | } |
| | | } |
| | | |
| | | public class WorkThread |
| | |
| | | using HH.WCS.Mobox3.YNJT_PT.device; |
| | | using HH.WCS.Mobox3.YNJT_PT.models; |
| | | using HH.WCS.Mobox3.YNJT_PT.process; |
| | | using HH.WCS.Mobox3.YNJT_PT.util; |
| | | using HH.WCS.Mobox3.YNJT_PT.wms; |
| | | using Newtonsoft.Json; |
| | | using Newtonsoft.Json.Linq; |
| | | using SqlSugar; |
| | | using Swashbuckle.Swagger; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | |
| | | using System.Threading; |
| | | using static HH.WCS.Mobox3.YNJT_PT.api.ApiModel; |
| | | using static HH.WCS.Mobox3.YNJT_PT.api.OtherModel; |
| | | using static HH.WCS.Mobox3.YNJT_PT.api.WmsController; |
| | | using static System.Net.Mime.MediaTypeNames; |
| | | |
| | | namespace HH.WCS.Mobox3.YNJT_PT.api { |
| | | /// <summary> |
| | |
| | | static ApiHelper() { |
| | | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 成型机下线记录 |
| | | /// </summary> |
| | | /// <param name="model"></param> |
| | | public static ResponseResult cxjOffLineRecord(OffLineModel model) |
| | | { |
| | | ResponseResult response = new ResponseResult(); |
| | | var container = ContainerHelper.GetCntr(model.rfid); |
| | | var location = LocationHelper.GetLoc(model.loc); |
| | | if (location != null) |
| | | { |
| | | if (container == null) |
| | | { |
| | | ContainerHelper.AddCntr(model.rfid); |
| | | } |
| | | |
| | | try |
| | | { |
| | | OffLineRecord record = new OffLineRecord() |
| | | { |
| | | S_RFID = model.rfid, |
| | | S_LOC = model.loc, |
| | | N_IS_URGENT = model.isUrgent, |
| | | T_OFF_TIME = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), |
| | | N_IS_FULL = model.isFull, |
| | | |
| | | }; |
| | | WMSHelper.addOffLineRecord(record); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | LogHelper.Info($"添加成型机下线记录错误,错误原因:{ex.Message}", "WMS"); |
| | | response.code = 500; |
| | | response.msg = "WMS系统内部错误,请联系开发人员排查问题"; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | response.code = 1; |
| | | response.msg = $"货位:{model.loc}不存在"; |
| | | } |
| | | return response; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 下线请求 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | public static ResponseResult offLineRequest(NotifyDeviceSignalModel model) |
| | | { |
| | | ResponseResult response = new ResponseResult(); |
| | | var startLoc = LocationHelper.GetLoc(model.loc); |
| | | if (startLoc != null) |
| | | { |
| | | List<BarcodeModel> extData = model.extData; |
| | | int dataCount = extData.Count; |
| | | if (dataCount > 0) |
| | | { |
| | | var rfidExistNull = extData.Where(a => string.IsNullOrEmpty(a.rfid)).Count()>0; |
| | | if (rfidExistNull) |
| | | { |
| | | response.code = 1; |
| | | response.msg = "rfid不能为空"; |
| | | } |
| | | else |
| | | { |
| | | Dictionary<BarcodeModel, bool> rfidDic = new Dictionary<BarcodeModel, bool>(); |
| | | foreach (var ext in extData) |
| | | { |
| | | string rfid = ext.rfid; |
| | | if (rfid.Contains("ET")) |
| | | { |
| | | rfidDic.Add(ext, false); |
| | | } |
| | | else |
| | | { |
| | | // 1.查询成型机中间表,rfid 是否存在 |
| | | var offLineRecord = WMSHelper.getOffLineRecord(rfid); |
| | | if (offLineRecord != null) |
| | | { |
| | | // 2.查询物料条码信息表,条码信息是否存在 |
| | | var itemBarcodeInfo = WMSHelper.GetGreenTireInformation(ext.barcode); |
| | | if (itemBarcodeInfo == null) |
| | | { |
| | | rfidDic.Add(ext, false); |
| | | } |
| | | else |
| | | { |
| | | rfidDic.Add(ext, true); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | rfidDic.Add(ext, false); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 判断是否有异常托盘 |
| | | bool isNormal = rfidDic.Where(a => a.Value == false).Count() == 0; |
| | | if (isNormal && extData.Count == 2) |
| | | { |
| | | // 双托正常料入库 |
| | | Location endLoc = null; |
| | | var itemBarcodeInfo = WMSHelper.GetGreenTireInformation(extData[0].barcode); |
| | | string groupNo = WMSHelper.GenerateTaskGroupNo(); |
| | | var endLocList = WMSHelper.getInStockEndLoc(itemBarcodeInfo.ITEMCODE, 2); |
| | | if (endLocList.Count == 2) |
| | | { |
| | | var rfidList = rfidDic.Keys.ToList(); |
| | | for (int i = 0; i < rfidList.Count; i++) |
| | | { |
| | | endLoc = endLocList[i]; |
| | | var wmsTask = new WMSTask() |
| | | { |
| | | S_CNTR_CODE = rfidList[i].rfid, |
| | | S_CODE = WMSHelper.GenerateTaskNo(), |
| | | S_START_LOC = startLoc.S_CODE, |
| | | S_START_AREA = startLoc.S_AREA_CODE, |
| | | S_END_LOC = endLoc.S_CODE, |
| | | S_END_AREA = endLoc.S_AREA_CODE, |
| | | S_TYPE = "满料下线入库任务", |
| | | S_OP_DEF_CODE = model.reqId, |
| | | S_OP_DEF_NAME = "成型机满料下线入库", |
| | | N_PRIORITY = 1, |
| | | T_START_TIME = DateTime.Now, |
| | | S_GROUP_NO = groupNo, |
| | | }; |
| | | if (WMSHelper.CreateWmsTask(wmsTask)) |
| | | { |
| | | // 创建一段入库任务 |
| | | WCSTask wcsTask = new WCSTask() |
| | | { |
| | | S_OP_NAME = wmsTask.S_OP_DEF_NAME, |
| | | S_OP_CODE = wmsTask.S_CODE, |
| | | S_CODE = WCSHelper.GenerateTaskNo(), |
| | | S_CNTR_CODE = wmsTask.S_CNTR_CODE, |
| | | S_TYPE = wmsTask.S_TYPE, |
| | | S_START_LOC = startLoc.S_CODE, |
| | | S_START_AREA = startLoc.S_AREA_CODE, |
| | | S_END_LOC = endLoc.S_CODE, |
| | | S_END_AREA = endLoc.S_AREA_CODE, |
| | | S_SCHEDULE_TYPE = "WCS", |
| | | N_PRIORITY = 1, |
| | | T_START_TIME = DateTime.Now, |
| | | }; |
| | | |
| | | if (WCSHelper.CreateTask(wcsTask)) |
| | | { |
| | | // 起点、接驳点、终点加锁 |
| | | LocationHelper.LockLoc(wcsTask.S_START_LOC, 2); |
| | | LocationHelper.LockLoc(wcsTask.S_END_LOC, 1); |
| | | |
| | | // 更新作业任务状态 |
| | | wmsTask.N_B_STATE = 1; |
| | | WMSHelper.UpdateTaskState(wmsTask); |
| | | |
| | | // 绑定容器物料信息 |
| | | WMSHelper.bindBarcodeItemInfo(wmsTask.S_CNTR_CODE,itemBarcodeInfo); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | else |
| | | { |
| | | response.code = 1; |
| | | response.msg = "库区没有可入的空货位"; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | // 异常料出库检修 或 单拖物料入库 |
| | | foreach (var dic in rfidDic) |
| | | { |
| | | Location middleLoc = null; |
| | | Location endLoc = null; |
| | | if (dic.Value) |
| | | { |
| | | var itemBarcodeInfo = WMSHelper.GetGreenTireInformation(dic.Key.barcode); |
| | | var endLocList = WMSHelper.getInStockEndLoc(itemBarcodeInfo.ITEMCODE, 1); |
| | | if (endLocList.Count == 1) |
| | | { |
| | | endLoc = endLocList[0]; |
| | | var wmsTask = new WMSTask() |
| | | { |
| | | S_CNTR_CODE = dic.Key.rfid, |
| | | S_CODE = WMSHelper.GenerateTaskNo(), |
| | | S_START_LOC = startLoc.S_CODE, |
| | | S_START_AREA = startLoc.S_AREA_CODE, |
| | | S_END_LOC = endLoc.S_CODE, |
| | | S_END_AREA = endLoc.S_AREA_CODE, |
| | | S_TYPE = "满料下线入库任务", |
| | | S_OP_DEF_CODE = model.reqId, |
| | | S_OP_DEF_NAME = "成型机满料下线入库", |
| | | N_PRIORITY = 1, |
| | | T_START_TIME = DateTime.Now, |
| | | }; |
| | | if (WMSHelper.CreateWmsTask(wmsTask)) |
| | | { |
| | | // 创建一段入库任务 |
| | | WCSTask wcsTask = new WCSTask() |
| | | { |
| | | S_OP_NAME = wmsTask.S_OP_DEF_NAME, |
| | | S_OP_CODE = wmsTask.S_CODE, |
| | | S_CODE = WCSHelper.GenerateTaskNo(), |
| | | S_CNTR_CODE = wmsTask.S_CNTR_CODE, |
| | | S_TYPE = wmsTask.S_TYPE, |
| | | S_START_LOC = startLoc.S_CODE, |
| | | S_START_AREA = startLoc.S_AREA_CODE, |
| | | S_END_LOC = endLoc.S_CODE, |
| | | S_END_AREA = endLoc.S_AREA_CODE, |
| | | S_SCHEDULE_TYPE = "WCS", |
| | | N_PRIORITY = 1, |
| | | T_START_TIME = DateTime.Now, |
| | | }; |
| | | |
| | | if (WCSHelper.CreateTask(wcsTask)) |
| | | { |
| | | // 起点、接驳点、终点加锁 |
| | | LocationHelper.LockLoc(wcsTask.S_START_LOC, 2); |
| | | LocationHelper.LockLoc(wcsTask.S_END_LOC, 1); |
| | | |
| | | // 更新作业任务状态 |
| | | wmsTask.N_B_STATE = 1; |
| | | WMSHelper.UpdateTaskState(wmsTask); |
| | | |
| | | // 绑定容器物料信息 |
| | | WMSHelper.bindBarcodeItemInfo(wmsTask.S_CNTR_CODE, itemBarcodeInfo); |
| | | } |
| | | } |
| | | } |
| | | else |
| | | { |
| | | response.code = 1; |
| | | response.msg = "库区没有可入的空货位"; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | middleLoc = WMSHelper.getMinTaskMiddleLoc(1); // 1.异常排出位 |
| | | endLoc = WMSHelper.getAbnormalAreaEmptyLoc(Settings.abnormalArea); |
| | | var wmsTask = new WMSTask() |
| | | { |
| | | S_CNTR_CODE = dic.Key.rfid, |
| | | S_CODE = WMSHelper.GenerateTaskNo(), |
| | | S_START_LOC = startLoc.S_CODE, |
| | | S_START_AREA = startLoc.S_AREA_CODE, |
| | | S_END_LOC = endLoc.S_CODE, |
| | | S_END_AREA = endLoc.S_AREA_CODE, |
| | | S_TYPE = "异常托盘出库任务", |
| | | S_OP_DEF_CODE = model.reqId, |
| | | S_OP_DEF_NAME = "异常托盘出库检修", |
| | | N_PRIORITY = 1, |
| | | T_START_TIME = DateTime.Now, |
| | | }; |
| | | if (WMSHelper.CreateWmsTask(wmsTask)) |
| | | { |
| | | // 创建一段入库任务 |
| | | WCSTask wcsTask = new WCSTask() |
| | | { |
| | | S_OP_NAME = wmsTask.S_OP_DEF_NAME, |
| | | S_OP_CODE = wmsTask.S_CODE, |
| | | S_CODE = WCSHelper.GenerateTaskNo(), |
| | | S_CNTR_CODE = wmsTask.S_CNTR_CODE, |
| | | S_TYPE = wmsTask.S_TYPE, |
| | | S_START_LOC = startLoc.S_CODE, |
| | | S_START_AREA = startLoc.S_AREA_CODE, |
| | | S_END_LOC = middleLoc.S_CODE, |
| | | S_END_AREA = middleLoc.S_AREA_CODE, |
| | | S_SCHEDULE_TYPE = "WCS", |
| | | N_PRIORITY = 1, |
| | | T_START_TIME = DateTime.Now, |
| | | }; |
| | | |
| | | if (WCSHelper.CreateTask(wcsTask)) |
| | | { |
| | | // 起点、接驳点、终点加锁 |
| | | LocationHelper.LockLoc(wcsTask.S_START_LOC, 2); |
| | | LocationHelper.LockLoc(wcsTask.S_END_LOC, 1); |
| | | |
| | | // 更新作业任务状态 |
| | | wmsTask.N_B_STATE = 1; |
| | | WMSHelper.UpdateTaskState(wmsTask); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | else |
| | | { |
| | | response.code = 1; |
| | | response.msg = "入参缺少托盘和条码信息"; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | response.code = 1; |
| | | response.msg = "起点货位不存在"; |
| | | } |
| | | return response; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 读码请求 |
| | | /// </summary> |
| | | public static ResponseResult readCodeRequest(NotifyDeviceSignalModel model) |
| | | { |
| | | ResponseResult response = new ResponseResult(); |
| | | readCodeFeedbackResponse readCodeFeedbackResponse = new readCodeFeedbackResponse() |
| | | { |
| | | verifyResult = true |
| | | }; |
| | | var wmsTask = WMSHelper.GetWmsTask(model.taskNo); |
| | | if (wmsTask != null) |
| | | { |
| | | if (wmsTask.S_TYPE != "异常托盘出库任务") |
| | | { |
| | | Location endLoc = null; |
| | | Location middleLoc = null; |
| | | // 判断rfid是否异常 |
| | | if (model.cntrNo != wmsTask.S_CNTR_CODE) |
| | | { |
| | | middleLoc = WMSHelper.getMinTaskMiddleLoc(1); // 1.异常排出位 |
| | | endLoc = WMSHelper.getAbnormalAreaEmptyLoc(Settings.abnormalArea); |
| | | wmsTask.S_END_LOC = endLoc.S_CODE; |
| | | wmsTask.S_END_AREA = endLoc.S_AREA_CODE; |
| | | WMSHelper.UpdateTaskEnd(wmsTask); |
| | | |
| | | var wcsTask = WCSHelper.GetTaskBySrcNo(wmsTask.S_CODE); |
| | | if (wcsTask != null) |
| | | { |
| | | wcsTask.S_END_LOC = middleLoc.S_CODE; |
| | | wcsTask.S_END_AREA = middleLoc.S_AREA_CODE; |
| | | WCSHelper.updateTaskEnd(wcsTask); |
| | | } |
| | | |
| | | readCodeFeedbackResponse.verifyResult = false; |
| | | readCodeFeedbackResponse.endLoc = middleLoc.S_CODE; |
| | | response.data = readCodeFeedbackResponse; |
| | | } |
| | | else |
| | | { |
| | | var cntrItemRels = ContainerHelper.GetCntrItemRel(wmsTask.S_CNTR_CODE); |
| | | if (cntrItemRels.Count > 0) |
| | | { |
| | | if (cntrItemRels[0].S_ITEM_STATE != "OK") |
| | | { |
| | | middleLoc = WMSHelper.getMinTaskMiddleLoc(1); // 1.异常排出位 |
| | | endLoc = WMSHelper.getAbnormalAreaEmptyLoc(Settings.abnormalArea); |
| | | wmsTask.S_END_LOC = endLoc.S_CODE; |
| | | wmsTask.S_END_AREA = endLoc.S_AREA_CODE; |
| | | WMSHelper.UpdateTaskEnd(wmsTask); |
| | | |
| | | var wcsTask = WCSHelper.GetTaskBySrcNo(wmsTask.S_CODE); |
| | | if (wcsTask != null) |
| | | { |
| | | wcsTask.S_END_LOC = middleLoc.S_CODE; |
| | | wcsTask.S_END_AREA = middleLoc.S_AREA_CODE; |
| | | WCSHelper.updateTaskEnd(wcsTask); |
| | | } |
| | | |
| | | readCodeFeedbackResponse.verifyResult = false; |
| | | readCodeFeedbackResponse.endLoc = middleLoc.S_CODE; |
| | | response.data = readCodeFeedbackResponse; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | else |
| | | { |
| | | response.code = 1; |
| | | response.msg = $"任务号:{model.taskNo},未查询到执行中的任务"; |
| | | } |
| | | response.data = readCodeFeedbackResponse; |
| | | return response; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 硫化机呼叫胚胎出库 |
| | | /// </summary> |
| | | /// <param name="model"></param> |
| | | public static ResponseResult callItemOutStock(CallItemModel model) |
| | | { |
| | | ResponseResult response = new ResponseResult(); |
| | | |
| | | return response; |
| | | } |
| | | |
| | | public class readCodeFeedbackResponse |
| | | { |
| | | public bool verifyResult { get; set; } |
| | | public string endLoc { get; set; } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 创建任务 |
| | | /// </summary> |
| | |
| | | cacheInstockInfos.Add(pair); |
| | | } |
| | | } |
| | | |
| | | |
| | | internal static object in_lock = new object(); |
| | | |
| | | /// <summary> |
| | | /// pad入库 |
| | | /// </summary> |
| | | /// <param name="model"></param> |
| | | /// <returns></returns> |
| | | internal static SimpleResult Instock(InstockInfo model) { |
| | | var result = new SimpleResult(); |
| | | //pda入库 |
| | | //1 判断起点有没有任务,有没有入库锁 |
| | | lock (in_lock) { |
| | | var loc = LocationHelper.GetLoc(model.start); |
| | | if (loc != null && loc.N_LOCK_STATE == 0) |
| | | { |
| | | //2 根据终点库区计算终点 |
| | | var end = WMSHelper.GetInstockEnd(model.item, model.endArea); |
| | | LogHelper.Info("终点货位:" + JsonConvert.SerializeObject(end), "TSSG"); |
| | | if (end != null) |
| | | { |
| | | var cntrCode = ContainerHelper.GenerateCntrNo(); |
| | | var wcsTask = new WCSTask |
| | | { |
| | | S_OP_NAME = "入库", |
| | | S_CODE = WCSHelper.GenerateTaskNo(), |
| | | S_TYPE = "下线入库", |
| | | S_START_LOC = model.start, |
| | | S_END_LOC = end.S_CODE, |
| | | S_SCHEDULE_TYPE = "NDC", |
| | | N_CNTR_COUNT = 1, |
| | | S_CNTR_CODE = cntrCode, |
| | | N_START_LAYER = 1, |
| | | N_END_LAYER = end.N_CURRENT_NUM + 1 |
| | | }; |
| | | if (ContainerHelper.BindNewCntrItem(model.start, cntrCode, model.item) && WCSHelper.CreateTask(wcsTask)) |
| | | { |
| | | LocationHelper.LockLoc(model.start, 2); |
| | | LocationHelper.LockLoc(end.S_CODE, 1); |
| | | result.resultCode = 0; |
| | | result.resultMsg = $"任务创建成功,任务号为{wcsTask.S_CODE},终点为{end.S_CODE}"; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | addKeyValuePair(model.ip, model); |
| | | LogHelper.Info("缓存入库信息:" + JsonConvert.SerializeObject(model), "TSSG"); |
| | | result.resultCode = 2; |
| | | result.resultMsg = "未获取到入库终点"; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | result.resultCode = 1; |
| | | result.resultMsg = "起点有任务未完成"; |
| | | } |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 移库 |
| | | /// </summary> |
| | | /// <param name="model"></param> |
| | | /// <returns></returns> |
| | | internal static SimpleResult shiftStock(ShiftStockInfo model) |
| | | { |
| | | var result = new SimpleResult(); |
| | | //1 根据起点库区、排 确定起始货位 |
| | | var startLoc = WMSHelper.GetShiftStockStart(model.startArea, model.startRow); |
| | | if (startLoc != null && startLoc.N_LOCK_STATE == 0) |
| | | { |
| | | //2 根据终点库区计算终点 |
| | | var end = WMSHelper.GetShiftStockEnd( model.endArea, model.endRow); |
| | | if (end != null && end.N_LOCK_STATE == 0) |
| | | { |
| | | var wcsTask = new WCSTask |
| | | { |
| | | S_OP_NAME = "移库", |
| | | S_CODE = WCSHelper.GenerateTaskNo(), |
| | | S_TYPE = "移库", |
| | | S_START_LOC = startLoc.S_CODE, |
| | | S_END_LOC = end.S_CODE, |
| | | S_SCHEDULE_TYPE = "NDC", |
| | | N_CNTR_COUNT = 1, |
| | | S_CNTR_CODE = startLoc.LocCntrRel.S_CNTR_CODE, |
| | | N_START_LAYER = startLoc.N_CURRENT_NUM, |
| | | N_END_LAYER = end.N_CURRENT_NUM + 1 |
| | | }; |
| | | if (WCSHelper.CreateTask(wcsTask)) |
| | | { |
| | | LocationHelper.LockLoc(startLoc.S_CODE, 2); |
| | | LocationHelper.LockLoc(end.S_CODE, 1); |
| | | result.resultCode = 0; |
| | | result.resultMsg = $"任务创建成功,任务号为{wcsTask.S_CODE},终点为{end.S_CODE}"; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | result.resultCode = 2; |
| | | result.resultMsg = "终点库区没有可入的货位"; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | result.resultCode = 1; |
| | | result.resultMsg = "未找到指定物料"; |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | internal static CodeInfo GetCodeInfo(string code, string org) { |
| | | //return new CodeInfo { Fitemid_XK=code, FSourceNo="123456"}; |
| | |
| | | public static void agvCarAlarm(string forkliftNo, string errCode , string errCode2 , string failCode) { |
| | | bool turnLight = false; |
| | | |
| | | var errCodeList = Settings.agvAlarmNoList.Where(a => a.type == 1).Select(a => a.dex).ToList(); |
| | | var errCode2List = Settings.agvAlarmNoList.Where(a => a.type == 2).Select(a => a.dex).ToList(); |
| | | var failCodeList = Settings.agvAlarmNoList.Where(a => a.type == 3).Select(a => a.dex).ToList(); |
| | | |
| | | if (errCodeList.Contains(int.Parse(errCode))) |
| | | { |
| | | turnLight = true; |
| | | LogHelper.Info("StopWord 错误码:" + errCode, "HosttoagvCar"); |
| | | } |
| | | if (errCode2List.Contains(int.Parse(errCode2))) |
| | | { |
| | | turnLight = true; |
| | | LogHelper.Info("StopWord2 错误码:" + errCode2, "HosttoagvCar"); |
| | | } |
| | | if (failCodeList.Contains(int.Parse(failCode))) |
| | | { |
| | | turnLight = true; |
| | | LogHelper.Info("failCode 错误码:" + failCode, "HosttoagvCar"); |
| | | } |
| | | |
| | | var alertorDevices = Settings.alertorLightInfos.Where(a => a.deviceNo == 5 || a.deviceNo == 6).ToList(); |
| | | foreach (var alertorDevice in alertorDevices) |
| | | { |
| | | if (turnLight) |
| | | { |
| | | var result = HH.WCS.Mobox3.YNJT_PT.device.PlcHelper.SendHex(alertorDevice.address, alertorDevice.turnLight); |
| | | LogHelper.Info("开灯,modbus 返回信号:" + result, "HosttoagvCar"); |
| | | } |
| | | /*else |
| | | { |
| | | var result = HH.WCS.Mobox3.YNJT_PT.device.PlcHelper.SendHex(alertorDevice.address, alertorDevice.offLight); |
| | | LogHelper.Info("关灯,modbus 返回信号:" + result, "HosttoagvCar"); |
| | | }*/ |
| | | } |
| | | |
| | | } |
| | | |
| | | |
| | | public class OffLineModel |
| | | { |
| | | public string rfid { get; set; } // 托盘号 |
| | | public string loc { get; set; } // 下线货位 |
| | | public int isUrgent { get; set; } // N_IS_URGENT 是否加急(0.否 1.是) |
| | | public int isFull { get; set; } // 是否满拖 0.否 1.是 |
| | | } |
| | | public class AddTaskModel { |
| | | public string From { get; set; } |
| | | public string To { get; set; } |
| | |
| | | public string ResultMsg { get; set; } |
| | | |
| | | } |
| | | |
| | | public class ResponseResult { |
| | | public int code { get; set; } = 0; |
| | | public string msg { get; set; } |
| | | public object data { get; set; } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// hosttoagv上报任务状态 |
| | | /// </summary> |
| | |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 整排解绑 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | public SimpleResult RowUnbind(RowUnbindInfo model) { |
| | | LogHelper.Info("RowUnbind Request:" + JsonConvert.SerializeObject(model), "TSSG"); |
| | | SimpleResult result = new SimpleResult(); |
| | | List<Location> locations = WMSHelper.GetLocationList(model.area, model.row); |
| | | foreach (var item in locations) |
| | | { |
| | | //货位解锁 |
| | | LocationHelper.UnLockLoc(item.S_CODE); |
| | | |
| | | |
| | | //货位容器解绑 |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | var lcrList = db.Queryable<LocCntrRel>().Where(a => a.S_LOC_CODE == item.S_CODE).Select(s => s.S_CNTR_CODE).ToList(); |
| | | LocationHelper.UnBindingLoc(item.S_CODE, lcrList); |
| | | |
| | | } |
| | | LogHelper.Info("RowUnbind response:" + JsonConvert.SerializeObject(model), "TSSG"); |
| | | return result; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// pda入库申请 |
| | | /// </summary> |
| | | /// <param name="model"></param> |
| | | /// <returns></returns> |
| | | public SimpleResult Instock(InstockInfo model) { |
| | | var result = new SimpleResult(); |
| | | LogHelper.Info("Instock Request:" + JsonConvert.SerializeObject(model), "TSSG"); |
| | | result = ApiHelper.Instock(model); |
| | | LogHelper.Info("Instock response:" + JsonConvert.SerializeObject(result), "TSSG"); |
| | | return result; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// pda移库申请 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | public SimpleResult shiftStock(ShiftStockInfo model) { |
| | | var result = new SimpleResult(); |
| | | LogHelper.Info("shiftStock Request:" + JsonConvert.SerializeObject(model), "TSSG"); |
| | | result = ApiHelper.shiftStock(model); |
| | | LogHelper.Info("shiftStock response:" + JsonConvert.SerializeObject(result), "TSSG"); |
| | | return result; |
| | | } |
| | | |
| | | |
| | | } |
| | | } |
| | |
| | | using HH.WCS.Mobox3.YNJT_PT.dispatch; |
| | | using HH.WCS.Mobox3.YNJT_PT.wms; |
| | | using Newtonsoft.Json; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Web.Http; |
| | | using static HH.WCS.Mobox3.YNJT_PT.api.ApiHelper; |
| | | using static HH.WCS.Mobox3.YNJT_PT.api.ApiModel; |
| | | using static HH.WCS.Mobox3.YNJT_PT.api.OtherModel; |
| | | using static HH.WCS.Mobox3.YNJT_PT.util.ExcetionHelper; |
| | | |
| | | namespace HH.WCS.Mobox3.YNJT_PT.api |
| | | { |
| | |
| | | public class WmsController : System.Web.Http.ApiController |
| | | { |
| | | |
| | | |
| | | /// <summary> |
| | | /// 1.成型机下线记录 |
| | | /// </summary> |
| | | /// <param name="model"></param> |
| | | /// <returns></returns> |
| | | [HttpPost] |
| | | public ResponseResult cxjOffLineRecord(OffLineModel model) |
| | | { |
| | | LogHelper.Info("【1.成型机下线记录】Request:" + JsonConvert.SerializeObject(model), "WMS"); |
| | | var result = ApiHelper.cxjOffLineRecord(model); |
| | | LogHelper.Info("【1.成型机下线记录】response:" + JsonConvert.SerializeObject(result), "WMS"); |
| | | return result; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 2.设备信号反馈 |
| | | /// 业务场景:WCS反馈成型机胚胎下线入库信号(注:必须两托一起上报,没有两托,则补充一个空托) |
| | | /// 逻辑: |
| | | /// 1.查询成型机下线记录表,判断RFID是否存在,状态是否OK,不存在或NG异常排出 |
| | | /// 2.查询物料条码信息表(green_tire_information),保存胚胎信息 |
| | | /// 3.开始计算终点,生成任务 |
| | | /// </summary> |
| | | /// <param name="model"></param> |
| | | /// <returns></returns> |
| | | [HttpPost] |
| | | public ResponseResult notifyDeviceSignal(NotifyDeviceSignalModel model) |
| | | { |
| | | LogHelper.Info("【2.设备信号反馈】notifyDeviceSignal 入参:" + JsonConvert.SerializeObject(model), "WMS"); |
| | | ResponseResult responseResult = new ResponseResult(); |
| | | try |
| | | { |
| | | if (model.signalType == 1) |
| | | { |
| | | responseResult = ApiHelper.offLineRequest(model); |
| | | } |
| | | else if(model.signalType == 3) |
| | | { |
| | | responseResult = ApiHelper.readCodeRequest(model); |
| | | } |
| | | } |
| | | catch (BusinessException be) |
| | | { |
| | | responseResult.code = 501; |
| | | responseResult.msg = be.Message; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | LogHelper.Info($"WMS内部错误,错误原因:{ex.Message}", "WMS"); |
| | | responseResult.code = 500; |
| | | responseResult.msg = $"WMS内部错误,请联系开发人员处理"; |
| | | } |
| | | LogHelper.Info("【2.设备信号反馈】notifyDeviceSignal 出参:" + JsonConvert.SerializeObject(responseResult), "WMS"); |
| | | return responseResult; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 3.硫化机呼叫胚胎出库 |
| | | /// 逻辑: |
| | | /// 1.根据机台号查询【硫化机工单表】、【胚胎已完成的条码中间表】筛选当前班次的生产计划数量是否满足,当预计生产数量 = 实际数+在途数量 ,则停止叫料 |
| | | /// 2.查询机台号在【硫化机工单表】对应的物料编码, |
| | | /// 开始计算(1.巷道不报警、2.物料状态OK、3.小于失效时间 大于等于生效时间 4.加急料先出、5.先入先出(生产时间))出库物料,生成任务 |
| | | /// </summary> |
| | | /// <param name="model"></param> |
| | | /// <returns></returns> |
| | | public ResponseResult callItemOutStock(CallItemModel model ) |
| | | { |
| | | LogHelper.Info("【3.硫化机呼叫胚胎出库】callItemOutStock 入参:" + JsonConvert.SerializeObject(model), "WMS"); |
| | | ResponseResult responseResult = new ResponseResult(); |
| | | responseResult = ApiHelper.callItemOutStock(model); |
| | | LogHelper.Info("【3.硫化机呼叫胚胎出库】callItemOutStock 出参:" + JsonConvert.SerializeObject(responseResult), "WMS"); |
| | | return responseResult; |
| | | } |
| | | |
| | | public class CallItemModel |
| | | { |
| | | public string mcn { get; set; } |
| | | public List<string> locCodes { get; set; } |
| | | } |
| | | |
| | | public class NotifyDeviceSignalModel |
| | | { |
| | | public string reqId { get; set; } |
| | | public string reqTime { get; set; } |
| | | public string loc { get; set; } |
| | | public string taskNo { get; set; } |
| | | public string cntrNo { get; set; } |
| | | public int signalType { get; set; } |
| | | public List<BarcodeModel> extData { get; set; } |
| | | public string deviceNo { get; set; } |
| | | } |
| | | |
| | | public class BarcodeModel |
| | | { |
| | | public string rfid { get; set; } |
| | | public string barcode { get; set; } |
| | | } |
| | | |
| | | /* /// <summary> |
| | | /// 3.任务状态反馈 |
| | | /// 业务场景:WCS在执行任务时,回报任务状态 |
| | | /// </summary> |
| | | /// <param name="model"></param> |
| | | /// <returns></returns> |
| | | [HttpPost] |
| | | *//*[Route("notifyTaskStatus")]*//* |
| | | public ResponseResult notifyTaskStatus(TaskStatusFeedbackModel model) |
| | | { |
| | | LogHelper.Info("notifyTaskStatus 入参:" + JsonConvert.SerializeObject(model), "WMS"); |
| | | var result = ApiHelper.taskStatusFeedback(model); |
| | | LogHelper.Info("notifyTaskStatus 出参:" + JsonConvert.SerializeObject(result), "WMS"); |
| | | return result; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 3.申请终点 |
| | | /// </summary> |
| | | /// <param name="model"></param> |
| | | /// <returns></returns> |
| | | [HttpPost] |
| | | *//* [Route("applyDest")]*//* |
| | | public ResponseResult applyDest(ApplyDestinationModel model) |
| | | { |
| | | LogHelper.Info("applyDest 入参:" + JsonConvert.SerializeObject(model), "WMS"); |
| | | var result = ApiHelper.applyDest(model); |
| | | LogHelper.Info("applyDest 出参:" + JsonConvert.SerializeObject(result), "WMS"); |
| | | return result; |
| | | }*/ |
| | | } |
| | | } |
| | |
| | | "ApiPort": 8901, |
| | | "FacCode": "1122", |
| | | "WHCode": "TSCK", |
| | | "DeviceInfo": [ |
| | | { |
| | | "address": "192.168.1.160", |
| | | "deviceName": "1号下线口", |
| | | "deviceNo": [], |
| | | "location": [ "TSSG-XXK-1" ], |
| | | "deviceType": 1, |
| | | "enable": 1 |
| | | }, |
| | | { |
| | | "address": "192.168.1.161", |
| | | "deviceName": "2号下线口", |
| | | "deviceNo": [], |
| | | "location": [ "TSSG-XXK-2" ], |
| | | "deviceType": 1, |
| | | "enable": 1 |
| | | } |
| | | ], |
| | | "ListenAddress": "127.0.0.1", |
| | | "AlertorLightDevice": [ |
| | | { |
| | | "deviceNo": 1, |
| | | "address": "192.168.1.50", |
| | | "turnLight": "01 06 00 10 01 03 C9 9E", |
| | | "offLight": "01 06 00 10 04 00 8A CF" |
| | | }, |
| | | { |
| | | "deviceNo": 2, |
| | | "address": "192.168.1.51", |
| | | "turnLight": "02 06 00 10 01 03 C9 AD", |
| | | "offLight": "02 06 00 10 04 00 8A FC" |
| | | "StockArea": "area2", |
| | | "AbnormalArea": "area1", // 异常区 |
| | | |
| | | // 接驳位 type 1.排出口 |
| | | "ConnectLoc": [ |
| | | { |
| | | "locCode": "loc1", |
| | | "roadway": 1, |
| | | "type": 1 |
| | | }, |
| | | { |
| | | "deviceNo": 3, |
| | | "address": "192.168.1.52", |
| | | "turnLight": "03 06 00 10 01 03 C8 7C", |
| | | "offLight": "03 06 00 10 04 00 8B 2D" |
| | | }, |
| | | { |
| | | "deviceNo": 4, |
| | | "address": "192.168.1.53", |
| | | "turnLight": "04 06 00 10 01 03 C9 CB", |
| | | "offLight": "04 06 00 10 04 00 8A 9A" |
| | | }, |
| | | { |
| | | "deviceNo": 5, |
| | | "address": "192.168.1.160", |
| | | "turnLight": "3F 00 50 0D 0A", |
| | | "offLight": "3F 00 12 22 0D 0A" |
| | | }, |
| | | { |
| | | "deviceNo": 6, |
| | | "address": "192.168.1.161", |
| | | "turnLight": "3F 00 50 0D 0A", |
| | | "offLight": "3F 00 12 22 0D 0A" |
| | | "locCode": "loc1", |
| | | "roadway": 2, |
| | | "type": 1 |
| | | } |
| | | ], |
| | | // type 1、stopWord 2、stopWord2 3、failCode |
| | | "AgvAlarmNo": [ |
| | | { |
| | | "type": 1, |
| | | "dex": 16, |
| | | "code": "StopStartDelay", |
| | | "name": "急停复位" |
| | | }, |
| | | { |
| | | "type": 1, |
| | | "dex": 32, |
| | | "code": "StopBumper", |
| | | "name": "触边触发" |
| | | }, |
| | | { |
| | | "type": 1, |
| | | "dex": 512, |
| | | "code": "StopRear", |
| | | "name": "叉尖光电触发" |
| | | }, |
| | | { |
| | | "type": 1, |
| | | "dex": 2048, |
| | | "code": "StopAdjustHeightErro", |
| | | "name": "视觉调整高度数据异常" |
| | | }, |
| | | { |
| | | "type": 2, |
| | | "dex": 2, |
| | | "code": "StopNoOpCode", |
| | | "name": "没有作业代码" |
| | | }, |
| | | { |
| | | "type": 2, |
| | | "dex": 4, |
| | | "code": "StopFailCode", |
| | | "name": "作业失败" |
| | | }, |
| | | { |
| | | "type": 2, |
| | | "dex": 8, |
| | | "code": "StopLoadDroppedWhileUnloading", |
| | | "name": "货物掉落" |
| | | }, |
| | | { |
| | | "type": 2, |
| | | "dex": 16, |
| | | "code": "StopLoadOp", |
| | | "name": "取货失败" |
| | | }, |
| | | { |
| | | "type": 2, |
| | | "dex": 256, |
| | | "code": "StopEstopButton", |
| | | "name": "急停按钮触发" |
| | | }, |
| | | { |
| | | "type": 2, |
| | | "dex": 8192, |
| | | "code": "StopDelay", |
| | | "name": "作业等待" |
| | | }, |
| | | { |
| | | "type": 2, |
| | | "dex": 32768, |
| | | "code": "StopACS5_OT", |
| | | "name": "行走电机过温" |
| | | }, |
| | | { |
| | | "type": 2, |
| | | "dex": 65536, |
| | | "code": "StopACS7_OT", |
| | | "name": "油泵电机过温" |
| | | }, |
| | | { |
| | | "type": 2, |
| | | "dex": 131072, |
| | | "code": "StopACS5_OC", |
| | | "name": "行走电机过流" |
| | | }, |
| | | { |
| | | "type": 2, |
| | | "dex": 262144, |
| | | "code": "StopACS7_FwOC", |
| | | "name": "油泵电机上升过流" |
| | | }, |
| | | { |
| | | "type": 2, |
| | | "dex": 524288, |
| | | "code": "StopACS7_UpOC", |
| | | "name": "油泵电机下降过流" |
| | | }, |
| | | { |
| | | "type": 2, |
| | | "dex": 1048576, |
| | | "code": "StopACD6_OT", |
| | | "name": "转向电机过温" |
| | | }, |
| | | { |
| | | "type": 2, |
| | | "dex": 2097152, |
| | | "code": "StopCyclePower", |
| | | "name": "循环电源" |
| | | }, |
| | | { |
| | | "type": 2, |
| | | "dex": 16777216, |
| | | "code": "StopCameraError", |
| | | "name": "相机拍照失败" |
| | | }, |
| | | { |
| | | "type": 3, |
| | | "dex": 32, |
| | | "code": "FailCode_STNIsEmpty ", |
| | | "name": "取货时未检测到货物" |
| | | }, |
| | | { |
| | | "type": 3, |
| | | "dex": 256, |
| | | "code": "FailCode_ForkError ", |
| | | "name": "货叉高度异常" |
| | | }, |
| | | { |
| | | "type": 3, |
| | | "dex": 1024, |
| | | "code": "FailCode_NoOpCode ", |
| | | "name": "没有作业代码" |
| | | }, |
| | | { |
| | | "type": 3, |
| | | "dex": 2048, |
| | | "code": "FailCode_LoadForkOrderError ", |
| | | "name": "货叉没有获取作业代码" |
| | | }, |
| | | { |
| | | "type": 3, |
| | | "dex": 4096, |
| | | "code": "FailCode_ChargeError ", |
| | | "name": "充电失败" |
| | | }, |
| | | { |
| | | "type": 3, |
| | | "dex": 8192, |
| | | "code": "FailCode_Goods_OverWide ", |
| | | "name": "压力传感器异常" |
| | | }, |
| | | { |
| | | "type": 3, |
| | | "dex": 16384, |
| | | "code": "FailCode_VisualIdentity_Err ", |
| | | "name": "视觉数据超时作业失败" |
| | | } |
| | | ], |
| | | |
| | | // 存储信号等待时间(单位:分钟) |
| | | "WaitTime": 5, |
| | | // 缓存库区 |
| | | "BufferArea": "" |
| | | |
| | | ] |
| | | } |
| | |
| | | |
| | | } |
| | | |
| | | internal static void CheckOutWork() { |
| | | //读自己的中间表,我们自己的表有表有个字段计数,计数小于最大值,继续出库,一次生成一条任务 |
| | | |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 待定,此项目plc怎么对接还不确定 |
| | | /// </summary> |
| | | internal static void CheckDevice() { |
| | | //检测输送线状态 |
| | | |
| | | S7Helper.ReadStr("plc1", 100, 1, 8); |
| | | S7Helper.ReadBit("plc1", 101, 1, 2); |
| | | S7Helper.ReadInt("plc1", 102, 1, 6); |
| | | //1 设备plc的ip deviceNo 自动建立连接 |
| | | //2 设备对应的通讯项和线体类型(输送线入口、输送线出口、提升机的入口。。。。)起始读的偏移地址,写的偏移地址 |
| | | //{ "deviceNo":"5","code":"9001","location":"F1CJ-SSX1-01","writeAddr900":0,"writeAddr905":-1,"writeAddr710":0,"readAddr901":2,"readAddr902":0,"lineType":1}, |
| | | //3 通讯项自动读plc,读到的数据根据lineType做处理,自动创建任务或者更新任务状态(创建一个设备动作或任务动作,如果是任务动作有个线程去读) |
| | | } |
| | | |
| | | // 定时器(单位:分钟) |
| | | private static System.Timers.Timer aTimer = new System.Timers.Timer(Settings.WaitTime * 60000); |
| | | private static System.Timers.Timer bTimer = new System.Timers.Timer(Settings.WaitTime * 60000); |
| | | |
| | | private static string flag1 = null; |
| | | private static string flag2 = null; |
| | | |
| | | internal static void CheckEndLoc() { |
| | | |
| | | foreach (var item in ApiHelper.cacheInstockInfos) |
| | | { |
| | | var instockInfo = item.Value; |
| | | var end = WMSHelper.GetInstockEnd(instockInfo.item, instockInfo.endArea); |
| | | LogHelper.Info("终点货位:" + JsonConvert.SerializeObject(end), "TSSG"); |
| | | if (end != null) |
| | | { |
| | | ApiHelper.Instock(instockInfo); |
| | | ApiHelper.cacheInstockInfos.Remove(item); |
| | | LogHelper.Info("缓存信息生成入库任务,并删除缓存信息:" + JsonConvert.SerializeObject(item), "TSSG"); |
| | | return; |
| | | } |
| | | |
| | | if (item.Key == "192.168.1.160" && instockInfo.UDID != flag1) |
| | | { |
| | | flag1 = instockInfo.UDID; |
| | | |
| | | // 挂钩Elapsed事件以提供定时器信号 |
| | | aTimer.Elapsed -= OnTimedEvent1; |
| | | aTimer.Elapsed += OnTimedEvent1; |
| | | |
| | | // 设置自动重置为true(意味着定时器会重复触发) |
| | | aTimer.AutoReset = false; |
| | | |
| | | aTimer.Stop(); // 确保定时器停止 |
| | | aTimer.Enabled = true; // 启动定时器 |
| | | } |
| | | |
| | | if (item.Key == "192.168.1.161" && instockInfo.UDID != flag2) |
| | | { |
| | | flag2 = instockInfo.UDID; |
| | | |
| | | // 挂钩Elapsed事件以提供定时器信号 |
| | | aTimer.Elapsed -= OnTimedEvent2; |
| | | aTimer.Elapsed += OnTimedEvent2; |
| | | |
| | | // 设置自动重置为true(意味着定时器会重复触发) |
| | | aTimer.AutoReset = true; |
| | | |
| | | aTimer.Stop(); // 确保定时器停止 |
| | | aTimer.Enabled = true; // 启动定时器 |
| | | |
| | | } |
| | | } |
| | | } |
| | | |
| | | private static void OnTimedEvent1(Object source, ElapsedEventArgs e) |
| | | { |
| | | foreach (var item in ApiHelper.cacheInstockInfos) |
| | | { |
| | | var instockInfo = item.Value; |
| | | if (instockInfo.UDID == flag1) { |
| | | if (Settings.BufferArea != null && Settings.BufferArea != "") { |
| | | item.Value.endArea = Settings.BufferArea; |
| | | LogHelper.Info("ip:" + item.Key + "信号等待时间超时,变更终点库区为缓存区", "TSSG"); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | private static void OnTimedEvent2(Object source, ElapsedEventArgs e) |
| | | { |
| | | foreach (var item in ApiHelper.cacheInstockInfos) |
| | | { |
| | | var instockInfo = item.Value; |
| | | if (instockInfo.UDID == flag2) |
| | | { |
| | | if (Settings.BufferArea != null && Settings.BufferArea != "") |
| | | { |
| | | item.Value.endArea = Settings.BufferArea; |
| | | LogHelper.Info("ip:" + item.Key + "信号等待时间超时,变更终点库区为缓存区", "TSSG"); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | // 自动移库 |
| | | internal static void AutoShiftStock() |
| | | { |
| | | var startLoc = WMSHelper.GetShiftStockStart(Settings.BufferArea); |
| | | if (startLoc != null) { |
| | | var end = WMSHelper.GetInstockEnd(startLoc.LocCntrRel.CntrItemRel.S_ITEM_CODE); |
| | | if (end != null) { |
| | | var wcsTask = new WCSTask |
| | | { |
| | | S_OP_NAME = "入库", |
| | | S_CODE = WCSHelper.GenerateTaskNo(), |
| | | S_TYPE = "下线入库", |
| | | S_START_LOC = startLoc.S_CODE, |
| | | S_END_LOC = end.S_CODE, |
| | | S_SCHEDULE_TYPE = "NDC", |
| | | N_CNTR_COUNT = 1, |
| | | S_CNTR_CODE = startLoc.LocCntrRel.S_CNTR_CODE, |
| | | N_START_LAYER = startLoc.N_CURRENT_NUM, |
| | | N_END_LAYER = end.N_CURRENT_NUM + 1 |
| | | }; |
| | | if (WCSHelper.CreateTask(wcsTask)) |
| | | { |
| | | LocationHelper.LockLoc(startLoc.S_CODE, 2); |
| | | LocationHelper.LockLoc(end.S_CODE, 1); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 移库单移库 |
| | | /// </summary> |
| | | public static void ShiftStockOrder() { |
| | | List<TN_YiKuDetail> tN_YiKuDetails = WMSHelper.getShiftOrderDetail(); |
| | | foreach (var item in tN_YiKuDetails) |
| | | { |
| | | if (item.N_QTY > item.N_COMPLETE_NUM) { |
| | | Location startLoc = WMSHelper.GetShiftStockStart(item.S_START_AREA, item.S_START_ROW); |
| | | Location endLoc = WMSHelper.GetShiftStockEnd(item.S_END_AREA, item.S_END_ROW); |
| | | if (startLoc != null && endLoc != null && !WMSHelper.isRowLock(endLoc)) |
| | | { |
| | | var wcsTask = new WCSTask |
| | | { |
| | | S_OP_CODE = item.S_NO, |
| | | S_OP_NAME = "移库单移库", |
| | | S_CODE = WCSHelper.GenerateTaskNo(), |
| | | S_TYPE = "移库", |
| | | S_START_LOC = startLoc.S_CODE, |
| | | S_END_LOC = endLoc.S_CODE, |
| | | S_SCHEDULE_TYPE = "NDC", |
| | | N_CNTR_COUNT = 1, |
| | | S_CNTR_CODE = startLoc.LocCntrRel.S_CNTR_CODE, |
| | | N_START_LAYER = startLoc.N_CURRENT_NUM, |
| | | N_END_LAYER = endLoc.N_CURRENT_NUM + 1 |
| | | }; |
| | | if (WCSHelper.CreateTask(wcsTask)) |
| | | { |
| | | LocationHelper.LockLoc(startLoc.S_CODE, 2); |
| | | LocationHelper.LockLoc(endLoc.S_CODE, 1); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | } |
| | | } |
| | |
| | | internal class WCSCore { |
| | | public static void OperateAgvTaskStatus(AgvTaskState model) { |
| | | if (string.IsNullOrEmpty(model.No)) { |
| | | var alertorDevice = Settings.alertorLightInfos.Where(a => a.deviceNo == int.Parse(model.LockNo)).FirstOrDefault(); |
| | | if (model.State == 1023) |
| | | { |
| | | var result = HH.WCS.Mobox3.YNJT_PT.device.TcpClient.SendHexOnce(alertorDevice.address, 502, alertorDevice.turnLight); |
| | | LogHelper.Info("modbus 返回信号:" + result, "TSSG"); |
| | | } |
| | | |
| | | if (model.State == 1025) |
| | | { |
| | | var result = HH.WCS.Mobox3.YNJT_PT.device.TcpClient.SendHexOnce(alertorDevice.address, 502, alertorDevice.offLight); |
| | | LogHelper.Info("modbus 返回信号:" + result, "TSSG"); |
| | | } |
| | | } |
| | | else { |
| | | var TN_Task = WCSHelper.GetTask(model.No); |
| | |
| | | break; |
| | | case 5: |
| | | WCSHelper.UpdateStatus(TN_Task, "开始卸货"); |
| | | WCSHelper.UpdateStatus(TN_Task, "卸货完成"); |
| | | TaskProcess.OperateStatus(TN_Task, 6); |
| | | if (TN_Task.S_OP_NAME == "移库单移库") |
| | | { |
| | | var startLoc = LocationHelper.GetLoc(TN_Task.S_START_LOC); |
| | | var endLoc = LocationHelper.GetLoc(TN_Task.S_END_LOC); |
| | | |
| | | TN_YiKuDetail detail = new TN_YiKuDetail() |
| | | { |
| | | S_NO = TN_Task.S_OP_CODE, |
| | | S_START_AREA = startLoc.S_AREA_CODE, |
| | | S_START_ROW = startLoc.N_ROW, |
| | | S_END_AREA = endLoc.S_AREA_CODE, |
| | | S_END_ROW = endLoc.N_ROW |
| | | }; |
| | | WMSHelper.updateShiftOrderDetail(detail); |
| | | } |
| | | WCSHelper.End(TN_Task); |
| | | break; |
| | | case 6: |
| | | WCSHelper.UpdateStatus(TN_Task, "卸货完成"); |
| | | TaskProcess.OperateStatus(TN_Task, 6); |
| | | break; |
| | | #endregion |
| | | case 2: |
| | | // 修改工单状态 |
| | | /* WCSHelper.UpdateWorkOrderStatus(TN_Task.S_OP_CODE, "已完成");*/ |
| | | WCSHelper.End(TN_Task); |
| | | break; |
| | | case 7: |
| | | //判断是否收到过强制取消,有就不做任何处理 |
| | |
| | | //终点托盘绑定 |
| | | if (LocationHelper.BindingLoc(wcsTask.S_END_LOC, new List<string> { wcsTask.S_CNTR_CODE })) { |
| | | //修改托盘状态为可用,增加库存量表,后面分拣出可以计算到 |
| | | ContainerHelper.Enable(wcsTask.S_CNTR_CODE, wcsTask.S_END_LOC); |
| | | /* ContainerHelper.Enable(wcsTask.S_CNTR_CODE, wcsTask.S_END_LOC);*/ |
| | | |
| | | } |
| | | } |
| | |
| | | [SugarTable("TN_CG_Detail")] |
| | | public class CntrItemRel : BaseModel |
| | | { |
| | | |
| | | |
| | | public string S_CG_ID { get; set; } |
| | | public string S_GRID_NO { get; set; } |
| | | public string S_SERIAL_NO { get; set; } |
| | | public string S_ITEM_CODE { get; set; } |
| | | public string S_ITEM_NAME { get; set; } = ""; |
| | | public string S_ITEM_SPEC { get; set; } |
| | | public string S_ITEM_STATE { get; set; } = "合格"; |
| | | /// <summary> |
| | | /// 1:合格 2:不合格 |
| | | /// </summary> |
| | | public int N_ITEM_STATE { get; set; } |
| | | public string S_BATCH_NO { get; set; } = ""; |
| | | public string S_END_USER { get; set; } = ""; |
| | | public string S_OWNER { get; set; } |
| | | public string S_SUPPLIER_NO { get; set; } |
| | | public string S_PACK_TYPE { get; set; } |
| | | public float F_PACK_QTY { get; set; } |
| | | public float F_QTY { get; set; } |
| | | public string S_UOM { get; set; } = "kg"; |
| | | public string S_CG_ID { get; set; } // 条形码 |
| | | [SugarColumn(IsPrimaryKey = true)] |
| | | public string S_CNTR_CODE { get; set; } |
| | | public string S_BS_TYPE { get; set; } = ""; |
| | | public string S_BS_NO { get; set; } = ""; |
| | | |
| | | public string S_ITEM_ROUTE { get; set; } = ""; |
| | | public float F_NET_WEIGHT { get; set; } |
| | | public float F_GROSS_WEIGHT { get; set; } |
| | | public string S_WU { get; set; } = ""; |
| | | /// <summary> |
| | | /// 分配量,被其它 |
| | | /// </summary> |
| | | public float F_ALLOC_QTY { get; set; } |
| | | public string C_ITEM_MERGE { get; set; } = "N"; |
| | | public string S_PUTAWAY_NO { get; set; } |
| | | |
| | | ///// <summary> |
| | | ///// 反向映射 |
| | | ///// </summary> |
| | | //[SugarColumn(IsIgnore = true)] |
| | | //[Navigate(NavigateType.OneToOne, nameof(S_CNTR_CODE), nameof(Container.S_CODE))] |
| | | //public Container Cntr { get; set; } |
| | | public string S_CNTR_CODE { get; set; } // 容器编码 |
| | | public string S_ITEM_CODE { get; set; } // 物料编码 |
| | | public string S_CELL_NO { get; set; } // 商品编码 |
| | | public string S_ITEM_STATE { get; set; } = "OK"; // 质检状态 |
| | | public float F_QTY { get; set; } // 数量 |
| | | public string S_MCN { get; set; } // 机器代码 |
| | | public string S_OPR { get; set; } // 操作员id1 |
| | | public string S_OPR02 { get; set; } // 操作员id2 |
| | | public string S_OPR03 { get; set; } // 操作员id3 |
| | | public string S_OPR04 { get; set; } // 操作员id4 |
| | | public string S_WINDUP { get; set; } // windup |
| | | public string S_TXNDATE { get; set; } // 生产时间 |
| | | public string S_DATE_SHIFT { get; set; } // 转班日期 |
| | | public string S_EFFECTIVE_TIME { get; set; } // 生效时间 |
| | | public string S_EXPIRATION_TIME { get; set; } // 失效时间 |
| | | } |
| | | } |
New file |
| | |
| | | using SqlSugar; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | |
| | | namespace HH.WCS.Mobox3.YNJT_PT.models |
| | | { |
| | | [SugarTable("TN_green_tire_information")] |
| | | public class GreenTireInformation : BaseModel |
| | | { |
| | | public string ITEMCODE { get; set; } // 物料编码 |
| | | public string BARCODE { get; set; } // 条形码 |
| | | public string TIRECODE { get; set; } // 商品代码 |
| | | public string MCN { get; set; } // 机器代码 |
| | | public string OPR { get; set; } // 操作员id1 |
| | | public string OPR02 { get; set; } // 操作员id2 |
| | | public string OPR03 { get; set; } // 操作员id3 |
| | | public string OPR04 { get; set; } // 操作员id4 |
| | | public string WINDUP { get; set; } // windup |
| | | public int QTY { get; set; } // 数量 |
| | | public string TXNDATE { get; set; } // 生产时间 |
| | | public string DATE_SHIFT { get; set; } // 转班日期 |
| | | } |
| | | } |
New file |
| | |
| | | using SqlSugar; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | |
| | | namespace HH.WCS.Mobox3.YNJT_PT.models |
| | | { |
| | | /// <summary> |
| | | /// 成型机下线记录表 |
| | | /// </summary> |
| | | [SugarTable("TN_CXJ_OFF_LINE_RECORD")] |
| | | public class OffLineRecord : BaseModel |
| | | { |
| | | public string S_RFID { get; set; } // 托盘号 |
| | | public string S_LOC { get; set; } // 下线货位 |
| | | public int N_IS_URGENT { get; set; } // N_IS_URGENT 是否加急(0.否 1.是) |
| | | public string T_OFF_TIME { get; set; } // 下线时间 |
| | | public int N_IS_FULL { get; set; } // 是否满拖 0.否 1.是 |
| | | |
| | | } |
| | | } |
New file |
| | |
| | | using HH.WCS.Mobox3.YNJT_PT.models; |
| | | using SqlSugar; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | |
| | | namespace HH.WCS.Mobox3.YNJT_BZP_PT.models |
| | | { |
| | | [SugarTable("TN_standard_overage")] |
| | | internal class Overage : BaseModel |
| | | { |
| | | public string MCNGRP { get; set; } //生产流程组 |
| | | public string ITEMPATT { get; set; } // 物料前缀 |
| | | public int OVERAGE { get; set; } // 最大保存时间 |
| | | public float MINHOUR { get; set; } // 多久后生效 |
| | | public string FLAG_STS { get; set; } // 标记 |
| | | public int RECID { get; set; } // 标记 |
| | | } |
| | | } |
| | |
| | | public int N_FAIL_MAX { get; set; } |
| | | public DateTime? T_LAST_FAIL { get; set; } |
| | | |
| | | // ----------------- 印尼佳通-硫化---------------- |
| | | public string S_GROUP_NO { get; set; } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 0 等待/1 执行/2 完成/3 错误/4 启劢失败 /5 暂停启劢 |
| | | /// </summary> |
| | |
| | | //去掉消息头3F 00 |
| | | data = data.Substring(4); |
| | | Console.WriteLine($"{ip}-{data}"); |
| | | var plc = Settings.deviceInfos.Where(a => a.address == ip && a.enable == 1).FirstOrDefault(); |
| | | Console.WriteLine("plc:" + JsonConvert.SerializeObject(plc)); |
| | | if (plc != null) { |
| | | if (plc.deviceType == 1) { |
| | | |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | var workOrder = db.Queryable<WorkOrder>().Where(a => a.S_STATUS.Equals("执行中") && a.S_PROD_LINE.Equals(plc.deviceName)).First(); |
| | | Console.WriteLine("工单:" + JsonConvert.SerializeObject(workOrder)); |
| | | if (workOrder != null) { |
| | | string endArea = LocationHelper.getAreaByAreaName(workOrder.S_END_AREA).S_CODE; |
| | | |
| | | InstockInfo instockInfo = new InstockInfo() |
| | | { |
| | | start = plc.location[0], |
| | | item = workOrder.S_ITEM_CODE, |
| | | endArea = endArea, |
| | | ip = ip, |
| | | UDID = GenerateTaskNo() |
| | | }; |
| | | LogHelper.Info("接收信号处理:"+ JsonConvert.SerializeObject(instockInfo),"TSSG"); |
| | | ApiHelper.Instock(instockInfo); |
| | | } |
| | | } |
| | | else if (plc.deviceType == 2) { |
| | | //出库缓存位的光电信息 |
| | | //如果有缓存位是空的状态,我们先判断有没有任务终点分配到这里,如果没有,就找一条出库任务,终点是虚拟点的任务,分配到这个空位 |
| | | //修改任务终点 |
| | | } |
| | | } |
| | | else { |
| | | Console.WriteLine($"TCP信号处理:未查询到IP为{ip}的数据,请检查deviceInfo配置中心是否存在该IP的数据!"); |
| | | } |
| | | |
| | | |
| | | |
| | | } |
| | | |
| | | } |
File was renamed from HH.WCS.Mobox3/HH.WCS.Mobox3.FJJT/util/ExcetionHelper.cs |
| | |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | |
| | | namespace HH.WCS.Mobox3.FJJT.util |
| | | namespace HH.WCS.Mobox3.YNJT_PT.util |
| | | { |
| | | public class ExcetionHelper |
| | | { |
| | | |
| | | public class BusinessException : Exception |
| | | { |
| | | public BusinessException(string message) : base(message) { } |
| | |
| | | public static string HASeverUrl { get; set; } |
| | | public static string SqlServer { get; set; } |
| | | public static string SqlServer1 { get; set; } |
| | | public static List<deviceInfo> deviceInfos { get; set; } |
| | | public static List<ConnectLoc> connectLocList { get; set; } |
| | | public static int port { get; set; } |
| | | public static string WHCode { get; set; } |
| | | public static string FacCode { get; set; } |
| | | public static string listenAddress { get; set; } |
| | | public static int WaitTime { get; set; } |
| | | public static string BufferArea { get; set; } |
| | | public static List<AgvAlarmNo> agvAlarmNoList { get; set; } |
| | | public static List<AlertorDeviceInfo> alertorLightInfos { get; set; } |
| | | public static string abnormalArea { get; set; } |
| | | public static string stockArea { get; set; } |
| | | |
| | | |
| | | public static void Init() { |
| | | LogHelper.Info("加载配置文件信息 开始"); |
| | |
| | | if (keyValue.Name == "ApiPort") { |
| | | port = int.Parse(keyValue.Value.ToString()); |
| | | } |
| | | if (keyValue.Name == "DeviceInfo") { |
| | | deviceInfos = JsonConvert.DeserializeObject<List<deviceInfo>>(keyValue.Value.ToString()); |
| | | if (keyValue.Name == "ConnectLoc") { |
| | | connectLocList = JsonConvert.DeserializeObject<List<ConnectLoc>>(keyValue.Value.ToString()); |
| | | } |
| | | if (keyValue.Name == "ListenAddress") |
| | | if (keyValue.Name == "AbnormalArea") |
| | | { |
| | | listenAddress = keyValue.Value.ToString(); |
| | | abnormalArea = keyValue.Value.ToString(); |
| | | } |
| | | if (keyValue.Name == "WaitTime") |
| | | if (keyValue.Name == "StockArea") |
| | | { |
| | | WaitTime = JsonConvert.DeserializeObject<int>(keyValue.Value.ToString()); |
| | | stockArea = keyValue.Value.ToString(); |
| | | } |
| | | if (keyValue.Name == "BufferArea") |
| | | { |
| | | BufferArea = keyValue.Value.ToString(); |
| | | } |
| | | if (keyValue.Name == "AlertorLightDevice") |
| | | { |
| | | alertorLightInfos = JsonConvert.DeserializeObject<List<AlertorDeviceInfo>>(keyValue.Value.ToString()); |
| | | } |
| | | if (keyValue.Name == "AgvAlarmNo") |
| | | { |
| | | agvAlarmNoList = JsonConvert.DeserializeObject<List<AgvAlarmNo>>(keyValue.Value.ToString()); |
| | | } |
| | | |
| | | } |
| | | } |
| | | } |
| | |
| | | |
| | | } |
| | | |
| | | /* public static AlertorDeviceInfo getAlertorAdress(int deviceNo) |
| | | { |
| | | var alertorDeviceInfo = alertorLightInfos.Where(a => a.deviceNo == deviceNo).FirstOrDefault(); |
| | | return alertorDeviceInfo; |
| | | }*/ |
| | | |
| | | public class AgvAlarmNo |
| | | public class ConnectLoc |
| | | { |
| | | public string locCode { get; set; } |
| | | public int roadway { get; set; } |
| | | public int type { get; set; } |
| | | public int dex { get; set; } |
| | | public string code { get; set; } |
| | | public string name { get; set; } |
| | | } |
| | | |
| | | public class AlertorDeviceInfo |
| | | { |
| | | public int deviceNo { get; set; } |
| | | public string address { get; set; } |
| | | public string turnLight { get; set; } |
| | | public string offLight { get; set; } |
| | | } |
| | | |
| | | public class deviceInfo |
| | | { |
| | | public string address { get; set; } |
| | | public string deviceName { get; set; } |
| | | public string[] deviceNo { get; set; } |
| | | public string[] location { get; set; } |
| | | |
| | | public int deviceType { get; set; } |
| | | public int enable { get; set; } |
| | | } |
| | | public class TableName |
| | | { |
| | | public string name { get; set; } |
| | | public string code { get; set; } |
| | | } |
| | | |
| | | |
| | | } |
| | | } |
| | |
| | | |
| | | } |
| | | |
| | | internal static bool AddCntr(string cntrCode) |
| | | { |
| | | var res = false; |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | var TN_Container = new Container { S_CODE = cntrCode }; |
| | | try |
| | | { |
| | | res = db.Insertable<Container>(TN_Container).ExecuteCommand() > 0; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | LogHelper.Info($"添加容器错误,错误原因:{ex.Message}", "WMS"); |
| | | } |
| | | return res; |
| | | } |
| | | |
| | | internal static bool AddCntr(string cntrCode, string itemCode) { |
| | | var res = false; |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | |
| | | var list = db.Queryable<CntrItemRel>().Where(a => a.S_CNTR_CODE == cntr).ToList(); |
| | | return list; |
| | | } |
| | | internal static bool BindNewCntrItem(string loc,string cntrCode, string itemCode) { |
| | | var res = false; |
| | | var itemName = ItemHelper.GetItemInfo(itemCode).S_ITEM_NAME; |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | try { |
| | | db.BeginTran(); |
| | | var cntr = new Container { S_CODE = cntrCode, N_DETAIL_COUNT = 1 }; |
| | | db.Insertable(cntr).ExecuteCommand(); |
| | | //获取物料信息,填充到容器货品明细,方便人工查看 |
| | | var cir = new CntrItemRel { S_CNTR_CODE = cntr.S_CODE.Trim(), F_QTY = 1, S_ITEM_CODE = itemCode, S_ITEM_NAME = itemName }; |
| | | db.Insertable<CntrItemRel>(cir).ExecuteCommand(); |
| | | var lcr = new LocCntrRel { S_CNTR_CODE = cntrCode, S_LOC_CODE = loc }; |
| | | db.Insertable<LocCntrRel>(lcr).ExecuteCommand(); |
| | | db.CommitTran(); |
| | | res = true; |
| | | } |
| | | catch (Exception ex) { |
| | | db.RollbackTran(); |
| | | Console.WriteLine(ex.Message); |
| | | } |
| | | |
| | | return res; |
| | | } |
| | | /// <summary> |
| | | /// 物料信息绑定到满容器上 |
| | | /// </summary> |
| | | /// <param name="cntrCode"></param> |
| | | /// <param name="itemCode"></param> |
| | | /// <param name="batchNo"></param> |
| | | /// <param name="qty"></param> |
| | | /// <returns></returns> |
| | | internal static bool BindCntrItem(Container cntr, string itemCode, string batchNo, float qty, string putawayNo) { |
| | | var res = false; |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | try { |
| | | db.BeginTran(); |
| | | //1.查看是否有相同物料批次的信息,如果有要累加,不同批次的可以分开 |
| | | var cir = db.Queryable<CntrItemRel>().Where(a => a.S_CNTR_CODE == cntr.S_CODE && a.S_ITEM_CODE == itemCode && a.S_BATCH_NO == batchNo).First(); |
| | | if (cir != null) { |
| | | cir.F_QTY += qty; |
| | | db.Updateable(cir).UpdateColumns(it => new { it.F_QTY }).ExecuteCommand(); |
| | | } |
| | | else { |
| | | //2.插入新的容器物料信息(容器号不变) |
| | | cir = new CntrItemRel { S_CNTR_CODE = cntr.S_CODE.Trim(), S_BATCH_NO = batchNo, F_QTY = qty, S_ITEM_CODE = itemCode, S_PUTAWAY_NO = putawayNo }; |
| | | db.Insertable<CntrItemRel>(cir).ExecuteCommand(); |
| | | } |
| | | var count = db.Queryable<CntrItemRel>().Count(a => a.S_CNTR_CODE == cntr.S_CODE); |
| | | cntr.N_DETAIL_COUNT = count; |
| | | cntr.C_ENABLE = "N";//码盘后将托盘设置为不可用状态,入库后变成可用 |
| | | db.Updateable(cntr).UpdateColumns(it => new { it.N_DETAIL_COUNT, it.C_ENABLE, it.S_SRC }).ExecuteCommand(); |
| | | |
| | | db.CommitTran(); |
| | | res = true; |
| | | } |
| | | catch (Exception ex) { |
| | | db.RollbackTran(); |
| | | Console.WriteLine(ex.Message); |
| | | } |
| | | |
| | | return res; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 物料信息绑定到满容器上 |
| | | /// </summary> |
| | | /// <param name="cntrCode"></param> |
| | | /// <param name="itemCode"></param> |
| | | /// <param name="batchNo"></param> |
| | | /// <param name="qty"></param> |
| | | /// <param name="purpose">容器用途,用于哪个线边还是目的点</param> |
| | | /// <returns></returns> |
| | | internal static bool BindCntrItemSingle(Container cntr, string itemCode, string batchNo, float qty) { |
| | | var res = false; |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | try { |
| | | db.BeginTran(); |
| | | db.Updateable(cntr).UpdateColumns(it => new { it.S_DEST }).ExecuteCommand(); |
| | | //1.将原有容器物料信息删除 |
| | | db.Deleteable<CntrItemRel>().Where(it => it.S_CNTR_CODE == cntr.S_CODE.Trim()).ExecuteCommand(); |
| | | //2.插入新的容器物料信息(容器号不变) |
| | | var cir = new CntrItemRel { S_CNTR_CODE = cntr.S_CODE.Trim(), S_BATCH_NO = batchNo, F_QTY = qty, S_ITEM_CODE = itemCode }; |
| | | db.Insertable<CntrItemRel>(cir).ExecuteCommand(); |
| | | |
| | | db.CommitTran(); |
| | | res = true; |
| | | } |
| | | catch (Exception ex) { |
| | | db.RollbackTran(); |
| | | } |
| | | |
| | | return res; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 根据容器来源和状态获取托盘 |
| | | /// </summary> |
| | |
| | | return db.Queryable<Container>().Where(a => a.S_SRC == src && a.N_B_STATE == state && a.S_TYPE == cntrType).ToList(); |
| | | } |
| | | } |
| | | /// <summary> |
| | | /// enable 让托盘允许被出库计算到,同时增加量表数据 |
| | | /// </summary> |
| | | /// <param name="cntr"></param> |
| | | internal static void Enable(string cntr, string loc) { |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | var cntrInfo = db.Queryable<Container>().Where(a => a.S_CODE == cntr).First(); |
| | | //获取仓库量表 |
| | | //获取物理库区 |
| | | //获取逻辑库区 |
| | | if (cntrInfo != null) { |
| | | try { |
| | | db.BeginTran(); |
| | | //防止接口重复调用,量表重复增加 |
| | | if (cntrInfo.C_ENABLE == "N") { |
| | | cntrInfo.C_ENABLE = "Y"; |
| | | db.Updateable(cntrInfo).UpdateColumns(a => new { a.C_ENABLE, a.T_MODIFY }).ExecuteCommand(); |
| | | var cirList = db.Queryable<CntrItemRel>().Where(a => a.S_CNTR_CODE == cntr).ToList(); |
| | | if (cirList.Count > 0) { |
| | | cirList.ForEach(a => { |
| | | var wh = db.Queryable<WHInventory>().Where(b => b.S_ITEM_CODE == a.S_ITEM_CODE).First(); |
| | | if (wh != null) { |
| | | //更新仓库量表 |
| | | wh.F_QTY += a.F_QTY; |
| | | wh.T_MODIFY = DateTime.Now; |
| | | db.Updateable(wh).UpdateColumns(it => new { it.F_QTY, it.T_MODIFY }).ExecuteCommand(); |
| | | } |
| | | else { |
| | | //新增仓库量表 |
| | | wh = new WHInventory { F_QTY = a.F_QTY, S_ITEM_CODE = a.S_ITEM_CODE }; |
| | | db.Insertable(wh).ExecuteCommand(); |
| | | } |
| | | //写入第三方中间表 |
| | | var di = new DayuanIn |
| | | { |
| | | CN_S_ARRIVAL_NO = a.S_PUTAWAY_NO, |
| | | CN_F_QUANTITY = a.F_QTY, |
| | | CN_S_BATCH_NO = a.S_BATCH_NO, |
| | | CN_S_ITEM_CODE = a.S_ITEM_CODE, |
| | | }; |
| | | db.Insertable(di).ExecuteCommand(); |
| | | //如果要统计分拣中,分拣回的量,无法跟踪托盘,除非对托盘加标识,属于哪个库区。 |
| | | //另外分拣回可能去别的巷道,别的逻辑库区,逻辑库区的量控制更复杂,不能计算分拣中和分拣回。所以库区量表本项目暂不考虑 |
| | | /* |
| | | //获取货位的物理库区和所有逻辑库区 |
| | | var location = db.Queryable<Location>().Where(l => l.S_CODE == loc).First(); |
| | | if (location != null) { |
| | | var az = db.Queryable<AZInventory>().Where(b => b.S_ITEM_CODE == a.S_ITEM_CODE && b.S_AREA_CODE == location.S_AREA_CODE).First(); |
| | | if (az != null) { |
| | | //更新库区量表 |
| | | az.F_QTY += a.F_QTY; |
| | | az.T_MODIFY = DateTime.Now; |
| | | db.Updateable(az).UpdateColumns(it => new { it.F_QTY, it.T_MODIFY }).ExecuteCommand(); |
| | | } |
| | | else { |
| | | //新增库区量表 |
| | | az = new AZInventory { F_QTY = a.F_QTY, S_ITEM_CODE = a.S_ITEM_CODE, S_AREA_CODE = location.S_AREA_CODE }; |
| | | db.Insertable(az).ExecuteCommand(); |
| | | } |
| | | |
| | | } |
| | | //逻辑库区的量表 |
| | | var zoneList = db.Queryable<ZoneLoc>().Where(l => l.S_LOC_CODE == loc).ToList(); |
| | | if (zoneList.Count > 0) { |
| | | zoneList.ForEach(z => { |
| | | var az = db.Queryable<AZInventory>().Where(b => b.S_ITEM_CODE == a.S_ITEM_CODE && b.S_AREA_CODE == z.S_ZONE_CODE).First(); |
| | | if (az != null) { |
| | | //更新库区量表 |
| | | az.F_QTY += a.F_QTY; |
| | | az.T_MODIFY = DateTime.Now; |
| | | db.Updateable(az).UpdateColumns(it => new { it.F_QTY, it.T_MODIFY }).ExecuteCommand(); |
| | | } |
| | | else { |
| | | //新增库区量表 |
| | | az = new AZInventory { F_QTY = a.F_QTY, S_ITEM_CODE = a.S_ITEM_CODE, S_AREA_CODE = z.S_ZONE_CODE, C_IS_LOGIC_AREA = "Y" }; |
| | | db.Insertable(az).ExecuteCommand(); |
| | | } |
| | | }); |
| | | } |
| | | */ |
| | | |
| | | }); |
| | | } |
| | | } |
| | | db.CommitTran(); |
| | | } |
| | | catch (Exception ex) { |
| | | Console.WriteLine(ex.Message); |
| | | db.RollbackTran(); |
| | | |
| | | } |
| | | } |
| | | } |
| | | |
| | | } |
| | | } |
| | |
| | | db.Updateable(task).UpdateColumns(it => new {it.N_B_STATE, it.S_B_STATE,it.T_MODIFY ,it.S_EQ_NO }).ExecuteCommand(); |
| | | return res; |
| | | } |
| | | |
| | | public static bool updateTaskEnd(WCSTask task) |
| | | { |
| | | var res = false; |
| | | var db = new SqlHelper<WCSTask>().GetInstance(); |
| | | res = db.Updateable(task).UpdateColumns(it => new { it.S_END_LOC, it.S_END_AREA, it.T_MODIFY}).ExecuteCommand() > 0; |
| | | return res; |
| | | } |
| | | |
| | | internal static bool UpdateInfo(WCSTask task, string sourceNo, string endBit, string status) { |
| | | var res = false; |
| | | var db = new SqlHelper<WCSTask>().GetInstance(); |
| | |
| | | using HH.WCS.Mobox3.YNJT_PT.api; |
| | | using HH.WCS.Mobox3.YNJT_BZP_PT.models; |
| | | using HH.WCS.Mobox3.YNJT_PT.api; |
| | | using HH.WCS.Mobox3.YNJT_PT.models; |
| | | using HH.WCS.Mobox3.YNJT_PT.models.other; |
| | | using HH.WCS.Mobox3.YNJT_PT.util; |
| | | using Newtonsoft.Json; |
| | | using NLog.Fluent; |
| | | using SqlSugar; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | |
| | | var date = DateTime.Now.ToString("yyMMdd"); |
| | | return $"OP{date}{id.ToString().PadLeft(4, '0')}"; |
| | | } |
| | | internal static string GenerateSortingNo() { |
| | | var id = SYSHelper.GetSerialNumber("分拣单", "SO"); |
| | | internal static string GenerateTaskGroupNo() { |
| | | var id = SYSHelper.GetSerialNumber("任务组", "GP"); |
| | | var date = DateTime.Now.ToString("yyMMdd"); |
| | | return $"SO{date}{id.ToString().PadLeft(4, '0')}"; |
| | | return $"GP{date}{id.ToString().PadLeft(4, '0')}"; |
| | | } |
| | | internal static List<WMSTask> GetOperationListByState(string state) { |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | |
| | | return result; |
| | | } |
| | | |
| | | internal static bool CreateSortingOrder(List<string> list) { |
| | | var res = false; |
| | | //遍历获取发货单,然后判断库存,如果全都没库存,则不生成分拣单,如果有生成分拣单 |
| | | //更新波次单,即使只有一个发货单也更新波次单 |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | var sortingOrderNo = ""; |
| | | SortingOrder sortingOrder = null; |
| | | try { |
| | | db.BeginTran(); |
| | | list.ForEach(a => { |
| | | var so = db.Queryable<ShippingOrder>().Includes(s => s.Details).Where(s => s.S_NO == a).First(); |
| | | //判断库存,只有已经入库的才可以计算,码盘的不算,入库后出库途中的也要计算,码盘后默认叫待入库,入库后叫正常 |
| | | //生成出库任务,只有托盘位置在立库才需要创建出库任务(先写死立库) |
| | | //只有全部分拣完成才允许回库(一个托盘可能对应多个分拣明细) |
| | | |
| | | |
| | | //查找仓库量表和库区量表,出库单需要定位仓库和库区了,出库定位物理库区就行,入库可能物料库区还要区分逻辑库区 |
| | | |
| | | //暂时只查仓库量表(量表如何重置,查找所有查找C_ENABLE=N的,判断如果在仓库中,改成Y,然后统计) |
| | | |
| | | //生成分拣单时候增加仓库量表分配量,生成分拣单明细时候,增加库区量表分配量 |
| | | if (so != null && so.Details.Count > 0) { |
| | | var fail = true; |
| | | for (int i = 0; i < so.Details.Count; i++) { |
| | | var whi = db.Queryable<WHInventory>().Where(w => w.S_ITEM_CODE == so.Details[i].S_ITEM_CODE).First(); |
| | | if (whi != null && whi.F_QTY - whi.F_ALLOC_QTY > 0) { |
| | | //有货就出 |
| | | float qty = whi.F_QTY - whi.F_ALLOC_QTY > so.Details[i].F_QTY ? so.Details[i].F_QTY : whi.F_QTY - whi.F_ALLOC_QTY; |
| | | fail = false; |
| | | //有可用库存,生成分拣单 |
| | | if (sortingOrderNo == "") { |
| | | sortingOrderNo = GenerateSortingNo(); |
| | | sortingOrder = new SortingOrder |
| | | { |
| | | S_NO = sortingOrderNo, |
| | | S_SHIPPING_NO = so.S_NO, |
| | | Composes = new List<SortingCompose>() |
| | | }; |
| | | //创建分拣单 |
| | | db.Insertable(sortingOrder).ExecuteCommand(); |
| | | } |
| | | else { |
| | | //获取最新分拣单 |
| | | sortingOrder = db.Queryable<SortingOrder>().Includes(s => s.Composes).Where(s => s.S_NO == sortingOrderNo).First(); |
| | | //更新分拣单中的发货单单号 |
| | | sortingOrder.S_SHIPPING_NO = sortingOrder.S_SHIPPING_NO + ";" + so.S_NO; |
| | | sortingOrder.T_MODIFY = DateTime.Now; |
| | | db.Updateable(sortingOrder).UpdateColumns(it => new { it.S_SHIPPING_NO, it.T_MODIFY }).ExecuteCommand(); |
| | | } |
| | | //查询分拣单子表(正常情况还需要增加批次判断) |
| | | var soc = db.Queryable<SortingCompose>().Where(s => s.S_ITEM_CODE == so.Details[i].S_ITEM_CODE && s.S_SORTING_NO == sortingOrder.S_NO).First(); |
| | | if (soc == null) { |
| | | soc = new SortingCompose |
| | | { |
| | | S_ITEM_CODE = so.Details[i].S_ITEM_CODE, |
| | | S_SORTING_NO = sortingOrder.S_NO, |
| | | F_QTY = qty, |
| | | N_ROW_NO = sortingOrder.Composes.Count() + 1, |
| | | S_BATCH_NO = so.Details[i].S_BATCH_NO |
| | | }; |
| | | |
| | | //创建分拣单子表 |
| | | db.Insertable(soc).ExecuteCommand(); |
| | | } |
| | | else { |
| | | soc.F_QTY += qty; |
| | | soc.T_MODIFY = DateTime.Now; |
| | | //更新分拣单子表 |
| | | db.Updateable(soc).UpdateColumns(it => new { it.F_QTY, it.T_MODIFY }).ExecuteCommand(); |
| | | } |
| | | //更新仓库量表分配量 |
| | | whi.F_ALLOC_QTY += qty; |
| | | whi.T_MODIFY = DateTime.Now; |
| | | db.Updateable(whi).UpdateColumns(it => new { it.F_ALLOC_QTY, it.T_MODIFY }).ExecuteCommand(); |
| | | //跟新发货单子表配货数量 |
| | | so.Details[i].F_ACC_D_QTY += qty; |
| | | so.Details[i].T_MODIFY = DateTime.Now; |
| | | db.Updateable(so.Details[i]).UpdateColumns(it => new { it.F_ACC_D_QTY, it.T_MODIFY }).ExecuteCommand(); |
| | | } |
| | | |
| | | } |
| | | //更新发货单状态 |
| | | so.N_B_STATE = fail ? 5 : 1; |
| | | if (fail) { |
| | | so.S_NOTE = "没有库存"; |
| | | } |
| | | so.S_WAVE_CODE = sortingOrderNo; |
| | | so.T_MODIFY = DateTime.Now; |
| | | db.Updateable(so).UpdateColumns(it => new { it.N_B_STATE, it.T_MODIFY, it.S_WAVE_CODE, it.S_NOTE }).ExecuteCommand(); |
| | | |
| | | } |
| | | |
| | | |
| | | //查找库区内托盘生成托盘明细(包括分拣中)怎么判断库内?查找货位绑定?还是托盘上加标识比较好,如果是整托出的,分拣确认后去掉分拣标识。 |
| | | //1、只有码盘入库后的才需要加标识,分拣回的不用,分拣回的标识还在,没有变。写死码盘入的完成后加标识,整托分拣的去掉标识,防止后面重新码盘脏数据 |
| | | //2、或者关联查询库内的,只给分拣出的加标识,每次分拣回再把标识清除了(如果不清除带标识的会很多,还不如全部加标识),整托的清除。 |
| | | //综合选择还是方案1,这样创建分拣明细,只需要托盘物料两表查询就能定位托盘(如果信息不准,可以重置),方案2需要货位、托盘、物料三表联查 |
| | | |
| | | //暂时不计库区,标识用容器表 C_ENABLE 来判断,表示能不能出库 |
| | | |
| | | //执行分拣创建任务,遍历分拣明细中的托盘,如果在仓库就出库,如果不在就不用出库 |
| | | |
| | | |
| | | }); |
| | | //全部分拣单生成之后将分拣单状态设置为开始配货,波次号为发货单 |
| | | sortingOrder = db.Queryable<SortingOrder>().Where(s => s.S_NO == sortingOrderNo).First(); |
| | | sortingOrder.N_B_STATE = 1; |
| | | sortingOrder.T_MODIFY = DateTime.Now; |
| | | db.Updateable(sortingOrder).UpdateColumns(it => new { it.N_B_STATE, it.T_MODIFY }).ExecuteCommand(); |
| | | db.CommitTran(); |
| | | res = true; |
| | | } |
| | | catch (Exception ex) { |
| | | Console.WriteLine(ex.Message); |
| | | db.RollbackTran(); |
| | | } |
| | | return res; |
| | | |
| | | } |
| | | |
| | | internal static List<SortingDetail> GetSortingDetailByCntr(string cntr) { |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | var result = db.Queryable<SortingDetail>().Where(a => a.S_CNTR_CODE == cntr && a.N_B_STATE != 2).ToList(); |
| | | return result; |
| | | } |
| | | |
| | | |
| | | internal static bool CreateWmsTask(WMSTask wmsTask) { |
| | | try { |
| | |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | return db.Queryable<WMSTask>().Where(a => a.S_CODE == code).First(); |
| | | } |
| | | /* |
| | | internal static void CreateSortingOrderDetail(string so_no) { |
| | | //分拣单配货 |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | var so = db.Queryable<SortingOrder>().Includes(a => a.Composes).Where(a => a.S_NO == so_no && (a.N_B_STATE == 1 || a.N_B_STATE == 20)).First();// |
| | | if (so != null && so.Composes.Count > 0) { |
| | | db.BeginTran(); |
| | | try { |
| | | int rowNo = 1; |
| | | so.Composes.ForEach(a => { |
| | | //按分拣单子表去配货,查找可用托盘(先查所有符合的,后面再优化) |
| | | var cirList = db.Queryable<CntrItemRel>().Includes(c => c.Cntr).Where(c => c.Cntr.C_ENABLE == "Y" && c.S_ITEM_CODE == a.S_ITEM_CODE && (c.F_QTY - c.F_ALLOC_QTY) > 0).OrderBy(c => c.T_CREATE).ToList(); |
| | | for (int i = 0; i < cirList.Count; i++) { |
| | | var cir = cirList[i]; |
| | | var sd = new SortingDetail |
| | | { |
| | | N_ROW_NO = rowNo, |
| | | S_BATCH_NO = a.S_BATCH_NO, |
| | | S_ITEM_CODE = a.S_ITEM_CODE, |
| | | S_CNTR_CODE = cir.S_CNTR_CODE, |
| | | S_SORTING_NO = a.S_SORTING_NO |
| | | }; |
| | | bool needBreak = false; |
| | | if (cir.F_QTY - cir.F_ALLOC_QTY >= (a.F_QTY - a.F_ACC_S_QTY)) { |
| | | //容器可用数量大于分拣单子表要求的数量,生成分拣明细,然后跳出循环 |
| | | sd.F_QTY = a.F_QTY - a.F_ACC_S_QTY; |
| | | needBreak = true; |
| | | } |
| | | else { |
| | | //生成分拣明细,继续创建 |
| | | sd.F_QTY = cir.F_QTY - cir.F_ALLOC_QTY; |
| | | } |
| | | db.Insertable(sd).ExecuteCommand(); |
| | | rowNo++; |
| | | //更新容器货品表分配量 |
| | | cir.F_ALLOC_QTY += sd.F_QTY; |
| | | cir.T_MODIFY = DateTime.Now; |
| | | db.Updateable(cir).UpdateColumns(it => new { it.F_ALLOC_QTY, it.T_MODIFY }).ExecuteCommand(); |
| | | //更新分拣单子表的量 |
| | | a.F_ACC_S_QTY += sd.F_QTY; |
| | | a.T_MODIFY = DateTime.Now; |
| | | db.Updateable(cir).UpdateColumns(it => new { it.F_ALLOC_QTY, it.T_MODIFY }).ExecuteCommand(); |
| | | if (needBreak) { |
| | | break; |
| | | } |
| | | } |
| | | }); |
| | | //全部分拣单子表生成分拣明细,修改分拣单状态为配货完成(反正仓库的货能配的都配完了,除非数据有异常) |
| | | so.N_B_STATE = 2; |
| | | so.T_MODIFY = DateTime.Now; |
| | | db.Updateable(so).UpdateColumns(it => new { it.N_B_STATE, it.T_MODIFY }).ExecuteCommand(); |
| | | db.CommitTran(); |
| | | } |
| | | catch (Exception ex) { |
| | | Console.WriteLine(ex.Message); |
| | | db.RollbackTran(); |
| | | } |
| | | } |
| | | } |
| | | */ |
| | | /// <summary> |
| | | /// 获取开始配货的分拣单,一次性生成分拣明细,避免生成一半再生成,所以创建分拣明细的时候加上事务 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | internal static List<SortingOrder> GetWaitingSortingOrderList() { |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | return db.Queryable<SortingOrder>().Includes(a => a.Composes).Where(a => a.N_B_STATE == 1 || a.N_B_STATE == 20).ToList(); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 获取配货完成的分拣单,每个分拣单单独创建分拣作业 |
| | | /// </summary> |
| | |
| | | return result; |
| | | } |
| | | |
| | | public static Location GetLocation4InEmptyRow() |
| | | |
| | | // ----------------------------------------------- 印尼佳通 - 硫化-------------------------------------------- |
| | | |
| | | /// <summary> |
| | | /// 添加成型机下线记录 |
| | | /// </summary> |
| | | /// <param name="record"></param> |
| | | /// <returns></returns> |
| | | public static bool addOffLineRecord(OffLineRecord record) |
| | | { |
| | | Location result = null; |
| | | try |
| | | { |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | |
| | | #region 查找所有数量是空的排 |
| | | //Console.WriteLine("查找所有数量是空的排"); |
| | | //2.0 简化查询只查每一排第一列 |
| | | var list = db.Queryable<Location>().OrderBy(a => a.N_COL).Take(1).PartitionBy(a => a.N_ROW).ToList().Where(a => a.N_CURRENT_NUM == 0).ToList(); |
| | | //2.1 选一个空排 |
| | | for (int i = 0; i < list.Count; i++) |
| | | { |
| | | var other = db.Queryable<Location>().Where(a => a.S_AREA_CODE == list[i].S_AREA_CODE && a.N_ROW == list[i].N_ROW && a.S_LOCK_STATE != "无").First(); |
| | | if (list[i].N_LOCK_STATE == 0 && other == null) |
| | | { |
| | | //二次校验当前排所有货位都是空的,防止系统数据错乱 |
| | | var rowSumInfo = db.Queryable<Location>().Where(l => l.S_AREA_CODE == list[i].S_AREA_CODE && l.N_ROW == list[i].N_ROW && l.N_CURRENT_NUM != 0).Count(); |
| | | if (rowSumInfo == 0) |
| | | { |
| | | result = list[i]; |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | #endregion |
| | | |
| | | if (result != null && (!string.IsNullOrEmpty(result.C_ENABLE) && (result.C_ENABLE == "禁用" || result.C_ENABLE == "N"))) |
| | | { |
| | | //禁用了选择后面一个货位 |
| | | Console.WriteLine("禁用了选择后面一个货位"); |
| | | result = db.Queryable<Location>().OrderBy(a => a.N_COL).Where(a => a.S_AREA_CODE == result.S_AREA_CODE && a.N_ROW == result.N_ROW && (string.IsNullOrEmpty(a.C_ENABLE) || (a.C_ENABLE != "禁用" && a.C_ENABLE != "N")) && a.N_COL > result.N_COL).First(); |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | |
| | | LogHelper.Error("GetLocation4InEmptyRow:" + ex.Message, ex); |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | internal static Location GetInstockEnd(string item) |
| | | { |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | Location end = null; |
| | | // 查询相同物料的排是否有可放货的库位 |
| | | var listMaxCol = db.Queryable<Location>() |
| | | .LeftJoin<LocCntrRel>((l, lc) => l.S_CODE == lc.S_LOC_CODE) |
| | | .LeftJoin<CntrItemRel>((l, lc, ci) => lc.S_CNTR_CODE == ci.S_CNTR_CODE) |
| | | .Where((l, lc, ci) => l.N_CURRENT_NUM > 0 && ci.S_ITEM_CODE == item && l.S_AREA_CODE != Settings.BufferArea) |
| | | .OrderByDescending((l, lc, ci) => l.N_COL).Take(1).PartitionBy((l, lc, ci) => l.N_ROW).ToList(); |
| | | |
| | | foreach (var loc in listMaxCol) |
| | | { |
| | | //排有锁也排除 |
| | | var other = db.Queryable<Location>().Where(a => a.S_AREA_CODE == loc.S_AREA_CODE && a.N_ROW == loc.N_ROW && a.S_LOCK_STATE != "无" && a.N_LOCK_STATE != 0).First(); |
| | | if (other != null) |
| | | { |
| | | continue; |
| | | } |
| | | |
| | | end = db.Queryable<Location>().OrderBy(a => a.N_COL).Where(a => a.S_AREA_CODE == loc.S_AREA_CODE && a.N_ROW == loc.N_ROW && a.N_CURRENT_NUM < a.N_CAPACITY && (string.IsNullOrEmpty(a.C_ENABLE) || (a.C_ENABLE != "禁用" && a.C_ENABLE != "N")) && a.N_COL >= loc.N_COL).First(); |
| | | if (end != null) { |
| | | return end; |
| | | } |
| | | } |
| | | // 如果没有,则随机放空的排 |
| | | if (end == null) { |
| | | end = GetLocation4InEmptyRow(); |
| | | } |
| | | return end; |
| | | } |
| | | |
| | | public static Location GetShiftStockStart(string area ,int row) |
| | | { |
| | | Location result = null; |
| | | try |
| | | { |
| | | // 1、查询当前库区-排-物料 有托盘的货位 |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | result = db.Queryable<Location>() |
| | | .Where(l => l.N_CURRENT_NUM > 0 && l.S_AREA_CODE == area && l.N_ROW == row && l.N_LOCK_STATE == 0 && (l.C_ENABLE != "禁用" && l.C_ENABLE != "N")) |
| | | .Includes(l => l.LocCntrRel, l => l.CntrItemRel) |
| | | .OrderByDescending(l => l.N_COL) |
| | | .First(); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | LogHelper.Error("GetShiftStockStart:" + ex.Message, ex); |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | public static Location GetShiftStockStart(string area) |
| | | { |
| | | Location result = null; |
| | | try |
| | | { |
| | | // 1、查询当前库区-排-物料 有托盘的货位 |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | var listMaxCol = db.Queryable<Location>() |
| | | .Where(l => l.N_CURRENT_NUM > 0 && l.S_AREA_CODE == area) |
| | | .Includes(l => l.LocCntrRel, l => l.CntrItemRel) |
| | | .OrderByDescending(l => l.N_COL) |
| | | .Take(1) |
| | | .PartitionBy(l => l.N_ROW) |
| | | .ToList(); |
| | | |
| | | foreach (var loc in listMaxCol) |
| | | { |
| | | //排有锁也排除 |
| | | var other = db.Queryable<Location>().Where(a => a.S_AREA_CODE == loc.S_AREA_CODE && a.N_ROW == loc.N_ROW && a.S_LOCK_STATE != "无" && a.N_LOCK_STATE != 0).First(); |
| | | if (other != null) |
| | | { |
| | | continue; |
| | | } |
| | | return loc; |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | LogHelper.Error("GetShiftStockStart:" + ex.Message, ex); |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | public static bool isRowLock(Location location) { |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | return db.Queryable<Location>().Where(a => a.S_AREA_CODE == location.S_AREA_CODE && a.N_ROW == location.N_ROW && a.S_LOCK_STATE != "无" && a.N_LOCK_STATE != 0).Count() > 0; |
| | | } |
| | | |
| | | public static Location GetShiftStockEnd(string area, int row) |
| | | { |
| | | Location result = null; |
| | | |
| | | try |
| | | { |
| | | //1.0 获取每一排最大的列 |
| | | //1.1 判断当前数量是不是满的,如果是满的并且是最大列,需要排除 |
| | | var listMaxCol = new SqlHelper<Location>().GetInstance().Queryable<Location>().Where(a => a.S_AREA_CODE == area && a.N_ROW == row).OrderByDescending(a => a.N_COL).Take(1).PartitionBy(a => a.N_ROW).ToList(); |
| | | //1.1 查到所有有托盘的排 |
| | | Console.WriteLine("查到所有有托盘的排 "); |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | var list = db.Queryable<Location>().Where(a => a.N_CURRENT_NUM > 0 && a.S_AREA_CODE == area && a.N_ROW == row).Includes(a => a.LocCntrRel, a => a.CntrItemRel).OrderByDescending(a => a.N_COL).Take(1).PartitionBy(a => a.N_ROW).ToList(); |
| | | if (list.Count > 0) |
| | | { |
| | | //1.2 查找其它尺寸有托盘或者锁定的排 |
| | | for (int i = list.Count - 1; i >= 0; i--) |
| | | { |
| | | //排除已经锁定的货位 和 放满了且是最大列的货位 |
| | | if (list[i].N_LOCK_STATE != 0 || (list[i].N_CURRENT_NUM == list[i].N_CAPACITY && listMaxCol.Count(a => a.S_CODE == list[i].S_CODE) > 0)) |
| | | { |
| | | Console.WriteLine($"排除已经锁定的货位 和 放满了且是最大列的货位 排{list[i].N_ROW}"); |
| | | list.Remove(list[i]); |
| | | } |
| | | else |
| | | { |
| | | //排有锁也排除 |
| | | var other = db.Queryable<Location>().Where(a => a.S_AREA_CODE == area && a.N_ROW == list[i].N_ROW && a.S_LOCK_STATE != "无" && a.N_LOCK_STATE != 0).First(); |
| | | if (other != null) |
| | | { |
| | | Console.WriteLine($"排除有锁的排{list[i].N_ROW}"); |
| | | list.Remove(list[i]); |
| | | } |
| | | } |
| | | } |
| | | Console.WriteLine($"有托盘排数为{list.Count}"); |
| | | if (list.Count > 0) |
| | | { |
| | | |
| | | //1.3 遍历判断物料类型是否相同 |
| | | Console.WriteLine("遍历判断物料类型是否相同"); |
| | | for (int i = 0; i < list.Count; i++) |
| | | { |
| | | //todo 还需要判断锁 |
| | | if (list[i].LocCntrRel != null && list[i].LocCntrRel.CntrItemRel != null) |
| | | { |
| | | if (list[i].N_CURRENT_NUM < list[i].N_CAPACITY) |
| | | { |
| | | result = list[i]; |
| | | } |
| | | else |
| | | { |
| | | Console.WriteLine("选择后面空位"); |
| | | result = db.Queryable<Location>().Where(a => a.S_AREA_CODE == area && a.N_ROW == list[i].N_ROW && a.N_COL > list[i].N_COL && a.C_ENABLE == "Y").OrderBy(a => a.N_COL).First(); |
| | | } |
| | | |
| | | if (result != null) |
| | | { |
| | | break; |
| | | } |
| | | } |
| | | |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (result == null) |
| | | { |
| | | #region 查找所有数量是空的排 |
| | | //Console.WriteLine("查找所有数量是空的排"); |
| | | //2.0 简化查询只查每一排第一列 |
| | | list = db.Queryable<Location>().Where(a => a.S_AREA_CODE == area && a.N_ROW == row).OrderBy(a => a.N_COL).Take(1).PartitionBy(a => a.N_ROW).ToList().Where(a => a.N_CURRENT_NUM == 0).ToList(); |
| | | //2.1 选一个空排 |
| | | for (int i = 0; i < list.Count; i++) |
| | | { |
| | | var other = db.Queryable<Location>().Where(a => a.S_AREA_CODE == area && a.N_ROW == list[i].N_ROW && a.S_LOCK_STATE != "无").First(); |
| | | if (list[i].N_LOCK_STATE == 0 && other == null) |
| | | { |
| | | //二次校验当前排所有货位都是空的,防止系统数据错乱 |
| | | var rowSumInfo = db.Queryable<Location>().Where(l => l.S_AREA_CODE == area && l.N_ROW == list[i].N_ROW && l.N_CURRENT_NUM != 0).Count(); |
| | | if (rowSumInfo == 0) |
| | | { |
| | | result = list[i]; |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | #endregion |
| | | } |
| | | |
| | | if (result != null && (!string.IsNullOrEmpty(result.C_ENABLE) && (result.C_ENABLE == "禁用" || result.C_ENABLE == "N"))) |
| | | { |
| | | //禁用了选择后面一个货位 |
| | | //Console.WriteLine("禁用了选择后面一个货位"); |
| | | result = db.Queryable<Location>().OrderBy(a => a.N_COL).Where(a => a.S_AREA_CODE == area && a.N_ROW == result.N_ROW && (string.IsNullOrEmpty(a.C_ENABLE) || (a.C_ENABLE != "禁用" && a.C_ENABLE != "N")) && a.N_COL > result.N_COL).First(); |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | LogHelper.Error("GetLocation4InFinish:" + ex.Message, ex); |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | |
| | | public static List<Location> GetLocationList(string area , int row) { |
| | | List<Location> result = new List<Location> (); |
| | | try { |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | result = db.Queryable<Location>().Where(a => a.S_AREA_CODE == area && a.N_ROW == row).Includes(a => a.LocCntrRel, a => a.CntrItemRel).ToList(); |
| | | } |
| | | catch (Exception ex) { |
| | | LogHelper.Error("GetLocationList:" + ex.Message, ex); |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | public static List<TN_YiKuDetail> getShiftOrderDetail(string orderNo = null) { |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | List<TN_YiKuDetail> details = new List<TN_YiKuDetail>(); |
| | | var orderList = db.Queryable<TN_YiKuOrder>().Where(a => a.S_B_STATE == "执行").ToList(); |
| | | foreach (var order in orderList) |
| | | { |
| | | var detail = db.Queryable<TN_YiKuDetail>().Where(a => order.S_NO == a.S_NO).First(); |
| | | if (detail != null) |
| | | { |
| | | details.Add(detail); |
| | | } |
| | | } |
| | | return details; |
| | | } |
| | | |
| | | public static bool updateShiftOrderDetail(TN_YiKuDetail detail) { |
| | | bool result = false; |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | LogHelper.Info("移库完成数量变更参数:" + JsonConvert.SerializeObject(detail), "TSSG"); |
| | | result = db.Updateable<TN_YiKuDetail>() |
| | | .SetColumns(a => new TN_YiKuDetail() { N_COMPLETE_NUM = a.N_COMPLETE_NUM + 1 }) |
| | | .Where(a => a.S_NO == detail.S_NO |
| | | && a.S_START_AREA == detail.S_START_AREA |
| | | && a.S_START_ROW == detail.S_START_ROW |
| | | && a.S_END_AREA == detail.S_END_AREA |
| | | && a.S_END_ROW == detail.S_END_ROW |
| | | ) |
| | | .ExecuteCommand() > 0; |
| | | var offLineRecord = db.Queryable<OffLineRecord>().Where(a => a.S_RFID == record.S_RFID).First(); |
| | | if (offLineRecord != null) |
| | | { |
| | | offLineRecord.S_LOC = record.S_LOC; |
| | | offLineRecord.N_IS_URGENT = record.N_IS_URGENT; |
| | | offLineRecord.T_OFF_TIME = record.T_OFF_TIME; |
| | | offLineRecord.N_IS_FULL = record.N_IS_FULL; |
| | | result = db.Updateable(offLineRecord).ExecuteCommand() > 0; |
| | | } |
| | | else |
| | | { |
| | | result = db.Insertable(record).ExecuteCommand() > 0; |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | var completeResult = db.Queryable<TN_YiKuDetail>().Where(a => a.S_NO == detail.S_NO && a.N_QTY > a.N_COMPLETE_NUM).Count() == 0; |
| | | if(completeResult) { |
| | | result = db.Updateable<TN_YiKuOrder>().SetColumns(a => new TN_YiKuOrder() { S_B_STATE = "完成" }).Where(a => a.S_NO == detail.S_NO).ExecuteCommand() > 0; |
| | | /// <summary> |
| | | /// 查询成型机下线记录 |
| | | /// </summary> |
| | | /// <param name="rfid"></param> |
| | | /// <returns></returns> |
| | | public static OffLineRecord getOffLineRecord(string rfid) |
| | | { |
| | | OffLineRecord offLineRecord = null; |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | if (rfid != null) |
| | | { |
| | | offLineRecord = db.Queryable<OffLineRecord>().Where(a => a.S_RFID == rfid).First(); |
| | | } |
| | | return offLineRecord; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 查询物料条码信息 |
| | | /// </summary> |
| | | /// <param name="barcode"></param> |
| | | /// <returns></returns> |
| | | public static GreenTireInformation GetGreenTireInformation(string barcode) |
| | | { |
| | | GreenTireInformation greenTireInformation = null; |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | if (barcode != null) |
| | | { |
| | | greenTireInformation = db.Queryable<GreenTireInformation>().Where(a => a.BARCODE == barcode).First(); |
| | | } |
| | | return greenTireInformation; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 查询入库终点货位 |
| | | /// </summary> |
| | | /// <param name="itemCode"></param> |
| | | /// <param name="locNum">1.单货位 2.双货位</param> |
| | | /// <returns></returns> |
| | | public static List<Location> getInStockEndLoc(string itemCode, int locNum) |
| | | { |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | List<Location> locations = new List<Location>(); |
| | | // 1.按容积率从大到小,对巷道进行排序 |
| | | var roadwayOrderList = db.Queryable<Location>().Where(a => a.S_AREA_CODE == Settings.stockArea && a.N_CURRENT_NUM == 0 && a.N_LOCK_STATE == 0 && a.C_ENABLE == "Y") |
| | | .GroupBy(a => a.N_ROADWAY) |
| | | .Select(a => new { roadway = a.N_ROADWAY , num = SqlFunc.AggregateCount(a.S_CODE)}) |
| | | .OrderByDescending(a => a.num) |
| | | .ToList(); |
| | | |
| | | // 查询单货位 |
| | | if (locNum == 1) |
| | | { |
| | | foreach (var order in roadwayOrderList) |
| | | { |
| | | // 1. 查询1号货位是否有相同物料,有,则查询对应的2号货位是否为空 |
| | | var oneLocList = db.Queryable<Location>() |
| | | .LeftJoin<LocCntrRel>((a,b) => a.S_CODE == b.S_LOC_CODE) |
| | | .LeftJoin<CntrItemRel>((a,b,c) => b.S_CNTR_CODE == c.S_CNTR_CODE) |
| | | .Where((a, b, c) => a.S_AREA_CODE == Settings.stockArea |
| | | && a.N_ROADWAY == order.roadway |
| | | && a.N_COL % 2 == 1 |
| | | && a.N_CURRENT_NUM == 1 |
| | | && a.N_LOCK_STATE == 0 |
| | | && a.C_ENABLE == "Y" |
| | | && c.S_ITEM_CODE == itemCode |
| | | ) |
| | | .OrderBy(a => a.N_LAYER).OrderBy(a => a.N_COL) |
| | | .ToList(); |
| | | if (oneLocList.Count > 0) |
| | | { |
| | | foreach (var loc in oneLocList) |
| | | { |
| | | var twoLoc = db.Queryable<Location>().Where(a => a.S_AREA_CODE == Settings.stockArea && a.N_ROADWAY == order.roadway && a.N_ROW == loc.N_ROW && a.N_COL == loc.N_COL + 1 && a.N_LAYER == loc.N_LAYER && a.N_CURRENT_NUM == 0 && a.N_LOCK_STATE == 0 && a.C_ENABLE == "Y").First(); |
| | | if (twoLoc != null) |
| | | { |
| | | locations.Add(twoLoc); |
| | | return locations; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 2.查询2号货位是否有相同物料,有,则查询对应的1号位是否为空 |
| | | if (locations.Count == 0) |
| | | { |
| | | var twoLocList = db.Queryable<Location>() |
| | | .LeftJoin<LocCntrRel>((a, b) => a.S_CODE == b.S_LOC_CODE) |
| | | .LeftJoin<CntrItemRel>((a, b, c) => b.S_CNTR_CODE == c.S_CNTR_CODE) |
| | | .Where((a, b, c) => a.S_AREA_CODE == Settings.stockArea |
| | | && a.N_ROADWAY == order.roadway |
| | | && a.N_COL % 2 == 0 |
| | | && a.N_CURRENT_NUM == 1 |
| | | && a.N_LOCK_STATE == 0 |
| | | && a.C_ENABLE == "Y" |
| | | && c.S_ITEM_CODE == itemCode |
| | | ) |
| | | .OrderBy(a => a.N_LAYER).OrderBy(a => a.N_COL) |
| | | .ToList(); |
| | | |
| | | if (twoLocList.Count > 0) |
| | | { |
| | | foreach (var loc in twoLocList) |
| | | { |
| | | var oneLoc = db.Queryable<Location>().Where(a => a.S_AREA_CODE == Settings.stockArea && a.N_ROADWAY == order.roadway && a.N_ROW == loc.N_ROW && a.N_COL == loc.N_COL - 1 && a.N_LAYER == loc.N_LAYER && a.N_CURRENT_NUM == 0 && a.N_LOCK_STATE == 0 && a.C_ENABLE == "Y").First(); |
| | | if (oneLoc != null) |
| | | { |
| | | locations.Add(oneLoc); |
| | | return locations; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 3.没有相同物料的,优先放禁用货位旁边(单一货位) |
| | | if (locations.Count == 0) |
| | | { |
| | | var disableLocList= db.Queryable<Location>().Where(a => a.S_AREA_CODE == Settings.stockArea && a.N_ROADWAY == order.roadway && a.C_ENABLE == "N").OrderBy(a => a.N_LAYER).ToList(); |
| | | foreach (var loc in disableLocList) |
| | | { |
| | | // 货位为1号位,则查询对应二号位是否为空 |
| | | if (loc.N_LAYER % 2 == 1) |
| | | { |
| | | var twoLoc = db.Queryable<Location>().Where(a => a.S_AREA_CODE == Settings.stockArea && a.N_ROADWAY == order.roadway && a.N_ROW == loc.N_ROW && a.N_COL == loc.N_COL + 1 && a.N_LAYER == loc.N_LAYER && a.N_CURRENT_NUM == 0 && a.N_LOCK_STATE == 0 && a.C_ENABLE == "Y").First(); |
| | | if (twoLoc != null) |
| | | { |
| | | locations.Add(twoLoc); |
| | | return locations; |
| | | } |
| | | } |
| | | |
| | | // 货位为2号位,则查询对应一号位是否为空 |
| | | if (loc.N_LAYER % 2 == 0) |
| | | { |
| | | var oneLoc = db.Queryable<Location>().Where(a => a.S_AREA_CODE == Settings.stockArea && a.N_ROADWAY == order.roadway && a.N_ROW == loc.N_ROW && a.N_COL == loc.N_COL - 1 && a.N_LAYER == loc.N_LAYER && a.N_CURRENT_NUM == 0 && a.N_LOCK_STATE == 0 && a.C_ENABLE == "Y").First(); |
| | | if (oneLoc != null) |
| | | { |
| | | locations.Add(oneLoc); |
| | | return locations; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 4.没有相同物料的,且禁用货位旁边没有空货位,则优先放1号位 |
| | | if (locations.Count == 0) |
| | | { |
| | | oneLocList = db.Queryable<Location>().Where(a => a.S_AREA_CODE == Settings.stockArea && a.N_ROADWAY == order.roadway && a.N_COL % 2 == 1 && a.N_CURRENT_NUM == 0 && a.N_LOCK_STATE == 0 && a.C_ENABLE == "Y").OrderBy(a => a.N_LAYER).OrderByDescending(a => a.N_COL).ToList(); |
| | | if (oneLocList.Count > 0) |
| | | { |
| | | locations.Add(oneLocList[0]); |
| | | return locations; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 查询双货位 |
| | | if (locNum == 2) |
| | | { |
| | | foreach (var order in roadwayOrderList) |
| | | { |
| | | var oneLocList = db.Queryable<Location>().Where( a => a.S_AREA_CODE == Settings.stockArea && a.N_ROADWAY == order.roadway && a.N_COL % 2 == 1 && a.N_CURRENT_NUM == 0 && a.N_LOCK_STATE == 0 && a.C_ENABLE == "Y").OrderBy(a => a.N_LAYER).OrderBy(a => a.N_COL).ToList(); |
| | | foreach (var loc in oneLocList) |
| | | { |
| | | var twoLoc = db.Queryable<Location>().Where(a => a.S_AREA_CODE == Settings.stockArea && a.N_ROADWAY == order.roadway && a.N_ROW == loc.N_ROW && a.N_COL == loc.N_COL + 1 && a.N_LAYER == loc.N_LAYER && a.N_CURRENT_NUM == 0 && a.N_LOCK_STATE == 0 && a.C_ENABLE == "Y").First(); |
| | | if (twoLoc != null) |
| | | { |
| | | locations.Add(loc); |
| | | locations.Add(twoLoc); |
| | | return locations; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | return locations; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 查询异常区空货位 |
| | | /// </summary> |
| | | /// <param name="areaCode"></param> |
| | | public static Location getAbnormalAreaEmptyLoc(string areaCode) |
| | | { |
| | | Location location = new Location(); |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | location = db.Queryable<Location>().Where(a => a.S_AREA_CODE == areaCode && a.N_CURRENT_NUM == 0 && a.C_ENABLE == "Y" && a.N_LOCK_STATE == 0).First(); |
| | | return location; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 查询巷道任务最少的接驳位 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | public static Location getMinTaskMiddleLoc(int type) |
| | | { |
| | | Location location = new Location(); |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | var roadwayGroup = db.Queryable<Location>() |
| | | .LeftJoin<WCSTask>((a,b) => a.S_CODE == b.S_END_LOC && b.N_B_STATE < 3) |
| | | .Where((a, b) => a.S_AREA_CODE == Settings.stockArea && b.S_CODE != null ) |
| | | .GroupBy((a, b) => a.N_ROADWAY) |
| | | .Select( (a, b) => new { roadway = a.N_ROADWAY , num = SqlFunc.AggregateDistinctCount(a.S_CODE)}) |
| | | .OrderBy(a => a.num) |
| | | .ToList(); |
| | | |
| | | foreach (var item in roadwayGroup) |
| | | { |
| | | // 1.查询巷道内的堆垛机状态是否正常 |
| | | |
| | | // 2.查询接驳位 |
| | | var connectLoc = Settings.connectLocList.Where(a => a.type == type && a.roadway == item.roadway).FirstOrDefault(); |
| | | if (connectLoc != null) |
| | | { |
| | | location = LocationHelper.GetLoc(connectLoc.locCode); |
| | | break; |
| | | } |
| | | } |
| | | return location; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 查询物料存放时间配置信息 |
| | | /// </summary> |
| | | /// <param name="bc_entried"></param> |
| | | /// <returns></returns> |
| | | public static Overage getOverage(string bc_entried) |
| | | { |
| | | |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | |
| | | // 直接执行 SQL(参数化查询) |
| | | var sql = "SELECT get_ovg_bar(@barcode, @mcngrp) AS overage_value"; |
| | | var sql1 = "SELECT get_minhour_bar(@barcode, @mcngrp) AS overage_value"; |
| | | |
| | | // 使用匿名对象传递参数 |
| | | var ovg_bar = db.Ado.SqlQuery<int>(sql, new { barcode = bc_entried, mcngrp = "0" }); |
| | | var minhour_bar = db.Ado.SqlQuery<float>(sql1, new { barcode = bc_entried, mcngrp = "0" }); |
| | | if (ovg_bar.Count > 0 && minhour_bar.Count > 0) |
| | | { |
| | | Overage overage = new Overage() |
| | | { |
| | | MINHOUR = minhour_bar[0], |
| | | OVERAGE = ovg_bar[0] |
| | | }; |
| | | return overage; |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | public static bool bindBarcodeItemInfo( string cntrCode,GreenTireInformation greenTireInformation) |
| | | { |
| | | bool result = false; |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | var cntrItemRel = db.Queryable<CntrItemRel>().Where(a => a.S_CNTR_CODE == cntrCode).First(); |
| | | if (cntrItemRel == null) |
| | | { |
| | | var overage = getOverage(greenTireInformation.BARCODE); |
| | | DateTime txndate = DateTime.Parse(greenTireInformation.TXNDATE); |
| | | DateTime minTime = txndate.AddHours(overage.MINHOUR); |
| | | DateTime maxTime = txndate.AddDays(overage.OVERAGE); |
| | | cntrItemRel = new CntrItemRel() |
| | | { |
| | | S_CG_ID = greenTireInformation.BARCODE, |
| | | S_ITEM_CODE = greenTireInformation.ITEMCODE, |
| | | S_CNTR_CODE = cntrCode, |
| | | S_CELL_NO = greenTireInformation.TIRECODE, |
| | | F_QTY = greenTireInformation.QTY, |
| | | S_MCN = greenTireInformation.MCN, |
| | | S_OPR = greenTireInformation.OPR, |
| | | S_OPR02 = greenTireInformation.OPR02, |
| | | S_OPR03 = greenTireInformation.OPR03, |
| | | S_OPR04 = greenTireInformation.OPR04, |
| | | S_WINDUP = greenTireInformation.WINDUP, |
| | | S_TXNDATE = greenTireInformation.TXNDATE, |
| | | S_DATE_SHIFT = greenTireInformation.DATE_SHIFT, |
| | | S_EFFECTIVE_TIME = minTime.ToString("yyyy-MM-dd HH:mm:ss"), |
| | | S_EXPIRATION_TIME = maxTime.ToString("yyyy-MM-dd HH:mm:ss"), |
| | | }; |
| | | result = db.Insertable(cntrItemRel).ExecuteCommand() > 0; |
| | | } |
| | | else |
| | | { |
| | | var overage = getOverage(greenTireInformation.BARCODE); |
| | | DateTime txndate = DateTime.Parse(greenTireInformation.TXNDATE); |
| | | DateTime minTime = txndate.AddHours(overage.MINHOUR); |
| | | DateTime maxTime = txndate.AddDays(overage.OVERAGE); |
| | | cntrItemRel.S_CG_ID = greenTireInformation.BARCODE; |
| | | cntrItemRel.S_ITEM_CODE = greenTireInformation.ITEMCODE; |
| | | cntrItemRel.S_CNTR_CODE = cntrCode; |
| | | cntrItemRel.S_CELL_NO = greenTireInformation.TIRECODE; |
| | | cntrItemRel.F_QTY = greenTireInformation.QTY; |
| | | cntrItemRel.S_MCN = greenTireInformation.MCN; |
| | | cntrItemRel.S_OPR = greenTireInformation.OPR; |
| | | cntrItemRel.S_OPR02 = greenTireInformation.OPR02; |
| | | cntrItemRel.S_OPR03 = greenTireInformation.OPR03; |
| | | cntrItemRel.S_OPR04 = greenTireInformation.OPR04; |
| | | cntrItemRel.S_WINDUP = greenTireInformation.WINDUP; |
| | | cntrItemRel.S_TXNDATE = greenTireInformation.TXNDATE; |
| | | cntrItemRel.S_DATE_SHIFT = greenTireInformation.DATE_SHIFT; |
| | | cntrItemRel.S_EFFECTIVE_TIME = minTime.ToString("yyyy-MM-dd HH:mm:ss"); |
| | | cntrItemRel.S_EXPIRATION_TIME = maxTime.ToString("yyyy-MM-dd HH:mm:ss"); |
| | | result = db.Updateable(cntrItemRel).ExecuteCommand() > 0; |
| | | } |
| | | return result; |
| | | } |