using SqlSugar; using System; using System.Collections.Generic; using System.Linq; using System.Text; using WMS.Core._02Entity; using WMS.Core.AppBll; using WMS.Info; using WMS.Info.Models; using WMS.Util; namespace WMS.Core.APPBLL { public class ProductBLL : AppCoreBLL { public ResInfo StockOutPickSubimit(ProductStockOutRequest request) { using (var ctx = SysDbCore.GetDbCtx()) { ctx.BeginTran(); try { if (string.IsNullOrWhiteSpace(request?.TrayNo) || !request.BoxNos.Any() || !request.OrderLines.Any()) throw SysExCore.ThrowFailException("参数不能为空"); //根据托盘码获取出库单号 var stockOutEntity = ctx.Queryable((ord, detail) => new object[] { JoinType.Inner, ord.F_no == detail.F_pNo }) .Where((ord, detail) => detail.F_trayNo == request.TrayNo && ord.F_orderStatus != (int)EOrderState.Executed).Select().First(); if(stockOutEntity==null) throw SysExCore.ThrowFailException("当前托盘已不存在需要出库信息,请同步销售工单后再进行拣选出库!"); ctx.Updateable().SetColumns(it => new BILL_STOCKOUTLINE { F_editTime = DateTime.Now, F_editUserNo = LoginUser.UserNo, F_actualQty = request.OrderLines.Sum(s => s.F_actualQty) }).Where(w => w.F_matNo == request.OrderLines.FirstOrDefault().F_matNo && w.F_pNo == stockOutEntity.F_no).ExecuteCommand(); var stockOutLineLst = ctx.Queryable().Where(w => w.F_pNo == stockOutEntity.F_no).ToList(); if (!stockOutLineLst.Any(a => a.F_actualQty != a.F_planQty)) { ctx.Updateable().SetColumns(it => new BILL_STOCKOUT { F_editTime = DateTime.Now, F_editUserNo = LoginUser.UserNo, F_orderStatus = (int)EOrderState.Executed }).Where(w => w.F_no == stockOutEntity.F_no).ExecuteCommand(); } List lstInv = new List(); foreach (var box in request.BoxNos.Distinct()) { var inv = ctx.Queryable().First(f => f.F_trayNo == request.TrayNo && f.F_boxNo == box && f.F_matNo == request.OrderLines.FirstOrDefault().F_matNo); var detail = ctx.Queryable().Where(f => f.F_pNo == stockOutEntity.F_no && f.F_trayNo == request.TrayNo && f.F_boxNo == box).First(); if (inv == null || detail == null) continue; inv.F_quantity = detail.F_quantity * -1; lstInv.Add(inv); } //更新库存 UpdateInventory(lstInv, ctx); ctx.CommitTran(); return SysExCore.GetResSucc("出库成功!"); } catch (Exception ex) { ctx.RollbackTran(); throw ex; } finally { ctx.Dispose(); } } } public ResInfo Entry(ScanCodeRequest reqData) { using (var ctx = SysDbCore.GetDbCtx()) { try { if (string.IsNullOrWhiteSpace(reqData?.LocationNo) || string.IsNullOrWhiteSpace(reqData.TrayNo)) throw SysExCore.ThrowFailException("参数不能为空"); ctx.BeginTran(); //获取当前点位信息 var location = GetPointInfo(reqData.LocationNo); if (location == null) throw SysExCore.ThrowFailException("请输入有效的位置码!"); if (location.F_type != (int)EPointType.CPRKJXK && location.F_type != (int)EPointType.CPCKJXK) throw SysExCore.ThrowFailException("请扫描正确的成品入库拣选口!"); if (location.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("异常口任务生成成功"); } var trayLocation = new FxBaseLocationCore().GetLociotnByTrayNo(reqData.TrayNo); if (trayLocation != null && trayLocation.F_status != (int)EWareCellState.Empty) throw SysExCore.ThrowFailException("当前托盘号已存在货位数据"); var entryOrder = new BILL_ENTRYORDER { F_no = SerialNumberProvider.Instance.OrderNumber("wms", "RK"), F_addTime = DateTime.Now, F_addUserNo = LoginUser.UserNo, F_editTime = DateTime.Now, F_locationNo = reqData.LocationNo, F_orderStatus = (int)EOrderState.New, F_orderType = (int)EEntryOrderType.EntryOrderTypeProduct, F_trayNo = reqData.TrayNo, F_isBonded = reqData.TrayNo.StartsWith("B"), F_warehouseNo = SysSetCore.GetSysSet().DefaultWarehouseNo }; var task = new WMS_TASK { F_addTime = DateTime.Now, F_addUserNo = LoginUser.UserNo, F_editTime = DateTime.Now, F_trayNo = reqData.TrayNo, F_posidNext = GetFreePointInfoByType((int)EPointType.RKDFPHWDW).F_no, F_priority = (int)EPriority.NotUrgent, F_taskStatus = (int)ETaskStatus.NotIssued, F_taskType = (int)ETaskComType.InStock, F_orderType = (int)ETaskOrderType.EntryOrderTypeProduct, F_posidFrom = reqData.LocationNo, F_posidcur = reqData.LocationNo, F_EquipmentType = (int)EEquipmentType.Convey, F_isBonded = reqData.TrayNo.StartsWith("B"), }; task.F_orderNo = entryOrder.F_no; if (location.F_type == (int)EPointType.CPCKJXK) { #region 出库拣选入库 var invs = ctx.Queryable().Where(i => i.F_trayNo == reqData.TrayNo && i.F_quantity > 0).ToList(); if (!invs.Any()) throw SysExCore.ThrowFailException("当前托盘信息为空!"); entryOrder.F_totalOrderLines = invs.Count(); invs.ForEach(inv => { ctx.Insertable(new BILL_ENTRYORDERLINEDETAIL { F_addTime = DateTime.Now, F_addUserNo = LoginUser.UserNo, F_quantity = inv.F_quantity, F_matNo = inv.F_matNo, F_matName = inv.F_matName, F_matType = (int)EMatType.Product, F_pNo = entryOrder.F_no, F_trayNo = inv.F_trayNo, F_batchNo = inv.F_batchNo, F_boxNo = inv.F_boxNo, }).ExecuteCommand(); }); #endregion } if (location.F_type == (int)EPointType.CPRKJXK) { #region 组盘拣选入库 List lstInv = new List(); var matInfos = ctx.Queryable((wo, info) => new object[] { JoinType.Inner, wo.order_code == info.order_code }) .Where((wo, info) => info.tray_no == reqData.TrayNo && wo.wo_status == 1).Select().ToList(); if (!matInfos.Any()) throw SysExCore.ThrowFailException($"未获取到托盘号{reqData.TrayNo}组盘信息"); matInfos.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_pNo = entryOrder.F_no, F_boxNo = orderLine.box_code, F_trayNo = reqData.TrayNo }).ExecuteCommand(); var matDetail = ctx.Queryable().Where(c => c.order_code == orderLine.order_code && c.wo_part == orderLine.wo_part).ToList(); foreach (var item in matDetail) { lstInv.Add(new BILL_INVENTORY { F_addTime = DateTime.Now, F_addUserNo = LoginUser.UserNo, F_editTime = DateTime.Now, F_matNo = item.wo_part, F_matType = (int)EMatType.Product, F_projectNo = mat.F_projectNo, F_quantity = item.qty, F_unit = mat?.F_unit, F_boxNo = item.box_code, F_matName = mat?.F_matName, F_trayNo = reqData.TrayNo, F_warehouseNo = SysSetCore.GetSysSet().DefaultWarehouseNo, F_isBonded = reqData.TrayNo.StartsWith("B"), }); } }); entryOrder.F_totalOrderLines = matInfos.Count; entryOrder.F_relatedOrderNo = string.Join(",", matInfos.Select(s => s.order_code)); ctx.Updateable().SetColumns(it => new FX_wo_mstr() { edit_Time = DateTime.Now, edit_user = LoginUser.UserNo, wo_status = 2 }).Where(w => w.order_code == matInfos.First().order_code).ExecuteCommand(); //更新库存 UpdateInventory(lstInv, ctx); #endregion } ctx.Insertable(entryOrder).ExecuteCommand(); ctx.Insertable(task).ExecuteReturnEntity(); ctx.CommitTran(); return SysExCore.GetResSucc("成品入库任务生成成功"); } catch (Exception ex) { ctx.RollbackTran(); throw ex; } } } /// /// 工单提交验证并获取出库明细 /// /// /// public ResInfo WorkOrderSubmit(WorkOrderRequest reqData) { if (reqData?.workOrders.Count < 1) { SysExCore.ThrowFailException("请求工单数据不能为空"); } using (var ctx = SysDbCore.GetDbCtx()) { try { //验证工单 StringBuilder sb = new StringBuilder(); sb.Append(@" "); foreach (var item in reqData.workOrders) { //if (ctx.Queryable().Any(c => c.wo_lot == item.wo_lot)) // throw SysExCore.ThrowFailException($"工单{item.wo_lot}已经验证过!"); sb.Append(""); sb.Append($"{item.wo_lot}"); sb.Append($"{item.wo_qty_ord} "); sb.Append($"{item.lotserial}"); sb.Append($"{item.location}"); sb.Append(@""); } sb.Append(@" "); var res = WebServiceCall.callWebService(SysSetCore.GetSysSet().FxWebServiceUrl, "processQdocMessage", sb.ToString()); if (res.Contains("error")) throw SysExCore.ThrowFailException($"工单验证失败!{string.Join(",", new TransferBLL().WebSerciceResponse(res))}"); //string whereStr = string.Join("','", reqData.workOrders.Select(s => s.wo_lot)); reqData.workOrders.ForEach(order => { if (ctx.Queryable().Any(a => a.wo_lot == order.wo_lot)) throw SysExCore.ThrowFailException($"工单{ order.wo_lot}已存在!"); var fxmat = FxDbCore.GetData($"select * from pub.wo_mstr where wo_domain = 'AFCN' and wo_site='SUZ' and wo_lot ='{order.wo_lot}' "); fxmat.ForEach(mat => { mat.order_code = SerialNumberProvider.Instance.OrderNumber("wms", "ZP"); mat.add_Time = DateTime.Now; mat.add_user = LoginUser.UserNo; mat.wo_qty_ord = order.wo_qty_ord; mat.wo_qty_comp = 0; mat.wo_loc = order.location; mat.wo_lotserial = order.lotserial; mat.edit_Time = DateTime.Now; mat.wo_lot = order.wo_lot; var woMat = ctx.Queryable().Where(a => a.wo_lot == mat.wo_lot && a.wo_part == mat.wo_part).First(); if (woMat != null) { ctx.Updateable().SetColumns(it => new FX_wo_mstr { wo_qty_ord = woMat.wo_qty_ord + order.wo_qty_ord, wo_status = 0, edit_Time = DateTime.Now, edit_user = LoginUser.UserNo, }).Where(w => w.order_code == woMat.order_code && w.wo_lot == woMat.wo_lot && w.wo_part == woMat.wo_part).ExecuteCommand(); } else { ctx.Insertable(fxmat).ExecuteCommand(); } }); }); ctx.CommitTran(); return SysExCore.GetResSucc("验证成功!"); } catch (Exception ex) { ctx.RollbackTran(); throw ex; } } } /// /// 已验证工单查询 /// /// /// public ResInfo WorkOrderQuery(string lotNo) { var woEntity = SysDbCore.GetDbCtx().Queryable().Where(w => w.wo_lot == lotNo).ToList(); return SysExCore.GetResSucc(data: woEntity); } /// /// 根据栈板或箱码获取物料明细 /// /// /// public ResInfo CombByFxCode(string code) { return null; //FxWebReference.interfaceClass interfaceClass = new FxWebReference.interfaceClass(); ////FxWebReference.interfaceClassPortTypeClient interfaceClass = new FxWebReference.interfaceClassPortTypeClient(); //var param = new //{ // uuid = Guid.NewGuid().ToString(), // condition = new // { // code = code // }, // dataType = "getBoxOrPalletData" //}; //var res = interfaceClass.GetDataFromMes(param.ToJson()); //var respEntity = res.ToObject(); //if (respEntity.result != "PASS") // throw SysExCore.ThrowFailException(respEntity.message); //if (respEntity.responseData?.is_success != true) // throw SysExCore.ThrowFailException(respEntity.responseData.message); //var wo = SysDbCore.GetDbCtx().Queryable().Where(c => c.add_user == LoginUser.UserNo && c.wo_qty_comp < c.wo_qty_ord && c.wo_status < 1 && SqlFunc.ContainsArray(respEntity.responseData.data.Select(S => S.pt_part).ToList(), c.wo_part)).OrderBy(o => o.add_Time).First(); //if (wo == null) // throw SysExCore.ThrowFailException("找到不该物料对应的已验证工单或该托盘数量大于工单计划数量"); //List matInfos = new List(); //respEntity.responseData.data.ForEach(item => //{ // var mat = CacheFacade.GetMatInfo(item.pt_part, EMatType.Product); // matInfos.Add(new MatInfo // { // order_code = wo.order_code, // boxCode = item.box_code, // matNo = item.pt_part, // quantity = item.qty, // productDate = item.pro_time, // matType = (int)EMatType.Product, // matName = mat.F_matName, // }); //}); //return SysExCore.GetResSucc(data: matInfos); } /// /// 组盘提交 /// /// /// public ResInfo CombSubmit(PackTrayRequest reqData) { if (!reqData.Mats.Any()) throw SysExCore.ThrowFailException("组盘信息不能为空"); var trayLocation = new FxBaseLocationCore().GetLociotnByTrayNo(reqData.TrayNo); if (trayLocation != null && trayLocation.F_status != (int)EWareCellState.Empty) throw SysExCore.ThrowFailException("当前托盘号已存在货位数据"); using (var ctx = SysDbCore.GetDbCtx()) { try { ctx.BeginTran(); List mstr_Infos = new List(); reqData.Mats.ForEach(mat => { mstr_Infos.Add(new FX_wo_mstr_info { pro_time = mat.productDate, box_code = mat.boxCode, qty = mat.quantity, tray_no = reqData.TrayNo, order_code = mat.order_code, wo_part = mat.matNo, wo_part_name = mat.matName, }); var woMat = ctx.Queryable().OrderBy(o => o.add_Time).First(c => c.order_code == mat.order_code && c.wo_part == mat.matNo && c.wo_status < 2 && c.wo_qty_ord > c.wo_qty_comp && (c.wo_qty_ord - c.wo_qty_comp) > mat.quantity); if(woMat==null) throw SysExCore.ThrowFailException($"未匹配到有效验证的工单!"); if ((woMat.wo_qty_comp + mat.quantity) > woMat.wo_qty_ord) throw SysExCore.ThrowFailException($"绑盘数量不能大于工单{woMat.wo_lot}需求数量!"); woMat.wo_qty_comp += mat.quantity; ctx.Updateable().SetColumns(it => new FX_wo_mstr() { wo_qty_comp = woMat.wo_qty_comp }).Where(it => it.wo_lot == woMat.wo_lot && it.wo_part == woMat.wo_part).ExecuteCommand(); if (ctx.Queryable().Any(a => a.wo_qty_comp == a.wo_qty_ord && a.order_code == woMat.order_code && a.wo_lot == woMat.wo_lot && a.wo_part == woMat.wo_part)) { ctx.Updateable().SetColumns(it => new FX_wo_mstr { wo_status = 1, edit_user = LoginUser.UserNo, edit_Time = DateTime.Now }).Where(w => w.order_code == woMat.order_code && w.wo_lot == woMat.wo_lot && w.wo_part == woMat.wo_part).ExecuteCommand(); } }); var retCount = ctx.Insertable(mstr_Infos).ExecuteCommand(); if (retCount < 1) throw SysExCore.ThrowFailException("提交失败"); ctx.CommitTran(); } catch (Exception) { ctx.RollbackTran(); throw; } return SysExCore.GetResSucc("提交成功"); } } /// /// 根据托盘和箱码获取拣选出库明细 /// /// /// public ResInfo GetStockOutLineDetail(StockOutScanBoxCodeRequest request) { if (string.IsNullOrWhiteSpace(request.BoxCode) || string.IsNullOrWhiteSpace(request.TrayNo)) throw SysExCore.ThrowFailException("托盘码或箱码都不能为空"); var stockOutLines = SysDbCore.GetDbCtx().Queryable((line, detail) => new object[] { JoinType.Inner, line.F_pNo == detail.F_pNo && line.F_matNo == detail.F_matNo }) .Where((line, detail) => detail.F_trayNo == request.TrayNo && detail.F_boxNo == request.BoxCode).Select().ToList(); return SysExCore.GetResSucc(data: stockOutLines); } } }