using System; using HH.WCS.Mobox3.AnGang.AppStart; using HH.WCS.Mobox3.AnGang.Consts; using HH.WCS.Mobox3.AnGang.Helper; using HH.WCS.Mobox3.AnGang.Helpers; using HH.WCS.Mobox3.AnGang.Models; using Newtonsoft.Json; using static HH.WCS.Mobox3.AnGang.Dtos.Request.ErpRequest; using static HH.WCS.Mobox3.AnGang.Dtos.Request.MoboxRequest; using static HH.WCS.Mobox3.AnGang.Dtos.Response.MoboxResponse; namespace HH.WCS.Mobox3.AnGang.Services { public class MoboxService { /// /// 产品入库(PDA) /// /// /// internal static SimpleResult Inbound(InboundInfo model) { LogHelper.Info("触发API:产品入库(PDA)" + JsonConvert.SerializeObject(model), "API"); var db = DbHelper.GetDbClient(); var startLoc = new TN_Location(); //var endLoc = new TN_Location(); try { // 起点位置必须:为空、无锁、启用、属于收发区域 startLoc = db.Queryable(). First(a => a.S_CODE == model.startLoc && a.N_CURRENT_NUM == 0 && a.N_LOCK_STATE == 0 && a.S_LOCK_STATE == "无" && a.C_ENABLE == "Y" && a.S_SHELF_CODE == AreaCode.收发货位区); if (startLoc == null) { return BuildSimpleResult(1, $"起点位置{model.startLoc}不存在!"); } //if (!LocationHelper.IsStartLocationTransferOk(model.startLoc, // a => a.S_SHELF_CODE == Settings.Areas[0], // out startLoc)) { // return BuildSimpleResult(1, $"起点位置{model.startLoc}不存在!"); //} // 容器 ID 和 物料 ID 未指定,由系统直接生成 var cntID = Guid.NewGuid().ToString("D"); var CgId = Guid.NewGuid().ToString("D"); // 初始是没有绑定信息的,先将起点位置与容器绑定,容器与物料绑定 var cntLoc = new TN_Loc_Container() { S_LOC_CODE = startLoc.S_CODE, S_CNTR_CODE = cntID, }; var cgCnt = new TN_CG_Detail() { S_ITEM_CODE = CgId, S_CNTR_CODE = cntID, }; var endArea = ""; // 默认终点区域为空 // 指定货位排号(不能为空、空字符串或空格) if (model.endShelf != null && model.endShelf.Trim() != "") { endArea = model.endShelf; // 没有在配置文件找到这个货架号 if (!Settings.AreaMap[AreaName.货架区].Contains(endArea)) { return BuildSimpleResult(2, $"货架号 {model.endShelf} 不存在"); } } // 无论是否选择终点货架,都等到称重之后再计算终点货位 using (var trans = db.Ado.UseTran()) { if (db.Insertable(cntLoc).ExecuteCommand() > 0 && db.Insertable(cgCnt).ExecuteCommand() > 0) { //创建产品入库任务:创建搬送任务,起点终点容器 if (WCSHelper.CreateTaskWithArea(startLoc.S_CODE, endArea, "产品入库(PDA)", 3, cntID)) { //如果操作TN_Location会造成死锁 LocationHelper.LockLoc(startLoc.S_CODE, 2);//起点出库锁, //LocationHelper.LockLoc(endLoc.S_CODE, 1);//终点入库锁 trans.CommitTran(); return BuildSimpleResult(0, $"生成 产品入库(PDA) 成功,容器号 {cntID} ,起点 {startLoc.S_CODE} ,终点货架 {endArea} ,终点货位未指定"); } else { trans.RollbackTran(); return BuildSimpleResult(5, $"生成 产品入库(PDA) 失败,容器号 {cntID} ,起点 {startLoc.S_CODE} ,终点货架 {endArea} ,终点货位未指定"); } } else { return BuildSimpleResult(6, $"插入表数据失败"); } } } catch (Exception ex) { return BuildSimpleResult(1, $"发生了异常:{ex.Message}"); } } /// /// PDA选择终点货位 /// /// /// internal static SimpleResult SelectLocation(SelectLocationInfo model) { LogHelper.Info("触发API:PDA选择终点货位" + JsonConvert.SerializeObject(model), "API"); var db = DbHelper.GetDbClient(); try { // 任务号存在:终点货架和终点位置为空,且任务为产品入库(PDA) //var task = db.Queryable().First(a => a.S_CODE == model.taskNo && a.S_END_AREA == "" && a.S_END_LOC == "" && a.S_TYPE == "产品入库(PDA)"); var task = db.Queryable().First(a => a.S_EQ_NO == model.forklift_no && a.S_END_AREA == "" && a.S_END_LOC == "" && a.S_TYPE == "产品入库(PDA)"); if (task == null) { //return BuildSimpleResult(2, $"任务号 {model.taskNo} 不存在,或不满足终点货架为空、终点位置为空且为 产品入库(PDA) 任务"); return BuildSimpleResult(2, $"小车 '{model.forklift_no}' 当前不存在任务,或不满足终点货架为空、终点位置为空且为 产品入库(PDA) 任务"); } var endLoc = new TN_Location(); if (task.F_WEIGHT > 1500) { // 重量超过1.5t,需要选择1-3层货架 endLoc = db.Queryable().First( a => a.S_CODE == model.endLoc && a.N_LOCK_STATE == 0 && a.S_LOCK_STATE == "无" && a.C_ENABLE == "Y" && a.N_CURRENT_NUM == 0 && a.N_HEIGHT <= 3); } else { endLoc = db.Queryable().First( a => a.S_CODE == model.endLoc && a.N_LOCK_STATE == 0 && a.S_LOCK_STATE == "无" && a.C_ENABLE == "Y" && a.N_CURRENT_NUM == 0); } // 没有符合条件的货位 if (endLoc == null) { return BuildSimpleResult(3, $"货位{model.endLoc}不满足要求:不存在或不满足称重放置要求"); } // 修改任务终点为PDA指定终点 task.S_END_LOC = endLoc.S_CODE; task.S_END_AREA = endLoc.S_SHELF_CODE; using (var trans = db.Ado.UseTran()) { if (db.Updateable(task).ExecuteCommand() > 0) { LocationHelper.LockLoc(endLoc.S_CODE, 1);//终点入库锁 trans.CommitTran(); return BuildSimpleResult(0, $"任务{task.S_CODE}修改成功,修改终点位置为{endLoc.S_CODE}"); } else { trans.RollbackTran(); return BuildSimpleResult(4, $"任务{task.S_CODE}修改失败,修改终点位置为{endLoc.S_CODE}"); } } } catch (Exception ex) { return BuildSimpleResult(1, $"发生了异常:{ex.Message}"); } } /// /// 产品部分出库(WMS) /// /// /// internal static SimpleResult PartOutbound(PartOutboundInfo model) { LogHelper.Info("触发API:产品部分出库(WMS)" + JsonConvert.SerializeObject(model), "API"); var db = DbHelper.GetDbClient(); try { // 起点位置:货架(有货、没有锁、已启用) var startLoc = db.Queryable().First(a => a.S_CODE == model.startLoc && a.N_CURRENT_NUM == 1 && a.N_LOCK_STATE == 0 && a.S_LOCK_STATE == "无" && a.C_ENABLE == "Y"); if (startLoc == null) { return BuildSimpleResult(2, $"起点位置 {model.startLoc} 不存在或不具备取货要求"); } var locCtnrRel = db.Queryable().First(a => a.S_LOC_CODE == model.startLoc); if (locCtnrRel == null) { return BuildSimpleResult(3, $"起点位置 {model.startLoc} 没有绑定容器,无可出库的物料"); } var endLoc = db.Queryable().First(a => a.S_CODE == model.endLoc && a.N_CURRENT_NUM == 0 && a.N_LOCK_STATE == 0 && a.S_LOCK_STATE == "无" && a.C_ENABLE == "Y" && a.S_AREA_CODE == AreaCode.收发货位区); if (endLoc == null) { return BuildSimpleResult(4, $"终点位置 {model.endLoc} 不具备放货条件"); } using (var trans = db.Ado.UseTran()) { // 解绑:起点货位与待搬运容器(不需要手动deleteable操作,内部会自动操作的) if (WCSHelper.CreateTask(startLoc.S_CODE, endLoc.S_CODE, "产品部分出库(WMS)", 3, locCtnrRel.S_CNTR_CODE))//创建搬送任务,起点终点容器 {//如果操作TN_Location会造成死锁 LocationHelper.LockLoc(startLoc.S_CODE, 2);//起点出库锁, LocationHelper.LockLoc(endLoc.S_CODE, 1);//终点入库锁 trans.CommitTran(); return BuildSimpleResult(0, $"生成 产品出库(WMS) 成功,容器号{locCtnrRel.S_CNTR_CODE},起点{startLoc.S_CODE},终点{endLoc.S_CODE}"); } else { trans.RollbackTran(); return BuildSimpleResult(5, $"生成 产品出库(WMS) 失败,容器号{locCtnrRel.S_CNTR_CODE},起点{startLoc.S_CODE},终点{endLoc.S_CODE}"); } } } catch (Exception ex) { return BuildSimpleResult(1, $"发生了异常:{ex.Message}"); } } /// /// 产品部分回库(WMS) /// /// /// internal static SimpleResult PartInbound(PartInboundInfo model) { LogHelper.Info("触发API:产品部分回库(WMS)" + JsonConvert.SerializeObject(model), "API"); var db = DbHelper.GetDbClient(); try { // 起点位置:取放货区(有货物、没有锁、已启用) var startLoc = db.Queryable().First(a => a.S_CODE == model.startLoc && a.N_CURRENT_NUM == 1 && a.N_LOCK_STATE == 0 && a.S_LOCK_STATE == "无" && a.C_ENABLE == "Y" && a.S_AREA_CODE == AreaCode.收发货位区); if (startLoc == null) { return BuildSimpleResult(2, $"起点位置 {model.startLoc} 不符合回库条件"); } var locCtnrRel = db.Queryable().First(a => a.S_LOC_CODE == model.startLoc); if (locCtnrRel == null) { return BuildSimpleResult(3, $"起点位置 {model.startLoc} 没有绑定容器,无可回库的物料"); } // 终点位置:货架(没有货物,没有锁) var endLoc = db.Queryable().First(a => a.S_CODE == model.endLoc && a.N_CURRENT_NUM == 0 && a.N_LOCK_STATE == 0 && a.S_LOCK_STATE == "无" && a.C_ENABLE == "Y"); if (endLoc == null) { return BuildSimpleResult(4, $"终点位置 {model.endLoc} 不具备放货条件"); } using (var trans = db.Ado.UseTran()) { // 解绑:起点货位与待搬运容器(不需要手动deleteable操作,内部会自动操作的) if (WCSHelper.CreateTask(startLoc.S_CODE, endLoc.S_CODE, "产品部分入库(WMS)", 3, locCtnrRel.S_CNTR_CODE))//创建搬送任务,起点终点容器 {//如果操作TN_Location会造成死锁 LocationHelper.LockLoc(startLoc.S_CODE, 2);//起点出库锁, LocationHelper.LockLoc(endLoc.S_CODE, 1);//终点入库锁 trans.CommitTran(); return BuildSimpleResult(0, $"生成 产品部分回库(WMS) 成功,容器号{locCtnrRel.S_CNTR_CODE},起点{startLoc.S_CODE},终点{endLoc.S_CODE}"); } else { trans.RollbackTran(); return BuildSimpleResult(5, $"生成 产品部分回库(WMS) 成功,容器号{locCtnrRel.S_CNTR_CODE},起点{startLoc.S_CODE},终点{endLoc.S_CODE}"); } } } catch (Exception ex) { return BuildSimpleResult(1, $"发生了异常:{ex.Message}"); } } /// /// 盘点理货出库(WMS) /// /// /// internal static SimpleResult CheckOutbound(CheckOutboundInfo model) { LogHelper.Info("触发API:盘点理货出库(WMS)" + JsonConvert.SerializeObject(model), "API"); var db = DbHelper.GetDbClient(); try { // 起点位置:取放货区(有货物、没有锁、已启用) var startLoc = db.Queryable().First(a => a.S_CODE == model.startLoc && a.N_CURRENT_NUM == 1 && a.N_LOCK_STATE == 0 && a.S_LOCK_STATE == "无" && a.C_ENABLE == "Y" && a.S_AREA_CODE == AreaCode.收发货位区); if (startLoc == null) { return BuildSimpleResult(2, $"起点位置 {model.startLoc} 不符合出库条件"); } var locCtnrRel = db.Queryable().First(a => a.S_LOC_CODE == model.startLoc); if (locCtnrRel == null) { return BuildSimpleResult(3, $"起点位置 {model.startLoc} 没有绑定容器,无可回库的物料"); } // 终点位置:货架(没有货物,没有锁) var endLoc = db.Queryable().First(a => a.S_CODE == model.endLoc && a.N_CURRENT_NUM == 0 && a.N_LOCK_STATE == 0 && a.S_LOCK_STATE == "无" && a.C_ENABLE == "Y"); if (endLoc == null) { return BuildSimpleResult(4, $"终点位置 {model.endLoc} 不具备放货条件"); } using (var trans = db.Ado.UseTran()) { // 解绑:起点货位与待搬运容器(不需要手动deleteable操作,内部会自动操作的) if (WCSHelper.CreateTask(startLoc.S_CODE, endLoc.S_CODE, "盘点理货出库(WMS)", 3, locCtnrRel.S_CNTR_CODE))//创建搬送任务,起点终点容器 {//如果操作TN_Location会造成死锁 LocationHelper.LockLoc(startLoc.S_CODE, 2);//起点出库锁, LocationHelper.LockLoc(endLoc.S_CODE, 1);//终点入库锁 trans.CommitTran(); return BuildSimpleResult(0, $"生成 盘点理货出库(WMS) 成功,容器号{locCtnrRel.S_CNTR_CODE},起点{startLoc.S_CODE},终点{endLoc.S_CODE}"); } else { trans.RollbackTran(); return BuildSimpleResult(5, $"生成 盘点理货出库(WMS) 成功,容器号{locCtnrRel.S_CNTR_CODE},起点{startLoc.S_CODE},终点{endLoc.S_CODE}"); } } } catch (Exception ex) { return BuildSimpleResult(1, $"发生了异常:{ex.Message}"); } } /// /// 盘点理货回库(WMS) /// /// /// internal static SimpleResult CheckInbound(CheckInboundInfo model) { LogHelper.Info("触发API:盘点理货回库(WMS)" + JsonConvert.SerializeObject(model), "API"); var db = DbHelper.GetDbClient(); try { // 起点位置:取放货区(有货物、没有锁、已启用) var startLoc = db.Queryable().First(a => a.S_CODE == model.startLoc && a.N_CURRENT_NUM == 1 && a.N_LOCK_STATE == 0 && a.S_LOCK_STATE == "无" && a.C_ENABLE == "Y" && a.S_AREA_CODE == AreaCode.收发货位区); if (startLoc == null) { return BuildSimpleResult(2, $"起点位置 {model.startLoc} 不符合回库条件"); } var locCtnrRel = db.Queryable().First(a => a.S_LOC_CODE == model.startLoc); if (locCtnrRel == null) { return BuildSimpleResult(3, $"起点位置 {model.startLoc} 没有绑定容器,无可回库的物料"); } // 终点位置:货架(没有货物,没有锁) var endLoc = db.Queryable().First(a => a.S_CODE == model.endLoc && a.N_CURRENT_NUM == 0 && a.N_LOCK_STATE == 0 && a.S_LOCK_STATE == "无" && a.C_ENABLE == "Y"); if (endLoc == null) { return BuildSimpleResult(4, $"终点位置 {model.endLoc} 不具备放货条件"); } using (var trans = db.Ado.UseTran()) { // 解绑:起点货位与待搬运容器(不需要手动deleteable操作,内部会自动操作的) if (WCSHelper.CreateTask(startLoc.S_CODE, endLoc.S_CODE, "盘点理货回库(WMS)", 3, locCtnrRel.S_CNTR_CODE))//创建搬送任务,起点终点容器 {//如果操作TN_Location会造成死锁 LocationHelper.LockLoc(startLoc.S_CODE, 2);//起点出库锁, LocationHelper.LockLoc(endLoc.S_CODE, 1);//终点入库锁 trans.CommitTran(); return BuildSimpleResult(0, $"生成 盘点理货回库(WMS) 成功,容器号{locCtnrRel.S_CNTR_CODE},起点{startLoc.S_CODE},终点{endLoc.S_CODE}"); } else { trans.RollbackTran(); return BuildSimpleResult(5, $"生成 盘点理货回库(WMS) 成功,容器号{locCtnrRel.S_CNTR_CODE},起点{startLoc.S_CODE},终点{endLoc.S_CODE}"); } } } catch (Exception ex) { return BuildSimpleResult(1, $"发生了异常:{ex.Message}"); } } } }