using System; using System.Collections.Generic; using System.ComponentModel.Design; using System.Linq; using System.Linq.Expressions; using System.Net; using System.Text; using System.Threading.Tasks; using Microsoft.AspNetCore.Identity; using Model.InterFaceModel; using Model.ModelDto.BllCheckDto; using Model.ModelDto.DataDto; using Model.ModelDto.SysDto; using Model.ModelVm; using Model.ModelVm.BllCheckVm; using Model.ModelVm.LogVm; using Newtonsoft.Json; using SqlSugar; using SqlSugar.Extensions; using Utility; using Utility.Tools; 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.IBllCheckServer; using WMS.IBLL.ILogServer; namespace WMS.BLL.BllCheckServer { public class StockCheckServer : DbHelper, IStockCheckServer { private static readonly SqlSugarScope Db = DataContext.Db; private readonly UserManager _userManager; private readonly IOperationCRServer _operation; public StockCheckServer(UserManager userManager, IOperationCRServer operation) : base(Db) { _userManager = userManager; _operation = operation; } //获取盘点单据 public async Task> GetStockCheckList(string crNo, string status, string palletNo, string skuNo, string skuName, string lotNo, string startTime, string endTime, int page, int limit, RefAsync count) { var strList = new List(); if (!string.IsNullOrWhiteSpace(palletNo) || !string.IsNullOrWhiteSpace(skuNo) || !string.IsNullOrWhiteSpace(skuName) || !string.IsNullOrWhiteSpace(lotNo)) { Expression> demo = Expressionable.Create() .AndIF(!string.IsNullOrWhiteSpace(palletNo), m => m.PalletNo.Contains(palletNo.Trim())) .AndIF(!string.IsNullOrWhiteSpace(skuNo), m => m.SkuNo.Contains(skuNo.Trim())) .AndIF(!string.IsNullOrWhiteSpace(skuName), m => m.SkuName.Contains(skuName.Trim())) .AndIF(!string.IsNullOrWhiteSpace(lotNo), m => m.LotNo.Contains(lotNo.Trim())) .And(m => m.IsDel == "0") .ToExpression();//注意 这一句 不能少 var detailList = await Db.Queryable().Where(demo).Select(m => m.CRNo).Distinct().ToListAsync(); strList = detailList; } Expression> item = Expressionable.Create() .AndIF(!string.IsNullOrWhiteSpace(crNo), m => m.CRNo.Contains(crNo.Trim())) .AndIF(!string.IsNullOrWhiteSpace(status), m => m.Status == int.Parse(status)) .AndIF(!string.IsNullOrWhiteSpace(startTime), m => m.CheckDate >= Convert.ToDateTime(startTime)) .AndIF(!string.IsNullOrWhiteSpace(endTime), m => m.CheckDate <= Convert.ToDateTime(endTime).AddDays(1)) .AndIF(!string.IsNullOrWhiteSpace(palletNo), m => strList.Contains(m.CRNo)) .AndIF(!string.IsNullOrWhiteSpace(skuNo), m => strList.Contains(m.CRNo)) .AndIF(!string.IsNullOrWhiteSpace(skuName), m => strList.Contains(m.CRNo)) .AndIF(!string.IsNullOrWhiteSpace(lotNo), m => strList.Contains(m.CRNo)) .And(m => m.IsDel == "0") .ToExpression();//注意 这一句 不能少 var list = await Db.Queryable().Where(item) .LeftJoin((a, b) => a.AuditUser == b.Id) .LeftJoin((a, b, c) => a.CreateUser == c.Id) .LeftJoin((a, b, c, d) => a.CreateUser == d.Id) .Select((a, b, c, d) => new StockCheckDto() { Id = a.Id, CrNo = a.CRNo, CheckDate = a.CheckDate, CompleteDate = a.CompleteDate, Status = a.Status, Origin = a.Origin, AuditStatusNo = a.AuditStatusNo, IsDoubleCheck = a.IsDoubleCheck, AuditUserName = b.RealName, AuditTime = a.AuditTime, Demo = a.Demo, CreateUserName = c.RealName, UpdateUserName = d.RealName, CreateTime = a.CreateTime, UpdateTime = a.UpdateTime, }).OrderByDescending(a => a.CreateTime).ToPageListAsync(page, limit, count); return list; } //获取盘点单据明细 public async Task> GetStockCheckDetailList(string crNo, int page, int limit, RefAsync count) { return await Db.Queryable().Where(m => m.IsDel == "0" && m.CRNo == crNo) .LeftJoin((a, b) => a.CreateUser == b.Id) .LeftJoin((a, b, c) => a.UpdateUser == c.Id) .Select((a, b, c) => new StockCheckDetailDto() { Id = a.Id, CrNo = a.CRNo, PalletNo = a.PalletNo, Qty = a.Qty, RealQty = a.RealQty, CheckResult = a.CheckResult, Status = a.Status, SkuNo = a.SkuNo, SkuName = a.SkuName, Standard = a.Standard, LotNo = a.LotNo, LotText = a.LotText, SupplierLot = a.SupplierLot, CreateUserName = b.RealName, UpdateUserName = c.RealName, CreateTime = a.CreateTime, UpdateTime = a.UpdateTime, }).ToPageListAsync(page, limit, count); } //获取库存明细信息(盘点选择明细数据源) public async Task> GetCheckStockDetailList(string houseNo, string roadwayNo, string locateNo, string msg, int page, int limit, RefAsync count) { Expression> item = Expressionable.Create() .AndIF(!string.IsNullOrWhiteSpace(houseNo), m => m.WareHouseNo == houseNo) .AndIF(!string.IsNullOrWhiteSpace(roadwayNo), m => m.RoadwayNo == roadwayNo) .AndIF(!string.IsNullOrWhiteSpace(locateNo), m => m.LocatNo == locateNo) .AndIF(!string.IsNullOrWhiteSpace(msg), m => m.SkuNo.Contains(msg.Trim()) || m.SkuName.Contains(msg.Trim()) || m.LotNo.Contains(msg.Trim())) .And(m => m.IsDel == "0" && m.SkuNo != "100099" && m.Status == "0") .ToExpression();//注意 这一句 不能少 return await Db.Queryable().Where(item).GroupBy(m => new { m.SkuNo, m.SkuName, m.Standard, m.LotNo, m.LotText, m.SupplierLot, m.LocatNo, m.PalletNo }) .Select(a => new StockDetailDto() { SkuNo = a.SkuNo, SkuName = a.SkuName, Standard = a.Standard, LotNo = a.LotNo, LotText = a.LotText, SupplierLot = a.SupplierLot, Qty = SqlFunc.AggregateSum(a.Qty), LocatNo = a.LocatNo, PalletNo = a.PalletNo }).ToPageListAsync(page, limit, count); } public async Task GetStockCheckDetailById(string crNo) { var notify = await Db.Queryable().FirstAsync(m => m.CRNo == crNo && m.IsDel == "0"); if (notify == null) { throw new Exception($"未查询到{crNo}的盘点单据信息"); } var detail = await Db.Queryable().Where(m => m.CRNo == crNo && m.IsDel == "0").Select(m => new EditStockCheckDetailDto() { SkuNo = m.SkuNo, SkuName = m.SkuName, Standard = m.Standard, LotNo = m.LotNo, LotText = m.LotText, SupplierLot = m.SupplierLot, Qty = m.Qty, PalletNo = m.PalletNo }).ToListAsync(); var data = new EditStockCheckDto() { CrNo = crNo, Detail = detail }; return data; } //添加盘点单、编辑盘点单 public async Task AddEditStockCheck(AddEditStockCheckVm model) { if (model.Detail.Count == 0) { throw Oops.Bah("盘点明细不能为空"); } var time = DateTime.Now; //添加 if (string.IsNullOrWhiteSpace(model.CrNo)) { var num = await Db.Queryable().CountAsync(m => m.IsDel == "0" && (m.Status == 0 || m.Status == 1)); if (num > 0) { throw Oops.Bah("已有等待执行的盘点单据请先完成或删除"); } var crNo = new Common().GetMaxNo("CR"); var stockDetail = Db.Queryable().Where(m => m.IsDel == "0"); var check = new BllStockCheck() { CRNo = crNo, Origin = "0", Status = 0, CreateUser = _userManager.UserId, CreateTime = time }; var list = new List(); foreach (var item in model.Detail) { var detail = new BllStockCheckDetail() { CRNo = crNo, PalletNo = item.PalletNo, Qty = item.Qty, Status = 0, //0:未盘 1:已盘 2:已调整 SkuNo = item.SkuNo, SkuName = item.SkuName, Standard = item.Standard, LotNo = item.LotNo, LotText = item.LotText, SupplierLot = item.SupplierLot, CreateUser = _userManager.UserId, CreateTime = time }; list.Add(detail); var sd = await stockDetail.FirstAsync(m => m.SkuNo == item.SkuNo && m.LotNo == item.LotNo && m.PalletNo == item.PalletNo && m.Status == "0"); sd.Status = "3"; Db.Updateable(sd).ExecuteCommand(); } Db.Insertable(check).ExecuteCommand(); Db.Insertable(list).ExecuteCommand(); //添加操作日志记录 await _operation.AddLogOperationCr(new OperationInputVm() { ParentName = "库内作业", MenuName = "盘点单据", FkNo = crNo, TypeName = "添加", Msg = $"添加了单据号为{crNo}的盘点单信息" }); //var k = new OperationCrServer().AddLogOperationCr("库内作业", "盘点单据", crNo, "添加", $"添加了单据号为{crNo}的盘点单信息", _userManager.UserId); } else //编辑 { var check = await Db.Queryable().FirstAsync(m => m.IsDel == "0" && m.CRNo == model.CrNo); if (check == null) { throw Oops.Bah("未查询到盘点单据的信息"); } check.UpdateUser = _userManager.UserId; check.UpdateTime = time; await Db.Updateable(check).ExecuteCommandAsync(); //盘点明细信息 var checkDetail = Db.Queryable().Where(m => m.IsDel == "0" && m.CRNo == model.CrNo).ToList(); //删除旧的 foreach (var d in checkDetail) { var mq = model.Detail.Where(o => o.SkuNo == d.SkuNo && o.LotNo == d.LotNo && o.PalletNo == d.PalletNo).ToList(); if (mq.Any()) //如果有这个物料及批次则跳过 { continue; } var sd = Db.Queryable().Where(m => m.IsDel == "0" && m.SkuNo == d.SkuNo && m.LotNo == d.LotNo && m.PalletNo == d.PalletNo && m.Status == "3").ToList(); foreach (var s in sd) { s.Status = "0"; } d.IsDel = "1"; d.UpdateUser = _userManager.UserId; d.UpdateTime = time; //修改库存明细的状态(解除盘点锁定) await Db.Updateable(sd).ExecuteCommandAsync(); await Db.Updateable(d).ExecuteCommandAsync(); } //添加与修改 var list = new List(); foreach (var item in model.Detail) { var de = checkDetail.FirstOrDefault(m => m.PalletNo == item.PalletNo && m.SkuNo == item.SkuNo && m.LotNo == item.LotNo); //新加项 if (de == null) { var detail = new BllStockCheckDetail() { CRNo = model.CrNo, PalletNo = item.PalletNo, Qty = item.Qty, Status = 0, //0:未盘 1:已盘 2:已调整 SkuNo = item.SkuNo, SkuName = item.SkuName, Standard = item.Standard, LotNo = item.LotNo, LotText = item.LotText, SupplierLot = item.SupplierLot, CreateUser = _userManager.UserId, CreateTime = time }; list.Add(detail); var sd = Db.Queryable().Where(m => m.IsDel == "0" && m.SkuNo == item.SkuNo && m.LotNo == item.LotNo && m.PalletNo == item.PalletNo && m.Status == "0").ToList(); foreach (var s in sd) { s.Status = "3"; } await Db.Updateable(sd).ExecuteCommandAsync(); } else if (de.Qty != item.Qty) { de.Qty = item.Qty; de.UpdateUser = _userManager.UserId; de.UpdateTime = time; await Db.Updateable(de).ExecuteCommandAsync(); } } if (list.Count > 0) { await Db.Insertable(list).ExecuteCommandAsync(); } //添加操作日志记录 await _operation.AddLogOperationCr(new OperationInputVm() { ParentName = "库内作业", MenuName = "盘点单据", FkNo = model.CrNo, TypeName = "编辑", Msg = $"编辑了单据号为{model.CrNo}的盘点单信息" }); //var k = new OperationCrServer().AddLogOperationCr("库内作业", "盘点单据", model.CrNo, "编辑", $"编辑了单据号为{model.CrNo}的盘点单信息", _userManager.UserId); } } //删除盘点单 public async Task DelStockCheck(int id) { var notice = await Db.Queryable().FirstAsync(m => m.IsDel == "0" && m.Id == id); if (notice == null || notice.Status != 0) { throw Oops.Bah("未查询到状态为等待执行的盘点单信息"); } var detail = await Db.Queryable().Where(m => m.IsDel == "0" && m.CRNo == notice.CRNo).ToListAsync(); if (detail.Count == 0) { throw Oops.Bah("未查询到盘点单据明细信息"); } var time = DateTime.Now; foreach (var d in detail) { d.IsDel = "1"; d.UpdateTime = time; d.UpdateUser = _userManager.UserId; var item = await Db.Queryable().Where(m => m.IsDel == "0" && m.PalletNo == d.PalletNo && m.SkuNo == d.SkuNo && m.LotNo == d.LotNo && m.Status == "3").ToListAsync(); foreach (var i in item) { i.Status = "0"; } await Db.Updateable(item).ExecuteCommandAsync(); } notice.IsDel = "1"; notice.UpdateTime = time; notice.UpdateUser = _userManager.UserId; await Db.Updateable(notice).ExecuteCommandAsync(); await Db.Updateable(detail).ExecuteCommandAsync(); //添加操作日志记录 await _operation.AddLogOperationCr(new OperationInputVm() { ParentName = "库内作业", MenuName = "盘点单据", FkNo = notice.CRNo, TypeName = "删除", Msg = $"删除了单据号为{notice.CRNo}的盘点单信息" }); //var k = new OperationCrServer().AddLogOperationCr("库内作业", "盘点单据", notice.CRNo, "删除", $"删除了单据号为{notice.CRNo}的盘点单信息", userId); } /// /// 维护盘点单备注信息 /// /// /// /// public async Task EditNoticeDemo(int id, string demo) { try { var notice = await Db.Queryable().FirstAsync(m => m.IsDel == "0" && m.Id == id); if (notice == null) { throw new Exception("未查询到盘点单据信息"); } notice.Demo = demo + "".Trim(); notice.UpdateUser = _userManager.UserId; notice.UpdateTime = DateTime.Now; int i = Db.Updateable(notice).ExecuteCommand(); if (i > 0) { //添加操作日志 await _operation.AddLogOperationCr(new OperationInputVm() { ParentName = "库内作业", MenuName = "盘点单据", FkNo = notice.CRNo, TypeName = "编辑", Msg = $"编辑了单据号为{notice.CRNo}的备注信息" }); //new OperationCrServer().AddLogOperationCr("库内作业", "盘点单据", notice.CRNo, "编辑", $"编辑了单据号为{notice.CRNo}的备注信息", userId); } } catch (Exception ex) { throw new Exception(ex.Message); } } //调整库存 public async Task StockAdjust(int id) { try { //盘点信息 var notice = await Db.Queryable().FirstAsync(m => m.IsDel == "0" && m.Id == id); if (notice == null || notice.Status != 2) { throw Oops.Bah("未查询到状态为盘点完成的盘点单信息"); } if (notice == null || notice.Status != 2) { throw Oops.Bah("未查询到状态为盘点完成的盘点单信息"); } //盘点明细 var detail = await Db.Queryable().Where(m => m.IsDel == "0" && m.CRNo == notice.CRNo).ToListAsync(); if (detail.Count == 0) { throw Oops.Bah("未查询到盘点单据明细信息"); } //开启事务 Db.BeginTran(); var stock = await Db.Queryable().Where(m => m.IsDel == "0").ToListAsync();//库存表 var stockDetail = await Db.Queryable().Where(m => m.IsDel == "0").ToListAsync();//库存明细 var stockBox = await Db.Queryable().Where(m => m.IsDel == "0").ToListAsync();//库存箱支明细 var materialList = await Db.Queryable().Where(m => m.IsDel == "0").ToListAsync();//物料信息 var packagList = await Db.Queryable().Where(m => m.IsDel == "0").ToListAsync();//包装信息 var time = DateTime.Now; //盘点记录 var checkLog = await Db.Queryable().Where(m => m.IsDel == "0" && m.CRNo == notice.CRNo).ToListAsync(); if (checkLog.Count(m => m.CheckResult == null) > 0) { throw Oops.Bah($"{notice.CRNo}单据中含有未盘点的信息,请核实!"); } List boxQtyList = new List(); #region#此段代码为了判断盘点后箱子是否零头箱 //循环盘点明细, foreach (var d in detail) { var demo = checkLog.Where(m => m.PalletNo == d.PalletNo).ToList();//盘点记录 foreach (var l in demo) { var boxInfo = boxQtyList.FirstOrDefault(m => m.boxNo == l.BoxNo); if (boxInfo == null) { var totalRealQty = checkLog.Where(m => m.PalletNo == d.PalletNo && m.BoxNo == l.BoxNo).Sum(m => m.RealQty); BoxQtyInfo boxQtyInfo = new BoxQtyInfo(); boxQtyInfo.boxNo = l.BoxNo; boxQtyInfo.realQty = (int)totalRealQty; boxQtyList.Add(boxQtyInfo); } } } foreach (var item in boxQtyList) { var stockBoxInfo = stockBox.FirstOrDefault(m => m.BoxNo == item.boxNo);//库存箱支明细 if (stockBoxInfo == null) { continue; } if (item.realQty < stockBoxInfo.FullQty) { item.bitBoxMark = "1"; } else { item.bitBoxMark = "0"; } var stockBoxList = stockBox.Where(m => m.BoxNo == item.boxNo).ToList(); foreach (var s in stockBoxList) { s.BitBoxMark = item.bitBoxMark; Db.Updateable(s).ExecuteCommand(); } } #endregion //循环盘点明细 foreach (var d in detail) { var demo = checkLog.Where(m => m.PalletNo == d.PalletNo).ToList();//盘点记录 //循环盘点记录 foreach (var l in demo) { var sku = await Db.Queryable().FirstAsync(a => a.IsDel == "0" && a.SkuNo == l.SkuNo); if (l.CheckResult == 0)//正常 { if (sku.Type != "4") { var de3 = stockBox.First(m => m.BoxNo == l.BoxNo && m.BoxNo3 == l.BoxNo3); if (de3 == null) { throw Oops.Bah($"未查询到{l.BoxNo}箱中{l.BoxNo3}库存箱码的信息"); } var de2 = stockDetail.First(m => m.Id == de3.StockDetailId); if (de2 == null) { throw Oops.Bah($"未查询到{l.BoxNo}箱中{l.BoxNo3}库存明细的信息"); } de2.Status = "0";//将库存明细状态改为待分配 await Db.Updateable(de2).ExecuteCommandAsync(); } else { var de2 = stockDetail.First(m => m.PalletNo == l.PalletNo && m.SkuNo == l.SkuNo); if (de2 == null) { throw Oops.Bah($"未查询到{l.PalletNo}的库存明细的信息"); } de2.Status = "0";//将库存明细状态改为待分配 await Db.Updateable(de2).ExecuteCommandAsync(); } } else if (l.CheckResult == 1)//盘亏 { if (sku.Type != "4") { var de3 = stockBox.First(m => m.BoxNo == l.BoxNo && m.BoxNo3 == l.BoxNo3); if (de3 == null) { throw Oops.Bah($"未查询到{l.BoxNo}箱中{l.BoxNo3}库存箱码的信息"); } var de2 = stockDetail.First(m => m.Id == de3.StockDetailId); if (de2 == null) { throw Oops.Bah($"未查询到{l.BoxNo}箱中{l.BoxNo3}库存明细的信息"); } de2.Status = "0"; de2.Qty -= de3.Qty; var de = stock.First(m => m.SkuNo == l.SkuNo && m.LotNo == l.LotNo); if (de == null) { throw new Exception($"未查询到物料{l.SkuNo}批次{l.LotNo}的总库存的信息"); } de.Qty -= de3.Qty; await Db.Updateable(de).ExecuteCommandAsync(); await Db.Updateable(de2).ExecuteCommandAsync(); await Db.Deleteable(de3).ExecuteCommandAsync(); } else { var de2 = stockDetail.First(m => m.PalletNo == l.PalletNo && m.SkuNo == l.SkuNo); if (de2 == null) { throw Oops.Bah($"未查询到{l.PalletNo}的库存明细的信息"); } de2.Status = "0"; de2.Qty = l.RealQty; var de = stock.First(m => m.SkuNo == l.SkuNo && m.LotNo == l.LotNo); if (de == null) { throw Oops.Bah($"未查询到物料{l.SkuNo}批次{l.LotNo}的总库存的信息"); } de.Qty -= Convert.ToDecimal(l.Qty - l.RealQty); await Db.Updateable(de).ExecuteCommandAsync(); await Db.Updateable(de2).ExecuteCommandAsync(); } } else if (l.CheckResult == 2)//盘盈 { var stockDetailInfo = stockDetail.First(m => m.PalletNo == d.PalletNo && m.SkuNo == d.SkuNo && m.LotNo == d.LotNo);//库存明细 if (sku.Type != "4") { var stockBoxInfo = stockBox.First(m => m.StockDetailId == stockDetailInfo.Id);//库存箱支明细 var boxInfo = boxQtyList.First(m => m.boxNo == l.BoxNo);//找到对应箱子是否零箱 //添加库存箱支信息 var databox = new DataBoxInfo { StockDetailId = stockDetailInfo.Id, BindNo = stockBoxInfo.BindNo, BoxNo = l.BoxNo, BoxNo2 = l.BoxNo2, BoxNo3 = l.BoxNo3, PalletNo = l.PalletNo, Qty = (decimal)l.RealQty, FullQty = stockBoxInfo.FullQty,//满箱数量 Status = "2", SkuNo = l.SkuNo, SkuName = l.SkuName, LotNo = l.LotNo, LotText = l.LotText, Standard = l.Standard, SupplierLot = l.SupplierLot, InspectMark = stockBoxInfo.InspectMark, InspectStatus = stockBoxInfo.InspectStatus, ProductionTime = stockBoxInfo.ProductionTime, BitBoxMark = boxInfo.bitBoxMark, }; await Db.Insertable(databox).ExecuteCommandAsync(); //库存明细增加数量 stockDetailInfo.Qty += (int)l.RealQty; } else { //库存明细增加数量 stockDetailInfo.Qty = (int)l.RealQty; } stockDetailInfo.Status = "0"; await Db.Updateable(stockDetailInfo).ExecuteCommandAsync(); //库存增加数量 var de = stock.First(m => m.SkuNo == l.SkuNo && m.LotNo == l.LotNo); if (de == null) { throw Oops.Bah($"未查询到{l.BoxNo}箱中{l.BoxNo3}库存的信息"); } if (sku.Type != "4") { de.Qty += (int)l.RealQty; } else { de.Qty += (int)(l.RealQty - l.Qty); } await Db.Updateable(de).ExecuteCommandAsync(); } } //修改盘点明细 d.Status = 4;//状态 d.UpdateTime = time; d.UpdateUser = _userManager.UserId; //盘点结果 if (d.Qty == d.RealQty) { d.CheckResult = 0; if (demo.Count(m => m.CheckResult == 1 || m.CheckResult == 2) > 0) { d.CheckResult = 3; } } if (d.Qty < d.RealQty) { d.CheckResult = 2; } if (d.Qty > d.RealQty) { d.CheckResult = 1; } await Db.Updateable(d).ExecuteCommandAsync(); #region 添加判断盘点完托盘是否是零托 var material = materialList.FirstOrDefault(m => m.SkuNo == d.SkuNo); if (material == null) { throw Oops.Bah($"未查询到{d.SkuNo}的物料信息;"); } var pack = packagList.FirstOrDefault(m => m.PackagNo == material.PackagNo); if (pack == null) { throw Oops.Bah($"未查询到{d.SkuNo}的包装信息;"); } var pNum = 0;//托盘物品数量 var bNum = 0;//箱物品数量 if (pack.L5Num.HasValue) { pNum = Convert.ToInt32(pack.L5Num); } else if (pack.L4Num.HasValue) { pNum = Convert.ToInt32(pack.L4Num); } else if (pack.L3Num.HasValue) { pNum = Convert.ToInt32(pack.L3Num); } else if (pack.L2Num.HasValue) { pNum = Convert.ToInt32(pack.L2Num); } else if (pack.L1Num.HasValue) { pNum = Convert.ToInt32(pack.L1Num); } if (pNum == 0) { throw Oops.Bah("未查询到物料包装托箱关系信息"); } var stockDetailInfo2 = stockDetail.First(m => m.PalletNo == d.PalletNo && m.SkuNo == d.SkuNo && m.LotNo == d.LotNo);//库存明细 if (stockDetailInfo2.Qty >= pNum) { stockDetailInfo2.BitPalletMark = "0"; } if (stockDetailInfo2.Qty < pNum) { stockDetailInfo2.BitPalletMark = "1"; } await Db.Updateable(stockDetailInfo2).ExecuteCommandAsync(); #endregion } //修该盘点信息 notice.Status = 3;//状态 notice.UpdateTime = time; notice.UpdateUser = _userManager.UserId; await Db.Updateable(notice).ExecuteCommandAsync(); //添加操作日志记录 //var k = new OperationCrServer().AddLogOperationCr("库内作业", "盘点单据", notice.CRNo, "调整单据", $"调整了单据号为{notice.CRNo}的盘点单信息", userId); await _operation.AddLogOperationCr(new OperationInputVm() { ParentName = "库内作业", MenuName = "盘点单据", FkNo = notice.CRNo, TypeName = "调整单据", Msg = $"调整了单据号为{notice.CRNo}的盘点单信息" }); //提交事务 Db.CommitTran(); } catch (Exception e) { //回滚事务 Db.RollbackTran(); throw new Exception(e.Message); } } //调整库存-针对异常生成的 public async Task StockAdjustAuto(int id) { try { //盘点表 var notice = Db.Queryable().First(m => m.IsDel == "0" && m.Id == id); if (notice == null || notice.Status != 2) { throw Oops.Bah("未查询到状态为盘点完成的盘点单信息"); } //盘点明细 var detail = Db.Queryable().Where(m => m.IsDel == "0" && m.CRNo == notice.CRNo).ToList(); if (detail.Count == 0) { throw Oops.Bah("未查询到盘点单据明细信息"); } //开启事务 Db.BeginTran(); var stock = Db.Queryable().Where(m => m.IsDel == "0");//库存 var stockDetail = Db.Queryable().Where(m => m.IsDel == "0");//库存明细 var stockBox = Db.Queryable().Where(m => m.IsDel == "0");//库存箱支信息 var time = DateTime.Now; //盘点记录 var checkLog = Db.Queryable().Where(m => m.IsDel == "0" && m.CRNo == notice.CRNo); if (await checkLog.CountAsync(m => m.CheckResult == null) > 0) { throw new Exception($"{notice.CRNo}单据中含有未盘点的信息,请核实!"); } foreach (var d in detail) { //托盘绑定表 var palletBind = await Db.Queryable().FirstAsync(m => m.PalletNo == d.PalletNo); //储位表 var storageLocat = await Db.Queryable().FirstAsync(m => m.LocatNo == palletBind.LocatNo); if (storageLocat != null && storageLocat.Flag == "1") { //将储位标志Flag修改为:0:正常 storageLocat.Flag = "0"; storageLocat.UpdateUser = _userManager.UserId; storageLocat.UpdateTime = time; await Db.Updateable(storageLocat).ExecuteCommandAsync(); } //条码管理(托盘) var pallets = await Db.Queryable().FirstAsync(m => m.PalletNo == d.PalletNo); if (pallets != null && pallets.Status == "1") { //将托盘号状态变更为 0 未使用 pallets.Status = "0"; pallets.UpdateUser = _userManager.UserId; pallets.UpdateTime = time; await Db.Updateable(pallets).ExecuteCommandAsync(); } //盘点记录 var demo = await checkLog.Where(m => m.PalletNo == d.PalletNo).ToListAsync(); foreach (var l in demo) { if (l.CheckResult == 0)//正常 { continue; } else if (l.CheckResult == 1)//盘亏 { //物理删除库存箱支信息 var de3 = await stockBox.FirstAsync(m => m.BoxNo == l.BoxNo && m.BoxNo3 == l.BoxNo3); if (de3 == null) { throw Oops.Bah($"未查询到{l.BoxNo}箱中{l.BoxNo3}库存箱码的信息"); } await Db.Deleteable(de3).ExecuteCommandAsync(); //物理删除库存明细 var de2 = await stockDetail.FirstAsync(m => m.Id == de3.StockDetailId); if (de2 == null) { throw Oops.Bah($"未查询到{l.BoxNo}箱中{l.BoxNo3}库存明细的信息"); } await Db.Deleteable(de2).ExecuteCommandAsync(); //更改库存数量和锁定数量 var de = await stock.FirstAsync(m => m.SkuNo == l.SkuNo && m.LotNo == l.LotNo); if (de == null) { throw Oops.Bah($"未查询到物料{l.SkuNo}批次{l.LotNo}的总库存的信息"); } de.Qty -= de3.Qty; de.LockQty -= de3.Qty; await Db.Updateable(de).ExecuteCommandAsync(); } } //将盘点明细状态改为 已调整 d.Status = 4; d.UpdateTime = time; d.UpdateUser = _userManager.UserId; await Db.Updateable(d).ExecuteCommandAsync(); } //将盘点总表状态改为 生成调整 notice.Status = 3; notice.UpdateTime = time; notice.UpdateUser = _userManager.UserId; await Db.Updateable(notice).ExecuteCommandAsync(); //添加操作日志记录 //var k = new OperationCrServer().AddLogOperationCr("库内作业", "盘点单据", notice.CRNo, "调整单据", $"调整了单据号为{notice.CRNo}的盘点单信息", userId); await _operation.AddLogOperationCr(new OperationInputVm() { ParentName = "库内作业", MenuName = "盘点单据", FkNo = notice.CRNo, TypeName = "调整单据", Msg = $"调整了单据号为{notice.CRNo}的盘点单信息" }); //提交事务 Db.CommitTran(); } catch (Exception e) { Db.RollbackTran(); throw new Exception(e.Message); } } //盘点下发出库 public async Task> CheckOutHouse(string crNo, string outMode, string url, string str) { #region 集合 var outDtoList = new List(); //出库数据的集合 //记录错误信息的集合 var flagList = new List();//1:当前要出库的储位正在移出、2 出库的托盘储位信息错误(在储位表中未查询到)、3储位损坏不能出库、4 要出库的托盘正在入库 #endregion var com = new Common(); //assign.IsHavePyTask(); var notice = await Db.Queryable().FirstAsync(m => m.CRNo == crNo && m.IsDel == "0"); if (notice == null) { throw Oops.Bah($"未找到{crNo}盘点单信息"); } //所有要出库的盘点明细信息(等待的信息和待拣货的信息) var funSetting = Db.Queryable().First(a => a.IsDel == "0" && a.FunSetNo == "InventoryCheckMethod"); if (funSetting == null || funSetting.IsEnable == "OFF") { throw Oops.Bah("需配置盘点方式"); } var list = await Db.Queryable().Where(a => a.IsDel == "0" && a.CRNo == crNo && (a.Status == 0 || a.Status == 1 || a.Status == 2)).ToListAsync(); if (list.Count == 0) //判断是否有需要下发的盘点明细 { throw Oops.Bah("当前盘点单据无需要下发的托盘"); } if (funSetting.SetValue == "once") { if (list.Any(s => s.Status == 1 || s.Status == 2)) { throw Oops.Bah("已有正在出库或待盘点的数据,请完成盘点后再出库"); } list = new List() { list.FirstOrDefault() }; } else { list = list.Where(s => s.Status == 0).ToList(); } #region //要出库的托盘集合 var outLpnList = list.Select(m => m.PalletNo).Distinct().ToList(); //要出库的明细集合 var outStockDetail = await Db.Queryable().Where(m => m.IsDel == "0" && outLpnList.Contains(m.PalletNo)).ToListAsync(); var outStockBox = await Db.Queryable().Where(m => m.IsDel == "0" && outLpnList.Contains(m.PalletNo)).ToListAsync(); //获取物料信息 var skuNo = await Db.Queryable().Where(a => a.IsDel == "0" && a.Type == "4").Select(a => a.SkuNo).ToListAsync(); var time = DateTime.Now; //Db.BeginTran(); //循环盘点明细的信息生成出库任务 foreach (var item in list) { if (item.Status == 0) { var logList = new List(); //判断是否为无码物料 if (skuNo.Contains(item.SkuNo)) { var de = outStockDetail.First(m => m.IsDel == "0" && m.SkuNo == item.SkuNo && m.LotNo == item.LotNo && m.PalletNo == item.PalletNo); var checkLog = new BllStockCheckLog() { CRNo = item.CRNo, PalletNo = item.PalletNo, BoxNo = "", BoxNo2 = "", BoxNo3 = "", Qty = (int?)de.Qty, SkuNo = de.SkuNo, SkuName = de.SkuName, Standard = de.Standard, LotNo = de.LotNo, LotText = de.LotText, SupplierLot = de.SupplierLot, CreateUser = _userManager.UserId, CreateTime = time }; logList.Add(checkLog); } else { var de = outStockDetail.Where(m => m.SkuNo == item.SkuNo && m.LotNo == item.LotNo && m.PalletNo == item.PalletNo).Select(m => m.Id).ToList(); var bo = outStockBox.Where(m => de.Contains(m.StockDetailId)).ToList(); foreach (var b in bo) { var checkLog = new BllStockCheckLog() { CRNo = item.CRNo, PalletNo = item.PalletNo, BoxNo = b.BoxNo, BoxNo2 = b.BoxNo2, BoxNo3 = b.BoxNo3, Qty = b.Qty, SkuNo = b.SkuNo, SkuName = b.SkuName, Standard = b.Standard, LotNo = b.LotNo, LotText = b.LotText, SupplierLot = b.SupplierLot, CreateUser = _userManager.UserId, CreateTime = time }; logList.Add(checkLog); } } //生成盘点记录 await Db.Insertable(logList).ExecuteCommandAsync(); } // 储位号 var locateNo = outStockDetail.First(m => m.PalletNo == item.PalletNo && m.SkuNo == item.SkuNo && m.LotNo == item.LotNo).LocatNo; #region 判断 //判断托盘是否在库内 if (string.IsNullOrWhiteSpace(locateNo)) { var de = outStockDetail.First(m => m.SkuNo == item.SkuNo && m.LotNo == item.LotNo && m.PalletNo == item.PalletNo); //判断是否是零箱库,当前明细信息直接更新出库完成 if (de != null && de.WareHouseNo == "W02") { //盘点明细状态改为待盘点 item.Status = 2; await Db.Updateable(item).ExecuteCommandAsync(); //盘点信息修改 if (notice.Status == 0) { notice.CheckDate = DateTime.Now; notice.Status = 1; notice.UpdateUser = _userManager.UserId; notice.UpdateTime = time; await Db.Updateable(notice).ExecuteCommandAsync(); } //库存中当前托盘的信息 var stockDetail = await Db.Queryable().Where(m => m.PalletNo == item.PalletNo).ToListAsync(); foreach (var s in stockDetail) { s.LocatNo = "";//储位更改(改为空) s.WareHouseNo = "";//所属仓库更改(改为空) s.RoadwayNo = "";//所属巷道更改(改为空) s.AreaNo = "";//所属区域更改(改为空) await Db.Updateable(s).ExecuteCommandAsync(); } flagList.Add(5); continue; } //判断托盘是否在入库中 var imBl = com.GetImTask(item.PalletNo); if (imBl != null) { flagList.Add(4); continue; } //判断是否是已经出过库又回库(状态为待拣货的 1) if (item.Status == 0) { //如果不在仓库内,当前明细信息直接更新出库完成 item.Status = 2;//状态 await Db.Updateable(item).ExecuteCommandAsync(); if (notice.Status == 0) { notice.CheckDate = DateTime.Now; notice.Status = 1; notice.UpdateUser = _userManager.UserId; notice.UpdateTime = time; await Db.Updateable(notice).ExecuteCommandAsync(); } } continue; } //当前出库的储位信息 var locate = await Db.Queryable().FirstAsync(m => m.LocatNo == locateNo && m.IsDel == "0"); if (locate == null) { flagList.Add(2); continue; } //判断储位标志是否为损坏 if (locate.Flag == "2") { flagList.Add(3); continue; } #endregion if (locate.Status == "1") //有物品 { #region 添加出库任务 var taskNo = new Common().GetMaxNo("TK"); //添加出库任务 var exTask = new LogTask { TaskNo = taskNo, Sender = "WMS", Receiver = "WCS", IsSuccess = 0, //是否下发成功 0失败 1成功 StartLocat = locate.LocatNo,//起始位置 EndLocat = outMode,//目标位置 PalletNo = item.PalletNo,//托盘码 IsSend = 1,//是否可再次下发 IsCancel = 1,//是否可取消 IsFinish = 1,//是否可完成 Type = "1",//任务类型 0 入库任务 1 出库任务 2 移库任务 Status = "0",//任务状态0:等待执行1正在执行2执行完成 OrderType = "2",//0 入库单 1 出库单 2 盘点单 3 移库单 CreateTime = time }; await Db.Insertable(exTask).ExecuteCommandAsync(); outDtoList.Add(new OutCommandDto() { PalletNo = item.PalletNo,//托盘号 StartLocate = locate.LocatNo, // 起始位置 StartRoadway = locate.RoadwayNo, EndLocate = "", // 目标位置 TaskNo = exTask.TaskNo, // 任务号 TaskType = "1",// 任务类型 (出库) OutMode = "", //目标地址 Order = 1 }); #endregion #region 改变数据 if (item.Status == 0)//判断托盘是否下发过 { if (notice.Status == 0) { notice.CheckDate = DateTime.Now; notice.Status = 1; notice.UpdateUser = _userManager.UserId; notice.UpdateTime = time; await Db.Updateable(notice).ExecuteCommandAsync(); } } locate.Status = "3"; //要出库的储位改变状态 正在出库 await Db.Updateable(locate).ExecuteCommandAsync(); item.TaskNo = exTask.TaskNo; // 出库分配信息中更新任务号 item.Status = 1; // 出库分配信息状态改为正在执行 await Db.Updateable(item).ExecuteCommandAsync(); #endregion flagList.Add(0); } else if (locate.Status == "3") //出库中 { #region 改变数据 //判断是否是已经出过库又回库(状态为待拣货的 1) if (item.Status == 0) { if (notice.Status == 0) { notice.CheckDate = DateTime.Now; notice.Status = 1; notice.UpdateUser = _userManager.UserId; notice.UpdateTime = time; await Db.Updateable(notice).ExecuteCommandAsync(); } } var taskNo = Db.Queryable().First(m => m.OrderType == "2" && m.TaskNo != item.TaskNo && m.Status == "1" && m.PalletNo == item.PalletNo); item.TaskNo = taskNo.TaskNo; item.Status = 1; // 出库分配信息状态改为正在执行 await Db.Updateable(item).ExecuteCommandAsync(); #endregion } else if (locate.Status == "5") //移出中 { flagList.Add(1); } } //添加操作日志记录 //var k = new OperationCrServer().AddLogOperationCr("库内作业", "盘点单据", crNo, "出库", $"点击出库按钮盘点单号为:{crNo}的盘点单", userId); await _operation.AddLogOperationCr(new OperationInputVm() { ParentName = "库内作业", MenuName = "盘点单据", FkNo = crNo, TypeName = "出库", Msg = $"点击出库按钮盘点单号为:{crNo}的盘点单" }); //Db.CommitTran(); str = string.Empty; if (flagList.Count(m => m == 1) > 0) { str += "1.当前要出库的储位正在移出、"; } if (flagList.Count(m => m == 2) > 0) { str += "2.出库的托盘储位信息错误(在储位表中未查询到)、"; } if (flagList.Count(m => m == 3) > 0) { str += "3.储位损坏不能出库、"; } if (flagList.Count(m => m == 4) > 0) { str += "4.要出库的托盘正在入库、"; } if (flagList.Count(m => m == 5) > 0) { str += "5.要出库的托盘在零箱库、"; } if (!string.IsNullOrEmpty(str)) throw Oops.Bah(str); if (outDtoList.Count > 0) { // 正式运行程序放开 var list2 = outDtoList.Select(m => m.TaskNo).ToList(); var jsonData = JsonConvert.SerializeObject(outDtoList); string response = ""; 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 Oops.Bah(wcsModel.Msg); //} } return outDtoList; #endregion } /// /// 视觉盘点 /// /// /// /// /// public async Task> CheckVision(string crNo, string url, string str) { #region 集合 var outDtoList = new List(); //出库数据的集合 //记录错误信息的集合 var flagList = new List();//1:当前要出库的储位正在移出、2 出库的托盘储位信息错误(在储位表中未查询到)、3储位损坏不能出库、4 要出库的托盘正在入库 #endregion var com = new Common(); //assign.IsHavePyTask(); var notice = await Db.Queryable().FirstAsync(m => m.CRNo == crNo && m.IsDel == "0"); if (notice == null) { throw Oops.Bah($"未找到{crNo}盘点单信息"); } //所有要出库的盘点明细信息(等待的信息和待拣货的信息) var funSetting = Db.Queryable().First(a => a.IsDel == "0" && a.FunSetNo == "InventoryCheckMethod"); if (funSetting == null || funSetting.IsEnable == "OFF") { throw Oops.Bah("需配置盘点方式"); } var list = await Db.Queryable().Where(a => a.IsDel == "0" && a.CRNo == crNo && (a.Status == 0 || a.Status == 1 || a.Status == 2)).ToListAsync(); if (list.Count == 0) //判断是否有需要下发的盘点明细 { throw Oops.Bah("当前盘点单据无需要下发的托盘"); } if (funSetting.SetValue == "once") { if (list.Any(s => s.Status == 1 || s.Status == 2)) { throw Oops.Bah("已有正在出库或待盘点的数据,请完成盘点后再出库"); } list = new List() { list.FirstOrDefault() }; } else { list = list.Where(s => s.Status == 0).ToList(); } #region //要出库的托盘集合 var outLpnList = list.Select(m => m.PalletNo).Distinct().ToList(); //要出库的明细集合 var outStockDetail = await Db.Queryable().Where(m => m.IsDel == "0" && outLpnList.Contains(m.PalletNo)).ToListAsync(); var outStockBox = await Db.Queryable().Where(m => m.IsDel == "0" && outLpnList.Contains(m.PalletNo)).ToListAsync(); //获取物料信息 var skuNo = await Db.Queryable().Where(a => a.IsDel == "0" && a.Type == "4").Select(a => a.SkuNo).ToListAsync(); var time = DateTime.Now; //Db.BeginTran(); //循环盘点明细的信息生成出库任务 foreach (var item in list) { if (item.Status == 0) { var logList = new List(); //判断是否为无码物料 if (skuNo.Contains(item.SkuNo)) { var de = outStockDetail.First(m => m.IsDel == "0" && m.SkuNo == item.SkuNo && m.LotNo == item.LotNo && m.PalletNo == item.PalletNo); var checkLog = new BllStockCheckLog() { CRNo = item.CRNo, PalletNo = item.PalletNo, BoxNo = "", BoxNo2 = "", BoxNo3 = "", Qty = (int?)de.Qty, SkuNo = de.SkuNo, SkuName = de.SkuName, Standard = de.Standard, LotNo = de.LotNo, LotText = de.LotText, SupplierLot = de.SupplierLot, CreateUser = _userManager.UserId, CreateTime = time }; logList.Add(checkLog); } else { var de = outStockDetail.Where(m => m.SkuNo == item.SkuNo && m.LotNo == item.LotNo && m.PalletNo == item.PalletNo).Select(m => m.Id).ToList(); var bo = outStockBox.Where(m => de.Contains(m.StockDetailId)).ToList(); foreach (var b in bo) { var checkLog = new BllStockCheckLog() { CRNo = item.CRNo, PalletNo = item.PalletNo, BoxNo = b.BoxNo, BoxNo2 = b.BoxNo2, BoxNo3 = b.BoxNo3, Qty = b.Qty, SkuNo = b.SkuNo, SkuName = b.SkuName, Standard = b.Standard, LotNo = b.LotNo, LotText = b.LotText, SupplierLot = b.SupplierLot, CreateUser = _userManager.UserId, CreateTime = time }; logList.Add(checkLog); } } //生成盘点记录 await Db.Insertable(logList).ExecuteCommandAsync(); } // 储位号 var locateNo = outStockDetail.First(m => m.PalletNo == item.PalletNo && m.SkuNo == item.SkuNo && m.LotNo == item.LotNo).LocatNo; #region 判断 //判断托盘是否在库内 if (string.IsNullOrWhiteSpace(locateNo)) { var de = outStockDetail.First(m => m.SkuNo == item.SkuNo && m.LotNo == item.LotNo && m.PalletNo == item.PalletNo); //判断是否是零箱库,当前明细信息直接更新出库完成 if (de != null && de.WareHouseNo == "W02") { //盘点明细状态改为待盘点 item.Status = 2; await Db.Updateable(item).ExecuteCommandAsync(); //盘点信息修改 if (notice.Status == 0) { notice.CheckDate = DateTime.Now; notice.Status = 1; notice.UpdateUser = _userManager.UserId; notice.UpdateTime = time; await Db.Updateable(notice).ExecuteCommandAsync(); } //库存中当前托盘的信息 var stockDetail = await Db.Queryable().Where(m => m.PalletNo == item.PalletNo).ToListAsync(); foreach (var s in stockDetail) { s.LocatNo = "";//储位更改(改为空) s.WareHouseNo = "";//所属仓库更改(改为空) s.RoadwayNo = "";//所属巷道更改(改为空) s.AreaNo = "";//所属区域更改(改为空) await Db.Updateable(s).ExecuteCommandAsync(); } flagList.Add(5); continue; } //判断托盘是否在入库中 var imBl = com.GetImTask(item.PalletNo); if (imBl != null) { flagList.Add(4); continue; } //判断是否是已经出过库又回库(状态为待拣货的 1) if (item.Status == 0) { //如果不在仓库内,当前明细信息直接更新出库完成 item.Status = 2;//状态 await Db.Updateable(item).ExecuteCommandAsync(); if (notice.Status == 0) { notice.CheckDate = DateTime.Now; notice.Status = 1; notice.UpdateUser = _userManager.UserId; notice.UpdateTime = time; await Db.Updateable(notice).ExecuteCommandAsync(); } } continue; } //当前出库的储位信息 var locate = await Db.Queryable().FirstAsync(m => m.LocatNo == locateNo && m.IsDel == "0"); if (locate == null) { flagList.Add(2); continue; } //判断储位标志是否为损坏 if (locate.Flag == "2") { flagList.Add(3); continue; } #endregion if (locate.Status == "1") //有物品 { #region 添加视觉盘点任务 var taskNo = new Common().GetMaxNo("TK"); var exTask = new LogTask { TaskNo = taskNo, Sender = "WMS", Receiver = "WCS", IsSuccess = 0, //是否下发成功 0失败 1成功 StartLocat = locate.LocatNo,//起始位置 //EndLocat = outMode,//目标位置 PalletNo = item.PalletNo,//托盘码 IsSend = 1,//是否可再次下发 IsCancel = 1,//是否可取消 IsFinish = 1,//是否可完成 Type = "1",//任务类型 0 入库任务 1 出库任务 2 移库任务 Status = "0",//任务状态0:等待执行1正在执行2执行完成 OrderType = "6",////0 入库单 1 出库单 2 盘点单 3 移库单 4 取样出库单 6视觉盘点 Msg = $"{locateNo}的视觉盘点任务", CreateTime = time }; await Db.Insertable(exTask).ExecuteCommandAsync(); outDtoList.Add(new OutCommandDto() { PalletNo = item.PalletNo,//托盘号 StartLocate = locate.LocatNo, // 起始位置 StartRoadway = locate.RoadwayNo, EndLocate = "", // 目标位置 TaskNo = exTask.TaskNo, // 任务号 TaskType = "1",// 任务类型 (出库) OutMode = "", //目标地址 Order = 1 }); #endregion #region 改变数据 if (item.Status == 0)//判断托盘是否下发过 { if (notice.Status == 0) { notice.CheckDate = DateTime.Now; notice.Status = 1; notice.UpdateUser = _userManager.UserId; notice.UpdateTime = time; await Db.Updateable(notice).ExecuteCommandAsync(); } } //locate.Status = "3"; //要出库的储位改变状态 正在出库 await Db.Updateable(locate).ExecuteCommandAsync(); item.TaskNo = exTask.TaskNo; // 出库分配信息中更新任务号 item.Status = 1; // 出库分配信息状态改为正在执行 await Db.Updateable(item).ExecuteCommandAsync(); #endregion flagList.Add(0); } else if (locate.Status == "3") //出库中 { #region 改变数据 //判断是否是已经出过库又回库(状态为待拣货的 1) if (item.Status == 0) { if (notice.Status == 0) { notice.CheckDate = DateTime.Now; notice.Status = 1; notice.UpdateUser = _userManager.UserId; notice.UpdateTime = time; await Db.Updateable(notice).ExecuteCommandAsync(); } } var taskNo = Db.Queryable().First(m => m.OrderType == "2" && m.TaskNo != item.TaskNo && m.Status == "1" && m.PalletNo == item.PalletNo); item.TaskNo = taskNo.TaskNo; item.Status = 1; // 出库分配信息状态改为正在执行 await Db.Updateable(item).ExecuteCommandAsync(); #endregion } else if (locate.Status == "5") //移出中 { flagList.Add(1); } } //添加操作日志记录 //var k = new OperationCrServer().AddLogOperationCr("库内作业", "盘点单据", crNo, "出库", $"点击出库按钮盘点单号为:{crNo}的盘点单", userId); await _operation.AddLogOperationCr(new OperationInputVm() { ParentName = "库内作业", MenuName = "盘点单据", FkNo = crNo, TypeName = "出库", Msg = $"点击出库按钮盘点单号为:{crNo}的盘点单" }); //Db.CommitTran(); str = string.Empty; if (flagList.Count(m => m == 1) > 0) { str += "1.当前要出库的储位正在移出、"; } if (flagList.Count(m => m == 2) > 0) { str += "2.出库的托盘储位信息错误(在储位表中未查询到)、"; } if (flagList.Count(m => m == 3) > 0) { str += "3.储位损坏不能出库、"; } if (flagList.Count(m => m == 4) > 0) { str += "4.要出库的托盘正在入库、"; } if (flagList.Count(m => m == 5) > 0) { str += "5.要出库的托盘在零箱库、"; } if (!string.IsNullOrEmpty(str)) throw Oops.Bah(str); if (outDtoList.Count > 0) { // 正式运行程序放开 var list2 = outDtoList.Select(m => m.TaskNo).ToList(); var jsonData = JsonConvert.SerializeObject(outDtoList); string response = ""; 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 Oops.Bah(wcsModel.Msg); //} } return outDtoList; #endregion } /// /// 视觉盘点传结果 /// /// /// /// /// public async Task CheckVision(CheckVm model) { if (string.IsNullOrWhiteSpace(model.CrNo)) { throw Oops.Bah("盘点单据不能为空"); } if (string.IsNullOrWhiteSpace(model.SkuNo)) { throw Oops.Bah("物料不能为空"); } if (string.IsNullOrWhiteSpace(model.LotNo)) { throw Oops.Bah("物料批次不能为空"); } if (string.IsNullOrWhiteSpace(model.PalletNo)) { throw Oops.Bah("托盘码不能为空"); } //盘点明细 var checkDetail = await Db.Queryable().FirstAsync(m => m.IsDel == "0" && m.CRNo == model.CrNo && m.PalletNo == model.PalletNo && m.SkuNo == model.SkuNo && m.LotNo == model.LotNo); if (checkDetail == null) { throw Oops.Bah("未查询到未盘点的盘点明细信息"); } var modSku = await Db.Queryable().Where(s => s.SkuNo == model.SkuNo).FirstAsync(); } //盘点出库完成 public async Task CheckSuccess(string taskNo, int userId) { try { //当前任务信息 var task = Db.Queryable().First(m => m.TaskNo == taskNo && m.IsDel == "0"); if (task == null) { throw Oops.Bah($"未查询到任务号为:‘{taskNo}’的任务信息"); } if (task.Status == "2") { throw Oops.Bah("当前任务已完成"); } Db.BeginTran(); //库存中当前托盘的信息 var stockDetail = await Db.Queryable().Where(m => m.PalletNo == task.PalletNo).ToListAsync(); var locateNo = stockDetail.Select(m => m.LocatNo).Distinct().FirstOrDefault(); //当前任务中的储位信息 var locate = await Db.Queryable().FirstAsync(m => m.LocatNo == locateNo); task.Status = "2";//任务状态 task.IsSend = 0; task.IsCancel = 0; task.IsFinish = 0; task.FinishDate = DateTime.Now;//完成时间 await Db.Updateable(task).ExecuteCommandAsync(); if(task.OrderType != "6")//视觉盘点不更改状态 { locate.Status = "0"; // 更改当前任务中的储位状态(改为0空储位) await Db.Updateable(locate).ExecuteCommandAsync(); foreach (var item in stockDetail) { item.LocatNo = "";//储位更改(改为空) item.WareHouseNo = "";//所属仓库更改(改为空) item.RoadwayNo = "";//所属巷道更改(改为空) item.AreaNo = "";//所属区域更改(改为空) await Db.Updateable(item).ExecuteCommandAsync(); } } //盘点明细(更改状态) var checkDetails = await Db.Queryable().Where(m => m.IsDel == "0" && (m.TaskNo == taskNo || (m.Status == 1 && m.PalletNo == task.PalletNo))).ToListAsync(); foreach (var item in checkDetails) { item.Status = 2; await Db.Updateable(item).ExecuteCommandAsync(); } if (_userManager.UserId != 0) { //添加操作日志记录 //var k = new OperationCrServer().AddLogOperationCr("库内作业", "库内日志", taskNo, "完成", $"点击完成按钮、完成任务号为:{taskNo}的任务", userId); await _operation.AddLogOperationCr(new OperationInputVm() { ParentName = "库内作业", MenuName = "库内日志", FkNo = taskNo, TypeName = "完成", Msg = $"点击完成按钮、完成任务号为:{taskNo}的任务" }); } Db.CommitTran(); } catch (Exception ex) { Db.RollbackTran(); throw new Exception("完成反馈失败:" + ex.Message); } } //AGV移库完成 public async Task MoveSuccess(string taskNo) { try { //当前任务信息 var task = Db.Queryable().First(m => m.TaskNo == taskNo && m.IsDel == "0"); if (task == null) { throw new Exception($"未查询到任务号为:‘{taskNo}’的任务信息"); } if (task.Status == "2") { throw new Exception("当前任务已完成"); } Db.BeginTran(); //库存中当前托盘的信息 var stockDetail = Db.Queryable().Where(m => m.PalletNo == task.PalletNo).ToList(); //当前任务中的目标储位信息 //当前任务中的原储位 var locate = Db.Queryable().First(m => m.LocatNo == task.StartLocat); if (locate == null) { throw new Exception($"WMS系统中没有该{task.StartLocat}储位对应的信息"); } var locate2 = Db.Queryable().First(m => m.LocatNo == task.EndLocat); if (locate2 == null) { throw new Exception($"WMS系统中没有该{task.EndLocat}储位对应的信息"); } //平库中储位集合 var pingKuLocate = Db.Queryable().Where(m => m.WareHouseNo == "W04" && m.IsDel == "0").ToList(); //车间暂存区 var pingKuLocate2 = Db.Queryable().Where(m => m.WareHouseNo == "W04" && m.IsDel == "0" && (m.AreaNo == "B06" || m.AreaNo == "B07")).ToList(); var pingKuList = pingKuLocate.Select(m => m.LocatNo).ToList(); try { task.Status = "2";//任务状态 //判断起始目标位置都是平库 if (pingKuList.Contains(task.StartLocat) && pingKuList.Contains(task.EndLocat)) { task.Status = "5"; } task.IsSend = 0; task.IsCancel = 0; task.IsFinish = 0; task.FinishDate = DateTime.Now;//完成时间 Db.Updateable(task).ExecuteCommand(); #region 修改储位状态 if (!pingKuList.Contains(task.StartLocat)) { //原储位改为空储位 0 locate.Status = "0"; Db.Updateable(locate).ExecuteCommand(); } //目标储位改为有货物 1 locate2.Status = "1"; Db.Updateable(locate2).ExecuteCommand(); //判断目标位置如果不是是车间暂存区 并且是平库储位 更改库存位置 if (pingKuLocate2.Count(m=>m.LocatNo == task.EndLocat)<=0 && pingKuList.Contains(task.EndLocat)) { foreach (var item in stockDetail) { item.WareHouseNo = locate2.WareHouseNo; item.AreaNo = locate2.AreaNo; item.RoadwayNo = locate2.RoadwayNo; item.LocatNo = locate2.LocatNo; } Db.Updateable(stockDetail).ExecuteCommand(); } #endregion if (_userManager.UserId != 0) { //添加操作日志记录 //var k = new OperationCrServer().AddLogOperationCr("库内作业", "库内日志", taskNo, "完成", $"点击完成按钮、完成任务号为:{taskNo}的任务", userId); await _operation.AddLogOperationCr(new OperationInputVm() { ParentName = "库内作业", MenuName = "库内日志", FkNo = taskNo, TypeName = "完成", Msg = $"点击完成按钮、完成任务号为:{taskNo}的任务" }); } Db.CommitTran(); } catch (Exception ex) { Db.RollbackTran(); throw new Exception(ex.Message); } } catch (Exception ex) { Db.RollbackTran(); throw new Exception("完成反馈失败:" + ex.Message); } } //重新下发盘点出库任务 public async Task AgainSendCheckTask(string taskNo, string url) { try { var task = await Db.Queryable().FirstAsync(m => m.TaskNo == taskNo && m.IsDel == "0"); if (task == null) { throw Oops.Bah("未查询到任务信息"); } var stockDetail = await Db.Queryable().FirstAsync(m => m.PalletNo == task.PalletNo); if (stockDetail == null) { throw Oops.Bah(task.PalletNo + " 当前托盘未在库内,请核实信息"); } Db.BeginTran(); var locateNo = task.StartLocat; //判断任务中起始位置是否和库存中位置一致 if (task.StartLocat != stockDetail.LocatNo) { locateNo = stockDetail.LocatNo; task.StartLocat = locateNo; await Db.Updateable(task).ExecuteCommandAsync(); } var locate = Db.Queryable().First(m => m.LocatNo == locateNo); if (locate != null && locate.Status != "3") { locate.Status = "3"; await Db.Updateable(locate).ExecuteCommandAsync(); } var outDto = new OutCommandDto() { PalletNo = task.PalletNo,//托盘号 StartLocate = locateNo, // 起始位置 StartRoadway = locate.RoadwayNo, EndLocate = "", // 目标位置 TaskNo = task.TaskNo, // 任务号 TaskType = "1",// 任务类型 (出库) OutMode = "", //目标地址 Order = 1 }; //出库数据 //添加操作日志记录 //var k = new OperationCrServer().AddLogOperationCr("库内作业", "库内日志", taskNo, "下发", $"点击下发按钮、重新下发了任务号为:{taskNo}的任务", userId); await _operation.AddLogOperationCr(new OperationInputVm() { ParentName = "库内作业", MenuName = "库内日志", FkNo = taskNo, TypeName = "下发", Msg = $"点击下发按钮、重新下发了任务号为:{taskNo}的任务" }); Db.CommitTran(); // 正式运行程序放开 var list = new List { outDto.TaskNo }; var jsonData = JsonConvert.SerializeObject(outDto); try { //程序正式发布后放开 var time1 = DateTime.Now;//发送时间 .ToString("yyyy-MM-dd HH:mm:ss") var 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.code == 200) { //更改任务的发送返回时间// new TaskServer().EditTaskIssueOk(list, time1, time2); } else { new TaskServer().EditTaskIssueNo(list, time1, time2, wcsModel.message); throw new Exception($"wcs返回状态异常:{wcsModel.message}"); } } catch (Exception ex) { throw new Exception(ex.Message); } return outDto; } catch (Exception e) { Db.RollbackTran(); throw new Exception(e.Message); } } //取消盘点出库任务 public async Task CancelCheckTask(string taskNo) { try { Db.BeginTran(); try { var task = await Db.Queryable().FirstAsync(m => m.TaskNo == taskNo && m.IsDel == "0"); if (task == null) { throw Oops.Bah("未查询到任务信息"); } //修改任务 task.IsSuccess = 0; task.IsSend = 0; task.IsCancel = 0; task.IsFinish = 0; task.Status = "4"; task.CancelDate = DateTime.Now; await Db.Updateable(task).ExecuteCommandAsync(); //修改盘点明细 var checkDetail = await Db.Queryable().FirstAsync(w => w.TaskNo == task.TaskNo); if (checkDetail == null) { throw Oops.Bah("未查询到盘点明细信息,请核实!"); } checkDetail.Status = 0; checkDetail.TaskNo = ""; await Db.Updateable(checkDetail).ExecuteCommandAsync(); //修改盘点记录 var checkLog = await Db.Queryable().FirstAsync(w => w.CRNo == checkDetail.CRNo && w.PalletNo == checkDetail.PalletNo && w.IsDel == "0"); if (checkLog == null) { throw Oops.Bah("未查询到盘点记录信息,请核实!"); } checkLog.IsDel = "1"; await Db.Updateable(checkLog).ExecuteCommandAsync(); //修改储位信息 var locat = await Db.Queryable().FirstAsync(a => a.IsDel == "0" && a.WareHouseNo == "W02" && a.LocatNo == task.StartLocat); if (locat == null) { throw Oops.Bah("未查询到储位信息,请核实!"); } locat.Status = "1"; //有物品 await Db.Updateable(locat).ExecuteCommandAsync(); //添加操作日志记录 //var k = new OperationCrServer().AddLogOperationCr("库内作业", "库内日志", taskNo, "取消", $"点击取消按钮、取消了任务号为:{taskNo}的任务", userId); await _operation.AddLogOperationCr(new OperationInputVm() { ParentName = "库内作业", MenuName = "库内日志", FkNo = taskNo, TypeName = "取消", Msg = $"点击取消按钮、取消了任务号为:{taskNo}的任务" }); Db.CommitTran(); } catch (Exception e) { Db.RollbackTran(); throw new Exception(e.Message); } } catch (Exception e) { throw new Exception(e.Message); } } //取消AGV移库任务 public async Task CancelMoveTask(string taskNo) { try { Db.BeginTran(); var task = await Db.Queryable().FirstAsync(m => m.TaskNo == taskNo && m.IsDel == "0"); if (task == null) { throw Oops.Bah("未查询到任务信息"); } //修改任务 task.IsSuccess = 0; task.IsSend = 0; task.IsCancel = 0; task.IsFinish = 0; task.Status = "4"; task.CancelDate = DateTime.Now; await Db.Updateable(task).ExecuteCommandAsync(); //修改起始储位信息 var locat = await Db.Queryable().FirstAsync(a => a.IsDel == "0" && a.WareHouseNo == "W02" && a.LocatNo == task.StartLocat); if (locat == null) { throw Oops.Bah("未查询到储位信息,请核实!"); } locat.Status = "1"; //有物品 Db.Updateable(locat).ExecuteCommand(); //修改目标储位信息 var locatEnd = await Db.Queryable().FirstAsync(a => a.IsDel == "0" && a.WareHouseNo == "W02" && a.LocatNo == task.EndLocat); if (locatEnd != null) { locatEnd.Status = "0"; //空储位 await Db.Updateable(locatEnd).ExecuteCommandAsync(); } //修改库存明细 var stockDetail = await Db.Queryable().FirstAsync(w => w.IsDel == "0" && w.PalletNo == task.PalletNo); if (stockDetail == null) { throw Oops.Bah("托盘上物料库存明细信息不存在,请检查!"); } stockDetail.Status = "0";//待分配 stockDetail.LockQty = 0;//锁定数量 await Db.Updateable(stockDetail).ExecuteCommandAsync(); //修改库存 var stock = await Db.Queryable().FirstAsync(w => w.IsDel == "0" && w.SkuNo == stockDetail.SkuNo && w.LotNo == stockDetail.LotNo); if (stock == null) { throw Oops.Bah("托盘上物料库存信息不存在,请检查!"); } stock.LockQty -= (decimal)stockDetail.Qty; await Db.Updateable(stock).ExecuteCommandAsync(); //添加操作日志记录 //var k = new OperationCrServer().AddLogOperationCr("库内作业", "库内日志", taskNo, "取消", $"点击取消按钮、取消了任务号为:{taskNo}的任务", userId); await _operation.AddLogOperationCr(new OperationInputVm() { ParentName = "库内作业", MenuName = "库内日志", FkNo = taskNo, TypeName = "取消", Msg = $"点击取消按钮、取消了任务号为:{taskNo}的任务" }); Db.CommitTran(); } catch (Exception e) { Db.RollbackTran(); throw new Exception(e.Message); } } #region 上游系统接口 //盘点结果返回erp public bool FinishCr(int id, string url, int userId) { throw new NotImplementedException(); //try //{ // //Db.BeginTran(); // //try // //{ // //} // //catch (Exception e) // //{ // // Console.WriteLine(e); // // throw; // //} // Db.CommitTran(); //} //catch (Exception e) //{ // Db.RollbackTran(); // throw new Exception(e.Message); //} } #endregion #region 数据归档 /// /// 获取盘点单据-数据归档 /// /// public List GetArchivingStockCheckList(string crNo, string status, string palletNo, string skuNo, string skuName, string lotNo, string startTime, string endTime, int page, int limit, out int count) { try { string sqlString = string.Empty; string sqlCount = string.Empty; string sqlPub = string.Empty; sqlCount += "SELECT COUNT(tb1.ID) FROM ArchivingStockCheck AS tb1 "; sqlString += "select tb1.*,tb2.RealName as AuditUserName,tb3.RealName as CreateUserName,tb4.RealName as UpdateUserName from ArchivingStockCheck as tb1 "; sqlPub += "left join SysUserInfor as tb2 on tb1.AuditUser=tb2.Id "; sqlPub += "left join SysUserInfor as tb3 on tb1.CreateUser=tb3.Id "; sqlPub += "left join SysUserInfor as tb4 on tb1.UpdateUser=tb4.Id "; sqlPub += "where tb1.IsDel = '0' "; if (!string.IsNullOrEmpty(crNo)) { sqlPub += $"AND tb1.CRNo like '%{crNo.Trim()}%' "; } if (!string.IsNullOrEmpty(status)) { sqlPub += $"AND tb1.Status = {int.Parse(status)} "; } if (!string.IsNullOrEmpty(startTime)) { sqlPub += $"AND tb1.CheckDate >= '{Convert.ToDateTime(startTime)}' "; } if (!string.IsNullOrEmpty(endTime)) { sqlPub += $"AND tb1.CheckDate <= '{Convert.ToDateTime(endTime)}' "; } if (!string.IsNullOrEmpty(palletNo) || !string.IsNullOrEmpty(skuNo) || !string.IsNullOrEmpty(skuName) || !string.IsNullOrEmpty(lotNo)) { string detailSql = $"select Distinct CRNo from ArchivingStockCheckDetail as de where 1=1 "; if (!string.IsNullOrEmpty(palletNo)) { detailSql += $"AND de.PalletNo like '%{palletNo.Trim()}%' "; } if (!string.IsNullOrEmpty(skuNo)) { detailSql += $"AND de.SkuNo like '%{skuNo.Trim()}%' "; } if (!string.IsNullOrEmpty(skuName)) { detailSql += $"AND de.SkuName like '%{skuName.Trim()}%' "; } if (!string.IsNullOrEmpty(lotNo)) { detailSql += $"AND de.LotNo like '%{lotNo.Trim()}%' "; } sqlPub += $"AND tb1.CRNo in ({detailSql}) "; } sqlCount += sqlPub; sqlPub += " order by tb1.CreateTime desc "; if (page == 0) { page = 1; } sqlString += sqlPub + $" offset {((page - 1) * limit)} rows fetch next {limit} rows only;"; var com = new Common(); count = com.GetRowCount(sqlCount); var modelList = Db.Ado.SqlQuery(sqlString); return modelList; } catch (Exception e) { throw new Exception(e.Message); } } /// /// 获取盘点单据明细-数据归档 /// /// public List GetArchivingStockCheckDetailList(string crNo, int page, int limit, out int count) { try { string sqlString = string.Empty; string sqlCount = string.Empty; string sqlPub = string.Empty; sqlCount += "SELECT COUNT(tb1.ID) FROM ArchivingStockCheckDetail AS tb1 "; sqlString += "select tb1.*,tb2.RealName as CreateUserName,tb3.RealName as UpdateUserName from ArchivingStockCheckDetail as tb1 "; sqlPub += "left join SysUserInfor as tb2 on tb1.CreateUser=tb2.Id "; sqlPub += "left join SysUserInfor as tb3 on tb1.UpdateUser=tb3.Id "; sqlPub += $"where tb1.IsDel = '0' and tb1.CRNo='{crNo}'"; sqlCount += sqlPub; sqlPub += " order by tb1.CreateTime desc "; if (page == 0) { page = 1; } sqlString += sqlPub + $" offset {((page - 1) * limit)} rows fetch next {limit} rows only;"; var com = new Common(); count = com.GetRowCount(sqlCount); var modelList = Db.Ado.SqlQuery(sqlString); return modelList; } catch (Exception e) { throw new Exception(e.Message); } } #endregion } }