using Model.InterFaceModel; using Model.ModelDto.BllSoDto; using Model.ModelVm.BllSoVm; using SqlSugar; using System; using System.Collections; using System.Collections.Generic; using System.Data; using System.Linq; using System.Linq.Expressions; using System.Xml; using Model.ModelDto.DataDto; using Newtonsoft.Json; using Utility.Tools; using WMS.BLL.DataServer; using WMS.BLL.Logic; using WMS.BLL.LogServer; using WMS.DAL; using WMS.Entity.BllSoEntity; using WMS.Entity.Context; using WMS.Entity.DataEntity; using WMS.Entity.LogEntity; using WMS.Entity.SysEntity; using WMS.IBLL.IBllSoServer; using Model.ModelVm; using System.Runtime.Intrinsics.X86; namespace WMS.BLL.BllSoServer { public class ExportNoticeServer : DbHelper, IExportNoticeServer { private static readonly SqlSugarScope Db = DataContext.Db; public ExportNoticeServer() : base(Db) { } #region 上游接口 /// /// 创建出库单据 /// /// /// public bool ErpAddExportNotice(SoInfo model) { try { if (string.IsNullOrEmpty(model.SoType)) { throw new Exception("单据类型不可为空!"); } if (string.IsNullOrEmpty(model.Customer)) { throw new Exception("客户不可为空!"); } if (string.IsNullOrEmpty(model.OrderCode)) { throw new Exception("系统单号不可为空!"); } if (model.SoDetails.Count <= 0) { throw new Exception("出库单明细不可为空!"); } var skuNos = model.SoDetails.Select(a => a.SkuNo).Distinct().ToList(); //根据物料号获取物料信息、库存明细中获取批次描述供货批次等 var skuList = Db.Queryable().Where(a => skuNos.Contains(a.SkuNo) && a.IsDel == "0").ToList(); var stockList = Db.Queryable().Where(s => skuNos.Contains(s.SkuNo) && (s.Qty - s.FrozenQty - s.LockQty) > 0).ToList(); //客户信息 var customer = Db.Queryable().First(m => m.IsDel == "0" && m.CustomerNo == model.Customer); if (customer == null) { throw new Exception("客户不可为空!"); } var logistics = Db.Queryable().First(m => m.IsDel == "0" && m.CarrierName == model.LogisticsNo); int? logisticsId = null; if (logistics != null) { logisticsId = logistics.Id; } var billNo = ""; var bl = true; do { //获取自增单据号 billNo = new Common().GetMaxNo("SO"); var no = billNo; bl = Db.Queryable().Any(m => m.SONo == no); } while (bl); Db.BeginTran();//开启事务 try { var list = new List(); //添加出库单 foreach (var d in model.SoDetails) { if (d.Qty < 1) { throw new Exception("出库数量必须大于0"); } var sku = skuList.FirstOrDefault(a => a.SkuNo == d.SkuNo); if (sku == null) { throw new Exception($"物料信息中未查询到出库物料信息:{d.SkuNo}"); } //库存 List stocks; if (!string.IsNullOrWhiteSpace(d.LotNo)) { stocks = stockList.Where(s => s.SkuNo == d.SkuNo && s.LotNo == d.LotNo).ToList(); } else { stocks = stockList.Where(s => s.SkuNo == d.SkuNo && string.IsNullOrWhiteSpace(s.LotNo)).ToList(); } if (stocks.Count < 1) { throw new Exception($"总库存中未查询到出库物料信息:{d.SkuNo}"); } var item = new BllExportNoticeDetail() { SONo = billNo, SkuNo = sku.SkuNo, SkuName = sku.SkuName, Standard = sku.Standard, LotNo = d.LotNo, LotText = "", Qty = d.Qty, AllotQty = 0, FactQty = 0, CompleteQty = 0, PackagNo = sku.PackagNo, Price = sku.Price, Money = string.IsNullOrWhiteSpace(sku.Price.ToString()) ? null : sku.Price * d.Qty, IsBale = "", IsBelt = "", SupplierLot = stocks.First().SupplierLot, IsWave = "0", WaveNo = "", CreateUser = 0, }; list.Add(item); stocks.First().LockQty += d.Qty;//锁定数量 var i = Db.Updateable(stocks.First()).UpdateColumns(it => new { it.LockQty }) .ExecuteCommand(); } var notice = new BllExportNotice() { SONo = billNo, Type = model.SoType, Status = "0", Origin = "WMS", CustomerNo = model.Customer, CustomerName = customer.CustomerName, LogisticsId = logisticsId, IsWave = "0", WaveNo = "", IsDespatch = "0", CreateUser = 0, }; var n = Db.Insertable(notice).ExecuteCommand(); var m = Db.Insertable(list).ExecuteCommand(); if (n <= 0 || m <= 0) { Db.RollbackTran(); return false; } Db.CommitTran(); return true; } catch (Exception ex) { Db.RollbackTran(); throw new Exception(ex.Message); } } catch (Exception ex) { Db.RollbackTran(); throw new Exception(ex.Message); } } //回传出库单 public bool FinishSo(int id, string url, int userId) { try { var notice = Db.Queryable().First(m => m.Id == id&& m.IsDel == "0"); if (notice == null) { throw new Exception("未查询到单据信息"); } var detail = Db.Queryable().Where(m => m.SONo == notice.SONo && m.IsDel == "0").ToList(); if (detail.Count == 0) { throw new Exception("未查询到单据明细信息"); } var list = new List(); foreach (var d in detail) { var item = new SoDetail() { SkuNo = d.SkuNo, LotNo = d.LotNo, Qty = int.Parse(d.CompleteQty.ToString()) }; list.Add(item); } var soInfo = new SoInfo() { OrderCode = notice.OrderCode, SoDetails = list }; // 通过接口发送至erp var jsonData = JsonConvert.SerializeObject(soInfo); var response = HttpHelper.DoPost(url, jsonData, "出库单完成上传", "ERP"); //解析返回数据 var obj = JsonConvert.DeserializeObject(response); if (obj.Success != 0) { throw new Exception("上传失败" + obj.Message); } notice.Status = "6"; notice.UpdateTime = DateTime.Now; notice.UpdateUser = userId; Db.Updateable(notice).ExecuteCommand(); return true; } catch (Exception e) { throw new Exception(e.Message); } } #endregion #region 基础功能 public List GetExportNoticeList(string no, string type, string status, string lotNo, int? logisticsId, string isWave, string isDespatch, string waveNo, int page, int limit, out int count) { try { var strList = new List(); if (!string.IsNullOrWhiteSpace(lotNo)) { var detailList = Db.Queryable().Where(m => m.IsDel == "0" && m.LotNo.Contains(lotNo.Trim())).Select(m => m.SONo).Distinct().ToList(); strList = detailList; } Expression> item = Expressionable.Create() .AndIF(!string.IsNullOrWhiteSpace(no), it => it.SONo.Contains(no.Trim())) .AndIF(!string.IsNullOrWhiteSpace(type), it => it.Type == type) .AndIF(!string.IsNullOrWhiteSpace(status), it => it.Status == status) .AndIF(logisticsId != null, it => it.LogisticsId == logisticsId) .AndIF(!string.IsNullOrWhiteSpace(isWave), it => it.IsWave == isWave) .AndIF(!string.IsNullOrWhiteSpace(isDespatch), it => it.IsDespatch == isDespatch) .AndIF(!string.IsNullOrWhiteSpace(waveNo), it => it.WaveNo.Contains(waveNo.Trim())) .AndIF(!string.IsNullOrWhiteSpace(lotNo), it => strList.Contains(it.SONo)) .ToExpression();//注意 这一句 不能少 var total = 0; var data = GetAllWhereAsync(item) .LeftJoin((a, b) => a.LogisticsId == 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 ExportNoticeDto() { Id = a.Id, SONo = a.SONo, Type = a.Type, Status = a.Status, Origin = a.Origin, CustomerNo = a.CustomerNo, CustomerName = a.CustomerName, LotNo = a.LotNo, LotText = a.LotText, SupplierLot = a.SupplierLot, LogisticsId = a.LogisticsId, LogisticsName = b.CarrierName, IsWave = a.IsWave, WaveNo = a.WaveNo, IsDespatch = a.IsDespatch, Demo=a.Demo, CreateUserName = c.RealName, UpdateUserName = c.RealName, CreateTime = a.CreateTime, UpdateTime = a.UpdateTime }) .OrderByDescending(a => a.CreateTime) .ToOffsetPage(page, limit, ref total); count = total; return data; } catch (Exception e) { throw new Exception(e.Message); } } public List GetStockGroupList(string type, string msg) { try { var plnList = new List() { "100099" }; var skuList = new List(); var sku = Db.Queryable().Where(m => m.IsDel == "0" && !plnList.Contains(m.SkuNo)); //排除空托盘的物料集合 var inspectStatus = "1";//库存内物料的质检状态 var skuTypeC = new List() { "0" };//标准 var skuTypeY = new List() { "1" };//非标 if (type == "0" || type == "2") //标准 { inspectStatus = "0"; //if (type == "0") //成品 //{ skuList = sku.Where(m => inspectStatus==m.IsControlled).Select(m => m.SkuNo).ToList(); //} //if (type == "1") //原料 //{ // skuList = sku.Where(m => skuTypeY.Contains(m.Type)).Select(m => m.SkuNo).ToList(); //} } else if (type == "1" || type == "3") //非标 { inspectStatus = "1"; //if (type == "2") //成品 //{ skuList = sku.Where(m => inspectStatus==m.IsControlled).Select(m => m.SkuNo).ToList(); //} //if (type == "3") //原料 //{ // skuList = sku.Where(m => skuTypeY.Contains(m.Type)).Select(m => m.SkuNo).ToList(); //} } else { throw new Exception("单据状态有误"); } //skuList = sku.Select(m => m.SkuNo).ToList(); var stockRst = new StockServer(); var stockDetailRst = new StockDetailServer(); Expression> item = Expressionable.Create() //.And(it => it.WareHouseNo == wareHouseNo) .And(it => it.InspectStatus == "1") .And(m => skuList.Contains(m.SkuNo)) .AndIF(!string.IsNullOrWhiteSpace(msg), it => (it.SkuNo.Contains(msg) || it.SkuName.Contains(msg) || it.LotNo.Contains(msg))) .And(it => (it.Qty - it.LockQty - it.FrozenQty) > 0) .And(it => (it.Status == "0" || it.Status == "1")) .ToExpression();//注意 这一句 不能少 //库存明细 var stockDetail = stockDetailRst.GetAllWhereAsync(item).GroupBy(m => new { m.SkuNo, m.SkuName, m.LotNo, m.Standard, }).Select(it => new ExStockInfoDto { SkuNo = it.SkuNo, SkuName = it.SkuName, LotNo = it.LotNo, Standard = it.Standard, Qty = SqlFunc.AggregateSumNoNull(it.Qty - it.LockQty - it.FrozenQty), }).ToList(); //库存总表 var stock = stockRst.GetAllAsync().Select(it => new ExStockInfoDto { SkuNo = it.SkuNo, SkuName = it.SkuName, LotNo = it.LotNo, Standard = it.Standard, Qty = type == "4" ? it.Qty : it.Qty - it.LockQty - it.FrozenQty }).ToList(); foreach (var l in stockDetail.ToArray()) { var fq = stock.Where(s => s.SkuNo == l.SkuNo); if (!string.IsNullOrWhiteSpace(l.LotNo)) { fq = fq.Where(s => s.LotNo == l.LotNo); } else { fq = fq.Where(s => string.IsNullOrWhiteSpace(s.LotNo)); } var f = fq.FirstOrDefault(); if (f == null) { throw new Exception("库存信息错误,请核实"); } if (f.Qty != null && f.Qty.Value < l.Qty) { l.Qty = f.Qty.Value; } if (l.Qty <= 0) { stockDetail.Remove(l); } } return stockDetail; } catch (Exception e) { throw new Exception(e.Message); } } //WMS添加出库单 public bool AddExportNotice(AddEditExportNoticeVm model, int userId) { try { if (model == null || model.Detail.Count == 0) { throw new Exception("参数异常"); } var skuNos = model.Detail.Select(a => a.SkuNo).Distinct().ToList(); //根据物料号获取物料信息、库存明细中获取批次描述供货批次等 var skuList = Db.Queryable().Where(a => skuNos.Contains(a.SkuNo) && a.IsDel == "0").ToList(); var stockList = Db.Queryable().Where(s => skuNos.Contains(s.SkuNo) && (s.Qty-s.FrozenQty-s.LockQty) > 0).ToList(); //var palletList = contextDb.Queryable().Where(s => skuNos.Contains(s.SkuNo) && (s.Qty - s.FrozenQty - s.LockQty) > 0).ToList(); //客户信息 var customer = Db.Queryable().Where(m => m.IsDel == "0" && m.CustomerNo == model.CustomerNo).ToList(); var billNo = ""; var bl = true; do { //获取自增单据号 billNo = new Common().GetMaxNo("SO"); var no = billNo; bl = Db.Queryable().Any(m => m.SONo == no); } while (bl); Db.BeginTran();//开启事务 try { var list = new List(); //添加出库单 foreach (var d in model.Detail) { if (d.Qty < 1) { throw new Exception("出库数量必须大于0"); } var sku = skuList.FirstOrDefault(a => a.SkuNo == d.SkuNo); if (sku == null) { throw new Exception($"物料信息中未查询到出库物料信息:{d.SkuNo}"); } //库存 List stocks; //List pallets; if (!string.IsNullOrWhiteSpace(d.LotNo)) { stocks = stockList.Where(s => s.SkuNo == d.SkuNo && s.LotNo == d.LotNo).ToList(); //pallets = palletList.Where(p => p.SkuNo == d.SkuNo && p.LotNo == d.LotNo).ToList(); } else { stocks = stockList.Where(s => s.SkuNo == d.SkuNo && string.IsNullOrWhiteSpace(s.LotNo)).ToList(); //pallets = palletList.Where(p => p.SkuNo == d.SkuNo && string.IsNullOrWhiteSpace(p.LotNo)).ToList(); } if (stocks.Count < 1) { throw new Exception($"总库存中未查询到出库物料信息:{d.SkuNo}"); } //判断数量 var qty = stocks.First().Qty - stocks.First().LockQty - stocks.First().FrozenQty; if (d.Qty > qty) { throw new Exception($"总库存中出库物料信息:{d.SkuNo}、{d.LotNo} 库存数量不足"); } var item = new BllExportNoticeDetail() { SONo = billNo, SkuNo = sku.SkuNo, SkuName = sku.SkuName, Standard = sku.Standard, LotNo = d.LotNo, LotText = "", Status = "0", Qty = d.Qty, AllotQty = 0, FactQty = 0, CompleteQty = 0, PackagNo = sku.PackagNo, Price = sku.Price, Money = string.IsNullOrWhiteSpace(sku.Price.ToString()) ? null : sku.Price*d.Qty, IsBale = d.IsBale, IsBelt = d.IsBelt, SupplierLot = stocks.First().SupplierLot, IsWave = "0", WaveNo= "", CreateUser = userId, }; list.Add(item); stocks.First().LockQty += d.Qty;//锁定数量 var i = Db.Updateable(stocks.First()).UpdateColumns(it => new { it.LockQty }) .ExecuteCommand(); } var notice = new BllExportNotice() { SONo = billNo, Type = model.Type, Status = "0", Origin = "WMS", CustomerNo = model.CustomerNo, CustomerName = customer.FirstOrDefault() == null ? "" : customer.First().CustomerName, LogisticsId = model.LogisticsId, IsWave = "0", WaveNo = "", IsDespatch="0", CreateUser = userId, }; var n = Db.Insertable(notice).ExecuteCommand(); var m = Db.Insertable(list).ExecuteCommand(); if (n <= 0 || m <= 0) { Db.RollbackTran(); return false; } //添加操作日志记录 var k = new OperationSOServer().AddLogOperationSo("出库作业", "出库单据", billNo, "添加", $"添加了单据号为{billNo}的单据信息", userId); Db.CommitTran(); return true; } catch (Exception ex) { Db.RollbackTran(); throw new Exception(ex.Message); } } catch (Exception e) { throw new Exception(e.Message); } } //获取编辑出库单及明细信息 public EditExportNotifyDto GetEditExportNotice(string code) { try { var notify = Db.Queryable().Where(m => m.SONo == code && m.IsDel == "0").ToList().FirstOrDefault(); if (notify == null) { throw new Exception($"未查询到{code}的单据信息"); } var detail = Db.Queryable().Where(m => m.SONo == code && m.IsDel == "0").ToList(); var skuList = detail.Select(m => m.SkuNo).ToList(); var stock = Db.Queryable().Where(m => skuList.Contains(m.SkuNo) && m.IsDel == "0").ToList(); var model = new EditExportNotifyDto { SoNo = notify.SONo, Type = notify.Type, CustomerNo = notify.CustomerNo, LogisticsId = notify.LogisticsId, //ExportWarehouseId = notify.ExportWarehouseId, }; model.Detail = new List(); DataStock s; foreach (var d in detail) { if (string.IsNullOrWhiteSpace(d.LotNo)) { s = stock.FirstOrDefault(m => m.SkuNo == d.SkuNo && string.IsNullOrWhiteSpace(m.LotNo)); } else { s = stock.FirstOrDefault(m => m.SkuNo == d.SkuNo && m.LotNo == d.LotNo); } var stockCount = 0; //st.StockQuantity.Value if (s != null) { stockCount = s.Qty-s.FrozenQty-s.LockQty+d.Qty; } var dm = new SelectStockSkuDto() { SkuNo = d.SkuNo, SkuName = d.SkuName, Standard = d.Standard, LotNo = d.LotNo, Qty = stockCount, ExQty = d.Qty, IsBale = d.IsBale, IsBelt = d.IsBelt }; model.Detail.Add(dm); } return model; } catch (Exception e) { throw new Exception(e.Message); } } //修改出库单 public bool EditExportNotice(AddEditExportNoticeVm model, int userId) { try { if (model == null || model.Detail.Count == 0) { throw new Exception("参数异常"); } var notice = Db.Queryable().Where(m => m.IsDel == "0" && m.Id == model.Id).ToList().FirstOrDefault(); if (notice == null) { throw new Exception("未查询到出库单据信息"); } if (notice.Origin != "WMS" || notice.Status != "0") { throw new Exception("参数异常,请检查状态是否未等待执行或来源是否是WMS"); } //出库单明细 var noticeDetail = Db.Queryable().Where(m => m.IsDel == "0" && m.SONo == notice.SONo).ToList(); //根据物料号获取物料信息、库存明细中获取批次描述供货批次等 var skuList = Db.Queryable().Where(a => a.IsDel == "0").ToList(); var stockList = Db.Queryable().Where(s => (s.Qty - s.FrozenQty - s.LockQty + noticeDetail[0].Qty) > 0).ToList(); var palletList = Db.Queryable().Where(s => (s.Qty - s.FrozenQty - s.LockQty + noticeDetail[0].Qty) > 0).ToList(); Db.BeginTran();//开启事务 try { //删除旧 foreach (var d in noticeDetail) { var mq = model.Detail.Where(o => o.SkuNo == d.SkuNo).ToList(); if (!string.IsNullOrWhiteSpace(d.LotNo)) { mq = mq.Where(o => o.LotNo == d.LotNo).ToList(); } if (mq.Any()) //如果有这个物料及批次则跳过 { continue; } // var fl = stockList.Where(s => s.SkuNo == d.SkuNo).ToList(); DataStock fls; if (!string.IsNullOrWhiteSpace(d.LotNo)) { fls = fl.FirstOrDefault(s => s.SkuNo == d.SkuNo && s.LotNo == d.LotNo); } else { fls = fl.FirstOrDefault(s => s.SkuNo == d.SkuNo && string.IsNullOrWhiteSpace(s.LotNo)); } if (fls == null) { throw new Exception($"未找到物料{d.SkuNo}、批次{d.LotNo} 的库存信息"); } fls.LockQty -= d.Qty; d.IsDel = "1"; d.UpdateUser = userId; d.UpdateTime = DateTime.Now; Db.Updateable(d).ExecuteCommand(); Db.Updateable(fls).UpdateColumns(it => new { it.LockQty }).ExecuteCommand(); } //更新出库单 foreach (var d in model.Detail) { if (d.Qty < 1) { throw new Exception("出库数据必须大于0"); } var sku = skuList.FirstOrDefault(a => a.SkuNo == d.SkuNo); if (sku == null) { throw new Exception("出库物品为空"); } //库存 List stocks; List pallet; if (!string.IsNullOrWhiteSpace(d.LotNo)) { stocks = stockList.Where(s => s.SkuNo == d.SkuNo && s.LotNo == d.LotNo).ToList(); pallet = palletList.Where(p => p.SkuNo == d.SkuNo && p.LotNo == d.LotNo).ToList(); } else { stocks = stockList.Where(s => s.SkuNo == d.SkuNo && string.IsNullOrWhiteSpace(s.LotNo)).ToList(); pallet = palletList.Where(p => p.SkuNo == d.SkuNo && string.IsNullOrWhiteSpace(p.LotNo)).ToList(); } if (stocks.Count < 1) { throw new Exception("出库物品库存不足"); } var stock = stocks.First();//总库存 // BllExportNoticeDetail old; if (string.IsNullOrWhiteSpace(d.LotNo)) { old = noticeDetail.FirstOrDefault(o => o.SkuNo == d.SkuNo && string.IsNullOrWhiteSpace(o.LotNo)); } else { old = noticeDetail.FirstOrDefault(o => o.SkuNo == d.SkuNo && o.LotNo == d.LotNo); } //新加项 if (old == null) { //判断数量 var qty = stock.Qty - stock.LockQty - stock.FrozenQty; if (d.Qty > qty) { throw new Exception($"总库存中出库物料信息:{d.SkuNo}、{d.LotNo} 库存数量不足"); } var item = new BllExportNoticeDetail() { SONo = notice.SONo, SkuNo = sku.SkuNo, SkuName = sku.SkuName, Standard = sku.Standard, LotNo = d.LotNo, LotText = "", Status = "0", Qty = d.Qty, AllotQty = 0, FactQty = 0, CompleteQty = 0, PackagNo = sku.PackagNo, Price = sku.Price, Money = string.IsNullOrWhiteSpace(sku.Price.ToString()) ? null : sku.Price * qty, IsBale = d.IsBale, IsBelt = d.IsBelt, SupplierLot = stocks.First().SupplierLot, IsWave = "0", WaveNo = "", CreateUser = userId, }; stock.LockQty += d.Qty;//锁定数量 var m = Db.Insertable(item).ExecuteCommand(); var i = Db.Updateable(stock).UpdateColumns(it => new { it.LockQty }).ExecuteCommand(); } else if (old.Qty != d.Qty || old.IsBale != d.IsBale || old.IsBelt != d.IsBelt) { if (d.Qty > (stock.Qty-stock.FrozenQty-stock.LockQty) + old.Qty) { throw new Exception("物品库存数量不足"); } //增加 if (d.Qty > old.Qty) { stock.LockQty += d.Qty - old.Qty; } else { stock.LockQty -= old.Qty - d.Qty; } old.IsBale = d.IsBale; old.IsBelt = d.IsBelt; old.Qty = d.Qty; old.UpdateUser = userId; old.UpdateTime = DateTime.Now; var m = Db.Updateable(old).UpdateColumns(it => new { it.IsBale, it.IsBelt, it.Qty, it.UpdateUser, it.UpdateTime }).ExecuteCommand(); var i = Db.Updateable(stock).UpdateColumns(it => new { it.LockQty }).ExecuteCommand(); } } //客户信息 var customer = Db.Queryable().Where(m => m.IsDel == "0" && m.CustomerNo == model.CustomerNo).ToList().FirstOrDefault(); notice.Type = model.Type; notice.CustomerNo = model.CustomerNo; notice.CustomerName = customer == null ? "" : customer.CustomerName; notice.LogisticsId = model.LogisticsId; notice.UpdateUser = userId; notice.UpdateTime = DateTime.Now; var n = Db.Updateable(notice).ExecuteCommand(); if (n <= 0) { Db.RollbackTran(); return false; } //添加操作日志记录 var k = new OperationSOServer().AddLogOperationSo("出库作业", "出库单据", notice.SONo, "编辑", $"编辑了单据号为{notice.SONo}的单据信息", userId); Db.CommitTran(); return true; } catch (Exception ex) { Db.RollbackTran(); throw new Exception(ex.Message); } } catch (Exception e) { throw new Exception(e.Message); } } //删除出库单 public bool DelExportNotice(int id, int userId) { try { var notice = Db.Queryable().Where(m => m.IsDel == "0" && m.Id == id).ToList().FirstOrDefault(); if (notice == null) { throw new Exception("未查询到出库单据信息"); } if (notice.Origin != "WMS" || notice.Status != "0") { throw new Exception("参数异常,请检查状态是否未等待执行或来源是否是WMS"); } //总库存信息 var stockList = Db.Queryable().ToList(); //出库单明细 var noticeDetail = Db.Queryable().Where(m => m.IsDel == "0" && m.SONo == notice.SONo).ToList(); Db.BeginTran();//开启事务 try { foreach (var d in noticeDetail) { //总库存 var sq = stockList.Where(s => s.SkuNo == d.SkuNo); if (!string.IsNullOrWhiteSpace(d.LotNo)) { sq = sq.Where(s => s.LotNo == d.LotNo); } else { sq = sq.Where(s => string.IsNullOrWhiteSpace(s.LotNo)); } var fd = sq.FirstOrDefault(); if (fd == null) { throw new Exception($"未找到物料{d.SkuNo}、批次{d.LotNo} 的库存信息"); } fd.LockQty -= d.Qty; d.IsDel = "1"; d.UpdateUser = userId; d.UpdateTime = DateTime.Now; Db.Updateable(d).ExecuteCommand(); Db.Updateable(fd).UpdateColumns(it => new { it.LockQty }).ExecuteCommand(); } //删除出库单 notice.IsDel = "1"; notice.UpdateUser = userId; notice.UpdateTime = DateTime.Now; var n = Db.Updateable(notice).ExecuteCommand(); if (n <= 0) { Db.RollbackTran(); return false; } //添加操作日志记录 var k = new OperationSOServer().AddLogOperationSo("出库作业", "出库单据", notice.SONo, "删除", $"删除了单据号为{notice.SONo}的单据信息", userId); Db.CommitTran(); return true; } catch (Exception e) { Db.RollbackTran(); throw new Exception(e.Message); } } catch (Exception e) { throw new Exception(e.Message); } } //订单关闭 public bool CloseExportNotice(int id, int userId) { try { var notice = Db.Queryable().Where(m => m.IsDel == "0" && m.Id == id).ToList().FirstOrDefault(); if (notice == null) { throw new Exception("未查询到出库单据信息"); } if (notice.Status != "4") { throw new Exception("参数异常,请检查状态是否为执行完成或订单关闭"); } //总库存信息 var stockList = Db.Queryable().ToList(); //出库单明细 var noticeDetail = Db.Queryable().Where(m => m.IsDel == "0" && m.SONo == notice.SONo).ToList(); Db.BeginTran();//开启事务 try { //修改出库单状态 notice.Status = "5"; notice.UpdateUser = userId; notice.UpdateTime = DateTime.Now; Db.Updateable(notice).ExecuteCommand(); var skuList = noticeDetail.Select(d => d.SkuNo).ToList(); var stocks = stockList.Where(s => skuList.Contains(s.SkuNo)).ToList(); foreach (var d in noticeDetail) { //更改库存明细锁定数量 //var orders = dataContext.WmsExportOrder.Where(o => o.ExportDetailId == d.Id // && o.ExportExecuteFlag != "4" && o.ExportExecuteFlag == "3" && o.pickingType == 0).ToList(); //foreach (var o in orders) //{ // if (o.ExportQuantity > o.PickedNum) //判断拣货是否已拣完 // { // var pq = dataContext.WmsStockTray.Where(t => t.StockGoodId == o.ExportGoodsCode && t.StockStockCode == o.ExportStockCode); // if (string.IsNullOrWhiteSpace(o.ExportLotNo)) // { // pq = pq.Where(t => t.StockLotNo == null || t.StockLotNo == ""); // } // else // { // pq = pq.Where(t => t.StockLotNo == o.ExportLotNo); // } // var pallet = pq.FirstOrDefault(); // //库存托盘信息锁定数量还原为未锁定 // if (pq != null) // { // pallet.LockQuantity -= o.ExportQuantity.Value - o.PickedNum; // pallet.StockQuantity += o.ExportQuantity.Value - o.PickedNum; // } // } //} if (d.Qty != d.CompleteQty) { throw new Exception("当前单据明细中计划数量与拣货数量不符,请核实"); } #region 库存表减去锁定数量与总数量(PDA拣货的时候已经减去数量了) /*var sq = stocks.Where(s => s.SkuNo == d.SkuNo); if (!string.IsNullOrWhiteSpace(d.LotNo)) { sq = sq.Where(s => s.LotNo == d.LotNo); } else { sq = sq.Where(s => string.IsNullOrWhiteSpace(s.LotNo)); } var st = sq.FirstOrDefault(); if (st != null) { if (d.CompleteQty <= d.Qty) { st.Qty += d.Qty - d.CompleteQty.Value; } else { st.Qty -= d.CompleteQty.Value - d.Qty; } st.LockQty -= d.Qty; st.Qty -= d.Qty; //修改总库存表 Db.Updateable(st).UpdateColumns(it => new { it.Qty, it.LockQty }).ExecuteCommand(); }*/ #endregion } //添加操作日志记录 var k = new OperationSOServer().AddLogOperationSo("出库作业", "出库单据", notice.SONo, "关单", $"关闭了单据号为{notice.SONo}的单据信息", userId); Db.CommitTran(); return true; } catch (Exception e) { Db.RollbackTran(); throw new Exception(e.Message); } } catch (Exception ex) { throw new Exception("关闭出库单据失败:" + ex.Message); } } public XmlNode AddExXmlStr(int id, int userId) { try { var notice = Db.Queryable().Where(m => m.IsDel == "0" && m.Id == id).ToList().FirstOrDefault(); if (notice == null) { throw new Exception("未查询到出库单据信息"); } var statusLis = new List() { "4", "5", "6" }; if (!statusLis.Contains(notice.Status)) { throw new Exception("参数异常,请检查状态是否为执行完成或订单关闭/已上传"); } //出库单明细 var comDetail = Db.Queryable().Where(m => m.IsDel == "0" && m.SONo == notice.SONo).Select(m => m.BoxNo3).ToList(); Db.BeginTran();//开启事务 try { //Hashtable pars = new Hashtable(); //用来存放参数 var pars = new List(); //for (int i = 0; i < 10; i++) //{ // pars.Add("202203240009000479940290"); //} var dom = HttpHelper.EncodeParsToFuMa(comDetail, "ceshi", "ExInfoXml"); ////添加操作日志记录 //var k = new OperationSOServer().AddLogOperationSo("出库作业", "出库单据", notice.SONo, "关单", $"关闭了单据号为{notice.SONo}的单据信息", userId); Db.CommitTran(); return dom; } catch (Exception e) { Db.RollbackTran(); throw new Exception(e.Message); } } catch (Exception ex) { throw new Exception("生成XML文件错误:" + ex.Message); } } #endregion #region 托盘出库 /// /// 获取托盘出库明细 /// /// 物料号 /// 物料名称 /// 托盘号 /// 批次号 /// 检验标记 /// 零托标记 /// 零托标记 /// 零托标记 /// 零托标记 /// public List GetPalletNoOutList(string skuNo, string skuName, string palletNo, string lotNo, string inspectMark, string bitPalletMark, int page, int limit, out int count) { try { Expression> item = Expressionable.Create() .AndIF(!string.IsNullOrWhiteSpace(skuNo), m => m.SkuNo.Contains(skuNo.Trim())) .AndIF(!string.IsNullOrWhiteSpace(skuName), m => m.SkuName.Contains(skuName.Trim())) .AndIF(!string.IsNullOrWhiteSpace(palletNo), m => m.PalletNo.Contains(palletNo.Trim())) .AndIF(!string.IsNullOrWhiteSpace(lotNo), m => m.LotNo.Contains(lotNo.Trim())) .AndIF(!string.IsNullOrWhiteSpace(inspectMark), m => m.InspectMark==inspectMark) .AndIF(!string.IsNullOrWhiteSpace(bitPalletMark), m => m.BitPalletMark== bitPalletMark) .And(m => !string.IsNullOrWhiteSpace(m.WareHouseNo)) .And(a => a.Status == "0") .And(a => a.WareHouseNo == "W01") .ToExpression(); var total = 0; var data = Db.Queryable().Where(item).OrderBy(m => m.LocatNo).ToOffsetPage(page, limit, ref total); //data.Select(m => m.Status == "0" && m.IsDel == "0"); count = total; return data; } catch (Exception e) { throw new Exception(e.Message); } } //托盘出库 public List IssuePalletNoOut(string palletNo, string outMode, int userId, string url, out string str) { try { //判断托盘号是否为空 if (string.IsNullOrWhiteSpace(palletNo)) { throw new Exception($"托盘号不能为空,请核实"); } var outDtoList = new List(); //出库数据的集合 str = ""; var stockDetailList = Db.Queryable().Where(m => m.PalletNo == palletNo && m.IsDel == "0").ToList(); if (stockDetailList.Count == 0) { throw new Exception($"未在库内查询到该托盘信息"); } var stocka = Db.Queryable().First(a => a.IsDel == "0" && a.SkuNo == stockDetailList[0].SkuNo); //验证库存托盘状态 if (stockDetailList[0].Status != "0") { throw new Exception($"当前托盘未处于待分配状态,请核实!"); } //判断托盘库存信息分组后是否大于1条 var detailGroup = stockDetailList.GroupBy(m => new { m.SkuNo, m.PalletNo, m.WareHouseNo, m.LocatNo }).ToList(); if (detailGroup.Count>1) { throw new Exception($"未在库内查询到该托盘信息"); } #region 集合 Db.BeginTran(); try { // 储位号 var de = stockDetailList.First(); var locateNo = de.LocatNo; #region 判断 //判断托盘是否在库内 if (string.IsNullOrWhiteSpace(locateNo)) { if (de.WareHouseNo == "W02")//盘断是否是零箱库 { if (de.SkuNo == "100099")//判断是否是空托出库 { //判断总库存是否为0,如果为0删除 否则减去数量 var stock = Db.Queryable().First(m => m.SkuNo == "100099"); if (stock != null) { if (de.Qty != null) { stock.Qty -= de.Qty.Value; Db.Updateable(stock).ExecuteCommand(); } if (stock.Qty == 0) { Db.Deleteable(stock).ExecuteCommand(); } } //托盘状态改为未使用 var sCode = Db.Queryable().First(m => m.PalletNo == de.PalletNo); if (sCode != null) { sCode.Status = "0"; Db.Updateable(sCode).ExecuteCommand(); } foreach (var item in stockDetailList) { Db.Deleteable(item).ExecuteCommand(); } str = "出库完成"; return outDtoList; } foreach (var item in stockDetailList) { item.LocatNo = "";//储位更改(改为空) item.WareHouseNo = "";//所属仓库更改(改为空) item.RoadwayNo = "";//所属巷道更改(改为空) item.AreaNo = "";//所属区域更改(改为空) Db.Updateable(de).ExecuteCommand(); } str = "出库完成"; return outDtoList; } } var locate = Db.Queryable().First(m => m.LocatNo == locateNo && m.IsDel == "0");//当前出库的储位信息 if (locate == null) { throw new Exception($"出库的托盘储位信息错误、在储位表中未查询到"); } //判断储位标志是否为损坏 if (locate.Flag == "2") { throw new Exception($"当前托盘所在的储位已损坏,不能出库,请核实"); } if (locate.Status !="1") { throw new Exception($"当前托盘所在的储位状态不是有物品,不能出库,请核实"); } #endregion #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 = de.PalletNo,//托盘码 IsSend = 1,//是否可再次下发 IsCancel = 1,//是否可取消 IsFinish = 1,//是否可完成 Type = "1",//任务类型 0 入库任务 1 出库任务 2 移库任务 Status = "0",//任务状态0:等待执行1正在执行2执行完成 OrderType = "1",//0 入库单 1 出库单 2 盘点单 3 移库单 Msg = "从" + locate.LocatNo + "到" + outMode + "的出库任务", //关键信息 }; Db.Insertable(exTask).ExecuteCommand(); outDtoList.Add(new OutCommandDto() { PalletNo = palletNo,//托盘号 StartLocate = locate.LocatNo, // 起始位置 StartRoadway = locate.RoadwayNo, EndLocate = outMode, // 目标位置 TaskNo = exTask.TaskNo, // 任务号 TaskType = "1",// 任务类型 (出库) OutMode = outMode, //目标地址 Order = 1 }); #endregion #region 改变数据 //判断是否为空托盘 if (de.SkuNo == "100099") { //增加锁定数量 de.LockQty += de.Qty; //增加锁定数量 de.Status = "2"; //状态 2:已分配 stocka.LockQty += (int)de.Qty; //增加库存总量锁定数量 Db.Updateable(de).ExecuteCommand(); Db.Updateable(stocka).ExecuteCommand(); } locate.Status = "3"; //要出库的储位改变状态 正在出库 Db.Updateable(locate).ExecuteCommand(); #endregion //添加操作日志记录 new OperationSOServer().AddLogOperationSo("出库作业", "托盘出库", palletNo, "出库", $"点击出库按钮出库托盘为:{palletNo}", userId); Db.CommitTran(); if (outDtoList.Count > 0) { // 正式运行程序放开 var list2 = outDtoList.Select(m => m.TaskNo).ToList(); var jsonData = JsonConvert.SerializeObject(outDtoList); 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); } } return outDtoList; } catch (Exception e) { Db.RollbackTran(); throw new Exception(e.Message); } #endregion } catch (Exception e) { throw new Exception(e.Message); } } #endregion //------------------------------------------------------------------ #region 下发出库、出库完成、重新下发任务、取消任务、异常处理 // 下发出库(调用cs接口给他库位地址) public List IssueOutHouse(string soNo, string outMode, int userId, string url, out string str) { try { #region 集合 var outDtoList = new List(); //出库数据的集合 //记录错误信息的集合 var flagList = new List();//1:当前要出库的储位正在移出、2 出库的托盘储位信息错误(在储位表中未查询到)、3储位损坏不能出库、4 要出库的托盘正在入库 #endregion var com = new Common(); //assign.IsHavePyTask(); var notice = Db.Queryable().First(m => m.SONo == soNo && m.IsDel == "0"); if (notice == null) { throw new Exception($"未找到{soNo}出库单信息"); } //所有要出库的出库分配信息(未下发的信息和待拣货的信息) var list = Db.Queryable().Where(a => a.IsDel == "0" && a.SONo == soNo && a.Status == "0").ToList(); if (list.Count == 0) //判断是否有需要下发的出库流水 { throw new Exception("当前出库单据无需要下发的托盘"); } #region 集合 //要出库的托盘集合 var outLpnList = list.Select(m => m.PalletNo).ToList(); //要出库的明细集合 var outStockDetail = Db.Queryable().Where(m => m.IsDel == "0" && outLpnList.Contains(m.PalletNo)).ToList(); Db.BeginTran(); try { List logTaskList = new List();//此次出库任务集合,为应对同托盘不同物料出库 //循环分配的信息生成出库任务 foreach (var item in list) { // 储位号 var locateNo = outStockDetail.First(m => m.PalletNo == item.PalletNo).LocatNo; #region 判断 //判断托盘是否在库内 if (string.IsNullOrWhiteSpace(locateNo)) { //判断托盘是否在入库中 var imBl = com.GetImTask(item.PalletNo); if (imBl != null) { flagList.Add(4); continue; } 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 = "1"; // 出库分配信息状态改为正在执行 item.OutMode = outMode;//出库口 Db.Updateable(item).ExecuteCommand(); var noticeDetail = Db.Queryable().First(m => m.IsDel == "0" && m.Id == item.SODetailNo); if (noticeDetail != null) //更新出库单据的下发数量 { noticeDetail.FactQty += item.Qty; Db.Updateable(noticeDetail).ExecuteCommand(); } //var notice2 = Db.Queryable().First(m => m.IsDel == "0" && m.SONo == item.SONo); if (notice.Status == "0" || notice.Status == "1" || notice.Status == "2") { var detailList = Db.Queryable().Where(m => m.IsDel == "0" && m.SONo == item.SONo).ToList(); if (detailList.Count(m => m.Qty >= m.AllotQty) > 0) { notice.Status = "3"; //变更状态为正在执行 Db.Updateable(notice).ExecuteCommand(); } } flagList.Add(0); continue; } //判断是否是已经出过库又回库(状态为待拣货的 1) if (item.Status == "0") { //如果不在仓库内,当前分配信息直接更新出库完成 item.Status = "2";//状态 item.OutMode = outMode;//出库口 Db.Updateable(item).ExecuteCommand(); var noticeDetail = Db.Queryable().First(m => m.IsDel == "0" && m.Id == item.SODetailNo); if (noticeDetail != null) //更新出库单据的下发数量 { noticeDetail.FactQty += item.Qty; Db.Updateable(noticeDetail).ExecuteCommand(); } //var notice2 = Db.Queryable().First(m => m.IsDel == "0" && m.SONo == item.SONo); if (notice.Status == "0" || notice.Status == "1" || notice.Status == "2") { var detailList = Db.Queryable().Where(m => m.IsDel == "0" && m.SONo == item.SONo).ToList(); if (detailList.Count(m => m.Qty >= m.AllotQty) > 0) { notice.Status = "3"; //变更状态为正在执行 Db.Updateable(notice).ExecuteCommand(); } } } flagList.Add(0); continue; } var locate = Db.Queryable().First(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 = "1",//0 入库单 1 出库单 2 盘点单 3 移库单 Msg = "从" + locate.LocatNo + "到" + outMode + "的出库任务", //关键信息 }; Db.Insertable(exTask).ExecuteCommand(); logTaskList.Add(exTask); outDtoList.Add(new OutCommandDto() { PalletNo = item.PalletNo,//托盘号 StartLocate = locate.LocatNo, // 起始位置 StartRoadway = locate.RoadwayNo,//其实巷道 EndLocate = outMode, // 目标位置 TaskNo = exTask.TaskNo, // 任务号 TaskType = "1",// 任务类型 (出库) OutMode = "", //目标地址 Order = 1 }); #endregion #region 改变数据 if (item.Status == "0")//判断托盘是否下发过 { var noticeDetail = Db.Queryable().First(m => m.IsDel == "0" && m.Id == item.SODetailNo); if (noticeDetail != null) //更新出库单据的下发数量 { noticeDetail.FactQty += item.Qty; Db.Updateable(noticeDetail).ExecuteCommand(); } //var notice2 = Db.Queryable().First(m => m.IsDel == "0" && m.SONo == item.SONo); if (notice.Status == "0" || notice.Status == "1" || notice.Status == "2") { var detailList = Db.Queryable().Where(m => m.IsDel == "0" && m.SONo == item.SONo).ToList(); if (detailList.Count(m => m.Qty >= m.AllotQty) > 0) { notice.Status = "3"; //变更状态为正在执行 Db.Updateable(notice).ExecuteCommand(); } } } locate.Status = "3"; //要出库的储位改变状态 正在出库 Db.Updateable(locate).ExecuteCommand(); item.TaskNo = exTask.TaskNo; // 出库分配信息中更新任务号 item.Status = "1"; // 出库分配信息状态改为正在执行 item.OutMode = outMode;//出库口 Db.Updateable(item).ExecuteCommand(); #endregion flagList.Add(0); } else if (locate.Status == "3") //出库中 { #region 改变数据 //判断是否是已经出过库又回库(状态为待拣货的 1) if (item.Status == "0") { var noticeDetail = Db.Queryable().First(m => m.IsDel == "0" && m.Id == item.SODetailNo); if (noticeDetail != null) //更新出库单据的下发数量 { noticeDetail.FactQty += item.Qty; Db.Updateable(noticeDetail).ExecuteCommand(); } //var notice2 = Db.Queryable().First(m => m.IsDel == "0" && m.SONo == item.SONo); if (notice.Status == "0" || notice.Status == "1" || notice.Status == "2") { var detailList = Db.Queryable().Where(m => m.IsDel == "0" && m.SONo == item.SONo).ToList(); if (detailList.Count(m => m.Qty >= m.AllotQty) > 0) { notice.Status = "3"; //变更状态为正在执行 Db.Updateable(notice).ExecuteCommand(); } } } var taskNo = Db.Queryable().First(m => m.OrderType =="1"&& m.TaskNo != item.TaskNo && m.Status == "1" && m.PalletNo==item.PalletNo); if (taskNo == null) { taskNo = logTaskList.First(m => m.PalletNo == item.PalletNo);//当前有同托盘不同物料出库 } if (taskNo == null) { throw new Exception($"托盘号:{item.PalletNo},出库异常"); } item.TaskNo = taskNo.TaskNo; item.Status = "1"; // 出库分配信息状态改为正在执行 item.OutMode = taskNo.EndLocat; Db.Updateable(item).ExecuteCommand(); flagList.Add(0); #endregion } else if (locate.Status == "5") //移出中 { flagList.Add(1); } } //添加操作日志记录 var k = new OperationSOServer().AddLogOperationSo("出库作业", "出库单据", soNo, "出库", $"点击出库按钮出库单号为:{soNo}的出库单", userId); Db.CommitTran(); str = string.Empty; if (flagList.Count(m => m == 0) > 0) { str += "0.下发成功、"; } 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 += "4.储位损坏不能出库、"; } if (flagList.Count(m => m == 4) > 0) { str += "3.要出库的托盘正在入库、"; } if (outDtoList.Count > 0) { // 正式运行程序放开 var list2 = outDtoList.Select(m => m.TaskNo).ToList(); var jsonData = JsonConvert.SerializeObject(outDtoList); 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); } } return outDtoList; } catch (Exception e) { Db.RollbackTran(); throw new Exception(e.Message); } #endregion } catch (Exception e) { throw new Exception(e.Message); } } //wcs返回的成功信号(出库成功) public void ExportSuccess(string taskNo, int userId) { 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 locateNo = stockDetail.Select(m => m.LocatNo).Distinct().FirstOrDefault(); //当前任务中的储位信息 var locate = Db.Queryable().First(m => m.LocatNo == locateNo); try { task.Status = "2";//任务状态 task.IsSend = 0; task.IsCancel = 0; task.IsFinish = 0; task.FinishDate = DateTime.Now;//完成时间 Db.Updateable(task).ExecuteCommand(); if (locate != null) { locate.Status = "0"; // 更改当前任务中的储位状态(改为0空储位) Db.Updateable(locate).ExecuteCommand(); } 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(); #region 拣货信息 //var pickQty = 0;//拣货的数量 //var comList = new List(); // //添加拣货明细 // var completeDetail = new BllCompleteDetail() // { // SONo = "", // SODetailNo = 0, // ExportAllotId = 0, // StockId = exportAllot.StockId, // BoxNo = item.BoxNo, // BoxNo2 = item.BoxNo2, // BoxNo3 = item.BoxNo3, // LotNo = exportAllot.LotNo, // LotText = exportAllot.LotText, // SupplierLot = exportAllot.SupplierLot, // SkuNo = exportAllot.SkuNo, // SkuName = exportAllot.SkuName, // Standard = exportAllot.Standard, // PalletNo = palletNo, // CompleteQty = item.Qty, // CreateUser = userId // }; // comList.Add(completeDetail); // //删除库存箱码明细 // Db.Deleteable(item).ExecuteCommand(); // pickQty += item.Qty; // exportAllot.Status = "5"; //待回库 : 已完成 // exportAllot.CompleteQty += item.Qty; //拣货数量 // exportAllot.UpdateUser = userId; //修改人 // exportAllot.UpdateTime = serverTime; //修改时间 // Db.Updateable(exportAllot).ExecuteCommand(); // //验证拣货信息是否为已完成 // if (exportAllot.Status == "5") // { // break; // } //Db.Insertable(comList).ExecuteCommand(); #endregion continue; } item.LocatNo = "";//储位更改(改为空) item.WareHouseNo = "";//所属仓库更改(改为空) item.RoadwayNo = "";//所属巷道更改(改为空) item.AreaNo = "";//所属区域更改(改为空) Db.Updateable(item).ExecuteCommand(); } //出库流水(更改状态) var allot = Db.Queryable().Where(m => m.IsDel == "0" && (m.TaskNo == taskNo || (m.Status == "1" && m.PalletNo == task.PalletNo))).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(); if (userId != 0) { //添加操作日志记录 var k = new OperationSOServer().AddLogOperationSo("出库作业", "出库日志", taskNo, "完成", $"点击完成按钮、完成任务号为:{taskNo}的任务", userId); } Db.CommitTran(); } catch (Exception ex) { Db.RollbackTran(); throw new Exception(ex.Message); } } catch (Exception ex) { throw new Exception("完成反馈失败:" + ex.Message); } } //重新下发出库任务 public OutCommandDto AgainSendSoTask(string taskNo, int userId, string url) { try { var task = Db.Queryable().First(m => m.TaskNo == taskNo && m.IsDel == "0"); if (task == null) { throw new Exception("未查询到任务信息"); } var stockDetail = Db.Queryable().First(m => m.PalletNo == task.PalletNo); if (stockDetail == null) { throw new Exception(task.PalletNo + " 当前托盘未在库内,请核实信息"); } Db.BeginTran(); var locateNo = task.StartLocat; //判断任务中起始位置是否和库存中位置一致 if (task.StartLocat != stockDetail.LocatNo) { locateNo = stockDetail.LocatNo; task.StartLocat = locateNo; Db.Updateable(task).ExecuteCommand(); } var locate = Db.Queryable().First(m => m.LocatNo == locateNo); if (locate != null && locate.Status != "3") { locate.Status = "3"; Db.Updateable(locate).ExecuteCommand(); } var outDto = new OutCommandDto() { PalletNo = task.PalletNo,//托盘号 StartLocate = locateNo, // 起始位置 StartRoadway = locate.RoadwayNo, EndLocate = task.EndLocat, // 目标位置 TaskNo = task.TaskNo, // 任务号 TaskType = "1",// 任务类型 (出库) OutMode = "", //目标地址 Order = 1 }; //出库数据 //添加操作日志记录 var k = new OperationSOServer().AddLogOperationSo("出库作业", "出库日志", taskNo, "下发", $"点击下发按钮、重新下发了任务号为:{taskNo}的任务", (int)userId); 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.StatusCode == 0) { //更改任务的发送返回时间// new TaskServer().EditTaskIssueOk(list, time1, time2); } if (wcsModel.StatusCode == -1) { new TaskServer().EditTaskIssueNo(list, time1, time2, wcsModel.Msg); throw new Exception($"wcs返回状态异常:{wcsModel.Msg}"); } } catch (Exception ex) { throw new Exception(ex.Message); } return outDto; } catch (Exception e) { Db.RollbackTran(); throw new Exception(e.Message); } } //取消出库任务 public void CancelSoTask(string taskNo, int userId) { try { Db.BeginTran(); try { var task = Db.Queryable().First(m => m.TaskNo == taskNo && m.IsDel == "0"); if (task == null) { throw new Exception("未查询到任务信息"); } //修改任务 task.IsSuccess = 1; task.IsSend = 0; task.IsCancel = 0; task.IsFinish = 0; task.Status = "4"; task.CancelDate = DateTime.Now; Db.Updateable(task).ExecuteCommand(); //出库分配信息 var allot = Db.Queryable().Where(m => m.IsDel == "0" && m.TaskNo == taskNo).ToList(); foreach (var item in allot) { item.Status = "0";//修改分配信息状态 item.TaskNo = ""; var noticeDetail = Db.Queryable().First(m => m.IsDel == "0" && m.Id == item.SODetailNo); if (noticeDetail == null) { throw new Exception("未查询到出库单明细信息"); } noticeDetail.FactQty -= item.Qty; //修改出库单明细的下架数量 Db.Updateable(noticeDetail).ExecuteCommand(); //获取储位信息 var locat = Db.Queryable().First(a => a.IsDel == "0" && a.WareHouseNo == "W01" && a.LocatNo == task.StartLocat); if (locat == null) { Db.RollbackTran(); throw new Exception("未查询到储位信息,请核实!"); } locat.Status = "1"; //有物品 Db.Updateable(locat).ExecuteCommand(); if (noticeDetail.FactQty == 0) { var noticeDetail2 = Db.Queryable().Where(m => m.IsDel == "0" && m.SONo == item.SONo && m.Id != noticeDetail.Id).ToList(); var num = noticeDetail2.Count(m => m.FactQty>0); //判断出库单的所有明细是否都为0;如果为0变更出库单状态为已分配 if (num == 0) { var notice = Db.Queryable().First(m => m.IsDel == "0" && m.SONo == item.SONo); notice.Status = "2"; Db.Updateable(notice).ExecuteCommand(); } } } //判断是否存在分配信息 if (allot == null) { //获取库存明细 var stockDetail = Db.Queryable().First(a => a.IsDel == "0" && a.PalletNo == task.PalletNo); //获取库存 var datastock = Db.Queryable().First(a => a.IsDel == "0" && a.SkuNo == stockDetail.SkuNo); //获取储位信息 var locate = Db.Queryable().First(a => a.IsDel == "0" && a.WareHouseNo == "W01" && a.LocatNo == stockDetail.LocatNo); //判断是否为空托盘 if (stockDetail.SkuNo == "100099") { //修改库存明细 stockDetail.LockQty -= stockDetail.Qty; //锁定数量 stockDetail.Status = "0"; //库存状态 0:待分配 //修改库存总表 datastock.LockQty -= (int)stockDetail.Qty; //锁定数量 //修改储位状态 locate.Status = "1"; //储位状态 1:有物品 Db.Updateable(stockDetail).ExecuteCommand(); Db.Updateable(datastock).ExecuteCommand(); Db.Updateable(locate).ExecuteCommand(); } else { //修改储位状态 locate.Status = "1"; //储位状态 1:有物品 Db.Updateable(locate).ExecuteCommand(); } } else { Db.Updateable(allot).ExecuteCommand(); } //添加操作日志记录 var k = new OperationSOServer().AddLogOperationSo("出库作业", "出库日志", taskNo, "取消", $"点击取消按钮、取消了任务号为:{taskNo}的任务", (int)userId); Db.CommitTran(); } catch (Exception e) { Db.RollbackTran(); throw new Exception(e.Message); } } catch (Exception e) { throw new Exception(e.Message); } } /// /// 空取异常 /// /// 任务反馈信息 /// public bool EmptyException(ReceiveWcsSignal model) { try { // 判断当前任务状态 Status 1:正在执行 3:异常结束 var taskModel = Db.Queryable().First(m => m.TaskNo == model.TaskNo && m.IsDel == "0" && m.Status == "1"); if (taskModel == null) { throw new Exception("此任务不存在或任务状态已变更!"); } Db.BeginTran(); // 将当前任务状态变更异常结束 taskModel.Status = "3"; taskModel.Information = "空取异常"; taskModel.IsSend = 0; taskModel.IsCancel = 0; taskModel.IsFinish = 0; taskModel.FinishDate = DateTime.Now; Db.Updateable(taskModel).ExecuteCommand(); // 改变当前储位地址的储位标志变更为屏蔽 var locatModel = Db.Queryable().First(m => m.LocatNo == taskModel.StartLocat && m.IsDel == "0"); locatModel.Flag = "1"; Db.Updateable(locatModel).ExecuteCommand(); var allotModels = Db.Queryable().Where(m => m.PalletNo == taskModel.PalletNo && (m.Status == "1" || m.Status == "0")).ToList(); // 循环处理应对同个托盘多个分配任务 foreach (BllExportAllot allotModel in allotModels) { // 出库明细表 状态修改为分配中 分配数量回滚 var noticeDetailModel = Db.Queryable().First(m => m.Id == allotModel.SODetailNo && m.IsDel == "0"); noticeDetailModel.AllotQty = noticeDetailModel.AllotQty - allotModel.Qty; if (allotModel.Status == "1") { noticeDetailModel.FactQty = noticeDetailModel.FactQty - allotModel.Qty; } noticeDetailModel.Status = "1"; Db.Updateable(noticeDetailModel).ExecuteCommand(); // 出库分配表 状态修改为异常取消 allotModel.Status = "6"; // 出库总表 状态改为部分分配 var noticeModel = Db.Queryable().First(m => m.SONo == noticeDetailModel.SONo && m.IsDel == "0"); noticeModel.Status = "1"; Db.Updateable(noticeModel).ExecuteCommand(); // 库存明细表 状态修改为异常锁定 锁定数量修改为托盘上数量 var stockDetailModel = Db.Queryable().First(m => m.Id == allotModel.StockId && m.IsDel == "0"); var lockQty = stockDetailModel.LockQty; stockDetailModel.Status = "5"; stockDetailModel.LockQty = stockDetailModel.Qty; Db.Updateable(stockDetailModel).ExecuteCommand(); // 库存总表 锁定数量=当前锁定数量 + (库存明细托盘上数量-库存明细托盘上已锁定的数量) var stockModel = Db.Queryable().First(m => m.LotNo == stockDetailModel.LotNo && m.SkuNo == stockDetailModel.SkuNo && m.IsDel == "0"); stockModel.LockQty = stockModel.LockQty + (int)(stockDetailModel.Qty - lockQty); Db.Updateable(stockModel).ExecuteCommand(); // 拣货明细表 删除 var completeDetailModels = Db.Queryable().Where(m => m.ExportAllotId == allotModel.Id && m.IsDel == "0").ToList(); Db.Deleteable(completeDetailModels).ExecuteCommand(); // 插入异常处理表 string exceptionNo = new Common().GetMaxNo("EX"); var exceptionModel = new SysException() { ExceptionNo = exceptionNo, Type = "0", PalletNo = taskModel.PalletNo, ExcLocatNo = taskModel.StartLocat, OrderNo = noticeModel.SONo, TaskNo = taskModel.TaskNo, Status = "0", Text = "", // 处理描述 CreateUser = 0 }; Db.Insertable(exceptionModel).ExecuteCommand(); } Db.Updateable(allotModels).ExecuteCommand(); Db.CommitTran(); return true; } catch (Exception e) { Db.RollbackTran(); throw new Exception("程序错误:" + e.Message); } } #endregion #region 自动分配、取消分配、获取手动分配的数据源、手动分配 //自动分配 public bool AutoAllot(string soNo, int userId) { try { #region 判断条件(出库单、出库单明细) //出库单 var notice = Db.Queryable().Where(m => m.IsDel == "0" && m.SONo == soNo).ToList().FirstOrDefault(); if (notice == null) { throw new Exception("未查询到出库单据信息"); } if (notice.Status != "0" && notice.Status != "1") { throw new Exception("参数异常,请检查状态是否为等待执行或部分分配或来源是否是WMS"); } //出库单明细 var detailList = Db.Queryable().Where(m => m.IsDel == "0" && m.SONo == soNo && (m.AllotQty - m.Qty) <= 0).ToList(); if (!detailList.Any()) { throw new Exception("未查询到符合分配条件的出库单据明细信息"); } #endregion //包装信息 var packageNos = detailList.Select(d => d.PackagNo).ToList(); var packList = Db.Queryable().Where(m => packageNos.Contains(m.PackagNo)).ToList(); var exAllotList = new List(); var assign = new AllotSku(); Db.BeginTran(); try { foreach (var detail in detailList) { if (detail.AllotQty >= detail.Qty) { continue; } //还需要分配的数量 var needQty = detail.Qty - detail.AllotQty; //库存明细 Status 0:待分配 1:部分分配 2:已分配 var stockDetail = Db.Queryable().Where(m => m.SkuNo == detail.SkuNo && (m.Qty - m.FrozenQty - m.LockQty + m.InspectQty) > 0 && (m.Status == "0" || m.Status == "1") && m.IsDel == "0").ToList(); //判断单号是否指定批次 if (!string.IsNullOrWhiteSpace(detail.LotNo)) { stockDetail = stockDetail.Where(m => m.SkuNo == detail.SkuNo && m.LotNo == detail.LotNo && m.IsDel == "0").ToList(); } else { stockDetail = stockDetail.Where(m => m.SkuNo == detail.SkuNo && string.IsNullOrWhiteSpace(m.LotNo) && m.IsDel == "0").ToList(); } if (stockDetail.Count < 1) { throw new Exception("库存不足,无可出库库存"); } //if (notice.Type == "0" || notice.Type == "1")//成品、原辅料出库 //{ stockDetail = stockDetail.Where(m => m.InspectStatus == "1").ToList(); //} //else if (notice.Type == "2" || notice.Type == "3")//成品、原辅料出库(不合格) //{ // stockDetail = stockDetail.Where(m => m.InspectStatus == "2").ToList(); //} //else if (notice.Type == "4")//取样出库 //{ // stockDetail = stockDetail.Where(m => m.InspectStatus == "0").ToList(); //} //将库存明细按深度进行排序 深度1在前 深度2在后 //stockDetail = stockDetail.OrderBy(d => int.Parse(d.LocatNo.Substring(6, 2))).ToList(); #region 包装信息 var pack = packList.FirstOrDefault(p => p.PackagNo == detail.PackagNo); if (pack == null) { throw new Exception("未查询到物料包装"); } var pNum = 0;//托盘物品数量 var bNum = 0;//箱物品数量 if (pack.L5Num.HasValue) { pNum = Convert.ToInt32(pack.L5Num); bNum = Convert.ToInt32(pack.L4Num); } else if (pack.L4Num.HasValue) { pNum = Convert.ToInt32(pack.L4Num); bNum = Convert.ToInt32(pack.L3Num); } else if (pack.L3Num.HasValue) { pNum = Convert.ToInt32(pack.L3Num); bNum = Convert.ToInt32(pack.L2Num); } else if (pack.L2Num.HasValue) { pNum = Convert.ToInt32(pack.L2Num); bNum = Convert.ToInt32(pack.L1Num); } else if (pack.L1Num.HasValue) { pNum = Convert.ToInt32(pack.L1Num); bNum = Convert.ToInt32(pack.L1Num); } if (pNum == 0) { throw new Exception("未查询到物料包装托箱关系信息"); } #endregion //取合适库存商品 Dictionary stockQtyDic = new Dictionary();//托出库物品数 Dictionary zxQtyDic = new Dictionary();//托出整箱数 //分配货物 //assign.AllocatePallets(stocks, pNum, bNum, needQty, stockQtyDic, zxQtyDic); int qty = assign.AllotPallets(stockDetail, int.Parse(needQty.ToString()), pNum, bNum, stockQtyDic); foreach (var sc in stockQtyDic) { var s = stockDetail.FirstOrDefault(m => m.Id == sc.Key); //添加分配表信息 var allot = new BllExportAllot { SONo = notice.SONo, WaveNo = "", SODetailNo = detail.Id, StockId = sc.Key, LotNo = s.LotNo, LotText = s.LotText, SupplierLot = s.SupplierLot, SkuNo = s.SkuNo, SkuName = s.SkuName, Standard = s.Standard, PalletNo = s.PalletNo, IsBale = detail.IsBale == "0" ? "0" : s.IsBale == "1" ? "0" : "1", //是否裹包 IsBelt = detail.IsBelt == "0" ? "0" : s.IsBelt == "1" ? "0" : "1", //是否打带 Qty = sc.Value, CompleteQty = 0, //BoxexQty = s.Qty, //箱内数量 Status = "0", LogisticsId = notice.LogisticsId, IsAdvance = "0", OutMode = "",//出库口 CreateUser = userId, CreateTime = DateTime.Now }; exAllotList.Add(allot); s.LockQty += stockQtyDic[s.Id]; if (s.LockQty == s.Qty) { s.Status = "2"; } else { s.Status = "1"; } var sd = Db.Updateable(s).UpdateColumns(it => new { it.LockQty, it.Status }).ExecuteCommand(); } detail.AllotQty += qty; detail.UpdateUser = userId; detail.UpdateTime = DateTime.Now; if (detail.Status == "0") { detail.Status = "1"; } //库存总表 //var stock = Db.Queryable().First(d => d.IsDel == "0" && d.SkuNo == detail.SkuNo && d.LotNo == detail.LotNo); //stock.LockQty += qty; //Db.Updateable(stock).ExecuteCommand(); } var mx = Db.Updateable(detailList).ExecuteCommand(); var fp = Db.Insertable(exAllotList).ExecuteCommand(); //修改分配单据的状态 if (notice.Status == "0" || notice.Status == "1") { var bl = 0; var bl2 = 0; foreach (var item in detailList) { if (item.AllotQty <= 0) { continue; } if (item.AllotQty < item.Qty) { bl = 1; } else { bl2 = 1; } } switch (bl2) { case 1 when bl == 1: notice.Status = "1";//证明部分分配数量全部大于等于出库数量 修改为已分配 break; case 0 when bl == 1: notice.Status = "1";//证明部分分配数量全部大于等于出库数量 修改为已分配 break; case 1 when bl == 0: notice.Status = "2";//证明分配数量全部大于等于出库数量 修改为已分配 break; case 0 when bl == 0: //证明所有分配数量全部小于等于出库数量 不做修改 break; } } notice.UpdateUser = userId; notice.UpdateTime = DateTime.Now; var zd = Db.Updateable(notice).ExecuteCommand(); //添加操作日志记录 var k = new OperationSOServer().AddLogOperationSo("出库作业", "出库单据", notice.SONo, "分配", $"自动分配了单据号为{notice.SONo}的单据信息", userId); if (zd > 0 && mx > 0 && fp > 0 && k) { Db.CommitTran(); return true; } Db.RollbackTran(); return false; } catch (Exception e) { Db.RollbackTran(); throw new Exception(e.Message); } } catch (Exception e) { throw new Exception("自动分配失败:" + e.Message); } } //取消分配 public bool CancelAllot(string soNo, int userId) { try { var notice = Db.Queryable().Where(m => m.IsDel == "0" && m.SONo == soNo).ToList().FirstOrDefault(); if (notice == null) { throw new Exception("未查询到出库单据信息"); } if (notice.Status != "1" && notice.Status != "2") { throw new Exception("参数异常,请检查状态是否为已分配或部分分配或来源是否是WMS"); } //该单据的分配信息 Status 0:任务下发 1:待拣货 2:部分拣货 3:待回库 4:已完成 var allotList = Db.Queryable().Where(o => o.IsDel == "0" && o.SONo == soNo).ToList(); //有已执行的分配数据不能取消 if (allotList.Any(o => o.Status != "0")) { throw new Exception("当前单据的分配信息已有执行中,不能取消分配"); } Db.BeginTran(); try { //查询分配的明细 var detail = Db.Queryable().Where(d => d.SONo == soNo && d.AllotQty > 0 && d.IsDel == "0").ToList(); foreach (var d in detail) { var orders = allotList.Where(o => o.SODetailNo == d.Id).ToList(); foreach (var o in orders) { var pq = Db.Queryable().Where(t => t.Id == o.StockId); var pq2 = !string.IsNullOrWhiteSpace(o.LotNo) ? pq.Where(t => t.LotNo == o.LotNo).ToList() : pq.Where(t => string.IsNullOrWhiteSpace(t.LotNo)).ToList(); var pallet = pq2.FirstOrDefault(); if (pallet != null) { pallet.LockQty -= o.Qty; pallet.Status = pallet.LockQty == 0 ? "0" : "1"; //如果锁定数量是0状态变更为待分配 否则为部分分配 Db.Updateable(pallet).ExecuteCommand(); //库存总表 //var stock = Db.Queryable().First(t => t.SkuNo == pallet.SkuNo && t.IsDel == "0"); //stock.LockQty -= o.Qty; //Db.Updateable(stock).ExecuteCommand(); } } Db.Deleteable(orders).ExecuteCommand(); d.AllotQty = 0; d.Status = "0"; d.UpdateUser = userId; d.UpdateTime = DateTime.Now; } notice.Status = "0"; notice.UpdateUser = userId; notice.UpdateTime = DateTime.Now; Db.Updateable(detail).ExecuteCommand(); Db.Updateable(notice).ExecuteCommand(); //添加操作日志记录 var k = new OperationSOServer().AddLogOperationSo("出库作业", "出库单据", notice.SONo, "取消分配", $"取消分配了单据号为{notice.SONo}的单据信息", userId); Db.CommitTran(); } catch (Exception e) { Db.RollbackTran(); throw new Exception(e.Message); } return true; } catch (Exception e) { throw new Exception("取消分配失败" + e.Message); } } /// /// 维护出库单备注信息 /// /// /// /// public void EditNoticeDemo(int id, string demo, int userId) { try { var notice = Db.Queryable().First(m => m.IsDel == "0" && m.Id == id); if (notice == null) { throw new Exception("未查询到出库单据信息"); } notice.Demo = demo + "".Trim(); notice.UpdateUser = userId; notice.UpdateTime = DateTime.Now; int i = Db.Updateable(notice).ExecuteCommand(); if (i > 0) { //添加操作日志 new OperationSOServer().AddLogOperationSo("出库作业", "出库单据", notice.SONo, "编辑", $"编辑了单据号为{notice.SONo}的备注信息", userId); } } catch (Exception ex) { throw new Exception(ex.Message); } } //获取库存明细信息(出库单手动分配选择数据源) public List GetHandOutList(int detailId, string houseNo, string roadwayNo, string locateNo, string msg, string palletNo) { try { var detail = Db.Queryable().First(d => d.Id == detailId); #region 判断条件 if (detail == null) { throw new Exception("获取失败,未找到指定出库单!"); } if (detail.Status != "0" && detail.Status != "1" && detail.AllotQty >= detail.Qty) { throw new Exception("获取失败,出库单状态不是等待执行或分配中!"); } if (detail.AllotQty >= detail.Qty) { throw new Exception("获取失败,出库单已分配完成!"); } var notice = Db.Queryable().First(a => a.SONo == detail.SONo); if (notice == null) { throw new Exception("获取失败,未找到指定出库单!"); } if (notice.Status == "3" && detail.AllotQty >= detail.Qty || notice.Status == "4" || notice.Status == "5") { throw new Exception("获取失败,出库单状态不允许!"); } #endregion 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(palletNo), m => m.PalletNo == palletNo) .AndIF(!string.IsNullOrWhiteSpace(msg), m => m.SkuNo.Contains(msg.Trim()) || m.SkuName.Contains(msg.Trim()) || m.LocatNo.Contains(msg.Trim())) .And(m => m.IsDel == "0" && m.SkuNo == detail.SkuNo && m.LotNo == detail.LotNo &&(m.Status == "0" || m.Status == "1")) .ToExpression();//注意 这一句 不能少 var list = Db.Queryable().Where(item).Select(a => new StockDetailDto { Id = a.Id, SkuNo = a.SkuNo, SkuName = a.SkuName, Standard = a.Standard, LotNo = a.LotNo, LotText = a.LotText, SupplierLot = a.SupplierLot, Qty = a.Qty - a.LockQty - a.FrozenQty, LocatNo = a.LocatNo, RoadwayNo = a.RoadwayNo, PalletNo = a.PalletNo, }).ToList(); return list; } catch (Exception e) { throw new Exception(e.Message); } } //手动分配出库单明细 public void AddHandOutAllot(AddHandOutVm model, int userId) { try { #region 判断条件 //数据验证 var detail = Db.Queryable().First(a => a.IsDel == "0" && a.Id == model.Id); if (detail == null) { throw new Exception("操作失败,未找到指定出库单详情!"); } if (detail.AllotQty >= detail.Qty || (detail.Status != "0" && detail.Status != "1")) { throw new Exception("操作失败,出库单已分配完成!"); } var notice = Db.Queryable().First(a => a.IsDel =="0" && a.SONo == detail.SONo); if (notice == null) { throw new Exception("操作失败,未找到指定出库单!"); } if (notice.Status == "3" && detail.AllotQty >= detail.Qty || notice.Status == "4" || notice.Status == "5") { throw new Exception("操作失败,出库单已分配完成!"); } #endregion //单据明细需要的出库数量 var needQty = detail.Qty - detail.AllotQty; //分配的出库数量 var outQty = model.StockList.Select(s => s.Qty).ToList().Sum(); if (outQty != needQty) { throw new Exception("操作失败,出库数量与计划数量不一致!"); } var stockIds = model.StockList.Select(a => a.StockId).ToList(); //库存明细 var stockList = Db.Queryable().Where(a => stockIds.Contains(a.Id)).ToList(); //库存总表 //var stockz = Db.Queryable().First(d => d.IsDel == "0" && d.SkuNo == detail.SkuNo && d.LotNo == detail.LotNo); var allotList = new List(); var outQtys = 0; foreach (var st in model.StockList) { var stock = stockList.First(a => a.Id == st.StockId); if (stock == null) { throw new Exception("操作失败,部分储位库存异常!"); } if (st.Qty > (stock.Qty-stock.LockQty-stock.FrozenQty -stock.InspectQty)) { throw new Exception("操作失败,出库数量超出库存数量!"); } //添加分配表信息 var allot = new BllExportAllot { SONo = notice.SONo, WaveNo = "", SODetailNo = detail.Id, StockId = st.StockId, LotNo = stock.LotNo, LotText = stock.LotText, SupplierLot = stock.SupplierLot, SkuNo = stock.SkuNo, SkuName = stock.SkuName, Standard = stock.Standard, PalletNo = stock.PalletNo, IsBale = stock.IsBale, IsBelt = stock.IsBelt, Qty = st.Qty, CompleteQty = 0, Status = "0", LogisticsId = notice.LogisticsId, IsAdvance = "0", OutMode = "",//出库口 CreateUser = userId, CreateTime = DateTime.Now }; allotList.Add(allot); //库存明细 stock.LockQty += st.Qty; stock.Status = stock.LockQty == stock.Qty ? "2" : "1"; //库存总表 //stockz.LockQty += st.Qty; //Db.Updateable(stockz).ExecuteCommand(); Db.Updateable(stock).UpdateColumns(it => new { it.LockQty, it.Status }).ExecuteCommand(); outQtys += st.Qty; } Db.Insertable(allotList).ExecuteCommand(); //修改单据明细 detail.AllotQty += outQtys; detail.UpdateUser = userId; detail.UpdateTime = DateTime.Now; if (detail.Status == "0") { detail.Status = "1"; } Db.Updateable(detail).ExecuteCommand(); var detailList = Db.Queryable() .Where(m => m.IsDel == "0" && m.SONo == notice.SONo).ToList(); //修改出库单状态 if (notice.Status == "0" || notice.Status == "1") { int totalQty = 0; int totalAllotQty = 0; foreach (var item in detailList) { totalQty += item.Qty; totalAllotQty += Convert.ToInt32(item.AllotQty); } if (totalAllotQty >= totalQty) { notice.Status = "2";//证明分配数量大于等于出库数量 修改为已分配 } else if (totalAllotQty< totalQty && totalAllotQty>0) { notice.Status = "1";//证明分配数量小于等于出库数量 修改为部分分配 } Db.Updateable(notice).ExecuteCommand(); } //添加操作日志记录 var k = new OperationSOServer().AddLogOperationSo("出库作业", "出库单据", notice.SONo, "分配", $"手动分配了单据号为{notice.SONo}、物料:{detail.SkuNo}、批次:{detail.LotNo}的单据信息", userId); Db.CommitTran(); } catch (Exception e) { Db.RollbackTran(); throw new Exception(e.Message); } } #endregion } }