using System; using System.Collections.Generic; using WMS.Core._02Entity; using WMS.Info; using WMS.Info.Models; using WMS.Util; namespace WMS.Core.APPBLL { public class EmptyTrayBLL : AppCoreBLL { public EmptyTrayBLL(bool isSkipOauth = false) : base(isSkipOauth) { } public ResInfo StockOut(EmptyTrayRequestDto reqData) { using (var ctx = SysDbCore.GetDbCtx()) { ctx.BeginTran(); try { if (string.IsNullOrWhiteSpace(reqData?.LocationNo)) throw SysExCore.ThrowFailException("参数不能为空"); var task = new WMS_TASK { F_addTime = DateTime.Now, F_addUserNo = LoginUser.UserNo, F_editTime = DateTime.Now, F_isBonded = reqData.IsBonded, F_posidTo = reqData.LocationNo, F_priority = (int)EPriority.NotUrgent, F_taskStatus = (int)ETaskStatus.NotIssued, F_taskType = (int)ETaskComType.OutStock }; if (reqData.IsGroup)//空托盘组需要生成出库单和出库任务 { if (ctx.Queryable().Any(c => c.F_posidTo == reqData.LocationNo && c.F_taskStatus < (int)ETaskStatus.TaskFinish)) return SysExCore.GetResSucc("请勿重复创建任务"); var inventoryEntity = ctx.Queryable().Where(it => it.F_matType == (int)EMatType.Tary && it.F_isBonded == reqData.IsBonded).First(); if (inventoryEntity == null) throw SysExCore.ThrowFailException("没有可用的空托盘组库存"); var loctionEntity = ctx.Queryable().Where(it => it.F_trayNo == inventoryEntity.F_trayNo).First(); if (loctionEntity == null) throw SysExCore.ThrowFailException($"托盘{inventoryEntity.F_trayNo}货位数据状态异常!"); if (loctionEntity.F_status != (int)EWareCellState.Stored) throw SysExCore.ThrowFailException($"当前已存在空托盘组出库任务!"); var point = ctx.Queryable().Where(c => c.F_no == reqData.LocationNo || c.F_agv == reqData.LocationNo).First(); if (point == null) throw SysExCore.ThrowFailException($"当前点位信息无效!"); if (point.F_type == (int)EPointType.BSCPJ || point.F_type == (int)EPointType.CPJ) task.F_posidNext = reqData.LocationNo; else task.F_posidNext = GetFreePointInfoByType((int)EPointType.YCK)?.F_no;//目标地址为agv点位从整盘口出 var stockOut = new BILL_STOCKOUT { F_no = SerialNumberProvider.Instance.OrderNumber("wms", "CK"), F_addTime = DateTime.Now, F_addUserNo = LoginUser.UserNo, F_editTime = DateTime.Now, //F_locationNo = loctionEntity.F_no, F_orderStatus = (int)EOrderState.New, F_totalOrderLines = 0, F_orderType = (int)EStockOutOrderType.StockOutOrderTypeTray, F_warehouseNo = SysSetCore.GetSysSet().DefaultWarehouseNo }; ctx.Insertable(stockOut).ExecuteReturnEntity(); var stockOutLine = new BILL_STOCKOUTLINE { F_addTime = DateTime.Now, F_actualQty = 1, F_addUserNo = LoginUser.UserNo, F_matNo = inventoryEntity.F_matNo, F_matName = inventoryEntity.F_matName, F_matType = inventoryEntity.F_matType, F_orderLineNo = 1, F_pNo = stockOut.F_no, F_planQty = 1, F_warehouseNo = SysSetCore.GetSysSet().DefaultWarehouseNo }; ctx.Insertable(stockOutLine).ExecuteReturnEntity(); var stockOutLineDetail = new BILL_STOCKOUTLINEDETAIL { F_addTime = DateTime.Now, F_addUserNo = LoginUser.UserNo, F_locationNo = reqData.LocationNo, F_boxNo = inventoryEntity.F_boxNo, F_matName = SysSetCore.GetSysSet().DefaultEmptyTrayGroupName, F_matNo = SysSetCore.GetSysSet().DefaultEmptyTrayGroupNo, F_matType = (int)EMatType.Tary, F_quantity = 1, F_pNo = stockOut.F_no }; ctx.Insertable(stockOutLine).ExecuteReturnEntity(); task.F_orderNo = stockOut?.F_no; task.F_posidFrom = loctionEntity.F_no; task.F_posidcur = loctionEntity.F_no; task.F_orderType = (int)ETaskOrderType.StockOutOrderTypeEmptyTrayGroup; task.F_trayNo = inventoryEntity.F_trayNo; task.F_EquipmentType = (int)EEquipmentType.RGV; var upd = ctx.Updateable().SetColumns(it => new BASE_LOCATION() { F_status = (int)EWareCellState.Out, F_editTime = DateTime.Now, F_editUserNo = LoginUser.UserNo, //F_isBonded = reqData.IsBonded }).Where(w => w.F_no == loctionEntity.F_no).ExecuteCommand(); if (upd <= 0) throw SysExCore.ThrowFailException("更新货位状态失败,请重试。"); } else { //验证拆盘机是否还有托盘 var pointEntiry = GetFreePointInfoByType(reqData.IsBonded ? (int)EPointType.BSCPJ : (int)EPointType.CPJ); if (pointEntiry == null) throw SysExCore.ThrowFailException("获取拆盘机信息异常"); PolicyHelper.GetRetryTimesPolicy(3, ex => { throw ex; }).Execute(() => { var resStr = httpClinet.Get(null, $"/api/Equipment/CheckState?equNo={ pointEntiry.F_no}"); var result = resStr.ToObject(); if (result == null || !result.isSuccess) throw SysExCore.ThrowFailException($"调用wcs接口失败{result?.msg}!"); if ((bool)result.data == true) throw SysExCore.ThrowFailException($"任务创建失败,没有托盘库存!"); }); task.F_orderType = (int)ETaskOrderType.StockOutOrderTypeTray; task.F_posidFrom = pointEntiry.F_no; task.F_posidcur = pointEntiry.F_no; task.F_EquipmentType = (int)EEquipmentType.Convey; } ctx.Insertable(task).ExecuteReturnEntity(); ctx.CommitTran(); return SysExCore.GetResSucc(); } catch (Exception ex) { ctx.RollbackTran(); throw ex; } finally { ctx.Dispose(); } } } public ResInfo TrayEntry(ScanCodeRequest reqData) { using (var ctx = SysDbCore.GetDbCtx()) { try { if (string.IsNullOrWhiteSpace(reqData?.LocationNo) || string.IsNullOrWhiteSpace(reqData.TrayNo)) throw SysExCore.ThrowFailException("参数不能为空!"); var point = ctx.Queryable().First(p => p.F_no == reqData.LocationNo); if (point == null || !(point.F_type >= (int)EPointType.YLCKJXK && point.F_type <= (int)EPointType.YLRKJXK)) throw SysExCore.ThrowFailException("请扫码正确的位置码!"); if (ctx.Queryable().Any(a => a.F_trayNo == reqData.TrayNo)) throw SysExCore.ThrowFailException("当前托盘存在货位信息,无法生成空托盘入库任务!"); var task = new WMS_TASK { F_addTime = DateTime.Now, F_addUserNo = LoginUser.UserNo, F_editTime = DateTime.Now, F_trayNo = reqData.TrayNo, F_posidTo = GetFreePointInfoByType(reqData.TrayNo.StartsWith("B") ? (int)EPointType.BSDPJ : (int)EPointType.DPJ).F_no, F_isBonded = reqData.TrayNo.StartsWith("B"), F_priority = (int)EPriority.NotUrgent, F_taskStatus = (int)ETaskStatus.NotIssued, F_taskType = (int)ETaskComType.InStock, F_EquipmentType = (int)EEquipmentType.Convey, F_posidFrom = reqData.LocationNo, F_posidcur = reqData.LocationNo, F_orderType = (int)ETaskOrderType.EntryOrderTypeTray, }; task.F_posidNext = task.F_posidTo; ctx.Insertable(task).ExecuteReturnEntity(); return SysExCore.GetResSucc("空托盘入库任务生成成功"); } catch (Exception ex) { throw ex; } } } public ResInfo TrayGroupEntry(ScanCodeRequest reqData, bool IsBonded = false) { using (var ctx = SysDbCore.GetDbCtx()) { try { if (string.IsNullOrWhiteSpace(reqData?.LocationNo)) throw SysExCore.ThrowFailException("参数不能为空"); if (ctx.Queryable().Any(c => c.F_posidFrom == reqData.LocationNo && c.F_taskStatus < (int)ETaskStatus.TaskFinish)) return SysExCore.GetResSucc("请勿重复创建任务"); if (!string.IsNullOrWhiteSpace(reqData.TrayNo) && !IsBonded) IsBonded = reqData.TrayNo.StartsWith("B"); reqData.TrayNo = string.IsNullOrWhiteSpace(reqData.TrayNo) ? Guid.NewGuid().ToString() : reqData.TrayNo;//界面传入托盘码只为了区分是否保税,托盘组默认生成guid以便存库操作 var point = ctx.Queryable().First(p => p.F_no == reqData.LocationNo && p.F_status == (int)EPointSatus.Idle); if (point.F_type == (int)EPointType.YCK)//异常口处理逻辑 { var curTask = ctx.Queryable().Where(f => f.F_taskStatus < (int)ETaskStatus.TaskFinish && f.F_trayNo == reqData.TrayNo).First(); if (curTask == null) throw SysExCore.ThrowFailException("当前异常任务找不到对应的入库任务!"); ctx.Updateable().SetColumns(it => new WMS_TASK() { F_editTime = DateTime.Now, F_editUserNo = LoginUser.UserNo, F_posidFrom = reqData.LocationNo, F_posidcur = reqData.LocationNo, F_taskStatus = (int)ETaskStatus.NotIssued, F_posidNext = "1036" }).Where(w => w.F_taskNo == curTask.F_taskNo).ExecuteCommand(); ctx.CommitTran(); return SysExCore.GetResSucc("异常口任务生成成功"); ; } if (point == null || (point.F_type != (int)EPointType.DPJ && point.F_type != (int)EPointType.CPAGV && point.F_type != (int)EPointType.BSDPJ)) throw SysExCore.ThrowFailException("点位信息无效!"); ctx.BeginTran(); var task = new WMS_TASK { F_addTime = DateTime.Now, F_addUserNo = LoginUser.UserNo, F_editTime = DateTime.Now, F_trayNo = reqData.TrayNo, F_isBonded = IsBonded, //F_posidNext = GetFreePointInfoByType((int)EPointType.RKDFPHWDW).F_no, F_priority = (int)EPriority.NotUrgent, F_taskStatus = (int)ETaskStatus.NotIssued, F_taskType = (int)ETaskComType.InStock, F_posidFrom = reqData.LocationNo, F_posidcur = reqData.LocationNo, F_orderType = (int)ETaskOrderType.EntryOrderTypeTrayGroup }; //task.F_posidFrom = GetFreePointInfoByType(reqData.TrayNo.StartsWith("B") ? (int)EPointType.BSDPJ : (int)EPointType.DPJ).F_no; var entryorder = ctx.Insertable(new BILL_ENTRYORDER { F_addTime = DateTime.Now, F_addUserNo = LoginUser.UserNo, F_isBonded = IsBonded, F_orderStatus = (int)EOrderState.New, F_orderType = (int)EEntryOrderType.EntryOrderTypeTray, F_no = SerialNumberProvider.Instance.OrderNumber("wms", "RK"), F_totalOrderLines = 0, F_trayNo = reqData.TrayNo, F_warehouseNo = SysSetCore.GetSysSet().DefaultWarehouseNo }).ExecuteReturnEntity(); task.F_orderNo = entryorder.F_no; //添加空托盘库存 List lstInv = new List(); lstInv.Add(new BILL_INVENTORY { F_addTime = DateTime.Now, F_addUserNo = LoginUser.UserNo, F_editTime = DateTime.Now, F_matNo = SysSetCore.GetSysSet().DefaultEmptyTrayGroupNo, F_matType = (int)EMatType.Tary, F_quantity = 1, F_trayNo = reqData.TrayNo, F_boxNo = Guid.NewGuid().ToString(), F_matName = SysSetCore.GetSysSet().DefaultEmptyTrayGroupName, F_warehouseNo = SysSetCore.GetSysSet().DefaultWarehouseNo }); //更新库存 UpdateInventory(lstInv, ctx); if (point.F_type == (int)EPointType.CPAGV) { var p = GetFreePointInfoByType((int)EPointType.SSXRK); task.F_EquipmentType = (int)EEquipmentType.AGV; task.F_posidNext = p.F_no; } else { var loc = ctx.Queryable().OrderBy("F_layer ASC, F_line DESC,F_cell asc").First(f => f.F_status == (int)EWareCellState.Empty); if (loc == null) throw SysExCore.ThrowFailException($"没有可分配的货位!"); ctx.Updateable().SetColumns(it => new BASE_LOCATION() { F_editTime = DateTime.Now, F_editUserNo = LoginUser.UserNo, F_status = (int)EWareCellState.In, F_isBonded = IsBonded, F_trayNo = reqData.TrayNo }).Where(it => it.F_no == loc.F_no).ExecuteCommand(); task.F_EquipmentType = (int)EEquipmentType.Convey; task.F_posidNext = loc.F_no; task.F_posidTo = loc.F_no; } ctx.Insertable(task).ExecuteReturnEntity(); ctx.CommitTran(); return SysExCore.GetResSucc("空托盘组入库任务生成成功"); } catch (Exception ex) { ctx.RollbackTran(); throw ex; } } } } }