From 482aa82a99419383848cabbdf135744259b17c77 Mon Sep 17 00:00:00 2001
From: pan <antony1029@163.com>
Date: 星期五, 21 十一月 2025 18:59:23 +0800
Subject: [PATCH] 提交

---
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundPickingService.cs | 1933 ++++++++++++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 1,609 insertions(+), 324 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 06a4835..90abb47 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"
@@ -1,6 +1,8 @@
 锘縰sing Dm.filter;
 using MailKit.Search;
 using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Logging;
 using SqlSugar;
 using System;
 using System.Collections.Generic;
@@ -10,10 +12,13 @@
 using WIDESEA_Common.LocationEnum;
 using WIDESEA_Common.OrderEnum;
 using WIDESEA_Common.StockEnum;
+using WIDESEA_Common.TaskEnum;
 using WIDESEA_Core;
 using WIDESEA_Core.BaseRepository;
 using WIDESEA_Core.BaseServices;
 using WIDESEA_Core.Helper;
+using WIDESEA_DTO.Basic;
+using WIDESEA_DTO.Inbound;
 using WIDESEA_DTO.Outbound;
 using WIDESEA_IBasicService;
 using WIDESEA_IOutboundService;
@@ -39,9 +44,30 @@
         private readonly IOutboundOrderService _outboundOrderService;
         private readonly ISplitPackageService _splitPackageService;
         private readonly IRepository<Dt_Task> _taskRepository;
+        private readonly IESSApiService _eSSApiService;
+        private readonly IInvokeMESService _invokeMESService;
+        private readonly IDailySequenceService _dailySequenceService;
 
+        private readonly ILogger<OutboundPickingService> _logger;
 
-        public OutboundPickingService(IRepository<Dt_PickingRecord> BaseDal, IUnitOfWorkManage unitOfWorkManage, IStockInfoService stockInfoService, IStockService stockService, IOutStockLockInfoService outStockLockInfoService, IStockInfoDetailService stockInfoDetailService, ILocationInfoService locationInfoService, IOutboundOrderDetailService outboundOrderDetailService, ISplitPackageService splitPackageService, IOutboundOrderService outboundOrderService, IRepository<Dt_Task> taskRepository) : base(BaseDal)
+        private Dictionary<string, string> stations = new Dictionary<string, string>
+        {
+            {"2-1","2-9" },
+            {"3-1","3-9" },
+
+        };
+
+        private Dictionary<string, string> movestations = new Dictionary<string, string>
+        {
+            {"2-1","2-5" },
+            {"3-1","3-5" },
+
+        };
+
+        public OutboundPickingService(IRepository<Dt_PickingRecord> BaseDal, IUnitOfWorkManage unitOfWorkManage, IStockInfoService stockInfoService, IStockService stockService,
+            IOutStockLockInfoService outStockLockInfoService, IStockInfoDetailService stockInfoDetailService, ILocationInfoService locationInfoService,
+            IOutboundOrderDetailService outboundOrderDetailService, ISplitPackageService splitPackageService, IOutboundOrderService outboundOrderService,
+            IRepository<Dt_Task> taskRepository, IESSApiService eSSApiService, ILogger<OutboundPickingService> logger, IInvokeMESService invokeMESService, IDailySequenceService dailySequenceService) : base(BaseDal)
         {
             _unitOfWorkManage = unitOfWorkManage;
             _stockInfoService = stockInfoService;
@@ -53,6 +79,10 @@
             _splitPackageService = splitPackageService;
             _outboundOrderService = outboundOrderService;
             _taskRepository = taskRepository;
+            _eSSApiService = eSSApiService;
+            _logger = logger;
+            _invokeMESService = invokeMESService;
+            _dailySequenceService = dailySequenceService;
         }
 
 
@@ -117,183 +147,19 @@
             }
         }
 
-        /// <summary>
-        /// 鎵爜鎷i�夌‘璁� 
-        /// </summary>
-        public async Task<WebResponseContent> ConfirmPicking(PickingConfirmRequest request)
-        {
-            try
-            {
-                _unitOfWorkManage.BeginTran();
-
-                // 1. 楠岃瘉鏉$爜鏈夋晥鎬�
-                var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
-                    .Where(x => x.Barcode == request.Barcode && x.MaterielCode == request.MaterielCode)
-                    .FirstAsync();
-
-                if (stockDetail == null)
-                    return WebResponseContent.Instance.Error("鏃犳晥鐨勬潯鐮佹垨鐗╂枡缂栫爜");
-
-                // 2. 妫�鏌ュ簱瀛樺彲鐢ㄦ暟閲�
-                decimal availableQuantity = stockDetail.StockQuantity - stockDetail.OutboundQuantity;
-                if (request.PickQuantity > availableQuantity)
-                    return WebResponseContent.Instance.Error($"鎷i�夋暟閲忚秴杩囧彲鐢ㄥ簱瀛橈紝鍙敤鏁伴噺锛歿availableQuantity}");
-
-                // 3. 鏌ユ壘鐩稿叧鐨勫嚭搴撻攣瀹氫俊鎭紙鏀寔鎷嗗寘鍚庣殑鏂版潯鐮侊級
-                var lockInfo = await FindLockInfoByBarcode(request.OrderDetailId, request.Barcode, request.MaterielCode);
-
-                if (lockInfo == null)
-                    return WebResponseContent.Instance.Error("鏈壘鍒扮浉鍏崇殑鍑哄簱閿佸畾淇℃伅");
-
-                // 4. 妫�鏌ラ攣瀹氭暟閲�
-                decimal remainingLockQuantity = lockInfo.AssignQuantity - lockInfo.PickedQty;
-                if (request.PickQuantity > remainingLockQuantity)
-                    return WebResponseContent.Instance.Error($"鎷i�夋暟閲忚秴杩囬攣瀹氭暟閲忥紝鍓╀綑鍙嫞閫夛細{remainingLockQuantity}");
-
-                // 5. 鏇存柊閿佸畾淇℃伅鐨勫凡鎷i�夋暟閲�
-                lockInfo.PickedQty += request.PickQuantity;
-                await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync();
-
-                // 6. 鏇存柊搴撳瓨鍑哄簱鏁伴噺 - 瀹為檯鍑忓皯搴撳瓨
-                stockDetail.OutboundQuantity += request.PickQuantity;
-                await _stockInfoService.Db.Updateable(stockDetail).ExecuteCommandAsync();
-
-                // 7. 鏇存柊鍑哄簱鍗曟槑缁�
-                var orderDetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
-                    .Where(x => x.Id == request.OrderDetailId)
-                    .FirstAsync();
-
-                orderDetail.OverOutQuantity += request.PickQuantity;
-                orderDetail.LockQuantity -= request.PickQuantity;
-
-                // 妫�鏌ユ槸鍚﹀畬鎴愬嚭搴�
-                if (Math.Abs(orderDetail.OverOutQuantity - orderDetail.OrderQuantity) < 0.001m)
-                {
-                    orderDetail.OrderDetailStatus = (int)OrderDetailStatusEnum.Over;
-                    orderDetail.LockQuantity = 0;
-
-                    // 鏇存柊鐩稿叧鐨勯攣瀹氫俊鎭姸鎬佷负宸插嚭搴�
-                    var relatedLockInfos = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
-                        .Where(x => x.OrderDetailId == request.OrderDetailId &&
-                                   x.Status == (int)OutLockStockStatusEnum.鍑哄簱涓�)
-                        .ToListAsync();
-
-                    foreach (var relatedLock in relatedLockInfos)
-                    {
-                        relatedLock.Status = (int)OutLockStockStatusEnum.宸插嚭搴�;
-                    }
-                    await _outStockLockInfoService.Db.Updateable(relatedLockInfos).ExecuteCommandAsync();
-                }
-
-                await _outboundOrderDetailService.Db.Updateable(orderDetail).ExecuteCommandAsync();
-
-                // 8. 璁板綍鎷i�夊巻鍙�
-                var pickHistory = new Dt_PickingRecord
-                {
-                    OrderDetailId = request.OrderDetailId,
-                    Barcode = request.Barcode,
-                    PickQuantity = request.PickQuantity,
-                    PickTime = DateTime.Now,
-
-                    LocationCode = request.LocationCode,
-                    StockId = stockDetail.StockId
-                };
-                await Db.Insertable(pickHistory).ExecuteCommandAsync();
-
-                _unitOfWorkManage.CommitTran();
-
-                return WebResponseContent.Instance.OK("鎷i�夌‘璁ゆ垚鍔�");
-            }
-            catch (Exception ex)
-            {
-                _unitOfWorkManage.RollbackTran();
-                return WebResponseContent.Instance.Error($"鎷i�夌‘璁ゅけ璐�: {ex.Message}");
-            }
-        }
-
-        public async Task<WebResponseContent> ConfirmPicking(string orderNo, string palletCode, string barcode)
-        {
-            try
-            {
-                _unitOfWorkManage.BeginTran();
-                var lockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
-                  .Where(it => it.OrderNo == orderNo &&
-                             it.Status == (int)OutLockStockStatusEnum.鍑哄簱涓� &&
-                             it.PalletCode == palletCode &&
-                             it.CurrentBarcode == barcode)
-                  .FirstAsync();
-
-                if (lockInfo == null)
-                    throw new Exception($"鏉$爜{barcode}涓嶅睘浜庢墭鐩榹palletCode}鎴栦笉瀛樺湪寰呭垎鎷h褰�");
-
-
-
-                var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
-                        .Where(x => x.Barcode == barcode && x.StockId == lockInfo.StockId)
-                        .FirstAsync();
-
-                if (stockDetail == null)
-                    return WebResponseContent.Instance.Error("鏃犳晥鐨勬潯鐮佹垨鐗╂枡缂栫爜");
-
-
-                decimal actualQty = lockInfo.AssignQuantity - lockInfo.PickedQty;
-
-                // 4. 鏇存柊搴撳瓨
-                stockDetail.StockQuantity -= actualQty;
-                stockDetail.OutboundQuantity -= actualQty;
-                await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync();
-
-                lockInfo.PickedQty += actualQty;
-                lockInfo.Status = (int)OutLockStockStatusEnum.鎷i�夊畬鎴�;
-                await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync();
-
-
-                await _outboundOrderDetailService.Db.Updateable<Dt_OutboundOrderDetail>()
-               .SetColumns(it => it.PickedQty == it.PickedQty + actualQty)
-               .Where(it => it.Id == lockInfo.OrderDetailId)
-               .ExecuteCommandAsync();
-
-                
-                await CheckAndUpdateOrderStatus(orderNo);
-
-                //鏌ヨ浠诲姟琛� 
-                var task = _taskRepository.QueryData(x => x.OrderNo == orderNo && x.PalletCode == palletCode).FirstOrDefault();
-                // 9. 璁板綍鎷i�夊巻鍙�
-                var pickingHistory = new Dt_PickingRecord
-                {
-                    FactoryArea = lockInfo.FactoryArea,
-                    TaskNo = task?.TaskNum ?? 0,
-                    LocationCode = task?.SourceAddress ?? "",
-                    StockId = stockDetail.Id,
-                    OrderNo = orderNo,
-                    OrderDetailId = lockInfo.OrderDetailId,
-                    PalletCode = palletCode,
-                    Barcode = barcode,
-                    MaterielCode = lockInfo.MaterielCode,
-                    PickQuantity = lockInfo.AssignQuantity,
-                    PickTime = DateTime.Now,
-                    Operator = App.User.UserName,
-                    OutStockLockId = lockInfo.Id
-                };
-                await Db.Insertable(pickingHistory).ExecuteCommandAsync();
-
-                _unitOfWorkManage.CommitTran();
-                return WebResponseContent.Instance.OK("鎷i�夌‘璁ゆ垚鍔�");
-
-            }
-            catch (Exception ex)
-            {
-                return WebResponseContent.Instance.Error($"鎷i�夌‘璁ゅけ璐ワ細{ex.Message}");
-            }
-        }
         // 妫�鏌ュ苟鏇存柊璁㈠崟鐘舵��
         private async Task CheckAndUpdateOrderStatus(string orderNo)
         {
 
+            var orderDetails = _stockInfoDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
+                      .LeftJoin<Dt_OutboundOrder>((o, item) => o.OrderId == item.Id) // 鍏宠仈鏉′欢锛氱埗琛� Id = 瀛愯〃 OrderId
+                      .Where((o, item) => item.OrderNo == orderNo) // 杩囨护鐖惰〃 OrderNo
+                      .Select((o, item) => o) // 鍙繑鍥炲瓙琛ㄦ暟鎹�
+                      .ToList();
 
-            var orderDetails = await _stockInfoDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
-                .Where(x => x.OrderId == orderNo.ObjToInt())
-                .ToListAsync();
+            //var orderDetails = await _stockInfoDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
+            //    .Where(x => x.OrderId == orderNo.ObjToInt())
+            //    .ToListAsync();
 
             bool allCompleted = true;
             foreach (var detail in orderDetails)
@@ -307,75 +173,1566 @@
 
             if (allCompleted)
             {
-                await _outboundOrderService.Db.Updateable<Dt_OutboundOrder>()
-                    .SetColumns(x => x.OrderStatus == 2) // 宸插畬鎴�
-                    .Where(x => x.OrderNo == orderNo)
-                    .ExecuteCommandAsync();
+                try
+                {
+                    await _outboundOrderService.Db.Updateable<Dt_OutboundOrder>()
+                        .SetColumns(x => x.OrderStatus == 2) // 宸插畬鎴�
+                        .Where(x => x.OrderNo == orderNo)
+                        .ExecuteCommandAsync();
+
+                    var outboundOrder = _stockInfoService.Db.Queryable<Dt_OutboundOrder>().First(x => x.OrderNo == orderNo);
+
+
+                    if (outboundOrder != null && outboundOrder.OrderStatus == OutOrderStatusEnum.鍑哄簱瀹屾垚.ObjToInt())
+                    {
+
+                        if (outboundOrder.OrderType == OutOrderTypeEnum.Allocate.ObjToInt().ObjToInt())//璋冩嫧鍑哄簱
+                        {
+
+                        }
+                        else if (outboundOrder.OrderType == OutOrderTypeEnum.ReCheck.ObjToInt()) //閲嶆鍑哄簱
+                        {
+
+                        }
+                        else
+                        {
+                            var feedmodel = new FeedbackOutboundRequestModel
+                            {
+                                reqCode = Guid.NewGuid().ToString(),
+                                reqTime = DateTime.Now.ToString(),
+                                business_type = outboundOrder.BusinessType,
+                                factoryArea = outboundOrder.FactoryArea,
+                                operationType = 1,
+                                Operator = outboundOrder.Operator,
+                                orderNo = outboundOrder.UpperOrderNo,
+                                status = outboundOrder.OrderStatus,
+                                details = new List<FeedbackOutboundDetailsModel>()
+
+                            };
+                            var lists = _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>().Where(x => x.OrderNo == orderNo && x.Status == (int)OutLockStockStatusEnum.鎷i�夊畬鎴�).ToList();
+
+                            var groupedData = lists.GroupBy(item => new { item.MaterielCode, item.lineNo, item.Unit, item.WarehouseCode })
+                               .Select(group => new FeedbackOutboundDetailsModel
+                               {
+                                   materialCode = group.Key.MaterielCode,
+                                   lineNo = group.Key.lineNo,
+                                   warehouseCode = group.Key.WarehouseCode,
+                                   currentDeliveryQty = group.Sum(x => x.OrderQuantity),
+                                   // warehouseCode= "1072",
+                                   unit = group.Key.Unit,
+                                   barcodes = group.Select(row => new WIDESEA_DTO.Outbound.BarcodesModel
+                                   {
+                                       barcode = row.CurrentBarcode,
+                                       supplyCode = row.SupplyCode,
+                                       batchNo = row.BatchNo,
+                                       unit = row.Unit,
+                                       qty = row.PickedQty
+                                   }).ToList()
+                               }).ToList();
+                            feedmodel.details = groupedData;
+
+                            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();
+                            }
+                        }
+
+                    }
+                }
+                catch (Exception ex)
+                {
+                    _logger.LogError(" OutboundPickingService  FeedbackOutbound : " + ex.Message);
+                }
+
             }
         }
-        // 鍙栨秷鎷i�夊姛鑳�
+
+        public async Task<WebResponseContent> ConfirmPicking(string orderNo, string palletCode, string barcode)
+        {
+            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();
+
+                if (lockInfo == null)
+                {
+                    lockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+                        .Where(it => it.CurrentBarcode == barcode &&
+                                   it.Status == (int)OutLockStockStatusEnum.鍑哄簱涓� &&
+                                   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�夊畬鎴� ||
+                                        it.PickedQty >= it.AssignQuantity))
+                            .FirstAsync();
+
+                        if (completedLockInfo != null)
+                            throw new Exception($"鏉$爜{barcode}宸茬粡瀹屾垚鍒嗘嫞锛屼笉鑳介噸澶嶅垎鎷�");
+                        else
+                            throw new Exception($"鏉$爜{barcode}涓嶅睘浜庢墭鐩榹palletCode}鎴栦笉瀛樺湪寰呭垎鎷h褰�");
+                    }
+                }
+
+                if (lockInfo.PalletCode != palletCode)
+                    throw new Exception($"鏉$爜{barcode}涓嶅睘浜庢墭鐩榹palletCode}");
+
+                // 妫�鏌ユ嫞閫夊巻鍙诧紝闃叉閲嶅鍒嗘嫞
+                var existingPicking = await Db.Queryable<Dt_PickingRecord>()
+                    .Where(x => x.Barcode == barcode &&
+                               x.OrderNo == orderNo &&
+                               x.PalletCode == palletCode &&
+                               x.OutStockLockId == lockInfo.Id)
+                    .FirstAsync();
+
+                if (existingPicking != null)
+                {
+                    throw new Exception($"鏉$爜{barcode}宸茬粡鍒嗘嫞杩囷紝涓嶈兘閲嶅鍒嗘嫞");
+                }
+
+                // 鑾峰彇璁㈠崟鏄庣粏骞舵鏌ユ暟閲忛檺鍒�
+                var orderDetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
+                    .FirstAsync(x => x.Id == lockInfo.OrderDetailId);
+
+                if (orderDetail == null)
+                    throw new Exception($"鏈壘鍒拌鍗曟槑缁嗭紝ID: {lockInfo.OrderDetailId}");
+
+                // 鍏抽敭淇锛氭鏌ョ疮璁℃嫞閫夋暟閲忔槸鍚︿細瓒呰繃璁㈠崟鏁伴噺
+                decimal actualQty = lockInfo.AssignQuantity - lockInfo.PickedQty;
+                decimal remainingOrderQty = orderDetail.NeedOutQuantity - orderDetail.OverOutQuantity;
+
+                if (actualQty > remainingOrderQty)
+                {
+                    // 濡傛灉鍒嗛厤鏁伴噺澶т簬鍓╀綑璁㈠崟鏁伴噺锛岃皟鏁村疄闄呮嫞閫夋暟閲�
+                    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();
+
+                if (stockDetail == null)
+                    return WebResponseContent.Instance.Error("鏃犳晥鐨勬潯鐮佹垨鐗╂枡缂栫爜");
+
+                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;
+
+                    // 鏇存柊鍘熸潯鐮佸簱瀛樹负鍓╀綑鏁伴噺
+                    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,
+                        OrderDetailId = lockInfo.OrderDetailId,
+                        BatchNo = lockInfo.BatchNo,
+                        MaterielCode = lockInfo.MaterielCode,
+                        MaterielName = lockInfo.MaterielName,
+                        StockId = lockInfo.StockId,
+                        OrderQuantity = actualQty,
+                        OriginalQuantity = actualQty,
+                        AssignQuantity = actualQty,
+                        PickedQty = actualQty,
+                        LocationCode = lockInfo.LocationCode,
+                        PalletCode = lockInfo.PalletCode,
+                        TaskNum = lockInfo.TaskNum,
+                        Status = (int)OutLockStockStatusEnum.鎷i�夊畬鎴�,
+                        Unit = lockInfo.Unit,
+                        SupplyCode = lockInfo.SupplyCode,
+                        OrderType = lockInfo.OrderType,
+                        CurrentBarcode = newBarcode,
+                        OriginalLockQuantity = actualQty,
+                        IsSplitted = 1,
+                        ParentLockId = lockInfo.Id
+                    };
+
+                    var newLockId = await _outStockLockInfoService.Db.Insertable(newLockInfo).ExecuteReturnIdentityAsync();
+                    newLockInfo.Id = newLockId;
+
+                    // 璁板綍鎷嗗寘鍘嗗彶
+                    var splitHistory = new Dt_SplitPackageRecord
+                    {
+                        FactoryArea = lockInfo.FactoryArea,
+                        TaskNum = lockInfo.TaskNum,
+                        OutStockLockInfoId = lockInfo.Id,
+                        StockId = stockDetail.StockId,
+                        Operator = App.User.UserName,
+                        IsReverted = false,
+                        OriginalBarcode = barcode,
+                        NewBarcode = newBarcode,
+                        SplitQty = actualQty,
+                        RemainQuantity = remainingStockQty,
+                        MaterielCode = lockInfo.MaterielCode,
+                        SplitTime = DateTime.Now,
+                        OrderNo = lockInfo.OrderNo,
+                        PalletCode = lockInfo.PalletCode,
+                        Status = (int)SplitPackageStatusEnum.宸叉嫞閫�
+                    };
+                    await _splitPackageService.Db.Insertable(splitHistory).ExecuteCommandAsync();
+
+                    // 鏇存柊鍘熼攣瀹氫俊鎭负鍓╀綑搴撳瓨鏁伴噺
+                    lockInfo.AssignQuantity = remainingStockQty;
+                    lockInfo.PickedQty = 0;
+                    await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync();
+
+                    splitResults.Add(new SplitResult
+                    {
+                        materialCode = lockInfo.MaterielCode,
+                        supplierCode = lockInfo.SupplyCode,
+                        quantityTotal = actualQty.ToString("F2"),
+                        batchNumber = newBarcode,
+                        batch = lockInfo.BatchNo,
+                        factory = lockInfo.FactoryArea,
+                        date = DateTime.Now.ToString("yyyy-MM-dd"),
+                    });
+
+                    splitResults.Add(new SplitResult
+                    {
+                        materialCode = lockInfo.MaterielCode,
+                        supplierCode = lockInfo.SupplyCode,
+                        quantityTotal = remainingStockQty.ToString("F2"),
+                        batchNumber = barcode,
+                        batch = lockInfo.BatchNo,
+                        factory = lockInfo.FactoryArea,
+                        date = DateTime.Now.ToString("yyyy-MM-dd"),
+                    });
+
+                    finalLockInfo = newLockInfo;
+                    finalBarcode = newBarcode;
+                }
+                else if (actualQty == stockQuantity)
+                {
+                    // 鎯呭喌2: 鍒嗛厤鏁伴噺绛変簬搴撳瓨鏁伴噺锛屾暣鍖呭嚭搴�
+                    stockDetail.StockQuantity = 0;
+                    stockDetail.OutboundQuantity = 0;
+                    await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync();
+
+                    lockInfo.PickedQty += actualQty;
+                    lockInfo.Status = (int)OutLockStockStatusEnum.鎷i�夊畬鎴�;
+                    await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync();
+                }
+                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();
+
+                    foreach (var record in relatedSplitRecords)
+                    {
+                        record.Status = (int)SplitPackageStatusEnum.宸叉嫞閫�;
+                        await _splitPackageService.Db.Updateable(record).ExecuteCommandAsync();
+                    }
+
+                    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 => 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
+                {
+                    FactoryArea = finalLockInfo.FactoryArea,
+                    TaskNo = task?.TaskNum ?? 0,
+                    LocationCode = task?.SourceAddress ?? "",
+                    StockId = finalStockId,
+                    OrderNo = orderNo,
+                    OrderDetailId = finalLockInfo.OrderDetailId,
+                    PalletCode = palletCode,
+                    Barcode = finalBarcode,
+                    MaterielCode = finalLockInfo.MaterielCode,
+                    PickQuantity = actualPickedQty,
+                    PickTime = DateTime.Now,
+                    Operator = App.User.UserName,
+                    OutStockLockId = finalLockInfo.Id
+                };
+                await Db.Insertable(pickingHistory).ExecuteCommandAsync();
+
+                _unitOfWorkManage.CommitTran();
+
+                if (splitResults.Any())
+                {
+                    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 outStockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
-                        .Where(x => x.OrderNo == orderNo &&
-                                   x.PalletCode == palletCode &&
-                                   x.CurrentBarcode == barcode &&
-                                   x.Status == 2)
-                        .FirstAsync();
-
-                if (outStockInfo == null)
-                    return WebResponseContent.Instance.Error("鏈壘鍒板凡鎷i�夎褰�");
-
-                // 杩樺師鍑哄簱璇︽儏鐘舵��
-                outStockInfo.PickedQty = 0;
-                outStockInfo.Status = 1;
-                await _outStockLockInfoService.Db.Updateable(outStockInfo).ExecuteCommandAsync();
-
-                //// 杩樺師搴撳瓨鍑哄簱鏁伴噺
-                //await _stockInfoDetailService.Db.Updateable<Dt_StockInfoDetail>()
-                //        .SetColumns(x => x.OutboundQuantity == x.OutboundQuantity - outStockInfo.AssignQuantity)
-                //        .Where(x => x.Barcode == barcode)
-                //        .ExecuteCommandAsync();
-
-                // 杩樺師鍑哄簱鍗曟槑缁�
-                var orderDetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
-                    .Where(x => x.Id == outStockInfo.OrderDetailId)
+                var pickingRecord = await Db.Queryable<Dt_PickingRecord>()
+                    .Where(it => it.OrderNo == orderNo &&
+                               it.PalletCode == palletCode &&
+                               it.Barcode == barcode)
+                    .OrderByDescending(it => it.PickTime)
                     .FirstAsync();
 
-                orderDetail.OverOutQuantity -= outStockInfo.AssignQuantity;
-                await _outboundOrderDetailService.Db.Updateable(orderDetail).ExecuteCommandAsync();
+                if (pickingRecord == null)
+                    return WebResponseContent.Instance.Error("鏈壘鍒板搴旂殑鎷i�夎褰�");
 
-                // 鍒犻櫎鎷i�夊巻鍙�
-                await Db.Deleteable<Dt_PickingRecord>()
-                    .Where(x => x.OutStockLockId == outStockInfo.Id)
+                // 鏌ユ壘鍑哄簱閿佸畾淇℃伅
+                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("鍙栨秷鎷i�夋垚鍔�");
+                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();
+            }
+        }
+
+        public async Task<WebResponseContent> ReturnRemaining(string orderNo, string palletCode, string reason)
+        {
+            try
+            {
+                _unitOfWorkManage.BeginTran();
+                        
+                if (string.IsNullOrEmpty(orderNo) || string.IsNullOrEmpty(palletCode))
+                {
+                    return WebResponseContent.Instance.Error("璁㈠崟鍙峰拰鎵樼洏鐮佷笉鑳戒负绌�");
+                }               
+                var stockInfo = await _stockInfoService.Db.Queryable<Dt_StockInfo>()
+                    .FirstAsync(x => x.PalletCode == palletCode);
+
+                if (stockInfo == null)
+                {
+                    return WebResponseContent.Instance.Error($"鏈壘鍒版墭鐩� {palletCode} 瀵瑰簲鐨勫簱瀛樹俊鎭�");
+                }             
+                var task = await GetCurrentTask(orderNo, palletCode);
+                if (task == null)
+                {
+                    return WebResponseContent.Instance.Error("鏈壘鍒板搴旂殑浠诲姟淇℃伅");
+                }
+
+                // 鍒嗘瀽闇�瑕佸洖搴撶殑璐х墿
+                var returnAnalysis = await AnalyzeReturnItems(orderNo, palletCode, stockInfo.Id);
+
+                if (!returnAnalysis.HasItemsToReturn)
+                {
+                    return await HandleNoReturnItems(orderNo, palletCode);
+                }
+
+                // 鎵ц鍥炲簱鎿嶄綔
+                await ExecuteReturnOperations(orderNo, palletCode, stockInfo, task, returnAnalysis);
+
+                //鍒涘缓鍥炲簱浠诲姟骞跺鐞咵SS
+                await CreateReturnTaskAndHandleESS(orderNo, palletCode, task, returnAnalysis);
+
+                _unitOfWorkManage.CommitTran();
+
+                // 鏇存柊璁㈠崟鐘舵�� 
+                await UpdateOrderStatusForReturn(orderNo);
+
+                return WebResponseContent.Instance.OK($"鍥炲簱鎿嶄綔鎴愬姛锛屽叡鍥炲簱鏁伴噺锛歿returnAnalysis.TotalReturnQty}");
 
             }
             catch (Exception ex)
             {
-                return WebResponseContent.Instance.Error($"鍙栨秷鎷i�夊け璐ワ細{ex.Message}");
+                _unitOfWorkManage.RollbackTran();
+                _logger.LogError($"ReturnRemaining澶辫触 - OrderNo: {orderNo}, PalletCode: {palletCode}, Error: {ex.Message}");
+                return WebResponseContent.Instance.Error($"鍥炲簱鎿嶄綔澶辫触: {ex.Message}");
             }
         }
-        /// <summary>
-        /// 鏍规嵁鏉$爜鏌ユ壘閿佸畾淇℃伅
-        /// </summary>
-        private async Task<Dt_OutStockLockInfo> FindLockInfoByBarcode(int orderDetailId, string barcode, string materielCode)
+
+        #region 璁㈠崟鐘舵�� 
+
+        private async Task UpdateOrderStatusForReturn(string orderNo)
         {
-            return await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
-                .Where(x => x.OrderDetailId == orderDetailId &&
-                           x.MaterielCode == materielCode &&
-                           x.CurrentBarcode == barcode &&
-                           x.Status == (int)OutLockStockStatusEnum.鍑哄簱涓� &&
-                           x.AssignQuantity > x.PickedQty)
-                .FirstAsync();
+            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();
+
+                bool allCompleted = true;
+                foreach (var detail in orderDetails)
+                {
+                    if (detail.OverOutQuantity < detail.NeedOutQuantity)
+                    {
+                        allCompleted = false;
+                        break;
+                    }
+                }
+
+                var outboundOrder = await _outboundOrderService.Db.Queryable<Dt_OutboundOrder>()
+                    .FirstAsync(x => x.OrderNo == orderNo);
+
+                if (outboundOrder == null) return;
+
+                // 鍙湁褰撶姸鎬佺‘瀹炲彂鐢熷彉鍖栨椂鎵嶆洿鏂�
+                int newStatus = allCompleted ? (int)OutOrderStatusEnum.鍑哄簱瀹屾垚 : (int)OutOrderStatusEnum.鍑哄簱涓�;
+
+                if (outboundOrder.OrderStatus != newStatus)
+                {
+                    await _outboundOrderService.Db.Updateable<Dt_OutboundOrder>()
+                        .SetColumns(x => x.OrderStatus == newStatus)
+                        .Where(x => x.OrderNo == orderNo)
+                        .ExecuteCommandAsync();
+
+                    _logger.LogInformation($"鍥炲簱鎿嶄綔鏇存柊璁㈠崟鐘舵�� - OrderNo: {orderNo}, 鏂扮姸鎬�: {newStatus}");
+                }
+            }
+            catch (Exception ex)
+            {
+                _logger.LogError($"UpdateOrderStatusForReturn澶辫触 - OrderNo: {orderNo}, Error: {ex.Message}");
+                
+            }
         }
+
+        #endregion
+
+        #region Private Methods
+
+        private async Task<Dt_Task> GetCurrentTask(string orderNo, string palletCode)
+        {
+            // 鍏堝皾璇曢�氳繃璁㈠崟鍙峰拰鎵樼洏鍙锋煡鎵句换鍔�
+            var task = await _taskRepository.Db.Queryable<Dt_Task>()
+                .Where(x => x.OrderNo == orderNo && x.PalletCode == palletCode)
+                .FirstAsync();
+
+            if (task == null)
+            {
+                // 濡傛灉鎵句笉鍒帮紝鍐嶉�氳繃鎵樼洏鍙锋煡鎵�
+                task = await _taskRepository.Db.Queryable<Dt_Task>()
+                    .Where(x => x.PalletCode == palletCode)
+                    .FirstAsync();
+            }
+
+            return task;
+        }
+
+        private async Task<ReturnAnalysisResult> AnalyzeReturnItems(string orderNo, string palletCode, int stockId)
+        {
+            var result = new ReturnAnalysisResult();
+
+            // 鑾峰彇鏈垎鎷g殑鍑哄簱閿佸畾璁板綍
+            var remainingLocks = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+                .Where(it => it.OrderNo == orderNo &&
+                           it.PalletCode == palletCode &&
+                           it.Status == (int)OutLockStockStatusEnum.鍑哄簱涓�)
+                .ToListAsync();
+
+            if (remainingLocks.Any())
+            {
+                result.HasRemainingLocks = true;
+                result.RemainingLocks = remainingLocks;
+                result.RemainingLocksReturnQty = remainingLocks.Sum(x => x.AssignQuantity - x.PickedQty);
+            }
+
+            // 妫�鏌ユ墭鐩樹笂鏄惁鏈夊叾浠栧簱瀛樿揣鐗�    
+            var palletStockGoods = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
+                .Where(it => it.StockId == stockId &&
+                            (it.Status == StockStatusEmun.鍏ュ簱纭.ObjToInt() ||
+                             it.Status == StockStatusEmun.鍏ュ簱瀹屾垚.ObjToInt() ||
+                             it.Status == StockStatusEmun.鍑哄簱閿佸畾.ObjToInt()))
+                .Where(it => it.StockQuantity > 0) // 鏈夊簱瀛樼殑
+                .ToListAsync();
+
+
+            if (palletStockGoods.Any())
+            {
+                result.HasPalletStockGoods = true;
+                result.PalletStockGoods = palletStockGoods;
+                result.PalletStockReturnQty = palletStockGoods.Sum(x => x.StockQuantity);
+            }
+
+            //  妫�鏌ユ媶鍖呰褰�
+            var splitRecords = await _splitPackageService.Db.Queryable<Dt_SplitPackageRecord>()
+                .Where(it => it.OrderNo == orderNo && it.PalletCode == palletCode && !it.IsReverted)
+                .ToListAsync();
+
+            if (splitRecords.Any())
+            {
+                result.HasSplitRecords = true;
+                result.SplitRecords = splitRecords;
+                result.SplitReturnQty = await CalculateSplitReturnQuantity(splitRecords, stockId);
+            }
+
+            result.TotalReturnQty = result.RemainingLocksReturnQty + result.PalletStockReturnQty + result.SplitReturnQty;
+            result.HasItemsToReturn = result.TotalReturnQty > 0;
+
+            return result;
+        }
+
+        private async Task<decimal> CalculateSplitReturnQuantity(List<Dt_SplitPackageRecord> splitRecords, int stockId)
+        {
+            decimal totalQty = 0;
+            var processedBarcodes = new HashSet<string>();
+
+            foreach (var splitRecord in splitRecords)
+            {
+                // 妫�鏌ュ師鏉$爜
+                if (!processedBarcodes.Contains(splitRecord.OriginalBarcode))
+                {
+                    var originalStock = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
+                        .Where(it => it.Barcode == splitRecord.OriginalBarcode && it.StockId == stockId)
+                        .FirstAsync();
+
+                    if (originalStock != null && originalStock.StockQuantity > 0)
+                    {
+                        totalQty += originalStock.StockQuantity;
+                        processedBarcodes.Add(splitRecord.OriginalBarcode);
+                    }
+                }
+
+                // 妫�鏌ユ柊鏉$爜
+                if (!processedBarcodes.Contains(splitRecord.NewBarcode))
+                {
+                    var newStock = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
+                        .Where(it => it.Barcode == splitRecord.NewBarcode && it.StockId == stockId)
+                        .FirstAsync();
+
+                    if (newStock != null && newStock.StockQuantity > 0)
+                    {
+                        totalQty += newStock.StockQuantity;
+                        processedBarcodes.Add(splitRecord.NewBarcode);
+                    }
+                }
+            }
+
+            return totalQty;
+        }
+
+        private async Task<WebResponseContent> HandleNoReturnItems(string orderNo, string palletCode)
+        {
+            // 妫�鏌ユ槸鍚︽墍鏈夎揣鐗╅兘宸叉嫞閫夊畬鎴�
+            var allPicked = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+                .Where(it => it.OrderNo == orderNo && it.PalletCode == palletCode)
+                .AnyAsync(it => it.Status == (int)OutLockStockStatusEnum.鎷i�夊畬鎴�);
+
+            if (allPicked)
+            {
+                return WebResponseContent.Instance.OK("鎵�鏈夎揣鐗╁凡鎷i�夊畬鎴愶紝鎵樼洏涓虹┖");
+            }
+            else
+            {
+                return WebResponseContent.Instance.Error("娌℃湁闇�瑕佸洖搴撶殑鍓╀綑璐х墿");
+            }
+        }
+
+        private async Task ExecuteReturnOperations(string orderNo, string palletCode, Dt_StockInfo stockInfo,
+            Dt_Task task, ReturnAnalysisResult analysis)
+        {
+            // 鎯呭喌1锛氬鐞嗘湭鍒嗘嫞鐨勫嚭搴撻攣瀹氳褰�
+            if (analysis.HasRemainingLocks)
+            {
+                await HandleRemainingLocksReturn(analysis.RemainingLocks, stockInfo.Id);
+
+                // 鍏抽敭锛氭洿鏂拌鍗曟槑缁嗙殑宸叉嫞閫夋暟閲�
+                await UpdateOrderDetailsOnReturn(analysis.RemainingLocks);
+            }
+
+            // 鎯呭喌2锛氬鐞嗘墭鐩樹笂鍏朵粬搴撳瓨璐х墿
+            if (analysis.HasPalletStockGoods)
+            {
+                await HandlePalletStockGoodsReturn(analysis.PalletStockGoods);
+            }
+
+            // 鎯呭喌3锛氬鐞嗘媶鍖呰褰�
+            if (analysis.HasSplitRecords)
+            {
+                await HandleSplitRecordsReturn(analysis.SplitRecords, orderNo, palletCode);
+            }
+
+            // 鏇存柊搴撳瓨涓昏〃鐘舵��
+            await UpdateStockInfoStatus(stockInfo);
+        }
+
+        private async Task HandleRemainingLocksReturn(List<Dt_OutStockLockInfo> remainingLocks, int stockId)
+        {
+            var lockIds = remainingLocks.Select(x => x.Id).ToList();
+
+            // 鏇存柊鍑哄簱閿佸畾璁板綍鐘舵�佷负鍥炲簱涓�
+            await _outStockLockInfoService.Db.Updateable<Dt_OutStockLockInfo>()
+                .SetColumns(it => new Dt_OutStockLockInfo
+                {
+                    Status = (int)OutLockStockStatusEnum.鍥炲簱涓� 
+                })
+                .Where(it => lockIds.Contains(it.Id))
+                .ExecuteCommandAsync();
+
+            // 澶勭悊搴撳瓨璁板綍
+            foreach (var lockInfo in remainingLocks)
+            {
+                decimal returnQty = lockInfo.AssignQuantity - lockInfo.PickedQty;
+
+                // 鏌ユ壘瀵瑰簲鐨勫簱瀛樻槑缁�
+                var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
+                    .Where(it => it.Barcode == lockInfo.CurrentBarcode && it.StockId == lockInfo.StockId)
+                    .FirstAsync();
+
+                if (stockDetail != null)
+                {
+                    // 鎭㈠搴撳瓨鐘舵��
+                    stockDetail.OutboundQuantity = Math.Max(0, stockDetail.OutboundQuantity - returnQty);
+                    stockDetail.Status = StockStatusEmun.鍏ュ簱瀹屾垚.ObjToInt();
+                    await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync();
+                }
+                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();
+                }
+            }
+        }
+
+        private async Task UpdateOrderDetailsOnReturn(List<Dt_OutStockLockInfo> remainingLocks)
+        {
+            // 鎸夎鍗曟槑缁嗗垎缁�
+            var orderDetailGroups = remainingLocks.GroupBy(x => x.OrderDetailId);
+
+            foreach (var group in orderDetailGroups)
+            {
+                var orderDetailId = group.Key;
+                var totalReturnQty = group.Sum(x => x.AssignQuantity - x.PickedQty);
+
+                // 鑾峰彇褰撳墠璁㈠崟鏄庣粏
+                var orderDetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
+                    .FirstAsync(x => x.Id == orderDetailId);
+
+                if (orderDetail != null)
+                {
+                    // 璋冩暣宸叉嫞閫夋暟閲忓拰宸插嚭搴撴暟閲�
+                    decimal newPickedQty = Math.Max(0, orderDetail.PickedQty - totalReturnQty);
+                    decimal newOverOutQuantity = Math.Max(0, orderDetail.OverOutQuantity - totalReturnQty);
+
+                    await _outboundOrderDetailService.Db.Updateable<Dt_OutboundOrderDetail>()
+                        .SetColumns(it => new Dt_OutboundOrderDetail
+                        {
+                            PickedQty = newPickedQty,
+                            OverOutQuantity = newOverOutQuantity
+                        })
+                        .Where(it => it.Id == orderDetailId)
+                        .ExecuteCommandAsync();
+                }
+            }
+        }
+
+        private async Task HandlePalletStockGoodsReturn(List<Dt_StockInfoDetail> palletStockGoods)
+        {
+            foreach (var stockGood in palletStockGoods)
+            {
+                // 鎭㈠搴撳瓨鐘舵��
+                stockGood.OutboundQuantity = 0;
+                stockGood.Status = StockStatusEmun.鍏ュ簱瀹屾垚.ObjToInt(); 
+                await _stockInfoDetailService.Db.Updateable(stockGood).ExecuteCommandAsync();
+            }
+        }
+
+        private async Task HandleSplitRecordsReturn(List<Dt_SplitPackageRecord> splitRecords, string orderNo, string palletCode)
+        {
+            // 鏇存柊鎷嗗寘璁板綍鐘舵��
+            await _splitPackageService.Db.Updateable<Dt_SplitPackageRecord>()
+                .SetColumns(x => new Dt_SplitPackageRecord
+                {
+                    Status = (int)SplitPackageStatusEnum.宸插洖搴�               
+                })
+                .Where(x => x.OrderNo == orderNo && x.PalletCode == palletCode && !x.IsReverted)
+                .ExecuteCommandAsync();
+        }
+
+        private async Task UpdateStockInfoStatus(Dt_StockInfo stockInfo)
+        {
+            // 鏇存柊搴撳瓨涓昏〃鐘舵��
+            stockInfo.StockStatus = StockStatusEmun.鍏ュ簱瀹屾垚.ObjToInt();  
+            await _stockInfoService.Db.Updateable(stockInfo).ExecuteCommandAsync();
+        }
+
+        private async Task CreateReturnTaskAndHandleESS(string orderNo, string palletCode, Dt_Task originalTask, ReturnAnalysisResult analysis)
+        {
+            var firstLocation = await _locationInfoService.Db.Queryable<Dt_LocationInfo>()
+                .FirstAsync(x => x.LocationCode == originalTask.SourceAddress);
+
+            // 鍒嗛厤鏂拌揣浣嶏紙鍥炲簱鍒板瓨鍌ㄤ綅锛�
+            var newLocation = _locationInfoService.AssignLocation(firstLocation.LocationType);
+
+            Dt_Task returnTask = new()
+            {
+                CurrentAddress = stations[originalTask.TargetAddress],
+                Grade = 0,
+                PalletCode = palletCode,
+                NextAddress = "",
+                OrderNo = originalTask.OrderNo,
+                Roadway = newLocation.RoadwayNo,
+                SourceAddress = stations[originalTask.TargetAddress],
+                TargetAddress = newLocation.LocationCode,
+                TaskStatus = TaskStatusEnum.New.ObjToInt(),
+                TaskType = TaskTypeEnum.InPick.ObjToInt(),
+                PalletType = originalTask.PalletType,
+                WarehouseId = originalTask.WarehouseId,
+
+            }; 
+
+            // 淇濆瓨鍥炲簱浠诲姟
+            await _taskRepository.Db.Insertable(returnTask).ExecuteCommandAsync();
+
+            // 鍒犻櫎鍘熷鍑哄簱浠诲姟
+              _taskRepository.Db.Deleteable(originalTask);
+
+            // 缁� ESS 鍙戦�佹祦鍔ㄤ俊鍙峰拰鍒涘缓浠诲姟
+            await SendESSCommands(palletCode, originalTask, returnTask);
+        }
+
+        private async Task<int> GenerateTaskNumber()
+        {
+            return await _dailySequenceService.GetNextSequenceAsync();
+        }
+
+        private async Task SendESSCommands(string palletCode, Dt_Task originalTask, Dt_Task returnTask)
+        {
+            try
+            {
+                // 1. 鍙戦�佹祦鍔ㄤ俊鍙�
+                var moveResult = await _eSSApiService.MoveContainerAsync(new WIDESEA_DTO.Basic.MoveContainerRequest
+                {
+                    slotCode = movestations[originalTask.TargetAddress],
+                    containerCode = palletCode
+                });
+
+                if (moveResult)
+                {
+                    // 2. 鍒涘缓鍥炲簱浠诲姟
+                    var essTask = new TaskModel()
+                    {
+                        taskType = "putaway",
+                        taskGroupCode = "",
+                        groupPriority = 0,
+                        tasks = new List<TasksType>
+                {
+                    new()
+                    {
+                        taskCode = returnTask.TaskNum.ToString(),
+                        taskPriority = 0,
+                        taskDescribe = new TaskDescribeType
+                        {
+                            containerCode = palletCode,
+                            containerType = "CT_KUBOT_STANDARD",
+                            fromLocationCode = stations.GetValueOrDefault(originalTask.TargetAddress) ?? "",
+                            toStationCode = "",
+                            toLocationCode = returnTask.TargetAddress,
+                            deadline = 0,
+                            storageTag = ""
+                        }
+                    }
+                }
+                    };
+
+                    var resultTask = await _eSSApiService.CreateTaskAsync(essTask);
+                    _logger.LogInformation($"ReturnRemaining 鍒涘缓浠诲姟鎴愬姛: {resultTask}");
+                }
+            }
+            catch (Exception ex)
+            {
+                _logger.LogError($"ReturnRemaining ESS鍛戒护鍙戦�佸け璐�: {ex.Message}");
+                throw new Exception($"ESS绯荤粺閫氫俊澶辫触: {ex.Message}");
+            }
+        }
+
+        #endregion
+
+  
+
+        /// <summary>
+        /// 鍥炲簱鎿嶄綔  
+        /// </summary>
+
+        //public async Task<WebResponseContent> ReturnRemaining(string orderNo, string palletCode, string reason)
+        //{
+        //    try
+        //    {
+        //        _unitOfWorkManage.BeginTran();
+
+        //        // 鑾峰彇鎵�鏈夋湭鍒嗘嫞鐨勫嚭搴撻攣瀹氳褰曪紝鍖呮嫭鎷嗗寘浜х敓鐨勮褰�
+        //        var remainingLocks = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+        //            .Where(it => it.OrderNo == orderNo && it.Status == (int)OutLockStockStatusEnum.鍑哄簱涓�)
+        //            .ToListAsync();
+
+        //        var stockinfo = _stockInfoService.Db.Queryable<Dt_StockInfo>().First(x => x.PalletCode == palletCode);
+
+        //        var tasks = new List<Dt_Task>();
+
+        //        // 鏌ヨ浠诲姟琛�
+        //        var task = remainingLocks.Any()
+        //            ? _taskRepository.QueryData(x => x.TaskNum == remainingLocks.First().TaskNum).FirstOrDefault()
+        //            : _taskRepository.QueryData(x => x.PalletCode == palletCode).FirstOrDefault();
+
+        //        if (task == null)
+        //        {
+        //            return WebResponseContent.Instance.Error("鏈壘鍒板搴旂殑浠诲姟淇℃伅");
+        //        }
+
+        //        // 妫�鏌ユ墭鐩樹笂鏄惁鏈夊叾浠栭潪鍑哄簱璐х墿锛堝簱瀛樿揣鐗╋級
+        //        var palletStockGoods = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
+        //            .Where(it => it.StockId == stockinfo.Id &&
+        //                        (it.Status == StockStatusEmun.鍏ュ簱纭.ObjToInt() ||
+        //                         it.Status == StockStatusEmun.鍏ュ簱瀹屾垚.ObjToInt() ||
+        //                         it.Status == StockStatusEmun.鍑哄簱閿佸畾.ObjToInt()))
+        //            .Where(it => it.OutboundQuantity == 0 || it.OutboundQuantity < it.StockQuantity) // 鏈畬鍏ㄥ嚭搴撶殑
+        //            .ToListAsync();
+
+        //        // 妫�鏌ユ媶鍖呰褰曪紝鎵惧嚭闇�瑕佸洖搴撶殑鏉$爜
+        //        var splitRecords = await _splitPackageService.Db.Queryable<Dt_SplitPackageRecord>()
+        //            .Where(it => it.OrderNo == orderNo && it.PalletCode == palletCode && !it.IsReverted)
+        //            .ToListAsync();
+
+        //        // 璁$畻闇�瑕佸洖搴撶殑鎷嗗寘鏉$爜
+        //        var splitBarcodesToReturn = new List<string>();
+        //        foreach (var splitRecord in splitRecords)
+        //        {
+        //            // 妫�鏌ュ師鏉$爜鏄惁杩樻湁搴撳瓨闇�瑕佸洖搴�
+        //            var originalStock = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
+        //                .Where(it => it.Barcode == splitRecord.OriginalBarcode && it.StockId == stockinfo.Id)
+        //                .FirstAsync();
+
+        //            if (originalStock != null && originalStock.StockQuantity > 0)
+        //            {
+        //                splitBarcodesToReturn.Add(splitRecord.OriginalBarcode);
+        //            }
+
+        //            // 妫�鏌ユ柊鏉$爜鏄惁杩樻湁搴撳瓨闇�瑕佸洖搴�
+        //            var newStock = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
+        //                .Where(it => it.Barcode == splitRecord.NewBarcode && it.StockId == stockinfo.Id)
+        //                .FirstAsync();
+
+        //            if (newStock != null && newStock.StockQuantity > 0)
+        //            {
+        //                splitBarcodesToReturn.Add(splitRecord.NewBarcode);
+        //            }
+        //        }
+
+        //        // 濡傛灉娌℃湁闇�瑕佸洖搴撶殑璐х墿锛堟棦鏃犳湭鍒嗘嫞鍑哄簱璐х墿锛屼篃鏃犲叾浠栧簱瀛樿揣鐗╋紝涔熸棤鎷嗗寘鍓╀綑璐х墿锛�
+        //        if (!remainingLocks.Any() && !palletStockGoods.Any() && !splitBarcodesToReturn.Any())
+        //        {
+        //            // 妫�鏌ユ槸鍚︽墍鏈夎揣鐗╅兘宸叉嫞閫夊畬鎴�
+        //            var allPicked = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+        //                .Where(it => it.OrderNo == orderNo && it.PalletCode == palletCode)
+        //                .AnyAsync(it => it.Status == (int)OutLockStockStatusEnum.鎷i�夊畬鎴�);
+
+        //            if (allPicked)
+        //            {
+        //                return WebResponseContent.Instance.OK("鎵�鏈夎揣鐗╁凡鎷i�夊畬鎴愶紝鎵樼洏涓虹┖");
+        //            }
+        //            else
+        //            {
+        //                return WebResponseContent.Instance.Error("娌℃湁闇�瑕佸洖搴撶殑鍓╀綑璐х墿");
+        //            }
+        //        }
+
+        //        var firstlocation = _locationInfoService.Db.Queryable<Dt_LocationInfo>().First(x => x.LocationCode == task.SourceAddress);
+        //        decimal totalReturnQty = 0;
+
+        //        // 鎯呭喌1锛氬鐞嗘湭鍒嗘嫞鐨勫嚭搴撻攣瀹氳褰�
+        //        if (remainingLocks.Any(x => x.PalletCode == palletCode))
+        //        {
+        //            var palletLocks = remainingLocks.Where(x => x.PalletCode == palletCode).ToList();
+        //            totalReturnQty = palletLocks.Sum(x => x.AssignQuantity - x.PickedQty);
+
+        //            if (totalReturnQty > 0)
+        //            {
+        //                // 鍒嗛厤鏂拌揣浣�
+        //                var newLocation = _locationInfoService.AssignLocation(firstlocation.LocationType);
+
+        //                // 鏇存柊鍑哄簱閿佸畾璁板綍鐘舵��
+        //                var lockIds = palletLocks.Select(x => x.Id).ToList();
+        //                await _outStockLockInfoService.Db.Updateable<Dt_OutStockLockInfo>()
+        //                    .SetColumns(it => new Dt_OutStockLockInfo { Status = (int)OutLockStockStatusEnum.鍥炲簱涓� })
+        //                    .Where(it => lockIds.Contains(it.Id))
+        //                    .ExecuteCommandAsync();
+
+
+
+        //                // 澶勭悊搴撳瓨璁板綍
+        //                foreach (var lockInfo in palletLocks)
+        //                {
+        //                    decimal returnQty = lockInfo.AssignQuantity - lockInfo.PickedQty;
+
+        //                    // 妫�鏌ュ簱瀛樿褰曟槸鍚﹀瓨鍦�
+        //                    var existingStock = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
+        //                        .Where(it => it.Barcode == lockInfo.CurrentBarcode && it.StockId == lockInfo.StockId)
+        //                        .FirstAsync();
+
+        //                    if (existingStock != null)
+        //                    {
+        //                        // 搴撳瓨璁板綍瀛樺湪锛屾仮澶嶉攣瀹氭暟閲�
+        //                        existingStock.OutboundQuantity = 0;
+
+        //                        await _stockInfoDetailService.Db.Updateable(existingStock).ExecuteCommandAsync();
+        //                    }
+        //                    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();
+        //                    }
+        //                }
+
+        //                // 鍒涘缓鍥炲簱浠诲姟
+        //                CreateReturnTask(tasks, task, palletCode, newLocation);
+        //            }
+        //        }
+
+        //        // 鎯呭喌2锛氬鐞嗘媶鍖呭墿浣欑殑搴撳瓨璐х墿
+        //        if (splitBarcodesToReturn.Any())
+        //        {
+        //            decimal splitReturnQty = 0;
+
+        //            foreach (var barcode in splitBarcodesToReturn)
+        //            {
+        //                var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
+        //                    .Where(it => it.Barcode == barcode && it.StockId == stockinfo.Id)
+        //                    .FirstAsync();
+
+        //                if (stockDetail != null && stockDetail.StockQuantity > 0)
+        //                {
+        //                    splitReturnQty += stockDetail.StockQuantity;
+
+        //                    // 鎭㈠搴撳瓨鐘舵�佷负鍏ュ簱瀹屾垚
+        //                    stockDetail.OutboundQuantity = 0;
+
+        //                    await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync();
+        //                }
+        //            }
+
+        //            totalReturnQty += splitReturnQty;
+
+        //            // 濡傛灉娌℃湁鍒涘缓浠诲姟锛屽垱寤哄洖搴撲换鍔�
+        //            if (!tasks.Any())
+        //            {
+        //                var newLocation = _locationInfoService.AssignLocation(firstlocation.LocationType);
+        //                CreateReturnTask(tasks, task, palletCode, newLocation);
+        //            }
+        //        }
+
+        //        // 鎯呭喌3锛氬嚭搴撹揣鐗╁凡鍒嗘嫞瀹岋紝浣嗘墭鐩樹笂杩樻湁鍏朵粬搴撳瓨璐х墿闇�瑕佸洖搴�
+        //        if (palletStockGoods.Any() && !remainingLocks.Any(x => x.PalletCode == palletCode))
+        //        {
+        //            decimal otherReturnQty = palletStockGoods.Sum(x => x.StockQuantity - x.OutboundQuantity);
+        //            totalReturnQty += otherReturnQty;
+        //            // 鏇存柊杩欎簺搴撳瓨璐х墿鐨勭姸鎬�
+        //            foreach (var stockGood in palletStockGoods)
+        //            {
+        //                stockGood.OutboundQuantity = 0;
+
+        //                await _stockInfoDetailService.Db.Updateable(stockGood).ExecuteCommandAsync();
+        //            }
+        //            // 濡傛灉娌℃湁鍒涘缓浠诲姟锛屽垱寤哄洖搴撲换鍔�
+        //            if (!tasks.Any())
+        //            {
+        //                var newLocation = _locationInfoService.AssignLocation(firstlocation.LocationType);
+        //                CreateReturnTask(tasks, task, palletCode, newLocation);
+        //            }
+
+
+        //        }
+
+        //        var allSplitRecords = await _splitPackageService.Db.Queryable<Dt_SplitPackageRecord>()
+        //            .Where(it => it.OrderNo == orderNo && it.PalletCode == palletCode && !it.IsReverted)
+        //            .ToListAsync();
+
+        //        foreach (var record in allSplitRecords)
+        //        {
+        //            record.Status = (int)SplitPackageStatusEnum.宸插洖搴�;
+        //            await _splitPackageService.Db.Updateable(record).ExecuteCommandAsync();
+        //        }
+        //        // 淇濆瓨浠诲姟 缁橢SS涓嬪彂浠诲姟
+        //        if (tasks.Any())
+        //        {
+        //            try
+        //            {
+        //                await _taskRepository.Db.Insertable(tasks).ExecuteCommandAsync();
+        //                var targetAddress = task.TargetAddress;
+        //                _taskRepository.DeleteData(task);
+
+        //                // 缁� ESS 娴佸姩淇″彿鍜屽垱寤轰换鍔�
+        //                try
+        //                {
+        //                    var result = await _eSSApiService.MoveContainerAsync(new WIDESEA_DTO.Basic.MoveContainerRequest
+        //                    {
+        //                        slotCode = movestations[targetAddress],
+        //                        containerCode = palletCode
+        //                    });
+
+        //                    if (result)
+        //                    {
+        //                        TaskModel esstask = new TaskModel()
+        //                        {
+        //                            taskType = "putaway",
+        //                            taskGroupCode = "",
+        //                            groupPriority = 0,
+        //                            tasks = new List<TasksType>
+        //                    {
+        //                        new()
+        //                        {
+        //                            taskCode = tasks.First().TaskNum.ToString(),
+        //                            taskPriority = 0,
+        //                            taskDescribe = new TaskDescribeType {
+        //                                containerCode = palletCode,
+        //                                containerType = "CT_KUBOT_STANDARD",
+        //                                fromLocationCode = stations.GetValueOrDefault(targetAddress) ?? "",
+        //                                toStationCode = "",
+        //                                toLocationCode = tasks.First().TargetAddress,
+        //                                deadline = 0, storageTag = ""
+        //                            }
+        //                        }
+        //                    }
+        //                        };
+
+        //                        var resulttask = await _eSSApiService.CreateTaskAsync(esstask);
+        //                        _logger.LogInformation("ReturnRemaining 鍒涘缓浠诲姟杩斿洖:  " + resulttask);
+        //                    }
+        //                }
+        //                catch (Exception ex)
+        //                {
+        //                    _logger.LogInformation("ReturnRemaining 鍒涘缓浠诲姟杩斿洖 catch err:  " + ex.Message);
+        //                }
+
+        //                _unitOfWorkManage.CommitTran();
+        //                return WebResponseContent.Instance.OK($"鍥炲簱鎿嶄綔鎴愬姛锛屽叡鍥炲簱鏁伴噺锛歿totalReturnQty}");
+        //            }
+        //            catch (Exception ex)
+        //            {
+        //                _unitOfWorkManage.RollbackTran();
+        //                return WebResponseContent.Instance.Error($"鍒涘缓鍥炲簱浠诲姟澶辫触: {ex.Message}");
+        //            }
+        //        }
+
+        //        _unitOfWorkManage.RollbackTran();
+        //        return WebResponseContent.Instance.Error("鏈垱寤轰换浣曞洖搴撲换鍔�");
+        //    }
+        //    catch (Exception ex)
+        //    {
+        //        _unitOfWorkManage.RollbackTran();
+        //        return WebResponseContent.Instance.Error($"鍥炲簱鎿嶄綔澶辫触: {ex.Message}");
+        //    }
+        //}
+
+
+        /// <summary>
+        /// 鍒涘缓鍥炲簱浠诲姟
+        /// </summary>
+        private void CreateReturnTask(List<Dt_Task> tasks, Dt_Task originalTask, string palletCode, Dt_LocationInfo newLocation)
+        {
+            Dt_Task newTask = new()
+            {
+                CurrentAddress = stations[originalTask.TargetAddress],
+                Grade = 0,
+                PalletCode = palletCode,
+                NextAddress = "",
+                OrderNo = originalTask.OrderNo,
+                Roadway = newLocation.RoadwayNo,
+                SourceAddress = stations[originalTask.TargetAddress],
+                TargetAddress = newLocation.LocationCode,
+                TaskStatus = TaskStatusEnum.New.ObjToInt(),
+                TaskType = TaskTypeEnum.InPick.ObjToInt(),
+                PalletType = originalTask.PalletType,
+                WarehouseId = originalTask.WarehouseId,
+
+            };
+            tasks.Add(newTask);
+        }
+
+        /// <summary>
+        /// 妫�鏌ユ墭鐩樻槸鍚﹂渶瑕佸洖搴撶殑杈呭姪鏂规硶
+        /// </summary>
+        public async Task<bool> CheckPalletNeedReturn(string orderNo, string palletCode)
+        {
+            // 1. 妫�鏌ユ槸鍚︽湁鏈垎鎷g殑鍑哄簱璁板綍
+            var hasUnpickedLocks = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+                .Where(it => it.OrderNo == orderNo && it.PalletCode == palletCode && it.Status == 1)
+                .AnyAsync();
+
+            if (hasUnpickedLocks)
+                return true;
+
+            // 2. 妫�鏌ュ嚭搴撴槸鍚﹀凡瀹屾垚浣嗘墭鐩樿繕鏈夊簱瀛樿揣鐗�
+            var outboundFinished = !await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+                .Where(it => it.PalletCode == palletCode && it.Status == 1)
+                .AnyAsync();
+
+            var stockinfo = _stockInfoService.Db.Queryable<Dt_StockInfo>().First(x => x.PalletCode == palletCode);
+
+
+            var hasRemainingGoods = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
+                .Where(it => it.StockId == stockinfo.Id && it.Status == StockStatusEmun.鍏ュ簱纭.ObjToInt())
+                .Where(it => it.OutboundQuantity == 0 || it.OutboundQuantity < it.StockQuantity)
+                .AnyAsync();
+
+            return outboundFinished && hasRemainingGoods;
+        }
+
+ 
+        /// <summary>
+        /// 鑾峰彇鎷嗗寘閾撅紙浠庡綋鍓嶆潯鐮佽拷婧埌鍘熷鏉$爜锛�
+        /// </summary>
+        // 鍦� GetSplitChain 鏂规硶涓坊鍔犳洿涓ユ牸鐨勯獙璇�
+        private async Task<List<SplitChainItem>> GetSplitChain(string currentBarcode)
+        {
+            var chain = new List<SplitChainItem>();
+            var visited = new HashSet<string>();
+
+            string current = currentBarcode;
+            int maxDepth = 10; // 闃叉鏃犻檺寰幆
+
+            while (!string.IsNullOrEmpty(current) && maxDepth > 0)
+            {
+                maxDepth--;
+
+                if (visited.Contains(current))
+                {
+                    _logger.LogWarning($"妫�娴嬪埌寰幆寮曠敤鍦ㄦ媶鍖呴摼涓�: {current}");
+                    break;
+                }
+
+                visited.Add(current);
+
+                var splitRecord = await _splitPackageService.Db.Queryable<Dt_SplitPackageRecord>()
+                    .Where(it => it.NewBarcode == current && !it.IsReverted)
+                    .FirstAsync();
+
+                if (splitRecord == null)
+                    break;
+
+                // 楠岃瘉鎷嗗寘璁板綍鐨勫畬鏁存��
+                if (string.IsNullOrEmpty(splitRecord.OriginalBarcode))
+                {
+                    _logger.LogError($"鎷嗗寘璁板綍 {splitRecord.Id} 缂哄皯鍘熷鏉$爜");
+                    break;
+                }
+
+                var item = new SplitChainItem
+                {
+                    SplitRecord = splitRecord,
+                    OriginalBarcode = splitRecord.OriginalBarcode,
+                    NewBarcode = splitRecord.NewBarcode,
+                    SplitQuantity = splitRecord.SplitQty
+                };
+
+                chain.Add(item);
+
+                current = splitRecord.OriginalBarcode;
+            }
+
+            if (maxDepth <= 0)
+            {
+                _logger.LogWarning($"鎷嗗寘閾捐拷婧揪鍒版渶澶ф繁搴�: {currentBarcode}");
+            }
+
+            chain.Reverse();
+            return chain;
+        }
+        /// <summary>
+        /// 澶勭悊鎷嗗寘閾剧殑鍙栨秷鍒嗘嫞
+        /// </summary>
+        private async Task HandleSplitChainCancel(string orderNo, string palletCode, string barcode,
+            decimal cancelQty, Dt_OutStockLockInfo lockInfo, Dt_PickingRecord pickingRecord, List<SplitChainItem> splitChain)
+        {
+            if (!splitChain.Any())
+                return;
+
+            //  鎵惧埌鍘熷鏉$爜锛堥摼鐨勭涓�涓級
+            var originalSplitItem = splitChain.First();
+            var originalBarcode = originalSplitItem.OriginalBarcode;
+
+            // 鏌ユ壘鍘熷鏉$爜鐨勯攣瀹氫俊鎭拰搴撳瓨
+            var originalLockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+                .Where(it => it.CurrentBarcode == originalBarcode && it.Status == (int)OutLockStockStatusEnum.鍑哄簱涓�)
+                .FirstAsync();
+
+            var originalStockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
+                .Where(it => it.Barcode == originalBarcode && it.StockId == originalLockInfo.StockId)
+                .FirstAsync();
+
+            if (originalLockInfo == null || originalStockDetail == null)
+                throw new Exception("鏈壘鍒板師濮嬫潯鐮佺殑閿佸畾淇℃伅鎴栧簱瀛樹俊鎭�");
+
+            // 鎭㈠鍘熷鏉$爜搴撳瓨锛堝皢鍙栨秷鐨勬暟閲忓姞鍥炲幓锛�
+            originalStockDetail.StockQuantity += cancelQty;
+            originalStockDetail.OutboundQuantity += cancelQty;
+            await _stockInfoDetailService.Db.Updateable(originalStockDetail).ExecuteCommandAsync();
+
+            // 鎭㈠鍘熷鏉$爜閿佸畾淇℃伅
+            originalLockInfo.AssignQuantity += cancelQty;
+            await _outStockLockInfoService.Db.Updateable(originalLockInfo).ExecuteCommandAsync();
+
+            //  鍒犻櫎鎷嗗寘閾句腑鎵�鏈夋柊鏉$爜鐨勯攣瀹氫俊鎭拰搴撳瓨璁板綍
+            var allNewBarcodes = splitChain.Select(x => x.NewBarcode).ToList();
+
+            // 鍒犻櫎閿佸畾淇℃伅
+            await _outStockLockInfoService.Db.Deleteable<Dt_OutStockLockInfo>()
+                .Where(it => allNewBarcodes.Contains(it.CurrentBarcode))
+                .ExecuteCommandAsync();
+
+            // 鍒犻櫎搴撳瓨璁板綍锛堝彧鍒犻櫎鎷嗗寘浜х敓鐨勬柊鏉$爜搴撳瓨锛屼繚鐣欏師濮嬫潯鐮侊級
+            await _stockInfoDetailService.Db.Deleteable<Dt_StockInfoDetail>()
+                .Where(it => allNewBarcodes.Contains(it.Barcode) && it.Barcode != originalBarcode)
+                .ExecuteCommandAsync();
+
+            // 鏇存柊鎷嗗寘閾句腑鎵�鏈夋媶鍖呰褰曠姸鎬佷负宸叉媶鍖�
+            foreach (var chainItem in splitChain)
+            {
+                chainItem.SplitRecord.Status = (int)SplitPackageStatusEnum.宸叉媶鍖�;
+                await _splitPackageService.Db.Updateable(chainItem.SplitRecord).ExecuteCommandAsync();
+            }
+
+            //  鎭㈠璁㈠崟鏄庣粏鎷i�夋暟閲忥紙浣跨敤鍘熷閿佸畾淇℃伅鐨勮鍗曟槑缁咺D锛�
+            await _outboundOrderDetailService.Db.Updateable<Dt_OutboundOrderDetail>()
+                .SetColumns(it => it.PickedQty == it.PickedQty - cancelQty)
+                .Where(it => it.Id == originalLockInfo.OrderDetailId)
+                .ExecuteCommandAsync();
+
+            //   鎭㈠璁㈠崟鐘舵��
+            await CheckAndRevertOrderStatus(orderNo);
+
+            //  鍒犻櫎鎷i�夎褰�
+            await Db.Deleteable<Dt_PickingRecord>()
+                .Where(it => it.Id == pickingRecord.Id)
+                .ExecuteCommandAsync();
+
+            ////  璁板綍鍙栨秷鎿嶄綔鍘嗗彶
+            //await RecordCancelHistory(orderNo, palletCode, barcode, cancelQty, pickingRecord.Id,
+            //    lockInfo.MaterielCode, "鍙栨秷鎷嗗寘閾惧垎鎷�");
+        }
+
+        /// <summary>
+        /// 澶勭悊鏅�氭潯鐮佺殑鍙栨秷鍒嗘嫞
+        /// </summary>
+        private async Task HandleNormalBarcodeCancel(string orderNo, string palletCode, string barcode,
+            decimal cancelQty, Dt_OutStockLockInfo lockInfo, Dt_PickingRecord pickingRecord)
+        {
+            // 1. 鏌ユ壘搴撳瓨淇℃伅
+            var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
+                .Where(it => it.Barcode == barcode && it.StockId == lockInfo.StockId)
+                .FirstAsync();
+
+            if (stockDetail == null)
+                throw new Exception("鏈壘鍒板搴旂殑搴撳瓨淇℃伅");
+
+            // 2. 鎭㈠搴撳瓨鏁伴噺
+            if (stockDetail.StockQuantity == 0)
+            {
+                // 鏁村寘鍑哄簱鐨勬儏鍐�
+                stockDetail.StockQuantity = cancelQty;
+                stockDetail.OutboundQuantity = cancelQty;
+            }
+            else
+            {
+                // 閮ㄥ垎鍑哄簱鐨勬儏鍐�
+                stockDetail.StockQuantity += cancelQty;
+                stockDetail.OutboundQuantity += cancelQty;
+            }
+            await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync();
+
+            // 3. 鎭㈠閿佸畾淇℃伅鐘舵��
+            lockInfo.AssignQuantity += cancelQty;
+            lockInfo.PickedQty -= cancelQty;
+
+            if (lockInfo.PickedQty == 0)
+            {
+                lockInfo.Status = (int)OutLockStockStatusEnum.鍑哄簱涓�;
+            }
+            await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync();
+
+            // 4. 澶勭悊鐩稿叧鐨勬媶鍖呰褰曠姸鎬佹仮澶�
+            var relatedSplitRecords = await _splitPackageService.Db.Queryable<Dt_SplitPackageRecord>()
+                .Where(it => it.OriginalBarcode == barcode &&
+                           it.Status == (int)SplitPackageStatusEnum.宸叉嫞閫�)
+                .ToListAsync();
+
+            foreach (var record in relatedSplitRecords)
+            {
+                record.Status = (int)SplitPackageStatusEnum.宸叉媶鍖�;
+                await _splitPackageService.Db.Updateable(record).ExecuteCommandAsync();
+            }
+
+            // 5. 鎭㈠璁㈠崟鏄庣粏鐨勬嫞閫夋暟閲�
+            await _outboundOrderDetailService.Db.Updateable<Dt_OutboundOrderDetail>()
+                .SetColumns(it => it.PickedQty == it.PickedQty - cancelQty)
+                .Where(it => it.Id == lockInfo.OrderDetailId)
+                .ExecuteCommandAsync();
+
+            // 6. 鎭㈠璁㈠崟鐘舵��
+            await CheckAndRevertOrderStatus(orderNo);
+
+            // 7. 鍒犻櫎鎷i�夎褰�
+            await Db.Deleteable<Dt_PickingRecord>().Where(it => it.Id == pickingRecord.Id).ExecuteCommandAsync();
+
+            //// 8. 璁板綍鍙栨秷鎿嶄綔鍘嗗彶
+            //await RecordCancelHistory(orderNo, palletCode, barcode, cancelQty, pickingRecord.Id,
+            //    lockInfo.MaterielCode, "鍙栨秷鍒嗘嫞");
+        }
+
+        /// <summary>
+        /// 妫�鏌ュ苟鎭㈠璁㈠崟鐘舵��
+        /// </summary>
+        private async Task CheckAndRevertOrderStatus(string orderNo)
+        {
+            var order = await _outboundOrderService.Db.Queryable<Dt_OutboundOrder>()
+                .Where(x => x.OrderNo == orderNo)
+                .FirstAsync();
+
+            if (order != null && order.OrderStatus == OutOrderStatusEnum.鍑哄簱瀹屾垚.ObjToInt())
+            {
+                await _outboundOrderService.Db.Updateable<Dt_OutboundOrder>()
+                    .SetColumns(x => x.OrderStatus == OutOrderStatusEnum.鍑哄簱涓�.ObjToInt())
+                    .Where(x => x.OrderNo == orderNo)
+                    .ExecuteCommandAsync();
+            }
+        }
+
+ 
+
 
         // 鑾峰彇鏈嫞閫夊垪琛�
         public async Task<List<Dt_OutStockLockInfo>> GetUnpickedList(string orderNo, string palletCode)
@@ -394,36 +1751,17 @@
             var list = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
                 .Where(x => x.OrderNo == orderNo &&
                            x.PalletCode == palletCode &&
-                           x.Status == 2)
+                           x.Status == 6)
                 .ToListAsync();
             return list;
         }
-
-        public async Task<object> GetPickingSummary(string orderNo, string palletCode)
-        {
-            var summary = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
-                .Where(x => x.OrderNo == orderNo &&
-                           x.PalletCode == palletCode && x.Status == 1)
-                .GroupBy(x => new { x.PalletCode, x.MaterielCode })
-                .Select(x => new
-                {
-                    PalletCode = x.PalletCode,
-                    MaterielCode = x.MaterielCode,
-                    UnpickedCount = SqlFunc.AggregateCount(x.Id),
-                    UnpickedQuantity = SqlFunc.AggregateSum(x.AssignQuantity) - SqlFunc.AggregateSum(x.PickedQty)
-                })
-                .FirstAsync();
-
-            return summary;
-        }
-
         // 鑾峰彇鎷i�夋眹鎬�
         public async Task<object> GetPickingSummary(ConfirmPickingDto dto)
         {
             var picked = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
              .WhereIF(!string.IsNullOrEmpty(dto.OrderNo), x => x.OrderNo == dto.OrderNo)
              .WhereIF(!string.IsNullOrEmpty(dto.PalletCode), x => x.PalletCode == dto.PalletCode)
-             .Where(x => x.Status == 2)
+             .Where(x => x.Status == 6)
              .GroupBy(x => new { x.PalletCode, x.MaterielCode })
              .Select(x => new SummaryPickingDto
              {
@@ -475,88 +1813,6 @@
                 .ToListAsync();
         }
 
-        public async Task GetPalletPickingSummary(string orderNo, string palletCode)
-        {
-            var summary = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
-                .Where(x => x.OrderNo == orderNo && x.PalletCode == palletCode)
-                .GroupBy(x => new { x.PalletCode, x.Status })
-                .Select(x => new
-                {
-                    PalletCode = x.PalletCode,
-                    Status = x.Status,
-                    TotalAssignQty = SqlFunc.AggregateSum(x.AssignQuantity),
-                    TotalPickedQty = SqlFunc.AggregateSum(x.PickedQty)
-                })
-                .ToListAsync();
-
-            //   return summary;
-        }
-
-
-
-        /// <summary>
-        /// 鎾ら攢鎷i��
-        /// </summary>
-        public async Task<WebResponseContent> CancelPicking(CancelPickingRequest request)
-        {
-            // 瀹炵幇鎾ら攢鎷i�夌殑閫昏緫锛岄渶瑕侊細
-            // 1. 鎭㈠搴撳瓨鍑哄簱鏁伴噺
-            // 2. 鎭㈠閿佸畾淇℃伅鐨勫凡鎷i�夋暟閲�
-            // 3. 鎭㈠鍑哄簱鍗曟槑缁嗙殑宸插嚭鏁伴噺鍜岄攣瀹氭暟閲�
-            // 4. 鍒犻櫎鎴栨爣璁版嫞閫夊巻鍙茶褰�
-            // 娉ㄦ剰锛氳繖閲岄渶瑕佷簨鍔″鐞�
-            try
-            {
-                _unitOfWorkManage.BeginTran();
-
-                var pickHistory = await Db.Queryable<Dt_PickingRecord>()
-                    .Where(x => x.Id == request.PickingHistoryId)
-                    .FirstAsync();
-
-                if (pickHistory == null)
-                    return WebResponseContent.Instance.Error("鏈壘鍒版嫞閫夎褰�");
-
-                // 鎭㈠搴撳瓨
-                var stockDetail = await _stockInfoService.Db.Queryable<Dt_StockInfoDetail>()
-                    .Where(x => x.Barcode == pickHistory.Barcode && x.StockId == pickHistory.StockId)
-                    .FirstAsync();
-                if (stockDetail != null)
-                {
-                    stockDetail.OutboundQuantity -= pickHistory.PickQuantity;
-                    await _stockInfoService.Db.Updateable(stockDetail).ExecuteCommandAsync();
-                }
-                // 鎭㈠閿佸畾淇℃伅
-                var lockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
-                    .Where(x => x.OrderDetailId == pickHistory.OrderDetailId && x.StockId == pickHistory.StockId)
-                    .FirstAsync();
-                lockInfo.PickedQty -= pickHistory.PickQuantity;
-                await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync();
-
-                // 鎭㈠鍑哄簱鍗曟槑缁�
-                var orderDetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
-                    .Where(x => x.Id == pickHistory.OrderDetailId)
-                    .FirstAsync();
-                orderDetail.OverOutQuantity -= pickHistory.PickQuantity;
-                orderDetail.LockQuantity += pickHistory.PickQuantity;
-                if (orderDetail.OverOutQuantity < orderDetail.OrderQuantity)
-                {
-                    orderDetail.OrderDetailStatus = orderDetail.LockQuantity > 0 ?
-                        (int)OrderDetailStatusEnum.Outbound : (int)OrderDetailStatusEnum.AssignOverPartial;
-                }
-                await _outboundOrderDetailService.Db.Updateable(orderDetail).ExecuteCommandAsync();
-
-                // 鍒犻櫎鎷i�夊巻鍙茶褰�
-                await Db.Deleteable<Dt_PickingRecord>().Where(x => x.Id == request.PickingHistoryId).ExecuteCommandAsync();
-
-                _unitOfWorkManage.CommitTran();
-                return WebResponseContent.Instance.OK("鎾ら攢鎴愬姛");
-            }
-            catch (Exception ex)
-            {
-                _unitOfWorkManage.RollbackTran();
-                return WebResponseContent.Instance.Error($"鎾ら攢澶辫触: {ex.Message}");
-            }
-        }
 
         /// <summary>
         /// 鑾峰彇鎵樼洏鐨勫嚭搴撶姸鎬佷俊鎭�
@@ -673,7 +1929,7 @@
                     {
                         orderDetail.OverOutQuantity = item.TotalQuantity;
                         orderDetail.LockQuantity = 0;
-                        orderDetail.OrderDetailStatus = (int)OrderDetailStatusEnum.Over;                      
+                        orderDetail.OrderDetailStatus = (int)OrderDetailStatusEnum.Over;
                         await _outboundOrderDetailService.Db.Updateable(orderDetail).ExecuteCommandAsync();
                     }
                 }
@@ -721,4 +1977,33 @@
         }
     }
 
+
+    #region 杩斿洖
+    /// <summary>
+    /// 鎷嗗寘閾鹃」
+    /// </summary>
+    public class SplitChainItem
+    {
+        public Dt_SplitPackageRecord SplitRecord { get; set; }
+        public string OriginalBarcode { get; set; }
+        public string NewBarcode { get; set; }
+        public decimal SplitQuantity { get; set; }
+    }
+    public  class ReturnAnalysisResult
+    {
+        public bool HasItemsToReturn { get; set; }
+        public bool HasRemainingLocks { get; set; }
+        public bool HasPalletStockGoods { get; set; }
+        public bool HasSplitRecords { get; set; }
+        public decimal RemainingLocksReturnQty { get; set; }
+        public decimal PalletStockReturnQty { get; set; }
+        public decimal SplitReturnQty { get; set; }
+        public decimal TotalReturnQty { get; set; }
+        public List<Dt_OutStockLockInfo> RemainingLocks { get; set; } = new List<Dt_OutStockLockInfo>();
+        public List<Dt_StockInfoDetail> PalletStockGoods { get; set; } = new List<Dt_StockInfoDetail>();
+        public List<Dt_SplitPackageRecord> SplitRecords { get; set; } = new List<Dt_SplitPackageRecord>();
+    }
+
+    #endregion
+
 }

--
Gitblit v1.9.3