using HH.WCS.Mobox3.HD.core; using HH.WCS.Mobox3.HD.models; using HH.WCS.Mobox3.HD.util; using HH.WCS.Mobox3.HD.wms; using Newtonsoft.Json; using SqlSugar; using System; using System.Collections.Generic; using System.Linq; using static HH.WCS.Mobox3.HD.api.ApiModel; using static HH.WCS.Mobox3.HD.api.MoboxController; using static HH.WCS.Mobox3.HD.api.OtherModel; using static HH.WCS.Mobox3.HD.api.WmsController; using static HH.WCS.Mobox3.HD.util.Settings; using static HH.WCS.Mobox3.HD.wms.WMSHelper; namespace HH.WCS.Mobox3.HD.api { /// /// api接口辅助类 /// public class ApiHelper { static ApiHelper() { } /// /// 创建任务 /// /// internal static void AddTask(AddTaskModel model) { if (!WCSHelper.CheckExist(model.No)) { if (LocationHelper.CheckExist(model.From) && LocationHelper.CheckExist(model.To)) { WCSHelper.CreateTask(model.No, model.From, model.To, "搬运", 99, ""); } } } /// /// 创建入库单主子表 /// /// /// internal static SimpleResult Putaway_Order_In(Putaway_Order_In model) { var result = new SimpleResult(); //创建入库单主子表 var po = WMSHelper.GetPutawayOrder(model.Data.arrival_no); if (po == null) { po = new PutawayOrder { S_NO = model.Data.arrival_no, S_BS_TYPE = model.Data.op_type }; po.Details = new List(); if (model.Data.items.Count > 0) { model.Data.items.ForEach(a => { po.Details.Add(new PutawayDetail { S_PUTAWAY_NO = model.Data.arrival_no, N_ROW_NO = po.Details.Count + 1, S_ITEM_CODE = a.item_code, F_QTY = a.qty, S_BATCH_NO = a.batch_no, }); }); WMSHelper.CreatePutawayOrder(po); } } return result; } /// /// 创建发货单主子表 /// /// /// internal static SimpleResult OutboundOrder(OutboundOrder model) { var result = new SimpleResult(); //创建发货单,人工点确认后生成分拣单,没有缺货的自动更新为失败,有货的更新为执行中 //创建出库单主子表 var po = WMSHelper.GetShippingOrder(model.Data.out_no); if (po == null) { po = new ShippingOrder { S_NO = model.Data.out_no, S_BS_TYPE = model.Data.op_type }; po.Details = new List(); if (model.Data.items.Count > 0) { model.Data.items.ForEach(a => { po.Details.Add(new ShippingDetail { S_SHIPPING_NO = model.Data.out_no, N_ROW_NO = po.Details.Count + 1, S_ITEM_CODE = a.item_code, F_QTY = a.qty, S_BATCH_NO = a.batch_no, }); }); WMSHelper.CreateShippingOrder(po); } } return result; } /// /// pad入库 /// /// /// internal static SimpleResult Instock(InstockInfo model) { var result = new SimpleResult(); //pda入库 //1 判断起点有没有任务,有没有入库锁 var loc = LocationHelper.GetLoc(model.start); if (loc != null && loc.N_LOCK_STATE == 0) { //2 根据终点库区计算终点 var end = WMSHelper.GetInstockEnd(model.item, model.endArea); 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 { result.resultCode = 2; result.resultMsg = "未获取到入库终点"; } } else { result.resultCode = 1; result.resultMsg = "起点有任务未完成"; } return result; } /// /// 移库 /// /// /// internal static SimpleResult shiftStock(ShiftStockInfo model) { var result = new SimpleResult(); //1 根据起点库区、排 确定起始货位 var startLoc = WMSHelper.GetShiftStockStart(model.item, model.startArea, model.startRow); if (startLoc != null && startLoc.N_LOCK_STATE == 0) { //2 根据终点库区计算终点 var end = WMSHelper.GetShiftStockEnd(model.item, model.endArea, model.startRow); 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"}; CodeInfo result = null; try { var db = new SqlHelper().GetInstance(Settings.SqlServer1); var nameP = new SugarParameter("@FBarCode", code); var orgP = new SugarParameter("@Forg", org); //var ageP = new SugarParameter("@age", null, true);//设置为output //var dt = db.Ado.UseStoredProcedure().GetDataTable("sp_school", nameP, ageP);//返回dt result = db.Ado.UseStoredProcedure().SqlQuery("WMS_FBarCode", nameP, orgP).First();//返回List Console.WriteLine($"读存储过程成功,result={result}"); } catch (Exception ex) { Console.WriteLine(ex.Message); } return result; } // ---------------------------------- 哈电 ------------------------------------- private static readonly object in_lock = new object(); /// /// 入库请求参数验证 /// /// /// public static ResponseResult inStockRequestParamVerify(InStockInfo model) { ResponseResult responseResult = new ResponseResult() { success = false }; if (model.taskType.Equals("半成品/成品入库") && (model.trayItemInfoList == null || model.trayItemInfoList.Count == 0)) { responseResult.message = "物料信息不能为空!"; return responseResult; } LocCntrRel locCntrRel = ContainerHelper.getLocCntr(model.trayCode); if (locCntrRel != null && !locCntrRel.S_LOC_CODE.Equals(model.startBit)) { responseResult.message = $"起点货位与容器货位不匹配,当前起点货位:{model.startBit},系统显示容器应该所在货位:{locCntrRel.S_LOC_CODE}"; return responseResult; } var existWmsTask = WMSHelper.GetWmsTaskByCntr(model.trayCode); if (existWmsTask != null) { responseResult.message = $"相关容器存在未完成任务【已有{existWmsTask.T_CREATE.ToString("yyyy-MM-dd HH:mm:ss")}的{existWmsTask.S_TYPE}任务】"; return responseResult; } return null; } internal static int freqFlag = 0; /// /// 按一定频率分配库区(频率 1栋立库:7栋立库:横栋立库 = 1:2:1) /// /// public static Dictionary distributeArea() { Dictionary map = new Dictionary(); List areaInfos = Settings.storeAreaInfos.Where(a => a.cargoType == 1).ToList(); int index = 0; foreach (var item in areaInfos) { for (int i = 0; i < item.frequency; i++) { map.Add(index, item.areaCode); index++; } } return map; } /// /// 查询半成品/成品入库任务终点 /// /// public static TaskEndData getInStcokTaskEnd(InStockInfo model) { TaskEndData taskEndData = new TaskEndData(); List conLocCodes = new List(); Location endLoc = null; Location firstTaskEnd = null; var map = distributeArea(); //按规定频率分配库区 string areaCode = Settings.getStoreAreaByAccessArea(model.endArea); // 优先选定库区入库 if (areaCode != null) { LogHelper.Info("车间任务号:" + JsonConvert.SerializeObject(model.taskNo), "Mobox"); conLocCodes = LocationHelper.GetConnectLocation(areaCode, 1, 1, 1, model.startArea); if (conLocCodes != null && conLocCodes.Count > 0) { foreach (var item in conLocCodes) { LogHelper.Info("接驳位:" + JsonConvert.SerializeObject(item), "Mobox"); var conLoc = LocationHelper.GetLoc(item); endLoc = WMSHelper.GetEndLocation(areaCode, model.trayItemInfoList[0].itemCode, conLoc.N_ROADWAY, conLoc.N_ROW,4); if (endLoc != null) { firstTaskEnd = conLoc; endLoc.S_CODE = "虚拟货位"; break; } } } } // 如选定库区不能入库,则选择其他库区 /*if (endLoc == null) { // TODO freqFlag = 1 freqFlag = 1; if (map.TryGetValue(freqFlag, out areaCode)) { conLocCodes = LocationHelper.GetConnectLocation(areaCode, 1, freqFlag == 2 ? 2 : 1, 1, model.startArea); if (conLocCodes != null && conLocCodes.Count > 0) { foreach (var item in conLocCodes) { var conLoc = LocationHelper.GetLoc(item); endLoc = WMSHelper.GetEndLocation(areaCode, model.trayItemInfoList[0].itemCode, conLoc.N_ROADWAY, conLoc.N_ROW); if (endLoc != null) { firstTaskEnd = conLoc; freqFlag += 1; if (freqFlag == 4) { freqFlag = 0; } break; } } } } }*/ if (endLoc != null) { // 绑定容器物料信息 model.trayItemInfoList.ForEach(it => { CntrItemRel cntrItemRel = new CntrItemRel() { S_ITEM_CODE = it.itemCode, S_ITEM_NAME = it.itemName, S_WORK_NO = it.workNo, S_WORK_NAME = it.workName, S_DEPART_NO = it.dePartNo, S_PART_TASK_ID = it.partTaskId, S_PARTDRAW_NO = it.partDrawNo, S_PART_NAME = it.partName, S_OPER_NO = it.operNo, S_OPER_NAME = it.operName, F_QTY = float.Parse(it.quantity == null ? "0" : it.quantity), F_WEIGHT = float.Parse(it.weight == null ? "0" : it.weight), S_ITEM_SPEC = it.spec, S_ITEM_TYPE = it.isFinish }; ContainerHelper.initContainer(model.trayCode); ContainerHelper.BindCntrItemSingle(model.trayCode, cntrItemRel); }); } taskEndData.endLoc = endLoc; taskEndData.firstTaskEnd = firstTaskEnd; return taskEndData; } /// /// 查询钢卷入库任务终点 /// /// /// public static TaskEndData steelCoilInStock(InStockInfo model) { TaskEndData taskEndData = new TaskEndData(); List conLocCodes = new List(); Location endLoc = null; Location firstTaskEnd = null; var coil = ItemHelper.GetCoilItemInfo(model.trayCode); if (coil != null) { coil.S_WORK_NAME = model.trayItemInfoList[0].workName; ItemHelper.UpdateCntrItemInfo(coil); ContainerHelper.addCntr(model.trayCode); } else { return null; } endLoc = new Location() { S_CODE = "虚拟库位", S_AREA_CODE = "虚拟库区" }; List gjkAreaCodes = Settings.getStoreAreaCodes(1, 2); foreach (var gjArea in gjkAreaCodes) { var connectLoc = LocationHelper.GetConnectLocation(gjArea, 1).FirstOrDefault(); if (connectLoc != null) { firstTaskEnd = LocationHelper.GetLoc(connectLoc); break; } } taskEndData.endLoc = endLoc; taskEndData.firstTaskEnd = firstTaskEnd; return taskEndData; } /// /// 查询空盘垛入库终点 /// /// /// public static TaskEndData emptyTrayInStock(InStockInfo model) { TaskEndData taskEndData = new TaskEndData(); List conLocCodes = new List(); Location endLoc = null; Location firstTaskEnd = null; var map = distributeArea(); //按规定频率分配库区 string areaCode = Settings.getStoreAreaByAccessArea(model.endArea); if (freqFlag == 4 || freqFlag % 4 == 3) { freqFlag = 0; } if (map.TryGetValue(freqFlag, out areaCode)) { conLocCodes = LocationHelper.GetConnectLocation(areaCode, 1, 1, 1); foreach (var item in conLocCodes) { var conLoc = LocationHelper.GetLoc(item); endLoc = WMSHelper.GetEndLocation(areaCode, null, conLoc.N_ROADWAY, conLoc.N_ROW); if (endLoc != null) { firstTaskEnd = conLoc; endLoc.S_CODE = "虚拟货位"; break; } } } freqFlag += 1; taskEndData.endLoc = endLoc; taskEndData.firstTaskEnd = firstTaskEnd; return taskEndData; } /// /// 查询模具入库终点 /// /// /// public static TaskEndData mouldInStock(InStockInfo model) { TaskEndData taskEndData = new TaskEndData(); Location endLoc = null; Location firstTaskEnd = null; MouldCntr mouldCntr = MouldHelper.GetMouldCntr(new MouldCntr() { S_CNTR_CODE = model.trayCode }); if (mouldCntr != null) { ContainerHelper.addCntr(model.trayCode); endLoc = LocationHelper.GetLocation(mouldCntr.S_LOC_CODE); firstTaskEnd = endLoc; } taskEndData.endLoc = endLoc; taskEndData.firstTaskEnd = firstTaskEnd; return taskEndData; } /// /// /// /// /// public static TaskEndData finishInStockTemporaryArea(InStockInfo model) { TaskEndData taskEndData = new TaskEndData(); Location endLoc = null; Location firstTaskEnd = null; if (model.endArea != null) { endLoc = WMSHelper.GetDeliverEndLocation(model.endArea); } if (endLoc == null) { List areaCodes = Settings.getDispatchAreaCodes(); foreach (var item in areaCodes) { endLoc = WMSHelper.GetDeliverEndLocation(item); if (endLoc != null) { break; } } } firstTaskEnd = endLoc; if (endLoc != null) { // 绑定容器物料信息 model.trayItemInfoList.ForEach(it => { CntrItemRel cntrItemRel = new CntrItemRel() { S_ITEM_CODE = it.itemCode, S_ITEM_NAME = it.itemName, S_WORK_NO = it.workNo, S_WORK_NAME = it.workName, S_DEPART_NO = it.dePartNo, S_PARTDRAW_NO = it.partDrawNo, S_PART_NAME = it.partName, S_OPER_NO = it.operNo, S_OPER_NAME = it.operName, F_QTY = float.Parse(it.quantity == null ? "0" : it.quantity), F_WEIGHT = float.Parse(it.weight == null ? "0" : it.weight), S_ITEM_SPEC = it.spec, S_ITEM_TYPE = it.isFinish }; ContainerHelper.BindCntrItemSingle(model.trayCode, cntrItemRel); }); } taskEndData.endLoc = endLoc; taskEndData.firstTaskEnd = firstTaskEnd; return taskEndData; } public class TaskEndData { public Location endLoc { get; set; } public Location firstTaskEnd { get; set; } } /// /// 创建入库搬运任务 /// * 钢卷\模具入库需要传起点库位 /// * 任务类型分为 半成品/成品入库 、钢卷入库 、模具入库、模具托盘回库 /// * 半成品/成品入库 横栋、1栋、7栋的分配频率为 1:1:2 /// /// /// internal static ResponseResult createInOrder(InStockInfo model) { ResponseResult responseResult = new ResponseResult() { success = true }; InStockRetureData retureData = new InStockRetureData(){ startStationCode = model.startBit,startAreaCode = model.startArea }; var response = inStockRequestParamVerify(model); // 参数验证 if (response != null) { return response; } var map = distributeArea(); //按规定频率分配库区 Location startLoc = LocationHelper.GetLoc(model.startBit); Location endLoc = null; Location firstTaskEnd = null; // 一阶段任务终点 TaskEndData taskEndData = null; List conLocCodes = new List(); lock (in_lock) { switch (model.taskType) { case "半成品/成品入库": taskEndData = getInStcokTaskEnd(model); if (taskEndData.firstTaskEnd == null) { responseResult.success = false; responseResult.message = "当前区域无可用接驳位,请排查"; return responseResult; } break; case "钢卷入库": taskEndData = steelCoilInStock(model); break; case "模具入库": case "模具托盘入库": taskEndData = mouldInStock(model); break; case "空盘垛入库": taskEndData = emptyTrayInStock(model); break; case "成品入库备货区": taskEndData = finishInStockTemporaryArea(model); break; default: responseResult.success = false; responseResult.message = "没有相应的任务类型"; return responseResult; } } if (startLoc == null) { if (model.taskType.Contains("模具") || model.taskType.Contains("钢卷")) { responseResult.success = false; responseResult.message = "开始货位未指定或不存在"; return responseResult; } startLoc = new Location() { S_CODE = model.startBit, S_AREA_CODE = model.startArea }; } else { if (startLoc.N_LOCK_STATE != 0) { responseResult.success = false; responseResult.message = "开始货位已上锁"; return responseResult; } } if (taskEndData != null) { endLoc = taskEndData.endLoc; firstTaskEnd = taskEndData.firstTaskEnd; } // 2.创建入库作业任务 if (endLoc != null ) { var wmsTask = new WMSTask() { S_CNTR_CODE = model.trayCode, 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 = model.taskType, S_OP_DEF_CODE = model.taskNo, S_OP_DEF_NAME = "入库搬运任务", N_PRIORITY = model.taskPri == null ? 1 : int.Parse(model.taskPri), T_START_TIME = DateTime.Now, }; if (WMSHelper.CreateWmsTask(wmsTask)) { string S_SCHEDULE_TYPE = "HL"; if (model.taskType.Equals("半成品/成品入库") || model.taskType.Equals("空盘垛入库") || model.taskType.Equals("成品入库备货区")) { S_SCHEDULE_TYPE = "LD-AUTO"; } // 创建一段入库任务 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 + "-1", S_START_LOC = startLoc.S_CODE, S_START_AREA = startLoc.S_AREA_CODE, S_END_LOC = firstTaskEnd.S_CODE, S_END_AREA = firstTaskEnd.S_AREA_CODE, S_SCHEDULE_TYPE = S_SCHEDULE_TYPE, N_PRIORITY = 1, T_START_TIME = DateTime.Now, }; if (WCSHelper.CreateTask(wcsTask)) { // 起点、接驳点、终点加锁 LocationHelper.LockLoc(wcsTask.S_START_LOC, 2); LocationHelper.LockLoc(firstTaskEnd.S_CODE, 1); // 更新作业任务状态 wmsTask.N_B_STATE = 1; WMSHelper.UpdateTaskState(wmsTask); } retureData.wmsId = wmsTask.S_CODE; retureData.endStationCode = firstTaskEnd.S_CODE; retureData.endAreaCode = firstTaskEnd.S_AREA_CODE; responseResult.result = retureData; } } else { responseResult.success = false; responseResult.message = "未获取到终点库位,剩余货位不足"; } return responseResult; } private static readonly object out_lock = new object(); /// /// 移库(立库出库阻塞) /// /// /// /// public static bool shiftStock(Location outLoc,string wmsTaskId) { bool result = false; string outCntrCode = ContainerHelper.getLocCntrByLoc(outLoc.S_CODE).S_CNTR_CODE; var cntrItemRels = ItemHelper.GetCntrItemByCntrCode(outCntrCode); string itemCode = null; if(cntrItemRels != null && cntrItemRels.Count > 0) { itemCode = cntrItemRels[0].S_ITEM_CODE; } Location inLoc = WMSHelper.GetEndLocation(outLoc.S_AREA_CODE, itemCode, outLoc.N_ROADWAY, 1); // 进行移库操作 if (inLoc != null) { var shiftWcsTask = new WCSTask { S_CODE = WCSHelper.GenerateTaskNo(), S_TYPE = "移库", S_START_LOC = outLoc.S_CODE, S_START_AREA = outLoc.S_AREA_CODE, S_END_LOC = inLoc.S_CODE, S_END_AREA = inLoc.S_AREA_CODE, S_CNTR_CODE = outCntrCode, S_SCHEDULE_TYPE = "RB", S_OP_CODE = wmsTaskId, S_EQ_NO = getEqNo(outLoc.S_AREA_CODE, outLoc.N_ROADWAY), N_PRIORITY = 9, T_START_TIME = DateTime.Now, }; if (WCSHelper.CreateTask(shiftWcsTask)) { LocationHelper.LockLoc(outLoc.S_CODE, 2); LocationHelper.LockLoc(inLoc.S_CODE, 1); result = true; } } return result; } /// /// 创建出库搬运任务 /// *钢卷/模具出库需要指定终点 /// /// /// internal static ResponseResult createOutOrder(OutStockInfo model) { ResponseResult responseResult = new ResponseResult(){success = false}; Location endLoc = LocationHelper.GetLoc(model.endBit); if (endLoc == null) { if (model.taskType.Contains("模具") || model.taskType.Contains("钢卷")) { responseResult.message = "终点货位未指定或不存在"; return responseResult; } endLoc = new Location() { S_CODE = model.endBit, S_AREA_CODE = model.endArea }; } else { if (endLoc.N_LOCK_STATE != 0) { responseResult.message = "终点货位已上锁"; return responseResult; } } Location startLoc = null; Location firstTaskEnd = null; ItemStartLoc itemStartLoc = new ItemStartLoc(); MouldCntr mouldCntr = null; // 1、查询开始货位、终点货位 lock (out_lock) { switch (model.taskType) { case "半成品/成品出库": itemStartLoc = WMSHelper.GetStartLocation(model.itemCode, model.partTaskId, model.workNo, null, model.endArea); if (itemStartLoc.type != 0) { startLoc = itemStartLoc.loc; firstTaskEnd = itemStartLoc.connectloc; if (startLoc != null && firstTaskEnd == null) { responseResult.message = "堆垛机或输送线设备可能存在故障,请排查"; return responseResult; } } else { responseResult.message = "库区没有该物料"; return responseResult; } break; case "钢卷出库": startLoc = WMSHelper.GetGJStartLocation(model.itemCode, model.coilNo, model.workNo, model.weight, model.width); break; case "模具出库": var mouldCntrs = MouldHelper.GetMouldCntrList(new MouldCntr() { S_ITEM_CODE = model.itemCode, S_MOULD_NO = model.itemCode }); if (mouldCntrs != null && mouldCntrs.Count > 0) { mouldCntr = mouldCntrs[0]; startLoc = LocationHelper.GetLocation(mouldCntr.S_LOC_CODE); if (startLoc.N_LOCK_STATE != 0 || startLoc.N_CURRENT_NUM == 0) { responseResult.message = "模具库位已出库或已上锁"; return responseResult; } } break; case "模具托盘出库": mouldCntr = MouldHelper.GetMouldCntr(new MouldCntr() { S_ITEM_CODE = model.itemCode, S_MOULD_NO = model.itemCode }); if (mouldCntr != null) { startLoc = LocationHelper.GetLocation(mouldCntr.S_LOC_CODE); if (startLoc.N_LOCK_STATE != 0 || startLoc.N_CURRENT_NUM == 0) { responseResult.message = "模具托盘已出库或已上锁"; return responseResult; } } break; case "叫托盘出库": if (model.trayCode != null) { itemStartLoc = WMSHelper.GetStartLocationByTrayCode(model.trayCode, model.endArea); if (itemStartLoc.type != 0) { startLoc = itemStartLoc.loc; firstTaskEnd = itemStartLoc.connectloc; } else { responseResult.message = "该托盘处于不可用状态:锁定、禁用、阻塞、不存在"; return responseResult; } } else { responseResult.message = "托盘号不能为空"; return responseResult; } break; case "空盘垛出库": itemStartLoc = WMSHelper.GetStartLocation(null, null, null, null,model.endArea); if (itemStartLoc.type != 0) { startLoc = itemStartLoc.loc; firstTaskEnd = itemStartLoc.connectloc; } else { responseResult.message = "库区没有该物料"; return responseResult; } break; } if (startLoc == null){ responseResult.message = "未找到符合出库条件的物料"; return responseResult; } // 2、创建出库作业任务 string cntrCode = null; LocCntrRel locCntrRel = ContainerHelper.getLocCntrByLoc(startLoc.S_CODE); if (locCntrRel != null){ cntrCode = locCntrRel.S_CNTR_CODE; } var existWmsTask = WMSHelper.GetWmsTaskByCntr(cntrCode); if (existWmsTask != null){ responseResult.message = "相关容器存在未完成任务"; return responseResult; } Location externalTaskStartLoc = null; // 模具钢卷出库只有一段任务 if (model.taskType.Contains("模具") || model.taskType.Contains("钢卷")) { externalTaskStartLoc = startLoc; firstTaskEnd = endLoc; } else { if (firstTaskEnd != null) { externalTaskStartLoc = LocationHelper.GetLoc(WCSHelper.GetLinePlcInfoByLoc(firstTaskEnd.S_CODE).descLocation); } } WMSTask wmsTask = null; if (firstTaskEnd != null) { 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 = model.taskType, S_OP_DEF_CODE = model.taskNo, S_OP_DEF_NAME = "出库搬运任务", N_PRIORITY = int.Parse(model.taskPri), T_START_TIME = DateTime.Now}; LogHelper.Info($"开始创建作业任务,创建时间:" + DateTime.Now, "车间控制器"); if (WMSHelper.CreateWmsTask(wmsTask)){ LogHelper.Info($"创建作业任务完成,创建时间:" + DateTime.Now, "车间控制器"); // 物料不可取货位,需先进行移库 if ((model.taskType.Equals("半成品/成品出库") || model.taskType.Equals("空盘垛出库") || model.taskType.Equals("叫托盘出库")) && itemStartLoc.type == 2){ bool shiftResult = shiftStock(itemStartLoc.outLoc,wmsTask.S_CODE); if (!shiftResult) { wmsTask.N_B_STATE = 3; WMSHelper.UpdateTaskState(wmsTask); responseResult.message = "取货阻塞且巷道两边货物已满,无法取货"; return responseResult; } } // 查询立体库库区 string S_SCHEDULE_TYPE = null; List areaCodes = Settings.getStoreAreaCodes(2, 1); if (areaCodes.Contains(startLoc.S_AREA_CODE)){ S_SCHEDULE_TYPE = "RB"; /* string firstEndLoc = WCSHelper.GetLinePlcInfoByDesc(firstTaskEnd.S_CODE).localtion; firstTaskEnd = LocationHelper.GetLoc(firstEndLoc);*/ } else{ S_SCHEDULE_TYPE = "HL"; } var wcsTask = new WCSTask{ S_OP_NAME = wmsTask.S_OP_DEF_NAME, S_CODE = WCSHelper.GenerateTaskNo(), S_TYPE = wmsTask.S_TYPE + "-1", S_START_LOC = startLoc.S_CODE, S_START_AREA = startLoc.S_AREA_CODE, S_END_LOC = firstTaskEnd.S_CODE, S_END_AREA = firstTaskEnd.S_AREA_CODE, S_CNTR_CODE = cntrCode, S_SCHEDULE_TYPE = S_SCHEDULE_TYPE, S_OP_CODE = wmsTask.S_CODE, S_EQ_NO = getEqNo(startLoc.S_AREA_CODE, startLoc.N_ROADWAY), N_PRIORITY = 1, T_START_TIME = DateTime.Now}; LogHelper.Info($"开始创建任务,创建时间:" + DateTime.Now, "车间控制器"); if (WCSHelper.CreateTask(wcsTask)){ LogHelper.Info($"创建任务完成,创建时间:" + DateTime.Now, "车间控制器"); // 开始货位、终点货位进行加锁 LocationHelper.LockLoc(startLoc.S_CODE, 2); LocationHelper.LockLoc(firstTaskEnd.S_CODE, 1); LocationHelper.LockLoc(endLoc.S_CODE, 1); // 更新作业任务状态 wmsTask.N_B_STATE = 1; WMSHelper.UpdateTaskState(wmsTask); } } } else{ responseResult.message = "接驳位处于锁定状态,请联系管理人员解锁"; return responseResult; } // 3、组装返回数据 return assembleResponseData(externalTaskStartLoc, endLoc, model.taskType, wmsTask); } } /// /// 组装返回数据 /// /// /// /// /// /// public static ResponseResult assembleResponseData(Location externalTaskStartLoc,Location endLoc ,string taskType ,WMSTask wmsTask ) { ResponseResult responseResult = new ResponseResult() { success = true }; OutStockReturnData outStockReturnData = new OutStockReturnData() { startStationCode = externalTaskStartLoc.S_CODE, startAreaCode = externalTaskStartLoc.S_AREA_CODE, endStationCode = endLoc.S_CODE, endAreaCode = endLoc.S_AREA_CODE, wmsId = wmsTask.S_CODE }; List trayItemInfos = new List(); if ("模具出库".Equals(taskType) || "模具托盘出库".Equals(taskType)) { MouldCntr mouldCntr = MouldHelper.GetMouldCntr(new MouldCntr() { S_CNTR_CODE = wmsTask.S_CNTR_CODE }); foreach (var item in mouldCntr.mouldDetails) { TrayItemInfoRes trayItemInfo = new TrayItemInfoRes() { trayCode = mouldCntr.S_CNTR_CODE, itemCode = item.S_MOULD_NO, itemName = item.S_NAME, quantity = item.N_QTY.ToString() }; trayItemInfos.Add(trayItemInfo); } } else { List cntrItemRels = ContainerHelper.GetCntrItemRel(wmsTask.S_CNTR_CODE); foreach (var item in cntrItemRels) { TrayItemInfoRes trayItemInfo = new TrayItemInfoRes() { trayCode = item.S_CNTR_CODE, workNo = item.S_WORK_NO, dePartNo = item.S_DEPART_NO, partTaskId = item.S_PART_TASK_ID, partDrawNo = item.S_PARTDRAW_NO, partName = item.S_PART_NAME, operNo = item.S_OPER_NO, operName = item.S_OPER_NAME, itemCode = item.S_ITEM_CODE, itemName = item.S_ITEM_NAME, spec = item.S_ITEM_SPEC, quantity = item.F_QTY.ToString(), weight = item.F_WEIGHT.ToString(), width = item.S_WIDTH, isFinish = item.S_ITEM_TYPE, }; trayItemInfos.Add(trayItemInfo); } } outStockReturnData.trayItemInfo = trayItemInfos; responseResult.result = outStockReturnData; return responseResult; } /// /// 获取堆垛机设备号 /// /// /// /// public static string getEqNo(string areaCode,int roadWay) { DevicePlcInfo devicePlcInfo = Settings.devicePlcInfos.Where(a => a.area == areaCode && a.roadway == roadWay).FirstOrDefault(); if (devicePlcInfo != null) { return devicePlcInfo.deviceNo; } return null; } /// /// 钢卷入库 /// /// /// public static SimpleResult steelCoilIntoStorage(SteelCoilInStockInfo model) { SimpleResult result = new SimpleResult(); var startLoc = LocationHelper.GetLoc(model.locCode); if (startLoc == null ) { result.resultCode = 1; result.resultMsg = "开始货位不存在"; return result; } var mst = WMSHelper.GetWmsTaskByCntr(model.coilNo); if (mst != null) { result.resultCode = 1; result.resultMsg = "该钢卷存在执行中的任务"; return result; } var coil = ItemHelper.GetCoilItemInfo(model.coilNo); if (coil != null) { var gjWeight = WCSCore.getGjWeight(model.locCode, model.coilNo); if (gjWeight == 0) { result.resultCode = 1; result.resultMsg = "钢卷重量为0"; return result; } Location endLoc = WMSHelper.GetGJEndLocation(gjWeight); if ( endLoc != null) { var wmsTask = new WMSTask() { S_CNTR_CODE = model.coilNo, 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_NAME = "入库搬运任务", N_PRIORITY = 1, }; if (WMSHelper.CreateWmsTask(wmsTask)) { var wcsTask = new WCSTask { S_OP_CODE = wmsTask.S_CODE, S_OP_NAME = wmsTask.S_OP_DEF_NAME, S_CODE = WCSHelper.GenerateTaskNo(), 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_CNTR_CODE = model.coilNo, S_SCHEDULE_TYPE = "HL", }; if (WCSHelper.CreateTask(wcsTask)) { // 开始货位、终点货位进行加锁 LocationHelper.LockLoc(startLoc.S_CODE, 2); LocationHelper.LockLoc(endLoc.S_CODE, 1); wmsTask.N_B_STATE = 1; WMSHelper.UpdateTaskState(wmsTask); } } } else { result.resultCode = 1; result.resultMsg = "没有可入的钢卷货位"; } } else { result.resultCode = 1; result.resultMsg = "未查询到钢卷信息"; } return result; } /// /// 初始化模具 /// /// public static void initMould(mouldModel model) { var oldMouldCntr = MouldHelper.GetMouldCntrByCntr(model.trayCode); if (oldMouldCntr != null) { MouldHelper.deleteMouldByCntr(model.trayCode); } MouldCntr mouldCntr = new MouldCntr() { S_ITEM_CODE = model.itemCode, S_CNTR_CODE = model.trayCode, S_MOULD_NO = model.mouldNo, S_MOULD_TYPE = model.mouldType, S_LOC_CODE = model.locCode, S_ABLE_FLAG = model.ableFlag }; MouldHelper.addMould(mouldCntr); ContainerHelper.addCntr(mouldCntr.S_CNTR_CODE); List mouldDetails = new List(); MouldDetail aMouldDetail = new MouldDetail() { S_MOULD_NO = model.mouldNo, S_NAME = "主片模块", N_INIT_QTY = model.aMouldNum, N_QTY = model.aMouldNum, }; mouldDetails.Add(aMouldDetail); MouldDetail bMouldDetail = new MouldDetail() { S_MOULD_NO = model.mouldNo, S_NAME = "项号片模块", N_INIT_QTY = model.bMouldNum, N_QTY = model.bMouldNum, }; mouldDetails.Add(bMouldDetail); MouldDetail cMouldDetail = new MouldDetail() { S_MOULD_NO = model.mouldNo, S_NAME = "冲头", N_INIT_QTY = model.cMouldNum, N_QTY = model.cMouldNum, }; mouldDetails.Add(cMouldDetail); MouldHelper.batchAddChildMould(mouldDetails); } /// /// 初始化模具 /// /// /// 主片模块 /// 项号片模块 /// 冲头 public static void updateMouldNum(string mouldNo , int aMouldNum ,int bMouldNum ,int cMouldNum) { List mouldDetails = MouldHelper.GetMouldDetails(mouldNo); if (mouldDetails != null && mouldDetails.Count > 0) { foreach (var detail in mouldDetails) { if (detail.S_NAME == "主片模块") { detail.N_QTY = aMouldNum; } if (detail.S_NAME == "项号片模块") { detail.N_QTY = bMouldNum; } if (detail.S_NAME == "冲头") { detail.N_QTY = cMouldNum; } } MouldHelper.updateMouldNum(mouldDetails); } } public class AddTaskModel { public string From { get; set; } public string To { get; set; } public string No { get; set; } } public class TN_LocationModel { public string TN_Location { get; set; } } public class CodeInfo { /// /// 生产订单内码 /// public string FInterID { get; set; } /// /// 生产订单编号 /// public string FSourceNo { get; set; } /// /// 批号 /// public string FGMPBatchNo { get; set; } public string FState { get; set; } /// /// 物料编码(内码就是编码) /// public string Fitemid_XK { get; set; } /// /// 分录id /// public string Fentryid { get; set; } } public class NoteInfo : CodeInfo { public string WmsBillNo { get; set; } } } }