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 Microsoft.AspNetCore.Http; using System.Reflection.Metadata; using OfficeOpenXml.FormulaParsing.Excel.Functions.RefAndLookup; using System.Diagnostics; using Newtonsoft.Json; using System.Security.Policy; using static WIDESEA_ITaskInfoService.ITaskService; using MailKit.Search; using WIDESEA_Common.Log; using OfficeOpenXml.FormulaParsing.Excel.Functions.DateTime; using WIDESEA_Common; using WIDESEA_DTO.Outbound; using WIDESEA_Core.Utilities; using System.Transactions; using Microsoft.Data.SqlClient; namespace WIDESEA_TaskInfoService { public partial class TaskService { public string ReceiveTask = WIDESEA_Core.Helper.AppSettings.Configuration["ReceiveTask"]; /// /// 库存数据转出库任务 /// /// /// public List GetTasks(List stockInfos) { 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); Dt_Task dt_Task = BaseDal.QueryFirst(x => x.SourceAddress == locationInfo.LocationCode || x.TargetAddress == locationInfo.LocationCode); if (dt_Task != null) { throw new Exception("该货位已存在起点任务或终点任务"); } Dt_Task dt_Task1 = BaseDal.QueryFirst(x => x.PalletCode == stockInfo.PalletCode); if (dt_Task1 != null) { throw new Exception("该托盘已存在任务"); } Dt_RoadwayInfo roadwayInfo = _basicService.RoadwayInfoService.Repository.QueryFirst(x => x.RoadwayNo == locationInfo.RoadwayNo); Dt_StockInfoDetail stockInfoDetail = _stockService.StockInfoDetailService.Repository.QueryFirst(x => x.StockId == stockInfo.Id); if (roadwayInfo != null) { Dt_Task task = new() { OrderNo = stockInfoDetail.OrderNo, CurrentAddress = "0", Grade = 0, Creater = "WMS", PalletCode = stockInfo.PalletCode, NextAddress = "", Roadway = locationInfo.RoadwayNo, SourceAddress = stockInfo.LocationCode, TargetAddress = roadwayInfo.OutStationCode, TaskStatus = OutTaskStatusEnum.OutNew.ObjToInt(), TaskType = TaskTypeEnum.Outbound.ObjToInt(), Depth = locationInfo.Depth, TaskNum = BaseDal.GetTaskNum(nameof(SequenceEnum.SeqTaskNum)) }; tasks.Add(task); //var responses = HttpHelper.Post(ReceiveTask, tasks, "立库出库数量回传WMS"); } } } BaseDal.AddData(tasks); 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.OrderId == 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) { tasks = GetTasks(result.Item1); int task = tasks[0].TaskNum; result.Item3.ForEach(x => { x.TaskNum = task; }); result.Item2.OrderDetailStatus = OrderDetailStatusEnum.Outbound.ObjToInt(); result.Item3.ForEach(x => { x.Status = OutStockStatus.出库中.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); 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, orderDetail == null ? null : new List { orderDetail }, outStockLockInfos, locationInfos); } /// /// 立库出库指令上传,出库任务下发 /// /// /// public WebResponseContent AddOutboundOrders(Houseounbound orderAddDTO) { WebResponseContent content = new(); try { OutboundOrderAddDTO orderAddDTO1 = new OutboundOrderAddDTO(); orderAddDTO1.OrderNo = orderAddDTO.No; orderAddDTO1.UpperOrderNo = orderAddDTO.No; orderAddDTO1.OutWareHouse = orderAddDTO.OutWareHouse; orderAddDTO1.TransactionCode = orderAddDTO.TransactionCode; orderAddDTO1.InoutType = orderAddDTO.OrderType; orderAddDTO1.OrderType = orderAddDTO.InoutType.ObjToInt(); IEnumerable inOrderTypes = Enum.GetValues().Cast(); //orderAddDTO1.OrderType = orderAddDTO.OrderType.ObjToInt(); orderAddDTO1.Details = orderAddDTO.DetailList.DicToIEnumerable(); #region 验证数据 (bool, string, object?) result = CheckOutboundOrderAddData(orderAddDTO1); if (!result.Item1) return content = WebResponseContent.Instance.Error(result.Item2); #endregion Dt_OutboundOrder inboundOrder = _mapper.Map(orderAddDTO1); inboundOrder.OrderStatus = InboundStatusEnum.未开始.ObjToInt(); inboundOrder.Creater = "WMS"; inboundOrder.CreateDate = DateTime.Now; Dt_OutboundOrder oldOutboundOrder = BaseDal.Db.Queryable().Where(x => x.UpperOrderNo == orderAddDTO1.OrderNo).Includes(x => x.Details).First(); Dt_OutboundOrderDetail outboundOrderDetail = _outboundService.OutboundOrderDetailService.Repository.QueryFirst(x => x.OrderId == oldOutboundOrder.Id); List stockSelectViews = new List(); StockSelectViewDTO stockSelectViewDTO = new() { OrderNo = orderAddDTO1.OrderNo, MaterielCode = outboundOrderDetail.MaterielCode, MaterielName = outboundOrderDetail.MaterielName, UseableQuantity = outboundOrderDetail.OrderQuantity, BatchNo = outboundOrderDetail.BatchNo, LinId = outboundOrderDetail.LinId, PalletCode = outboundOrderDetail.LPNNo, }; _unitOfWorkManage.BeginTran(); bool a = BaseDal.Db.InsertNav(inboundOrder).Include(x => x.Details).ExecuteCommand(); stockSelectViews.Add(stockSelectViewDTO); GenerateOutboundTasks(oldOutboundOrder.Id, stockSelectViews); _unitOfWorkManage.CommitTran(); content = WebResponseContent.Instance.OK(); } catch (Exception ex) { _unitOfWorkManage.RollbackTran(); content = WebResponseContent.Instance.Error(ex.Message); } return content; } /// /// 盘点任务上传立库 /// /// public WebResponseContent InventoryOut(HouseCancelOut houseInventoryOut) { WebResponseContent content = new(); try { OutboundOrderAddDTO orderAddDTO1 = new OutboundOrderAddDTO(); orderAddDTO1.OrderNo = houseInventoryOut.No; orderAddDTO1.UpperOrderNo = houseInventoryOut.No; orderAddDTO1.Details = houseInventoryOut.DetailList.DicToIEnumerable(); #region 验证数据 (bool, string, object?) result = CheckOutboundOrderAddData(orderAddDTO1); if (!result.Item1) return content = WebResponseContent.Instance.Error(result.Item2); #endregion Dt_OutboundOrder inboundOrder = _mapper.Map(orderAddDTO1); inboundOrder.OrderStatus = InboundStatusEnum.未开始.ObjToInt(); inboundOrder.OrderType = OutOrderTypeEnum.OutInventory.ObjToInt(); inboundOrder.Creater = "WMS"; inboundOrder.CreateDate = DateTime.Now; Dt_OutboundOrder oldOutboundOrder = BaseDal.Db.Queryable().Where(x => x.OrderNo == orderAddDTO1.OrderNo).Includes(x => x.Details).First(); Dt_OutboundOrderDetail outboundOrderDetail = _outboundService.OutboundOrderDetailService.Repository.QueryFirst(x => x.OrderId == oldOutboundOrder.Id); List stockSelectViews = new List(); StockSelectViewDTO stockSelectViewDTO = new() { OrderNo = orderAddDTO1.OrderNo, MaterielCode = outboundOrderDetail.MaterielCode, MaterielName = outboundOrderDetail.MaterielName, UseableQuantity = outboundOrderDetail.OrderQuantity, BatchNo = outboundOrderDetail.BatchNo, LinId = outboundOrderDetail.LinId, }; _unitOfWorkManage.BeginTran(); bool a = BaseDal.Db.InsertNav(inboundOrder).Include(x => x.Details).ExecuteCommand(); stockSelectViews.Add(stockSelectViewDTO); GenerateOutboundTasks(oldOutboundOrder.Id, stockSelectViews); _unitOfWorkManage.CommitTran(); content = WebResponseContent.Instance.OK(); } catch (Exception ex) { _unitOfWorkManage.RollbackTran(); content = WebResponseContent.Instance.Error(ex.Message); } finally { } return content; } private (bool, string, object?) CheckOutboundOrderAddData(OutboundOrderAddDTO outboundOrderAddDTO) { (bool, string, object?) result1 = ModelValidate.ValidateModelData(outboundOrderAddDTO); if (!result1.Item1) return result1; (bool, string, object?) result2 = ModelValidate.ValidateModelData(outboundOrderAddDTO.Details); if (!result2.Item1) return result2; IEnumerable inOrderTypes = Enum.GetValues().Cast(); if (!inOrderTypes.Contains(outboundOrderAddDTO.OrderType)) { return (false, "未找到该单据类型", outboundOrderAddDTO); } //List materielCodes = outboundOrderAddDTO.Details.Select(x => x.MaterielCode).ToList(); //if (!_materielInfoService.ExsitMateriels(materielCodes)) //{ // return (false, "有物料信息未录入,请录入物料信息", outboundOrderAddDTO); //} Dt_OutboundOrder dt_OutboundOrder = _outboundService.OutboundOrderService.Repository.QueryFirst(x => x.UpperOrderNo == outboundOrderAddDTO.UpperOrderNo && !string.IsNullOrEmpty(x.UpperOrderNo)); if (dt_OutboundOrder != null) { return (false, "单据已存在", outboundOrderAddDTO); } return (true, "成功", outboundOrderAddDTO); } 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 GenerateOutboundTasks(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) { throw new Exception(ex.Message); } } /// /// 生成出库任务后数据更新到数据库 /// /// /// /// /// /// /// public WebResponseContent GenerateOutboundTaskDataUpdate(List tasks, List? stockInfos = null, List? outboundOrderDetails = null, List? outStockLockInfos = null, List? locationInfos = null) { try { WebResponseContent content = new WebResponseContent(); _unitOfWorkManage.BeginTran(); //判断移库 //content = RelocationTasks(tasks.OrderBy(x => x.Depth).ToList()); //if (content.Status) //{ // _unitOfWorkManage.CommitTran(); //} //else //{ // _unitOfWorkManage.RollbackTran(); // return content; //} //BaseDal.AddData(tasks); if (stockInfos != null && outboundOrderDetails != null && outStockLockInfos != null && locationInfos != null) { content = _outboundService.OutboundOrderDetailService.LockOutboundStockDataUpdate(stockInfos, outboundOrderDetails, outStockLockInfos, locationInfos, tasks: tasks); if (content.Status) { _unitOfWorkManage.CommitTran(); } else { _unitOfWorkManage.RollbackTran(); } return content; } else if (outboundOrderDetails != null && outboundOrderDetails.Count > 0) { outboundOrderDetails.ForEach(x => { x.OrderDetailStatus = OrderDetailStatusEnum.Outbound.ObjToInt(); }); _outboundService.OutboundOrderDetailService.Repository.UpdateData(outboundOrderDetails); } _unitOfWorkManage.CommitTran(); return WebResponseContent.Instance.OK(); } catch (Exception ex) { _unitOfWorkManage.RollbackTran(); return WebResponseContent.Instance.Error(ex.Message); } } /// /// 判断巷道内移库 /// /// /// /// public WebResponseContent IsRelocations(int TaskNum, string SourceAddress) { try { WebResponseContent content = new WebResponseContent(); List loca = new List(); Dt_Task task = BaseDal.QueryFirst(x => x.TaskNum == TaskNum); if (task == null) { return content = WebResponseContent.Instance.Error($"未找到该任务信息,任务号:{TaskNum}"); } else { //判断是否需要移库 string[] targetCodes = SourceAddress.Split("-"); if (targetCodes[1] == "001") { targetCodes[1] = "002"; } else if (targetCodes[1] == "004") { targetCodes[1] = "003"; } else { return content = WebResponseContent.Instance.Error($"货位解析失败,货位编号:{SourceAddress}"); } targetCodes[4] = "01"; string LocationCode = string.Join("-", targetCodes); //组装浅库位地址 Dt_LocationInfo locationInfos = _basicService.LocationInfoService.Repository.QueryFirst(x => x.LocationCode == LocationCode && (x.LocationStatus == (int)LocationStatusEnum.Free || x.LocationStatus == (int)LocationStatusEnum.InStock)); if (locationInfos == null) { return content = WebResponseContent.Instance.Error($"未找到该货位信息,货位编号:{locationInfos}"); } else { if (locationInfos.LocationStatus == (int)LocationStatusEnum.Free) //判断浅货位是否有货 { return content = WebResponseContent.Instance.OK(); } else { Dt_StockInfo dt_StockInfo = _stockService.StockInfoService.Repository.QueryFirst(x => x.LocationCode == LocationCode && x.StockStatus == (int)StockStatusEmun.已入库); if (dt_StockInfo == null) { return content = WebResponseContent.Instance.Error($"未找到该货位的库存信息,货位编号:{LocationCode}"); } else { Dt_LocationInfo newLocation; //查走货位,进行生成移库任务 int Locationtype = 9; //默认为9 if (dt_StockInfo.MaterialType == (int)InventoryMaterialType.成品) { Locationtype = 11; } else if (dt_StockInfo.MaterialType == (int)InventoryMaterialType.原材料) { Locationtype = 10; } newLocation = _basicService.LocationInfoService.GetLocation(locationInfos.RoadwayNo, Locationtype); //拿到了移库后的货位 if (dt_StockInfo.MaterialType == (int)InventoryMaterialType.成品) { string[] targetCodesst = dt_StockInfo.PalletCode.Split("*"); //Dt_InboundOrder dt_Inbound = _inboundService.InbounOrderService.Repository.QueryFirst(x => x.OrderName == targetCodesst[0]); //if (dt_Inbound.Startingcolumn != 0 || dt_Inbound.Terminationcolumn != 0) //{ // newLocation = _basicService.LocationInfoService.GetLocation2(locationInfos.RoadwayNo, Locationtype, dt_Inbound.Startingcolumn, dt_Inbound.Terminationcolumn); //} //else //{ // newLocation = _basicService.LocationInfoService.GetLocation(locationInfos.RoadwayNo, Locationtype); //} } else { newLocation = _basicService.LocationInfoService.GetLocation(locationInfos.RoadwayNo, Locationtype); } if (newLocation != null) { Dt_Task dt_Task = new() { PalletCode = dt_StockInfo.PalletCode, Roadway = locationInfos.RoadwayNo, TaskType = TaskTypeEnum.RelocationIn.ObjToInt(), TaskStatus = OutTaskStatusEnum.OutNew.ObjToInt(), SourceAddress = locationInfos.LocationCode, TargetAddress = newLocation.LocationCode, CurrentAddress = locationInfos.LocationCode, NextAddress = newLocation.LocationCode, Grade = 2, Creater = "WMS", CreateDate = DateTime.Now, TaskNum = BaseDal.GetTaskNum(nameof(SequenceEnum.SeqTaskNum)), MaterialType = dt_StockInfo.MaterialType }; _unitOfWorkManage.BeginTran(); if (locationInfos.LocationStatus == LocationStatusEnum.InStock.ObjToInt()) { locationInfos.LocationStatus = LocationStatusEnum.Lock.ObjToInt(); newLocation.LocationStatus = LocationStatusEnum.Lock.ObjToInt(); } else if (locationInfos.LocationStatus == LocationStatusEnum.Pallet.ObjToInt()) { locationInfos.LocationStatus = LocationStatusEnum.PalletLock.ObjToInt(); newLocation.LocationStatus = LocationStatusEnum.PalletLock.ObjToInt(); } loca.Add(newLocation); loca.Add(locationInfos); _basicService.LocationInfoService.UpdateData(loca); _unitOfWorkManage.CommitTran(); return content = WebResponseContent.Instance.OK(data: dt_Task); } else { return content = WebResponseContent.Instance.Error($"未找到巷道内可移库的货位"); } } } } } } catch (Exception ex) { _unitOfWorkManage.RollbackTran(); throw; } } public string ReceiveWMSTask = WIDESEA_Core.Helper.AppSettings.Configuration["ReceiveWMSTask"]; /// /// 生成出库任务 /// /// /// public WebResponseContent GenerateOutboundTask(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(); foreach (int key in keys) { (List, List?, List?, List?, List?) result = OutboundTaskDataHandle(key, stockSelectViews); 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 Cancelinventory(int taskNum) { WebResponseContent content = new WebResponseContent(); Dt_Task task = BaseDal.QueryFirst(x => x.TaskNum == taskNum); if (task != null) { if (task.TaskType == (int)TaskTypeEnum.Outbound || task.TaskType == (int)TaskTypeEnum.PalletOutbound) { //处理出库的逻辑 Dt_LocationInfo locationinfo = _basicService.LocationInfoService.Repository.QueryFirst(x => x.LocationCode == task.SourceAddress); if (locationinfo.LocationStatus == LocationStatusEnum.Lock.ObjToInt()) { locationinfo.LocationStatus = LocationStatusEnum.InStock.ObjToInt(); } if (locationinfo.LocationStatus == LocationStatusEnum.PalletLock.ObjToInt()) { locationinfo.LocationStatus = LocationStatusEnum.Pallet.ObjToInt(); } _basicService.LocationInfoService.Repository.UpdateData(locationinfo); Dt_StockInfo stockInfo = _stockService.StockInfoService.Repository.QueryFirst(x => x.PalletCode == task.PalletCode); stockInfo.StockStatus = (int)StockStatusEmun.已入库; _stockService.StockInfoService.Repository.UpdateData(stockInfo); Dt_StockInfoDetail stocktdetail = _stockService.StockInfoDetailService.Repository.QueryFirst(x => x.StockId == stockInfo.Id); if (stocktdetail != null) { stocktdetail.Status = (int)StockStatusEmun.已入库; _stockService.StockInfoDetailService.Repository.UpdateData(stocktdetail); } BaseDal.DeleteData(task); BaseDal.DeleteAndMoveIntoHty(task, OperateType.人工删除); WriteLog.GetLog("任务日志").Write($"出库任务取消成功,托盘条码:{task.PalletCode}", $"任务取消"); return content = WebResponseContent.Instance.Error($"出库任务取消成功"); } else if (task.TaskType == (int)TaskTypeEnum.Inbound || task.TaskType == (int)TaskTypeEnum.PalletInbound) { //处理出库的逻辑 Dt_LocationInfo locationinfo = _basicService.LocationInfoService.Repository.QueryFirst(x => x.LocationCode == task.TargetAddress); if (locationinfo.LocationStatus == LocationStatusEnum.Lock.ObjToInt() || locationinfo.LocationStatus == LocationStatusEnum.PalletLock.ObjToInt()) { locationinfo.LocationStatus = LocationStatusEnum.Free.ObjToInt(); } _basicService.LocationInfoService.Repository.UpdateData(locationinfo); Dt_StockInfo stockInfo = _stockService.StockInfoService.Repository.QueryFirst(x => x.PalletCode == task.PalletCode); _stockService.StockInfoService.Repository.DeleteData(stockInfo); Dt_StockInfoDetail stocktdetail = _stockService.StockInfoDetailService.Repository.QueryFirst(x => x.StockId == stockInfo.Id); if (stocktdetail != null) { _stockService.StockInfoDetailService.Repository.DeleteData(stocktdetail); } BaseDal.DeleteData(task); BaseDal.DeleteAndMoveIntoHty(task, OperateType.人工删除); WriteLog.GetLog("任务日志").Write($"入库任务取消成功,托盘条码:{task.PalletCode}", $"任务取消"); return content = WebResponseContent.Instance.Error($"入库任务取消成功"); } else { return content = WebResponseContent.Instance.Error($"该任务的任务类型异常,取消失败"); } } else { return content = WebResponseContent.Instance.Error($"未找到任务号"); } } } }