| | |
| | | List<Task> tasks = new List<Task>(); |
| | | // 添加任务推送线程 |
| | | tasks.Add(GetTask(WCSCore.Dispatch)); |
| | | // 监听MES任务,下发任务 |
| | | tasks.Add(GetTask(Monitor.MonitorMesTask)); |
| | | // 监听成型机叫料任务 |
| | | tasks.Add(GetTask(Monitor.MonitorCXJCallMaterialMesTask)); |
| | | // 监听钢包满料下线任务 |
| | | tasks.Add(GetTask(Monitor.MonitorGBOffLineMesTask)); |
| | | // 监听斜裁出库任务表 |
| | | tasks.Add(GetTask(Monitor.MonitorXcOutTask)); |
| | | // 自动补充空工装任务 |
| | |
| | | public static ResponseResult offLineProcess(OffLineRequest model) { |
| | | ResponseResult responseResult = new ResponseResult(); |
| | | |
| | | var areaCodes = Settings.areaPropertyList.Select(a => a.areaCode).ToList(); |
| | | var isExistCntr = LocationHelper.checkAreaExistCntr(areaCodes,model.cntrNo); |
| | | if (!isExistCntr) |
| | | { |
| | | // 查询起点货位是否存在已存在任务,防止任务重复发起 |
| | | var existWmsTask = WMSHelper.GetWmsTaskByStart(model.loc); |
| | | if (existWmsTask == null) |
| | |
| | | { |
| | | WMSHelper.addAlarmRecord("流程异常", "低", $"下线货位:{model.loc}已有任务,请勿重复下发任务"); |
| | | throw new BusinessException($"下线货位:{model.loc}已有任务,请勿重复下发任务"); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | WMSHelper.addAlarmRecord("流程异常", "高", $"工装:{model.cntrNo}已入库,请勿重复入库"); |
| | | throw new BusinessException($"工装:{model.cntrNo}已入库,请勿重复入库"); |
| | | } |
| | | return responseResult; |
| | | } |
| | |
| | | } |
| | | else |
| | | { |
| | | WMSHelper.addAlarmRecord("流程异常", "中", $"空工装出库站台:{logicConfig.S_LKKTJBLOC},没有空工装"); |
| | | photoStatus = false; |
| | | kgzCntrCode = "虚拟容器"; |
| | | WMSHelper.addAlarmRecord("流程异常", "低", $"空工装出库站台:{logicConfig.S_LKKTJBLOC},没有空工装"); |
| | | } |
| | | } |
| | | |
| | |
| | | // 更新出库任务中间表状态 |
| | | WMSHelper.updateLotOutTask(cst.S_CNTR_CODE, "2"); |
| | | } |
| | | |
| | | } |
| | | } |
| | | } |
| | |
| | | if (mst != null && mst.N_B_STATE < 2) { |
| | | |
| | | int emptyFlag = 0; // 容器空满标识 |
| | | Container cntr = ContainerHelper.GetCntr(cst.S_CNTR_CODE); |
| | | if (cntr != null && cntr.N_DETAIL_COUNT > 0) { |
| | | var cntrItemRels = ContainerHelper.GetCntrItemRel(cst.S_CNTR_CODE); |
| | | if (cntrItemRels.Count > 0) { |
| | | emptyFlag = 1; |
| | | } |
| | | |
| | | // 1:堆垛机放货异常申请新终点 |
| | | if (model.applyType == 1) { |
| | | // 报警:流程异常 |
| | | WMSHelper.addAlarmRecord("流程异常", "低", $"堆垛机放货异常,异常货位:{cst.S_END_LOC}"); |
| | | WMSHelper.addAlarmRecord("流程异常", "中", $"堆垛机放货异常,任务号:{cst.S_CODE},异常货位:{cst.S_END_LOC}"); |
| | | |
| | | // 1.将异常货位上锁,并报警 |
| | | LocationHelper.LockLoc(cst.S_END_LOC, 3); |
| | |
| | | LocationHelper.LockLoc(endLoc.S_CODE, 1); |
| | | applyDest.destLoc = endLoc.S_CODE; |
| | | } |
| | | else if (model.applyType == 2) |
| | | { |
| | | if (cst.S_END_LOC == "虚拟库位") |
| | | { |
| | | var transfeRelevance = WMSHelper.GetTransfeRelevance(model.loc); // 接驳位关联属性 |
| | | if (transfeRelevance != null) |
| | | { |
| | | // 1.查询新的入库终点 |
| | | Location endLoc = WMSHelper.getInStockEndLoc(transfeRelevance.S_RELE_AREA, emptyFlag); |
| | | cst.S_END_LOC = endLoc.S_CODE; |
| | | WCSHelper.UpdateEndLoc(cst); |
| | | |
| | | LocationHelper.LockLoc(endLoc.S_CODE, 1); |
| | | applyDest.destLoc = endLoc.S_CODE; |
| | | } |
| | | } |
| | | } |
| | | |
| | | } |
| | | } |
| | | result.data = applyDest; |
| | |
| | | { |
| | | if (mst.S_TYPE == "余料/空工装入库") |
| | | { |
| | | var mesTask = WMSHelper.GetLjMesTaskById(int.Parse(mst.S_OP_DEF_CODE)); |
| | | var bo = int.TryParse(mst.S_OP_DEF_CODE, out int mesId); |
| | | if (bo) |
| | | { |
| | | var mesTask = WMSHelper.GetLjMesTaskById(mesId); |
| | | if (mesTask.QTY != 0) |
| | | { |
| | | var awaitTask = WMSHelper.GetAwaitWmsTaskByMaterialCode(mesTask.MATERIAL_CODE); |
| | |
| | | agvEndLoc = LocationHelper.GetLoc(awaitTask.S_END_LOC); |
| | | wmsEndLoc = agvEndLoc; |
| | | mst.S_TYPE = "叫料出库任务"; |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | } |
| | | else |
| | | { |
| | | WMSHelper.addAlarmRecord("流程异常", "高", $"AGV申请终点失败,未查询到立库接驳位"); |
| | | WMSHelper.addAlarmRecord("流程异常", "高", $"AGV申请终点失败,立库:{wmsEndLoc.S_AREA_CODE}未配置立库接驳位"); |
| | | return null; |
| | | } |
| | | } |
| | |
| | | /// 成新机叫料 |
| | | /// </summary> |
| | | /// <param name="materialCode"></param> |
| | | /// <param name="endLocCode"></param> |
| | | /// <param name="jtNo"></param> |
| | | /// <param name="mesTaskId"></param> |
| | | public static void callMaterial(string materialCode, string endLocCode, int mesTaskId) |
| | | public static void callMaterial(string materialCode, string jtNo, int mesTaskId) |
| | | { |
| | | var oldWmsTask = WMSHelper.GetWmsTaskByEnd(endLocCode); |
| | | if (oldWmsTask == null) { |
| | | string cntrCode = ""; |
| | | Location endLoc = LocationHelper.GetLoc(endLocCode); |
| | | var mesTask = WMSHelper.GetLjMesTaskById(mesTaskId); |
| | | |
| | | if (mesTask != null) |
| | | { |
| | | Location endLoc = WMSHelper.getCallMaterialLocCode(jtNo); |
| | | if (endLoc != null) |
| | | { |
| | | Location middleLoc = null; |
| | | Location startLoc = WMSHelper.getOutStockStartLoc(null, materialCode); |
| | | if (startLoc == null) |
| | | { |
| | | var mesTask = WMSHelper.GetLjMesTaskById(mesTaskId); |
| | | if (mesTask != null) |
| | | { |
| | | mesTask.RECEIVE_MSG = "没有库存"; |
| | | WMSHelper.updateLjMesTask(mesTask); |
| | | } |
| | | WMSHelper.addAlarmRecord("流程异常", "高", $"叫料失败,物料:{materialCode}没有库存"); |
| | | return; |
| | | } |
| | | else |
| | | if (startLoc != null) |
| | | { |
| | | var locCntrRels = LocationHelper.GetLocCntr(startLoc.S_CODE); |
| | | if (locCntrRels.Count > 0) |
| | | { |
| | | cntrCode = locCntrRels[0].S_CNTR_CODE; |
| | | } |
| | | else |
| | | { |
| | | WMSHelper.addAlarmRecord("流程异常", "高", $"查询物料异常,货位:{startLoc.S_CODE}缺少容器信息"); |
| | | return; |
| | | } |
| | | } |
| | | |
| | | middleLoc = WMSHelper.GetTransfeRelevanceLoc(startLoc.S_AREA_CODE, 1 , 2); |
| | | |
| | | if (middleLoc != null) |
| | | { |
| | | // 1.创建成新机叫料作业 |
| | |
| | | S_OP_CODE = wmsTask.S_CODE, |
| | | S_CODE = WCSHelper.GenerateTaskNo(), |
| | | S_CNTR_CODE = wmsTask.S_CNTR_CODE, |
| | | S_TYPE = wmsTask.S_TYPE + "-WCS", |
| | | S_TYPE = wmsTask.S_TYPE, |
| | | S_START_LOC = startLoc.S_CODE, |
| | | S_START_AREA = startLoc.S_AREA_CODE, |
| | | S_END_LOC = middleLoc.S_CODE, |
| | |
| | | N_B_STATE = -1 |
| | | }; |
| | | WCSHelper.CreateTask(twoWcsTask); |
| | | |
| | | WMSHelper.readLjMesCallItemTask(wmsTask.S_CODE, mesTaskId); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | WMSHelper.addAlarmRecord("流程异常", "高", $"库区{startLoc.S_AREA_CODE}未查询到可用的接驳位"); |
| | | WMSHelper.addAlarmRecord("流程异常", "高", $"成型机叫料失败,库区{startLoc.S_AREA_CODE}未查询到可用的接驳位"); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | WMSHelper.addAlarmRecord("流程异常", "高", $"成型机叫料失败,开始货位:{startLoc.S_CODE}异常,缺少容器信息"); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | mesTask.AWAIT_MSG = "库存不足"; |
| | | WMSHelper.updateLjMesTask(mesTask); |
| | | WMSHelper.addAlarmRecord("流程异常", "高", $"成型机叫料失败,物料:{materialCode}库存不足"); |
| | | } |
| | | } |
| | | } |
| | | |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | /// <param name="materialCode"></param> |
| | | /// <param name="endLocCode"></param> |
| | | /// <param name="mesTaskId"></param> |
| | | public static void callMaterialHDK(string materialCode, string endLocCode, int mesTaskId) |
| | | public static void callMaterialXC(string materialCode, string endLocCode, int mesTaskId) |
| | | { |
| | | // 1.查询环带库物料库存 |
| | | DateTime inStockTimeXc = DateTime.MinValue; |
| | | List<CntrItemRel> cntrItemRelsXc = new List<CntrItemRel>(); |
| | | if (cntrItemRelsXc.Count > 0) |
| | | { |
| | | inStockTimeXc = cntrItemRelsXc[0].T_INBOUND_TIME; |
| | | } |
| | | |
| | | // 2.查询中转库库存,根据入库时间 进行先入先出 |
| | | // 2.查询中转库库存 |
| | | DateTime inStockTime = DateTime.MinValue; |
| | | var cntrItemRels = WMSHelper.getZZKInventoryInfo(materialCode); |
| | | if (cntrItemRels.Count > 0) |
| | | { |
| | | inStockTime = cntrItemRels[0].T_INBOUND_TIME; |
| | | } |
| | | |
| | | // 3.将MES任务写入环带库任务中间表 |
| | | WMSHelper.addLjXcTask(mesTaskId); |
| | | // 3.根据先进先出计算出库的物料是环带库 还是中转库 |
| | | var mesTask = WMSHelper.GetLjMesTaskById(mesTaskId); |
| | | if (inStockTime >= inStockTimeXc) |
| | | { |
| | | //斜裁物料出库 |
| | | if (cntrItemRelsXc.Count > 0) |
| | | { |
| | | // 4.将MES任务写入环带库任务中间表 |
| | | WMSHelper.addLjXcTask(mesTask); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | //中转库物料出库 |
| | | if (cntrItemRels.Count > 0) |
| | | { |
| | | var cntrItemRel = cntrItemRels[0]; |
| | | var locCntrRel = LocationHelper.GetLocCntrByCntr(cntrItemRel.S_CNTR_CODE); |
| | | if (locCntrRel != null) |
| | | { |
| | | var endLoc = LocationHelper.GetLoc(locCntrRel.S_LOC_CODE); |
| | | if (endLoc != null) |
| | | { |
| | | Location middleLoc = null; |
| | | Location startLoc = WMSHelper.getOutStockStartLoc(null, materialCode); |
| | | if (startLoc != null) |
| | | { |
| | | var locCntrRels = LocationHelper.GetLocCntr(startLoc.S_CODE); |
| | | if (locCntrRels.Count > 0) |
| | | { |
| | | var cntrCode = cntrItemRel.S_CNTR_CODE; |
| | | middleLoc = WMSHelper.GetTransfeRelevanceLoc(startLoc.S_AREA_CODE, 1, 2); |
| | | if (middleLoc != null) |
| | | { |
| | | // 1.创建成新机叫料作业 |
| | | var wmsTask = new WMSTask() |
| | | { |
| | | S_CNTR_CODE = cntrCode, |
| | | 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 = mesTaskId.ToString(), |
| | | S_OP_DEF_NAME = "成型机叫料出库任务", |
| | | 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 = 10, |
| | | 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); |
| | | } |
| | | |
| | | // 预创建二段任务 |
| | | WCSTask twoWcsTask = 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 = middleLoc.S_CODE, |
| | | S_START_AREA = middleLoc.S_AREA_CODE, |
| | | S_END_LOC = endLoc.S_CODE, |
| | | S_END_AREA = endLoc.S_AREA_CODE, |
| | | S_SCHEDULE_TYPE = "AGV", |
| | | N_PRIORITY = 10, |
| | | T_START_TIME = DateTime.Now, |
| | | N_B_STATE = -1 |
| | | }; |
| | | WCSHelper.CreateTask(twoWcsTask); |
| | | WMSHelper.readLjMesCallItemTask(wmsTask.S_CODE, mesTaskId); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | WMSHelper.addAlarmRecord("流程异常", "高", $"成型机叫料失败,库区{startLoc.S_AREA_CODE}未查询到可用的接驳位"); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | WMSHelper.addAlarmRecord("流程异常", "高", $"成型机叫料失败,开始货位:{startLoc.S_CODE}异常,缺少容器信息"); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | mesTask.AWAIT_MSG = "库存不足"; |
| | | WMSHelper.updateLjMesTask(mesTask); |
| | | WMSHelper.addAlarmRecord("流程异常", "高", $"成型机叫料失败,物料:{materialCode}库存不足"); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | /// 3.创建余料回库作业,创建agv搬运任务,虚拟终点 |
| | | /// </summary> |
| | | /// <param name="locCode">成型机叫料终点</param> |
| | | public static void returnMaterialOrEmptyTray(string locCode) |
| | | /// <param name="jtNo">成型机叫料终点</param> |
| | | public static void returnMaterialOrEmptyTray(string locCode ,string jtNo) |
| | | { |
| | | if (locCode != null) |
| | | { |
| | | // 2.查询mes任务中间表 |
| | | var mesTask = WMSHelper.getLjMesTaskByLoc(locCode); |
| | | var mesTask = WMSHelper.getLjMesTaskByJtNo(jtNo); |
| | | if (mesTask != null) |
| | | { |
| | | createReturnTask(locCode, mesTask); |
| | |
| | | } |
| | | } |
| | | |
| | | if (cst.S_TYPE == "叫料出库任务") |
| | | var bo = int.TryParse(mst.S_OP_DEF_CODE, out int mesId); |
| | | if (bo) |
| | | { |
| | | var mesTask = WMSHelper.GetLjMesTaskByAgvorderId(mst.S_CODE); |
| | | var mesTask = WMSHelper.GetLjMesTaskById(mesId); |
| | | callMaterial( mesTask.MATERIAL_CODE, mesTask.POSITION_ID, mesTask.ID); |
| | | } |
| | | } |
| | |
| | | //---------------------------------------------------------------------------------------------------------------------------- |
| | | public class LocModel |
| | | { |
| | | public string locCode { get; set; } |
| | | public string locCode { get; set; } // 返料货位编号 |
| | | public string jtNo { get; set; } // 机台号 |
| | | } |
| | | |
| | | public class ApplyDest { |
| | |
| | | { |
| | | LogHelper.Info("余料/空工装返回-returnMaterialAndPallet 入参:" + JsonConvert.SerializeObject(model), "Mobox"); |
| | | ResponseResult responseResult = new ResponseResult(); |
| | | ApiHelper.returnMaterialOrEmptyTray(model.locCode); |
| | | ApiHelper.returnMaterialOrEmptyTray(model.locCode ,model.jtNo); |
| | | LogHelper.Info("余料/空工装返回-returnMaterialAndPallet 出参:" + JsonConvert.SerializeObject(responseResult), "Mobox"); |
| | | return responseResult; |
| | | } |
| | |
| | | { |
| | | |
| | | /// <summary> |
| | | /// 监听MES任务中间表 |
| | | /// 1.钢包满料下线 |
| | | /// 2.成型机叫料 |
| | | /// 监听钢包满料下线MES任务 |
| | | /// </summary> |
| | | public static void MonitorMesTask() { |
| | | LogHelper.Info("监听MES任务中间表", "WMS"); |
| | | var mesTaskList = WMSHelper.GetLjMesTaskList("PENDING"); |
| | | foreach (var mesTask in mesTaskList) |
| | | public static void MonitorGBOffLineMesTask() |
| | | { |
| | | // 1.钢包满料下线 |
| | | List<string> lineLoclist = new List<string>() { }; |
| | | lineLoclist.Add("GBJTW-01"); |
| | | lineLoclist.Add("GBJTW-02"); |
| | | if (mesTask.MSG_TYPE == "1" && mesTask.PALLET_TYPE == "7" && lineLoclist.Contains(mesTask.PALLET_ID)) |
| | | var mesTaskList = WMSHelper.GetLjMesTaskList("PENDING"); |
| | | if (mesTaskList.Count > 0) |
| | | { |
| | | mesTaskList = mesTaskList.Where(a => a.MSG_TYPE == "1" && a.PALLET_TYPE == "7").ToList(); |
| | | if (mesTaskList.Count > 0) |
| | | { |
| | | foreach (var mesTask in mesTaskList) |
| | | { |
| | | LogHelper.Info("MES钢包满料下线任务", "WMS"); |
| | | OffLineRequest request = new OffLineRequest(){ loc = mesTask.POSITION_ID, cntrNo = mesTask.PALLET_ID}; |
| | | ApiHelper.offLineProcess(request); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 2.成新机叫料 |
| | | if (mesTask.MSG_TYPE == "0") { |
| | | var lineSideLoc = WMSHelper.GetLineSideLoc(mesTask.POSITION_ID); |
| | | /// <summary> |
| | | /// 监听成型机叫料MES任务 |
| | | /// </summary> |
| | | public static void MonitorCXJCallMaterialMesTask() |
| | | { |
| | | var mesTaskList = WMSHelper.GetLjMesTaskList("PENDING"); |
| | | if (mesTaskList.Count > 0) |
| | | { |
| | | mesTaskList = mesTaskList.Where(a => a.MSG_TYPE == "0").ToList(); |
| | | if (mesTaskList.Count > 0) |
| | | { |
| | | foreach (var mesTask in mesTaskList) |
| | | { |
| | | var lineSideLoc = WMSHelper.GetLineSideLoc(mesTask.EQP); |
| | | if (lineSideLoc != null ) |
| | | { |
| | | LogHelper.Info("MES成新机叫料任务", "WMS"); |
| | | LogHelper.Info($"成型机叫料任务,MES任务ID:{mesTask.ID}", "WMS"); |
| | | |
| | | // 2.1成新机叫料(斜裁) |
| | | if (mesTask.PALLET_TYPE == "5" || mesTask.PALLET_TYPE == "6") |
| | |
| | | var xcTask = WMSHelper.GetLjXcTaskById(mesTask.ID); |
| | | if (xcTask == null) |
| | | { |
| | | ApiHelper.callMaterialHDK(mesTask.MATERIAL_CODE, mesTask.POSITION_ID, mesTask.ID); |
| | | ApiHelper.callMaterialXC(mesTask.MATERIAL_CODE, mesTask.POSITION_ID, mesTask.ID); |
| | | } |
| | | else |
| | | { |
| | |
| | | else |
| | | { |
| | | // 2.2 成新机叫料 |
| | | ApiHelper.callMaterial(mesTask.MATERIAL_CODE, mesTask.POSITION_ID, mesTask.ID); |
| | | ApiHelper.callMaterial(mesTask.MATERIAL_CODE, mesTask.EQP, mesTask.ID); |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | if (mesTask != null && mesTask.RETURN_CODE == "2") |
| | | { |
| | | Location startLoc = LocationHelper.GetLoc(outTask.POSITION_ID); |
| | | Location endLoc = LocationHelper.GetLoc(mesTask.POSITION_ID); |
| | | |
| | | if (startLoc == null) |
| | | { |
| | | WMSHelper.addAlarmRecord("流程异常", "高", $"成型机叫料出库(斜裁),起点:{outTask.POSITION_ID}在WMS系统中不存在"); |
| | | } |
| | | Location endLoc = WMSHelper.getCallMaterialLocCode(mesTask.EQP); |
| | | if (endLoc != null) |
| | | { |
| | | var wmsTask = WMSHelper.GetWmsTaskByCntr(outTask.PALLET_ID); |
| | | if (wmsTask == null) |
| | | { |
| | | if (startLoc.N_LOCK_STATE == 0 && endLoc.N_LOCK_STATE == 0) |
| | | { |
| | | // 1.创建斜裁-成新机叫料作业 |
| | | wmsTask = new WMSTask() |
| | |
| | | WMSHelper.UpdateTaskState(wmsTask); |
| | | } |
| | | } |
| | | } |
| | | else |
| | | { |
| | | LogHelper.Info($"XC出库任务ID:{mesTask.ID},无法生成叫料任务,起点或终点上锁", "斜裁"); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | 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 = "AGV", |
| | | N_PRIORITY = 10, |
| | | 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.addRfidAnomalyRecord(cst.S_CNTR_CODE, 2, cst.S_START_LOC, null); |
| | | // 查询扫描的RFID |
| | | // 发送 00 04 71 02到扫码器 ,接受返回数据并解析 |
| | | byte[] bytes = new byte[] { 00, 04, 71, 02 }; |
| | | /* byte[] bytes = new byte[] { 00, 04, 71, 02 }; |
| | | var plc = Settings.carDeviceInfos.Where(a => a.deviceNo == model.ForkliftNo && a.enable == 1).FirstOrDefault(); |
| | | TcpServer.TcpServerSend(plc.address, bytes); |
| | | TcpServer.TcpServerSend(plc.address, bytes);*/ |
| | | } |
| | | else if (model.State == 1002) |
| | | { |
| | |
| | | // AGV任务完成 |
| | | if (model.State == 2) |
| | | { |
| | | // 检测物料是否合格,如不合格, |
| | | // 判断物料是否是环带库物料,是则回环带库,并让环带下发新的物料 |
| | | // 非环带库物料,则退出立库,同时下发新的物料出库任务 |
| | | if (cst.S_TYPE.Contains("叫料出库任务")) |
| | | { |
| | | var cntrItemRels = ContainerHelper.GetCntrItemRel(cst.S_CNTR_CODE); |
| | | if (cntrItemRels != null && cntrItemRels.Count > 0) |
| | | { |
| | | if (cntrItemRels[0].S_ITEM_STATE == "2") |
| | | { |
| | | // 不合格品回库 |
| | | ApiHelper.rejectReturnStock(mst, cst); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 检测是否是读码位,非读码位,可以激活预创建任务 |
| | | var transfe = WMSHelper.GetTransfeRelevance(cst.S_END_LOC); // 接驳位属性 |
| | | if (transfe != null && transfe.N_READ_LOC == 1) |
| | | { |
| | | // 激活预创建任务 |
| | | // 场景:1.读码位激活预创建任务 2.空工装出库激活满料下线任务(非直连) |
| | | WCSHelper.ActivatePreCreateTask(mst.S_CODE); |
| | | } |
| | | else if ( transfe.N_READ_LOC == 0) |
| | | { |
| | | if (cst.S_TYPE.Contains("【异常】")) |
| | | { |
| | | WCSHelper.ActivatePreCreateTask(mst.S_CODE,1); |
| | | } |
| | | else |
| | | { |
| | | WCSHelper.ActivatePreCreateTask(mst.S_CODE); |
| | | } |
| | | } |
| | | |
| | | // 查询是否有未完成的任务 |
| | | if (WMSHelper.isFinishTask(mst.S_CODE)) |
| | |
| | | |
| | | // 更新任务中间表状态 |
| | | WMSHelper.updateMesTaskStatus(mst.S_CODE, "3"); |
| | | } |
| | | |
| | | // 检测物料是否合格,如不合格, |
| | | // 判断物料是否是环带库物料,是则回环带库,并让环带下发新的物料 |
| | | // 非环带库物料,则退出立库,同时下发新的物料出库任务 |
| | | if (cst.S_TYPE.Contains("叫料出库任务")) |
| | | { |
| | | var bo = int.TryParse(mst.S_OP_DEF_CODE, out int mesId); |
| | | if (bo) |
| | | { |
| | | var mesTask = WMSHelper.GetLjMesTaskById(mesId); |
| | | var cntrItemRels = ContainerHelper.GetCntrItemRel(cst.S_CNTR_CODE); |
| | | if (cntrItemRels != null && cntrItemRels.Count > 0) |
| | | { |
| | | if (cntrItemRels[0].S_ITEM_STATE == "2") |
| | | { |
| | | mesTask.AWAIT_MSG = "物料检验状态为不合格,重新叫料中"; |
| | | WMSHelper.updateLjMesTask(mesTask); |
| | | |
| | | // 不合格品回库 |
| | | ApiHelper.rejectReturnStock(mst, cst); |
| | | } |
| | | else |
| | | { |
| | | // 如果作业名称为成型机叫料出库任务,则触发余料/空托搬运任务 |
| | | string locCode = WMSHelper.getReturnMaterialLocCode(mst.S_END_LOC); |
| | | ApiHelper.returnMaterialOrEmptyTray(locCode); |
| | | var sideLocConfig = WMSHelper.getReturnMaterialLocCode(mst.S_END_LOC); |
| | | ApiHelper.returnMaterialOrEmptyTray(sideLocConfig.S_RETURN_LOC_CODE, sideLocConfig.EQP); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | public float QTY { get; set; } //数量 |
| | | public DateTime IN_DATE { get; set; } //入库时间 |
| | | public DateTime CREATION_DATE { get; set; } //创建日期 |
| | | public string WAREHOUSE_TYPE { get; set; } //区分不同厂家(1/思尔特,2/杭叉) |
| | | } |
| | | } |
| | |
| | | [SugarTable("TN_Side_Loc_Config")] |
| | | internal class SideLocConfig : BaseModel |
| | | { |
| | | public string EQP { get; set; } // 机台号 |
| | | public string S_LOC_CODE { get; set; } // 线边叫料货位 |
| | | public string S_RETURN_LOC_CODE { get; set; } // 对应返料货位 |
| | | } |
| | |
| | | return db.Queryable<Location>().Where(a => a.S_AREA_CODE.Trim() == areaCode && a.N_CURRENT_NUM == 0 && a.N_LOCK_STATE == 0 && a.C_ENABLE == "Y").First(); |
| | | } |
| | | |
| | | internal static bool checkAreaExistCntr(List<string> areaCodes ,string cntrCode) |
| | | { |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | return db.Queryable<Location>() |
| | | .LeftJoin<LocCntrRel>((a,b) => a.S_CODE == b.S_LOC_CODE) |
| | | .Where((a, b) => areaCodes.Contains(a.S_AREA_CODE.Trim()) |
| | | && a.N_CURRENT_NUM == 0 |
| | | && a.N_LOCK_STATE == 0 |
| | | && a.C_ENABLE == "Y" |
| | | && b.S_CNTR_CODE == cntrCode |
| | | ).Count() > 0; |
| | | } |
| | | |
| | | /// <summary> |
| | | ///获取所有货位扩展信息 |
| | | /// </summary> |
| | |
| | | }); |
| | | } |
| | | return result; |
| | | |
| | | } |
| | | |
| | | internal static LocCntrRel GetLocCntrByCntr(string cntrCode) |
| | | { |
| | | var result = new List<LocCntrRel>(); |
| | | //1.0 查货位容器表 |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | return db.Queryable<LocCntrRel>().Where(a => a.S_CNTR_CODE.Trim() == cntrCode).OrderBy(a => a.T_CREATE).First(); |
| | | } |
| | | |
| | | internal static List<LocCntrRel> GetLocCntrRel(string loc) { |
| | | //1.0 查货位容器表 |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// |
| | | /// 查询成型机返料货位 |
| | | /// </summary> |
| | | /// <param name="locCode"></param> |
| | | /// <returns></returns> |
| | | public static string getReturnMaterialLocCode(string locCode) |
| | | public static SideLocConfig getReturnMaterialLocCode(string locCode) |
| | | { |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | var returnMaterialLoc = db.Queryable<SideLocConfig>().Where(a => a.S_LOC_CODE.Trim() == locCode).First(); |
| | | if (returnMaterialLoc != null) { |
| | | return returnMaterialLoc.S_RETURN_LOC_CODE; |
| | | return db.Queryable<SideLocConfig>().Where(a => a.S_LOC_CODE.Trim() == locCode).First(); |
| | | } |
| | | return null; |
| | | |
| | | /// <summary> |
| | | /// 查询成型机叫料位 |
| | | /// </summary> |
| | | /// <param name="jtNo"></param> |
| | | /// <returns></returns> |
| | | public static Location getCallMaterialLocCode(string jtNo) |
| | | { |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | |
| | | Location loc = null; |
| | | var returnMaterialLocs = db.Queryable<SideLocConfig>().Where(a => a.EQP.Trim() == jtNo).ToList(); |
| | | if (returnMaterialLocs.Count > 0) |
| | | { |
| | | foreach (var item in returnMaterialLocs) |
| | | { |
| | | loc = LocationHelper.GetLoc(item.S_LOC_CODE); |
| | | if (loc.N_CURRENT_NUM == 0 && loc.N_LOCK_STATE == 0) |
| | | { |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | return loc; |
| | | } |
| | | // --------------------------------------------------------福建佳通----------------------------------------- |
| | | |
| | |
| | | .OrderBy(a => a.S_PRI) |
| | | .First(); |
| | | return logicConfig; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 查询某个物料在中转库的库存信息 |
| | | /// </summary> |
| | | /// <param name="itemCode"></param> |
| | | /// <returns></returns> |
| | | public static List<CntrItemRel> getZZKInventoryInfo(string itemCode) |
| | | { |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | List < CntrItemRel > cntrItemRels = new List<CntrItemRel>(); |
| | | string areaCode = Settings.areaPropertyList.Where(a => a.areaName.Contains("中转库")).Select(a => a.areaCode).FirstOrDefault(); |
| | | if (areaCode != null) |
| | | { |
| | | cntrItemRels = db.Queryable<CntrItemRel>() |
| | | .LeftJoin<LocCntrRel>((a, b) => a.S_CNTR_CODE == b.S_CNTR_CODE) |
| | | .LeftJoin<Location>((a, b, c) => b.S_LOC_CODE == c.S_CODE) |
| | | .LeftJoin<Container>((a, b, c, d) => a.S_CNTR_CODE == d.S_CODE) |
| | | .Where((a, b, c, d) => c.S_AREA_CODE == areaCode |
| | | && c.N_CURRENT_NUM == 1 |
| | | && c.N_LOCK_STATE == 0 |
| | | && a.S_ITEM_CODE == itemCode |
| | | && d.N_E_STATE == 0 // 托盘正常 |
| | | ) |
| | | .OrderBy((a, b, c, d) => a.T_INBOUND_TIME) |
| | | .ToList(); |
| | | } |
| | | return cntrItemRels; |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | }; |
| | | result = db.Insertable<AlarmRecord>(alarmRecord).ExecuteCommand() > 0; |
| | | } |
| | | else |
| | | { |
| | | alarmRecord.T_MODIFY = DateTime.Now; |
| | | result = db.Updateable<AlarmRecord>(alarmRecord).ExecuteCommand() > 0; |
| | | } |
| | | return result; |
| | | } |
| | | |
| | |
| | | /// <summary> |
| | | /// 查询成型机线边 |
| | | /// </summary> |
| | | /// <param name="locCode"></param> |
| | | /// <param name="jtNo"></param> |
| | | /// <returns></returns> |
| | | public static SideLocConfig GetLineSideLoc(string locCode) |
| | | public static SideLocConfig GetLineSideLoc(string jtNo) |
| | | { |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | return db.Queryable<SideLocConfig>().Where(a => a.S_LOC_CODE.Trim() == locCode).First(); |
| | | return db.Queryable<SideLocConfig>().Where(a => a.EQP.Trim() == jtNo).First(); |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 查询MES叫料任务 |
| | | /// 根据机台号查询MES任务 |
| | | /// </summary> |
| | | /// <param name="jtNo"></param> |
| | | /// <returns></returns> |
| | | internal static LjMesTask getLjMesTaskByJtNo(string jtNo) |
| | | { |
| | | // 1.查询MES任务表 |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | var mesTask = db.Queryable<LjMesTask>().Where(a => a.EQP.Trim() == jtNo && a.RECEIVE_FLAG.Trim() == "PENDING").OrderByDescending(a => a.T_CREATE).First(); |
| | | return mesTask; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 根据点位编号查询MES叫料任务 |
| | | /// </summary> |
| | | /// <param name="positionId"></param> |
| | | /// <returns></returns> |
| | |
| | | { |
| | | bool result = false; |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | mesTask.RECEIVE_FLAG = "COMPLETE"; |
| | | mesTask.RECEIVE_DATE = DateTime.Now.ToString("yyyy-MM-dd"); |
| | | result = db.Updateable(mesTask).ExecuteCommand() > 0; |
| | | return result; |
| | | } |
| | |
| | | /// <summary> |
| | | /// 下发XC任务 |
| | | /// </summary> |
| | | /// <param name="mesTaksId"></param> |
| | | /// <param name="mesTask"></param> |
| | | /// <returns></returns> |
| | | public static bool addLjXcTask(int mesTaksId) |
| | | public static bool addLjXcTask(LjMesTask mesTask) |
| | | { |
| | | bool result = false; |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | var ljMesTask = GetLjMesTaskById(mesTaksId); |
| | | if (ljMesTask != null) { |
| | | if (mesTask != null) { |
| | | LjXcTask ljXcTask = new LjXcTask() { |
| | | ID = ljMesTask.ID, |
| | | POSITION_ID = ljMesTask.POSITION_ID, |
| | | RETURN_CODE = ljMesTask.RETURN_CODE, |
| | | MSG_TYPE = ljMesTask.MSG_TYPE, |
| | | PALLET_TYPE = ljMesTask.PALLET_TYPE, |
| | | MATERIAL_NAME = ljMesTask.MATERIAL_NAME, |
| | | MATERIAL_CODE = ljMesTask.MATERIAL_CODE, |
| | | QTY = ljMesTask.QTY, |
| | | YCL_BATCH = ljMesTask.YCL_BATCH, |
| | | PALLET_ID = ljMesTask.PALLET_ID, |
| | | AGVORDER_ID = ljMesTask.AGVORDER_ID, |
| | | ID = mesTask.ID, |
| | | POSITION_ID = mesTask.POSITION_ID, |
| | | RETURN_CODE = mesTask.RETURN_CODE, |
| | | MSG_TYPE = mesTask.MSG_TYPE, |
| | | PALLET_TYPE = mesTask.PALLET_TYPE, |
| | | MATERIAL_NAME = mesTask.MATERIAL_NAME, |
| | | MATERIAL_CODE = mesTask.MATERIAL_CODE, |
| | | QTY = mesTask.QTY, |
| | | YCL_BATCH = mesTask.YCL_BATCH, |
| | | PALLET_ID = mesTask.PALLET_ID, |
| | | AGVORDER_ID = mesTask.AGVORDER_ID, |
| | | CREATION_DATE = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), |
| | | RECEIVE_FLAG = ljMesTask.RECEIVE_FLAG, |
| | | EQP = ljMesTask.EQP, |
| | | PLAN_ID = ljMesTask.PLAN_ID |
| | | RECEIVE_FLAG = mesTask.RECEIVE_FLAG, |
| | | EQP = mesTask.EQP, |
| | | PLAN_ID = mesTask.PLAN_ID |
| | | }; |
| | | result = db.Insertable<LjXcTask>(ljXcTask).ExecuteCommand() > 0; |
| | | } |
| | |
| | | EndLocGroup endLocGroup = null; |
| | | if (barcodeList.Count > 0) |
| | | { |
| | | endLocGroup = WMSHelper.getInStockEndLoc(barcodeList.Count); |
| | | string itemCode = null; |
| | | var cntrItemRels = ContainerHelper.GetCntrItemRel(barcodeList[0].rfid); |
| | | if (cntrItemRels.Count > 0) |
| | | { |
| | | itemCode = cntrItemRels[0].S_ITEM_CODE; |
| | | } |
| | | endLocGroup = WMSHelper.getInStockEndLoc(barcodeList.Count, itemCode); |
| | | } |
| | | |
| | | foreach (var ext in extData) |
| | |
| | | { |
| | | ResponseResult response = new ResponseResult(); |
| | | |
| | | //参数校验 |
| | | if (model.locCodes.Count == 0) |
| | | int locNum = model.locCodes.Count; |
| | | if (locNum > 0) |
| | | { |
| | | string msg = $"硫化机:{model.mcn}呼叫胚胎出库,参数校验失败,缺少货位信息"; |
| | | LogHelper.Info(msg, "WMS"); |
| | | response.code = 1; |
| | | response.msg = msg; |
| | | return response; |
| | | } |
| | | |
| | | Location prevLoc = null; |
| | | Dictionary<string,Location> outLocDic = new Dictionary<string,Location>(); |
| | | foreach (var mcn in model.locCodes) |
| | | { |
| | | // 1.一个硫化机工位只能同时存在一个正在执行中的任务 |
| | | WCSTask existTask = WCSHelper.GetTaskByEqNo(model.mcn); |
| | | if (existTask == null) |
| | | var existTask = WCSHelper.GetTaskByEnd(mcn); |
| | | if (existTask.Count == 0) |
| | | { |
| | | // 2.根据当前时间,判断班次日期和班次 |
| | | var currentTime = DateTime.Now; |
| | | var shift = getShift(currentTime.TimeOfDay); |
| | | var dateShift = DateTime.Now.ToString("dd/MM/yyyy"); |
| | | var shift = getShift(currentTime.TimeOfDay); // 班次 |
| | | var dateShift = currentTime.ToString("dd/MM/yyyy"); |
| | | TimeSpan shiftIII_Start = new TimeSpan(7, 00, 0); // 7:00:00 |
| | | if (shift == "III" && currentTime.TimeOfDay < shiftIII_Start) |
| | | { |
| | | dateShift = DateTime.Now.AddDays(-1).ToString("dd/MM/yyyy"); |
| | | } |
| | | |
| | | // 3.根据班次日期+班次+硫化机工位号查询呼叫的物料编码、预计生产数量 |
| | | var productionShedule = WMSHelper.getProductionShedule(dateShift, model.mcn, shift); |
| | | // 3.根据班次日期+班次+硫化机工位号查询 硫化机工单 中的物料编码、预计生产数量 |
| | | var productionShedule = WMSHelper.getProductionShedule(dateShift, mcn, shift); |
| | | |
| | | if (productionShedule != null && productionShedule.QTY != 0) |
| | | { |
| | | // 4.查询【胚胎已完成的条码中间表】并计算当前班次的已完成数量 |
| | | int finishNum = WMSHelper.getEmbryoFinishNum(dateShift, model.mcn, shift); |
| | | |
| | | // 4查询【胚胎已完成的条码中间表】并计算当前班次的已完成数量 |
| | | int finishNum = WMSHelper.getEmbryoFinishNum(dateShift, mcn, shift); |
| | | if (productionShedule.QTY > finishNum) |
| | | { |
| | | // 5.计算(1.巷道不报警、2.物料状态OK、3.小于失效时间 大于等于生效时间 4.加急料先出、5.先入先出(生产时间))出库物料,生成任务 |
| | | int locNum = model.locCodes.Count; |
| | | var startLocData = WMSHelper.getOutStockStartLoc(productionShedule.ITEMCODE,locNum); |
| | | if (startLocData.startLocList != null && startLocData.startLocList.Count == locNum) |
| | | // 5.出库策略 1.优先查询前一拖货位的左右两边是否满足条件 2.计算(1.巷道不报警、2.物料状态OK、3.小于失效时间 大于等于生效时间 4.加急料先出、5.先入先出(生产时间))出库物料,生成任务 |
| | | var startLoc = WMSHelper.getOutStockStartLoc(productionShedule.ITEMCODE, prevLoc); |
| | | if (startLoc != null) |
| | | { |
| | | var startLocList = startLocData.startLocList; |
| | | for (int i = 0; i < locNum; i++) |
| | | outLocDic.Add(mcn, startLoc); |
| | | prevLoc = startLoc; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 6.判断出库货位是否是同一巷道,同一巷道生成任务组号 |
| | | string groupNo = null; |
| | | if (outLocDic.Count > 1) |
| | | { |
| | | Location startLoc = startLocList[i]; |
| | | Location endLoc = LocationHelper.GetLoc(model.locCodes[i]); |
| | | var groupNum = outLocDic.Select(a => a.Value).ToList().GroupBy(a => a.N_ROADWAY).Count(); |
| | | if (groupNum == 1) |
| | | { |
| | | groupNo = GenerateTaskGroupNo(); |
| | | } |
| | | } |
| | | |
| | | // 7.生成出库任务 |
| | | if (outLocDic.Count > 0) |
| | | { |
| | | foreach (var item in outLocDic) |
| | | { |
| | | Location endLoc = LocationHelper.GetLoc(item.Key); |
| | | Location startLoc = item.Value; |
| | | if (endLoc != null) |
| | | { |
| | | var locCntrRels = LocationHelper.GetLocCntr(startLoc.S_CODE); |
| | |
| | | S_OP_DEF_NAME = "成型机满料下线入库", |
| | | N_PRIORITY = 1, |
| | | T_START_TIME = DateTime.Now, |
| | | S_GROUP_NO = startLocData.groupNo, |
| | | S_GROUP_NO = groupNo, |
| | | }; |
| | | if (WMSHelper.CreateWmsTask(wmsTask)) |
| | | { |
| | |
| | | } |
| | | } |
| | | } |
| | | else |
| | | { |
| | | string msg = $"库内没有满足条件的物料"; |
| | | LogHelper.Info(msg, "WMS"); |
| | | response.code = 1; |
| | | response.msg = msg; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | string msg = $"硫化机:{model.mcn}的当前班次任务已完成,停止叫料"; |
| | | LogHelper.Info(msg, "WMS"); |
| | | response.code = 1; |
| | | response.msg = msg; |
| | | } |
| | | } |
| | | } |
| | | else |
| | | { |
| | | string msg = $"硫化机:{model.mcn}的存在正在执行中的任务,请勿重复叫料"; |
| | | LogHelper.Info(msg, "WMS"); |
| | | response.code = 1; |
| | | response.msg = msg; |
| | | } |
| | | return response; |
| | | } |
| | |
| | | { |
| | | ResponseResult response = new ResponseResult(); |
| | | Location startLoc = LocationHelper.GetLoc(model.startLoc); |
| | | var endLocGroup = WMSHelper.getInStockEndLoc(1); |
| | | var endLocGroup = WMSHelper.getInStockEndLoc(1,null); |
| | | if (endLocGroup.endLocList.Count == 1) |
| | | { |
| | | Location endLoc = endLocGroup.endLocList[0]; |
| | |
| | | public static ResponseResult callEmptyTrayOutStock(CallEmptyTrayOutStockModel model) |
| | | { |
| | | ResponseResult responseResult = new ResponseResult(); |
| | | Location endLoc = LocationHelper.GetLoc(model.endLoc); |
| | | var startLocData = WMSHelper.getOutStockStartLoc(null, 1); |
| | | if (startLocData.startLocList != null && startLocData.startLocList.Count == 1) |
| | | Location startLoc = WMSHelper.getOutStockStartLoc(null); |
| | | if (startLoc != null) |
| | | { |
| | | Location startLoc = startLocData.startLocList[0]; |
| | | Location endLoc = LocationHelper.GetLoc(model.endLoc); |
| | | if (endLoc != null) |
| | | { |
| | | var locCntrRels = LocationHelper.GetLocCntr(startLoc.S_CODE); |
| | |
| | | S_OP_DEF_CODE = model.reqId, |
| | | S_OP_DEF_NAME = "呼叫空托出库", |
| | | N_PRIORITY = 1, |
| | | T_START_TIME = DateTime.Now, |
| | | S_GROUP_NO = startLocData.groupNo, |
| | | T_START_TIME = DateTime.Now |
| | | }; |
| | | if (WMSHelper.CreateWmsTask(wmsTask)) |
| | | { |
| | |
| | | } |
| | | } |
| | | } |
| | | else |
| | | { |
| | | responseResult.code = 1; |
| | | responseResult.msg = $"终点货位:{model.endLoc}在WMS系统中不存在"; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | string msg = $"库内没有满足条件的物料"; |
| | | LogHelper.Info(msg, "WMS"); |
| | | responseResult.code = 1; |
| | | responseResult.msg = msg; |
| | | responseResult.msg = "库内空托不足"; |
| | | } |
| | | return responseResult; |
| | | } |
| | |
| | | { |
| | | public string reqId { get; set; } |
| | | public string reqTime { get; set; } |
| | | public string mcn { get; set; } |
| | | public List<string> locCodes { get; set; } |
| | | public List<string> locCodes { get; set; } // 硫化机工位 |
| | | } |
| | | |
| | | public class NotifyDeviceSignalModel |
| | |
| | | return greenTireInformation; |
| | | } |
| | | |
| | | /// <summary> |
| | | /*/// <summary> |
| | | /// 查询入库终点货位 |
| | | /// 入库策略: |
| | | /// 巷道内同规格数量 小于 10(暂定),按物料均衡计算,如果所有的巷道内同规格数量都大于10,则按照巷道均衡计算 |
| | | /// </summary> |
| | | /// <param name="locNum">1.单货位 2.双货位</param> |
| | | /// <returns></returns> |
| | | public static EndLocGroup getInStockEndLoc(int locNum) |
| | | public static EndLocGroup getInStockEndLoc(int locNum , string itemCode) |
| | | { |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | EndLocGroup endLocGroup = new EndLocGroup(); |
| | | 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") |
| | | |
| | | List<int> roadwayList = new List<int>(); |
| | | |
| | | // 1.按巷道进行分组,查询每个巷道内同规格物料的数量,并从小到大排序 |
| | | var roadwayItemNumOrderGroup = 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_CURRENT_NUM == 1 && a.N_LOCK_STATE == 0 && a.C_ENABLE == "Y" && c.S_ITEM_CODE == itemCode) |
| | | .GroupBy((a, b, c) => a.N_ROADWAY) |
| | | .Select((a, b, c) => new { roadway = a.N_ROADWAY, num = SqlFunc.AggregateCount(a.S_CODE) }) |
| | | .OrderBy(a => a.num) |
| | | .ToList(); |
| | | |
| | | roadwayList = roadwayItemNumOrderGroup.Where(a => a.num < 10).OrderBy(a => a.num).Select(a => a.roadway).ToList(); |
| | | |
| | | // 2.按巷道进行分组,查询每个巷道空货位数量,并从大到小排序 |
| | | if (roadwayList.Count == 0) |
| | | { |
| | | var roadwayEmptyNumOrderGroup = 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(); |
| | | roadwayList = roadwayEmptyNumOrderGroup.Select(a => a.roadway).ToList(); |
| | | } |
| | | |
| | | if (roadwayList.Count > 0) |
| | | { |
| | | // 查询单货位 |
| | | foreach (var order in roadwayOrderList) |
| | | foreach (var roadway in roadwayList) |
| | | { |
| | | if (locNum == 1) |
| | | { |
| | | /*// 查询所有相同物料货位 |
| | | var sameItemLocList = 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_CURRENT_NUM == 1 |
| | | && a.N_LOCK_STATE == 0 |
| | | && a.C_ENABLE == "Y" |
| | | && b.S_CNTR_CODE != null |
| | | && c.S_ITEM_CODE == itemCode |
| | | ) |
| | | .OrderBy((a, b, c) => new { a.N_LAYER, a.N_COL }) |
| | | .ToList(); |
| | | |
| | | // 查询相同物料的左右是否有空货位 |
| | | foreach (var loc in sameItemLocList) |
| | | { |
| | | var leftLoc = 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 (leftLoc != null) |
| | | { |
| | | locations.Add(leftLoc); |
| | | break; |
| | | } |
| | | |
| | | var rightLoc = 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 (rightLoc != null) |
| | | { |
| | | locations.Add(leftLoc); |
| | | break; |
| | | } |
| | | }*/ |
| | | |
| | | // 查询空货位 |
| | | var emptyLoc = db.Queryable<Location>().Where(a => a.S_AREA_CODE == Settings.stockArea && a.N_ROADWAY == order.roadway && a.N_CURRENT_NUM == 0 && a.N_LOCK_STATE == 0 && a.C_ENABLE == "Y").OrderBy(a => new { a.N_LAYER, a.N_COL }).First(); |
| | | var emptyLoc = db.Queryable<Location>().Where(a => a.S_AREA_CODE == Settings.stockArea && a.N_ROADWAY == roadway && a.N_CURRENT_NUM == 0 && a.N_LOCK_STATE == 0 && a.C_ENABLE == "Y").OrderBy(a => new { a.N_LAYER, a.N_COL }).First(); |
| | | if (emptyLoc != null) |
| | | { |
| | | locations.Add(emptyLoc); |
| | |
| | | |
| | | if (locNum == 2) |
| | | { |
| | | var emptyLocList = db.Queryable<Location>().Where(a => a.S_AREA_CODE == Settings.stockArea && a.N_ROADWAY == order.roadway && a.N_CURRENT_NUM == 0 && a.N_LOCK_STATE == 0 && a.C_ENABLE == "Y").OrderBy(a => new { a.N_LAYER, a.N_COL }).ToList(); |
| | | |
| | | var emptyLocList = db.Queryable<Location>().Where(a => a.S_AREA_CODE == Settings.stockArea && a.N_ROADWAY == roadway && a.N_CURRENT_NUM == 0 && a.N_LOCK_STATE == 0 && a.C_ENABLE == "Y").OrderBy(a => new { a.N_LAYER, a.N_COL }).ToList(); |
| | | if (emptyLocList.Count > 0) |
| | | { |
| | | // 查询双拖空货位 |
| | | // 优先查询相邻双拖空货位 |
| | | if (locations.Count == 0) |
| | | { |
| | | foreach (var loc in emptyLocList) |
| | | { |
| | | var leftLoc = 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(); |
| | | // 查询相邻左侧是否有空货位 |
| | | var leftLoc = db.Queryable<Location>().Where(a => a.S_AREA_CODE == Settings.stockArea && a.N_ROADWAY == 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 (leftLoc != null) |
| | | { |
| | | locations.Add(loc); |
| | |
| | | break; |
| | | } |
| | | |
| | | var rightLoc = 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(); |
| | | // 查询相邻右侧是否有空货位 |
| | | var rightLoc = db.Queryable<Location>().Where(a => a.S_AREA_CODE == Settings.stockArea && a.N_ROADWAY == 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 (rightLoc != null) |
| | | { |
| | | locations.Add(loc); |
| | | locations.Add(leftLoc); |
| | | locations.Add(rightLoc); |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (locations.Count == locNum) |
| | | if (locations.Count < locNum) |
| | | { |
| | | endLocGroup.groupNo = WMSHelper.GenerateTaskGroupNo(); |
| | | endLocGroup.endLocList = locations; |
| | | return endLocGroup; |
| | | } |
| | | } |
| | | |
| | | // 查询单拖货位 |
| | | // 查询不相邻的单拖货位 |
| | | foreach (var loc in emptyLocList) |
| | | { |
| | | locations.Add(loc); |
| | | if (locations.Count == locNum) |
| | | { |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (locations.Count == locNum) |
| | | { |
| | | endLocGroup.endLocList = locations; |
| | | // 校验货位是否是同巷道,是则生成任务组号 |
| | | var groupNum = locations.GroupBy(a => a.N_ROADWAY).Count(); |
| | | if (groupNum == 1) |
| | | { |
| | | endLocGroup.groupNo = WMSHelper.GenerateTaskGroupNo(); |
| | | } |
| | | return endLocGroup; |
| | | } |
| | | } |
| | |
| | | } |
| | | } |
| | | return endLocGroup; |
| | | }*/ |
| | | |
| | | /// <summary> |
| | | /// 查询入库终点货位 |
| | | /// 入库策略: |
| | | /// 巷道内同规格数量 小于 10(暂定),按物料均衡计算,如果所有的巷道内同规格数量都大于10,则按照巷道均衡计算 |
| | | /// </summary> |
| | | /// <param name="locNum"></param> |
| | | /// <param name="itemCode"></param> |
| | | /// <returns></returns> |
| | | public static EndLocGroup getInStockEndLoc(int locNum, string itemCode) |
| | | { |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | EndLocGroup endLocGroup = new EndLocGroup { endLocList = new List<Location>() }; |
| | | |
| | | // 1. 获取候选巷道列表(物料均衡或巷道均衡) |
| | | var candidateRoadways = GetCandidateRoadways(db, itemCode); |
| | | if (candidateRoadways.Count == 0) return endLocGroup; |
| | | |
| | | // 2. 处理单货位入库 |
| | | if (locNum == 1) |
| | | { |
| | | return FindSingleLocation(db, candidateRoadways); |
| | | } |
| | | |
| | | // 3. 处理双货位入库 |
| | | return FindDoubleLocations(db, candidateRoadways); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 获取候选巷道列表(按策略排序) |
| | | /// </summary> |
| | | private static List<int> GetCandidateRoadways(SqlSugarClient db, string itemCode) |
| | | { |
| | | // 策略1:巷道内同规格物料 < 10 的巷道(按数量升序) |
| | | var materialRoadways = 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_CURRENT_NUM == 1 && |
| | | a.N_LOCK_STATE == 0 && |
| | | a.C_ENABLE == "Y" && |
| | | b.S_CNTR_CODE != null && |
| | | c.S_ITEM_CODE == itemCode) |
| | | .GroupBy(a => a.N_ROADWAY) |
| | | .Having(a => SqlFunc.AggregateCount(a.S_CODE) < 10) |
| | | .Select(a => new { Roadway = a.N_ROADWAY, Count = SqlFunc.AggregateCount(a.S_CODE) }) |
| | | .OrderBy(a => a.Count) |
| | | .Select(a => a.Roadway) |
| | | .ToList(); |
| | | |
| | | if (materialRoadways.Count > 0) return materialRoadways; |
| | | |
| | | // 策略2:所有巷道按空货位数降序排序 |
| | | return 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, Count = SqlFunc.AggregateCount(a.S_CODE) }) |
| | | .OrderByDescending(a => a.Count) |
| | | .Select(a => a.Roadway) |
| | | .ToList(); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 查找单货位 |
| | | /// </summary> |
| | | private static EndLocGroup FindSingleLocation(SqlSugarClient db, List<int> candidateRoadways) |
| | | { |
| | | foreach (var roadway in candidateRoadways) |
| | | { |
| | | var location = db.Queryable<Location>() |
| | | .Where(a => |
| | | a.S_AREA_CODE == Settings.stockArea && |
| | | a.N_ROADWAY == roadway && |
| | | a.N_CURRENT_NUM == 0 && |
| | | a.N_LOCK_STATE == 0 && |
| | | a.C_ENABLE == "Y") |
| | | .OrderBy(a => a.N_LAYER) |
| | | .OrderBy(a => a.N_COL) |
| | | .First(); |
| | | |
| | | if (location != null) |
| | | { |
| | | return new EndLocGroup |
| | | { |
| | | endLocList = new List<Location> { location } |
| | | }; |
| | | } |
| | | } |
| | | return new EndLocGroup(); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 查找双货位(优化相邻货位查找) |
| | | /// </summary> |
| | | private static EndLocGroup FindDoubleLocations(SqlSugarClient db, List<int> candidateRoadways) |
| | | { |
| | | // 先尝试找相邻货位 |
| | | foreach (var roadway in candidateRoadways) |
| | | { |
| | | // 一次性获取巷道所有空货位(减少DB查询) |
| | | var emptyLocs = db.Queryable<Location>() |
| | | .Where(a => |
| | | a.S_AREA_CODE == Settings.stockArea && |
| | | a.N_ROADWAY == roadway && |
| | | 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(); |
| | | |
| | | if (emptyLocs.Count < 2) continue; |
| | | |
| | | // 在内存中查找相邻货位(高性能) |
| | | var adjacentPair = FindAdjacentLocations(emptyLocs); |
| | | if (adjacentPair != null) |
| | | { |
| | | return CreateDoubleLocGroup(adjacentPair); |
| | | } |
| | | } |
| | | |
| | | // 没有相邻货位时,取任意两个货位 |
| | | foreach (var roadway in candidateRoadways) |
| | | { |
| | | var emptyLocs = db.Queryable<Location>() |
| | | .Where(a => |
| | | a.S_AREA_CODE == Settings.stockArea && |
| | | a.N_ROADWAY == roadway && |
| | | a.N_CURRENT_NUM == 0 && |
| | | a.N_LOCK_STATE == 0 && |
| | | a.C_ENABLE == "Y") |
| | | .OrderBy(a => a.N_LAYER) |
| | | .OrderBy(a => a.N_COL) |
| | | .Take(2) |
| | | .ToList(); |
| | | |
| | | if (emptyLocs.Count == 2) |
| | | { |
| | | return CreateDoubleLocGroup(emptyLocs); |
| | | } |
| | | } |
| | | |
| | | return new EndLocGroup(); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 在内存中查找相邻货位(高效算法) |
| | | /// </summary> |
| | | private static List<Location> FindAdjacentLocations(List<Location> locations) |
| | | { |
| | | // 按层->列排序,便于查找相邻 |
| | | var sorted = locations |
| | | .OrderBy(l => l.N_LAYER) |
| | | .ThenBy(l => l.N_COL) |
| | | .ToList(); |
| | | |
| | | for (int i = 0; i < sorted.Count - 1; i++) |
| | | { |
| | | var current = sorted[i]; |
| | | var next = sorted[i + 1]; |
| | | |
| | | // 判断是否同一层且相邻列 |
| | | if (current.N_LAYER == next.N_LAYER && |
| | | current.N_COL + 1 == next.N_COL) |
| | | { |
| | | return new List<Location> { current, next }; |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 创建双货位返回结果 |
| | | /// </summary> |
| | | private static EndLocGroup CreateDoubleLocGroup(List<Location> locations) |
| | | { |
| | | return new EndLocGroup |
| | | { |
| | | endLocList = locations, |
| | | groupNo = locations.GroupBy(a => a.N_ROADWAY).Count() == 1 |
| | | ? WMSHelper.GenerateTaskGroupNo() |
| | | : null |
| | | }; |
| | | } |
| | | |
| | | public class EndLocGroup |
| | |
| | | |
| | | /// <summary> |
| | | /// 查询出库开始货位 |
| | | /// 计算(1.巷道不报警、2.物料状态OK、3.小于失效时间 大于等于生效时间 4.加急料先出、5.先入先出(生产时间))出库物料 |
| | | /// 1.计算(1.巷道不报警、2.物料状态OK、3.小于失效时间 大于等于生效时间 4.加急料先出、5.先入先出(生产时间))出库物料 |
| | | /// 2.同等条件下,优先取前一托货的相邻货位(暂时不做考虑,需确定先入先出(生产时间)是按天算,还是精确到时分秒) |
| | | /// </summary> |
| | | /// <param name="itemCode"></param> |
| | | /// <param name="locNum"></param> |
| | | public static StartLocGroup getOutStockStartLoc(string itemCode, int locNum ) |
| | | /// <param name="prevLoc"></param> |
| | | public static Location getOutStockStartLoc(string itemCode, Location prevLoc = null) |
| | | { |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | StartLocGroup startLocGroup = new StartLocGroup(); |
| | | Location startLoc = null; |
| | | |
| | | // 1.查询(物料状态OK ,且小于失效时间,大于等于生效时间)出库物料,并按加急料先出,先入先出(生产时间)的原则进行排序 |
| | | var query = db.Queryable<Location>() |
| | |
| | | continue; |
| | | } |
| | | |
| | | var cntrItemRel = db.Queryable<CntrItemRel>().LeftJoin<LocCntrRel>((a, b) => a.S_CNTR_CODE == b.S_CNTR_CODE).Where((a, b) => b.S_LOC_CODE == loc.S_CODE).First(); |
| | | if (cntrItemRel != null) |
| | | { |
| | | startLocGroup.startLocList.Add(loc); |
| | | if (locNum == startLocGroup.startLocList.Count) |
| | | { |
| | | break; |
| | | } |
| | | |
| | | var leftLoc = db.Queryable<Location>().Where(a => a.S_AREA_CODE == Settings.stockArea && a.N_ROADWAY == loc.N_ROADWAY && a.N_ROW == loc.N_ROW && a.N_COL == loc.N_COL - 1 && a.N_LAYER == loc.N_LAYER && a.N_CURRENT_NUM == 1 && a.N_LOCK_STATE == 0 && a.C_ENABLE == "Y").First(); |
| | | if (leftLoc != null) |
| | | { |
| | | var locCntrRel = db.Queryable<LocCntrRel>() |
| | | .LeftJoin<CntrItemRel>((a, b) => a.S_CNTR_CODE == b.S_CNTR_CODE) |
| | | .Where((a, b) => a.S_LOC_CODE == leftLoc.S_CODE && b.S_ITEM_CODE == itemCode) |
| | | .First(); |
| | | if (locCntrRel != null) |
| | | { |
| | | startLocGroup.groupNo = WMSHelper.GenerateTaskGroupNo(); |
| | | startLocGroup.startLocList.Add(leftLoc); |
| | | break; |
| | | startLoc = loc; |
| | | } |
| | | } |
| | | |
| | | var rightLoc = db.Queryable<Location>().Where(a => a.S_AREA_CODE == Settings.stockArea && a.N_ROADWAY == loc.N_ROADWAY && a.N_ROW == loc.N_ROW && a.N_COL == loc.N_COL + 1 && a.N_LAYER == loc.N_LAYER && a.N_CURRENT_NUM == 1 && a.N_LOCK_STATE == 0 && a.C_ENABLE == "Y").First(); |
| | | if (rightLoc != null && startLocGroup.startLocList.Count == 0) |
| | | { |
| | | var locCntrRel = db.Queryable<LocCntrRel>() |
| | | .LeftJoin<CntrItemRel>((a, b) => a.S_CNTR_CODE == b.S_CNTR_CODE) |
| | | .Where((a, b) => a.S_LOC_CODE == rightLoc.S_CODE && b.S_ITEM_CODE == itemCode) |
| | | .First(); |
| | | if (locCntrRel != null) |
| | | { |
| | | startLocGroup.groupNo = WMSHelper.GenerateTaskGroupNo(); |
| | | startLocGroup.startLocList.Add(rightLoc); |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | return startLocGroup; |
| | | return startLoc; |
| | | |
| | | } |
| | | |