using System; using System.Collections.Generic; using System.Linq; using System.Security.Cryptography.X509Certificates; using System.Text; using System.Threading.Tasks; using Dm; using Model.ModelDto.BllCheckDto; using Model.ModelDto.PdaDto; using SqlSugar; using Utility; using WMS.BLL.LogServer; using WMS.DAL; using WMS.Entity.BllAsnEntity; using WMS.Entity.BllCheckEntity; using WMS.Entity.BllSoEntity; using WMS.Entity.Context; using WMS.Entity.DataEntity; using WMS.Entity.LogEntity; using WMS.Entity.SysEntity; using WMS.IBLL.IPdaServer; namespace WMS.BLL.BllPdaServer { public class PdaCrServer : IPdaCrServer { private static readonly SqlSugarScope Db = DataContext.Db; #region 盘点 //获取盘库单正在执行单号 public async Task> GetStockCheckNoList(string palletNo) { List list; if (!string.IsNullOrWhiteSpace(palletNo)) { list = await Db.Queryable().Where(m => m.IsDel == "0" && m.PalletNo == palletNo && m.Status == 2).Select(m => m.CRNo).Distinct().ToListAsync(); } else { list = await Db.Queryable().Where(m => m.IsDel == "0" && m.Status == 1).Select(m => m.CRNo) .Distinct().ToListAsync(); } return list; } //获取盘点明细物料批次信息 public async Task> GetStockCheckDetailList(string crNo, string palletNo) { if (string.IsNullOrWhiteSpace(crNo)) { throw Oops.Bah("盘点单据不能为空"); } var list = Db.Queryable().Where(m => m.IsDel == "0" && m.CRNo == crNo); if (!string.IsNullOrWhiteSpace(palletNo)) { list = list.Where(m => m.PalletNo == palletNo); } var data = await list.GroupBy(m => new { m.SkuNo, m.SkuName, m.LotNo }).Select(m => new StockCheckDetailDto() { SkuNo = m.SkuNo, SkuName = m.SkuName, LotNo = m.LotNo }).ToListAsync(); return data; } //获取要盘点的箱码信息(盘点记录中数据) public async Task> GetStockCheckLogList(string crNo, string crDetail, string palletNo, string boxNo, string isContinue) { if (string.IsNullOrWhiteSpace(crNo)) { throw Oops.Bah("盘点单据不能为空"); } if (string.IsNullOrWhiteSpace(crDetail)) { throw Oops.Bah("物料批次不能为空"); } if (string.IsNullOrWhiteSpace(palletNo)) { throw Oops.Bah("托盘码不能为空"); } var detail = crDetail.Split("-"); var sku = detail[0]; //判断是否为无码物料 var skuinfo = await Db.Queryable().FirstAsync(m => m.IsDel == "0" && m.SkuNo == sku); //判断是否存在物料消息 if (skuinfo == null) { throw Oops.Bah("托盘码不能为空"); } int isQtySku = 0; if (skuinfo.Type == "4" && isContinue == "1") { isQtySku = 1; } var lotNo = detail[1]; var list = Db.Queryable().Where(m => m.IsDel == "0" && m.CRNo == crNo); //var deList= Db.Queryable().Where(m => m.IsDel == "0" && m.SkuNo == sku && m.LotNo == lotNo && m.PalletNo == palletNo); //if (deList.Count() == 0) //{ // throw new Exception("未查询到托盘上的盘点物料批次信息"); //} list = list.Where(m => m.SkuNo == sku && m.LotNo == lotNo && m.PalletNo == palletNo); if (!string.IsNullOrWhiteSpace(boxNo)) { list = list.Where(m => m.BoxNo == boxNo); } List data = new List(); //判断是否为无码物料 if (isQtySku == 1) { //获取库存信息 var stockDetail = Db.Queryable().First(a => a.IsDel == "0" && a.Status == "3" && a.SkuNo == sku && a.PalletNo == palletNo); var model = new StockCheckLogDto() { PalletNo = palletNo, SkuNo = sku, Qty = stockDetail.Qty, CheckResult = 4, }; data.Add(model); } else { data = await list.Select(m => new StockCheckLogDto() { BoxNo = m.BoxNo, BoxNo3 = m.BoxNo3, SkuNo = m.SkuNo, SkuName = m.SkuName, LotNo = m.LotNo, Qty = m.Qty, CheckResult = m.CheckResult, }).ToListAsync(); } return data; } public async Task CrSetCheck(string crNo, string crDetail, string palletNo, string boxNo, string boxNo3, string result, decimal? qty, string isContinue, int userId) { if (string.IsNullOrWhiteSpace(crNo)) { throw Oops.Bah("盘点单据不能为空"); } if (string.IsNullOrWhiteSpace(crDetail)) { throw Oops.Bah("物料批次不能为空"); } if (string.IsNullOrWhiteSpace(palletNo)) { throw Oops.Bah("托盘码不能为空"); } //箱码为空 是整托要盘点的都正常 var detail = crDetail.Split("-"); var sku = detail[0]; var lotNo = detail[1]; //盘点明细 var checkDetail = await Db.Queryable().FirstAsync(m => m.IsDel == "0" && m.CRNo == crNo && m.PalletNo == palletNo && m.SkuNo == sku && m.LotNo == lotNo); if (checkDetail == null) { throw Oops.Bah("未查询到未盘点的盘点明细信息"); } var modSku = await Db.Queryable().Where(s => s.SkuNo == sku).FirstAsync(); if (modSku.IsPasteCode == "1" && isContinue == "1") { throw Oops.Bah("贴标物料不允许数量盘点"); } else if (modSku.IsPasteCode == "0" && isContinue == "0") { throw Oops.Bah("不贴标物料请使用数量盘点"); } //盘点记录 var checkLog = Db.Queryable().Where(m => m.IsDel == "0" && m.CRNo == crNo && m.PalletNo == palletNo && m.SkuNo == sku && m.LotNo == lotNo && m.CheckResult == null); var time = DateTime.Now; //正常 if (result == "0") { if (!string.IsNullOrWhiteSpace(boxNo)) { checkLog = checkLog.Where(m => m.BoxNo == boxNo); } if (!string.IsNullOrWhiteSpace(boxNo3)) { checkLog = checkLog.Where(m => m.BoxNo3 == boxNo3); } if (await checkLog.CountAsync() == 0 && isContinue == "0") { throw Oops.Bah("未查询到未盘点的箱支信息"); } var list = await checkLog.ToListAsync(); var num = 0; foreach (var l in list) { if (l.CheckResult != null) { continue; } l.RealQty = l.Qty; l.CheckResult = 0; l.CheckDate = time; l.CheckUserId = userId; num += Convert.ToInt32(l.Qty); } if (checkDetail.RealQty == null) { checkDetail.RealQty = 0; } checkDetail.RealQty += num; checkDetail.CheckResult = 0; //if (checkDetail.CheckResult == null || checkDetail.CheckResult == 0) //{ // checkDetail.CheckResult = 0; //} await Db.Updateable(checkDetail).ExecuteCommandAsync(); await Db.Updateable(list).ExecuteCommandAsync(); } //盘亏 else if (result == "1") { if (!string.IsNullOrWhiteSpace(boxNo)) { checkLog = checkLog.Where(m => m.BoxNo == boxNo); } if (!string.IsNullOrWhiteSpace(boxNo3)) { checkLog = checkLog.Where(m => m.BoxNo3 == boxNo3); } if (checkLog.Count() == 0 && isContinue == "0") { throw Oops.Bah("未查询到箱支信息"); } // if (isContinue == "1") { if (qty == null || qty <= 0) { throw Oops.Bah("数量盘点时、盘亏数量不能为空且需大于0"); } } var list = checkLog.ToList(); var num = 0; foreach (var l in list) { l.RealQty = 0; l.CheckResult = 1; l.CheckDate = time; l.CheckUserId = userId; num -= Convert.ToInt32(l.RealQty); } if (checkDetail.RealQty == null) { checkDetail.RealQty = 0; } checkDetail.RealQty += num; if (isContinue == "1") { checkDetail.RealQty = qty; } checkDetail.CheckResult = 1; var checkInfo = await Db.Queryable().FirstAsync(m => m.IsDel == "0" && m.CRNo == crNo && m.PalletNo == palletNo && m.SkuNo == sku && m.LotNo == lotNo); checkInfo.RealQty = qty; checkInfo.CheckResult = 1; checkInfo.CheckUserId = userId; checkInfo.CheckDate = time; checkInfo.UpdateUser = userId; checkInfo.UpdateTime = time; await Db.Updateable(checkInfo).ExecuteCommandAsync(); await Db.Updateable(checkDetail).ExecuteCommandAsync(); await Db.Updateable(list).ExecuteCommandAsync(); } //盘盈 else if (result == "2") { if (isContinue == "0") { if (string.IsNullOrWhiteSpace(boxNo) || string.IsNullOrWhiteSpace(boxNo3)) { throw Oops.Bah("盘盈时箱码与支码不能为空"); } } if (qty == null || qty <= 0) { throw Oops.Bah("盘盈时数量不能为空且需大于0"); } if (isContinue == "0") { var count = await Db.Queryable() .CountAsync(m => m.IsDel == "0" && m.BoxNo == boxNo && m.BoxNo3 == boxNo3); var count2 = await Db.Queryable() .CountAsync(m => m.IsDel == "0" && m.BoxNo == boxNo && m.BoxNo3 == boxNo3); if (count > 0 || count2 > 0) { throw Oops.Bah("当前库存中已存在该箱支信息"); } } BllStockCheckLog crLog = new BllStockCheckLog(); if (isContinue == "0") { crLog = new BllStockCheckLog() { CRNo = crNo, PalletNo = palletNo, BoxNo = boxNo, BoxNo2 = null, BoxNo3 = boxNo3, Qty = qty, SkuNo = checkDetail.SkuNo, SkuName = checkDetail.SkuName, Standard = checkDetail.Standard, LotNo = checkDetail.LotNo, LotText = checkDetail.LotText, SupplierLot = checkDetail.SupplierLot, RealQty = qty, CheckResult = 2, CheckDate = time, CheckUserId = userId, CreateUser = userId, CreateTime = time }; } else { var checkInfo = await Db.Queryable().FirstAsync(m => m.IsDel == "0" && m.CRNo == crNo && m.PalletNo == palletNo && m.SkuNo == sku && m.LotNo == lotNo); checkInfo.RealQty = qty; checkInfo.CheckResult = 2; checkInfo.CheckUserId = userId; checkInfo.CheckDate = time; checkInfo.UpdateUser = userId; checkInfo.UpdateTime = time; await Db.Updateable(checkInfo).ExecuteCommandAsync(); } if (checkDetail.RealQty == null && isContinue == "0") { checkDetail.RealQty = 0; } checkDetail.RealQty += qty; if (isContinue == "1") { checkDetail.RealQty = qty; } checkDetail.CheckResult = 2; await Db.Updateable(checkDetail).ExecuteCommandAsync(); if (isContinue == "0") { await Db.Insertable(crLog).ExecuteCommandAsync(); } } else { throw Oops.Bah("盘点结果不符,请核实!"); } var checkLogNum = Db.Queryable().Where(m => m.IsDel == "0" && m.CRNo == crNo && m.PalletNo == palletNo && m.SkuNo == sku && m.LotNo == lotNo); if (await checkLogNum.CountAsync(m => m.CheckResult == null) == 0) { var checkDe = await Db.Queryable().FirstAsync(m => m.IsDel == "0" && m.CRNo == crNo && m.PalletNo == palletNo && m.SkuNo == sku && m.LotNo == lotNo); checkDe.Status = 3; await Db.Updateable(checkDe).ExecuteCommandAsync(); var checkDeNum = await Db.Queryable().CountAsync(m => m.IsDel == "0" && m.CRNo == crNo && m.Status != 3 && m.Id != checkDe.Id); if (checkDeNum == 0) { var check = await Db.Queryable().FirstAsync(m => m.CRNo == crNo && m.IsDel == "0"); check.Status = 2; check.CompleteDate = DateTime.Now; await Db.Updateable(check).ExecuteCommandAsync(); } } } #endregion #region 库存查询 /// /// pda库存查询 /// /// 储位编号 /// 托盘号 /// public async Task> GetStockQueryList(string locatNo, string palletNo) { return await Db.Queryable() .Where(s => s.IsDel == "0" && s.LocatNo.Contains(locatNo) && s.PalletNo.Contains(palletNo)) .OrderBy(s => new { s.LotNo, s.LocatNo, s.PalletNo }) .ToListAsync(); } #endregion #region 托盘变更(托盘解绑绑定) //根据托盘号获取箱码和箱内数量 public async Task> GetDataDetailList(string palletNo) { if (string.IsNullOrWhiteSpace(palletNo)) { throw Oops.Bah("托盘号不能为空"); } var detail = await Db.Queryable().Where(m => m.IsDel == "0" && m.PalletNo == palletNo).Select(m => m.Id).ToListAsync(); var info = await Db.Queryable().Where(m => m.IsDel == "0" && detail.Contains(m.StockDetailId)) .GroupBy(m => m.BoxNo).Select(a => new PdaPalletNoCheckDto { BoxNo = a.BoxNo, Qty = SqlFunc.AggregateSum(a.Qty) }).ToListAsync(); return info; } //根据箱码获取物料、批次、数量等信息 public async Task GetBoxInfoByBox(string boxNo) { if (string.IsNullOrWhiteSpace(boxNo)) { throw Oops.Bah("箱码不能为空"); } var info = await Db.Queryable().Where(m => m.IsDel == "0" && m.BoxNo == boxNo) .GroupBy(m => new { m.BoxNo, m.SkuNo, m.SkuName, m.LotNo }).Select(a => new PdaPalletNoCheckDto { BoxNo = a.BoxNo, SkuNo = a.SkuNo, SkuName = a.SkuName, LotNo = a.LotNo, Qty = SqlFunc.AggregateSum(a.Qty) }).ToListAsync(); if (info.Count > 1) { throw Oops.Bah("当前箱码查询出多条物料或批次信息,请核实"); } return info.FirstOrDefault(); } //解绑原托盘绑定新托盘 public async Task SaveUnbind(string palletNo, string boxNo, string palletNoNew, int userId) { if (string.IsNullOrWhiteSpace(palletNo) || string.IsNullOrWhiteSpace(palletNoNew)) { throw Oops.Bah("新旧托盘号不能为空"); } if (palletNo == palletNoNew) { throw Oops.Bah("新旧托盘号不能为相同"); } //库存箱支信息 var infos = Db.Queryable().Where(m => m.IsDel == "0" && m.PalletNo == palletNo);//整托变更 if (!string.IsNullOrWhiteSpace(boxNo)) { //按箱变更 infos = infos.Where(m => m.IsDel == "0" && m.BoxNo == boxNo); } List infosList = await infos.ToListAsync(); if (infosList.Count <= 0) { throw Oops.Bah("原托盘上未查到箱支明细,请核实"); } //库存明细id var infoIds = await infos.GroupBy(m => m.StockDetailId).Select(a => a.StockDetailId).ToListAsync(); if (infoIds.Count == 0) { throw Oops.Bah("未查询到当前箱码信息,请核实"); } var comTime = DateTime.Now; //新托盘库存明细 bool newPalletHaveGoods = false;//新托盘上是否有物品 string pallWareHouseNo = string.Empty;//新托盘所在的位置(库外/平库) var stockDetailList = await Db.Queryable().Where(m => m.IsDel == "0" && m.PalletNo == palletNoNew).ToListAsync(); if (stockDetailList != null && stockDetailList.Count() > 0) { newPalletHaveGoods = true; pallWareHouseNo = stockDetailList[0].WareHouseNo; if (!string.IsNullOrEmpty(stockDetailList[0].LocatNo)) { throw Oops.Bah("新托盘在立库内不允许变更,请核实"); } #region 验证是否允许立库同托盘不同物料入库或同托盘同物料不同批次入库 var box = await Db.Queryable().FirstAsync(m => m.IsDel == "0" && m.PalletNo == palletNoNew && m.BitBoxMark == "0"); if (box != null) { foreach (var item in infosList) { if (box.SkuNo != item.SkuNo || box.LotNo != item.LotNo) { var funSetting = await Db.Queryable().FirstAsync(a => a.IsDel == "0" && a.FunSetNo == "Fun045"); if (funSetting == null || funSetting.IsEnable == "OFF") { throw Oops.Bah($"不允许立库同托盘不同物料入库或同托盘不同批次入库!"); } } } } #endregion } if (!newPalletHaveGoods)//新托盘上没有物品 { var pallet = await Db.Queryable().FirstAsync(m => m.IsDel == "0" && m.PalletNo == palletNoNew); if (pallet == null) { throw Oops.Bah("未查询到新托盘号信息"); } if (pallet.Status == "0") { pallet.Status = "1";//将新托盘状态修改为已使用 await Db.Updateable(pallet).ExecuteCommandAsync(); } else { throw Oops.Bah("新托盘号状态不是未使用"); } } foreach (var infoIdItem in infoIds) { var infosList2 = infosList.Where(w => w.StockDetailId == infoIdItem).ToList(); //原托盘库存明细 var stockDetail1 = await Db.Queryable().FirstAsync(m => m.IsDel == "0" && m.PalletNo == palletNo && m.Id == infoIdItem); if (stockDetail1 == null) { throw Oops.Bah("未在原托盘上查询到箱码信息,请核实"); } if (!string.IsNullOrEmpty(stockDetail1.LocatNo)) { throw Oops.Bah("原托盘在立库内不允许变更,请核实"); } var stockDetail2 = stockDetailList.FirstOrDefault(w => w.SkuNo == stockDetail1.SkuNo && w.LotNo == stockDetail1.LotNo); var stId = 0; if (stockDetail2 == null) //添加-新托盘上没有同物料同批次物品 { //新托盘添加库存明细 var detail = new DataStockDetail() { LotNo = stockDetail1.LotNo, LotText = stockDetail1.LotText, SupplierLot = stockDetail1.SupplierLot, SkuNo = stockDetail1.SkuNo, SkuName = stockDetail1.SkuName, Standard = stockDetail1.Standard, Qty = infosList2.Sum(m => m.Qty), LockQty = 0, FrozenQty = 0, InspectQty = 0, ASNNo = stockDetail1.ASNNo, ASNDetailNo = stockDetail1.ASNDetailNo, WareHouseNo = pallWareHouseNo, RoadwayNo = "", AreaNo = "", LocatNo = stockDetail1.LocatNo, PalletNo = palletNoNew,//新托盘号 PalletNo2 = "", PalletNo3 = "", CompleteTime = comTime, ProductionTime = stockDetail1.ProductionTime, ExpirationTime = stockDetail1.ExpirationTime, Status = "0", InspectMark = stockDetail1.InspectMark, InspectStatus = stockDetail1.InspectStatus, BitPalletMark = stockDetail1.BitPalletMark, PackagNo = stockDetail1.PackagNo, IsBale = "0", IsBelt = "0", IsDel = "0", CreateUser = userId, CreateTime = DateTime.Now }; stId = await Db.Insertable(detail).ExecuteReturnIdentityAsync(); } else //修改-新托盘有物品 { stockDetail2.Qty += infosList2.Sum(m => m.Qty);//新托盘增加库存 await Db.Updateable(stockDetail2).ExecuteCommandAsync(); stId = stockDetail2.Id; } //修改库存 stockDetail1.Qty -= infosList2.Sum(m => m.Qty); stockDetail1.BitPalletMark = "1";//是否零托 0:否 1:是 if (stockDetail1.Qty == 0) { await Db.Deleteable(stockDetail1).ExecuteCommandAsync();//删除原托盘库存明细 //判原托盘还有没有货物 var stockDetail3 = await Db.Queryable().Where(m => m.IsDel == "0" && m.PalletNo == palletNo && m.Id != infoIds.First()).ToListAsync(); if (stockDetail3 == null || stockDetail3.Count <= 0) { var pallet = Db.Queryable().First(m => m.IsDel == "0" && m.PalletNo == palletNo); pallet.Status = "0";//原托盘没有货物后将状态修改为未使用 await Db.Updateable(pallet).ExecuteCommandAsync(); } } else { await Db.Updateable(stockDetail1).ExecuteCommandAsync();//修改原托盘库存明细 } foreach (var item in infosList2) { //修改库存箱码明细 item.StockDetailId = stId; item.BindNo = null; item.PalletNo = palletNoNew; await Db.Updateable(item).ExecuteCommandAsync(); } //添加托盘解绑绑定记录 var unBind = new BllPalletUnbind() { UpbindPalletNo = palletNo, BindPalletNo = palletNoNew, LotNo = stockDetail1.LotNo, LotText = stockDetail1.LotText, SupplierLot = stockDetail1.SupplierLot, SkuNo = stockDetail1.SkuNo, SkuName = stockDetail1.SkuName, Standard = stockDetail1.Standard, Qty = infosList2.Sum(m => m.Qty), PalletNo2 = stockDetail1.PalletNo2, PalletNo3 = stockDetail1.PalletNo3, BoxNo = boxNo, InspectNo = "", InspectStatus = stockDetail1.InspectStatus, IsDel = "0", CreateTime = comTime, CreateUser = userId }; await Db.Insertable(unBind).ExecuteCommandAsync(); } //添加操作日志 if (string.IsNullOrEmpty(boxNo)) { boxNo = "全部"; } new OperationCrServer().AddLogOperationCr("库内作业", "操作日志", boxNo, "编辑", $"托盘变更:原托盘码:{palletNo}上的箱码{boxNo}解绑,绑定到新托盘{palletNoNew}上", userId); } #endregion #region AGV转运 /// /// 获取托盘所在储位地址 /// /// /// public async Task GetPalletLocatNo(string palletNo) { var models = await Db.Queryable().FirstAsync(w => w.IsDel == "0" && w.PalletNo == palletNo); if (models == null) { throw Oops.Bah("托盘库存信息不存在,请检查!"); } if (string.IsNullOrEmpty(models.LocatNo)) { throw Oops.Bah("托盘储位信息不存在,请检查!"); } if (models.WareHouseNo != "W02") { throw Oops.Bah("该托盘未在平库内,请检查!"); } return models.LocatNo; } /// /// 获取托盘所在楼层所有区域 /// /// /// public async Task> GetStorageArea(string palletNo) { var storageArea = new List(); if (string.IsNullOrEmpty(palletNo)) { storageArea = await Db.Queryable().Where(w => w.IsDel == "0" && w.Status == "0" && w.WareHouseNo == "W02").OrderBy(o => o.AreaNo).ToListAsync(); } else { var models = await Db.Queryable().FirstAsync(w => w.IsDel == "0" && w.PalletNo == palletNo); if (models == null) { throw Oops.Bah("托盘库存信息不存在,请检查!"); } if (string.IsNullOrEmpty(models.LocatNo)) { throw Oops.Bah("托盘储位信息不存在,请检查!"); } if (models.WareHouseNo != "W02") { throw Oops.Bah("该托盘未在平库内,请检查!"); } var storageLocat = await Db.Queryable().FirstAsync(w => w.IsDel == "0" && w.LocatNo == models.LocatNo); if (storageLocat == null) { throw Oops.Bah("储位信息不存在,请检查!"); } if (storageLocat.AreaNo.Contains("B0")) { storageArea = await Db.Queryable().Where(w => w.IsDel == "0" && w.Status == "0" && w.AreaNo.Contains("B0") && w.WareHouseNo == "W02").OrderBy(o => o.AreaNo).ToListAsync(); } else { storageArea = await Db.Queryable().Where(w => w.IsDel == "0" && w.Status == "0" && w.AreaNo.Contains("B1") && w.WareHouseNo == "W02").OrderBy(o => o.AreaNo).ToListAsync(); } } return storageArea; } /// /// 获取已分配的出库单据 /// /// public async Task> GetRunSoNoticeList() { return await Db.Queryable().Where(m => m.IsDel == "0" && m.Status == "2").Select(m => m.SONo).Distinct().ToListAsync(); } /// /// 根据托盘号获取托盘上物料信息 /// /// /// public async Task> GetSkuInfoByPalletNo(string palletNo) { if (string.IsNullOrEmpty(palletNo)) { throw Oops.Bah("请扫描托盘条码!"); } return await Db.Queryable().Where(m => m.IsDel == "0" && m.PalletNo == palletNo).ToListAsync(); } /// /// 根据出库单号获取分配的托盘信息 /// /// /// public async Task> GetPalletNoListBySoNo(string soNo) { if (string.IsNullOrEmpty(soNo)) { throw Oops.Bah("请选择出库单号!"); } var palletNoList = await Db.Queryable().Where(m => m.IsDel == "0" && m.SONo == soNo).Select(m => m.PalletNo).Distinct().ToListAsync(); return palletNoList; } /// /// agv转运呼叫小车 /// /// /// /// public async Task AgvTransport(string palletNo, string areaNo, string ruku, int userId) { if (string.IsNullOrEmpty(palletNo)) { throw Oops.Bah("请扫描托盘条码!"); } if (string.IsNullOrEmpty(areaNo) && string.IsNullOrEmpty(ruku)) { throw Oops.Bah("请选择目标区域或入库口!"); } if (!string.IsNullOrEmpty(areaNo) && !string.IsNullOrEmpty(ruku)) { throw Oops.Bah("目标区域和入库口不能同时选择!"); } string EndLocat = string.Empty;//目标位置 var log = await Db.Queryable().FirstAsync(w => w.IsDel == "0" && w.PalletNo == palletNo && (w.Status == "0" || w.Status == "1")); if (log != null) { throw Oops.Bah("该托盘已有小车等待执行或正在执行的任务!"); } var stockDetail = await Db.Queryable().FirstAsync(w => w.IsDel == "0" && w.PalletNo == palletNo); if (stockDetail == null) { throw Oops.Bah("托盘上物料库存明细信息不存在,请检查!"); } if (!string.IsNullOrEmpty(areaNo)) { var storageArea = await Db.Queryable().FirstAsync(w => w.IsDel == "0" && w.AreaNo == areaNo); if (storageArea == null) { throw Oops.Bah("所选区域信息不存在,请检查!"); } EndLocat = await GetLocat(areaNo, stockDetail.SkuNo, stockDetail.LotNo, palletNo); } else { EndLocat = ruku; } var stock = await Db.Queryable().FirstAsync(w => w.IsDel == "0" && w.SkuNo == stockDetail.SkuNo && w.LotNo == stockDetail.LotNo); if (stock == null) { throw Oops.Bah("托盘上物料库存信息不存在,请检查!"); } if (string.IsNullOrEmpty(stockDetail.LocatNo)) { throw Oops.Bah("托盘储位信息不存在,请检查!"); } if (stockDetail.WareHouseNo != "W02") { throw Oops.Bah("该托盘未在平库内,请检查!"); } //起始储位信息 var storageLocat = await Db.Queryable().FirstAsync(w => w.IsDel == "0" && w.LocatNo == stockDetail.LocatNo); if (storageLocat == null) { throw Oops.Bah("储位信息不存在,请检查!"); } //目标储位信息 var storageLocatEnd = new SysStorageLocat(); if (!string.IsNullOrEmpty(areaNo)) { storageLocatEnd = await Db.Queryable().FirstAsync(w => w.IsDel == "0" && w.LocatNo == EndLocat && w.Flag == "0" && w.Status == "0"); if (storageLocatEnd == null) { throw Oops.Bah("目标储位信息不存在,请检查!"); } } //添加出库任务 var taskNo = new Common().GetMaxNo("TK"); var exTask = new LogTask { TaskNo = taskNo, Sender = "WMS", Receiver = "AGV", IsSuccess = 0, //是否下发成功 0失败 1成功 StartLocat = stockDetail.LocatNo,//起始位置 EndLocat = EndLocat,//目标位置 PalletNo = palletNo,//托盘码 Msg = string.Format("转运任务:{0}=>>{1}", stockDetail.LocatNo, EndLocat), 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 }; await Db.Insertable(exTask).ExecuteCommandAsync(); //修改库存明细信息 stockDetail.Status = "4";//移库锁定 stockDetail.LockQty = stockDetail.Qty;//锁定库存数量 await Db.Updateable(stockDetail).ExecuteCommandAsync(); //修改库存信息 stock.LockQty += (decimal)stockDetail.Qty; await Db.Updateable(stock).ExecuteCommandAsync(); //修改起始储位地址状态 storageLocat.Status = "5";//0:空储位 1:有物品 2:入库中 3:出库中 4:移入中 5:移出中 await Db.Updateable(storageLocat).ExecuteCommandAsync(); //修改目标储位地址状态 if (storageLocatEnd != null) { storageLocatEnd.Status = "4";//0:空储位 1:有物品 2:入库中 3:出库中 4:移入中 5:移出中 await Db.Updateable(storageLocatEnd).ExecuteCommandAsync(); } //添加操作日志记录 var k = new OperationCrServer().AddLogOperationCr("PDA模块", "AGV转运", palletNo, "移库", $"PDA呼叫小车对托盘号:{palletNo}发起转运", userId); #region 呼叫小车代码 #endregion } /// /// agv转运呼叫小车取货 /// /// /// /// /// public async Task AgvTransport2(string soNo, string palletNo, string areaNo, int userId) { if (string.IsNullOrEmpty(soNo)) { throw Oops.Bah("请选择出库单据!"); } if (string.IsNullOrEmpty(areaNo)) { throw Oops.Bah("请选择目标区域!"); } //出库单信息 var notice = await Db.Queryable().FirstAsync(w => w.IsDel == "0" && w.SONo == soNo); if (notice == null) { throw Oops.Bah("出库单据信息不存在,请检查!"); } //目标区域信息 var storageArea = await Db.Queryable().FirstAsync(w => w.IsDel == "0" && w.AreaNo == areaNo); if (storageArea == null) { throw Oops.Bah("所选区域信息不存在,请检查!"); } List stockDetailList = new List();//需要的托盘明细 if (!string.IsNullOrEmpty(palletNo))//单托盘叫货 { stockDetailList = await Db.Queryable().Where(w => w.IsDel == "0" && w.PalletNo == palletNo).ToListAsync(); } else//整个出库单叫货 { string sqlStr = $"select * from DataStockDetail where PalletNo in (select PalletNo from BllExportAllot where IsDel='0' and SONo='{soNo}')"; stockDetailList = Db.Ado.SqlQuery(sqlStr).ToList(); } if (stockDetailList.Count <= 0) { throw Oops.Bah("托盘明细不存在,请检查!"); } var log = Db.Queryable().Where(w => w.IsDel == "0" && (w.Status == "0" || w.Status == "1"));//任务表 var storageLocat = Db.Queryable().Where(w => w.IsDel == "0");//储位表 var stock = Db.Queryable().Where(w => w.IsDel == "0");//库存总表 string EndLocat = string.Empty;//目标位置 string hasLocatNoList = string.Empty;//已分配的储位 foreach (var item in stockDetailList) { //任务信息 var logInfo = await log.FirstAsync(w => w.PalletNo == item.PalletNo); if (logInfo != null) { throw Oops.Bah($"托盘号:{item.PalletNo}已有小车等待执行或正在执行的任务!"); } if (string.IsNullOrEmpty(item.LocatNo)) { throw Oops.Bah($"托盘号:{item.PalletNo}的储位信息不存在,请检查!"); } if (item.WareHouseNo != "W02") { throw Oops.Bah($"托盘号:{item.PalletNo}未在平库内,请检查!"); } //起始储位信息 var storageLocatBegin = await storageLocat.FirstAsync(w => w.LocatNo == item.LocatNo); if (storageLocat == null) { throw Oops.Bah($"托盘号:{item.PalletNo}所在的储位信息不存在,请检查!"); } //获取目标储位 EndLocat = await GetLocat(areaNo, item.SkuNo, item.LotNo, palletNo); if (string.IsNullOrEmpty(EndLocat)) { throw Oops.Bah("分配目标储位失败,请检查!"); } if (string.IsNullOrEmpty(hasLocatNoList)) { hasLocatNoList = EndLocat; } else { hasLocatNoList = hasLocatNoList + "," + EndLocat; } //目标储位信息 var storageLocatEnd = storageLocat.First(w => w.LocatNo == EndLocat && w.Flag == "0" && w.Status == "0"); if (storageLocatEnd == null) { throw Oops.Bah("目标储位信息不存在,请检查!"); } //添加出库任务 var taskNo = new Common().GetMaxNo("TK"); var exTask = new LogTask { TaskNo = taskNo, Sender = "WMS", Receiver = "AGV", IsSuccess = 0, //是否下发成功 0失败 1成功 Msg = string.Format("转运任务:{0}=>>{1}", item.LocatNo, EndLocat), StartLocat = item.LocatNo,//起始位置 EndLocat = EndLocat,//目标位置 PalletNo = palletNo,//托盘码 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 }; await Db.Insertable(exTask).ExecuteCommandAsync(); //修改库存明细信息 item.Status = "4";//移库锁定 item.LockQty = item.Qty;//锁定库存数量 await Db.Updateable(item).ExecuteCommandAsync(); //修改起始储位地址状态 storageLocatBegin.Status = "5";//0:空储位 1:有物品 2:入库中 3:出库中 4:移入中 5:移出中 await Db.Updateable(storageLocatBegin).ExecuteCommandAsync(); //修改目标储位地址状态 storageLocatEnd.Status = "4";//0:空储位 1:有物品 2:入库中 3:出库中 4:移入中 5:移出中 await Db.Updateable(storageLocatEnd).ExecuteCommandAsync(); var stockInfo = await stock.FirstAsync(w => w.SkuNo == item.SkuNo && w.LotNo == item.LotNo); //修改库存信息 stockInfo.LockQty += (decimal)item.Qty;//锁定数量 await Db.Updateable(stockInfo).ExecuteCommandAsync(); } if (string.IsNullOrEmpty(palletNo)) { //添加操作日志记录 var k = new OperationCrServer().AddLogOperationCr("PDA模块", "AGV转运", palletNo, "移库", $"PDA呼叫小车对出库单:{soNo}下所有托盘发起转运", userId); } else { //添加操作日志记录 var k = new OperationCrServer().AddLogOperationCr("PDA模块", "AGV转运", palletNo, "移库", $"PDA呼叫小车对托盘号:{palletNo}发起转运", userId); } #region 呼叫小车代码 #endregion } /// /// 根据区域分配储位 /// /// /// /// /// private async Task GetLocat(string areaNo, string skuNo, string lotNo, string palletNo, string hasLocatNoList = "") { string endLocat = string.Empty;//目标储位 //当然区域所有储位信息 var storageLocatList = await Db.Queryable().Where(w => w.WareHouseNo == "W02" && w.AreaNo == areaNo).ToListAsync(); //同区域同批次物料的储位信息 List locatList = await Db.Queryable().Where(w => w.IsDel == "0" && w.SkuNo == skuNo && w.LotNo == lotNo && w.WareHouseNo == "W02" && w.AreaNo == areaNo && w.PalletNo != palletNo) .OrderByDescending(o => o.LocatNo).Select(s => s.LocatNo).Distinct().ToListAsync(); foreach (var item in locatList) { var locatInfo = storageLocatList.Where(w => w.LocatNo == item).First(); var locatInfo2 = storageLocatList.Where(w => w.IsDel == "0" && w.Status == "0" && w.Flag == "0" && w.LocatNo != locatInfo.LocatNo && w.Row == locatInfo.Row && !hasLocatNoList.Contains(w.LocatNo)) .OrderByDescending(o => o.Column).First(); if (locatInfo2 != null) { endLocat = locatInfo2.LocatNo; } } if (string.IsNullOrEmpty(endLocat)) { var locatInfo3 = storageLocatList.Where(w => w.IsDel == "0" && w.Flag == "0" && w.Status == "0" && !hasLocatNoList.Contains(w.LocatNo)) .OrderByDescending(m => m.Layer).OrderByDescending(m => m.Column).OrderByDescending(m => m.Row).First(); if (locatInfo3 != null) { endLocat = locatInfo3.LocatNo; } } return endLocat; } #endregion #region 零箱解绑 public void LingxingUnbind(string palletNo,string boxNo, int userId) { try { if (string.IsNullOrEmpty(palletNo)) { throw new Exception("托盘号不能为空"); } if (string.IsNullOrEmpty(boxNo)) { throw new Exception("箱码不能为空"); } //开启事务 Db.BeginTran(); var comTime = DateTime.Now; //托盘库存明细信息 var detail = Db.Queryable().First(w => w.IsDel == "0" && w.PalletNo == palletNo); if (detail == null) { throw new Exception("该托盘库存明细信息不存在"); } //库存箱支明细信息 var boxList = Db.Queryable().Where(w => w.IsDel == "0" && w.StockDetailId == detail.Id && w.BoxNo == boxNo).ToList(); if (boxList.Count <= 0) { throw new Exception("该箱码库存箱支信息不存在"); } decimal boxQty = 0;//箱内数量 foreach (var item in boxList) { boxQty += item.Qty; item.StockDetailId = 0;//清空托盘外键 } //更新库存箱支明细表 Db.Updateable(boxList).ExecuteCommand(); detail.Qty -= boxQty;//托盘库存数量 detail.BitPalletMark = "1";//零托标记 //更新托盘库存表 Db.Updateable(detail).ExecuteCommand(); //添加托盘解绑绑定记录 var unBind = new BllPalletUnbind() { UpbindPalletNo = palletNo, BindPalletNo = "", LotNo = detail.LotNo, LotText = detail.LotText, SupplierLot = detail.SupplierLot, SkuNo = detail.SkuNo, SkuName = detail.SkuName, Standard = detail.Standard, Qty = boxQty, PalletNo2 = detail.PalletNo2, PalletNo3 = detail.PalletNo3, BoxNo = boxNo, InspectNo = "", InspectStatus = detail.InspectStatus, IsDel = "0", CreateTime = comTime, CreateUser = userId }; Db.Insertable(unBind).ExecuteCommand(); //添加操作日志 new OperationCrServer().AddLogOperationCr("库内作业", "操作日志", boxNo, "编辑", $"零箱解绑:原托盘码:{palletNo}上的箱码{boxNo}解绑", userId); //提交事务 Db.CommitTran(); } catch (Exception e) { //回滚事务 Db.RollbackTran(); throw new Exception(e.Message); } } #endregion #region 箱码拆箱贴标 /// /// 拆箱添加标签 /// /// /// /// public void AddLableByDevanning(string boxNo, decimal devanQty, int userId) { try { if (string.IsNullOrEmpty(boxNo)) { throw new Exception("箱码不能为空"); } //开启事务 Db.BeginTran(); //库存箱支明细信息 var boxList = Db.Queryable().Where(w => w.IsDel == "0" && w.BoxNo == boxNo).ToList(); if (boxList.Count != 1) { throw new Exception("该箱码信息错误,存在多个此箱码信息"); } var boxInfo = boxList.First(); if (boxInfo.Qty<=devanQty) { throw new Exception("拆箱数量大等于当前箱内数量"); } boxInfo.Qty -= devanQty; boxInfo.BitBoxMark = "1"; //更新箱码库存表 Db.Updateable(boxInfo).ExecuteCommand(); var boxStr = boxInfo.BoxNo.Substring(0, boxInfo.BoxNo.Length - 6);//获取箱码前缀-除后六位流水外 var maxBoxCode = Db.Queryable().Where(m => m.BoxNo.Contains(boxStr) && m.IsDel == "0" && m.Origin == "WMS生成").Max(a => a.BoxNo); var boxNoNew = maxBoxCode.Substring(0, maxBoxCode.Length - 6) + (int.Parse(maxBoxCode.Substring(maxBoxCode.Length - 6, 6)) + 1).ToString().PadLeft(6, '0'); // 添加新箱码信息 var boxModel = new DataBoxInfo() { StockDetailId = boxInfo.StockDetailId, PalletNo = boxInfo.PalletNo, BoxNo = boxNoNew, Qty = devanQty, FullQty = boxInfo.FullQty, Status = "2",//0:未组托 1:已组托 2:已入库 3:已出库 4:已分配 5:已拣货 LotNo = boxInfo.LotNo, LotText = boxInfo.LotText, SkuNo = boxInfo.SkuNo, SkuName = boxInfo.SkuName, Standard = boxInfo.Standard, SupplierLot = boxInfo.SupplierLot, InspectStatus = boxInfo.InspectStatus, InspectMark = boxInfo.InspectMark, BitBoxMark = "1", ProductionTime = boxInfo.ProductionTime, ExpirationTime = boxInfo.ExpirationTime, CreateUser = 0, CreateTime = DateTime.Now }; Db.Insertable(boxModel).ExecuteCommand(); //添加操作日志 new OperationCrServer().AddLogOperationCr("库内作业", "操作日志", boxNo, "编辑", $"拆箱贴标:原箱码:{boxNo}拆箱,添加新箱码{boxNoNew}", userId); //提交事务 Db.CommitTran(); } catch (Exception e) { //回滚事务 Db.RollbackTran(); throw new Exception(e.Message); } } #endregion } }