pan
2025-11-21 70ae387bfb08b5734215711018a0f832e4ac6a41
提交
已修改2个文件
93 ■■■■ 文件已修改
项目代码/WIDESEA_WMSClient/src/views/inbound/inboundOrder.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundPickingService.cs 91 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/views/inbound/inboundOrder.vue
@@ -78,7 +78,7 @@
    const searchFormFields = ref({
      inboundOrderNo: "",
      upperOrderNo: "",
      orderType: "",
      orderType: "0",
      orderStatus: "",
      createType: "",
      creater: "",
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundPickingService.cs
@@ -251,6 +251,9 @@
            }
        }
        public async Task<WebResponseContent> ConfirmPicking(string orderNo, string palletCode, string barcode)
        {
            #region "测试打印"
@@ -283,25 +286,25 @@
            {
                _unitOfWorkManage.BeginTran();
                // 1. æŸ¥æ‰¾å‡ºåº“锁定信息
                var lockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
           .Where(it => it.OrderNo == orderNo &&
                      it.Status == (int)OutLockStockStatusEnum.出库中 &&
                      it.PalletCode == palletCode &&
                      it.CurrentBarcode == barcode &&
                      it.AssignQuantity > it.PickedQty) // å¢žåŠ ï¼šåªæœ‰æœªå®Œæˆåˆ†æ‹£çš„æ‰èƒ½ç»§ç»­
           .FirstAsync();
                    .Where(it => it.OrderNo == orderNo &&
                               it.Status == (int)OutLockStockStatusEnum.出库中 &&
                               it.PalletCode == palletCode &&
                               it.CurrentBarcode == barcode &&
                               it.AssignQuantity > it.PickedQty)
                    .FirstAsync();
                if (lockInfo == null)
                {
                    lockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
                        .Where(it => it.CurrentBarcode == barcode &&
                                   it.Status == (int)OutLockStockStatusEnum.出库中 &&
                                   it.AssignQuantity > it.PickedQty) // å¢žåŠ ï¼šæ£€æŸ¥åˆ†æ‹£è¿›åº¦
                                   it.AssignQuantity > it.PickedQty)
                        .FirstAsync();
                    if (lockInfo == null)
                    {
                        // æ£€æŸ¥æ˜¯å¦å·²ç»å®Œæˆåˆ†æ‹£
                        var completedLockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
                            .Where(it => it.CurrentBarcode == barcode &&
                                       (it.Status == (int)OutLockStockStatusEnum.拣选完成 ||
@@ -318,12 +321,7 @@
                if (lockInfo.PalletCode != palletCode)
                    throw new Exception($"条码{barcode}不属于托盘{palletCode}");
                if (lockInfo.PickedQty >= lockInfo.AssignQuantity)
                {
                    throw new Exception($"条码{barcode}已经完成分拣,不能重复分拣");
                }
                //  æ£€æŸ¥æ‹£é€‰åŽ†å²ï¼Œé˜²æ­¢é‡å¤åˆ†æ‹£
                // æ£€æŸ¥æ‹£é€‰åŽ†å²ï¼Œé˜²æ­¢é‡å¤åˆ†æ‹£
                var existingPicking = await Db.Queryable<Dt_PickingRecord>()
                    .Where(x => x.Barcode == barcode &&
                               x.OrderNo == orderNo &&
@@ -336,16 +334,17 @@
                    throw new Exception($"条码{barcode}已经分拣过,不能重复分拣");
                }
                var outorderdetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
                    .FirstAsync(x => x.Id == lockInfo.OrderDetailId);
                var outorderdetail = _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>().First(x => x.Id == lockInfo.OrderDetailId);
                if (outorderdetail != null && lockInfo.AssignQuantity > outorderdetail.OrderQuantity)
                if (outorderdetail != null && (lockInfo.AssignQuantity + outorderdetail.OverOutQuantity) > outorderdetail.NeedOutQuantity)
                {
                    throw new Exception($"条码{barcode}的出库数量大于订单的数量");
                    throw new Exception($"条码{barcode}的出库数量将导致订单明细已出库数量超过需求数量");
                }
                var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
                        .Where(x => x.Barcode == barcode && x.StockId == lockInfo.StockId)
                        .FirstAsync();
                    .Where(x => x.Barcode == barcode && x.StockId == lockInfo.StockId)
                    .FirstAsync();
                if (stockDetail == null)
                    return WebResponseContent.Instance.Error("无效的条码或物料编码");
@@ -357,23 +356,20 @@
                Dt_OutStockLockInfo finalLockInfo = lockInfo;
                var finalBarcode = barcode;
                var finalStockId = stockDetail.Id;
                decimal actualPickedQty = actualQty; // å®žé™…拣选数量
                if (actualQty < stockQuantity)
                {
                    // æƒ…况1: åˆ†é…æ•°é‡å°äºŽåº“存数量,需要自动拆包
                    // è®¡ç®—剩余库存数量
                    decimal remainingStockQty = stockQuantity - actualQty;
                    // æ›´æ–°åŽŸæ¡ç åº“å­˜ä¸ºå‰©ä½™æ•°é‡
                    stockDetail.StockQuantity = remainingStockQty;
                    stockDetail.OutboundQuantity = remainingStockQty;
                    await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync();
                    // ç”Ÿæˆæ–°æ¡ç ç”¨äºŽè®°å½•拣选数量(但不创建库存记录)
                    var seq = await _dailySequenceService.GetNextSequenceAsync();
                    string newBarcode = "WSLOT" + DateTime.Now.ToString("yyyyMMdd") + seq.ToString()?.PadLeft(5, '0');
                    // ä¸ºæ–°æ¡ç åˆ›å»ºå‡ºåº“锁定信息(用于记录拣选)
                    var newLockInfo = new Dt_OutStockLockInfo
                    {
                        OrderNo = lockInfo.OrderNo,
@@ -398,11 +394,10 @@
                        IsSplitted = 1,
                        ParentLockId = lockInfo.Id
                    };
                    // æ’入新锁定信息并获取ID
                    var newLockId = await _outStockLockInfoService.Db.Insertable(newLockInfo).ExecuteReturnIdentityAsync();
                    newLockInfo.Id = newLockId; // ç¡®ä¿ID被正确设置
                    // è®°å½•拆包历史(用于追踪)
                    var newLockId = await _outStockLockInfoService.Db.Insertable(newLockInfo).ExecuteReturnIdentityAsync();
                    newLockInfo.Id = newLockId;
                    var splitHistory = new Dt_SplitPackageRecord
                    {
                        FactoryArea = lockInfo.FactoryArea,
@@ -423,10 +418,8 @@
                    };
                    await _splitPackageService.Db.Insertable(splitHistory).ExecuteCommandAsync();
                    // æ›´æ–°åŽŸé”å®šä¿¡æ¯ä¸ºå‰©ä½™åº“å­˜æ•°é‡
                    lockInfo.AssignQuantity = remainingStockQty;
                    lockInfo.PickedQty = 0;
                    await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync();
                    splitResults.Add(new SplitResult
@@ -438,8 +431,8 @@
                        batch = lockInfo.BatchNo,
                        factory = lockInfo.FactoryArea,
                        date = DateTime.Now.ToString("yyyy-MM-dd"),
                    });
                    splitResults.Add(new SplitResult
                    {
                        materialCode = lockInfo.MaterielCode,
@@ -450,12 +443,12 @@
                        factory = lockInfo.FactoryArea,
                        date = DateTime.Now.ToString("yyyy-MM-dd"),
                    });
                    // æ›´æ–°æ‹£é€‰è®°å½•中的条码为新条码
                    barcode = newBarcode;
                    lockInfo = newLockInfo;
                    finalLockInfo = newLockInfo;
                    finalBarcode = newBarcode;
                    finalStockId = stockDetail.Id; // ä½¿ç”¨åŽŸåº“å­˜ID
                    finalStockId = stockDetail.Id;
                }
                else if (actualQty == stockQuantity)
                {
@@ -467,6 +460,7 @@
                    lockInfo.PickedQty += actualQty;
                    lockInfo.Status = (int)OutLockStockStatusEnum.拣选完成;
                    await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync();
                    finalLockInfo = lockInfo;
                    finalBarcode = barcode;
                    finalStockId = stockDetail.Id;
@@ -474,51 +468,53 @@
                else
                {
                    // æƒ…况3: åˆ†é…æ•°é‡å¤§äºŽåº“存数量,库存整包出库
                    // æ•´åŒ…出库当前库存
                    decimal stockOutQty = stockQuantity;
                    stockDetail.StockQuantity = 0;
                    stockDetail.OutboundQuantity = 0;
                    await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync();
                    // è®¡ç®—剩余分配数量
                    decimal remainingAssignQty = actualQty - stockQuantity;
                    // æ›´æ–°é”å®šä¿¡æ¯ï¼ˆåªå®Œæˆåº“存部分)
                    lockInfo.PickedQty += stockOutQty;
                    lockInfo.AssignQuantity = remainingAssignQty;
                    await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync();
                    var _relatedSplitRecords = await _splitPackageService.Db.Queryable<Dt_SplitPackageRecord>()
                                                .Where(it => it.OriginalBarcode == barcode || it.NewBarcode == barcode)
                                                .Where(it => !it.IsReverted)
                                                .ToListAsync();
                        .Where(it => it.OriginalBarcode == barcode || it.NewBarcode == barcode)
                        .Where(it => !it.IsReverted)
                        .ToListAsync();
                    foreach (var record in _relatedSplitRecords)
                    {
                        record.Status = (int)SplitPackageStatusEnum.已拣选;
                        await _splitPackageService.Db.Updateable(record).ExecuteCommandAsync();
                    }
                    finalLockInfo = lockInfo;
                    finalBarcode = barcode;
                    finalStockId = stockDetail.Id;
                    actualPickedQty = stockOutQty; // å®žé™…拣选数量调整为库存数量
                }
                // æ›´æ–°è®¢å•明细的拣选数量和已出库数量
                await _outboundOrderDetailService.Db.Updateable<Dt_OutboundOrderDetail>()
                    .SetColumns(it => it.PickedQty == it.PickedQty + actualQty)
                    .SetColumns(it => new Dt_OutboundOrderDetail
                    {
                        PickedQty = it.PickedQty + actualPickedQty,
                        OverOutQuantity = it.OverOutQuantity + actualPickedQty
                    })
                    .Where(it => it.Id == lockInfo.OrderDetailId)
                    .ExecuteCommandAsync();
                await CheckAndUpdateOrderStatus(orderNo);
                // æŸ¥è¯¢ä»»åŠ¡è¡¨
                // æŸ¥è¯¢ä»»åŠ¡è¡¨
                var task = _taskRepository.QueryData(x => x.OrderNo == orderNo && x.PalletCode == palletCode).FirstOrDefault();
                if (finalLockInfo.Id <= 0)
                {
                    throw new Exception($"锁定信息ID无效: {finalLockInfo.Id},无法记录拣选历史");
                }
                // è®°å½•拣选历史
                var pickingHistory = new Dt_PickingRecord
                {
@@ -531,7 +527,7 @@
                    PalletCode = palletCode,
                    Barcode = finalBarcode,
                    MaterielCode = finalLockInfo.MaterielCode,
                    PickQuantity = actualQty,
                    PickQuantity = actualPickedQty,
                    PickTime = DateTime.Now,
                    Operator = App.User.UserName,
                    OutStockLockId = finalLockInfo.Id
@@ -540,22 +536,21 @@
                _unitOfWorkManage.CommitTran();
                // å¦‚果有拆包结果,返回拆包信息
                if (splitResults.Any())
                {
                    return WebResponseContent.Instance.OK("拣选确认成功,已自动拆包", new { SplitResults = splitResults });
                }
                return WebResponseContent.Instance.OK("拣选确认成功", new { SplitResults = splitResults });
                return WebResponseContent.Instance.OK("拣选确认成功");
            }
            catch (Exception ex)
            {
                _unitOfWorkManage.RollbackTran();
                _logger.LogError($"ConfirmPicking失败 - OrderNo: {orderNo}, PalletCode: {palletCode}, Barcode: {barcode}, Error: {ex.Message}");
                return WebResponseContent.Instance.Error($"拣选确认失败:{ex.Message}");
            }
        }
        /// <summary>
        /// å›žåº“操作  
        /// </summary>