using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; using WIDESEA_Core.Enums; using WIDESEA_Core; using WIDESEA_Model.Models; using WIDESEA_Core.Helper; using WIDESEAWCS_DTO.WCSInfo; using System.Transactions; using OfficeOpenXml.FormulaParsing.Excel.Functions.RefAndLookup; namespace WIDESEA_TaskInfoService { public partial class TaskService { /// /// PDA申请入库--堆垛机立库入库 /// /// 起始地址 /// 任务类型--入空,入料 /// 托盘编号 /// 返回处理结果 public WebResponseContent GenerateInboundTask(string stationCode, int taskType, string palletCode) { string? name = Enum.GetName(typeof(TaskTypeEnum), taskType); MethodInfo? methodInfo = GetType().GetMethod(name + "Request"); if (methodInfo != null) { WebResponseContent? responseContent = (WebResponseContent?)methodInfo.Invoke(this, new object[] { stationCode, palletCode }); if (responseContent != null) { return responseContent; } } else { return WebResponseContent.Instance.Error("未找到该任务类型业务"); } return WebResponseContent.Instance.Error("错误"); } /// /// 空托盘入库 /// /// 起始地址 /// 托盘编号 /// 返回处理结果 public WebResponseContent PalletInboundRequest(string stationCode, string palletCode) { WebResponseContent content = new WebResponseContent(); try { (bool, string) result = CheckRequestInbound(stationCode, palletCode, false); if (!result.Item1) return content = WebResponseContent.Instance.Error(result.Item2); content = AssignLocUpdateData(stationCode, TaskTypeEnum.PalletInbound.ObjToInt(), palletCode, false); } catch (Exception ex) { content = WebResponseContent.Instance.Error(ex.Message); } return content; } /// /// 物料入库 /// /// 起始地址 /// 托盘编号 /// 返回处理结果 public WebResponseContent InboundRequest(string stationCode, string palletCode) { WebResponseContent content = new WebResponseContent(); try { Dt_StockInfo stockInfo = _stockService.StockInfoService.Repository.GetStockInfo(palletCode); (bool, string) result = CheckRequestInbound(stationCode, palletCode, true, stockInfo); if (!result.Item1) return content = WebResponseContent.Instance.Error(result.Item2); content = AssignLocUpdateData(stationCode, TaskTypeEnum.Inbound.ObjToInt(), palletCode, true, stockInfo); } catch (Exception ex) { content = WebResponseContent.Instance.Error(ex.Message); } return content; } /// /// 入库分配货位及处理数据 /// /// 起始地址 /// 任务类型 /// 托盘编号 /// 是否更新组盘信息--区分物料入库和空托入库 /// 组盘信息--可空 /// 订单号--可空 /// 返回处理结果 private WebResponseContent AssignLocUpdateData(string stationCode, int taskType, string palletCode, bool isUpdateStock = true, Dt_StockInfo? stockInfo = null, string orderNo = "") { WebResponseContent content = new WebResponseContent(); try { Dt_LocationInfo? locationInfo = _basicService.LocationInfoService.AssignLocation(stationCode, taskType); if (locationInfo != null) { Dt_Task task = new() { CurrentAddress = stationCode, Grade = 0, PalletCode = palletCode, NextAddress = locationInfo.LocationCode, Roadway = locationInfo.RoadwayNo, SourceAddress = stationCode, TargetAddress = locationInfo.LocationCode, TaskState = InTaskStatusEnum.InNew.ObjToInt(), TaskType = taskType, }; BaseDal.AddData(task); int beforeStatus = locationInfo.LocationStatus; locationInfo.LocationStatus = LocationStatusEnum.PalletLock.ObjToInt(); if (isUpdateStock) { locationInfo.LocationStatus = LocationStatusEnum.OutLock.ObjToInt(); if (stockInfo != null && stockInfo.Details != null && stockInfo.Details.Count > 0) { orderNo = stockInfo.Details.FirstOrDefault()?.OrderNo ?? ""; stockInfo.StockStatus = StockStatusEmun.入库确认.ObjToInt(); _stockService.StockInfoService.Repository.UpdateData(stockInfo); } else { return content = WebResponseContent.Instance.Error("未找到库存信息"); } } _basicService.LocationInfoService.Repository.UpdateData(locationInfo); _recordService.LocationStatusChangeRecordSetvice.AddLocationStatusChangeRecord(locationInfo, beforeStatus, StockChangeType.Inbound.ObjToInt(), orderNo, task.TaskNum); return content = WebResponseContent.Instance.OK(); } return content = WebResponseContent.Instance.Error("未找到可分配货位"); } catch (Exception ex) { content = WebResponseContent.Instance.Error(ex.Message); } return content; } /// /// 堆垛机申请入库 /// /// /// public WebResponseContent StackerCraneRequestInbound(ConveyorLineDTO lineDTO) { WebResponseContent content = new WebResponseContent(); try { Dt_RoadwayInfo roadwayInfo = _basicRepository.RoadwayInfoRepository.QueryFirst(x => x.InStationCode == lineDTO.stationCode) ?? throw new Exception("未找到该站台对应的巷道,请检查基础配置信息"); if (roadwayInfo.EnableStatus != EnableStatusEnum.Normal.ObjToInt() && roadwayInfo.EnableStatus != EnableStatusEnum.OnlyIn.ObjToInt()) { throw new Exception("该巷道不可入库,请检查巷道禁用信息"); } if (roadwayInfo.AreaId > 0) { Dt_AreaInfo areaInfo = _basicRepository.AreaInfoRepository.QueryFirst(x => x.Id == roadwayInfo.AreaId); if (areaInfo != null && areaInfo.AreaStatus == EnableEnum.Disable.ObjToInt()) { throw new Exception("区域被禁用,不可入库"); } } var task = BaseDal.QueryFirst(x => x.PalletCode == lineDTO.Barcode); if (task == null) throw new Exception($"未找到托盘号[{lineDTO.Barcode}]的入库任务"); if (task.TaskState >= (int)InTaskStatusEnum.SC_InExecuting) throw new Exception($"托盘号[{lineDTO.Barcode}]的入库任务状态不匹配"); #region 判断是否为空托入库 if (task.TaskType == TaskTypeEnum.PalletInbound.ObjToInt()) return GetEmptyLocation(task); #endregion Dt_StockInfo stockInfo = _stockService.StockInfoService.Repository.GetStockInfo(lineDTO.Barcode); if (stockInfo == null) throw new Exception($"未找到托盘[{lineDTO.Barcode}]的组盘信息"); Dt_StockInfoDetail? stockInfoDetail = stockInfo.Details.Where(x => x.StockId == stockInfo.Id).FirstOrDefault(); if (stockInfoDetail == null) throw new Exception($"未找到托盘[{lineDTO.Barcode}]的组盘详情"); if (stockInfo.StockStatus != StockStatusEmun.入库确认.ObjToInt() || !string.IsNullOrEmpty(stockInfo.LocationCode)) throw new Exception($"托盘[{lineDTO.Barcode}],该组盘状态不可入库"); Dt_InboundOrder inboundOrder = _inboundService.InbounOrderService.GetInboundOrder(stockInfoDetail.OrderNo); if (inboundOrder == null) throw new Exception($"未找到托盘[{lineDTO.Barcode}]的入库单信息"); var BatchNo = stockInfoDetail.BatchNo; #region 判断是否指定货位 Dt_InboundOrderDetail? orderDetail = inboundOrder.Details.FirstOrDefault(x => x.BatchNo == stockInfoDetail.BatchNo); if (orderDetail == null) throw new Exception($"未找到托盘[{lineDTO.Barcode}]的入库单明细信息"); Dt_LocationInfo? locationInfo = null; if (!string.IsNullOrEmpty(orderDetail.LocationCode)) { locationInfo = _basicService.LocationInfoService.GetLocation(orderDetail.LocationCode); } #endregion else { #region 判断当前入库托盘批次号是否存在已分配入库 Dt_StockInfo? instockInfo = null; Dt_StockInfoDetail instockInfoDetail = _stockService.StockInfoDetailService.Get_StockInfoDetail(stockInfoDetail.OrderNo, stockInfoDetail.BatchNo); if (instockInfoDetail != null) instockInfo = _stockService.StockInfoService.Repository.GetStockInfo(instockInfoDetail.StockId); if (instockInfo != null) { locationInfo = _basicService.LocationInfoService.GetLocation(instockInfo.LocationCode); if (locationInfo?.MaxQty <= locationInfo?.CurrentQty) locationInfo = null; } #endregion else { instockInfoDetail = _stockService.StockInfoDetailService.Get_StockInfoDetail(stockInfoDetail.OrderNo /*BatchNo*/);//入库单存在库存,判断货位 if (instockInfoDetail != null) instockInfo = _stockService.StockInfoService.Repository.GetStockInfo(instockInfoDetail.StockId); if (instockInfo != null) { Dt_LocationInfo? location = _basicService.LocationInfoService.GetLocation(instockInfo.LocationCode);//查询已存在库存货位状态 if (location?.Row == 1) { var instockInfos = _stockService.StockInfoService.Repository.GetDt_StockInfos(instockInfo.LocationCode); List Details = new List(); foreach (var item in instockInfos) { Details.AddRange(item.Details); } var count = Details.GroupBy(x => x.BatchNo).Count(); if (count <= 1) locationInfo = location; } } } if (locationInfo == null)//分配新货位 { List inboundOrderDetailList = inboundOrder.Details.Where(x => /*x.BatchNo.Contains(BatchNo) &&*/ x.OverInQuantity == 0).ToList(); int inboundOrderCount = inboundOrderDetailList.Count; locationInfo = _basicService.LocationInfoService.AssignLocation(inboundOrderCount);//重新分配货位 } } if (locationInfo == null) throw new Exception($"无可入货位"); #region 修改库存及货位信息 task.TaskState = (int)InTaskStatusEnum.SC_InExecuting; task.CurrentAddress = task.NextAddress; task.NextAddress = locationInfo.LocationCode; task.TargetAddress = task.NextAddress; string[] targetCodes = task.NextAddress.Split("-"); var Row = Convert.ToInt16(targetCodes[0]); task.TargetIsPickPlace = /*Row > 1 ?*/ locationInfo.MaxQty - locationInfo.CurrentQty == 1; task.SourceIsPickPlace = false; stockInfo.LocationCode = locationInfo.LocationCode; stockInfo.StockStatus = StockStatusEmun.入库中.ObjToInt(); stockInfoDetail.Status = StockStatusEmun.入库中.ObjToInt(); locationInfo.CurrentQty++; orderDetail.OverInQuantity++; if (locationInfo.MaxQty < locationInfo.CurrentQty) throw new Exception(); /*if (locationInfo.MaxQty == 12)*/ locationInfo.EnableStatus = EnableStatusEnum.OnlyOut.ObjToInt(); locationInfo.LocationStatus = LocationStatusEnum.Inbounding.ObjToInt(); Db.Ado.BeginTran(); UpdateData(task); _stockService.StockInfoService.Repository.UpdateData(stockInfo); _inboundService.InboundOrderDetailService.Repository.UpdateData(orderDetail); _stockService.StockInfoDetailService.Repository.UpdateData(stockInfoDetail); _basicService.LocationInfoService.Repository.UpdateData(locationInfo); Db.Ado.CommitTran(); #endregion content.OK(data: new ReceiveWMSInfo() { TargetAddress = task.TargetAddress, SourceIsPickPlace = task.SourceIsPickPlace, TargetIsPickPlace = task.TargetIsPickPlace, }); } catch (Exception ex) { Db.Ado.RollbackTran(); content.Error(ex.Message); } return content; } /// /// 获取空托盘入库货位 /// /// /// public WebResponseContent GetEmptyLocation(Dt_Task task) { try { Dt_StockInfo stockInfo = _stockService.StockInfoService.Repository.GetStockInfo(task.PalletCode); if (stockInfo == null) throw new Exception($"未找到托盘[{task.PalletCode}]的组盘信息"); Dt_StockInfoDetail? stockInfoDetail = stockInfo.Details.Where(x => x.StockId == stockInfo.Id).FirstOrDefault(); if (stockInfoDetail == null) throw new Exception($"未找到托盘[{task.PalletCode}]的组盘详情"); if (stockInfo.StockStatus != StockStatusEmun.入库确认.ObjToInt() || !string.IsNullOrEmpty(stockInfo.LocationCode)) throw new Exception($"托盘[{task.PalletCode}],该组盘状态不可入库"); Dt_StockInfo? instockInfo = null; Dt_LocationInfo? locationInfo = null; string CarChargingStation = AppSettings.Configuration[nameof(CarChargingStation)];//获取穿梭车充电位置 var ChargingStations = CarChargingStation.Split(","); Dt_StockInfoDetail? instockInfoDetail = null; var instockInfoDetails = _stockService.StockInfoDetailService.Repository.QueryData(x => x.MaterielCode == stockInfoDetail.MaterielCode && x.Status == StockStatusEmun.入库中.ObjToInt()); if (instockInfoDetails.Count > 0) instockInfoDetail = instockInfoDetails.OrderByDescending(x => x.CreateDate).First(); if (instockInfoDetails.Count < 1) { instockInfoDetails = _stockService.StockInfoDetailService.Repository.QueryData(x => x.MaterielCode == stockInfoDetail.MaterielCode && x.Status == StockStatusEmun.已入库.ObjToInt()); if (instockInfoDetails.Count > 0) instockInfoDetail = instockInfoDetails.OrderByDescending(x => x.CreateDate).First(); } if (instockInfoDetail != null) instockInfo = _stockService.StockInfoService.Repository.GetStockInfo(instockInfoDetail.StockId); if (instockInfo != null)//无库存 { locationInfo = _basicRepository.LocationInfoRepository.QueryFirst(x => x.LocationCode == instockInfo.LocationCode); //if (BaseDal.QueryFirst(x => x.SourceAddress == locationInfo.LocationCode && x.TaskState < OutTaskStatusEnum.SC_OutFinish.ObjToInt()) != null) locationInfo = null; if (locationInfo != null && ChargingStations.Contains(locationInfo.LocationCode)) { if (locationInfo.MaxQty - locationInfo.CurrentQty <= 1) locationInfo = null; } else if (locationInfo != null && locationInfo.MaxQty - locationInfo.CurrentQty < 1) { locationInfo = null; } if (locationInfo == null) { var locationInfos = _basicService.LocationInfoService.GetLocationPallet(); foreach (var item in locationInfos) { if (BaseDal.QueryFirst(x => x.SourceAddress == item.LocationCode) == null) { locationInfo = item; break; } } } } //else //{ // locationInfo = _basicService.LocationInfoService.AssignLocation(ChargingStations);//查找穿梭车充电货位 //} if (locationInfo == null) locationInfo = _basicService.LocationInfoService.AssignLocation(2);//重新分配货位 if (locationInfo == null) throw new Exception($"无可入货位"); Dt_LocationInfo? locationInfo1 = null; if (locationInfo.Row == 1) { locationInfo1 = _basicService.LocationInfoService.Repository.QueryFirst(x => x.Row == 2 && x.Layer == locationInfo.Layer && x.Column == locationInfo.Column); locationInfo1.LocationStatus = LocationStatusEnum.Pallet.ObjToInt(); } task.TaskState = (int)InTaskStatusEnum.SC_InExecuting; task.CurrentAddress = task.NextAddress; task.NextAddress = locationInfo.LocationCode; task.TargetAddress = task.NextAddress; task.TargetIsPickPlace = locationInfo.Row > 1 ? locationInfo.MaxQty - locationInfo.CurrentQty == 1 : false; task.SourceIsPickPlace = false; stockInfo.LocationCode = locationInfo.LocationCode; stockInfo.StockStatus = StockStatusEmun.入库中.ObjToInt(); stockInfoDetail.Status = StockStatusEmun.入库中.ObjToInt(); locationInfo.CurrentQty++; if (locationInfo.MaxQty < locationInfo.CurrentQty) throw new Exception(); locationInfo.EnableStatus = EnableStatusEnum.OnlyOut.ObjToInt(); locationInfo.LocationStatus = LocationStatusEnum.Inbounding.ObjToInt(); Db.Ado.BeginTran(); UpdateData(task); _stockService.StockInfoService.Repository.UpdateData(stockInfo); _stockService.StockInfoDetailService.Repository.UpdateData(stockInfoDetail); _basicService.LocationInfoService.Repository.UpdateData(locationInfo); if (locationInfo1 != null) _basicService.LocationInfoService.Repository.UpdateData(locationInfo1); Db.Ado.CommitTran(); return WebResponseContent.Instance.OK(data: new ReceiveWMSInfo() { TargetAddress = task.TargetAddress, SourceIsPickPlace = task.SourceIsPickPlace, TargetIsPickPlace = task.TargetIsPickPlace, }); } catch (Exception ex) { Db.Ado.RollbackTran(); return WebResponseContent.Instance.Error(ex.Message); } } } }