ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/views/outbound/PickingConfirm.vue
@@ -935,21 +935,16 @@ if (res.status) { successCount++; this.$message.success(`æååæ¶`); } else { errorCount++; console.error(`åæ¶æ£é失败: ${row.Barcode}`, res.message); this.$message.warning(`åæ¶æ£é失败: ${row.currentBarcode} - ${res.message}`); } } catch (error) { errorCount++; console.error(`åæ¶æ£é失败: ${row.Barcode}`, error); this.$message.warning(`åæ¶æ£é失败: ${row.currentBarcode} - ${error.message}` ); } } if (errorCount === 0) { this.$message.success(`æååæ¶ ${successCount} 项`); } else { this.$message.warning(`æååæ¶ ${successCount} 项ï¼å¤±è´¥ ${errorCount} 项`); } } this.loadData(); this.selectedPickedRows = []; ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_BasicService/InvokeMESService.cs
@@ -103,7 +103,7 @@ return JsonConvert.DeserializeObject<ResponseModel>(body); } public async Task<ResponseModel> FeedbackAllocate(AllocateDto model) public async Task<ResponseModel> FeedbackAllocate(AllocateDto model) { string json = JsonConvert.SerializeObject(model, new JsonSerializerSettings { ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundOrderDetailService.cs
@@ -21,9 +21,9 @@ private readonly IUnitOfWorkManage _unitOfWorkManage; public IRepository<Dt_OutboundOrderDetail> Repository => BaseDal; private readonly IStockService _stockService; private readonly IOutStockLockInfoService _outStockLockInfoService; private readonly ILocationInfoService _locationInfoService; private readonly IBasicService _basicService; @@ -68,16 +68,16 @@ List<Dt_OutStockLockInfo> outStockLockInfos = new List<Dt_OutStockLockInfo>(); List<Dt_LocationInfo> locationInfos = new List<Dt_LocationInfo>(); // æç©æåæ¹æ¬¡åç»å¤ç // æç©æãæ¹æ¬¡ãä¾åºååç» var groupDetails = outboundOrderDetails .GroupBy(x => new { x.MaterielCode, x.BatchNo ,x.SupplyCode}) .GroupBy(x => new { x.MaterielCode, x.BatchNo, x.SupplyCode }) .Select(x => new { MaterielCode = x.Key.MaterielCode, BatchNo = x.Key.BatchNo, SupplyCode = x.Key.SupplyCode, x.Key.MaterielCode, x.Key.BatchNo, x.Key.SupplyCode, Details = x.ToList(), TotalNeedQuantity = x.Sum(v => v.OrderQuantity - v.OverOutQuantity - v.LockQuantity-v.MoveQty) TotalNeedQuantity = x.Sum(v => v.OrderQuantity - v.OverOutQuantity - v.LockQuantity - v.MoveQty) }) .Where(x => x.TotalNeedQuantity > 0) .ToList(); @@ -86,125 +86,98 @@ { var needQuantity = item.TotalNeedQuantity; // è·åå¯ç¨åºåï¼æå è¿å åºæåºï¼ List<Dt_StockInfo> stockInfos = _stockService.StockInfoService.GetUseableStocks(item.MaterielCode, item.BatchNo,item.SupplyCode); // è·åå¯ç¨åºåï¼å·²æå è¿å åºæåºï¼ List<Dt_StockInfo> stockInfos = _stockService.StockInfoService.GetUseableStocks( item.MaterielCode, item.BatchNo, item.SupplyCode); if (!stockInfos.Any()) { throw new Exception($"ç©æ[{item.MaterielCode}]æ¹æ¬¡[{item.BatchNo}]æªæ¾å°å¯åé åºå"); } // åé åºåï¼æå è¿å åºï¼ // åé åºå var (autoAssignStocks, stockAllocations) = _stockService.StockInfoService.GetOutboundStocks( stockInfos, item.MaterielCode, needQuantity, out decimal residueQuantity); if (residueQuantity > 0 && residueQuantity == needQuantity) // æ£æ¥åé ç»æ if (residueQuantity > 0) { throw new Exception($"ç©æ[{item.MaterielCode}]åºåä¸è¶³ï¼éè¦{needQuantity}ï¼å¯ç¨{needQuantity - residueQuantity}"); var allocatedQuantity = needQuantity - residueQuantity; throw new Exception($"ç©æ[{item.MaterielCode}]åºåä¸è¶³ï¼éè¦{needQuantity}ï¼å®é åé {allocatedQuantity}"); } outStocks.AddRange(autoAssignStocks); // æå è¿å åºåååé é宿°éå°å个æç» DistributeLockQuantityByFIFO(item.Details, autoAssignStocks, stockAllocations, outStockLockInfos, outboundOrder); // æå è¿å åºåé é宿°é DistributeLockQuantityByFIFO(item.Details, autoAssignStocks, stockAllocations, outStockLockInfos, outboundOrder); } locationInfos.AddRange(_locationInfoService.GetLocationInfos(outStocks.Select(x => x.LocationCode).Distinct().ToList())); locationInfos.AddRange(_locationInfoService.GetLocationInfos( outStocks.Select(x => x.LocationCode).Distinct().ToList())); return (outStocks, outboundOrderDetails, outStockLockInfos, locationInfos); } /// <summary> /// æå è¿å åºåååé é宿°éå°å个æç» /// </summary> private void DistributeLockQuantityByFIFO( List<Dt_OutboundOrderDetail> details, List<Dt_StockInfo> assignStocks, Dictionary<int, decimal> stockAllocations, List<Dt_OutStockLockInfo> outStockLockInfos, Dt_OutboundOrder outboundOrder) private void DistributeLockQuantityByFIFO(List<Dt_OutboundOrderDetail> details,List<Dt_StockInfo> assignStocks,Dictionary<int, decimal> stockAllocations,List<Dt_OutStockLockInfo> outStockLockInfos, Dt_OutboundOrder outboundOrder) { // æå è¿å åºæåºåºåºåæç»ï¼å设å å建çæç»éè¦ä¼å æ»¡è¶³ï¼ var sortedDetails = details .Where(d => d.OrderQuantity - d.OverOutQuantity - d.LockQuantity -d.MoveQty> 0) // åªå¤çè¿éè¦åé çæ°é .OrderBy(x => x.Id) .ToList(); var sortedStocks = assignStocks.OrderBy(x => x.CreateDate).ToList(); var totalNeedQuantity = details.Sum(d => d.OrderQuantity - d.OverOutQuantity - d.LockQuantity - d.MoveQty); decimal allocatedQuantity = 0; if (!sortedDetails.Any()) return; // è·åææåé äºåºåçæç»ï¼æå è¿å åºæåº var allocatedStockDetails = assignStocks .SelectMany(x => x.Details) .Where(x => stockAllocations.ContainsKey(x.Id)) .OrderBy(x => x.CreateDate) .ThenBy(x => x.StockId) .ToList(); // 为æ¯ä¸ªåºåæç»å建åé è®°å½ foreach (var stockDetail in allocatedStockDetails) foreach (var stock in sortedStocks) { if (!stockAllocations.TryGetValue(stockDetail.Id, out decimal allocatedQuantity)) if (allocatedQuantity >= totalNeedQuantity) break; if (!stockAllocations.TryGetValue(stock.Id, out decimal stockAllocation) || stockAllocation <= 0) continue; if (allocatedQuantity <= 0) continue; var sortedDetails = details .Where(d => d.OrderQuantity - d.OverOutQuantity - d.LockQuantity - d.MoveQty > 0) .OrderBy(x => x.Id) .ToList(); var stockInfo = assignStocks.First(x => x.Id == stockDetail.StockId); decimal remainingAllocate = allocatedQuantity; // æé¡ºåºåé ç»å个åºåºåæç» foreach (var detail in sortedDetails) { if (remainingAllocate <= 0) break; if (stockAllocation <= 0) break; // 计ç®è¿ä¸ªæç»è¿éè¦åé çæ°é var detailNeed = detail.OrderQuantity - detail.OverOutQuantity - detail.LockQuantity-detail.MoveQty; var detailNeed = detail.OrderQuantity - detail.OverOutQuantity - detail.LockQuantity - detail.MoveQty; if (detailNeed <= 0) continue; // åé æ°é var assignQuantity = Math.Min(remainingAllocate, detailNeed); var assignQuantity = Math.Min(stockAllocation, detailNeed); // éªè¯æ¡ç æ¯å¦åå¨ if (string.IsNullOrEmpty(stockDetail.Barcode)) // 使ç¨åºåä¸çæææ¡ç var barcode = stock.Details .Where(d => !string.IsNullOrEmpty(d.Barcode)) .Select(d => d.Barcode) .FirstOrDefault(); if (string.IsNullOrEmpty(barcode)) { throw new Exception($"åºåæç»ID[{stockDetail.Id}]çæ¡ç 为空"); throw new Exception($"åºåID[{stock.Id}]çæ¡ç 为空"); } // å建åºåºéå®ä¿¡æ¯ var lockInfo = _outStockLockInfoService.GetOutStockLockInfo( outboundOrder, detail, stockInfo, assignQuantity, stockDetail.Barcode); outboundOrder, detail, stock, assignQuantity, barcode); outStockLockInfos.Add(lockInfo); // æ´æ°æç»çé宿°é detail.LockQuantity += assignQuantity; remainingAllocate -= assignQuantity; stockAllocation -= assignQuantity; allocatedQuantity += assignQuantity; if (allocatedQuantity >= totalNeedQuantity) break; } } // å¦æè¿æå©ä½åé æ°éï¼éæ°åé æè®°å½è¦å if (remainingAllocate > 0) { // éæ°åé ç»å ¶ä»éè¦åé çæç» foreach (var detail in sortedDetails) { if (remainingAllocate <= 0) break; var detailNeed = detail.OrderQuantity - detail.OverOutQuantity - detail.LockQuantity; if (detailNeed <= 0) continue; var assignQuantity = Math.Min(remainingAllocate, detailNeed); var lockInfo = _outStockLockInfoService.GetOutStockLockInfo( outboundOrder, detail, stockInfo, assignQuantity, stockDetail.Barcode); outStockLockInfos.Add(lockInfo); detail.LockQuantity += assignQuantity; remainingAllocate -= assignQuantity; } // å¦æè¿æå©ä½ï¼è®°å½è¦åä½ä¸æåºå¼å¸¸ if (remainingAllocate > 0) { _logger.LogWarning($"åºååé å仿å©ä½æ°éæªåé : {remainingAllocate}, æ¡ç : {stockDetail.Barcode}"); } } // éªè¯æ¯å¦å®å ¨åé if (allocatedQuantity < totalNeedQuantity) { _logger.LogWarning($"åºååé ä¸å®å ¨ï¼éè¦{totalNeedQuantity}ï¼å®é åé {allocatedQuantity}"); } } @@ -218,8 +191,8 @@ /// <param name="locationStatus"></param> /// <param name="tasks"></param> /// <returns></returns> public WebResponseContent LockOutboundStockDataUpdate(List<Dt_StockInfo> stockInfos, List<Dt_OutboundOrderDetail> outboundOrderDetails, List<Dt_OutStockLockInfo> outStockLockInfos, List<Dt_LocationInfo> locationInfos, public WebResponseContent LockOutboundStockDataUpdate(List<Dt_StockInfo> stockInfos, List<Dt_OutboundOrderDetail> outboundOrderDetails, List<Dt_OutStockLockInfo> outStockLockInfos, List<Dt_LocationInfo> locationInfos, LocationStatusEnum locationStatus = LocationStatusEnum.Lock, List<Dt_Task>? tasks = null) { try @@ -227,7 +200,7 @@ // æ´æ°åºåç¶æ stockInfos.ForEach(x => x.StockStatus = (int)StockStatusEmun.åºåºéå®); _stockService.StockInfoService.Repository.UpdateData(stockInfos); // æ´æ°åºåæç» var stockDetails = stockInfos.SelectMany(x => x.Details).ToList(); _stockService.StockInfoDetailService.Repository.UpdateData(stockDetails); @@ -280,16 +253,16 @@ SearchParameters? searchParameters = searchParametersList.FirstOrDefault(x => x.Name == nameof(Dt_InboundOrderDetail.OrderId).FirstLetterToLower()); if (searchParameters != null) { sugarQueryable1 = sugarQueryable1.Where(x => x.OrderId== searchParameters.Value.ObjToInt()); var dataList = sugarQueryable1.ToPageList(options.Page, options.Rows, ref totalCount); sugarQueryable1 = sugarQueryable1.Where(x => x.OrderId == searchParameters.Value.ObjToInt()); var dataList = sugarQueryable1.ToPageList(options.Page, options.Rows, ref totalCount); return new PageGridData<Dt_OutboundOrderDetail>(totalCount, dataList); } } } } return new PageGridData<Dt_OutboundOrderDetail> (); return new PageGridData<Dt_OutboundOrderDetail>(); } @@ -299,12 +272,12 @@ if (!checkResult.Item1) throw new Exception(checkResult.Item2); Dt_OutboundOrder outboundOrder = _outboundOrderService.Repository.QueryFirst(x => x.Id == outboundOrderDetail.OrderId); var originalNeedQuantity = outboundOrderDetail.OrderQuantity - outboundOrderDetail.LockQuantity-outboundOrderDetail.MoveQty; var originalNeedQuantity = outboundOrderDetail.OrderQuantity - outboundOrderDetail.LockQuantity - outboundOrderDetail.MoveQty; var needQuantity = originalNeedQuantity; List<Dt_StockInfo> outStocks = _stockService.StockInfoService.GetStockInfosByPalletCodes(stockSelectViews.Select(x => x.PalletCode).ToList()); var assignQuantity =0m; var assignQuantity = 0m; outStocks.ForEach(x => { x.Details.ForEach(v => @@ -324,9 +297,9 @@ needQuantity -= assignQuantity; if (outboundOrderDetail.OrderQuantity > outboundOrderDetail.LockQuantity) { List<Dt_StockInfo> stockInfos = _stockService.StockInfoService.GetUseableStocks(outboundOrderDetail.MaterielCode, outboundOrderDetail.BatchNo,""); List<Dt_StockInfo> stockInfos = _stockService.StockInfoService.GetUseableStocks(outboundOrderDetail.MaterielCode, outboundOrderDetail.BatchNo, ""); stockInfos = stockInfos.Where(x => !stockSelectViews.Select(v => v.PalletCode).Contains(x.PalletCode)).ToList(); var (autoAssignStocks, stockAllocations) = _stockService.StockInfoService.GetOutboundStocks(stockInfos, outboundOrderDetail.MaterielCode, needQuantity, out decimal residueQuantity); var (autoAssignStocks, stockAllocations) = _stockService.StockInfoService.GetOutboundStocks(stockInfos, outboundOrderDetail.MaterielCode, needQuantity, out decimal residueQuantity); outboundOrderDetail.LockQuantity += needQuantity - residueQuantity; outStocks.AddRange(autoAssignStocks); outboundOrderDetail.OrderDetailStatus = OrderDetailStatusEnum.AssignOver.ObjToInt(); ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundPickingService.cs
@@ -293,14 +293,15 @@ _unitOfWorkManage.CommitTran(); // å建ååºä»»å¡ await CreateReturnTaskAndHandleESS(orderNo, palletCode, task, TaskTypeEnum.InPick); await CreateReturnTaskAndHandleESS(orderNo, palletCode, task, TaskTypeEnum.InPick,task.PalletType); // æ´æ°è®¢åç¶æï¼ä¸è§¦åMESåä¼ ï¼ await UpdateOrderStatusForReturn(orderNo); return WebResponseContent.Instance.OK($"ååºæä½æåï¼å ±ååºæ°éï¼{statusAnalysis.TotalReturnQty}"); return WebResponseContent.Instance.OK($"ååºæä½æå"); //return WebResponseContent.Instance.OK($"ååºæä½æåï¼å ±ååºæ°éï¼{statusAnalysis.TotalReturnQty}"); } catch (Exception ex) { @@ -616,7 +617,7 @@ result.FinalBarcode = newBarcode; result.SplitResults.AddRange(CreateSplitResults(lockInfo, actualQty, remainingStockQty, newBarcode, stockDetail.Barcode)); _logger.LogInformation($"æå 忣宿 - OrderDetailId: {lockInfo.OrderDetailId}, 忣æ°é: {actualQty}"); } @@ -1037,7 +1038,7 @@ return task; } private async Task<decimal> CalculateSplitReturnQuantity(List<Dt_SplitPackageRecord> splitRecords, int stockId) { decimal totalQty = 0; @@ -1045,11 +1046,14 @@ foreach (var splitRecord in splitRecords) { if (splitRecord.Status != (int)SplitPackageStatusEnum.å·²æ¤é) continue; // æ£æ¥åæ¡ç if (!processedBarcodes.Contains(splitRecord.OriginalBarcode)) { var originalStock = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>() .Where(it => it.Barcode == splitRecord.OriginalBarcode && it.StockId == stockId) .Where(it => it.Barcode == splitRecord.OriginalBarcode && it.StockId == stockId && it.Status != StockStatusEmun.åºåºå®æ.ObjToInt()) .FirstAsync(); if (originalStock != null && originalStock.StockQuantity > 0) @@ -1063,7 +1067,7 @@ if (!processedBarcodes.Contains(splitRecord.NewBarcode)) { var newStock = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>() .Where(it => it.Barcode == splitRecord.NewBarcode && it.StockId == stockId) .Where(it => it.Barcode == splitRecord.NewBarcode && it.StockId == stockId && it.Status != StockStatusEmun.åºåºå®æ.ObjToInt()) .FirstAsync(); if (newStock != null && newStock.StockQuantity > 0) @@ -1111,11 +1115,13 @@ else { locationtype = stockInfo.LocationType; _stockInfoService.DeleteData(stockInfo); } var targetAddress = originalTask.TargetAddress; await CleanupZeroStockData(stockInfoId); var emptystockInfo = new Dt_StockInfo() { PalletType = PalletTypeEnum.Empty.ObjToInt(), StockStatus = StockStatusEmun.ç»çæå.ObjToInt(), PalletCode = palletCode, LocationType = locationtype }; emptystockInfo.Details = new List<Dt_StockInfoDetail>(); @@ -1123,7 +1129,7 @@ //空æçå¦ä½å¤ç è¿æä¸ä¸ªåºåºä»»å¡è¦å¤çã originalTask.PalletType = PalletTypeEnum.Empty.ObjToInt(); await CreateReturnTaskAndHandleESS(orderNo, palletCode, originalTask, TaskTypeEnum.InEmpty); await CreateReturnTaskAndHandleESS(orderNo, palletCode, originalTask, TaskTypeEnum.InEmpty,PalletTypeEnum.Empty.ObjToInt()); } catch (Exception ex) @@ -1143,19 +1149,41 @@ { await HandleRemainingLocksReturn(analysis.RemainingLocks, stockInfo.Id); // await UpdateOrderDetailsOnReturn(analysis.RemainingLocks); } // await UpdateOrderDetailsOnReturn(analysis.RemainingLocks); } // å¤çæçä¸å ¶ä»åºåè´§ç© if (analysis.HasPalletStockGoods) { await HandlePalletStockGoodsReturn(analysis.PalletStockGoods); var validStockGoods = analysis.PalletStockGoods .Where(x => x.Status != StockStatusEmun.åºåºå®æ.ObjToInt()) .ToList(); if (validStockGoods.Any()) { await HandlePalletStockGoodsReturn(analysis.PalletStockGoods); } else { _logger.LogInformation("æ²¡æææçåºåè´§ç©éè¦ååº"); } } // å¤çæå è®°å½ if (analysis.HasSplitRecords) { await HandleSplitRecordsReturn(analysis.SplitRecords, orderNo, palletCode); var validSplitRecords = analysis.SplitRecords .Where(x => x.Status != (int)SplitPackageStatusEnum.å·²æ£é) .ToList(); if (validSplitRecords.Any()) { await HandleSplitRecordsReturn(analysis.SplitRecords, orderNo, palletCode); } else { _logger.LogInformation("æ²¡æææçæå è®°å½éè¦å¤ç"); } } // æ´æ°åºåä¸»è¡¨ç¶æ @@ -1179,7 +1207,13 @@ foreach (var lockInfo in remainingLocks) { decimal returnQty = lockInfo.AssignQuantity - lockInfo.PickedQty; if (returnQty <= 0) { _logger.LogWarning($"éå®è®°å½{lockInfo.Id}æ éååºï¼åé æ°é: {lockInfo.AssignQuantity}, å·²æ£é: {lockInfo.PickedQty}"); continue; } _logger.LogInformation($"å¤çéå®è®°å½ååº - éå®ID: {lockInfo.Id}, æ¡ç : {lockInfo.CurrentBarcode}, ååºæ°é: {returnQty}"); // æ¥æ¾å¯¹åºçåºåæç» var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>() .Where(it => it.Barcode == lockInfo.CurrentBarcode && it.StockId == lockInfo.StockId) @@ -1195,23 +1229,23 @@ else { // å建æ°çåºåè®°å½ var newStockDetail = new Dt_StockInfoDetail { StockId = lockInfo.StockId, MaterielCode = lockInfo.MaterielCode, MaterielName = lockInfo.MaterielName, OrderNo = lockInfo.OrderNo, BatchNo = lockInfo.BatchNo, StockQuantity = returnQty, OutboundQuantity = 0, Barcode = lockInfo.CurrentBarcode, InboundOrderRowNo = "", Status = StockStatusEmun.å ¥åºç¡®è®¤.ObjToInt(), SupplyCode = lockInfo.SupplyCode, WarehouseCode = lockInfo.WarehouseCode, Unit = lockInfo.Unit, }; await _stockInfoDetailService.Db.Insertable(newStockDetail).ExecuteCommandAsync(); //var newStockDetail = new Dt_StockInfoDetail //{ // StockId = lockInfo.StockId, // MaterielCode = lockInfo.MaterielCode, // MaterielName = lockInfo.MaterielName, // OrderNo = lockInfo.OrderNo, // BatchNo = lockInfo.BatchNo, // StockQuantity = returnQty, // OutboundQuantity = 0, // Barcode = lockInfo.CurrentBarcode, // InboundOrderRowNo = "", // Status = StockStatusEmun.å ¥åºç¡®è®¤.ObjToInt(), // SupplyCode = lockInfo.SupplyCode, // WarehouseCode = lockInfo.WarehouseCode, // Unit = lockInfo.Unit, //}; //await _stockInfoDetailService.Db.Insertable(newStockDetail).ExecuteCommandAsync(); } } } @@ -1255,23 +1289,41 @@ { _logger.LogInformation($"å¾ ååºè´§ç© - æ¡ç : {stockGood.Barcode}, æ°é: {stockGood.StockQuantity}, å½åç¶æ: {stockGood.Status}"); // æ¢å¤åºåç¶æ stockGood.OutboundQuantity = 0; stockGood.Status = StockStatusEmun.å ¥åºç¡®è®¤.ObjToInt(); if (stockGood.Status != StockStatusEmun.åºåºå®æ.ObjToInt()) { stockGood.OutboundQuantity = 0; stockGood.Status = StockStatusEmun.å ¥åºç¡®è®¤.ObjToInt(); await _stockInfoDetailService.Db.Updateable(stockGood).ExecuteCommandAsync(); await _stockInfoDetailService.Db.Updateable(stockGood).ExecuteCommandAsync(); _logger.LogInformation($"åºåè´§ç©ååºå®æ - æ¡ç : {stockGood.Barcode}, æ°ç¶æ: {stockGood.Status}"); } else { _logger.LogWarning($"è·³è¿å·²åºåºå®æçè´§ç© - æ¡ç : {stockGood.Barcode}"); } } } private async Task HandleSplitRecordsReturn(List<Dt_SplitPackageRecord> splitRecords, string orderNo, string palletCode) { var validRecords = splitRecords.Where(x => x.Status != (int)SplitPackageStatusEnum.å·²æ£é).ToList(); if (!validRecords.Any()) { _logger.LogInformation("没æéè¦ååºçæå è®°å½"); return; } _logger.LogInformation($"æ´æ°{validRecords.Count}æ¡æå è®°å½ç¶æä¸ºå·²ååº"); // æ´æ°æå è®°å½ç¶æ await _splitPackageService.Db.Updateable<Dt_SplitPackageRecord>() .SetColumns(x => new Dt_SplitPackageRecord { Status = (int)SplitPackageStatusEnum.å·²ååº, Operator = App.User.UserName }) .Where(x => x.OrderNo == orderNo && x.PalletCode == palletCode && !x.IsReverted) .Where(x => validRecords.Select(r => r.Id).Contains(x.Id)) .ExecuteCommandAsync(); } @@ -1290,7 +1342,7 @@ /// <param name="originalTask"></param> /// <param name="analysis"></param> /// <returns></returns> private async Task CreateReturnTaskAndHandleESS(string orderNo, string palletCode, Dt_Task originalTask, TaskTypeEnum taskTypeEnum) private async Task CreateReturnTaskAndHandleESS(string orderNo, string palletCode, Dt_Task originalTask, TaskTypeEnum taskTypeEnum,int palletType) { var firstLocation = await _locationInfoService.Db.Queryable<Dt_LocationInfo>() .FirstAsync(x => x.LocationCode == originalTask.SourceAddress); @@ -1304,15 +1356,16 @@ Grade = 0, PalletCode = palletCode, NextAddress = "", OrderNo = originalTask.OrderNo, // OrderNo = originalTask.OrderNo, OrderNo = orderNo, Roadway = newLocation.RoadwayNo, SourceAddress = stations[originalTask.TargetAddress], TargetAddress = newLocation.LocationCode, TaskStatus = TaskStatusEnum.New.ObjToInt(), TaskType = taskTypeEnum.ObjToInt(), PalletType = originalTask.PalletType, PalletType = palletType, WarehouseId = originalTask.WarehouseId }; // ä¿åååºä»»å¡ await _taskRepository.Db.Insertable(returnTask).ExecuteCommandAsync(); @@ -1420,10 +1473,10 @@ .ExecuteCommandAsync(); // åªææ£å¸¸åæ£å®ææ¶æåMESåé¦ if (allCompleted && newStatus == (int)OutOrderStatusEnum.åºåºå®æ) { await HandleOrderCompletion(outboundOrder, orderNo); } //if (allCompleted && newStatus == (int)OutOrderStatusEnum.åºåºå®æ) //{ // await HandleOrderCompletion(outboundOrder, orderNo); //} } } catch (Exception ex) @@ -1432,7 +1485,7 @@ } } private async Task UpdateOrderStatusForReturn(string orderNo) { @@ -1728,7 +1781,7 @@ StockId = stockId }; // 1. åææªåæ£çåºåºéå®è®°å½ // åææªåæ£çåºåºéå®è®°å½ var remainingLocks = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>() .Where(it => it.OrderNo == orderNo && it.PalletCode == palletCode && @@ -1740,9 +1793,10 @@ result.HasRemainingLocks = true; result.RemainingLocks = remainingLocks; result.RemainingLocksReturnQty = remainingLocks.Sum(x => x.AssignQuantity - x.PickedQty); _logger.LogInformation($"åç°{remainingLocks.Count}æ¡æªåæ£éå®è®°å½ï¼æ»æ°é: {result.RemainingLocksReturnQty}"); } // 2. åææçä¸çåºåè´§ç© // åææçä¸çåºåè´§ç© var palletStockGoods = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>() .Where(it => it.StockId == stockId && (it.Status == StockStatusEmun.å ¥åºç¡®è®¤.ObjToInt() || @@ -1756,13 +1810,21 @@ result.HasPalletStockGoods = true; result.PalletStockGoods = palletStockGoods; result.PalletStockReturnQty = palletStockGoods.Sum(x => x.StockQuantity); _logger.LogInformation($"åç°{palletStockGoods.Count}个åºåè´§ç©ï¼æ»æ°é: {result.PalletStockReturnQty}"); // è®°å½è¯¦ç»ç¶æåå¸ var statusGroups = palletStockGoods.GroupBy(x => x.Status); foreach (var group in statusGroups) { _logger.LogInformation($"åºåç¶æ{group.Key}: {group.Count()}个货ç©ï¼æ°é: {group.Sum(x => x.StockQuantity)}"); } } // 3. åææå è®°å½ //åææå è®°å½ var splitRecords = await _splitPackageService.Db.Queryable<Dt_SplitPackageRecord>() .Where(it => it.OrderNo == orderNo && it.PalletCode == palletCode && !it.IsReverted && !it.IsReverted && it.Status != (int)SplitPackageStatusEnum.å·²æ£é && it.Status != (int)SplitPackageStatusEnum.å·²ååº) .ToListAsync(); @@ -1771,6 +1833,8 @@ result.HasSplitRecords = true; result.SplitRecords = splitRecords; result.SplitReturnQty = await CalculateSplitReturnQuantity(splitRecords, stockId); _logger.LogInformation($"åç°{splitRecords.Count}æ¡æªæ£éæå è®°å½ï¼æ»æ°é: {result.SplitReturnQty}"); } // 4. è®¡ç®æ»ååºæ°éå空æçç¶æ @@ -1785,6 +1849,10 @@ x.TaskStatus == (int)TaskStatusEnum.New) .AnyAsync(); _logger.LogInformation($"æçç¶æåæå®æ - 订å: {orderNo}, æç: {palletCode}, " + $"æ»ååºæ°é: {result.TotalReturnQty}, æ¯å¦ç©ºæç: {result.IsEmptyPallet}, " + $"æè¿è¡ä¸ä»»å¡: {result.HasActiveTasks}"); return result; } ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_StockService/StockInfoService.cs
@@ -201,12 +201,9 @@ if (!string.IsNullOrEmpty(supplyCode)) { query = query.Where(x => x.Details.Any(d => d.SupplyCode == supplyCode)); } } var stocks = query.ToList(); return stocks.OrderBy(x => x.Details.Where(d => d.MaterielCode == materielCode && (string.IsNullOrEmpty(supplyCode) || d.SupplyCode == supplyCode) && (string.IsNullOrEmpty(lotNo) || d.BatchNo == lotNo)).Min(d => d.CreateDate)).ToList(); return query.OrderBy(x => x.CreateDate).ToList(); //ISugarQueryable<Dt_LocationInfo> sugarQueryable = Db.Queryable<Dt_LocationInfo>().Where(x => locationCodes.Contains(x.LocationCode)); //ISugarQueryable<Dt_StockInfo> sugarQueryable1 = Db.Queryable<Dt_StockInfo>().Includes(x => x.Details).Where(x => x.Details.Any(v => v.MaterielCode == materielCode)); //return sugarQueryable.InnerJoin(sugarQueryable1, (a, b) => a.LocationCode == b.LocationCode).Select((a, b) => b).OrderBy(a => a.CreateDate).Includes(a => a.Details).ToList(); @@ -227,7 +224,7 @@ public List<Dt_StockInfo> GetStockInfosByPalletCodes(List<string> palletCodes) { return Db.Queryable<Dt_StockInfo>().Where(x => palletCodes.Contains(x.PalletCode)).Includes(x => x.Details).ToList(); return Db.Queryable<Dt_StockInfo>().Where(x => palletCodes.Contains(x.PalletCode)).Includes(x => x.Details).OrderBy(x => x.CreateDate).ToList(); } ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs
@@ -41,6 +41,7 @@ using WIDESEA_DTO.Allocate; using WIDESEA_DTO.Basic; using WIDESEA_DTO.Inbound; using WIDESEA_DTO.Outbound; using WIDESEA_DTO.Task; using WIDESEA_IAllocateService; using WIDESEA_IBasicService; @@ -126,7 +127,7 @@ if (int.TryParse(taskNum, out var newTaskNum)) { task = BaseDal.QueryFirst(x => x.TaskNum == newTaskNum); task =await BaseDal.QueryFirstAsync(x => x.TaskNum == newTaskNum); if (task == null) { return WebResponseContent.Instance.Error("æªæ¾å°ä»»å¡ä¿¡æ¯"); @@ -141,10 +142,28 @@ MethodInfo? methodInfo = GetType().GetMethod(((TaskTypeEnum)task.TaskType) + "TaskCompleted"); if (methodInfo != null) { WebResponseContent? responseContent = (WebResponseContent?)methodInfo.Invoke(this, new object[] { task }); if (responseContent != null) object? taskResult = methodInfo.Invoke(this, new object[] { task }); if (taskResult is Task<WebResponseContent> asyncTask) { return responseContent; try { // 3. 弿¥çå¾ Task 宿ï¼èªå¨è§£æåº WebResponseContent WebResponseContent responseContent = await asyncTask; if (responseContent != null) { return responseContent; } } catch (AggregateException ex) { _logger.LogError($"TaskService TaskCompleted taskResult: {ex.Message} "); return WebResponseContent.Instance.Error(ex.Message); } catch(Exception ex) { _logger.LogError(ex, $"Unexpected error in {task.TaskType}"); return WebResponseContent.Instance.Error(ex.Message); } } } return WebResponseContent.Instance.Error("æªæ¾å°ä»»å¡ç±»å对åºä¸å¡å¤çé»è¾"); @@ -363,7 +382,7 @@ return WebResponseContent.Instance.OK(); } public WebResponseContent OutboundTaskCompleted(Dt_Task task) public async Task<WebResponseContent> OutboundTaskCompleted(Dt_Task task) { _logger.LogInformation($"TaskService OutboundTaskCompleted: {task.TaskNum}"); //æ¥è´§ä½ @@ -375,7 +394,7 @@ locationInfo.LocationStatus = LocationStatusEnum.Free.ObjToInt(); _locationInfoService.Repository.UpdateData(locationInfo); var outloks = _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>().Where(x => x.TaskNum == task.TaskNum).ToList(); var outloks =await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>().Where(x => x.TaskNum == task.TaskNum).ToListAsync(); var stockids = outloks.Select(x => x.StockId).ToList(); @@ -439,12 +458,22 @@ stockInfo.StockStatus = StockStatusEmun.å ¥åºå®æ.ObjToInt(); _stockRepository.UpdateData(stockInfo); var outboundOrder = _outboundOrderService.Db.Queryable<Dt_OutboundOrder>().First(x => x.OrderNo == task.OrderNo); task.TaskStatus = TaskStatusEnum.Finish.ObjToInt(); BaseDal.DeleteAndMoveIntoHty(task, App.User.UserId == 0 ? WIDESEA_Core.Enums.OperateTypeEnum.èªå¨å®æ : OperateTypeEnum.äººå·¥å®æ); _locationStatusChangeRecordService.AddLocationStatusChangeRecord(locationInfo, beforelocationStatus, StockChangeType.Inbound.ObjToInt(), "", task.TaskNum); if (outboundOrder != null) { await HandleOutboundOrderToMESCompletion(outboundOrder, outboundOrder.OrderNo); } else { _logger.LogInformation($"TaskService InEmptyTaskCompleted: {task.TaskNum} ,æªæ¾å°åºåºåã "); } return content; } @@ -460,25 +489,30 @@ try { //æ¥åºå Dt_StockInfo stockInfo = _stockRepository.Db.Queryable<Dt_StockInfo>().Includes(x => x.Details).Where(x => x.PalletCode == task.PalletCode).First(); Dt_StockInfo stockInfo =await _stockRepository.Db.Queryable<Dt_StockInfo>().Includes(x => x.Details).Where(x => x.PalletCode == task.PalletCode).FirstAsync(); if (stockInfo == null) { _logger.LogInformation($"TaskService InPickTaskCompleted: æªæ¾å°æç对åºçç»çä¿¡æ¯.{task.TaskNum}"); return WebResponseContent.Instance.Error($"æªæ¾å°æç对åºçç»çä¿¡æ¯"); } if (stockInfo.Details.Count == 0 && stockInfo.PalletType != PalletTypeEnum.Empty.ObjToInt()) { _logger.LogInformation($"TaskService InPickTaskCompleted: æªæ¾å°è¯¥æçåºåæç»ä¿¡æ¯.{task.TaskNum}"); return WebResponseContent.Instance.Error($"æªæ¾å°è¯¥æçåºåæç»ä¿¡æ¯"); } //æ¥è´§ä½ Dt_LocationInfo locationInfo = _locationInfoService.Repository.QueryFirst(x => x.LocationCode == task.TargetAddress); if (locationInfo == null) { _logger.LogInformation($"TaskService InPickTaskCompleted: æªæ¾å°å¯¹åºçç»ç¹è´§ä½ä¿¡æ¯ {task.TaskNum}."); return WebResponseContent.Instance.Error($"æªæ¾å°å¯¹åºçç»ç¹è´§ä½ä¿¡æ¯"); } var beforelocationStatus = locationInfo.LocationStatus; // è·åææååºä¸çåºåºéå®è®°å½ var returnLocks = _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>() var returnLocks =await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>() .Where(it => it.OrderNo == task.OrderNo && it.PalletCode == task.PalletCode && it.Status == (int)OutLockStockStatusEnum.ååºä¸) .ToList(); .ToListAsync(); // æ´æ°åºåºéå®è®°å½ç¶æä¸ºååºå®æ foreach (var lockInfo in returnLocks) { @@ -512,17 +546,98 @@ locationInfo.LocationStatus = LocationStatusEnum.InStock.ObjToInt(); } _locationInfoService.Repository.UpdateData(locationInfo); var outboundOrder = _outboundOrderService.Db.Queryable<Dt_OutboundOrder>().First(x => x.OrderNo == task.OrderNo); task.TaskStatus = TaskStatusEnum.Finish.ObjToInt(); BaseDal.DeleteAndMoveIntoHty(task, App.User.UserId == 0 ? OperateTypeEnum.èªå¨å®æ : OperateTypeEnum.äººå·¥å®æ); BaseDal.DeleteData(task); _locationStatusChangeRecordService.AddLocationStatusChangeRecord(locationInfo, beforelocationStatus, StockChangeType.Inbound.ObjToInt(), "", task.TaskNum); if (outboundOrder != null) { await HandleOutboundOrderToMESCompletion(outboundOrder, outboundOrder.OrderNo); } else { _logger.LogInformation($"TaskService InPickTaskCompleted: {task.TaskNum} ,æªæ¾å°åºåºåã "); } } catch (Exception ex) { _logger.LogInformation($"TaskService InPickTaskCompleted: {task.TaskNum} , {ex.Message}"); } return WebResponseContent.Instance.OK(); return await Task.FromResult(WebResponseContent.Instance.OK()); } private async Task HandleOutboundOrderToMESCompletion(Dt_OutboundOrder outboundOrder, string orderNo) { // è·å订åæç»æ°æ® var orderDetails = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>() .LeftJoin<Dt_OutboundOrder>((d, o) => d.OrderId == o.Id) .Where((d, o) => o.OrderNo == orderNo) .Select((d, o) => d) .ToListAsync(); var feedmodel = new FeedbackOutboundRequestModel { reqCode = Guid.NewGuid().ToString(), reqTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), business_type = outboundOrder.BusinessType, factoryArea = outboundOrder.FactoryArea, operationType = 1, Operator = App.User.UserName, orderNo = outboundOrder.UpperOrderNo, documentsNO = outboundOrder.OrderNo, status = outboundOrder.OrderStatus, details = new List<FeedbackOutboundDetailsModel>() }; // 使ç¨è®¢åæç»çOverOutQuantityä½ä¸ºåä¼ æ°é foreach (var detail in orderDetails) { // è·å该æç»å¯¹åºçæ¡ç ä¿¡æ¯ï¼ä»éå®è®°å½ï¼ var detailLocks = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>() .Where(x => x.OrderNo == orderNo && x.OrderDetailId == detail.Id && x.Status == (int)OutLockStockStatusEnum.æ£é宿) .ToListAsync(); var detailModel = new FeedbackOutboundDetailsModel { materialCode = detail.MaterielCode, lineNo = detail.lineNo, // 注æï¼è¿éå¯è½éè¦è°æ´å段å warehouseCode = detail.WarehouseCode, qty = detail.OverOutQuantity, // 使ç¨è®¢åæç»çå·²åºåºæ°é currentDeliveryQty = detail.OverOutQuantity, unit = detail.Unit, barcodes = detailLocks.Select(lockInfo => new WIDESEA_DTO.Outbound.BarcodesModel { barcode = lockInfo.CurrentBarcode, supplyCode = lockInfo.SupplyCode, batchNo = lockInfo.BatchNo, unit = lockInfo.Unit, qty = lockInfo.PickedQty // æ¡ç 级å«çæ°éä»ç¨éå®è®°å½ }).ToList() }; feedmodel.details.Add(detailModel); } var result = await _invokeMESService.FeedbackOutbound(feedmodel); if (result != null && result.code == 200) { await _outboundOrderDetailService.Db.Updateable<Dt_OutboundOrderDetail>() .SetColumns(x => x.ReturnToMESStatus == 1) .Where(x => x.OrderId == outboundOrder.Id) .ExecuteCommandAsync(); await _outboundOrderService.Db.Updateable<Dt_OutboundOrder>() .SetColumns(x => x.ReturnToMESStatus == 1) .Where(x => x.OrderNo == orderNo) .ExecuteCommandAsync(); } } /// <summary> @@ -611,7 +726,7 @@ _locationStatusChangeRecordService.AddLocationStatusChangeRecord(locationInfo, beforeStatus, StockChangeType.Outbound.ObjToInt(), stockInfo.Details.FirstOrDefault()?.OrderNo ?? "", task.TaskNum); return WebResponseContent.Instance.OK(); return await Task.FromResult(WebResponseContent.Instance.OK()); } catch (Exception ex) ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/ESSController.cs
@@ -217,7 +217,7 @@ _logger.LogInformation("ä»»å¡å®æ: TaskCode={TaskCode}, Container={Container}, Robot={Robot}", request.TaskCode, request.ContainerCode, request.RobotCode); _taskService.TaskCompleted(request.TaskCode); await _taskService.TaskCompleted(request.TaskCode); // æ ¹æ®ä¸åçä»»å¡ç±»åè¿è¡ç¹æ®å¤ç if (request.Weight.HasValue) {