From 34211e1481c7a96b53675a733843349ff9e8c7f0 Mon Sep 17 00:00:00 2001
From: pan <antony1029@163.com>
Date: 星期二, 09 十二月 2025 08:58:41 +0800
Subject: [PATCH] 提交
---
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundBatchPickingService.cs | 2885 +++++----------------------------------------------
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundPickingService.cs | 403 ------
2 files changed, 354 insertions(+), 2,934 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/OutboundBatchPickingService.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/OutboundBatchPickingService.cs"
index 0948e79..cb55dde 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/OutboundBatchPickingService.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/OutboundBatchPickingService.cs"
@@ -261,7 +261,7 @@
_unitOfWorkManage.BeginTran();
- // 1. 楠岃瘉鍒嗘嫞璇锋眰
+ // 楠岃瘉鍒嗘嫞璇锋眰
var validationResult = await ValidatePickingRequest(orderNo, palletCode, barcode);
if (!validationResult.IsValid)
{
@@ -284,7 +284,7 @@
decimal originalStockQty = stockDetail.StockQuantity;
decimal originalOutboundQty = stockDetail.OutboundQuantity;
- // 2. 妫�鏌ユ槸鍚﹂渶瑕佽嚜鍔ㄦ媶鍖�
+ // 妫�鏌ユ槸鍚﹂渶瑕佽嚜鍔ㄦ媶鍖�
var autoSplitResult = await CheckAndAutoSplitIfNeeded(lockInfo, stockDetail, palletCode);
if (autoSplitResult != null)
{
@@ -301,7 +301,7 @@
(lockInfo, orderDetail, stockDetail, batch) = refreshedValidation.Data;
- // 銆愰噸瑕併�戣皟鐢ㄨ嚜鍔ㄦ媶鍖呭悗楠岃瘉
+ // 璋冪敤鑷姩鎷嗗寘鍚庨獙璇�
decimal splitQuantity = autoSplitResult.FirstOrDefault()?.quantityTotal.ObjToDecimal()??0 ;
bool autoSplitValid = await ValidateAfterAutoSplit(lockInfo, orderDetail, stockDetail, splitQuantity,originalStockQtyBeforeSplit);
@@ -314,7 +314,7 @@
_logger.LogInformation($"鑷姩鎷嗗寘楠岃瘉閫氳繃锛岀户缁墽琛屽垎鎷�");
}
- // 3. 璁$畻瀹為檯鎷i�夋暟閲�
+ // 璁$畻瀹為檯鎷i�夋暟閲�
decimal actualPickedQty = lockInfo.AssignQuantity - lockInfo.PickedQty;
if (actualPickedQty <= 0)
@@ -325,16 +325,16 @@
_logger.LogInformation($"寮�濮嬫嫞閫� - 鏁伴噺: {actualPickedQty}");
- // 4. 鎵ц鍒嗘嫞閫昏緫
+ // 鎵ц鍒嗘嫞閫昏緫
var pickingResult = await ExecutePickingLogic(lockInfo, orderDetail, stockDetail, actualPickedQty);
- // 5. 鏇存柊鎵规鍜岃鍗曟暟鎹�
+ // 鏇存柊鎵规鍜岃鍗曟暟鎹�
await UpdateBatchAndOrderData(batch, orderDetail, actualPickedQty, orderNo);
- // 6. 璁板綍鎷i�夊巻鍙�
+ //璁板綍鎷i�夊巻鍙�
await RecordPickingHistory(pickingResult, orderNo, palletCode);
- // 7. 鎷i�夊悗楠岃瘉
+ // 鎷i�夊悗楠岃瘉
await ValidateAfterPicking(orderNo, palletCode, barcode, actualPickedQty);
_unitOfWorkManage.CommitTran();
@@ -361,8 +361,7 @@
/// <summary>
- /// 鑷姩鎷嗗寘鍚庨獙璇佹暟鎹竴鑷存�� - 淇鐗�
- /// 閲嶇偣淇锛氭纭殑鍘熷簱瀛樻湡鏈涘�艰绠�
+ /// 鑷姩鎷嗗寘鍚庨獙璇佹暟鎹竴鑷存��
/// </summary>
private async Task<bool> ValidateAfterAutoSplit(Dt_OutStockLockInfo lockInfo, Dt_OutboundOrderDetail orderDetail,
Dt_StockInfoDetail originalStockDetail, decimal splitQuantity, decimal originalStockQtyBeforeSplit)
@@ -375,7 +374,7 @@
bool allValid = true;
List<string> validationErrors = new List<string>();
- // 1. 閲嶆柊鑾峰彇鏈�鏂扮殑鏁版嵁锛堟媶鍖呭悗鐨勫綋鍓嶇姸鎬侊級
+ // 閲嶆柊鑾峰彇鏈�鏂扮殑鏁版嵁锛堟媶鍖呭悗鐨勫綋鍓嶇姸鎬侊級
var refreshedOrderDetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
.FirstAsync(x => x.Id == orderDetail.Id);
@@ -385,9 +384,8 @@
var refreshedStockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
.FirstAsync(x => x.Id == originalStockDetail.Id);
- // 2. 銆愭牳蹇冧慨姝c�戦獙璇佸師搴撳瓨鏄庣粏鏁版嵁
- // 閲嶈锛氭媶鍖呭悗鍘熷簱瀛樼殑鏈熸湜鍊� = 鍒嗛厤鏁伴噺 (鍥犱负鑷姩鎷嗗寘鏃讹紝鍘熷簱瀛樺簲鍙繚鐣欏垎閰嶆暟閲�)
- decimal expectedOriginalStockQty = lockInfo.AssignQuantity; // 搴旇鏄�120锛岃�屼笉鏄敤璁$畻
+ // 楠岃瘉鍘熷簱瀛樻槑缁嗘暟鎹�
+ decimal expectedOriginalStockQty = lockInfo.AssignQuantity;
_logger.LogInformation($"搴撳瓨楠岃瘉鍩哄噯:");
_logger.LogInformation($" 鎷嗗寘鍓嶅師搴撳瓨: {originalStockQtyBeforeSplit}");
@@ -430,7 +428,7 @@
_logger.LogError(error);
}
- // 3. 楠岃瘉鏂板簱瀛樻槑缁嗭紙鎷嗗寘浜х敓鐨勶級
+ // 楠岃瘉鏂板簱瀛樻槑缁嗭紙鎷嗗寘浜х敓鐨勶級
// 鏌ユ壘鏂版潯鐮侊紙閫氳繃鎷嗗寘璁板綍锛�
var splitRecords = await _splitPackageService.Db.Queryable<Dt_SplitPackageRecord>()
.Where(x => x.OutStockLockInfoId == lockInfo.Id &&
@@ -493,7 +491,7 @@
_logger.LogError(error);
}
- // 5. 楠岃瘉璁㈠崟鏄庣粏鏁版嵁鏈敼鍙�
+ // 楠岃瘉璁㈠崟鏄庣粏鏁版嵁鏈敼鍙�
if (Math.Abs(refreshedOrderDetail.AllocatedQuantity - orderDetail.AllocatedQuantity) > 0.01m)
{
string error = $"璁㈠崟鏄庣粏鍒嗛厤鏁伴噺寮傚父鍙樺寲锛佹媶鍖呭墠: {orderDetail.AllocatedQuantity}, 鎷嗗寘鍚�: {refreshedOrderDetail.AllocatedQuantity}";
@@ -502,7 +500,7 @@
_logger.LogError(error);
}
- // 6. 楠岃瘉鍘熼攣瀹氳褰曟暟鎹湭鏀瑰彉锛堝垎閰嶆暟閲忎笉鍙橈級
+ // 楠岃瘉鍘熼攣瀹氳褰曟暟鎹湭鏀瑰彉锛堝垎閰嶆暟閲忎笉鍙橈級
if (Math.Abs(refreshedLockInfo.AssignQuantity - lockInfo.AssignQuantity) > 0.01m)
{
string error = $"閿佸畾璁板綍鍒嗛厤鏁伴噺寮傚父鍙樺寲锛佹媶鍖呭墠: {lockInfo.AssignQuantity}, 鎷嗗寘鍚�: {refreshedLockInfo.AssignQuantity}";
@@ -511,7 +509,7 @@
_logger.LogError(error);
}
- // 7. 銆愭柊澧炪�戦獙璇佹�诲簱瀛樺畧鎭�
+ // 鏂板銆戦獙璇佹�诲簱瀛樺畧鎭�
// 鎷嗗寘鍓嶆�诲簱瀛� = 鍘熷簱瀛樻暟閲�
// 鎷嗗寘鍚庢�诲簱瀛� = 鍘熷簱瀛樼幇鏈夋暟閲� + 鏂板簱瀛樻暟閲�
decimal totalStockAfterSplit = refreshedStockDetail.StockQuantity;
@@ -576,11 +574,11 @@
{
_logger.LogInformation($"寮�濮嬫嫞閫夊悗楠岃瘉");
- // 1. 楠岃瘉搴撳瓨鏄庣粏
+ // 楠岃瘉搴撳瓨鏄庣粏
var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
.FirstAsync(x => x.Barcode == barcode);
- // 2. 鏌ユ壘璇ユ潯鐮佺殑鎵�鏈夋嫞閫夎褰�
+ // 鏌ユ壘璇ユ潯鐮佺殑鎵�鏈夋嫞閫夎褰�
var pickingRecords = await Db.Queryable<Dt_PickingRecord>()
.Where(x => x.Barcode == barcode && x.OrderNo == orderNo && !x.IsCancelled)
.ToListAsync();
@@ -660,95 +658,7 @@
#region 鍙栬蛋绌虹閫昏緫
-
-
- /// <summary>
- /// 楠岃瘉绌虹鍙栬蛋鏉′欢
- /// </summary>
- private async Task<ValidationResult<List<Dt_OutStockLockInfo>>> ValidateEmptyPalletRemoval(string orderNo, string palletCode)
- {
- _logger.LogInformation($"寮�濮嬮獙璇佺┖鎵樼洏鍙栬蛋 - 璁㈠崟: {orderNo}, 鎵樼洏: {palletCode}");
-
- // 鑾峰彇鎵樼洏鐨勬墍鏈夐攣瀹氳褰�
- var lockInfos = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
- .Where(x => x.OrderNo == orderNo && x.PalletCode == palletCode)
- .ToListAsync();
-
- if (!lockInfos.Any())
- return ValidationResult<List<Dt_OutStockLockInfo>>.Error("璇ユ墭鐩樻病鏈夐攣瀹氳褰�");
-
- // 鑾峰彇搴撳瓨淇℃伅
- var stockInfo = await _stockInfoService.Db.Queryable<Dt_StockInfo>()
- .FirstAsync(x => x.PalletCode == palletCode);
-
- if (stockInfo == null)
- {
- _logger.LogWarning($"鏈壘鍒版墭鐩樼殑搴撳瓨淇℃伅锛屽彲鑳藉凡琚竻鐞�");
- // 濡傛灉鎵句笉鍒板簱瀛樹俊鎭紝鍙鏌ラ攣瀹氳褰�
- }
- else
- {
- // 妫�鏌ユ墭鐩樹笂鏄惁杩樻湁搴撳瓨璐х墿
- var remainingStock = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
- .Where(x => x.StockId == stockInfo.Id &&
- x.StockQuantity > 0) // 鍙鏌ユ暟閲忓ぇ浜�0鐨勫簱瀛�
- .ToListAsync();
-
- if (remainingStock.Any())
- {
- var remainingQty = remainingStock.Sum(x => x.StockQuantity);
- var barcodes = string.Join(", ", remainingStock.Select(x => x.Barcode).Take(5)); // 鍙樉绀哄墠5涓�
- return ValidationResult<List<Dt_OutStockLockInfo>>.Error(
- $"鎵樼洏涓婅繕鏈夊簱瀛樿揣鐗╋紝鏁伴噺{remainingQty}锛屾潯鐮�: {barcodes}锛屼笉鑳藉彇璧扮┖绠�");
- }
- }
-
- // 妫�鏌ユ槸鍚︽湁鏈畬鎴愮殑閿佸畾璁板綍锛堢姸鎬佷负鍑哄簱涓垨鍥炲簱涓級
- var unfinishedLocks = lockInfos.Where(x =>
- x.Status == (int)OutLockStockStatusEnum.鍑哄簱涓� ||
- x.Status == (int)OutLockStockStatusEnum.鍥炲簱涓�).ToList();
-
- if (unfinishedLocks.Any())
- {
- var unfinishedCount = unfinishedLocks.Count;
- var unfinishedQty = unfinishedLocks.Sum(x => x.AssignQuantity - x.PickedQty);
- return ValidationResult<List<Dt_OutStockLockInfo>>.Error(
- $"鎵樼洏杩樻湁{unfinishedCount}鏉℃湭瀹屾垚璁板綍锛屽墿浣欐暟閲弡unfinishedQty}锛屼笉鑳藉彇璧扮┖绠�");
- }
-
- // 鑾峰彇宸插畬鎴愮殑閿佸畾璁板綍锛堢姸鎬佷负鎷i�夊畬鎴愭垨宸插彇璧帮級
- var completedLocks = lockInfos.Where(x =>
- x.Status == (int)OutLockStockStatusEnum.鎷i�夊畬鎴� ||
- x.Status == (int)OutLockStockStatusEnum.宸插彇璧�).ToList();
-
- if (!completedLocks.Any())
- return ValidationResult<List<Dt_OutStockLockInfo>>.Error("璇ユ墭鐩樻病鏈夊凡瀹屾垚鎷i�夌殑璁板綍");
-
- _logger.LogInformation($"绌烘墭鐩橀獙璇侀�氳繃 - 鎵惧埌 {completedLocks.Count} 鏉″凡瀹屾垚璁板綍");
-
- return ValidationResult<List<Dt_OutStockLockInfo>>.Success(completedLocks);
- }
-
-
- /// <summary>
- /// 娓呯悊宸插畬鎴愮殑閿佸畾璁板綍
- /// </summary>
- private async Task CleanupCompletedLocks(List<Dt_OutStockLockInfo> completedLocks)
- {
- foreach (var lockInfo in completedLocks)
- {
- // 鏍囪閿佸畾璁板綍涓哄凡鍙栬蛋
- lockInfo.Status = (int)OutLockStockStatusEnum.宸插彇璧�;
- lockInfo.Operator = App.User.UserName;
- await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync();
-
- // 娓呯悊瀵瑰簲鐨勫簱瀛樿褰曠姸鎬�
- await CleanupStockInfo(lockInfo);
- }
- }
-
-
- /// <summary>
+ /// <summary>
/// 娓呯悊搴撳瓨淇℃伅 - 瀹屾暣淇鐗�
/// 纭繚OutboundQuantity姝g‘娓呴浂
/// </summary>
@@ -772,7 +682,6 @@
_logger.LogInformation($"娓呯悊鍓嶇姸鎬� - 搴撳瓨: {originalStockQty}, 鍑哄簱: {originalOutboundQty}, 鐘舵��: {GetStockStatusName(originalStatus)}");
// 銆愰噸瑕併�戞鏌ュ簱瀛樻暟閲忔槸鍚﹀簲璇ヤ负0
- // 濡傛灉閿佸畾鐘舵�佹槸鎷i�夊畬鎴愶紝鐞嗚涓婂簱瀛樺簲璇ヤ负0
if (lockInfo.Status == (int)OutLockStockStatusEnum.鎷i�夊畬鎴�)
{
if (stockDetail.StockQuantity > 0)
@@ -783,7 +692,7 @@
// 娓呯悊搴撳瓨鍜屽嚭搴撴暟閲�
stockDetail.StockQuantity = 0;
- stockDetail.OutboundQuantity = 0; // 銆愪慨姝c�戠‘淇濆嚭搴撴暟閲忔竻闆�
+ stockDetail.OutboundQuantity = 0;
stockDetail.Status = (int)StockStatusEmun.宸叉竻鐞�;
await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync();
@@ -813,7 +722,7 @@
decimal originalOutbound = stock.OutboundQuantity;
stock.StockQuantity = 0;
- stock.OutboundQuantity = 0; // 銆愪慨姝c�戠‘淇濆嚭搴撴暟閲忔竻闆�
+ stock.OutboundQuantity = 0;
stock.Status = (int)StockStatusEmun.宸叉竻鐞�;
await _stockInfoDetailService.Db.Updateable(stock).ExecuteCommandAsync();
@@ -1022,7 +931,6 @@
if (orderDetail.AllocatedQuantity != totalLockAssignQuantity)
{
_logger.LogWarning($"璁㈠崟鏄庣粏鍒嗛厤鏁伴噺涓庨攣瀹氫俊鎭笉涓�鑷� - 璁㈠崟鏄庣粏鍒嗛厤鏁伴噺: {orderDetail.AllocatedQuantity}, 閿佸畾淇℃伅鎬诲垎閰嶆暟閲�: {totalLockAssignQuantity}");
- // 杩欓噷涓嶇洿鎺ヨ繑鍥為敊璇紝鍥犱负鎷嗗寘鎿嶄綔鏈韩涓嶄細瀵艰嚧涓嶄竴鑷达紝鍙槸璁板綍璀﹀憡
}
_logger.LogInformation($"鎷嗗寘楠岃瘉閫氳繃 - 鍘熸潯鐮�: {originalBarcode}, 鎷嗗寘鏁伴噺: {splitQuantity}");
@@ -1118,7 +1026,7 @@
await _stockInfoDetailService.Db.Insertable(newStockDetail).ExecuteCommandAsync();
_logger.LogInformation($"鍒涘缓鏂板簱瀛樻槑缁嗘垚鍔� - 鏉$爜: {newBarcode}, 搴撳瓨鏁伴噺: {newStockQuantity}");
- // 淇锛氭洿鏂板師搴撳瓨鏄庣粏 - 纭繚鏁版嵁涓�鑷存��
+ // 鏇存柊鍘熷簱瀛樻槑缁�
stockDetail.StockQuantity = originalRemainingStockQuantity;
// 纭繚涓嶄細涓鸿礋鏁�
@@ -1126,10 +1034,7 @@
{
_logger.LogWarning($"鍘熷簱瀛樻暟閲忓嚭鐜拌礋鏁帮紝閲嶇疆涓�0");
stockDetail.StockQuantity = 0;
- }
-
- // 鍑哄簱鏁伴噺淇濇寔涓嶅彉锛屽洜涓烘槸鎷嗗寘锛屼笉鏄疄闄呭嚭搴�
- // stockDetail.OutboundQuantity = stockDetail.OutboundQuantity;
+ }
await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync();
_logger.LogInformation($"鏇存柊鍘熷簱瀛樻槑缁� - 鏉$爜: {stockDetail.Barcode}, " +
@@ -1197,46 +1102,7 @@
}
}
- /// <summary>
- /// 楠岃瘉鎷嗗寘鍚庤鍗曟槑缁嗙殑鍒嗛厤鏁伴噺鏄惁淇濇寔涓嶅彉
- /// </summary>
- private async Task ValidateOrderDetailAllocationAfterSplit(long orderDetailId, decimal originalTotalAssignQty)
- {
- try
- {
- // 鑾峰彇璁㈠崟鏄庣粏鐨勬墍鏈夐攣瀹氫俊鎭殑鎬诲垎閰嶆暟閲�
- var allLocks = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
- .Where(x => x.OrderDetailId == orderDetailId)
- .ToListAsync();
-
- decimal totalLockAssignQty = allLocks.Sum(x => x.AssignQuantity);
-
- _logger.LogInformation($"鎷嗗寘鍚庡垎閰嶆暟閲忛獙璇� - 璁㈠崟鏄庣粏ID: {orderDetailId}");
- _logger.LogInformation($"鍘熷鎬诲垎閰嶆暟閲�: {originalTotalAssignQty}, 褰撳墠鎬诲垎閰嶆暟閲�: {totalLockAssignQty}");
-
- // 鎵嬪姩鎷嗗寘鍚庢�诲垎閰嶆暟閲忓簲璇ヤ繚鎸佷笉鍙�
- if (Math.Abs(originalTotalAssignQty - totalLockAssignQty) > 0.01m)
- {
- _logger.LogWarning($"鎷嗗寘鍚庢�诲垎閰嶆暟閲忓彂鐢熷彉鍖� - 鏈熸湜: {originalTotalAssignQty}, 瀹為檯: {totalLockAssignQty}");
-
- // 濡傛灉鍙樺寲寰堝皬锛屽彲鑳芥槸绮惧害闂锛岃褰曚絾涓嶆姏鍑哄紓甯�
- if (Math.Abs(originalTotalAssignQty - totalLockAssignQty) > 1.0m)
- {
- throw new InvalidOperationException($"鎷嗗寘鍚庢�诲垎閰嶆暟閲忓紓甯稿彉鍖栵紝鏈熸湜: {originalTotalAssignQty}, 瀹為檯: {totalLockAssignQty}");
- }
- }
- else
- {
- _logger.LogInformation($"鎷嗗寘鍚庡垎閰嶆暟閲忛獙璇侀�氳繃 - 鎬诲垎閰嶆暟閲忎繚鎸佷笉鍙�");
- }
- }
- catch (Exception ex)
- {
- _logger.LogError($"楠岃瘉鎷嗗寘鍚庡垎閰嶆暟閲忓け璐� - OrderDetailId: {orderDetailId}, Error: {ex.Message}");
- throw;
- }
- }
- /// <summary>
+ /// <summary>
/// 楠岃瘉鎷嗗寘鍚庢暟鎹竴鑷存��
/// </summary>
private async Task ValidateDataConsistencyAfterSplit(long orderDetailId, decimal expectedAllocatedQty, decimal expectedLockQty)
@@ -1287,18 +1153,18 @@
{
_unitOfWorkManage.BeginTran();
- // 1. 鏌ユ壘鎷嗗寘璁板綍骞堕獙璇�
+ // 鏌ユ壘鎷嗗寘璁板綍骞堕獙璇�
var validationResult = await ValidateCancelSplitRequest(orderNo, palletCode, newBarcode);
if (!validationResult.IsValid)
return WebResponseContent.Instance.Error(validationResult.ErrorMessage);
var (splitRecord, newLockInfo, newStockDetail) = validationResult.Data;
- // 2. 鏌ユ壘鍘熷閿佸畾淇℃伅
+ // 鏌ユ壘鍘熷閿佸畾淇℃伅
var originalLockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
.FirstAsync(x => x.Id == splitRecord.OutStockLockInfoId);
- // 3. 妫�鏌ヨ鏉$爜鏄惁琚啀娆℃媶鍖�
+ // 妫�鏌ヨ鏉$爜鏄惁琚啀娆℃媶鍖�
var childSplitRecords = await _splitPackageService.Db.Queryable<Dt_SplitPackageRecord>()
.Where(x => x.OriginalBarcode == newBarcode && !x.IsReverted)
.ToListAsync();
@@ -1308,7 +1174,7 @@
return WebResponseContent.Instance.Error("璇ユ潯鐮佸凡琚啀娆℃媶鍖咃紝璇峰厛鍙栨秷鍚庣画鐨勬媶鍖呮搷浣�");
}
- // 4. 鎵ц鍙栨秷鎷嗗寘閫昏緫
+ // 鎵ц鍙栨秷鎷嗗寘閫昏緫
await ExecuteCancelSplitLogic(splitRecord, originalLockInfo, newLockInfo, newStockDetail);
_unitOfWorkManage.CommitTran();
@@ -1378,7 +1244,7 @@
if (orderDetail == null)
throw new InvalidOperationException("鏈壘鍒拌鍗曟槑缁�");
- // 1. 鎭㈠璁㈠崟鏄庣粏鐨勫垎閰嶆暟閲忥紙鑷姩鎷嗗寘浼氬鍔犲垎閰嶆暟閲忥級
+ // 鎭㈠璁㈠崟鏄庣粏鐨勫垎閰嶆暟閲�
decimal originalAllocatedQty = orderDetail.AllocatedQuantity;
decimal originalLockQty = orderDetail.LockQuantity;
@@ -1392,7 +1258,7 @@
await _outboundOrderDetailService.Db.Updateable(orderDetail).ExecuteCommandAsync();
_logger.LogInformation($"鑷姩鎷嗗寘鍙栨秷鎭㈠璁㈠崟鏄庣粏 - 鍒嗛厤鏁伴噺: {originalAllocatedQty} -> {orderDetail.AllocatedQuantity}");
- // 2. 鎭㈠鍘熷簱瀛橈紙灏嗘媶鍖呯殑鏁伴噺鍔犲洖鍘熷簱瀛橈級
+ // 鎭㈠鍘熷簱瀛�
var originalStock = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
.FirstAsync(x => x.Barcode == splitRecord.OriginalBarcode && x.StockId == splitRecord.StockId);
@@ -1411,7 +1277,7 @@
_logger.LogInformation($"鑷姩鎷嗗寘鍙栨秷鎭㈠鍘熷簱瀛� - 鏉$爜: {originalStock.Barcode}, 鏁伴噺: {originalStockQty} -> {originalStock.StockQuantity}");
}
- // 3. 鍒犻櫎鏂伴攣瀹氫俊鎭拰搴撳瓨鏄庣粏
+ // 鍒犻櫎鏂伴攣瀹氫俊鎭拰搴撳瓨鏄庣粏
await DeleteNewSplitRecords(newLockInfo, newStockDetail);
}
@@ -1424,7 +1290,7 @@
{
_logger.LogInformation($"澶勭悊鎵嬪姩鎷嗗寘鍙栨秷 - 鍘熸潯鐮�: {splitRecord.OriginalBarcode}, 鏂版潯鐮�: {splitRecord.NewBarcode}");
- // 1. 鎭㈠鍘熼攣瀹氫俊鎭殑鍒嗛厤鏁伴噺
+ // 鎭㈠鍘熼攣瀹氫俊鎭殑鍒嗛厤鏁伴噺
decimal originalAssignQty = originalLockInfo.AssignQuantity;
decimal originalOrderQty = originalLockInfo.OrderQuantity;
@@ -1440,7 +1306,7 @@
await _outStockLockInfoService.Db.Updateable(originalLockInfo).ExecuteCommandAsync();
_logger.LogInformation($"鎵嬪姩鎷嗗寘鍙栨秷鎭㈠鍘熼攣瀹氫俊鎭� - 鍒嗛厤鏁伴噺: {originalAssignQty} -> {originalLockInfo.AssignQuantity}");
- // 2. 鎭㈠鍘熷簱瀛樻槑缁�
+ // 鎭㈠鍘熷簱瀛樻槑缁�
var originalStock = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
.FirstAsync(x => x.Barcode == splitRecord.OriginalBarcode && x.StockId == splitRecord.StockId);
@@ -1459,7 +1325,7 @@
_logger.LogInformation($"鎵嬪姩鎷嗗寘鍙栨秷鎭㈠鍘熷簱瀛� - 鏉$爜: {originalStock.Barcode}, 鏁伴噺: {originalStockQty} -> {originalStock.StockQuantity}");
}
- // 3. 鍒犻櫎鏂伴攣瀹氫俊鎭拰搴撳瓨鏄庣粏
+ // 鍒犻櫎鏂伴攣瀹氫俊鎭拰搴撳瓨鏄庣粏
await DeleteNewSplitRecords(newLockInfo, newStockDetail);
}
@@ -1486,6 +1352,7 @@
.ExecuteCommandAsync();
}
}
+
/// <summary>
/// 楠岃瘉鍙栨秷鎷嗗寘鍚庢暟鎹竴鑷存�� - 鏈�鏂扮増鏈�
/// </summary>
@@ -1664,7 +1531,7 @@
{
_unitOfWorkManage.BeginTran();
- // 1. 鏌ユ壘鎵�鏈夌浉鍏崇殑鎷嗗寘璁板綍锛堝舰鎴愭媶鍖呴摼锛�
+ // 鏌ユ壘鎵�鏈夌浉鍏崇殑鎷嗗寘璁板綍锛堝舰鎴愭媶鍖呴摼锛�
var splitChain = await GetSplitPackageChain(orderNo, startBarcode);
if (!splitChain.Any())
@@ -1672,11 +1539,11 @@
_logger.LogInformation($"鎵惧埌鎷嗗寘閾撅紝鍏� {splitChain.Count} 鏉¤褰�");
- // 2. 鏀堕泦鎷嗗寘閾句腑娑夊強鐨勬墍鏈夋潯鐮侊紙鍖呮嫭鍘熸潯鐮佸拰鏂版潯鐮侊級
+ // 鏀堕泦鎷嗗寘閾句腑娑夊強鐨勬墍鏈夋潯鐮侊紙鍖呮嫭鍘熸潯鐮佸拰鏂版潯鐮侊級
var allBarcodesInChain = new List<string> { startBarcode };
allBarcodesInChain.AddRange(splitChain.Select(x => x.NewBarcode));
- // 3. 妫�鏌ユ媶鍖呴摼涓槸鍚︽湁宸茶鍒嗘嫞鐨勬潯鐮�
+ // 妫�鏌ユ媶鍖呴摼涓槸鍚︽湁宸茶鍒嗘嫞鐨勬潯鐮�
var pickedBarcodesInfo = await GetPickedBarcodesInfo(orderNo, allBarcodesInChain);
if (pickedBarcodesInfo.Any())
@@ -1686,7 +1553,7 @@
$"浠ヤ笅鏉$爜宸茶鍒嗘嫞锛岃鍏堝彇娑堝垎鎷o細{pickedBarcodes}");
}
- // 4. 鎸夋媶鍖呴『搴忓�掑簭鍙栨秷锛堜粠鏈�鏂扮殑寮�濮嬪彇娑堬級
+ // 鎸夋媶鍖呴『搴忓�掑簭鍙栨秷锛堜粠鏈�鏂扮殑寮�濮嬪彇娑堬級
var reversedChain = splitChain.OrderByDescending(x => x.SplitTime).ToList();
foreach (var splitRecord in reversedChain)
@@ -1707,106 +1574,7 @@
}
}
- /// <summary>
- /// 鑾峰彇鏉$爜鐨勬媶鍖呭拰鎷i�夌姸鎬�
- /// </summary>
- public async Task<WebResponseContent> GetBarcodeSplitAndPickStatus(string orderNo, string barcode)
- {
- try
- {
- // 1. 鑾峰彇鎷嗗寘淇℃伅
- var splitChain = await GetSplitPackageChain(orderNo, barcode);
- var isOriginalBarcode = !splitChain.Any(x => x.NewBarcode == barcode);
-
- // 2. 鑾峰彇鎷i�変俊鎭�
- var pickingRecords = await Db.Queryable<Dt_PickingRecord>()
- .Where(x => x.Barcode == barcode && x.OrderNo == orderNo && !x.IsCancelled)
- .ToListAsync();
-
- var totalPickedQty = pickingRecords.Sum(x => x.PickQuantity);
-
- // 3. 鑾峰彇閿佸畾淇℃伅
- var lockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
- .Where(x => x.CurrentBarcode == barcode && x.OrderNo == orderNo)
- .FirstAsync();
-
- // 4. 鑾峰彇搴撳瓨淇℃伅
- var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
- .Where(x => x.Barcode == barcode)
- .FirstAsync();
-
- var statusInfo = new BarcodeStatusInfoDto
- {
- Barcode = barcode,
- OrderNo = orderNo,
- IsOriginalBarcode = isOriginalBarcode,
- SplitChainCount = splitChain.Count,
- HasBeenPicked = pickingRecords.Any(),
- TotalPickedQuantity = totalPickedQty,
- PickRecordCount = pickingRecords.Count,
- LockInfoStatus = lockInfo?.Status ?? 0,
- LockInfoPickedQty = lockInfo?.PickedQty ?? 0,
- LockInfoAssignQty = lockInfo?.AssignQuantity ?? 0,
- StockQuantity = stockDetail?.StockQuantity ?? 0,
- StockStatus = stockDetail?.Status ?? 0,
- CanCancelSplit = !pickingRecords.Any(), // 鏈鍒嗘嫞鎵嶈兘鍙栨秷鎷嗗寘
- NeedCancelPickFirst = pickingRecords.Any() // 闇�瑕佸厛鍙栨秷鍒嗘嫞
- };
-
- // 5. 鑾峰彇鎿嶄綔寤鸿
- statusInfo.OperationSuggestions = GetOperationSuggestions(statusInfo);
-
- return WebResponseContent.Instance.OK("鑾峰彇鐘舵�佹垚鍔�", statusInfo);
- }
- catch (Exception ex)
- {
- _logger.LogError($"鑾峰彇鏉$爜鐘舵�佸け璐� - OrderNo: {orderNo}, Barcode: {barcode}, Error: {ex.Message}");
- return WebResponseContent.Instance.Error("鑾峰彇鏉$爜鐘舵�佸け璐�");
- }
- }
- /// <summary>
- /// 鑾峰彇鎿嶄綔寤鸿
- /// </summary>
- private List<string> GetOperationSuggestions(BarcodeStatusInfoDto statusInfo)
- {
- var suggestions = new List<string>();
-
- if (statusInfo.HasBeenPicked)
- {
- suggestions.Add($"璇ユ潯鐮佸凡琚垎鎷o紙鏁伴噺锛歿statusInfo.TotalPickedQuantity}锛夛紝濡傞渶鍙栨秷鎷嗗寘锛岃鍏堝彇娑堝垎鎷�");
-
- if (statusInfo.IsOriginalBarcode)
- {
- suggestions.Add("杩欐槸鍘熸潯鐮侊紝鍙栨秷鍒嗘嫞鍚庡皢鎭㈠涓哄彲鍒嗘嫞鐘舵��");
- }
- else
- {
- suggestions.Add("杩欐槸鎷嗗寘鐢熸垚鐨勬柊鏉$爜锛屽彇娑堝垎鎷e悗鎵嶈兘鍙栨秷鎷嗗寘");
- }
- }
- else
- {
- if (statusInfo.IsOriginalBarcode && statusInfo.SplitChainCount > 0)
- {
- suggestions.Add("杩欐槸鍘熸潯鐮侊紝鍙互鍙栨秷鎷嗗寘閾�");
- }
- else if (!statusInfo.IsOriginalBarcode)
- {
- suggestions.Add("杩欐槸鎷嗗寘鐢熸垚鐨勬柊鏉$爜锛屽彲浠ュ崟鐙彇娑堟媶鍖�");
- }
- }
-
- if (statusInfo.LockInfoStatus == (int)OutLockStockStatusEnum.鎷i�夊畬鎴�)
- {
- suggestions.Add("閿佸畾鐘舵�侊細鎷i�夊畬鎴�");
- }
- else if (statusInfo.LockInfoStatus == (int)OutLockStockStatusEnum.鍑哄簱涓�)
- {
- suggestions.Add("閿佸畾鐘舵�侊細鍑哄簱涓�");
- }
-
- return suggestions;
- }
+
/// <summary>
/// 鑾峰彇宸茶鍒嗘嫞鐨勬潯鐮佷俊鎭�
/// </summary>
@@ -2031,153 +1799,13 @@
#endregion
#region 缁熶竴鍥炲簱閫昏緫
- private async Task<Dt_Task> GetCurrentTask(string orderNo, string palletCode)
- {
- // 鍏堝皾璇曢�氳繃璁㈠崟鍙峰拰鎵樼洏鍙锋煡鎵句换鍔�
- var task = await _taskRepository.Db.Queryable<Dt_Task>()
- .Where(x => x.OrderNo == orderNo && x.PalletCode == palletCode)
- .FirstAsync();
-
- if (task == null)
- {
- // 濡傛灉鎵句笉鍒帮紝鍐嶉�氳繃鎵樼洏鍙锋煡鎵�
- task = await _taskRepository.Db.Queryable<Dt_Task>()
- .Where(x => x.PalletCode == palletCode)
- .FirstAsync();
- }
-
- return task;
- }
- private async Task<PalletStatusAnalysis> AnalyzePalletStatus(string orderNo, string palletCode, int stockId)
- {
- var result = new PalletStatusAnalysis
- {
- OrderNo = orderNo,
- PalletCode = palletCode,
- StockId = stockId
- };
-
- // 鍒嗘瀽鏈垎鎷g殑鍑哄簱閿佸畾璁板綍
- var remainingLocks = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
- .Where(it => it.OrderNo == orderNo &&
- it.PalletCode == palletCode &&
- it.Status == (int)OutLockStockStatusEnum.鍑哄簱涓�)
- .ToListAsync();
-
- if (remainingLocks.Any())
- {
- result.HasRemainingLocks = true;
- result.RemainingLocks = remainingLocks;
- result.RemainingLocksReturnQty = remainingLocks.Sum(x => x.AssignQuantity - x.PickedQty);
- _logger.LogInformation($"鍙戠幇{remainingLocks.Count}鏉℃湭鍒嗘嫞閿佸畾璁板綍锛屾�绘暟閲�: {result.RemainingLocksReturnQty}");
- }
-
- // 鍒嗘瀽鎵樼洏涓婄殑搴撳瓨璐х墿
- var palletStockGoods = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
- .Where(it => it.StockId == stockId &&
- (it.Status == StockStatusEmun.鍏ュ簱纭.ObjToInt() ||
- it.Status == StockStatusEmun.鍏ュ簱瀹屾垚.ObjToInt() ||
- it.Status == StockStatusEmun.鍑哄簱閿佸畾.ObjToInt()))
- .Where(it => it.StockQuantity > 0)
- .ToListAsync();
-
- if (palletStockGoods.Any())
- {
- result.HasPalletStockGoods = true;
- result.PalletStockGoods = palletStockGoods;
- result.PalletStockReturnQty = palletStockGoods.Sum(x => x.StockQuantity);
- _logger.LogInformation($"鍙戠幇{palletStockGoods.Count}涓簱瀛樿揣鐗╋紝鎬绘暟閲�: {result.PalletStockReturnQty}");
-
- // 璁板綍璇︾粏鐘舵�佸垎甯�
- var statusGroups = palletStockGoods.GroupBy(x => x.Status);
- foreach (var group in statusGroups)
- {
- _logger.LogInformation($"搴撳瓨鐘舵�亄group.Key}: {group.Count()}涓揣鐗╋紝鏁伴噺: {group.Sum(x => x.StockQuantity)}");
- }
- }
-
- //鍒嗘瀽鎷嗗寘璁板綍
- var splitRecords = await _splitPackageService.Db.Queryable<Dt_SplitPackageRecord>()
- .Where(it => it.OrderNo == orderNo &&
- it.PalletCode == palletCode &&
- !it.IsReverted && it.Status != (int)SplitPackageStatusEnum.宸叉嫞閫� &&
- it.Status != (int)SplitPackageStatusEnum.宸插洖搴�)
- .ToListAsync();
-
- if (splitRecords.Any())
- {
- result.HasSplitRecords = true;
- result.SplitRecords = splitRecords;
- result.SplitReturnQty = await CalculateSplitReturnQuantity(splitRecords, stockId);
-
- _logger.LogInformation($"鍙戠幇{splitRecords.Count}鏉℃湭鎷i�夋媶鍖呰褰曪紝鎬绘暟閲�: {result.SplitReturnQty}");
- }
-
- // 4. 璁$畻鎬诲洖搴撴暟閲忓拰绌烘墭鐩樼姸鎬�
- result.TotalReturnQty = result.RemainingLocksReturnQty + result.PalletStockReturnQty + result.SplitReturnQty;
- result.HasItemsToReturn = result.TotalReturnQty > 0;
- result.IsEmptyPallet = !result.HasItemsToReturn;
-
- // 5. 妫�鏌ユ槸鍚︽湁杩涜涓殑浠诲姟
- result.HasActiveTasks = await _taskRepository.Db.Queryable<Dt_Task>()
- .Where(x => x.OrderNo == orderNo && x.TaskType == TaskTypeEnum.InPick.ObjToInt() &&
- x.PalletCode == palletCode &&
- x.TaskStatus == (int)TaskStatusEnum.New)
- .AnyAsync();
-
- _logger.LogInformation($"鎵樼洏鐘舵�佸垎鏋愬畬鎴� - 璁㈠崟: {orderNo}, 鎵樼洏: {palletCode}, " +
- $"鎬诲洖搴撴暟閲�: {result.TotalReturnQty}, 鏄惁绌烘墭鐩�: {result.IsEmptyPallet}, " +
- $"鏈夎繘琛屼腑浠诲姟: {result.HasActiveTasks}");
-
- return result;
- }
- private async Task<decimal> CalculateSplitReturnQuantity(List<Dt_SplitPackageRecord> splitRecords, int stockId)
- {
- decimal totalQty = 0;
- var processedBarcodes = new HashSet<string>();
-
- foreach (var splitRecord in splitRecords)
- {
- if (splitRecord.Status != (int)SplitPackageStatusEnum.宸叉挙閿�)
- continue;
- // 妫�鏌ュ師鏉$爜
- if (!processedBarcodes.Contains(splitRecord.OriginalBarcode))
- {
- var originalStock = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
- .Where(it => it.Barcode == splitRecord.OriginalBarcode && it.StockId == stockId &&
- it.Status != StockStatusEmun.鍑哄簱瀹屾垚.ObjToInt())
- .FirstAsync();
-
- if (originalStock != null && originalStock.StockQuantity > 0)
- {
- totalQty += originalStock.StockQuantity;
- processedBarcodes.Add(splitRecord.OriginalBarcode);
- }
- }
-
- // 妫�鏌ユ柊鏉$爜
- if (!processedBarcodes.Contains(splitRecord.NewBarcode))
- {
- var newStock = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
- .Where(it => it.Barcode == splitRecord.NewBarcode && it.StockId == stockId && it.Status != StockStatusEmun.鍑哄簱瀹屾垚.ObjToInt())
- .FirstAsync();
-
- if (newStock != null && newStock.StockQuantity > 0)
- {
- totalQty += newStock.StockQuantity;
- processedBarcodes.Add(splitRecord.NewBarcode);
- }
- }
- }
-
- return totalQty;
- }
/// <summary>
/// 缁熶竴鍥炲簱鏂规硶
/// </summary>
public async Task<WebResponseContent> ExecutePalletReturn(string orderNo, string palletCode, string returnReason = "鍒嗘壒鍥炲簱")
{
+ ReturnTaskInfo returnTaskInfo = null;
try
{
_logger.LogInformation($"銆愬寮哄洖搴撳紑濮嬨�戣鍗�: {orderNo}, 鎵樼洏: {palletCode}");
@@ -2189,8 +1817,7 @@
return WebResponseContent.Instance.Error("璁㈠崟鍙峰拰鎵樼洏鐮佷笉鑳戒负绌�");
// 鑾峰彇搴撳瓨淇℃伅
- var stockInfo = await _stockInfoService.Db.Queryable<Dt_StockInfo>()
- .FirstAsync(x => x.PalletCode == palletCode);
+ var stockInfo = await _stockInfoService.Db.Queryable<Dt_StockInfo>().FirstAsync(x => x.PalletCode == palletCode);
if (stockInfo == null)
return WebResponseContent.Instance.Error($"鏈壘鍒版墭鐩� {palletCode} 瀵瑰簲鐨勫簱瀛樹俊鎭�");
@@ -2201,8 +1828,7 @@
var validationResult = await ValidateDataBeforeReturn(orderNo, palletCode, stockId);
if (!validationResult.IsValid)
{
- _logger.LogWarning($"鍥炲簱鍓嶆暟鎹獙璇佸け璐�: {validationResult.ErrorMessage}");
- // 鍙互鏍规嵁瀹為檯鎯呭喌鍐冲畾鏄惁缁х画
+ _logger.LogWarning($"鍥炲簱鍓嶆暟鎹獙璇佸け璐�: {validationResult.ErrorMessage}");
}
// 鍒嗘瀽鎵樼洏鐘舵��
@@ -2215,6 +1841,12 @@
_logger.LogInformation($"銆愭棤鍥炲簱鐗╁搧銆戝鐞嗙┖鎵樼洏");
var result = await HandleEmptyPalletReturn(orderNo, palletCode, stockInfo);
_unitOfWorkManage.CommitTran();
+
+ // 鍦ㄤ簨鍔℃彁浜ゅ悗澶勭悊ESS鍛戒护
+ if (result.Status && result.Data is ReturnTaskInfo taskInfo)
+ {
+ await ProcessESSAfterTransaction(palletCode, taskInfo);
+ }
return result;
}
catch (Exception ex)
@@ -2241,13 +1873,13 @@
// 鏇存柊璁㈠崟鐘舵��
await UpdateOrderStatusAfterReturn(orderNo);
-
-
-
+
// 鍒涘缓鍥炲簱浠诲姟
try
{
- await CreateReturnTask(orderNo, palletCode, stockInfo);
+ // 鍒涘缓鍥炲簱浠诲姟锛屼絾涓嶅彂閫丒SS鍛戒护
+ returnTaskInfo = await CreateReturnTaskWithoutESS(orderNo, palletCode, stockInfo);
+
}
catch (Exception taskEx)
{
@@ -2255,7 +1887,13 @@
// 浠诲姟鍒涘缓澶辫触涓嶅奖鍝嶆暟鎹洖搴�
}
_unitOfWorkManage.CommitTran();
- // 8. 鍥炲簱鍚庨獙璇�
+
+ // 鍦ㄤ簨鍔℃彁浜ゅ悗澶勭悊ESS鍛戒护
+ if (returnTaskInfo != null && returnTaskInfo.ShouldSendESS)
+ {
+ await ProcessESSAfterTransaction(palletCode, returnTaskInfo);
+ }
+ // 鍥炲簱鍚庨獙璇�
await ValidateDataAfterReturn(orderNo, palletCode, stockId);
return WebResponseContent.Instance.OK($"鍥炲簱鎴愬姛锛屽洖搴撴暟閲忥細{statusAnalysis.TotalReturnQty}", new
@@ -2276,6 +1914,107 @@
}
/// <summary>
+ /// 浜嬪姟鎻愪氦鍚庡鐞咵SS鍛戒护 - 鐙珛鏂规硶锛岄伩鍏嶄簨鍔¢攣
+ /// </summary>
+ private async Task ProcessESSAfterTransaction(string palletCode, ReturnTaskInfo taskInfo)
+ {
+ try
+ {
+ _logger.LogInformation($"寮�濮嬪鐞咵SS鍛戒护 - 鎵樼洏: {palletCode}");
+
+ if (taskInfo == null || !taskInfo.ShouldSendESS || taskInfo.ReturnTask == null)
+ {
+ _logger.LogWarning($"鏃犻渶鍙戦�丒SS鍛戒护鎴栦换鍔′俊鎭笉瀹屾暣");
+ return;
+ }
+
+ // 鍙戦�丒SS鍛戒护
+ await SendESSCommands(palletCode, taskInfo.OriginalTaskTargetAddress, taskInfo.ReturnTask);
+
+ _logger.LogInformation($"ESS鍛戒护澶勭悊瀹屾垚 - 鎵樼洏: {palletCode}, 浠诲姟鍙�: {taskInfo.ReturnTask.TaskNum}");
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError($"澶勭悊ESS鍛戒护澶辫触 - 鎵樼洏: {palletCode}, Error: {ex.Message}");
+ // 杩欓噷涓嶆姏鍑哄紓甯革紝鍥犱负鏁版嵁鍥炲簱宸茬粡鎴愬姛锛孍SS鍛戒护鍙戦�佸け璐ュ彲浠ョ◢鍚庨噸璇�
+ }
+ }
+ /// <summary>
+ /// 鍒涘缓鍥炲簱浠诲姟锛堜笉鍙戦�丒SS鍛戒护锛�- 鐢ㄤ簬浜嬪姟鍐呭鐞�
+ /// </summary>
+ private async Task<ReturnTaskInfo> CreateReturnTaskWithoutESS(string orderNo, string palletCode, Dt_StockInfo stockInfo)
+ {
+ try
+ {
+ // 鑾峰彇褰撳墠浠诲姟淇℃伅
+ var currentTask = await _taskRepository.Db.Queryable<Dt_Task>()
+ .Where(x => x.OrderNo == orderNo && x.PalletCode == palletCode)
+ .FirstAsync();
+
+ if (currentTask == null)
+ {
+ _logger.LogWarning($"鏈壘鍒板綋鍓嶄换鍔� - 璁㈠崟: {orderNo}, 鎵樼洏: {palletCode}");
+ return null;
+ }
+
+ // 鍒嗛厤鏂拌揣浣�
+ var newLocation = _locationInfoService.AssignLocation(stockInfo.LocationType);
+
+ var returnTask = new Dt_Task()
+ {
+ CurrentAddress = stations[currentTask.TargetAddress],
+ Grade = 0,
+ PalletCode = palletCode,
+ NextAddress = "",
+ OrderNo = orderNo,
+ Roadway = newLocation.RoadwayNo,
+ SourceAddress = stations[currentTask.TargetAddress],
+ TargetAddress = newLocation.LocationCode,
+ TaskStatus = TaskStatusEnum.New.ObjToInt(),
+ TaskType = TaskTypeEnum.InPick.ObjToInt(),
+ PalletType = stockInfo.PalletType,
+ WarehouseId = currentTask.WarehouseId
+ };
+
+ try
+ {
+ await _taskRepository.Db.Insertable(returnTask).ExecuteCommandAsync();
+
+ _logger.LogInformation($"鍒涘缓鍥炲簱浠诲姟鎴愬姛: {returnTask.TaskNum}, 璁㈠崟: {orderNo}, 鎵樼洏: {palletCode}");
+
+ // 鍒犻櫎鍘熷鍑哄簱浠诲姟
+ _logger.LogInformation($"寮�濮嬪垹闄ゅ巻鍙蹭换鍔�: {orderNo}, {currentTask.TaskNum}");
+ var result = _task_HtyService.DeleteAndMoveIntoHty(currentTask, OperateTypeEnum.浜哄伐鍒犻櫎);
+ await _taskRepository.Db.Deleteable(currentTask).ExecuteCommandAsync();
+
+ if (!result)
+ {
+ await _taskRepository.Db.Deleteable(currentTask).ExecuteCommandAsync();
+ }
+ _logger.LogInformation($"鍒犻櫎鍘嗗彶浠诲姟瀹屾垚: {currentTask.TaskNum}, 褰卞搷琛屾暟: {result}");
+
+ // 杩斿洖浠诲姟淇℃伅锛屼絾涓嶅彂閫丒SS鍛戒护
+ return new ReturnTaskInfo
+ {
+ ShouldSendESS = true,
+ PalletCode = palletCode,
+ OriginalTaskTargetAddress = currentTask.TargetAddress,
+ ReturnTask = returnTask
+ };
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError($"鍒涘缓鍥炲簱浠诲姟澶辫触 - 璁㈠崟: {orderNo}, 鎵樼洏: {palletCode}, Error: {ex.Message}");
+ throw new Exception($"鍒涘缓鍥炲簱浠诲姟澶辫触 - 璁㈠崟: {orderNo}, 鎵樼洏: {palletCode}", ex);
+ }
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError($"鍒涘缓鍥炲簱浠诲姟澶辫触 - 璁㈠崟: {orderNo}, 鎵樼洏: {palletCode}, Error: {ex.Message}");
+ return null;
+ }
+ }
+ /// <summary>
/// 澧炲己鐨勫洖搴撳墠鏁版嵁楠岃瘉
/// </summary>
private async Task<ValidationResult<bool>> ValidateDataBeforeReturn(string orderNo, string palletCode, int stockId)
@@ -2284,7 +2023,7 @@
try
{
- // 1. 楠岃瘉搴撳瓨鏁版嵁
+ // 楠岃瘉搴撳瓨鏁版嵁
var stockDetails = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
.Where(x => x.StockId == stockId)
.ToListAsync();
@@ -2296,7 +2035,7 @@
errors.Add($"鍙戠幇璐熸暟搴撳瓨: {string.Join(", ", negativeStocks.Select(x => $"{x.Barcode}:{x.StockQuantity}"))}");
}
- // 2. 楠岃瘉閿佸畾璁板綍
+ // 楠岃瘉閿佸畾璁板綍
var lockInfos = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
.Where(x => x.OrderNo == orderNo && x.PalletCode == palletCode)
.ToListAsync();
@@ -2308,7 +2047,7 @@
errors.Add($"鍙戠幇宸叉嫞閫夋暟閲忓ぇ浜庡垎閰嶆暟閲忕殑閿佸畾璁板綍");
}
- // 3. 楠岃瘉鎷嗗寘璁板綍
+ // 楠岃瘉鎷嗗寘璁板綍
var splitRecords = await _splitPackageService.Db.Queryable<Dt_SplitPackageRecord>()
.Where(x => x.OrderNo == orderNo && x.PalletCode == palletCode)
.ToListAsync();
@@ -2364,7 +2103,7 @@
var locallyProcessedBarcodes = new HashSet<string>();
decimal totalProcessedQty = 0;
- // 1. 澶勭悊宸插垎閰嶇殑閿佸畾璁板綍
+ // 澶勭悊宸插垎閰嶇殑閿佸畾璁板綍
if (statusAnalysis.HasRemainingLocks)
{
_logger.LogInformation($"澶勭悊宸插垎閰嶉攣瀹氳褰� - {statusAnalysis.RemainingLocks.Count} 鏉�");
@@ -2389,7 +2128,7 @@
}
}
- // 2. 澶勭悊鏈垎閰嶇殑閿佸畾璁板綍
+ // 澶勭悊鏈垎閰嶇殑閿佸畾璁板綍
if (statusAnalysis.HasUnallocatedLocks)
{
_logger.LogInformation($"澶勭悊鏈垎閰嶉攣瀹氳褰� - {statusAnalysis.UnallocatedLocks.Count} 鏉�");
@@ -2414,7 +2153,7 @@
}
}
- // 3. 澶勭悊鏈垎閰嶇殑搴撳瓨璐х墿
+ // 澶勭悊鏈垎閰嶇殑搴撳瓨璐х墿
if (statusAnalysis.HasPalletStockGoods)
{
_logger.LogInformation($"澶勭悊鏈垎閰嶅簱瀛樿揣鐗� - {statusAnalysis.PalletStockGoods.Count} 涓�");
@@ -2438,7 +2177,7 @@
}
}
- // 4. 銆愪慨姝c�戝鐞嗘媶鍖呰褰� - 鍙鐞嗘湭琚叾浠栭�昏緫瑕嗙洊鐨勬潯鐮�
+ // 澶勭悊鎷嗗寘璁板綍 - 鍙鐞嗘湭琚叾浠栭�昏緫瑕嗙洊鐨勬潯鐮�
if (statusAnalysis.HasSplitRecords && statusAnalysis.SplitReturnQty > 0)
{
_logger.LogInformation($"澶勭悊鎷嗗寘璁板綍鐩稿叧搴撳瓨 - 鏂板鏁伴噺: {statusAnalysis.SplitReturnQty}");
@@ -2483,282 +2222,6 @@
/// <summary>
- /// 澶勭悊宸插垎閰嶉攣瀹氳褰曠殑鍥炲簱
- /// 宸插垎閰嶉攣瀹氳褰曢渶瑕侊細1.鎭㈠搴撳瓨 2.鏇存柊閿佸畾鐘舵�� 3.鍑忓皯璁㈠崟鏄庣粏鍒嗛厤鏁伴噺
- /// </summary>
- private async Task ProcessSingleLockReturn(Dt_OutStockLockInfo lockInfo, decimal returnQty)
- {
- try
- {
- _logger.LogInformation($"寮�濮嬪鐞嗗凡鍒嗛厤閿佸畾璁板綍鍥炲簱 - 閿佸畾ID: {lockInfo.Id}, 鏉$爜: {lockInfo.CurrentBarcode}, 鍥炲簱鏁伴噺: {returnQty}");
-
- if (returnQty <= 0)
- {
- _logger.LogInformation($"鍥炲簱鏁伴噺鏃犳晥({returnQty})锛岃烦杩囧鐞�");
- return;
- }
-
- // 1. 楠岃瘉閿佸畾璁板綍鐘舵��
- if (lockInfo.Status != (int)OutLockStockStatusEnum.鍑哄簱涓� &&
- lockInfo.Status != (int)OutLockStockStatusEnum.鍥炲簱涓�)
- {
- _logger.LogWarning($"閿佸畾璁板綍鐘舵�佷笉鏄嚭搴撲腑鎴栧洖搴撲腑锛岃烦杩囧鐞� - 鐘舵��: {lockInfo.Status}");
- return;
- }
-
- // 2. 鑾峰彇鍏宠仈鐨勫簱瀛樻槑缁�
- var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
- .FirstAsync(x => x.Barcode == lockInfo.CurrentBarcode && x.StockId == lockInfo.StockId);
-
- if (stockDetail == null)
- {
- _logger.LogError($"鏈壘鍒板簱瀛樻槑缁� - 鏉$爜: {lockInfo.CurrentBarcode}, StockId: {lockInfo.StockId}");
- throw new InvalidOperationException($"搴撳瓨鏄庣粏涓嶅瓨鍦�: {lockInfo.CurrentBarcode}");
- }
-
- // 3. 鑾峰彇鍏宠仈鐨勮鍗曟槑缁�
- var orderDetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
- .FirstAsync(x => x.Id == lockInfo.OrderDetailId);
-
- if (orderDetail == null)
- {
- _logger.LogError($"鏈壘鍒拌鍗曟槑缁� - OrderDetailId: {lockInfo.OrderDetailId}");
- throw new InvalidOperationException($"璁㈠崟鏄庣粏涓嶅瓨鍦�: {lockInfo.OrderDetailId}");
- }
-
- // 璁板綍鍘熷鍊硷紙鐢ㄤ簬鏃ュ織鍜屽洖婊氭鏌ワ級
- decimal originalStockQty = stockDetail.StockQuantity;
- decimal originalOutboundQty = stockDetail.OutboundQuantity;
- int originalStockStatus = stockDetail.Status;
-
- decimal originalAllocatedQty = orderDetail.AllocatedQuantity;
- decimal originalLockQty = orderDetail.LockQuantity;
- decimal originalOverOutQty = orderDetail.OverOutQuantity;
-
- decimal originalLockPickedQty = lockInfo.PickedQty;
- decimal originalLockAssignQty = lockInfo.AssignQuantity;
- int originalLockStatus = lockInfo.Status;
-
- _logger.LogInformation($"鍥炲簱鍓嶆暟鎹姸鎬�:");
- _logger.LogInformation($" 搴撳瓨 - 鏉$爜: {stockDetail.Barcode}, 鏁伴噺: {originalStockQty}, 鍑哄簱: {originalOutboundQty}, 鐘舵��: {GetStockStatusName(originalStockStatus)}");
- _logger.LogInformation($" 璁㈠崟鏄庣粏 - 鍒嗛厤: {originalAllocatedQty}, 閿佸畾: {originalLockQty}, 宸插嚭搴�: {originalOverOutQty}");
- _logger.LogInformation($" 閿佸畾璁板綍 - 鍒嗛厤: {originalLockAssignQty}, 宸叉嫞閫�: {originalLockPickedQty}, 鐘舵��: {GetLockStatusName(originalLockStatus)}");
-
- // 4. 銆愭牳蹇冮�昏緫銆戞仮澶嶅簱瀛樻暟鎹�
- // 4.1 澧炲姞搴撳瓨鏁伴噺
- stockDetail.StockQuantity += returnQty;
-
- // 4.2 鍑忓皯鍑哄簱鏁伴噺锛堜絾闇�纭繚涓嶄細鍑虹幇璐熸暟锛�
- if (stockDetail.OutboundQuantity >= returnQty)
- {
- stockDetail.OutboundQuantity -= returnQty;
- }
- else
- {
- // 濡傛灉鍑哄簱鏁伴噺灏忎簬鍥炲簱鏁伴噺锛岃鏄庢暟鎹紓甯�
- _logger.LogWarning($"鍑哄簱鏁伴噺({stockDetail.OutboundQuantity})灏忎簬鍥炲簱鏁伴噺({returnQty})锛屾暟鎹紓甯�");
- stockDetail.OutboundQuantity = 0;
- }
-
- // 4.3 鏇存柊搴撳瓨鐘舵��
- if (stockDetail.OutboundQuantity <= 0 && stockDetail.StockQuantity > 0)
- {
- stockDetail.Status = (int)StockStatusEmun.鍏ュ簱瀹屾垚;
- _logger.LogInformation($"搴撳瓨鐘舵�佹洿鏂颁负: 鍏ュ簱瀹屾垚");
- }
- else if (stockDetail.StockQuantity > 0)
- {
- stockDetail.Status = (int)StockStatusEmun.鍑哄簱閿佸畾;
- _logger.LogInformation($"搴撳瓨鐘舵�佷繚鎸佷负: 鍑哄簱閿佸畾");
- }
-
- await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync();
- _logger.LogInformation($"搴撳瓨鏇存柊瀹屾垚 - 鏉$爜: {stockDetail.Barcode}");
- _logger.LogInformation($" 搴撳瓨鏁伴噺: {originalStockQty} -> {stockDetail.StockQuantity}");
- _logger.LogInformation($" 鍑哄簱鏁伴噺: {originalOutboundQty} -> {stockDetail.OutboundQuantity}");
- _logger.LogInformation($" 鐘舵��: {GetStockStatusName(originalStockStatus)} -> {GetStockStatusName(stockDetail.Status)}");
-
- // 5. 鏇存柊閿佸畾璁板綍鐘舵��
- lockInfo.Status = (int)OutLockStockStatusEnum.宸插洖搴�;
- lockInfo.Operator = App.User.UserName;
-
- // 銆愰噸瑕併�戝鏋滈攣瀹氳褰曟槸閮ㄥ垎鎷i�夊悗鍥炲簱锛岄渶瑕佽皟鏁村凡鎷i�夋暟閲�
- // 浣嗕竴鑸儏鍐典笅锛屽洖搴撶殑鏄湭鎷i�夌殑閮ㄥ垎锛屾墍浠ickedQty淇濇寔涓嶅彉
-
- await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync();
- _logger.LogInformation($"閿佸畾璁板綍鏇存柊瀹屾垚 - ID: {lockInfo.Id}");
- _logger.LogInformation($" 鐘舵��: {GetLockStatusName(originalLockStatus)} -> {GetLockStatusName(lockInfo.Status)}");
- _logger.LogInformation($" 鍒嗛厤鏁伴噺: {originalLockAssignQty} (涓嶅彉)");
- _logger.LogInformation($" 宸叉嫞閫夋暟閲�: {originalLockPickedQty} (涓嶅彉)");
-
- // 6. 鏇存柊璁㈠崟鏄庣粏鏁版嵁
- // 6.1 鍑忓皯宸插垎閰嶆暟閲�
- if (orderDetail.AllocatedQuantity >= returnQty)
- {
- orderDetail.AllocatedQuantity -= returnQty;
- }
- else
- {
- // 濡傛灉鍒嗛厤鏁伴噺灏忎簬鍥炲簱鏁伴噺锛岃鏄庢暟鎹紓甯�
- _logger.LogWarning($"鍒嗛厤鏁伴噺({orderDetail.AllocatedQuantity})灏忎簬鍥炲簱鏁伴噺({returnQty})锛岄噸缃负0");
- orderDetail.AllocatedQuantity = 0;
- }
-
- // 6.2 鍑忓皯閿佸畾鏁伴噺锛堝簲涓庡垎閰嶆暟閲忎繚鎸佸悓姝ワ級
- if (orderDetail.LockQuantity >= returnQty)
- {
- orderDetail.LockQuantity -= returnQty;
- }
- else
- {
- _logger.LogWarning($"閿佸畾鏁伴噺({orderDetail.LockQuantity})灏忎簬鍥炲簱鏁伴噺({returnQty})锛岄噸缃负0");
- orderDetail.LockQuantity = 0;
- }
-
- // 6.3 宸插嚭搴撴暟閲忎繚鎸佷笉鍙橈紙鍥炲簱涓嶅奖鍝嶅凡鍑哄簱鏁伴噺锛�
- // orderDetail.OverOutQuantity = orderDetail.OverOutQuantity;
-
- // 6.4 鏇存柊鎵规鍒嗛厤鐘舵��
- await UpdateBatchAllocateStatus(orderDetail);
-
- await _outboundOrderDetailService.Db.Updateable(orderDetail).ExecuteCommandAsync();
- _logger.LogInformation($"璁㈠崟鏄庣粏鏇存柊瀹屾垚 - ID: {orderDetail.Id}");
- _logger.LogInformation($" 鍒嗛厤鏁伴噺: {originalAllocatedQty} -> {orderDetail.AllocatedQuantity}");
- _logger.LogInformation($" 閿佸畾鏁伴噺: {originalLockQty} -> {orderDetail.LockQuantity}");
- _logger.LogInformation($" 宸插嚭搴撴暟閲�: {originalOverOutQty} (淇濇寔涓嶅彉)");
-
- // 7. 楠岃瘉鍥炲簱鍚庣殑鏁版嵁涓�鑷存��
- await ValidateAfterLockReturn(lockInfo, stockDetail, orderDetail, returnQty);
-
- _logger.LogInformation($"宸插垎閰嶉攣瀹氳褰曞洖搴撳鐞嗗畬鎴� - 閿佸畾ID: {lockInfo.Id}, 鍥炲簱鏁伴噺: {returnQty}");
- }
- catch (Exception ex)
- {
- _logger.LogError($"澶勭悊宸插垎閰嶉攣瀹氳褰曞洖搴撳け璐� - 閿佸畾ID: {lockInfo.Id}, Error: {ex.Message}");
- throw new InvalidOperationException($"澶勭悊閿佸畾璁板綍鍥炲簱澶辫触: {ex.Message}", ex);
- }
- }
-
- /// <summary>
- /// 閿佸畾璁板綍鍥炲簱鍚庨獙璇佹暟鎹竴鑷存��
- /// </summary>
- private async Task ValidateAfterLockReturn(Dt_OutStockLockInfo lockInfo, Dt_StockInfoDetail stockDetail,
- Dt_OutboundOrderDetail orderDetail, decimal returnQty)
- {
- try
- {
- _logger.LogInformation($"寮�濮嬪洖搴撳悗鏁版嵁楠岃瘉 - 閿佸畾ID: {lockInfo.Id}");
-
- bool allValid = true;
- List<string> validationErrors = new List<string>();
-
- // 1. 閲嶆柊鑾峰彇鏈�鏂版暟鎹�
- var refreshedStock = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
- .FirstAsync(x => x.Id == stockDetail.Id);
-
- var refreshedOrder = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
- .FirstAsync(x => x.Id == orderDetail.Id);
-
- var refreshedLock = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
- .FirstAsync(x => x.Id == lockInfo.Id);
-
- // 2. 楠岃瘉搴撳瓨鏁版嵁
- // 璁$畻搴撳瓨鏁伴噺搴旇澧炲姞鍥炲簱鏁伴噺
- decimal expectedStockQty = stockDetail.StockQuantity + returnQty;
- if (Math.Abs(refreshedStock.StockQuantity - expectedStockQty) > 0.01m)
- {
- string error = $"搴撳瓨鏁伴噺涓嶆纭紒鏈熸湜: {expectedStockQty}, 瀹為檯: {refreshedStock.StockQuantity}";
- validationErrors.Add(error);
- allValid = false;
- _logger.LogError(error);
- }
-
- // 楠岃瘉搴撳瓨鐘舵�佸簲涓哄叆搴撳畬鎴愭垨鍑哄簱閿佸畾
- if (refreshedStock.Status != (int)StockStatusEmun.鍏ュ簱瀹屾垚 &&
- refreshedStock.Status != (int)StockStatusEmun.鍑哄簱閿佸畾)
- {
- string error = $"搴撳瓨鐘舵�佸紓甯革紒鏈熸湜:鍏ュ簱瀹屾垚鎴栧嚭搴撻攣瀹�, 瀹為檯:{GetStockStatusName(refreshedStock.Status)}";
- validationErrors.Add(error);
- allValid = false;
- _logger.LogError(error);
- }
-
- // 3. 楠岃瘉閿佸畾璁板綍鐘舵��
- if (refreshedLock.Status != (int)OutLockStockStatusEnum.宸插洖搴�)
- {
- string error = $"閿佸畾璁板綍鐘舵�佸紓甯革紒鏈熸湜:宸插洖搴�, 瀹為檯:{GetLockStatusName(refreshedLock.Status)}";
- validationErrors.Add(error);
- allValid = false;
- _logger.LogError(error);
- }
-
- // 4. 楠岃瘉璁㈠崟鏄庣粏鏁版嵁
- // 璁$畻鍒嗛厤鏁伴噺搴旇鍑忓皯鍥炲簱鏁伴噺
- decimal expectedAllocatedQty = Math.Max(0, orderDetail.AllocatedQuantity - returnQty);
- if (Math.Abs(refreshedOrder.AllocatedQuantity - expectedAllocatedQty) > 0.01m)
- {
- string error = $"璁㈠崟鍒嗛厤鏁伴噺涓嶆纭紒鏈熸湜: {expectedAllocatedQty}, 瀹為檯: {refreshedOrder.AllocatedQuantity}";
- validationErrors.Add(error);
- allValid = false;
- _logger.LogError(error);
- }
-
- // 鍒嗛厤鏁伴噺搴斾笌閿佸畾鏁伴噺涓�鑷�
- if (Math.Abs(refreshedOrder.AllocatedQuantity - refreshedOrder.LockQuantity) > 0.01m)
- {
- string error = $"璁㈠崟鍒嗛厤鏁伴噺涓庨攣瀹氭暟閲忎笉涓�鑷达紒鍒嗛厤: {refreshedOrder.AllocatedQuantity}, 閿佸畾: {refreshedOrder.LockQuantity}";
- validationErrors.Add(error);
- allValid = false;
- _logger.LogError(error);
- }
-
- // 5. 鏁版嵁鍏宠仈鎬ч獙璇�
- // 閿佸畾璁板綍鐨勫凡鎷i�夋暟閲� + 褰撳墠搴撳瓨鐨勫嚭搴撴暟閲忓簲绛変簬鍘熷鍑哄簱鏁伴噺
- decimal totalOutboundFromLock = refreshedLock.PickedQty + refreshedStock.OutboundQuantity;
-
- // 鏌ユ壘璇ユ潯鐮佺殑鎵�鏈夋湭鍙栨秷鎷i�夎褰�
- var pickingRecords = await Db.Queryable<Dt_PickingRecord>()
- .Where(x => x.Barcode == stockDetail.Barcode && !x.IsCancelled)
- .ToListAsync();
-
- decimal totalPickedFromRecords = pickingRecords.Sum(x => x.PickQuantity);
-
- if (Math.Abs(totalOutboundFromLock - totalPickedFromRecords) > 0.01m)
- {
- string error = $"鏁版嵁鍏宠仈鎬у紓甯革紒閿佸畾鎷i��({refreshedLock.PickedQty})+搴撳瓨鍑哄簱({refreshedStock.OutboundQuantity})={totalOutboundFromLock}, 浣嗘嫞閫夎褰曟�诲拰={totalPickedFromRecords}";
- validationErrors.Add(error);
- allValid = false;
- _logger.LogError(error);
- }
-
- // 6. 杈撳嚭楠岃瘉缁撴灉
- if (allValid)
- {
- _logger.LogInformation($"鍥炲簱鍚庢暟鎹獙璇佸叏閮ㄩ�氳繃");
- }
- else
- {
- _logger.LogError($"鍥炲簱鍚庢暟鎹獙璇佸け璐ワ紝鍙戠幇{validationErrors.Count}涓棶棰�");
- foreach (var error in validationErrors.Take(3)) // 鍙樉绀哄墠3涓棶棰�
- {
- _logger.LogError($"楠岃瘉闂: {error}");
- }
-
- // 濡傛灉闂涓ラ噸锛屽彲浠ユ姏鍑哄紓甯�
- if (validationErrors.Any(e => e.Contains("寮傚父")))
- {
- throw new InvalidOperationException($"鍥炲簱鍚庢暟鎹獙璇佸け璐�: {string.Join("; ", validationErrors.Take(2))}");
- }
- }
- }
- catch (Exception ex)
- {
- _logger.LogError($"鍥炲簱鍚庨獙璇佸紓甯�: {ex.Message}");
- // 涓嶉噸鏂版姏鍑猴紝閬垮厤褰卞搷涓绘祦绋�
- }
- }
-
- /// <summary>
/// 澶勭悊鍗曚釜鏉$爜鍥炲簱锛堥�氱敤鏂规硶锛�- 鍖哄垎宸插垎閰嶅拰鏈垎閰�
/// </summary>
private async Task ProcessSingleBarcodeReturn(string barcode, int stockId, decimal returnQty, bool isUnallocated = false)
@@ -2782,7 +2245,7 @@
_logger.LogInformation($"鍥炲簱鍓嶇姸鎬� - 搴撳瓨: {originalStockQty}, 鍑哄簱: {originalOutboundQty}, 鐘舵��: {GetStockStatusName(originalStatus)}");
- // 銆愪慨澶嶃�戞牴鎹槸鍚︽湭鍒嗛厤鍐冲畾澶勭悊閫昏緫
+ // 鏍规嵁鏄惁鏈垎閰嶅喅瀹氬鐞嗛�昏緫
if (isUnallocated)
{
// 鏈垎閰嶉攣瀹氾細鍙仮澶嶇姸鎬侊紝涓嶆敼鍙樺簱瀛樻暟閲�
@@ -2847,7 +2310,7 @@
return;
}
- // 銆愪慨澶嶃�戣幏鍙栧簱瀛樻槑缁�
+ // 鑾峰彇搴撳瓨鏄庣粏
var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
.FirstAsync(x => x.Barcode == lockInfo.CurrentBarcode && x.StockId == lockInfo.StockId);
@@ -2865,7 +2328,7 @@
_logger.LogInformation($"鏈垎閰嶉攣瀹氬洖搴撳墠鐘舵��:");
_logger.LogInformation($" 搴撳瓨 - 鏉$爜: {stockDetail.Barcode}, 鏁伴噺: {originalStockQty}, 鍑哄簱: {originalOutboundQty}, 鐘舵��: {GetStockStatusName(originalStatus)}");
- // 銆愪慨澶嶅叧閿�戝浜庢湭鍒嗛厤閿佸畾璁板綍锛屽簱瀛樻暟閲忎笉搴旀敼鍙橈紒
+ // 瀵逛簬鏈垎閰嶉攣瀹氳褰曪紝搴撳瓨鏁伴噺涓嶅簲鏀瑰彉锛�
// 鍥犱负搴撳瓨鏈潵灏卞瓨鍦紝鍙槸鐘舵�佽閿佸畾
// stockDetail.StockQuantity 淇濇寔涓嶅彉
@@ -2923,7 +2386,7 @@
{
_logger.LogInformation($"寮�濮嬪洖搴撳悗鏁版嵁楠岃瘉");
- // 1. 楠岃瘉搴撳瓨鐘舵�佸拰鏁伴噺
+ // 楠岃瘉搴撳瓨鐘舵�佸拰鏁伴噺
var stockDetails = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
.Where(x => x.StockId == stockId)
.ToListAsync();
@@ -2937,7 +2400,7 @@
_logger.LogError($"鍙戠幇璐熸暟搴撳瓨鏁伴噺锛佹潯鐮�: {string.Join(", ", unreasonableStocks.Select(x => x.Barcode))}");
}
- // 2. 楠岃瘉閿佸畾璁板綍鐘舵��
+ // 楠岃瘉閿佸畾璁板綍鐘舵��
var lockInfos = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
.Where(x => x.OrderNo == orderNo && x.PalletCode == palletCode)
.ToListAsync();
@@ -2956,7 +2419,7 @@
}
}
- // 3. 鏁版嵁涓�鑷存�ч獙璇�
+ // 鏁版嵁涓�鑷存�ч獙璇�
decimal totalExpectedReturnQty = lockInfos
.Where(x => x.Status == (int)OutLockStockStatusEnum.宸插洖搴�)
.Sum(x => x.AssignQuantity - x.PickedQty);
@@ -2966,7 +2429,7 @@
_logger.LogInformation($" 宸插洖搴撻攣瀹氳褰曟暟閲�: {lockInfos.Count(x => x.Status == (int)OutLockStockStatusEnum.宸插洖搴�)}");
_logger.LogInformation($" 鎬诲洖搴撴暟閲忥紙閿佸畾璁板綍璁$畻锛�: {totalExpectedReturnQty}");
- // 4. 楠岃瘉搴撳瓨鏁伴噺涓庨攣瀹氳褰曠殑涓�鑷存��
+ // 楠岃瘉搴撳瓨鏁伴噺涓庨攣瀹氳褰曠殑涓�鑷存��
foreach (var lockInfo in lockInfos.Where(x => !string.IsNullOrEmpty(x.CurrentBarcode)))
{
var stock = stockDetails.FirstOrDefault(x => x.Barcode == lockInfo.CurrentBarcode);
@@ -2989,76 +2452,7 @@
}
}
- /// <summary>
- /// 楠岃瘉鍥炲簱鍓嶅悗鏁版嵁涓�鑷存��
- /// </summary>
- private async Task<bool> ValidateReturnData(string orderNo, string palletCode, int stockId, bool isBefore = true)
- {
- string phase = isBefore ? "鍥炲簱鍓�" : "鍥炲簱鍚�";
- try
- {
-
- _logger.LogInformation($"銆恵phase}鏁版嵁楠岃瘉銆戝紑濮� - 璁㈠崟: {orderNo}, 鎵樼洏: {palletCode}");
-
- // 1. 妫�鏌ュ簱瀛樻槑缁�
- var stockDetails = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
- .Where(x => x.StockId == stockId)
- .ToListAsync();
-
- decimal totalStockQty = stockDetails.Sum(x => x.StockQuantity);
- _logger.LogInformation($"{phase}搴撳瓨鎬婚噺: {totalStockQty}");
-
- // 2. 妫�鏌ラ攣瀹氳褰�
- var lockInfos = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
- .Where(x => x.OrderNo == orderNo && x.PalletCode == palletCode)
- .ToListAsync();
-
- // 妫�鏌ラ攣瀹氳褰曠姸鎬佸垎甯�
- var statusGroups = lockInfos.GroupBy(x => x.Status)
- .Select(g => new { Status = g.Key, Count = g.Count() })
- .ToList();
-
- foreach (var group in statusGroups)
- {
- _logger.LogInformation($"{phase}閿佸畾鐘舵�� {GetLockStatusName(group.Status)}: {group.Count} 鏉�");
- }
-
- // 3. 鍩烘湰楠岃瘉
- bool isValid = true;
-
- // 楠岃瘉1: 濡傛灉閿佸畾璁板綍鐘舵�佷负"鎷i�夊畬鎴�"锛屽搴斿簱瀛樺簲璇ヤ负0
- var completedLocks = lockInfos.Where(x => x.Status == (int)OutLockStockStatusEnum.鎷i�夊畬鎴�).ToList();
- foreach (var lockInfo in completedLocks)
- {
- if (!string.IsNullOrEmpty(lockInfo.CurrentBarcode))
- {
- var stock = stockDetails.FirstOrDefault(x => x.Barcode == lockInfo.CurrentBarcode);
- if (stock != null && stock.StockQuantity > 0)
- {
- _logger.LogWarning($"{phase}楠岃瘉璀﹀憡 - 閿佸畾ID {lockInfo.Id} 鎷i�夊畬鎴愪絾搴撳瓨涓嶄负0: {stock.StockQuantity}");
- }
- }
- }
-
- // 楠岃瘉2: 搴撳瓨鐘舵�佷竴鑷存��
- foreach (var stock in stockDetails)
- {
- if (stock.Status == (int)StockStatusEmun.鍑哄簱閿佸畾 && stock.StockQuantity == 0)
- {
- _logger.LogWarning($"{phase}楠岃瘉璀﹀憡 - 鏉$爜 {stock.Barcode} 鐘舵�佷负鍑哄簱閿佸畾浣嗗簱瀛樹负0");
- }
- }
-
- _logger.LogInformation($"銆恵phase}鏁版嵁楠岃瘉銆戝畬鎴� - 鐘舵��: {(isValid ? "閫氳繃" : "鏈夎鍛�")}");
- return isValid;
- }
- catch (Exception ex)
- {
- _logger.LogError($"{phase} 鏁版嵁楠岃瘉澶辫触: {ex.Message}");
- return false;
- }
- }
-
+
private string GetLockStatusName(int status)
{
return status switch
@@ -3173,464 +2567,6 @@
/// <summary>
- /// 鎵ц鍥炲簱鏁版嵁鎿嶄綔 - 绠�鍖栫増鏈�
- /// </summary>
- private async Task ExecuteReturnDataOperations(PalletStatusAnalysis statusAnalysis)
- {
- _logger.LogInformation($"寮�濮嬫墽琛屽洖搴撴暟鎹搷浣� - 璁㈠崟: {statusAnalysis.OrderNo}, 鎵樼洏: {statusAnalysis.PalletCode}");
-
- try
- {
- // 浣跨敤 HashSet 閬垮厤閲嶅澶勭悊鏉$爜
- var processedBarcodes = new HashSet<string>();
- decimal totalReturnedQty = 0;
-
- // 1. 澶勭悊宸插垎閰嶇殑鏈垎鎷i攣瀹氳褰�
- if (statusAnalysis.HasRemainingLocks)
- {
- _logger.LogInformation($"澶勭悊 {statusAnalysis.RemainingLocks.Count} 鏉″凡鍒嗛厤鏈垎鎷i攣瀹氳褰�");
-
- foreach (var lockInfo in statusAnalysis.RemainingLocks)
- {
- if (string.IsNullOrEmpty(lockInfo.CurrentBarcode) || processedBarcodes.Contains(lockInfo.CurrentBarcode))
- {
- _logger.LogInformation($"璺宠繃閲嶅鎴栫┖鏉$爜鐨勯攣瀹氳褰� - ID: {lockInfo.Id}");
- continue;
- }
-
- // 璁$畻鍥炲簱鏁伴噺锛堟湭鎷i�夌殑閮ㄥ垎锛�
- decimal returnQty = lockInfo.AssignQuantity - lockInfo.PickedQty;
-
- if (returnQty > 0)
- {
- _logger.LogInformation($"澶勭悊閿佸畾璁板綍鍥炲簱 - ID: {lockInfo.Id}, 鏉$爜: {lockInfo.CurrentBarcode}, 鍥炲簱鏁伴噺: {returnQty}");
-
- // 澶勭悊搴撳瓨
- await ProcessStockForReturn(lockInfo.CurrentBarcode, statusAnalysis.StockId, returnQty);
-
- // 鏍囪涓哄凡鍥炲簱
- lockInfo.Status = (int)OutLockStockStatusEnum.宸插洖搴�;
- lockInfo.Operator = App.User.UserName;
-
-
- await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync();
-
- // 鍑忓皯璁㈠崟鏄庣粏鐨勫垎閰嶆暟閲�
- if (lockInfo.OrderDetailId > 0)
- {
- var orderDetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>().FirstAsync(x => x.Id == lockInfo.OrderDetailId);
- await ReduceOrderDetailAllocation(orderDetail, returnQty);
- }
-
- processedBarcodes.Add(lockInfo.CurrentBarcode);
- totalReturnedQty += returnQty;
-
- _logger.LogInformation($"閿佸畾璁板綍鍥炲簱瀹屾垚 - ID: {lockInfo.Id}, 鍥炲簱鏁伴噺: {returnQty}");
- }
- else
- {
- _logger.LogInformation($"閿佸畾璁板綍鏃犻渶鍥炲簱 - ID: {lockInfo.Id}, 宸叉嫞閫夊畬鎴�");
- }
- }
- }
-
- // 2. 澶勭悊鏈垎閰嶇殑搴撳瓨璐х墿
- if (statusAnalysis.HasPalletStockGoods)
- {
- _logger.LogInformation($"澶勭悊 {statusAnalysis.PalletStockGoods.Count} 涓湭鍒嗛厤搴撳瓨璐х墿");
-
- foreach (var stockDetail in statusAnalysis.PalletStockGoods)
- {
- if (string.IsNullOrEmpty(stockDetail.Barcode) || processedBarcodes.Contains(stockDetail.Barcode))
- {
- _logger.LogInformation($"璺宠繃閲嶅鎴栫┖鏉$爜鐨勫簱瀛� - 搴撳瓨ID: {stockDetail.Id}");
- continue;
- }
-
- if (stockDetail.StockQuantity > 0)
- {
- decimal returnQty = stockDetail.StockQuantity;
- _logger.LogInformation($"澶勭悊鏈垎閰嶅簱瀛樺洖搴� - 鏉$爜: {stockDetail.Barcode}, 鍥炲簱鏁伴噺: {returnQty}");
-
- // 鐩存帴鎭㈠搴撳瓨鐘舵��
- stockDetail.Status = (int)StockStatusEmun.鍏ュ簱瀹屾垚;
-
- await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync();
-
- processedBarcodes.Add(stockDetail.Barcode);
- totalReturnedQty += returnQty;
-
- _logger.LogInformation($"鏈垎閰嶅簱瀛樺洖搴撳畬鎴� - 鏉$爜: {stockDetail.Barcode}, 鏁伴噺: {returnQty}");
- }
- }
- }
-
- // 3. 澶勭悊鎷嗗寘璁板綍鐩稿叧鐨勬潯鐮�
- if (statusAnalysis.HasSplitRecords)
- {
- _logger.LogInformation($"澶勭悊 {statusAnalysis.SplitRecords.Count} 鏉℃媶鍖呰褰�");
-
- // 鏀堕泦鎷嗗寘鐩稿叧鐨勬墍鏈夋潯鐮�
- var splitBarcodes = new List<string>();
- foreach (var splitRecord in statusAnalysis.SplitRecords)
- {
- if (!string.IsNullOrEmpty(splitRecord.OriginalBarcode))
- splitBarcodes.Add(splitRecord.OriginalBarcode);
- if (!string.IsNullOrEmpty(splitRecord.NewBarcode))
- splitBarcodes.Add(splitRecord.NewBarcode);
- }
-
- // 鍘婚噸
- splitBarcodes = splitBarcodes.Distinct().ToList();
-
- foreach (var barcode in splitBarcodes)
- {
- if (processedBarcodes.Contains(barcode))
- {
- _logger.LogInformation($"鎷嗗寘鏉$爜宸插鐞�: {barcode}");
- continue;
- }
-
- // 鏌ユ壘搴撳瓨
- var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
- .FirstAsync(x => x.Barcode == barcode && x.StockId == statusAnalysis.StockId);
-
- if (stockDetail != null && stockDetail.StockQuantity > 0)
- {
- decimal returnQty = stockDetail.StockQuantity;
- _logger.LogInformation($"澶勭悊鎷嗗寘鐩稿叧搴撳瓨鍥炲簱 - 鏉$爜: {barcode}, 鍥炲簱鏁伴噺: {returnQty}");
-
- // 鎭㈠搴撳瓨鐘舵��
- if (stockDetail.Status == (int)StockStatusEmun.鍑哄簱閿佸畾)
- {
- stockDetail.Status = (int)StockStatusEmun.鍏ュ簱瀹屾垚;
-
- await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync();
-
- processedBarcodes.Add(barcode);
- totalReturnedQty += returnQty;
-
- _logger.LogInformation($"鎷嗗寘搴撳瓨鍥炲簱瀹屾垚 - 鏉$爜: {barcode}, 鏁伴噺: {returnQty}");
- }
- }
- }
- }
-
- _logger.LogInformation($"鍥炲簱鏁版嵁鎿嶄綔瀹屾垚 - 鎬诲洖搴撴暟閲�: {totalReturnedQty}, 澶勭悊鏉$爜鏁�: {processedBarcodes.Count}");
- }
- catch (Exception ex)
- {
- _logger.LogError($"鍥炲簱鏁版嵁鎿嶄綔澶辫触 - 璁㈠崟: {statusAnalysis.OrderNo}, 鎵樼洏: {statusAnalysis.PalletCode}, Error: {ex.Message}");
- throw;
- }
- }
-
-
- /// <summary>
- /// 澶勭悊搴撳瓨鍥炲簱 - 瀹屾暣淇鐗�
- /// 纭繚OutboundQuantity姝g‘鍑忓皯
- /// </summary>
- private async Task ProcessStockForReturn(string barcode, int stockId, decimal returnQty)
- {
- try
- {
- _logger.LogInformation($"澶勭悊搴撳瓨鍥炲簱 - 鏉$爜: {barcode}, 鍥炲簱鏁伴噺: {returnQty}");
-
- var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
- .FirstAsync(x => x.Barcode == barcode && x.StockId == stockId);
-
- if (stockDetail == null)
- {
- _logger.LogWarning($"鏈壘鍒板簱瀛樻槑缁� - 鏉$爜: {barcode}");
- return;
- }
-
- // 璁板綍鍘熷鍊�
- decimal originalStockQty = stockDetail.StockQuantity;
- decimal originalOutboundQty = stockDetail.OutboundQuantity;
- int originalStatus = stockDetail.Status;
-
- _logger.LogInformation($"鍥炲簱鍓嶇姸鎬� - 搴撳瓨: {originalStockQty}, 鍑哄簱: {originalOutboundQty}, 鐘舵��: {GetStockStatusName(originalStatus)}");
-
- // 銆愭牳蹇冧慨姝c�戠‘淇濆洖搴撴搷浣滄纭鐞�
- // 1. 搴撳瓨鏁伴噺澧炲姞锛堝洖搴撶殑璐х墿鍥炲埌搴撳瓨锛�
- stockDetail.StockQuantity += returnQty;
-
- // 2. 鍑哄簱鏁伴噺鍑忓皯锛堝洜涓鸿揣鐗╂病鏈夊嚭搴擄紝鑰屾槸鍥炲簱浜嗭級
- // 浣嗛渶瑕佺‘淇濅笉浼氬嚭鐜拌礋鏁�
- if (stockDetail.OutboundQuantity >= returnQty)
- {
- stockDetail.OutboundQuantity -= returnQty;
- }
- else
- {
- // 濡傛灉鍑哄簱鏁伴噺灏忎簬鍥炲簱鏁伴噺锛岃鏄庢暟鎹紓甯�
- _logger.LogWarning($"鍑哄簱鏁伴噺({stockDetail.OutboundQuantity})灏忎簬鍥炲簱鏁伴噺({returnQty})锛岄噸缃嚭搴撴暟閲忎负0");
- stockDetail.OutboundQuantity = 0;
- }
-
- // 3. 鏇存柊鐘舵�佷负鍏ュ簱瀹屾垚
- stockDetail.Status = (int)StockStatusEmun.鍏ュ簱瀹屾垚;
-
- await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync();
-
- _logger.LogInformation($"搴撳瓨鍥炲簱瀹屾垚 - 鏉$爜: {barcode}");
- _logger.LogInformation($" 搴撳瓨鏁伴噺: {originalStockQty} -> {stockDetail.StockQuantity}");
- _logger.LogInformation($" 鍑哄簱鏁伴噺: {originalOutboundQty} -> {stockDetail.OutboundQuantity}");
- _logger.LogInformation($" 鐘舵��: {GetStockStatusName(originalStatus)} -> {GetStockStatusName(stockDetail.Status)}");
-
- // 楠岃瘉鍥炲簱鍚庣殑鏁版嵁
- await ValidateStockAfterReturn(barcode, stockId, returnQty);
- }
- catch (Exception ex)
- {
- _logger.LogError($"澶勭悊搴撳瓨鍥炲簱澶辫触 - 鏉$爜: {barcode}, Error: {ex.Message}");
- throw;
- }
- }
-
- /// <summary>
- /// 楠岃瘉鍥炲簱鍚庡簱瀛樻暟鎹�
- /// </summary>
- private async Task ValidateStockAfterReturn(string barcode, int stockId, decimal returnQty)
- {
- try
- {
- var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
- .FirstAsync(x => x.Barcode == barcode && x.StockId == stockId);
-
- // 妫�鏌ュ嚭搴撴暟閲忔槸鍚︿负0鎴栧悎鐞�
- if (stockDetail.OutboundQuantity > stockDetail.StockQuantity)
- {
- _logger.LogWarning($"鍥炲簱鍚庢暟鎹紓甯� - 鍑哄簱鏁伴噺({stockDetail.OutboundQuantity})澶т簬搴撳瓨鏁伴噺({stockDetail.StockQuantity})");
- }
-
- // 妫�鏌ョ姸鎬佹槸鍚︽纭�
- if (stockDetail.Status != (int)StockStatusEmun.鍏ュ簱瀹屾垚)
- {
- _logger.LogWarning($"鍥炲簱鍚庣姸鎬佸紓甯� - 鏈熸湜:鍏ュ簱瀹屾垚, 瀹為檯:{GetStockStatusName(stockDetail.Status)}");
- }
- }
- catch (Exception ex)
- {
- _logger.LogError($"楠岃瘉鍥炲簱鍚庢暟鎹け璐�: {ex.Message}");
- }
- }
-
- /// <summary>
- /// 涓洪攣瀹氳褰曞噺灏戣鍗曟槑缁嗙殑鍒嗛厤鏁伴噺
- /// </summary>
- private async Task ReduceOrderDetailAllocationForLock(long orderDetailId, decimal reduceQty)
- {
- if (orderDetailId <= 0)
- return;
-
- var orderDetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
- .FirstAsync(x => x.Id == orderDetailId);
-
- if (orderDetail == null)
- return;
-
- decimal originalAllocated = orderDetail.AllocatedQuantity;
- decimal originalLock = orderDetail.LockQuantity;
-
- // 楠岃瘉鍑忓皯鏁伴噺涓嶄細瀵艰嚧璐熸暟
- if (orderDetail.AllocatedQuantity < reduceQty)
- {
- _logger.LogWarning($"鍒嗛厤鏁伴噺涓嶈冻锛岃皟鏁村噺灏戞暟閲� - 鍘熻鍒掑噺灏�: {reduceQty}, 瀹為檯鍙敤: {orderDetail.AllocatedQuantity}");
- reduceQty = orderDetail.AllocatedQuantity;
- }
-
- // 鍑忓皯鍒嗛厤鏁伴噺鍜岄攣瀹氭暟閲�
- orderDetail.AllocatedQuantity -= reduceQty;
- orderDetail.LockQuantity -= reduceQty;
-
- // 纭繚鏁伴噺涓嶄細涓鸿礋鏁�
- if (orderDetail.AllocatedQuantity < 0)
- {
- _logger.LogWarning($"鍒嗛厤鏁伴噺鍑虹幇璐熸暟锛岄噸缃负0銆傚師鍊�: {orderDetail.AllocatedQuantity + reduceQty}, 鍑忓皯: {reduceQty}");
- orderDetail.AllocatedQuantity = 0;
- }
-
- if (orderDetail.LockQuantity < 0)
- {
- _logger.LogWarning($"閿佸畾鏁伴噺鍑虹幇璐熸暟锛岄噸缃负0銆傚師鍊�: {orderDetail.LockQuantity + reduceQty}, 鍑忓皯: {reduceQty}");
- orderDetail.LockQuantity = 0;
- }
-
- // 鏇存柊鎵规鍒嗛厤鐘舵��
- await UpdateBatchAllocateStatus(orderDetail);
-
- await _outboundOrderDetailService.Db.Updateable(orderDetail).ExecuteCommandAsync();
-
- _logger.LogInformation($"鍑忓皯璁㈠崟鏄庣粏鍒嗛厤 - OrderDetailId: {orderDetail.Id}, " +
- $"鍒嗛厤鏁伴噺: {originalAllocated} -> {orderDetail.AllocatedQuantity}, " +
- $"閿佸畾鏁伴噺: {originalLock} -> {orderDetail.LockQuantity}, " +
- $"鍑忓皯鏁伴噺: {reduceQty}");
- }
-
- /// <summary>
- /// 澶勭悊鏈垎閰嶇殑閿佸畾璁板綍鍥炲簱 - 淇鐗�
- /// 娉ㄦ剰锛氭湭鍒嗛厤閿佸畾璁板綍娌℃湁缁戝畾璁㈠崟鏄庣粏锛屼笉闇�瑕佸噺灏戣鍗曟槑缁嗙殑鍒嗛厤鏁伴噺
- /// </summary>
- private async Task HandleUnallocatedLocksReturn(List<Dt_OutStockLockInfo> unallocatedLocks)
- {
- _logger.LogInformation($"寮�濮嬪鐞嗘湭鍒嗛厤閿佸畾璁板綍鍥炲簱 - 鍏� {unallocatedLocks.Count} 鏉¤褰�");
-
- foreach (var lockInfo in unallocatedLocks)
- {
- // 璁$畻鍥炲簱鏁伴噺锛堟湭鎷i�夌殑閮ㄥ垎锛�
- decimal returnQty = lockInfo.AssignQuantity - lockInfo.PickedQty;
-
- if (returnQty <= 0)
- {
- _logger.LogInformation($"璺宠繃鏈垎閰嶉攣瀹氳褰� - 閿佸畾ID: {lockInfo.Id}, 宸叉嫞閫夊畬鎴愭垨鏃犻渶鍥炲簱");
- continue;
- }
-
- _logger.LogInformation($"澶勭悊鏈垎閰嶉攣瀹氳褰曞洖搴� - 閿佸畾ID: {lockInfo.Id}, 鏉$爜: {lockInfo.CurrentBarcode}, 鍥炲簱鏁伴噺: {returnQty}");
-
- // 鎭㈠搴撳瓨鐘舵��
- var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
- .FirstAsync(x => x.Barcode == lockInfo.CurrentBarcode && x.StockId == lockInfo.StockId);
-
- if (stockDetail != null)
- {
- // 銆愪慨姝c�戞仮澶嶅簱瀛樻暟閲忥紝鍑哄簱鏁伴噺淇濇寔涓嶅彉锛堝洜涓烘湭鍒嗛厤閿佸畾鐨勫嚭搴撴暟閲忔湰鏉ュ氨鏄�0锛�
- decimal originalStockQty = stockDetail.StockQuantity;
- stockDetail.StockQuantity += returnQty;
-
- // 鍑哄簱鏁伴噺淇濇寔涓�0涓嶅彉锛�
- // stockDetail.OutboundQuantity = stockDetail.OutboundQuantity; // 淇濇寔涓嶅彉
-
- // 鎭㈠搴撳瓨鐘舵�佷负鍙敤鐘舵��
- if (stockDetail.Status == (int)StockStatusEmun.鍑哄簱閿佸畾)
- {
- stockDetail.Status = (int)StockStatusEmun.鍏ュ簱瀹屾垚;
- }
-
- await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync();
- _logger.LogInformation($"鎭㈠鏈垎閰嶅簱瀛� - 鏉$爜: {stockDetail.Barcode}, 搴撳瓨鏁伴噺: {originalStockQty} -> {stockDetail.StockQuantity}");
- }
-
- // 鏇存柊閿佸畾璁板綍鐘舵�佷负宸插洖搴�
- lockInfo.Status = (int)OutLockStockStatusEnum.宸插洖搴�;
- lockInfo.Operator = App.User.UserName;
-
- await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync();
-
- _logger.LogInformation($"鏇存柊鏈垎閰嶉攣瀹氱姸鎬� - 閿佸畾ID: {lockInfo.Id}, 鐘舵��: 鍑哄簱涓� -> 宸插洖搴�");
- }
-
- _logger.LogInformation($"鏈垎閰嶉攣瀹氳褰曞洖搴撳鐞嗗畬鎴� - 鍏卞鐞� {unallocatedLocks.Count} 鏉¤褰�");
- }
-
- private async Task HandleAllocatedLocksReturn(List<Dt_OutStockLockInfo> allocatedLocks)
- {
- _logger.LogInformation($"寮�濮嬪鐞嗗凡鍒嗛厤閿佸畾璁板綍鍥炲簱 - 鍏� {allocatedLocks.Count} 鏉¤褰�");
-
- // 鎸夎鍗曟槑缁嗗垎缁勫鐞�
- var orderDetailGroups = allocatedLocks.GroupBy(x => x.OrderDetailId);
-
- foreach (var group in orderDetailGroups)
- {
- var orderDetailId = group.Key;
- var groupLocks = group.ToList();
-
- _logger.LogInformation($"澶勭悊璁㈠崟鏄庣粏 {orderDetailId} 鐨� {groupLocks.Count} 鏉¢攣瀹氳褰�");
-
- // 鑾峰彇璁㈠崟鏄庣粏
- var orderDetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
- .FirstAsync(x => x.Id == orderDetailId);
-
- if (orderDetail == null)
- {
- _logger.LogWarning($"鏈壘鍒拌鍗曟槑缁� - OrderDetailId: {orderDetailId}");
- continue;
- }
-
- decimal totalReturnQtyForDetail = 0;
-
- foreach (var lockInfo in groupLocks)
- {
- // 璁$畻鍥炲簱鏁伴噺锛堟湭鎷i�夌殑閮ㄥ垎锛�
- decimal returnQty = lockInfo.AssignQuantity - lockInfo.PickedQty;
-
- if (returnQty <= 0)
- {
- _logger.LogInformation($"璺宠繃閿佸畾璁板綍 - 閿佸畾ID: {lockInfo.Id}, 宸叉嫞閫夊畬鎴愭垨鏃犻渶鍥炲簱");
- continue;
- }
-
- _logger.LogInformation($"澶勭悊宸插垎閰嶉攣瀹氳褰曞洖搴� - 閿佸畾ID: {lockInfo.Id}, 鏉$爜: {lockInfo.CurrentBarcode}, 鍥炲簱鏁伴噺: {returnQty}");
-
- // 鎭㈠搴撳瓨鐘舵��
- await RestoreStockForLockInfo(lockInfo, returnQty);
-
- // 鏇存柊閿佸畾璁板綍鐘舵�佷负宸插洖搴�
- lockInfo.Status = (int)OutLockStockStatusEnum.宸插洖搴�;
- lockInfo.Operator = App.User.UserName;
-
- await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync();
-
- _logger.LogInformation($"鏇存柊宸插垎閰嶉攣瀹氱姸鎬� - 閿佸畾ID: {lockInfo.Id}, 鐘舵��: 鍑哄簱涓� -> 宸插洖搴�");
-
- totalReturnQtyForDetail += returnQty;
- }
-
- // 鍑忓皯璁㈠崟鏄庣粏鐨勫垎閰嶆暟閲�
- if (totalReturnQtyForDetail > 0)
- {
- await ReduceOrderDetailAllocation(orderDetail, totalReturnQtyForDetail);
- }
- }
-
- _logger.LogInformation($"宸插垎閰嶉攣瀹氳褰曞洖搴撳鐞嗗畬鎴� - 鍏卞鐞� {allocatedLocks.Count} 鏉¤褰�");
- }
- /// <summary>
- /// 鎭㈠閿佸畾璁板綍瀵瑰簲鐨勫簱瀛�
- /// </summary>
- private async Task RestoreStockForLockInfo(Dt_OutStockLockInfo lockInfo, decimal returnQty)
- {
- var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
- .FirstAsync(x => x.Barcode == lockInfo.CurrentBarcode && x.StockId == lockInfo.StockId);
-
- if (stockDetail != null)
- {
- // 璁板綍鎭㈠鍓嶇殑搴撳瓨鐘舵��
- decimal originalStockQty = stockDetail.StockQuantity;
- decimal originalOutboundQty = stockDetail.OutboundQuantity;
-
- // 鎭㈠搴撳瓨鏁伴噺锛氬嚭搴撴暟閲忓噺灏戯紝搴撳瓨鏁伴噺澧炲姞
- stockDetail.OutboundQuantity -= returnQty;
- stockDetail.StockQuantity += returnQty;
-
- // 纭繚鏁伴噺涓嶄細涓鸿礋鏁�
- if (stockDetail.OutboundQuantity < 0)
- {
- _logger.LogWarning($"鍑哄簱鏁伴噺鍑虹幇璐熸暟锛岄噸缃负0銆傚師鍊�: {stockDetail.OutboundQuantity + returnQty}");
- stockDetail.OutboundQuantity = 0;
- }
-
- // 鎭㈠搴撳瓨鐘舵�佷负鍙敤鐘舵��
- if (stockDetail.Status == (int)StockStatusEmun.鍑哄簱閿佸畾)
- {
- stockDetail.Status = (int)StockStatusEmun.鍏ュ簱瀹屾垚;
- _logger.LogInformation($"搴撳瓨鐘舵�佹洿鏂颁负鍏ュ簱瀹屾垚 - 鏉$爜: {stockDetail.Barcode}");
- }
-
- await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync();
-
- _logger.LogInformation($"鎭㈠搴撳瓨鐘舵�� - 鏉$爜: {stockDetail.Barcode}, " +
- $"搴撳瓨鏁伴噺: {originalStockQty} -> {stockDetail.StockQuantity}, " +
- $"鍑哄簱鏁伴噺: {originalOutboundQty} -> {stockDetail.OutboundQuantity}");
- }
- else
- {
- _logger.LogWarning($"鏈壘鍒板搴旂殑搴撳瓨淇℃伅 - 鏉$爜: {lockInfo.CurrentBarcode}, StockId: {lockInfo.StockId}");
- }
- }
- /// <summary>
/// 鍒涘缓鍥炲簱浠诲姟
/// </summary>
private async Task CreateReturnTask(string orderNo, string palletCode, Dt_StockInfo stockInfo)
@@ -3691,6 +2627,7 @@
_logger.LogInformation($"鍒涘缓鍥炲簱浠诲姟鎴愬姛 - 璁㈠崟: {orderNo}, 鎵樼洏: {palletCode}");
}
}
+
/// <summary>
/// 鏇存柊鍥炲簱鍚庣殑璁㈠崟鐘舵��
/// </summary>
@@ -3730,6 +2667,12 @@
// 娓呯悊闆跺簱瀛樻暟鎹�
await CleanupZeroStockData(stockInfo.Id);
+ // 鑾峰彇褰撳墠浠诲姟
+ var currentTask = await GetCurrentTask(orderNo, palletCode);
+ if (currentTask == null)
+ {
+ return WebResponseContent.Instance.Error("鏈壘鍒板綋鍓嶄换鍔�");
+ }
// 鍒涘缓绌烘墭鐩樺簱瀛樿褰�
var emptyStockInfo = new Dt_StockInfo()
{
@@ -3741,8 +2684,8 @@
emptyStockInfo.Details = new List<Dt_StockInfoDetail>();
_stockInfoService.AddMaterielGroup(emptyStockInfo);
- // 鍒涘缓绌烘墭鐩樺洖搴撲换鍔�
- await CreateReturnTask(orderNo, palletCode, emptyStockInfo);
+ // 鍒涘缓鍥炲簱浠诲姟锛堜笉鍙戦�丒SS鍛戒护锛�
+ var returnTaskInfo = await CreateEmptyPalletReturnTask(orderNo, palletCode, emptyStockInfo, currentTask);
return WebResponseContent.Instance.OK("绌烘墭鐩樺洖搴撴垚鍔�");
}
@@ -3752,10 +2695,79 @@
return WebResponseContent.Instance.Error($"绌烘墭鐩樺洖搴撳け璐�: {ex.Message}");
}
}
- /// <summary>
- /// 鍒嗘瀽鎵樼洏鐘舵�佺敤浜庡洖搴�
- /// 纭繚涓嶄細閿欒璇嗗埆闇�瑕佸洖搴撶殑鐗╁搧
+
+ private async Task<Dt_Task> GetCurrentTask(string orderNo, string palletCode)
+ {
+ // 鍏堝皾璇曢�氳繃璁㈠崟鍙峰拰鎵樼洏鍙锋煡鎵句换鍔�
+ var task = await _taskRepository.Db.Queryable<Dt_Task>()
+ .Where(x => x.OrderNo == orderNo && x.PalletCode == palletCode)
+ .FirstAsync();
+
+ if (task == null)
+ {
+ // 濡傛灉鎵句笉鍒帮紝鍐嶉�氳繃鎵樼洏鍙锋煡鎵�
+ task = await _taskRepository.Db.Queryable<Dt_Task>()
+ .Where(x => x.PalletCode == palletCode)
+ .FirstAsync();
+ }
+
+ return task;
+ }
+
+ // <summary>
+ /// 鍒涘缓绌烘墭鐩樺洖搴撲换鍔★紙涓嶅彂閫丒SS鍛戒护锛�
/// </summary>
+ private async Task<ReturnTaskInfo> CreateEmptyPalletReturnTask(string orderNo, string palletCode, Dt_StockInfo emptyStockInfo, Dt_Task currentTask)
+ {
+ try
+ {
+ // 鍒嗛厤鏂拌揣浣�
+ var newLocation = _locationInfoService.AssignLocation(emptyStockInfo.LocationType);
+
+ var returnTask = new Dt_Task()
+ {
+ CurrentAddress = stations[currentTask.TargetAddress],
+ Grade = 0,
+ PalletCode = palletCode,
+ NextAddress = "",
+ OrderNo = orderNo,
+ Roadway = newLocation.RoadwayNo,
+ SourceAddress = stations[currentTask.TargetAddress],
+ TargetAddress = newLocation.LocationCode,
+ TaskStatus = TaskStatusEnum.New.ObjToInt(),
+ TaskType = TaskTypeEnum.InEmpty.ObjToInt(),
+ PalletType = PalletTypeEnum.Empty.ObjToInt(),
+ WarehouseId = currentTask.WarehouseId
+ };
+
+ await _taskRepository.Db.Insertable(returnTask).ExecuteCommandAsync();
+
+ _logger.LogInformation($"鍒涘缓绌烘墭鐩樺洖搴撲换鍔℃垚鍔�: {returnTask.TaskNum}");
+
+ // 鍒犻櫎鍘熷鍑哄簱浠诲姟
+ var result = _task_HtyService.DeleteAndMoveIntoHty(currentTask, OperateTypeEnum.浜哄伐鍒犻櫎);
+ await _taskRepository.Db.Deleteable(currentTask).ExecuteCommandAsync();
+
+ if (!result)
+ {
+ await _taskRepository.Db.Deleteable(currentTask).ExecuteCommandAsync();
+ }
+
+ // 杩斿洖浠诲姟淇℃伅
+ return new ReturnTaskInfo
+ {
+ ShouldSendESS = true,
+ PalletCode = palletCode,
+ OriginalTaskTargetAddress = currentTask.TargetAddress,
+ ReturnTask = returnTask
+ };
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError($"鍒涘缓绌烘墭鐩樺洖搴撲换鍔″け璐�: {ex.Message}");
+ throw;
+ }
+ }
/// <summary>
/// 鍒嗘瀽鎵樼洏鐘舵�佺敤浜庡洖搴� - 淇鐗堬紙瑙e喅鎷嗗寘璁板綍閲嶅璁$畻闂锛�
@@ -3775,14 +2787,14 @@
try
{
- // 1. 棣栧厛鑾峰彇鎵樼洏涓婃墍鏈夌殑搴撳瓨鏄庣粏锛堝熀纭�鏁版嵁锛�
+ // 棣栧厛鑾峰彇鎵樼洏涓婃墍鏈夌殑搴撳瓨鏄庣粏锛堝熀纭�鏁版嵁锛�
var allStockDetails = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
.Where(x => x.StockId == stockId && x.StockQuantity > 0)
.ToListAsync();
_logger.LogInformation($"鎵惧埌 {allStockDetails.Count} 涓湁搴撳瓨鐨勬槑缁嗚褰�");
- // 2. 鍒嗘瀽鎵�鏈夐攣瀹氳褰曪紙宸插垎閰嶅拰鏈垎閰嶏級
+ // 鍒嗘瀽鎵�鏈夐攣瀹氳褰曪紙宸插垎閰嶅拰鏈垎閰嶏級
var allLockInfos = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
.Where(x => x.OrderNo == orderNo && x.PalletCode == palletCode)
.ToListAsync();
@@ -3804,7 +2816,7 @@
result.HasRemainingLocks = true;
result.RemainingLocks = allocatedLocks;
- // 銆愪慨澶嶃�戝浜庡凡鍒嗛厤閿佸畾璁板綍锛屽洖搴撴暟閲忔槸鏈嫞閫夌殑閮ㄥ垎
+ // 瀵逛簬宸插垎閰嶉攣瀹氳褰曪紝鍥炲簱鏁伴噺鏄湭鎷i�夌殑閮ㄥ垎
result.RemainingLocksReturnQty = allocatedLocks.Sum(x =>
{
var returnQty = x.AssignQuantity - x.PickedQty;
@@ -3828,7 +2840,7 @@
result.HasUnallocatedLocks = true;
result.UnallocatedLocks = unallocatedLocks;
- // 銆愪慨澶嶃�戝浜庢湭鍒嗛厤閿佸畾璁板綍锛屽洖搴撴暟閲忔槸瀹冪殑鍒嗛厤鏁伴噺锛堝洜涓烘湭鎷i�夎繃锛�
+ // 瀵逛簬鏈垎閰嶉攣瀹氳褰曪紝鍥炲簱鏁伴噺鏄畠鐨勫垎閰嶆暟閲忥紙鍥犱负鏈嫞閫夎繃锛�
// 浣嗗疄闄呬笂锛屽簱瀛樻湰鏉ュ氨瀛樺湪锛屽彧鏄姸鎬侀渶瑕佹仮澶�
result.UnallocatedLocksReturnQty = unallocatedLocks.Sum(x => x.AssignQuantity);
@@ -3844,7 +2856,7 @@
_logger.LogInformation($"鍙戠幇 {unallocatedLocks.Count} 鏉℃湭鍒嗛厤閿佸畾璁板綍锛屽洖搴撴暟閲忥紙鐘舵�佹仮澶嶏級: {result.UnallocatedLocksReturnQty}");
}
- // 3. 銆愰噸瑕佷慨澶嶃�戦噸鏂拌绠楁�诲洖搴撴暟閲�
+ // 閲嶆柊璁$畻鎬诲洖搴撴暟閲�
// 瀵逛簬宸插垎閰嶉攣瀹氾細鍥炲簱鏁伴噺 = 鏈嫞閫夋暟閲�
// 瀵逛簬鏈垎閰嶉攣瀹氾細娌℃湁瀹為檯鐨勫簱瀛樻暟閲忓彉鍖栵紝鍙槸鐘舵�佹仮澶�
result.TotalReturnQty = result.RemainingLocksReturnQty; // 鍙绠楀凡鍒嗛厤閿佸畾鐨勫洖搴撴暟閲�
@@ -3868,358 +2880,8 @@
_logger.LogError($"鍥炲簱鍒嗘瀽澶辫触 - 璁㈠崟: {orderNo}, 鎵樼洏: {palletCode}, Error: {ex.Message}");
throw;
}
- }
-
-
- /// <summary>
- /// 楠岃瘉娌℃湁閲嶅鏉$爜
- /// </summary>
- private async Task ValidateNoDuplicateBarcodes(PalletStatusAnalysis analysis, List<Dt_StockInfoDetail> allStockDetails)
- {
- try
- {
- // 妫�鏌llBarcodes涓槸鍚︽湁閲嶅
- var duplicateBarcodes = analysis.AllBarcodes
- .GroupBy(b => b)
- .Where(g => g.Count() > 1)
- .Select(g => g.Key)
- .ToList();
-
- if (duplicateBarcodes.Any())
- {
- _logger.LogError($"鍙戠幇閲嶅鏉$爜: {string.Join(", ", duplicateBarcodes)}");
-
- // 鑷姩鍘婚噸
- analysis.AllBarcodes = analysis.AllBarcodes.Distinct().ToList();
- _logger.LogWarning($"宸茶嚜鍔ㄥ幓閲嶏紝鏉$爜鏁�: {analysis.AllBarcodes.Count}");
- }
-
- // 妫�鏌ユ瘡涓潯鐮佺殑瀹為檯搴撳瓨
- decimal totalStockFromBarcodes = 0;
- foreach (var barcode in analysis.AllBarcodes)
- {
- var stock = allStockDetails.FirstOrDefault(x => x.Barcode == barcode);
- if (stock != null)
- {
- totalStockFromBarcodes += stock.StockQuantity;
- _logger.LogInformation($"鏉$爜搴撳瓨 - {barcode}: {stock.StockQuantity}");
- }
- }
-
- _logger.LogInformation($"鍥炲簱鍒嗘瀽鎬诲簱瀛�: {analysis.TotalReturnQty}, 鏉$爜瀹為檯鎬诲簱瀛�: {totalStockFromBarcodes}");
-
- // 濡傛灉鍒嗘瀽鐨勬暟閲忓ぇ浜庡疄闄呭簱瀛橈紝璇存槑鏈夐噸澶嶈绠�
- if (analysis.TotalReturnQty > totalStockFromBarcodes * 1.1m) // 鍏佽10%鐨勮宸�
- {
- _logger.LogError($"鍥炲簱鏁伴噺({analysis.TotalReturnQty})鏄庢樉澶т簬瀹為檯搴撳瓨({totalStockFromBarcodes})锛屽彲鑳藉瓨鍦ㄩ噸澶嶈绠楋紒");
- }
- }
- catch (Exception ex)
- {
- _logger.LogError($"楠岃瘉閲嶅鏉$爜澶辫触: {ex.Message}");
- }
- }
-
-
- /// <summary>
- /// 楠岃瘉鍒嗘瀽缁撴灉锛岀‘淇濇暟鎹竴鑷存��
- /// </summary>
- private async Task ValidateAnalysisResults(PalletStatusAnalysis analysis, int stockId)
- {
- _logger.LogInformation($"寮�濮嬮獙璇佸垎鏋愮粨鏋� - 璁㈠崟: {analysis.OrderNo}, 鎵樼洏: {analysis.PalletCode}");
-
- try
- {
- // 1. 楠岃瘉閿佸畾璁板綍鍜屽簱瀛樻槑缁嗙殑鍖归厤
- foreach (var lockInfo in analysis.RemainingLocks.Concat(analysis.UnallocatedLocks))
- {
- if (!string.IsNullOrEmpty(lockInfo.CurrentBarcode))
- {
- var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
- .FirstAsync(x => x.Barcode == lockInfo.CurrentBarcode && x.StockId == lockInfo.StockId);
-
- if (stockDetail == null)
- {
- _logger.LogWarning($"閿佸畾璁板綍 {lockInfo.Id} 鐨勬潯鐮� {lockInfo.CurrentBarcode} 鍦ㄥ簱瀛樻槑缁嗕腑涓嶅瓨鍦�");
- }
- else if (stockDetail.StockQuantity <= 0)
- {
- _logger.LogWarning($"閿佸畾璁板綍 {lockInfo.Id} 鐨勬潯鐮� {lockInfo.CurrentBarcode} 搴撳瓨鏁伴噺涓�0鎴栬礋鏁�");
- }
- }
- }
-
- // 2. 楠岃瘉鎬诲洖搴撴暟閲忕殑鍚堢悊鎬�
- // 鑾峰彇鎵樼洏涓婄殑鎬诲簱瀛樻暟閲�
- var totalStockOnPallet = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
- .Where(x => x.StockId == stockId)
- .SumAsync(x => x.StockQuantity);
-
- if (analysis.TotalReturnQty > totalStockOnPallet)
- {
- _logger.LogWarning($"鎬诲洖搴撴暟閲� {analysis.TotalReturnQty} 澶т簬鎵樼洏鎬诲簱瀛� {totalStockOnPallet}锛屽彲鑳藉瓨鍦ㄨ绠楅敊璇�");
- }
-
- // 3. 楠岃瘉鏉$爜鐨勫敮涓�鎬�
- var duplicateBarcodes = analysis.AllBarcodes
- .GroupBy(x => x)
- .Where(g => g.Count() > 1)
- .Select(g => g.Key)
- .ToList();
-
- if (duplicateBarcodes.Any())
- {
- _logger.LogWarning($"鍙戠幇閲嶅鐨勬潯鐮�: {string.Join(", ", duplicateBarcodes)}");
- }
-
- _logger.LogInformation($"鍒嗘瀽缁撴灉楠岃瘉瀹屾垚");
- }
- catch (Exception ex)
- {
- _logger.LogError($"鍒嗘瀽缁撴灉楠岃瘉澶辫触 - Error: {ex.Message}");
- // 涓嶆姏鍑哄紓甯革紝鍙褰曢敊璇�
- }
- }
-
- /// <summary>
- /// 澶勭悊鏈垎鎷g殑閿佸畾璁板綍鍥炲簱
- /// 纭繚涓嶄細閿欒缁戝畾鏉$爜鏁伴噺鍒伴攣瀹氭暟閲�
- /// </summary>
- private async Task HandleRemainingLocksReturn(List<Dt_OutStockLockInfo> remainingLocks)
- {
- _logger.LogInformation($"寮�濮嬪鐞嗘湭鍒嗘嫞閿佸畾璁板綍鍥炲簱 - 鍏� {remainingLocks.Count} 鏉¤褰�");
-
- // 鎸夎鍗曟槑缁嗗垎缁勫鐞嗭紝纭繚璁㈠崟鏄庣粏鏁版嵁鐨勪竴鑷存��
- var orderDetailGroups = remainingLocks.GroupBy(x => x.OrderDetailId);
-
- foreach (var group in orderDetailGroups)
- {
- var orderDetailId = group.Key;
- var groupLocks = group.ToList();
-
- _logger.LogInformation($"澶勭悊璁㈠崟鏄庣粏 {orderDetailId} 鐨� {groupLocks.Count} 鏉¢攣瀹氳褰�");
-
- // 鑾峰彇璁㈠崟鏄庣粏
- var orderDetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
- .FirstAsync(x => x.Id == orderDetailId);
-
- if (orderDetail == null)
- {
- _logger.LogWarning($"鏈壘鍒拌鍗曟槑缁� - OrderDetailId: {orderDetailId}");
- continue;
- }
-
- decimal totalReturnQtyForDetail = 0;
-
- foreach (var lockInfo in groupLocks)
- {
- // 鍙鐞嗙姸鎬佷负鍑哄簱涓殑閿佸畾璁板綍
- if (lockInfo.Status != (int)OutLockStockStatusEnum.鍑哄簱涓�)
- {
- _logger.LogInformation($"璺宠繃闈炲嚭搴撲腑鐘舵�佺殑閿佸畾璁板綍 - 閿佸畾ID: {lockInfo.Id}, 鐘舵��: {lockInfo.Status}");
- continue;
- }
-
- // 璁$畻鍥炲簱鏁伴噺锛堟湭鎷i�夌殑閮ㄥ垎锛�
- decimal returnQty = lockInfo.AssignQuantity - lockInfo.PickedQty;
-
- if (returnQty <= 0)
- {
- _logger.LogInformation($"璺宠繃閿佸畾璁板綍 - 閿佸畾ID: {lockInfo.Id}, 宸叉嫞閫夊畬鎴愭垨鏃犻渶鍥炲簱");
- continue;
- }
-
- _logger.LogInformation($"澶勭悊閿佸畾璁板綍鍥炲簱 - 閿佸畾ID: {lockInfo.Id}, 鏉$爜: {lockInfo.CurrentBarcode}, 鍥炲簱鏁伴噺: {returnQty}");
-
- // 鎭㈠搴撳瓨鐘舵��
- var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
- .FirstAsync(x => x.Barcode == lockInfo.CurrentBarcode && x.StockId == lockInfo.StockId);
-
- if (stockDetail != null)
- {
- // 璁板綍鎭㈠鍓嶇殑搴撳瓨鐘舵��
- decimal originalStockQty = stockDetail.StockQuantity;
- decimal originalOutboundQty = stockDetail.OutboundQuantity;
-
- // 鍙仮澶嶅疄闄呯殑搴撳瓨鏁伴噺锛屼笉鍒涘缓鏂扮殑鏉$爜鎴栫粦瀹�
- // 鎭㈠搴撳瓨鏁伴噺锛氬嚭搴撴暟閲忓噺灏戯紝搴撳瓨鏁伴噺澧炲姞
- stockDetail.OutboundQuantity -= returnQty;
- stockDetail.StockQuantity += returnQty;
-
- // 纭繚鏁伴噺涓嶄細涓鸿礋鏁�
- if (stockDetail.OutboundQuantity < 0)
- {
- _logger.LogWarning($"鍑哄簱鏁伴噺鍑虹幇璐熸暟锛岄噸缃负0銆傚師鍊�: {stockDetail.OutboundQuantity + returnQty}");
- stockDetail.OutboundQuantity = 0;
- }
-
- // 鎭㈠搴撳瓨鐘舵�佷负鍙敤鐘舵��
- if (stockDetail.Status == (int)StockStatusEmun.鍑哄簱閿佸畾)
- {
- stockDetail.Status = (int)StockStatusEmun.鍏ュ簱瀹屾垚;
- _logger.LogInformation($"搴撳瓨鐘舵�佹洿鏂颁负鍏ュ簱瀹屾垚 - 鏉$爜: {stockDetail.Barcode}");
- }
-
- await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync();
-
- _logger.LogInformation($"鎭㈠搴撳瓨鐘舵�� - 鏉$爜: {stockDetail.Barcode}, " +
- $"搴撳瓨鏁伴噺: {originalStockQty} -> {stockDetail.StockQuantity}, " +
- $"鍑哄簱鏁伴噺: {originalOutboundQty} -> {stockDetail.OutboundQuantity}");
- }
- else
- {
- _logger.LogWarning($"鏈壘鍒板搴旂殑搴撳瓨淇℃伅 - 鏉$爜: {lockInfo.CurrentBarcode}, StockId: {lockInfo.StockId}");
- // 閲嶈锛氬鏋滄壘涓嶅埌搴撳瓨淇℃伅锛岃烦杩囨閿佸畾璁板綍锛岄伩鍏嶆暟鎹笉涓�鑷�
- continue;
- }
-
- // 鏇存柊閿佸畾璁板綍鐘舵�佷负宸插洖搴擄紝浣嗕笉淇敼鍒嗛厤鏁伴噺
- // 鍒嗛厤鏁伴噺鍦ㄨ鍗曟槑缁嗗眰闈㈢粺涓�澶勭悊
- var originalStatus = lockInfo.Status;
- lockInfo.Status = (int)OutLockStockStatusEnum.宸插洖搴�;
- lockInfo.Operator = App.User.UserName;
-
- await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync();
-
- _logger.LogInformation($"鏇存柊閿佸畾鐘舵�� - 閿佸畾ID: {lockInfo.Id}, 鐘舵��: {originalStatus} -> {lockInfo.Status}");
-
- totalReturnQtyForDetail += returnQty;
-
- _logger.LogInformation($"閿佸畾璁板綍鍥炲簱瀹屾垚 - 閿佸畾ID: {lockInfo.Id}, 鍥炲簱鏁伴噺: {returnQty}");
- }
-
- // 鍑忓皯璁㈠崟鏄庣粏鐨勫垎閰嶆暟閲�
- if (totalReturnQtyForDetail > 0)
- {
- await ReduceOrderDetailAllocation(orderDetail, totalReturnQtyForDetail);
- }
- }
-
- _logger.LogInformation($"鏈垎鎷i攣瀹氳褰曞洖搴撳鐞嗗畬鎴� - 鍏卞鐞� {remainingLocks.Count} 鏉¤褰�");
- }
- /// <summary>
- /// 澶勭悊鏈垎閰嶇殑搴撳瓨璐х墿鍥炲簱
- /// 纭繚涓嶄細鍒涘缓鏂扮殑閿佸畾璁板綍
- /// </summary>
- private async Task HandleUnallocatedStockReturn(List<Dt_StockInfoDetail> stockGoods)
- {
- _logger.LogInformation($"寮�濮嬪鐞嗘湭鍒嗛厤搴撳瓨鍥炲簱 - 鍏� {stockGoods.Count} 涓揣鐗�");
-
- foreach (var stockDetail in stockGoods)
- {
- if (stockDetail.StockQuantity <= 0)
- {
- _logger.LogInformation($"璺宠繃闆跺簱瀛樿揣鐗� - 鏉$爜: {stockDetail.Barcode}");
- continue;
- }
-
- _logger.LogInformation($"澶勭悊鏈垎閰嶅簱瀛樺洖搴� - 鏉$爜: {stockDetail.Barcode}, 鏁伴噺: {stockDetail.StockQuantity}");
-
- // 妫�鏌ユ槸鍚﹀凡缁忔湁瀵瑰簲鐨勯攣瀹氳褰�
- var existingLock = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
- .Where(x => x.CurrentBarcode == stockDetail.Barcode &&
- x.Status == (int)OutLockStockStatusEnum.鍑哄簱涓�)
- .FirstAsync();
-
- if (existingLock != null)
- {
- _logger.LogWarning($"搴撳瓨鏉$爜 {stockDetail.Barcode} 宸叉湁閿佸畾璁板綍锛岃烦杩囩洿鎺ュ洖搴撳鐞�");
- continue;
- }
-
- // 璁板綍鎭㈠鍓嶇殑鐘舵��
- var originalStatus = stockDetail.Status;
-
- // 鐩存帴鎭㈠搴撳瓨鐘舵�佷负鍙敤鐘舵�侊紝涓嶅垱寤轰换浣曢攣瀹氳褰�
- stockDetail.Status = (int)StockStatusEmun.鍏ュ簱瀹屾垚;
-
- await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync();
-
- _logger.LogInformation($"鏈垎閰嶅簱瀛樺洖搴撳畬鎴� - 鏉$爜: {stockDetail.Barcode}, 鐘舵��: {originalStatus} -> {stockDetail.Status}");
- }
-
- _logger.LogInformation($"鏈垎閰嶅簱瀛樺洖搴撳鐞嗗畬鎴� - 鍏卞鐞� {stockGoods.Count} 涓揣鐗�");
- }
- /// <summary>
- /// 鍑忓皯璁㈠崟鏄庣粏鐨勫垎閰嶆暟閲�
- /// 纭繚鍒嗛厤鏁伴噺鐨勫噺灏戞槸鍑嗙‘鐨�
- /// </summary>
- private async Task ReduceOrderDetailAllocation(Dt_OutboundOrderDetail orderDetail, decimal reduceQty)
- {
- if (orderDetail == null)
- return;
-
- decimal originalAllocated = orderDetail.AllocatedQuantity;
- decimal originalLock = orderDetail.LockQuantity;
-
- // 楠岃瘉鍑忓皯鏁伴噺涓嶄細瀵艰嚧璐熸暟
- if (orderDetail.AllocatedQuantity < reduceQty)
- {
- _logger.LogWarning($"鍒嗛厤鏁伴噺涓嶈冻锛岃皟鏁村噺灏戞暟閲� - 鍘熻鍒掑噺灏�: {reduceQty}, 瀹為檯鍙敤: {orderDetail.AllocatedQuantity}");
- reduceQty = orderDetail.AllocatedQuantity;
- }
-
- // 鍑忓皯鍒嗛厤鏁伴噺鍜岄攣瀹氭暟閲�
- orderDetail.AllocatedQuantity -= reduceQty;
- orderDetail.LockQuantity -= reduceQty;
-
- // 纭繚鏁伴噺涓嶄細涓鸿礋鏁�
- if (orderDetail.AllocatedQuantity < 0)
- {
- _logger.LogWarning($"鍒嗛厤鏁伴噺鍑虹幇璐熸暟锛岄噸缃负0銆傚師鍊�: {orderDetail.AllocatedQuantity + reduceQty}, 鍑忓皯: {reduceQty}");
- orderDetail.AllocatedQuantity = 0;
- }
-
- if (orderDetail.LockQuantity < 0)
- {
- _logger.LogWarning($"閿佸畾鏁伴噺鍑虹幇璐熸暟锛岄噸缃负0銆傚師鍊�: {orderDetail.LockQuantity + reduceQty}, 鍑忓皯: {reduceQty}");
- orderDetail.LockQuantity = 0;
- }
-
- // 鏇存柊鎵规鍒嗛厤鐘舵��
- await UpdateBatchAllocateStatus(orderDetail);
-
- await _outboundOrderDetailService.Db.Updateable(orderDetail).ExecuteCommandAsync();
-
- _logger.LogInformation($"鍑忓皯璁㈠崟鏄庣粏鍒嗛厤 - OrderDetailId: {orderDetail.Id}, " +
- $"鍒嗛厤鏁伴噺: {originalAllocated} -> {orderDetail.AllocatedQuantity}, " +
- $"閿佸畾鏁伴噺: {originalLock} -> {orderDetail.LockQuantity}, " +
- $"鍑忓皯鏁伴噺: {reduceQty}");
-
- // 楠岃瘉鏁版嵁涓�鑷存��
- await ValidateOrderDetailConsistency(orderDetail.Id);
- }
- /// <summary>
- /// 楠岃瘉璁㈠崟鏄庣粏鏁版嵁涓�鑷存��
- /// </summary>
- private async Task ValidateOrderDetailConsistency(long orderDetailId)
- {
- var orderDetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
- .FirstAsync(x => x.Id == orderDetailId);
-
- if (orderDetail == null)
- return;
-
- // 璁$畻鎵�鏈夌浉鍏抽攣瀹氳褰曠殑鎬诲垎閰嶆暟閲�
- var relatedLocks = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
- .Where(x => x.OrderDetailId == orderDetailId &&
- x.Status != (int)OutLockStockStatusEnum.宸插洖搴�)
- .ToListAsync();
-
- decimal totalLockAssignQty = relatedLocks.Sum(x => x.AssignQuantity);
-
- // 楠岃瘉璁㈠崟鏄庣粏鍒嗛厤鏁伴噺涓庨攣瀹氳褰曟�诲垎閰嶆暟閲忕殑涓�鑷存��
- if (Math.Abs(orderDetail.AllocatedQuantity - totalLockAssignQty) > 0.01m)
- {
- _logger.LogWarning($"鏁版嵁涓嶄竴鑷磋鍛� - OrderDetailId: {orderDetailId}, " +
- $"璁㈠崟鏄庣粏鍒嗛厤鏁伴噺: {orderDetail.AllocatedQuantity}, " +
- $"閿佸畾璁板綍鎬诲垎閰嶆暟閲�: {totalLockAssignQty}");
- }
- else
- {
- _logger.LogInformation($"鏁版嵁涓�鑷存�ч獙璇侀�氳繃 - OrderDetailId: {orderDetailId}");
- }
- }
+ }
+
/// <summary>
/// 鍒嗘壒鍥炲簱 - 璋冪敤缁熶竴鍥炲簱鏂规硶
/// </summary>
@@ -4228,13 +2890,7 @@
return await ExecutePalletReturn(orderNo, palletCode, "鍒嗘壒鍥炲簱");
}
- /// <summary>
- /// 鍓╀綑鍥炲簱 - 璋冪敤缁熶竴鍥炲簱鏂规硶
- /// </summary>
- public async Task<WebResponseContent> ReturnRemaining(string orderNo, string palletCode, string reason)
- {
- return await ExecutePalletReturn(orderNo, palletCode, reason);
- }
+
/// <summary>
/// 鍙栬蛋绌虹 - 淇鐗堬紝姝g‘澶勭悊鏈垎閰嶉攣瀹氳褰�
@@ -4247,7 +2903,7 @@
_unitOfWorkManage.BeginTran();
- // 1. 鍏堝皾璇曟墽琛屽洖搴撴搷浣滐紝纭繚鎵�鏈夌墿鍝侀兘鍥炲簱
+ // 鍏堝皾璇曟墽琛屽洖搴撴搷浣滐紝纭繚鎵�鏈夌墿鍝侀兘鍥炲簱
_logger.LogInformation($"姝ラ1: 鍏堟墽琛屽洖搴撴搷浣�");
var returnResult = await ExecutePalletReturn(orderNo, palletCode, "鍙栬蛋绌虹鍓嶅洖搴�");
@@ -4257,7 +2913,7 @@
_logger.LogWarning($"鍥炲簱鎿嶄綔鍙兘澶辫触鎴栨棤鐗╁搧: {returnResult.Message}");
}
- // 2. 楠岃瘉绌虹鍙栬蛋鏉′欢锛堝繀椤诲叏閮ㄥ畬鎴愭嫞閫夋垨宸插洖搴擄級
+ // 楠岃瘉绌虹鍙栬蛋鏉′欢锛堝繀椤诲叏閮ㄥ畬鎴愭嫞閫夋垨宸插洖搴擄級
_logger.LogInformation($"姝ラ2: 楠岃瘉绌虹鍙栬蛋鏉′欢");
// 鑾峰彇鎵樼洏鐨勬墍鏈夐攣瀹氳褰曪紙鍖呮嫭宸插洖搴撳拰宸插彇璧扮殑锛�
@@ -4271,7 +2927,7 @@
return WebResponseContent.Instance.Error("璇ユ墭鐩樻病鏈夐攣瀹氳褰�");
}
- // 銆愪慨姝c�戞鏌ユ槸鍚︽湁鏈畬鎴愮殑閿佸畾璁板綍
+ // 妫�鏌ユ槸鍚︽湁鏈畬鎴愮殑閿佸畾璁板綍
var unfinishedLocks = allLockInfos.Where(x =>
x.Status == (int)OutLockStockStatusEnum.鍑哄簱涓� ||
x.Status == (int)OutLockStockStatusEnum.鍥炲簱涓�).ToList();
@@ -4316,7 +2972,7 @@
_logger.LogInformation($"楠岃瘉閫氳繃锛屾壘鍒� {completedLocks.Count} 鏉″凡瀹屾垚璁板綍");
- // 3. 娓呯悊宸插畬鎴愮殑閿佸畾璁板綍锛堟爣璁颁负宸插彇璧帮級
+ // 娓呯悊宸插畬鎴愮殑閿佸畾璁板綍锛堟爣璁颁负宸插彇璧帮級
_logger.LogInformation($"姝ラ3: 娓呯悊閿佸畾璁板綍");
foreach (var lockInfo in completedLocks)
{
@@ -4330,20 +2986,20 @@
}
}
- // 4. 娓呯悊瀵瑰簲鐨勫簱瀛樿褰曠姸鎬�
+ // 娓呯悊瀵瑰簲鐨勫簱瀛樿褰曠姸鎬�
_logger.LogInformation($"姝ラ4: 娓呯悊搴撳瓨璁板綍");
foreach (var lockInfo in completedLocks)
{
await CleanupStockInfo(lockInfo);
}
- // 5. 鏇存柊鐩稿叧璁㈠崟鐘舵��
+ // 鏇存柊鐩稿叧璁㈠崟鐘舵��
_logger.LogInformation($"姝ラ5: 鏇存柊璁㈠崟鐘舵��");
await UpdateOrderStatusAfterPalletRemoval(orderNo);
- // 6. 璁板綍鎿嶄綔鍘嗗彶
- _logger.LogInformation($"姝ラ6: 璁板綍鎿嶄綔鍘嗗彶");
- await RecordEmptyPalletRemoval(orderNo, palletCode, completedLocks);
+ // 璁板綍鎿嶄綔鍘嗗彶
+ //_logger.LogInformation($"姝ラ6: 璁板綍鎿嶄綔鍘嗗彶");
+ //await RecordEmptyPalletRemoval(orderNo, palletCode, completedLocks);
_unitOfWorkManage.CommitTran();
@@ -4358,687 +3014,16 @@
return WebResponseContent.Instance.Error($"鍙栬蛋绌虹澶辫触锛歿ex.Message}");
}
}
-
-
- /// <summary>
- /// 鏀堕泦闇�瑕佸洖搴撶殑鏉$爜
- /// </summary>
- private async Task<List<string>> CollectReturnBarcodes(PalletStatusAnalysis status)
- {
- var returnBarcodes = new HashSet<string>();
-
- try
- {
- _logger.LogInformation($"寮�濮嬫敹闆嗗洖搴撴潯鐮� - 璁㈠崟: {status.OrderNo}, 鎵樼洏: {status.PalletCode}");
-
- // 1. 鏀堕泦鏈垎鎷i攣瀹氳褰曠殑鏉$爜
- if (status.HasRemainingLocks)
- {
- foreach (var lockInfo in status.RemainingLocks)
- {
- if (!string.IsNullOrEmpty(lockInfo.CurrentBarcode))
- {
- returnBarcodes.Add(lockInfo.CurrentBarcode);
- _logger.LogInformation($"娣诲姞閿佸畾璁板綍鏉$爜: {lockInfo.CurrentBarcode}");
- }
- }
- }
-
- // 2. 鏀堕泦鎵樼洏涓婂簱瀛樿揣鐗╃殑鏉$爜
- if (status.HasPalletStockGoods)
- {
- foreach (var stockDetail in status.PalletStockGoods)
- {
- if (!string.IsNullOrEmpty(stockDetail.Barcode) && stockDetail.StockQuantity > 0)
- {
- returnBarcodes.Add(stockDetail.Barcode);
- _logger.LogInformation($"娣诲姞搴撳瓨璐х墿鏉$爜: {stockDetail.Barcode}, 鏁伴噺: {stockDetail.StockQuantity}");
- }
- }
- }
-
- // 3. 鏀堕泦鎷嗗寘璁板綍鐩稿叧鐨勬潯鐮�
- if (status.HasSplitRecords)
- {
- foreach (var splitRecord in status.SplitRecords)
- {
- // 娣诲姞鍘熸潯鐮�
- if (!string.IsNullOrEmpty(splitRecord.OriginalBarcode))
- {
- var originalStock = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
- .FirstAsync(x => x.Barcode == splitRecord.OriginalBarcode && x.StockId == status.StockId);
-
- if (originalStock != null && originalStock.StockQuantity > 0)
- {
- returnBarcodes.Add(splitRecord.OriginalBarcode);
- _logger.LogInformation($"娣诲姞鎷嗗寘鍘熸潯鐮�: {splitRecord.OriginalBarcode}, 鏁伴噺: {originalStock.StockQuantity}");
- }
- }
-
- // 娣诲姞鏂版潯鐮�
- if (!string.IsNullOrEmpty(splitRecord.NewBarcode))
- {
- var newStock = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
- .FirstAsync(x => x.Barcode == splitRecord.NewBarcode && x.StockId == status.StockId);
-
- if (newStock != null && newStock.StockQuantity > 0)
- {
- returnBarcodes.Add(splitRecord.NewBarcode);
- _logger.LogInformation($"娣诲姞鎷嗗寘鏂版潯鐮�: {splitRecord.NewBarcode}, 鏁伴噺: {newStock.StockQuantity}");
- }
- }
- }
- }
-
- _logger.LogInformation($"鍥炲簱鏉$爜鏀堕泦瀹屾垚 - 鍏� {returnBarcodes.Count} 涓潯鐮�: {string.Join(", ", returnBarcodes)}");
-
- return returnBarcodes.ToList();
- }
- catch (Exception ex)
- {
- _logger.LogError($"鏀堕泦鍥炲簱鏉$爜澶辫触 - Error: {ex.Message}");
- return returnBarcodes.ToList();
- }
- }
+
#endregion
- #region 鍥炲簱鎿嶄綔鏍稿績鏂规硶
-
- /// <summary>
- /// 鎵ц鍥炲簱鎿嶄綔 - 澧炲己鐗堟湰
- /// </summary>
- private async Task ExecuteReturnOperations(string orderNo, string palletCode, Dt_StockInfo stockInfo,
- Dt_Task task, PalletStatusAnalysis statusAnalysis)
- {
- _logger.LogInformation($"寮�濮嬫墽琛屽洖搴撴搷浣� - 璁㈠崟: {orderNo}, 鎵樼洏: {palletCode}");
-
- // 澶勭悊鏈垎鎷g殑閿佸畾璁板綍
- if (statusAnalysis.HasRemainingLocks)
- {
- _logger.LogInformation($"澶勭悊 {statusAnalysis.RemainingLocks.Count} 鏉℃湭鍒嗘嫞閿佸畾璁板綍");
- await HandleRemainingLocksReturn(statusAnalysis.RemainingLocks);
- }
-
- //澶勭悊鎵樼洏涓婄殑搴撳瓨璐х墿
- if (statusAnalysis.HasPalletStockGoods)
- {
- _logger.LogInformation($"澶勭悊 {statusAnalysis.PalletStockGoods.Count} 涓簱瀛樿揣鐗�");
- await HandlePalletStockGoodsReturn(statusAnalysis.PalletStockGoods, stockInfo.Id);
- }
-
- //澶勭悊鎷嗗寘璁板綍
- if (statusAnalysis.HasSplitRecords)
- {
- _logger.LogInformation($"澶勭悊 {statusAnalysis.SplitRecords.Count} 鏉℃媶鍖呰褰�");
- await HandleSplitRecordsReturn(statusAnalysis.SplitRecords, stockInfo.Id);
- }
-
- _logger.LogInformation($"鍥炲簱鎿嶄綔瀹屾垚 - 鎬诲洖搴撴暟閲�: {statusAnalysis.TotalReturnQty}");
- }
-
- /// <summary>
- /// 澶勭悊鏈垎鎷g殑閿佸畾璁板綍鍥炲簱
- /// </summary>
-
-
- /// <summary>
- /// 澶勭悊鎵樼洏涓婄殑搴撳瓨璐х墿鍥炲簱
- /// </summary>
- private async Task HandlePalletStockGoodsReturn(List<Dt_StockInfoDetail> palletStockGoods, int stockId)
- {
- foreach (var stockDetail in palletStockGoods)
- {
- // 鍙鐞嗗嚭搴撻攣瀹氱姸鎬佺殑搴撳瓨
- if (stockDetail.Status == (int)StockStatusEmun.鍑哄簱閿佸畾 && stockDetail.StockQuantity > 0)
- {
- // 鎭㈠搴撳瓨鐘舵�佷负鍙敤鐘舵��
- stockDetail.Status = (int)StockStatusEmun.鍏ュ簱瀹屾垚;
- await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync();
-
- _logger.LogInformation($"鎭㈠搴撳瓨璐х墿 - 鏉$爜: {stockDetail.Barcode}, 鏁伴噺: {stockDetail.StockQuantity}");
- }
- }
- }
-
- /// <summary>
- /// 澶勭悊鎷嗗寘璁板綍鍥炲簱
- /// </summary>
- private async Task HandleSplitRecordsReturn(List<Dt_SplitPackageRecord> splitRecords, int stockId)
- {
- foreach (var splitRecord in splitRecords)
- {
- // 澶勭悊鏂版潯鐮�
- var newLockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
- .Where(x => x.CurrentBarcode == splitRecord.NewBarcode &&
- x.Status == (int)OutLockStockStatusEnum.鍑哄簱涓�)
- .FirstAsync();
-
- if (newLockInfo != null)
- {
- await HandleSingleLockReturn(newLockInfo);
- }
-
- // 澶勭悊鍘熸潯鐮�
- var originalLockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
- .Where(x => x.CurrentBarcode == splitRecord.OriginalBarcode &&
- x.Status == (int)OutLockStockStatusEnum.鍑哄簱涓�)
- .FirstAsync();
-
- if (originalLockInfo != null)
- {
- await HandleSingleLockReturn(originalLockInfo);
- }
-
- // 鏇存柊鎷嗗寘璁板綍鐘舵�佷负宸插洖搴�
- splitRecord.Status = (int)SplitPackageStatusEnum.宸插洖搴�;
- await _splitPackageService.Db.Updateable(splitRecord).ExecuteCommandAsync();
- }
- }
-
- private async Task HandleSingleLockReturn(Dt_OutStockLockInfo lockInfo)
- {
- decimal returnQty = lockInfo.AssignQuantity - lockInfo.PickedQty;
-
- if (returnQty <= 0)
- {
- _logger.LogInformation($"璺宠繃閿佸畾璁板綍 - 閿佸畾ID: {lockInfo.Id}, 宸叉嫞閫夊畬鎴愭垨鏃犻渶鍥炲簱");
- return;
- }
-
- _logger.LogInformation($"澶勭悊鎷嗗寘鐩稿叧閿佸畾璁板綍 - 閿佸畾ID: {lockInfo.Id}, 鏉$爜: {lockInfo.CurrentBarcode}, 鍥炲簱鏁伴噺: {returnQty}");
-
- // 鎭㈠搴撳瓨
- var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
- .FirstAsync(x => x.Barcode == lockInfo.CurrentBarcode && x.StockId == lockInfo.StockId);
-
- if (stockDetail != null)
- {
- decimal originalStockQty = stockDetail.StockQuantity;
- decimal originalOutboundQty = stockDetail.OutboundQuantity;
-
- stockDetail.StockQuantity += returnQty;
- stockDetail.OutboundQuantity -= returnQty;
-
- if (stockDetail.OutboundQuantity < 0)
- {
- stockDetail.OutboundQuantity = 0;
- }
-
- stockDetail.Status = (int)StockStatusEmun.鍏ュ簱瀹屾垚;
- await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync();
-
- _logger.LogInformation($"鎭㈠鎷嗗寘鐩稿叧搴撳瓨 - 鏉$爜: {stockDetail.Barcode}, " +
- $"搴撳瓨鏁伴噺: {originalStockQty} -> {stockDetail.StockQuantity}");
- }
-
- // 鏇存柊閿佸畾鐘舵��
- lockInfo.Status = (int)OutLockStockStatusEnum.宸插洖搴�;
- lockInfo.Operator = App.User.UserName;
- await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync();
-
- // 鍑忓皯璁㈠崟鏄庣粏鐨勫垎閰嶆暟閲�
- if (lockInfo.OrderDetailId > 0)
- {
- var orderDetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
- .FirstAsync(x => x.Id == lockInfo.OrderDetailId);
-
- if (orderDetail != null)
- {
- await ReduceOrderDetailAllocation(orderDetail, returnQty);
- }
- }
-
- _logger.LogInformation($"鎷嗗寘鐩稿叧閿佸畾璁板綍鍥炲簱瀹屾垚 - 閿佸畾ID: {lockInfo.Id}, 鍥炲簱鏁伴噺: {returnQty}");
- }
- /// <summary>
- /// 閲婃斁鎵�鏈夐攣瀹氫互渚块噸鏂板垎閰�
- /// </summary>
- private async Task ReleaseAllLocksForReallocation(string orderNo, string palletCode, PalletStatusAnalysis statusAnalysis)
- {
- // 鏇存柊璁㈠崟鏄庣粏鐨勫凡鍒嗛厤鏁伴噺
- if (statusAnalysis.HasRemainingLocks)
- {
- var orderDetailGroups = statusAnalysis.RemainingLocks.GroupBy(x => x.OrderDetailId);
-
- foreach (var group in orderDetailGroups)
- {
- var orderDetailId = group.Key;
- var returnedQty = group.Sum(x => x.AssignQuantity - x.PickedQty);
-
- var orderDetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
- .FirstAsync(x => x.Id == orderDetailId);
-
- if (orderDetail != null)
- {
- orderDetail.AllocatedQuantity -= returnedQty;
- orderDetail.LockQuantity = orderDetail.AllocatedQuantity;
-
- await UpdateBatchAllocateStatus(orderDetail);
- await _outboundOrderDetailService.Db.Updateable(orderDetail).ExecuteCommandAsync();
-
- _logger.LogInformation($"鏇存柊璁㈠崟鏄庣粏 - OrderDetailId: {orderDetailId}, 鍑忓皯鍒嗛厤鏁伴噺: {returnedQty}");
- }
- }
- }
- }
-
- /// <summary>
- /// 鏀堕泦闇�瑕佸洖搴撶殑鏉$爜锛堥伩鍏嶉噸澶嶏級
- /// </summary>
- private async Task<HashSet<string>> CollectBarcodesForReturn(string orderNo, string palletCode, int stockId)
- {
- var barcodes = new HashSet<string>();
-
- try
- {
- _logger.LogInformation($"寮�濮嬫敹闆嗗洖搴撴潯鐮� - 璁㈠崟: {orderNo}, 鎵樼洏: {palletCode}, StockId: {stockId}");
-
- // 1. 浠庨攣瀹氳褰曟敹闆�
- var lockInfos = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
- .Where(x => x.OrderNo == orderNo &&
- x.PalletCode == palletCode &&
- (x.Status == (int)OutLockStockStatusEnum.鍑哄簱涓�
- // || x.Status == (int)OutLockStockStatusEnum.鍑哄簱閿佸畾)
- ))
- .ToListAsync();
-
- foreach (var lockInfo in lockInfos)
- {
- if (!string.IsNullOrEmpty(lockInfo.CurrentBarcode))
- {
- barcodes.Add(lockInfo.CurrentBarcode);
- _logger.LogInformation($"浠庨攣瀹氳褰曟坊鍔犳潯鐮�: {lockInfo.CurrentBarcode}");
- }
- }
-
- // 2. 浠庡簱瀛樻槑缁嗘敹闆嗭紙鐘舵�佷负鍑哄簱閿佸畾鐨勶級
- var stockDetails = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
- .Where(x => x.StockId == stockId &&
- x.Status == (int)StockStatusEmun.鍑哄簱閿佸畾 &&
- x.StockQuantity > 0)
- .ToListAsync();
-
- foreach (var stockDetail in stockDetails)
- {
- if (!barcodes.Contains(stockDetail.Barcode) && !string.IsNullOrEmpty(stockDetail.Barcode))
- {
- barcodes.Add(stockDetail.Barcode);
- _logger.LogInformation($"浠庡簱瀛樻槑缁嗘坊鍔犳潯鐮�: {stockDetail.Barcode}, 鏁伴噺: {stockDetail.StockQuantity}");
- }
- }
-
- // 3. 浠庢媶鍖呰褰曟敹闆�
- var splitRecords = await _splitPackageService.Db.Queryable<Dt_SplitPackageRecord>()
- .Where(x => x.OrderNo == orderNo &&
- x.PalletCode == palletCode &&
- !x.IsReverted &&
- x.Status != (int)SplitPackageStatusEnum.宸叉嫞閫�)
- .ToListAsync();
-
- foreach (var splitRecord in splitRecords)
- {
- // 娣诲姞鍘熸潯鐮�
- if (!string.IsNullOrEmpty(splitRecord.OriginalBarcode) && !barcodes.Contains(splitRecord.OriginalBarcode))
- {
- barcodes.Add(splitRecord.OriginalBarcode);
- _logger.LogInformation($"浠庢媶鍖呰褰曟坊鍔犲師鏉$爜: {splitRecord.OriginalBarcode}");
- }
-
- // 娣诲姞鏂版潯鐮�
- if (!string.IsNullOrEmpty(splitRecord.NewBarcode) && !barcodes.Contains(splitRecord.NewBarcode))
- {
- barcodes.Add(splitRecord.NewBarcode);
- _logger.LogInformation($"浠庢媶鍖呰褰曟坊鍔犳柊鏉$爜: {splitRecord.NewBarcode}");
- }
- }
-
- _logger.LogInformation($"鏉$爜鏀堕泦瀹屾垚 - 鍏� {barcodes.Count} 涓潯鐮�: {string.Join(", ", barcodes)}");
-
- return barcodes;
- }
- catch (Exception ex)
- {
- _logger.LogError($"鏀堕泦鍥炲簱鏉$爜澶辫触 - Error: {ex.Message}");
- return barcodes;
- }
- }
-
- /// <summary>
- /// 缁熶竴澶勭悊鏉$爜鍥炲簱锛堥伩鍏嶉噸澶嶅鐞嗭級
- /// </summary>
- private async Task ProcessBarcodeReturn(string barcode, int stockId, decimal returnQty, HashSet<string> processedBarcodes)
- {
- if (returnQty <= 0)
- return;
-
- // 妫�鏌ユ槸鍚﹀凡澶勭悊杩�
- if (processedBarcodes.Contains(barcode))
- {
- _logger.LogInformation($"璺宠繃宸插鐞嗙殑鏉$爜: {barcode}");
- return;
- }
-
- // 鑾峰彇搴撳瓨鏄庣粏
- var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
- .FirstAsync(x => x.Barcode == barcode && x.StockId == stockId);
-
- if (stockDetail == null)
- {
- _logger.LogWarning($"鏈壘鍒版潯鐮佸搴旂殑搴撳瓨鏄庣粏: {barcode}");
- return;
- }
-
- // 璁板綍鍘熷鍊�
- decimal originalStockQty = stockDetail.StockQuantity;
- decimal originalOutboundQty = stockDetail.OutboundQuantity;
- int originalStatus = stockDetail.Status;
-
- _logger.LogInformation($"澶勭悊鏉$爜鍥炲簱 - {barcode}: 鍘熷搴撳瓨={originalStockQty}, 鍘熷鍑哄簱={originalOutboundQty}, 鐘舵��={originalStatus}");
-
- // 楠岃瘉鏁版嵁涓�鑷存��
- if (originalOutboundQty < returnQty)
- {
- _logger.LogWarning($"鍑哄簱鏁伴噺灏忎簬鍥炲簱鏁伴噺锛岃皟鏁村洖搴撴暟閲� - 鏉$爜: {barcode}, 鍑哄簱鏁伴噺: {originalOutboundQty}, 鍥炲簱鏁伴噺: {returnQty}");
- returnQty = originalOutboundQty;
- }
-
- // 鏇存柊搴撳瓨锛氬嚭搴撴暟閲忓噺灏戯紝搴撳瓨鏁伴噺澧炲姞
- stockDetail.OutboundQuantity -= returnQty;
- stockDetail.StockQuantity += returnQty;
-
- // 纭繚涓嶄細鍑虹幇璐熸暟
- if (stockDetail.OutboundQuantity < 0)
- {
- _logger.LogWarning($"鍑哄簱鏁伴噺鍑虹幇璐熸暟锛岄噸缃负0 - 鏉$爜: {barcode}");
- stockDetail.OutboundQuantity = 0;
- }
-
- // 鏇存柊鐘舵��
- if (stockDetail.OutboundQuantity <= 0 && stockDetail.StockQuantity > 0)
- {
- stockDetail.Status = (int)StockStatusEmun.鍏ュ簱瀹屾垚;
- _logger.LogInformation($"搴撳瓨鐘舵�佹洿鏂颁负鍏ュ簱瀹屾垚 - 鏉$爜: {barcode}");
- }
- else if (stockDetail.StockQuantity > 0)
- {
- stockDetail.Status = (int)StockStatusEmun.鍑哄簱閿佸畾;
- _logger.LogInformation($"搴撳瓨鐘舵�佷繚鎸佷负鍑哄簱閿佸畾 - 鏉$爜: {barcode}");
- }
-
- await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync();
-
- // 鏍囪涓哄凡澶勭悊
- processedBarcodes.Add(barcode);
-
- _logger.LogInformation($"鏉$爜鍥炲簱瀹屾垚 - {barcode}: " +
- $"搴撳瓨 {originalStockQty} -> {stockDetail.StockQuantity}, " +
- $"鍑哄簱 {originalOutboundQty} -> {stockDetail.OutboundQuantity}, " +
- $"鐘舵�� {originalStatus} -> {stockDetail.Status}");
- }
-
- /// <summary>
- /// 澶勭悊鎷嗗寘璁板綍鍥炲簱 - 閬垮厤閲嶅
- /// </summary>
- private async Task HandleSplitRecordsReturn(List<Dt_SplitPackageRecord> splitRecords, int stockId, HashSet<string> processedBarcodes)
- {
- if (!splitRecords.Any())
- return;
-
- _logger.LogInformation($"寮�濮嬪鐞嗘媶鍖呰褰曞洖搴� - 鍏� {splitRecords.Count} 鏉¤褰�");
-
- foreach (var splitRecord in splitRecords)
- {
- // 鍙鐞嗘湭鎾ら攢鐨勬媶鍖呰褰�
- if (splitRecord.IsReverted)
- {
- _logger.LogInformation($"璺宠繃宸叉挙閿�鐨勬媶鍖呰褰� - ID: {splitRecord.Id}");
- continue;
- }
-
- // 澶勭悊鏂版潯鐮�
- if (!string.IsNullOrEmpty(splitRecord.NewBarcode) && !processedBarcodes.Contains(splitRecord.NewBarcode))
- {
- var newStock = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
- .FirstAsync(x => x.Barcode == splitRecord.NewBarcode && x.StockId == stockId);
-
- if (newStock != null && newStock.StockQuantity > 0)
- {
- // 鎷嗗寘鐨勬柊鏉$爜鍥炲簱鏁伴噺搴旇鏄叾搴撳瓨鏁伴噺
- await ProcessBarcodeReturn(splitRecord.NewBarcode, stockId, newStock.StockQuantity, processedBarcodes);
- }
- }
-
- // 澶勭悊鍘熸潯鐮�
- if (!string.IsNullOrEmpty(splitRecord.OriginalBarcode) && !processedBarcodes.Contains(splitRecord.OriginalBarcode))
- {
- var originalStock = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
- .FirstAsync(x => x.Barcode == splitRecord.OriginalBarcode && x.StockId == stockId);
-
- if (originalStock != null && originalStock.StockQuantity > 0)
- {
- // 鍘熸潯鐮佺殑鍥炲簱鏁伴噺搴旇鏄媶鍖呭悗鍓╀綑鐨勬暟閲�
- await ProcessBarcodeReturn(splitRecord.OriginalBarcode, stockId, originalStock.StockQuantity, processedBarcodes);
- }
- }
-
- // 鏇存柊鎷嗗寘璁板綍鐘舵�佷负宸插洖搴�
- splitRecord.Status = (int)SplitPackageStatusEnum.宸插洖搴�;
- await _splitPackageService.Db.Updateable(splitRecord).ExecuteCommandAsync();
-
- _logger.LogInformation($"鎷嗗寘璁板綍鐘舵�佹洿鏂颁负宸插洖搴� - 璁板綍ID: {splitRecord.Id}");
- }
-
- _logger.LogInformation($"鎷嗗寘璁板綍鍥炲簱澶勭悊瀹屾垚");
- }
-
- /// <summary>
- /// 绠�鍖栫増鍥炲簱鏂规硶 - 缁曡繃澶嶆潅楠岃瘉
- /// </summary>
- public async Task<WebResponseContent> SimplePalletReturn(string orderNo, string palletCode, string returnReason = "绠�鍖栧洖搴�")
- {
- try
- {
- _logger.LogInformation($"銆愮畝鍖栧洖搴撳紑濮嬨�戣鍗�: {orderNo}, 鎵樼洏: {palletCode}");
-
- _unitOfWorkManage.BeginTran();
-
- // 1. 鑾峰彇搴撳瓨淇℃伅锛堣烦杩囧鏉傞獙璇侊級
- var stockInfo = await _stockInfoService.Db.Queryable<Dt_StockInfo>()
- .FirstAsync(x => x.PalletCode == palletCode);
-
- if (stockInfo == null)
- {
- _unitOfWorkManage.RollbackTran();
- return WebResponseContent.Instance.Error($"鏈壘鍒版墭鐩� {palletCode} 瀵瑰簲鐨勫簱瀛樹俊鎭�");
- }
-
- // 2. 鐩存帴鏌ユ壘闇�瑕佸洖搴撶殑鏉$爜锛堢畝鍖栭�昏緫锛�
- var barcodesToReturn = await GetBarcodesForSimpleReturn(orderNo, palletCode, stockInfo.Id);
-
- if (!barcodesToReturn.Any())
- {
- try
- {
- _logger.LogInformation($"銆愭棤鍥炲簱鐗╁搧銆戝鐞嗙┖鎵樼洏");
- var result = await HandleEmptyPalletReturn(orderNo, palletCode, stockInfo);
- _unitOfWorkManage.CommitTran();
- return result;
- }
- catch (Exception ex)
- {
- _unitOfWorkManage.RollbackTran();
- _logger.LogError($"绌虹鍥炲簱澶辫触: {ex.Message}");
- return WebResponseContent.Instance.Error($"绌虹鍥炲簱澶辫触锛歿ex.Message}");
- }
- }
-
- // 3. 绠�鍖栧鐞嗘瘡涓潯鐮�
- foreach (var barcode in barcodesToReturn)
- {
- await ProcessSimpleBarcodeReturn(barcode, stockInfo.Id);
- }
-
- // 4. 鏇存柊璁㈠崟鐘舵�侊紙绠�鍖栵級
- await UpdateOrderStatusAfterReturn(orderNo);
-
-
- // 5. 鍒涘缓鍥炲簱浠诲姟
- await CreateReturnTask(orderNo, palletCode, stockInfo);
-
- _unitOfWorkManage.CommitTran();
- return WebResponseContent.Instance.OK($"绠�鍖栧洖搴撴垚鍔燂紝澶勭悊 {barcodesToReturn.Count} 涓潯鐮�");
- }
- catch (Exception ex)
- {
- _unitOfWorkManage.RollbackTran();
- _logger.LogError($"绠�鍖栧洖搴撳け璐�: {ex.Message}");
- return WebResponseContent.Instance.Error($"鍥炲簱澶辫触: {ex.Message}");
- }
- }
- /// <summary>
- /// 绠�鍖栬幏鍙栧洖搴撴潯鐮�
- /// </summary>
- private async Task<List<string>> GetBarcodesForSimpleReturn(string orderNo, string palletCode, int stockId)
- {
- var barcodes = new List<string>();
-
- try
- {
- // 1. 浠庨攣瀹氳褰曡幏鍙�
- var lockInfos = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
- .Where(x => x.OrderNo == orderNo && x.PalletCode == palletCode)
- .Select(x => x.CurrentBarcode)
- .ToListAsync();
-
- barcodes.AddRange(lockInfos.Where(b => !string.IsNullOrEmpty(b)));
-
- // 2. 浠庡簱瀛樻槑缁嗚幏鍙�
- var stockDetails = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
- .Where(x => x.StockId == stockId && x.StockQuantity > 0)
- .Select(x => x.Barcode)
- .ToListAsync();
-
- barcodes.AddRange(stockDetails.Where(b => !string.IsNullOrEmpty(b)));
-
- // 鍘婚噸
- return barcodes.Distinct().ToList();
- }
- catch (Exception ex)
- {
- _logger.LogError($"鑾峰彇鍥炲簱鏉$爜澶辫触: {ex.Message}");
- return barcodes;
- }
- }
-
- /// <summary>
- /// 绠�鍖栧鐞嗘潯鐮佸洖搴�
- /// </summary>
- private async Task ProcessSimpleBarcodeReturn(string barcode, int stockId)
- {
- try
- {
- // 1. 鑾峰彇搴撳瓨鏄庣粏
- var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
- .FirstAsync(x => x.Barcode == barcode && x.StockId == stockId);
-
- if (stockDetail == null)
- {
- _logger.LogWarning($"鏈壘鍒版潯鐮佸搴旂殑搴撳瓨鏄庣粏: {barcode}");
- return;
- }
-
- // 2. 濡傛灉鏄嚭搴撻攣瀹氱姸鎬侊紝鎭㈠涓哄叆搴撳畬鎴�
- if (stockDetail.Status == (int)StockStatusEmun.鍑哄簱閿佸畾)
- {
- stockDetail.Status = (int)StockStatusEmun.鍏ュ簱瀹屾垚;
- await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync();
- _logger.LogInformation($"鏉$爜鐘舵�佹仮澶� - {barcode}: 鍑哄簱閿佸畾 -> 鍏ュ簱瀹屾垚");
- }
-
- // 3. 鏇存柊鐩稿叧鐨勯攣瀹氳褰�
- var lockInfos = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
- .Where(x => x.CurrentBarcode == barcode &&
- (x.Status == (int)OutLockStockStatusEnum.鍑哄簱涓� ||
- x.Status == (int)OutLockStockStatusEnum.鎷i�夊畬鎴�))
- .ToListAsync();
-
- foreach (var lockInfo in lockInfos)
- {
- lockInfo.Status = (int)OutLockStockStatusEnum.宸插洖搴�;
- lockInfo.Operator = App.User.UserName;
- await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync();
- _logger.LogInformation($"閿佸畾璁板綍鐘舵�佹洿鏂� - ID: {lockInfo.Id}: 宸插洖搴�");
- }
- }
- catch (Exception ex)
- {
- _logger.LogError($"澶勭悊鏉$爜鍥炲簱澶辫触 - 鏉$爜: {barcode}, Error: {ex.Message}");
- }
- }
- #endregion
-
- #region 杈呭姪鏂规硶
-
- /// <summary>
- /// 澶勭悊娌℃湁鍥炲簱鐗╁搧鐨勬儏鍐�
- /// </summary>
- private async Task<WebResponseContent> HandleNoReturnItems(string orderNo, string palletCode, Dt_Task originalTask, int stockId)
- {
- _logger.LogInformation($"鎵樼洏 {palletCode} 娌℃湁闇�瑕佸洖搴撶殑鐗╁搧");
-
- // 妫�鏌ユ槸鍚︽槸绌烘墭鐩�
- var statusAnalysis = await AnalyzePalletStatus(orderNo, palletCode, stockId);
- if (statusAnalysis.IsEmptyPallet)
- {
- try
- {
- var locationtype = 0;
- var stockInfo = await _stockInfoService.Db.Queryable<Dt_StockInfo>()
- .Where(x => x.PalletCode == palletCode)
- .FirstAsync();
-
- if (stockInfo == null)
- {
- var firstLocation = await _locationInfoService.Db.Queryable<Dt_LocationInfo>().FirstAsync(x => x.LocationCode == originalTask.SourceAddress);
- locationtype = firstLocation?.LocationType ?? 1;
- }
- else
- {
- locationtype = stockInfo.LocationType;
- _stockInfoService.DeleteData(stockInfo);
- }
-
- var targetAddress = originalTask.TargetAddress;
-
- await CleanupZeroStockData(stockId);
-
-
- var emptystockInfo = new Dt_StockInfo() { PalletType = PalletTypeEnum.Empty.ObjToInt(), StockStatus = StockStatusEmun.缁勭洏鏆傚瓨.ObjToInt(), PalletCode = palletCode, LocationType = locationtype };
- emptystockInfo.Details = new List<Dt_StockInfoDetail>();
- _stockInfoService.AddMaterielGroup(emptystockInfo);
- //绌烘墭鐩樺浣曞鐞� 杩樻湁涓�涓嚭搴撲换鍔¤澶勭悊銆�
- originalTask.PalletType = PalletTypeEnum.Empty.ObjToInt();
-
- await CreateReturnTaskAndHandleESS(orderNo, palletCode, originalTask, TaskTypeEnum.InEmpty, PalletTypeEnum.Empty.ObjToInt());
-
- }
- catch (Exception ex)
- {
- _logger.LogError($" HandleNoReturnItems 澶辫触: {ex.Message}");
- return WebResponseContent.Instance.Error($" 鍥炲簱绌烘墭鐩樺け璐ワ紒");
- }
- return WebResponseContent.Instance.OK("绌烘墭鐩樺洖搴撲换鍔″垱寤烘垚鍔�");
- }
- else
- {
- return WebResponseContent.Instance.Error("鎵樼洏鐘舵�佸紓甯革細鏈夌墿鍝佷絾鏃犳硶璁$畻鍥炲簱鏁伴噺");
- }
- }
+ #region 杈呭姪鏂规硶
+
private async Task CleanupZeroStockData(int stockId)
{
try
{
- // 1. 鍒犻櫎搴撳瓨鏁伴噺涓�0鐨勬槑缁嗚褰�
+ // 鍒犻櫎搴撳瓨鏁伴噺涓�0鐨勬槑缁嗚褰�
var deleteDetailCount = await _stockInfoDetailService.Db.Deleteable<Dt_StockInfoDetail>()
.Where(x => x.StockId == stockId && x.StockQuantity == 0)
.ExecuteCommandAsync();
@@ -5054,38 +3039,10 @@
catch (Exception ex)
{
_logger.LogWarning($"娓呯悊闆跺簱瀛樻暟鎹け璐� - StockId: {stockId}, Error: {ex.Message}");
- // 娉ㄦ剰锛氭竻鐞嗗け璐ヤ笉搴旇褰卞搷涓绘祦绋�
+
}
}
- /// <summary>
- /// 鏇存柊璁㈠崟鐘舵�侊紙鍥炲簱鍚庯級
- /// </summary>
- private async Task UpdateOrderStatusForReturn(string orderNo)
- {
- // 妫�鏌ヨ鍗曟槸鍚︽墍鏈夋墭鐩橀兘宸插畬鎴愭垨宸插洖搴�
- var allLocks = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
- .Where(x => x.OrderNo == orderNo)
- .ToListAsync();
-
- var activeLocks = allLocks.Where(x =>
- x.Status == (int)OutLockStockStatusEnum.鍑哄簱涓� ||
- x.Status == (int)OutLockStockStatusEnum.鍥炲簱涓�).ToList();
-
- // 濡傛灉娌℃湁娲昏穬鐨勯攣瀹氳褰曪紝鏇存柊璁㈠崟鐘舵��
- if (!activeLocks.Any())
- {
- await _outboundOrderService.Db.Updateable<Dt_OutboundOrder>()
- .SetColumns(x => new Dt_OutboundOrder
- {
- OrderStatus = (int)OutOrderStatusEnum.鍑哄簱瀹屾垚,
- })
- .Where(x => x.OrderNo == orderNo)
- .ExecuteCommandAsync();
-
- _logger.LogInformation($"鏇存柊璁㈠崟鐘舵�佷负鍑哄簱瀹屾垚 - 璁㈠崟: {orderNo}");
- }
- }
-
+
#endregion
#region 楠岃瘉鏂规硶
@@ -5235,18 +3192,18 @@
try
{
- // 1. 楠岃瘉鎷嗗寘鏁伴噺鍚堢悊鎬�
+ // 楠岃瘉鎷嗗寘鏁伴噺鍚堢悊鎬�
if (splitQuantity <= 0)
throw new InvalidOperationException($"鎷嗗寘鏁伴噺蹇呴』澶т簬0锛屽綋鍓嶅��: {splitQuantity}");
if (stockDetail.StockQuantity < lockInfo.AssignQuantity + splitQuantity)
throw new InvalidOperationException($"搴撳瓨鏁伴噺涓嶈冻浠ヨ繘琛岃嚜鍔ㄦ媶鍖咃紝搴撳瓨: {stockDetail.StockQuantity}, 闇�瑕�: {lockInfo.AssignQuantity + splitQuantity}");
- // 2. 鐢熸垚鏂版潯鐮�
+ // 鐢熸垚鏂版潯鐮�
string newBarcode = await GenerateNewBarcode();
_logger.LogInformation($"鐢熸垚鏂版潯鐮�: {newBarcode}");
- // 3. 銆愭牳蹇冧慨姝c�戞洿鏂板師搴撳瓨鏄庣粏锛氬彧鍑忓皯鐗╃悊搴撳瓨锛屼笉褰卞搷鍑哄簱鏁伴噺
+ // 銆愭牳蹇冧慨姝c�戞洿鏂板師搴撳瓨鏄庣粏锛氬彧鍑忓皯鐗╃悊搴撳瓨锛屼笉褰卞搷鍑哄簱鏁伴噺
decimal originalStockQty = stockDetail.StockQuantity;
stockDetail.StockQuantity -= splitQuantity; // 浠呭簱瀛樺噺灏�
// stockDetail.OutboundQuantity 淇濇寔涓嶅彉锛�
@@ -5254,7 +3211,7 @@
await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync();
_logger.LogInformation($"鏇存柊鍘熷簱瀛樻槑缁嗭細鏉$爜 {stockDetail.Barcode} 搴撳瓨 {originalStockQty} -> {stockDetail.StockQuantity}锛屽嚭搴撴暟閲忎笉鍙�({stockDetail.OutboundQuantity})");
- // 4. 鍒涘缓鏂板簱瀛樻槑缁嗭紙澶氫綑閮ㄥ垎锛�- 鍑哄簱鏁伴噺涓�0
+ // 鍒涘缓鏂板簱瀛樻槑缁嗭紙澶氫綑閮ㄥ垎锛�- 鍑哄簱鏁伴噺涓�0
var newStockDetail = new Dt_StockInfoDetail
{
StockId = stockDetail.StockId,
@@ -5262,7 +3219,7 @@
OrderNo = stockDetail.OrderNo,
BatchNo = stockDetail.BatchNo,
StockQuantity = splitQuantity, // 鏂板簱瀛樻暟閲�
- OutboundQuantity = 0, // 銆愰噸鐐广�戝垵濮嬪嚭搴撴暟閲忎负0
+ OutboundQuantity = 0, // 鍒濆鍑哄簱鏁伴噺涓�0
Barcode = newBarcode,
Status = (int)StockStatusEmun.鍑哄簱閿佸畾, // 浠嶄负閿佸畾鐘舵�侊紝浣嗘湭缁戝畾璁㈠崟
SupplyCode = stockDetail.SupplyCode,
@@ -5276,11 +3233,11 @@
await _stockInfoDetailService.Db.Insertable(newStockDetail).ExecuteCommandAsync();
_logger.LogInformation($"鍒涘缓鏂板簱瀛樻槑缁嗭細鏉$爜 {newBarcode}锛屽簱瀛� {splitQuantity}锛屽嚭搴� 0");
- // 5. 鍒涘缓鏂伴攣瀹氫俊鎭� - 鏍囪涓烘湭鍒嗛厤
+ // 鍒涘缓鏂伴攣瀹氫俊鎭� - 鏍囪涓烘湭鍒嗛厤
var newLockInfo = new Dt_OutStockLockInfo
{
OrderNo = lockInfo.OrderNo,
- OrderDetailId = 0, // 銆愰噸鐐广�戜笉缁戝畾鍒板叿浣撹鍗曟槑缁嗭紝琛ㄧず鏈垎閰�
+ OrderDetailId = 0, // 涓嶇粦瀹氬埌鍏蜂綋璁㈠崟鏄庣粏锛岃〃绀烘湭鍒嗛厤
OutboundBatchNo = lockInfo.OutboundBatchNo,
MaterielCode = lockInfo.MaterielCode,
MaterielName = lockInfo.MaterielName,
@@ -5304,13 +3261,13 @@
WarehouseCode = lockInfo.WarehouseCode,
BarcodeQty = lockInfo.BarcodeQty,
BarcodeUnit = lockInfo.BarcodeUnit,
- IsUnallocated = 1 // 銆愰噸鐐广�戞槑纭爣璁颁负"鏈垎閰�"鐨勯攣瀹氳褰�
+ IsUnallocated = 1 // 鏄庣‘鏍囪涓�"鏈垎閰�"鐨勯攣瀹氳褰�
};
await _outStockLockInfoService.Db.Insertable(newLockInfo).ExecuteCommandAsync();
_logger.LogInformation($"鍒涘缓鏈垎閰嶉攣瀹氳褰曪細ID {newLockInfo.Id}锛屾潯鐮� {newBarcode}锛屾暟閲� {splitQuantity}");
- // 6. 銆愬叧閿慨姝c�戝師閿佸畾璁板綍鍜屽師璁㈠崟鏄庣粏鏁版嵁瀹屽叏淇濇寔涓嶅彉锛�
+ //鍘熼攣瀹氳褰曞拰鍘熻鍗曟槑缁嗘暟鎹畬鍏ㄤ繚鎸佷笉鍙橈紒
// - 涓嶄慨鏀� lockInfo 鐨勪换浣曞瓧娈�
// - 涓嶄慨鏀瑰叧鑱旂殑 Dt_OutboundOrderDetail 鐨� AllocatedQuantity 鍜� LockQuantity
@@ -5329,64 +3286,6 @@
_logger.LogError($"鑷姩鎷嗗寘閫昏緫鎵ц澶辫触 - 鍘熸潯鐮�: {stockDetail.Barcode}, Error: {ex.Message}");
throw;
}
- }
-
- /// <summary>
- /// 楠岃瘉鑷姩鎷嗗寘鍚庢暟鎹竴鑷存�� - 淇鐗�
- /// 鍘熷垯锛氶獙璇佹湭鍒嗛厤閿佸畾璁板綍鐨勫垱寤猴紝鑰屼笉鏄鍗曟槑缁嗘暟閲忕殑鍙樺寲
- /// </summary>
- private async Task ValidateDataConsistencyAfterAutoSplit(long orderDetailId, decimal originalAllocatedQty, decimal originalLockQty, decimal splitQuantity)
- {
- // 閲嶆柊鑾峰彇璁㈠崟鏄庣粏鏁版嵁
- var orderDetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
- .FirstAsync(x => x.Id == orderDetailId);
-
- if (orderDetail == null)
- return;
-
- // 銆愪慨姝c�戣嚜鍔ㄦ媶鍖呭悗锛岃鍗曟槑缁嗗垎閰嶆暟閲忓簲璇ヤ繚鎸佷笉鍙橈紒
- if (Math.Abs(orderDetail.AllocatedQuantity - originalAllocatedQty) > 0.01m)
- {
- _logger.LogError($"鑷姩鎷嗗寘鍚庤鍗曟槑缁嗗垎閰嶆暟閲忓紓甯稿彉鍖栵紒鏈熸湜淇濇寔涓嶅彉: {originalAllocatedQty}, 瀹為檯: {orderDetail.AllocatedQuantity}");
- // 璁板綍涓ラ噸閿欒锛屼絾涓嶆姏鍑哄紓甯革紙鐢熶骇鐜鍙兘闇�瑕佸憡璀︼級
- }
-
- if (Math.Abs(orderDetail.LockQuantity - originalLockQty) > 0.01m)
- {
- _logger.LogError($"鑷姩鎷嗗寘鍚庤鍗曟槑缁嗛攣瀹氭暟閲忓紓甯稿彉鍖栵紒鏈熸湜淇濇寔涓嶅彉: {originalLockQty}, 瀹為檯: {orderDetail.LockQuantity}");
- }
-
- // 楠岃瘉鏈垎閰嶉攣瀹氳褰曠殑鍒涘缓
- // 鏌ユ壘鐖堕攣瀹氳褰�
- var parentLockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
- .FirstAsync(x => x.OrderDetailId == orderDetailId);
-
- if (parentLockInfo != null)
- {
- // 鏌ユ壘鏈垎閰嶇殑瀛愰攣瀹氳褰曪紙鑷姩鎷嗗寘鐢熸垚鐨勶級
- var unallocatedChildLocks = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
- .Where(x => x.ParentLockId == parentLockInfo.Id &&
- x.IsUnallocated == 1 &&
- x.OrderDetailId == 0)
- .ToListAsync();
-
- if (unallocatedChildLocks.Any())
- {
- decimal totalUnallocatedQty = unallocatedChildLocks.Sum(x => x.AssignQuantity);
- _logger.LogInformation($"楠岃瘉閫氳繃锛氬垱寤轰簡{unallocatedChildLocks.Count}鏉℃湭鍒嗛厤閿佸畾璁板綍锛屾�绘暟閲�: {totalUnallocatedQty}");
-
- if (Math.Abs(totalUnallocatedQty - splitQuantity) > 0.01m)
- {
- _logger.LogWarning($"鏈垎閰嶉攣瀹氳褰曟�绘暟閲忎笌鎷嗗寘鏁伴噺涓嶅尮閰嶏紝鎷嗗寘鏁伴噺: {splitQuantity}, 鏈垎閰嶆�绘暟: {totalUnallocatedQty}");
- }
- }
- else
- {
- _logger.LogWarning($"鏈壘鍒拌嚜鍔ㄦ媶鍖呯敓鎴愮殑鏈垎閰嶉攣瀹氳褰�");
- }
- }
-
- _logger.LogInformation($"鑷姩鎷嗗寘鏁版嵁涓�鑷存�ч獙璇佸畬鎴�");
}
#endregion
@@ -5414,7 +3313,7 @@
decimal originalOutboundQty = stockDetail.OutboundQuantity;
int originalStatus = stockDetail.Status;
- // 銆愭牳蹇冧慨姝c�戠‘淇漁utboundQuantity鍙鍔犳湰娆℃嫞閫夋暟閲忥紝涓嶅寘鍚叾浠�
+ // 纭繚OutboundQuantity鍙鍔犳湰娆℃嫞閫夋暟閲忥紝涓嶅寘鍚叾浠�
stockDetail.StockQuantity -= actualPickedQty;
stockDetail.OutboundQuantity += actualPickedQty; // 鍙鍔犳湰娆℃嫞閫夋暟閲�
@@ -5475,7 +3374,7 @@
{
_logger.LogInformation($"楠岃瘉鎷i�夋暟鎹竴鑷存�� - 鏉$爜: {stockDetail.Barcode}");
- // 1. 楠岃瘉搴撳瓨鏄庣粏鐨凮utboundQuantity澧炲姞閲忕瓑浜庢嫞閫夋暟閲�
+ // 楠岃瘉搴撳瓨鏄庣粏鐨凮utboundQuantity澧炲姞閲忕瓑浜庢嫞閫夋暟閲�
var refreshedStockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
.FirstAsync(x => x.Id == stockDetail.Id);
@@ -5484,13 +3383,13 @@
if (Math.Abs(outboundIncrease - pickedQty) > 0.01m)
{
_logger.LogError($"鎷i�夋暟鎹笉涓�鑷达細鍑哄簱鏁伴噺澧炲姞 {outboundIncrease}锛屼絾鎷i�夋暟閲忔槸 {pickedQty}");
- // 淇锛氱‘淇漁utboundQuantity姝g‘
+ // 纭繚OutboundQuantity姝g‘
refreshedStockDetail.OutboundQuantity = stockDetail.OutboundQuantity + pickedQty;
await _stockInfoDetailService.Db.Updateable(refreshedStockDetail).ExecuteCommandAsync();
_logger.LogWarning($"宸蹭慨澶嶅嚭搴撴暟閲忥細{stockDetail.OutboundQuantity} -> {refreshedStockDetail.OutboundQuantity}");
}
- // 2. 楠岃瘉閿佸畾璁板綍鐨勫凡鎷i�夋暟閲�
+ // 楠岃瘉閿佸畾璁板綍鐨勫凡鎷i�夋暟閲�
var refreshedLockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
.FirstAsync(x => x.Id == lockInfo.Id);
@@ -5506,7 +3405,7 @@
{
_logger.LogInformation($"寮�濮嬫仮澶嶆嫞閫夋暟鎹� - 鎷i�夎褰旾D: {pickingRecord.Id}, 鏉$爜: {pickingRecord.Barcode}, 鎷i�夋暟閲�: {pickingRecord.PickQuantity}");
- // 1. 鎭㈠閿佸畾淇℃伅
+ // 鎭㈠閿佸畾淇℃伅
var lockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
.FirstAsync(x => x.Id == pickingRecord.OutStockLockId);
@@ -5545,7 +3444,7 @@
await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync();
- // 2. 鎭㈠搴撳瓨淇℃伅
+ // 鎭㈠搴撳瓨淇℃伅
var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
.FirstAsync(x => x.Barcode == pickingRecord.Barcode);
@@ -5738,7 +3637,7 @@
await _outboundOrderDetailService.Db.Updateable(orderDetail).ExecuteCommandAsync();
}
- // 3. 閲嶆柊妫�鏌ヨ鍗曠姸鎬�
+ // 閲嶆柊妫�鏌ヨ鍗曠姸鎬�
await CheckAndUpdateOrderStatus(pickingRecord.OrderNo);
_logger.LogInformation($"鎭㈠鎵规鍜岃鍗曟暟鎹畬鎴�");
@@ -5759,136 +3658,9 @@
orderDetail.BatchAllocateStatus = OrderDetailStatusEnum.New.ObjToInt();
}
}
- private async Task ReleaseLockAndStock(Dt_OutStockLockInfo lockInfo)
- {
- // 鎭㈠搴撳瓨鐘舵�� - 鍥炲簱鍚庡簱瀛樺彉涓哄彲鐢ㄧ姸鎬�
- var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
- .FirstAsync(x => x.Barcode == lockInfo.CurrentBarcode && x.StockId == lockInfo.StockId);
-
- if (stockDetail != null)
- {
- // 鍥炲簱鍚庡簱瀛樼姸鎬佹仮澶嶄负鍏ュ簱瀹屾垚锛堝彲鐢ㄧ姸鎬侊級
- stockDetail.Status = (int)StockStatusEmun.鍏ュ簱瀹屾垚;
- await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync();
- }
-
- // 鏇存柊閿佸畾璁板綍鐘舵�佷负宸插洖搴�
- lockInfo.Status = (int)OutLockStockStatusEnum.宸插洖搴�;
- lockInfo.Operator = App.User.UserName;
- await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync();
- }
-
- /// <summary>
- /// 鏇存柊鎵规鐘舵�侊紙鍥炲簱锛�
- /// </summary>
- private async Task UpdateBatchStatusForReturn(string outboundBatchNo, List<Dt_OutStockLockInfo> returnedLocks)
- {
- var batch = await _outboundBatchRepository.Db.Queryable<Dt_OutboundBatch>()
- .FirstAsync(x => x.BatchNo == outboundBatchNo);
-
- if (batch != null)
- {
- // 璁$畻鍥炲簱鏁伴噺锛堟湭鎷i�夌殑閮ㄥ垎锛�
- var returnedQty = returnedLocks.Sum(x => x.AssignQuantity - x.PickedQty);
- batch.CompletedQuantity -= returnedQty;
-
- // 鏇存柊鎵规鐘舵��
- if (batch.CompletedQuantity <= 0)
- {
- batch.BatchStatus = (int)BatchStatusEnum.宸插洖搴�;
- }
- else if (batch.CompletedQuantity < batch.BatchQuantity)
- {
- batch.BatchStatus = (int)BatchStatusEnum.鎵ц涓�;
- }
- else
- {
- batch.BatchStatus = (int)BatchStatusEnum.宸插畬鎴�;
- }
-
- batch.Operator = App.User.UserName;
- await _outboundBatchRepository.Db.Updateable(batch).ExecuteCommandAsync();
- }
- }
-
- /// <summary>
- /// 鏇存柊璁㈠崟鏄庣粏锛堝洖搴撳悗锛�
- /// </summary>
- private async Task UpdateOrderDetailAfterReturn(List<Dt_OutStockLockInfo> returnedLocks)
- {
- var orderDetailGroups = returnedLocks.GroupBy(x => x.OrderDetailId);
-
- foreach (var group in orderDetailGroups)
- {
- var orderDetailId = group.Key;
- var returnedQty = group.Sum(x => x.AssignQuantity - x.PickedQty);
-
- var orderDetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
- .FirstAsync(x => x.Id == orderDetailId);
-
- if (orderDetail != null)
- {
- orderDetail.AllocatedQuantity -= returnedQty;
- // LockQuantity 鍚屾鍑忓皯锛屼繚鎸佷笌宸插垎閰嶆暟閲忎竴鑷�
- orderDetail.LockQuantity = orderDetail.AllocatedQuantity;
-
- await UpdateBatchAllocateStatus(orderDetail);
-
- await _outboundOrderDetailService.Db.Updateable(orderDetail).ExecuteCommandAsync();
- }
- }
- }
+
#endregion
-
- private async Task CreateReturnTaskAndHandleESS(string orderNo, string palletCode, Dt_Task originalTask, TaskTypeEnum taskTypeEnum, int palletType)
- {
- var firstLocation = await _locationInfoService.Db.Queryable<Dt_LocationInfo>()
- .FirstAsync(x => x.LocationCode == originalTask.SourceAddress);
-
- // 鍒嗛厤鏂拌揣浣�
- var newLocation = _locationInfoService.AssignLocation(firstLocation.LocationType);
-
- Dt_Task returnTask = new()
- {
- CurrentAddress = stations[originalTask.TargetAddress],
- Grade = 0,
- PalletCode = palletCode,
- NextAddress = "",
- // OrderNo = originalTask.OrderNo,
- OrderNo = orderNo,
- Roadway = newLocation.RoadwayNo,
- SourceAddress = stations[originalTask.TargetAddress],
- TargetAddress = newLocation.LocationCode,
- TaskStatus = TaskStatusEnum.New.ObjToInt(),
- TaskType = taskTypeEnum.ObjToInt(),
- PalletType = palletType,
- WarehouseId = originalTask.WarehouseId
-
- };
- // 淇濆瓨鍥炲簱浠诲姟
- var insertcount = await _taskRepository.Db.Insertable(returnTask).ExecuteCommandAsync();
- if (insertcount <= 0)
- {
- throw new Exception("鍒涘缓浠诲姟澶辫触锛�");
- }
- var targetAddress = originalTask.TargetAddress;
-
- _logger.LogInformation($"CreateReturnTaskAndHandleESS 鍒嗘壒鍒犻櫎鍘嗗彶浠诲姟: {orderNo} 锛� {originalTask.TaskNum}");
- // 鍒犻櫎鍘熷鍑哄簱浠诲姟
- //_taskRepository.DeleteAndMoveIntoHty(originalTask, OperateTypeEnum.鑷姩瀹屾垚);
- var result = _task_HtyService.DeleteAndMoveIntoHty(originalTask, OperateTypeEnum.浜哄伐鍒犻櫎);
- await _taskRepository.Db.Deleteable(originalTask).ExecuteCommandAsync();
-
- if (!result)
- {
- await _taskRepository.Db.Deleteable(originalTask).ExecuteCommandAsync();
- }
- _logger.LogInformation($"CreateReturnTaskAndHandleESS 鍒嗘壒鍒犻櫎鍘嗗彶浠诲姟: {orderNo} 锛� {originalTask.TaskNum},褰卞搷琛� {result}");
-
-
- // 缁� ESS 鍙戦�佹祦鍔ㄤ俊鍙峰拰鍒涘缓浠诲姟
- await SendESSCommands(palletCode, targetAddress, returnTask);
- }
+
/// <summary>
/// 缁橢SS涓嬩换鍔�
/// </summary>
@@ -5901,16 +3673,14 @@
{
try
{
- // 1. 鍙戦�佹祦鍔ㄤ俊鍙�
+ // 鍙戦�佹祦鍔ㄤ俊鍙�
var moveResult = await _eSSApiService.MoveContainerAsync(new WIDESEA_DTO.Basic.MoveContainerRequest
{
slotCode = movestations[targetAddress],
containerCode = palletCode
});
- //if (moveResult)
- //{
- // 2. 鍒涘缓鍥炲簱浠诲姟
+
var essTask = new TaskModel()
{
taskType = "putaway",
@@ -5934,7 +3704,7 @@
var resultTask = await _eSSApiService.CreateTaskAsync(essTask);
_logger.LogInformation($"ReturnRemaining 鍒涘缓浠诲姟鎴愬姛: {resultTask}");
- //}
+
}
catch (Exception ex)
{
@@ -6032,26 +3802,31 @@
#endregion
#region DTO绫�
+
/// <summary>
- /// 鏉$爜鐘舵�佷俊鎭疍TO
+ /// 鍥炲簱浠诲姟淇℃伅绫�
/// </summary>
- public class BarcodeStatusInfoDto
+ public class ReturnTaskInfo
{
- public string Barcode { get; set; }
- public string OrderNo { get; set; }
- public bool IsOriginalBarcode { get; set; }
- public int SplitChainCount { get; set; }
- public bool HasBeenPicked { get; set; }
- public decimal TotalPickedQuantity { get; set; }
- public int PickRecordCount { get; set; }
- public int LockInfoStatus { get; set; }
- public decimal LockInfoPickedQty { get; set; }
- public decimal LockInfoAssignQty { get; set; }
- public decimal StockQuantity { get; set; }
- public int StockStatus { get; set; }
- public bool CanCancelSplit { get; set; }
- public bool NeedCancelPickFirst { get; set; }
- public List<string> OperationSuggestions { get; set; } = new List<string>();
+ /// <summary>
+ /// 鏄惁闇�瑕佸彂閫丒SS鍛戒护
+ /// </summary>
+ public bool ShouldSendESS { get; set; }
+
+ /// <summary>
+ /// 鎵樼洏鐮�
+ /// </summary>
+ public string PalletCode { get; set; }
+
+ /// <summary>
+ /// 鍘熷浠诲姟鐨勭洰鏍囧湴鍧�
+ /// </summary>
+ public string OriginalTaskTargetAddress { get; set; }
+
+ /// <summary>
+ /// 鍥炲簱浠诲姟
+ /// </summary>
+ public Dt_Task ReturnTask { get; set; }
}
public class PickedBarcodeInfo
{
@@ -6059,14 +3834,7 @@
public decimal PickedQty { get; set; }
public int PickRecordCount { get; set; }
}
- /// <summary>
- /// 鑷姩鎷嗗寘缁撴灉
- /// </summary>
- public class AutoSplitResult
- {
- public string NewBarcode { get; set; }
- public decimal SplitQuantity { get; set; }
- }
+
public class PickingResult
{
@@ -6078,11 +3846,6 @@
{
public Dt_OutStockLockInfo LockInfo { get; set; }
public Dt_StockInfoDetail StockDetail { get; set; }
- }
-
- public class SplitResultDto
- {
- public string NewBarcode { get; set; }
}
public class ValidationResult<T>
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundPickingService.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundPickingService.cs"
index 599aedd..1adb870 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundPickingService.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundPickingService.cs"
@@ -1,19 +1,7 @@
-锘縰sing Dm.filter;
-using MailKit.Search;
-using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Mvc;
-using Microsoft.Extensions.Logging;
+锘縰sing Microsoft.Extensions.Logging;
using SqlSugar;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Reflection.Metadata;
-using System.Text;
-using System.Text.Json;
-using System.Threading.Tasks;
using WIDESEA_BasicService;
using WIDESEA_Common.CommonEnum;
-using WIDESEA_Common.LocationEnum;
using WIDESEA_Common.OrderEnum;
using WIDESEA_Common.StockEnum;
using WIDESEA_Common.TaskEnum;
@@ -23,7 +11,6 @@
using WIDESEA_Core.Enums;
using WIDESEA_Core.Helper;
using WIDESEA_Core.Utilities;
-using WIDESEA_DTO.Allocate;
using WIDESEA_DTO.Basic;
using WIDESEA_DTO.Inbound;
using WIDESEA_DTO.Outbound;
@@ -298,10 +285,6 @@
return WebResponseContent.Instance.Error("鏈壘鍒板搴旂殑浠诲姟淇℃伅");
//鍒嗘瀽闇�瑕佸洖搴撶殑璐х墿
- //var returnAnalysis = await AnalyzeReturnItems(orderNo, palletCode, stockInfo.Id);
- //if (!returnAnalysis.HasItemsToReturn)
- // return await HandleNoReturnItems(orderNo, palletCode, task);
-
var statusAnalysis = await AnalyzePalletStatus(orderNo, palletCode, stockInfo.Id);
if (!statusAnalysis.HasItemsToReturn)
{
@@ -326,7 +309,7 @@
}
- // 4. 妫�鏌ユ槸鍚︽湁杩涜涓殑浠诲姟
+ // 妫�鏌ユ槸鍚︽湁杩涜涓殑浠诲姟
if (statusAnalysis.HasActiveTasks)
{
return WebResponseContent.Instance.Error($"鎵樼洏 {palletCode} 鏈夎繘琛屼腑鐨勪换鍔★紝涓嶈兘鎵ц鍥炲簱鎿嶄綔");
@@ -428,16 +411,16 @@
private async Task<ValidationResult<(Dt_OutStockLockInfo, Dt_OutboundOrderDetail, Dt_StockInfoDetail)>> ValidatePickingRequest(string orderNo, string palletCode, string barcode)
{
- // 1. 鍩虹鍙傛暟楠岃瘉
+ // 鍩虹鍙傛暟楠岃瘉
if (string.IsNullOrEmpty(orderNo) || string.IsNullOrEmpty(palletCode) || string.IsNullOrEmpty(barcode))
return ValidationResult<(Dt_OutStockLockInfo, Dt_OutboundOrderDetail, Dt_StockInfoDetail)>.Error("璁㈠崟鍙枫�佹墭鐩樼爜鍜屾潯鐮佷笉鑳戒负绌�");
- // 2. 鏌ユ壘鏈夋晥鐨勯攣瀹氫俊鎭�
+ // 鏌ユ壘鏈夋晥鐨勯攣瀹氫俊鎭�
var lockInfo = await FindValidLockInfo(orderNo, palletCode, barcode);
if (lockInfo == null)
return ValidationResult<(Dt_OutStockLockInfo, Dt_OutboundOrderDetail, Dt_StockInfoDetail)>.Error($"鏈壘鍒版湁鏁堢殑閿佸畾淇℃伅");
- // 3. 妫�鏌ヨ鍗曠姸鎬�
+ // 妫�鏌ヨ鍗曠姸鎬�
var order = await _outboundOrderService.Db.Queryable<Dt_OutboundOrder>()
.Where(x => x.OrderNo == orderNo)
.FirstAsync();
@@ -445,18 +428,18 @@
if (order?.OrderStatus == (int)OutOrderStatusEnum.鍑哄簱瀹屾垚)
return ValidationResult<(Dt_OutStockLockInfo, Dt_OutboundOrderDetail, Dt_StockInfoDetail)>.Error($"璁㈠崟{orderNo}宸插畬鎴愶紝涓嶈兘缁х画鍒嗘嫞");
- // 4. 鑾峰彇璁㈠崟鏄庣粏
+ // 鑾峰彇璁㈠崟鏄庣粏
var orderDetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
.FirstAsync(x => x.Id == lockInfo.OrderDetailId);
if (orderDetail == null)
return ValidationResult<(Dt_OutStockLockInfo, Dt_OutboundOrderDetail, Dt_StockInfoDetail)>.Error($"鏈壘鍒拌鍗曟槑缁�");
- // 5. 妫�鏌ヨ鍗曟槑缁嗘暟閲�
+ // 妫�鏌ヨ鍗曟槑缁嗘暟閲�
if (orderDetail.OverOutQuantity >= orderDetail.NeedOutQuantity)
return ValidationResult<(Dt_OutStockLockInfo, Dt_OutboundOrderDetail, Dt_StockInfoDetail)>.Error($"璁㈠崟鏄庣粏闇�姹傛暟閲忓凡婊¤冻");
- // 6. 鑾峰彇搴撳瓨鏄庣粏
+ // 鑾峰彇搴撳瓨鏄庣粏
var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
.Where(x => x.Barcode == barcode && x.StockId == lockInfo.StockId &&
x.Status != StockStatusEmun.鍏ュ簱纭.ObjToInt())
@@ -465,14 +448,14 @@
if (stockDetail == null)
return ValidationResult<(Dt_OutStockLockInfo, Dt_OutboundOrderDetail, Dt_StockInfoDetail)>.Error($"鏃犳晥鐨勬潯鐮佹垨鐗╂枡缂栫爜");
- // 7. 妫�鏌ュ簱瀛樼姸鎬佸拰鏁伴噺
+ // 妫�鏌ュ簱瀛樼姸鎬佸拰鏁伴噺
if (stockDetail.StockQuantity <= 0)
return ValidationResult<(Dt_OutStockLockInfo, Dt_OutboundOrderDetail, Dt_StockInfoDetail)>.Error($"鏉$爜{barcode}搴撳瓨涓嶈冻");
if (stockDetail.Status != StockStatusEmun.鍑哄簱閿佸畾.ObjToInt())
return ValidationResult<(Dt_OutStockLockInfo, Dt_OutboundOrderDetail, Dt_StockInfoDetail)>.Error($"鏉$爜{barcode}鐘舵�佷笉姝g‘锛屾棤娉曞垎鎷�");
- // 8. 妫�鏌ユ槸鍚﹂噸澶嶅垎鎷�
+ //妫�鏌ユ槸鍚﹂噸澶嶅垎鎷�
var existingPicking = await Db.Queryable<Dt_PickingRecord>()
.Where(x => x.Barcode == barcode && x.OrderNo == orderNo && x.PalletCode == palletCode && x.OutStockLockId == lockInfo.Id)
.FirstAsync();
@@ -681,13 +664,13 @@
private async Task HandleFullPicking(Dt_OutStockLockInfo lockInfo, Dt_StockInfoDetail stockDetail,
decimal actualQty, PickingResult result)
{
- // 1. 鏇存柊搴撳瓨
+ // 鏇存柊搴撳瓨
stockDetail.StockQuantity = 0;
stockDetail.OutboundQuantity = 0;
stockDetail.Status = StockStatusEmun.鍑哄簱瀹屾垚.ObjToInt();
await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync();
- // 2. 鏇存柊閿佸畾淇℃伅
+ // 鏇存柊閿佸畾淇℃伅
lockInfo.PickedQty += actualQty;
lockInfo.Status = (int)OutLockStockStatusEnum.鎷i�夊畬鎴�;
lockInfo.Operator = App.User.UserName;
@@ -700,19 +683,19 @@
decimal stockOutQty = stockQuantity;
decimal remainingAssignQty = actualQty - stockQuantity;
- // 1. 鏇存柊搴撳瓨
+ // 鏇存柊搴撳瓨
stockDetail.StockQuantity = 0;
stockDetail.OutboundQuantity = 0;
stockDetail.Status = StockStatusEmun.鍑哄簱瀹屾垚.ObjToInt();
await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync();
- // 2. 鏇存柊閿佸畾淇℃伅
+ // 鏇存柊閿佸畾淇℃伅
lockInfo.PickedQty += stockOutQty;
lockInfo.AssignQuantity = remainingAssignQty;
lockInfo.Operator = App.User.UserName;
await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync();
- // 3. 鏇存柊鎷嗗寘璁板綍鐘舵��
+ // 鏇存柊鎷嗗寘璁板綍鐘舵��
await UpdateSplitRecordsStatus(stockDetail.Barcode);
result.ActualPickedQty = stockOutQty;
@@ -951,22 +934,7 @@
return ValidationResult<(Dt_PickingRecord, Dt_OutStockLockInfo, Dt_OutboundOrderDetail)>.Success((pickingRecord, lockInfo, orderDetail));
}
- /// <summary>
- /// 妫�鏌ユ潯鐮佹槸鍚﹀凡缁忓洖搴�
- /// </summary>
- private async Task<bool> IsBarcodeReturned(string barcode, int stockId)
- {
- var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
- .Where(it => it.Barcode == barcode && it.StockId == stockId)
- .FirstAsync();
-
- if (stockDetail == null)
- return false;
-
- // 濡傛灉鐘舵�佹槸鍏ュ簱纭鎴栧叆搴撳畬鎴愶紝璇存槑宸茬粡鍥炲簱
- return stockDetail.Status == StockStatusEmun.鍏ュ簱纭.ObjToInt() ||
- stockDetail.Status == StockStatusEmun.鍏ュ簱瀹屾垚.ObjToInt();
- }
+
/// <summary>
/// 妫�鏌ラ攣瀹氫俊鎭搴旂殑鏉$爜鏄惁宸茬粡鍥炲簱
@@ -1204,12 +1172,7 @@
#endregion
#region 鍥炲簱鎿嶄綔绉佹湁鏂规硶
-
- private async Task<Dt_StockInfo> GetStockInfo(string palletCode)
- {
- return await _stockInfoService.Db.Queryable<Dt_StockInfo>()
- .FirstAsync(x => x.PalletCode == palletCode);
- }
+
/// <summary>
/// 妫�鏌ユ暣涓墭鐩樻槸鍚﹀凡缁忓洖搴�
/// </summary>
@@ -1287,24 +1250,7 @@
}
private async Task<WebResponseContent> HandleNoReturnItems(string orderNo, string palletCode, Dt_Task originalTask, int stockInfoId)
- {
- // 妫�鏌ユ槸鍚︽墍鏈夎揣鐗╅兘宸叉嫞閫夊畬鎴�
- //var allPicked = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
- // .Where(it => it.OrderNo == orderNo && it.PalletCode == palletCode)
- // .AnyAsync(it => it.Status == (int)OutLockStockStatusEnum.鎷i�夊畬鎴�);
-
- //if (allPicked)
- //{
- // // 鍒犻櫎鍘熷鍑哄簱浠诲姟 缁勭┖鐩� 绌虹洏鍥炲簱
- // //await _taskRepository.Db.Deleteable(originalTask).ExecuteCommandAsync();
- // return WebResponseContent.Instance.OK("鎵�鏈夎揣鐗╁凡鎷i�夊畬鎴愶紝鎵樼洏涓虹┖");
- //}
- //else
- //{
- // // 鍒犻櫎鍘熷鍑哄簱浠诲姟
- // //await _taskRepository.Db.Deleteable(originalTask).ExecuteCommandAsync();
- // return WebResponseContent.Instance.Error("娌℃湁闇�瑕佸洖搴撶殑鍓╀綑璐х墿");
- //}
+ {
try
{
var locationtype = 0;
@@ -1400,16 +1346,16 @@
{
_logger.LogInformation($"寮�濮嬮噴鏀鹃攣瀹氫互渚块噸鏂板垎閰� - 璁㈠崟: {orderNo}, 鎵樼洏: {palletCode}");
- // 1. 澶勭悊鏈垎鎷g殑鍑哄簱閿佸畾璁板綍 - 瀹屽叏閲婃斁
+ // 澶勭悊鏈垎鎷g殑鍑哄簱閿佸畾璁板綍 - 瀹屽叏閲婃斁
if (analysis.HasRemainingLocks)
{
await ReleaseRemainingLocks(analysis.RemainingLocks);
}
- // 2. 澶勭悊宸插洖搴撶殑閿佸畾璁板綍 - 鍒犻櫎鎴栨爣璁颁负鏃犳晥
+ // 澶勭悊宸插洖搴撶殑閿佸畾璁板綍 - 鍒犻櫎鎴栨爣璁颁负鏃犳晥
await CleanupReturnedLocks(orderNo, palletCode);
- // 3. 閲嶇疆璁㈠崟鏄庣粏鐨勯攣瀹氭暟閲�
+ // 閲嶇疆璁㈠崟鏄庣粏鐨勯攣瀹氭暟閲�
await ResetOrderDetailLockQuantities(analysis);
_logger.LogInformation($"閿佸畾閲婃斁瀹屾垚 - 璁㈠崟: {orderNo}, 鎵樼洏: {palletCode}");
@@ -1591,38 +1537,7 @@
}
-
- private async Task UpdateOrderDetailsOnReturn(List<Dt_OutStockLockInfo> remainingLocks)
- {
- // 鎸夎鍗曟槑缁嗗垎缁�
- var orderDetailGroups = remainingLocks.GroupBy(x => x.OrderDetailId);
-
- foreach (var group in orderDetailGroups)
- {
- var orderDetailId = group.Key;
- var totalReturnQty = group.Sum(x => x.AssignQuantity - x.PickedQty);
-
- // 鑾峰彇褰撳墠璁㈠崟鏄庣粏
- var orderDetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
- .FirstAsync(x => x.Id == orderDetailId);
-
- if (orderDetail != null)
- {
- // 璋冩暣宸叉嫞閫夋暟閲忓拰宸插嚭搴撴暟閲�
- decimal newPickedQty = Math.Max(0, orderDetail.PickedQty - totalReturnQty);
- decimal newOverOutQuantity = Math.Max(0, orderDetail.OverOutQuantity - totalReturnQty);
-
- await _outboundOrderDetailService.Db.Updateable<Dt_OutboundOrderDetail>()
- .SetColumns(it => new Dt_OutboundOrderDetail
- {
- PickedQty = newPickedQty,
- OverOutQuantity = newOverOutQuantity,
- })
- .Where(it => it.Id == orderDetailId)
- .ExecuteCommandAsync();
- }
- }
- }
+
private async Task HandlePalletStockGoodsReturn(List<Dt_StockInfoDetail> palletStockGoods)
{
@@ -1750,7 +1665,7 @@
{
try
{
- // 1. 鍙戦�佹祦鍔ㄤ俊鍙�
+ // 鍙戦�佹祦鍔ㄤ俊鍙�
var moveResult = await _eSSApiService.MoveContainerAsync(new WIDESEA_DTO.Basic.MoveContainerRequest
{
slotCode = movestations[targetAddress],
@@ -1759,7 +1674,7 @@
//if (moveResult)
//{
- // 2. 鍒涘缓鍥炲簱浠诲姟
+ // 鍒涘缓鍥炲簱浠诲姟
var essTask = new TaskModel()
{
taskType = "putaway",
@@ -1979,148 +1894,7 @@
_logger.LogError($"UpdateOrderStatusForReturn澶辫触 - OrderNo: {orderNo}, Error: {ex.Message}");
}
}
-
- private async Task HandleOrderCompletion(Dt_OutboundOrder outboundOrder, string orderNo)
- {
- // 璋冩嫧鍑哄簱鍜岄噸妫�鍑哄簱涓嶉渶瑕佸弽棣圡ES
- if (outboundOrder.OrderType == OutOrderTypeEnum.Allocate.ObjToInt())
- {
- var allocate = _allocateService.Repository.QueryData(x => x.UpperOrderNo == outboundOrder.UpperOrderNo).First();
- var allocatefeedmodel = new AllocateDto
- {
- ReqCode = Guid.NewGuid().ToString(),
- ReqTime = DateTime.Now.ToString(),
- BusinessType = "2",
-
- FactoryArea = outboundOrder.FactoryArea,
- OperationType = 1,
- Operator = App.User.UserName,
- OrderNo = outboundOrder.UpperOrderNo,
- // documentsNO = outboundOrder.OrderNo,
- // status = outboundOrder.OrderStatus,
- fromWarehouse = allocate?.FromWarehouse ?? "",
- toWarehouse = allocate?.ToWarehouse ?? "",
- Details = new List<AllocateDtoDetail>()
-
- };
- // 鍙幏鍙栧凡鎷i�夊畬鎴愮殑閿佸畾璁板綍
- var lists = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
- .Where(x => x.OrderNo == orderNo && x.Status == (int)OutLockStockStatusEnum.鎷i�夊畬鎴�)
- .ToListAsync();
-
- var groupedData = lists.GroupBy(item => new { item.MaterielCode, item.lineNo, item.BarcodeUnit, item.WarehouseCode })
- .Select(group => new AllocateDtoDetail
- {
- MaterialCode = group.Key.MaterielCode,
- LineNo = group.Key.lineNo,
- WarehouseCode = group.Key.WarehouseCode,
- Qty = group.Sum(x => x.PickedQty),
-
- Unit = group.Key.BarcodeUnit,
- Barcodes = group.Select(row => new BarcodeInfo
- {
- Barcode = row.CurrentBarcode,
- SupplyCode = row.SupplyCode,
- BatchNo = row.BatchNo,
- Unit = row.BarcodeUnit,
- Qty = row.PickedQty
- }).ToList()
-
-
- }).ToList();
- allocatefeedmodel.Details = groupedData;
-
- var result = await _invokeMESService.FeedbackAllocate(allocatefeedmodel);
- if (result != null && result.code == 200)
- {
- await _outboundOrderDetailService.Db.Updateable<Dt_OutboundOrderDetail>()
- .SetColumns(x => x.ReturnToMESStatus == 1)
- .Where(x => x.OrderId == outboundOrder.Id).ExecuteCommandAsync();
-
- await _outboundOrderService.Db.Updateable<Dt_OutboundOrder>()
- .SetColumns(x => new Dt_OutboundOrder
- {
- ReturnToMESStatus = 1,
- Operator = App.User.UserName,
- }).Where(x => x.OrderNo == orderNo).ExecuteCommandAsync();
- }
- }
- else if (outboundOrder.OrderType == OutOrderTypeEnum.ReCheck.ObjToInt())
- {
-
- }
- else
- {
- try
- {
- var feedmodel = new FeedbackOutboundRequestModel
- {
- reqCode = Guid.NewGuid().ToString(),
- reqTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
- business_type = outboundOrder.BusinessType,
- factoryArea = outboundOrder.FactoryArea,
- operationType = 1,
- Operator = App.User.UserName,
- orderNo = outboundOrder.UpperOrderNo,
- documentsNO = outboundOrder.OrderNo,
- status = outboundOrder.OrderStatus,
- details = new List<FeedbackOutboundDetailsModel>()
- };
-
- // 鍙幏鍙栧凡鎷i�夊畬鎴愮殑閿佸畾璁板綍
- var lists = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
- .Where(x => x.OrderNo == orderNo && (x.Status == (int)OutLockStockStatusEnum.鎷i�夊畬鎴� || x.Status == (int)OutLockStockStatusEnum.宸插洖搴�))
- .ToListAsync();
-
- var groupedData = lists.GroupBy(item => new { item.MaterielCode, item.lineNo, item.BarcodeUnit, item.WarehouseCode })
- .Select(group => new FeedbackOutboundDetailsModel
- {
- materialCode = group.Key.MaterielCode,
- lineNo = group.Key.lineNo,
- warehouseCode = group.Key.WarehouseCode,
- qty = group.Sum(x => x.PickedQty),
- currentDeliveryQty = group.Sum(x => x.PickedQty),
- unit = group.Key.BarcodeUnit,
- barcodes = group.Select(row => new WIDESEA_DTO.Outbound.BarcodesModel
- {
- barcode = row.CurrentBarcode,
- supplyCode = row.SupplyCode,
- batchNo = row.BatchNo,
- unit = row.BarcodeUnit,
- qty = row.PickedQty
- }).ToList()
- }).ToList();
-
- feedmodel.details = groupedData;
-
- var result = await _invokeMESService.FeedbackOutbound(feedmodel);
- if (result != null && result.code == 200)
- {
- await _outboundOrderDetailService.Db.Updateable<Dt_OutboundOrderDetail>()
- .SetColumns(x => x.ReturnToMESStatus == 1)
- .Where(x => x.OrderId == outboundOrder.Id)
- .ExecuteCommandAsync();
-
- await _outboundOrderService.Db.Updateable<Dt_OutboundOrder>()
- .SetColumns(x => new Dt_OutboundOrder
- {
- ReturnToMESStatus = 1,
- Operator = App.User.UserName,
- })
-
- .Where(x => x.OrderNo == orderNo)
- .ExecuteCommandAsync();
- }
-
- _logger.LogError($"FeedbackOutbound鎴愬姛 - OrderNo: {orderNo}, {JsonSerializer.Serialize(result)}");
- }
- catch (Exception ex)
- {
- _logger.LogError($"FeedbackOutbound澶辫触 - OrderNo: {orderNo}, Error: {ex.Message}");
- }
- }
- }
-
+
#endregion
#region 绌烘墭鐩�
@@ -2157,7 +1931,7 @@
{
try
{
- // 1. 鏌ユ壘鎵�鏈変笌璇ヨ鍗曞拰鎵樼洏鐩稿叧鐨勪换鍔�
+ // 鏌ユ壘鎵�鏈変笌璇ヨ鍗曞拰鎵樼洏鐩稿叧鐨勪换鍔�
var tasks = await _taskRepository.Db.Queryable<Dt_Task>().Where(x => x.OrderNo == orderNo && x.PalletCode == palletCode).ToListAsync();
if (tasks.Any())
@@ -2210,7 +1984,7 @@
_logger.LogInformation($"璁㈠崟 {orderNo} 杩樻湁鍏朵粬鎵樼洏鍦ㄥ鐞嗭紝涓嶆洿鏂拌鍗曠姸鎬�");
}
- // 3. 鏇存柊鎷i�夎褰曠姸鎬侊紙鍙�夛級
+ // 鏇存柊鎷i�夎褰曠姸鎬侊紙鍙�夛級
await UpdatePickingRecordsStatus(orderNo, palletCode);
}
@@ -2253,8 +2027,6 @@
_logger.LogInformation($"璁㈠崟 {orderNo} 宸叉爣璁颁负鍑哄簱瀹屾垚");
- // 鍚慚ES鍙嶉璁㈠崟瀹屾垚锛堝鏋滈渶瑕侊級
- //await HandleOrderCompletion(outboundOrder, orderNo);
}
}
@@ -2272,7 +2044,6 @@
// 杩欓噷鍙互鏍规嵁闇�瑕佹洿鏂版嫞閫夎褰曠殑鐘舵�佸瓧娈�
// 渚嬪锛歱ickingRecord.Status = (int)PickingStatusEnum.宸插畬鎴�;
-
_logger.LogInformation($"鎵惧埌{pickingRecords.Count}鏉℃嫞閫夎褰� - 璁㈠崟: {orderNo}, 鎵樼洏: {palletCode}");
}
@@ -2372,89 +2143,7 @@
return result;
}
-
- /// <summary>
- /// 妫�鏌ユ墭鐩樻槸鍚︿负绌�
- /// </summary>
- private async Task<bool> IsPalletEmpty(string orderNo, string palletCode)
- {
- try
- {
- // 鑾峰彇搴撳瓨淇℃伅
- var stockInfo = await _stockInfoService.Db.Queryable<Dt_StockInfo>()
- .Where(x => x.PalletCode == palletCode)
- .FirstAsync();
-
- if (stockInfo == null)
- return false;
-
- // 浣跨敤缁熶竴鐨勭姸鎬佸垎鏋�
- var statusAnalysis = await AnalyzePalletStatus(orderNo, palletCode, stockInfo.Id);
- return statusAnalysis.IsEmptyPallet;
- }
- catch (Exception ex)
- {
- _logger.LogWarning($"妫�鏌ユ墭鐩樻槸鍚︿负绌哄け璐� - OrderNo: {orderNo}, PalletCode: {palletCode}, Error: {ex.Message}");
- return false;
- }
- }
- /// <summary>
- /// 妫�鏌ュ苟澶勭悊绌烘墭鐩�
- /// </summary>
- private async Task<bool> CheckAndHandleEmptyPallet(string orderNo, string palletCode)
- {
- try
- {
- // 1. 鑾峰彇搴撳瓨淇℃伅
- var stockInfo = await _stockInfoService.Db.Queryable<Dt_StockInfo>()
- .Where(x => x.PalletCode == palletCode)
- .FirstAsync();
-
- if (stockInfo == null)
- {
- _logger.LogWarning($"鏈壘鍒版墭鐩� {palletCode} 鐨勫簱瀛樹俊鎭�");
- return false;
- }
-
- // 2. 浣跨敤缁熶竴鐨勭姸鎬佸垎鏋�
- var statusAnalysis = await AnalyzePalletStatus(orderNo, palletCode, stockInfo.Id);
-
- // 3. 妫�鏌ユ槸鍚︿负绌烘墭鐩樹笖娌℃湁杩涜涓殑浠诲姟
- if (!statusAnalysis.IsEmptyPallet || statusAnalysis.HasActiveTasks)
- {
- return false;
- }
-
- _logger.LogInformation($"妫�娴嬪埌绌烘墭鐩橈紝寮�濮嬭嚜鍔ㄥ鐞� - 璁㈠崟: {orderNo}, 鎵樼洏: {palletCode}");
-
- //// 娓呯悊闆跺簱瀛樻暟鎹�
- //await CleanupZeroStockData(stockInfo.Id);
-
- //// 鏇存柊搴撳瓨涓昏〃鐘舵�佷负绌烘墭鐩�
- //await UpdateStockInfoAsEmpty(stockInfo);
-
- //// 澶勭悊鍑哄簱閿佸畾璁板綍
- //await HandleOutStockLockRecords(orderNo, palletCode);
-
- //// 澶勭悊浠诲姟鐘舵��
- //await HandleTaskStatusForEmptyPallet(orderNo, palletCode);
-
- //// 鏇存柊璁㈠崟鏁版嵁
- //await UpdateOrderDataForEmptyPallet(orderNo, palletCode);
-
- ////璁板綍鎿嶄綔鍘嗗彶
- //await RecordAutoEmptyPalletOperation(orderNo, palletCode);
-
- _logger.LogInformation($"绌烘墭鐩樿嚜鍔ㄥ鐞嗗畬鎴� - 璁㈠崟: {orderNo}, 鎵樼洏: {palletCode}");
-
- return true;
- }
- catch (Exception ex)
- {
- _logger.LogError($"鑷姩澶勭悊绌烘墭鐩樺け璐� - OrderNo: {orderNo}, PalletCode: {palletCode}, Error: {ex.Message}");
- return false;
- }
- }
+
private async Task<string> GenerateNewBarcode()
{
@@ -2565,11 +2254,6 @@
record.Status = (int)SplitPackageStatusEnum.宸叉嫞閫�;
await _splitPackageService.Db.Updateable(record).ExecuteCommandAsync();
}
- }
-
- private async Task<int> GenerateTaskNumber()
- {
- return await _dailySequenceService.GetNextSequenceAsync();
}
private WebResponseContent CreatePickingResponse(PickingResult result, string adjustedReason)
@@ -3224,8 +2908,6 @@
#endregion
}
-
-
#region 鏀寔绫诲畾涔�
public class ValidationResult<T>
@@ -3262,20 +2944,6 @@
public List<SplitResult> SplitResults { get; set; } = new List<SplitResult>();
}
- public class ReturnAnalysisResult
- {
- public bool HasItemsToReturn { get; set; }
- public bool HasRemainingLocks { get; set; }
- public bool HasPalletStockGoods { get; set; }
- public bool HasSplitRecords { get; set; }
- public decimal RemainingLocksReturnQty { get; set; }
- public decimal PalletStockReturnQty { get; set; }
- public decimal SplitReturnQty { get; set; }
- public decimal TotalReturnQty { get; set; }
- public List<Dt_OutStockLockInfo> RemainingLocks { get; set; } = new List<Dt_OutStockLockInfo>();
- public List<Dt_StockInfoDetail> PalletStockGoods { get; set; } = new List<Dt_StockInfoDetail>();
- public List<Dt_SplitPackageRecord> SplitRecords { get; set; } = new List<Dt_SplitPackageRecord>();
- }
public class PalletStatusAnalysis
{
public string OrderNo { get; set; }
@@ -3302,7 +2970,7 @@
public List<Dt_StockInfoDetail> PalletStockGoods { get; set; } = new List<Dt_StockInfoDetail>();
public List<Dt_SplitPackageRecord> SplitRecords { get; set; } = new List<Dt_SplitPackageRecord>();
- // 銆愭柊澧炪�戝凡澶勭悊鐨勬潯鐮侀泦鍚堬紙鐢ㄤ簬閬垮厤閲嶅锛�
+ // 宸插鐞嗙殑鏉$爜闆嗗悎锛堢敤浜庨伩鍏嶉噸澶嶏級
public HashSet<string> ProcessedBarcodes { get; set; } = new HashSet<string>();
public List<string> AllBarcodes { get; set; } = new List<string>();
// 绌烘墭鐩樼浉鍏冲睘鎬�
@@ -3313,18 +2981,7 @@
public bool CanReturn => HasItemsToReturn && !HasActiveTasks;
public bool CanRemove => IsEmptyPallet && !HasActiveTasks;
}
- public class PickingContext
- {
- public string OrderNo { get; set; }
- public string PalletCode { get; set; }
- public string Barcode { get; set; }
- public string Operator { get; set; }
- public Dt_OutStockLockInfo LockInfo { get; set; }
- public Dt_OutboundOrderDetail OrderDetail { get; set; }
- public Dt_StockInfoDetail StockDetail { get; set; }
- public decimal ActualQuantity { get; set; }
- public string AdjustedReason { get; set; }
- }
+
public class CancelPickingContext
{
public string OrderNo { get; set; }
--
Gitblit v1.9.3