From 9753fb2756f6b4e30ff79d901a7bb86145517c8b Mon Sep 17 00:00:00 2001
From: huangxiaoqiang <huangxiaoqiang@hnkhzn.com>
Date: 星期四, 18 十二月 2025 11:29:13 +0800
Subject: [PATCH] 1

---
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundService.cs |  516 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 506 insertions(+), 10 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 aa37561..ecc4177 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,7 +1,15 @@
 锘縰sing AutoMapper;
+using Dm.filter;
+using MailKit.Search;
+using Mapster;
 using Newtonsoft.Json;
 using Newtonsoft.Json.Serialization;
+using Org.BouncyCastle.Asn1.Ocsp;
+using Org.BouncyCastle.Crypto;
 using SqlSugar;
+using System.Reflection.Emit;
+using WIDESEA_BasicService;
+using WIDESEA_Common.CommonEnum;
 using WIDESEA_Common.LocationEnum;
 using WIDESEA_Common.OrderEnum;
 using WIDESEA_Common.StockEnum;
@@ -10,6 +18,7 @@
 using WIDESEA_Core.BaseRepository;
 using WIDESEA_Core.CodeConfigEnum;
 using WIDESEA_Core.Helper;
+using WIDESEA_DTO.Basic;
 using WIDESEA_DTO.CalcOut;
 using WIDESEA_DTO.ReturnMES;
 using WIDESEA_IBasicService;
@@ -44,8 +53,23 @@
         private readonly IRepository<Dt_StockQuantityChangeRecord> _stockChangeRepository;
         private readonly IRepository<Dt_StockInfoDetail_Hty> _stockDetailHistoryRepository;
         private readonly IFeedbackMesService _feedbackMesService;
+        private readonly IRepository<Dt_Task> _taskRepository;
+        private readonly ILocationInfoService _locationInfoService;
+        private readonly IESSApiService _eSSApiService;
 
-        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)
+        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 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, IRepository<Dt_Task> taskRepository, ILocationInfoService locationInfoService, IESSApiService eSSApiService)
         {
             _mapper = mapper;
             _unitOfWorkManage = unitOfWorkManage;
@@ -63,6 +87,9 @@
             _stockDetailHistoryRepository = stockDetailHistoryRepository;
             _basicService = basicService;
             _feedbackMesService = feedbackMesService;
+            _taskRepository = taskRepository;
+            _locationInfoService = locationInfoService;
+            _eSSApiService = eSSApiService;
         }
 
         #region 鍑哄簱鍒嗛厤
@@ -138,14 +165,18 @@
 
                     pickedDetails.AddRange(materielPickedDetails.PickedDetails);
 
+                    decimal allallocatedQuantity = materielCalc.UnallocatedQuantity;
                     // 鏇存柊鍑哄簱鍗曟槑缁嗭紙澧炲姞閿佸畾鏁伴噺锛屼笉澧炲姞宸插嚭鏁伴噺锛�
                     foreach (var detail in materielCalc.Details)
                     {
+                        if (allallocatedQuantity <= 0) break;
+
                         decimal lockQuantity = (detail.OrderQuantity - detail.OverOutQuantity);
                         if (lockQuantity < materielCalc.UnallocatedQuantity)
                         {
                             detail.LockQuantity += lockQuantity; // 澧炲姞閿佸畾鏁伴噺 涓嶆洿鏂� OverOutQuantity 鍜� OrderDetailStatus锛屽洜涓鸿繕娌℃湁瀹為檯鍑哄簱
                             outboundOrderDetails.Add(detail);
+                            materielCalc.UnallocatedQuantity -= lockQuantity;
                         }
                         else
                         {
@@ -170,6 +201,9 @@
 
                 // 7. 鏇存柊搴撳瓨璇︽儏
                 UpdateOutStockLockInfo(outStockLockInfos);
+
+                // 8. 娣诲姞浠诲姟鏁版嵁
+                _taskRepository.AddData(tasks);
 
                 _unitOfWorkManage.CommitTran();
 
@@ -215,7 +249,7 @@
 
                 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);
+                    selectedDetails = _detailRepository.QueryData(x => x.OrderId == selectedDetails.First().OrderId && x.WarehouseCode == selectedDetails.First().WarehouseCode && x.MaterielCode == selectedDetails.First().MaterielCode && x.BatchNo == selectedDetails.First().BatchNo && x.SupplyCode == selectedDetails.First().SupplyCode);
                 }
 
 
@@ -267,6 +301,18 @@
                         return result;
                     }
 
+                    decimal inputQuantity = request.OutboundQuantity.Value;
+                    List<Dt_OutboundOrderDetail> outboundOrderDetails = new List<Dt_OutboundOrderDetail>();
+                    foreach (var item in selectedDetails)
+                    {
+                        inputQuantity -= (item.OrderQuantity - item.MoveQty - item.LockQuantity);
+                        outboundOrderDetails.Add(item);
+                        if (inputQuantity <= 0)
+                        {
+                            break;
+                        }
+                    }
+
                     result.MaterielCalculations = new List<MaterielOutboundCalculationDTO>()
                     {
                         new MaterielOutboundCalculationDTO
@@ -281,9 +327,11 @@
                             AssignedQuantity = lockQuantity,
                             UnallocatedQuantity = request.OutboundQuantity.Value,
                             MovedQuantity = moveQuantity,
-                            Details = selectedDetails
+                            Details = outboundOrderDetails
                         }
                     };
+
+                    outboundOrder.Details = outboundOrderDetails;
                 }
 
                 result.CanOutbound = true;
@@ -791,6 +839,332 @@
         #endregion
 
 
+
+        public WebResponseContent CompleteOutboundWithPallet(OutboundCompletePalletRequestDTO request)
+        {
+            WebResponseContent content = WebResponseContent.Instance;
+
+            OutboundCompleteResponseDTO response = new();
+            try
+            {
+                // 1. 鏍规嵁鎵樼洏鍙锋煡鎵惧簱瀛樹俊鎭�
+                Dt_StockInfo stockInfo = _stockInfoRepository.Db.Queryable<Dt_StockInfo>().Where(x => x.PalletCode == request.PalletCode).Includes(x => x.Details).First();
+                if (stockInfo == null)
+                {
+                    response.Success = false;
+                    response.Message = $"鎵樼洏鍙� {request.PalletCode} 瀵瑰簲鐨勫簱瀛樹笉瀛樺湪";
+                    return WebResponseContent.Instance.Error(response.Message);
+                }
+
+                if (!stockInfo.Details.Any())
+                {
+                    response.Success = false;
+                    response.Message = $"鎵樼洏 {request.PalletCode} 瀵瑰簲鐨勫簱瀛樻槑缁嗕笉瀛樺湪";
+                    return WebResponseContent.Instance.Error(response.Message);
+                }
+
+                bool isMatMixed = stockInfo.Details.GroupBy(x => new
+                {
+                    x.MaterielCode,
+                    x.MaterielName,
+                    x.BatchNo,
+                    x.SupplyCode,
+                    x.WarehouseCode
+                }).Count() > 1;
+
+                if (isMatMixed)
+                {
+                    response.Success = false;
+                    response.Message = $"娣锋枡鎵樼洏 {request.PalletCode} 涓嶈兘鏁寸鍑哄簱";
+                    return WebResponseContent.Instance.Error(response.Message);
+                }
+
+                // 2. 鏌ユ壘鍑哄簱鍗曚俊鎭�
+                Dt_OutboundOrder outboundOrder = _outboundRepository.QueryFirst(o => o.OrderNo == request.OrderNo);
+                if (outboundOrder == null)
+                {
+                    response.Success = false;
+                    response.Message = $"鍑哄簱鍗� {request.OrderNo} 涓嶅瓨鍦�";
+                    return WebResponseContent.Instance.Error(response.Message);
+                }
+
+                Dt_StockInfoDetail stockInfoDetail = stockInfo.Details.First();
+
+                // 3. 鏌ユ壘閿佸畾璁板綍
+                Dt_OutStockLockInfo lockInfo = _outboundLockInfoRepository.QueryFirst(x =>
+                    x.OrderNo == request.OrderNo &&
+                    x.StockId == stockInfo.Id &&
+                    x.MaterielCode == stockInfoDetail.MaterielCode &&
+                    x.PalletCode == stockInfo.PalletCode);
+
+                if (lockInfo == null || lockInfo.AssignQuantity <= 0)
+                {
+                    response.Success = false;
+                    response.Message = $"璇ュ簱瀛樻病鏈夊垎閰嶅嚭搴撻噺锛屾墭鐩樺彿锛歿request.PalletCode}";
+                    return WebResponseContent.Instance.Error(response.Message);
+                }
+
+                // 鎵惧嚭宸插垎閰嶇殑璁㈠崟鏄庣粏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);
+                    }
+                }
+                // 4. 鏌ユ壘鍑哄簱鍗曟槑缁嗕俊鎭�
+                List<Dt_OutboundOrderDetail> outboundOrderDetails = FindMatchingOutboundDetails(outboundOrder.Id, stockInfoDetail, detailIds);
+                if (!outboundOrderDetails.Any())
+                {
+                    response.Success = false;
+                    response.Message = $"鏈壘鍒板尮閰嶇殑鍑哄簱鍗曟槑缁嗭紝鐗╂枡锛歿stockInfoDetail.MaterielCode}锛屾壒娆★細{stockInfoDetail.BatchNo}";
+                    return WebResponseContent.Instance.Error(response.Message);
+                }
+
+                decimal totalStockQuantity = stockInfo.Details.Sum(x => x.StockQuantity);
+
+                // 5. 璁$畻瀹為檯鍑哄簱閲�
+                decimal actualOutboundQuantity = CalculateActualOutboundQuantity(stockInfo.Details, outboundOrderDetails, lockInfo);// 闇�鍑哄簱閲�
+
+                if (actualOutboundQuantity <= 0)
+                {
+                    decimal totalAllocatedQuantity = lockInfo.AllocatedQuantity;
+                    decimal availableOutboundQuantity = lockInfo.AssignQuantity - totalAllocatedQuantity;
+                    decimal detailRemainingQuantity = outboundOrderDetails.Sum(x => x.OrderQuantity - x.OverOutQuantity - x.MoveQty);
+
+                    response.Success = false;
+                    response.Message = $"鏃犳硶鍑哄簱锛屾墭鐩樺彿锛歿request.PalletCode}锛屽簱瀛橀噺锛歿totalStockQuantity}锛屽凡鍑哄簱锛歿totalAllocatedQuantity}锛屽垎閰嶉噺锛歿lockInfo.AssignQuantity}锛屾槑缁嗗墿浣欙細{detailRemainingQuantity}";
+                    return WebResponseContent.Instance.Error(response.Message);
+                }
+
+                if (lockInfo.AssignQuantity != totalStockQuantity)
+                {
+                    response.Success = false;
+                    response.Message = $"鏃犳硶鍑哄簱锛屾墭鐩樺彿锛歿request.PalletCode}锛屽簱瀛橀噺锛歿totalStockQuantity}锛屽垎閰嶉噺锛歿lockInfo.AssignQuantity}";
+                    return WebResponseContent.Instance.Error(response.Message);
+                }
+
+                // 6. 寮�鍚簨鍔�
+                _unitOfWorkManage.BeginTran();
+                try
+                {
+                    // 鏁寸鍑哄簱鏃犻渶鎷嗗寘
+                    PerformFullOutboundOperation(stockInfo, request, lockInfo.TaskNum.GetValueOrDefault());
+
+
+                    decimal allocatedQuantity = actualOutboundQuantity;
+                    List<Dt_OutboundOrderDetail> updateDetails = new();
+                    foreach (var item in outboundOrderDetails)
+                    {
+                        if (allocatedQuantity <= 0) break;
+
+
+                        //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;
+                        //}
+                        List<Barcodes> barcodesList = new List<Barcodes>();
+                        List<Dt_StockInfoDetail> stockInfoDetails = stockInfo.Details.Where((x => x.StockQuantity > x.OutboundQuantity)).ToList();
+                        foreach (var stockDetail in stockInfoDetails)
+                        {
+                            if (item.LockQuantity - item.OverOutQuantity >= stockDetail.StockQuantity - stockInfoDetail.OutboundQuantity)
+                            {
+                                Barcodes barcodes = new Barcodes
+                                {
+                                    Barcode = stockDetail.Barcode,
+                                    Qty = stockDetail.StockQuantity - stockInfoDetail.OutboundQuantity,
+                                    SupplyCode = stockDetail?.SupplyCode ?? "",
+                                    BatchNo = stockDetail?.BatchNo ?? "",
+                                    Unit = stockDetail?.Unit ?? ""
+                                };
+
+                                stockDetail.StockQuantity = stockInfoDetail.OutboundQuantity;
+                                barcodesList.Add(barcodes);
+                            }
+                            else
+                            {
+                                Barcodes barcodes = new Barcodes
+                                {
+                                    Barcode = stockDetail.Barcode,
+                                    Qty = item.LockQuantity - item.OverOutQuantity,
+                                    SupplyCode = stockDetail?.SupplyCode ?? "",
+                                    BatchNo = stockDetail?.BatchNo ?? "",
+                                    Unit = stockDetail?.Unit ?? ""
+                                };
+                                stockInfoDetail.OutboundQuantity += item.LockQuantity - item.OverOutQuantity;
+                                barcodesList.Add(barcodes);
+                            }
+                        }
+
+                        decimal barcodeQuantity = allocatedQuantity;
+
+                        if (item.LockQuantity - item.OverOutQuantity >= allocatedQuantity)
+                        {
+                            item.OverOutQuantity += allocatedQuantity;
+                            item.CurrentDeliveryQty += allocatedQuantity;
+                            allocatedQuantity = 0;
+                        }
+                        else
+                        {
+                            barcodeQuantity = item.LockQuantity - item.OverOutQuantity;
+                            allocatedQuantity -= (item.LockQuantity - item.OverOutQuantity);
+                            item.OverOutQuantity = item.LockQuantity;
+                            item.CurrentDeliveryQty = item.LockQuantity;
+                        }
+
+                        updateDetails.Add(item);
+
+
+                        if (!string.IsNullOrEmpty(item.ReturnJsonData))
+                        {
+                            barcodesList.AddRange(JsonConvert.DeserializeObject<List<Barcodes>>(item.ReturnJsonData) ?? new List<Barcodes>());
+                        }
+
+                        JsonSerializerSettings settings = new JsonSerializerSettings
+                        {
+                            ContractResolver = new CamelCasePropertyNamesContractResolver()
+                        };
+                        item.ReturnJsonData = JsonConvert.SerializeObject(barcodesList, settings);
+                    }
+
+                    lockInfo.SortedQuantity = lockInfo.SortedQuantity + actualOutboundQuantity;
+
+                    if (lockInfo.SortedQuantity == lockInfo.AssignQuantity)
+                    {
+                        _outboundLockInfoRepository.DeleteAndMoveIntoHty(lockInfo, WIDESEA_Core.Enums.OperateTypeEnum.鑷姩瀹屾垚);
+                    }
+                    else
+                    {
+                        // 鏇存柊閿佸畾璁板綍
+                        _outboundLockInfoRepository.UpdateData(lockInfo);
+                    }
+
+                    // 鏇存柊鍑哄簱鍗曟槑缁嗙殑宸插嚭搴撴暟閲�
+                    _detailRepository.UpdateData(updateDetails);
+
+                    // 鏇存柊閿佸畾璁板綍鐨勭疮璁″凡鍑哄簱鏁伴噺锛堥渶瑕佹洿鏂拌鎵樼洏璇ョ墿鏂欑殑鎵�鏈夌浉鍏宠褰曪級
+                    //UpdateLockInfoAllocatedQuantity(stockInfo.Id, stockDetail.MaterielCode, stockDetail.BatchNo, actualOutboundQuantity);
+
+                    // 鎻愪氦浜嬪姟
+                    _unitOfWorkManage.CommitTran();
+
+                    response.Success = true;
+                    response.Message = "鍑哄簱瀹屾垚";
+                    response.UpdatedDetails = updateDetails;
+
+                    // 妫�鏌ュ嚭搴撳崟鏄惁瀹屾垚
+                    if (CheckOutboundOrderCompleted(request.OrderNo))
+                    {
+                        UpdateOutboundOrderStatus(request.OrderNo, OutOrderStatusEnum.鍑哄簱瀹屾垚.ObjToInt());
+
+
+                        //todo: 鍥炰紶MES
+                    }
+                }
+                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;
+        }
+
+        /// <summary>
+        /// 璁$畻瀹為檯鍑哄簱鏁伴噺
+        /// </summary>
+        private decimal CalculateActualOutboundQuantity(List<Dt_StockInfoDetail> stockDetails, List<Dt_OutboundOrderDetail> outboundDetails, Dt_OutStockLockInfo lockInfo)
+        {
+            decimal availableOutboundQuantity = lockInfo.AssignQuantity;
+            decimal detailRemainingQuantity = outboundDetails.Sum(x => x.OrderQuantity - x.OverOutQuantity - x.MoveQty);//outboundDetail.OrderQuantity - outboundDetail.OverOutQuantity;
+
+            return Math.Min(
+                Math.Min(availableOutboundQuantity, detailRemainingQuantity),
+                stockDetails.Sum(x => x.StockQuantity));
+        }
+
+        /// <summary>
+        /// 鎵ц瀹屾暣鍑哄簱鎿嶄綔锛堜笉鎷嗗寘锛�
+        /// </summary>
+        private void PerformFullOutboundOperation(Dt_StockInfo stockInfo, OutboundCompletePalletRequestDTO request, int taskNum)
+        {
+            List<Dt_StockInfoDetail_Hty> historyRecords = new List<Dt_StockInfoDetail_Hty>();
+            List<Dt_StockQuantityChangeRecord> changeRecords = new List<Dt_StockQuantityChangeRecord>();
+            foreach (var item in stockInfo.Details)
+            {
+                // 淇濆瓨搴撳瓨鏄庣粏鍒板巻鍙茶褰�
+                Dt_StockInfoDetail_Hty historyRecord = new Dt_StockInfoDetail_Hty
+                {
+                    SourceId = item.Id,
+                    OperateType = "鍑哄簱瀹屾垚",
+                    InsertTime = DateTime.Now,
+                    StockId = item.StockId,
+                    MaterielCode = item.MaterielCode,
+                    MaterielName = item.MaterielName,
+                    OrderNo = item.OrderNo,
+                    BatchNo = item.BatchNo,
+                    ProductionDate = item.ProductionDate,
+                    EffectiveDate = item.EffectiveDate,
+                    SerialNumber = item.SerialNumber,
+                    StockQuantity = item.StockQuantity,
+                    OutboundQuantity = item.StockQuantity,
+                    Status = item.Status,
+                    Unit = item.Unit,
+                    InboundOrderRowNo = item.InboundOrderRowNo,
+                    SupplyCode = item.SupplyCode,
+                    FactoryArea = item.FactoryArea,
+                    WarehouseCode = item.WarehouseCode,
+                    Barcode = item.Barcode,
+                    Remark = $"鏁寸鍑哄簱瀹屾垚鍒犻櫎锛屾潯鐮侊細{request.PalletCode}锛屽師鏁伴噺锛歿item.StockQuantity}锛屽嚭搴撴暟閲忥細{item.StockQuantity}锛屾搷浣滆�咃細{request.Operator}"
+                };
+                historyRecords.Add(historyRecord);
+
+                // 璁板綍搴撳瓨鍙樺姩
+                Dt_StockQuantityChangeRecord changeRecord = new Dt_StockQuantityChangeRecord
+                {
+                    StockDetailId = item.Id,
+                    PalleCode = stockInfo.PalletCode,
+                    MaterielCode = item.MaterielCode,
+                    MaterielName = item.MaterielName,
+                    BatchNo = item.BatchNo,
+                    OriginalSerilNumber = item.Barcode,
+                    NewSerilNumber = "",
+                    OrderNo = request.OrderNo,
+                    TaskNum = taskNum,
+                    ChangeType = (int)StockChangeTypeEnum.Outbound,
+                    ChangeQuantity = -item.StockQuantity,
+                    BeforeQuantity = item.StockQuantity,
+                    AfterQuantity = 0,
+                    SupplyCode = item.SupplyCode,
+                    WarehouseCode = item.WarehouseCode,
+                    Remark = $"鏁寸鍑哄簱瀹屾垚鍒犻櫎搴撳瓨鏄庣粏锛屾潯鐮侊細{request.PalletCode}锛屽嚭搴撴暟閲忥細{item.StockQuantity}锛屾搷浣滆�咃細{request.Operator}"
+                };
+                changeRecords.Add(changeRecord);
+            }
+            _stockDetailHistoryRepository.AddData(historyRecords);
+
+            // 鍒犻櫎搴撳瓨鏄庣粏璁板綍
+            _stockDetailRepository.DeleteData(stockInfo.Details);
+            _stockChangeRepository.AddData(changeRecords);
+        }
+
+        #region 鎷i��
         /// <summary>
         /// 鍑哄簱瀹屾垚澶勭悊锛堟壂鎻忔潯鐮佹墸鍑忓簱瀛橈級
         /// </summary>
@@ -885,12 +1259,12 @@
                     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}");
-                }
+                //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;
@@ -930,6 +1304,8 @@
                         //    item.OverOutQuantity = item.OrderQuantity - item.MoveQty;
                         //}
 
+                        decimal barcodeQuantity = allocatedQuantity;
+
                         if (item.LockQuantity - item.OverOutQuantity >= allocatedQuantity)
                         {
                             item.OverOutQuantity += allocatedQuantity;
@@ -938,6 +1314,7 @@
                         }
                         else
                         {
+                            barcodeQuantity = item.LockQuantity - item.OverOutQuantity;
                             allocatedQuantity -= (item.LockQuantity - item.OverOutQuantity);
                             item.OverOutQuantity = item.LockQuantity;
                             item.CurrentDeliveryQty = item.LockQuantity;
@@ -949,7 +1326,7 @@
                         Barcodes barcodes = new Barcodes
                         {
                             Barcode = request.Barcode,
-                            Qty = actualOutboundQuantity,
+                            Qty = barcodeQuantity,
                             SupplyCode = stockDetail?.SupplyCode ?? "",
                             BatchNo = stockDetail?.BatchNo ?? "",
                             Unit = stockDetail?.Unit ?? ""
@@ -1012,6 +1389,7 @@
                     if (CheckOutboundOrderCompleted(request.OrderNo))
                     {
                         UpdateOutboundOrderStatus(request.OrderNo, OutOrderStatusEnum.鍑哄簱瀹屾垚.ObjToInt());
+
 
                         //todo: 鍥炰紶MES
                     }
@@ -1325,5 +1703,123 @@
             // 妫�鏌ユ墍鏈夋槑缁嗙殑宸插嚭鏁伴噺鏄惁閮界瓑浜庡崟鎹暟閲�
             return details.All(x => x.OverOutQuantity >= x.OrderQuantity - x.MoveQty);
         }
+
+        #endregion
+
+        #region 鍙栫┖绠�
+        public async Task<WebResponseContent> EmptyBox(string palletCode)
+        {
+            WebResponseContent content = new WebResponseContent();
+            try
+            {
+                var stock = await _stockInfoRepository.Db.Queryable<Dt_StockInfo>().Includes(x=>x.Details).Where(x => x.PalletCode == palletCode).FirstAsync();
+
+                if (stock == null)
+                {
+                    return content.Error($"鏈壘鍒版墭鐩榹palletCode}搴撳瓨淇℃伅");
+                }
+                if (stock.Details.Count > 0)
+                {
+                    return content.Error($"鎵樼洏{palletCode}杩樺瓨鍦ㄥ簱瀛樹俊鎭笉鍏佽鍙栬蛋");
+                }
+                Dt_StockInfo_Hty stockInfo_Hty = stock.Adapt<Dt_StockInfo_Hty>();
+                stockInfo_Hty.SourceId = stock.Id;
+                stockInfo_Hty.OperateType = "鍙栫┖绠�";
+                stockInfo_Hty.InsertTime = DateTime.Now;
+                
+                _unitOfWorkManage.BeginTran();
+                await _outboundRepository.Db.InsertNav(stockInfo_Hty).IncludesAllFirstLayer().ExecuteCommandAsync();
+                await _stockInfoRepository.DeleteDataByIdAsync(stock.Id);
+                _unitOfWorkManage.CommitTran();
+                return content.OK();
+            }
+            catch (Exception ex)
+            {
+                _unitOfWorkManage.RollbackTran();
+                return content.Error(ex.Message);
+            }
+        }
+
+        #endregion
+
+        #region
+        public async Task<WebResponseContent> ReturnToWarehouse(string palletCode, string OrderNo, string station)
+        {
+            WebResponseContent content = new WebResponseContent();
+            try
+            {
+                var stock = await _stockInfoRepository.Db.Queryable<Dt_StockInfo>().Includes(x => x.Details).Where(x => x.PalletCode == palletCode).FirstAsync();
+
+                if (stock == null)
+                {
+                    return content.Error($"鏈壘鍒版墭鐩榹palletCode}搴撳瓨淇℃伅涓嶅厑璁稿洖搴�");
+                }
+
+                if (stock.Details.Count <= 0)
+                {
+                    stock.PalletType = (int)PalletTypeEnum.Empty;
+                    stock.StockStatus = (int)StockStatusEmun.缁勭洏鏆傚瓨;
+                    stock.LocationCode = "";
+                }
+                else if (stock.Details.Count > 0)
+                {
+                    Dt_OutStockLockInfo lockInfo = _outboundLockInfoRepository.QueryFirst(x =>
+                       x.OrderNo == OrderNo &&
+                       x.StockId == stock.Id &&
+                       x.PalletCode == palletCode);
+
+                    if (lockInfo != null && lockInfo.SortedQuantity != lockInfo.AssignQuantity)
+                    {
+                        return content.Error($"鎵樼洏{palletCode}搴撳瓨鏈嫞閫夊畬涓嶅厑璁稿洖搴�");
+                    }
+                    stock.StockStatus = (int)StockStatusEmun.缁勭洏鏆傚瓨;
+                    stock.LocationCode = "";
+                }
+
+                var task = await _taskRepository.Db.Queryable<Dt_Task>()
+                    .Where(x => x.PalletCode == palletCode)
+                    .FirstAsync();
+
+                if (task != null)
+                {
+                    return content.Error($"鎵樼洏{palletCode}瀛樺湪浠诲姟鍥炲簱澶辫触!");
+                }
+
+                // 鍒嗛厤鏂拌揣浣�
+                var newLocation = _locationInfoService.AssignLocation(stock.LocationType);
+
+                var newTask = new Dt_Task()
+                {
+                    CurrentAddress = stations[station],
+                    Grade = 0,
+                    PalletCode = palletCode,
+                    NextAddress = "",
+                    OrderNo = OrderNo,
+                    Roadway = newLocation.RoadwayNo,
+                    SourceAddress = stations[station],
+                    TargetAddress = newLocation.LocationCode,
+                    TaskStatus = (int)TaskStatusEnum.New,
+                    TaskType = stock.Details.Count > 0 ? (int)TaskTypeEnum.InPick : (int)TaskTypeEnum.InEmpty,
+                    PalletType = stock.PalletType,
+                    WarehouseId = stock.WarehouseId
+                };
+                _stockInfoRepository.UpdateData(stock);
+                _taskRepository.AddData(newTask);
+
+                //var moveResult = await _eSSApiService.MoveContainerAsync(new MoveContainerRequest
+                //{
+                //    slotCode = movestations[station],
+                //    containerCode = palletCode
+                //});
+                return content.OK();
+
+            }
+            catch (Exception ex)
+            {
+                return content.Error(ex.Message);
+            }
+        }
+
+        #endregion
     }
 }

--
Gitblit v1.9.3