using System; using System.Collections.Generic; using SqlSugar; using System.Linq; using System.Linq.Expressions; using Model.InterFaceModel; using Model.ModelDto; using SqlSugar.Extensions; using WMS.Entity.BllSoEntity; using WMS.Entity.Context; using WMS.Entity.DataEntity; using WMS.Entity.SysEntity; using WMS.IBLL.IPdaServer; using Model.ModelVm; using Model.ModelVm.PdaVm; using Newtonsoft.Json; using Utility.Tools; using WMS.BLL.LogServer; using WMS.DAL; using WMS.Entity.LogEntity; using Model.ModelDto.SysDto; using Model.ModelDto.BllSoDto; using System.Security.Policy; namespace WMS.BLL.BllPdaServer { public class PdaSoServer : IPdaSoServer { private static readonly SqlSugarScope Db = DataContext.Db; //验证托盘是否存在并是否可出库 public string IsEnableOkPalletNo(string palletNo) { try { string sqlMsg = ""; var models = Db.Queryable().Where(m => m.IsDel == "0" && m.PalletNo == palletNo).ToList(); if (models.Count > 1) { sqlMsg = "-1:存在重复托盘号,请检查!"; return sqlMsg; } if (models.Count > 0) { if (models[0].Status == "0") { sqlMsg = "-1:托盘号状态为未使用!"; } } else { sqlMsg = "-1:托盘号不存在!"; } return sqlMsg; } catch (Exception ex) { throw new Exception(ex.Message); } } //获取托盘中含有的执行中的单据 public List GetRunSoNoticeList(string palletNo, string type) { try { if (string.IsNullOrWhiteSpace(palletNo))//判断托盘是否为空 { throw new Exception("托盘码为空,请输入托盘码"); } var palletInfo = Db.Queryable().First(w => w.IsDel == "0" && w.PalletNo == palletNo); if (!string.IsNullOrEmpty(palletInfo.WareHouseNo) && type != "1") { throw new Exception("该托盘还未出库"); } if (type == "1")//平库出库获取单据 { var allotList = Db.Queryable().Where(m => m.IsDel == "0" && m.Status == "1" && m.PalletNo == palletNo).Select(m => m.SONo).Distinct().Where(m => !string.IsNullOrWhiteSpace(m)).ToList(); return allotList; } //获取状态为待拣货或者部分拣货的出库单 var allotList2 = Db.Queryable().Where(m => m.IsDel == "0" && (m.Status == "2" || m.Status == "3") && m.PalletNo == palletNo).Select(m => m.SONo).Distinct().Where(m => !string.IsNullOrWhiteSpace(m)).ToList(); //var allotList = Db.Queryable().Where(m => m.IsDel == "0" && m.PalletNo == palletNo).Select(m => m.SONo).Distinct().Where(m => !string.IsNullOrWhiteSpace(m)).ToList(); //获取出库单据不为待拣货 执行完毕 订单关闭 等待执行的单据 //var export = Db.Queryable().Where(a => a.IsDel == "0" && a.Status == "1" || a.Status == "2" || a.Status == "3").Select(a => a.SONo).Distinct().Where(m => !string.IsNullOrWhiteSpace(m)).ToList(); return allotList2; } catch (Exception ex) { throw new Exception(ex.Message); } } //获取出库托盘上的物料批次(根据托盘码) public List GetSoSkuLotNoListByPallet(string palletNo, string soNo) { try { if (string.IsNullOrWhiteSpace(palletNo))//判断托盘是否为空 { throw new Exception("托盘码为空,请输入托盘码"); } //获取状态为待拣货或者部分拣货的出库单 var allotList = Db.Queryable().Where(m => m.IsDel == "0" && (m.Status == "2" || m.Status == "3") && m.PalletNo == palletNo); //var allotList = Db.Queryable().Where(m => m.IsDel == "0" && m.SONo == soNo && m.Status != "4" && m.Status != "5"); if (!string.IsNullOrWhiteSpace(soNo)) { allotList = allotList.Where(m => m.SONo == soNo); } var list = allotList.GroupBy(m => new { m.SODetailNo, m.PalletNo, m.SkuNo, m.SkuName, m.LotNo }).Select(m => new DetailIdSkuLotNo() { SoDetailId = m.SODetailNo, PalletNo = m.PalletNo, SkuNo = m.SkuNo, SkuName = m.SkuName, LotNo = m.LotNo, }).ToList(); return list; } catch (Exception ex) { throw new Exception(ex.Message); } } //获取出库口、规格、待拣及已拣数量(根据出库单明细ID、托盘号) public OutPdaInfo GetOutlets(string soDetailId, string palletNo) { try { var allotInfo = Db.Queryable().Where(m => m.IsDel == "0" && m.SODetailNo == int.Parse(soDetailId) && m.PalletNo == palletNo && (m.Status == "2" || m.Status == "3")).ToList(); if (allotInfo.Count == 0) { throw new Exception($"{palletNo}托盘上未查询到分配信息,请核实"); } if (allotInfo.Count > 1) { throw new Exception($"{palletNo}托盘上存在多条相同的分配信息,请核实"); } var data = allotInfo.First(); var data2 = new OutPdaInfo() { OutModel = data.OutMode, Standard = data.Standard, PickQty = data.Qty, PickedQty = data.CompleteQty }; return data2; } catch (Exception e) { throw new Exception(e.Message); } } //获取出库单的计划数量和完成 public OutPdaInfo GetPlanAndFinishQty(string soDetailId) { try { var detail = Db.Queryable().First(m => m.Id == int.Parse(soDetailId) && m.IsDel == "0"); if (detail == null) { throw new Exception("未查询到出库单的明细"); } var data = new OutPdaInfo() { PlanQty = detail.Qty, FinishQty = detail.CompleteQty }; return data; } catch (Exception e) { throw new Exception(e.Message); } } //获取箱码信息(根据箱码在库存箱码明细中查询及拣货明细中拣货数量) public List GetDataComBoxInfo(string soDetailId, string palletNo, string boxNo, string boxNo3) { try { if (string.IsNullOrWhiteSpace(palletNo)) { throw new Exception("托盘号不能为空"); } Expression> item = Expressionable.Create() .And(it => it.PalletNo == palletNo) .AndIF(!string.IsNullOrWhiteSpace(boxNo), it => it.BoxNo == boxNo) .AndIF(!string.IsNullOrWhiteSpace(boxNo3), it => it.BoxNo3 == boxNo3) .And(m => m.IsDel == "0") .ToExpression();//注意 这一句 不能少 var info = Db.Queryable().Where(item); if (info.Count() == 0) { throw new Exception("未在库存中查询到信息"); } var type = "0";//0:查箱码或支码不分组 1:查托盘分组 显示箱 var list = new List(); if (!string.IsNullOrWhiteSpace(boxNo3) || !string.IsNullOrWhiteSpace(boxNo))//判断支码是否为空 { foreach (var demo in info.ToList()) { var t = new BoxInfo() { BoxNo = demo.BoxNo3, Qty = demo.Qty, //SkuNo = demo.SkuNo, //SkuName = demo.SkuName, //LotNo = demo.LotNo, }; list.Add(t); } } else if (!string.IsNullOrWhiteSpace(palletNo)) { list = info.GroupBy(m => new { m.BoxNo }).Select(it => new BoxInfo { BoxNo = it.BoxNo, Qty = SqlFunc.AggregateSum(it.Qty) }).ToList(); type = "1"; } if (!string.IsNullOrWhiteSpace(soDetailId)) { var allotInfos = Db.Queryable().Where(m => m.IsDel == "0" && m.SODetailNo == int.Parse(soDetailId) && m.PalletNo == palletNo && (m.Status == "2" || m.Status == "3")).ToList(); if (allotInfos.Count == 0) { throw new Exception($"{palletNo}托盘上未查询到分配信息,请核实"); } if (allotInfos.Count > 1) { throw new Exception($"{palletNo}托盘上存在多条相同的分配信息,请核实"); } var allotInfo = allotInfos.First(); var comInfo = Db.Queryable().Where(m => m.IsDel == "0" && m.ExportAllotId == allotInfo.Id).ToList(); if (comInfo.Count != 0) { if (type == "0") { foreach (var demo in list) { //if (!string.IsNullOrWhiteSpace(boxNo3)) //{ // var com = comInfo.FirstOrDefault(m => m.IsDel == "0" && m.BoxNo3 == demo.BoxNo); //} //else if (!string.IsNullOrWhiteSpace(boxNo)) //{ // if (expr) // { // } //} var com = comInfo.FirstOrDefault(m => m.IsDel == "0" && m.BoxNo3 != null && m.BoxNo3 == demo.BoxNo); if (com != null) { demo.PickedQty = com.CompleteQty; } } } if (type == "1") { var com = comInfo.Where(m => m.IsDel == "0").GroupBy(m => m.BoxNo).Select(it => new BoxInfo { BoxNo = it.Key, PickedQty = it.Sum(a => a.CompleteQty) }).ToList(); foreach (var demo in list) { var com2 = com.FirstOrDefault(m => m.BoxNo == demo.BoxNo); if (com2 != null) { demo.PickedQty = com2.PickedQty; } } } } } return list; } catch (Exception e) { throw new Exception(e.Message); } } //获取库内无箱码的托盘分配信息 public List GetAllotPlnInfo(string soDetailId, string palletNo) { try { #region 判断 //根据id及托盘获取出库单和托盘拣货信息 if (string.IsNullOrWhiteSpace(palletNo)) { throw new Exception("托盘号不能为空"); } //获取对应托盘下是否存在箱码信息 var boxInfo = Db.Queryable().First(b => b.IsDel == "0" && b.PalletNo == palletNo); if (boxInfo != null) { throw new Exception($"{palletNo}托盘上存在箱码信息,无法在数量拣货进行操作!"); } BllExportAllot allot = null; if (!string.IsNullOrWhiteSpace(soDetailId)) { //出库单明细 var noticeDetail = Db.Queryable().First(a => a.Id == int.Parse(soDetailId) && a.IsDel == "0"); if (noticeDetail == null) { throw new Exception($"未查询到对应出库单明细信息,请核实!"); } //出库单总单 var notice = Db.Queryable().First(a => a.IsDel == "0" && a.SONo == noticeDetail.SONo); if (notice == null) { throw new Exception($"未查询到对应出库单总单信息,请核实!"); } //分配信息 allot = Db.Queryable().First(a => a.IsDel == "0" && a.SONo == notice.SONo && a.SODetailNo == noticeDetail.Id && a.PalletNo == palletNo && (a.Status == "2" || a.Status == "3")); if (allot == null) { throw new Exception($"未查询到对应分配信息,请核实!"); } } //库存明细 var detail = Db.Queryable().First(a => a.IsDel == "0" && a.PalletNo == palletNo); if (detail == null) { throw new Exception($"未查询到库存明细信息,请核实!"); } #endregion List pdaInfo = new List(); BoxInfo info = new BoxInfo() { SkuNo = detail.SkuNo, BoxNo = detail.SkuNo, Qty = allot == null ? (int)(detail.Qty - detail.LockQty) : (int)allot.Qty, PickedQty = allot == null ? 0 : (int)allot.CompleteQty, }; pdaInfo.Add(info); return pdaInfo; } catch (Exception e) { throw new Exception(e.Message); } } //出库pda拣货 public void SoSetPick(string soNo, string soDetailId, string palletNo, string boxNo, string boxNo3, string pickQty1, int userId) { Db.BeginTran(); try { #region 判断 if (string.IsNullOrWhiteSpace(soNo)) { throw new Exception("出库单据不能为空"); } if (string.IsNullOrWhiteSpace(soDetailId)) { throw new Exception("出库物料-批次不能为空"); } if (string.IsNullOrWhiteSpace(palletNo)) { throw new Exception("托盘码不能为空"); } if (!string.IsNullOrEmpty(boxNo3) && !string.IsNullOrEmpty(pickQty1) && decimal.Parse(pickQty1) > 0) { throw new Exception("追溯条码和拣货数量不能同时输入"); } //出库单 var notice = Db.Queryable().First(m => m.IsDel == "0" && m.SONo == soNo); if (notice == null) { throw new Exception("未查询到该出库单的信息"); } var type1 = new List() { "0", "4" }; //拣货不可多出 成品出库、不合格品出库 var type2 = new List() { "1", "2", "3", "5", "6", "7", "8" };//拣货可多出 领料出库、抽检出库、物料取样出库、中间品出库、代储出库、其他出库、寄存出库 if (type1.Contains(notice.Type)) { if (notice.Status != "3") { throw new Exception("出库单的状态不是正在执行,不能拣货"); } } if (type2.Contains(notice.Type)) { if (notice.Status != "3" && notice.Status != "4") { throw new Exception("出库单的状态不是正在执行或执行完成,不能拣货"); } } //出库单明细 var noticeDetail = Db.Queryable() .First(m => m.IsDel == "0" && m.Id == int.Parse(soDetailId)); if (noticeDetail == null) { throw new Exception("未查询到该出库单明细的信息"); } //出库分配信息 var allot = Db.Queryable().First(m => m.IsDel == "0" && (m.Status == "2" || m.Status == "3") && m.SONo == soNo && m.SODetailNo == int.Parse(soDetailId) && m.PalletNo == palletNo); if (allot == null) { throw new Exception("未查询到该托盘的分配信息"); } //剩余拣货数量(待拣减去已拣) var needQty = allot.Qty - allot.CompleteQty; //库存明细 var stockDetail = Db.Queryable().First(m => m.IsDel == "0" && m.Id == allot.StockId); if (stockDetail == null) { throw new Exception("未查询到该托盘分配的库存明细信息!"); } //库存总表 var stock = Db.Queryable().First(a => a.IsDel == "0" && a.SkuNo == stockDetail.SkuNo && a.LotNo == stockDetail.LotNo); if (stock == null) { throw new Exception("未查询到该托盘分配的库存信息!"); } #endregion if (string.IsNullOrWhiteSpace(boxNo))//整托拣货 { List boxInfos; var boxInfo = Db.Queryable().Where(m => m.IsDel == "0" && m.PalletNo == palletNo);//找到托盘上所有箱码 boxInfos = boxInfo.ToList(); if (boxInfo.Count() <= 0) { throw new Exception("该托盘上没有可拣货的箱子"); } var boxQty = boxInfo.GroupBy(m => m.PalletNo).Select(m => SqlFunc.AggregateSum(m.Qty)).ToList(); if (boxQty[0] > needQty) { throw new Exception("拣货数量不能大于箱内剩余待拣数量"); } decimal pickQty = 0;//拣货的数量 var comDetailList = Db.Queryable().Where(m => m.IsDel == "0" && m.ExportAllotId == allot.Id && m.PalletNo == palletNo).ToList(); var comList = new List(); foreach (var item in boxInfos) { if (comDetailList.Any(m => m.BoxNo3 == item.BoxNo3) && item.BoxNo3 != null) { throw new Exception($"当前{item.BoxNo}中{item.BoxNo3}已拣货完成,请勿重复拣货"); } if (item.SkuNo != allot.SkuNo || item.LotNo != allot.LotNo) { throw new Exception("当前托盘上有其他不同物料批次,拣货失败"); } //添加拣货明细 var completeDetail = new BllCompleteDetail() { SONo = soNo, SODetailNo = int.Parse(soDetailId), ExportAllotId = allot.Id, StockId = allot.StockId, BoxNo = item.BoxNo, BoxNo2 = item.BoxNo2, BoxNo3 = item.BoxNo3, LotNo = allot.LotNo, LotText = allot.LotText, SupplierLot = allot.SupplierLot, SkuNo = allot.SkuNo, SkuName = allot.SkuName, Standard = allot.Standard, PalletNo = palletNo, CompleteQty = item.Qty, CreateUser = userId }; comList.Add(completeDetail); //删除库存箱码明细 Db.Deleteable(item).ExecuteCommand(); pickQty += item.Qty; } //添加拣货明细 Db.Insertable(comList).ExecuteCommand(); //修改出库分配信息 allot.CompleteQty += pickQty; allot.Status = allot.Qty == allot.CompleteQty ? "5" : "3"; allot.UpdateTime = DateTime.Now; Db.Updateable(allot).ExecuteCommand(); //删除库存明细 Db.Deleteable(stockDetail).ExecuteCommand(); //删除或修改库存 stock.Qty -= pickQty; stock.LockQty -= pickQty; if (stock.Qty <= 0) { Db.Deleteable(stock).ExecuteCommand(); } else { Db.Updateable(stock).ExecuteCommand(); } //改变托盘状态为:未使用 var pallet = Db.Queryable().First(m => m.PalletNo == palletNo && m.IsDel == "0"); if (pallet == null) { throw new Exception("未在托盘表中查询到托盘信息"); } pallet.Status = "0"; Db.Updateable(pallet).ExecuteCommand(); //修改出库单明细拣货数量 noticeDetail.CompleteQty += pickQty; noticeDetail.Status = "2"; Db.Updateable(noticeDetail).ExecuteCommand(); var num = Db.Queryable() .Count(m => m.IsDel == "0" && m.SONo == soNo && m.CompleteQty < m.Qty); if (num <= 0) { notice.Status = "4"; //更改为执行完成 noticeDetail.Status = "3"; Db.Updateable(noticeDetail).ExecuteCommand(); } //修改出库单信息 Db.Updateable(notice).ExecuteCommand(); } else { var biaoShi = "0";//0:整箱拣货、1:散支拣货、2:数量拣货 List boxInfos; var boxInfo = Db.Queryable().Where(m => m.IsDel == "0" && m.BoxNo == boxNo && m.StockDetailId == stockDetail.Id); if (boxInfo.Count() == 0) { throw new Exception("未查询到该箱码及追溯码的信息"); } boxInfos = boxInfo.ToList(); var comDetailList = Db.Queryable().Where(m => m.IsDel == "0" && m.ExportAllotId == allot.Id && m.PalletNo == palletNo).ToList(); if (!string.IsNullOrWhiteSpace(boxNo3)) //散支拣货 { boxInfos = boxInfos.Where(m => m.BoxNo3 == boxNo3).ToList(); if (boxInfos.Count() == 0) { throw new Exception("未查询到该箱码及追溯码的信息"); } if (boxInfos.Count() > 1) { throw new Exception("该追溯支码的信息大于1条,信息错误,请核实!"); } if (boxInfos.Any(m => m.PalletNo != palletNo)) { throw new Exception("该托盘与箱码没有绑定关系"); } var boxQty = boxInfos.First().Qty; if (boxQty > needQty) { throw new Exception("拣货数量不能大于剩余待拣数量"); } foreach (var item in boxInfos) { if (biaoShi != "2" && comDetailList.Any(m => m.BoxNo3 == item.BoxNo3)) { throw new Exception($"当前{item.BoxNo}中{item.BoxNo3}已拣货完成,请勿重复拣货"); } } biaoShi = "1"; } else if (!string.IsNullOrEmpty(pickQty1) && decimal.Parse(pickQty1) > 0)//数量拣货 { if (boxInfo.Count() > 1) { throw new Exception("该箱码内存在支码不能进行数量拣货"); } decimal boxQty = boxInfo.First().Qty; if (Convert.ToDecimal(pickQty1) > boxQty) { throw new Exception("拣货数量不能大于箱内数量"); } if (Convert.ToDecimal(pickQty1) > needQty) { throw new Exception("拣货数量不能大于剩余待拣数量"); } biaoShi = "2"; } else //整箱拣货 { if (boxInfo.Count() == 0) { throw new Exception("未查询到该箱码的信息"); } if (boxInfo.Any(m => m.PalletNo != palletNo)) { throw new Exception("该托盘与箱码没有绑定关系"); } var boxQty = boxInfo.GroupBy(m => m.BoxNo).Select(m => SqlFunc.AggregateSum(m.Qty)).ToList(); if (boxQty[0] > needQty) { throw new Exception("拣货数量不能大于箱内剩余待拣数量"); } foreach (var item in boxInfos) { if (biaoShi != "2" && comDetailList.Any(m => m.BoxNo == item.BoxNo)) { throw new Exception($"当前{item.BoxNo}已拣货完成,请勿重复拣货"); } } } decimal pickQty = 0;//拣货的数量 var comList = new List(); foreach (var item in boxInfos) { //添加拣货明细 var completeDetail = new BllCompleteDetail() { SONo = soNo, SODetailNo = int.Parse(soDetailId), ExportAllotId = allot.Id, StockId = allot.StockId, BoxNo = item.BoxNo, BoxNo2 = item.BoxNo2, BoxNo3 = item.BoxNo3, LotNo = allot.LotNo, LotText = allot.LotText, SupplierLot = allot.SupplierLot, SkuNo = allot.SkuNo, SkuName = allot.SkuName, Standard = allot.Standard, PalletNo = palletNo, CompleteQty = biaoShi == "2" ? decimal.Parse(pickQty1) : item.Qty, CreateUser = userId }; comList.Add(completeDetail); if (biaoShi != "2") { pickQty += item.Qty; //删除库存箱码明细 Db.Deleteable(item).ExecuteCommand(); } else//数量拣货 { if (decimal.Parse(pickQty1) == item.Qty) { pickQty += item.Qty; //删除库存箱码明细 Db.Deleteable(item).ExecuteCommand(); } else { pickQty += decimal.Parse(pickQty1); item.Qty -= decimal.Parse(pickQty1); item.BitBoxMark = "1";//零箱标识 Db.Updateable(item).ExecuteCommand(); } } } //改变库内箱码是否零箱信息 if (biaoShi == "1") { var boxSurplusList = boxInfo.Where(m => m.BoxNo3 != boxNo3).ToList(); foreach (var item in boxSurplusList) { item.BitBoxMark = "1"; Db.Updateable(item).ExecuteCommand(); } } Db.Insertable(comList).ExecuteCommand(); //修改出库分配信息 allot.CompleteQty += pickQty; allot.Status = allot.Qty == allot.CompleteQty ? "5" : "3"; allot.UpdateTime = DateTime.Now; if (allot.Status == "5") { //判断该托盘是否还存在物料 存在改为待回库 待回库完成后改为已完成 } Db.Updateable(allot).ExecuteCommand(); //删除或修改库存明细 stockDetail.BitPalletMark = "1";//修改为零托标识 stockDetail.Qty -= pickQty; stockDetail.LockQty -= pickQty; if (stockDetail.Qty == stockDetail.LockQty) { stockDetail.Status = "2"; } else if (stockDetail.Qty > stockDetail.LockQty && stockDetail.LockQty > 0) { stockDetail.Status = "1"; } else { stockDetail.Status = "0"; } if (stockDetail.Qty <= 0) { Db.Deleteable(stockDetail).ExecuteCommand(); } else { Db.Updateable(stockDetail).ExecuteCommand(); } stock.Qty -= pickQty; stock.LockQty -= pickQty; if (stock.Qty <= 0) { Db.Deleteable(stock).ExecuteCommand(); } else { Db.Updateable(stock).ExecuteCommand(); } var num2 = Db.Queryable().Count(m => m.IsDel == "0" && m.PalletNo == palletNo); if (num2 <= 0) { //改变托盘状态 var pallet = Db.Queryable().First(m => m.PalletNo == palletNo && m.IsDel == "0"); if (pallet == null) { throw new Exception("未在托盘表中查询到托盘信息"); } pallet.Status = "0"; Db.Updateable(pallet).ExecuteCommand(); } //修改出库单明细拣货数量 noticeDetail.CompleteQty += pickQty; noticeDetail.Status = "2"; Db.Updateable(noticeDetail).ExecuteCommand(); var num = Db.Queryable() .Count(m => m.IsDel == "0" && m.SONo == soNo && m.CompleteQty < m.Qty); if (num <= 0) { notice.Status = "4"; //更改为执行完成 noticeDetail.Status = "3"; Db.Updateable(noticeDetail).ExecuteCommand(); } //修改出库单信息 Db.Updateable(notice).ExecuteCommand(); } //添加操作日志记录 var k = new OperationSOServer().AddLogOperationSo("PDA模块", "拣货出库", soNo, "拣货", $"在PDA上对出库单号为:{soNo}的托盘码为:{palletNo}的拣货操作", userId); Db.CommitTran(); } catch (Exception e) { Db.RollbackTran(); throw new Exception(e.Message); } } //出库pda拣货 public void SoSetQtyPick(string soNo, string soDetailId, string palletNo, string PickQty, int userId) { Db.BeginTran(); try { #region 判断 if (string.IsNullOrWhiteSpace(soNo)) { throw new Exception("出库单据不能为空"); } //if (string.IsNullOrWhiteSpace(soDetailId)) //{ // throw new Exception("出库物料-批次不能为空"); //} if (string.IsNullOrWhiteSpace(palletNo)) { throw new Exception("托盘码不能为空"); } //出库单 var notice = Db.Queryable().First(m => m.IsDel == "0" && m.SONo == soNo); if (notice == null) { throw new Exception("未查询到该出库单的信息"); } if (notice.Status != "3") { throw new Exception("出库单的状态不是正在执行,不能拣货"); } //出库单明细 var noticeDetail = Db.Queryable() .First(m => m.IsDel == "0" && m.Id == int.Parse(soDetailId)); if (noticeDetail == null) { throw new Exception("未查询到该出库单明细的信息"); } //出库分配信息 var allot = Db.Queryable().First(m => m.IsDel == "0" && (m.Status == "2" || m.Status == "3") && m.SONo == soNo && m.SODetailNo == int.Parse(soDetailId) && m.PalletNo == palletNo); if (allot == null) { throw new Exception("未查询到该托盘的分配信息"); } //剩余拣货数量(待拣减去已拣) var needQty = allot.Qty - allot.CompleteQty; if (decimal.Parse(PickQty) > needQty) { throw new Exception("拣货数量不能大于托内剩余待拣数量"); } //库存明细 var stockDetail = Db.Queryable().First(m => m.IsDel == "0" && m.Id == allot.StockId); if (stockDetail == null) { throw new Exception("未查询到该托盘分配的库存明细信息!"); } //库存总表 var stock = Db.Queryable().First(a => a.IsDel == "0" && a.SkuNo == stockDetail.SkuNo && a.LotNo == stockDetail.LotNo); if (stock == null) { throw new Exception("未查询到该托盘分配的库存信息!"); } #endregion //获取当前托盘拣货明细 var complete = Db.Queryable().First(a => a.IsDel == "0" && a.PalletNo == palletNo && a.SONo == notice.SONo && a.SODetailNo == noticeDetail.Id && a.ExportAllotId == allot.Id && a.StockId == stockDetail.Id); //判读是否存在拣货明细 int isComplete = 0; if (complete != null) { isComplete = 1; } var comList = new List(); //判断是否存在拣货明细 isComplete = 0;// 所有无箱码或一级箱码拣货时,拣货明细应重新插入数据(体现多次拣货流程记录) if (isComplete == 0) { //添加拣货明细 var completeDetail = new BllCompleteDetail() { SONo = soNo, SODetailNo = int.Parse(soDetailId), ExportAllotId = allot.Id, StockId = allot.StockId, BoxNo = "", BoxNo2 = "", BoxNo3 = "", LotNo = allot.LotNo, LotText = allot.LotText, SupplierLot = allot.SupplierLot, SkuNo = allot.SkuNo, SkuName = allot.SkuName, Standard = allot.Standard, PalletNo = palletNo, CompleteQty = int.Parse(PickQty), CreateUser = userId, CreateTime = Db.GetDate(), }; comList.Add(completeDetail); //添加拣货明细 Db.Insertable(comList).ExecuteCommand(); } else if (isComplete == 1) { complete.CompleteQty += decimal.Parse(PickQty); complete.UpdateUser = userId; complete.UpdateTime = Db.GetDate(); Db.Updateable(complete).ExecuteCommand(); } //修改出库分配信息 allot.CompleteQty += decimal.Parse(PickQty); allot.Status = allot.Qty == allot.CompleteQty ? "5" : "3"; allot.UpdateTime = DateTime.Now; Db.Updateable(allot).ExecuteCommand(); int isDel = 0; //删除或修改库存明细 stockDetail.BitPalletMark = "1";//修改为零托标识 stockDetail.Qty -= decimal.Parse(PickQty); stockDetail.LockQty -= decimal.Parse(PickQty); if (stockDetail.Qty == stockDetail.LockQty) { stockDetail.Status = "2"; } else if (stockDetail.Qty > stockDetail.LockQty && stockDetail.LockQty > 0) { stockDetail.Status = "1"; } else { stockDetail.Status = "0"; } if (stockDetail.Qty <= 0) { Db.Deleteable(stockDetail).ExecuteCommand(); } else { isDel = 1; Db.Updateable(stockDetail).ExecuteCommand(); } //删除或修改库存 stock.Qty -= decimal.Parse(PickQty); stock.LockQty -= decimal.Parse(PickQty); if (stock.Qty <= 0) { Db.Deleteable(stock).ExecuteCommand(); } else { Db.Updateable(stock).ExecuteCommand(); } //改变托盘状态为:未使用 var pallet = Db.Queryable().First(m => m.PalletNo == palletNo && m.IsDel == "0"); if (pallet == null) { throw new Exception("未在托盘表中查询到托盘信息"); } //判断托盘上物料是否拣货完毕 if (isDel == 0) { pallet.Status = "0"; Db.Updateable(pallet).ExecuteCommand(); } //修改出库单明细拣货数量 noticeDetail.CompleteQty += int.Parse(PickQty); noticeDetail.Status = "2"; Db.Updateable(noticeDetail).ExecuteCommand(); var num = Db.Queryable() .Count(m => m.IsDel == "0" && m.SONo == soNo && m.CompleteQty < m.Qty); if (num <= 0) { notice.Status = "4"; //更改为执行完成 noticeDetail.Status = "3"; Db.Updateable(noticeDetail).ExecuteCommand(); } //修改出库单信息 Db.Updateable(notice).ExecuteCommand(); //添加操作日志记录 var k = new OperationSOServer().AddLogOperationSo("PDA模块", "拣货出库", soNo, "拣货", $"在PDA上对出库单号为:{soNo}的托盘码为:{palletNo}的拣货操作", userId); Db.CommitTran(); } catch (Exception e) { Db.RollbackTran(); throw new Exception(e.Message); } } /// /// 下发空托出库 /// /// /// /// /// /// public string IssuePlnOutHouse(OutModePalletVm model, int userId, string url) { try { string strMsg = ""; var outDto1 = new List(); //先出库数据的集合(深度为1的储位) var outDto2 = new List(); //后出库数据的集合(深度为2的储位) var moveDto = new List(); //要移库数据的集合 //获取当前时间 DateTime serverTime = Db.GetDate(); //获取库存明细是否小于等于该垛数 string str = "select * from DataStockDetail where IsDel = '0' and SkuNo = '100099' and Status = '0' "; var stockDetail = Db.Ado.SqlQuery(str); if (stockDetail.Count > 0) { //判断是否大于需要垛数 if (stockDetail.Count < int.Parse(model.Num)) { strMsg = "需要垛数大于库存垛数,请重新输入!"; return strMsg; } } //获取库存总表信息 var stock = Db.Queryable().First(s => s.IsDel == "0" && s.SkuNo == "100099"); //验证库存总表是否为空 if (stock == null) { strMsg = "库存信息不存在,请核查!"; return strMsg; } var com = new Common(); Db.BeginTran(); //遍历库存信息 foreach (var s in stockDetail) { //if (outDto1.Contains(m=>m.PalletNo == s.PalletNo) >0) //{ // continue; //} //获取储位信息 var locat = Db.Queryable().First(l => l.LocatNo == s.LocatNo && l.IsDel == "0" && l.WareHouseNo == "W01"); if(locat == null) { continue; } ////更改储位状态为出库中 //locat.Status = "3"; //3 出库中 //locat.UpdateTime = serverTime; //修改时间 //locat.UpdateUser = userId; //修改人 ////修改储位信息 //Db.Updateable(locat).ExecuteCommand(); if (locat.Status == "1") { if (locat.Depth == "01") //深度为1 { #region 改变库存 //增加库存锁定数量 stock.LockQty += (int)s.Qty; //锁定数量 stock.UpdateTime = serverTime; //修改时间 stock.UpdateUser = userId; //修改人 Db.Updateable(stock).ExecuteCommand();//修改库存总表信息 //增加库存明细锁定数量 s.LockQty += (int)s.Qty; //锁定数量 s.UpdateTime = serverTime; //修改时间 s.UpdateUser = userId; //修改人 s.Status = "2"; //2 已分配 Db.Updateable(s).ExecuteCommand();//修改库存明细信息 #endregion #region 分配 //添加分配表信息 var allot = new BllExportAllot { SONo = "", WaveNo = "", SODetailNo = 0, StockId = s.Id, LotNo = "", LotText = "", SupplierLot = "", SkuNo = s.SkuNo, SkuName = s.SkuName, Standard = s.Standard, PalletNo = s.PalletNo, IsBale = "0", //是否裹包 IsBelt = "0", //是否打带 //BoxexQty = s.Qty, Qty = (int)s.Qty, CompleteQty = 0, Status = "1", LogisticsId = 0, IsAdvance = "0", OutMode = model.OutMode,//出库口 CreateUser = userId, CreateTime = DateTime.Now }; Db.Insertable(allot).ExecuteCommand(); #endregion #region 添加出库任务信息 var taskNo = new Common().GetMaxNo("TK"); var exTask = new LogTask //出库任务 { TaskNo = taskNo, Sender = "WMS", Receiver = "PDA", IsSuccess = 1, //是否下发成功 0失败 1成功 StartLocat = locat == null ? "" : s.LocatNo,//起始位置 EndLocat = model.OutMode,//目标位置 PalletNo = s.PalletNo,//托盘码 IsSend = 1,//是否可再次下发 IsCancel = 1,//是否可取消 IsFinish = 1,//是否可完成 Type = "1",//任务类型 0 入库任务 1 出库任务 2 移库任务 Status = "1",//任务状态0:等待执行1正在执行2执行完成 OrderType = "1",//0 入库单 1 出库单 2 盘点单 3 移库单 CreateTime = serverTime, //创建时间 CreateUser = userId, //创建人 Msg = "Pda空托从" + locat == null ? "" : s.LocatNo + "到" + model.OutMode + "的出库任务", //关键信息 //FinishDate = serverTime, //完成时间 }; outDto1.Add(new OutCommandDto() { PalletNo = exTask.PalletNo,//托盘号 StartLocate = exTask.StartLocat, // 起始位置 StartRoadway = locat.RoadwayNo, //所属巷道 EndLocate = model.OutMode, // 目标位置 TaskNo = exTask.TaskNo, // 任务号 TaskType = "1",// 任务类型 (出库) OutMode = model.OutMode, //目标地址 Order = 1 }); Db.Insertable(exTask).ExecuteCommand(); #endregion #region 储位状态变更 //更改储位状态为出库中 locat.Status = "3"; //3 出库中 Db.Updateable(locat).ExecuteCommand();//修改储位信息 #endregion } else if (locat.Depth == "02") //深度为2 { //获取出库深度为2储位前面的储位信息 var sql2 = $@"select * from SysStorageLocat where WareHouseNo = '{locat.WareHouseNo}' and row = {locat.Row} and [Column] = {locat.Column} and Layer = {locat.Layer} and Depth = '01'; "; var slotBefore = Db.Ado.SqlQuery(sql2).First(); if (slotBefore == null) { #region 改变库存 //增加库存锁定数量 stock.LockQty += (int)s.Qty; //锁定数量 stock.UpdateTime = serverTime; //修改时间 stock.UpdateUser = userId; //修改人 Db.Updateable(stock).ExecuteCommand();//修改库存总表信息 //增加库存明细锁定数量 s.LockQty += (int)s.Qty; //锁定数量 s.UpdateTime = serverTime; //修改时间 s.UpdateUser = userId; //修改人 s.Status = "2"; //2 已分配 Db.Updateable(s).ExecuteCommand();//修改库存明细信息 #endregion #region 分配 //添加分配表信息 var allot = new BllExportAllot { SONo = "", WaveNo = "", SODetailNo = 0, StockId = s.Id, LotNo = "", LotText = "", SupplierLot = "", SkuNo = s.SkuNo, SkuName = s.SkuName, Standard = s.Standard, PalletNo = s.PalletNo, IsBale = "0", //是否裹包 IsBelt = "0", //是否打带 //BoxexQty = s.Qty, Qty = (int)s.Qty, CompleteQty = 0, Status = "1", LogisticsId = 0, IsAdvance = "0", OutMode = model.OutMode,//出库口 CreateUser = userId, CreateTime = DateTime.Now }; Db.Insertable(allot).ExecuteCommand(); #endregion #region 添加出库任务信息 var taskNo = new Common().GetMaxNo("TK"); var exTask = new LogTask //出库任务 { TaskNo = taskNo, Sender = "WMS", Receiver = "PDA", IsSuccess = 1, //是否下发成功 0失败 1成功 StartLocat = locat == null ? "" : s.LocatNo,//起始位置 EndLocat = model.OutMode,//目标位置 PalletNo = s.PalletNo,//托盘码 IsSend = 1,//是否可再次下发 IsCancel = 1,//是否可取消 IsFinish = 1,//是否可完成 Type = "1",//任务类型 0 入库任务 1 出库任务 2 移库任务 Status = "1",//任务状态0:等待执行1正在执行2执行完成 OrderType = "1",//0 入库单 1 出库单 2 盘点单 3 移库单 CreateTime = serverTime, //创建时间 CreateUser = userId, //创建人 Msg = "Pda空托从" + locat == null ? "" : s.LocatNo + "到" + model.OutMode + "的出库任务", //关键信息 //FinishDate = serverTime, //完成时间 }; outDto1.Add(new OutCommandDto() { PalletNo = exTask.PalletNo,//托盘号 StartLocate = exTask.StartLocat, // 起始位置 StartRoadway = locat.RoadwayNo, //所属巷道 EndLocate = model.OutMode, // 目标位置 TaskNo = exTask.TaskNo, // 任务号 TaskType = "1",// 任务类型 (出库) OutMode = model.OutMode, //目标地址 Order = 1 }); Db.Insertable(exTask).ExecuteCommand(); #endregion #region 储位状态变更 //更改储位状态为出库中 locat.Status = "3"; //3 出库中 Db.Updateable(locat).ExecuteCommand();//修改储位信息 #endregion } else { //判断储位状态 if (slotBefore.Status == "0") { #region 改变库存 //增加库存锁定数量 stock.LockQty += (int)s.Qty; //锁定数量 stock.UpdateTime = serverTime; //修改时间 stock.UpdateUser = userId; //修改人 Db.Updateable(stock).ExecuteCommand();//修改库存总表信息 //增加库存明细锁定数量 s.LockQty += (int)s.Qty; //锁定数量 s.UpdateTime = serverTime; //修改时间 s.UpdateUser = userId; //修改人 s.Status = "2"; //2 已分配 Db.Updateable(s).ExecuteCommand();//修改库存明细信息 #endregion #region 分配 //添加分配表信息 var allot = new BllExportAllot { SONo = "", WaveNo = "", SODetailNo = 0, StockId = s.Id, LotNo = "", LotText = "", SupplierLot = "", SkuNo = s.SkuNo, SkuName = s.SkuName, Standard = s.Standard, PalletNo = s.PalletNo, IsBale = "0", //是否裹包 IsBelt = "0", //是否打带 //BoxexQty = s.Qty, Qty = (int)s.Qty, CompleteQty = 0, Status = "1", LogisticsId = 0, IsAdvance = "0", OutMode = model.OutMode,//出库口 CreateUser = userId, CreateTime = DateTime.Now }; Db.Insertable(allot).ExecuteCommand(); #endregion #region 添加出库任务信息 var taskNo = new Common().GetMaxNo("TK"); var exTask = new LogTask //出库任务 { TaskNo = taskNo, Sender = "WMS", Receiver = "PDA", IsSuccess = 1, //是否下发成功 0失败 1成功 StartLocat = locat == null ? "" : s.LocatNo,//起始位置 EndLocat = model.OutMode,//目标位置 PalletNo = s.PalletNo,//托盘码 IsSend = 1,//是否可再次下发 IsCancel = 1,//是否可取消 IsFinish = 1,//是否可完成 Type = "1",//任务类型 0 入库任务 1 出库任务 2 移库任务 Status = "1",//任务状态0:等待执行1正在执行2执行完成 OrderType = "1",//0 入库单 1 出库单 2 盘点单 3 移库单 CreateTime = serverTime, //创建时间 CreateUser = userId, //创建人 Msg = "Pda空托从" + locat == null ? "" : s.LocatNo + "到" + model.OutMode + "的出库任务", //关键信息 //FinishDate = serverTime, //完成时间 }; outDto1.Add(new OutCommandDto() { PalletNo = exTask.PalletNo,//托盘号 StartLocate = exTask.StartLocat, // 起始位置 StartRoadway = locat.RoadwayNo, //所属巷道 EndLocate = model.OutMode, // 目标位置 TaskNo = exTask.TaskNo, // 任务号 TaskType = "1",// 任务类型 (出库) OutMode = model.OutMode, //目标地址 Order = 1 }); Db.Insertable(exTask).ExecuteCommand(); #endregion #region 储位状态变更 //更改储位状态为出库中 locat.Status = "3"; //3 出库中 Db.Updateable(locat).ExecuteCommand();//修改储位信息 #endregion } else if(slotBefore.Status == "1") { //判断托盘上物料 var pallSku = Db.Queryable().First(m=>m.SkuNo == "100099" && m.LocatNo == slotBefore.LocatNo); if (pallSku == null) //移库 { #region 分配 ////添加分配表信息 //var allot = new BllExportAllot //{ // SONo = "", // WaveNo = "", // SODetailNo = 0, // StockId = s.Id, // LotNo = "", // LotText = "", // SupplierLot = "", // SkuNo = s.SkuNo, // SkuName = s.SkuName, // Standard = s.Standard, // PalletNo = s.PalletNo, // IsBale = "0", //是否裹包 // IsBelt = "0", //是否打带 // //BoxexQty = s.Qty, // Qty = (int)s.Qty, // CompleteQty = 0, // Status = "1", // LogisticsId = 0, // IsAdvance = "0", // OutMode = model.OutMode,//出库口 // CreateUser = userId, // CreateTime = DateTime.Now //}; //Db.Insertable(allot).ExecuteCommand(); #endregion #region 添加移库任务信息 var stkModel = Db.Queryable().First(m => m.LocatNo == slotBefore.LocatNo); string PalletNo = "LN000000"; // 默认演示托盘 string SkuNo = ""; if (stkModel != null) { PalletNo = stkModel.PalletNo; SkuNo = stkModel.SkuNo; } //获取移库的库位 var newSlot = MoveAddress(slotBefore.LocatNo, slotBefore.RoadwayNo, SkuNo, slotBefore.AreaNo); if (string.IsNullOrWhiteSpace(newSlot)) { continue; } var taskNo = new Common().GetMaxNo("TK"); var exTask = new LogTask //出库任务 { TaskNo = taskNo, Sender = "WMS", Receiver = "PDA", IsSuccess = 1, //是否下发成功 0失败 1成功 StartLocat = slotBefore.LocatNo,//起始位置 EndLocat = newSlot,//目标位置 PalletNo = PalletNo,//托盘码 IsSend = 1,//是否可再次下发 IsCancel = 1,//是否可取消 IsFinish = 1,//是否可完成 Type = "2",//任务类型 0 入库任务 1 出库任务 2 移库任务 Status = "1",//任务状态0:等待执行1正在执行2执行完成 OrderType = "1",//0 入库单 1 出库单 2 盘点单 3 移库单 CreateTime = serverTime, //创建时间 CreateUser = userId, //创建人 Msg = "Pda空托从" + locat == null ? "" : slotBefore.LocatNo + "到" + newSlot + "的移库任务", //关键信息 //FinishDate = serverTime, //完成时间 }; moveDto.Add(new OutCommandDto() { PalletNo = exTask.PalletNo,//托盘号 StartLocate = exTask.StartLocat, // 起始位置 StartRoadway = locat.RoadwayNo, //所属巷道 EndLocate = exTask.EndLocat, // 目标位置 TaskNo = exTask.TaskNo, // 任务号 TaskType = "2",// 任务类型 (移库) OutMode = "", //目标地址 Order = 1 }); Db.Insertable(exTask).ExecuteCommand(); #endregion #region 储位状态变更 //更改储位状态为移出中 slotBefore.Status = "5"; //5 移出中 Db.Updateable(slotBefore).ExecuteCommand();//修改储位信息 var newSlot2 = Db.Queryable().First(m => m.LocatNo == newSlot && m.IsDel == "0"); if (newSlot2!= null) { newSlot2.Status = "4";//移入中 Db.Updateable(newSlot2).ExecuteCommand();//修改储位信息 } #endregion } else //出库 { #region 改变库存 //增加库存锁定数量 stock.LockQty += (int)pallSku.Qty; //锁定数量 stock.UpdateTime = serverTime; //修改时间 stock.UpdateUser = userId; //修改人 Db.Updateable(stock).ExecuteCommand();//修改库存总表信息 //增加库存明细锁定数量 pallSku.LockQty += (int)pallSku.Qty; //锁定数量 pallSku.UpdateTime = serverTime; //修改时间 pallSku.UpdateUser = userId; //修改人 pallSku.Status = "2"; //2 已分配 Db.Updateable(pallSku).ExecuteCommand();//修改库存明细信息 #endregion #region 分配 //添加分配表信息 var allot = new BllExportAllot { SONo = "", WaveNo = "", SODetailNo = 0, StockId = pallSku.Id, LotNo = "", LotText = "", SupplierLot = "", SkuNo = pallSku.SkuNo, SkuName = pallSku.SkuName, Standard = pallSku.Standard, PalletNo = pallSku.PalletNo, IsBale = "0", //是否裹包 IsBelt = "0", //是否打带 //BoxexQty = s.Qty, Qty = (int)pallSku.Qty, CompleteQty = 0, Status = "1", LogisticsId = 0, IsAdvance = "0", OutMode = model.OutMode,//出库口 CreateUser = userId, CreateTime = DateTime.Now }; Db.Insertable(allot).ExecuteCommand(); #endregion #region 添加出库任务信息 var taskNo = new Common().GetMaxNo("TK"); var exTask = new LogTask //出库任务 { TaskNo = taskNo, Sender = "WMS", Receiver = "PDA", IsSuccess = 1, //是否下发成功 0失败 1成功 StartLocat = locat == null ? "" : pallSku.LocatNo,//起始位置 EndLocat = model.OutMode,//目标位置 PalletNo = pallSku.PalletNo,//托盘码 IsSend = 1,//是否可再次下发 IsCancel = 1,//是否可取消 IsFinish = 1,//是否可完成 Type = "1",//任务类型 0 入库任务 1 出库任务 2 移库任务 Status = "1",//任务状态0:等待执行1正在执行2执行完成 OrderType = "1",//0 入库单 1 出库单 2 盘点单 3 移库单 CreateTime = serverTime, //创建时间 CreateUser = userId, //创建人 Msg = "Pda空托从" + locat == null ? "" : pallSku.LocatNo + "到" + model.OutMode + "的出库任务", //关键信息 //FinishDate = serverTime, //完成时间 }; outDto2.Add(new OutCommandDto() { PalletNo = exTask.PalletNo,//托盘号 StartLocate = exTask.StartLocat, // 起始位置 StartRoadway = locat.RoadwayNo, //所属巷道 EndLocate = model.OutMode, // 目标位置 TaskNo = exTask.TaskNo, // 任务号 TaskType = "1",// 任务类型 (出库) OutMode = model.OutMode, //目标地址 Order = 1 }); Db.Insertable(exTask).ExecuteCommand(); #endregion #region 储位状态变更 //更改储位状态为出库中 slotBefore.Status = "3"; //3 出库中 Db.Updateable(slotBefore).ExecuteCommand();//修改储位信息 #endregion } if (int.Parse(model.Num) == outDto1.Count + outDto2.Count) { break;//需求垛数已达到 可以出库了 } else { #region 改变库存 //增加库存锁定数量 stock.LockQty += (int)s.Qty; //锁定数量 stock.UpdateTime = serverTime; //修改时间 stock.UpdateUser = userId; //修改人 Db.Updateable(stock).ExecuteCommand();//修改库存总表信息 //增加库存明细锁定数量 s.LockQty += (int)s.Qty; //锁定数量 s.UpdateTime = serverTime; //修改时间 s.UpdateUser = userId; //修改人 s.Status = "2"; //2 已分配 Db.Updateable(s).ExecuteCommand();//修改库存明细信息 #endregion #region 分配 //添加分配表信息 var allot = new BllExportAllot { SONo = "", WaveNo = "", SODetailNo = 0, StockId = s.Id, LotNo = "", LotText = "", SupplierLot = "", SkuNo = s.SkuNo, SkuName = s.SkuName, Standard = s.Standard, PalletNo = s.PalletNo, IsBale = "0", //是否裹包 IsBelt = "0", //是否打带 //BoxexQty = s.Qty, Qty = (int)s.Qty, CompleteQty = 0, Status = "1", LogisticsId = 0, IsAdvance = "0", OutMode = model.OutMode,//出库口 CreateUser = userId, CreateTime = DateTime.Now }; Db.Insertable(allot).ExecuteCommand(); #endregion #region 添加出库任务信息 var taskNo = new Common().GetMaxNo("TK"); var exTask = new LogTask //出库任务 { TaskNo = taskNo, Sender = "WMS", Receiver = "PDA", IsSuccess = 1, //是否下发成功 0失败 1成功 StartLocat = locat == null ? "" : s.LocatNo,//起始位置 EndLocat = model.OutMode,//目标位置 PalletNo = s.PalletNo,//托盘码 IsSend = 1,//是否可再次下发 IsCancel = 1,//是否可取消 IsFinish = 1,//是否可完成 Type = "1",//任务类型 0 入库任务 1 出库任务 2 移库任务 Status = "1",//任务状态0:等待执行1正在执行2执行完成 OrderType = "1",//0 入库单 1 出库单 2 盘点单 3 移库单 CreateTime = serverTime, //创建时间 CreateUser = userId, //创建人 Msg = "Pda空托从" + locat == null ? "" : s.LocatNo + "到" + model.OutMode + "的出库任务", //关键信息 //FinishDate = serverTime, //完成时间 }; outDto2.Add(new OutCommandDto() { PalletNo = exTask.PalletNo,//托盘号 StartLocate = exTask.StartLocat, // 起始位置 StartRoadway = locat.RoadwayNo, //所属巷道 EndLocate = model.OutMode, // 目标位置 TaskNo = exTask.TaskNo, // 任务号 TaskType = "1",// 任务类型 (出库) OutMode = model.OutMode, //目标地址 Order = 1 }); Db.Insertable(exTask).ExecuteCommand(); #endregion #region 储位状态变更 //更改储位状态为出库中 locat.Status = "3"; //3 出库中 Db.Updateable(locat).ExecuteCommand();//修改储位信息 #endregion } } } } } if (int.Parse(model.Num) == outDto1.Count+ outDto2.Count) { break;//需求垛数已达到 可以出库了 } } outDto1.AddRange(moveDto); outDto1.AddRange(outDto2); if (outDto1.Count > 0) { // 正式运行程序放开 var list2 = outDto1.Select(m => m.TaskNo).ToList(); var jsonData = JsonConvert.SerializeObject(outDto1); string response = ""; try { var time1 = DateTime.Now;//发送时间 .ToString("yyyy-MM-dd HH:mm:ss") response = HttpHelper.DoPost(url, jsonData, "下发给WCS出库命令", "WCS"); var time2 = DateTime.Now;//返回时间 .ToString("yyyy-MM-dd HH:mm:ss") ////解析返回数据 var wcsModel = JsonConvert.DeserializeObject(response); if (wcsModel.StatusCode == 0) { //更改任务的发送返回时间// new TaskServer().EditTaskIssueOk(list2, time1, time2); str += "下发成功"; } if (wcsModel.StatusCode == -1) { new TaskServer().EditTaskIssueNo(list2, time1, time2, wcsModel.Msg); throw new Exception(wcsModel.Msg); } } catch (Exception ex) { throw new Exception(ex.Message); } } //添加操作日志记录 var k = new OperationSOServer().AddLogOperationSo("PDA模块", "空托出库", int.Parse(model.Num) + "", "下发", $"用PDA下发了 {int.Parse(model.Num)} 个空托垛", userId); Db.CommitTran(); return ""; } catch (Exception e) { Db.RollbackTran(); throw new Exception(e.Message); } } /// /// WCS申请空托出库 /// /// /// /// /// /// public List IssuePlnOutHouseWcs(OutModePalletVm model, int userId) { try { string strMsg = ""; var outDto1 = new List(); //先出库数据的集合(深度为1的储位) var outDto2 = new List(); //后出库数据的集合(深度为2的储位) var moveDto = new List(); //要移库数据的集合 //获取当前时间 DateTime serverTime = Db.GetDate(); //获取库存明细是否小于等于该垛数 string str = "select * from DataStockDetail where IsDel = '0' and SkuNo = '100099' and Status = '0' "; var stockDetail = Db.Ado.SqlQuery(str); if (stockDetail.Count > 0) { //判断是否大于需要垛数 if (stockDetail.Count < int.Parse(model.Num)) { throw new Exception("需要垛数大于库存垛数,请重新输入!"); } } //获取库存总表信息 var stock = Db.Queryable().First(s => s.IsDel == "0" && s.SkuNo == "100099"); //验证库存总表是否为空 if (stock == null) { throw new Exception("库存信息不存在,请核查!"); } var com = new Common(); Db.BeginTran(); //遍历库存信息 foreach (var s in stockDetail) { //if (outDto1.Contains(m=>m.PalletNo == s.PalletNo) >0) //{ // continue; //} //获取储位信息 var locat = Db.Queryable().First(l => l.LocatNo == s.LocatNo && l.IsDel == "0" && l.WareHouseNo == "W01"); if (locat == null) { continue; } ////更改储位状态为出库中 //locat.Status = "3"; // 1 有物品 //locat.UpdateTime = serverTime; //修改时间 //locat.UpdateUser = userId; //修改人 ////修改储位信息 //Db.Updateable(locat).ExecuteCommand(); if (locat.Status == "1") { if (locat.Depth == "01") //深度为1 { #region 改变库存 //增加库存锁定数量 stock.LockQty += (int)s.Qty; //锁定数量 stock.UpdateTime = serverTime; //修改时间 stock.UpdateUser = 0; //修改人 Db.Updateable(stock).ExecuteCommand();//修改库存总表信息 //增加库存明细锁定数量 s.LockQty += (int)s.Qty; //锁定数量 s.UpdateTime = serverTime; //修改时间 s.UpdateUser = userId; //修改人 s.Status = "2"; //2 已分配 Db.Updateable(s).ExecuteCommand();//修改库存明细信息 #endregion #region 分配 //添加分配表信息 var allot = new BllExportAllot { SONo = "", WaveNo = "", SODetailNo = 0, StockId = s.Id, LotNo = "", LotText = "", SupplierLot = "", SkuNo = s.SkuNo, SkuName = s.SkuName, Standard = s.Standard, PalletNo = s.PalletNo, IsBale = "0", //是否裹包 IsBelt = "0", //是否打带 //BoxexQty = s.Qty, Qty = (int)s.Qty, CompleteQty = 0, Status = "1", LogisticsId = 0, IsAdvance = "0", OutMode = model.OutMode,//出库口 CreateUser = userId, CreateTime = DateTime.Now }; Db.Insertable(allot).ExecuteCommand(); #endregion #region 添加出库任务信息 var taskNo = new Common().GetMaxNo("TK"); var exTask = new LogTask //出库任务 { TaskNo = taskNo, Sender = "WMS", Receiver = "WCS", IsSuccess = 1, //是否下发成功 0失败 1成功 StartLocat = locat == null ? "" : s.LocatNo,//起始位置 EndLocat = model.OutMode,//目标位置 PalletNo = s.PalletNo,//托盘码 IsSend = 1,//是否可再次下发 IsCancel = 1,//是否可取消 IsFinish = 1,//是否可完成 Type = "1",//任务类型 0 入库任务 1 出库任务 2 移库任务 Status = "1",//任务状态0:等待执行1正在执行2执行完成 OrderType = "1",//0 入库单 1 出库单 2 盘点单 3 移库单 CreateTime = serverTime, //创建时间 CreateUser = userId, //创建人 Msg = "WCS空托从" + locat == null ? "" : s.LocatNo + "到" + model.OutMode + "的出库任务", //关键信息 //FinishDate = serverTime, //完成时间 }; outDto1.Add(new OutCommandDto() { PalletNo = exTask.PalletNo,//托盘号 StartLocate = exTask.StartLocat, // 起始位置 StartRoadway = locat.RoadwayNo, //所属巷道 EndLocate = model.OutMode, // 目标位置 TaskNo = exTask.TaskNo, // 任务号 TaskType = "1",// 任务类型 (出库) OutMode = model.OutMode, //目标地址 Order = 1 }); Db.Insertable(exTask).ExecuteCommand(); #endregion #region 储位状态变更 //更改储位状态为出库中 locat.Status = "3"; //3 出库中 Db.Updateable(locat).ExecuteCommand();//修改储位信息 #endregion } else if (locat.Depth == "02") //深度为2 { //获取出库深度为2储位前面的储位信息 var sql2 = $@"select * from SysStorageLocat where WareHouseNo = '{locat.WareHouseNo}' and row = {locat.Row} and [Column] = {locat.Column} and Layer = {locat.Layer} and Depth = '01'; "; var slotBefore = Db.Ado.SqlQuery(sql2).First(); if (slotBefore == null) { #region 改变库存 //增加库存锁定数量 stock.LockQty += (int)s.Qty; //锁定数量 stock.UpdateTime = serverTime; //修改时间 //stock.UpdateUser = userId; //修改人 Db.Updateable(stock).ExecuteCommand();//修改库存总表信息 //增加库存明细锁定数量 s.LockQty += (int)s.Qty; //锁定数量 s.UpdateTime = serverTime; //修改时间 s.UpdateUser = userId; //修改人 s.Status = "2"; //2 已分配 Db.Updateable(s).ExecuteCommand();//修改库存明细信息 #endregion #region 分配 //添加分配表信息 var allot = new BllExportAllot { SONo = "", WaveNo = "", SODetailNo = 0, StockId = s.Id, LotNo = "", LotText = "", SupplierLot = "", SkuNo = s.SkuNo, SkuName = s.SkuName, Standard = s.Standard, PalletNo = s.PalletNo, IsBale = "0", //是否裹包 IsBelt = "0", //是否打带 //BoxexQty = s.Qty, Qty = (int)s.Qty, CompleteQty = 0, Status = "1", LogisticsId = 0, IsAdvance = "0", OutMode = model.OutMode,//出库口 CreateUser = userId, CreateTime = DateTime.Now }; Db.Insertable(allot).ExecuteCommand(); #endregion #region 添加出库任务信息 var taskNo = new Common().GetMaxNo("TK"); var exTask = new LogTask //出库任务 { TaskNo = taskNo, Sender = "WMS", Receiver = "WCS", IsSuccess = 1, //是否下发成功 0失败 1成功 StartLocat = locat == null ? "" : s.LocatNo,//起始位置 EndLocat = model.OutMode,//目标位置 PalletNo = s.PalletNo,//托盘码 IsSend = 1,//是否可再次下发 IsCancel = 1,//是否可取消 IsFinish = 1,//是否可完成 Type = "1",//任务类型 0 入库任务 1 出库任务 2 移库任务 Status = "1",//任务状态0:等待执行1正在执行2执行完成 OrderType = "1",//0 入库单 1 出库单 2 盘点单 3 移库单 CreateTime = serverTime, //创建时间 CreateUser = userId, //创建人 Msg = "WCS空托从" + locat == null ? "" : s.LocatNo + "到" + model.OutMode + "的出库任务", //关键信息 //FinishDate = serverTime, //完成时间 }; outDto1.Add(new OutCommandDto() { PalletNo = exTask.PalletNo,//托盘号 StartLocate = exTask.StartLocat, // 起始位置 StartRoadway = locat.RoadwayNo, //所属巷道 EndLocate = model.OutMode, // 目标位置 TaskNo = exTask.TaskNo, // 任务号 TaskType = "1",// 任务类型 (出库) OutMode = model.OutMode, //目标地址 Order = 1 }); Db.Insertable(exTask).ExecuteCommand(); #endregion #region 储位状态变更 //更改储位状态为出库中 locat.Status = "3"; //3 出库中 Db.Updateable(locat).ExecuteCommand();//修改储位信息 #endregion } else { //判断储位状态 if (slotBefore.Status == "0") { #region 改变库存 //增加库存锁定数量 stock.LockQty += (int)s.Qty; //锁定数量 stock.UpdateTime = serverTime; //修改时间 //stock.UpdateUser = userId; //修改人 Db.Updateable(stock).ExecuteCommand();//修改库存总表信息 //增加库存明细锁定数量 s.LockQty += (int)s.Qty; //锁定数量 s.UpdateTime = serverTime; //修改时间 s.UpdateUser = userId; //修改人 s.Status = "2"; //2 已分配 Db.Updateable(s).ExecuteCommand();//修改库存明细信息 #endregion #region 分配 //添加分配表信息 var allot = new BllExportAllot { SONo = "", WaveNo = "", SODetailNo = 0, StockId = s.Id, LotNo = "", LotText = "", SupplierLot = "", SkuNo = s.SkuNo, SkuName = s.SkuName, Standard = s.Standard, PalletNo = s.PalletNo, IsBale = "0", //是否裹包 IsBelt = "0", //是否打带 //BoxexQty = s.Qty, Qty = (int)s.Qty, CompleteQty = 0, Status = "1", LogisticsId = 0, IsAdvance = "0", OutMode = model.OutMode,//出库口 CreateUser = userId, CreateTime = DateTime.Now }; Db.Insertable(allot).ExecuteCommand(); #endregion #region 添加出库任务信息 var taskNo = new Common().GetMaxNo("TK"); var exTask = new LogTask //出库任务 { TaskNo = taskNo, Sender = "WMS", Receiver = "WCS", IsSuccess = 1, //是否下发成功 0失败 1成功 StartLocat = locat == null ? "" : s.LocatNo,//起始位置 EndLocat = model.OutMode,//目标位置 PalletNo = s.PalletNo,//托盘码 IsSend = 1,//是否可再次下发 IsCancel = 1,//是否可取消 IsFinish = 1,//是否可完成 Type = "1",//任务类型 0 入库任务 1 出库任务 2 移库任务 Status = "1",//任务状态0:等待执行1正在执行2执行完成 OrderType = "1",//0 入库单 1 出库单 2 盘点单 3 移库单 CreateTime = serverTime, //创建时间 CreateUser = userId, //创建人 Msg = "WCS空托从" + locat == null ? "" : s.LocatNo + "到" + model.OutMode + "的出库任务", //关键信息 //FinishDate = serverTime, //完成时间 }; outDto1.Add(new OutCommandDto() { PalletNo = exTask.PalletNo,//托盘号 StartLocate = exTask.StartLocat, // 起始位置 StartRoadway = locat.RoadwayNo, //所属巷道 EndLocate = model.OutMode, // 目标位置 TaskNo = exTask.TaskNo, // 任务号 TaskType = "1",// 任务类型 (出库) OutMode = model.OutMode, //目标地址 Order = 1 }); Db.Insertable(exTask).ExecuteCommand(); #endregion #region 储位状态变更 //更改储位状态为出库中 locat.Status = "3"; //3 出库中 Db.Updateable(locat).ExecuteCommand();//修改储位信息 #endregion } else if (slotBefore.Status == "1") { //判断托盘上物料 var pallSku = Db.Queryable().First(m => m.SkuNo == "100099" && m.LocatNo == slotBefore.LocatNo); if (pallSku == null) //移库 { #region 分配 //添加分配表信息 var allot = new BllExportAllot { SONo = "", WaveNo = "", SODetailNo = 0, StockId = s.Id, LotNo = "", LotText = "", SupplierLot = "", SkuNo = s.SkuNo, SkuName = s.SkuName, Standard = s.Standard, PalletNo = s.PalletNo, IsBale = "0", //是否裹包 IsBelt = "0", //是否打带 //BoxexQty = s.Qty, Qty = (int)s.Qty, CompleteQty = 0, Status = "1", LogisticsId = 0, IsAdvance = "0", OutMode = model.OutMode,//出库口 CreateUser = userId, CreateTime = DateTime.Now }; Db.Insertable(allot).ExecuteCommand(); #endregion #region 添加移库任务信息 var stkModel = Db.Queryable().First(m=>m.LocatNo == slotBefore.LocatNo); string PalletNo = "LN000000"; // 默认演示托盘 string SkuNo = ""; if (stkModel != null) { PalletNo = stkModel.PalletNo; SkuNo= stkModel.SkuNo; } //获取移库的库位 var newSlot = MoveAddress(slotBefore.LocatNo, slotBefore.RoadwayNo, SkuNo, slotBefore.AreaNo); var taskNo = new Common().GetMaxNo("TK"); var exTask = new LogTask // 移库任务 { TaskNo = taskNo, Sender = "WMS", Receiver = "WCS", IsSuccess = 1, //是否下发成功 0失败 1成功 StartLocat = slotBefore.LocatNo,//起始位置 EndLocat = newSlot,//目标位置 PalletNo = PalletNo,//托盘码 IsSend = 1,//是否可再次下发 IsCancel = 1,//是否可取消 IsFinish = 1,//是否可完成 Type = "2",//任务类型 0 入库任务 1 出库任务 2 移库任务 Status = "1",//任务状态0:等待执行1正在执行2执行完成 OrderType = "1",//0 入库单 1 出库单 2 盘点单 3 移库单 CreateTime = serverTime, //创建时间 CreateUser = userId, //创建人 Msg = "WCS空托从" + locat == null ? "" : s.LocatNo + "到" + newSlot + "的移库任务", //关键信息 //FinishDate = serverTime, //完成时间 }; moveDto.Add(new OutCommandDto() { PalletNo = exTask.PalletNo,//托盘号 StartLocate = exTask.StartLocat, // 起始位置 StartRoadway = locat.RoadwayNo, //所属巷道 EndLocate = exTask.EndLocat, // 目标位置 TaskNo = exTask.TaskNo, // 任务号 TaskType = "2",// 任务类型 (出库) OutMode = "", //目标地址 Order = 1 }); Db.Insertable(exTask).ExecuteCommand(); #endregion #region 储位状态变更 //更改储位状态为移出中 slotBefore.Status = "5"; //5 移出中 Db.Updateable(slotBefore).ExecuteCommand();//修改储位信息 #endregion } else //出库 { #region 改变库存 //增加库存锁定数量 stock.LockQty += (int)s.Qty; //锁定数量 stock.UpdateTime = serverTime; //修改时间 //stock.UpdateUser = userId; //修改人 Db.Updateable(stock).ExecuteCommand();//修改库存总表信息 //增加库存明细锁定数量 s.LockQty += (int)s.Qty; //锁定数量 s.UpdateTime = serverTime; //修改时间 s.UpdateUser = userId; //修改人 s.Status = "2"; //2 已分配 Db.Updateable(s).ExecuteCommand();//修改库存明细信息 #endregion #region 分配 //添加分配表信息 var allot = new BllExportAllot { SONo = "", WaveNo = "", SODetailNo = 0, StockId = s.Id, LotNo = "", LotText = "", SupplierLot = "", SkuNo = s.SkuNo, SkuName = s.SkuName, Standard = s.Standard, PalletNo = s.PalletNo, IsBale = "0", //是否裹包 IsBelt = "0", //是否打带 //BoxexQty = s.Qty, Qty = (int)s.Qty, CompleteQty = 0, Status = "1", LogisticsId = 0, IsAdvance = "0", OutMode = model.OutMode,//出库口 CreateUser = userId, CreateTime = DateTime.Now }; Db.Insertable(allot).ExecuteCommand(); #endregion #region 添加出库任务信息 var taskNo = new Common().GetMaxNo("TK"); var exTask = new LogTask //出库任务 { TaskNo = taskNo, Sender = "WMS", Receiver = "WCS", IsSuccess = 1, //是否下发成功 0失败 1成功 StartLocat = locat == null ? "" : s.LocatNo,//起始位置 EndLocat = model.OutMode,//目标位置 PalletNo = s.PalletNo,//托盘码 IsSend = 1,//是否可再次下发 IsCancel = 1,//是否可取消 IsFinish = 1,//是否可完成 Type = "1",//任务类型 0 入库任务 1 出库任务 2 移库任务 Status = "1",//任务状态0:等待执行1正在执行2执行完成 OrderType = "1",//0 入库单 1 出库单 2 盘点单 3 移库单 CreateTime = serverTime, //创建时间 CreateUser = userId, //创建人 Msg = "WCS空托从" + locat == null ? "" : s.LocatNo + "到" + model.OutMode + "的出库任务", //关键信息 //FinishDate = serverTime, //完成时间 }; outDto2.Add(new OutCommandDto() { PalletNo = exTask.PalletNo,//托盘号 StartLocate = exTask.StartLocat, // 起始位置 StartRoadway = locat.RoadwayNo, //所属巷道 EndLocate = model.OutMode, // 目标位置 TaskNo = exTask.TaskNo, // 任务号 TaskType = "1",// 任务类型 (出库) OutMode = model.OutMode, //目标地址 Order = 1 }); Db.Insertable(exTask).ExecuteCommand(); #endregion #region 储位状态变更 //更改储位状态为出库中 slotBefore.Status = "3"; //3 出库中 Db.Updateable(slotBefore).ExecuteCommand();//修改储位信息 #endregion } if (int.Parse(model.Num) == outDto1.Count + outDto2.Count) { break;//需求垛数已达到 可以出库了 } else { #region 改变库存 //增加库存锁定数量 stock.LockQty += (int)s.Qty; //锁定数量 stock.UpdateTime = serverTime; //修改时间 //stock.UpdateUser = userId; //修改人 Db.Updateable(stock).ExecuteCommand();//修改库存总表信息 //增加库存明细锁定数量 s.LockQty += (int)s.Qty; //锁定数量 s.UpdateTime = serverTime; //修改时间 s.UpdateUser = userId; //修改人 s.Status = "2"; //2 已分配 Db.Updateable(s).ExecuteCommand();//修改库存明细信息 #endregion #region 分配 //添加分配表信息 var allot = new BllExportAllot { SONo = "", WaveNo = "", SODetailNo = 0, StockId = s.Id, LotNo = "", LotText = "", SupplierLot = "", SkuNo = s.SkuNo, SkuName = s.SkuName, Standard = s.Standard, PalletNo = s.PalletNo, IsBale = "0", //是否裹包 IsBelt = "0", //是否打带 //BoxexQty = s.Qty, Qty = (int)s.Qty, CompleteQty = 0, Status = "1", LogisticsId = 0, IsAdvance = "0", OutMode = model.OutMode,//出库口 CreateUser = userId, CreateTime = DateTime.Now }; Db.Insertable(allot).ExecuteCommand(); #endregion #region 添加出库任务信息 var taskNo = new Common().GetMaxNo("TK"); var exTask = new LogTask //出库任务 { TaskNo = taskNo, Sender = "WMS", Receiver = "WCS", IsSuccess = 1, //是否下发成功 0失败 1成功 StartLocat = locat == null ? "" : s.LocatNo,//起始位置 EndLocat = model.OutMode,//目标位置 PalletNo = s.PalletNo,//托盘码 IsSend = 1,//是否可再次下发 IsCancel = 1,//是否可取消 IsFinish = 1,//是否可完成 Type = "1",//任务类型 0 入库任务 1 出库任务 2 移库任务 Status = "1",//任务状态0:等待执行1正在执行2执行完成 OrderType = "1",//0 入库单 1 出库单 2 盘点单 3 移库单 CreateTime = serverTime, //创建时间 CreateUser = userId, //创建人 Msg = "WCS空托从" + locat == null ? "" : s.LocatNo + "到" + model.OutMode + "的出库任务", //关键信息 //FinishDate = serverTime, //完成时间 }; outDto2.Add(new OutCommandDto() { PalletNo = exTask.PalletNo,//托盘号 StartLocate = exTask.StartLocat, // 起始位置 StartRoadway = locat.RoadwayNo, //所属巷道 EndLocate = model.OutMode, // 目标位置 TaskNo = exTask.TaskNo, // 任务号 TaskType = "1",// 任务类型 (出库) OutMode = model.OutMode, //目标地址 Order = 1 }); Db.Insertable(exTask).ExecuteCommand(); #endregion #region 储位状态变更 //更改储位状态为出库中 locat.Status = "3"; //3 出库中 Db.Updateable(locat).ExecuteCommand();//修改储位信息 #endregion } } } } } if (int.Parse(model.Num) == outDto1.Count + outDto2.Count) { break;//需求垛数已达到 可以出库了 } } outDto1.AddRange(moveDto); outDto1.AddRange(outDto2); if (outDto1.Count <= 0) { throw new Exception("暂无出库任务,请核查!"); } //添加操作日志记录 var k = new OperationSOServer().AddLogOperationSo("PDA模块", "空托出库", int.Parse(model.Num) + "", "下发", $"WCS下发了 {int.Parse(model.Num)} 个空托垛", userId); Db.CommitTran(); return outDto1; } catch (Exception e) { Db.RollbackTran(); throw new Exception(e.Message); } } /// /// WMS申请拣货空托 /// /// /// /// /// /// public string IssuePlnCehckHouseWcs(CheckModePalletVm model, int userId, string url) { try { string StartLocate = "" ,EndLocate = ""; Db.BeginTran(); if (model.OutMode == "001") //西侧拣货位叫空托盘 { var xLocate = Db.Queryable().First(w => w.Status == "1" && (w.LocatNo == "B13010101" || w.LocatNo == "B13020101" || w.LocatNo == "B13030101")); if (xLocate == null) { throw new Exception("没有可用的空托盘"); } StartLocate = Db.Queryable().First(w => w.Status == "1" && (w.LocatNo == "B13010101" || w.LocatNo == "B13020101" || w.LocatNo == "B13030101")).LocatNo; EndLocate = "B15010101"; } else//东侧拣货位叫空托盘 { var dLocate = Db.Queryable().First(w => w.Status == "1" && (w.LocatNo == "B13030101" || w.LocatNo == "B13040101" || w.LocatNo == "B13050101")); if (dLocate == null) { throw new Exception("没有可用的空托盘"); } StartLocate = Db.Queryable().First(w => w.Status == "1" && (w.LocatNo == "B13030101" || w.LocatNo == "B13040101" || w.LocatNo == "B13050101")).LocatNo; EndLocate = "B15020101"; } //添加出库任务 var taskNo = new Common().GetMaxNo("TK"); var exTask = new LogTask { TaskNo = taskNo, Sender = "WMS", Receiver = "AGV", IsSuccess = 0, //是否下发成功 0失败 1成功 StartLocat = StartLocate,//起始位置 EndLocat = EndLocate,//目标位置 PalletNo = "",//托盘码 Msg = string.Format("转运任务:{0}=>>{1}", StartLocate, EndLocate), IsSend = 1,//是否可再次下发 IsCancel = 1,//是否可取消 IsFinish = 1,//是否可完成 Type = "2",//任务类型 0 入库任务 1 出库任务 2 移库任务 Status = "0",//任务状态0:等待执行1正在执行2执行完成 OrderType = "3",//0 入库单 1 出库单 2 盘点单 3 移库单 CreateTime = DateTime.Now }; Db.Insertable(exTask).ExecuteCommand(); var storageLocatEnd = Db.Queryable().First(w => w.LocatNo == EndLocate); //修改目标储位地址状态 if (storageLocatEnd != null) { storageLocatEnd.Status = "4";//0:空储位 1:有物品 2:入库中 3:出库中 4:移入中 5:移出中 Db.Updateable(storageLocatEnd).ExecuteCommand(); } #region 呼叫小车代码 var endlono = EndLocate; string tasktype = "D01"; //点到点指令集合 object[] position = new object[2]; position[0] = new { positionCode = StartLocate, type = "00" }; position[1] = new { positionCode = endlono, type = "00" }; List agvTaskList = new List(); AgvSchedulingTask agvTask = new AgvSchedulingTask(); Random r = new Random(); long ran = DateTime.Now.Ticks; agvTask.ReqCode = ran.ToString(); agvTask.TaskCode = taskNo; agvTask.TaskTyp = tasktype; agvTask.PositionCodePath = position; agvTask.CtnrTyp = "1"; agvTaskList.Add(agvTask); string str = ""; var list2 = agvTaskList.Select(m => m.TaskCode).ToList(); var jsonData = JsonConvert.SerializeObject(agvTaskList); jsonData = jsonData.Substring(1, jsonData.Length - 1); jsonData = jsonData.Substring(0, jsonData.Length - 1); string response = ""; try { var time1 = DateTime.Now;//发送时间 .ToString("yyyy-MM-dd HH:mm:ss") response = HttpHelper.DoPost(url, jsonData, "下发给AGV转运命令", "AGV"); var time2 = DateTime.Now;//返回时间 .ToString("yyyy-MM-dd HH:mm:ss") //////解析返回数据 var agvModel = JsonConvert.DeserializeObject(response); if (agvModel.Code == "0") { //更改任务的发送返回时间// new TaskServer().EditTaskIssueOk(list2, time1, time2); str += "下发成功"; } if (agvModel.Code == "1") { new TaskServer().EditTaskIssueNo(list2, time1, time2, agvModel.Message); throw new Exception(agvModel.Message); } } catch (Exception ex) { throw new Exception(ex.Message); } #endregion //添加操作日志记录 var k = new OperationCrServer().AddLogOperationCr("PDA模块", "AGV转运", "", "移库", $"PDA呼叫小车拆空托盘拣货", userId); Db.CommitTran(); return ""; } catch (Exception e) { Db.RollbackTran(); throw new Exception(e.Message); } } public string MoveAddress(string oldAddress, string roadWay, string skuNo,string areaNo="")//01020201 排-列-层-深度 { string nowAddress = ""; var category = new SysMaterialCategory(); if (!string.IsNullOrEmpty(skuNo)) { //根据物料编码获取对应区域 var skuCategoryNo = Db.Queryable().Where(a => a.IsDel == "0" && a.SkuNo == skuNo).Select(a => a.CategoryNo).First(); category = Db.Queryable().First(a => a.IsDel == "0" && a.CategoryNo == skuCategoryNo); areaNo = category.AreaNo; } else { //todo 待验证 category = Db.Queryable().First(a => a.IsDel == "0" && a.AreaNo == areaNo); } // 获取移库目标储位 var row = int.Parse(oldAddress.Substring(0, 2)); var lie = int.Parse(oldAddress.Substring(2, 2)); var ceng = int.Parse(oldAddress.Substring(4, 2)); var sqlString = $@"select LocatNo,[Row],[Column],Layer, (ABS(Row-{row}) + ABS([Column]-{lie}) + ABS(Layer-{ceng})) as distNum from SysStorageLocat where Flag = '0' and Status = '0' and Depth = '02' and RoadwayNo = '{roadWay}' and AreaNo in ('{areaNo}') order by distNum;"; var addressModels = Db.Ado.SqlQuery(sqlString).ToList(); if (addressModels.Count > 0) // 判断同巷道内排空库位 { var listLocaete = new List(); foreach (var item in addressModels) { // 目标内库位对应的外库位 string addressee = item.LocatNo.Substring(0, 6) + "01"; // 判断目标库位的外库位是否存在货物 (正常情况下正在移入情况不存在,因为移库先移入里面,后移入外面) //SlotStatus 0: 空储位 1:有货 2:正在入库 3:正在出库 4:正在移入 5:正在移出 sqlString = $"select count(*) from SysStorageLocat where LocatNo = '{addressee}' and Status = '0' and Flag in ('0','1') ; "; var rowNum = Db.Ado.SqlQuery(sqlString).First(); if (rowNum == 0) { continue; } else { nowAddress = item.LocatNo; break; } } } if (nowAddress == "") { // 判断同巷道外排空库位 sqlString = $@"select LocatNo,[Row],[Column],Layer, (ABS(Row-{row}) + ABS([Column]-{lie}) + ABS(Layer-{ceng})) as distNum from SysStorageLocat where Flag = '0' and Status = '0' and Depth = '01' and RoadwayNo = '{roadWay}' and AreaNo in '{category}' order by distNum;"; var adderModeling = Db.Ado.SqlQuery(sqlString).ToList(); if (adderModeling.Count > 0) { nowAddress = adderModeling[0].LocatNo; } else { // 库内不存在空储位 nowAddress = ""; } } return nowAddress; } //获取平库托盘信息 public List GetPingKuInfoByPallet(string soNo, string palletNo) { try { var info = Db.Queryable().Where(m => m.SONo == soNo && m.PalletNo == palletNo && m.IsDel == "0"); if (info.Count() == 0) { throw new Exception("未查询到托盘分配下发的信息"); } var data = info.GroupBy(m => new { m.SkuNo, m.SkuName, m.LotNo }).Select(m => new BoxInfo() { SkuNo = m.SkuNo, SkuName = m.SkuName, LotNo = m.LotNo }).ToList(); return data; } catch (Exception e) { throw new Exception(e.Message); } } /// /// 平库出库完成 /// /// 单据号 /// 托盘码 /// 操作人 public void PlaneExportSuccess(string soNo, string palletNo, int userId) { try { #region 托盘信息 //获取托盘信息 var pallet = Db.Queryable().First(p => p.IsDel == "0" && p.PalletNo == palletNo); //验证托盘信息是否为空 if (pallet == null) { throw new Exception("托盘信息不存在,请检查!"); } if (pallet.Status == "0") { throw new Exception("托盘未使用,请检查!"); } #endregion #region 托盘是否在平库验证 var result = Db.Queryable().First(m => m.PalletNo == palletNo); if (result == null) { throw new Exception("库存信息中不存在该托盘信息,请检查!"); } if (result.WareHouseNo != "W02")//W02:零箱库 { throw new Exception("该托盘未在平库内,请检查!"); } #endregion #region 验证储位状态是否正常 var locat = Db.Queryable().First(a=>a.IsDel == "0" && a.LocatNo == result.LocatNo); if (locat == null) { throw new Exception("未获取到对应储位信息,请检查!"); } if (locat.Status != "3") { throw new Exception("当前储位不是出库中,请检查!"); } #endregion //获取库存明细信息 var stockDetail = Db.Queryable().Where(s => s.IsDel == "0" && s.PalletNo == palletNo).ToList(); //验证库存明细信息是否存在 if (stockDetail == null) { throw new Exception("库存明细不存在,请检查库存信息!"); } Db.BeginTran(); try { foreach (var item in stockDetail) { if (item.SkuNo == "100099")//判断是否是空托出库 { //判断总库存是否为0,如果为0删除 否则减去数量 var stock = Db.Queryable().First(m => m.SkuNo == "100099"); if (stock != null) { if (item.LockQty != null) { stock.Qty -= item.LockQty.Value; stock.LockQty -= item.LockQty.Value; Db.Updateable(stock).ExecuteCommand(); } if (stock.Qty == 0) { Db.Deleteable(stock).ExecuteCommand(); } } //托盘状态改为未使用 var sCode = Db.Queryable().First(m => m.PalletNo == item.PalletNo); if (sCode != null) { sCode.Status = "0"; Db.Updateable(sCode).ExecuteCommand(); } Db.Deleteable(item).ExecuteCommand(); continue; } item.LocatNo = "";//储位更改(改为空) item.WareHouseNo = "";//所属仓库更改(改为空) item.RoadwayNo = "";//所属巷道更改(改为空) item.AreaNo = "";//所属区域更改(改为空) Db.Updateable(item).ExecuteCommand(); } //变更储位状态 locat.Status = "0";//储位更改(改为空储位) Db.Updateable(locat).ExecuteCommand(); //出库流水(更改状态) var allot = Db.Queryable().Where(m => m.IsDel == "0" && m.Status == "1" && m.PalletNo == palletNo && m.SONo == soNo).ToList(); foreach (var item in allot) { if (item.SkuNo == "100099") { item.Status = "5"; item.CompleteQty += stockDetail[0].Qty; } else { item.Status = "2"; } } Db.Updateable(allot).ExecuteCommand(); #region 添加出库操作日志记录信息 //添加操作日志记录 var k = new OperationSOServer().AddLogOperationSo("出库作业", "拣货明细", soNo, "完成", $"用PDA完成了单据号为{soNo}的平库出库", userId); #endregion Db.CommitTran(); } catch (Exception e) { Db.RollbackTran(); throw new Exception(e.Message); } } catch (Exception e) { throw new Exception(e.Message); } } //根据托盘号获取取样类型 public string GetSampleType(string palletNo) { try { var type = ""; var detail = Db.Queryable().First(m => m.IsDel == "0" && m.PalletNo == palletNo); if (detail == null) { throw new Exception("当前托盘未在库存中"); } //怎么判断当前托盘是库外要取样的托盘,正常出库剩余托盘目前这种情况也能拣货啊,也没有分配信息 var allot = Db.Queryable().First(m => m.IsDel == "0" && m.PalletNo == palletNo && m.Status != "5" && m.Status != "6"); if (allot != null) { var soNo = Db.Queryable() .First(m => m.IsDel == "0" && m.SONo == allot.SONo); if (soNo == null) { throw new Exception("未找到托盘上出库单据信息"); } if (soNo.Type != "3") { throw new Exception("该托盘不是取样托盘"); } type = "0";//库内取样 } else { //判断当前托盘是否是在平库或库外 type = "1";//库前取样 } return type; } catch (Exception e) { throw new Exception(e.Message); } } //根据托盘号获取入库单据 public List GetAsnNoByPallet(string palletNo) { try { var type = ""; var detail = Db.Queryable().First(m => m.IsDel == "0" && m.PalletNo == palletNo); if (detail == null) { throw new Exception("当前托盘未在库存中"); } var list = new List(); if (string.IsNullOrWhiteSpace(detail.ASNNo)) { throw new Exception("未查询到该托盘的入库单信息"); } list.Add(detail.ASNNo); return list; } catch (Exception e) { throw new Exception(e.Message); } } //取样出库拣货(标签) public void SampleSoSetPick(string soType, string soNo, string soDetailId, string palletNo, string boxNo, string boxNo3, string pickQty1, string asnNo, int userId) { Db.BeginTran(); try { if (string.IsNullOrWhiteSpace(soType)) { throw new Exception("取样标识不能为空"); } //soType: 0库内取样,有出库单及分配信息; 1库前取样,反向添加出库单及分配信息 if (soType == "1") { #region 判断 if (string.IsNullOrWhiteSpace(asnNo)) { throw new Exception("入库单不能为空"); } if (string.IsNullOrWhiteSpace(palletNo)) { throw new Exception("托盘码不能为空"); } if (!string.IsNullOrEmpty(boxNo3) && !string.IsNullOrEmpty(pickQty1) && decimal.Parse(pickQty1) > 0) { throw new Exception("追溯条码和拣货数量不能同时输入"); } //先判断是否是库外取样托盘 var allot = Db.Queryable().First(m => m.IsDel == "0" && m.PalletNo == palletNo && m.Status != "5" && m.Status != "6"); if (allot != null) { throw new Exception("当前托盘不属于库前取样"); } //库存明细 var stockDetail = Db.Queryable().First(m => m.IsDel == "0" && m.ASNNo == asnNo && m.PalletNo == palletNo); if (stockDetail == null) { throw new Exception("未查询到该托盘的库存明细信息!"); } var sku = Db.Queryable().First(m => m.IsDel == "0" && m.SkuNo == stockDetail.SkuNo); if (sku == null) { throw new Exception("未查询到当前托盘上的物料信息"); } //库存总表 var stock = Db.Queryable().First(a => a.IsDel == "0" && a.SkuNo == stockDetail.SkuNo && a.LotNo == stockDetail.LotNo); if (stock == null) { throw new Exception("未查询到该托盘分配的库存信息!"); } //出库单 var notice = Db.Queryable().First(m => m.IsDel == "0" && m.AsnSampleNo == asnNo); //创建出库单 if (notice == null || notice.Status == "6") { var billNo = ""; var bl = true; do { //获取自增单据号 billNo = new Common().GetMaxNo("SO"); var no = billNo; bl = Db.Queryable().Any(m => m.SONo == no); } while (bl); var addNotice = new BllExportNotice() { SONo = billNo, Type = "3", Status = "4", Origin = "WMS", AsnSampleNo = asnNo, IsWave = "0", WaveNo = "", IsDespatch = "0", CompleteTime = DateTime.Now, CreateUser = userId, }; var n = Db.Insertable(addNotice).ExecuteReturnEntity(); notice = n; } //创建出库单明细 var noticeDetail = Db.Queryable().First(m => m.IsDel == "0" && m.SONo == notice.SONo && m.SkuNo == stockDetail.SkuNo && m.LotNo.Contains(stockDetail.LotNo)); if (noticeDetail == null) { var addNoticeDetail = new BllExportNoticeDetail() { SONo = notice.SONo, SkuNo = sku.SkuNo, SkuName = sku.SkuName, Standard = sku.Standard, LotNo = stockDetail.LotNo, LotText = "", Qty = 0, AllotQty = 0, FactQty = 0, CompleteQty = 0, PackagNo = sku.PackagNo, Price = sku.Price, //Money = string.IsNullOrWhiteSpace(sku.Price.ToString()) ? null : sku.Price * pickQty, IsBale = "", IsBelt = "", SupplierLot = stock.SupplierLot, IsWave = "0", WaveNo = "", IsIssueLotNo = "0", Status = "3", CreateUser = userId, }; var m = Db.Insertable(addNoticeDetail).ExecuteReturnEntity(); noticeDetail = m; } //出库分配信息 var allot2 = Db.Queryable().First(m => m.IsDel == "0" && m.Status == "5" && m.SONo == notice.SONo && m.PalletNo == palletNo); if (allot2 == null) { //添加分配表信息 var addAllot = new BllExportAllot { SONo = notice.SONo, WaveNo = "", SODetailNo = noticeDetail.Id, StockId = stockDetail.Id, LotNo = stockDetail.LotNo, LotText = stockDetail.LotText, SupplierLot = stockDetail.SupplierLot, SkuNo = sku.SkuNo, SkuName = sku.SkuName, Standard = sku.Standard, PalletNo = palletNo, IsBale = "0", //是否裹包 IsBelt = "0", //是否打带 Qty = 0, CompleteQty = 0, Status = "5", LogisticsId = notice.LogisticsId, IsAdvance = "0", OutMode = "",//出库口 CreateUser = userId, UpdateTime = DateTime.Now }; var fp = Db.Insertable(addAllot).ExecuteReturnEntity(); allot2 = fp; } #endregion //判断是散支拣货还是数量拣货 var biaoShi = "0";//0:整箱拣货、1:散支拣货、2:数量拣货 List boxInfos; var boxInfo = Db.Queryable().Where(m => m.IsDel == "0" && m.BoxNo == boxNo); if (boxInfo.Count() == 0) { throw new Exception("未查询到该箱码及追溯码的信息"); } boxInfos = boxInfo.ToList(); var comDetailList = Db.Queryable().Where(m => m.IsDel == "0" && m.ExportAllotId == allot2.Id && m.PalletNo == palletNo).ToList(); if (!string.IsNullOrWhiteSpace(boxNo3)) //散支拣货 { boxInfos = boxInfos.Where(m => m.BoxNo3 == boxNo3).ToList(); if (boxInfos.Count() == 0) { throw new Exception("未查询到该箱码及追溯码的信息"); } if (boxInfos.Count() > 1) { throw new Exception("该追溯支码的信息大于1条,信息错误,请核实!"); } if (boxInfos.Any(m => m.PalletNo != palletNo)) { throw new Exception("该托盘与箱码没有绑定关系"); } foreach (var item in boxInfos) { if (biaoShi != "2" && comDetailList.Any(m => m.BoxNo3 == item.BoxNo3)) { throw new Exception($"当前{item.BoxNo}中{item.BoxNo3}已拣货完成,请勿重复拣货"); } } biaoShi = "1"; } else if (!string.IsNullOrEmpty(pickQty1) && decimal.Parse(pickQty1) > 0)//数量拣货 { if (boxInfo.Count() > 1) { throw new Exception("该箱码内存在支码不能进行数量拣货"); } decimal boxQty = boxInfo.First().Qty; if (Convert.ToInt32(pickQty1) > boxQty) { throw new Exception("拣货数量不能大于箱内数量"); } biaoShi = "2"; } else //整箱拣货 { if (boxInfo.Count() == 0) { throw new Exception("未查询到该箱码的信息"); } if (boxInfo.Any(m => m.PalletNo != palletNo)) { throw new Exception("该托盘与箱码没有绑定关系"); } foreach (var item in boxInfos) { if (biaoShi != "2" && comDetailList.Any(m => m.BoxNo == item.BoxNo)) { throw new Exception($"当前{item.BoxNo}已拣货完成,请勿重复拣货"); } } } decimal pickQty = 0;//拣货的数量 var comList = new List(); foreach (var item in boxInfos) { //if (biaoShi != "2" && comDetailList.Any(m => m.BoxNo3 == item.BoxNo3)) //{ // throw new Exception($"当前{item.BoxNo}中{item.BoxNo3}已拣货完成,请勿重复拣货"); //} //添加拣货明细 var completeDetail = new BllCompleteDetail() { SONo = notice.SONo, SODetailNo = noticeDetail.Id, ExportAllotId = allot2.Id, StockId = allot2.StockId, BoxNo = item.BoxNo, BoxNo2 = item.BoxNo2, BoxNo3 = item.BoxNo3, LotNo = allot2.LotNo, LotText = allot2.LotText, SupplierLot = allot2.SupplierLot, SkuNo = allot2.SkuNo, SkuName = allot2.SkuName, Standard = allot2.Standard, PalletNo = palletNo, CompleteQty = biaoShi == "2" ? decimal.Parse(pickQty1) : item.Qty, InspectMark = "1", CreateUser = userId }; comList.Add(completeDetail); if (biaoShi != "2") { //删除库存箱码明细 Db.Deleteable(item).ExecuteCommand(); } else//数量拣货 { if (decimal.Parse(pickQty1) == item.Qty) { //删除库存箱码明细 Db.Deleteable(item).ExecuteCommand(); } else { item.Qty -= decimal.Parse(pickQty1); item.BitBoxMark = "1";//零箱标识 item.InspectMark = "1";//抽检箱标识 Db.Updateable(item).ExecuteCommand(); } } pickQty += biaoShi == "2" ? decimal.Parse(pickQty1) : item.Qty; } //改变库内箱码是否零箱信息 if (biaoShi == "1") { var boxSurplusList = boxInfo.Where(m => m.BoxNo3 != boxNo3).ToList(); foreach (var item in boxSurplusList) { item.BitBoxMark = "1"; item.InspectMark = "1"; Db.Updateable(item).ExecuteCommand(); } } Db.Insertable(comList).ExecuteCommand(); //修改出库分配信息 allot2.Qty += pickQty; allot2.CompleteQty += pickQty; Db.Updateable(allot2).ExecuteCommand(); //删除或修改库存明细 stockDetail.BitPalletMark = "1";//修改为零托标识 stockDetail.Qty -= pickQty; if (stockDetail.Qty <= 0) { Db.Deleteable(stockDetail).ExecuteCommand(); } else { Db.Updateable(stockDetail).ExecuteCommand(); } stock.Qty -= pickQty; if (stock.Qty <= 0) { Db.Deleteable(stock).ExecuteCommand(); } else { Db.Updateable(stock).ExecuteCommand(); } var num2 = Db.Queryable().Count(m => m.IsDel == "0" && m.PalletNo == palletNo); if (num2 <= 0) { //改变托盘状态 var pallet = Db.Queryable().First(m => m.PalletNo == palletNo && m.IsDel == "0"); if (pallet == null) { throw new Exception("未在托盘表中查询到托盘信息"); } pallet.Status = "0"; Db.Updateable(pallet).ExecuteCommand(); } //修改出库单明细拣货数量 noticeDetail.Qty += pickQty; noticeDetail.AllotQty += pickQty; noticeDetail.FactQty += pickQty; noticeDetail.CompleteQty += pickQty; noticeDetail.Money = string.IsNullOrWhiteSpace(sku.Price.ToString()) ? null : sku.Price * noticeDetail.Qty; Db.Updateable(noticeDetail).ExecuteCommand(); } else if (soType == "0") { #region 判断 if (string.IsNullOrWhiteSpace(soNo)) { throw new Exception("出库单据不能为空"); } if (string.IsNullOrWhiteSpace(soDetailId)) { throw new Exception("出库物料-批次不能为空"); } if (string.IsNullOrWhiteSpace(palletNo)) { throw new Exception("托盘码不能为空"); } if (!string.IsNullOrEmpty(boxNo3) && !string.IsNullOrEmpty(pickQty1) && decimal.Parse(pickQty1) > 0) { throw new Exception("追溯条码和拣货数量不能同时输入"); } //出库单 var notice = Db.Queryable().First(m => m.IsDel == "0" && m.SONo == soNo); if (notice == null) { throw new Exception("未查询到该出库单的信息"); } if (notice.Status != "3") { throw new Exception("出库单的状态不是正在执行,不能拣货"); } //出库单明细 var noticeDetail = Db.Queryable() .First(m => m.IsDel == "0" && m.Id == int.Parse(soDetailId)); if (noticeDetail == null) { throw new Exception("未查询到该出库单明细的信息"); } //出库分配信息 var allot = Db.Queryable().First(m => m.IsDel == "0" && (m.Status == "2" || m.Status == "3") && m.SONo == soNo && m.SODetailNo == int.Parse(soDetailId) && m.PalletNo == palletNo); if (allot == null) { throw new Exception("未查询到该托盘的分配信息"); } //剩余拣货数量(待拣减去已拣) var needQty = allot.Qty - allot.CompleteQty; //库存明细 var stockDetail = Db.Queryable().First(m => m.IsDel == "0" && m.Id == allot.StockId); if (stockDetail == null) { throw new Exception("未查询到该托盘分配的库存明细信息!"); } //库存总表 var stock = Db.Queryable().First(a => a.IsDel == "0" && a.SkuNo == stockDetail.SkuNo && a.LotNo == stockDetail.LotNo); if (stock == null) { throw new Exception("未查询到该托盘分配的库存信息!"); } #endregion var biaoShi = "0";//0:整箱拣货、1:散支拣货、2:数量拣货 List boxInfos; var boxInfo = Db.Queryable().Where(m => m.IsDel == "0" && m.BoxNo == boxNo); if (boxInfo.Count() == 0) { throw new Exception("未查询到该箱码及追溯码的信息"); } boxInfos = boxInfo.ToList(); var comDetailList = Db.Queryable().Where(m => m.IsDel == "0" && m.ExportAllotId == allot.Id && m.PalletNo == palletNo).ToList(); if (!string.IsNullOrWhiteSpace(boxNo3)) //散支拣货 { boxInfos = boxInfos.Where(m => m.BoxNo3 == boxNo3).ToList(); if (boxInfos.Count() == 0) { throw new Exception("未查询到该箱码及追溯码的信息"); } if (boxInfos.Count() > 1) { throw new Exception("该追溯支码的信息大于1条,信息错误,请核实!"); } if (boxInfos.Any(m => m.PalletNo != palletNo)) { throw new Exception("该托盘与箱码没有绑定关系"); } var boxQty = boxInfos.First().Qty; if (boxQty > needQty) { throw new Exception("拣货数量不能大于剩余待拣数量"); } foreach (var item in boxInfos) { if (biaoShi != "2" && comDetailList.Any(m => m.BoxNo3 == item.BoxNo3)) { throw new Exception($"当前{item.BoxNo}中{item.BoxNo3}已拣货完成,请勿重复拣货"); } } biaoShi = "1"; } else if (!string.IsNullOrEmpty(pickQty1) && decimal.Parse(pickQty1) > 0)//数量拣货 { if (boxInfo.Count() > 1) { throw new Exception("该箱码内存在支码不能进行数量拣货"); } decimal boxQty = boxInfo.First().Qty; if (Convert.ToDecimal(pickQty1) > boxQty) { throw new Exception("拣货数量不能大于箱内数量"); } if (Convert.ToDecimal(pickQty1) > needQty) { throw new Exception("拣货数量不能大于剩余待拣数量"); } biaoShi = "2"; } else //整箱拣货 { if (boxInfo.Count() == 0) { throw new Exception("未查询到该箱码的信息"); } if (boxInfo.Any(m => m.PalletNo != palletNo)) { throw new Exception("该托盘与箱码没有绑定关系"); } var boxQty = boxInfo.GroupBy(m => m.BoxNo).Select(m => SqlFunc.AggregateSum(m.Qty)).ToList(); if (boxQty[0] > needQty) { throw new Exception("拣货数量不能大于箱内剩余待拣数量"); } foreach (var item in boxInfos) { if (biaoShi != "2" && comDetailList.Any(m => m.BoxNo == item.BoxNo)) { throw new Exception($"当前{item.BoxNo}已拣货完成,请勿重复拣货"); } } } decimal pickQty = 0;//拣货的数量 var comList = new List(); foreach (var item in boxInfos) { //if (biaoShi != "2" && comDetailList.Any(m => m.BoxNo3 == item.BoxNo3)) //{ // throw new Exception($"当前{item.BoxNo}中{item.BoxNo3}已拣货完成,请勿重复拣货"); //} //添加拣货明细 var completeDetail = new BllCompleteDetail() { SONo = soNo, SODetailNo = int.Parse(soDetailId), ExportAllotId = allot.Id, StockId = allot.StockId, BoxNo = item.BoxNo, BoxNo2 = item.BoxNo2, BoxNo3 = item.BoxNo3, LotNo = allot.LotNo, LotText = allot.LotText, SupplierLot = allot.SupplierLot, SkuNo = allot.SkuNo, SkuName = allot.SkuName, Standard = allot.Standard, PalletNo = palletNo, CompleteQty = biaoShi == "2" ? decimal.Parse(pickQty1) : item.Qty, CreateUser = userId }; comList.Add(completeDetail); if (biaoShi != "2") { pickQty += item.Qty; //删除库存箱码明细 Db.Deleteable(item).ExecuteCommand(); } else//数量拣货 { if (decimal.Parse(pickQty1) == item.Qty) { pickQty += item.Qty; //删除库存箱码明细 Db.Deleteable(item).ExecuteCommand(); } else { pickQty += decimal.Parse(pickQty1); item.Qty -= decimal.Parse(pickQty1); item.BitBoxMark = "1";//零箱标识 Db.Updateable(item).ExecuteCommand(); } } } //改变库内箱码是否零箱信息 if (biaoShi == "1") { var boxSurplusList = boxInfo.Where(m => m.BoxNo3 != boxNo3).ToList(); foreach (var item in boxSurplusList) { item.BitBoxMark = "1"; Db.Updateable(item).ExecuteCommand(); } } Db.Insertable(comList).ExecuteCommand(); //修改出库分配信息 allot.CompleteQty += pickQty; allot.Status = allot.Qty == allot.CompleteQty ? "5" : "3"; allot.UpdateTime = DateTime.Now; if (allot.Status == "5") { //判断该托盘是否还存在物料 存在改为待回库 待回库完成后改为已完成 } Db.Updateable(allot).ExecuteCommand(); //删除或修改库存明细 stockDetail.BitPalletMark = "1";//修改为零托标识 stockDetail.Qty -= pickQty; stockDetail.LockQty -= pickQty; if (stockDetail.Qty == stockDetail.LockQty) { stockDetail.Status = "2"; } else if (stockDetail.Qty > stockDetail.LockQty && stockDetail.LockQty > 0) { stockDetail.Status = "1"; } else { stockDetail.Status = "0"; } if (stockDetail.Qty <= 0) { Db.Deleteable(stockDetail).ExecuteCommand(); } else { Db.Updateable(stockDetail).ExecuteCommand(); } stock.Qty -= pickQty; stock.LockQty -= pickQty; if (stock.Qty <= 0) { Db.Deleteable(stock).ExecuteCommand(); } else { Db.Updateable(stock).ExecuteCommand(); } var num2 = Db.Queryable().Count(m => m.IsDel == "0" && m.PalletNo == palletNo); if (num2 <= 0) { //改变托盘状态 var pallet = Db.Queryable().First(m => m.PalletNo == palletNo && m.IsDel == "0"); if (pallet == null) { throw new Exception("未在托盘表中查询到托盘信息"); } pallet.Status = "0"; Db.Updateable(pallet).ExecuteCommand(); } //修改出库单明细拣货数量 noticeDetail.CompleteQty += pickQty; Db.Updateable(noticeDetail).ExecuteCommand(); var num = Db.Queryable() .Count(m => m.IsDel == "0" && m.SONo == soNo && m.CompleteQty < m.Qty); if (num <= 0) { notice.Status = "4"; //更改为执行完成 } //修改出库单信息 Db.Updateable(notice).ExecuteCommand(); } //添加操作日志记录 var k = new OperationSOServer().AddLogOperationSo("PDA模块", "拣货出库", soNo, "拣货", $"在PDA上对出库单号为:{soNo}的托盘码为:{palletNo}的拣货操作", userId); Db.CommitTran(); } catch (Exception e) { Db.RollbackTran(); throw new Exception(e.Message); } } //取样出库拣货(无标签) public void SampleSoSetQtyPick(string soType, string soNo, string soDetailId, string palletNo, string PickQty, string asnNo, int userId) { Db.BeginTran(); try { if (string.IsNullOrWhiteSpace(soType)) { throw new Exception("取样标识不能为空"); } if (soType == "1") { if (string.IsNullOrWhiteSpace(asnNo)) { throw new Exception("入库单据不能为空"); } if (string.IsNullOrWhiteSpace(palletNo)) { throw new Exception("托盘码不能为空"); } //先判断是否是库外取样托盘 var allot = Db.Queryable().First(m => m.IsDel == "0" && m.PalletNo == palletNo && m.Status != "5" && m.Status != "6"); if (allot != null) { throw new Exception("当前托盘不属于库前取样"); } //库存明细 var stockDetail = Db.Queryable().First(m => m.IsDel == "0" && m.ASNNo == asnNo && m.PalletNo == palletNo); if (stockDetail == null) { throw new Exception("未查询到该托盘的库存明细信息!"); } var sku = Db.Queryable().First(m => m.IsDel == "0" && m.SkuNo == stockDetail.SkuNo); if (sku == null) { throw new Exception("未查询到当前托盘上的物料信息"); } //库存总表 var stock = Db.Queryable().First(a => a.IsDel == "0" && a.SkuNo == stockDetail.SkuNo && a.LotNo == stockDetail.LotNo); if (stock == null) { throw new Exception("未查询到该托盘分配的库存信息!"); } //出库单 var notice = Db.Queryable().First(m => m.IsDel == "0" && m.AsnSampleNo == asnNo); //创建出库单 if (notice == null || notice.Status == "6") { var billNo = ""; var bl = true; do { //获取自增单据号 billNo = new Common().GetMaxNo("SO"); var no = billNo; bl = Db.Queryable().Any(m => m.SONo == no); } while (bl); var addNotice = new BllExportNotice() { SONo = billNo, Type = "3", Status = "4", Origin = "WMS", AsnSampleNo = asnNo, IsWave = "0", WaveNo = "", IsDespatch = "0", CompleteTime = DateTime.Now, CreateUser = userId, }; var n = Db.Insertable(addNotice).ExecuteReturnEntity(); notice = n; } //创建出库单明细 var noticeDetail = Db.Queryable().First(m => m.IsDel == "0" && m.SONo == notice.SONo && m.SkuNo == stockDetail.SkuNo && m.LotNo.Contains(stockDetail.LotNo)); if (noticeDetail == null) { var addNoticeDetail = new BllExportNoticeDetail() { SONo = notice.SONo, SkuNo = sku.SkuNo, SkuName = sku.SkuName, Standard = sku.Standard, LotNo = stockDetail.LotNo, LotText = "", Qty = 0, AllotQty = 0, FactQty = 0, CompleteQty = 0, PackagNo = sku.PackagNo, Price = sku.Price, //Money = string.IsNullOrWhiteSpace(sku.Price.ToString()) ? null : sku.Price * pickQty, IsBale = "", IsBelt = "", SupplierLot = stock.SupplierLot, IsWave = "0", WaveNo = "", IsIssueLotNo = "0", Status = "3", CreateUser = userId, }; var m = Db.Insertable(addNoticeDetail).ExecuteReturnEntity(); noticeDetail = m; } //出库分配信息 var allot2 = Db.Queryable().First(m => m.IsDel == "0" && m.Status == "5" && m.SONo == notice.SONo && m.PalletNo == palletNo); if (allot2 == null) { //添加分配表信息 var addAllot = new BllExportAllot { SONo = notice.SONo, WaveNo = "", SODetailNo = noticeDetail.Id, StockId = stockDetail.Id, LotNo = stockDetail.LotNo, LotText = stockDetail.LotText, SupplierLot = stockDetail.SupplierLot, SkuNo = sku.SkuNo, SkuName = sku.SkuName, Standard = sku.Standard, PalletNo = palletNo, IsBale = "0", //是否裹包 IsBelt = "0", //是否打带 Qty = 0, CompleteQty = 0, Status = "5", LogisticsId = notice.LogisticsId, IsAdvance = "0", OutMode = "",//出库口 CreateUser = userId, UpdateTime = DateTime.Now }; var fp = Db.Insertable(addAllot).ExecuteReturnEntity(); allot2 = fp; } //获取当前托盘拣货明细 var complete = Db.Queryable().First(a => a.IsDel == "0" && a.PalletNo == palletNo && a.SONo == notice.SONo && a.ExportAllotId == allot2.Id && a.StockId == stockDetail.Id); //判读是否存在拣货明细 int isComplete = 0; if (complete != null) { isComplete = 1; } var comList = new List(); //判断是否存在拣货明细 if (isComplete == 0) { //添加拣货明细 var completeDetail = new BllCompleteDetail() { SONo = notice.SONo, SODetailNo = noticeDetail.Id, ExportAllotId = allot2.Id, StockId = allot2.StockId, BoxNo = "", BoxNo2 = "", BoxNo3 = "", LotNo = allot2.LotNo, LotText = allot2.LotText, SupplierLot = allot2.SupplierLot, SkuNo = allot2.SkuNo, SkuName = allot2.SkuName, Standard = allot2.Standard, PalletNo = palletNo, CompleteQty = decimal.Parse(PickQty), InspectMark = "1", CreateUser = userId }; comList.Add(completeDetail); //添加拣货明细 Db.Insertable(comList).ExecuteCommand(); } else if (isComplete == 1) { complete.CompleteQty += decimal.Parse(PickQty); complete.UpdateUser = userId; complete.UpdateTime = Db.GetDate(); Db.Updateable(complete).ExecuteCommand(); } //修改出库分配信息 allot2.Qty += decimal.Parse(PickQty); allot2.CompleteQty += decimal.Parse(PickQty); Db.Updateable(allot2).ExecuteCommand(); int isDel = 0; //删除或修改库存明细 stockDetail.BitPalletMark = "1";//修改为零托标识 stockDetail.InspectMark = "1";//修改为抽检托标识 stockDetail.Qty -= decimal.Parse(PickQty); if (stockDetail.Qty == stockDetail.LockQty && stockDetail.Qty != 0) { stockDetail.Status = "2"; } else if (stockDetail.Qty > stockDetail.LockQty && stockDetail.LockQty > 0) { stockDetail.Status = "1"; } else { stockDetail.Status = "0"; } if (stockDetail.Qty <= 0) { Db.Deleteable(stockDetail).ExecuteCommand(); } else { isDel = 1; Db.Updateable(stockDetail).ExecuteCommand(); } //删除或修改库存 stock.Qty -= int.Parse(PickQty); if (stock.Qty <= 0) { Db.Deleteable(stock).ExecuteCommand(); } else { Db.Updateable(stock).ExecuteCommand(); } //改变托盘状态为:未使用 var pallet = Db.Queryable().First(m => m.PalletNo == palletNo && m.IsDel == "0"); if (pallet == null) { throw new Exception("未在托盘表中查询到托盘信息"); } //判断托盘上物料是否拣货完毕 if (isDel == 0) { pallet.Status = "0"; Db.Updateable(pallet).ExecuteCommand(); } //修改出库单明细拣货数量 noticeDetail.Qty += decimal.Parse(PickQty); noticeDetail.AllotQty += decimal.Parse(PickQty); noticeDetail.FactQty += decimal.Parse(PickQty); noticeDetail.CompleteQty += decimal.Parse(PickQty); noticeDetail.Money = string.IsNullOrWhiteSpace(sku.Price.ToString()) ? null : sku.Price * noticeDetail.Qty; Db.Updateable(noticeDetail).ExecuteCommand(); } else if (soType == "0") { #region 判断 if (string.IsNullOrWhiteSpace(soNo)) { throw new Exception("出库单据不能为空"); } //if (string.IsNullOrWhiteSpace(soDetailId)) //{ // throw new Exception("出库物料-批次不能为空"); //} if (string.IsNullOrWhiteSpace(palletNo)) { throw new Exception("托盘码不能为空"); } //出库单 var notice = Db.Queryable().First(m => m.IsDel == "0" && m.SONo == soNo); if (notice == null) { throw new Exception("未查询到该出库单的信息"); } if (notice.Status != "3") { throw new Exception("出库单的状态不是正在执行,不能拣货"); } //出库单明细 var noticeDetail = Db.Queryable() .First(m => m.IsDel == "0" && m.Id == int.Parse(soDetailId)); if (noticeDetail == null) { throw new Exception("未查询到该出库单明细的信息"); } //出库分配信息 var allot = Db.Queryable().First(m => m.IsDel == "0" && (m.Status == "2" || m.Status == "3") && m.SONo == soNo && m.SODetailNo == int.Parse(soDetailId) && m.PalletNo == palletNo); if (allot == null) { throw new Exception("未查询到该托盘的分配信息"); } //剩余拣货数量(待拣减去已拣) var needQty = allot.Qty - allot.CompleteQty; if (decimal.Parse(PickQty) > needQty) { throw new Exception("拣货数量不能大于托内剩余待拣数量"); } //库存明细 var stockDetail = Db.Queryable().First(m => m.IsDel == "0" && m.Id == allot.StockId); if (stockDetail == null) { throw new Exception("未查询到该托盘分配的库存明细信息!"); } //库存总表 var stock = Db.Queryable().First(a => a.IsDel == "0" && a.SkuNo == stockDetail.SkuNo && a.LotNo == stockDetail.LotNo); if (stock == null) { throw new Exception("未查询到该托盘分配的库存信息!"); } #endregion //获取当前托盘拣货明细 var complete = Db.Queryable().First(a => a.IsDel == "0" && a.PalletNo == palletNo && a.SONo == notice.SONo && a.SODetailNo == noticeDetail.Id && a.ExportAllotId == allot.Id && a.StockId == stockDetail.Id); //判读是否存在拣货明细 int isComplete = 0; if (complete != null) { isComplete = 1; } var comList = new List(); //判断是否存在拣货明细 if (isComplete == 0) { //添加拣货明细 var completeDetail = new BllCompleteDetail() { SONo = soNo, SODetailNo = int.Parse(soDetailId), ExportAllotId = allot.Id, StockId = allot.StockId, BoxNo = "", BoxNo2 = "", BoxNo3 = "", LotNo = allot.LotNo, LotText = allot.LotText, SupplierLot = allot.SupplierLot, SkuNo = allot.SkuNo, SkuName = allot.SkuName, Standard = allot.Standard, PalletNo = palletNo, CompleteQty = decimal.Parse(PickQty), CreateUser = userId, CreateTime = Db.GetDate(), }; comList.Add(completeDetail); //添加拣货明细 Db.Insertable(comList).ExecuteCommand(); } else if (isComplete == 1) { complete.CompleteQty += decimal.Parse(PickQty); complete.UpdateUser = userId; complete.UpdateTime = Db.GetDate(); Db.Updateable(complete).ExecuteCommand(); } //修改出库分配信息 allot.CompleteQty += decimal.Parse(PickQty); allot.Status = allot.Qty == allot.CompleteQty ? "5" : "3"; allot.UpdateTime = DateTime.Now; Db.Updateable(allot).ExecuteCommand(); int isDel = 0; //删除或修改库存明细 stockDetail.BitPalletMark = "1";//修改为零托标识 stockDetail.Qty -= decimal.Parse(PickQty); stockDetail.LockQty -= decimal.Parse(PickQty); if (stockDetail.Qty == stockDetail.LockQty) { stockDetail.Status = "2"; } else if (stockDetail.Qty > stockDetail.LockQty && stockDetail.LockQty > 0) { stockDetail.Status = "1"; } else { stockDetail.Status = "0"; } if (stockDetail.Qty <= 0) { Db.Deleteable(stockDetail).ExecuteCommand(); } else { isDel = 1; Db.Updateable(stockDetail).ExecuteCommand(); } //删除或修改库存 stock.Qty -= decimal.Parse(PickQty); stock.LockQty -= decimal.Parse(PickQty); if (stock.Qty <= 0) { Db.Deleteable(stock).ExecuteCommand(); } else { Db.Updateable(stock).ExecuteCommand(); } //改变托盘状态为:未使用 var pallet = Db.Queryable().First(m => m.PalletNo == palletNo && m.IsDel == "0"); if (pallet == null) { throw new Exception("未在托盘表中查询到托盘信息"); } //判断托盘上物料是否拣货完毕 if (isDel == 0) { pallet.Status = "0"; Db.Updateable(pallet).ExecuteCommand(); } //修改出库单明细拣货数量 noticeDetail.CompleteQty += decimal.Parse(PickQty); Db.Updateable(noticeDetail).ExecuteCommand(); var num = Db.Queryable() .Count(m => m.IsDel == "0" && m.SONo == soNo && m.CompleteQty < m.Qty); if (num <= 0) { notice.Status = "4"; //更改为执行完成 } //修改出库单信息 Db.Updateable(notice).ExecuteCommand(); } //添加操作日志记录 var k = new OperationSOServer().AddLogOperationSo("PDA模块", "拣货出库", soNo, "拣货", $"在PDA上对出库单号为:{soNo}的托盘码为:{palletNo}的拣货操作", userId); Db.CommitTran(); } catch (Exception e) { Db.RollbackTran(); throw new Exception(e.Message); } } #region 拣货拼托 /// /// 拼托出库pda拣货-标签 /// /// /// /// /// /// /// /// /// public void SoSetPinPick(string soNo, string soDetailId, string palletNo, string boxNo, string boxNo3, string pickQty1, string palletNoNew, int userId) { Db.BeginTran(); try { var nowDate = DateTime.Now;//当前时间 #region 判断 if (string.IsNullOrWhiteSpace(soNo)) { throw new Exception("出库单据不能为空"); } if (string.IsNullOrWhiteSpace(soDetailId)) { throw new Exception("出库物料-批次不能为空"); } if (string.IsNullOrWhiteSpace(palletNo)) { throw new Exception("托盘码不能为空"); } if (!string.IsNullOrEmpty(boxNo3) && !string.IsNullOrEmpty(pickQty1) && decimal.Parse(pickQty1) > 0) { throw new Exception("追溯条码和拣货数量不能同时输入"); } if (string.IsNullOrWhiteSpace(palletNoNew)) { throw new Exception("新托盘码不能为空"); } if (palletNo == palletNoNew)//原托盘与新托盘一致 { if (!string.IsNullOrEmpty(boxNo)) { throw new Exception("原托盘与新托盘一致,请选择整托出库"); } } //出库单 var notice = Db.Queryable().First(m => m.IsDel == "0" && m.SONo == soNo); if (notice == null) { throw new Exception("未查询到该出库单的信息"); } if (notice.Type != "1" && notice.Type != "2" && notice.Type != "3") { if (notice.Status != "3") { throw new Exception("出库单的状态不是正在执行,不能拣货"); } } //出库单明细 var noticeDetail = Db.Queryable() .First(m => m.IsDel == "0" && m.Id == int.Parse(soDetailId)); if (noticeDetail == null) { throw new Exception("未查询到该出库单明细的信息"); } //出库分配信息 var allot = Db.Queryable().First(m => m.IsDel == "0" && (m.Status == "2" || m.Status == "3") && m.SONo == soNo && m.SODetailNo == int.Parse(soDetailId) && m.PalletNo == palletNo); if (allot == null) { throw new Exception("未查询到该托盘的分配信息"); } //剩余拣货数量(待拣减去已拣) var needQty = allot.Qty - allot.CompleteQty; //库存明细 var stockDetail = Db.Queryable().First(m => m.IsDel == "0" && m.Id == allot.StockId); if (stockDetail == null) { throw new Exception("未查询到该托盘分配的库存明细信息!"); } //库存总表 var stock = Db.Queryable().First(a => a.IsDel == "0" && a.SkuNo == stockDetail.SkuNo && a.LotNo == stockDetail.LotNo); if (stock == null) { throw new Exception("未查询到该托盘分配的库存信息!"); } #endregion #region 拼托信息 var sdId = 0; bool isNew = false; var pinStockDetail = Db.Queryable().First(m => m.IsDel == "0" && m.PalletNo == palletNoNew); if (pinStockDetail != null) { if (palletNo != palletNoNew)//非整托拣货 { if (pinStockDetail.SONo != notice.SONo) { throw new Exception("拼托托盘上只能放同一个出库单下的物料!"); } if (pinStockDetail.SkuName != stockDetail.SkuName || pinStockDetail.LotNo != stockDetail.LotNo) { isNew = true; } } sdId = pinStockDetail.Id; } else { isNew = true; var newPalletInfo = Db.Queryable().First(m => m.IsDel == "0" && m.PalletNo == palletNoNew && m.Status == "0"); if (newPalletInfo == null) { throw new Exception("新托盘信息不存在或已被使用!"); } //修改新托盘状态 newPalletInfo.Status = "1"; Db.Updateable(newPalletInfo).ExecuteCommand(); } var sd = new DataStockDetail(); if (isNew) { sd.LotNo = stockDetail.LotNo; sd.LotText = stockDetail.LotText; sd.SupplierLot = stockDetail.SupplierLot; sd.SkuNo = stockDetail.SkuNo; sd.SkuName = stockDetail.SkuName; sd.Standard = stockDetail.Standard; sd.FrozenQty = 0; sd.InspectQty = 0; sd.ASNNo = ""; sd.ASNDetailNo = null; sd.SONo = soNo;//出库单号 sd.WareHouseNo = ""; sd.RoadwayNo = ""; sd.AreaNo = ""; sd.LocatNo = ""; sd.PalletNo = palletNoNew; sd.PalletNo2 = ""; sd.PalletNo3 = ""; //PalletType = item.PalletType, sd.CompleteTime = nowDate; sd.ProductionTime = stockDetail.ProductionTime; sd.ExpirationTime = stockDetail.ExpirationTime; sd.Status = "2";//状态,已分配 sd.InspectMark = stockDetail.InspectMark; sd.InspectStatus = stockDetail.InspectStatus; sd.BitPalletMark = "0"; sd.PackagNo = noticeDetail.PackagNo; sd.IsBale = stockDetail.IsBale; sd.IsBelt = stockDetail.IsBelt; sd.Demo = stockDetail.Demo; sd.OwnerName = stockDetail.OwnerName; sd.OwnerNo = stockDetail.OwnerNo; sd.SupplierName = stockDetail.SupplierName; sd.SupplierNo = stockDetail.SupplierNo; sd.IsDel = "0"; sd.CreateUser = userId; sd.CreateTime = nowDate; //新增拼托库存明细信息 sdId = Db.Insertable(sd).ExecuteReturnIdentity(); } #endregion decimal pickQty = 0;//拣货的数量 if (string.IsNullOrWhiteSpace(boxNo))//整托拣货 { List boxInfos; var boxInfo = Db.Queryable().Where(m => m.IsDel == "0" && m.PalletNo == palletNo);//找到托盘上所有箱码 boxInfos = boxInfo.ToList(); if (boxInfo.Count() <= 0) { throw new Exception("该托盘上没有可拣货的箱子"); } var boxQty = boxInfo.GroupBy(m => m.PalletNo).Select(m => SqlFunc.AggregateSum(m.Qty)).ToList(); if (boxQty[0] > needQty) { throw new Exception("拣货数量不能大于箱内剩余待拣数量"); } var comDetailList = Db.Queryable().Where(m => m.IsDel == "0" && m.ExportAllotId == allot.Id && m.PalletNo == palletNo).ToList(); var comList = new List(); foreach (var item in boxInfos) { if (comDetailList.Any(m => m.BoxNo3 == item.BoxNo3)) { throw new Exception($"当前{item.BoxNo}中{item.BoxNo3}已拣货完成,请勿重复拣货"); } if (item.SkuNo != allot.SkuNo || item.LotNo != allot.LotNo) { throw new Exception("当前托盘上有其他不同物料批次,拣货失败"); } //添加拣货明细 var completeDetail = new BllCompleteDetail() { SONo = soNo, SODetailNo = int.Parse(soDetailId), ExportAllotId = allot.Id, StockId = allot.StockId, BoxNo = item.BoxNo, BoxNo2 = item.BoxNo2, BoxNo3 = item.BoxNo3, LotNo = allot.LotNo, LotText = allot.LotText, SupplierLot = allot.SupplierLot, SkuNo = allot.SkuNo, SkuName = allot.SkuName, Standard = allot.Standard, PalletNo = palletNo, CompleteQty = item.Qty, CreateUser = userId }; comList.Add(completeDetail); if (palletNo != palletNoNew) { item.StockDetailId = sdId; item.BindNo = null;//托盘绑定号 item.PalletNo = palletNoNew; } item.Status = "5";//箱支状态,0:未组托 1:已组托 2:已入库 3:已出库 4:已分配 5:已拣货 //修改库存箱码明细 Db.Updateable(item).ExecuteCommand(); pickQty += item.Qty; } //添加拣货明细 Db.Insertable(comList).ExecuteCommand(); //修改出库分配信息 allot.CompleteQty += pickQty; allot.Status = allot.Qty == allot.CompleteQty ? "5" : "3"; allot.UpdateTime = DateTime.Now; Db.Updateable(allot).ExecuteCommand(); if (palletNo != palletNoNew) { //删除原托盘库存明细 Db.Deleteable(stockDetail).ExecuteCommand(); //改变原托盘状态为:未使用 var pallet = Db.Queryable().First(m => m.PalletNo == palletNo && m.IsDel == "0"); if (pallet == null) { throw new Exception("未在托盘表中查询到托盘信息"); } pallet.Status = "0"; Db.Updateable(pallet).ExecuteCommand(); } else { stockDetail.SONo = soNo; Db.Updateable(stockDetail).ExecuteCommand(); } //修改出库单明细拣货数量 noticeDetail.CompleteQty += pickQty; noticeDetail.Status = "2"; Db.Updateable(noticeDetail).ExecuteCommand(); var num = Db.Queryable() .Count(m => m.IsDel == "0" && m.SONo == soNo && m.CompleteQty < m.Qty); if (num <= 0) { notice.Status = "4"; //更改为执行完成 noticeDetail.Status = "3"; Db.Updateable(noticeDetail).ExecuteCommand(); } //修改出库单信息 Db.Updateable(notice).ExecuteCommand(); } else { var biaoShi = "0";//0:整箱拣货、1:散支拣货、2:数量拣货 List boxInfos; var boxInfo = Db.Queryable().Where(m => m.IsDel == "0" && m.BoxNo == boxNo && m.StockDetailId == stockDetail.Id); if (boxInfo.Count() == 0) { throw new Exception("未查询到该箱码及追溯码的信息"); } boxInfos = boxInfo.ToList(); var comDetailList = Db.Queryable().Where(m => m.IsDel == "0" && m.ExportAllotId == allot.Id && m.PalletNo == palletNo).ToList(); if (!string.IsNullOrWhiteSpace(boxNo3)) //散支拣货 { boxInfos = boxInfos.Where(m => m.BoxNo3 == boxNo3).ToList(); if (boxInfos.Count() == 0) { throw new Exception("未查询到该箱码及追溯码的信息"); } if (boxInfos.Count() > 1) { throw new Exception("该追溯支码的信息大于1条,信息错误,请核实!"); } if (boxInfos.Any(m => m.PalletNo != palletNo)) { throw new Exception("该托盘与箱码没有绑定关系"); } var boxQty = boxInfos.First().Qty; if (boxQty > needQty) { throw new Exception("拣货数量不能大于剩余待拣数量"); } foreach (var item in boxInfos) { if (biaoShi != "2" && comDetailList.Any(m => m.BoxNo3 == item.BoxNo3)) { throw new Exception($"当前{item.BoxNo}中{item.BoxNo3}已拣货完成,请勿重复拣货"); } } biaoShi = "1"; } else if (!string.IsNullOrEmpty(pickQty1) && decimal.Parse(pickQty1) > 0)//数量拣货 { if (boxInfo.Count() > 1) { throw new Exception("该箱码内存在支码不能进行数量拣货"); } decimal boxQty = boxInfo.First().Qty; if (decimal.Parse(pickQty1) > boxQty) { throw new Exception("拣货数量不能大于箱内数量"); } if (decimal.Parse(pickQty1) > needQty) { throw new Exception("拣货数量不能大于剩余待拣数量"); } biaoShi = "2"; } else //整箱拣货 { if (boxInfo.Count() == 0) { throw new Exception("未查询到该箱码的信息"); } if (boxInfo.Any(m => m.PalletNo != palletNo)) { throw new Exception("该托盘与箱码没有绑定关系"); } var boxQty = boxInfo.GroupBy(m => m.BoxNo).Select(m => SqlFunc.AggregateSum(m.Qty)).ToList(); if (boxQty[0] > needQty) { throw new Exception("拣货数量不能大于箱内剩余待拣数量"); } foreach (var item in boxInfos) { if (biaoShi != "2" && comDetailList.Any(m => m.BoxNo == item.BoxNo)) { throw new Exception($"当前{item.BoxNo}已拣货完成,请勿重复拣货"); } } } var comList = new List(); foreach (var item in boxInfos) { //添加拣货明细 var completeDetail = new BllCompleteDetail() { SONo = soNo, SODetailNo = int.Parse(soDetailId), ExportAllotId = allot.Id, StockId = allot.StockId, BoxNo = item.BoxNo, BoxNo2 = item.BoxNo2, BoxNo3 = item.BoxNo3, LotNo = allot.LotNo, LotText = allot.LotText, SupplierLot = allot.SupplierLot, SkuNo = allot.SkuNo, SkuName = allot.SkuName, Standard = allot.Standard, PalletNo = palletNo, CompleteQty = biaoShi == "2" ? decimal.Parse(pickQty1) : item.Qty, CreateUser = userId }; comList.Add(completeDetail); if (biaoShi == "0")//整箱拣货 { //修改库存箱码明细 item.StockDetailId = sdId; item.BindNo = null;//托盘绑定号 item.PalletNo = palletNoNew; item.Status = "5";//箱支状态,0:未组托 1:已组托 2:已入库 3:已出库 4:已分配 5:已拣货 Db.Updateable(item).ExecuteCommand(); pickQty += item.Qty; } else if (biaoShi == "1")//散支拣货 { //修改库存箱码明细 item.StockDetailId = sdId; item.BindNo = null;//托盘绑定号 item.PalletNo = palletNoNew; item.BoxNo = item.BoxNo3;//将支码赋给箱码 item.BitBoxMark = "1";//零箱标记 item.Status = "5";//箱支状态,0:未组托 1:已组托 2:已入库 3:已出库 4:已分配 5:已拣货 Db.Updateable(item).ExecuteCommand(); pickQty += item.Qty; } else//数量拣货 { var boxInfo2 = Db.Queryable().First(m => m.IsDel == "0" && m.BoxNo == boxNo && m.StockDetailId == sdId); if (decimal.Parse(pickQty1) == item.Qty) { //修改库存箱码明细 item.StockDetailId = sdId; item.BindNo = null;//托盘绑定号 item.PalletNo = palletNoNew; item.Status = "5";//箱支状态,0:未组托 1:已组托 2:已入库 3:已出库 4:已分配 5:已拣货 Db.Updateable(item).ExecuteCommand(); } else { if (boxInfo2 == null) { var dataBoxInfo = new DataBoxInfo() { StockDetailId = sdId, BindNo = item.BindNo, BoxNo = item.BoxNo, BoxNo2 = item.BoxNo2, BoxNo3 = item.BoxNo3, PalletNo = item.PalletNo, PalletNo2 = item.PalletNo2, PalletNo3 = item.PalletNo3, Qty = decimal.Parse(pickQty1), FullQty = item.FullQty, Status = "5", LotNo = item.LotNo, LotText = item.LotText, SkuNo = item.SkuNo, SkuName = item.SkuName, Standard = item.Standard, ProductionTime = item.ProductionTime, SupplierLot = item.SupplierLot, InspectMark = item.InspectMark, BitBoxMark = "1", InspectStatus = item.InspectStatus, InspectTime = item.InspectTime, }; Db.Insertable(dataBoxInfo).ExecuteCommand(); } else { boxInfo2.Qty += decimal.Parse(pickQty1); item.BitBoxMark = boxInfo2.Qty>= boxInfo2.FullQty? "0":"1" ;//零箱标识 Db.Updateable(boxInfo2).ExecuteCommand(); } item.Qty -= decimal.Parse(pickQty1); item.BitBoxMark = "1";//零箱标识 if (item.Qty<=0) { Db.Deleteable(item).ExecuteCommand(); } else { Db.Updateable(item).ExecuteCommand(); } } pickQty += decimal.Parse(pickQty1); } } //改变库内箱码是否零箱信息 if (biaoShi == "1") { var boxSurplusList = boxInfo.Where(m => m.BoxNo3 != boxNo3).ToList(); foreach (var item in boxSurplusList) { item.BitBoxMark = "1"; Db.Updateable(item).ExecuteCommand(); } } Db.Insertable(comList).ExecuteCommand(); //修改出库分配信息 allot.CompleteQty += pickQty; allot.Status = allot.Qty == allot.CompleteQty ? "5" : "3"; allot.UpdateTime = DateTime.Now; if (allot.Status == "5") { //判断该托盘是否还存在物料 存在改为待回库 待回库完成后改为已完成 } Db.Updateable(allot).ExecuteCommand(); //删除或修改库存明细 stockDetail.BitPalletMark = "1";//修改为零托标识 stockDetail.Qty -= pickQty; stockDetail.LockQty -= pickQty; if (stockDetail.Qty == stockDetail.LockQty) { stockDetail.Status = "2"; } else if (stockDetail.Qty > stockDetail.LockQty && stockDetail.LockQty > 0) { stockDetail.Status = "1"; } else { stockDetail.Status = "0"; } if (stockDetail.Qty <= 0) { Db.Deleteable(stockDetail).ExecuteCommand(); } else { Db.Updateable(stockDetail).ExecuteCommand(); } var num2 = Db.Queryable().Count(m => m.IsDel == "0" && m.PalletNo == palletNo); if (num2 <= 0) { //改变托盘状态 var pallet = Db.Queryable().First(m => m.PalletNo == palletNo && m.IsDel == "0"); if (pallet == null) { throw new Exception("未在托盘表中查询到托盘信息"); } pallet.Status = "0"; Db.Updateable(pallet).ExecuteCommand(); } //修改出库单明细拣货数量 noticeDetail.CompleteQty += pickQty; noticeDetail.Status = "2"; Db.Updateable(noticeDetail).ExecuteCommand(); var num = Db.Queryable() .Count(m => m.IsDel == "0" && m.SONo == soNo && m.CompleteQty < m.Qty); if (num <= 0) { notice.Status = "4"; //更改为执行完成 noticeDetail.Status = "3"; Db.Updateable(noticeDetail).ExecuteCommand(); } //修改出库单信息 Db.Updateable(notice).ExecuteCommand(); } if (isNew) { var sd2 = Db.Queryable().First(m=>m.Id == sdId); sd2.Qty = pickQty; sd2.LockQty = pickQty; Db.Updateable(sd2).ExecuteCommand(); } else { if (palletNo != palletNoNew) { //修改拼托托盘库存明细 pinStockDetail.Qty += pickQty; pinStockDetail.LockQty += pickQty; Db.Updateable(pinStockDetail).ExecuteCommand(); } } //添加操作日志记录 var k = new OperationSOServer().AddLogOperationSo("PDA模块", "拣货拼托", soNo, "拣货", $"在PDA上对出库单号为:{soNo}的原托盘码为:{palletNo},新托盘码为:{palletNoNew}的拣货拼托操作", userId); Db.CommitTran(); } catch (Exception e) { Db.RollbackTran(); throw new Exception(e.Message); } } /// /// 拼托出库pda拣货-数量 /// /// /// /// /// /// /// public void SoSetQtyPinPick(string soNo, string soDetailId, string palletNo, string PickQty, string palletNoNew, int userId) { Db.BeginTran(); try { var nowDate = DateTime.Now;//当前时间 #region 判断 if (string.IsNullOrWhiteSpace(soNo)) { throw new Exception("出库单据不能为空"); } //if (string.IsNullOrWhiteSpace(soDetailId)) //{ // throw new Exception("出库物料-批次不能为空"); //} if (string.IsNullOrWhiteSpace(palletNo)) { throw new Exception("托盘码不能为空"); } if (string.IsNullOrWhiteSpace(palletNoNew)) { throw new Exception("新托盘码不能为空"); } //出库单 var notice = Db.Queryable().First(m => m.IsDel == "0" && m.SONo == soNo); if (notice == null) { throw new Exception("未查询到该出库单的信息"); } if (notice.Status != "3") { throw new Exception("出库单的状态不是正在执行,不能拣货"); } //出库单明细 var noticeDetail = Db.Queryable() .First(m => m.IsDel == "0" && m.Id == int.Parse(soDetailId)); if (noticeDetail == null) { throw new Exception("未查询到该出库单明细的信息"); } //出库分配信息 var allot = Db.Queryable().First(m => m.IsDel == "0" && (m.Status == "2" || m.Status == "3") && m.SONo == soNo && m.SODetailNo == int.Parse(soDetailId) && m.PalletNo == palletNo); if (allot == null) { throw new Exception("未查询到该托盘的分配信息"); } //剩余拣货数量(待拣减去已拣) var needQty = allot.Qty - allot.CompleteQty; if (decimal.Parse(PickQty) > needQty) { throw new Exception("拣货数量不能大于托内剩余待拣数量"); } //库存明细 var stockDetail = Db.Queryable().First(m => m.IsDel == "0" && m.Id == allot.StockId); if (stockDetail == null) { throw new Exception("未查询到该托盘分配的库存明细信息!"); } //库存总表 var stock = Db.Queryable().First(a => a.IsDel == "0" && a.SkuNo == stockDetail.SkuNo && a.LotNo == stockDetail.LotNo); if (stock == null) { throw new Exception("未查询到该托盘分配的库存信息!"); } if (palletNo == palletNoNew)//原托盘与新托盘一致 { if (decimal.Parse(PickQty) != stockDetail.Qty) { throw new Exception("原托盘与新托盘一致,需要把托盘上所有数量拣货"); } } #endregion #region 拼托信息 bool isNew = false; var pinStockDetail = Db.Queryable().First(m => m.IsDel == "0" && m.PalletNo == palletNoNew); if (pinStockDetail != null) { if (palletNo != palletNoNew)//非整托拣货 { if (pinStockDetail.SONo != notice.SONo) { throw new Exception("拼托托盘上只能放同一个出库单下的物料!"); } if (pinStockDetail.SkuName != stockDetail.SkuName || pinStockDetail.LotNo != stockDetail.LotNo) { isNew = true; } } } else { isNew = true; var newPalletInfo = Db.Queryable().First(m => m.IsDel == "0" && m.PalletNo == palletNoNew && m.Status == "0"); if (newPalletInfo == null) { throw new Exception("新托盘信息不存在或已被使用!"); } //修改新托盘状态 newPalletInfo.Status = "1"; Db.Updateable(newPalletInfo).ExecuteCommand(); } if (isNew) { var sd = new DataStockDetail(); sd.LotNo = stockDetail.LotNo; sd.LotText = stockDetail.LotText; sd.SupplierLot = stockDetail.SupplierLot; sd.SkuNo = stockDetail.SkuNo; sd.SkuName = stockDetail.SkuName; sd.Standard = stockDetail.Standard; sd.Qty = decimal.Parse(PickQty); sd.LockQty = decimal.Parse(PickQty); sd.FrozenQty = 0; sd.InspectQty = 0; sd.ASNNo = ""; sd.ASNDetailNo = null; sd.SONo = soNo;//出库单号 sd.WareHouseNo = ""; sd.RoadwayNo = ""; sd.AreaNo = ""; sd.LocatNo = ""; sd.PalletNo = palletNoNew; sd.PalletNo2 = ""; sd.PalletNo3 = ""; //PalletType = item.PalletType, sd.CompleteTime = nowDate; sd.ProductionTime = stockDetail.ProductionTime; sd.ExpirationTime = stockDetail.ExpirationTime; sd.Status = "2";//状态,已分配 sd.InspectMark = stockDetail.InspectMark; sd.InspectStatus = stockDetail.InspectStatus; sd.BitPalletMark = "0"; sd.PackagNo = noticeDetail.PackagNo; sd.IsBale = stockDetail.IsBale; sd.IsBelt = stockDetail.IsBelt; sd.Demo = stockDetail.Demo; sd.OwnerName = stockDetail.OwnerName; sd.OwnerNo = stockDetail.OwnerNo; sd.SupplierName = stockDetail.SupplierName; sd.SupplierNo = stockDetail.SupplierNo; sd.IsDel = "0"; sd.CreateUser = userId; sd.CreateTime = nowDate; //新增拼托库存明细信息 Db.Insertable(sd).ExecuteReturnIdentity(); } else { if (palletNo != palletNoNew) { //修改拼托托盘库存明细 pinStockDetail.Qty += decimal.Parse(PickQty); pinStockDetail.LockQty += decimal.Parse(PickQty); Db.Updateable(pinStockDetail).ExecuteCommand(); } else { pinStockDetail.SONo = soNo; Db.Updateable(pinStockDetail).ExecuteCommand(); } } #endregion //获取当前托盘拣货明细 var complete = Db.Queryable().First(a => a.IsDel == "0" && a.PalletNo == palletNo && a.SONo == notice.SONo && a.SODetailNo == noticeDetail.Id && a.ExportAllotId == allot.Id && a.StockId == stockDetail.Id); //判读是否存在拣货明细 int isComplete = 0; if (complete != null) { isComplete = 1; } var comList = new List(); //判断是否存在拣货明细 isComplete = 0;//所有无箱码或一级箱码拣货时,拣货明细应重新插入数据(体现多次拣货流程记录) if (isComplete == 0) { //添加拣货明细 var completeDetail = new BllCompleteDetail() { SONo = soNo, SODetailNo = int.Parse(soDetailId), ExportAllotId = allot.Id, StockId = allot.StockId, BoxNo = "", BoxNo2 = "", BoxNo3 = "", LotNo = allot.LotNo, LotText = allot.LotText, SupplierLot = allot.SupplierLot, SkuNo = allot.SkuNo, SkuName = allot.SkuName, Standard = allot.Standard, PalletNo = palletNo, CompleteQty = decimal.Parse(PickQty), CreateUser = userId, CreateTime = Db.GetDate(), }; comList.Add(completeDetail); //添加拣货明细 Db.Insertable(comList).ExecuteCommand(); } else if (isComplete == 1) { complete.CompleteQty += decimal.Parse(PickQty); complete.UpdateUser = userId; complete.UpdateTime = Db.GetDate(); Db.Updateable(complete).ExecuteCommand(); } //修改出库分配信息 allot.CompleteQty += decimal.Parse(PickQty); allot.Status = allot.Qty == allot.CompleteQty ? "5" : "3"; allot.UpdateTime = DateTime.Now; Db.Updateable(allot).ExecuteCommand(); int isDel = 0; if (palletNo != palletNoNew) { //删除或修改库存明细 stockDetail.BitPalletMark = "1";//修改为零托标识 stockDetail.Qty -= decimal.Parse(PickQty); stockDetail.LockQty -= decimal.Parse(PickQty); if (stockDetail.Qty == stockDetail.LockQty) { stockDetail.Status = "2"; } else if (stockDetail.Qty > stockDetail.LockQty && stockDetail.LockQty > 0) { stockDetail.Status = "1"; } else { stockDetail.Status = "0"; } if (stockDetail.Qty <= 0) { Db.Deleteable(stockDetail).ExecuteCommand(); } else { isDel = 1; Db.Updateable(stockDetail).ExecuteCommand(); } } else { isDel = 1; } //判断托盘上物料是否拣货完毕 if (isDel == 0) { //改变托盘状态为:未使用 var pallet = Db.Queryable().First(m => m.PalletNo == palletNo && m.IsDel == "0"); if (pallet == null) { throw new Exception("未在托盘表中查询到托盘信息"); } pallet.Status = "0"; Db.Updateable(pallet).ExecuteCommand(); } //修改出库单明细拣货数量 noticeDetail.CompleteQty += decimal.Parse(PickQty); noticeDetail.Status = "2"; Db.Updateable(noticeDetail).ExecuteCommand(); var num = Db.Queryable() .Count(m => m.IsDel == "0" && m.SONo == soNo && m.CompleteQty < m.Qty); if (num <= 0) { notice.Status = "4"; //更改为执行完成 noticeDetail.Status = "3"; Db.Updateable(noticeDetail).ExecuteCommand(); } //修改出库单信息 Db.Updateable(notice).ExecuteCommand(); //添加操作日志记录 var k = new OperationSOServer().AddLogOperationSo("PDA模块", "拣货拼托", soNo, "拣货", $"在PDA上对出库单号为:{soNo}的托盘码为:{palletNo},新托盘码为:{palletNoNew}的拣货操作", userId); Db.CommitTran(); } catch (Exception e) { Db.RollbackTran(); throw new Exception(e.Message); } } #endregion } }