using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using WIDESEA_Core.Enums; using WIDESEA_Core; using WIDESEA_DTO.Stock; using WIDESEA_Model.Models; using WIDESEA_Core.Helper; using WIDESEA_Common.OtherEnum; using WIDESEA_Common.TaskEnum; using WIDESEA_Common.OrderEnum; using WIDESEA_Common.StockEnum; using WIDESEA_Common.CommonEnum; using WIDESEA_Common.LocationEnum; using MailKit.Search; using WIDESEA_External.Model; using WIDESEA_Core.CodeConfigEnum; using Microsoft.AspNetCore.Mvc; using WIDESEA_DTO.ERP; namespace WIDESEA_TaskInfoService { public partial class TaskService { /// /// 选择库存生成出库任务 /// /// /// public WebResponseContent Outbound(int id) { WebResponseContent content = new WebResponseContent(); try { Dt_StockInfo stockInfo = _stockRepository.StockInfoRepository.Db.Queryable().Where(x => x.Id == id).Includes(x => x.Details).First(); if (stockInfo == null) { return content.Error($"未找到库存"); } Dt_LocationInfo locationInfo = _basicRepository.LocationInfoRepository.QueryFirst(x => x.LocationCode == stockInfo.LocationCode); if (locationInfo != null && (locationInfo.EnableStatus == EnableStatusEnum.OnlyOut.ObjToInt() || locationInfo.EnableStatus == EnableStatusEnum.Normal.ObjToInt()) && locationInfo.LocationStatus == LocationStatusEnum.InStock.ObjToInt() && stockInfo.StockStatus == StockStatusEmun.入库完成.ObjToInt()) { List tasks = GetTasks(new List() { stockInfo }, TaskTypeEnum.Outbound); if (tasks == null || tasks.Count <= 0) { return content.Error($"生成任务失败"); } //处理库存数据 stockInfo.StockStatus = (int)StockStatusEmun.出库锁定; LocationStatusEnum locationStatus = (LocationStatusEnum)locationInfo.LocationStatus; locationInfo.LocationStatus = (int)LocationStatusEnum.Lock; //判断是否有出库单信息 _unitOfWorkManage.BeginTran(); //更新库存状态 _stockRepository.StockInfoRepository.UpdateData(stockInfo); //更新货位状态 _basicService.LocationInfoService.UpdateLocationStatus(locationInfo, stockInfo.PalletType, LocationStatusEnum.Lock, stockInfo.WarehouseId); //新建任务 BaseDal.AddData(tasks); //加入货位变动记录 _recordService.LocationStatusChangeRecordSetvice.AddLocationStatusChangeRecord(locationInfo, locationStatus, LocationStatusEnum.Lock, LocationChangeType.OutboundAssignLocation, stockInfo.Details.FirstOrDefault()?.OrderNo ?? "", tasks[0].TaskNum); _unitOfWorkManage.CommitTran(); PushTasksToWCS(tasks); content.OK(); } else { content.Error($"货位出库条件不满足"); } } catch (Exception ex) { content.Error(ex.Message); } return content; } /// /// 生成成品出库任务 /// /// 出库订单号 /// 站台地址 /// public async Task OutProductTask(int[] keys, string StationCode, int Grade) { WebResponseContent content = new WebResponseContent(); try { if (StationCode.IsNullOrEmpty()) { return await Task.FromResult(content.Error("线体输入错误")); } //获取成品出库订单 List _ProOutOrderDetails = await _outboundRepository.ProOutOrderDetailRepository.QueryDataAsync(x => keys.Contains(x.Id) && x.ProOrderDetailStatus== OrderDetailStatusEnum.New.ObjToInt()); if (_ProOutOrderDetails.Count<=0) { return await Task.FromResult(content.Error("勾选订单明细状态为出库中")); } List tasks = new List(); List stockSelectViews = new List(); List proStockInfos = new List(); List proOutOrderDetails = new List(); List outProStockInfos = new List(); List locationInfos = new List(); (List, List?, List?, List?, List?) result = OutProductTaskDataHandle(_ProOutOrderDetails); if (result.Item2 != null && result.Item2.Count > 0) { proStockInfos.AddRange(result.Item2); } if (result.Item3 != null && result.Item3.Count > 0) { proOutOrderDetails.AddRange(result.Item3); } if (result.Item4 != null && result.Item4.Count > 0) { outProStockInfos.AddRange(result.Item4); } if (result.Item5 != null && result.Item5.Count > 0) { locationInfos.AddRange(result.Item5); } if (result.Item1 != null && result.Item1.Count > 0) { Dt_Task? task = BaseDal.QueryData(x=>x.TaskType==TaskTypeEnum.OutProduct.ObjToInt()).OrderBy(x=>x.Grade).FirstOrDefault(); //更新出库目的位置 result.Item1.ForEach(x => { x.TargetAddress = StationCode; if (Grade==1 || task==null) { x.Grade = 127; } else { if (task.Grade==0 || task.Grade==1) { x.Grade = 1; } else { x.Grade = task.Grade - 1; } } }); tasks.AddRange(result.Item1); } //处理出库数据 return await Task.FromResult(GenerateOutboundTaskDataUpdate(tasks, proStockInfos, proOutOrderDetails, outProStockInfos, locationInfos)); } catch (Exception ex) { _unitOfWorkManage.RollbackTran(); content.Error(ex.Message); } return content; } /// /// 人工选定库存出库 /// /// public WebResponseContent OutProductSelect(int orderDetailId,List proStockViews) { WebResponseContent content = new WebResponseContent(); try { //获取出库单明细 Dt_ProOutOrderDetail proOutOrderDetail = _outboundRepository.ProOutOrderDetailRepository.QueryFirst(x=>x.Id==orderDetailId); if (proOutOrderDetail == null) { return content.Error("订单明细不存在"); } if (proOutOrderDetail.ProOrderDetailStatus == OrderDetailStatusEnum.Over.ObjToInt()) { return content.Error("当前的明细单已完成"); } //获取出库单据 Dt_ProOutOrder proOutOrder = _outboundRepository.ProOutOrderRepository.Db.Queryable().Where(x=>x.Id==proOutOrderDetail.ProOrderId).Includes(x => x.Details).First(); if (proOutOrder==null) { return content.Error("出库单据不存在"); } if (proOutOrder.ProOrderStatus>=OutOrderStatusEnum.出库完成.ObjToInt()) { return content.Error($"{proOutOrder.ProOutOrderNo}出库单已完成"); } if ((proOutOrderDetail.QtyPcs-proOutOrderDetail.OverQtyPcs)> proStockViews.Sum(x=>x.SumStocks)) { return content.Error($"需满足{proOutOrderDetail.QtyPcs - proOutOrderDetail.OverQtyPcs}出库量"); } //获取所有库存 List proStockInfos = _stockRepository.ProStockInfoRepository.Db.Queryable().Where(b => b.LocationCode == "成品待发货区" && b.StockStatus == StockStatusEmun.平库入库完成.ObjToInt() && (b.ShipmentOrder == null || b.ShipmentOrder == "")).Includes(x => x.proStockInfoDetails).Where(x => x.proStockInfoDetails.Any(v => v.ProductCode == proOutOrderDetail.PCode)).ToList(); //获取已完成数量 int OverCount = proOutOrder.Details.Where(x => x.ProOrderDetailStatus == OrderDetailStatusEnum.Over.ObjToInt()).Count(); List outStockInfos=new List(); List outStockInfoDetails=new List(); List stockOutItems = new List(); foreach (var item in proStockViews.OrderBy(x => x.SumStocks)) { //获取当前库存 Dt_ProStockInfo? proStockInfo = proStockInfos.FirstOrDefault(x => x.Id == item.ProStockId); if (proStockInfo!=null && proStockInfo.proStockInfoDetails.Count>0) { proStockInfo.ShipmentOrder = proOutOrder.ProOutOrderNo; proStockInfo.StockStatus = StockStatusEmun.平库待发货.ObjToInt(); //剩余数量 float Amount = proOutOrderDetail.QtyPcs - proOutOrderDetail.LockQtyPcs; if (Amount > item.SumStocks) { proOutOrderDetail.LockQtyPcs += item.SumStocks; Dt_ProStockInfoDetail proStockInfoDetail = proStockInfo.proStockInfoDetails.FirstOrDefault(); proStockInfoDetail.OutboundQuantity = proStockInfoDetail.StockPcsQty; proStockInfoDetail.OutSETQty = proStockInfoDetail.SETQty; proStockInfoDetail.OutDetailSaleNo = proOutOrderDetail.SaleOrder; outStockInfoDetails.Add(proStockInfoDetail); } else { Dt_ProStockInfoDetail proStockInfoDetail = proStockInfo.proStockInfoDetails.FirstOrDefault(); float intervalSet = proStockInfoDetail.StockPcsQty / proStockInfoDetail.SETQty; proStockInfoDetail.OutboundQuantity += Amount; proStockInfoDetail.OutSETQty += (Amount / intervalSet); proOutOrderDetail.LockQtyPcs += Amount; proStockInfoDetail.OutDetailSaleNo = proOutOrderDetail.SaleOrder; outStockInfoDetails.Add(proStockInfoDetail); } if (proOutOrderDetail.QtyPcs==proOutOrderDetail.LockQtyPcs) { proOutOrderDetail.ProOrderDetailStatus = OrderDetailStatusEnum.Over.ObjToInt(); } outStockInfos.Add(proStockInfo); } else { return content.Error("未找到成品库存"); } } List deleteStocks=new List(); List deleteStockDetails = new List(); List updateStocks = new List(); List updateStockDetails = new List(); if (proOutOrderDetail.ProOrderDetailStatus == OrderDetailStatusEnum.Over.ObjToInt() && (OverCount+1)== proOutOrder.Details.Count) { proOutOrder.ProOrderStatus=OutOrderStatusEnum.出库完成.ObjToInt(); //获取所有已扫码待发货的库存 List AllOutStocks = _stockRepository.ProStockInfoRepository.Db.Queryable() .Where(x => x.ShipmentOrder == proOutOrder.ProOutOrderNo && x.StockStatus == StockStatusEmun.平库待发货.ObjToInt()) .Includes(x => x.proStockInfoDetails).ToList(); AllOutStocks.ForEach(x => { outStockInfoDetails.AddRange(x.proStockInfoDetails); }); outStockInfos.AddRange(AllOutStocks); foreach (var item in outStockInfoDetails) { StockOutItemsItem outItemsItem = new StockOutItemsItem() { PartNum = item.ProductCode, Rev = item.ProductVersion, SoNumber = item.OutDetailSaleNo, BatchNumber = item.BagNo, QtyPcs = item.OutboundQuantity, QtySet = item.OutSETQty }; stockOutItems.Add(outItemsItem); if (item.OutboundQuantity == item.StockPcsQty) { Dt_ProStockInfo proStockInfo = outStockInfos.FirstOrDefault(x => x.Id == item.ProStockId); if (proStockInfo != null) { deleteStocks.Add(proStockInfo); deleteStockDetails.Add(item); } else { return content.Error("未找到上报的库存数据"); } } if (item.OutboundQuantity < item.StockPcsQty) { Dt_ProStockInfo proStockInfo = outStockInfos.FirstOrDefault(x => x.Id == item.ProStockId); if (proStockInfo != null) { proStockInfo.StockStatus = StockStatusEmun.平库入库完成.ObjToInt(); proStockInfo.ShipmentOrder = ""; updateStocks.Add(proStockInfo); item.StockPcsQty -= item.OutboundQuantity; item.OutboundQuantity = 0; item.OutSETQty = 0; updateStockDetails.Add(item); } else { return content.Error("未找到上报的库存数据"); } } } } Dt_Warehouse warehouse = _basicRepository.WarehouseRepository.QueryFirst(x => x.WarehouseId == proOutOrder.WarehouseId); _unitOfWorkManage.BeginTran(); if (proOutOrder.ProOrderStatus == OutOrderStatusEnum.出库完成.ObjToInt()) { //成品库存记录变动待加入 ERPProOutOrderModel proOutOrderModel = new ERPProOutOrderModel() { Way = 1, StockOutCode = _outboundService.OutboundOrderService.CreateCodeByRule(nameof(RuleCodeEnum.ProOutCOdeRule)), ConfirmedUserNo = App.User.UserName, AssignUserNo = App.User.UserName, WarehouseCode = warehouse.WarehouseCode, ShipDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), DeliverplanCode = proOutOrder.ProOutOrderNo, Remark = proOutOrder.Remark, StockOutItems = stockOutItems }; _stockRepository.ProStockInfoRepository.DeleteAndMoveIntoHty(deleteStocks, OperateTypeEnum.自动完成); _stockRepository.ProStockInfoDetailRepository.DeleteAndMoveIntoHty(deleteStockDetails, OperateTypeEnum.自动完成); if (updateStockDetails.Count>0) { _stockRepository.ProStockInfoRepository.UpdateData(updateStocks); updateStockDetails.ForEach(x => { x.OutDetailSaleNo = ""; }); _stockRepository.ProStockInfoDetailRepository.UpdateData(updateStockDetails); } string response = _invokeERPService.InvokeProOutApi(proOutOrderModel); ErpRequestContent erpRequestContent = response.DeserializeObject(); if (erpRequestContent.res != 1) { throw new Exception("同步ERP失败,错误信息:" + erpRequestContent.Data); } } else { _stockRepository.ProStockInfoRepository.UpdateData(outStockInfos); _stockRepository.ProStockInfoDetailRepository.UpdateData(outStockInfoDetails); _outboundRepository.ProOutOrderDetailRepository.UpdateData(proOutOrderDetail); _outboundRepository.ProOutOrderRepository.UpdateData(proOutOrder); } _unitOfWorkManage.CommitTran(); content.OK("成功"); } catch (Exception ex) { _unitOfWorkManage.RollbackTran(); content.Error(ex.Message); } return content; } /// /// 处理出库数据 /// public WebResponseContent GenerateOutboundTaskDataUpdate(List tasks, List? proStockInfos = null, List? proOutOrderDetails = null, List? outProStockInfos = null, List? locationInfos = null) { try { _unitOfWorkManage.BeginTran(); //获取成品出库单主表 Dt_ProOutOrder proOutOrder = _outboundRepository.ProOutOrderRepository.QueryFirst(x => x.Id == proOutOrderDetails.FirstOrDefault().ProOrderId); if (proOutOrder!=null && proOutOrder.ProOrderStatus == OutOrderStatusEnum.未开始.ObjToInt()) { proOutOrder.ProOrderStatus = OutOrderStatusEnum.出库中.ObjToInt(); _outboundRepository.ProOutOrderRepository.UpdateData(proOutOrder); } BaseDal.AddData(tasks); if (proStockInfos != null && proStockInfos.Count > 0 && proOutOrderDetails != null && proOutOrderDetails.Count > 0 && outProStockInfos != null && outProStockInfos.Count > 0 && locationInfos != null && locationInfos.Count > 0) { proStockInfos.ForEach(x => { x.StockStatus = StockStatusEmun.出库锁定.ObjToInt(); }); WebResponseContent content = _outboundService.ProOutOrderDetailService.LockOutboundStockDataUpdate(proStockInfos, proOutOrderDetails, outProStockInfos, locationInfos, tasks: tasks); if (!content.Status) { _unitOfWorkManage.RollbackTran(); return content; } } else if (proOutOrderDetails != null && proOutOrderDetails.Count > 0) { proOutOrderDetails.ForEach(x => { x.ProOrderDetailStatus = OrderDetailStatusEnum.Outbound.ObjToInt(); }); _outboundRepository.ProOutOrderDetailRepository.UpdateData(proOutOrderDetails); } _unitOfWorkManage.CommitTran(); PushTasksToWCS(tasks); return WebResponseContent.Instance.OK(); } catch (Exception ex) { _unitOfWorkManage.RollbackTran(); return WebResponseContent.Instance.Error(ex.Message); } } /// /// 处理成品出库数据 /// /// public (List, List?, List?, List?, List?) OutProductTaskDataHandle(List proOutOrderDetails) { List tasks = new List(); List proStockInfos = new List(); List assignOutOrderDetails = new List(); List outProStockInfos=new List(); List locationInfos = new List(); //分配库存 (List, List, List, List) result = _outboundService.ProOutOrderDetailService.AssignProStockOut(proOutOrderDetails); if (result.Item1!=null&&result.Item1.Count>0) { //获取成品单 Dt_ProOutOrder proOutOrder = _outboundRepository.ProOutOrderRepository.QueryFirst(x => x.Id == proOutOrderDetails.FirstOrDefault().ProOrderId); if (proOutOrder==null) { throw new Exception("未找到成品订单"); } TaskTypeEnum typeEnum = proOutOrder.ProOrderType switch { (int)OutProTypeEnum.ProOut => TaskTypeEnum.OutProduct, (int)OutProTypeEnum.SendProOut => TaskTypeEnum.OutSendProduct, _ => new TaskTypeEnum() }; tasks = GetTasks(result.Item1, typeEnum); result.Item2.ForEach(x => { x.ProOrderDetailStatus = OrderDetailStatusEnum.Outbound.ObjToInt(); }); result.Item3.ForEach(x => { x.Status = OutLockStockStatusEnum.出库中.ObjToInt(); }); tasks.ForEach(x => x.OrderNo = proOutOrder.ProOutOrderNo); proStockInfos = result.Item1; proOutOrderDetails = result.Item2; outProStockInfos = result.Item3; locationInfos = result.Item4; } else { throw new Exception("无可分配库存"); } return (tasks, proStockInfos, proOutOrderDetails, outProStockInfos, locationInfos); } /// /// 生成任务 /// /// /// /// public List GetTasks(List stockInfos, TaskTypeEnum taskType) { List tasks = new List(); string groupId = DateTime.Now.ToString("yyMMddHHmmss"); for (int i = 1; i <= stockInfos.Count; i++) { Dt_ProStockInfo stockInfo = stockInfos[i-1]; if (i%5==0) { groupId= DateTime.Now.AddSeconds(i).ToString("yyMMddHHmmss"); } if (stockInfo != null) { Dt_LocationInfo locationInfo = _basicService.LocationInfoService.Repository.QueryFirst(x => x.LocationCode == stockInfo.LocationCode); if (!tasks.Exists(x => x.PalletCode == stockInfo.PalletCode)) { Dt_Task task = new() { CurrentAddress = stockInfo.LocationCode, Grade = 0, PalletCode = stockInfo.PalletCode, NextAddress = "", Roadway = locationInfo.RoadwayNo, SourceAddress = stockInfo.LocationCode, TargetAddress = "", TaskStatus = TaskStatusEnum.New.ObjToInt(), TaskType = taskType.ObjToInt(), TaskNum = BaseDal.GetTaskNum(nameof(SequenceEnum.SeqTaskNum)), PalletType = stockInfo.PalletType, WarehouseId = stockInfo.WarehouseId, GroupId= groupId, MaterielCode = stockInfo.proStockInfoDetails.Where(x => x.ProStockId == stockInfo.Id).FirstOrDefault()?.ProductCode, Quantity = (float)stockInfo.proStockInfoDetails.Where(x => x.ProStockId == stockInfo.Id).Sum(x=> x.StockPcsQty) }; tasks.Add(task); } } } return tasks; } /// /// 库存数据转出库任务 /// /// /// public List GetTasks(List stockInfos, TaskTypeEnum taskType) { List tasks = new List(); for (int i = 0; i < stockInfos.Count; i++) { Dt_StockInfo stockInfo = stockInfos[i]; if (stockInfo != null) { Dt_LocationInfo locationInfo = _basicService.LocationInfoService.Repository.QueryFirst(x => x.LocationCode == stockInfo.LocationCode); if (!tasks.Exists(x => x.PalletCode == stockInfo.PalletCode)) { Dt_Task task = new() { CurrentAddress = stockInfo.LocationCode, Grade = 0, PalletCode = stockInfo.PalletCode, NextAddress = "", Roadway = locationInfo.RoadwayNo, SourceAddress = stockInfo.LocationCode, TargetAddress = "", TaskStatus = TaskStatusEnum.New.ObjToInt(), TaskType = taskType.ObjToInt(), TaskNum = BaseDal.GetTaskNum(nameof(SequenceEnum.SeqTaskNum)), PalletType = stockInfo.PalletType, WarehouseId = stockInfo.WarehouseId, }; if (taskType != TaskTypeEnum.OutEmpty) { task.MaterielCode = stockInfo.Details.Where(x => x.StockId == stockInfo.Id).FirstOrDefault()?.MaterielCode; task.Quantity = (float)stockInfo.Details.Where(x => x.StockId == stockInfo.Id).FirstOrDefault()?.StockQuantity; } if (stockInfo.StockLength>0) { task.TaskLength = stockInfo.StockLength; } tasks.Add(task); } } } return tasks; } /// /// 出库任务数据处理 /// /// /// /// /// public (List, List?, List?, List?, List?) OutboundTaskDataHandle(int orderDetailId, List stockSelectViews) { List tasks = new List(); Dt_OutboundOrderDetail outboundOrderDetail = _outboundService.OutboundOrderDetailService.Repository.QueryFirst(x => x.Id == orderDetailId); if (outboundOrderDetail == null) { throw new Exception("未找到出库单明细信息"); } if (stockSelectViews.Sum(x => x.UseableQuantity) > outboundOrderDetail.OrderQuantity - outboundOrderDetail.LockQuantity) { throw new Exception("选择数量超出单据数量"); } List? stockInfos = null; Dt_OutboundOrderDetail? orderDetail = null; List? outStockLockInfos = null; List? locationInfos = null; if (outboundOrderDetail.OrderDetailStatus == OrderDetailStatusEnum.New.ObjToInt()) { (List, Dt_OutboundOrderDetail, List, List) result = _outboundService.OutboundOrderDetailService.AssignStockOutbound(outboundOrderDetail, stockSelectViews); if (result.Item1 != null && result.Item1.Count > 0) { Dt_OutboundOrder outboundOrder = _outboundService.OutboundOrderService.Repository.QueryFirst(x => x.Id == outboundOrderDetail.OrderId); TaskTypeEnum typeEnum = outboundOrder.OrderType switch { (int)OutOrderTypeEnum.Issue => TaskTypeEnum.Outbound, (int)OutOrderTypeEnum.Allocate => TaskTypeEnum.OutAllocate, (int)OutOrderTypeEnum.Quality => TaskTypeEnum.OutQuality, _ => new TaskTypeEnum() }; tasks = GetTasks(result.Item1, typeEnum); result.Item2.OrderDetailStatus = OrderDetailStatusEnum.Outbound.ObjToInt(); result.Item3.ForEach(x => { x.Status = OutLockStockStatusEnum.出库中.ObjToInt(); }); stockInfos = result.Item1; orderDetail = result.Item2; outStockLockInfos = result.Item3; locationInfos = result.Item4; } else { throw new Exception("无库存"); } } else { List stockLockInfos = _outboundService.OutboundStockLockInfoService.GetByOrderDetailId(outboundOrderDetail.OrderId, OutLockStockStatusEnum.已分配); if (stockLockInfos != null && stockLockInfos.Count > 0) { List stocks = _stockService.StockInfoService.Repository.GetStockInfosByPalletCodes(stockLockInfos.Select(x => x.PalletCode).Distinct().ToList()); tasks = GetTasks(stocks, TaskTypeEnum.Outbound); } } return (tasks, stockInfos, orderDetail == null ? null : new List { orderDetail }, outStockLockInfos, locationInfos); } /// /// 出库任务数据处理 /// /// /// /// /// public (List, List?, List?, List?, List?) OutboundTaskDataHandle(int[] keys) { List tasks = new List(); List outboundOrderDetails = _outboundService.OutboundOrderDetailService.Repository.QueryData(x => keys.Contains(x.Id)); if (outboundOrderDetails == null || outboundOrderDetails.Count == 0) { throw new Exception("未找到出库单明细信息"); } if (outboundOrderDetails.FirstOrDefault(x => x.OrderDetailStatus > OrderDetailStatusEnum.New.ObjToInt() && x.OrderDetailStatus != OrderDetailStatusEnum.AssignOverPartial.ObjToInt()) != null) { throw new Exception("所选出库单明细存在出库中或已完成"); } List? stockInfos = null; List? orderDetails = null; List? outStockLockInfos = null; List? locationInfos = null; //if (outboundOrderDetail.OrderDetailStatus == OrderDetailStatusEnum.New.ObjToInt()) { (List, List, List, List) result = _outboundService.OutboundOrderDetailService.AssignStockOutbound(outboundOrderDetails); if (result.Item1 != null && result.Item1.Count > 0) { Dt_OutboundOrder outboundOrder =_outboundService.OutboundOrderService.Repository.QueryFirst(x => x.Id == outboundOrderDetails.FirstOrDefault().OrderId); TaskTypeEnum typeEnum = outboundOrder.OrderType switch { (int)OutOrderTypeEnum.Issue => TaskTypeEnum.Outbound, (int)OutOrderTypeEnum.Allocate=> TaskTypeEnum.OutAllocate, (int)OutOrderTypeEnum.Quality => TaskTypeEnum.OutQuality, _ =>new TaskTypeEnum() }; tasks = GetTasks(result.Item1, typeEnum); tasks.ForEach(x => { x.OrderNo = outboundOrder.UpperOrderNo; }); result.Item2.ForEach(x => { x.OrderDetailStatus = OrderDetailStatusEnum.Outbound.ObjToInt(); }); result.Item3.ForEach(x => { x.Status = OutLockStockStatusEnum.出库中.ObjToInt(); }); stockInfos = result.Item1; orderDetails = result.Item2; outStockLockInfos = result.Item3; locationInfos = result.Item4; } else { throw new Exception("无库存"); } } //else //{ // List stockLockInfos = _outboundService.OutboundStockLockInfoService.GetByOrderDetailId(outboundOrderDetail.OrderId, OutLockStockStatusEnum.已分配); // if (stockLockInfos != null && stockLockInfos.Count > 0) // { // List stocks = _stockService.StockInfoService.Repository.GetStockInfosByPalletCodes(stockLockInfos.Select(x => x.PalletCode).Distinct().ToList()); // tasks = GetTasks(stocks); // } //} return (tasks, stockInfos, orderDetails, outStockLockInfos, locationInfos); } /// /// 生成出库任务 /// /// /// /// public WebResponseContent GenerateOutboundTask(int orderDetailId, List stockSelectViews) { try { (List, List?, List?, List?, List?) result = OutboundTaskDataHandle(orderDetailId, stockSelectViews); WebResponseContent content = GenerateOutboundTaskDataUpdate(result.Item1, result.Item2, result.Item3, result.Item4, result.Item5); return content; } catch (Exception ex) { return WebResponseContent.Instance.Error(ex.Message); } } /// /// 平库直接出库 /// /// /// /// public WebResponseContent GeneratePKOutboundTask(int orderDetailId, List stockSelectViews) { try { #region MyRegion Dt_OutboundOrderDetail OrderDetail = _outboundService.OutboundOrderDetailService.Repository.QueryFirst(x => x.Id == orderDetailId); if (OrderDetail == null) { throw new Exception("未找到出库单明细信息"); } if (OrderDetail.OrderDetailStatus == OrderDetailStatusEnum.Over.ObjToInt()) throw new Exception("出库单已完成"); Dt_OutboundOrder outboundOrder = BaseDal.Db.Queryable().Where(x => x.Id == OrderDetail.OrderId).Includes(x => x.Details).First(); if (outboundOrder == null) { return WebResponseContent.Instance.Error($"未找到出库单信息"); } Dt_Warehouse warehouse = _basicService.WarehouseService.Repository.QueryFirst(x => x.WarehouseId == outboundOrder.WarehouseId); List outStocks = _stockService.StockInfoService.Repository.GetStockInfosByPalletCodes(stockSelectViews.Select(x => x.PalletCode).ToList()); if (outStocks.Count < 1) return WebResponseContent.Instance.Error($"库存不足"); List outStockLockInfos = new List(); List upStocks = new List(); List deStocks = new List(); List upstockDetails = new List(); List destockDetails = new List(); outStocks.ForEach(x => { x.Details.Where(x => x.MaterielCode == OrderDetail.MaterielCode).ToList().ForEach(v => { float OriginalQuantity = v.StockQuantity; float assignQuantity = 0;//分配数量 float assignAmount = OrderDetail.OrderQuantity - OrderDetail.OverOutQuantity;//待出数量 if (assignAmount > 0) { if (v.StockQuantity >= assignAmount) { assignQuantity = assignAmount; v.StockQuantity -= assignAmount; OrderDetail.OverOutQuantity += assignAmount; OrderDetail.LockQuantity += assignAmount; upstockDetails.Add(v); } else { assignQuantity = v.StockQuantity; OrderDetail.OverOutQuantity += v.StockQuantity; OrderDetail.LockQuantity += v.StockQuantity; v.StockQuantity = 0; destockDetails.Add(v); } Dt_OutStockLockInfo outStockLockInfo = new Dt_OutStockLockInfo() { PalletCode = x.PalletCode, AssignQuantity = assignQuantity, MaterielCode = OrderDetail.MaterielCode, BatchNo = v.BatchNo, LocationCode = x.LocationCode, MaterielName = v.MaterielName, OrderDetailId = OrderDetail.Id, OrderNo = outboundOrder.OrderNo, OrderType = outboundOrder.OrderType, OriginalQuantity = OriginalQuantity, Status = OutLockStockStatusEnum.出库完成.ObjToInt(), StockId = x.Id, TaskNum = 0, OrderQuantity = OrderDetail.OrderQuantity, Unit = OrderDetail.Unit, ProductionDate = v.ProductionDate, EffectiveDate = v.EffectiveDate }; outStockLockInfos.Add(outStockLockInfo); } }); int overCount = x.Details.Where(x => x.StockQuantity == 0).Count(); if (overCount == x.Details.Count) deStocks.Add(x); else upStocks.Add(x); }); outboundOrder.OrderStatus = OutOrderStatusEnum.出库中.ObjToInt(); OrderDetail.OrderDetailStatus = OrderDetail.OrderQuantity > OrderDetail.OverOutQuantity ? OrderDetailStatusEnum.AssignOverPartial.ObjToInt() : OrderDetailStatusEnum.Over.ObjToInt(); if (OrderDetail.OrderDetailStatus == OrderDetailStatusEnum.Over.ObjToInt()) { int overCount = outboundOrder.Details.Where(x => x.OrderDetailStatus == OrderDetailStatusEnum.Over.ObjToInt()).Count(); if (outboundOrder.Details.Count - 1 == overCount) outboundOrder.OrderStatus = OutOrderStatusEnum.出库完成.ObjToInt(); } _unitOfWorkManage.BeginTran(); _outboundService.OutboundStockLockInfoService.AddData(outStockLockInfos); _outboundService.OutboundOrderService.UpdateData(outboundOrder); _outboundService.OutboundOrderDetailService.UpdateData(OrderDetail); _stockRepository.StockInfoRepository.UpdateData(upStocks); _stockRepository.StockInfoRepository.DeleteData(deStocks); _stockRepository.StockInfoDetailRepository.UpdateData(upstockDetails); _stockRepository.StockInfoDetailRepository.DeleteData(destockDetails); _unitOfWorkManage.CommitTran(); #endregion #region 上报ERP if (outboundOrder.OrderStatus == OutOrderStatusEnum.出库完成.ObjToInt() && outboundOrder.OrderType==OutOrderTypeEnum.Issue.ObjToInt()) { //List eRPPickModels = new List(); //outStockLockInfos.ForEach(x => //{ // ERPPickItemModel pickItemModel = new ERPPickItemModel() // { // Lotno = x.BatchNo, // Qty = x.AssignQuantity.ToString(), // Location = warehouse.WarehouseCode // }; // ERPPickModel pickModel = new ERPPickModel() // { // Rowindex = OrderDetail.RowNo, // Material = OrderDetail.MaterielCode, // Qty = pickItemModel.Qty, // Dataitem = new List { pickItemModel } // }; // eRPPickModels.Add(pickModel); //}); //ERPIssueItemModel issueItemModel = new ERPIssueItemModel() //{ // Pickcode = outboundOrder.UpperOrderNo, // PickList = eRPPickModels //}; //ERPIssueModel issueModel = new ERPIssueModel() //{ // UniqueTag = outboundOrder.Id.ToString(), // Code = _outboundService.OutboundOrderService.CreateCodeByRule(nameof(RuleCodeEnum.FLCodeRule)), // WarehouseCode = warehouse.WarehouseCode, // Docremark = "", // Deptno = outboundOrder.DepartmentCode, // Deptname = outboundOrder.DepartmentName, // Createtime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), // Createuser = App.User.UserName, // Issitem = new List() { issueItemModel } //}; _invokeERPService.InvokeOutStandardsApi(_outboundService.OutboundOrderService.GetERPIssueModel(outboundOrder, warehouse.WarehouseCode)); } #endregion return WebResponseContent.Instance.OK(); } catch (Exception ex) { return WebResponseContent.Instance.Error(ex.Message); } } /// /// 生成出库任务后数据更新到数据库 /// /// /// /// /// /// /// public WebResponseContent GenerateOutboundTaskDataUpdate(List tasks, List? stockInfos = null, List? outboundOrderDetails = null, List? outStockLockInfos = null, List? locationInfos = null) { try { _unitOfWorkManage.BeginTran(); BaseDal.AddData(tasks); if (stockInfos != null && stockInfos.Count > 0 && outboundOrderDetails != null && outboundOrderDetails.Count > 0 && outStockLockInfos != null && outStockLockInfos.Count > 0 && locationInfos != null && locationInfos.Count > 0) { stockInfos.ForEach(x => { x.StockStatus = StockStatusEmun.出库锁定.ObjToInt(); }); outboundOrderDetails.ForEach(x => { x.OrderDetailStatus = OrderDetailStatusEnum.Outbound.ObjToInt(); }); Dt_OutboundOrder outboundOrder = _outboundRepository.OutboundOrderRepository.QueryFirst(x => x.Id == outboundOrderDetails.FirstOrDefault().OrderId); if (outboundOrder.OrderStatus != OutOrderStatusEnum.出库中.ObjToInt()) { _outboundRepository.OutboundOrderRepository.UpdateData(outboundOrder); } WebResponseContent content = _outboundService.OutboundOrderDetailService.LockOutboundStockDataUpdate(stockInfos, outboundOrderDetails, outStockLockInfos, locationInfos, tasks: tasks); if (!content.Status) { _unitOfWorkManage.RollbackTran(); return content; } } else if (outboundOrderDetails != null && outboundOrderDetails.Count > 0) { outboundOrderDetails.ForEach(x => { x.OrderDetailStatus = OrderDetailStatusEnum.Outbound.ObjToInt(); }); Dt_OutboundOrder outboundOrder = _outboundRepository.OutboundOrderRepository.QueryFirst(x=>x.Id== outboundOrderDetails.FirstOrDefault().OrderId); if (outboundOrder.OrderStatus!=OutOrderStatusEnum.出库中.ObjToInt()) { _outboundRepository.OutboundOrderRepository.UpdateData(outboundOrder); } _outboundService.OutboundOrderDetailService.Repository.UpdateData(outboundOrderDetails); } _unitOfWorkManage.CommitTran(); PushTasksToWCS(tasks); return WebResponseContent.Instance.OK(); } catch (Exception ex) { _unitOfWorkManage.RollbackTran(); return WebResponseContent.Instance.Error(ex.Message); } } /// /// 生成出库任务 /// /// 出库单明细主键 /// public WebResponseContent GenerateOutboundTasks(int[] keys) { try { List tasks = new List(); List stockSelectViews = new List(); List stockInfos = new List(); List outboundOrderDetails = new List(); List outStockLockInfos = new List(); List locationInfos = new List(); (List, List?, List?, List?, List?) result = OutboundTaskDataHandle(keys); if (result.Item2 != null && result.Item2.Count > 0) { stockInfos.AddRange(result.Item2); } if (result.Item3 != null && result.Item3.Count > 0) { outboundOrderDetails.AddRange(result.Item3); } if (result.Item4 != null && result.Item4.Count > 0) { outStockLockInfos.AddRange(result.Item4); } if (result.Item5 != null && result.Item5.Count > 0) { locationInfos.AddRange(result.Item5); } if (result.Item1 != null && result.Item1.Count > 0) { tasks.AddRange(result.Item1); } WebResponseContent content = GenerateOutboundTaskDataUpdate(tasks, stockInfos, outboundOrderDetails, outStockLockInfos, locationInfos); return content; } catch (Exception ex) { _unitOfWorkManage.RollbackTran(); return WebResponseContent.Instance.Error(ex.Message); } } /// /// 生成出库任务 /// /// 出库单主键 /// public WebResponseContent GenerateOutboundTaskByHeadId(int outboundId) { try { List keys = _outboundService.OutboundOrderDetailService.Repository.QueryData(x => x.Id, x => x.OrderId == outboundId); return GenerateOutboundTasks(keys.ToArray()); } catch (Exception ex) { _unitOfWorkManage.RollbackTran(); return WebResponseContent.Instance.Error(ex.Message); } } #region ///// ///// 生成出库任务 ///// ///// 出库单明细主键 ///// //public WebResponseContent MESPPGenerateOutboundTasks(int[] keys) //{ // try // { // List tasks = new List(); // List stockSelectViews = new List(); // List stockInfos = new List(); // List outboundOrderDetails = new List(); // List outStockLockInfos = new List(); // List locationInfos = new List(); // (List, List?, List?, List?, List?) result = MESPPOutboundTaskDataHandle(keys); // if (result.Item2 != null && result.Item2.Count > 0) // { // stockInfos.AddRange(result.Item2); // } // if (result.Item3 != null && result.Item3.Count > 0) // { // outboundOrderDetails.AddRange(result.Item3); // } // if (result.Item4 != null && result.Item4.Count > 0) // { // outStockLockInfos.AddRange(result.Item4); // } // if (result.Item5 != null && result.Item5.Count > 0) // { // locationInfos.AddRange(result.Item5); // } // if (result.Item1 != null && result.Item1.Count > 0) // { // tasks.AddRange(result.Item1); // } // WebResponseContent content = MESPPGenerateOutboundTaskDataUpdate(tasks, stockInfos, outboundOrderDetails, outStockLockInfos, locationInfos); // return content; // } // catch (Exception ex) // { // _unitOfWorkManage.RollbackTran(); // return WebResponseContent.Instance.Error(ex.Message); // } //} ///// ///// 出库任务数据处理 ///// ///// ///// ///// ///// //public (List, List?, List?, List?, List?) MESPPOutboundTaskDataHandle(int[] keys) //{ // List tasks = new List(); // List outboundOrderDetailss = _outboundService.MesPPOutboundOrderDetailService.Repository.QueryData(x => keys.Contains(x.Id)); // List outboundOrderDetails = BaseDal.Db.Queryable().Where(x => keys.Contains(x.Id)).ToList(); // if (outboundOrderDetails == null || outboundOrderDetails.Count == 0) // { // throw new Exception("未找到出库单明细信息"); // } // if (outboundOrderDetails.FirstOrDefault(x => x.OrderDetailStatus > OrderDetailStatusEnum.New.ObjToInt() && x.OrderDetailStatus != OrderDetailStatusEnum.AssignOverPartial.ObjToInt()) != null) // { // throw new Exception("所选出库单明细存在出库中或已完成"); // } // List? stockInfos = null; // List? orderDetails = null; // List? outStockLockInfos = null; // List? locationInfos = null; // //if (outboundOrderDetail.OrderDetailStatus == OrderDetailStatusEnum.New.ObjToInt()) // { // (List, List, List, List) result = _outboundService.MesPPOutboundOrderDetailService.AssignStockOutbound(outboundOrderDetails); // if (result.Item1 != null && result.Item1.Count > 0) // { // Dt_MesPPOutboundOrder outboundOrder = _outboundService.MesPPOutboundOrderService.Repository.QueryFirst(x => x.Id == outboundOrderDetails.FirstOrDefault().OrderId); // TaskTypeEnum typeEnum = outboundOrder.OrderType switch // { // (int)OutOrderTypeEnum.Issue => TaskTypeEnum.Outbound, // (int)OutOrderTypeEnum.Allocate => TaskTypeEnum.OutAllocate, // (int)OutOrderTypeEnum.Quality => TaskTypeEnum.OutQuality, // _ => new TaskTypeEnum() // }; // tasks = GetTasks(result.Item1, typeEnum); // result.Item2.ForEach(x => // { // x.OrderDetailStatus = OrderDetailStatusEnum.Outbound.ObjToInt(); // }); // result.Item3.ForEach(x => // { // x.Status = OutLockStockStatusEnum.出库中.ObjToInt(); // }); // stockInfos = result.Item1; // orderDetails = result.Item2; // outStockLockInfos = result.Item3; // locationInfos = result.Item4; // } // else // { // throw new Exception("无库存"); // } // } // //else // //{ // // List stockLockInfos = _outboundService.OutboundStockLockInfoService.GetByOrderDetailId(outboundOrderDetail.OrderId, OutLockStockStatusEnum.已分配); // // if (stockLockInfos != null && stockLockInfos.Count > 0) // // { // // List stocks = _stockService.StockInfoService.Repository.GetStockInfosByPalletCodes(stockLockInfos.Select(x => x.PalletCode).Distinct().ToList()); // // tasks = GetTasks(stocks); // // } // //} // return (tasks, stockInfos, orderDetails, outStockLockInfos, locationInfos); //} ///// ///// 生成出库任务后数据更新到数据库 ///// ///// ///// ///// ///// ///// ///// //public WebResponseContent MESPPGenerateOutboundTaskDataUpdate(List tasks, List? stockInfos = null, List? outboundOrderDetails = null, List? outStockLockInfos = null, List? locationInfos = null) //{ // try // { // _unitOfWorkManage.BeginTran(); // BaseDal.AddData(tasks); // if (stockInfos != null && stockInfos.Count > 0 && outboundOrderDetails != null && outboundOrderDetails.Count > 0 && outStockLockInfos != null && outStockLockInfos.Count > 0 && locationInfos != null && locationInfos.Count > 0) // { // stockInfos.ForEach(x => // { // x.StockStatus = StockStatusEmun.出库锁定.ObjToInt(); // }); // WebResponseContent content = _outboundService.MesPPOutboundOrderDetailService.LockOutboundStockDataUpdate(stockInfos, outboundOrderDetails, outStockLockInfos, locationInfos, tasks: tasks); // if (!content.Status) // { // _unitOfWorkManage.RollbackTran(); // return content; // } // } // else if (outboundOrderDetails != null && outboundOrderDetails.Count > 0) // { // outboundOrderDetails.ForEach(x => // { // x.OrderDetailStatus = OrderDetailStatusEnum.Outbound.ObjToInt(); // }); // _outboundService.MesPPOutboundOrderDetailService.Repository.UpdateData(outboundOrderDetails); // } // _unitOfWorkManage.CommitTran(); // PushTasksToWCS(tasks); // return WebResponseContent.Instance.OK(); // } // catch (Exception ex) // { // _unitOfWorkManage.RollbackTran(); // return WebResponseContent.Instance.Error(ex.Message); // } //} #endregion } }