From 51bd4ac4f323fab99ff9ac20763ca15af0e53a57 Mon Sep 17 00:00:00 2001
From: heshaofeng <heshaofeng@hnkhzn.com>
Date: 星期四, 22 一月 2026 21:51:15 +0800
Subject: [PATCH] 1

---
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_InboundService/TakeStockOrderService.cs |  510 ++++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 472 insertions(+), 38 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_InboundService/TakeStockOrderService.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_InboundService/TakeStockOrderService.cs"
index d98ba61..ded4b28 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_InboundService/TakeStockOrderService.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_InboundService/TakeStockOrderService.cs"
@@ -22,6 +22,15 @@
 using WIDESEA_Common.CommonEnum;
 using WIDESEA_Common.TaskEnum;
 using WIDESEA_IBasicService;
+using static HslCommunication.Profinet.Knx.KnxCode;
+using System.Collections;
+using WIDESEA_Common.AllocateEnum;
+using WIDESEA_Model.Models.Basic;
+using WIDESEA_IOutboundService;
+using WIDESEA_DTO.CalcOut;
+using Newtonsoft.Json.Serialization;
+using Newtonsoft.Json;
+using WIDESEA_DTO.Basic;
 
 namespace WIDESEA_InboundService
 {
@@ -34,7 +43,16 @@
         private readonly IRepository<Dt_TakeStockOrderDetail> _takeStockOrderDetail;
         private readonly IRepository<Dt_Task> _taskRepository;
         private readonly ILocationInfoService _locationInfoService;
-        public TakeStockOrderService(IRepository<Dt_TakeStockOrder> BaseDal, IUnitOfWorkManage unitOfWorkManage,IRepository<Dt_TakeStockOrder> takeStockOrder,IRepository<Dt_StockInfo> stockInfoRepository,IRepository<Dt_TakeStockOrderDetail> takeStockOrderDetail,IRepository<Dt_Task> taskRepository,ILocationInfoService locationInfoService) : base(BaseDal)
+        private readonly IRepository<Dt_InboundOrder> _inboundOrderRepository;
+        private readonly IRepository<Dt_OutboundOrder> _outboundOrderRepository;
+        private readonly IRepository<Dt_InboundOrderDetail> _inboundOrderDetailRepository;
+        private readonly IRepository<Dt_OutboundOrderDetail> _outboundOrderDetailRepository;
+        private readonly IOutboundPickingService _outboundPickingService;
+        private readonly IRepository<Dt_StockInfoDetail> _stockInfoDetailRepository;
+        private readonly IOutboundService _outboundService;
+        private readonly IFeedbackMesService _feedbackMesService;
+        private readonly IESSApiService _eSSApiService;
+        public TakeStockOrderService(IRepository<Dt_TakeStockOrder> BaseDal, IUnitOfWorkManage unitOfWorkManage,IRepository<Dt_TakeStockOrder> takeStockOrder,IRepository<Dt_StockInfo> stockInfoRepository,IRepository<Dt_TakeStockOrderDetail> takeStockOrderDetail,IRepository<Dt_Task> taskRepository,ILocationInfoService locationInfoService, IRepository<Dt_InboundOrder> inboundOrderRepository,IRepository<Dt_OutboundOrder> outboundOrderRepository,IRepository<Dt_InboundOrderDetail> inboundOrderDetailRepository, IRepository<Dt_OutboundOrderDetail> outboundOrderDetailRepository, IOutboundPickingService outboundPickingService, IRepository<Dt_StockInfoDetail> stockInfoDetailRepository, IOutboundService outboundService,IFeedbackMesService feedbackMesService,IESSApiService eSSApiService) : base(BaseDal)
         {
             _unitOfWorkManage = unitOfWorkManage;
             _takeStockOrder = takeStockOrder;
@@ -42,8 +60,28 @@
             _takeStockOrderDetail = takeStockOrderDetail;
             _taskRepository = taskRepository;
             _locationInfoService = locationInfoService;
+            _inboundOrderRepository = inboundOrderRepository;
+            _outboundOrderRepository = outboundOrderRepository;
+            _inboundOrderDetailRepository = inboundOrderDetailRepository;
+            _outboundOrderDetailRepository = outboundOrderDetailRepository;
+            _outboundPickingService = outboundPickingService;
+            _stockInfoDetailRepository = stockInfoDetailRepository;
+            _outboundService = outboundService;
+            _feedbackMesService = feedbackMesService;
+            _eSSApiService = eSSApiService;
         }
 
+        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 WebResponseContent ValidateBoxNo(string orderNo, string boxNo)
         {
             try
@@ -52,14 +90,14 @@
                 if (stockInfo == null) {
                     return WebResponseContent.Instance.Error("鏈壘鍒拌鎵樼洏搴撳瓨");
                 }
-                if(stockInfo.StockStatus != StockStatusEmun.鐩樼偣鍑哄簱瀹屾垚.ObjToInt())
+                if(stockInfo.StockStatus != StockStatusEmun.鐩樼偣鍑哄簱瀹屾垚.ObjToInt() && stockInfo.StockStatus != StockStatusEmun.鐩樼偣搴撳瓨瀹屾垚.ObjToInt())
                 {
                     return WebResponseContent.Instance.Error("璇ユ墭鐩樺浜庨潪鐩樼偣鐘舵�侊紝璇锋鏌ョ洏鐐逛换鍔�");
                 }
-                Dt_TakeStockOrder takeStockOrder = _takeStockOrder.QueryFirst(x=>x.OrderNo == orderNo);
+                Dt_TakeStockOrder takeStockOrder = _takeStockOrder.QueryFirst(x=>x.AllPalletCode.Contains(boxNo)&& x.TakeStockStatus == TakeStockStatusEnum.鐩樼偣涓�.ObjToInt());
                 if (takeStockOrder == null)
                 {
-                    return WebResponseContent.Instance.Error("鏈壘鍒拌鐩樼偣鍗曟嵁");
+                    return WebResponseContent.Instance.Error("璇ユ墭鐩樻湭鎵惧埌璇ョ洏鐐瑰崟鎹�");
                 }
                 if (takeStockOrder.AllPalletCode.Contains(","))
                 {
@@ -76,19 +114,11 @@
                     bool isMatch = remarkValues.Any(val => val.Equals(boxNo, StringComparison.OrdinalIgnoreCase));
                     if (!isMatch)
                     {
-                        return WebResponseContent.Instance.Error($"绠卞彿銆恵boxNo}銆戞湭鍦ㄧ洏鐐瑰崟绠卞彿銆恵takeStockOrder.Remark}銆戜腑鎵惧埌鍖归厤椤�");
+                        return WebResponseContent.Instance.Error($"绠卞彿銆恵boxNo}銆戞湭鍦ㄧ洏鐐瑰崟绠卞彿銆恵takeStockOrder.AllPalletCode}銆戜腑鎵惧埌鍖归厤椤�");
                     }
                 }
-                else
-                {
-                    bool isMatch = takeStockOrder.Remark.Trim().Equals(boxNo, StringComparison.OrdinalIgnoreCase);
-                    if (!isMatch)
-                    {
-                        return WebResponseContent.Instance.Error($"绠卞彿銆恵boxNo}銆戜笌鐩樼偣鍗曠鍙枫�恵takeStockOrder.Remark}銆戜笉鍖归厤");
-                    }
-                }
-
-                return WebResponseContent.Instance.OK();
+                var resultData = new { takeStockOrder = takeStockOrder.OrderNo };
+                return WebResponseContent.Instance.OK(data:resultData);
             }
             catch(Exception ex)
             {
@@ -151,34 +181,40 @@
                 {
                     TakeStockId = takeStockOrder.Id,
                     MaterielCode = stockInfoDetail.MaterielCode,
-                    MaterielName = stockInfoDetail.MaterielName??"",
+                    MaterielName = stockInfoDetail.MaterielName ?? "",
                     BatchNo = stockInfoDetail.BatchNo,
                     TakePalletCode = completeStockTakeDTO.boxNo,
-                    TakeDetalStatus = TakeStockDetailStatusEnum.鐩樼偣瀹屾垚.ObjToInt(),
+                    TakeDetalStatus = TakeStockDetailStatusEnum.鏈繘琛屽钩璐﹀鐞�.ObjToInt(),
                     Unit = stockInfoDetail.Unit,
                     SysQty = completeStockTakeDTO.stockQuantity,
-                    Qty =completeStockTakeDTO.actualQuantity,
-                    Remark = completeStockTakeDTO.stockQuantity-completeStockTakeDTO.actualQuantity>=0 ?"鐩樹簭":"鐩樼泩",
+                    Qty = completeStockTakeDTO.actualQuantity,
+                    Remark = "鐩樹簭",
                     barcode = completeStockTakeDTO.barcode,
-                    WarehouseCode = stockInfoDetail.WarehouseCode??"",
+                    WarehouseCode = stockInfoDetail.WarehouseCode ?? "",
                     FactoryArea = stockInfoDetail.FactoryArea,
-                    SupplyCode = stockInfoDetail.SupplyCode??"",
+                    SupplyCode = stockInfoDetail.SupplyCode ?? "",
                     TakeStockNo = takeStockOrder.OrderNo,
+                    DifferenceQty = completeStockTakeDTO.actualQuantity - completeStockTakeDTO.stockQuantity
 
                 };
+                stockInfoDetail.StockId = 0;
+                stockInfoDetail.OrderNo = takeStockOrder.OrderNo;
+                stockInfo.StockStatus = StockStatusEmun.鐩樼偣搴撳瓨瀹屾垚.ObjToInt();
                 _unitOfWorkManage.BeginTran();
                 _takeStockOrderDetail.AddData(takeStockOrderDetail);
+                _stockInfoDetailRepository.UpdateData(stockInfoDetail);
+                _stockInfoRepository.UpdateData(stockInfo);
                 _unitOfWorkManage.CommitTran();
-                return WebResponseContent.Instance.OK();
-            } 
-            catch (Exception ex) 
+                return WebResponseContent.Instance.OK("鐩樼偣瀹屾垚锛岃鍙栬蛋璇ュ紓甯告枡绠辫繘琛屽钩璐﹀鐞嗭紒");
+            }
+            catch (Exception ex)
             {
                 _unitOfWorkManage.RollbackTran();
                 return WebResponseContent.Instance.Error(ex.Message);
             }
         }
 
-        public WebResponseContent ReturnBox(string orderNo, string boxNo)
+        public WebResponseContent ReturnBox(string orderNo, string boxNo, string sourceAddress)
         {
             WebResponseContent content = new WebResponseContent();
             try
@@ -188,7 +224,7 @@
                 {
                     return content.Error("鏈壘鍒拌鐩樼偣鍗曟嵁");
                 }
-                var stock = _stockInfoRepository.QueryFirst(x => x.PalletCode == boxNo);
+                var stock = _stockInfoRepository.Db.Queryable<Dt_StockInfo>().Where(x => x.PalletCode == boxNo).Includes(x=>x.Details).First();
 
                 if (stock == null)
                 {
@@ -196,19 +232,30 @@
                 }
 
                 var task = _taskRepository.QueryFirst(x => x.PalletCode == boxNo);
-                    
-
                 if (task != null)
                 {
-                    return content.Error($"鎵樼洏{boxNo}瀛樺湪浠诲姟鍥炲簱澶辫触!");
+                    return content.Error($"鎵樼洏{boxNo}瀛樺湪浠诲姟锛屽洖搴撳け璐�!");
                 }
-                if(stock.StockStatus != StockStatusEmun.鐩樼偣鍑哄簱瀹屾垚.ObjToInt())
+                if(stock.StockStatus != StockStatusEmun.鐩樼偣鍑哄簱瀹屾垚.ObjToInt() && stock.StockStatus != StockStatusEmun.鐩樼偣搴撳瓨瀹屾垚.ObjToInt())
                 {
                     return content.Error("璇ユ墭鐩樼姸鎬佷笉瀵�,涓嶅厑璁哥洏鐐瑰叆搴�");
                 }
-                stock.StockStatus = StockStatusEmun.鍏ュ簱纭.ObjToInt();
+                var palletCodes = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
+                if (!string.IsNullOrEmpty(takeStockOrder.AllPalletCode))
+                {
+                    palletCodes = takeStockOrder.AllPalletCode
+                        .Split(new[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries)
+                        .Select(p => p.Trim())
+                        .ToHashSet(StringComparer.OrdinalIgnoreCase);
+                }
+                int overPalletCodeCount = _stockInfoRepository.QueryData(x => palletCodes.Contains(x.PalletCode) && (x.StockStatus == StockStatusEmun.鍑哄簱瀹屾垚.ObjToInt() || x.StockStatus == StockStatusEmun.鍏ュ簱瀹屾垚.ObjToInt() || x.StockStatus == StockStatusEmun.鍑哄簱閿佸畾.ObjToInt()|| x.StockStatus == StockStatusEmun.鍏ュ簱纭.ObjToInt())).Count();
+                bool hasRelatedTasks = palletCodes.Count == overPalletCodeCount + 1;
 
-                takeStockOrder.TakeStockStatus = TakeStockStatusEnum.鐩樼偣瀹屾垚.ObjToInt();
+                if (hasRelatedTasks)
+                {
+                    takeStockOrder.TakeStockStatus = (int)TakeStockStatusEnum.鐩樼偣瀹屾垚;
+                }
+                stock.StockStatus = StockStatusEmun.鍏ュ簱纭.ObjToInt();
                 // 鍒嗛厤鏂拌揣浣�
                 var newLocation = _locationInfoService.AssignLocation(stock.LocationType);
 
@@ -220,24 +267,29 @@
                     NextAddress = "",
                     OrderNo = takeStockOrder.OrderNo,
                     Roadway = newLocation.RoadwayNo,
-                    SourceAddress = takeStockOrder.Remark,
+                    SourceAddress = stations.GetValueOrDefault(sourceAddress)??"",
                     TargetAddress = newLocation.LocationCode,
                     TaskStatus = (int)TaskStatusEnum.New,
                     TaskType = TaskTypeEnum.InInventory.ObjToInt(),
                     PalletType = stock.PalletType,
                     WarehouseId = stock.WarehouseId
                 };
+                if (stock.Details.Count <= 0)
+                {
+                    stock.PalletType = (int)PalletTypeEnum.Empty;
+                    newTask.TaskType = TaskTypeEnum.InEmpty.ObjToInt();
+                }
                 _unitOfWorkManage.BeginTran();
                 _stockInfoRepository.UpdateData(stock);
                 _takeStockOrder.UpdateData(takeStockOrder);
                 _taskRepository.AddData(newTask);
                 _unitOfWorkManage.CommitTran();
 
-                //var moveResult = await _eSSApiService.MoveContainerAsync(new MoveContainerRequest
-                //{
-                //    slotCode = movestations[station],
-                //    containerCode = palletCode
-                //});
+                var moveResult = _eSSApiService.MoveContainerAsync(new MoveContainerRequest
+                {
+                    slotCode = movestations[sourceAddress],
+                    containerCode = boxNo
+                });
                 return content.OK();
 
             }
@@ -247,6 +299,388 @@
                 return content.Error(ex.Message);
             }
         }
+
+        public WebResponseContent ManualReconciliation(int id)
+        {
+            try
+            {
+                Dt_TakeStockOrderDetail takeStockOrderDetail = _takeStockOrderDetail.QueryFirst(x=>x.Id == id);
+                if(takeStockOrderDetail == null)
+                {
+                    return WebResponseContent.Instance.Error("鏈壘鍒拌鐩樼偣宸紓璁板綍");
+                }
+                else
+                {
+                    if(takeStockOrderDetail.TakeDetalStatus != TakeStockDetailStatusEnum.鏈繘琛屽钩璐﹀鐞�.ObjToInt())
+                    {
+                        return WebResponseContent.Instance.Error("璇ヨ褰曞凡缁忚繘琛屼簡骞宠处鎿嶄綔");
+                    }
+                    takeStockOrderDetail.DifferenceQty = 0;
+                    takeStockOrderDetail.TakeDetalStatus = TakeStockDetailStatusEnum.宸茶繘琛屽钩璐﹀鐞�.ObjToInt();
+                }
+                _takeStockOrderDetail.UpdateData(takeStockOrderDetail);
+                return WebResponseContent.Instance.OK();
+            }
+            catch(Exception ex)
+            {
+                return WebResponseContent.Instance.Error(ex.Message);
+            }
+        }
+
+        public WebResponseContent SelectOrder(string remark, int id)
+        {
+            try
+            {
+                Dt_TakeStockOrderDetail takeStockOrderDetail = _takeStockOrderDetail.QueryFirst(x => x.Id == id);
+                if (takeStockOrderDetail == null)
+                {
+                    return WebResponseContent.Instance.Error("鏈壘鍒拌鐩樼偣宸紓璁板綍");
+                }
+                else
+                {
+                    //鏌ユ潅鏀跺崟
+                    if (takeStockOrderDetail.Remark == "鐩樼泩")
+                    {
+                        List<Dt_InboundOrderDetail> inboundOrderDetails = new List<Dt_InboundOrderDetail>();
+                        List<Dt_InboundOrder> inboundOrders = _inboundOrderRepository.Db.Queryable<Dt_InboundOrder>().Where(x => x.BusinessType == "12" && x.OrderStatus != InOrderStatusEnum.鍏ュ簱瀹屾垚.ObjToInt()).Includes(x => x.Details).ToList();
+                        foreach (var inboundOrder in inboundOrders)
+                        {
+
+                            var matchedDetails = inboundOrder.Details
+
+                                .Where(detail => !string.IsNullOrEmpty(detail.MaterielCode)
+                                              && detail.MaterielCode == takeStockOrderDetail.MaterielCode && detail.OrderDetailStatus != OrderDetailStatusEnum.Over.ObjToInt())
+
+                                .WhereIF(!string.IsNullOrEmpty(takeStockOrderDetail.FactoryArea),
+                                         detail => !string.IsNullOrEmpty(inboundOrder.FactoryArea)
+                                              && inboundOrder.FactoryArea == takeStockOrderDetail.FactoryArea)
+                                .WhereIF(!string.IsNullOrEmpty(takeStockOrderDetail.WarehouseCode),
+                                         detail => !string.IsNullOrEmpty(detail.WarehouseCode)
+                                         && detail.WarehouseCode == takeStockOrderDetail.WarehouseCode)
+                                .WhereIF(!string.IsNullOrEmpty(takeStockOrderDetail.BatchNo),
+                                         detail => !string.IsNullOrEmpty(detail.BatchNo)
+                                         && detail.BatchNo == takeStockOrderDetail.BatchNo)
+
+                                .ToList();
+
+                            // 灏嗗尮閰嶇殑鏄庣粏娣诲姞鍒版�诲垪琛�
+                            if (matchedDetails.Any())
+                            {
+                                inboundOrderDetails.AddRange(matchedDetails);
+                            }
+                        }
+                        return WebResponseContent.Instance.OK("鎴愬姛",data: inboundOrderDetails);
+                    }
+                    else
+                    {
+                        List<Dt_OutboundOrderDetail> outboundOrderDetails = new List<Dt_OutboundOrderDetail>();
+                        List<Dt_OutboundOrder> outboundOrders = _outboundOrderRepository.Db.Queryable<Dt_OutboundOrder>().Where(x => x.BusinessType == "23" && x.OrderStatus != OutOrderStatusEnum.鍑哄簱瀹屾垚.ObjToInt()).Includes(x => x.Details).ToList();
+                        foreach (var outboundOrder in outboundOrders)
+                        {
+                            var matchedDetails = outboundOrder.Details
+                                .Where(detail => !string.IsNullOrWhiteSpace(detail.MaterielCode)
+                                              && detail.MaterielCode == takeStockOrderDetail.MaterielCode && detail.OrderQuantity-detail.MoveQty-detail.OverOutQuantity>0)
+                                .WhereIF(!string.IsNullOrWhiteSpace(takeStockOrderDetail.FactoryArea),
+                                         detail => !string.IsNullOrWhiteSpace(outboundOrder.FactoryArea)
+                                              && outboundOrder.FactoryArea == takeStockOrderDetail.FactoryArea)
+                                .WhereIF(!string.IsNullOrWhiteSpace(takeStockOrderDetail.WarehouseCode),
+                                         detail => !string.IsNullOrWhiteSpace(detail.WarehouseCode)
+                                              && detail.WarehouseCode == takeStockOrderDetail.WarehouseCode)
+                                .Where(detail => string.IsNullOrWhiteSpace(detail.BatchNo)||
+                                         detail.BatchNo == takeStockOrderDetail.BatchNo)
+
+                                .Where(detail => string.IsNullOrWhiteSpace(detail.SupplyCode) ||
+                                         detail.SupplyCode == takeStockOrderDetail.SupplyCode)
+                                .ToList();
+
+                            if (matchedDetails.Any())
+                            {
+                                outboundOrderDetails.AddRange(matchedDetails);
+                            }
+                        }
+                        return WebResponseContent.Instance.OK("鎴愬姛", data: outboundOrderDetails);
+                    }
+                }
+            }
+            catch (Exception ex)
+            {
+                return WebResponseContent.Instance.Error(ex.Message);
+            }
+        }
+
+        public WebResponseContent DocumentReconciliation(string barcode)
+        {
+            WebResponseContent webResponseContent = new WebResponseContent();
+            try
+            {
+                Dt_TakeStockOrderDetail takeStockOrderDetail = _takeStockOrderDetail.QueryFirst(x => x.barcode == barcode);
+                if (takeStockOrderDetail == null)
+                {
+                    return WebResponseContent.Instance.Error("鏈壘鍒拌鐩樼偣宸紓鏁版嵁");
+                }
+                Dt_OutboundOrderDetail outboundOrderDetail = _outboundOrderDetailRepository.QueryFirst(x => x.Remark == takeStockOrderDetail.TakeStockNo && (x.OrderQuantity-x.LockQuantity-x.MoveQty)>0);
+                if (outboundOrderDetail == null)
+                {
+                    return WebResponseContent.Instance.Error("鏈壘鍒伴�夋嫨鐨勬潅鍙戝钩璐﹀崟鎹�");
+                }
+                if(outboundOrderDetail.MaterielCode != takeStockOrderDetail.MaterielCode)
+                {
+                    return WebResponseContent.Instance.Error("涓庢潅鍙戝钩璐﹀崟鎹墿鏂欑紪鐮佷笉鍖归厤");
+                }
+                if (!string.IsNullOrWhiteSpace(outboundOrderDetail.BatchNo)&& outboundOrderDetail.BatchNo != takeStockOrderDetail.BatchNo)
+                {
+                    return WebResponseContent.Instance.Error("涓庢潅鍙戝钩璐﹀崟鎹墿鏂欐壒娆′笉鍖归厤");
+                }
+                if (!string.IsNullOrWhiteSpace(outboundOrderDetail.SupplyCode) && outboundOrderDetail.SupplyCode != takeStockOrderDetail.SupplyCode)
+                {
+                    return WebResponseContent.Instance.Error("涓庢潅鍙戝钩璐﹀崟鎹緵搴斿晢涓嶅尮閰�");
+                }
+                Dt_OutboundOrder outboundOrder = _outboundOrderRepository.Db.Queryable<Dt_OutboundOrder>().Where(x => x.Id == outboundOrderDetail.OrderId).Includes(x => x.Details).First();
+
+                takeStockOrderDetail.TakeDetalStatus = TakeStockDetailStatusEnum.鏉傛敹鏉傚彂骞宠处澶勭悊.ObjToInt();
+                OutboundCompleteRequestDTO request = new OutboundCompleteRequestDTO()
+                {
+                    OrderNo = outboundOrder.OrderNo,
+                    PalletCode = takeStockOrderDetail.TakePalletCode,
+                    Barcode = takeStockOrderDetail.barcode,
+                    Operator = App.User.UserName
+                };
+                webResponseContent = CompleteOutboundWithBarcode(request,outboundOrderDetail.Id);
+                takeStockOrderDetail.DifferenceQty = 0;
+                _takeStockOrderDetail.UpdateData(takeStockOrderDetail);
+                return WebResponseContent.Instance.OK(data: webResponseContent);
+            }
+            catch(Exception ex)
+            {
+                _unitOfWorkManage.RollbackTran();
+                return WebResponseContent.Instance.Error(ex.Message);
+
+            }
+        }
+        public WebResponseContent CompleteOutboundWithBarcode(OutboundCompleteRequestDTO request ,int orderDetailId)
+        {
+            WebResponseContent content = WebResponseContent.Instance;
+
+            OutboundCompleteResponseDTO response = new();
+            try
+            {
+                // 1. 鏍规嵁鎵樼洏鍙锋煡鎵惧簱瀛樹俊鎭�
+                Dt_StockInfo stockInfo = _stockInfoRepository.QueryFirst(x => x.PalletCode == request.PalletCode);
+                if (stockInfo == null)
+                {
+                    response.Success = false;
+                    response.Message = $"鎵樼洏鍙� {request.PalletCode} 瀵瑰簲鐨勫簱瀛樹笉瀛樺湪";
+                    return WebResponseContent.Instance.Error($"鎵樼洏鍙� {request.PalletCode} 瀵瑰簲鐨勫簱瀛樹笉瀛樺湪");
+                }
+
+                // 2. 鏍规嵁鏉$爜鏌ユ壘搴撳瓨鏄庣粏
+                Dt_StockInfoDetail stockDetail = _stockInfoDetailRepository.QueryFirst(x => x.Barcode == request.Barcode);
+                if (stockDetail == null)
+                {
+                    response.Success = false;
+                    response.Message = $"鏉$爜 {request.Barcode} 瀵瑰簲鐨勫簱瀛樻槑缁嗕笉瀛樺湪";
+                    return WebResponseContent.Instance.Error($"鏉$爜 {request.Barcode} 瀵瑰簲鐨勫簱瀛樻槑缁嗕笉瀛樺湪");
+                }
+
+
+
+                // 4. 鏌ユ壘鍑哄簱鍗曚俊鎭�
+                Dt_OutboundOrder outboundOrder = _outboundOrderRepository.QueryFirst(o => o.OrderNo == request.OrderNo);
+                if (outboundOrder == null)
+                {
+                    response.Success = false;
+                    response.Message = $"鍑哄簱鍗� {request.OrderNo} 涓嶅瓨鍦�";
+                    return WebResponseContent.Instance.Error($"鍑哄簱鍗� {request.OrderNo} 涓嶅瓨鍦�");
+                }
+
+                Dt_OutboundOrderDetail outboundOrderDetail = _outboundOrderDetailRepository.QueryFirst(x => x.Id == orderDetailId);
+                if (outboundOrderDetail == null)
+                {
+                    return WebResponseContent.Instance.Error("鏈壘鍒板嚭搴撳崟鏄庣粏");
+                }
+                // 瀹為檯鍑哄簱閲�
+                decimal actualOutboundQuantity = outboundOrderDetail.OrderQuantity-outboundOrderDetail.LockQuantity-outboundOrderDetail.MoveQty;
+
+
+                // 8. 鍒ゆ柇鏄惁闇�瑕佹媶鍖咃紙褰撳嚭搴撴暟閲忓皬浜庡簱瀛樻暟閲忔椂闇�瑕佹媶鍖咃級
+                bool isUnpacked = actualOutboundQuantity < stockDetail.StockQuantity;
+                List<MaterialCodeReturnDTO> returnDTOs = new List<MaterialCodeReturnDTO>();
+                string newBarcode = string.Empty;
+                // 9. 寮�鍚簨鍔�
+                _unitOfWorkManage.BeginTran();
+                try
+                {
+                    decimal beforeQuantity = stockDetail.StockQuantity; // 鍘熷搴撳瓨閲�
+
+                    Dt_AllocateMaterialInfo allocateMaterialInfo = new Dt_AllocateMaterialInfo();
+
+                    // 鏍规嵁鏄惁鎷嗗寘鎵ц涓嶅悓鐨勬搷浣�
+                    if (isUnpacked)
+                    {
+                        (string NewBarcode, List<MaterialCodeReturnDTO> MaterialCodeReturnDTOs) result = _outboundService.PerformUnpackOperation(stockDetail, stockInfo, actualOutboundQuantity, request, beforeQuantity, 0, outboundOrder.Id, outboundOrder.OrderNo);
+
+                        returnDTOs = result.MaterialCodeReturnDTOs;
+                        newBarcode = result.NewBarcode;
+
+                        MaterialCodeReturnDTO returnDTO = returnDTOs.First(x => x.Barcode == newBarcode);
+
+                        if (outboundOrder.OrderType != 0)
+                        {
+                            allocateMaterialInfo = new Dt_AllocateMaterialInfo()
+                            {
+                                Barcode = returnDTO.Barcode,
+                                BatchNo = returnDTO.BatchNo,
+                                FactoryArea = returnDTO.FactoryArea,
+                                MaterialCode = returnDTO.MaterialCode,
+                                MaterialName = returnDTO.MaterialName,
+                                OrderId = outboundOrder.Id,
+                                OrderNo = outboundOrder.OrderNo,
+                                Quantity = returnDTO.Quantity,
+                                SupplyCode = returnDTO.SuplierCode,
+                                Unit = stockDetail.Unit
+                            };
+                        }
+
+                    }
+                    else
+                    {
+                       _outboundService.PerformFullOutboundOperation(stockDetail, stockInfo, actualOutboundQuantity, request, beforeQuantity, 0);
+
+                        if (outboundOrder.OrderType != 0)
+                        {
+                            allocateMaterialInfo = new Dt_AllocateMaterialInfo()
+                            {
+                                Barcode = stockDetail.Barcode,
+                                BatchNo = stockDetail.BatchNo,
+                                FactoryArea = stockDetail.FactoryArea,
+                                MaterialCode = stockDetail.MaterielCode,
+                                MaterialName = stockDetail.MaterielName,
+                                OrderId = outboundOrder.Id,
+                                OrderNo = outboundOrder.OrderNo,
+                                Quantity = stockDetail.StockQuantity,
+                                SupplyCode = stockDetail.SupplyCode,
+                                Unit = stockDetail.Unit
+                            };
+                        }
+
+                    }
+                    
+                    List<Dt_OutboundOrderDetail> outboundOrderDetails = new List<Dt_OutboundOrderDetail>();
+
+                    outboundOrderDetails.Add(outboundOrderDetail);
+
+                    decimal allocatedQuantity = actualOutboundQuantity;
+                    List<Dt_OutboundOrderDetail> updateDetails = new();
+                    foreach (var item in outboundOrderDetails)
+                    {
+                        if (allocatedQuantity <= 0) break;
+
+                        decimal barcodeQuantity = allocatedQuantity;
+
+                        if (item.LockQuantity - item.OverOutQuantity >= allocatedQuantity)
+                        {
+                            item.OverOutQuantity += allocatedQuantity;
+                            item.CurrentDeliveryQty += allocatedQuantity;
+                            allocatedQuantity = 0;
+                        }
+                        else
+                        {
+                            barcodeQuantity = allocatedQuantity;
+                            allocatedQuantity -= (item.LockQuantity - item.OverOutQuantity);
+                            item.OverOutQuantity = allocatedQuantity;
+                            item.LockQuantity = allocatedQuantity;
+                            item.CurrentDeliveryQty = allocatedQuantity;
+                        }
+
+                        updateDetails.Add(item);
+
+                        List<Barcodes> barcodesList = new List<Barcodes>();
+                        Barcodes barcodes = new Barcodes
+                        {
+                            Barcode = isUnpacked ? newBarcode : stockDetail?.Barcode,
+                            Qty = barcodeQuantity,
+                            SupplyCode = stockDetail?.SupplyCode ?? "",
+                            BatchNo = stockDetail?.BatchNo ?? "",
+                            Unit = stockDetail?.Unit ?? ""
+                        };
+                        if (!string.IsNullOrEmpty(item.ReturnJsonData))
+                        {
+                            barcodesList = JsonConvert.DeserializeObject<List<Barcodes>>(item.ReturnJsonData) ?? new List<Barcodes>();
+                        }
+                        barcodesList.Add(barcodes);
+                        JsonSerializerSettings settings = new JsonSerializerSettings
+                        {
+                            ContractResolver = new CamelCasePropertyNamesContractResolver()
+                        };
+                        item.ReturnJsonData = JsonConvert.SerializeObject(barcodesList, settings);
+                    }
+
+                    // 鏇存柊鍑哄簱鍗曟槑缁嗙殑宸插嚭搴撴暟閲�
+                    _outboundOrderDetailRepository.UpdateData(updateDetails);
+
+                    // 鏇存柊閿佸畾璁板綍鐨勭疮璁″凡鍑哄簱鏁伴噺锛堥渶瑕佹洿鏂拌鎵樼洏璇ョ墿鏂欑殑鎵�鏈夌浉鍏宠褰曪級
+                    //UpdateLockInfoAllocatedQuantity(stockInfo.Id, stockDetail.MaterielCode, stockDetail.BatchNo, actualOutboundQuantity);
+
+                    // 鎻愪氦浜嬪姟
+                    _unitOfWorkManage.CommitTran();
+
+                    // 鏋勫缓杩斿洖淇℃伅
+                    ScannedStockDetailDTO scannedDetail = new ScannedStockDetailDTO
+                    {
+                        StockDetailId = stockDetail.Id,
+                        PalletCode = stockInfo.PalletCode,
+                        MaterielCode = stockDetail.MaterielCode,
+                        MaterielName = stockDetail.MaterielName,
+                        BatchNo = stockDetail.BatchNo,
+                        OriginalBarcode = request.Barcode,
+                        BeforeQuantity = beforeQuantity,
+                        AfterQuantity = isUnpacked ? actualOutboundQuantity : 0,
+                        ChangeQuantity = -actualOutboundQuantity,
+                        IsUnpacked = isUnpacked,
+                        MaterialCodes = returnDTOs
+                    };
+
+                    response.Success = true;
+                    response.Message = "鍑哄簱瀹屾垚";
+                    response.ScannedDetail = scannedDetail;
+                    response.UpdatedDetails = updateDetails;
+
+                    if (!string.IsNullOrEmpty(newBarcode))
+                    {
+                        // 鐗╂枡鏂版潯鐮佸洖浼�
+                        _feedbackMesService.BarcodeFeedback(newBarcode);
+                    }
+                    List<Dt_OutboundOrderDetail> details = _outboundOrderDetailRepository.QueryData(x => x.OrderId == outboundOrder.Id);
+                    if(details.All(x => x.OverOutQuantity >= x.OrderQuantity - x.MoveQty))
+                    {
+                        _feedbackMesService.OutboundFeedback(outboundOrder.OrderNo);
+                        outboundOrder.OrderStatus = OutOrderStatusEnum.鍑哄簱瀹屾垚.ObjToInt();
+                        _outboundOrderRepository.UpdateData(outboundOrder);
+                    }
+                    
+
+                }
+                catch (Exception ex)
+                {
+                    _unitOfWorkManage.RollbackTran();
+                    response.Success = false;
+                    response.Message = $"鍑哄簱澶勭悊澶辫触锛歿ex.Message}";
+                    return WebResponseContent.Instance.Error(ex.Message);
+                }
+
+                content = WebResponseContent.Instance.OK(data: response);
+            }
+            catch (Exception ex)
+            {
+                content = WebResponseContent.Instance.Error("澶勭悊鍑哄簱瀹屾垚澶辫触锛�" + ex.Message);
+            }
+            return content;
+        }
+
+        public WebResponseContent StockTakeGroupPallet(string barcode, string boxNo)
+        {
+            throw new NotImplementedException();
+        }
     }
     
 }

--
Gitblit v1.9.3