using HH.WCS.DaYang.device; using HH.WCS.DaYang.process; using HH.WCS.DaYang.util; using HH.WCS.DaYang.wms; using Newtonsoft.Json; using NLog.Fluent; using Opc.Ua; using SqlSugar; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using static HH.WCS.DaYang.api.ApiModel; using static HH.WCS.DaYang.api.OtherModel; namespace HH.WCS.DaYang.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 PalletSorting(PalletSorting model) { var result = new SimpleResult(); //校验入库单数量,不可以超,成功后插入托盘物料表,更新入库单累计数量 //也可以直接lua查询入库单数量,做校验 var info = WMSHelper.GetPutawayOrderDetail(model.arrival_no, model.item_code); if (info != null) { if (info.F_QTY - info.F_ACC_B_QTY >= model.qty) { // 插入到托盘明细表 var cntr = ContainerHelper.GetCntr(model.cntr_code, true); if (cntr != null) { ContainerHelper.BindCntrItem(cntr, model.item_code, info.S_BATCH_NO, model.qty, model.arrival_no); //更新入库单累计绑定数量 info.F_ACC_B_QTY += model.qty; WMSHelper.UpdatePutawayOrderDetailQty(info); } else { result.resultCode = 2; result.resultMsg = "获取托盘信息失败"; } } else { result.resultCode = 1; result.resultMsg = "累计码盘数量超出入库单数量"; } } else { result.resultCode = 3; result.resultMsg = $"未找到入库单{model.arrival_no}"; } 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; } private static object lockObj = new object(); /// /// 创建任务 /// /// /// internal static Result createtask(CreateTaskModel model) { Result result = new Result { Code = 0, Msg = "创建成功" }; if (model == null) { result.Code = -1; result.Msg = "入参为空"; return result; } var db = new SqlHelper().GetInstance(); // string start = model.startBit; Location endloc = new Location(); Location startloc = new Location(); string Type = ""; lock (lockObj) { try { // 1 空托回库 if (model.TaskType.Trim() == "1") { Type = "空托入库"; #region 获取起点信息 startloc = LocationHelper.GetLoc(model.startBit); if (startloc == null) { result.Code = -1; result.Msg = $"根据起点:{model.startBit}未找到货位信息"; LogHelper.Info($"creattask:{result.Msg}"); return result; } else { if (startloc.N_LOCK_STATE != 0) { result.Code = -1; result.Msg = $"起点:{model.startBit}货位存在任务,该货位不允许再呼叫,请等待任务完成"; LogHelper.Info($"creattask:{result.Msg}"); return result; } if (startloc.N_CURRENT_NUM == 0) { result.Code = -1; result.Msg = $"起点:{model.startBit}货位不存在托盘,不允许下发任务"; LogHelper.Info($"creattask:{result.Msg}"); return result; } } #endregion #region 计算立库终点 endloc = LocationHelper.InStorage(""); if (endloc == null) { result.Code = -1; result.Msg = $"未计算到立库终点货位,请检查货位情况"; LogHelper.Info($"creattask:{result.Msg}"); return result; } #endregion #region 创建作业 if (startloc != null && endloc != null) { //获取托盘 var Cntr = db.Queryable().Where(a => a.S_LOC_CODE.Trim() == startloc.S_CODE).First(); if (Cntr == null) { result.Code = -1; result.Msg = $"根据起点:{startloc.S_CODE}未找到托盘货位绑定关系"; LogHelper.Info($"creattask:{result.Msg}"); return result; } //创建作业 var wcsTask = new WMSTask { S_CODE = WMSHelper.GenerateTaskNo(), S_TYPE = Type, N_TYPE = int.Parse(model.TaskType), S_START_LOC = startloc.S_CODE, S_END_LOC = endloc.S_CODE, S_CNTR_CODE = Cntr.S_CNTR_CODE, S_END_WH = endloc.S_WH_CODE, S_START_WH = startloc.S_WH_CODE, S_START_AREA = startloc.S_AREA_CODE, S_END_AREA = endloc.S_AREA_CODE, }; LogHelper.Info("创建作业:" + JsonConvert.SerializeObject(wcsTask), "CreateTask"); if (WMSHelper.CreateTask(wcsTask)) { LocationHelper.LockLoc(startloc.S_CODE, 2); LocationHelper.LockLoc(endloc.S_CODE, 1); LogHelper.Info("创建作业成功"); //空托回库成功,如果存在物料数据,删除 var itemcntr = db.Queryable().Where(a => a.S_CNTR_CODE.Trim() == Cntr.S_CNTR_CODE).First(); if (itemcntr != null) { db.Deleteable().Where(a => a.S_CNTR_CODE.Trim() == Cntr.S_CNTR_CODE).ExecuteCommand(); } LogHelper.Info("创建任务成功"); } } #endregion } // 2 出库 else if (model.TaskType.Trim() == "2") { Type = "出库"; #region 获取终点信息 endloc = LocationHelper.GetLoc(model.endBit); if (endloc == null) { result.Code = -1; result.Msg = $"根据终点:{model.startBit}未找到货位信息"; LogHelper.Info($"creattask:{result.Msg}"); return result; } else { if (endloc.N_LOCK_STATE != 0) { result.Code = -1; result.Msg = $"终点:{model.startBit}货位存在任务,该货位不允许再呼叫,请等待任务完成"; LogHelper.Info($"creattask:{result.Msg}"); return result; } if (endloc.N_CURRENT_NUM == 0) { result.Code = -1; result.Msg = $"起点:{model.startBit}货位不存在托盘,不允许下发任务"; LogHelper.Info($"creattask:{result.Msg}"); return result; } } #endregion #region 根据物料计算出库托盘,先进先出,优先出外侧 //先计算内侧货位,判断是否有单组托盘 var location = LocationHelper.GetLocByItemCodeOrderyTime("YCLLKQ", model.ItemCode); if (location != null) { startloc = location; } else { result.Code = -1; result.Msg = $"根据物料:{model.ItemCode}未找到库存托盘,或货位有锁,数量存在问题,请检查货位表"; LogHelper.Info($"creattask:{result.Msg}"); return result; } #endregion #region 创建作业 if (startloc != null && endloc != null) { //获取托盘 var Cntr = db.Queryable().Where(a => a.S_LOC_CODE.Trim() == startloc.S_CODE).First(); if (Cntr == null) { result.Code = -1; result.Msg = $"根据起点:{startloc.S_CODE}未找到托盘货位绑定关系"; LogHelper.Info($"creattask:{result.Msg}"); return result; } //创建作业 var wcsTask = new WMSTask { S_CODE = WMSHelper.GenerateTaskNo(), S_TYPE = Type, N_TYPE = int.Parse(model.TaskType), S_START_LOC = startloc.S_CODE, S_END_LOC = endloc.S_CODE, S_CNTR_CODE = Cntr.S_CNTR_CODE, S_END_WH = endloc.S_WH_CODE, S_START_WH = startloc.S_WH_CODE, S_START_AREA = startloc.S_AREA_CODE, S_END_AREA = endloc.S_AREA_CODE, }; LogHelper.Info("创建作业:" + JsonConvert.SerializeObject(wcsTask), "CreateTask"); if (WMSHelper.CreateTask(wcsTask)) { LocationHelper.LockLoc(startloc.S_CODE, 2); LocationHelper.LockLoc(endloc.S_CODE, 1); LogHelper.Info("创建作业成功"); } } #endregion } else { result.Code = -1; result.Msg = $"任务类型有误,{model.TaskType}任务类型不是规定任务类型"; LogHelper.Info($"creattask:{result.Msg}"); return result; } return result; } catch (Exception ex) { result.Code = -1; result.Msg = $"{ex.ToString()}"; return result; } } } /// /// 设备信号反馈 /// /// /// internal static Result NotifyDeviceSignal(NotifyDeviceSignalModel model) { Result result = new Result { Code = 0, Msg = "创建成功" }; if (model == null) { result.Code = -1; result.Msg = "入参为空"; return result; } Location endloc = new Location(); Location startloc = new Location(); string cntrcode = model.CntrNo; string DiePanLoc = "CPDPJ-1-1"; // string itemCode = ""; var db = new SqlHelper().GetInstance(); if (model.DeviceNo == "1")//叠盘机 { if (model.SignalType == 1) { //判断设备状态是否属于叠盘状态 var DeviceStatu = db.Queryable().Where(a => a.DEVICENO == model.DeviceNo).First(); if (DeviceStatu != null && DeviceStatu.STATUS == "1") { #region 获取起点信息,并判断空托是否叠满 //根据起点 获取绑定托盘数量 //var CntrLoc = db.Queryable().Where(a => a.S_LOC_CODE == model.Loc).ToList(); //if (CntrLoc.Count < 4) //{ // result.Code = -1; // result.Msg = $"根据货位:{model.Loc}获取托盘数量小于4"; // LogHelper.Info($"EquipmentInfo:{result.Msg}"); // return result; //} //else //{ // //拼接托盘号 // cntrcode = CntrLoc.Select(a => a.S_CNTR_CODE).ToString(); //} cntrcode = model.CntrNo; //if (ContainerHelper.CheckEmpty(cntrcode)) //{ // result.Code = -1; // result.Msg = $"托盘:{cntrcode}已经绑定货位,叠盘机"; // LogHelper.Info($"EquipmentInfo:{result.Msg}"); // return result; //} var containern = db.Queryable().Where(a => a.S_CODE.Trim() == cntrcode).First(); if (containern == null) { ContainerHelper.AddCntr(cntrcode, "2"); } else { containern.S_SOURCE = "2"; db.Updateable(containern).UpdateColumns(a => new { a.S_SOURCE }).ExecuteCommand(); } startloc = LocationHelper.GetLoc(model.Loc); if (startloc == null) { result.Code = -1; result.Msg = $"根据起点:{model.Loc}未找到货位信息"; LogHelper.Info($"EquipmentInfo:{result.Msg}"); return result; } #endregion #region 计算立库终点 endloc = LocationHelper.InStorage(""); if (endloc == null) { result.Code = -1; result.Msg = $"未计算到立库终点货位,请检查货位情况"; LogHelper.Info($"EquipmentInfo:{result.Msg}"); return result; } #endregion #region 创建作业 if (startloc != null && endloc != null) { var wcsTask = new WMSTask { S_CODE = WMSHelper.GenerateTaskNo(), S_TYPE = "叠盘机入库", N_TYPE = 3, S_START_LOC = startloc.S_CODE, S_END_LOC = endloc.S_CODE, S_START_WH = startloc.S_WH_CODE, S_START_AREA = startloc.S_AREA_CODE, S_END_WH = endloc.S_WH_CODE, S_END_AREA = endloc.S_AREA_CODE, S_CNTR_CODE = cntrcode }; LogHelper.Info("创建入平库作业:" + JsonConvert.SerializeObject(wcsTask)); if (WMSHelper.CreateTask(wcsTask)) { LocationHelper.LockLoc(startloc.S_CODE, 2); LocationHelper.LockLoc(endloc.S_CODE, 1); LogHelper.Info("创建作业成功"); } } #endregion } else { result.Code = -1; result.Msg = $"当前叠盘机状态不属于叠盘状态,不允许空托入库"; LogHelper.Info($"EquipmentInfo:{result.Msg}"); return result; } } else if (model.SignalType == 2) { //判断设备状态是否属于叠盘状态 var DeviceStatu = db.Queryable().Where(a => a.DEVICENO == model.DeviceNo).First(); if (DeviceStatu != null && DeviceStatu.STATUS == "2") { #region 获取叠盘机托盘数量 endloc = LocationHelper.GetLoc(DiePanLoc); if (endloc == null) { result.Code = -1; result.Msg = $"根据叠盘货位:{DiePanLoc}未找到货位信息"; LogHelper.Info($"EquipmentInfo:{result.Msg}"); return result; } #endregion #region 计算数量 if (endloc.N_CURRENT_NUM > 0 && endloc.N_CURRENT_NUM < 4) { startloc = LocationHelper.GetLocByItemCodeOrderyTime("YCLLKQ", null); } else { startloc = LocationHelper.GetLocByItemCodeOrderyTime("YCLLKQ", null, "2"); if (startloc == null) { startloc = LocationHelper.GetLocByItemCodeOrderyTime("YCLLKQ", null); } } if (startloc == null) { result.Code = -1; result.Msg = $"未找到库存空托"; LogHelper.Info($"EquipmentInfo:{result.Msg}"); return result; } else { var Cntr = db.Queryable().Where(a => a.S_LOC_CODE.Trim() == startloc.S_CODE).ToList(); if (Cntr == null) { result.Code = -1; result.Msg = $"起点{startloc.S_CODE},未找到托盘货位绑定关系,请检查货位数量"; LogHelper.Info($"EquipmentInfo:{result.Msg}"); return result; } cntrcode = string.Join(",", Cntr.Select(a => a.S_CNTR_CODE)); } #endregion #region 创建作业 if (startloc != null && endloc != null) { var wcsTask = new WMSTask { S_CODE = WMSHelper.GenerateTaskNo(), S_TYPE = "叠盘机呼叫空托", N_TYPE = 3, S_START_LOC = startloc.S_CODE, S_END_LOC = endloc.S_CODE, S_START_WH = startloc.S_WH_CODE, S_START_AREA = startloc.S_AREA_CODE, S_END_WH = endloc.S_WH_CODE, S_END_AREA = endloc.S_AREA_CODE, S_CNTR_CODE = cntrcode }; LogHelper.Info("创建入平库作业:" + JsonConvert.SerializeObject(wcsTask)); if (WMSHelper.CreateTask(wcsTask)) { LocationHelper.LockLoc(startloc.S_CODE, 2); LocationHelper.LockLoc(endloc.S_CODE, 1); LogHelper.Info("创建作业成功"); } } #endregion } else { result.Code = -1; result.Msg = $"当前叠盘机状态不属于拆托状态,不允许呼叫空托"; LogHelper.Info($"EquipmentInfo:{result.Msg}"); return result; } } else { result.Code = -1; result.Msg = $"下发类型错误"; LogHelper.Info($"EquipmentInfo:{result.Msg}"); return result; } } else //入库空 { //入库口申请入库 if (model.SignalType == 1) { #region 获取起点信息 //根据托盘获取起点信息 //var CntrLoc = db.Queryable().Where(a => a.S_LOC_CODE == model.Loc).First(); //if (CntrLoc == null) //{ // result.Code = -1; // result.Msg = $"根据起点:{model.Loc}未找到绑定托盘"; // LogHelper.Info($"EquipmentInfo:{result.Msg}"); // return result; //} startloc = LocationHelper.GetLoc(model.Loc); if (startloc == null) { result.Code = -1; result.Msg = $"根据起点:{model.Loc}未找到货位信息"; LogHelper.Info($"EquipmentInfo:{result.Msg}"); return result; } #endregion #region 计算立库终点 //获取托盘物料绑定关系 var cntrItem = db.Queryable().Where(a => a.S_CNTR_CODE == model.CntrNo).First(); if (cntrItem == null) { result.Code = -1; result.Msg = $"根据托盘:{model.CntrNo}未找到物料信息"; LogHelper.Info($"EquipmentInfo:{result.Msg}"); return result; } endloc = LocationHelper.InStorage(cntrItem.S_ITEM_CODE); if (endloc == null) { result.Code = -1; result.Msg = $"未计算到立库终点货位,请检查货位情况"; LogHelper.Info($"EquipmentInfo:未计算到立库终点货位,请检查货位情况"); return result; } #endregion #region 创建作业 if (startloc != null && endloc != null) { var wmsTask = new WMSTask { S_CODE = WMSHelper.GenerateTaskNo(), S_TYPE = "物料入库", N_TYPE = 3, S_START_LOC = startloc.S_CODE, S_END_LOC = endloc.S_CODE, S_START_WH = startloc.S_WH_CODE, S_START_AREA = startloc.S_AREA_CODE, S_END_WH = endloc.S_WH_CODE, S_END_AREA = endloc.S_AREA_CODE, S_CNTR_CODE = model.CntrNo }; LogHelper.Info("创建入平库作业:" + JsonConvert.SerializeObject(wmsTask)); if (WMSHelper.CreateTask(wmsTask)) { cntrItem.F_WEIGHT = float.Parse(model.Weight); var aaaaa = db.Updateable(cntrItem).UpdateColumns(a => new { a.F_WEIGHT }).ExecuteCommand(); LocationHelper.LockLoc(startloc.S_CODE, 2); LocationHelper.LockLoc(endloc.S_CODE, 1); LogHelper.Info("创建作业成功"); } } #endregion } //入库空申请叠盘 else { //判断设备状态是否属于叠盘状态 var DeviceStatu = db.Queryable().Where(a => a.DEVICENO == "1").First(); if (DeviceStatu != null && DeviceStatu.STATUS == "1") { #region 获取起点信息 //根据托盘获取起点信息 //var CntrLoc = db.Queryable().Where(a => a.S_CNTR_CODE == cntrcode).First(); //if (CntrLoc == null) //{ // result.Code = -1; // result.Msg = $"根据托盘:{cntrcode}未找到绑定托盘"; // LogHelper.Info($"EquipmentInfo:{result.Msg}"); // return result; //} ContainerHelper.AddCntr(cntrcode, "1"); startloc = LocationHelper.GetLoc(model.Loc); if (startloc == null) { result.Code = -1; result.Msg = $"根据起点:{model.Loc}未找到货位信息"; LogHelper.Info($"EquipmentInfo:{result.Msg}"); return result; } var cntrItem = db.Queryable().Where(a => a.S_CNTR_CODE == model.CntrNo).First(); if (cntrItem != null) { result.Code = -1; result.Msg = $"根据托盘:{model.CntrNo}找到物料信息,不允许叠盘入库"; LogHelper.Info($"EquipmentInfo:{result.Msg}"); return result; } #endregion #region 获取终点信息 //根据托盘获取起点信息 endloc = db.Queryable().Where(a => a.S_CODE == DiePanLoc).First(); if (endloc == null) { result.Code = -1; result.Msg = $"根据货位编码:{DiePanLoc}未找到叠盘货位"; LogHelper.Info($"EquipmentInfo:{result.Msg}"); return result; } #endregion #region 创建作业 if (startloc != null && endloc != null) { var wmsTask = new WMSTask { S_CODE = WMSHelper.GenerateTaskNo(), S_TYPE = "叠盘机空托入库", N_TYPE = 3, S_START_LOC = startloc.S_CODE, S_END_LOC = endloc.S_CODE, S_START_WH = startloc.S_WH_CODE, S_START_AREA = startloc.S_AREA_CODE, S_END_WH = endloc.S_WH_CODE, S_END_AREA = endloc.S_AREA_CODE, S_CNTR_CODE = cntrcode }; LogHelper.Info("创建入平库作业:" + JsonConvert.SerializeObject(wmsTask)); if (WMSHelper.CreateTask(wmsTask)) { LocationHelper.LockLoc(startloc.S_CODE, 2); LocationHelper.LockLoc(endloc.S_CODE, 1); LogHelper.Info("创建任务作业"); } } #endregion } else { result.Code = -1; result.Msg = $"当前叠盘机状态不属于叠盘状态,不允许空托叠托"; LogHelper.Info($"EquipmentInfo:{result.Msg}"); return result; } } } return result; } internal static Result ApplyDest(ApplyDestModel model) { Result result = new Result { Code = 0, Msg = "创建成功" }; if (model == null) { result.Code = -1; result.Msg = "入参为空"; return result; } var db = new SqlHelper().GetInstance(); string ItemCode = ""; var task = WCSHelper.GetTask(model.TaskNo); if (task != null) { //根据任务托盘获取物料信息 var cntrItem = db.Queryable().Where(a => a.S_CNTR_CODE == task.S_CNTR_CODE).First(); if (cntrItem != null) { ItemCode = cntrItem.S_ITEM_CODE; } var endloc = LocationHelper.InStorage(ItemCode); if (endloc != null) { result.Data = new ReseltApplyDestModel() { Loc = endloc.S_CODE }; } else { result.Code = -1; result.Msg = "当前没有可用终点可以分配"; return result; } } else { result.Code = 1; result.Msg = "任务不存在"; return result; } return result; } /// /// 获取托盘物料信息 /// /// /// internal static Result GetCntrInfo(GetCntrInfoModel model) { Result result = new Result { Code = 0, Msg = "创建成功" }; if (model == null) { result.Code = -1; result.Msg = "入参为空"; return result; } var db = new SqlHelper().GetInstance(); string cntrCode = model.CntrNo; var CntrItem = db.Queryable().Where(a => a.S_CNTR_CODE == cntrCode).ToList(); if (CntrItem.Count > 0) { } return result; } /// /// 绑定托盘物料 /// /// /// /// internal static Result bindCntr(BindCntr model) { Result result = new Result { resultCode = 0, resultMsg = "绑定成功" }; try { var traylist = ContainerHelper.GenerateCntrNo(); if (ContainerHelper.CreateCntrItem(model.LocCode, traylist, model.ItemCode)) { return result; } else { result.resultCode = -1; result.resultMsg = "绑定失败"; return result; } } catch (Exception ex) { result.resultCode = -1; result.resultMsg = ex.ToString(); return result; } } /// /// 解绑托盘 /// /// /// internal static Result untieCntr(UntieCntr model) { Result result = new Result { resultCode = 0, resultMsg = "创建成功" }; // var result = new SimpleResultModel { success = false, errCode = -1 }; string msg = ""; int n = 0; var db = new SqlHelper().GetInstance(); string cntrCode = model.CntrCode; string locCode = model.LocCode; var trayInfo = db.Queryable().Where(a => a.S_LOC_CODE == locCode).First(); if (trayInfo != null) { cntrCode = trayInfo.S_CNTR_CODE; //locCode = trayInfo.S_LOC_CODE.Trim(); db.Deleteable(a => a.S_CNTR_CODE == cntrCode).ExecuteCommand(); db.Deleteable(a => a.S_CNTR_CODE == cntrCode).ExecuteCommand(); msg = msg + $"{n++}:当前托盘号:{model.CntrCode},解绑成功!"; } else msg = msg + $"{n++}:当前托盘号:{model.CntrCode},不存在对应货位!"; if (!string.IsNullOrEmpty(locCode)) { var locNum = db.Queryable().Where(a => a.S_LOC_CODE == locCode).ToList(); int num = 0; var locInfo = db.Queryable().Where(a => a.S_CODE == locCode).First(); if (locInfo != null) { locInfo.N_CURRENT_NUM = GetLocTrayNum(locNum, num); LogHelper.Info("UnbindingTrayCode Dispose:更新当前货位当前数量!" + $"货位编码:{locCode},数量:{locInfo.N_CURRENT_NUM}", "ThirdSystemLog"); db.Updateable(locInfo).UpdateColumns(a => new { a.N_CURRENT_NUM }).ExecuteCommand(); // var locaHaveTray = db.Queryable().Where(a => a.N_ROW == locInfo.N_ROW && a.N_CURRENT_NUM > 0).ToList(); //if (locaHaveTray.Count == 0) TaskHelper.YiKuUnLockRow(db, locInfo.N_ROW.Trim(), locInfo.S_AREA_CODE.Trim(), true, false, true); //else TaskController.Monitor.YiKuUnLockRow(db, locInfo.N_ROW.Trim(), locInfo.S_AREA_CODE.Trim(), false); } } result.resultMsg = msg; LogHelper.Info("UnbindingTrayCode Dispose:" + result.resultMsg, "ThirdSystemLog"); return result; } /// /// 找终点空货位 /// /// /// internal static Location FindEndcolByLocList(List locations) { try { var db = new SqlHelper().GetInstance(); Location end = null; //根据终点货位找空闲货位 var rows = locations.Select(a => a.N_COL).Distinct().ToList(); for (int i = 0; i < rows.Count; i++) { var rowList = locations.Where(r => r.N_COL == rows[i]).ToList(); if (rowList.Count(a => a.N_CURRENT_NUM == 0) > 0) { Location other = null; //先找满位,然后后面一层要么是空,要么不存在 other = rowList.OrderByDescending(a => a.N_LAYER).Where(a => a.N_CURRENT_NUM == 0).FirstOrDefault(); //if (full == null) //{ // //没有满位,那就找最小的空位 // other = rowList.OrderBy(a => a.N_LAYER).FirstOrDefault(); //} //else //{ // other = rowList.OrderBy(a => a.N_LAYER).Where(a => a.N_LAYER > full.N_LAYER).FirstOrDefault(); //} //if (other != null && (!string.IsNullOrEmpty(other.C_ENABLE) && other.C_ENABLE == "禁用")) //{ // //禁用了选择后面一个货位 // other = db.Queryable().OrderBy(a => a.N_LAYER).Where(a => (string.IsNullOrEmpty(a.C_ENABLE) || a.C_ENABLE.Trim() != "禁用") && a.S_AREA_CODE == other.S_AREA_CODE && a.N_ROW == other.N_ROW && a.N_COL > other.N_COL).First(); // //LogHelper.Info($"禁用选择后一个货位{result}", "成品"); //} if (other != null) { end = other; break; } } } return end; } catch (Exception) { throw; } } /// /// 找起点满货位 /// /// /// internal static Location FindStartcolByLoclist(List locations) { try { Location start = null; var rowsStart = locations.Select(a => a.N_ROW).Distinct().ToList(); for (int i = 0; i < rowsStart.Count; i++) { var rowList = locations.Where(r => r.N_ROW == rowsStart[i]).ToList().OrderByDescending(a => a.N_COL); //当前排没有锁并且有满货位 if (rowList.Count(a => a.S_LOCK_STATE.Trim() != "无") == 0 && rowList.Count(a => a.N_CURRENT_NUM == 1) > 0) { Location other = null; //找到最大的满位,如果有就直接出 var full = rowList.OrderByDescending(a => a.N_COL).Where(a => a.N_CURRENT_NUM == 1).FirstOrDefault(); if (full != null) { other = full; } if (other != null) { start = other; break; } } } return start; } catch (Exception) { throw; } } private static int GetLocTrayNum(List locNum, int num) { int trayNum = locNum.Count(); switch (trayNum) { case 0: num = 0; break; case 1: num = 1; break; case 2: num = 1; break; case 3: num = 2; break; case 4: num = 2; break; } return num; } internal static SimpleResult ShippingOrderExecute(ShippingOrderCheck model) { var result = new SimpleResult(); //检查库存,更新发货单,生成分拣单,自动合并波次 //这个后台做比较麻烦,mobox3库存在内存中,任务完成的时候无法增加,还是用c#直接管内存,计算比较方便 WMSHelper.CreateSortingOrder(model.out_nos.Split(',').ToList()); return result; } /// /// 后面要把方法放到wmsHelper中 /// /// /// internal static SimpleResult SortingResultCheck(List models) { //生成分拣结果,更新分拣明细状态 var result = new SimpleResult(); WMSHelper.SortingConfrim(models); return result; } /// /// 后面要把方法放到wmsHelper中 /// /// /// internal static SimpleResult Instock(InstockInfo model) { var result = new SimpleResult(); //pda入库,目前人工放货在巷道口,扫托盘,后台只能计算当前巷道的终点,单深位立库 //1,判断托盘信息,一种是码盘后的,默认enable是N,另一种是分拣回的 var cntr = ContainerHelper.GetCntr(model.cntr); if (cntr != null) { var sortingInfo = WMSHelper.GetSortingDetailByCntr(model.cntr); if (cntr.C_ENABLE == "Y" && sortingInfo != null && sortingInfo.Count > 0) { result.resultCode = 2; result.resultMsg = $"托盘{model.cntr}未分拣完成"; } } else { result.resultCode = 1; result.resultMsg = $"托盘{model.cntr}不存在"; } if (result.resultCode == 0) { //获取接驳位所在的巷道, 查找功能区,入库接驳位找逻辑库区(每个巷道一个逻辑库区) var fa = LocationHelper.GetFunctionAreaByCode(model.start, 2, 10); if (fa != null) { //创建入库作业,简单判断一下是否有可入货位,如果不判断,人工货放上去一直不能入,也不知道原因 var end = LocationHelper.GetZoneLoc(fa.S_MASTER_CODE); if (end != null) { //判断托盘是否已经生成任务,如果没有则生成 var wmsTask = WMSHelper.GetWmsTaskByCntr(model.cntr); if (wmsTask != null) { result.resultCode = 3; result.resultMsg = $"起点{model.start} 托盘{model.cntr}已经创建任务,请勿重复申请"; } else { wmsTask = new WMSTask { S_CNTR_CODE = model.cntr, S_CODE = WMSHelper.GenerateTaskNo(), S_START_LOC = model.start, S_END_LOC = end.S_LOC_CODE, N_TYPE = 1, S_TYPE = WMSTask.GetTypeStr(1), S_OP_DEF_CODE = "", S_OP_DEF_NAME = "pda入立库" }; if (WMSHelper.CreateWmsTask(wmsTask)) { LocationHelper.LockLoc(end.S_LOC_CODE, 1); result.resultMsg = $"创建作业成功,作业号{wmsTask.S_CODE}"; } } } else { result.resultCode = 3; result.resultMsg = $"起点{model.start}对应的逻辑库区{fa.S_MASTER_CODE}没有可用货位,请更换巷道"; } } else { result.resultCode = 3; result.resultMsg = $"起点{model.start}没有对应的逻辑库区,请在逻辑库区设置功能区-入库接驳位"; } } return result; } internal static SimpleResult SortingOrderExecute(SortingOrderCheck model) { var result = new SimpleResult(); //分拣单配货执行 WMSHelper.CreateSortingOrderDetail(model.s_no); return result; } internal static SimpleResult CheckSortingWholeCntr(CheckSortingWholeCntr model) { var result = new SimpleResult(); if (WMSHelper.CheckSortingWholeCntr(model.cntr, model.autoSort == 1)) { 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; } internal static SimpleResult PalletSorting1(PalletSorting1 model) { var result = new SimpleResult(); //校验入库单数量,不可以超,成功后插入托盘物料表,更新入库单累计数量 //也可以直接lua查询入库单数量,做校验 //先用bar_code读存储过程获取信息 var codeInfo = GetCodeInfo(model.bar_code, model.org); var info = WMSHelper.GetPutawayOrderDetail(model.bar_code); if (info != null) { if (info.F_QTY - info.F_ACC_B_QTY >= model.qty) { // 插入到托盘明细表 var cntr = ContainerHelper.GetCntr(model.cntr_code, true); if (cntr != null) { ContainerHelper.BindCntrItem(cntr, model.bar_code, info.S_BATCH_NO, model.qty, info.S_BATCH_NO); //更新入库单累计绑定数量 info.F_ACC_B_QTY += model.qty; WMSHelper.UpdatePutawayOrderDetailQty(info); } else { result.resultCode = 2; result.resultMsg = "获取托盘信息失败"; } } else { result.resultCode = 1; result.resultMsg = "累计码盘数量超出入库单数量"; } } else { result.resultCode = 3; result.resultMsg = $"未获取到该物料{model.bar_code}的入库单明细信息"; } return result; } 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; } } } }