From 51579a9535b27cdf71cd6d1a8e5d45c581d49467 Mon Sep 17 00:00:00 2001
From: pan <antony1029@163.com>
Date: 星期五, 21 十一月 2025 15:28:50 +0800
Subject: [PATCH] 提交

---
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundPickingService.cs |  361 ++++++++++++++++++++++++++++++++-------------------
 1 files changed, 225 insertions(+), 136 deletions(-)

diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundPickingService.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundPickingService.cs"
index 5cf4570..4c19d90 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundPickingService.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundPickingService.cs"
@@ -253,55 +253,35 @@
 
         public async Task<WebResponseContent> ConfirmPicking(string orderNo, string palletCode, string barcode)
         {
-            #region "娴嬭瘯鎵撳嵃"
-            // var splitResults=new List<SplitResult>();
-            //  splitResults.Add(new SplitResult
-            //{
-            //    materialCode = "AAAAbbb",
-            //    supplierCode = "CVBG",
-            //    quantityTotal = "1234",
-            //    batchNumber = "WMLOT25111900032",
-            //    batch = "A234re",
-            //    factory = "01",
-            //    date = DateTime.Now.ToString("yyyy-MM-dd"),
-            //});
-
-            //splitResults.Add(new SplitResult
-            //{
-            //    materialCode = "CCDF",
-            //    supplierCode = "QWCVBG",
-            //    quantityTotal = "1234",
-            //    batchNumber = "WMLOT25111900032",
-            //    batch = "A234re",
-            //    factory = "01",
-            //    date = DateTime.Now.ToString("yyyy-MM-dd"),
-            //});
-
-            // return WebResponseContent.Instance.OK("鎷i�夌‘璁ゆ垚鍔燂紝宸茶嚜鍔ㄦ媶鍖�", new { SplitResults = splitResults });
-            #endregion
             try
             {
                 _unitOfWorkManage.BeginTran();
 
+                // 1. 楠岃瘉杈撳叆鍙傛暟
+                if (string.IsNullOrEmpty(orderNo) || string.IsNullOrEmpty(palletCode) || string.IsNullOrEmpty(barcode))
+                {
+                    throw new Exception("璁㈠崟鍙枫�佹墭鐩樼爜鍜屾潯鐮佷笉鑳戒负绌�");
+                }
+
+                // 2. 鏌ユ壘鍑哄簱閿佸畾淇℃伅
                 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) // 澧炲姞锛氭鏌ュ垎鎷h繘搴�
+                                   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.鎷i�夊畬鎴� ||
@@ -318,12 +298,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,32 +311,48 @@
                     throw new Exception($"鏉$爜{barcode}宸茬粡鍒嗘嫞杩囷紝涓嶈兘閲嶅鍒嗘嫞");
                 }
 
+                // 鑾峰彇璁㈠崟鏄庣粏骞舵鏌ユ暟閲忛檺鍒�
+                var orderDetail = 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 (orderDetail == null)
+                    throw new Exception($"鏈壘鍒拌鍗曟槑缁嗭紝ID: {lockInfo.OrderDetailId}");
+
+                // 鍏抽敭淇锛氭鏌ョ疮璁℃嫞閫夋暟閲忔槸鍚︿細瓒呰繃璁㈠崟鏁伴噺
+                decimal actualQty = lockInfo.AssignQuantity - lockInfo.PickedQty;
+                decimal remainingOrderQty = orderDetail.NeedOutQuantity - orderDetail.OverOutQuantity;
+
+                if (actualQty > remainingOrderQty)
                 {
-                    throw new Exception($"鏉$爜{barcode}鐨勫嚭搴撴暟閲忓ぇ浜庤鍗曠殑鏁伴噺");
+                    // 濡傛灉鍒嗛厤鏁伴噺澶т簬鍓╀綑璁㈠崟鏁伴噺锛岃皟鏁村疄闄呮嫞閫夋暟閲�
+                    actualQty = remainingOrderQty;
+
+                    if (actualQty <= 0)
+                    {
+                        throw new Exception($"璁㈠崟{orderNo}鐨勯渶姹傛暟閲忓凡婊¤冻锛屾棤娉曠户缁垎鎷�");
+                    }
+
+                    _logger.LogWarning($"璋冩暣鍒嗘嫞鏁伴噺锛氬師鍒嗛厤{lockInfo.AssignQuantity - lockInfo.PickedQty}锛岃皟鏁翠负{actualQty}锛岃鍗曢渶姹倇orderDetail.NeedOutQuantity}锛屽凡鍑哄簱{orderDetail.OverOutQuantity}");
                 }
 
                 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("鏃犳晥鐨勬潯鐮佹垨鐗╂枡缂栫爜");
 
-                decimal actualQty = lockInfo.AssignQuantity - lockInfo.PickedQty;
                 decimal stockQuantity = stockDetail.StockQuantity;
 
                 List<SplitResult> splitResults = new List<SplitResult>();
                 Dt_OutStockLockInfo finalLockInfo = lockInfo;
                 var finalBarcode = barcode;
                 var finalStockId = stockDetail.Id;
+                decimal actualPickedQty = actualQty;
 
                 if (actualQty < stockQuantity)
                 {
                     // 鎯呭喌1: 鍒嗛厤鏁伴噺灏忎簬搴撳瓨鏁伴噺锛岄渶瑕佽嚜鍔ㄦ媶鍖�
-                    // 璁$畻鍓╀綑搴撳瓨鏁伴噺
                     decimal remainingStockQty = stockQuantity - actualQty;
 
                     // 鏇存柊鍘熸潯鐮佸簱瀛樹负鍓╀綑鏁伴噺
@@ -369,11 +360,11 @@
                     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 +389,11 @@
                         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,
@@ -426,7 +417,6 @@
                     // 鏇存柊鍘熼攣瀹氫俊鎭负鍓╀綑搴撳瓨鏁伴噺
                     lockInfo.AssignQuantity = remainingStockQty;
                     lockInfo.PickedQty = 0;
-
                     await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync();
 
                     splitResults.Add(new SplitResult
@@ -438,8 +428,8 @@
                         batch = lockInfo.BatchNo,
                         factory = lockInfo.FactoryArea,
                         date = DateTime.Now.ToString("yyyy-MM-dd"),
-
                     });
+
                     splitResults.Add(new SplitResult
                     {
                         materialCode = lockInfo.MaterielCode,
@@ -450,12 +440,9 @@
                         factory = lockInfo.FactoryArea,
                         date = DateTime.Now.ToString("yyyy-MM-dd"),
                     });
-                    // 鏇存柊鎷i�夎褰曚腑鐨勬潯鐮佷负鏂版潯鐮�
-                    barcode = newBarcode;
-                    lockInfo = newLockInfo;
+
                     finalLockInfo = newLockInfo;
                     finalBarcode = newBarcode;
-                    finalStockId = stockDetail.Id; // 浣跨敤鍘熷簱瀛業D
                 }
                 else if (actualQty == stockQuantity)
                 {
@@ -467,58 +454,63 @@
                     lockInfo.PickedQty += actualQty;
                     lockInfo.Status = (int)OutLockStockStatusEnum.鎷i�夊畬鎴�;
                     await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync();
-                    finalLockInfo = lockInfo;
-                    finalBarcode = barcode;
-                    finalStockId = stockDetail.Id;
                 }
                 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();
+                    var relatedSplitRecords = await _splitPackageService.Db.Queryable<Dt_SplitPackageRecord>()
+                        .Where(it => it.OriginalBarcode == barcode || it.NewBarcode == barcode)
+                        .Where(it => !it.IsReverted)
+                        .ToListAsync();
 
-                    foreach (var record in _relatedSplitRecords)
+                    foreach (var record in relatedSplitRecords)
                     {
                         record.Status = (int)SplitPackageStatusEnum.宸叉嫞閫�;
                         await _splitPackageService.Db.Updateable(record).ExecuteCommandAsync();
                     }
-                    finalLockInfo = lockInfo;
-                    finalBarcode = barcode;
-                    finalStockId = stockDetail.Id;
+
+                    actualPickedQty = stockOutQty;
                 }
 
+                // 鍏抽敭淇锛氬啀娆℃鏌ヨ鍗曟暟閲忛檺鍒�
+                decimal newOverOutQuantity = orderDetail.OverOutQuantity + actualPickedQty;
+                decimal newPickedQty = orderDetail.PickedQty + actualPickedQty;
 
+                if (newOverOutQuantity > orderDetail.NeedOutQuantity)
+                {
+                    throw new Exception($"鍒嗘嫞鍚庡皢瀵艰嚧宸插嚭搴撴暟閲�({newOverOutQuantity})瓒呰繃璁㈠崟闇�姹傛暟閲�({orderDetail.NeedOutQuantity})");
+                }
 
+                // 鏇存柊璁㈠崟鏄庣粏
                 await _outboundOrderDetailService.Db.Updateable<Dt_OutboundOrderDetail>()
-                    .SetColumns(it => it.PickedQty == it.PickedQty + actualQty)
+                    .SetColumns(it => new Dt_OutboundOrderDetail
+                    {
+                        PickedQty = newPickedQty,
+                        OverOutQuantity = newOverOutQuantity
+                    })
                     .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}锛屾棤娉曡褰曟嫞閫夊巻鍙�");
                 }
+
                 // 璁板綍鎷i�夊巻鍙�
                 var pickingHistory = new Dt_PickingRecord
                 {
@@ -531,7 +523,7 @@
                     PalletCode = palletCode,
                     Barcode = finalBarcode,
                     MaterielCode = finalLockInfo.MaterielCode,
-                    PickQuantity = actualQty,
+                    PickQuantity = actualPickedQty,
                     PickTime = DateTime.Now,
                     Operator = App.User.UserName,
                     OutStockLockId = finalLockInfo.Id
@@ -540,19 +532,171 @@
 
                 _unitOfWorkManage.CommitTran();
 
-                // 濡傛灉鏈夋媶鍖呯粨鏋滐紝杩斿洖鎷嗗寘淇℃伅
                 if (splitResults.Any())
                 {
                     return WebResponseContent.Instance.OK("鎷i�夌‘璁ゆ垚鍔燂紝宸茶嚜鍔ㄦ媶鍖�", new { SplitResults = splitResults });
                 }
 
-                return WebResponseContent.Instance.OK("鎷i�夌‘璁ゆ垚鍔�", new { SplitResults = splitResults });
+                return WebResponseContent.Instance.OK("鎷i�夌‘璁ゆ垚鍔�", new { SplitResults = new List<SplitResult>() });
 
             }
             catch (Exception ex)
             {
                 _unitOfWorkManage.RollbackTran();
+                _logger.LogError($"ConfirmPicking澶辫触 - OrderNo: {orderNo}, PalletCode: {palletCode}, Barcode: {barcode}, Error: {ex.Message}");
                 return WebResponseContent.Instance.Error($"鎷i�夌‘璁ゅけ璐ワ細{ex.Message}");
+            }
+        }
+
+        public async Task<WebResponseContent> CancelPicking(string orderNo, string palletCode, string barcode)
+        {
+            try
+            {
+                _unitOfWorkManage.BeginTran();
+
+                // 鏌ユ壘鎷i�夎褰�
+                var pickingRecord = await Db.Queryable<Dt_PickingRecord>()
+                    .Where(it => it.OrderNo == orderNo &&
+                               it.PalletCode == palletCode &&
+                               it.Barcode == barcode)
+                    .OrderByDescending(it => it.PickTime)
+                    .FirstAsync();
+
+                if (pickingRecord == null)
+                    return WebResponseContent.Instance.Error("鏈壘鍒板搴旂殑鎷i�夎褰�");
+
+                // 鏌ユ壘鍑哄簱閿佸畾淇℃伅
+                var lockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+                    .Where(it => it.Id == pickingRecord.OutStockLockId)
+                    .FirstAsync();
+
+                if (lockInfo == null)
+                    return WebResponseContent.Instance.Error("鏈壘鍒板搴旂殑鍑哄簱閿佸畾淇℃伅");
+
+                // 妫�鏌ユ槸鍚﹀彲浠ュ彇娑�
+                if (lockInfo.Status != (int)OutLockStockStatusEnum.鎷i�夊畬鎴�)
+                    return WebResponseContent.Instance.Error("褰撳墠鐘舵�佷笉鍏佽鍙栨秷鍒嗘嫞");
+
+                decimal cancelQty = pickingRecord.PickQuantity;
+
+                // 鑾峰彇璁㈠崟鏄庣粏
+                var orderDetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
+                    .FirstAsync(x => x.Id == pickingRecord.OrderDetailId);
+
+                if (orderDetail == null)
+                    throw new Exception($"鏈壘鍒拌鍗曟槑缁嗭紝ID: {pickingRecord.OrderDetailId}");
+
+                // 鍏抽敭淇锛氭鏌ュ彇娑堝悗鏁伴噺涓嶄細涓鸿礋鏁�
+                decimal newOverOutQuantity = orderDetail.OverOutQuantity - cancelQty;
+                decimal newPickedQty = orderDetail.PickedQty - cancelQty;
+
+                if (newOverOutQuantity < 0 || newPickedQty < 0)
+                {
+                    throw new Exception($"鍙栨秷鍒嗘嫞灏嗗鑷村凡鍑哄簱鏁伴噺鎴栧凡鎷i�夋暟閲忎负璐熸暟");
+                }
+
+                // 澶勭悊鍙栨秷閫昏緫
+                if (lockInfo.IsSplitted == 1 && lockInfo.ParentLockId.HasValue)
+                {
+                    await HandleSplitBarcodeCancel(lockInfo, pickingRecord, cancelQty);
+                }
+                else
+                {
+                    await HandleNormalBarcodeCancel(lockInfo, pickingRecord, cancelQty);
+                }
+
+                // 鏇存柊璁㈠崟鏄庣粏
+                await _outboundOrderDetailService.Db.Updateable<Dt_OutboundOrderDetail>()
+                    .SetColumns(it => new Dt_OutboundOrderDetail
+                    {
+                        PickedQty = newPickedQty,
+                        OverOutQuantity = newOverOutQuantity
+                    })
+                    .Where(it => it.Id == pickingRecord.OrderDetailId)
+                    .ExecuteCommandAsync();
+
+                // 鍒犻櫎鎷i�夎褰�
+                await Db.Deleteable<Dt_PickingRecord>()
+                    .Where(x => x.Id == pickingRecord.Id)
+                    .ExecuteCommandAsync();
+
+                // 閲嶆柊妫�鏌ヨ鍗曠姸鎬�
+                await CheckAndUpdateOrderStatus(orderNo);
+
+                _unitOfWorkManage.CommitTran();
+                return WebResponseContent.Instance.OK($"鍙栨秷鍒嗘嫞鎴愬姛锛屾仮澶嶆暟閲忥細{cancelQty}");
+            }
+            catch (Exception ex)
+            {
+                _unitOfWorkManage.RollbackTran();
+                _logger.LogError($"CancelPicking澶辫触 - OrderNo: {orderNo}, PalletCode: {palletCode}, Barcode: {barcode}, Error: {ex.Message}");
+                return WebResponseContent.Instance.Error($"鍙栨秷鍒嗘嫞澶辫触锛歿ex.Message}");
+            }
+        }
+
+        private async Task HandleSplitBarcodeCancel(Dt_OutStockLockInfo lockInfo, Dt_PickingRecord pickingRecord, decimal cancelQty)
+        {
+            // 鏌ユ壘鐖堕攣瀹氫俊鎭�
+            var parentLockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+                .Where(x => x.Id == lockInfo.ParentLockId.Value)
+                .FirstAsync();
+
+            if (parentLockInfo == null)
+            {
+                throw new Exception("鏈壘鍒扮埗閿佸畾淇℃伅锛屾棤娉曞彇娑堟媶鍖呭垎鎷�");
+            }
+
+            // 鎭㈠鐖堕攣瀹氫俊鎭殑鍒嗛厤鏁伴噺
+            parentLockInfo.AssignQuantity += cancelQty;
+            await _outStockLockInfoService.Db.Updateable(parentLockInfo).ExecuteCommandAsync();
+
+            // 鎭㈠搴撳瓨
+            var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
+                .Where(x => x.Barcode == parentLockInfo.CurrentBarcode && x.StockId == parentLockInfo.StockId)
+                .FirstAsync();
+
+            if (stockDetail != null)
+            {
+                stockDetail.StockQuantity += cancelQty;
+                stockDetail.OutboundQuantity += cancelQty;
+                await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync();
+            }
+
+            // 鏇存柊鎷嗗寘璁板綍鐘舵��
+            await _splitPackageService.Db.Updateable<Dt_SplitPackageRecord>()
+                .SetColumns(x => new Dt_SplitPackageRecord
+                {
+                    Status = (int)SplitPackageStatusEnum.宸叉挙閿�,
+                    IsReverted = true
+                })
+                .Where(x => x.NewBarcode == lockInfo.CurrentBarcode && !x.IsReverted)
+                .ExecuteCommandAsync();
+
+            // 鍒犻櫎鎷嗗寘浜х敓鐨勯攣瀹氫俊鎭�
+            await _outStockLockInfoService.Db.Deleteable<Dt_OutStockLockInfo>()
+                .Where(x => x.Id == lockInfo.Id)
+                .ExecuteCommandAsync();
+        }
+
+        private async Task HandleNormalBarcodeCancel(Dt_OutStockLockInfo lockInfo, Dt_PickingRecord pickingRecord, decimal cancelQty)
+        {
+            // 鎭㈠閿佸畾淇℃伅
+            lockInfo.PickedQty -= cancelQty;
+            if (lockInfo.PickedQty < 0) lockInfo.PickedQty = 0;
+
+            lockInfo.Status = (int)OutLockStockStatusEnum.鍑哄簱涓�;
+            await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync();
+
+            // 鎭㈠搴撳瓨
+            var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
+                .Where(x => x.Barcode == pickingRecord.Barcode && x.StockId == pickingRecord.StockId)
+                .FirstAsync();
+
+            if (stockDetail != null)
+            {
+                stockDetail.StockQuantity += cancelQty;
+                stockDetail.OutboundQuantity += cancelQty;
+                await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync();
             }
         }
 
@@ -899,62 +1043,7 @@
             return outboundFinished && hasRemainingGoods;
         }
 
-        // 鍙栨秷鎷i�夊姛鑳�
-        public async Task<WebResponseContent> CancelPicking(string orderNo, string palletCode, string barcode)
-        {
-            try
-            {
-                _unitOfWorkManage.BeginTran();
-
-                //鏌ユ壘鎷i�夎褰�
-                var pickingRecord = await Db.Queryable<Dt_PickingRecord>()
-                    .Where(it => it.OrderNo == orderNo &&
-                               it.PalletCode == palletCode &&
-                               it.Barcode == barcode)
-                    .OrderByDescending(it => it.PickTime)
-                    .FirstAsync();
-
-                if (pickingRecord == null)
-                    return WebResponseContent.Instance.Error("鏈壘鍒板搴旂殑鎷i�夎褰�");
-
-                // 鏌ユ壘鍑哄簱閿佸畾淇℃伅
-                var lockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
-                    .Where(it => it.Id == pickingRecord.OutStockLockId)
-                    .FirstAsync();
-
-                if (lockInfo == null)
-                    return WebResponseContent.Instance.Error("鏈壘鍒板搴旂殑鍑哄簱閿佸畾淇℃伅");
-
-                //妫�鏌ユ槸鍚﹀彲浠ュ彇娑堬紙鐘舵�佸繀椤绘槸鎷i�夊畬鎴愶級
-                if (lockInfo.Status != (int)OutLockStockStatusEnum.鎷i�夊畬鎴�)
-                    return WebResponseContent.Instance.Error("褰撳墠鐘舵�佷笉鍏佽鍙栨秷鍒嗘嫞");
-
-                decimal cancelQty = pickingRecord.PickQuantity;
-
-                // 妫�鏌ユ媶鍖呴摼鍏崇郴
-                var splitChain = await GetSplitChain(barcode);
-
-                if (splitChain.Any())
-                {
-                    // 鎯呭喌A锛氬鐞嗘媶鍖呴摼鐨勫彇娑堬紙澶氭鎵嬪姩鎷嗗寘锛�
-                    await HandleSplitChainCancel(orderNo, palletCode, barcode, cancelQty, lockInfo, pickingRecord, splitChain);
-                }
-                else
-                {
-                    // 鎯呭喌B锛氬鐞嗘櫘閫氭潯鐮佺殑鍙栨秷
-                    await HandleNormalBarcodeCancel(orderNo, palletCode, barcode, cancelQty, lockInfo, pickingRecord);
-                }
-
-                _unitOfWorkManage.CommitTran();
-                return WebResponseContent.Instance.OK($"鍙栨秷鍒嗘嫞鎴愬姛锛屾仮澶嶆暟閲忥細{cancelQty}");
-            }
-            catch (Exception ex)
-            {
-                _unitOfWorkManage.RollbackTran();
-                return WebResponseContent.Instance.Error($"鍙栨秷鍒嗘嫞澶辫触锛歿ex.Message}");
-            }
-        }
-
+ 
         /// <summary>
         /// 鑾峰彇鎷嗗寘閾撅紙浠庡綋鍓嶆潯鐮佽拷婧埌鍘熷鏉$爜锛�
         /// </summary>

--
Gitblit v1.9.3