| | |
| | | foreach (var detail in stockInfo.Details) |
| | | { |
| | | detail.Status = StockStatusEmun.å
¥åºå®æ.ObjToInt(); |
| | | |
| | | // ç¡®ä¿åºåæ°éä¸åºåºæ°éä¸è´ |
| | | if (detail.Status == StockStatusEmun.å
¥åºå®æ.ObjToInt()) |
| | | { |
| | | detail.OutboundQuantity = 0; // å
¥åºå®ææ¶åºåºæ°éæ¸
é¶ |
| | | } |
| | | } |
| | | _stockService.StockInfoDetailService.Repository.UpdateData(stockInfo.Details); |
| | | } |
| | | |
| | | _stockService.StockInfoService.Repository.UpdateData(stockInfo); |
| | | |
| | | // å¤çååºç¸å
³çåºåæç» |
| | | await ProcessStockDetailsForReturn(task, stockInfo.Id); |
| | | |
| | | // å é¤é¶åºåæ°æ® |
| | | await DeleteZeroQuantityStockDetails(stockInfo.Id); |
| | | |
| | | await UpdateAffectedOrderDetails(task.OrderNo, returnLocks); |
| | | // æ´æ°è´§ä½ç¶æ |
| | | if (stockInfo.PalletType == PalletTypeEnum.Empty.ObjToInt()) |
| | | { |
| | |
| | | } |
| | | |
| | | _locationInfoService.Repository.UpdateData(locationInfo); |
| | | |
| | | // æ´æ°è®¢åç¸å
³æ°æ® |
| | | await UpdateOrderDataAfterReturn(task.OrderNo, returnLocks); |
| | | |
| | | // è·åå¹¶æ´æ°åºåºè®¢å |
| | | var outboundOrder = await _outboundOrderService.Db.Queryable<Dt_OutboundOrder>() |
| | | .FirstAsync(x => x.OrderNo == task.OrderNo); |
| | | |
| | | task.TaskStatus = TaskStatusEnum.Finish.ObjToInt(); |
| | | |
| | |
| | | "", |
| | | task.TaskNum |
| | | ); |
| | | await RecalculateOrderStatus(task.OrderNo); |
| | | |
| | | _unitOfWorkManage.CommitTran(); // æäº¤äºå¡ |
| | | _logger.LogInformation($"æçååºå®æå¤çæå - ä»»å¡å·: {task.TaskNum}, æç: {task.PalletCode}, 订å: {task.OrderNo}"); |
| | | _ = Task.Run(async () => |
| | | { |
| | | try |
| | | { |
| | | var outboundOrder = await _outboundOrderService.Db.Queryable<Dt_OutboundOrder>() |
| | | .FirstAsync(x => x.OrderNo == task.OrderNo); |
| | | |
| | | if (outboundOrder != null) |
| | | { |
| | | // æ£æ¥è®¢åç¶ææ¯å¦éè¦æ´æ° |
| | | await CheckAndUpdateOrderStatusAfterReturn(task.OrderNo); |
| | | |
| | | // å¤çMESåé¦ |
| | | // æ£æ¥è®¢åæ¯å¦å·²å®æï¼åªæå®ææ¶æåMESåé¦ |
| | | if (outboundOrder.OrderStatus == (int)OutOrderStatusEnum.åºåºå®æ) |
| | | { |
| | | await HandleOutboundOrderToMESCompletion(outboundOrder, outboundOrder.OrderNo); |
| | | } |
| | | else |
| | | { |
| | | _logger.LogInformation($"TaskService InPickTaskCompleted: {task.TaskNum} ,æªæ¾å°åºåºåã"); |
| | | _logger.LogInformation($"订å{task.OrderNo}ç¶æä¸º{outboundOrder.OrderStatus}ï¼æä¸åMESåé¦"); |
| | | } |
| | | |
| | | _unitOfWorkManage.CommitTran(); // æäº¤äºå¡ |
| | | |
| | | _logger.LogInformation($"ååºä»»å¡å®æå¤çæå - ä»»å¡å·: {task.TaskNum}, æç: {task.PalletCode}"); |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | _logger.LogError($"弿¥MESåé¦å¤ç失败 - OrderNo: {task.OrderNo}, Error: {ex.Message}"); |
| | | } |
| | | }); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | |
| | | |
| | | return WebResponseContent.Instance.OK(); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// ååºåæ´æ°è®¢åæ°æ® |
| | | // <summary> |
| | | /// æ´æ°åå½±åç订åæç»é宿°é |
| | | /// </summary> |
| | | private async Task UpdateOrderDataAfterReturn(string orderNo, List<Dt_OutStockLockInfo> returnLocks) |
| | | private async Task UpdateAffectedOrderDetails(string orderNo, List<Dt_OutStockLockInfo> returnLocks) |
| | | { |
| | | try |
| | | { |
| | | // è·åææåå½±åç订åæç»ID |
| | | // è·ååå½±åç订åæç»IDï¼å»éï¼ |
| | | var affectedDetailIds = returnLocks |
| | | .Select(x => x.OrderDetailId) |
| | | .Distinct() |
| | | .ToList(); |
| | | |
| | | if (!affectedDetailIds.Any()) |
| | | { |
| | | _logger.LogInformation($"没æåå½±åç订åæç» - OrderNo: {orderNo}"); |
| | | return; |
| | | } |
| | | |
| | | _logger.LogInformation($"æ´æ°{affectedDetailIds.Count}个åå½±åç订åæç» - OrderNo: {orderNo}"); |
| | | |
| | | foreach (var detailId in affectedDetailIds) |
| | | { |
| | | // 计ç®è¯¥è®¢åæç»çååºæ»æ°é |
| | | var detailReturnLocks = returnLocks |
| | | .Where(x => x.OrderDetailId == detailId) |
| | | .ToList(); |
| | | // éæ°è®¡ç®è¯¥è®¢åæç»çé宿°é |
| | | decimal currentLockQty = await CalculateOrderDetailLockQuantity(detailId); |
| | | |
| | | decimal totalReturnQty = detailReturnLocks.Sum(x => x.AssignQuantity - x.PickedQty); |
| | | |
| | | if (totalReturnQty > 0) |
| | | // æ£æ¥æ°æ®ä¸è´æ§ |
| | | if (currentLockQty < 0) |
| | | { |
| | | _logger.LogWarning($"é宿°é计ç®ä¸ºè´å¼ - OrderDetailId: {detailId}, å½åå¼: {currentLockQty}ï¼é置为0"); |
| | | currentLockQty = 0; |
| | | } |
| | | |
| | | // è·å订åæç» |
| | | var orderDetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>() |
| | | .FirstAsync(x => x.Id == detailId); |
| | | |
| | | if (orderDetail != null) |
| | | if (orderDetail == null) |
| | | { |
| | | // æ´æ°é宿°éï¼ååºåé宿°éåºåå°ï¼ |
| | | var remainingLocks = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>() |
| | | .Where(x => x.OrderDetailId == detailId && |
| | | x.Status == (int)OutLockStockStatusEnum.åºåºä¸) |
| | | .ToListAsync(); |
| | | _logger.LogWarning($"æªæ¾å°è®¢åæç» - OrderDetailId: {detailId}"); |
| | | continue; |
| | | } |
| | | |
| | | decimal remainingLockQty = remainingLocks.Sum(x => x.AssignQuantity - x.PickedQty); |
| | | |
| | | // æ´æ°è®¢åæç» |
| | | // æ´æ°é宿°é |
| | | if (orderDetail.LockQuantity != currentLockQty) |
| | | { |
| | | await _outboundOrderDetailService.Db.Updateable<Dt_OutboundOrderDetail>() |
| | | .SetColumns(it => new Dt_OutboundOrderDetail |
| | | { |
| | | LockQuantity = remainingLockQty, |
| | | LockQuantity = currentLockQty, |
| | | }) |
| | | .Where(it => it.Id == detailId) |
| | | .ExecuteCommandAsync(); |
| | | |
| | | // æ´æ°è®¢åæç»ç¶æ |
| | | await UpdateOrderDetailStatus(detailId); |
| | | _logger.LogInformation($"æ´æ°è®¢åæç»é宿°é - OrderDetailId: {detailId}, " + |
| | | $"æ§å¼: {orderDetail.LockQuantity}, æ°å¼: {currentLockQty}"); |
| | | } |
| | | |
| | | _logger.LogInformation($"ååºæ´æ°è®¢åæç» - OrderDetailId: {detailId}, " + |
| | | $"æ£åé宿°é: {totalReturnQty}, æ°é宿°é: {remainingLockQty}"); |
| | | } |
| | | } |
| | | // æ´æ°è®¢åæç»ç¶æ |
| | | await UpdateOrderDetailStatus(orderDetail); |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | _logger.LogError($"UpdateOrderDataAfterReturn失败 - OrderNo: {orderNo}, Error: {ex.Message}"); |
| | | _logger.LogError($"UpdateAffectedOrderDetails失败 - OrderNo: {orderNo}, Error: {ex.Message}"); |
| | | throw; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// æ´æ°è®¢åæç»ç¶æ |
| | | /// éæ°è®¡ç®è®¢åæç»é宿°é |
| | | /// </summary> |
| | | private async Task UpdateOrderDetailStatus(int orderDetailId) |
| | | private async Task<decimal> CalculateOrderDetailLockQuantity(int orderDetailId) |
| | | { |
| | | try |
| | | { |
| | | var orderDetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>() |
| | | .FirstAsync(x => x.Id == orderDetailId); |
| | | // æ¥æ¾è¯¥è®¢åæç»ä¸ææç¶æä¸º"åºåºä¸"çéå®è®°å½ |
| | | var activeLocks = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>() |
| | | .Where(x => x.OrderDetailId == orderDetailId && |
| | | x.Status == (int)OutLockStockStatusEnum.åºåºä¸) |
| | | .ToListAsync(); |
| | | |
| | | if (orderDetail == null) |
| | | // è¿æ»¤æå
è®°å½ |
| | | var filteredLocks = new List<Dt_OutStockLockInfo>(); |
| | | |
| | | foreach (var lockInfo in activeLocks) |
| | | { |
| | | _logger.LogWarning($"UpdateOrderDetailStatuså¤±è´¥ï¼æªæ¾å°è®¢åæç»ï¼ID: {orderDetailId}"); |
| | | return; |
| | | // å¦ææ¯æå
è®°å½ï¼éè¦ç¹æ®å¤ç |
| | | if (lockInfo.IsSplitted == 1 && lockInfo.ParentLockId.HasValue) |
| | | { |
| | | // æ¥æ¾ç¶éå®è®°å½ |
| | | var parentLock = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>() |
| | | .Where(x => x.Id == lockInfo.ParentLockId.Value) |
| | | .FirstAsync(); |
| | | |
| | | // 妿ç¶è®°å½åå¨ä¸ç¶æä¹æ¯åºåºä¸ï¼ååªè®¡ç®ç¶è®°å½ |
| | | if (parentLock != null && parentLock.Status == (int)OutLockStockStatusEnum.åºåºä¸) |
| | | { |
| | | // ç¶è®°å½å·²ç»å¨å表ä¸ï¼è·³è¿å½åæå
è®°å½ |
| | | continue; |
| | | } |
| | | } |
| | | |
| | | filteredLocks.Add(lockInfo); |
| | | } |
| | | |
| | | decimal totalLockQty = filteredLocks.Sum(x => x.AssignQuantity - x.PickedQty); |
| | | |
| | | _logger.LogDebug($"计ç®é宿°é - OrderDetailId: {orderDetailId}, " + |
| | | $"æ¾å°{filteredLocks.Count}个ææéå®è®°å½, " + |
| | | $"æ»é宿°é: {totalLockQty}"); |
| | | |
| | | return totalLockQty; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | _logger.LogError($"CalculateOrderDetailLockQuantity失败 - OrderDetailId: {orderDetailId}, Error: {ex.Message}"); |
| | | return 0; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// æ´æ°è®¢åæç»ç¶æ |
| | | /// </summary> |
| | | private async Task UpdateOrderDetailStatus(Dt_OutboundOrderDetail orderDetail) |
| | | { |
| | | try |
| | | { |
| | | int newStatus = orderDetail.OrderDetailStatus; |
| | | |
| | | // 1. æ£æ¥æ¯å¦å·²å®æ |
| | | // æ ¹æ®å®é
æä¸¾å¼è°æ´ |
| | | // 1. æ£æ¥æ¯å¦å·²å®æï¼å·²åºåºæ°é >= éæ±æ°éï¼ |
| | | if (orderDetail.OverOutQuantity >= orderDetail.NeedOutQuantity) |
| | | { |
| | | newStatus = (int)OrderDetailStatusEnum.Over; |
| | | newStatus = (int)OrderDetailStatusEnum.Over; // 已宿 |
| | | } |
| | | // 2. æ£æ¥æ¯å¦æ£å¨è¿è¡ä¸ï¼æé宿°éæé¨åæ£éï¼ |
| | | else if (orderDetail.LockQuantity > 0 || |
| | | (orderDetail.OverOutQuantity > 0 && orderDetail.OverOutQuantity < orderDetail.NeedOutQuantity)) |
| | | // 2. æ£æ¥æ¯å¦æé¨ååºåºææé宿°é |
| | | else if (orderDetail.OverOutQuantity > 0 || orderDetail.LockQuantity > 0) |
| | | { |
| | | newStatus = (int)OrderDetailStatusEnum.Outbound; |
| | | newStatus = (int)OrderDetailStatusEnum.Outbound; // é¨å宿/è¿è¡ä¸ |
| | | } |
| | | // 3. æ£æ¥æ¯å¦æéå®ä½æªæ£é |
| | | else if (orderDetail.LockQuantity > 0 && orderDetail.OverOutQuantity == 0) |
| | | { |
| | | newStatus = (int)OrderDetailStatusEnum.AssignOverPartial; |
| | | } |
| | | // 4. å¦å为æ°è®¢å |
| | | // 3. å¦å为æ°è®¢å |
| | | else |
| | | { |
| | | newStatus = (int)OrderDetailStatusEnum.New; |
| | | newStatus = (int)OrderDetailStatusEnum.New; // æ°å»º |
| | | } |
| | | |
| | | // åªæç¶æååæ¶ææ´æ° |
| | |
| | | { |
| | | OrderDetailStatus = newStatus, |
| | | }) |
| | | .Where(it => it.Id == orderDetailId) |
| | | .Where(it => it.Id == orderDetail.Id) |
| | | .ExecuteCommandAsync(); |
| | | |
| | | _logger.LogInformation($"æ´æ°è®¢åæç»ç¶æ - OrderDetailId: {orderDetailId}, " + |
| | | _logger.LogInformation($"æ´æ°è®¢åæç»ç¶æ - OrderDetailId: {orderDetail.Id}, " + |
| | | $"æ§ç¶æ: {orderDetail.OrderDetailStatus}, æ°ç¶æ: {newStatus}, " + |
| | | $"å·²åºåº: {orderDetail.OverOutQuantity}/{orderDetail.NeedOutQuantity}, " + |
| | | $"é宿°é: {orderDetail.LockQuantity}"); |
| | |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | _logger.LogError($"UpdateOrderDetailStatus失败 - OrderDetailId: {orderDetailId}, Error: {ex.Message}"); |
| | | _logger.LogError($"UpdateOrderDetailStatus失败 - OrderDetailId: {orderDetail.Id}, Error: {ex.Message}"); |
| | | throw; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// ååºåæ£æ¥å¹¶æ´æ°è®¢åç¶æ |
| | | /// éæ°è®¡ç®å¹¶æ´æ°è®¢åç¶æ |
| | | /// </summary> |
| | | private async Task CheckAndUpdateOrderStatusAfterReturn(string orderNo) |
| | | private async Task RecalculateOrderStatus(string orderNo) |
| | | { |
| | | try |
| | | { |
| | | // è·å订åçæææç» |
| | | var orderDetails = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>() |
| | | .LeftJoin<Dt_OutboundOrder>((o, item) => o.OrderId == item.Id) |
| | | .Where((o, item) => item.OrderNo == orderNo) |
| | | .Select((o, item) => o) |
| | | .ToListAsync(); |
| | | |
| | | if (!orderDetails.Any()) |
| | | { |
| | | _logger.LogWarning($"æªæ¾å°è®¢åæç» - OrderNo: {orderNo}"); |
| | | return; |
| | | } |
| | | |
| | | // æ£æ¥ç¶æ |
| | | bool allCompleted = true; |
| | | bool hasInProgress = false; |
| | | |
| | |
| | | |
| | | // æ£æ¥æ¯å¦æè¿è¡ä¸çä»»å¡ï¼é宿é¨åæ£éï¼ |
| | | if (detail.LockQuantity > 0 || |
| | | detail.OrderDetailStatus == OrderDetailStatusEnum.Outbound.ObjToInt()) |
| | | detail.OrderDetailStatus == (int)OrderDetailStatusEnum.Outbound) |
| | | { |
| | | hasInProgress = true; |
| | | } |
| | |
| | | var outboundOrder = await _outboundOrderService.Db.Queryable<Dt_OutboundOrder>() |
| | | .FirstAsync(x => x.OrderNo == orderNo); |
| | | |
| | | if (outboundOrder == null) return; |
| | | if (outboundOrder == null) |
| | | { |
| | | _logger.LogWarning($"æªæ¾å°åºåºè®¢å - OrderNo: {orderNo}"); |
| | | return; |
| | | } |
| | | |
| | | int newStatus; |
| | | if (allCompleted) |
| | |
| | | .Where(x => x.OrderNo == orderNo) |
| | | .ExecuteCommandAsync(); |
| | | |
| | | _logger.LogInformation($"ååºåæ´æ°è®¢åç¶æ - OrderNo: {orderNo}, æ°ç¶æ: {newStatus}"); |
| | | _logger.LogInformation($"æ´æ°è®¢åç¶æ - OrderNo: {orderNo}, æ§ç¶æ: {outboundOrder.OrderStatus}, æ°ç¶æ: {newStatus}"); |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | _logger.LogError($"CheckAndUpdateOrderStatusAfterReturn失败 - OrderNo: {orderNo}, Error: {ex.Message}"); |
| | | _logger.LogError($"RecalculateOrderStatus失败 - OrderNo: {orderNo}, Error: {ex.Message}"); |
| | | throw; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// å¤çååºçåºåæç»ï¼å¢å¼ºçï¼ |
| | | /// </summary> |
| | | private async Task ProcessStockDetailsForReturn(Dt_Task task, int stockId) |
| | | { |
| | | try |
| | | { |
| | | // è·åææéè¦å¤ççåºåæç» |
| | | var stockDetails = await _stockService.StockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>() |
| | | .Where(x => x.StockId == stockId) |
| | | .ToListAsync(); |
| | | |
| | | foreach (var detail in stockDetails) |
| | | { |
| | | // ç¡®ä¿åºåç¶ææ£ç¡® |
| | | if (detail.Status == StockStatusEmun.å
¥åºç¡®è®¤.ObjToInt()) |
| | | { |
| | | // å¦æå·²ç»æ¯å
¥åºç¡®è®¤ç¶æï¼æ´æ°ä¸ºå
¥åºå®æ |
| | | detail.Status = StockStatusEmun.å
¥åºå®æ.ObjToInt(); |
| | | detail.OutboundQuantity = 0; |
| | | |
| | | await _stockService.StockInfoDetailService.Db.Updateable(detail).ExecuteCommandAsync(); |
| | | |
| | | _logger.LogInformation($"æ´æ°åºåæç»ç¶æ - æ¡ç : {detail.Barcode}, " + |
| | | $"æ°ç¶æ: {detail.Status}, åºåºæ°é: {detail.OutboundQuantity}"); |
| | | } |
| | | else if (detail.Status == StockStatusEmun.åºåºéå®.ObjToInt() || |
| | | detail.Status == StockStatusEmun.åºåºå®æ.ObjToInt()) |
| | | { |
| | | // è¿äºç¶æä¸åºè¯¥åå¨ï¼è®°å½è¦å |
| | | _logger.LogWarning($"å¼å¸¸åºåç¶æ - æ¡ç : {detail.Barcode}, ç¶æ: {detail.Status}, " + |
| | | $"ä»»å¡å·: {task.TaskNum}"); |
| | | } |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | _logger.LogError($"ProcessStockDetailsForReturn失败 - StockId: {stockId}, Error: {ex.Message}"); |
| | | throw; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// å é¤é¶åºåæ°æ®ï¼å¢å¼ºçï¼ |
| | |
| | | MaterialCode = detail.MaterielCode, |
| | | LineNo = detail.lineNo, |
| | | WarehouseCode = detail.WarehouseCode, |
| | | Qty = detailLocks.Sum(x=>x.PickedQty), |
| | | Qty =0, |
| | | Unit = detail.BarcodeUnit, |
| | | Barcodes = new List<BarcodeInfo> () |
| | | }; |
| | |
| | | SupplyCode = item.SupplyCode, |
| | | BatchNo = item.BatchNo, |
| | | Unit = item.BarcodeUnit, |
| | | Qty = item.PickedQty |
| | | Qty = 0 |
| | | }; |
| | | // åä½ä¸ä¸è´æ¶è½¬æ¢ |
| | | if (item.BarcodeUnit != item.Unit) |
| | |
| | | materialCode = detail.MaterielCode, |
| | | lineNo = detail.lineNo, // 注æï¼è¿éå¯è½éè¦è°æ´å段å |
| | | warehouseCode = detail.WarehouseCode, |
| | | qty = detail.PickedQty, |
| | | currentDeliveryQty = detail.PickedQty, |
| | | qty = 0, |
| | | currentDeliveryQty =0, |
| | | unit = detail.Unit, |
| | | barcodes = new List<WIDESEA_DTO.Outbound.BarcodesModel>() |
| | | }; |