From 4a890499facf5b702b37966429d68d2bbdf363f0 Mon Sep 17 00:00:00 2001
From: pan <antony1029@163.com>
Date: 星期五, 21 十一月 2025 20:12:28 +0800
Subject: [PATCH] 提交
---
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Outbound/OutboundPickingController.cs | 56 -
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundPickingService.cs | 2243 +++++++++++++++++++++-----------------------------------
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_IOutboundService/IOutboundPickingService.cs | 15
3 files changed, 858 insertions(+), 1,456 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_IOutboundService/IOutboundPickingService.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_IOutboundService/IOutboundPickingService.cs"
index affec24..860e955 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_IOutboundService/IOutboundPickingService.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_IOutboundService/IOutboundPickingService.cs"
@@ -15,17 +15,14 @@
{
IRepository<Dt_PickingRecord> Repository { get; }
- Task<WebResponseContent> CancelPicking(string orderNo, string palletCode, string barcode);
- Task<bool> CheckPalletNeedReturn(string orderNo, string palletCode);
- Task<WebResponseContent> ConfirmPicking(string orderNo, string palletCode, string barcode);
- Task<WebResponseContent> DirectOutbound(DirectOutboundRequest request);
- Task<List<OutStockLockListResp>> GetOutStockLockListAsync(string orderNo);
- Task<WebResponseContent> GetPalletOutboundStatus(string palletCode);
- Task<List<Dt_OutStockLockInfo>> GetPickedList(string orderNo, string palletCode);
- Task<List<Dt_PickingRecord>> GetPickingHistory(int orderId);
Task<object> GetPickingSummary(ConfirmPickingDto dto);
+
Task<List<Dt_OutStockLockInfo>> GetUnpickedList(string orderNo, string palletCode);
+
+ Task<List<Dt_OutStockLockInfo>> GetPickedList(string orderNo, string palletCode);
+
+ Task<WebResponseContent> CancelPicking(string orderNo, string palletCode, string barcode);
+ Task<WebResponseContent> ConfirmPicking(string orderNo, string palletCode, string barcode);
Task<WebResponseContent> ReturnRemaining(string orderNo, string palletCode, string reason);
- Task<WebResponseContent> ValidateBarcode(string barcode);
}
}
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 4deb21d..a33a17c 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"
@@ -85,171 +85,69 @@
_dailySequenceService = dailySequenceService;
}
-
- #region 鏌ヨ鍑哄簱璇︽儏鍒楄〃
- public async Task<List<OutStockLockListResp>> GetOutStockLockListAsync(string orderNo)
+ // 鑾峰彇鏈嫞閫夊垪琛�
+ public async Task<List<Dt_OutStockLockInfo>> GetUnpickedList(string orderNo, string palletCode)
{
- var locks = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
- .Where(t => t.OrderNo == orderNo)
+ var list = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+ .Where(x => x.OrderNo == orderNo &&
+ x.PalletCode == palletCode &&
+ x.Status == 1)
.ToListAsync();
-
- return locks.Select(t => new OutStockLockListResp
- {
- Id = t.Id,
- // TaskNum = t.TaskNum,
- PalletCode = t.PalletCode,
- CurrentBarcode = t.CurrentBarcode,
- AssignQuantity = t.AssignQuantity,
- PickedQty = t.PickedQty,
- Status = t.Status,
- // IsSplitted = t.IsSplitted
- }).ToList();
+ return list.Where(x => x.RemainQuantity > 0).ToList();
}
- #endregion
- public async Task<WebResponseContent> ValidateBarcode(string barcode)
+
+ // 鑾峰彇宸叉嫞閫夊垪琛�
+ public async Task<List<Dt_OutStockLockInfo>> GetPickedList(string orderNo, string palletCode)
{
- try
- {
- if (string.IsNullOrEmpty(barcode))
- {
- return WebResponseContent.Instance.Error("鏉$爜涓嶈兘涓虹┖");
- }
-
- // 鏍规嵁鏉$爜鏌ヨ搴撳瓨鏄庣粏
- var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
- .Includes(x => x.StockInfo)
- .Where(x => x.Barcode == barcode)
- .FirstAsync();
-
- if (stockDetail == null)
- {
- return WebResponseContent.Instance.Error("鏉$爜涓嶅瓨鍦�");
- }
-
-
-
- var result = new
- {
- Barcode = barcode,
- MaterielCode = stockDetail.MaterielCode,
-
- BatchNo = stockDetail.BatchNo,
- AvailableQuantity = stockDetail.StockQuantity - stockDetail.OutboundQuantity,
- LocationCode = stockDetail.StockInfo?.LocationCode,
- PalletCode = stockDetail.StockInfo?.PalletCode
- };
-
- return WebResponseContent.Instance.OK(null, result);
- }
- catch (Exception ex)
- {
- return WebResponseContent.Instance.Error($"鏉$爜楠岃瘉澶辫触: {ex.Message}");
- }
+ var list = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+ .Where(x => x.OrderNo == orderNo &&
+ x.PalletCode == palletCode &&
+ x.Status == 6)
+ .ToListAsync();
+ return list;
}
-
- // 妫�鏌ュ苟鏇存柊璁㈠崟鐘舵��
- private async Task CheckAndUpdateOrderStatus(string orderNo)
+ // 鑾峰彇鎷i�夋眹鎬�
+ public async Task<object> GetPickingSummary(ConfirmPickingDto dto)
{
-
- var orderDetails = _stockInfoDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
- .LeftJoin<Dt_OutboundOrder>((o, item) => o.OrderId == item.Id) // 鍏宠仈鏉′欢锛氱埗琛� Id = 瀛愯〃 OrderId
- .Where((o, item) => item.OrderNo == orderNo) // 杩囨护鐖惰〃 OrderNo
- .Select((o, item) => o) // 鍙繑鍥炲瓙琛ㄦ暟鎹�
- .ToList();
-
- //var orderDetails = await _stockInfoDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
- // .Where(x => x.OrderId == orderNo.ObjToInt())
- // .ToListAsync();
-
- bool allCompleted = true;
- foreach (var detail in orderDetails)
+ var picked = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+ .WhereIF(!string.IsNullOrEmpty(dto.OrderNo), x => x.OrderNo == dto.OrderNo)
+ .WhereIF(!string.IsNullOrEmpty(dto.PalletCode), x => x.PalletCode == dto.PalletCode)
+ .Where(x => x.Status == 6)
+ .GroupBy(x => new { x.PalletCode, x.MaterielCode })
+ .Select(x => new SummaryPickingDto
+ {
+ PalletCode = x.PalletCode,
+ MaterielCode = x.MaterielCode,
+ pickedCount = SqlFunc.AggregateCount(x.Id)
+ }).FirstAsync();
+ if (picked == null)
{
- if (detail.OverOutQuantity < detail.NeedOutQuantity)
- {
- allCompleted = false;
- break;
- }
+ picked = new SummaryPickingDto { pickedCount = 0 };
}
- if (allCompleted)
+ var summary = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+ .WhereIF(!string.IsNullOrEmpty(dto.OrderNo), x => x.OrderNo == dto.OrderNo)
+ .WhereIF(!string.IsNullOrEmpty(dto.PalletCode), x => x.PalletCode == dto.PalletCode)
+ .Where(x => x.Status == 1)
+ .GroupBy(x => new { x.PalletCode, x.MaterielCode })
+ .Select(x => new SummaryPickingDto
+ {
+ PalletCode = x.PalletCode,
+ MaterielCode = x.MaterielCode,
+ UnpickedCount = SqlFunc.AggregateCount(x.Id),
+ UnpickedQuantity = SqlFunc.AggregateSum(x.AssignQuantity) - SqlFunc.AggregateSum(x.PickedQty),
+
+ }).FirstAsync();
+ if (summary == null)
{
- try
- {
- await _outboundOrderService.Db.Updateable<Dt_OutboundOrder>()
- .SetColumns(x => x.OrderStatus == 2) // 宸插畬鎴�
- .Where(x => x.OrderNo == orderNo)
- .ExecuteCommandAsync();
-
- var outboundOrder = _stockInfoService.Db.Queryable<Dt_OutboundOrder>().First(x => x.OrderNo == orderNo);
-
-
- if (outboundOrder != null && outboundOrder.OrderStatus == OutOrderStatusEnum.鍑哄簱瀹屾垚.ObjToInt())
- {
-
- if (outboundOrder.OrderType == OutOrderTypeEnum.Allocate.ObjToInt().ObjToInt())//璋冩嫧鍑哄簱
- {
-
- }
- else if (outboundOrder.OrderType == OutOrderTypeEnum.ReCheck.ObjToInt()) //閲嶆鍑哄簱
- {
-
- }
- else
- {
- var feedmodel = new FeedbackOutboundRequestModel
- {
- reqCode = Guid.NewGuid().ToString(),
- reqTime = DateTime.Now.ToString(),
- business_type = outboundOrder.BusinessType,
- factoryArea = outboundOrder.FactoryArea,
- operationType = 1,
- Operator = outboundOrder.Operator,
- orderNo = outboundOrder.UpperOrderNo,
- status = outboundOrder.OrderStatus,
- details = new List<FeedbackOutboundDetailsModel>()
-
- };
- var lists = _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>().Where(x => x.OrderNo == orderNo && x.Status == (int)OutLockStockStatusEnum.鎷i�夊畬鎴�).ToList();
-
- var groupedData = lists.GroupBy(item => new { item.MaterielCode, item.lineNo, item.Unit, item.WarehouseCode })
- .Select(group => new FeedbackOutboundDetailsModel
- {
- materialCode = group.Key.MaterielCode,
- lineNo = group.Key.lineNo,
- warehouseCode = group.Key.WarehouseCode,
- currentDeliveryQty = group.Sum(x => x.OrderQuantity),
- // warehouseCode= "1072",
- unit = group.Key.Unit,
- barcodes = group.Select(row => new WIDESEA_DTO.Outbound.BarcodesModel
- {
- barcode = row.CurrentBarcode,
- supplyCode = row.SupplyCode,
- batchNo = row.BatchNo,
- unit = row.Unit,
- 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 => x.ReturnToMESStatus == 1) // 宸插畬鎴�
- .Where(x => x.OrderNo == orderNo) .ExecuteCommandAsync();
- }
- }
-
- }
- }
- catch (Exception ex)
- {
- _logger.LogError(" OutboundPickingService FeedbackOutbound : " + ex.Message);
- }
-
+ summary = new SummaryPickingDto { pickedCount = 0 };
}
+ summary.pickedCount = picked.pickedCount;
+
+ return summary;
}
+
+ #region 鏍稿績涓氬姟娴佺▼
public async Task<WebResponseContent> ConfirmPicking(string orderNo, string palletCode, string barcode)
{
@@ -257,288 +155,32 @@
{
_unitOfWorkManage.BeginTran();
- // 1. 楠岃瘉杈撳叆鍙傛暟
- if (string.IsNullOrEmpty(orderNo) || string.IsNullOrEmpty(palletCode) || string.IsNullOrEmpty(barcode))
- {
- throw new Exception("璁㈠崟鍙枫�佹墭鐩樼爜鍜屾潯鐮佷笉鑳戒负绌�");
- }
+ // 1. 鍓嶇疆楠岃瘉鍜屼笟鍔℃鏌�
+ var validationResult = await ValidatePickingRequest(orderNo, palletCode, barcode);
+ if (!validationResult.IsValid)
+ return WebResponseContent.Instance.Error(validationResult.ErrorMessage);
- // 2. 鏌ユ壘鍑哄簱閿佸畾淇℃伅
- var lockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
- .Where(it => it.OrderNo == orderNo &&
- it.Status == (int)OutLockStockStatusEnum.鍑哄簱涓� &&
- it.PalletCode == palletCode &&
- it.CurrentBarcode == barcode &&
- it.AssignQuantity > it.PickedQty)
- .FirstAsync();
+ var (lockInfo, orderDetail, stockDetail) = validationResult.Data;
- if (lockInfo == null)
- {
- lockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
- .Where(it => it.CurrentBarcode == barcode &&
- it.Status == (int)OutLockStockStatusEnum.鍑哄簱涓� &&
- it.AssignQuantity > it.PickedQty)
- .FirstAsync();
+ // 2. 璁$畻瀹為檯鎷i�夋暟閲�
+ var quantityResult = await CalculateActualPickingQuantity(lockInfo, orderDetail, stockDetail);
+ if (!quantityResult.IsValid)
+ return WebResponseContent.Instance.Error(quantityResult.ErrorMessage);
- if (lockInfo == null)
- {
- var completedLockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
- .Where(it => it.CurrentBarcode == barcode &&
- (it.Status == (int)OutLockStockStatusEnum.鎷i�夊畬鎴� ||
- it.PickedQty >= it.AssignQuantity))
- .FirstAsync();
+ var (actualQty, adjustedReason) = quantityResult.Data;
- if (completedLockInfo != null)
- throw new Exception($"鏉$爜{barcode}宸茬粡瀹屾垚鍒嗘嫞锛屼笉鑳介噸澶嶅垎鎷�");
- else
- throw new Exception($"鏉$爜{barcode}涓嶅睘浜庢墭鐩榹palletCode}鎴栦笉瀛樺湪寰呭垎鎷h褰�");
- }
- }
+ // 3. 鎵ц鍒嗘嫞閫昏緫
+ var pickingResult = await ExecutePickingLogic(lockInfo, orderDetail, stockDetail, orderNo, palletCode, barcode, actualQty);
- if (lockInfo.PalletCode != palletCode)
- throw new Exception($"鏉$爜{barcode}涓嶅睘浜庢墭鐩榹palletCode}");
+ // 4. 鏇存柊鐩稿叧鏁版嵁
+ await UpdateOrderRelatedData(orderDetail.Id, pickingResult.ActualPickedQty, orderNo);
- // 妫�鏌ユ嫞閫夊巻鍙诧紝闃叉閲嶅鍒嗘嫞
- var existingPicking = await Db.Queryable<Dt_PickingRecord>()
- .Where(x => x.Barcode == barcode &&
- x.OrderNo == orderNo &&
- x.PalletCode == palletCode &&
- x.OutStockLockId == lockInfo.Id)
- .FirstAsync();
-
- if (existingPicking != null)
- {
- throw new Exception($"鏉$爜{barcode}宸茬粡鍒嗘嫞杩囷紝涓嶈兘閲嶅鍒嗘嫞");
- }
-
- // 鑾峰彇璁㈠崟鏄庣粏骞舵鏌ユ暟閲忛檺鍒�
- var orderDetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
- .FirstAsync(x => x.Id == lockInfo.OrderDetailId);
-
- if (orderDetail == null)
- throw new Exception($"鏈壘鍒拌鍗曟槑缁嗭紝ID: {lockInfo.OrderDetailId}");
-
- // 鍏抽敭淇锛氭鏌ョ疮璁℃嫞閫夋暟閲忔槸鍚︿細瓒呰繃璁㈠崟鏁伴噺
- decimal actualQty = lockInfo.AssignQuantity - lockInfo.PickedQty;
- decimal remainingOrderQty = orderDetail.NeedOutQuantity - orderDetail.OverOutQuantity;
-
- if (actualQty > remainingOrderQty)
- {
- // 濡傛灉鍒嗛厤鏁伴噺澶т簬鍓╀綑璁㈠崟鏁伴噺锛岃皟鏁村疄闄呮嫞閫夋暟閲�
- 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>()
- .Where(x => x.Barcode == barcode && x.StockId == lockInfo.StockId)
- .FirstAsync();
-
- if (stockDetail == null)
- return WebResponseContent.Instance.Error("鏃犳晥鐨勬潯鐮佹垨鐗╂枡缂栫爜");
-
- decimal stockQuantity = stockDetail.StockQuantity;
-
- List<SplitResult> splitResults = new List<SplitResult>();
- Dt_OutStockLockInfo finalLockInfo = lockInfo;
- var finalBarcode = barcode;
- var finalStockId = stockDetail.Id;
- 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,
- OrderDetailId = lockInfo.OrderDetailId,
- BatchNo = lockInfo.BatchNo,
- MaterielCode = lockInfo.MaterielCode,
- MaterielName = lockInfo.MaterielName,
- StockId = lockInfo.StockId,
- OrderQuantity = actualQty,
- OriginalQuantity = actualQty,
- AssignQuantity = actualQty,
- PickedQty = actualQty,
- LocationCode = lockInfo.LocationCode,
- PalletCode = lockInfo.PalletCode,
- TaskNum = lockInfo.TaskNum,
- Status = (int)OutLockStockStatusEnum.鎷i�夊畬鎴�,
- Unit = lockInfo.Unit,
- SupplyCode = lockInfo.SupplyCode,
- OrderType = lockInfo.OrderType,
- CurrentBarcode = newBarcode,
- OriginalLockQuantity = actualQty,
- IsSplitted = 1,
- ParentLockId = lockInfo.Id
- };
-
- var newLockId = await _outStockLockInfoService.Db.Insertable(newLockInfo).ExecuteReturnIdentityAsync();
- newLockInfo.Id = newLockId;
-
- // 璁板綍鎷嗗寘鍘嗗彶
- var splitHistory = new Dt_SplitPackageRecord
- {
- FactoryArea = lockInfo.FactoryArea,
- TaskNum = lockInfo.TaskNum,
- OutStockLockInfoId = lockInfo.Id,
- StockId = stockDetail.StockId,
- Operator = App.User.UserName,
- IsReverted = false,
- OriginalBarcode = barcode,
- NewBarcode = newBarcode,
- SplitQty = actualQty,
- RemainQuantity = remainingStockQty,
- MaterielCode = lockInfo.MaterielCode,
- SplitTime = DateTime.Now,
- OrderNo = lockInfo.OrderNo,
- PalletCode = lockInfo.PalletCode,
- Status = (int)SplitPackageStatusEnum.宸叉嫞閫�
- };
- await _splitPackageService.Db.Insertable(splitHistory).ExecuteCommandAsync();
-
- // 鏇存柊鍘熼攣瀹氫俊鎭负鍓╀綑搴撳瓨鏁伴噺
- lockInfo.AssignQuantity = remainingStockQty;
- lockInfo.PickedQty = 0;
- await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync();
-
- splitResults.Add(new SplitResult
- {
- materialCode = lockInfo.MaterielCode,
- supplierCode = lockInfo.SupplyCode,
- quantityTotal = actualQty.ToString("F2"),
- batchNumber = newBarcode,
- batch = lockInfo.BatchNo,
- factory = lockInfo.FactoryArea,
- date = DateTime.Now.ToString("yyyy-MM-dd"),
- });
-
- splitResults.Add(new SplitResult
- {
- materialCode = lockInfo.MaterielCode,
- supplierCode = lockInfo.SupplyCode,
- quantityTotal = remainingStockQty.ToString("F2"),
- batchNumber = barcode,
- batch = lockInfo.BatchNo,
- factory = lockInfo.FactoryArea,
- date = DateTime.Now.ToString("yyyy-MM-dd"),
- });
-
- finalLockInfo = newLockInfo;
- finalBarcode = newBarcode;
- }
- else if (actualQty == stockQuantity)
- {
- // 鎯呭喌2: 鍒嗛厤鏁伴噺绛変簬搴撳瓨鏁伴噺锛屾暣鍖呭嚭搴�
- stockDetail.StockQuantity = 0;
- stockDetail.OutboundQuantity = 0;
- await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync();
-
- lockInfo.PickedQty += actualQty;
- lockInfo.Status = (int)OutLockStockStatusEnum.鎷i�夊畬鎴�;
- await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync();
- }
- else
- {
- // 鎯呭喌3: 鍒嗛厤鏁伴噺澶т簬搴撳瓨鏁伴噺锛屽簱瀛樻暣鍖呭嚭搴�
- decimal stockOutQty = stockQuantity;
- stockDetail.StockQuantity = 0;
- stockDetail.OutboundQuantity = 0;
- await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync();
-
- decimal remainingAssignQty = actualQty - stockQuantity;
- lockInfo.PickedQty += stockOutQty;
- lockInfo.AssignQuantity = remainingAssignQty;
- await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync();
-
- 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)
- {
- record.Status = (int)SplitPackageStatusEnum.宸叉嫞閫�;
- await _splitPackageService.Db.Updateable(record).ExecuteCommandAsync();
- }
-
- 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 = newPickedQty,
- OverOutQuantity = newOverOutQuantity
- })
- .Where(it => it.Id == lockInfo.OrderDetailId)
- .ExecuteCommandAsync();
-
- await CheckAndUpdateOrderStatus(orderNo);
-
- // 鏌ヨ浠诲姟琛�
- var task = _taskRepository.QueryData(x => x.OrderNo == orderNo && x.PalletCode == palletCode).FirstOrDefault();
-
- if (finalLockInfo.Id <= 0)
- {
- throw new Exception($"閿佸畾淇℃伅ID鏃犳晥: {finalLockInfo.Id}锛屾棤娉曡褰曟嫞閫夊巻鍙�");
- }
-
- // 璁板綍鎷i�夊巻鍙�
- var pickingHistory = new Dt_PickingRecord
- {
- FactoryArea = finalLockInfo.FactoryArea,
- TaskNo = task?.TaskNum ?? 0,
- LocationCode = task?.SourceAddress ?? "",
- StockId = finalStockId,
- OrderNo = orderNo,
- OrderDetailId = finalLockInfo.OrderDetailId,
- PalletCode = palletCode,
- Barcode = finalBarcode,
- MaterielCode = finalLockInfo.MaterielCode,
- PickQuantity = actualPickedQty,
- PickTime = DateTime.Now,
- Operator = App.User.UserName,
- OutStockLockId = finalLockInfo.Id
- };
- await Db.Insertable(pickingHistory).ExecuteCommandAsync();
+ // 5. 璁板綍鎿嶄綔鍘嗗彶
+ await RecordPickingHistory(pickingResult, orderNo, palletCode);
_unitOfWorkManage.CommitTran();
- if (splitResults.Any())
- {
- return WebResponseContent.Instance.OK("鎷i�夌‘璁ゆ垚鍔燂紝宸茶嚜鍔ㄦ媶鍖�", new { SplitResults = splitResults });
- }
-
- return WebResponseContent.Instance.OK("鎷i�夌‘璁ゆ垚鍔�", new { SplitResults = new List<SplitResult>() });
-
+ return CreatePickingResponse(pickingResult, adjustedReason);
}
catch (Exception ex)
{
@@ -554,77 +196,19 @@
{
_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();
+ // 1. 鍓嶇疆楠岃瘉
+ var validationResult = await ValidateCancelRequest(orderNo, palletCode, barcode);
+ if (!validationResult.IsValid)
+ return WebResponseContent.Instance.Error(validationResult.ErrorMessage);
- if (pickingRecord == null)
- return WebResponseContent.Instance.Error("鏈壘鍒板搴旂殑鎷i�夎褰�");
+ var (pickingRecord, lockInfo, orderDetail) = validationResult.Data;
- // 鏌ユ壘鍑哄簱閿佸畾淇℃伅
- 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);
+ // 2. 鎵ц鍙栨秷閫昏緫
+ await ExecuteCancelLogic(lockInfo, pickingRecord, orderDetail, orderNo);
_unitOfWorkManage.CommitTran();
- return WebResponseContent.Instance.OK($"鍙栨秷鍒嗘嫞鎴愬姛锛屾仮澶嶆暟閲忥細{cancelQty}");
+
+ return WebResponseContent.Instance.OK($"鍙栨秷鍒嗘嫞鎴愬姛锛屾仮澶嶆暟閲忥細{pickingRecord.PickQuantity}");
}
catch (Exception ex)
{
@@ -632,6 +216,438 @@
_logger.LogError($"CancelPicking澶辫触 - OrderNo: {orderNo}, PalletCode: {palletCode}, Barcode: {barcode}, Error: {ex.Message}");
return WebResponseContent.Instance.Error($"鍙栨秷鍒嗘嫞澶辫触锛歿ex.Message}");
}
+ }
+
+ public async Task<WebResponseContent> ReturnRemaining(string orderNo, string palletCode, string reason)
+ {
+ try
+ {
+ _unitOfWorkManage.BeginTran();
+
+ // 1. 鍩虹楠岃瘉
+ if (string.IsNullOrEmpty(orderNo) || string.IsNullOrEmpty(palletCode))
+ return WebResponseContent.Instance.Error("璁㈠崟鍙峰拰鎵樼洏鐮佷笉鑳戒负绌�");
+
+ // 2. 鑾峰彇搴撳瓨鍜屼换鍔′俊鎭�
+ var stockInfo = await _stockInfoService.Db.Queryable<Dt_StockInfo>()
+ .FirstAsync(x => x.PalletCode == palletCode);
+
+ if (stockInfo == null)
+ return WebResponseContent.Instance.Error($"鏈壘鍒版墭鐩� {palletCode} 瀵瑰簲鐨勫簱瀛樹俊鎭�");
+
+ var task = await GetCurrentTask(orderNo, palletCode);
+ if (task == null)
+ return WebResponseContent.Instance.Error("鏈壘鍒板搴旂殑浠诲姟淇℃伅");
+
+ // 3. 鍒嗘瀽闇�瑕佸洖搴撶殑璐х墿
+ var returnAnalysis = await AnalyzeReturnItems(orderNo, palletCode, stockInfo.Id);
+ if (!returnAnalysis.HasItemsToReturn)
+ return await HandleNoReturnItems(orderNo, palletCode);
+
+ // 4. 鎵ц鍥炲簱鎿嶄綔
+ await ExecuteReturnOperations(orderNo, palletCode, stockInfo, task, returnAnalysis);
+
+ // 5. 鍒涘缓鍥炲簱浠诲姟
+ await CreateReturnTaskAndHandleESS(orderNo, palletCode, task, returnAnalysis);
+
+ _unitOfWorkManage.CommitTran();
+
+ // 6. 鏇存柊璁㈠崟鐘舵�侊紙涓嶈Е鍙慚ES鍥炰紶锛�
+ await UpdateOrderStatusForReturn(orderNo);
+
+ return WebResponseContent.Instance.OK($"鍥炲簱鎿嶄綔鎴愬姛锛屽叡鍥炲簱鏁伴噺锛歿returnAnalysis.TotalReturnQty}");
+ }
+ catch (Exception ex)
+ {
+ _unitOfWorkManage.RollbackTran();
+ _logger.LogError($"ReturnRemaining澶辫触 - OrderNo: {orderNo}, PalletCode: {palletCode}, Error: {ex.Message}");
+ return WebResponseContent.Instance.Error($"鍥炲簱鎿嶄綔澶辫触: {ex.Message}");
+ }
+ }
+
+ #endregion
+
+ #region 鍒嗘嫞纭绉佹湁鏂规硶
+
+ 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();
+
+ 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)
+ .FirstAsync();
+
+ 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();
+
+ if (existingPicking != null)
+ return ValidationResult<(Dt_OutStockLockInfo, Dt_OutboundOrderDetail, Dt_StockInfoDetail)>.Error($"鏉$爜{barcode}宸茬粡鍒嗘嫞杩�");
+
+ return ValidationResult<(Dt_OutStockLockInfo, Dt_OutboundOrderDetail, Dt_StockInfoDetail)>.Success((lockInfo, orderDetail, stockDetail));
+ }
+
+ private async Task<Dt_OutStockLockInfo> FindValidLockInfo(string orderNo, string palletCode, string barcode)
+ {
+ // 浼樺厛鏌ユ壘绮剧‘鍖归厤鐨勮褰�
+ var lockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+ .Where(it => it.OrderNo == orderNo &&
+ it.Status == (int)OutLockStockStatusEnum.鍑哄簱涓� &&
+ it.PalletCode == palletCode &&
+ it.CurrentBarcode == barcode &&
+ it.AssignQuantity > it.PickedQty)
+ .FirstAsync();
+
+ if (lockInfo == null)
+ {
+ // 鏌ユ壘鍚屼竴璁㈠崟涓嬬殑璁板綍
+ lockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+ .Where(it => it.OrderNo == orderNo &&
+ it.CurrentBarcode == barcode &&
+ it.Status == (int)OutLockStockStatusEnum.鍑哄簱涓� &&
+ it.AssignQuantity > it.PickedQty)
+ .FirstAsync();
+
+ if (lockInfo == null)
+ {
+ // 妫�鏌ユ槸鍚﹀凡缁忓畬鎴愬垎鎷�
+ var completedLockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+ .Where(it => it.CurrentBarcode == barcode &&
+ (it.Status == (int)OutLockStockStatusEnum.鎷i�夊畬鎴� ||
+ it.PickedQty >= it.AssignQuantity))
+ .FirstAsync();
+
+ if (completedLockInfo != null)
+ throw new Exception($"鏉$爜{barcode}宸茬粡瀹屾垚鍒嗘嫞锛屼笉鑳介噸澶嶅垎鎷�");
+ else
+ return null;
+ }
+ }
+
+ return lockInfo;
+ }
+
+ private async Task<ValidationResult<(decimal, string)>> CalculateActualPickingQuantity(
+ Dt_OutStockLockInfo lockInfo, Dt_OutboundOrderDetail orderDetail, Dt_StockInfoDetail stockDetail)
+ {
+ decimal plannedQty = lockInfo.AssignQuantity - lockInfo.PickedQty;
+ decimal remainingOrderQty = orderDetail.NeedOutQuantity - orderDetail.OverOutQuantity;
+ decimal stockQuantity = stockDetail.StockQuantity;
+
+ // 涓夐噸妫�鏌ワ細鍙栨渶灏忓��
+ decimal actualQty = plannedQty;
+ string adjustedReason = null;
+
+ // 妫�鏌�1锛氳鍗曟暟閲忛檺鍒�
+ if (plannedQty > remainingOrderQty && remainingOrderQty > 0)
+ {
+ actualQty = remainingOrderQty;
+ adjustedReason = $"璁㈠崟鏁伴噺闄愬埗锛氫粠{plannedQty}璋冩暣涓簕actualQty}";
+ }
+
+ // 妫�鏌�2锛氬簱瀛樻暟閲忛檺鍒�
+ if (actualQty > stockQuantity)
+ {
+ actualQty = stockQuantity;
+ adjustedReason = adjustedReason != null
+ ? $"{adjustedReason}锛屽簱瀛樻暟閲忛檺鍒讹細杩涗竴姝ヨ皟鏁翠负{actualQty}"
+ : $"搴撳瓨鏁伴噺闄愬埗锛氫粠{plannedQty}璋冩暣涓簕actualQty}";
+ }
+
+ // 妫�鏌�3锛氬疄闄呭彲鎷i�夋暟閲忓繀椤诲ぇ浜�0
+ if (actualQty <= 0)
+ {
+ return ValidationResult<(decimal, string)>.Error($"鏃犳硶鍒嗘嫞锛氳鍒掓暟閲弡plannedQty}锛屽墿浣欒鍗晎remainingOrderQty}锛屽簱瀛榹stockQuantity}");
+ }
+
+ if (adjustedReason != null)
+ {
+ _logger.LogWarning($"鍒嗘嫞鏁伴噺璋冩暣锛歿adjustedReason}锛岃鍗晎orderDetail.NeedOutQuantity}锛屽凡鍑哄簱{orderDetail.OverOutQuantity}锛屽簱瀛榹stockQuantity}");
+ }
+
+ return ValidationResult<(decimal, string)>.Success((actualQty, adjustedReason));
+ }
+
+ private async Task<PickingResult> ExecutePickingLogic(
+ Dt_OutStockLockInfo lockInfo, Dt_OutboundOrderDetail orderDetail, Dt_StockInfoDetail stockDetail,
+ string orderNo, string palletCode, string barcode, decimal actualQty)
+ {
+ decimal stockQuantity = stockDetail.StockQuantity;
+ var result = new PickingResult
+ {
+ FinalLockInfo = lockInfo,
+ FinalBarcode = barcode,
+ FinalStockId = stockDetail.Id,
+ ActualPickedQty = actualQty
+ };
+
+ if (actualQty < stockQuantity)
+ {
+ await HandleSplitPacking(lockInfo, stockDetail, actualQty, stockQuantity, result);
+ }
+ else if (actualQty == stockQuantity)
+ {
+ await HandleFullPicking(lockInfo, stockDetail, actualQty, result);
+ }
+ else
+ {
+ await HandlePartialPicking(lockInfo, stockDetail, actualQty, stockQuantity, result);
+ }
+
+ return result;
+ }
+
+ private async Task HandleSplitPacking(Dt_OutStockLockInfo lockInfo, Dt_StockInfoDetail stockDetail,
+ decimal actualQty, decimal stockQuantity, PickingResult result)
+ {
+ decimal remainingStockQty = stockQuantity - actualQty;
+
+ // 1. 鏇存柊鍘熸潯鐮佸簱瀛�
+ stockDetail.StockQuantity = remainingStockQty;
+ stockDetail.OutboundQuantity = remainingStockQty;
+ await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync();
+
+ // 2. 鐢熸垚鏂版潯鐮�
+ string newBarcode = await GenerateNewBarcode();
+
+ // 3. 鍒涘缓鏂伴攣瀹氫俊鎭�
+ var newLockInfo = await CreateSplitLockInfo(lockInfo, actualQty, newBarcode);
+
+ // 4. 璁板綍鎷嗗寘鍘嗗彶
+ await RecordSplitHistory(lockInfo, stockDetail, actualQty, remainingStockQty, newBarcode);
+
+ // 5. 鏇存柊鍘熼攣瀹氫俊鎭�
+ lockInfo.AssignQuantity = remainingStockQty;
+ lockInfo.PickedQty = 0;
+ await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync();
+
+ // 6. 璁剧疆缁撴灉
+ result.FinalLockInfo = newLockInfo;
+ result.FinalBarcode = newBarcode;
+ result.SplitResults.AddRange(CreateSplitResults(lockInfo, actualQty, remainingStockQty, newBarcode, stockDetail.Barcode));
+ }
+
+ 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�夊畬鎴�;
+ await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync();
+ }
+
+ private async Task HandlePartialPicking(Dt_OutStockLockInfo lockInfo, Dt_StockInfoDetail stockDetail,
+ decimal actualQty, decimal stockQuantity, PickingResult result)
+ {
+ 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;
+ await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync();
+
+ // 3. 鏇存柊鎷嗗寘璁板綍鐘舵��
+ await UpdateSplitRecordsStatus(stockDetail.Barcode);
+
+ result.ActualPickedQty = stockOutQty;
+ }
+
+ private async Task UpdateOrderRelatedData(int orderDetailId, decimal pickedQty, string orderNo)
+ {
+ // 鑾峰彇鏈�鏂扮殑璁㈠崟鏄庣粏鏁版嵁
+ var currentOrderDetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
+ .FirstAsync(x => x.Id == orderDetailId);
+
+ decimal newOverOutQuantity = currentOrderDetail.OverOutQuantity + pickedQty;
+ decimal newPickedQty = currentOrderDetail.PickedQty + pickedQty;
+
+ // 鏈�缁堟鏌ワ細纭繚涓嶄細瓒呰繃璁㈠崟闇�姹傛暟閲�
+ if (newOverOutQuantity > currentOrderDetail.NeedOutQuantity)
+ {
+ throw new Exception($"鍒嗘嫞鍚庡皢瀵艰嚧宸插嚭搴撴暟閲�({newOverOutQuantity})瓒呰繃璁㈠崟闇�姹傛暟閲�({currentOrderDetail.NeedOutQuantity})");
+ }
+
+ // 鏇存柊璁㈠崟鏄庣粏
+ await _outboundOrderDetailService.Db.Updateable<Dt_OutboundOrderDetail>()
+ .SetColumns(it => new Dt_OutboundOrderDetail
+ {
+ PickedQty = newPickedQty,
+ OverOutQuantity = newOverOutQuantity,
+ })
+ .Where(it => it.Id == orderDetailId)
+ .ExecuteCommandAsync();
+
+ // 妫�鏌ュ苟鏇存柊璁㈠崟鐘舵��
+ await CheckAndUpdateOrderStatus(orderNo);
+ }
+
+ private async Task RecordPickingHistory(PickingResult result, string orderNo, string palletCode)
+ {
+ var task = await _taskRepository.Db.Queryable<Dt_Task>()
+ .Where(x => x.OrderNo == orderNo && x.PalletCode == palletCode)
+ .FirstAsync();
+
+ if (result.FinalLockInfo.Id <= 0)
+ {
+ throw new Exception($"閿佸畾淇℃伅ID鏃犳晥: {result.FinalLockInfo.Id}锛屾棤娉曡褰曟嫞閫夊巻鍙�");
+ }
+
+ var pickingHistory = new Dt_PickingRecord
+ {
+ FactoryArea = result.FinalLockInfo.FactoryArea,
+ TaskNo = task?.TaskNum ?? 0,
+ LocationCode = task?.SourceAddress ?? "",
+ StockId = result.FinalStockId,
+ OrderNo = orderNo,
+ OrderDetailId = result.FinalLockInfo.OrderDetailId,
+ PalletCode = palletCode,
+ Barcode = result.FinalBarcode,
+ MaterielCode = result.FinalLockInfo.MaterielCode,
+ PickQuantity = result.ActualPickedQty,
+ PickTime = DateTime.Now,
+ Operator = App.User.UserName,
+ OutStockLockId = result.FinalLockInfo.Id
+ };
+
+ await Db.Insertable(pickingHistory).ExecuteCommandAsync();
+ }
+
+ #endregion
+
+ #region 鍙栨秷鍒嗘嫞绉佹湁鏂规硶
+
+ private async Task<ValidationResult<(Dt_PickingRecord, Dt_OutStockLockInfo, Dt_OutboundOrderDetail)>> ValidateCancelRequest(string orderNo, string palletCode, string barcode)
+ {
+ // 鍩虹鍙傛暟楠岃瘉
+ if (string.IsNullOrEmpty(orderNo) || string.IsNullOrEmpty(palletCode) || string.IsNullOrEmpty(barcode))
+ return ValidationResult<(Dt_PickingRecord, Dt_OutStockLockInfo, Dt_OutboundOrderDetail)>.Error("璁㈠崟鍙枫�佹墭鐩樼爜鍜屾潯鐮佷笉鑳戒负绌�");
+
+ // 鏌ユ壘鎷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 ValidationResult<(Dt_PickingRecord, Dt_OutStockLockInfo, Dt_OutboundOrderDetail)>.Error("鏈壘鍒板搴旂殑鎷i�夎褰�");
+
+ // 鏌ユ壘閿佸畾淇℃伅
+ var lockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+ .Where(it => it.Id == pickingRecord.OutStockLockId)
+ .FirstAsync();
+
+ if (lockInfo == null)
+ return ValidationResult<(Dt_PickingRecord, Dt_OutStockLockInfo, Dt_OutboundOrderDetail)>.Error("鏈壘鍒板搴旂殑鍑哄簱閿佸畾淇℃伅");
+
+ // 妫�鏌ョ姸鎬佹槸鍚﹀厑璁稿彇娑�
+ if (lockInfo.Status != (int)OutLockStockStatusEnum.鎷i�夊畬鎴�)
+ return ValidationResult<(Dt_PickingRecord, Dt_OutStockLockInfo, Dt_OutboundOrderDetail)>.Error("褰撳墠鐘舵�佷笉鍏佽鍙栨秷鍒嗘嫞");
+
+ // 妫�鏌ヨ鍗曠姸鎬�
+ var order = await _outboundOrderService.Db.Queryable<Dt_OutboundOrder>()
+ .Where(x => x.OrderNo == orderNo)
+ .FirstAsync();
+
+ if (order?.OrderStatus == (int)OutOrderStatusEnum.鍑哄簱瀹屾垚)
+ return ValidationResult<(Dt_PickingRecord, Dt_OutStockLockInfo, Dt_OutboundOrderDetail)>.Error("璁㈠崟宸插嚭搴撳畬鎴愶紝涓嶅厑璁稿彇娑堝垎鎷�");
+
+ // 鑾峰彇璁㈠崟鏄庣粏
+ var orderDetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
+ .FirstAsync(x => x.Id == pickingRecord.OrderDetailId);
+
+ if (orderDetail == null)
+ return ValidationResult<(Dt_PickingRecord, Dt_OutStockLockInfo, Dt_OutboundOrderDetail)>.Error($"鏈壘鍒拌鍗曟槑缁嗭紝ID: {pickingRecord.OrderDetailId}");
+
+ return ValidationResult<(Dt_PickingRecord, Dt_OutStockLockInfo, Dt_OutboundOrderDetail)>.Success((pickingRecord, lockInfo, orderDetail));
+ }
+
+ private async Task ExecuteCancelLogic(Dt_OutStockLockInfo lockInfo, Dt_PickingRecord pickingRecord,
+ Dt_OutboundOrderDetail orderDetail, string orderNo)
+ {
+ decimal cancelQty = pickingRecord.PickQuantity;
+
+ // 1. 妫�鏌ュ彇娑堝悗鏁伴噺涓嶄細涓鸿礋鏁�
+ decimal newOverOutQuantity = orderDetail.OverOutQuantity - cancelQty;
+ decimal newPickedQty = orderDetail.PickedQty - cancelQty;
+
+ if (newOverOutQuantity < 0 || newPickedQty < 0)
+ {
+ throw new Exception($"鍙栨秷鍒嗘嫞灏嗗鑷存暟鎹紓甯革細宸插嚭搴搟newOverOutQuantity}锛屽凡鎷i�墈newPickedQty}");
+ }
+
+ // 2. 澶勭悊涓嶅悓绫诲瀷鐨勫彇娑�
+ if (lockInfo.IsSplitted == 1 && lockInfo.ParentLockId.HasValue)
+ {
+ await HandleSplitBarcodeCancel(lockInfo, pickingRecord, cancelQty);
+ }
+ else
+ {
+ await HandleNormalBarcodeCancel(lockInfo, pickingRecord, cancelQty);
+ }
+
+ // 3. 鏇存柊璁㈠崟鏄庣粏
+ await UpdateOrderDetailOnCancel(pickingRecord.OrderDetailId, cancelQty);
+
+ // 4. 鍒犻櫎鎷i�夎褰�
+ await Db.Deleteable<Dt_PickingRecord>()
+ .Where(x => x.Id == pickingRecord.Id)
+ .ExecuteCommandAsync();
+
+ // 5. 閲嶆柊妫�鏌ヨ鍗曠姸鎬�
+ await UpdateOrderStatusForReturn(orderNo);
}
private async Task HandleSplitBarcodeCancel(Dt_OutStockLockInfo lockInfo, Dt_PickingRecord pickingRecord, decimal cancelQty)
@@ -642,9 +658,7 @@
.FirstAsync();
if (parentLockInfo == null)
- {
throw new Exception("鏈壘鍒扮埗閿佸畾淇℃伅锛屾棤娉曞彇娑堟媶鍖呭垎鎷�");
- }
// 鎭㈠鐖堕攣瀹氫俊鎭殑鍒嗛厤鏁伴噺
parentLockInfo.AssignQuantity += cancelQty;
@@ -658,7 +672,8 @@
if (stockDetail != null)
{
stockDetail.StockQuantity += cancelQty;
- stockDetail.OutboundQuantity += cancelQty;
+ stockDetail.OutboundQuantity = stockDetail.StockQuantity;
+ stockDetail.Status = StockStatusEmun.鍑哄簱閿佸畾.ObjToInt();
await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync();
}
@@ -667,7 +682,7 @@
.SetColumns(x => new Dt_SplitPackageRecord
{
Status = (int)SplitPackageStatusEnum.宸叉挙閿�,
- IsReverted = true
+ IsReverted = true,
})
.Where(x => x.NewBarcode == lockInfo.CurrentBarcode && !x.IsReverted)
.ExecuteCommandAsync();
@@ -695,114 +710,46 @@
if (stockDetail != null)
{
stockDetail.StockQuantity += cancelQty;
- stockDetail.OutboundQuantity += cancelQty;
+ stockDetail.OutboundQuantity = stockDetail.StockQuantity;
+ stockDetail.Status = StockStatusEmun.鍑哄簱閿佸畾.ObjToInt();
await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync();
}
}
- public async Task<WebResponseContent> ReturnRemaining(string orderNo, string palletCode, string reason)
+ private async Task UpdateOrderDetailOnCancel(int orderDetailId, decimal cancelQty)
{
- try
+ // 鑾峰彇鏈�鏂扮殑璁㈠崟鏄庣粏鏁版嵁
+ var currentOrderDetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
+ .FirstAsync(x => x.Id == orderDetailId);
+
+ decimal newOverOutQuantity = currentOrderDetail.OverOutQuantity - cancelQty;
+ decimal newPickedQty = currentOrderDetail.PickedQty - cancelQty;
+
+ // 妫�鏌ュ彇娑堝悗鏁伴噺涓嶄細涓鸿礋鏁�
+ if (newOverOutQuantity < 0 || newPickedQty < 0)
{
- _unitOfWorkManage.BeginTran();
-
- if (string.IsNullOrEmpty(orderNo) || string.IsNullOrEmpty(palletCode))
- {
- return WebResponseContent.Instance.Error("璁㈠崟鍙峰拰鎵樼洏鐮佷笉鑳戒负绌�");
- }
- var stockInfo = await _stockInfoService.Db.Queryable<Dt_StockInfo>()
- .FirstAsync(x => x.PalletCode == palletCode);
-
- if (stockInfo == null)
- {
- return WebResponseContent.Instance.Error($"鏈壘鍒版墭鐩� {palletCode} 瀵瑰簲鐨勫簱瀛樹俊鎭�");
- }
- var task = await GetCurrentTask(orderNo, palletCode);
- if (task == null)
- {
- return WebResponseContent.Instance.Error("鏈壘鍒板搴旂殑浠诲姟淇℃伅");
- }
-
- // 鍒嗘瀽闇�瑕佸洖搴撶殑璐х墿
- var returnAnalysis = await AnalyzeReturnItems(orderNo, palletCode, stockInfo.Id);
-
- if (!returnAnalysis.HasItemsToReturn)
- {
- return await HandleNoReturnItems(orderNo, palletCode);
- }
-
- // 鎵ц鍥炲簱鎿嶄綔
- await ExecuteReturnOperations(orderNo, palletCode, stockInfo, task, returnAnalysis);
-
- //鍒涘缓鍥炲簱浠诲姟骞跺鐞咵SS
- await CreateReturnTaskAndHandleESS(orderNo, palletCode, task, returnAnalysis);
-
- _unitOfWorkManage.CommitTran();
-
- // 鏇存柊璁㈠崟鐘舵��
- await UpdateOrderStatusForReturn(orderNo);
-
- return WebResponseContent.Instance.OK($"鍥炲簱鎿嶄綔鎴愬姛锛屽叡鍥炲簱鏁伴噺锛歿returnAnalysis.TotalReturnQty}");
-
+ throw new Exception($"鍙栨秷鍒嗘嫞灏嗗鑷村凡鍑哄簱鏁伴噺({newOverOutQuantity})鎴栧凡鎷i�夋暟閲�({newPickedQty})涓鸿礋鏁�");
}
- catch (Exception ex)
- {
- _unitOfWorkManage.RollbackTran();
- _logger.LogError($"ReturnRemaining澶辫触 - OrderNo: {orderNo}, PalletCode: {palletCode}, Error: {ex.Message}");
- return WebResponseContent.Instance.Error($"鍥炲簱鎿嶄綔澶辫触: {ex.Message}");
- }
- }
- #region 璁㈠崟鐘舵��
-
- private async Task UpdateOrderStatusForReturn(string orderNo)
- {
- try
- {
- var orderDetails = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
- .LeftJoin<Dt_OutboundOrder>((o, item) => o.OrderId == item.Id)
- .Where((o, item) => item.OrderNo == orderNo)
- .Select((o, item) => o)
- .ToListAsync();
-
- bool allCompleted = true;
- foreach (var detail in orderDetails)
+ await _outboundOrderDetailService.Db.Updateable<Dt_OutboundOrderDetail>()
+ .SetColumns(it => new Dt_OutboundOrderDetail
{
- if (detail.OverOutQuantity < detail.NeedOutQuantity)
- {
- allCompleted = false;
- break;
- }
- }
-
- var outboundOrder = await _outboundOrderService.Db.Queryable<Dt_OutboundOrder>()
- .FirstAsync(x => x.OrderNo == orderNo);
-
- if (outboundOrder == null) return;
-
- // 鍙湁褰撶姸鎬佺‘瀹炲彂鐢熷彉鍖栨椂鎵嶆洿鏂�
- int newStatus = allCompleted ? (int)OutOrderStatusEnum.鍑哄簱瀹屾垚 : (int)OutOrderStatusEnum.鍑哄簱涓�;
-
- if (outboundOrder.OrderStatus != newStatus)
- {
- await _outboundOrderService.Db.Updateable<Dt_OutboundOrder>()
- .SetColumns(x => x.OrderStatus == newStatus)
- .Where(x => x.OrderNo == orderNo)
- .ExecuteCommandAsync();
-
- _logger.LogInformation($"鍥炲簱鎿嶄綔鏇存柊璁㈠崟鐘舵�� - OrderNo: {orderNo}, 鏂扮姸鎬�: {newStatus}");
- }
- }
- catch (Exception ex)
- {
- _logger.LogError($"UpdateOrderStatusForReturn澶辫触 - OrderNo: {orderNo}, Error: {ex.Message}");
-
- }
+ PickedQty = newPickedQty,
+ OverOutQuantity = newOverOutQuantity,
+ })
+ .Where(it => it.Id == orderDetailId)
+ .ExecuteCommandAsync();
}
#endregion
- #region Private Methods
+ #region 鍥炲簱鎿嶄綔绉佹湁鏂规硶
+
+ private async Task<Dt_StockInfo> GetStockInfo(string palletCode)
+ {
+ return await _stockInfoService.Db.Queryable<Dt_StockInfo>()
+ .FirstAsync(x => x.PalletCode == palletCode);
+ }
private async Task<Dt_Task> GetCurrentTask(string orderNo, string palletCode)
{
@@ -826,7 +773,7 @@
{
var result = new ReturnAnalysisResult();
- // 鑾峰彇鏈垎鎷g殑鍑哄簱閿佸畾璁板綍
+ // 鎯呭喌1锛氳幏鍙栨湭鍒嗘嫞鐨勫嚭搴撻攣瀹氳褰�
var remainingLocks = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
.Where(it => it.OrderNo == orderNo &&
it.PalletCode == palletCode &&
@@ -840,15 +787,14 @@
result.RemainingLocksReturnQty = remainingLocks.Sum(x => x.AssignQuantity - x.PickedQty);
}
- // 妫�鏌ユ墭鐩樹笂鏄惁鏈夊叾浠栧簱瀛樿揣鐗�
+ // 鎯呭喌2锛氭鏌ユ墭鐩樹笂鏄惁鏈夊叾浠栧簱瀛樿揣鐗�
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) // 鏈夊簱瀛樼殑
+ .Where(it => it.StockQuantity > 0)
.ToListAsync();
-
if (palletStockGoods.Any())
{
@@ -857,7 +803,7 @@
result.PalletStockReturnQty = palletStockGoods.Sum(x => x.StockQuantity);
}
- // 妫�鏌ユ媶鍖呰褰�
+ // 鎯呭喌3锛氭鏌ユ媶鍖呰褰�
var splitRecords = await _splitPackageService.Db.Queryable<Dt_SplitPackageRecord>()
.Where(it => it.OrderNo == orderNo && it.PalletCode == palletCode && !it.IsReverted)
.ToListAsync();
@@ -967,7 +913,7 @@
await _outStockLockInfoService.Db.Updateable<Dt_OutStockLockInfo>()
.SetColumns(it => new Dt_OutStockLockInfo
{
- Status = (int)OutLockStockStatusEnum.鍥炲簱涓�
+ Status = (int)OutLockStockStatusEnum.鍥炲簱涓�,
})
.Where(it => lockIds.Contains(it.Id))
.ExecuteCommandAsync();
@@ -991,7 +937,7 @@
}
else
{
- // 鍒涘缓鏂扮殑搴撳瓨璁板綍锛堟媶鍖呬骇鐢熺殑鏂版潯鐮侊級
+ // 鍒涘缓鏂扮殑搴撳瓨璁板綍
var newStockDetail = new Dt_StockInfoDetail
{
StockId = lockInfo.StockId,
@@ -1006,7 +952,7 @@
Status = StockStatusEmun.鍏ュ簱瀹屾垚.ObjToInt(),
SupplyCode = lockInfo.SupplyCode,
WarehouseCode = lockInfo.WarehouseCode,
- Unit = lockInfo.Unit
+ Unit = lockInfo.Unit,
};
await _stockInfoDetailService.Db.Insertable(newStockDetail).ExecuteCommandAsync();
}
@@ -1037,7 +983,7 @@
.SetColumns(it => new Dt_OutboundOrderDetail
{
PickedQty = newPickedQty,
- OverOutQuantity = newOverOutQuantity
+ OverOutQuantity = newOverOutQuantity,
})
.Where(it => it.Id == orderDetailId)
.ExecuteCommandAsync();
@@ -1051,7 +997,8 @@
{
// 鎭㈠搴撳瓨鐘舵��
stockGood.OutboundQuantity = 0;
- stockGood.Status = StockStatusEmun.鍏ュ簱瀹屾垚.ObjToInt();
+ stockGood.Status = StockStatusEmun.鍏ュ簱瀹屾垚.ObjToInt();
+
await _stockInfoDetailService.Db.Updateable(stockGood).ExecuteCommandAsync();
}
}
@@ -1062,7 +1009,7 @@
await _splitPackageService.Db.Updateable<Dt_SplitPackageRecord>()
.SetColumns(x => new Dt_SplitPackageRecord
{
- Status = (int)SplitPackageStatusEnum.宸插洖搴�
+ Status = (int)SplitPackageStatusEnum.宸插洖搴�,
})
.Where(x => x.OrderNo == orderNo && x.PalletCode == palletCode && !x.IsReverted)
.ExecuteCommandAsync();
@@ -1071,7 +1018,7 @@
private async Task UpdateStockInfoStatus(Dt_StockInfo stockInfo)
{
// 鏇存柊搴撳瓨涓昏〃鐘舵��
- stockInfo.StockStatus = StockStatusEmun.鍏ュ簱瀹屾垚.ObjToInt();
+ stockInfo.StockStatus = StockStatusEmun.鍏ュ簱瀹屾垚.ObjToInt();
await _stockInfoService.Db.Updateable(stockInfo).ExecuteCommandAsync();
}
@@ -1080,7 +1027,7 @@
var firstLocation = await _locationInfoService.Db.Queryable<Dt_LocationInfo>()
.FirstAsync(x => x.LocationCode == originalTask.SourceAddress);
- // 鍒嗛厤鏂拌揣浣嶏紙鍥炲簱鍒板瓨鍌ㄤ綅锛�
+ // 鍒嗛厤鏂拌揣浣�
var newLocation = _locationInfoService.AssignLocation(firstLocation.LocationType);
Dt_Task returnTask = new()
@@ -1096,27 +1043,28 @@
TaskStatus = TaskStatusEnum.New.ObjToInt(),
TaskType = TaskTypeEnum.InPick.ObjToInt(),
PalletType = originalTask.PalletType,
- WarehouseId = originalTask.WarehouseId,
+ WarehouseId = originalTask.WarehouseId
- };
-
+ };
// 淇濆瓨鍥炲簱浠诲姟
await _taskRepository.Db.Insertable(returnTask).ExecuteCommandAsync();
-
+ var targetAddress = originalTask.TargetAddress;
+
// 鍒犻櫎鍘熷鍑哄簱浠诲姟
- _taskRepository.Db.Deleteable(originalTask);
+ await _taskRepository.Db.Deleteable(originalTask).ExecuteCommandAsync();
// 缁� ESS 鍙戦�佹祦鍔ㄤ俊鍙峰拰鍒涘缓浠诲姟
- await SendESSCommands(palletCode, originalTask, returnTask);
+ await SendESSCommands(palletCode, targetAddress, returnTask);
}
- private async Task SendESSCommands(string palletCode, Dt_Task originalTask, Dt_Task returnTask)
+
+ private async Task SendESSCommands(string palletCode, string targetAddress, Dt_Task returnTask)
{
try
{
// 1. 鍙戦�佹祦鍔ㄤ俊鍙�
var moveResult = await _eSSApiService.MoveContainerAsync(new WIDESEA_DTO.Basic.MoveContainerRequest
{
- slotCode = movestations[originalTask.TargetAddress],
+ slotCode = movestations[targetAddress],
containerCode = palletCode
});
@@ -1129,23 +1077,23 @@
taskGroupCode = "",
groupPriority = 0,
tasks = new List<TasksType>
- {
- new()
{
- taskCode = returnTask.TaskNum.ToString(),
- taskPriority = 0,
- taskDescribe = new TaskDescribeType
+ new()
{
- containerCode = palletCode,
- containerType = "CT_KUBOT_STANDARD",
- fromLocationCode = stations.GetValueOrDefault(originalTask.TargetAddress) ?? "",
- toStationCode = "",
- toLocationCode = returnTask.TargetAddress,
- deadline = 0,
- storageTag = ""
+ taskCode = returnTask.TaskNum.ToString(),
+ taskPriority = 0,
+ taskDescribe = new TaskDescribeType
+ {
+ containerCode = palletCode,
+ containerType = "CT_KUBOT_STANDARD",
+ fromLocationCode = stations.GetValueOrDefault(targetAddress) ?? "",
+ toStationCode = "",
+ toLocationCode = returnTask.TargetAddress,
+ deadline = 0,
+ storageTag = ""
+ }
}
}
- }
};
var resultTask = await _eSSApiService.CreateTaskAsync(essTask);
@@ -1161,829 +1109,331 @@
#endregion
-
+ #region 璁㈠崟鐘舵�佺鐞�
- /// <summary>
- /// 鍥炲簱鎿嶄綔
- /// </summary>
-
- //public async Task<WebResponseContent> ReturnRemaining(string orderNo, string palletCode, string reason)
- //{
- // try
- // {
- // _unitOfWorkManage.BeginTran();
-
- // // 鑾峰彇鎵�鏈夋湭鍒嗘嫞鐨勫嚭搴撻攣瀹氳褰曪紝鍖呮嫭鎷嗗寘浜х敓鐨勮褰�
- // var remainingLocks = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
- // .Where(it => it.OrderNo == orderNo && it.Status == (int)OutLockStockStatusEnum.鍑哄簱涓�)
- // .ToListAsync();
-
- // var stockinfo = _stockInfoService.Db.Queryable<Dt_StockInfo>().First(x => x.PalletCode == palletCode);
-
- // var tasks = new List<Dt_Task>();
-
- // // 鏌ヨ浠诲姟琛�
- // var task = remainingLocks.Any()
- // ? _taskRepository.QueryData(x => x.TaskNum == remainingLocks.First().TaskNum).FirstOrDefault()
- // : _taskRepository.QueryData(x => x.PalletCode == palletCode).FirstOrDefault();
-
- // if (task == null)
- // {
- // return WebResponseContent.Instance.Error("鏈壘鍒板搴旂殑浠诲姟淇℃伅");
- // }
-
- // // 妫�鏌ユ墭鐩樹笂鏄惁鏈夊叾浠栭潪鍑哄簱璐х墿锛堝簱瀛樿揣鐗╋級
- // var palletStockGoods = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
- // .Where(it => it.StockId == stockinfo.Id &&
- // (it.Status == StockStatusEmun.鍏ュ簱纭.ObjToInt() ||
- // it.Status == StockStatusEmun.鍏ュ簱瀹屾垚.ObjToInt() ||
- // it.Status == StockStatusEmun.鍑哄簱閿佸畾.ObjToInt()))
- // .Where(it => it.OutboundQuantity == 0 || it.OutboundQuantity < it.StockQuantity) // 鏈畬鍏ㄥ嚭搴撶殑
- // .ToListAsync();
-
- // // 妫�鏌ユ媶鍖呰褰曪紝鎵惧嚭闇�瑕佸洖搴撶殑鏉$爜
- // var splitRecords = await _splitPackageService.Db.Queryable<Dt_SplitPackageRecord>()
- // .Where(it => it.OrderNo == orderNo && it.PalletCode == palletCode && !it.IsReverted)
- // .ToListAsync();
-
- // // 璁$畻闇�瑕佸洖搴撶殑鎷嗗寘鏉$爜
- // var splitBarcodesToReturn = new List<string>();
- // foreach (var splitRecord in splitRecords)
- // {
- // // 妫�鏌ュ師鏉$爜鏄惁杩樻湁搴撳瓨闇�瑕佸洖搴�
- // var originalStock = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
- // .Where(it => it.Barcode == splitRecord.OriginalBarcode && it.StockId == stockinfo.Id)
- // .FirstAsync();
-
- // if (originalStock != null && originalStock.StockQuantity > 0)
- // {
- // splitBarcodesToReturn.Add(splitRecord.OriginalBarcode);
- // }
-
- // // 妫�鏌ユ柊鏉$爜鏄惁杩樻湁搴撳瓨闇�瑕佸洖搴�
- // var newStock = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
- // .Where(it => it.Barcode == splitRecord.NewBarcode && it.StockId == stockinfo.Id)
- // .FirstAsync();
-
- // if (newStock != null && newStock.StockQuantity > 0)
- // {
- // splitBarcodesToReturn.Add(splitRecord.NewBarcode);
- // }
- // }
-
- // // 濡傛灉娌℃湁闇�瑕佸洖搴撶殑璐х墿锛堟棦鏃犳湭鍒嗘嫞鍑哄簱璐х墿锛屼篃鏃犲叾浠栧簱瀛樿揣鐗╋紝涔熸棤鎷嗗寘鍓╀綑璐х墿锛�
- // if (!remainingLocks.Any() && !palletStockGoods.Any() && !splitBarcodesToReturn.Any())
- // {
- // // 妫�鏌ユ槸鍚︽墍鏈夎揣鐗╅兘宸叉嫞閫夊畬鎴�
- // 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)
- // {
- // return WebResponseContent.Instance.OK("鎵�鏈夎揣鐗╁凡鎷i�夊畬鎴愶紝鎵樼洏涓虹┖");
- // }
- // else
- // {
- // return WebResponseContent.Instance.Error("娌℃湁闇�瑕佸洖搴撶殑鍓╀綑璐х墿");
- // }
- // }
-
- // var firstlocation = _locationInfoService.Db.Queryable<Dt_LocationInfo>().First(x => x.LocationCode == task.SourceAddress);
- // decimal totalReturnQty = 0;
-
- // // 鎯呭喌1锛氬鐞嗘湭鍒嗘嫞鐨勫嚭搴撻攣瀹氳褰�
- // if (remainingLocks.Any(x => x.PalletCode == palletCode))
- // {
- // var palletLocks = remainingLocks.Where(x => x.PalletCode == palletCode).ToList();
- // totalReturnQty = palletLocks.Sum(x => x.AssignQuantity - x.PickedQty);
-
- // if (totalReturnQty > 0)
- // {
- // // 鍒嗛厤鏂拌揣浣�
- // var newLocation = _locationInfoService.AssignLocation(firstlocation.LocationType);
-
- // // 鏇存柊鍑哄簱閿佸畾璁板綍鐘舵��
- // var lockIds = palletLocks.Select(x => x.Id).ToList();
- // await _outStockLockInfoService.Db.Updateable<Dt_OutStockLockInfo>()
- // .SetColumns(it => new Dt_OutStockLockInfo { Status = (int)OutLockStockStatusEnum.鍥炲簱涓� })
- // .Where(it => lockIds.Contains(it.Id))
- // .ExecuteCommandAsync();
-
-
-
- // // 澶勭悊搴撳瓨璁板綍
- // foreach (var lockInfo in palletLocks)
- // {
- // decimal returnQty = lockInfo.AssignQuantity - lockInfo.PickedQty;
-
- // // 妫�鏌ュ簱瀛樿褰曟槸鍚﹀瓨鍦�
- // var existingStock = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
- // .Where(it => it.Barcode == lockInfo.CurrentBarcode && it.StockId == lockInfo.StockId)
- // .FirstAsync();
-
- // if (existingStock != null)
- // {
- // // 搴撳瓨璁板綍瀛樺湪锛屾仮澶嶉攣瀹氭暟閲�
- // existingStock.OutboundQuantity = 0;
-
- // await _stockInfoDetailService.Db.Updateable(existingStock).ExecuteCommandAsync();
- // }
- // else
- // {
- // // 搴撳瓨璁板綍涓嶅瓨鍦紙鍙兘鏄媶鍖呬骇鐢熺殑鏂版潯鐮侊級锛屽垱寤烘柊鐨勫簱瀛樿褰�
- // var newStockDetail = new Dt_StockInfoDetail
- // {
- // StockId = lockInfo.StockId,
- // MaterielCode = lockInfo.MaterielCode,
- // MaterielName = lockInfo.MaterielName,
- // OrderNo = lockInfo.OrderNo,
- // BatchNo = lockInfo.BatchNo,
- // StockQuantity = returnQty,
- // OutboundQuantity = 0,
- // Barcode = lockInfo.CurrentBarcode,
- // InboundOrderRowNo = "",
- // Status = StockStatusEmun.鍏ュ簱瀹屾垚.ObjToInt(),
- // SupplyCode = lockInfo.SupplyCode,
- // WarehouseCode = lockInfo.WarehouseCode,
- // Unit = lockInfo.Unit
- // };
- // await _stockInfoDetailService.Db.Insertable(newStockDetail).ExecuteCommandAsync();
- // }
- // }
-
- // // 鍒涘缓鍥炲簱浠诲姟
- // CreateReturnTask(tasks, task, palletCode, newLocation);
- // }
- // }
-
- // // 鎯呭喌2锛氬鐞嗘媶鍖呭墿浣欑殑搴撳瓨璐х墿
- // if (splitBarcodesToReturn.Any())
- // {
- // decimal splitReturnQty = 0;
-
- // foreach (var barcode in splitBarcodesToReturn)
- // {
- // var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
- // .Where(it => it.Barcode == barcode && it.StockId == stockinfo.Id)
- // .FirstAsync();
-
- // if (stockDetail != null && stockDetail.StockQuantity > 0)
- // {
- // splitReturnQty += stockDetail.StockQuantity;
-
- // // 鎭㈠搴撳瓨鐘舵�佷负鍏ュ簱瀹屾垚
- // stockDetail.OutboundQuantity = 0;
-
- // await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync();
- // }
- // }
-
- // totalReturnQty += splitReturnQty;
-
- // // 濡傛灉娌℃湁鍒涘缓浠诲姟锛屽垱寤哄洖搴撲换鍔�
- // if (!tasks.Any())
- // {
- // var newLocation = _locationInfoService.AssignLocation(firstlocation.LocationType);
- // CreateReturnTask(tasks, task, palletCode, newLocation);
- // }
- // }
-
- // // 鎯呭喌3锛氬嚭搴撹揣鐗╁凡鍒嗘嫞瀹岋紝浣嗘墭鐩樹笂杩樻湁鍏朵粬搴撳瓨璐х墿闇�瑕佸洖搴�
- // if (palletStockGoods.Any() && !remainingLocks.Any(x => x.PalletCode == palletCode))
- // {
- // decimal otherReturnQty = palletStockGoods.Sum(x => x.StockQuantity - x.OutboundQuantity);
- // totalReturnQty += otherReturnQty;
- // // 鏇存柊杩欎簺搴撳瓨璐х墿鐨勭姸鎬�
- // foreach (var stockGood in palletStockGoods)
- // {
- // stockGood.OutboundQuantity = 0;
-
- // await _stockInfoDetailService.Db.Updateable(stockGood).ExecuteCommandAsync();
- // }
- // // 濡傛灉娌℃湁鍒涘缓浠诲姟锛屽垱寤哄洖搴撲换鍔�
- // if (!tasks.Any())
- // {
- // var newLocation = _locationInfoService.AssignLocation(firstlocation.LocationType);
- // CreateReturnTask(tasks, task, palletCode, newLocation);
- // }
-
-
- // }
-
- // var allSplitRecords = await _splitPackageService.Db.Queryable<Dt_SplitPackageRecord>()
- // .Where(it => it.OrderNo == orderNo && it.PalletCode == palletCode && !it.IsReverted)
- // .ToListAsync();
-
- // foreach (var record in allSplitRecords)
- // {
- // record.Status = (int)SplitPackageStatusEnum.宸插洖搴�;
- // await _splitPackageService.Db.Updateable(record).ExecuteCommandAsync();
- // }
- // // 淇濆瓨浠诲姟 缁橢SS涓嬪彂浠诲姟
- // if (tasks.Any())
- // {
- // try
- // {
- // await _taskRepository.Db.Insertable(tasks).ExecuteCommandAsync();
- // var targetAddress = task.TargetAddress;
- // _taskRepository.DeleteData(task);
-
- // // 缁� ESS 娴佸姩淇″彿鍜屽垱寤轰换鍔�
- // try
- // {
- // var result = await _eSSApiService.MoveContainerAsync(new WIDESEA_DTO.Basic.MoveContainerRequest
- // {
- // slotCode = movestations[targetAddress],
- // containerCode = palletCode
- // });
-
- // if (result)
- // {
- // TaskModel esstask = new TaskModel()
- // {
- // taskType = "putaway",
- // taskGroupCode = "",
- // groupPriority = 0,
- // tasks = new List<TasksType>
- // {
- // new()
- // {
- // taskCode = tasks.First().TaskNum.ToString(),
- // taskPriority = 0,
- // taskDescribe = new TaskDescribeType {
- // containerCode = palletCode,
- // containerType = "CT_KUBOT_STANDARD",
- // fromLocationCode = stations.GetValueOrDefault(targetAddress) ?? "",
- // toStationCode = "",
- // toLocationCode = tasks.First().TargetAddress,
- // deadline = 0, storageTag = ""
- // }
- // }
- // }
- // };
-
- // var resulttask = await _eSSApiService.CreateTaskAsync(esstask);
- // _logger.LogInformation("ReturnRemaining 鍒涘缓浠诲姟杩斿洖: " + resulttask);
- // }
- // }
- // catch (Exception ex)
- // {
- // _logger.LogInformation("ReturnRemaining 鍒涘缓浠诲姟杩斿洖 catch err: " + ex.Message);
- // }
-
- // _unitOfWorkManage.CommitTran();
- // return WebResponseContent.Instance.OK($"鍥炲簱鎿嶄綔鎴愬姛锛屽叡鍥炲簱鏁伴噺锛歿totalReturnQty}");
- // }
- // catch (Exception ex)
- // {
- // _unitOfWorkManage.RollbackTran();
- // return WebResponseContent.Instance.Error($"鍒涘缓鍥炲簱浠诲姟澶辫触: {ex.Message}");
- // }
- // }
-
- // _unitOfWorkManage.RollbackTran();
- // return WebResponseContent.Instance.Error("鏈垱寤轰换浣曞洖搴撲换鍔�");
- // }
- // catch (Exception ex)
- // {
- // _unitOfWorkManage.RollbackTran();
- // return WebResponseContent.Instance.Error($"鍥炲簱鎿嶄綔澶辫触: {ex.Message}");
- // }
- //}
-
-
- /// <summary>
- /// 鍒涘缓鍥炲簱浠诲姟
- /// </summary>
- private void CreateReturnTask(List<Dt_Task> tasks, Dt_Task originalTask, string palletCode, Dt_LocationInfo newLocation)
+ private async Task CheckAndUpdateOrderStatus(string orderNo)
{
- Dt_Task newTask = new()
+ try
{
- CurrentAddress = stations[originalTask.TargetAddress],
- Grade = 0,
- PalletCode = palletCode,
- NextAddress = "",
- OrderNo = originalTask.OrderNo,
- Roadway = newLocation.RoadwayNo,
- SourceAddress = stations[originalTask.TargetAddress],
- TargetAddress = newLocation.LocationCode,
- TaskStatus = TaskStatusEnum.New.ObjToInt(),
- TaskType = TaskTypeEnum.InPick.ObjToInt(),
- PalletType = originalTask.PalletType,
- WarehouseId = originalTask.WarehouseId,
+ var orderDetails = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
+ .LeftJoin<Dt_OutboundOrder>((o, item) => o.OrderId == item.Id)
+ .Where((o, item) => item.OrderNo == orderNo)
+ .Select((o, item) => o)
+ .ToListAsync();
- };
- tasks.Add(newTask);
- }
-
- /// <summary>
- /// 妫�鏌ユ墭鐩樻槸鍚﹂渶瑕佸洖搴撶殑杈呭姪鏂规硶
- /// </summary>
- public async Task<bool> CheckPalletNeedReturn(string orderNo, string palletCode)
- {
- // 1. 妫�鏌ユ槸鍚︽湁鏈垎鎷g殑鍑哄簱璁板綍
- var hasUnpickedLocks = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
- .Where(it => it.OrderNo == orderNo && it.PalletCode == palletCode && it.Status == 1)
- .AnyAsync();
-
- if (hasUnpickedLocks)
- return true;
-
- // 2. 妫�鏌ュ嚭搴撴槸鍚﹀凡瀹屾垚浣嗘墭鐩樿繕鏈夊簱瀛樿揣鐗�
- var outboundFinished = !await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
- .Where(it => it.PalletCode == palletCode && it.Status == 1)
- .AnyAsync();
-
- var stockinfo = _stockInfoService.Db.Queryable<Dt_StockInfo>().First(x => x.PalletCode == palletCode);
-
-
- var hasRemainingGoods = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
- .Where(it => it.StockId == stockinfo.Id && it.Status == StockStatusEmun.鍏ュ簱纭.ObjToInt())
- .Where(it => it.OutboundQuantity == 0 || it.OutboundQuantity < it.StockQuantity)
- .AnyAsync();
-
- return outboundFinished && hasRemainingGoods;
- }
-
-
- /// <summary>
- /// 鑾峰彇鎷嗗寘閾撅紙浠庡綋鍓嶆潯鐮佽拷婧埌鍘熷鏉$爜锛�
- /// </summary>
- // 鍦� GetSplitChain 鏂规硶涓坊鍔犳洿涓ユ牸鐨勯獙璇�
- private async Task<List<SplitChainItem>> GetSplitChain(string currentBarcode)
- {
- var chain = new List<SplitChainItem>();
- var visited = new HashSet<string>();
-
- string current = currentBarcode;
- int maxDepth = 10; // 闃叉鏃犻檺寰幆
-
- while (!string.IsNullOrEmpty(current) && maxDepth > 0)
- {
- maxDepth--;
-
- if (visited.Contains(current))
+ bool allCompleted = true;
+ foreach (var detail in orderDetails)
{
- _logger.LogWarning($"妫�娴嬪埌寰幆寮曠敤鍦ㄦ媶鍖呴摼涓�: {current}");
- break;
+ if (detail.OverOutQuantity < detail.NeedOutQuantity)
+ {
+ allCompleted = false;
+ break;
+ }
}
- visited.Add(current);
+ var outboundOrder = await _outboundOrderService.Db.Queryable<Dt_OutboundOrder>()
+ .FirstAsync(x => x.OrderNo == orderNo);
- var splitRecord = await _splitPackageService.Db.Queryable<Dt_SplitPackageRecord>()
- .Where(it => it.NewBarcode == current && !it.IsReverted)
- .FirstAsync();
+ if (outboundOrder == null) return;
- if (splitRecord == null)
- break;
+ int newStatus = allCompleted ? (int)OutOrderStatusEnum.鍑哄簱瀹屾垚 : (int)OutOrderStatusEnum.鍑哄簱涓�;
- // 楠岃瘉鎷嗗寘璁板綍鐨勫畬鏁存��
- if (string.IsNullOrEmpty(splitRecord.OriginalBarcode))
+ if (outboundOrder.OrderStatus != newStatus)
{
- _logger.LogError($"鎷嗗寘璁板綍 {splitRecord.Id} 缂哄皯鍘熷鏉$爜");
- break;
+ await _outboundOrderService.Db.Updateable<Dt_OutboundOrder>()
+ .SetColumns(x => x.OrderStatus == newStatus)
+ .Where(x => x.OrderNo == orderNo)
+ .ExecuteCommandAsync();
+
+ // 鍙湁姝e父鍒嗘嫞瀹屾垚鏃舵墠鍚慚ES鍙嶉
+ if (allCompleted && newStatus == (int)OutOrderStatusEnum.鍑哄簱瀹屾垚)
+ {
+ await HandleOrderCompletion(outboundOrder, orderNo);
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError($"CheckAndUpdateOrderStatus澶辫触 - OrderNo: {orderNo}, Error: {ex.Message}");
+ }
+ }
+
+ private async Task UpdateOrderStatusForReturn(string orderNo)
+ {
+ try
+ {
+ var orderDetails = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
+ .LeftJoin<Dt_OutboundOrder>((o, item) => o.OrderId == item.Id)
+ .Where((o, item) => item.OrderNo == orderNo)
+ .Select((o, item) => o)
+ .ToListAsync();
+
+ bool allCompleted = true;
+ foreach (var detail in orderDetails)
+ {
+ if (detail.OverOutQuantity < detail.NeedOutQuantity)
+ {
+ allCompleted = false;
+ break;
+ }
}
- var item = new SplitChainItem
+ var outboundOrder = await _outboundOrderService.Db.Queryable<Dt_OutboundOrder>()
+ .FirstAsync(x => x.OrderNo == orderNo);
+
+ if (outboundOrder == null) return;
+
+ int newStatus = allCompleted ? (int)OutOrderStatusEnum.鍑哄簱瀹屾垚 : (int)OutOrderStatusEnum.鍑哄簱涓�;
+
+ if (outboundOrder.OrderStatus != newStatus)
{
- SplitRecord = splitRecord,
- OriginalBarcode = splitRecord.OriginalBarcode,
- NewBarcode = splitRecord.NewBarcode,
- SplitQuantity = splitRecord.SplitQty
+ await _outboundOrderService.Db.Updateable<Dt_OutboundOrder>()
+ .SetColumns(x => x.OrderStatus == newStatus)
+ .Where(x => x.OrderNo == orderNo)
+ .ExecuteCommandAsync();
+
+ _logger.LogInformation($"鍥炲簱鎿嶄綔鏇存柊璁㈠崟鐘舵�� - OrderNo: {orderNo}, 鏂扮姸鎬�: {newStatus}");
+ }
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError($"UpdateOrderStatusForReturn澶辫触 - OrderNo: {orderNo}, Error: {ex.Message}");
+ }
+ }
+
+ private async Task HandleOrderCompletion(Dt_OutboundOrder outboundOrder, string orderNo)
+ {
+ // 璋冩嫧鍑哄簱鍜岄噸妫�鍑哄簱涓嶉渶瑕佸弽棣圡ES
+ if (outboundOrder.OrderType == OutOrderTypeEnum.Allocate.ObjToInt() ||
+ outboundOrder.OrderType == OutOrderTypeEnum.ReCheck.ObjToInt())
+ {
+ return;
+ }
+
+ 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 = outboundOrder.Operator,
+ orderNo = outboundOrder.UpperOrderNo,
+ status = outboundOrder.OrderStatus,
+ details = new List<FeedbackOutboundDetailsModel>()
};
- chain.Add(item);
+ // 鍙幏鍙栧凡鎷i�夊畬鎴愮殑閿佸畾璁板綍
+ var lists = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+ .Where(x => x.OrderNo == orderNo && x.Status == (int)OutLockStockStatusEnum.鎷i�夊畬鎴�)
+ .ToListAsync();
- current = splitRecord.OriginalBarcode;
+ var groupedData = lists.GroupBy(item => new { item.MaterielCode, item.lineNo, item.Unit, item.WarehouseCode })
+ .Select(group => new FeedbackOutboundDetailsModel
+ {
+ materialCode = group.Key.MaterielCode,
+ lineNo = group.Key.lineNo,
+ warehouseCode = group.Key.WarehouseCode,
+ currentDeliveryQty = group.Sum(x => x.PickedQty),
+ unit = group.Key.Unit,
+ barcodes = group.Select(row => new WIDESEA_DTO.Outbound.BarcodesModel
+ {
+ barcode = row.CurrentBarcode,
+ supplyCode = row.SupplyCode,
+ batchNo = row.BatchNo,
+ unit = row.Unit,
+ 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 => x.ReturnToMESStatus == 1)
+ .Where(x => x.OrderNo == orderNo)
+ .ExecuteCommandAsync();
+ }
}
-
- if (maxDepth <= 0)
+ catch (Exception ex)
{
- _logger.LogWarning($"鎷嗗寘閾捐拷婧揪鍒版渶澶ф繁搴�: {currentBarcode}");
+ _logger.LogError($"FeedbackOutbound澶辫触 - OrderNo: {orderNo}, Error: {ex.Message}");
}
-
- chain.Reverse();
- return chain;
- }
- /// <summary>
- /// 澶勭悊鎷嗗寘閾剧殑鍙栨秷鍒嗘嫞
- /// </summary>
- private async Task HandleSplitChainCancel(string orderNo, string palletCode, string barcode,
- decimal cancelQty, Dt_OutStockLockInfo lockInfo, Dt_PickingRecord pickingRecord, List<SplitChainItem> splitChain)
- {
- if (!splitChain.Any())
- return;
-
- // 鎵惧埌鍘熷鏉$爜锛堥摼鐨勭涓�涓級
- var originalSplitItem = splitChain.First();
- var originalBarcode = originalSplitItem.OriginalBarcode;
-
- // 鏌ユ壘鍘熷鏉$爜鐨勯攣瀹氫俊鎭拰搴撳瓨
- var originalLockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
- .Where(it => it.CurrentBarcode == originalBarcode && it.Status == (int)OutLockStockStatusEnum.鍑哄簱涓�)
- .FirstAsync();
-
- var originalStockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
- .Where(it => it.Barcode == originalBarcode && it.StockId == originalLockInfo.StockId)
- .FirstAsync();
-
- if (originalLockInfo == null || originalStockDetail == null)
- throw new Exception("鏈壘鍒板師濮嬫潯鐮佺殑閿佸畾淇℃伅鎴栧簱瀛樹俊鎭�");
-
- // 鎭㈠鍘熷鏉$爜搴撳瓨锛堝皢鍙栨秷鐨勬暟閲忓姞鍥炲幓锛�
- originalStockDetail.StockQuantity += cancelQty;
- originalStockDetail.OutboundQuantity += cancelQty;
- await _stockInfoDetailService.Db.Updateable(originalStockDetail).ExecuteCommandAsync();
-
- // 鎭㈠鍘熷鏉$爜閿佸畾淇℃伅
- originalLockInfo.AssignQuantity += cancelQty;
- await _outStockLockInfoService.Db.Updateable(originalLockInfo).ExecuteCommandAsync();
-
- // 鍒犻櫎鎷嗗寘閾句腑鎵�鏈夋柊鏉$爜鐨勯攣瀹氫俊鎭拰搴撳瓨璁板綍
- var allNewBarcodes = splitChain.Select(x => x.NewBarcode).ToList();
-
- // 鍒犻櫎閿佸畾淇℃伅
- await _outStockLockInfoService.Db.Deleteable<Dt_OutStockLockInfo>()
- .Where(it => allNewBarcodes.Contains(it.CurrentBarcode))
- .ExecuteCommandAsync();
-
- // 鍒犻櫎搴撳瓨璁板綍锛堝彧鍒犻櫎鎷嗗寘浜х敓鐨勬柊鏉$爜搴撳瓨锛屼繚鐣欏師濮嬫潯鐮侊級
- await _stockInfoDetailService.Db.Deleteable<Dt_StockInfoDetail>()
- .Where(it => allNewBarcodes.Contains(it.Barcode) && it.Barcode != originalBarcode)
- .ExecuteCommandAsync();
-
- // 鏇存柊鎷嗗寘閾句腑鎵�鏈夋媶鍖呰褰曠姸鎬佷负宸叉媶鍖�
- foreach (var chainItem in splitChain)
- {
- chainItem.SplitRecord.Status = (int)SplitPackageStatusEnum.宸叉媶鍖�;
- await _splitPackageService.Db.Updateable(chainItem.SplitRecord).ExecuteCommandAsync();
- }
-
- // 鎭㈠璁㈠崟鏄庣粏鎷i�夋暟閲忥紙浣跨敤鍘熷閿佸畾淇℃伅鐨勮鍗曟槑缁咺D锛�
- await _outboundOrderDetailService.Db.Updateable<Dt_OutboundOrderDetail>()
- .SetColumns(it => it.PickedQty == it.PickedQty - cancelQty)
- .Where(it => it.Id == originalLockInfo.OrderDetailId)
- .ExecuteCommandAsync();
-
- // 鎭㈠璁㈠崟鐘舵��
- await CheckAndRevertOrderStatus(orderNo);
-
- // 鍒犻櫎鎷i�夎褰�
- await Db.Deleteable<Dt_PickingRecord>()
- .Where(it => it.Id == pickingRecord.Id)
- .ExecuteCommandAsync();
-
- //// 璁板綍鍙栨秷鎿嶄綔鍘嗗彶
- //await RecordCancelHistory(orderNo, palletCode, barcode, cancelQty, pickingRecord.Id,
- // lockInfo.MaterielCode, "鍙栨秷鎷嗗寘閾惧垎鎷�");
}
- /// <summary>
- /// 澶勭悊鏅�氭潯鐮佺殑鍙栨秷鍒嗘嫞
- /// </summary>
- private async Task HandleNormalBarcodeCancel(string orderNo, string palletCode, string barcode,
- decimal cancelQty, Dt_OutStockLockInfo lockInfo, Dt_PickingRecord pickingRecord)
+ #endregion
+
+ #region 杈呭姪鏂规硶
+
+ private async Task<string> GenerateNewBarcode()
{
- // 1. 鏌ユ壘搴撳瓨淇℃伅
- var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
- .Where(it => it.Barcode == barcode && it.StockId == lockInfo.StockId)
- .FirstAsync();
+ var seq = await _dailySequenceService.GetNextSequenceAsync();
+ return "WSLOT" + DateTime.Now.ToString("yyyyMMdd") + seq.ToString()?.PadLeft(5, '0');
+ }
- if (stockDetail == null)
- throw new Exception("鏈壘鍒板搴旂殑搴撳瓨淇℃伅");
-
- // 2. 鎭㈠搴撳瓨鏁伴噺
- if (stockDetail.StockQuantity == 0)
+ private async Task<Dt_OutStockLockInfo> CreateSplitLockInfo(Dt_OutStockLockInfo originalLock, decimal quantity, string newBarcode)
+ {
+ var newLockInfo = new Dt_OutStockLockInfo
{
- // 鏁村寘鍑哄簱鐨勬儏鍐�
- stockDetail.StockQuantity = cancelQty;
- stockDetail.OutboundQuantity = cancelQty;
- }
- else
+ OrderNo = originalLock.OrderNo,
+ OrderDetailId = originalLock.OrderDetailId,
+ BatchNo = originalLock.BatchNo,
+ MaterielCode = originalLock.MaterielCode,
+ MaterielName = originalLock.MaterielName,
+ StockId = originalLock.StockId,
+ OrderQuantity = quantity,
+ OriginalQuantity = quantity,
+ AssignQuantity = quantity,
+ PickedQty = quantity,
+ LocationCode = originalLock.LocationCode,
+ PalletCode = originalLock.PalletCode,
+ TaskNum = originalLock.TaskNum,
+ Status = (int)OutLockStockStatusEnum.鎷i�夊畬鎴�,
+ Unit = originalLock.Unit,
+ SupplyCode = originalLock.SupplyCode,
+ OrderType = originalLock.OrderType,
+ CurrentBarcode = newBarcode,
+ OriginalLockQuantity = quantity,
+ IsSplitted = 1,
+ ParentLockId = originalLock.Id
+ };
+
+ var newLockId = await _outStockLockInfoService.Db.Insertable(newLockInfo).ExecuteReturnIdentityAsync();
+ newLockInfo.Id = newLockId;
+ return newLockInfo;
+ }
+
+ private async Task RecordSplitHistory(Dt_OutStockLockInfo lockInfo, Dt_StockInfoDetail stockDetail,
+ decimal splitQty, decimal remainQty, string newBarcode)
+ {
+ var splitHistory = new Dt_SplitPackageRecord
{
- // 閮ㄥ垎鍑哄簱鐨勬儏鍐�
- stockDetail.StockQuantity += cancelQty;
- stockDetail.OutboundQuantity += cancelQty;
- }
- await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync();
+ FactoryArea = lockInfo.FactoryArea,
+ TaskNum = lockInfo.TaskNum,
+ OutStockLockInfoId = lockInfo.Id,
+ StockId = stockDetail.StockId,
+ Operator = App.User.UserName,
+ IsReverted = false,
+ OriginalBarcode = stockDetail.Barcode,
+ NewBarcode = newBarcode,
+ SplitQty = splitQty,
+ RemainQuantity = remainQty,
+ MaterielCode = lockInfo.MaterielCode,
+ SplitTime = DateTime.Now,
+ OrderNo = lockInfo.OrderNo,
+ PalletCode = lockInfo.PalletCode,
+ Status = (int)SplitPackageStatusEnum.宸叉嫞閫�
+ };
- // 3. 鎭㈠閿佸畾淇℃伅鐘舵��
- lockInfo.AssignQuantity += cancelQty;
- lockInfo.PickedQty -= cancelQty;
+ await _splitPackageService.Db.Insertable(splitHistory).ExecuteCommandAsync();
+ }
- if (lockInfo.PickedQty == 0)
+ private List<SplitResult> CreateSplitResults(Dt_OutStockLockInfo lockInfo, decimal splitQty, decimal remainQty, string newBarcode, string originalBarcode)
+ {
+ return new List<SplitResult>
+ {
+ new SplitResult
{
- lockInfo.Status = (int)OutLockStockStatusEnum.鍑哄簱涓�;
+ materialCode = lockInfo.MaterielCode,
+ supplierCode = lockInfo.SupplyCode,
+ quantityTotal = splitQty.ToString("F2"),
+ batchNumber = newBarcode,
+ batch = lockInfo.BatchNo,
+ factory = lockInfo.FactoryArea,
+ date = DateTime.Now.ToString("yyyy-MM-dd"),
+ },
+ new SplitResult
+ {
+ materialCode = lockInfo.MaterielCode,
+ supplierCode = lockInfo.SupplyCode,
+ quantityTotal = remainQty.ToString("F2"),
+ batchNumber = originalBarcode,
+ batch = lockInfo.BatchNo,
+ factory = lockInfo.FactoryArea,
+ date = DateTime.Now.ToString("yyyy-MM-dd"),
}
- await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync();
+ };
+ }
- // 4. 澶勭悊鐩稿叧鐨勬媶鍖呰褰曠姸鎬佹仮澶�
+ private async Task UpdateSplitRecordsStatus(string barcode)
+ {
var relatedSplitRecords = await _splitPackageService.Db.Queryable<Dt_SplitPackageRecord>()
- .Where(it => it.OriginalBarcode == barcode &&
- it.Status == (int)SplitPackageStatusEnum.宸叉嫞閫�)
+ .Where(it => it.OriginalBarcode == barcode || it.NewBarcode == barcode)
+ .Where(it => !it.IsReverted)
.ToListAsync();
foreach (var record in relatedSplitRecords)
{
- record.Status = (int)SplitPackageStatusEnum.宸叉媶鍖�;
+ record.Status = (int)SplitPackageStatusEnum.宸叉嫞閫�;
await _splitPackageService.Db.Updateable(record).ExecuteCommandAsync();
}
-
- // 5. 鎭㈠璁㈠崟鏄庣粏鐨勬嫞閫夋暟閲�
- await _outboundOrderDetailService.Db.Updateable<Dt_OutboundOrderDetail>()
- .SetColumns(it => it.PickedQty == it.PickedQty - cancelQty)
- .Where(it => it.Id == lockInfo.OrderDetailId)
- .ExecuteCommandAsync();
-
- // 6. 鎭㈠璁㈠崟鐘舵��
- await CheckAndRevertOrderStatus(orderNo);
-
- // 7. 鍒犻櫎鎷i�夎褰�
- await Db.Deleteable<Dt_PickingRecord>().Where(it => it.Id == pickingRecord.Id).ExecuteCommandAsync();
-
- //// 8. 璁板綍鍙栨秷鎿嶄綔鍘嗗彶
- //await RecordCancelHistory(orderNo, palletCode, barcode, cancelQty, pickingRecord.Id,
- // lockInfo.MaterielCode, "鍙栨秷鍒嗘嫞");
}
- /// <summary>
- /// 妫�鏌ュ苟鎭㈠璁㈠崟鐘舵��
- /// </summary>
- private async Task CheckAndRevertOrderStatus(string orderNo)
+ private async Task<int> GenerateTaskNumber()
{
- var order = await _outboundOrderService.Db.Queryable<Dt_OutboundOrder>()
- .Where(x => x.OrderNo == orderNo)
- .FirstAsync();
+ return await _dailySequenceService.GetNextSequenceAsync();
+ }
- if (order != null && order.OrderStatus == OutOrderStatusEnum.鍑哄簱瀹屾垚.ObjToInt())
+ private WebResponseContent CreatePickingResponse(PickingResult result, string adjustedReason)
+ {
+ if (result.SplitResults.Any())
{
- await _outboundOrderService.Db.Updateable<Dt_OutboundOrder>()
- .SetColumns(x => x.OrderStatus == OutOrderStatusEnum.鍑哄簱涓�.ObjToInt())
- .Where(x => x.OrderNo == orderNo)
- .ExecuteCommandAsync();
- }
- }
-
-
-
- // 鑾峰彇鏈嫞閫夊垪琛�
- public async Task<List<Dt_OutStockLockInfo>> GetUnpickedList(string orderNo, string palletCode)
- {
- var list = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
- .Where(x => x.OrderNo == orderNo &&
- x.PalletCode == palletCode &&
- x.Status == 1)
- .ToListAsync();
- return list.Where(x => x.RemainQuantity > 0).ToList();
- }
-
- // 鑾峰彇宸叉嫞閫夊垪琛�
- public async Task<List<Dt_OutStockLockInfo>> GetPickedList(string orderNo, string palletCode)
- {
- var list = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
- .Where(x => x.OrderNo == orderNo &&
- x.PalletCode == palletCode &&
- x.Status == 6)
- .ToListAsync();
- return list;
- }
- // 鑾峰彇鎷i�夋眹鎬�
- public async Task<object> GetPickingSummary(ConfirmPickingDto dto)
- {
- var picked = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
- .WhereIF(!string.IsNullOrEmpty(dto.OrderNo), x => x.OrderNo == dto.OrderNo)
- .WhereIF(!string.IsNullOrEmpty(dto.PalletCode), x => x.PalletCode == dto.PalletCode)
- .Where(x => x.Status == 6)
- .GroupBy(x => new { x.PalletCode, x.MaterielCode })
- .Select(x => new SummaryPickingDto
- {
- PalletCode = x.PalletCode,
- MaterielCode = x.MaterielCode,
- pickedCount = SqlFunc.AggregateCount(x.Id)
- }).FirstAsync();
- if (picked == null)
- {
- picked = new SummaryPickingDto { pickedCount = 0 };
+ return WebResponseContent.Instance.OK("鎷i�夌‘璁ゆ垚鍔燂紝宸茶嚜鍔ㄦ媶鍖�", new { SplitResults = result.SplitResults });
}
- var summary = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
- .WhereIF(!string.IsNullOrEmpty(dto.OrderNo), x => x.OrderNo == dto.OrderNo)
- .WhereIF(!string.IsNullOrEmpty(dto.PalletCode), x => x.PalletCode == dto.PalletCode)
- .Where(x => x.Status == 1)
- .GroupBy(x => new { x.PalletCode, x.MaterielCode })
- .Select(x => new SummaryPickingDto
- {
- PalletCode = x.PalletCode,
- MaterielCode = x.MaterielCode,
- UnpickedCount = SqlFunc.AggregateCount(x.Id),
- UnpickedQuantity = SqlFunc.AggregateSum(x.AssignQuantity) - SqlFunc.AggregateSum(x.PickedQty),
-
- }).FirstAsync();
- if (summary == null)
- {
- summary = new SummaryPickingDto { pickedCount = 0 };
- }
- summary.pickedCount = picked.pickedCount;
-
- return summary;
- }
- /// <summary>
- /// 鑾峰彇鎷i�夊巻鍙�
- /// </summary>
- public async Task<List<Dt_PickingRecord>> GetPickingHistory(int orderId)
- {
- // 閫氳繃鍑哄簱鍗旾D鏌ヨ鐩稿叧鐨勬嫞閫夊巻鍙�
- // 娉ㄦ剰锛欴t_PickingRecord 涓病鏈夌洿鎺ュ瓨鍌∣rderId锛岄渶瑕侀�氳繃鍑哄簱鍗曟槑缁嗗叧鑱�
- var detailIds = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
- .Where(d => d.OrderId == orderId)
- .Select(d => d.Id)
- .ToListAsync();
-
- return await Db.Queryable<Dt_PickingRecord>()
- .Where(p => detailIds.Contains(p.OrderDetailId))
- .OrderByDescending(p => p.PickTime)
- .ToListAsync();
+ return WebResponseContent.Instance.OK("鎷i�夌‘璁ゆ垚鍔�", new { SplitResults = new List<SplitResult>() });
}
-
- /// <summary>
- /// 鑾峰彇鎵樼洏鐨勫嚭搴撶姸鎬佷俊鎭�
- /// </summary>
- public async Task<WebResponseContent> GetPalletOutboundStatus(string palletCode)
- {
- // 鑾峰彇鎵樼洏鐨勯攣瀹氫俊鎭�
- var lockInfos = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
- .Where(x => x.PalletCode == palletCode)
- .ToListAsync();
-
- // 鑾峰彇鎵樼洏搴撳瓨淇℃伅
- var stockInfo = await _stockInfoService.Db.Queryable<Dt_StockInfo>()
- .Includes(x => x.Details)
- .Where(x => x.PalletCode == palletCode)
- .FirstAsync();
-
- if (stockInfo == null)
- return WebResponseContent.Instance.Error("鏈壘鍒版墭鐩樹俊鎭�");
-
- // 璁$畻鍚勭鏁伴噺
- var totalStockQuantity = stockInfo.Details.Sum(x => x.StockQuantity);
- var totalOutboundQuantity = stockInfo.Details.Sum(x => x.OutboundQuantity);
- var totalLockedQuantity = lockInfos.Where(x => x.Status == (int)OutLockStockStatusEnum.鍑哄簱涓�)
- .Sum(x => x.AssignQuantity - x.PickedQty);
- var totalPickedQuantity = lockInfos.Sum(x => x.PickedQty);
-
- var result = new
- {
- PalletCode = palletCode,
- LocationCode = stockInfo.LocationCode,
- StockStatus = stockInfo.StockStatus,
- TotalStockQuantity = totalStockQuantity,
- TotalOutboundQuantity = totalOutboundQuantity,
- TotalLockedQuantity = totalLockedQuantity,
- TotalPickedQuantity = totalPickedQuantity,
- AvailableQuantity = totalStockQuantity - totalOutboundQuantity,
- LockInfos = lockInfos.Select(x => new
- {
- x.Id,
- x.MaterielCode,
- x.OrderDetailId,
- x.AssignQuantity,
- x.PickedQty,
- x.Status,
- x.CurrentBarcode,
- x.IsSplitted
- }).ToList(),
- StockDetails = stockInfo.Details.Select(x => new
- {
- x.Barcode,
- x.MaterielCode,
- StockQuantity = x.StockQuantity,
- OutboundQuantity = x.OutboundQuantity,
- AvailableQuantity = x.StockQuantity - x.OutboundQuantity
- }).ToList()
- };
-
- return WebResponseContent.Instance.OK(null, result);
- }
-
- /// <summary>
- /// 鐩存帴鍑哄簱 - 鏁翠釜鎵樼洏鍑哄簱锛屾竻绌哄簱瀛�
- /// </summary>
- public async Task<WebResponseContent> DirectOutbound(DirectOutboundRequest request)
- {
- try
- {
- _unitOfWorkManage.BeginTran();
-
- var stockInfo = await _stockInfoService.Db.Queryable<Dt_StockInfo>()
- .Includes(x => x.Details)
- .Where(x => x.PalletCode == request.PalletCode).FirstAsync();
-
- if (stockInfo == null)
- return WebResponseContent.Instance.Error("鏈壘鍒版墭鐩樺簱瀛樹俊鎭�");
-
-
- var lockInfos = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
- .Where(x => x.OrderNo == request.OrderNo && x.PalletCode == request.PalletCode)
- .ToListAsync();
-
-
- foreach (var lockInfo in lockInfos)
- {
- if (lockInfo.Status == (int)OutLockStockStatusEnum.鍑哄簱涓�)
- {
- lockInfo.PickedQty = lockInfo.AssignQuantity;
- }
- lockInfo.Status = (int)OutLockStockStatusEnum.宸插嚭搴�;
- await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync();
-
- var orderDetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
- .Where(x => x.Id == lockInfo.OrderDetailId)
- .FirstAsync();
- if (orderDetail != null)
- {
- orderDetail.OverOutQuantity += lockInfo.PickedQty;
- orderDetail.LockQuantity -= lockInfo.PickedQty;
- orderDetail.OrderDetailStatus = (int)OrderDetailStatusEnum.Over;
- orderDetail.LockQuantity = 0;
- await _outboundOrderDetailService.Db.Updateable(orderDetail).ExecuteCommandAsync();
- }
- }
- var groupDetails = lockInfos.GroupBy(x => x.OrderDetailId).Select(x => new
- {
- OrderDetailId = x.Key,
- TotalQuantity = x.Sum(o => o.PickedQty)
- }).ToList();
- foreach (var item in groupDetails)
- {
- var orderDetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>().Where(x => x.Id == item.OrderDetailId).FirstAsync();
- if (orderDetail != null)
- {
- orderDetail.OverOutQuantity = item.TotalQuantity;
- orderDetail.LockQuantity = 0;
- orderDetail.OrderDetailStatus = (int)OrderDetailStatusEnum.Over;
- await _outboundOrderDetailService.Db.Updateable(orderDetail).ExecuteCommandAsync();
- }
- }
-
- await CheckAndUpdateOrderStatus(request.OrderNo);
-
- var lockInfoIds = lockInfos.Select(x => x.Id).ToList();
- var splitRecords = await _splitPackageService.Db.Queryable<Dt_SplitPackageRecord>()
- .Where(x => lockInfoIds.Contains(x.OutStockLockInfoId) &&
- x.Status == (int)SplitPackageStatusEnum.宸叉媶鍖�)
- .ToListAsync();
-
- foreach (var record in splitRecords)
- {
- record.Status = (int)SplitPackageStatusEnum.宸叉嫞閫�;
- await _splitPackageService.Db.Updateable(record).ExecuteCommandAsync();
- }
-
-
- var location = await _locationInfoService.Db.Queryable<Dt_LocationInfo>()
- .Where(x => x.LocationCode == stockInfo.LocationCode)
- .FirstAsync();
- if (location != null)
- {
- location.LocationStatus = (int)LocationStatusEnum.Free;
- await _locationInfoService.Db.Updateable(location).ExecuteCommandAsync();
- }
-
- foreach (var detail in stockInfo.Details)
- {
- await _stockInfoDetailService.Db.Deleteable(detail).ExecuteCommandAsync();
- }
- await _stockInfoService.Db.Deleteable(stockInfo).ExecuteCommandAsync();
-
-
-
- _unitOfWorkManage.CommitTran();
- return WebResponseContent.Instance.OK("鐩存帴鍑哄簱鎴愬姛");
- }
- catch (Exception ex)
- {
- _unitOfWorkManage.RollbackTran();
- return WebResponseContent.Instance.Error($"鐩存帴鍑哄簱澶辫触: {ex.Message}");
- }
- }
+ #endregion
}
+ #region 鏀寔绫诲畾涔�
- #region 杩斿洖
- /// <summary>
- /// 鎷嗗寘閾鹃」
- /// </summary>
- public class SplitChainItem
+ public class ValidationResult<T>
{
- public Dt_SplitPackageRecord SplitRecord { get; set; }
- public string OriginalBarcode { get; set; }
- public string NewBarcode { get; set; }
- public decimal SplitQuantity { get; set; }
+ public bool IsValid { get; set; }
+ public T Data { get; set; }
+ public string ErrorMessage { get; set; }
+
+ public static ValidationResult<T> Success(T data)
+ {
+ return new ValidationResult<T>
+ {
+ IsValid = true,
+ Data = data
+ };
+ }
+
+ public static ValidationResult<T> Error(string message)
+ {
+ return new ValidationResult<T>
+ {
+ IsValid = false,
+ ErrorMessage = message
+ };
+ }
}
- public class ReturnAnalysisResult
+
+ public class PickingResult
+ {
+ public Dt_OutStockLockInfo FinalLockInfo { get; set; }
+ public string FinalBarcode { get; set; }
+ public int FinalStockId { get; set; }
+ public decimal ActualPickedQty { get; set; }
+ public List<SplitResult> SplitResults { get; set; } = new List<SplitResult>();
+ }
+
+ public class ReturnAnalysisResult
{
public bool HasItemsToReturn { get; set; }
public bool HasRemainingLocks { get; set; }
@@ -1999,5 +1449,4 @@
}
#endregion
-
}
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_WMSServer/Controllers/Outbound/OutboundPickingController.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_WMSServer/Controllers/Outbound/OutboundPickingController.cs"
index 0acdabf..dd51866 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_WMSServer/Controllers/Outbound/OutboundPickingController.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_WMSServer/Controllers/Outbound/OutboundPickingController.cs"
@@ -21,14 +21,7 @@
_splitPackageService = splitPackageService;
_outStockLockInfoService = outStockLockInfoService;
}
- /// <summary>
- /// 鑾峰彇鎵樼洏鐨勫嚭搴撶姸鎬�
- /// </summary>
- [HttpPost("GetPalletOutboundStatus")]
- public async Task<WebResponseContent> GetPalletOutboundStatus(string palletCode)
- {
- return await Service.GetPalletOutboundStatus(palletCode);
- }
+
/// <summary>
/// 鑾峰彇鎵樼洏鐨勯攣瀹氫俊鎭�
@@ -98,50 +91,13 @@
return await Service.ReturnRemaining(dto.OrderNo, dto.PalletCode, "");
}
- [HttpPost("direct-outbound")]
- public async Task<WebResponseContent> DirectOutbound([FromBody] DirectOutboundRequest dto)
- {
- return await Service.DirectOutbound(dto);
-
- }
-
- ///// <summary>
- ///// 鎷i�夌‘璁�
- ///// </summary>
- //[HttpPost("ConfirmPicking")]
- //public async Task<WebResponseContent> ConfirmPicking([FromBody] PickingConfirmRequest request)
+ //[HttpPost("direct-outbound")]
+ //public async Task<WebResponseContent> DirectOutbound([FromBody] DirectOutboundRequest dto)
//{
- // return await Service.ConfirmPicking(request);
- //}
- /// <summary>
- /// 楠岃瘉鏉$爜骞惰幏鍙栫墿鏂欎俊鎭�
- /// </summary>
- [HttpGet("ValidateBarcode")]
- public async Task<WebResponseContent> ValidateBarcode(string barcode)
- {
- return await Service.ValidateBarcode(barcode);
- }
+ // return await Service.DirectOutbound(dto);
-
- ///// <summary>
- ///// 鐩存帴鍑哄簱
- ///// </summary>
- //[HttpPost("DirectOutbound")]
- //public async Task<WebResponseContent> DirectOutbound([FromBody] DirectOutboundRequest request)
- //{
- // return await Service.DirectOutbound(request);
- //}
-
- /// <summary>
- /// 鑾峰彇鎷i�夊巻鍙�
- /// </summary>
- [HttpGet("GetPickingHistory")]
- public async Task<WebResponseContent> GetPickingHistory(int orderId)
- {
- var history = await Service.GetPickingHistory(orderId);
- return WebResponseContent.Instance.OK(null, history);
- }
-
+ //}
+
/// <summary>
/// 鎾ら攢鎷i��
/// </summary>
--
Gitblit v1.9.3