From 51579a9535b27cdf71cd6d1a8e5d45c581d49467 Mon Sep 17 00:00:00 2001
From: pan <antony1029@163.com>
Date: 星期五, 21 十一月 2025 15:28:50 +0800
Subject: [PATCH] 提交
---
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundPickingService.cs | 310 +++++++++++++++++++++++++++++++++------------------
1 files changed, 202 insertions(+), 108 deletions(-)
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundPickingService.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundPickingService.cs"
index b511d51..4c19d90 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"
@@ -251,42 +251,19 @@
}
}
-
-
-
public async Task<WebResponseContent> ConfirmPicking(string orderNo, string palletCode, string barcode)
{
- #region "娴嬭瘯鎵撳嵃"
- // var splitResults=new List<SplitResult>();
- // splitResults.Add(new SplitResult
- //{
- // materialCode = "AAAAbbb",
- // supplierCode = "CVBG",
- // quantityTotal = "1234",
- // batchNumber = "WMLOT25111900032",
- // batch = "A234re",
- // factory = "01",
- // date = DateTime.Now.ToString("yyyy-MM-dd"),
- //});
-
- //splitResults.Add(new SplitResult
- //{
- // materialCode = "CCDF",
- // supplierCode = "QWCVBG",
- // quantityTotal = "1234",
- // batchNumber = "WMLOT25111900032",
- // batch = "A234re",
- // factory = "01",
- // date = DateTime.Now.ToString("yyyy-MM-dd"),
- //});
-
- // return WebResponseContent.Instance.OK("鎷i�夌‘璁ゆ垚鍔燂紝宸茶嚜鍔ㄦ媶鍖�", new { SplitResults = splitResults });
- #endregion
try
{
_unitOfWorkManage.BeginTran();
- // 1. 鏌ユ壘鍑哄簱閿佸畾淇℃伅
+ // 1. 楠岃瘉杈撳叆鍙傛暟
+ if (string.IsNullOrEmpty(orderNo) || string.IsNullOrEmpty(palletCode) || string.IsNullOrEmpty(barcode))
+ {
+ throw new Exception("璁㈠崟鍙枫�佹墭鐩樼爜鍜屾潯鐮佷笉鑳戒负绌�");
+ }
+
+ // 2. 鏌ユ壘鍑哄簱閿佸畾淇℃伅
var lockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
.Where(it => it.OrderNo == orderNo &&
it.Status == (int)OutLockStockStatusEnum.鍑哄簱涓� &&
@@ -334,12 +311,28 @@
throw new Exception($"鏉$爜{barcode}宸茬粡鍒嗘嫞杩囷紝涓嶈兘閲嶅鍒嗘嫞");
}
- var outorderdetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
+ // 鑾峰彇璁㈠崟鏄庣粏骞舵鏌ユ暟閲忛檺鍒�
+ var orderDetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
.FirstAsync(x => x.Id == lockInfo.OrderDetailId);
- if (outorderdetail != null && (lockInfo.AssignQuantity + outorderdetail.OverOutQuantity) > outorderdetail.NeedOutQuantity)
+ if (orderDetail == null)
+ throw new Exception($"鏈壘鍒拌鍗曟槑缁嗭紝ID: {lockInfo.OrderDetailId}");
+
+ // 鍏抽敭淇锛氭鏌ョ疮璁℃嫞閫夋暟閲忔槸鍚︿細瓒呰繃璁㈠崟鏁伴噺
+ decimal actualQty = lockInfo.AssignQuantity - lockInfo.PickedQty;
+ decimal remainingOrderQty = orderDetail.NeedOutQuantity - orderDetail.OverOutQuantity;
+
+ if (actualQty > remainingOrderQty)
{
- throw new Exception($"鏉$爜{barcode}鐨勫嚭搴撴暟閲忓皢瀵艰嚧璁㈠崟鏄庣粏宸插嚭搴撴暟閲忚秴杩囬渶姹傛暟閲�");
+ // 濡傛灉鍒嗛厤鏁伴噺澶т簬鍓╀綑璁㈠崟鏁伴噺锛岃皟鏁村疄闄呮嫞閫夋暟閲�
+ actualQty = remainingOrderQty;
+
+ if (actualQty <= 0)
+ {
+ throw new Exception($"璁㈠崟{orderNo}鐨勯渶姹傛暟閲忓凡婊¤冻锛屾棤娉曠户缁垎鎷�");
+ }
+
+ _logger.LogWarning($"璋冩暣鍒嗘嫞鏁伴噺锛氬師鍒嗛厤{lockInfo.AssignQuantity - lockInfo.PickedQty}锛岃皟鏁翠负{actualQty}锛岃鍗曢渶姹倇orderDetail.NeedOutQuantity}锛屽凡鍑哄簱{orderDetail.OverOutQuantity}");
}
var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
@@ -349,27 +342,29 @@
if (stockDetail == null)
return WebResponseContent.Instance.Error("鏃犳晥鐨勬潯鐮佹垨鐗╂枡缂栫爜");
- decimal actualQty = lockInfo.AssignQuantity - lockInfo.PickedQty;
decimal stockQuantity = stockDetail.StockQuantity;
List<SplitResult> splitResults = new List<SplitResult>();
Dt_OutStockLockInfo finalLockInfo = lockInfo;
var finalBarcode = barcode;
var finalStockId = stockDetail.Id;
- decimal actualPickedQty = actualQty; // 瀹為檯鎷i�夋暟閲�
+ decimal actualPickedQty = actualQty;
if (actualQty < stockQuantity)
{
// 鎯呭喌1: 鍒嗛厤鏁伴噺灏忎簬搴撳瓨鏁伴噺锛岄渶瑕佽嚜鍔ㄦ媶鍖�
decimal remainingStockQty = stockQuantity - actualQty;
+ // 鏇存柊鍘熸潯鐮佸簱瀛樹负鍓╀綑鏁伴噺
stockDetail.StockQuantity = remainingStockQty;
stockDetail.OutboundQuantity = remainingStockQty;
await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync();
+ // 鐢熸垚鏂版潯鐮佺敤浜庤褰曟嫞閫夋暟閲�
var seq = await _dailySequenceService.GetNextSequenceAsync();
string newBarcode = "WSLOT" + DateTime.Now.ToString("yyyyMMdd") + seq.ToString()?.PadLeft(5, '0');
+ // 涓烘柊鏉$爜鍒涘缓鍑哄簱閿佸畾淇℃伅
var newLockInfo = new Dt_OutStockLockInfo
{
OrderNo = lockInfo.OrderNo,
@@ -398,6 +393,7 @@
var newLockId = await _outStockLockInfoService.Db.Insertable(newLockInfo).ExecuteReturnIdentityAsync();
newLockInfo.Id = newLockId;
+ // 璁板綍鎷嗗寘鍘嗗彶
var splitHistory = new Dt_SplitPackageRecord
{
FactoryArea = lockInfo.FactoryArea,
@@ -418,6 +414,7 @@
};
await _splitPackageService.Db.Insertable(splitHistory).ExecuteCommandAsync();
+ // 鏇存柊鍘熼攣瀹氫俊鎭负鍓╀綑搴撳瓨鏁伴噺
lockInfo.AssignQuantity = remainingStockQty;
lockInfo.PickedQty = 0;
await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync();
@@ -444,11 +441,8 @@
date = DateTime.Now.ToString("yyyy-MM-dd"),
});
- barcode = newBarcode;
- lockInfo = newLockInfo;
finalLockInfo = newLockInfo;
finalBarcode = newBarcode;
- finalStockId = stockDetail.Id;
}
else if (actualQty == stockQuantity)
{
@@ -460,10 +454,6 @@
lockInfo.PickedQty += actualQty;
lockInfo.Status = (int)OutLockStockStatusEnum.鎷i�夊畬鎴�;
await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync();
-
- finalLockInfo = lockInfo;
- finalBarcode = barcode;
- finalStockId = stockDetail.Id;
}
else
{
@@ -478,29 +468,35 @@
lockInfo.AssignQuantity = remainingAssignQty;
await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync();
- var _relatedSplitRecords = await _splitPackageService.Db.Queryable<Dt_SplitPackageRecord>()
+ var relatedSplitRecords = await _splitPackageService.Db.Queryable<Dt_SplitPackageRecord>()
.Where(it => it.OriginalBarcode == barcode || it.NewBarcode == barcode)
.Where(it => !it.IsReverted)
.ToListAsync();
- foreach (var record in _relatedSplitRecords)
+ foreach (var record in relatedSplitRecords)
{
record.Status = (int)SplitPackageStatusEnum.宸叉嫞閫�;
await _splitPackageService.Db.Updateable(record).ExecuteCommandAsync();
}
- finalLockInfo = lockInfo;
- finalBarcode = barcode;
- finalStockId = stockDetail.Id;
- actualPickedQty = stockOutQty; // 瀹為檯鎷i�夋暟閲忚皟鏁翠负搴撳瓨鏁伴噺
+ actualPickedQty = stockOutQty;
}
- // 鏇存柊璁㈠崟鏄庣粏鐨勬嫞閫夋暟閲忓拰宸插嚭搴撴暟閲�
+ // 鍏抽敭淇锛氬啀娆℃鏌ヨ鍗曟暟閲忛檺鍒�
+ decimal newOverOutQuantity = orderDetail.OverOutQuantity + actualPickedQty;
+ decimal newPickedQty = orderDetail.PickedQty + actualPickedQty;
+
+ if (newOverOutQuantity > orderDetail.NeedOutQuantity)
+ {
+ throw new Exception($"鍒嗘嫞鍚庡皢瀵艰嚧宸插嚭搴撴暟閲�({newOverOutQuantity})瓒呰繃璁㈠崟闇�姹傛暟閲�({orderDetail.NeedOutQuantity})");
+ }
+
+ // 鏇存柊璁㈠崟鏄庣粏
await _outboundOrderDetailService.Db.Updateable<Dt_OutboundOrderDetail>()
.SetColumns(it => new Dt_OutboundOrderDetail
{
- PickedQty = it.PickedQty + actualPickedQty,
- OverOutQuantity = it.OverOutQuantity + actualPickedQty
+ PickedQty = newPickedQty,
+ OverOutQuantity = newOverOutQuantity
})
.Where(it => it.Id == lockInfo.OrderDetailId)
.ExecuteCommandAsync();
@@ -541,7 +537,7 @@
return WebResponseContent.Instance.OK("鎷i�夌‘璁ゆ垚鍔燂紝宸茶嚜鍔ㄦ媶鍖�", new { SplitResults = splitResults });
}
- return WebResponseContent.Instance.OK("鎷i�夌‘璁ゆ垚鍔�");
+ return WebResponseContent.Instance.OK("鎷i�夌‘璁ゆ垚鍔�", new { SplitResults = new List<SplitResult>() });
}
catch (Exception ex)
@@ -551,6 +547,159 @@
return WebResponseContent.Instance.Error($"鎷i�夌‘璁ゅけ璐ワ細{ex.Message}");
}
}
+
+ public async Task<WebResponseContent> CancelPicking(string orderNo, string palletCode, string barcode)
+ {
+ try
+ {
+ _unitOfWorkManage.BeginTran();
+
+ // 鏌ユ壘鎷i�夎褰�
+ var pickingRecord = await Db.Queryable<Dt_PickingRecord>()
+ .Where(it => it.OrderNo == orderNo &&
+ it.PalletCode == palletCode &&
+ it.Barcode == barcode)
+ .OrderByDescending(it => it.PickTime)
+ .FirstAsync();
+
+ if (pickingRecord == null)
+ return WebResponseContent.Instance.Error("鏈壘鍒板搴旂殑鎷i�夎褰�");
+
+ // 鏌ユ壘鍑哄簱閿佸畾淇℃伅
+ var lockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+ .Where(it => it.Id == pickingRecord.OutStockLockId)
+ .FirstAsync();
+
+ if (lockInfo == null)
+ return WebResponseContent.Instance.Error("鏈壘鍒板搴旂殑鍑哄簱閿佸畾淇℃伅");
+
+ // 妫�鏌ユ槸鍚﹀彲浠ュ彇娑�
+ if (lockInfo.Status != (int)OutLockStockStatusEnum.鎷i�夊畬鎴�)
+ return WebResponseContent.Instance.Error("褰撳墠鐘舵�佷笉鍏佽鍙栨秷鍒嗘嫞");
+
+ decimal cancelQty = pickingRecord.PickQuantity;
+
+ // 鑾峰彇璁㈠崟鏄庣粏
+ var orderDetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
+ .FirstAsync(x => x.Id == pickingRecord.OrderDetailId);
+
+ if (orderDetail == null)
+ throw new Exception($"鏈壘鍒拌鍗曟槑缁嗭紝ID: {pickingRecord.OrderDetailId}");
+
+ // 鍏抽敭淇锛氭鏌ュ彇娑堝悗鏁伴噺涓嶄細涓鸿礋鏁�
+ decimal newOverOutQuantity = orderDetail.OverOutQuantity - cancelQty;
+ decimal newPickedQty = orderDetail.PickedQty - cancelQty;
+
+ if (newOverOutQuantity < 0 || newPickedQty < 0)
+ {
+ throw new Exception($"鍙栨秷鍒嗘嫞灏嗗鑷村凡鍑哄簱鏁伴噺鎴栧凡鎷i�夋暟閲忎负璐熸暟");
+ }
+
+ // 澶勭悊鍙栨秷閫昏緫
+ if (lockInfo.IsSplitted == 1 && lockInfo.ParentLockId.HasValue)
+ {
+ await HandleSplitBarcodeCancel(lockInfo, pickingRecord, cancelQty);
+ }
+ else
+ {
+ await HandleNormalBarcodeCancel(lockInfo, pickingRecord, cancelQty);
+ }
+
+ // 鏇存柊璁㈠崟鏄庣粏
+ await _outboundOrderDetailService.Db.Updateable<Dt_OutboundOrderDetail>()
+ .SetColumns(it => new Dt_OutboundOrderDetail
+ {
+ PickedQty = newPickedQty,
+ OverOutQuantity = newOverOutQuantity
+ })
+ .Where(it => it.Id == pickingRecord.OrderDetailId)
+ .ExecuteCommandAsync();
+
+ // 鍒犻櫎鎷i�夎褰�
+ await Db.Deleteable<Dt_PickingRecord>()
+ .Where(x => x.Id == pickingRecord.Id)
+ .ExecuteCommandAsync();
+
+ // 閲嶆柊妫�鏌ヨ鍗曠姸鎬�
+ await CheckAndUpdateOrderStatus(orderNo);
+
+ _unitOfWorkManage.CommitTran();
+ return WebResponseContent.Instance.OK($"鍙栨秷鍒嗘嫞鎴愬姛锛屾仮澶嶆暟閲忥細{cancelQty}");
+ }
+ catch (Exception ex)
+ {
+ _unitOfWorkManage.RollbackTran();
+ _logger.LogError($"CancelPicking澶辫触 - OrderNo: {orderNo}, PalletCode: {palletCode}, Barcode: {barcode}, Error: {ex.Message}");
+ return WebResponseContent.Instance.Error($"鍙栨秷鍒嗘嫞澶辫触锛歿ex.Message}");
+ }
+ }
+
+ private async Task HandleSplitBarcodeCancel(Dt_OutStockLockInfo lockInfo, Dt_PickingRecord pickingRecord, decimal cancelQty)
+ {
+ // 鏌ユ壘鐖堕攣瀹氫俊鎭�
+ var parentLockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+ .Where(x => x.Id == lockInfo.ParentLockId.Value)
+ .FirstAsync();
+
+ if (parentLockInfo == null)
+ {
+ throw new Exception("鏈壘鍒扮埗閿佸畾淇℃伅锛屾棤娉曞彇娑堟媶鍖呭垎鎷�");
+ }
+
+ // 鎭㈠鐖堕攣瀹氫俊鎭殑鍒嗛厤鏁伴噺
+ parentLockInfo.AssignQuantity += cancelQty;
+ await _outStockLockInfoService.Db.Updateable(parentLockInfo).ExecuteCommandAsync();
+
+ // 鎭㈠搴撳瓨
+ var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
+ .Where(x => x.Barcode == parentLockInfo.CurrentBarcode && x.StockId == parentLockInfo.StockId)
+ .FirstAsync();
+
+ if (stockDetail != null)
+ {
+ stockDetail.StockQuantity += cancelQty;
+ stockDetail.OutboundQuantity += cancelQty;
+ await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync();
+ }
+
+ // 鏇存柊鎷嗗寘璁板綍鐘舵��
+ await _splitPackageService.Db.Updateable<Dt_SplitPackageRecord>()
+ .SetColumns(x => new Dt_SplitPackageRecord
+ {
+ Status = (int)SplitPackageStatusEnum.宸叉挙閿�,
+ IsReverted = true
+ })
+ .Where(x => x.NewBarcode == lockInfo.CurrentBarcode && !x.IsReverted)
+ .ExecuteCommandAsync();
+
+ // 鍒犻櫎鎷嗗寘浜х敓鐨勯攣瀹氫俊鎭�
+ await _outStockLockInfoService.Db.Deleteable<Dt_OutStockLockInfo>()
+ .Where(x => x.Id == lockInfo.Id)
+ .ExecuteCommandAsync();
+ }
+
+ private async Task HandleNormalBarcodeCancel(Dt_OutStockLockInfo lockInfo, Dt_PickingRecord pickingRecord, decimal cancelQty)
+ {
+ // 鎭㈠閿佸畾淇℃伅
+ lockInfo.PickedQty -= cancelQty;
+ if (lockInfo.PickedQty < 0) lockInfo.PickedQty = 0;
+
+ lockInfo.Status = (int)OutLockStockStatusEnum.鍑哄簱涓�;
+ await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync();
+
+ // 鎭㈠搴撳瓨
+ var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
+ .Where(x => x.Barcode == pickingRecord.Barcode && x.StockId == pickingRecord.StockId)
+ .FirstAsync();
+
+ if (stockDetail != null)
+ {
+ stockDetail.StockQuantity += cancelQty;
+ stockDetail.OutboundQuantity += cancelQty;
+ await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync();
+ }
+ }
+
/// <summary>
/// 鍥炲簱鎿嶄綔
/// </summary>
@@ -894,62 +1043,7 @@
return outboundFinished && hasRemainingGoods;
}
- // 鍙栨秷鎷i�夊姛鑳�
- public async Task<WebResponseContent> CancelPicking(string orderNo, string palletCode, string barcode)
- {
- try
- {
- _unitOfWorkManage.BeginTran();
-
- //鏌ユ壘鎷i�夎褰�
- var pickingRecord = await Db.Queryable<Dt_PickingRecord>()
- .Where(it => it.OrderNo == orderNo &&
- it.PalletCode == palletCode &&
- it.Barcode == barcode)
- .OrderByDescending(it => it.PickTime)
- .FirstAsync();
-
- if (pickingRecord == null)
- return WebResponseContent.Instance.Error("鏈壘鍒板搴旂殑鎷i�夎褰�");
-
- // 鏌ユ壘鍑哄簱閿佸畾淇℃伅
- var lockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
- .Where(it => it.Id == pickingRecord.OutStockLockId)
- .FirstAsync();
-
- if (lockInfo == null)
- return WebResponseContent.Instance.Error("鏈壘鍒板搴旂殑鍑哄簱閿佸畾淇℃伅");
-
- //妫�鏌ユ槸鍚﹀彲浠ュ彇娑堬紙鐘舵�佸繀椤绘槸鎷i�夊畬鎴愶級
- if (lockInfo.Status != (int)OutLockStockStatusEnum.鎷i�夊畬鎴�)
- return WebResponseContent.Instance.Error("褰撳墠鐘舵�佷笉鍏佽鍙栨秷鍒嗘嫞");
-
- decimal cancelQty = pickingRecord.PickQuantity;
-
- // 妫�鏌ユ媶鍖呴摼鍏崇郴
- var splitChain = await GetSplitChain(barcode);
-
- if (splitChain.Any())
- {
- // 鎯呭喌A锛氬鐞嗘媶鍖呴摼鐨勫彇娑堬紙澶氭鎵嬪姩鎷嗗寘锛�
- await HandleSplitChainCancel(orderNo, palletCode, barcode, cancelQty, lockInfo, pickingRecord, splitChain);
- }
- else
- {
- // 鎯呭喌B锛氬鐞嗘櫘閫氭潯鐮佺殑鍙栨秷
- await HandleNormalBarcodeCancel(orderNo, palletCode, barcode, cancelQty, lockInfo, pickingRecord);
- }
-
- _unitOfWorkManage.CommitTran();
- return WebResponseContent.Instance.OK($"鍙栨秷鍒嗘嫞鎴愬姛锛屾仮澶嶆暟閲忥細{cancelQty}");
- }
- catch (Exception ex)
- {
- _unitOfWorkManage.RollbackTran();
- return WebResponseContent.Instance.Error($"鍙栨秷鍒嗘嫞澶辫触锛歿ex.Message}");
- }
- }
-
+
/// <summary>
/// 鑾峰彇鎷嗗寘閾撅紙浠庡綋鍓嶆潯鐮佽拷婧埌鍘熷鏉$爜锛�
/// </summary>
--
Gitblit v1.9.3