From 20a71f4bafb8cda355948cc061827b8d4752966f Mon Sep 17 00:00:00 2001
From: z8018 <1282578289@qq.com>
Date: 星期三, 17 十二月 2025 10:44:17 +0800
Subject: [PATCH] Merge branch 'htq20251215' of http://115.159.85.185:8098/r/ZhongRui/ALDbanyunxiangmu into htq20251215

---
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundService.cs |  370 ++++++++++++++++++++++++++++++++++++++--------------
 1 files changed, 272 insertions(+), 98 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/OutboundService.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/OutboundService.cs"
index 72b1b1c..aa37561 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/OutboundService.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/OutboundService.cs"
@@ -1,12 +1,17 @@
-锘縰sing SqlSugar;
+锘縰sing AutoMapper;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Serialization;
+using SqlSugar;
 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.CodeConfigEnum;
 using WIDESEA_Core.Helper;
 using WIDESEA_DTO.CalcOut;
+using WIDESEA_DTO.ReturnMES;
 using WIDESEA_IBasicService;
 using WIDESEA_IOutboundService;
 using WIDESEA_IRecordService;
@@ -17,7 +22,7 @@
 {
     public partial class OutboundService : IOutboundService
     {
-
+        private readonly IMapper _mapper;
         public IUnitOfWorkManage _unitOfWorkManage { get; }
 
         public IOutboundOrderDetailService OutboundOrderDetailService { get; }
@@ -27,32 +32,40 @@
         public IOutStockLockInfoService OutboundStockLockInfoService { get; }
 
         private readonly ISqlSugarClient Db;
-        private readonly IOutboundOrderDetailService _detailService;
-        private readonly IOutboundOrderService _outboundOrderService;
-        private readonly IOutStockLockInfoService _outboundLockInfoService;
-        private readonly IStockInfoService _stockInfoService;
-        private readonly IStockInfoDetailService _stockDetailService;
-        private readonly ILocationInfoService _locationInfoService;
-        private readonly IStockQuantityChangeRecordService _stockChangeService;
-        private readonly IStockInfoDetail_HtyService _stockDetailHistoryService;
+        private readonly IBasicService _basicService;
 
-        public OutboundService(IUnitOfWorkManage unitOfWorkManage, IOutboundOrderDetailService outboundOrderDetailService, IOutboundOrderService outboundOrderService, IOutStockLockInfoService outboundStockLockInfoService, IStockInfoService stockInfoService, IStockInfoDetailService stockDetailService, ILocationInfoService locationInfoService, IStockQuantityChangeRecordService stockQuantityChangeRecordService, IStockInfoDetail_HtyService stockDetailHistoryService)
+
+        private readonly IRepository<Dt_OutboundOrderDetail> _detailRepository;
+        private readonly IRepository<Dt_OutboundOrder> _outboundRepository;
+        private readonly IRepository<Dt_OutStockLockInfo> _outboundLockInfoRepository;
+        private readonly IRepository<Dt_StockInfo> _stockInfoRepository;
+        private readonly IRepository<Dt_StockInfoDetail> _stockDetailRepository;
+        private readonly IRepository<Dt_LocationInfo> _locationInfoRepository;
+        private readonly IRepository<Dt_StockQuantityChangeRecord> _stockChangeRepository;
+        private readonly IRepository<Dt_StockInfoDetail_Hty> _stockDetailHistoryRepository;
+        private readonly IFeedbackMesService _feedbackMesService;
+
+        public OutboundService(IMapper mapper, IUnitOfWorkManage unitOfWorkManage, IRepository<Dt_OutboundOrderDetail> detailRepository, IRepository<Dt_OutboundOrder> outboundRepository, IRepository<Dt_OutStockLockInfo> outboundLockInfoRepository, IRepository<Dt_StockInfo> stockInfoRepository, IRepository<Dt_StockInfoDetail> stockDetailRepository, IRepository<Dt_StockQuantityChangeRecord> stockChangeRepository, IRepository<Dt_StockInfoDetail_Hty> stockDetailHistoryRepository, IBasicService basicService, IOutboundOrderDetailService outboundOrderDetailService, IOutboundOrderService outboundOrderService, IOutStockLockInfoService outboundStockLockInfoService, IFeedbackMesService feedbackMesService)
         {
+            _mapper = mapper;
             _unitOfWorkManage = unitOfWorkManage;
             Db = _unitOfWorkManage.GetDbClient();
             OutboundOrderDetailService = outboundOrderDetailService;
             OutboundOrderService = outboundOrderService;
             OutboundStockLockInfoService = outboundStockLockInfoService;
-            _detailService = outboundOrderDetailService;
-            _outboundOrderService = outboundOrderService;
-            _outboundLockInfoService = outboundStockLockInfoService;
-            _stockInfoService = stockInfoService;
-            _stockDetailService = stockDetailService;
-            _locationInfoService = locationInfoService;
-            _stockChangeService = stockQuantityChangeRecordService;
-            _stockDetailHistoryService = stockDetailHistoryService;
+            _detailRepository = detailRepository;
+            _outboundRepository = outboundRepository;
+            _outboundLockInfoRepository = outboundLockInfoRepository;
+            _stockInfoRepository = stockInfoRepository;
+            _stockDetailRepository = stockDetailRepository;
+            _locationInfoRepository = basicService.LocationInfoService.Repository;
+            _stockChangeRepository = stockChangeRepository;
+            _stockDetailHistoryRepository = stockDetailHistoryRepository;
+            _basicService = basicService;
+            _feedbackMesService = feedbackMesService;
         }
 
+        #region 鍑哄簱鍒嗛厤
         /// <summary>
         /// 鍒嗘嫞鍑哄簱鎿嶄綔
         /// </summary>
@@ -97,15 +110,31 @@
                         if (outStockLockInfo != null)
                         {
                             outStockLockInfo = item;
+                            Dt_Task? task = tasks.FirstOrDefault(x => x.PalletCode == item.PalletCode);
+                            if (task != null)
+                            {
+                                outStockLockInfo.TaskNum = task.TaskNum;
+                            }
                         }
                         else
                         {
+                            Dt_Task? task = tasks.FirstOrDefault(x => x.PalletCode == item.PalletCode);
+                            if (task != null)
+                            {
+                                item.TaskNum = task.TaskNum;
+                            }
                             materielCalc.OutStockLockInfos.Add(item);
                         }
                         outStockLockInfos.Add(item);
                     }
-
-                    tasks.AddRange(materielPickedDetails.Tasks);
+                    foreach (var item in materielPickedDetails.Tasks)
+                    {
+                        Dt_Task? task = tasks.FirstOrDefault(x => x.PalletCode == item.PalletCode);
+                        if (task == null)
+                        {
+                            tasks.Add(item);
+                        }
+                    }
 
                     pickedDetails.AddRange(materielPickedDetails.PickedDetails);
 
@@ -113,9 +142,17 @@
                     foreach (var detail in materielCalc.Details)
                     {
                         decimal lockQuantity = (detail.OrderQuantity - detail.OverOutQuantity);
-                        detail.LockQuantity += lockQuantity; // 澧炲姞閿佸畾鏁伴噺 涓嶆洿鏂� OverOutQuantity 鍜� OrderDetailStatus锛屽洜涓鸿繕娌℃湁瀹為檯鍑哄簱
-
-                        outboundOrderDetails.Add(detail);
+                        if (lockQuantity < materielCalc.UnallocatedQuantity)
+                        {
+                            detail.LockQuantity += lockQuantity; // 澧炲姞閿佸畾鏁伴噺 涓嶆洿鏂� OverOutQuantity 鍜� OrderDetailStatus锛屽洜涓鸿繕娌℃湁瀹為檯鍑哄簱
+                            outboundOrderDetails.Add(detail);
+                        }
+                        else
+                        {
+                            detail.LockQuantity += materielCalc.UnallocatedQuantity;
+                            outboundOrderDetails.Add(detail);
+                            break;
+                        }
                     }
                 }
 
@@ -123,7 +160,7 @@
                 UpdateOutboundOrderStatus(request.OrderNo, (int)OutOrderStatusEnum.鍑哄簱涓�);
 
                 // 4. 鏇存柊鍑哄簱鍗曟槑缁嗛攣瀹氭暟閲�
-                _detailService.Repository.UpdateData(outboundOrderDetails);
+                _detailRepository.UpdateData(outboundOrderDetails);
 
                 // 5. 鏇存柊搴撳瓨鐘舵��
                 UpdateStockStatus(pickedDetails.Select(x => x.PalletCode).ToList(), StockStatusEmun.鍑哄簱閿佸畾.ObjToInt());
@@ -163,7 +200,7 @@
 
             try
             {
-                Dt_OutboundOrder outboundOrder = _outboundOrderService.Repository.QueryFirst(x => x.OrderNo == request.OrderNo);
+                Dt_OutboundOrder outboundOrder = _outboundRepository.QueryFirst(x => x.OrderNo == request.OrderNo);
                 if (outboundOrder == null)
                 {
                     result.CanOutbound = false;
@@ -172,10 +209,15 @@
                 }
 
                 result.FactoryArea = outboundOrder.FactoryArea;
-                result.IsMultiDetail = request.IsMultiDetail;
 
                 // 鑾峰彇閫夋嫨鐨勫嚭搴撴槑缁�
-                List<Dt_OutboundOrderDetail> selectedDetails = _detailService.Repository.QueryData(x => x.OrderId == outboundOrder.Id && request.DetailIds.Contains(x.Id));
+                List<Dt_OutboundOrderDetail> selectedDetails = _detailRepository.QueryData(x => x.OrderId == outboundOrder.Id && request.DetailIds.Contains(x.Id));
+
+                if (outboundOrder.IsBatch == 1)
+                {
+                    selectedDetails = _detailRepository.QueryData(x => x.WarehouseCode == selectedDetails.First().WarehouseCode && x.MaterielCode == selectedDetails.First().MaterielCode && x.BatchNo == selectedDetails.First().BatchNo && x.SupplyCode == selectedDetails.First().SupplyCode);
+                }
+
 
                 if (!selectedDetails.Any())
                 {
@@ -183,7 +225,6 @@
                     result.ErrorMessage = $"鏈壘鍒伴�夋嫨鐨勫嚭搴撴槑缁嗕俊鎭�";
                     return result;
                 }
-
                 if (selectedDetails.Any(x => x.LockQuantity > x.OrderQuantity - x.MoveQty || x.OverOutQuantity > x.OrderQuantity - x.MoveQty))
                 {
                     List<int> selectDetailIds = selectedDetails.Where(x => x.LockQuantity > x.OrderQuantity - x.MoveQty || x.OverOutQuantity > x.OrderQuantity - x.MoveQty).Select(x => x.Id).ToList();
@@ -196,7 +237,7 @@
                 result.OutboundOrder = outboundOrder;
                 result.SelectedDetails = selectedDetails;
 
-                if (request.IsMultiDetail)
+                if (outboundOrder.IsBatch == 0)
                 {
                     // 澶氭槑缁嗗嚭搴擄細鎸夌墿鏂欏垎缁勫鐞�
                     result.MaterielCalculations = CalcMaterielOutboundQuantities(outboundOrder, selectedDetails.ToList());
@@ -211,15 +252,21 @@
                         return result;
                     }
 
+                    decimal lockQuantity = selectedDetails.Sum(x => x.LockQuantity);
+                    decimal orderQuantity = selectedDetails.Sum(x => x.OrderQuantity);
+                    decimal moveQuantity = selectedDetails.Sum(x => x.MoveQty);
+                    decimal overQuantity = selectedDetails.Sum(x => x.OverOutQuantity);
+
                     Dt_OutboundOrderDetail? singleDetail = selectedDetails.First();
 
                     //鍒ゆ柇鍙嚭搴撴暟閲�
-                    if (singleDetail.OrderQuantity - singleDetail.LockQuantity - singleDetail.MoveQty <= 0)
+                    if (orderQuantity - lockQuantity - moveQuantity < request.OutboundQuantity.Value || orderQuantity - overQuantity - moveQuantity < request.OutboundQuantity.Value)
                     {
                         result.CanOutbound = false;
-                        result.ErrorMessage = $"鏈鍑哄簱鏁伴噺 {request.OutboundQuantity.Value} 瓒呰繃鍙嚭搴撴暟閲� {singleDetail.OrderQuantity - singleDetail.LockQuantity - singleDetail.MoveQty}";
+                        result.ErrorMessage = $"鏈鍑哄簱鏁伴噺 {request.OutboundQuantity.Value} 瓒呰繃鍙嚭搴撴暟閲� {orderQuantity - lockQuantity - moveQuantity}";
                         return result;
                     }
+
                     result.MaterielCalculations = new List<MaterielOutboundCalculationDTO>()
                     {
                         new MaterielOutboundCalculationDTO
@@ -229,12 +276,12 @@
                             BatchNo = singleDetail.BatchNo,
                             SupplyCode = singleDetail.SupplyCode,
                             WarehouseCode = singleDetail.WarehouseCode,
-                            TotalOrderQuantity = singleDetail.OrderQuantity - singleDetail.MoveQty,
-                            TotalOverOutQuantity = singleDetail.OverOutQuantity,
-                            AssignedQuantity = singleDetail.LockQuantity,
-                            UnallocatedQuantity = singleDetail.OrderQuantity - singleDetail.LockQuantity - singleDetail.MoveQty,
-                            MovedQuantity = singleDetail.MoveQty,
-                            Details = new List<Dt_OutboundOrderDetail>() { singleDetail }
+                            TotalOrderQuantity = orderQuantity - moveQuantity,
+                            TotalOverOutQuantity = overQuantity,
+                            AssignedQuantity = lockQuantity,
+                            UnallocatedQuantity = request.OutboundQuantity.Value,
+                            MovedQuantity = moveQuantity,
+                            Details = selectedDetails
                         }
                     };
                 }
@@ -281,7 +328,7 @@
                     UnallocatedQuantity = g.Sum(x => x.OrderQuantity - x.LockQuantity - x.MoveQty),
                     MovedQuantity = g.Sum(x => x.MoveQty),
                     Details = g.ToList(),
-                    OutStockLockInfos = _outboundLockInfoService.Repository.QueryData(x => x.MaterielCode == g.Key.MaterielCode && x.BatchNo == g.Key.BatchNo && x.OrderType == (int)outboundOrder.OrderType && x.OrderNo == outboundOrder.OrderNo)
+                    OutStockLockInfos = _outboundLockInfoRepository.QueryData(x => x.MaterielCode == g.Key.MaterielCode && x.BatchNo == g.Key.BatchNo && x.OrderType == (int)outboundOrder.OrderType && x.OrderNo == outboundOrder.OrderNo)
                 })
                 .ToList();
 
@@ -353,9 +400,11 @@
                 decimal availableQuantity = availableStockMap.GetValueOrDefault(stock.Id, 0);
                 if (availableQuantity <= 0) continue;
 
+                // 璁$畻璇ユ墭鐩樺彲鍒嗛厤鏁伴噺
                 decimal allocateQuantity = Math.Min(remainingQuantity, availableQuantity);
                 (decimal ActualAllocatedQuantity, List<Dt_OutStockLockInfo> LockInfoList) actualAllocated = AllocateStockQuantity(stock, allocateQuantity, availableQuantity, outboundOrder, firstDetail, request, lockStockMap.GetValueOrDefault(stock.Id, new List<Dt_OutStockLockInfo>()), stockDetailMap);
 
+                // 鏈鍒嗛厤鐨勬暟閲�
                 decimal actualAllocatedQuantity = actualAllocated.ActualAllocatedQuantity;
 
                 if (actualAllocatedQuantity > 0)
@@ -436,7 +485,7 @@
         private List<Dt_StockInfo> BuildStockQueryWithInfo(MaterielOutboundCalculationDTO materielCalc, string factoryArea)
         {
             // 鍩虹鏌ヨ鏉′欢锛氱墿鏂欑紪鍙枫�佹壒娆″彿锛堝鏋滄彁渚涳級銆佸簱瀛樻暟閲�>0
-            ISugarQueryable<Dt_StockInfoDetail> stockDetails = _stockDetailService.Repository.Db.Queryable<Dt_StockInfoDetail>().Where(x => x.MaterielCode == materielCalc.MaterielCode && x.StockQuantity > 0);
+            ISugarQueryable<Dt_StockInfoDetail> stockDetails = _stockDetailRepository.Db.Queryable<Dt_StockInfoDetail>().Where(x => x.MaterielCode == materielCalc.MaterielCode && x.StockQuantity > 0);
 
             // 鏍规嵁鏉′欢娣诲姞渚涘簲鍟嗙紪鍙峰尮閰嶏紙涓嶄负绌烘椂鎵嶉渶瑕佸尮閰嶏級
             if (!string.IsNullOrEmpty(materielCalc.SupplyCode))
@@ -465,11 +514,11 @@
             List<Dt_StockInfoDetail> stockDetailList = stockDetails.ToList();
 
             // 鑾峰彇鍙敤璐т綅缂栧彿
-            List<string> locationCodes = _locationInfoService.Repository.QueryData(x => (x.LocationStatus == LocationStatusEnum.InStock.ObjToInt() /*|| x.LocationStatus == LocationStatusEnum.Lock.ObjToInt()*/) && x.EnableStatus == EnableStatusEnum.Normal.ObjToInt()).Select(x => x.LocationCode).ToList();
+            List<string> locationCodes = _locationInfoRepository.QueryData(x => (x.LocationStatus == LocationStatusEnum.InStock.ObjToInt() /*|| x.LocationStatus == LocationStatusEnum.Lock.ObjToInt()*/) && x.EnableStatus == EnableStatusEnum.Normal.ObjToInt()).Select(x => x.LocationCode).ToList();
 
             // 鑾峰彇鎵�鏈夌浉鍏崇殑搴撳瓨淇℃伅
             List<int> stockIds = stockDetailList.GroupBy(x => x.StockId).Select(x => x.Key).ToList();
-            List<Dt_StockInfo> stockInfos = _stockInfoService.Repository.QueryData(x => stockIds.Contains(x.Id) && (x.StockStatus == StockStatusEmun.鍏ュ簱瀹屾垚.ObjToInt() /*|| x.StockStatus == StockStatusEmun.鍑哄簱閿佸畾.ObjToInt()*/) && !string.IsNullOrEmpty(x.LocationCode) && locationCodes.Contains(x.LocationCode));
+            List<Dt_StockInfo> stockInfos = _stockInfoRepository.QueryData(x => stockIds.Contains(x.Id) && (x.StockStatus == StockStatusEmun.鍏ュ簱瀹屾垚.ObjToInt() /*|| x.StockStatus == StockStatusEmun.鍑哄簱閿佸畾.ObjToInt()*/) && !string.IsNullOrEmpty(x.LocationCode) && locationCodes.Contains(x.LocationCode));
 
             // 鍦ㄥ唴瀛樹腑鍏宠仈鏁版嵁
             foreach (var stockInfo in stockInfos)
@@ -502,7 +551,7 @@
                 // 璁$畻鎬诲簱瀛樻暟閲�
                 decimal totalQuantity = stockInfo.Details.Sum(x => x.StockQuantity);
 
-                List<Dt_OutStockLockInfo> outStockLockInfos = allocatedData.Where(x => x.StockId == stockInfo.Id).ToList();
+                List<Dt_OutStockLockInfo> outStockLockInfos = allocatedData.Where(x => x.StockId == stockInfo.Id && x.MaterielCode == materielCalc.MaterielCode).ToList();
 
                 // 璁$畻宸插垎閰嶆暟閲�
                 decimal allocatedQuantity = outStockLockInfos.Sum(x => x.AllocatedQuantity);
@@ -510,7 +559,6 @@
 
                 lockStockMap[stockInfo.Id] = outStockLockInfos;
             }
-
 
             return (availableStockMap, lockStockMap);
         }
@@ -560,7 +608,7 @@
 
                     // 鏇存柊鍒嗛厤鍑哄簱閲�
                     decimal beforeAssignQuantity = totalAllocatedQuantity; // 鏈鍒嗛厤鍓嶇殑鎬荤疮璁¢噺
-                    lockInfo.AssignQuantity += actualAllocatedQuantity; // 绱姞鏈鍒嗛厤鏁伴噺
+                    lockInfo.AssignQuantity += actualAllocatedQuantity; // 鏈鍒嗛厤鏁伴噺
                     lockInfo.AllocatedQuantity = beforeAssignQuantity; // 璁板綍鏈鍒嗛厤鍓嶇殑鎬荤疮璁¢噺
 
                     lockInfoList.Add(lockInfo);
@@ -635,7 +683,7 @@
         private decimal CalcTotalAllocatedQuantity(List<Dt_OutStockLockInfo> lockInfos, int stockId, string materielCode)
         {
             // 鏌ヨ璇ユ墭鐩樿鐗╂枡鍦ㄦ墍鏈夐攣瀹氳褰曚腑鐨勬渶澶у凡鍒嗛厤鏁伴噺
-            List<Dt_OutStockLockInfo> lockRecords = _outboundLockInfoService.Repository.QueryData(x =>
+            List<Dt_OutStockLockInfo> lockRecords = _outboundLockInfoRepository.QueryData(x =>
                 x.StockId == stockId &&
                 x.MaterielCode == materielCode);
 
@@ -655,11 +703,11 @@
         {
             try
             {
-                Dt_OutboundOrder outboundOrder = _outboundOrderService.Repository.QueryFirst(x => x.OrderNo == orderNo);
+                Dt_OutboundOrder outboundOrder = _outboundRepository.QueryFirst(x => x.OrderNo == orderNo);
                 if (outboundOrder == null) return false;
 
                 outboundOrder.OrderStatus = status;
-                _outboundOrderService.Repository.UpdateData(outboundOrder);
+                _outboundRepository.UpdateData(outboundOrder);
                 return true;
             }
             catch
@@ -678,13 +726,13 @@
         {
             try
             {
-                List<Dt_StockInfo> stockInfos = _stockInfoService.Repository.QueryData(x => palletCodes.Contains(x.PalletCode));
+                List<Dt_StockInfo> stockInfos = _stockInfoRepository.QueryData(x => palletCodes.Contains(x.PalletCode));
                 stockInfos.ForEach(stockInfo =>
                 {
                     stockInfo.StockStatus = status;
                 });
 
-                _stockInfoService.Repository.UpdateData(stockInfos);
+                _stockInfoRepository.UpdateData(stockInfos);
                 return true;
             }
             catch
@@ -703,13 +751,13 @@
         {
             try
             {
-                List<Dt_LocationInfo> locationInfos = _locationInfoService.Repository.QueryData(x => locationCodes.Contains(x.LocationCode));
+                List<Dt_LocationInfo> locationInfos = _locationInfoRepository.QueryData(x => locationCodes.Contains(x.LocationCode));
                 locationInfos.ForEach(x =>
                 {
                     x.LocationStatus = status;
                 });
 
-                _locationInfoService.Repository.UpdateData(locationInfos);
+                _locationInfoRepository.UpdateData(locationInfos);
                 return true;
             }
             catch
@@ -728,10 +776,10 @@
             try
             {
                 List<Dt_OutStockLockInfo> updateData = outStockLockInfos.Where(x => x.Id > 0).ToList();
-                _outboundLockInfoService.Repository.UpdateData(updateData);
+                _outboundLockInfoRepository.UpdateData(updateData);
 
                 List<Dt_OutStockLockInfo> addData = outStockLockInfos.Where(x => x.Id <= 0).ToList();
-                _outboundLockInfoService.Repository.AddData(addData);
+                _outboundLockInfoRepository.AddData(addData);
 
                 return true;
             }
@@ -740,6 +788,7 @@
                 return false;
             }
         }
+        #endregion
 
 
         /// <summary>
@@ -755,7 +804,7 @@
             try
             {
                 // 1. 鏍规嵁鎵樼洏鍙锋煡鎵惧簱瀛樹俊鎭�
-                Dt_StockInfo stockInfo = _stockInfoService.Repository.QueryFirst(x => x.PalletCode == request.PalletCode);
+                Dt_StockInfo stockInfo = _stockInfoRepository.QueryFirst(x => x.PalletCode == request.PalletCode);
                 if (stockInfo == null)
                 {
                     response.Success = false;
@@ -764,7 +813,7 @@
                 }
 
                 // 2. 鏍规嵁鏉$爜鏌ユ壘搴撳瓨鏄庣粏
-                Dt_StockInfoDetail stockDetail = _stockDetailService.Repository.QueryFirst(x => x.Barcode == request.Barcode);
+                Dt_StockInfoDetail stockDetail = _stockDetailRepository.QueryFirst(x => x.Barcode == request.Barcode);
                 if (stockDetail == null)
                 {
                     response.Success = false;
@@ -781,7 +830,7 @@
                 }
 
                 // 4. 鏌ユ壘鍑哄簱鍗曚俊鎭�
-                Dt_OutboundOrder outboundOrder = _outboundOrderService.Repository.QueryFirst(o => o.OrderNo == request.OrderNo);
+                Dt_OutboundOrder outboundOrder = _outboundRepository.QueryFirst(o => o.OrderNo == request.OrderNo);
                 if (outboundOrder == null)
                 {
                     response.Success = false;
@@ -789,17 +838,8 @@
                     return WebResponseContent.Instance.Error($"鍑哄簱鍗� {request.OrderNo} 涓嶅瓨鍦�");
                 }
 
-                // 5. 鏌ユ壘鍑哄簱鍗曟槑缁嗕俊鎭�
-                List<Dt_OutboundOrderDetail> outboundOrderDetails = FindMatchingOutboundDetails(outboundOrder.Id, stockDetail);
-                if (!outboundOrderDetails.Any())
-                {
-                    response.Success = false;
-                    response.Message = $"鏈壘鍒板尮閰嶇殑鍑哄簱鍗曟槑缁嗭紝鐗╂枡锛歿stockDetail.MaterielCode}锛屾壒娆★細{stockDetail.BatchNo}";
-                    return WebResponseContent.Instance.Error($"鏈壘鍒板尮閰嶇殑鍑哄簱鍗曟槑缁嗭紝鐗╂枡锛歿stockDetail.MaterielCode}锛屾壒娆★細{stockDetail.BatchNo}");
-                }
-
-                // 6. 鏌ユ壘閿佸畾璁板綍
-                Dt_OutStockLockInfo lockInfo = _outboundLockInfoService.Repository.QueryFirst(x =>
+                // 5. 鏌ユ壘閿佸畾璁板綍
+                Dt_OutStockLockInfo lockInfo = _outboundLockInfoRepository.QueryFirst(x =>
                     x.OrderNo == request.OrderNo &&
                     x.StockId == stockInfo.Id &&
                     x.MaterielCode == stockDetail.MaterielCode &&
@@ -810,6 +850,25 @@
                     response.Success = false;
                     response.Message = $"璇ュ簱瀛樻病鏈夊垎閰嶅嚭搴撻噺锛屾潯鐮侊細{request.Barcode}";
                     return WebResponseContent.Instance.Error($"璇ュ簱瀛樻病鏈夊垎閰嶅嚭搴撻噺锛屾潯鐮侊細{request.Barcode}");
+                }
+
+                // 鎵惧嚭宸插垎閰嶇殑璁㈠崟鏄庣粏Id
+                List<int> detailIds = new List<int>();
+                string[] ids = lockInfo.OrderDetailIds.Split(",");
+                foreach (string id in ids)
+                {
+                    if (int.TryParse(id, out int detailId))
+                    {
+                        detailIds.Add(detailId);
+                    }
+                }
+                // 6. 鏌ユ壘鍑哄簱鍗曟槑缁嗕俊鎭�
+                List<Dt_OutboundOrderDetail> outboundOrderDetails = FindMatchingOutboundDetails(outboundOrder.Id, stockDetail, detailIds);
+                if (!outboundOrderDetails.Any())
+                {
+                    response.Success = false;
+                    response.Message = $"鏈壘鍒板尮閰嶇殑鍑哄簱鍗曟槑缁嗭紝鐗╂枡锛歿stockDetail.MaterielCode}锛屾壒娆★細{stockDetail.BatchNo}";
+                    return WebResponseContent.Instance.Error($"鏈壘鍒板尮閰嶇殑鍑哄簱鍗曟槑缁嗭紝鐗╂枡锛歿stockDetail.MaterielCode}锛屾壒娆★細{stockDetail.BatchNo}");
                 }
 
                 // 7. 璁$畻瀹為檯鍑哄簱閲�
@@ -826,9 +885,16 @@
                     return WebResponseContent.Instance.Error($"鏃犳硶鍑哄簱锛屾潯鐮侊細{request.Barcode}锛屽簱瀛橈細{stockDetail.StockQuantity}锛屽凡鍑哄簱锛歿totalAllocatedQuantity}锛屽垎閰嶉噺锛歿lockInfo.AssignQuantity}锛屾槑缁嗗墿浣欙細{detailRemainingQuantity}");
                 }
 
+                if (actualOutboundQuantity + lockInfo.SortedQuantity > lockInfo.AssignQuantity)
+                {
+                    response.Success = false;
+                    response.Message = $"鏃犳硶鍑哄簱锛屾潯鐮侊細{request.Barcode}锛屽簱瀛橈細{stockDetail.StockQuantity}锛屽嚭搴撻噺{actualOutboundQuantity + lockInfo.SortedQuantity}澶т簬鍒嗛厤閲弡lockInfo.AssignQuantity}";
+                    return WebResponseContent.Instance.Error($"鏃犳硶鍑哄簱锛屾潯鐮侊細{request.Barcode}锛屽簱瀛橈細{stockDetail.StockQuantity}锛屽嚭搴撻噺{actualOutboundQuantity + lockInfo.SortedQuantity}澶т簬鍒嗛厤閲弡lockInfo.AssignQuantity}");
+                }
+
                 // 8. 鍒ゆ柇鏄惁闇�瑕佹媶鍖咃紙褰撳嚭搴撴暟閲忓皬浜庡簱瀛樻暟閲忔椂闇�瑕佹媶鍖咃級
                 bool isUnpacked = actualOutboundQuantity < stockDetail.StockQuantity;
-                string newBarcode = string.Empty;
+                List<MaterialCodeReturnDTO> returnDTOs = new List<MaterialCodeReturnDTO>();
 
                 // 9. 寮�鍚簨鍔�
                 _unitOfWorkManage.BeginTran();
@@ -839,7 +905,7 @@
                     // 鏍规嵁鏄惁鎷嗗寘鎵ц涓嶅悓鐨勬搷浣�
                     if (isUnpacked)
                     {
-                        newBarcode = PerformUnpackOperation(stockDetail, stockInfo, actualOutboundQuantity, request, beforeQuantity, lockInfo.TaskNum.GetValueOrDefault());
+                        returnDTOs = PerformUnpackOperation(stockDetail, stockInfo, actualOutboundQuantity, request, beforeQuantity, lockInfo.TaskNum.GetValueOrDefault());
                     }
                     else
                     {
@@ -852,29 +918,71 @@
                     {
                         if (allocatedQuantity <= 0) break;
 
-                        if (item.OrderQuantity - item.MoveQty - item.OverOutQuantity >= allocatedQuantity)
+
+                        //if (item.OrderQuantity - item.MoveQty - item.OverOutQuantity >= allocatedQuantity)
+                        //{
+                        //    item.OverOutQuantity += allocatedQuantity;
+                        //    allocatedQuantity = 0;
+                        //}
+                        //else
+                        //{
+                        //    allocatedQuantity -= (item.OrderQuantity - item.MoveQty - item.OverOutQuantity);
+                        //    item.OverOutQuantity = item.OrderQuantity - item.MoveQty;
+                        //}
+
+                        if (item.LockQuantity - item.OverOutQuantity >= allocatedQuantity)
                         {
                             item.OverOutQuantity += allocatedQuantity;
+                            item.CurrentDeliveryQty += allocatedQuantity;
                             allocatedQuantity = 0;
                         }
                         else
                         {
-                            allocatedQuantity -= (item.OrderQuantity - item.MoveQty - item.OverOutQuantity);
-                            item.OverOutQuantity = item.OrderQuantity - item.MoveQty;
+                            allocatedQuantity -= (item.LockQuantity - item.OverOutQuantity);
+                            item.OverOutQuantity = item.LockQuantity;
+                            item.CurrentDeliveryQty = item.LockQuantity;
                         }
+
                         updateDetails.Add(item);
+
+                        List<Barcodes> barcodesList = new List<Barcodes>();
+                        Barcodes barcodes = new Barcodes
+                        {
+                            Barcode = request.Barcode,
+                            Qty = actualOutboundQuantity,
+                            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);
                     }
 
                     lockInfo.SortedQuantity = lockInfo.SortedQuantity + actualOutboundQuantity;
 
-                    // 鏇存柊閿佸畾璁板綍
-                    _outboundLockInfoService.Repository.UpdateData(lockInfo);
+                    if (lockInfo.SortedQuantity == lockInfo.AssignQuantity)
+                    {
+                        _outboundLockInfoRepository.DeleteAndMoveIntoHty(lockInfo, WIDESEA_Core.Enums.OperateTypeEnum.鑷姩瀹屾垚);
+                    }
+                    else
+                    {
+                        // 鏇存柊閿佸畾璁板綍
+                        _outboundLockInfoRepository.UpdateData(lockInfo);
+                    }
 
                     // 鏇存柊鍑哄簱鍗曟槑缁嗙殑宸插嚭搴撴暟閲�
-                    _detailService.Repository.UpdateData(updateDetails);
+                    _detailRepository.UpdateData(updateDetails);
 
                     // 鏇存柊閿佸畾璁板綍鐨勭疮璁″凡鍑哄簱鏁伴噺锛堥渶瑕佹洿鏂拌鎵樼洏璇ョ墿鏂欑殑鎵�鏈夌浉鍏宠褰曪級
-                    UpdateLockInfoAllocatedQuantity(stockInfo.Id, stockDetail.MaterielCode, stockDetail.BatchNo, actualOutboundQuantity);
+                    //UpdateLockInfoAllocatedQuantity(stockInfo.Id, stockDetail.MaterielCode, stockDetail.BatchNo, actualOutboundQuantity);
 
                     // 鎻愪氦浜嬪姟
                     _unitOfWorkManage.CommitTran();
@@ -891,19 +999,21 @@
                         BeforeQuantity = beforeQuantity,
                         AfterQuantity = isUnpacked ? actualOutboundQuantity : 0,
                         ChangeQuantity = -actualOutboundQuantity,
-                        IsUnpacked = isUnpacked
+                        IsUnpacked = isUnpacked,
+                        MaterialCodes = returnDTOs
                     };
 
                     response.Success = true;
-                    response.Message = isUnpacked ? $"鎷嗗寘鍑哄簱瀹屾垚锛屽凡鐢熸垚鏂版潯鐮侊細{newBarcode}" : "鍑哄簱瀹屾垚";
+                    response.Message = "鍑哄簱瀹屾垚";
                     response.ScannedDetail = scannedDetail;
                     response.UpdatedDetails = updateDetails;
-                    response.NewBarcode = newBarcode;
 
                     // 妫�鏌ュ嚭搴撳崟鏄惁瀹屾垚
                     if (CheckOutboundOrderCompleted(request.OrderNo))
                     {
                         UpdateOutboundOrderStatus(request.OrderNo, OutOrderStatusEnum.鍑哄簱瀹屾垚.ObjToInt());
+
+                        //todo: 鍥炰紶MES
                     }
                 }
                 catch (Exception ex)
@@ -929,11 +1039,11 @@
         /// <param name="orderId"></param>
         /// <param name="stockDetail"></param>
         /// <returns></returns>
-        private List<Dt_OutboundOrderDetail> FindMatchingOutboundDetails(int orderId, Dt_StockInfoDetail stockDetail)
+        private List<Dt_OutboundOrderDetail> FindMatchingOutboundDetails(int orderId, Dt_StockInfoDetail stockDetail, List<int> detailIds)
         {
-            List<Dt_OutboundOrderDetail> details = _detailService.Repository.QueryData(x =>
+            List<Dt_OutboundOrderDetail> details = _detailRepository.QueryData(x =>
                 x.OrderId == orderId &&
-                x.MaterielCode == stockDetail.MaterielCode && x.OrderQuantity - x.MoveQty > x.OverOutQuantity);
+                x.MaterielCode == stockDetail.MaterielCode && x.OrderQuantity - x.MoveQty > x.OverOutQuantity && detailIds.Contains(x.Id));
 
             // 绮剧‘鍖归厤锛氬鐞唍ull鍊肩殑鎵规銆佷緵搴斿晢銆佷粨搴�
             List<Dt_OutboundOrderDetail> exactMatches = details.Where(x =>
@@ -960,7 +1070,6 @@
                 stockDetail.StockQuantity);
         }
 
-
         /// <summary>
         /// 鎵ц鎷嗗寘鎿嶄綔
         /// </summary>
@@ -971,10 +1080,16 @@
         /// <param name="beforeQuantity"></param>
         /// <param name="taskNum"></param>
         /// <returns></returns>
-        private string PerformUnpackOperation(Dt_StockInfoDetail stockDetail, Dt_StockInfo stockInfo,
+        private List<MaterialCodeReturnDTO> PerformUnpackOperation(Dt_StockInfoDetail stockDetail, Dt_StockInfo stockInfo,
             decimal actualOutboundQuantity, OutboundCompleteRequestDTO request, decimal beforeQuantity, int taskNum)
         {
             string newBarcode = GenerateNewBarcode();
+
+            string remark = $"鎷嗗寘璁板綍锛屽師鏉$爜锛歿request.Barcode}锛屽師鏁伴噺锛歿stockDetail.StockQuantity}锛屽嚭搴撴潯鐮侊細{newBarcode}锛� 鍑哄簱鏁伴噺锛歿actualOutboundQuantity}锛屽洖搴撴潯鐮侊細{request.Barcode}锛屽洖搴撴暟閲忥細{stockDetail.StockQuantity - actualOutboundQuantity},鎿嶄綔鑰咃細{request.Operator}";
+
+            List<Dt_MaterialCodeInfo> materialCodeInfos = CreateMaterialCodeInfos(stockDetail, newBarcode, actualOutboundQuantity, remark);
+
+            List<MaterialCodeReturnDTO> returnDTOs = _mapper.Map<List<MaterialCodeReturnDTO>>(materialCodeInfos);
 
             // 淇濆瓨鍘熷搴撳瓨鏄庣粏鍒板巻鍙茶褰�
             Dt_StockInfoDetail_Hty originalHistoryRecord = new Dt_StockInfoDetail_Hty
@@ -1000,7 +1115,7 @@
                 WarehouseCode = stockDetail.WarehouseCode,
                 Remark = $"鎷嗗寘鍓嶅師濮嬭褰曪紝鍘熸潯鐮侊細{request.Barcode}锛屽師鏁伴噺锛歿stockDetail.StockQuantity}锛屽嚭搴撴暟閲忥細{actualOutboundQuantity}锛屾搷浣滆�咃細{request.Operator}"
             };
-            _stockDetailHistoryService.Repository.AddData(originalHistoryRecord);
+            _stockDetailHistoryRepository.AddData(originalHistoryRecord);
 
             // 淇濆瓨鍓╀綑閮ㄥ垎鍒板巻鍙茶褰�
             decimal remainingQuantity = stockDetail.StockQuantity - actualOutboundQuantity;
@@ -1008,8 +1123,9 @@
             {
                 // 鏇存柊鍘熷簱瀛樻槑缁�
                 stockDetail.StockQuantity = remainingQuantity;
+                //stockDetail.Barcode = newBarcode;
                 stockDetail.Remark = $"鎷嗗寘鍚庢洿鏂帮紝鍘熸潯鐮侊細{request.Barcode}锛屾柊鏁伴噺锛歿remainingQuantity}锛屾搷浣滆�咃細{request.Operator}";
-                _stockDetailService.Repository.UpdateData(stockDetail);
+                _stockDetailRepository.UpdateData(stockDetail);
             }
 
             // 璁板綍鎷嗗寘鍙樺姩
@@ -1032,9 +1148,9 @@
                 WarehouseCode = stockDetail.WarehouseCode,
                 Remark = $"鎷嗗寘鍑哄簱锛屽師鏉$爜锛歿request.Barcode}锛屾柊鏉$爜锛歿newBarcode}锛屽嚭搴撴暟閲忥細{actualOutboundQuantity}锛屽墿浣欙細{remainingQuantity}锛屾搷浣滆�咃細{request.Operator}"
             };
-            _stockChangeService.Repository.AddData(unpackChangeRecord);
+            _stockChangeRepository.AddData(unpackChangeRecord);
 
-            return newBarcode;
+            return returnDTOs;
         }
 
         /// <summary>
@@ -1067,10 +1183,10 @@
                 WarehouseCode = stockDetail.WarehouseCode,
                 Remark = $"鍑哄簱瀹屾垚鍒犻櫎锛屾潯鐮侊細{request.Barcode}锛屽師鏁伴噺锛歿stockDetail.StockQuantity}锛屽嚭搴撴暟閲忥細{actualOutboundQuantity}锛屾搷浣滆�咃細{request.Operator}"
             };
-            _stockDetailHistoryService.Repository.AddData(historyRecord);
+            _stockDetailHistoryRepository.AddData(historyRecord);
 
             // 鍒犻櫎搴撳瓨鏄庣粏璁板綍
-            _stockDetailService.Repository.DeleteData(stockDetail);
+            _stockDetailRepository.DeleteData(stockDetail);
 
             // 璁板綍搴撳瓨鍙樺姩
             Dt_StockQuantityChangeRecord changeRecord = new Dt_StockQuantityChangeRecord
@@ -1092,7 +1208,7 @@
                 WarehouseCode = stockDetail.WarehouseCode,
                 Remark = $"鍑哄簱瀹屾垚鍒犻櫎搴撳瓨鏄庣粏锛屾潯鐮侊細{request.Barcode}锛屽嚭搴撴暟閲忥細{actualOutboundQuantity}锛屾搷浣滆�咃細{request.Operator}"
             };
-            _stockChangeService.Repository.AddData(changeRecord);
+            _stockChangeRepository.AddData(changeRecord);
         }
 
         /// <summary>
@@ -1104,9 +1220,67 @@
             // 浣跨敤鏃堕棿鎴冲拰闅忔満鏁扮敓鎴愬敮涓�鏉$爜
             string newBarcode = string.Empty;
 
-            //todo 閲嶆柊鐢熸垚鏉$爜閫昏緫
+            newBarcode = _basicService.CreateCodeByRule(RuleCodeEnum.NewBarcodeRule.ToString());
 
             return newBarcode;
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="stockDetail"></param>
+        /// <param name="newBarcode"></param>
+        /// <param name="splitQuantity"></param>
+        /// <param name="afterQuantity"></param>
+        /// <param name="remark"></param>
+        /// <returns></returns>
+        private List<Dt_MaterialCodeInfo> CreateMaterialCodeInfos(Dt_StockInfoDetail stockDetail, string newBarcode, decimal splitQuantity, string remark)
+        {
+            List<Dt_MaterialCodeInfo> materialCodeInfos = new List<Dt_MaterialCodeInfo>();
+
+            Dt_MaterielInfo? materielInfo = _basicService.MaterielInfoService.Repository.QueryFirst(x => x.MaterielCode == stockDetail.MaterielCode);
+
+            Dt_MaterialCodeInfo outMaterialCodeInfo = new Dt_MaterialCodeInfo()
+            {
+                AfterQuantity = splitQuantity,
+                BatchNo = stockDetail.BatchNo,
+                FactoryArea = stockDetail.FactoryArea,
+                MaterialName = materielInfo?.MaterielName ?? stockDetail.MaterielName,
+                MaterialSpec = materielInfo?.MaterielSpec ?? "",
+                MaterialCode = stockDetail.MaterielCode,
+                NewBarcode = newBarcode,
+                OldBarcode = stockDetail.Barcode,
+                OriginalQuantity = stockDetail.StockQuantity,
+                PruchaseOrderNo = stockDetail.OrderNo,
+                SuplierCode = stockDetail.SupplyCode,
+                Unit = stockDetail.Unit,
+                Date = DateTime.Now.ToString("yyyy-MM-dd"),
+                Remark = remark
+            };
+            materialCodeInfos.Add(outMaterialCodeInfo);
+
+            Dt_MaterialCodeInfo returnMaterialCodeInfo = new Dt_MaterialCodeInfo()
+            {
+                AfterQuantity = stockDetail.StockQuantity - splitQuantity,
+                BatchNo = stockDetail.BatchNo,
+                FactoryArea = stockDetail.FactoryArea,
+                MaterialName = materielInfo?.MaterielName ?? stockDetail.MaterielName,
+                MaterialSpec = materielInfo?.MaterielSpec ?? "",
+                MaterialCode = stockDetail.MaterielCode,
+                NewBarcode = stockDetail.Barcode,
+                OldBarcode = stockDetail.Barcode,
+                OriginalQuantity = stockDetail.StockQuantity,
+                PruchaseOrderNo = stockDetail.OrderNo,
+                SuplierCode = stockDetail.SupplyCode,
+                Unit = stockDetail.Unit,
+                Date = DateTime.Now.ToString("yyyy-MM-dd"),
+                Remark = remark
+            };
+
+            materialCodeInfos.Add(returnMaterialCodeInfo);
+
+            _basicService.MaterielCodeInfoService.Repository.AddData(materialCodeInfos);
+            return materialCodeInfos;
         }
 
         /// <summary>
@@ -1120,7 +1294,7 @@
         private void UpdateLockInfoAllocatedQuantity(int stockId, string materielCode, string batchNo, decimal actualOutboundQuantity)
         {
             // 鏌ヨ璇ユ墭鐩樿鐗╂枡鐨勬墍鏈夐攣瀹氳褰�
-            List<Dt_OutStockLockInfo> lockRecords = _outboundLockInfoService.Repository.QueryData(x =>
+            List<Dt_OutStockLockInfo> lockRecords = _outboundLockInfoRepository.QueryData(x =>
                 x.StockId == stockId &&
                 x.MaterielCode == materielCode &&
                 x.BatchNo == batchNo);
@@ -1134,7 +1308,7 @@
                 }
 
                 // 鎵归噺鏇存柊
-                _outboundLockInfoService.Repository.UpdateData(lockRecords);
+                _outboundLockInfoRepository.UpdateData(lockRecords);
             }
         }
 
@@ -1143,13 +1317,13 @@
         /// </summary>
         public bool CheckOutboundOrderCompleted(string orderNo)
         {
-            Dt_OutboundOrder outboundOrder = _outboundOrderService.Repository.QueryFirst(x => x.OrderNo == orderNo);
+            Dt_OutboundOrder outboundOrder = _outboundRepository.QueryFirst(x => x.OrderNo == orderNo);
             if (outboundOrder == null) return false;
 
-            List<Dt_OutboundOrderDetail> details = _detailService.Repository.QueryData(x => x.OrderId == outboundOrder.Id);
+            List<Dt_OutboundOrderDetail> details = _detailRepository.QueryData(x => x.OrderId == outboundOrder.Id);
 
             // 妫�鏌ユ墍鏈夋槑缁嗙殑宸插嚭鏁伴噺鏄惁閮界瓑浜庡崟鎹暟閲�
-            return details.All(x => x.OverOutQuantity >= x.OrderQuantity);
+            return details.All(x => x.OverOutQuantity >= x.OrderQuantity - x.MoveQty);
         }
     }
 }

--
Gitblit v1.9.3