using SqlSugar; using System; using System.Collections.Generic; using System.Linq; using WMS.Core._02Entity; using WMS.Info; using WMS.Info.Models; using WMS.Util; namespace WMS.Core.APPBLL { public class AgvCallBLL : AppCoreBLL { /// /// agv扫码入库 /// /// /// public ResInfo AgvIn(AgvCallRequest reqData) { SqlSugarClient ctx = SysDbCore.GetDbCtx(); try { if (string.IsNullOrWhiteSpace(reqData?.TrayNo) || string.IsNullOrWhiteSpace(reqData.LocationNo)) throw SysExCore.ThrowFailException("参数不能为空"); ctx.BeginTran(); //生产wms任务 WMS_TASK task = new WMS_TASK { F_addTime = DateTime.Now, F_addUserNo = LoginUser.UserNo, F_posidFrom = reqData.LocationNo, F_posidcur = reqData.LocationNo, F_posidNext = reqData.LocationNo, //F_posidTo = , F_priority = (int)EPriority.NotUrgent, F_taskStatus = (int)ETaskStatus.NotIssued, F_taskType = (int)ETaskComType.InStock, F_trayNo = reqData.TrayNo, F_EquipmentType = (int)EEquipmentType.AGV }; //根据位置码盘点判断成品或原料 var point = GetPointInfo(reqData.LocationNo); if (point == null) throw SysExCore.ThrowFailException("该点位数据无效!"); //整盘生产入库单 if (reqData.FullPlate) { if (ctx.Queryable().Any(a => a.F_trayNo == reqData.TrayNo && a.F_orderStatus != (int)EOrderState.Executed)) throw SysExCore.ThrowFailException($"托盘号{reqData.TrayNo}已存在入库信息!"); BILL_ENTRYORDER entryOrder = new BILL_ENTRYORDER { F_no = SerialNumberProvider.Instance.OrderNumber("wms", "RK"), F_addTime = DateTime.Now, F_addUserNo = LoginUser.UserNo, F_editTime = DateTime.Now, F_fullPlate = reqData.FullPlate, //F_locationNo = reqData.LocationNo, F_orderStatus = (int)EOrderState.New, F_trayNo = reqData.TrayNo, F_isBonded = reqData.TrayNo.StartsWith("B"), F_warehouseNo = SysSetCore.GetSysSet().DefaultWarehouseNo }; List lstInv = new List(); switch ((EPointType)point.F_type) { case EPointType.YLAGV: #region 原料 var mInfos = FxDbCore.GetData($"select ld_domain,ld_site,ld_loc,ld_part,ld_ref,ld_lot,ld_qty_oh from pub.ld_det where ld_domain='AFCN' and ld_site='SUZ' and ld_loc='{reqData.TrayNo}'"); if (mInfos.Count < 1) throw SysExCore.ThrowFailException($"未获取到托盘号{reqData.TrayNo}组盘信息"); mInfos.ToList().ForEach(orderLine => { var mat = CacheFacade.GetMatInfo(orderLine.ld_part, EMatType.Mat); ctx.Insertable(new BILL_ENTRYORDERLINEDETAIL { F_addTime = DateTime.Now, F_addUserNo = LoginUser.UserNo, F_batchNo = orderLine.ld_loc, F_matNo = orderLine.ld_part, F_matName = mat?.F_matName, F_matType = (int)EMatType.Mat, F_quantity = orderLine.ld_qty_oh, F_pNo = entryOrder.F_no, F_trayNo = reqData.TrayNo, F_UID = orderLine.ld_ref, }).ExecuteCommand(); lstInv.Add(new BILL_INVENTORY { F_addTime = DateTime.Now, F_addUserNo = LoginUser.UserNo, F_editTime = DateTime.Now, F_matNo = orderLine.ld_part, F_matType = (int)EMatType.Mat, F_projectNo = mat.F_projectNo, F_quantity = orderLine.ld_qty_oh, F_uid = orderLine.ld_ref, F_batchNo = orderLine.ld_lot, F_unit = mat.F_unit, F_matName = mat?.F_matName, F_trayNo = reqData.TrayNo, F_warehouseNo = SysSetCore.GetSysSet().DefaultWarehouseNo }); }); #region 原料入库直接覆盖当前托盘库存,不存在则清理 var trayInv = ctx.Queryable().Where(a => a.F_trayNo == reqData.TrayNo).ToList(); if (trayInv.Any()) { trayInv.ForEach(inv => { if (!mInfos.Any(orderLine => inv.F_trayNo == orderLine.ld_loc && inv.F_uid == orderLine.ld_ref && inv.F_matNo == orderLine.ld_part && inv.F_batchNo == orderLine.ld_lot)) { ctx.Deleteable().Where(c => c.F_no == inv.F_no).ExecuteCommand(); ctx.Insertable(new BILL_INVENTORYTRANSACTION { F_addTime = DateTime.Now, F_addUserNo = LoginUser.UserNo, F_batchNo = inv.F_batchNo, F_boxNo = inv.F_boxNo, F_matName = inv.F_matName, F_matNo = inv.F_matNo, F_matType = inv.F_matType, F_sourceLockQty = inv.F_lockQty, F_targetLockQty = 0, F_memo = inv.F_memo, F_projectNo = inv.F_projectNo, F_sourceTrayNo = inv.F_trayNo, F_targetTrayNo = string.Empty, F_warehouseNo = inv.F_warehouseNo, F_UID = string.Empty, F_sourceQuantity = inv.F_quantity, F_targetQuantity = 0 }).ExecuteCommand(); } }); } #endregion task.F_orderType = (int)EEntryOrderType.EntryOrderTypeMaterial; entryOrder.F_relatedOrderNo = mInfos.FirstOrDefault().ld_ref; entryOrder.F_orderType = (int)ETaskOrderType.EntryOrderTypeMaterial; entryOrder.F_totalOrderLines = mInfos.Count; #endregion break; case EPointType.CPAGV: #region 成品 if (ctx.Queryable().Any(a => a.F_trayNo == reqData.TrayNo && a.F_orderStatus != (int)EOrderState.Executed)) throw SysExCore.ThrowFailException($"托盘号{reqData.TrayNo}已存在入库信息!"); var pInfos = ctx.Queryable((wo, info) => new object[] { JoinType.Inner, wo.order_code == info.order_code }) .Where((wo, info) => info.tray_no == reqData.TrayNo).Select().ToList(); if (!pInfos.Any()) throw SysExCore.ThrowFailException("根据托盘未获取到有效的组盘信息"); entryOrder.F_orderType = (int)EEntryOrderType.EntryOrderTypeProduct; pInfos.ForEach(orderLine => { var mat = CacheFacade.GetMatInfo(orderLine.wo_part, EMatType.Product); ctx.Insertable(new BILL_ENTRYORDERLINEDETAIL { F_addTime = DateTime.Now, F_addUserNo = LoginUser.UserNo, F_quantity = orderLine.qty, F_matNo = orderLine.wo_part, F_matName = mat?.F_matName, F_matType = (int)EMatType.Product, F_boxNo = orderLine.box_code, F_trayNo = orderLine.tray_no, F_pNo = entryOrder.F_no, }).ExecuteCommand(); lstInv.Add(new BILL_INVENTORY { F_addTime = DateTime.Now, F_addUserNo = LoginUser.UserNo, F_editTime = DateTime.Now, F_matNo = orderLine.wo_part, F_matType = (int)EMatType.Mat, F_projectNo = mat.F_projectNo, F_quantity = orderLine.qty, F_unit = mat.F_unit, F_matName = mat?.F_matName, F_trayNo = reqData.TrayNo, F_warehouseNo = SysSetCore.GetSysSet().DefaultWarehouseNo }); }); entryOrder.F_totalOrderLines = pInfos.Count; entryOrder.F_relatedOrderNo = pInfos.FirstOrDefault()?.order_code; entryOrder.F_orderType = (int)EEntryOrderType.EntryOrderTypeProduct; task.F_orderType = (int)ETaskOrderType.EntryOrderTypeProduct; #endregion break; case EPointType.DPJ: #region 空托盘组 ctx.Insertable(new BILL_ENTRYORDERLINEDETAIL { F_addTime = DateTime.Now, F_addUserNo = LoginUser.UserNo, F_quantity = 1, F_matNo = SysSetCore.GetSysSet().DefaultEmptyTrayGroupNo, F_matName = SysSetCore.GetSysSet().DefaultEmptyTrayGroupName, F_matType = (int)EMatType.Tary, F_trayNo = reqData.TrayNo, F_pNo = entryOrder.F_no }).ExecuteCommand(); lstInv.Add(new BILL_INVENTORY { F_addTime = DateTime.Now, F_addUserNo = LoginUser.UserNo, F_editTime = DateTime.Now, F_matNo = nameof(EMatType.Tary), F_matType = (int)EMatType.Mat, //F_projectNo = mat.F_projectNo, F_quantity = 1, //F_unit = mat.F_unit, //F_matName = mat?.F_matName, F_trayNo = reqData.TrayNo, F_warehouseNo = SysSetCore.GetSysSet().DefaultWarehouseNo }); entryOrder.F_orderType = (int)EEntryOrderType.EntryOrderTypeTray; task.F_orderType = (int)ETaskOrderType.EntryOrderTypeTrayGroup; #endregion break; default: throw SysExCore.ThrowFailException("请扫描正确的货位码!"); } task.F_orderNo = entryOrder.F_no; task.F_posidNext = GetFreePointInfoByType((int)EPointType.SSXRK)?.F_no; UpdateInventory(lstInv, ctx); ctx.Insertable(entryOrder).ExecuteCommand(); } else { var pointTo = GetFreePointInfoByType(point.F_type == (int)EPointType.YLAGV ? (int)EPointType.YLRKJXK : (int)EPointType.CPRKJXK); task.F_posidTo = pointTo.F_agv; task.F_posidNext = pointTo.F_agv; task.F_orderType = (int)ETaskOrderType.EntryOrderTypeOther; } var taskReturn = ctx.Insertable(task).ExecuteReturnEntity(); ctx.CommitTran(); return SysExCore.GetResSucc("AGV任务已生成"); } catch (Exception ex) { ctx.RollbackTran(); throw ex; } finally { ctx.Dispose(); } } /// /// agv扫码出库 /// /// /// public ResInfo AgvOut(AgvCarryRequest reqData) { if (string.IsNullOrWhiteSpace(reqData.LocationNo)) throw SysExCore.ThrowFailException("请扫码正确的agv点位!"); using (var ctx = SysDbCore.GetDbCtx()) { ctx.BeginTran(); if (!ctx.Queryable().Any(a => (a.F_no == reqData.LocationNo ||a.F_agv==reqData.LocationNo) && (a.F_type == (int)EPointType.YLCKJXK || a.F_type == (int)EPointType.CPCKJXK || a.F_type == (int)EPointType.CPRKJXK || a.F_type == (int)EPointType.YLRKJXK))) throw SysExCore.ThrowFailException("请扫码正确的agv点位!"); var pointFrom = ctx.Queryable().Where(c => c.F_no == reqData.LocationNo).First(); ///获取存储区AGV点位 var pointTo = ctx.Queryable().Where(c => c.F_type == (int)EPointType.CPAGV && c.F_status == (int)EPointSatus.Idle).OrderBy(o => o.F_sort).First(); if (pointTo == null) throw SysExCore.ThrowFailException("没有闲置的存储区点位!"); if (ctx.Queryable().Any(t => t.F_posidFrom == reqData.LocationNo && t.F_taskStatus < (int)ETaskStatus.TaskFinish)) throw SysExCore.ThrowFailException("已存在当前点位AGV任务,请勿重复创建!"); //生产wms任务 WMS_TASK task = new WMS_TASK { F_addTime = DateTime.Now, F_addUserNo = LoginUser.UserNo, F_posidFrom = pointFrom.F_agv, F_posidcur = pointFrom.F_agv, F_posidNext = pointTo.F_no, F_posidTo = pointTo.F_no, F_priority = (int)EPriority.NotUrgent, F_taskStatus = (int)ETaskStatus.NotIssued, F_taskType = (int)ETaskComType.OutStock, F_EquipmentType = (int)EEquipmentType.AGV, F_orderType = (int)ETaskOrderType.StockOutOrderTypeOther, }; ctx.Insertable(task).ExecuteCommand(); //ctx.Updateable(point).UpdateColumns(it => it.F_status).WhereColumns(it => it.F_no== point.F_no).ExecuteCommand(); ctx.Updateable().SetColumns(it => new BASE_POINT() { F_status = (int)EPointSatus.Occupied, F_editTime = DateTime.Now, F_editUserNo = LoginUser.UserNo, //F_isBonded = reqData.IsBonded }).Where(w => w.F_no == pointTo.F_no).ExecuteCommand(); return SysExCore.GetResSucc("AGV任务已生成"); } } } }