| | |
| | | using System.Runtime.Intrinsics.X86; |
| | | using ZXing.OneD; |
| | | using System.Threading.Tasks; |
| | | using System.Diagnostics; |
| | | using System.Drawing.Drawing2D; |
| | | using Model.ModelDto.LogDto; |
| | | using AutoMapper.Internal; |
| | | |
| | | namespace WMS.BLL.BllSoServer |
| | | { |
| | | public class ExportNoticeServer : DbHelper<BllExportNotice>, IExportNoticeServer |
| | | { |
| | | private static readonly SqlSugarScope Db = DataContext.Db; |
| | | private readonly object IssueOutLock = new object(); |
| | | public ExportNoticeServer() : base(Db) |
| | | { |
| | | } |
| | |
| | | |
| | | #endregion |
| | | |
| | | #region JC34 |
| | | |
| | | #region 基础功能 |
| | | |
| | | public async Task<List<ExportNoticeDto>> GetExportNoticeList(GetExportNoticeVm model, RefAsync<int> count) |
| | |
| | | .LeftJoin<SysUserInfor>((a, b, c) => a.CreateUser == c.Id) |
| | | .LeftJoin<SysUserInfor>((a, b, c, d) => a.CreateUser == d.Id) |
| | | .LeftJoin<SysUserInfor>((a, b, c, d, e) => a.CheckUser == e.Id) |
| | | .Select((a, b, c, d, e) => new ExportNoticeDto() |
| | | .LeftJoin<SysWareHouse>((a, b, c, d, e,f) => a.WareHouseNo == f.WareHouseNo) |
| | | .Select((a, b, c, d, e,f) => new ExportNoticeDto() |
| | | { |
| | | Id = a.Id, |
| | | SONo = a.SONo, |
| | | Type = a.Type, |
| | | Status = a.Status, |
| | | WareHouseName = f.WareHouseName, |
| | | Origin = a.Origin, |
| | | CustomerNo = a.CustomerNo, |
| | | CustomerName = a.CustomerName, |
| | |
| | | } |
| | | |
| | | //获取添加/编辑出库单时选择物料明细信息 |
| | | public List<ExStockInfoDto> GetStockGroupList(string type, string ownerNo, string msg) |
| | | public List<ExStockInfoDto> GetStockGroupList(string house, string type, string ownerNo, string msg) |
| | | { |
| | | try |
| | | { |
| | | if (string.IsNullOrEmpty(house)) |
| | | { |
| | | throw new Exception("请选择出库仓库"); |
| | | } |
| | | if (string.IsNullOrEmpty(type)) |
| | | { |
| | | throw new Exception("请选择出库单类型"); |
| | |
| | | switch (type)//0:原料 1:包材 2:成品 3:耗材 4:半成品 |
| | | { |
| | | case "0"://成品出库 |
| | | if (house !="W01") |
| | | { |
| | | throw new Exception("成品出库只能选择成品库"); |
| | | } |
| | | skuType = "(2)"; |
| | | inspectStatus = "1"; |
| | | break; |
| | | case "1"://领料出库 |
| | | if (house != "W02") |
| | | { |
| | | throw new Exception("领料出库只能选择原料库"); |
| | | } |
| | | skuType = "(0,1,3)"; |
| | | inspectStatus = "1"; |
| | | break; |
| | | case "2"://抽检出库 |
| | | skuType = "(0,1,2,3)"; |
| | | if (house == "W01") |
| | | { |
| | | skuType = "(2)"; |
| | | } |
| | | if (house == "W02") |
| | | { |
| | | skuType = "(0,1,3)"; |
| | | } |
| | | inspectStatus = "0,1,2"; |
| | | break; |
| | | case "3"://物料取样出库 |
| | | skuType = "(0,1,2,3)"; |
| | | if (house == "W01") |
| | | { |
| | | skuType = "(2)"; |
| | | } |
| | | if (house == "W02") |
| | | { |
| | | skuType = "(0,1,3)"; |
| | | } |
| | | inspectStatus = "0"; |
| | | break; |
| | | case "4"://不合格品出库 |
| | | skuType = "(0,1,2,3)"; |
| | | if (house == "W01") |
| | | { |
| | | skuType = "(2)"; |
| | | } |
| | | if (house == "W02") |
| | | { |
| | | skuType = "(0,1,3)"; |
| | | } |
| | | inspectStatus = "2"; |
| | | break; |
| | | case "5"://中间品出库 |
| | |
| | | skuType = "(2)"; |
| | | inspectStatus = "0,1"; |
| | | break; |
| | | case "8"://寄存出库 |
| | | skuType = "(0,1,2,3)"; |
| | | case "7"://其它出库 |
| | | if (house == "W01") |
| | | { |
| | | skuType = "(2)"; |
| | | } |
| | | if (house == "W02") |
| | | { |
| | | skuType = "(0,1,3,4)"; |
| | | } |
| | | inspectStatus = "0,1"; |
| | | break; |
| | | case "8"://寄存出库 |
| | | if (house == "W01") |
| | | { |
| | | skuType = "(2)"; |
| | | } |
| | | if (house == "W02") |
| | | { |
| | | skuType = "(0,1,3)"; |
| | | } |
| | | inspectStatus = "0,1"; |
| | | break; |
| | | case "9"://生产领料出库 |
| | | if (house != "W02") |
| | | { |
| | | throw new Exception("生产领料出库只能选择原料库"); |
| | | } |
| | | skuType = "(0,1,3)"; |
| | | inspectStatus = "1"; |
| | | break; |
| | | default: //其它出库 |
| | | skuType = "(0,1,2,3,4)"; |
| | | inspectStatus = "0,1"; |
| | | break; |
| | | throw new Exception("单据类型错误"); |
| | | } |
| | | var skuList = sku.Where(m => skuType.Contains(m.Type)).ToList(); |
| | | if (skuList.Count == 0) |
| | |
| | | |
| | | if (type == "6") |
| | | { |
| | | skuList = skuList.Where(m=> string.IsNullOrWhiteSpace(m.PackagNo)).ToList(); |
| | | skuList = skuList.Where(m => string.IsNullOrWhiteSpace(m.PackagNo)).ToList(); |
| | | } |
| | | if (type!="8") |
| | | if (type != "8") |
| | | { |
| | | skuList = skuList.Where(m => m.SkuNo != "100088").ToList(); |
| | | } |
| | |
| | | var stockRst = new StockServer(); |
| | | var stockDetailRst = new StockDetailServer(); |
| | | Expression<Func<DataStockDetail, bool>> item = Expressionable.Create<DataStockDetail>() |
| | | //.And(it => it.WareHouseNo == wareHouseNo) |
| | | .And(it => it.WareHouseNo == house || string.IsNullOrWhiteSpace(it.LocatNo)) |
| | | .AndIF(!string.IsNullOrWhiteSpace(inspectStatus), it => inspectStatus.Contains(it.InspectStatus)) |
| | | .And(m => skuStrList.Contains(m.SkuNo)) |
| | | .AndIF(type == "6", m => m.OwnerNo == ownerNo)//代储出库需要关联货主 |
| | |
| | | var skuNos = model.Detail.Select(a => a.SkuNo).Distinct().ToList(); |
| | | //根据物料号获取物料信息、库存明细中获取批次描述供货批次等 |
| | | var skuList = Db.Queryable<SysMaterials>().Where(a => skuNos.Contains(a.SkuNo) && a.IsDel == "0").ToList(); |
| | | switch (model.WareHouseNo) |
| | | { |
| | | case "W01"://成品库 |
| | | if (skuList.Any(m=>m.Type !="2")) |
| | | { |
| | | throw new Exception("仓库与出库物料不符"); |
| | | } |
| | | break; |
| | | case "W02"://原料库 |
| | | if (skuList.Any(m => m.Type == "2")) |
| | | { |
| | | throw new Exception("仓库与出库物料不符"); |
| | | } |
| | | break; |
| | | default: |
| | | throw new Exception("仓库号错误"); |
| | | } |
| | | var stockList = Db.Queryable<DataStock>().Where(s => skuNos.Contains(s.SkuNo) && (s.Qty - s.FrozenQty - s.LockQty) > 0).ToList(); |
| | | //var palletList = contextDb.Queryable<DataStockDetail>().Where(s => skuNos.Contains(s.SkuNo) && (s.Qty - s.FrozenQty - s.LockQty) > 0).ToList(); |
| | | //客户信息 |
| | |
| | | throw new Exception($"物料信息中未查询到出库物料信息:{d.SkuNo}"); |
| | | } |
| | | |
| | | //0:成品出库、1:领料出库、2:抽检出库、4:不合格品出库、6:代储出库、7:其他出库、 ///3:物料取样出库、5:中间品出库、8:寄存出库 |
| | | //0:成品出库、1:领料出库、2:抽检出库、4:不合格品出库、7:其他出库、9生产领料出库 ///3:物料取样出库、5:中间品出库、6:代储出库、8:寄存出库 |
| | | if (model.Type == "0" || model.Type == "2" || model.Type == "4" || model.Type == "7") |
| | | { |
| | | if (string.IsNullOrWhiteSpace(d.LotNo)) |
| | |
| | | } |
| | | } |
| | | |
| | | if (model.Type == "1") |
| | | { |
| | | if (list.Count(m=>m.SkuNo == d.SkuNo)>=2) |
| | | { |
| | | throw new Exception("领料出库单同单据同物料不允许超过3个批次混批出库"); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | if (list.Count(m => m.SkuNo == d.SkuNo) >= 1) |
| | | { |
| | | throw new Exception("出库单同单据同物料不允许超过2个批次混批出库"); |
| | | } |
| | | } |
| | | //if (model.Type == "1") |
| | | //{ |
| | | // if (list.Count(m=>m.SkuNo == d.SkuNo)>=2) |
| | | // { |
| | | // throw new Exception("领料出库单同单据同物料不允许超过3个批次混批出库"); |
| | | // } |
| | | //} |
| | | //else |
| | | //{ |
| | | // if (list.Count(m => m.SkuNo == d.SkuNo) >= 1) |
| | | // { |
| | | // throw new Exception("出库单同单据同物料不允许超过2个批次混批出库"); |
| | | // } |
| | | //} |
| | | //库存 |
| | | List<DataStock> stocks; |
| | | |
| | |
| | | }; |
| | | list.Add(item); |
| | | |
| | | |
| | | |
| | | stocks.First().LockQty += d.Qty;//锁定数量 |
| | | var i = Db.Updateable(stocks.First()).UpdateColumns(it => new { it.LockQty }) |
| | | .ExecuteCommand(); |
| | |
| | | IsWave = "0", |
| | | WaveNo = "", |
| | | IsDespatch = "0", |
| | | |
| | | WareHouseNo = model.WareHouseNo, |
| | | CreateUser = userId, |
| | | }; |
| | | |
| | |
| | | { |
| | | SoNo = notify.SONo, |
| | | Type = notify.Type, |
| | | WareHouseNo = notify.WareHouseNo, |
| | | CustomerNo = notify.CustomerNo, |
| | | LogisticsId = notify.LogisticsId, |
| | | //ExportWarehouseId = notify.ExportWarehouseId, |
| | |
| | | //查询改后的单据信息 后期接口对接完后需改动回传参数 |
| | | var detail = Db.Queryable<BllExportNoticeDetail>().Where(m => m.IsDel == "0" && m.SONo == notice.SONo).Select(m => new SelectStockSkuDto |
| | | { |
| | | LotNo =m.LotNo, |
| | | LotNo = m.LotNo, |
| | | SkuNo = m.SkuNo, |
| | | SkuName = m.SkuName, |
| | | Qty = m.Qty, |
| | | Qty = m.Qty, |
| | | ExQty = decimal.Parse(m.CompleteQty.ToString()), |
| | | Standard = m.Standard, |
| | | IsBale = m.IsBale, |
| | |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | #region 自动分配、取消分配、获取手动分配的数据源、手动分配 |
| | | |
| | | // 判断是否是跨批出库 |
| | | public bool IsCrossLotNo(string soNo) |
| | | { |
| | | try |
| | | { |
| | | //方法返回结果:bl |
| | | var bl = true; |
| | | //查询单据信息 |
| | | var notice = Db.Queryable<BllExportNotice>().First(m => m.SONo == soNo && m.IsDel == "0"); |
| | | //判断单据类型 成品出库、领料出库(其它类型跳出此方法) |
| | | if (notice.Type != "0" && notice.Type != "1") |
| | | { |
| | | return bl; |
| | | } |
| | | //查询到当前单据下的出库单明细信息 |
| | | var noticeDetail = Db.Queryable<BllExportNoticeDetail>().Where(m => m.IsDel == "0" && m.SONo == soNo).ToList(); |
| | | //库存总表信息 |
| | | var data = Db.Queryable<DataStock>().Where(m => m.IsDel == "0").ToList(); |
| | | //库存明细中检验合格批次集合 |
| | | var dataDetail = Db.Queryable<DataStockDetail>().Where(m => m.IsDel == "0" && m.InspectStatus == "1").GroupBy(g => g.LotNo).Select(s => s.LotNo).ToList(); |
| | | //库存明细表信息 |
| | | var dataBoxInfo = Db.Queryable<DataBoxInfo>().Where(m => m.IsDel == "0").ToList(); |
| | | |
| | | |
| | | //循环单据明细信息 |
| | | foreach (var item in noticeDetail) |
| | | { |
| | | //验证先进先出原则 |
| | | //获取当前物料的所有批次信息(排除单据的批次,防止单据所在批次锁定数量后验证小于等于0) |
| | | var forData = data.Where(m => m.SkuNo == item.SkuNo |
| | | && m.LotNo != item.LotNo && (m.Qty - m.FrozenQty - m.LockQty) > 0 |
| | | && dataDetail.Contains(m.LotNo)).Select(m => m.LotNo).ToList(); |
| | | |
| | | forData.Add(item.LotNo); //集合添加单据的批次 |
| | | //获取排序后的第一个批次 |
| | | var firstLotNo = forData.OrderBy(m => m).First(); |
| | | if (firstLotNo != item.LotNo) |
| | | { |
| | | bl = false; |
| | | break; |
| | | } |
| | | |
| | | //验证效期优先原则 |
| | | var forDataBox = dataBoxInfo.Where(m => m.SkuNo == item.SkuNo && m.LotNo != item.LotNo && m.Qty > 0).ToList(); |
| | | //获取当前单据批次的最近效期 |
| | | var expirationTimedt = dataBoxInfo.Where(m => m.SkuNo == item.SkuNo |
| | | && m.LotNo == item.LotNo && m.Qty > 0).ToList(); |
| | | if (expirationTimedt.Count > 0) |
| | | { |
| | | var expirationTime = expirationTimedt.OrderBy(m => m.ExpirationTime).Select(m => m.ExpirationTime).First(); |
| | | //获取库存中其它批次效期大于当前单据批次的效期数量 |
| | | var num = forDataBox.Count(m => m.ExpirationTime > expirationTime); |
| | | //判断是否大于0 |
| | | if (num > 0) |
| | | { |
| | | bl = false; |
| | | break; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | var dataDetailtime = Db.Queryable<DataStockDetail>().Where(m => m.IsDel == "0" && m.InspectStatus == "1"). |
| | | Where(m => m.SkuNo == item.SkuNo |
| | | && m.LotNo == item.LotNo && m.Qty > 0) |
| | | .OrderBy(m => m.ExpirationTime) |
| | | .Select(m => m.ExpirationTime).First(); |
| | | |
| | | var num = forDataBox.Count(m => m.ExpirationTime > dataDetailtime); |
| | | //判断是否大于0 |
| | | if (num > 0) |
| | | { |
| | | bl = false; |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | return bl; |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | throw new Exception(e.Message); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 自动分配 |
| | | /// </summary> |
| | | /// <param name="soNo"></param> |
| | | /// <param name="userId"></param> |
| | | /// <returns></returns> |
| | | /// <exception cref="Exception"></exception> |
| | | public bool AutoAllot(string soNo, int userId) |
| | | { |
| | | try |
| | | { |
| | | #region 判断条件(出库单、出库单明细) |
| | | //出库单 |
| | | var notice = Db.Queryable<BllExportNotice>().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("参数异常,请检查状态是否为等待执行或部分分配;"); |
| | | } |
| | | //出库单明细 |
| | | var detailList = Db.Queryable<BllExportNoticeDetail>().Where(m => m.IsDel == "0" && m.SONo == soNo && (m.AllotQty - m.Qty) <= 0).ToList(); |
| | | if (!detailList.Any()) |
| | | { |
| | | throw new Exception("未查询到符合分配条件的出库单据明细信息"); |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | var exAllotList = new List<BllExportAllot>(); |
| | | var assign = new AllotSku(); |
| | | Db.BeginTran(); |
| | | try |
| | | { |
| | | List<SoDetailInfo> soDetailList = new List<SoDetailInfo>(); |
| | | foreach (var detail in detailList) |
| | | { |
| | | if (detail.AllotQty >= detail.Qty) |
| | | { |
| | | continue; |
| | | } |
| | | //还需要分配的数量 |
| | | decimal needQty = detail.Qty - (detail.AllotQty == null ? 0 : decimal.Parse(detail.AllotQty.ToString())); |
| | | //库存明细 Status 0:待分配 1:部分分配 2:已分配 |
| | | var stockDetail = Db.Queryable<DataStockDetail>().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 && m.IsDel == "0" && string.IsNullOrWhiteSpace(m.LotNo)).ToList(); |
| | | } |
| | | |
| | | if (stockDetail.Count < 1) |
| | | { |
| | | throw new Exception("库存不足,无可出库库存"); |
| | | } |
| | | //0:成品出库、1:领料出库、2:抽检出库、4:不合格品出库、7:其他出库、9:生产领料出库 ///3:取样出库、5:中间品出库、8:寄存出库 |
| | | if (notice.Type == "0" || notice.Type == "1" || notice.Type == "9")//成品、领料出库 |
| | | { |
| | | stockDetail = stockDetail.Where(m => m.InspectStatus == "1").ToList(); |
| | | } |
| | | else if (notice.Type == "2")//抽检出库 |
| | | { |
| | | stockDetail = stockDetail.Where(m => m.InspectStatus == "0" || m.InspectStatus == "1" || m.InspectStatus == "2").ToList(); |
| | | } |
| | | else if (notice.Type == "4")//不合格出库 |
| | | { |
| | | stockDetail = stockDetail.Where(m => m.InspectStatus == "2").ToList(); |
| | | } |
| | | else if (notice.Type == "7") //、其它 |
| | | { |
| | | stockDetail = stockDetail.Where(m => m.InspectStatus == "0" || m.InspectStatus == "1").ToList(); |
| | | } |
| | | if (stockDetail.Sum(m => m.Qty - m.LockQty) < needQty) |
| | | { |
| | | throw new Exception("库存明细数量不足"); |
| | | } |
| | | #region 包装信息 |
| | | |
| | | var pNum = 0;//托盘物品数量 |
| | | var bNum = 0;//箱物品数量 |
| | | //公共方法获取包装数量 |
| | | new Common().GetPackQtyInfo(detail.PackagNo, ref pNum, ref bNum); |
| | | |
| | | #endregion |
| | | |
| | | //取合适库存商品 |
| | | Dictionary<int, decimal> stockQtyDic = new Dictionary<int, decimal>();//托出库物品数 |
| | | var qty = 0m; |
| | | var house = ""; |
| | | |
| | | //分配货物 |
| | | qty += assign.AllotPallets(stockDetail, needQty, pNum, bNum, stockQtyDic, notice.WareHouseNo); |
| | | 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"; |
| | | } |
| | | if (qty > detail.Qty) |
| | | { |
| | | //库存总表 |
| | | var stock = Db.Queryable<DataStock>().First(d => d.IsDel == "0" |
| | | && d.SkuNo == detail.SkuNo |
| | | && d.LotNo == detail.LotNo); |
| | | stock.LockQty += qty - detail.Qty; |
| | | Db.Updateable(stock).ExecuteCommand(); |
| | | |
| | | //添加回传上游系统锁定数量更改代码 |
| | | SoDetailInfo soDetail = new SoDetailInfo(); |
| | | soDetail.OrderDetailCode = detail.OrderDetailCode; |
| | | soDetail.LockQty = qty - detail.Qty; |
| | | soDetail.LotNo = detail.LotNo; |
| | | |
| | | soDetailList.Add(soDetail); |
| | | } |
| | | |
| | | } |
| | | |
| | | 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) |
| | | { |
| | | #region 通过接口发送至erp |
| | | //系统对接后放开 |
| | | /*var jsonData = JsonConvert.SerializeObject(soDetailList); |
| | | |
| | | var response = HttpHelper.DoPost(url, jsonData, "库存锁定数量变更", "ERP"); |
| | | |
| | | var obj = JsonConvert.DeserializeObject<ErpModel>(response);//解析返回数据 |
| | | if (obj.Success != 0) |
| | | { |
| | | throw new Exception("上传失败" + obj.Message); |
| | | }*/ |
| | | #endregion |
| | | |
| | | 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<BllExportNotice>().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<BllExportAllot>().Where(o => o.IsDel == "0" && o.SONo == soNo).ToList(); |
| | | //有已执行的分配数据不能取消 |
| | | if (allotList.Any(o => o.Status != "0")) |
| | | { |
| | | throw new Exception("当前单据的分配信息已有执行中,不能取消分配"); |
| | | } |
| | | List<SoDetailInfo> soDetailList = new List<SoDetailInfo>(); |
| | | //开启事务 |
| | | Db.BeginTran(); |
| | | try |
| | | { |
| | | //查询分配的明细 |
| | | var detail = Db.Queryable<BllExportNoticeDetail>().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<DataStockDetail>().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<DataStock>().First(t => t.SkuNo == pallet.SkuNo && t.IsDel == "0"); |
| | | //stock.LockQty -= o.Qty; |
| | | //Db.Updateable(stock).ExecuteCommand(); |
| | | } |
| | | |
| | | } |
| | | Db.Deleteable<BllExportAllot>(orders).ExecuteCommand(); |
| | | |
| | | if (d.AllotQty > d.Qty) |
| | | { |
| | | //库存总表 |
| | | var stock = Db.Queryable<DataStock>().First(m => m.IsDel == "0" && m.SkuNo == d.SkuNo && m.LotNo == d.LotNo); |
| | | stock.LockQty -= (decimal)d.AllotQty - d.Qty; |
| | | Db.Updateable(stock).ExecuteCommand(); |
| | | |
| | | //添加回传上游系统锁定数量更改代码 |
| | | SoDetailInfo soDetail = new SoDetailInfo(); |
| | | soDetail.OrderDetailCode = d.OrderDetailCode; |
| | | soDetail.LockQty = (decimal)(d.Qty - d.AllotQty); |
| | | soDetail.LotNo = d.LotNo; |
| | | |
| | | soDetailList.Add(soDetail); |
| | | } |
| | | d.AllotQty = 0; |
| | | d.Status = "0"; |
| | | d.UpdateUser = userId; |
| | | d.UpdateTime = DateTime.Now; |
| | | //if (notice.Type == "1" || notice.Type == "5" || notice.Type == "6" || notice.Type == "7" || notice.Type == "8")//1:领料出库、 |
| | | //{ |
| | | // if (d.IsIssueLotNo != "1") |
| | | // { |
| | | // d.LotNo = ""; |
| | | // } |
| | | |
| | | //} |
| | | } |
| | | |
| | | //查询当前单据是否已添加备料任务 |
| | | if (notice.Type == "1") |
| | | { |
| | | var task = Db.Queryable<BllExportTimingTask>().First(m => m.IsDel == "0" && m.SoNo == soNo); |
| | | if (task != null) |
| | | { |
| | | task.IsDel = "1"; |
| | | task.UpdateUser = userId; |
| | | task.UpdateTime = DateTime.Now; |
| | | Db.Updateable(task).ExecuteCommand(); |
| | | } |
| | | } |
| | | notice.Status = "0"; |
| | | notice.UpdateUser = userId; |
| | | notice.UpdateTime = DateTime.Now; |
| | | Db.Updateable(detail).ExecuteCommand(); |
| | | Db.Updateable(notice).ExecuteCommand(); |
| | | |
| | | //系统对接后放开 |
| | | /*var jsonData = JsonConvert.SerializeObject(soDetailList); |
| | | |
| | | var response = HttpHelper.DoPost(url, jsonData, "库存锁定数量变更", "ERP"); |
| | | |
| | | var obj = JsonConvert.DeserializeObject<ErpModel>(response);//解析返回数据 |
| | | if (obj.Success != 0) |
| | | { |
| | | throw new Exception("上传失败" + obj.Message); |
| | | }*/ |
| | | |
| | | //添加操作日志记录 |
| | | 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); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 维护出库单备注信息 |
| | | /// </summary> |
| | | /// <param name="id"></param> |
| | | /// <param name="demo"></param> |
| | | /// <param name="userId"></param> |
| | | public void EditNoticeDemo(int id, string demo, int userId) |
| | | { |
| | | try |
| | | { |
| | | var notice = Db.Queryable<BllExportNotice>().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<StockDetailDto> GetHandOutList(int detailId, string houseNo, string roadwayNo, string locateNo, string msg, string palletNo) |
| | | { |
| | | try |
| | | { |
| | | var detail = Db.Queryable<BllExportNoticeDetail>().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<BllExportNotice>().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<Func<DataStockDetail, bool>> item = Expressionable.Create<DataStockDetail>() |
| | | .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<DataStockDetail>().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, |
| | | Demo = a.Demo, |
| | | }).ToList(); |
| | | |
| | | return list; |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | throw new Exception(e.Message); |
| | | } |
| | | } |
| | | |
| | | //手动分配出库单明细 |
| | | public void AddHandOutAllot(AddHandOutVm model, int userId) |
| | | { |
| | | try |
| | | { |
| | | #region 判断条件 |
| | | //数据验证 |
| | | var detail = Db.Queryable<BllExportNoticeDetail>().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<BllExportNotice>().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<DataStockDetail>().Where(a => stockIds.Contains(a.Id)).ToList(); |
| | | |
| | | //分配信息 |
| | | var allots = Db.Queryable<BllExportAllot>().Where(m => m.IsDel == "0" && m.SODetailNo == detail.Id && m.Status == "0").ToList(); |
| | | |
| | | //库存总表 |
| | | //var stockz = Db.Queryable<DataStock>().First(d => d.IsDel == "0" && d.SkuNo == detail.SkuNo && d.LotNo == detail.LotNo); |
| | | |
| | | var allotList = new List<BllExportAllot>(); |
| | | decimal 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)) // 输入的数量 - 托盘上可用的数量(托盘上数量-锁定的数量-冻结的数量) |
| | | { |
| | | throw new Exception("操作失败,出库数量超出库存数量!"); |
| | | } |
| | | |
| | | var bl = allots.FirstOrDefault(m => m.StockId == st.StockId); |
| | | if (bl == null) |
| | | { |
| | | //添加分配表信息 |
| | | 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); |
| | | } |
| | | else |
| | | { |
| | | bl.Qty += st.Qty; |
| | | Db.Updateable(bl).ExecuteCommand(); |
| | | } |
| | | |
| | | //库存明细 |
| | | 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<BllExportNoticeDetail>() |
| | | .Where(m => m.IsDel == "0" && m.SONo == notice.SONo).ToList(); |
| | | //修改出库单状态 |
| | | if (notice.Status == "0" || notice.Status == "1") |
| | | { |
| | | decimal totalQty = 0; |
| | | decimal 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 |
| | | |
| | | #region 下发出库、出库完成、重新下发任务、取消任务、异常处理 |
| | | |
| | | public string GetHouseBySo(string soNo) |
| | | { |
| | | try |
| | | { |
| | | var notcie = Db.Queryable<BllExportNotice>().First(m=>m.IsDel == "0" && m.SONo == soNo); |
| | | if (notcie == null) |
| | | { |
| | | throw new Exception("未查询到出库单信息"); |
| | | } |
| | | return notcie.WareHouseNo; |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | throw new Exception(e.Message); |
| | | } |
| | | } |
| | | |
| | | public List<OutCommandDto> IssueOutHouseLk(string soNo, string outMode, int userId, string url, out string str) |
| | | { |
| | | try |
| | | { |
| | | var outDto1 = new List<OutCommandDto>(); //出库数据的集合(深度为1的储位) |
| | | //记录错误信息的集合 //1:当前要出库的储位正在移出、2 出库的托盘储位信息错误(在储位表中未查询到)、3储位损坏不能出库、4 要出库的托盘正在入库 |
| | | var flagList = new List<int>(); |
| | | |
| | | var com = new Common(); |
| | | var notice = Db.Queryable<BllExportNotice>().First(m => m.SONo == soNo && m.IsDel == "0"); |
| | | if (notice == null) |
| | | { |
| | | throw new Exception($"未找到{soNo}出库单信息"); |
| | | } |
| | | if (notice.WareHouseNo != "W02") |
| | | { |
| | | throw new Exception("仓库号错误"); |
| | | } |
| | | //所有要出库的出库分配信息(未下发的信息和待拣货的信息) |
| | | var list = Db.Queryable<BllExportAllot>().Where(a => a.IsDel == "0" && a.SONo == soNo && (a.Status == "0" || a.Status == "2")).ToList(); |
| | | if (list.Count == 0) //判断是否有需要下发的出库流水 |
| | | { |
| | | throw new Exception("当前出库单据无需要下发的托盘"); |
| | | } |
| | | |
| | | #region 集合 |
| | | //要出库的托盘集合 |
| | | var outLpnList = list.Select(m => m.PalletNo).ToList(); |
| | | //要出库的明细集合 |
| | | var outStockDetail = Db.Queryable<DataStockDetail>().Where(m => m.IsDel == "0" && outLpnList.Contains(m.PalletNo)).ToList(); |
| | | //物料编码表 |
| | | var skuList = Db.Queryable<SysMaterials>().Where(w => w.IsDel == "0"); |
| | | //包装表 |
| | | var packagList = Db.Queryable<SysPackag>().Where(w => w.IsDel == "0"); |
| | | Db.BeginTran(); |
| | | try |
| | | { |
| | | List<LogTask> logTaskList = new List<LogTask>();//此次出库任务集合,为应对同托盘不同物料出库 |
| | | var i = 0; |
| | | var outLocatelist1 = Db.Queryable<SysStorageLocat>().Where(m => m.IsDel == "0" && m.AreaNo == "B02" && m.Flag == "0").ToList(); |
| | | var outLocatelist2 = Db.Queryable<SysStorageLocat>().Where(m => m.IsDel == "0" && m.AreaNo == "B05" && m.Flag == "0").ToList(); |
| | | //循环分配的信息生成出库任务 |
| | | foreach (var item in list) |
| | | { |
| | | var outModeLocate = ""; |
| | | if (outMode == "1") |
| | | { |
| | | if (i < outLocatelist1.Count) |
| | | { |
| | | outModeLocate = outLocatelist1[i].LocatNo; |
| | | } |
| | | else |
| | | { |
| | | var j = i % outLocatelist1.Count; |
| | | |
| | | outModeLocate = outLocatelist1[j].LocatNo; |
| | | } |
| | | } |
| | | else if(outMode == "2") |
| | | { |
| | | if (i < outLocatelist1.Count) |
| | | { |
| | | outModeLocate = outLocatelist2[i].LocatNo; |
| | | } |
| | | else |
| | | { |
| | | var j = i % outLocatelist1.Count; |
| | | |
| | | outModeLocate = outLocatelist2[j].LocatNo; |
| | | } |
| | | } |
| | | |
| | | var taskNoStr = ""; |
| | | |
| | | // 储位号 |
| | | 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; |
| | | } |
| | | //判断是否是已经出过库又回库(状态为待拣货的) |
| | | if (item.Status == "0") |
| | | { |
| | | //如果不在仓库内,当前分配信息直接更新出库完成 |
| | | item.Status = "2";//状态 |
| | | item.OutMode = outModeLocate;//出库口 |
| | | Db.Updateable(item).ExecuteCommand(); |
| | | var noticeDetail = Db.Queryable<BllExportNoticeDetail>().First(m => m.IsDel == "0" && m.Id == item.SODetailNo); |
| | | if (noticeDetail != null) //更新出库单据的下发数量 |
| | | { |
| | | noticeDetail.FactQty += item.Qty; |
| | | Db.Updateable(noticeDetail).ExecuteCommand(); |
| | | } |
| | | |
| | | //var notice2 = Db.Queryable<BllExportNotice>().First(m => m.IsDel == "0" && m.SONo == item.SONo); |
| | | if (notice.Status == "0" || notice.Status == "1" || notice.Status == "2") |
| | | { |
| | | var detailList = Db.Queryable<BllExportNoticeDetail>().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<SysStorageLocat>().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 = outModeLocate,//目标位置 |
| | | 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 + "到" + outModeLocate + "的出库任务", //关键信息 |
| | | }; |
| | | Db.Insertable(exTask).ExecuteCommand(); |
| | | logTaskList.Add(exTask); |
| | | |
| | | outDto1.Add(new OutCommandDto() |
| | | { |
| | | PalletNo = item.PalletNo,//托盘号 |
| | | StartLocate = locate.LocatNo, // 起始位置 |
| | | StartRoadway = locate.RoadwayNo,//其实巷道 |
| | | EndLocate = outModeLocate, // 目标位置 |
| | | TaskNo = exTask.TaskNo, // 任务号 |
| | | TaskType = "1",// 任务类型 (出库)0入 1出 2移 |
| | | OutMode = outModeLocate, //出库口 |
| | | Order = 1, |
| | | |
| | | //UnstackingMode = "unstackingMode2",//拣货方式 0机器拆托出 1 人工拣货出 |
| | | //CompleteQty = outCount2, //拆的件数 |
| | | //BoxexQty = outCount, //总件数 |
| | | }); |
| | | taskNoStr = exTask.TaskNo; |
| | | |
| | | #endregion |
| | | |
| | | #region 改变数据 |
| | | if (item.Status == "0")//判断托盘是否下发过 |
| | | { |
| | | var noticeDetail = Db.Queryable<BllExportNoticeDetail>().First(m => m.IsDel == "0" && m.Id == item.SODetailNo); |
| | | if (noticeDetail != null) //更新出库单据的下发数量 |
| | | { |
| | | noticeDetail.FactQty += item.Qty; |
| | | Db.Updateable(noticeDetail).ExecuteCommand(); |
| | | } |
| | | |
| | | //var notice2 = Db.Queryable<BllExportNotice>().First(m => m.IsDel == "0" && m.SONo == item.SONo); |
| | | if (notice.Status == "0" || notice.Status == "1" || notice.Status == "2") |
| | | { |
| | | var detailList = Db.Queryable<BllExportNoticeDetail>().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(); |
| | | var locate2 = Db.Queryable<SysStorageLocat>().First(m => m.LocatNo == outModeLocate && m.IsDel == "0");//当前出库的目标储位信息 |
| | | locate2.Status = "4"; |
| | | Db.Updateable(locate2).ExecuteCommand(); |
| | | |
| | | item.TaskNo = taskNoStr; // 出库分配信息中更新任务号 |
| | | item.Status = "1"; // 出库分配信息状态改为正在执行 |
| | | //item.UnstackingMode = unstackingMode2;//拆垛方式 |
| | | item.OutMode = outModeLocate;//出库口 |
| | | //item.LoadingAddre = unstackingMode2 == "0" ? loadingAddre : "";//装车口 |
| | | Db.Updateable(item).ExecuteCommand(); |
| | | |
| | | #endregion |
| | | |
| | | flagList.Add(0); |
| | | i++; |
| | | } |
| | | else if (locate.Status == "3") //出库中 |
| | | { |
| | | #region 改变数据 |
| | | //判断是否是已经出过库又回库(状态为待拣货的 1) |
| | | if (item.Status == "0") |
| | | { |
| | | var noticeDetail = Db.Queryable<BllExportNoticeDetail>().First(m => m.IsDel == "0" && m.Id == item.SODetailNo); |
| | | if (noticeDetail != null) //更新出库单据的下发数量 |
| | | { |
| | | noticeDetail.FactQty += item.Qty; |
| | | Db.Updateable(noticeDetail).ExecuteCommand(); |
| | | } |
| | | |
| | | //var notice2 = Db.Queryable<BllExportNotice>().First(m => m.IsDel == "0" && m.SONo == item.SONo); |
| | | if (notice.Status == "0" || notice.Status == "1" || notice.Status == "2") |
| | | { |
| | | var detailList = Db.Queryable<BllExportNoticeDetail>().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<LogTask>().First(m => m.OrderType == "1" && m.TaskNo != item.TaskNo && m.Status == "1" && m.PalletNo == item.PalletNo); |
| | | if (taskNo == null) |
| | | { |
| | | taskNo = logTaskList.FirstOrDefault(m => m.PalletNo == item.PalletNo);//当前有同托盘不同物料出库 |
| | | } |
| | | if (taskNo == null) |
| | | { |
| | | throw new Exception($"托盘号:{item.PalletNo},出库异常"); |
| | | } |
| | | item.TaskNo = taskNo.TaskNo; |
| | | item.Status = "1"; // 出库分配信息状态改为正在执行 |
| | | item.OutMode = item.OutMode;//出库口 |
| | | //item.UnstackingMode = unstackingMode2;//拆垛模式 |
| | | 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 (flagList.Count(m => m == 5) > 0) |
| | | { |
| | | str += "3.要出库的托盘正在拆托请稍后下发、"; |
| | | } |
| | | if (outDto1.Count > 0) |
| | | { |
| | | // 正式运行程序放开 |
| | | var list2 = outDto1.Select(m => m.TaskNo).ToList(); |
| | | var jsonData = JsonConvert.SerializeObject(outDto1); |
| | | string response = ""; |
| | | |
| | | try |
| | | { |
| | | var time1 = DateTime.Now;//发送时间 .ToString("yyyy-MM-dd HH:mm:ss") |
| | | //response = HttpHelper.DoPost(url, jsonData, "下发给WCS出库命令", "WCS"); |
| | | var time2 = DateTime.Now;//返回时间 .ToString("yyyy-MM-dd HH:mm:ss") |
| | | |
| | | //////解析返回数据 |
| | | //var wcsModel = JsonConvert.DeserializeObject<WcsModel>(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 outDto1; |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | Db.RollbackTran(); |
| | | throw new Exception(e.Message); |
| | | } |
| | | |
| | | |
| | | #endregion |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | throw new Exception(e.Message); |
| | | } |
| | | } |
| | | |
| | | public List<OutCommandDto> IssueOutHouseMk(string soNo, string outMode, int userId, string url, out string str) |
| | | { |
| | | try |
| | | { |
| | | #region 集合 |
| | | |
| | | var outDto1 = new List<OutCommandDto>(); //先出库数据的集合(深度为1的储位) |
| | | var outDto2 = new List<OutCommandDto>(); //后出库数据的集合(深度为2的储位) |
| | | var moveDto = new List<OutCommandDto>(); //要移库数据的集合 |
| | | //记录错误信息的集合 |
| | | var flagList = new List<int>();//1:当前要出库的储位正在移出、2 出库的托盘储位信息错误(在储位表中未查询到)、3储位损坏不能出库、4 要出库的托盘正在入库 |
| | | |
| | | #endregion |
| | | var com = new Common(); |
| | | var allot = new AllotLocation(); |
| | | |
| | | var notice = Db.Queryable<BllExportNotice>().First(m => m.SONo == soNo && m.IsDel == "0"); |
| | | if (notice == null) |
| | | { |
| | | throw new Exception($"未找到{soNo}出库单信息"); |
| | | } |
| | | //所有要出库的出库分配信息(未下发的信息和待拣货的信息) |
| | | var list = Db.Queryable<BllExportAllot>().Where(a => a.IsDel == "0" && a.SONo == soNo && (a.Status == "0" || a.Status == "2")).ToList(); |
| | | if (list.Count == 0) //判断是否有需要下发的出库流水 |
| | | { |
| | | throw new Exception("当前出库单据无需要下发的托盘"); |
| | | } |
| | | |
| | | #region 集合 |
| | | //要出库的托盘集合 |
| | | var outLpnList = list.Select(m => m.PalletNo).ToList(); |
| | | //要出库的明细集合 |
| | | var outStockDetail = Db.Queryable<DataStockDetail>().Where(m => m.IsDel == "0" && outLpnList.Contains(m.PalletNo)).ToList(); |
| | | //所有要出库的储位集合 |
| | | var locateListStrs = outStockDetail.Where(m=> !string.IsNullOrWhiteSpace(m.LocatNo)).Select(m => m.LocatNo).Distinct().ToList(); |
| | | //物料编码表 |
| | | var skuList = Db.Queryable<SysMaterials>().Where(w => w.IsDel == "0"); |
| | | //包装表 |
| | | var packagList = Db.Queryable<SysPackag>().Where(w => w.IsDel == "0"); |
| | | Db.BeginTran(); |
| | | try |
| | | { |
| | | List<LogTask> logTaskList = new List<LogTask>();//此次出库任务集合,为应对同托盘不同物料出库 |
| | | //循环分配的信息生成出库任务 |
| | | foreach (var item in list) |
| | | { |
| | | var taskNoStr = ""; |
| | | string toLocation = string.Empty;//目标位置 |
| | | |
| | | // 储位号 |
| | | var locateNo = outStockDetail.First(m => m.PalletNo == item.PalletNo).LocatNo; |
| | | |
| | | #region 判断托盘是否在库内 |
| | | |
| | | //判断托盘是否在库内 |
| | | if (string.IsNullOrWhiteSpace(locateNo)) //库外 |
| | | { |
| | | if (notice.Type == "0") |
| | | { |
| | | 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";//状态 |
| | | item.OutMode = outMode;//出库口 |
| | | Db.Updateable(item).ExecuteCommand(); |
| | | var noticeDetail = Db.Queryable<BllExportNoticeDetail>().First(m => m.IsDel == "0" && m.Id == item.SODetailNo); |
| | | if (noticeDetail != null) //更新出库单据的下发数量 |
| | | { |
| | | noticeDetail.FactQty += item.Qty; |
| | | Db.Updateable(noticeDetail).ExecuteCommand(); |
| | | } |
| | | |
| | | //var notice2 = Db.Queryable<BllExportNotice>().First(m => m.IsDel == "0" && m.SONo == item.SONo); |
| | | if (notice.Status == "0" || notice.Status == "1" || notice.Status == "2") |
| | | { |
| | | var detailList = Db.Queryable<BllExportNoticeDetail>().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<SysStorageLocat>().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") //有物品 |
| | | { |
| | | var row1 = int.Parse(locate.LocatNo.Substring(2,2)); |
| | | var row2 = int.Parse(locate.AisleOne.Substring(2, 2)); |
| | | //需要移库的信息 |
| | | var NeedMoveInfo = IsNeedMoveLocate(locate, locateListStrs, out int isOut); |
| | | if (isOut == 1) |
| | | { |
| | | //巷道组中有入库或移入的储位,或者是当前储位前有储位未下发成功的任务 |
| | | flagList.Add(2); |
| | | continue; |
| | | } |
| | | if (NeedMoveInfo.Count > 0)//需要移库 |
| | | { |
| | | //判断库内空储位是否够 |
| | | var okRoad = Db.Queryable<SysStorageRoadway>().Where(m => m.Status == "0" && m.IsDel == "0" && m.WareHouseNo == notice.WareHouseNo).Select(m => m.RoadwayNo).ToList(); |
| | | var nullSlotNum = Db.Queryable<SysStorageLocat>().Count(m => m.RoadwayNo != locate.RoadwayNo && okRoad.Contains(m.RoadwayNo) && m.Status == "0"); |
| | | //判断空储位的数量是否大于需要移库的数量 |
| | | if (nullSlotNum >= NeedMoveInfo.Count) |
| | | { |
| | | var isYk = false; |
| | | foreach (var s in NeedMoveInfo) |
| | | { |
| | | //储位列 |
| | | var rows = int.Parse(s.Substring(2,2)); |
| | | |
| | | //获取移库储位 |
| | | var moveAddress = GetMiJiMoveAddress(s, locate.AisleOne); |
| | | var tary = Db.Queryable<DataStockDetail>().First(m => m.LocatNo == s); |
| | | if (string.IsNullOrWhiteSpace(moveAddress)) // 判断是否获取到移库的库位 |
| | | { |
| | | isYk = true; |
| | | flagList.Add(5);//出库前有货物,需移库但未查询到空储位 |
| | | break; //没有移库的库位了 |
| | | } |
| | | else |
| | | { |
| | | //判断托盘有没有回移的任务 |
| | | //var hy = GetHyTask(item.ExportStockCode); |
| | | //if (hy != null) |
| | | //{ |
| | | // var hyentity = dataContext.WmsExportTask.FirstOrDefault(m => m.TaskId == hy.TaskId); |
| | | // if (hyentity != null) |
| | | // { |
| | | // isYk = true; |
| | | // msgList.Add(6);//出库前有货物,需移库但是回移托盘 |
| | | // break; //没有移库的库位了 |
| | | // } |
| | | //} |
| | | var ykTaskNo = new Common().GetMaxNo("TK"); |
| | | var ykTask = new LogTask //出库任务 |
| | | { |
| | | TaskNo = ykTaskNo, |
| | | Sender = "WMS", |
| | | Receiver = "WCS", |
| | | IsSuccess = 0, //是否下发成功 0失败 1成功 |
| | | |
| | | StartLocat = s,//起始位置 |
| | | EndLocat = moveAddress,//outMode,//目标位置 |
| | | PalletNo = tary.PalletNo,//托盘码 |
| | | IsSend = 1,//是否可再次下发 |
| | | IsCancel = 1,//是否可取消 |
| | | IsFinish = 1,//是否可完成 |
| | | Type = "2",//任务类型 0 入库任务 1 出库任务 2 移库任务 |
| | | Status = "0",//任务状态0:等待执行1正在执行2执行完成 |
| | | OrderType = "1",//0 入库单 1 出库单 2 盘点单 3 移库单 |
| | | Msg = "从" + locate.LocatNo + "到" + toLocation + "的出库任务", //关键信息 |
| | | }; |
| | | Db.Insertable(ykTask).ExecuteCommand(); |
| | | logTaskList.Add(ykTask); |
| | | |
| | | outDto1.Add(new OutCommandDto() |
| | | { |
| | | PalletNo = item.PalletNo,//托盘号 |
| | | StartLocate = locate.LocatNo, // 起始位置 |
| | | StartRoadway = locate.RoadwayNo,//其实巷道 |
| | | EndLocate = moveAddress,//outMode, // 目标位置 |
| | | TaskNo = ykTaskNo, // 任务号 |
| | | TaskType = "2",// 任务类型 (出库)0入 1出 2移 |
| | | Order = Math.Abs(row2 - rows), |
| | | Type = PLCTypeEnum.ShuttleCar |
| | | |
| | | }); |
| | | var slotChange = Db.Queryable<SysStorageLocat>().First(m => m.LocatNo == s); |
| | | var slotChange2 = Db.Queryable<SysStorageLocat>().First(m => m.LocatNo == moveAddress); |
| | | |
| | | slotChange.Status = "5"; //改变状态(正在出库) |
| | | slotChange2.Status = "4"; // 改变状态(正在移入) |
| | | Db.Updateable(slotChange).ExecuteCommand(); |
| | | Db.Updateable(slotChange2).ExecuteCommand(); |
| | | } |
| | | } |
| | | if (isYk) |
| | | { |
| | | break; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | flagList.Add(5); |
| | | break; |
| | | } |
| | | } |
| | | #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 = toLocation,//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 + "到" + toLocation + "的出库任务", //关键信息 |
| | | }; |
| | | Db.Insertable(exTask).ExecuteCommand(); |
| | | logTaskList.Add(exTask); |
| | | var endroad = allot.RoadwayToStationNum(locate.RoadwayNo, toLocation); |
| | | outDto1.Add(new OutCommandDto() |
| | | { |
| | | PalletNo = item.PalletNo,//托盘号 |
| | | StartLocate = locate.LocatNo, // 起始位置 |
| | | StartRoadway = locate.RoadwayNo,//起始巷道 |
| | | EndLocate = outMode,//, // 目标位置 |
| | | EndRoadway = endroad, |
| | | TaskNo = exTask.TaskNo, // 任务号 |
| | | TaskType = "1",// 任务类型 (出库)0入 1出 2移 |
| | | OutMode = outMode, //出库口 |
| | | Order = Math.Abs(row2 - row1), |
| | | Type = PLCTypeEnum.ShuttleCar |
| | | |
| | | }); |
| | | taskNoStr = exTask.TaskNo; |
| | | |
| | | #endregion |
| | | |
| | | #region 改变数据 |
| | | if (item.Status == "0")//判断托盘是否下发过 |
| | | { |
| | | var noticeDetail = Db.Queryable<BllExportNoticeDetail>().First(m => m.IsDel == "0" && m.Id == item.SODetailNo); |
| | | if (noticeDetail != null) //更新出库单据的下发数量 |
| | | { |
| | | noticeDetail.FactQty += item.Qty; |
| | | Db.Updateable(noticeDetail).ExecuteCommand(); |
| | | } |
| | | |
| | | //var notice2 = Db.Queryable<BllExportNotice>().First(m => m.IsDel == "0" && m.SONo == item.SONo); |
| | | if (notice.Status == "0" || notice.Status == "1" || notice.Status == "2") |
| | | { |
| | | var detailList = Db.Queryable<BllExportNoticeDetail>().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 = taskNoStr; // 出库分配信息中更新任务号 |
| | | item.Status = "1"; // 出库分配信息状态改为正在执行 |
| | | //item.UnstackingMode = unstackingMode2;//拆垛方式 |
| | | item.OutMode = outMode;//出库口 |
| | | //item.LoadingAddre = unstackingMode2 == "0" ? loadingAddre : "";//装车口 |
| | | Db.Updateable(item).ExecuteCommand(); |
| | | |
| | | #endregion |
| | | |
| | | flagList.Add(0); |
| | | } |
| | | else if (locate.Status == "3") //出库中 |
| | | { |
| | | #region 改变数据 |
| | | //判断是否是已经出过库又回库(状态为待拣货的 1) |
| | | if (item.Status == "0") |
| | | { |
| | | var noticeDetail = Db.Queryable<BllExportNoticeDetail>().First(m => m.IsDel == "0" && m.Id == item.SODetailNo); |
| | | if (noticeDetail != null) //更新出库单据的下发数量 |
| | | { |
| | | noticeDetail.FactQty += item.Qty; |
| | | Db.Updateable(noticeDetail).ExecuteCommand(); |
| | | } |
| | | |
| | | //var notice2 = Db.Queryable<BllExportNotice>().First(m => m.IsDel == "0" && m.SONo == item.SONo); |
| | | if (notice.Status == "0" || notice.Status == "1" || notice.Status == "2") |
| | | { |
| | | var detailList = Db.Queryable<BllExportNoticeDetail>().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<LogTask>().First(m => m.OrderType == "1" && m.TaskNo != item.TaskNo && m.Status == "1" && m.PalletNo == item.PalletNo); |
| | | if (taskNo == null) |
| | | { |
| | | taskNo = logTaskList.FirstOrDefault(m => m.PalletNo == item.PalletNo);//当前有同托盘不同物料出库 |
| | | } |
| | | if (taskNo == null) |
| | | { |
| | | throw new Exception($"托盘号:{item.PalletNo},出库异常"); |
| | | } |
| | | item.TaskNo = taskNo.TaskNo; |
| | | item.Status = "1"; // 出库分配信息状态改为正在执行 |
| | | item.OutMode = item.OutMode;//出库口 |
| | | //item.UnstackingMode = unstackingMode2;//拆垛模式 |
| | | Db.Updateable(item).ExecuteCommand(); |
| | | flagList.Add(0); |
| | | #endregion |
| | | } |
| | | else if (locate.Status == "5") //移出中 |
| | | { |
| | | flagList.Add(1); |
| | | } |
| | | } |
| | | outDto1.AddRange(moveDto); |
| | | outDto1.AddRange(outDto2); |
| | | //添加操作日志记录 |
| | | 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 (flagList.Count(m => m == 5) > 0) |
| | | { |
| | | str += "3.要出库的托盘正在拆托请稍后下发、"; |
| | | } |
| | | if (outDto1.Count > 0) |
| | | { |
| | | // 正式运行程序放开 |
| | | var list2 = outDto1.Select(m => m.TaskNo).ToList(); |
| | | var jsonData = JsonConvert.SerializeObject(outDto1); |
| | | string response = ""; |
| | | |
| | | try |
| | | { |
| | | //var time1 = DateTime.Now;//发送时间 .ToString("yyyy-MM-dd HH:mm:ss") |
| | | //response = HttpHelper.DoPost(url, jsonData, "下发给WCS出库命令", "WCS"); |
| | | //var time2 = DateTime.Now;//返回时间 .ToString("yyyy-MM-dd HH:mm:ss") |
| | | |
| | | //////解析返回数据 |
| | | //var wcsModel = JsonConvert.DeserializeObject<WcsModel>(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 outDto1; |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | Db.RollbackTran(); |
| | | throw new Exception(e.Message); |
| | | } |
| | | |
| | | |
| | | #endregion |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | throw new Exception(e.Message); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 判断是否需要进行移库操作 |
| | | /// </summary> |
| | | /// <param name="oldAddress">要出库的库位地址</param> |
| | | /// <param name="aisle">通道口</param> |
| | | /// <param name="addressList">要出口的储位集合</param> |
| | | /// <param name="isOut">是否出库 1:有未下发的任务在前面</param> |
| | | /// <returns>需要移库的集合(如果为空则不需移库)</returns> |
| | | private List<string> IsNeedMoveLocate(SysStorageLocat lcoate,List<string> locateStrList, out int isOut) |
| | | { |
| | | var nowAddress = new List<string>(); //需要移库的集合 |
| | | // 010101 派列层 |
| | | //var bol = String.CompareOrdinal(lcoate.LocatNo, lcoate.AisleOne); |
| | | |
| | | var sArray = lcoate.LocatNo.Substring(4,2); |
| | | var row = int.Parse(sArray);//储位列 |
| | | var sArray2 = lcoate.AisleOne.Substring(4, 2); |
| | | var row2 = int.Parse(sArray2); //通道口列 |
| | | |
| | | isOut = 0; |
| | | |
| | | var bol = row2 - row > 0; |
| | | |
| | | //同组的储位集合 |
| | | var slotList = Db.Queryable<SysStorageLocat>().Where(m => m.RoadwayNo == lcoate.RoadwayNo).ToList(); |
| | | List<string> list; |
| | | |
| | | |
| | | if (bol) |
| | | { |
| | | //储位小于通道口 倒序 |
| | | list = slotList.Where(m => m.Column < row2 && m.Column > row).Select(m => m.LocatNo).ToList(); |
| | | } |
| | | else |
| | | { |
| | | //储位大于通道口 正序 |
| | | list = slotList.Where(m => m.Column > row2 && m.Column < row).Select(m => m.LocatNo).ToList(); |
| | | } |
| | | |
| | | if (list.Any()) |
| | | { |
| | | //排除掉同巷道组中要出库的储位 |
| | | if (locateStrList.Count != 0) |
| | | { |
| | | list = list.Where(m => !locateStrList.Contains(m)).ToList(); |
| | | } |
| | | //判断是否有入库中或正在移入的 |
| | | var s = slotList.Where(m => list.Contains(m.LocatNo) && (m.Status == "2" || m.Status == "4")).Select(m => m.LocatNo).ToList(); |
| | | if (s.Count > 0) |
| | | { |
| | | isOut = 1; |
| | | return nowAddress; |
| | | } |
| | | //判断是否有在当前储位前未下发的任务(防止撞车) |
| | | var w = Db.Queryable<LogTask>().Where(m => list.Contains(m.StartLocat) && m.IsSuccess == 0).Select(m => m.StartLocat).ToList(); |
| | | if (w.Count > 0) |
| | | { |
| | | isOut = 1; |
| | | return nowAddress; |
| | | } |
| | | if (bol) |
| | | { |
| | | //储位小于通道口 倒序 |
| | | nowAddress = slotList.Where(m => list.Contains(m.LocatNo) && m.Status == "1").OrderByDescending(m => m.LocatNo).Select(m => m.LocatNo).ToList(); |
| | | } |
| | | else |
| | | { |
| | | //储位大于通道口 正序 |
| | | nowAddress = slotList.Where(m => list.Contains(m.LocatNo) && m.Status == "1").OrderBy(m => m.LocatNo).Select(m => m.LocatNo).ToList(); |
| | | |
| | | } |
| | | if (nowAddress.Count > 0) |
| | | { |
| | | return nowAddress; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | return nowAddress; |
| | | } |
| | | |
| | | |
| | | return nowAddress; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 获取移库目标库位 密集库 |
| | | /// </summary> |
| | | /// <param name="oldAddress">需要移动的库位地址</param> |
| | | /// <param name="slotOut">需要移动的库位的出口中转位</param> |
| | | /// <param name="billCode">出库单据或是波次单据</param> |
| | | /// <param name="flags">中转口</param> |
| | | /// <param name="refLanWayId">需回移的巷道id</param> |
| | | /// <param name="refLanOutCode">需回移的巷道中转口</param> |
| | | /// <returns>目标库位地址 为"" 直接下发两次出库指令</returns> |
| | | public string GetMiJiMoveAddress(string oldAddress, string slotOut) |
| | | { |
| | | var newAddress = ""; //新库位 |
| | | var newLaneWayAddress = ""; //新巷道口库位 |
| | | |
| | | // 获取移库目标储位 |
| | | |
| | | // |
| | | var sArray = oldAddress.Substring(4,2); |
| | | var ceng = int.Parse(sArray); |
| | | // |
| | | var sArray2 = slotOut.Substring(2, 2); |
| | | var row2 = sArray2; |
| | | //十字口 |
| | | var shiKou = new List<string>() |
| | | { |
| | | slotOut, |
| | | "070501", |
| | | "071301", |
| | | "070502", |
| | | "071302", |
| | | }; |
| | | var shiKou3 = new List<addreClass>(); |
| | | foreach (var item in shiKou) |
| | | { |
| | | var a = item.Substring(4, 2); |
| | | var b = item.Substring(2, 2); |
| | | if (int.Parse(a) != ceng) continue; |
| | | var s = Math.Abs(int.Parse(b) - int.Parse(row2)); |
| | | if (shiKou3.Any(m => m.distNum == s)) continue; |
| | | shiKou3.Add(new addreClass() |
| | | { |
| | | slotCode = item, |
| | | distNum = s |
| | | }); |
| | | } |
| | | //根据十字口差值最小的排序 |
| | | shiKou3 = shiKou3.OrderBy(m => m.distNum).ToList(); |
| | | |
| | | /** |
| | | //1 移动到最近的空储位,必须回移。 |
| | | //根据四向车移动轨迹计算出最近空储位。 |
| | | //出库完成后根据批次号 生产日期 出口计算回移储位。 |
| | | |
| | | //2 移动适合存放的组,系统自动计算是否回移。 |
| | | //根据批次号 生产日期 出口 物料等计算出移库目标储位 |
| | | //出库完成后,判断是否有比当前库位更合适的存储储位,有移动,无不移动。 |
| | | */ |
| | | |
| | | var oldSlot = Db.Queryable<SysStorageLocat>().First(m => m.LocatNo == oldAddress); |
| | | if (oldSlot == null) |
| | | { |
| | | throw new Exception("未能找到储位信息"); |
| | | } |
| | | #region 1不需要回移的 |
| | | |
| | | //后期库存托盘表改了后需要加筛选条件托盘的状态(退货/预拣) |
| | | var tray1 = Db.Queryable<DataStockDetail>().Where(m => m.LocatNo == oldAddress).ToList(); |
| | | //根据物料、批次、托盘状态(退货/预拣/暂存等)分组判断 |
| | | var d = tray1.GroupBy(m => new { m.SkuNo, m.LotNo, m.PalletTags }); |
| | | var location = string.Empty; |
| | | if (d.Any()) |
| | | { |
| | | //旧储位同组的储位集合 |
| | | var slotList = Db.Queryable<SysStorageLocat>().Where(m => m.RoadwayNo == oldSlot.RoadwayNo).Select(m => m.LocatNo).ToList(); |
| | | foreach (var item in d) |
| | | { |
| | | foreach (var item2 in item) |
| | | { |
| | | var okLan = Db.Queryable<SysStorageRoadway>().Where(m => m.Status == "0" && m.IsDel == "0").Select(m => m.RoadwayNo).ToList(); |
| | | var tray2 = Db.Queryable<DataStockDetail>().Where(m => m.SkuNo == item2.SkuNo |
| | | && m.LotNo == item2.LotNo && !slotList.Contains(m.LocatNo) && m.PalletTags == item2.PalletTags && okLan.Contains(m.RoadwayNo)).ToList(); |
| | | foreach (var s in tray2) |
| | | { |
| | | if (string.IsNullOrWhiteSpace(s.RoadwayNo))//判断是否在库外,如是跳过 |
| | | { |
| | | continue; |
| | | } |
| | | var lan = Db.Queryable<SysStorageLocat>().Where(m => m.RoadwayNo == s.RoadwayNo).OrderBy(m => m.LocatNo).ToList(); |
| | | //判断是否有入库中、出库中、移入中、移出中 |
| | | if (lan.Count(m => m.Status == "2" || m.Status == "3" || m.Status == "4" || m.Status == "5") > 0) |
| | | { |
| | | continue; |
| | | } |
| | | if (lan.Count(m => m.Status == "0") > 0) |
| | | { |
| | | |
| | | var bol = GetBecomingLocation(s.RoadwayNo, ref location); |
| | | if (bol && !string.IsNullOrWhiteSpace(location)) |
| | | { |
| | | newAddress = location; |
| | | return newAddress; |
| | | |
| | | } |
| | | |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | #region 2需要回移的 |
| | | |
| | | ////如果没有找到合适的储位 |
| | | //if (string.IsNullOrWhiteSpace(newAddress)) |
| | | //{ |
| | | // foreach (var s in shiKou3) |
| | | // { |
| | | |
| | | // var r = int.Parse(s.slotCode.Substring(0, 2)); |
| | | // var l = int.Parse(s.slotCode.Substring(2, 2)); |
| | | // var c = int.Parse(s.slotCode.Substring(4, 2)); |
| | | // //查询空储位 |
| | | // var sqlString = $@"select LocatNo,Row,Column,Layer,(ABS(Row-{r}) + ABS(Column-{l}) ) as distNum |
| | | // from SysStorageLocat where (AisleOneRow = {r} or AisleTwoRow = {r}) and Status in (0) and |
| | | // RoadwayNo !='{oldSlot.RoadwayNo}' and RoadwayNo not in(select RoadwayNo from SysStorageRoadway where Status = 1) order by distNum,SlotCode"; |
| | | |
| | | // var addressModels = dataContext.ExecuteQuery<addreClass>(sqlString).ToList(); |
| | | // foreach (var item in addressModels) |
| | | // { 、 |
| | | |
| | | |
| | | // newAddress = item.slotCode; |
| | | // var dz = newAddress.Split(new char[] { '-' }); |
| | | // var l1 = dz[1]; |
| | | // var c1 = dz[0]; |
| | | // newLaneWayAddress = $"{c1}-{l1}-{a[2]}"; |
| | | // flags = newLaneWayAddress; |
| | | |
| | | // var slotModel = dataContext.WmsBaseSlot.FirstOrDefault(m => m.SlotCode == item.slotCode); |
| | | |
| | | // var lan = dataContext.WmsBaseSlot.Where(m => m.SlotLanewayId == slotModel.SlotLanewayId).ToList(); |
| | | // if (slotModel.SlotRow > int.Parse(a[2])) |
| | | // { |
| | | // // 取最上面一排 |
| | | // lan = lan.OrderBy(m => m.SlotCode).ToList(); |
| | | // for (int i = 0; i < lan.Count; i++) |
| | | // { |
| | | // var slot = dataContext.WmsBaseSlot.FirstOrDefault(m => m.SlotCode == lan[i].SlotCode); |
| | | // if (slot.SlotStatus == 0) |
| | | // { |
| | | // if (i == lan.Count - 1) |
| | | // { |
| | | // newAddress = lan[lan.Count - 1].SlotCode; |
| | | |
| | | // break; |
| | | // } |
| | | // else |
| | | // { |
| | | // continue; |
| | | // } |
| | | |
| | | // } |
| | | // else |
| | | // { |
| | | // newAddress = lan[i - 1].SlotCode; |
| | | // break; |
| | | // } |
| | | // } |
| | | |
| | | // } |
| | | // else |
| | | // { |
| | | // // 取最下面一排 |
| | | // lan = lan.OrderByDescending(m => m.SlotCode).ToList(); |
| | | // for (int i = 0; i < lan.Count; i++) |
| | | // { |
| | | // var slot = dataContext.WmsBaseSlot.FirstOrDefault(m => m.SlotCode == lan[i].SlotCode); |
| | | // if (slot.SlotStatus == 0) |
| | | // { |
| | | // if (i == lan.Count - 1) |
| | | // { |
| | | // newAddress = lan[lan.Count - 1].SlotCode; |
| | | // break; |
| | | // } |
| | | // else |
| | | // { |
| | | // continue; |
| | | // } |
| | | |
| | | // } |
| | | // else |
| | | // { |
| | | // newAddress = lan[i - 1].SlotCode; |
| | | // break; |
| | | // } |
| | | // } |
| | | // } |
| | | // //添加回移任务 |
| | | // AddHyTask(oldAddress, newAddress, newLaneWayAddress, oldSlot.SlotLanewayId, slotOut, billCode); |
| | | // refLanWayId = slotModel.SlotLanewayId; |
| | | // refLanOutCode = newLaneWayAddress; |
| | | // //9:锁定储位 |
| | | // var updateSlot = dataContext.WmsBaseSlot.Where(m => m.SlotLanewayId == slotModel.SlotLanewayId).ToList(); |
| | | // var newAddressRow = dataContext.WmsBaseSlot.FirstOrDefault(m => m.SlotCode == newAddress); |
| | | // if (newAddressRow.SlotRow > int.Parse(a[2])) |
| | | // { |
| | | // updateSlot = updateSlot.Where(m => m.SlotRow < newAddressRow.SlotRow && m.SlotRow > int.Parse(a[2])).OrderBy(m => m.SlotCode).ToList(); |
| | | // } |
| | | // else |
| | | // { |
| | | // updateSlot = updateSlot.Where(m => m.SlotRow > newAddressRow.SlotRow && m.SlotRow < int.Parse(a[2])).OrderByDescending(m => m.SlotCode).ToList(); |
| | | |
| | | // } |
| | | // foreach (var source in updateSlot) |
| | | // { |
| | | // if (source.SlotCode == newAddress) |
| | | // { |
| | | // continue; |
| | | // } |
| | | // if (source.SlotStatus == 0) |
| | | // { |
| | | // source.SlotStatus = 8; |
| | | // } |
| | | // } |
| | | |
| | | // if (updateSlot.Count <= 0) |
| | | // { |
| | | // refLanWayId = ""; |
| | | // refLanOutCode = ""; |
| | | // } |
| | | // dataContext.SubmitChanges(); |
| | | // return newAddress; |
| | | |
| | | |
| | | |
| | | // } |
| | | |
| | | // } |
| | | |
| | | //} |
| | | |
| | | return newAddress; |
| | | #endregion |
| | | |
| | | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 获取移库合适的储位 密集库 |
| | | /// </summary> |
| | | /// <param name="laneWayId">合适组的巷道号</param> |
| | | /// <param name="location">分配储位</param> |
| | | /// <returns>true:存在合适储位 False:不存在合适储位</returns> |
| | | private bool GetBecomingLocation(string laneWayId, ref string location) |
| | | { |
| | | bool bl = false; |
| | | |
| | | // 循环判断当前组是否有剩余储位 |
| | | string sqlString = string.Empty; |
| | | location = ""; |
| | | |
| | | // 判断储位组是否有空储位 关联库存明细表可防止储位状态不准确避免造成满入异常//not in ('1','2','4','6','7','8') |
| | | sqlString = $"select LocatNo,Column,AisleOne from SysStorageLocat where RoadwayNo = {laneWayId} and Status in ('0') and LocatNo not in (select LocatNo from DataStockDetail where RoadwayNo = { laneWayId}) order by Row;"; |
| | | var slotModel =Db.SqlQueryable<LocateInfo>(sqlString).ToList(); |
| | | if (slotModel.Count == 0) |
| | | { |
| | | bl = false; |
| | | } |
| | | else // 存在空储位 |
| | | { |
| | | // 判断当前组合适的储位地址 |
| | | var numstr = slotModel[0].AisleOne.Substring(4,2); |
| | | int aisleRow = int.Parse(numstr); |
| | | |
| | | if (slotModel[0].Column > aisleRow) |
| | | { |
| | | // 取最上面一排 |
| | | location = slotModel[0].LocatNo; |
| | | |
| | | } |
| | | else |
| | | { |
| | | // 取最下面一排 |
| | | |
| | | location = slotModel[slotModel.Count - 1].LocatNo; |
| | | } |
| | | |
| | | bl = true; |
| | | } |
| | | |
| | | |
| | | |
| | | return bl; |
| | | } |
| | | |
| | | private class addreClass |
| | | { |
| | | public string slotCode { get; set; } |
| | | public int distNum { get; set; } |
| | | } |
| | | public class LocateInfo |
| | | { |
| | | public string LocatNo { get; set; } |
| | | public int Column { get; set; } |
| | | public string AisleOne { get; set; } |
| | | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// wcs返回的成功信号(出库成功) |
| | | /// </summary> |
| | | /// <param name="taskNo"></param> |
| | | /// <param name="userId"></param> |
| | | /// <exception cref="Exception"></exception> |
| | | public void ExportSuccess(string taskNo, int userId) |
| | | { |
| | | try |
| | | { |
| | | //当前任务信息 |
| | | var task = Db.Queryable<LogTask>().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<DataStockDetail>().Where(m => m.PalletNo == task.PalletNo).ToList(); |
| | | var locateNo = stockDetail.Select(m => m.LocatNo).Distinct().FirstOrDefault(); |
| | | //当前任务中的储位信息 |
| | | var locate = Db.Queryable<SysStorageLocat>().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<DataStock>().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<SysPallets>().First(m => m.PalletNo == item.PalletNo); |
| | | if (sCode != null) |
| | | { |
| | | sCode.Status = "0"; |
| | | Db.Updateable(sCode).ExecuteCommand(); |
| | | } |
| | | Db.Deleteable(item).ExecuteCommand(); |
| | | |
| | | continue; |
| | | } |
| | | item.LocatNo = "";//储位更改(改为空) |
| | | item.WareHouseNo = "";//所属仓库更改(改为空) |
| | | item.RoadwayNo = "";//所属巷道更改(改为空) |
| | | item.AreaNo = "";//所属区域更改(改为空) |
| | | |
| | | } |
| | | //出库流水(更改状态) |
| | | var allot = Db.Queryable<BllExportAllot>().Where(m => m.IsDel == "0" && (m.TaskNo == taskNo || (m.Status == "1" && m.PalletNo == task.PalletNo))).ToList(); |
| | | var PalletType = "0"; //0:物料托 1:空托盘托 |
| | | |
| | | foreach (var item in allot) |
| | | { |
| | | if (item.SkuNo == "100099") |
| | | { |
| | | item.Status = "5"; |
| | | item.CompleteQty += stockDetail[0].Qty; |
| | | PalletType = "1"; |
| | | } |
| | | else |
| | | { |
| | | item.Status = "2"; |
| | | } |
| | | |
| | | } |
| | | |
| | | var endLocateList = Db.Queryable<SysStorageLocat>().Where(m => m.IsDel == "0" && (m.AreaNo == "B02" || m.AreaNo == "B05")).Select(m=>m.LocatNo).ToList(); |
| | | //判断是否是原辅料出库任务 货架储位=》平库储位 |
| | | if ( endLocateList.Contains(task.EndLocat) && PalletType == "0") |
| | | { |
| | | //修改目标地址状态 |
| | | var endLocat = Db.Queryable<SysStorageLocat>().First(m => m.IsDel == "0" && m.LocatNo == task.EndLocat); |
| | | endLocat.Status = "1"; |
| | | Db.Updateable(endLocat).ExecuteCommand(); |
| | | foreach (var item in stockDetail) |
| | | { |
| | | item.LocatNo = endLocat.LocatNo;//储位更改(改为空) |
| | | item.WareHouseNo = endLocat.WareHouseNo;//所属仓库更改(改为空) |
| | | item.RoadwayNo = endLocat.RoadwayNo;//所属巷道更改(改为空) |
| | | item.AreaNo = endLocat.AreaNo;//所属区域更改(改为空) |
| | | } |
| | | } |
| | | Db.Updateable(stockDetail).ExecuteCommand(); |
| | | 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); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// wcs返回的成功信号(移库成功) |
| | | /// </summary> |
| | | /// <param name="taskNo">任务号</param> |
| | | /// <param name="userId">操作人</param> |
| | | /// <exception cref="Exception"></exception> |
| | | public void RelocationSuccess(string taskNo, int userId) |
| | | { |
| | | try |
| | | { |
| | | //当前任务信息 |
| | | var task = Db.Queryable<LogTask>().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<DataStockDetail>().Where(m => m.PalletNo == task.PalletNo).ToList(); |
| | | //当前任务中的目标储位信息 |
| | | //当前任务中的原储位 |
| | | var locate = Db.Queryable<SysStorageLocat>().First(m => m.LocatNo == task.StartLocat); |
| | | if (locate == null) |
| | | { |
| | | throw new Exception($"WMS系统中没有该{task.StartLocat}储位对应的信息"); |
| | | } |
| | | var locate2 = Db.Queryable<SysStorageLocat>().First(m => m.LocatNo == task.EndLocat); |
| | | if (locate2 == null) |
| | | { |
| | | throw new Exception($"WMS系统中没有该{task.EndLocat}储位对应的信息"); |
| | | } |
| | | //平库中储位集合 |
| | | var pingKuLocate = Db.Queryable<SysStorageLocat>().Where(m => m.WareHouseNo == "W04" && m.IsDel == "0").ToList(); |
| | | var pingKuList = pingKuLocate.Select(m => m.LocatNo).ToList(); |
| | | try |
| | | { |
| | | |
| | | task.Status = "5";//任务状态 |
| | | //判断起始目标位置都是平库 |
| | | if (pingKuList.Contains(task.StartLocat) && pingKuList.Contains(task.EndLocat)) |
| | | { |
| | | task.Status = "2"; |
| | | } |
| | | |
| | | 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 ( 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 |
| | | |
| | | Db.CommitTran(); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Db.RollbackTran(); |
| | | throw new Exception(ex.Message); |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | throw new Exception("完成反馈失败:" + ex.Message); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// AGV任务取货完成反馈 |
| | | /// </summary> |
| | | /// <param name="taskNo"></param> |
| | | public void AGVQuHuoSuccess(string taskNo) |
| | | { |
| | | try |
| | | { |
| | | Db.BeginTran(); |
| | | var task = Db.Queryable<LogTask>().First(m=>m.IsDel =="0" && m.TaskNo == taskNo); |
| | | if (task == null) |
| | | { |
| | | throw new Exception("没有查询到任务信息"); |
| | | } |
| | | if (task.Status!="1") |
| | | { |
| | | throw new Exception("任务状态不是正在执行,请核实"); |
| | | } |
| | | var locate = Db.Queryable<SysStorageLocat>().First(m => m.LocatNo == task.StartLocat && m.IsDel == "0"); |
| | | if (locate == null) |
| | | { |
| | | throw new Exception("没有查询到起始储位信息"); |
| | | } |
| | | if (locate.WareHouseNo!="W04") |
| | | { |
| | | throw new Exception("起始储位不是平库储位,请核实"); |
| | | } |
| | | locate.Status = "0"; //更改储位状态为空储位 |
| | | Db.Updateable(locate).ExecuteCommand(); |
| | | //查询出托盘信息 更改库存储位信息 |
| | | var stockDetail = Db.Queryable<DataStockDetail>().Where(m => m.IsDel == "0" && m.PalletNo == task.PalletNo).ToList(); |
| | | foreach (var item in stockDetail) |
| | | { |
| | | item.WareHouseNo = ""; |
| | | item.AreaNo = ""; |
| | | item.RoadwayNo = ""; |
| | | item.LocatNo = ""; |
| | | } |
| | | Db.Updateable(stockDetail).ExecuteCommand(); |
| | | Db.CommitTran(); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | Db.RollbackTran(); |
| | | throw new Exception(e.Message); |
| | | } |
| | | } |
| | | |
| | | |
| | | #endregion |
| | | |
| | | #endregion |
| | | |
| | | |
| | | |
| | | //------------------------------------------------------------------ |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | //wcs返回的成功信号(出库成功) |
| | | public void ExportSuccess(string taskNo, int userId) |
| | | { |
| | | try |
| | | { |
| | | //当前任务信息 |
| | | var task = Db.Queryable<LogTask>().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<DataStockDetail>().Where(m => m.PalletNo == task.PalletNo).ToList(); |
| | | var locateNo = stockDetail.Select(m => m.LocatNo).Distinct().FirstOrDefault(); |
| | | //当前任务中的储位信息 |
| | | var locate = Db.Queryable<SysStorageLocat>().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<DataStock>().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<SysPallets>().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<BllCompleteDetail>(); |
| | | // //添加拣货明细 |
| | | // 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<BllExportAllot>().Where(m => m.IsDel == "0" && (m.TaskNo == taskNo || (m.Status == "1" && m.PalletNo == task.PalletNo))).ToList(); |
| | | var PalletType = "0"; //0:物料托 1:空托盘托 |
| | | var soNo = ""; |
| | | var sku = ""; |
| | | foreach (var item in allot) |
| | | { |
| | | if (item.SkuNo == "100099") |
| | | { |
| | | item.Status = "5"; |
| | | item.CompleteQty += stockDetail[0].Qty; |
| | | PalletType = "1"; |
| | | } |
| | | else |
| | | { |
| | | item.Status = "2"; |
| | | soNo = item.SONo; |
| | | sku = item.SkuNo; |
| | | } |
| | | |
| | | } |
| | | //下发四楼调度AGV的任务 |
| | | if ((task.EndLocat == "outMode" || task.EndLocat == "outMode") && PalletType == "0") |
| | | { |
| | | foreach (var item in allot) |
| | | { |
| | | var detail = Db.Queryable<DataStockDetail>().First(m => m.Id == item.StockId); |
| | | detail.SONo = item.SONo; |
| | | Db.Updateable(detail).ExecuteCommand(); |
| | | } |
| | | |
| | | var locatePing = new AllotLocation().GetPingLocate(soNo, sku); |
| | | if (locatePing == null) |
| | | { |
| | | throw new Exception("平库未查询到空位置"); |
| | | } |
| | | var exTask = new LogTask //出库任务 |
| | | { |
| | | TaskNo = new Common().GetMaxNo("TK"), |
| | | Sender = "WMS", |
| | | Receiver = "AGV", |
| | | IsSuccess = 0, //是否下发成功 0失败 1成功 |
| | | |
| | | StartLocat = task.EndLocat,//起始位置 |
| | | EndLocat = locatePing.LocatNo,//outMode,//目标位置 |
| | | PalletNo = task.PalletNo,//托盘码 |
| | | IsSend = 1,//是否可再次下发 |
| | | IsCancel = 1,//是否可取消 |
| | | IsFinish = 1,//是否可完成 |
| | | Type = "1",//任务类型 0 入库任务 1 出库任务 2 移库任务 |
| | | Status = "0",//任务状态0:等待执行1正在执行2执行完成 |
| | | OrderType = "1",//0 入库单 1 出库单 2 盘点单 3 移库单 |
| | | Msg = "从" + task.EndLocat + "到" + locatePing.LocatNo + "的出库任务", //关键信息 |
| | | }; |
| | | Db.Insertable(exTask).ExecuteCommand(); |
| | | |
| | | var outDto = new List<OutCommandDto> |
| | | { |
| | | new OutCommandDto() |
| | | { |
| | | PalletNo = task.PalletNo,//托盘号 |
| | | StartLocate = task.EndLocat, // 起始位置 |
| | | StartRoadway = "",//其实巷道 |
| | | EndLocate = locatePing.LocatNo,//outMode, // 目标位置 |
| | | TaskNo = exTask.TaskNo, // 任务号 |
| | | TaskType = "1",// 任务类型 (出库)0入 1出 2移 |
| | | OutMode = "", //出库口 |
| | | Order = 1, |
| | | |
| | | //UnstackingMode = unstackingMode2,//拣货方式 0机器拆托出 1 人工拣货出 |
| | | //CompleteQty = outCount2, //拆的件数 |
| | | //BoxexQty = outCount, //总件数 |
| | | } |
| | | }; |
| | | // 正式运行程序放开 |
| | | var list2 = outDto.Select(m => m.TaskNo).ToList(); |
| | | var jsonData = JsonConvert.SerializeObject(outDto); |
| | | 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<WcsModel>(response); |
| | | //if (wcsModel.StatusCode == 0) |
| | | //{ |
| | | //更改任务的发送返回时间// |
| | | new TaskServer().EditTaskIssueOk(list2, time1, time2); |
| | | //} |
| | | //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); |
| | | } |
| | | } |
| | | |
| | | 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); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// wcs返回的成功信号(移库成功) |
| | | /// </summary> |
| | | /// <param name="taskNo">任务号</param> |
| | | /// <param name="userId">操作人</param> |
| | | /// <exception cref="Exception"></exception> |
| | | public void RelocationSuccess(string taskNo, int userId) |
| | | { |
| | | try |
| | | { |
| | | //当前任务信息 |
| | | var task = Db.Queryable<LogTask>().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<DataStockDetail>().Where(m => m.PalletNo == task.PalletNo).ToList(); |
| | | //当前任务中的目标储位信息 |
| | | //当前任务中的原储位 |
| | | var locate = Db.Queryable<SysStorageLocat>().First(m => m.LocatNo == task.StartLocat); |
| | | if (locate == null) |
| | | { |
| | | throw new Exception($"WMS系统中没有该{task.StartLocat}储位对应的信息"); |
| | | } |
| | | var locate2 = Db.Queryable<SysStorageLocat>().First(m => m.LocatNo == task.EndLocat); |
| | | if (locate2 == null) |
| | | { |
| | | throw new Exception($"WMS系统中没有该{task.EndLocat}储位对应的信息"); |
| | | } |
| | | |
| | | try |
| | | { |
| | | task.Status = "2";//任务状态 |
| | | task.IsSend = 0; |
| | | task.IsCancel = 0; |
| | | task.IsFinish = 0; |
| | | task.FinishDate = DateTime.Now;//完成时间 |
| | | Db.Updateable(task).ExecuteCommand(); |
| | | |
| | | #region 修改储位状态 |
| | | |
| | | //原储位改为空储位 0 |
| | | locate.Status = "0"; |
| | | Db.Updateable(locate).ExecuteCommand(); |
| | | |
| | | //目标储位改为有货物 1 |
| | | locate2.Status = "1"; |
| | | Db.Updateable(locate2).ExecuteCommand(); |
| | | 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 |
| | | |
| | | 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) |
| | | { |
| | |
| | | } |
| | | #endregion |
| | | |
| | | #region 自动分配、取消分配、获取手动分配的数据源、手动分配 |
| | | |
| | | // 判断是否是跨批出库 |
| | | public bool IsCrossLotNo(string soNo) |
| | | { |
| | | try |
| | | { |
| | | //方法返回结果:bl |
| | | var bl = true; |
| | | //查询单据信息 |
| | | var notice = Db.Queryable<BllExportNotice>().First(m=>m.SONo == soNo && m.IsDel == "0"); |
| | | //判断单据类型 成品出库、领料出库(其它类型跳出此方法) |
| | | if (notice.Type!="0" && notice.Type!="1") |
| | | { |
| | | return bl; |
| | | } |
| | | //查询到当前单据下的出库单明细信息 |
| | | var noticeDetail = Db.Queryable<BllExportNoticeDetail>().Where(m => m.IsDel == "0" && m.SONo == soNo).ToList(); |
| | | //库存总表信息 |
| | | var data = Db.Queryable<DataStock>().Where(m => m.IsDel == "0").ToList(); |
| | | //库存明细中检验合格批次集合 |
| | | var dataDetail = Db.Queryable<DataStockDetail>().Where(m => m.IsDel == "0" && m.InspectStatus == "1").GroupBy(g => g.LotNo).Select(s => s.LotNo).ToList(); |
| | | //库存明细表信息 |
| | | var dataBoxInfo = Db.Queryable<DataBoxInfo>().Where(m => m.IsDel == "0").ToList(); |
| | | |
| | | |
| | | //循环单据明细信息 |
| | | foreach (var item in noticeDetail) |
| | | { |
| | | //验证先进先出原则 |
| | | //获取当前物料的所有批次信息(排除单据的批次,防止单据所在批次锁定数量后验证小于等于0) |
| | | var forData = data.Where(m => m.SkuNo == item.SkuNo |
| | | && m.LotNo != item.LotNo && (m.Qty - m.FrozenQty - m.LockQty) > 0 |
| | | && dataDetail.Contains(m.LotNo)).Select(m=>m.LotNo).ToList(); |
| | | |
| | | forData.Add(item.LotNo); //集合添加单据的批次 |
| | | //获取排序后的第一个批次 |
| | | var firstLotNo = forData.OrderBy(m => m).First(); |
| | | if (firstLotNo != item.LotNo) |
| | | { |
| | | bl = false; |
| | | break; |
| | | } |
| | | |
| | | //验证效期优先原则 |
| | | var forDataBox = dataBoxInfo.Where(m => m.SkuNo == item.SkuNo && m.LotNo != item.LotNo && m.Qty > 0).ToList(); |
| | | //获取当前单据批次的最近效期 |
| | | var expirationTimedt = dataBoxInfo.Where(m => m.SkuNo == item.SkuNo |
| | | && m.LotNo == item.LotNo && m.Qty > 0).ToList(); |
| | | if (expirationTimedt.Count > 0) |
| | | { |
| | | var expirationTime = expirationTimedt.OrderBy(m => m.ExpirationTime).Select(m => m.ExpirationTime).First(); |
| | | //获取库存中其它批次效期大于当前单据批次的效期数量 |
| | | var num = forDataBox.Count(m => m.ExpirationTime > expirationTime); |
| | | //判断是否大于0 |
| | | if (num > 0) |
| | | { |
| | | bl = false; |
| | | break; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | var dataDetailtime = Db.Queryable<DataStockDetail>().Where(m => m.IsDel == "0" && m.InspectStatus == "1"). |
| | | Where(m => m.SkuNo == item.SkuNo |
| | | && m.LotNo == item.LotNo && m.Qty > 0) |
| | | .OrderBy(m => m.ExpirationTime) |
| | | .Select(m => m.ExpirationTime).First(); |
| | | |
| | | var num = forDataBox.Count(m => m.ExpirationTime > dataDetailtime); |
| | | //判断是否大于0 |
| | | if (num > 0) |
| | | { |
| | | bl = false; |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | return bl; |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | throw new Exception(e.Message); |
| | | } |
| | | } |
| | | |
| | | //自动分配 |
| | | public bool AutoAllot(string soNo, int userId) |
| | | { |
| | | try |
| | | { |
| | | #region 判断条件(出库单、出库单明细) |
| | | //出库单 |
| | | var notice = Db.Queryable<BllExportNotice>().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("参数异常,请检查状态是否为等待执行或部分分配;"); |
| | | } |
| | | //出库单明细 |
| | | var detailList = Db.Queryable<BllExportNoticeDetail>().Where(m => m.IsDel == "0" && m.SONo == soNo && (m.AllotQty - m.Qty) <= 0).ToList(); |
| | | if (!detailList.Any()) |
| | | { |
| | | throw new Exception("未查询到符合分配条件的出库单据明细信息"); |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | var exAllotList = new List<BllExportAllot>(); |
| | | var assign = new AllotSku(); |
| | | Db.BeginTran(); |
| | | try |
| | | { |
| | | List<SoDetailInfo> soDetailList = new List<SoDetailInfo>(); |
| | | foreach (var detail in detailList) |
| | | { |
| | | if (detail.AllotQty >= detail.Qty) |
| | | { |
| | | continue; |
| | | } |
| | | //还需要分配的数量 |
| | | decimal needQty = detail.Qty - (detail.AllotQty == null? 0: decimal.Parse(detail.AllotQty.ToString())); |
| | | //库存明细 Status 0:待分配 1:部分分配 2:已分配 |
| | | var stockDetail = Db.Queryable<DataStockDetail>().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 && m.IsDel == "0" && string.IsNullOrWhiteSpace(m.LotNo)).ToList(); |
| | | } |
| | | |
| | | if (stockDetail.Count < 1) |
| | | { |
| | | throw new Exception("库存不足,无可出库库存"); |
| | | } |
| | | //0:成品出库、1:领料出库、2:抽检出库、4:不合格品出库、6:代储出库、7:其他出库、 ///3:取样出库、5:中间品出库、8:寄存出库 |
| | | if (notice.Type == "0" || notice.Type == "1" )//成品、领料出库 |
| | | { |
| | | stockDetail = stockDetail.Where(m => m.InspectStatus == "1").ToList(); |
| | | } |
| | | else if (notice.Type == "2" )//抽检出库 |
| | | { |
| | | stockDetail = stockDetail.Where(m => m.InspectStatus == "0" || m.InspectStatus == "1" || m.InspectStatus == "2").ToList(); |
| | | } |
| | | else if (notice.Type == "6" || notice.Type == "7" ) //代储、其它 |
| | | { |
| | | stockDetail = stockDetail.Where(m => m.InspectStatus == "0" || m.InspectStatus == "1").ToList(); |
| | | } |
| | | else if (notice.Type == "4")//不合格出库 |
| | | { |
| | | stockDetail = stockDetail.Where(m => m.InspectStatus == "2").ToList(); |
| | | } |
| | | if (stockDetail.Sum(m=>m.Qty-m.LockQty) < needQty) |
| | | { |
| | | throw new Exception("库存明细数量不足"); |
| | | } |
| | | #region 包装信息 |
| | | |
| | | var pNum = 0;//托盘物品数量 |
| | | var bNum = 0;//箱物品数量 |
| | | //公共方法获取包装数量 |
| | | new Common().GetPackQtyInfo(detail.PackagNo,ref pNum,ref bNum); |
| | | |
| | | #endregion |
| | | |
| | | //取合适库存商品 |
| | | Dictionary<int, decimal> stockQtyDic = new Dictionary<int, decimal>();//托出库物品数 |
| | | var qty = 0m; |
| | | //分配货物 |
| | | qty += assign.AllotPallets(stockDetail, needQty, pNum, bNum, stockQtyDic, detail.LotNo, detail.IsMixBox); |
| | | 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"; |
| | | } |
| | | if (qty > detail.Qty) |
| | | { |
| | | //库存总表 |
| | | var stock = Db.Queryable<DataStock>().First(d => d.IsDel == "0" |
| | | && d.SkuNo == detail.SkuNo |
| | | && d.LotNo == detail.LotNo); |
| | | stock.LockQty += qty-detail.Qty; |
| | | Db.Updateable(stock).ExecuteCommand(); |
| | | |
| | | //添加回传上游系统锁定数量更改代码 |
| | | SoDetailInfo soDetail = new SoDetailInfo(); |
| | | soDetail.OrderDetailCode = detail.OrderDetailCode; |
| | | soDetail.LockQty = qty - detail.Qty; |
| | | soDetail.LotNo = detail.LotNo; |
| | | |
| | | soDetailList.Add(soDetail); |
| | | } |
| | | |
| | | } |
| | | |
| | | 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) |
| | | { |
| | | #region 通过接口发送至erp |
| | | //系统对接后放开 |
| | | /*var jsonData = JsonConvert.SerializeObject(soDetailList); |
| | | |
| | | var response = HttpHelper.DoPost(url, jsonData, "库存锁定数量变更", "ERP"); |
| | | |
| | | var obj = JsonConvert.DeserializeObject<ErpModel>(response);//解析返回数据 |
| | | if (obj.Success != 0) |
| | | { |
| | | throw new Exception("上传失败" + obj.Message); |
| | | }*/ |
| | | #endregion |
| | | |
| | | 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<BllExportNotice>().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<BllExportAllot>().Where(o => o.IsDel == "0" && o.SONo == soNo).ToList(); |
| | | //有已执行的分配数据不能取消 |
| | | if (allotList.Any(o => o.Status != "0")) |
| | | { |
| | | throw new Exception("当前单据的分配信息已有执行中,不能取消分配"); |
| | | } |
| | | List<SoDetailInfo> soDetailList = new List<SoDetailInfo>(); |
| | | //开启事务 |
| | | Db.BeginTran(); |
| | | try |
| | | { |
| | | //查询分配的明细 |
| | | var detail = Db.Queryable<BllExportNoticeDetail>().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<DataStockDetail>().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<DataStock>().First(t => t.SkuNo == pallet.SkuNo && t.IsDel == "0"); |
| | | //stock.LockQty -= o.Qty; |
| | | //Db.Updateable(stock).ExecuteCommand(); |
| | | } |
| | | |
| | | } |
| | | Db.Deleteable<BllExportAllot>(orders).ExecuteCommand(); |
| | | |
| | | if (d.AllotQty > d.Qty) |
| | | { |
| | | //库存总表 |
| | | var stock = Db.Queryable<DataStock>().First(m => m.IsDel == "0" && m.SkuNo == d.SkuNo && m.LotNo == d.LotNo); |
| | | stock.LockQty -= (decimal)d.AllotQty - d.Qty; |
| | | Db.Updateable(stock).ExecuteCommand(); |
| | | |
| | | //添加回传上游系统锁定数量更改代码 |
| | | SoDetailInfo soDetail = new SoDetailInfo(); |
| | | soDetail.OrderDetailCode = d.OrderDetailCode; |
| | | soDetail.LockQty = (decimal)(d.Qty-d.AllotQty); |
| | | soDetail.LotNo = d.LotNo; |
| | | |
| | | soDetailList.Add(soDetail); |
| | | } |
| | | d.AllotQty = 0; |
| | | d.Status = "0"; |
| | | d.UpdateUser = userId; |
| | | d.UpdateTime = DateTime.Now; |
| | | //if (notice.Type == "1" || notice.Type == "5" || notice.Type == "6" || notice.Type == "7" || notice.Type == "8")//1:领料出库、 |
| | | //{ |
| | | // if (d.IsIssueLotNo != "1") |
| | | // { |
| | | // d.LotNo = ""; |
| | | // } |
| | | |
| | | //} |
| | | } |
| | | |
| | | //查询当前单据是否已添加备料任务 |
| | | if (notice.Type == "1") |
| | | { |
| | | var task = Db.Queryable<BllExportTimingTask>().First(m => m.IsDel == "0" && m.SoNo == soNo); |
| | | if (task!=null) |
| | | { |
| | | task.IsDel = "1"; |
| | | task.UpdateUser = userId; |
| | | task.UpdateTime = DateTime.Now; |
| | | Db.Updateable(task).ExecuteCommand(); |
| | | } |
| | | } |
| | | notice.Status = "0"; |
| | | notice.UpdateUser = userId; |
| | | notice.UpdateTime = DateTime.Now; |
| | | Db.Updateable(detail).ExecuteCommand(); |
| | | Db.Updateable(notice).ExecuteCommand(); |
| | | |
| | | //系统对接后放开 |
| | | /*var jsonData = JsonConvert.SerializeObject(soDetailList); |
| | | |
| | | var response = HttpHelper.DoPost(url, jsonData, "库存锁定数量变更", "ERP"); |
| | | |
| | | var obj = JsonConvert.DeserializeObject<ErpModel>(response);//解析返回数据 |
| | | if (obj.Success != 0) |
| | | { |
| | | throw new Exception("上传失败" + obj.Message); |
| | | }*/ |
| | | |
| | | //添加操作日志记录 |
| | | 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); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 维护出库单备注信息 |
| | | /// </summary> |
| | | /// <param name="id"></param> |
| | | /// <param name="demo"></param> |
| | | /// <param name="userId"></param> |
| | | public void EditNoticeDemo(int id, string demo, int userId) |
| | | { |
| | | try |
| | | { |
| | | var notice = Db.Queryable<BllExportNotice>().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<StockDetailDto> GetHandOutList(int detailId, string houseNo, string roadwayNo, string locateNo, string msg, string palletNo) |
| | | { |
| | | try |
| | | { |
| | | var detail = Db.Queryable<BllExportNoticeDetail>().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<BllExportNotice>().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<Func<DataStockDetail, bool>> item = Expressionable.Create<DataStockDetail>() |
| | | .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<DataStockDetail>().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, |
| | | Demo = a.Demo, |
| | | }).ToList(); |
| | | |
| | | return list; |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | throw new Exception(e.Message); |
| | | } |
| | | } |
| | | |
| | | //手动分配出库单明细 |
| | | public void AddHandOutAllot(AddHandOutVm model, int userId) |
| | | { |
| | | try |
| | | { |
| | | #region 判断条件 |
| | | //数据验证 |
| | | var detail = Db.Queryable<BllExportNoticeDetail>().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<BllExportNotice>().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<DataStockDetail>().Where(a => stockIds.Contains(a.Id)).ToList(); |
| | | |
| | | //分配信息 |
| | | var allots = Db.Queryable<BllExportAllot>().Where(m => m.IsDel == "0" && m.SODetailNo == detail.Id && m.Status == "0").ToList(); |
| | | |
| | | //库存总表 |
| | | //var stockz = Db.Queryable<DataStock>().First(d => d.IsDel == "0" && d.SkuNo == detail.SkuNo && d.LotNo == detail.LotNo); |
| | | |
| | | var allotList = new List<BllExportAllot>(); |
| | | decimal 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)) // 输入的数量 - 托盘上可用的数量(托盘上数量-锁定的数量-冻结的数量) |
| | | { |
| | | throw new Exception("操作失败,出库数量超出库存数量!"); |
| | | } |
| | | |
| | | var bl = allots.FirstOrDefault(m => m.StockId == st.StockId); |
| | | if (bl == null) |
| | | { |
| | | //添加分配表信息 |
| | | 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); |
| | | } |
| | | else |
| | | { |
| | | bl.Qty += st.Qty; |
| | | Db.Updateable(bl).ExecuteCommand(); |
| | | } |
| | | |
| | | //库存明细 |
| | | 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<BllExportNoticeDetail>() |
| | | .Where(m => m.IsDel == "0" && m.SONo == notice.SONo).ToList(); |
| | | //修改出库单状态 |
| | | if (notice.Status == "0" || notice.Status == "1") |
| | | { |
| | | decimal totalQty = 0; |
| | | decimal 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 |
| | | |
| | | |
| | | /// <summary> |
| | | /// 判断出库是否需要拆箱 |