From 28e67084df6e36f7b3ac3b914d97fa51acb21f8f Mon Sep 17 00:00:00 2001
From: 647556386 <647556386@qq.com>
Date: 星期五, 06 二月 2026 18:22:31 +0800
Subject: [PATCH] 1
---
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundService.cs | 1109 +++++++++++++++++++++++++++++++++-------------------------
1 files changed, 631 insertions(+), 478 deletions(-)
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundService.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundService.cs"
index 6adef6d..af8d795 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundService.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundService.cs"
@@ -22,12 +22,14 @@
using WIDESEA_DTO.Base;
using WIDESEA_DTO.Basic;
using WIDESEA_DTO.CalcOut;
+using WIDESEA_DTO.Outbound;
using WIDESEA_DTO.ReturnMES;
using WIDESEA_IBasicService;
using WIDESEA_IOutboundService;
using WIDESEA_IRecordService;
using WIDESEA_IStockService;
using WIDESEA_Model.Models;
+using WIDESEA_Model.Models.Check;
using static HslCommunication.Profinet.Knx.KnxCode;
namespace WIDESEA_OutboundService
@@ -61,6 +63,8 @@
private readonly IESSApiService _eSSApiService;
private readonly IRepository<Dt_AllocateOrder> _allocateOrderRepository;
private readonly IRepository<Dt_AllocateMaterialInfo> _allocateMaterialInfoRepository;
+ public readonly IRepository<Dt_InboundOrderDetail> _inboundOrderDetailRepository;
+ public readonly IRepository<Dt_InboundOrder> _inboundOrderRepository;
private Dictionary<string, string> stations = new Dictionary<string, string>
{
@@ -74,7 +78,7 @@
{"3-1","3-5" },
};
- public OutboundService(IMapper mapper, IUnitOfWorkManage unitOfWorkManage, IRepository<Dt_OutboundOrderDetail> detailRepository, IRepository<Dt_OutboundOrder> outboundRepository, IRepository<Dt_OutStockLockInfo> outboundLockInfoRepository, IRepository<Dt_StockInfo> stockInfoRepository, IRepository<Dt_StockInfoDetail> stockDetailRepository, IRepository<Dt_StockQuantityChangeRecord> stockChangeRepository, IRepository<Dt_StockInfoDetail_Hty> stockDetailHistoryRepository, IBasicService basicService, IOutboundOrderDetailService outboundOrderDetailService, IOutboundOrderService outboundOrderService, IOutStockLockInfoService outboundStockLockInfoService, IFeedbackMesService feedbackMesService, IRepository<Dt_Task> taskRepository, ILocationInfoService locationInfoService, IESSApiService eSSApiService, IRepository<Dt_AllocateOrder> allocateOrderRepository, IRepository<Dt_AllocateMaterialInfo> allocateMaterialInfoRepository)
+ public OutboundService(IMapper mapper, IUnitOfWorkManage unitOfWorkManage, IRepository<Dt_OutboundOrderDetail> detailRepository, IRepository<Dt_OutboundOrder> outboundRepository, IRepository<Dt_OutStockLockInfo> outboundLockInfoRepository, IRepository<Dt_StockInfo> stockInfoRepository, IRepository<Dt_StockInfoDetail> stockDetailRepository, IRepository<Dt_StockQuantityChangeRecord> stockChangeRepository, IRepository<Dt_StockInfoDetail_Hty> stockDetailHistoryRepository, IBasicService basicService, IOutboundOrderDetailService outboundOrderDetailService, IOutboundOrderService outboundOrderService, IOutStockLockInfoService outboundStockLockInfoService, IFeedbackMesService feedbackMesService, IRepository<Dt_Task> taskRepository, ILocationInfoService locationInfoService, IESSApiService eSSApiService, IRepository<Dt_AllocateOrder> allocateOrderRepository, IRepository<Dt_AllocateMaterialInfo> allocateMaterialInfoRepository, IRepository<Dt_InboundOrderDetail> inboundOrderDetailRepository, IRepository<Dt_InboundOrder> inboundOrderRepository)
{
_mapper = mapper;
_unitOfWorkManage = unitOfWorkManage;
@@ -97,6 +101,35 @@
_eSSApiService = eSSApiService;
_allocateOrderRepository = allocateOrderRepository;
_allocateMaterialInfoRepository = allocateMaterialInfoRepository;
+ _inboundOrderDetailRepository = inboundOrderDetailRepository;
+ _inboundOrderRepository = inboundOrderRepository;
+ }
+
+ public WebResponseContent PrintFromData (string barcode)
+ {
+ var detail = _inboundOrderDetailRepository.QueryFirst(x => x.Barcode == barcode);
+ if(detail == null)
+ {
+ return WebResponseContent.Instance.Error();
+ }
+
+ var inbound = _inboundOrderRepository.QueryFirst(x=>x.Id == detail.OrderId);
+ if(inbound == null)
+ {
+ return WebResponseContent.Instance.Error();
+ }
+ var printFormData = new PrintFromDataDTO {
+ materialCode = detail.MaterielCode,
+ materialName = detail.MaterielName,
+ materialSpec = detail.Unit,
+ batchNo = detail.BatchNo,
+ pruchaseOrderNo = inbound.UpperOrderNo,
+ factoryArea = inbound.FactoryArea,
+ suplierCode = detail.SupplyCode,
+ quantity = detail.BarcodeQty
+ };
+
+ return WebResponseContent.Instance.OK(data:printFormData);
}
#region 鍑哄簱鍒嗛厤
@@ -108,139 +141,132 @@
public WebResponseContent ProcessPickingOutbound(PickingOutboundRequestDTO request)
{
WebResponseContent content = WebResponseContent.Instance;
-
PickingOutboundResponseDTO response = new PickingOutboundResponseDTO();
+ decimal totalNeedAllocate = 0; // 鎬婚渶姹傚垎閰嶉噺
+ decimal totalActualAllocate = 0; // 瀹為檯鎬诲垎閰嶉噺
+
try
{
_unitOfWorkManage.BeginTran();
// 1. 璁$畻鍑哄簱鏁伴噺閫昏緫
OutboundCalculationDTO calculationResult = CalcOutboundQuantity(request);
-
if (!calculationResult.CanOutbound)
{
content = WebResponseContent.Instance.Error("鏃犳硶澶勭悊鎷h揣鍑哄簱锛�" + calculationResult.ErrorMessage);
_unitOfWorkManage.RollbackTran();
return content;
}
+ // 璁板綍鎬婚渶姹傛暟閲�
+ totalNeedAllocate = calculationResult.MaterielCalculations.Sum(x => x.UnallocatedQuantity);
- // 2. 璋冪敤鍑哄簱澶勭悊閫昏緫锛岄攣瀹氬簱瀛橈紝鐢熸垚鍑哄簱璁板綍绛�
+ // 2. 澶勭悊鐗╂枡鍒嗛厤
List<PickedStockDetailDTO> pickedDetails = new List<PickedStockDetailDTO>();
-
- // 鑾峰彇鍑哄簱鍗曚俊鎭�
Dt_OutboundOrder outboundOrder = calculationResult.OutboundOrder;
-
- // 鍑哄簱璇︽儏娣诲姞鎴栦慨鏀归泦鍚�
List<Dt_OutStockLockInfo> outStockLockInfos = new List<Dt_OutStockLockInfo>();
-
- List<Dt_OutboundOrderDetail> outboundOrderDetails = new();
-
+ List<Dt_OutboundOrderDetail> outboundOrderDetails = new List<Dt_OutboundOrderDetail>();
List<Dt_Task> tasks = new List<Dt_Task>();
+
foreach (var materielCalc in calculationResult.MaterielCalculations)
{
- (List<PickedStockDetailDTO> PickedDetails, List<Dt_Task> Tasks, List<Dt_OutStockLockInfo> OutStockLockInfo) materielPickedDetails = ProcessMaterielTaskGeneration(outboundOrder, materielCalc, request, calculationResult.FactoryArea);
+ var materielPickedDetails = ProcessMaterielTaskGeneration(outboundOrder, materielCalc, request, calculationResult.FactoryArea);
+ // 璁$畻褰撳墠鐗╂枡瀹為檯鍒嗛厤閲�
+ decimal actualAllocatedQuantity = materielPickedDetails.PickedDetails.Sum(x => x.OutboundQuantity);
+ actualAllocatedQuantity = Math.Min(actualAllocatedQuantity, materielCalc.UnallocatedQuantity);
+ totalActualAllocate += actualAllocatedQuantity; // 绱姞鑷虫�诲疄闄呭垎閰嶉噺
+ materielCalc.UnallocatedQuantity = materielCalc.UnallocatedQuantity - actualAllocatedQuantity;
+ // 澶勭悊鍑哄簱閿佸畾璁板綍
foreach (var item in materielPickedDetails.OutStockLockInfo)
{
- Dt_OutStockLockInfo? outStockLockInfo = materielCalc.OutStockLockInfos.FirstOrDefault(x => x.Id == item.Id && x.Id > 0);
- if (outStockLockInfo != null)
+ Dt_OutStockLockInfo? existLockInfo = materielCalc.OutStockLockInfos.FirstOrDefault(x => x.Id == item.Id && x.Id > 0);
+ if (existLockInfo != null)
{
- outStockLockInfo = item;
+ existLockInfo = item;
Dt_Task? task = tasks.FirstOrDefault(x => x.PalletCode == item.PalletCode);
- if (task != null)
- {
- outStockLockInfo.TaskNum = task.TaskNum;
- }
+ if (task != null) existLockInfo.TaskNum = task.TaskNum;
}
else
{
Dt_Task? task = tasks.FirstOrDefault(x => x.PalletCode == item.PalletCode);
- if (task != null)
- {
- item.TaskNum = task.TaskNum;
- }
+ if (task != null) item.TaskNum = task.TaskNum;
materielCalc.OutStockLockInfos.Add(item);
}
outStockLockInfos.Add(item);
}
+
+ // 澶勭悊浠诲姟
foreach (var item in materielPickedDetails.Tasks)
{
- Dt_Task? task = tasks.FirstOrDefault(x => x.PalletCode == item.PalletCode);
- if (task == null)
- {
+ if (tasks.FirstOrDefault(x => x.PalletCode == item.PalletCode) == null)
tasks.Add(item);
- }
}
+ // 姹囨�诲垎鎷f槑缁�
pickedDetails.AddRange(materielPickedDetails.PickedDetails);
- decimal allallocatedQuantity = Math.Min(materielCalc.UnallocatedQuantity, materielPickedDetails.PickedDetails.Sum(x => x.OutboundQuantity));
- materielCalc.UnallocatedQuantity = allallocatedQuantity;
- // 鏇存柊鍑哄簱鍗曟槑缁嗭紙澧炲姞閿佸畾鏁伴噺锛屼笉澧炲姞宸插嚭鏁伴噺锛�
+ // 鎸夊疄闄呭垎閰嶉噺鏇存柊鍗曟嵁閿佸畾鏁伴噺
+ decimal remainingToLock = actualAllocatedQuantity;
foreach (var detail in materielCalc.Details)
{
- if (allallocatedQuantity <= 0) break;
-
- decimal lockQuantity = (detail.OrderQuantity - detail.OverOutQuantity);
- if (lockQuantity < materielCalc.UnallocatedQuantity)
- {
- detail.LockQuantity += lockQuantity; // 澧炲姞閿佸畾鏁伴噺 涓嶆洿鏂� OverOutQuantity 鍜� OrderDetailStatus锛屽洜涓鸿繕娌℃湁瀹為檯鍑哄簱
- outboundOrderDetails.Add(detail);
- materielCalc.UnallocatedQuantity -= lockQuantity;
- }
- else
- {
- detail.LockQuantity += materielCalc.UnallocatedQuantity;
- outboundOrderDetails.Add(detail);
- break;
- }
+ if (remainingToLock <= 0) break;
+ decimal maxLockableQty = detail.OrderQuantity - detail.OverOutQuantity;
+ if (maxLockableQty <= 0) continue;
+ decimal currentLockQty = Math.Min(remainingToLock, maxLockableQty);
+ detail.LockQuantity += currentLockQty;
+ outboundOrderDetails.Add(detail);
+ remainingToLock -= currentLockQty;
}
}
- // 3. 鏇存柊鍑哄簱鍗曠姸鎬佷负鍑哄簱涓紙琛ㄧず宸叉湁浠诲姟鍒嗛厤锛�
+ // 3. 鎵归噺鏇存柊鐘舵�侊紙鍘熸湁閫昏緫涓嶅彉锛�
UpdateOutboundOrderStatus(request.OrderNo, (int)OutOrderStatusEnum.鍑哄簱涓�);
-
- // 4. 鏇存柊鍑哄簱鍗曟槑缁嗛攣瀹氭暟閲�
_detailRepository.UpdateData(outboundOrderDetails);
+ if (pickedDetails.Any())
+ {
+ UpdateStockStatus(pickedDetails.Select(x => x.PalletCode).ToList(), StockStatusEmun.鍑哄簱閿佸畾.ObjToInt());
+ UpdateLocationStatus(pickedDetails.Select(x => x.LocationCode).ToList(), LocationStatusEnum.Lock.ObjToInt());
+ }
+ //閲嶆鍗曚笉鎷i�夛紝鍘绘帀閿佸畾璁板綍鍥炲簱锛屽啀娆$粍鐩樻椂鎵i櫎鍘熸潯鐮�
+ if (outboundOrder.OrderType != InOrderTypeEnum.ReCheck.ObjToInt())
+ {
+ UpdateOutStockLockInfo(outStockLockInfos);
+ }
+
+ if (tasks.Any()) _taskRepository.AddData(tasks);
- // 5. 鏇存柊搴撳瓨鐘舵��
- UpdateStockStatus(pickedDetails.Select(x => x.PalletCode).ToList(), StockStatusEmun.鍑哄簱閿佸畾.ObjToInt());
+
+ _unitOfWorkManage.CommitTran();
- // 6. 鏇存柊璐т綅鐘舵��
- UpdateLocationStatus(pickedDetails.Select(x => x.LocationCode).ToList(), LocationStatusEnum.Lock.ObjToInt());
-
- // 7. 鏇存柊搴撳瓨璇︽儏
- UpdateOutStockLockInfo(outStockLockInfos);
-
- // 8. 娣诲姞浠诲姟鏁版嵁
- _taskRepository.AddData(tasks);
-
- _unitOfWorkManage.CommitTran();
-
+ // 4. 鏋勯�犲搷搴旓細鍖哄垎銆屽叏閮ㄥ垎閰嶃�嶅拰銆岄儴鍒嗗垎閰嶃��
+ string responseMsg = totalActualAllocate == totalNeedAllocate
+ ? "鍒嗘嫞浠诲姟鍒嗛厤鎴愬姛"
+ : $"鍒嗘嫞浠诲姟鍒嗛厤瀹屾垚锛堝疄闄呭垎閰峽totalActualAllocate}锛岄渶姹倇totalNeedAllocate}锛屽簱瀛樹笉瓒抽儴鍒嗘湭鍒嗛厤锛�";
+ Dt_OutboundOrder outboundOrder1 = _outboundRepository.Db.Queryable<Dt_OutboundOrder>().Where(x => x.OrderNo == request.OrderNo).Includes(x=>x.Details).First();
+ if(totalActualAllocate == 0 && !outboundOrder1.Details.Any(x=>x.LockQuantity >0))
+ {
+ UpdateOutboundOrderStatus(request.OrderNo, (int)OutOrderStatusEnum.鏈紑濮�);
+ return WebResponseContent.Instance.Error("鍒嗛厤搴撳瓨鏁伴噺涓�0锛屾棤娉曞嚭搴�");
+ }
response.Success = true;
- response.Message = "鍒嗘嫞浠诲姟鍒嗛厤鎴愬姛";
- response.Tasks = tasks; // 杩斿洖绗竴涓换鍔″彿
- response.PickedDetails = pickedDetails; // 杩斿洖绗竴涓垎鎷f槑缁�
- content = WebResponseContent.Instance.OK("鍒嗘嫞浠诲姟鍒嗛厤鎴愬姛", response);
- return content;
+ response.Message = responseMsg;
+ response.Tasks = tasks;
+ response.PickedDetails = pickedDetails;
+ content = WebResponseContent.Instance.OK(responseMsg, response);
}
catch (Exception ex)
{
_unitOfWorkManage.RollbackTran();
-
content = WebResponseContent.Instance.Error("澶勭悊鎷h揣鍑哄簱澶辫触锛�" + ex.Message);
}
return content;
}
/// <summary>
- /// 璁$畻鍑哄簱鏁伴噺閫昏緫
+ /// 璁$畻鍑哄簱鏁伴噺閫昏緫锛堝師鏈夐�昏緫涓嶅彉锛�
/// </summary>
- /// <param name="request"></param>
- /// <returns></returns>
public OutboundCalculationDTO CalcOutboundQuantity(PickingOutboundRequestDTO request)
{
- OutboundCalculationDTO result = new();
-
+ OutboundCalculationDTO result = new OutboundCalculationDTO();
try
{
Dt_OutboundOrder outboundOrder = _outboundRepository.QueryFirst(x => x.OrderNo == request.OrderNo);
@@ -253,23 +279,14 @@
result.FactoryArea = outboundOrder.FactoryArea;
List<Dt_OutboundOrderDetail> selectedDetails = new List<Dt_OutboundOrderDetail>();
-
if (request.DetailIds == null || !request.DetailIds.Any())
{
selectedDetails = _detailRepository.QueryData(x => x.OrderId == outboundOrder.Id);
}
else
{
- // 鑾峰彇閫夋嫨鐨勫嚭搴撴槑缁�
selectedDetails = _detailRepository.QueryData(x => x.OrderId == outboundOrder.Id && request.DetailIds.Contains(x.Id));
}
-
-
- //if (outboundOrder.IsBatch == 1 && request.DetailIds.Count == 1)
- //{
- // selectedDetails = _detailRepository.QueryData(x => x.OrderId == selectedDetails.First().OrderId && x.WarehouseCode == selectedDetails.First().WarehouseCode && x.MaterielCode == selectedDetails.First().MaterielCode && x.BatchNo == selectedDetails.First().BatchNo && x.SupplyCode == selectedDetails.First().SupplyCode);
- //}
-
if (!selectedDetails.Any())
{
@@ -280,23 +297,21 @@
if (selectedDetails.Any(x => x.LockQuantity > x.OrderQuantity - x.MoveQty || x.OverOutQuantity > x.OrderQuantity - x.MoveQty))
{
List<int> selectDetailIds = selectedDetails.Where(x => x.LockQuantity > x.OrderQuantity - x.MoveQty || x.OverOutQuantity > x.OrderQuantity - x.MoveQty).Select(x => x.Id).ToList();
-
result.CanOutbound = false;
result.ErrorMessage = $"鍑哄簱鏄庣粏淇℃伅{string.Join(",", selectDetailIds)}宸插垎閰嶅畬鎴�";
return result;
}
+
outboundOrder.Details = selectedDetails;
result.OutboundOrder = outboundOrder;
result.SelectedDetails = selectedDetails;
if (outboundOrder.IsBatch == 0 || request.DetailIds.Count != 1)
{
- // 澶氭槑缁嗗嚭搴擄細鎸夌墿鏂欏垎缁勫鐞�
result.MaterielCalculations = CalcMaterielOutboundQuantities(outboundOrder, selectedDetails.ToList());
}
else
{
- // 鍗曟槑缁嗗嚭搴擄細楠岃瘉杈撳叆鐨勫嚭搴撴暟閲�
if (!request.OutboundQuantity.HasValue || request.OutboundQuantity.Value <= 0)
{
result.CanOutbound = false;
@@ -308,10 +323,8 @@
decimal orderQuantity = selectedDetails.Sum(x => x.OrderQuantity);
decimal moveQuantity = selectedDetails.Sum(x => x.MoveQty);
decimal overQuantity = selectedDetails.Sum(x => x.OverOutQuantity);
-
Dt_OutboundOrderDetail? singleDetail = selectedDetails.First();
- //鍒ゆ柇鍙嚭搴撴暟閲�
if (orderQuantity - lockQuantity - moveQuantity < request.OutboundQuantity.Value || orderQuantity - overQuantity - moveQuantity < request.OutboundQuantity.Value)
{
result.CanOutbound = false;
@@ -325,10 +338,7 @@
{
inputQuantity -= (item.OrderQuantity - item.MoveQty - item.LockQuantity);
outboundOrderDetails.Add(item);
- if (inputQuantity <= 0)
- {
- break;
- }
+ if (inputQuantity <= 0) break;
}
result.MaterielCalculations = new List<MaterielOutboundCalculationDTO>()
@@ -348,31 +358,24 @@
Details = outboundOrderDetails
}
};
-
outboundOrder.Details = outboundOrderDetails;
}
-
result.CanOutbound = true;
- return result;
}
catch (Exception ex)
{
result.CanOutbound = false;
result.ErrorMessage = ex.Message;
- return result;
}
-
+ return result;
}
/// <summary>
- /// 澶氬嚭搴撳崟鏄庣粏鏃讹紝鎸夌墿鏂欏垎缁勮绠楀嚭搴撴暟閲�
+ /// 鎸夌墿鏂欏垎缁勮绠楀嚭搴撴暟閲忥紙鍘熸湁閫昏緫涓嶅彉锛�
/// </summary>
- /// <param name="selectedDetails"></param>
- /// <returns></returns>
private List<MaterielOutboundCalculationDTO> CalcMaterielOutboundQuantities(Dt_OutboundOrder outboundOrder, List<Dt_OutboundOrderDetail> selectedDetails)
{
- // 鎸夌墿鏂欏垎缁勶細鐗╂枡缂栧彿銆佹壒娆″彿銆佷緵搴斿晢缂栧彿銆佷粨搴撶紪鍙�
- List<MaterielOutboundCalculationDTO> materielGroups = selectedDetails
+ return selectedDetails
.GroupBy(x => new
{
x.MaterielCode,
@@ -392,138 +395,395 @@
UnallocatedQuantity = g.Sum(x => x.OrderQuantity - x.LockQuantity - x.MoveQty),
MovedQuantity = g.Sum(x => x.MoveQty),
Details = g.ToList(),
- OutStockLockInfos = _outboundLockInfoRepository.QueryData(x => x.MaterielCode == g.Key.MaterielCode && x.BatchNo == g.Key.BatchNo && x.OrderType == (int)outboundOrder.OrderType && x.OrderNo == outboundOrder.OrderNo)
+ OutStockLockInfos = _outboundLockInfoRepository.QueryData(x =>
+ x.MaterielCode == g.Key.MaterielCode &&
+ x.BatchNo == g.Key.BatchNo &&
+ x.OrderType == (int)outboundOrder.OrderType &&
+ x.OrderNo == outboundOrder.OrderNo)
})
.ToList();
-
- return materielGroups;
}
/// <summary>
- /// 澶勭悊鐗╂枡鐨勪换鍔$敓鎴�
+ /// 澶勭悊鐗╂枡浠诲姟鐢熸垚锛堟牳蹇冿細鏈夊灏戝垎澶氬皯+绉婚櫎搴撳瓨涓嶈冻寮傚父锛�
/// </summary>
- /// <param name="outboundOrder">鍑哄簱璁㈠崟</param>
- /// <param name="materielCalc">鎸夌墿鏂欑殑鍑哄簱璁$畻缁撴灉</param>
- /// <param name="request">鍒嗘嫞鍑哄簱璇锋眰</param>
- /// <param name="factoryArea"></param>
- /// <returns></returns>
- /// <exception cref="Exception"></exception>
- private (List<PickedStockDetailDTO> PickedDetails, List<Dt_Task> Tasks, List<Dt_OutStockLockInfo> OutStockLockInfo) ProcessMaterielTaskGeneration(Dt_OutboundOrder outboundOrder, MaterielOutboundCalculationDTO materielCalc, PickingOutboundRequestDTO request, string factoryArea)
+ private (List<PickedStockDetailDTO> PickedDetails, List<Dt_Task> Tasks, List<Dt_OutStockLockInfo> OutStockLockInfo) ProcessMaterielTaskGeneration(
+ Dt_OutboundOrder outboundOrder,
+ MaterielOutboundCalculationDTO materielCalc,
+ PickingOutboundRequestDTO request,
+ string factoryArea)
{
List<PickedStockDetailDTO> pickedDetails = new List<PickedStockDetailDTO>();
- List<Dt_Task> generatedTasks = new List<Dt_Task>();
-
- // 鏋勫缓搴撳瓨鏌ヨ鏉′欢锛堝寘鍚簱瀛樿〃銆佸簱瀛樻槑缁嗭級
- List<Dt_StockInfo> stockQuery = BuildStockQueryWithInfo(materielCalc, factoryArea);
-
- if (!stockQuery.Any())
- {
- throw new Exception($"鐗╂枡 {materielCalc.MaterielCode} 瀵瑰簲鐨勫簱瀛樹笉瀛樺湪");
- }
-
- // 鎵归噺璁$畻鎬诲彲鐢ㄥ簱瀛樻暟閲�
- (Dictionary<int, decimal> AvailableStockMap, Dictionary<int, List<Dt_OutStockLockInfo>> LockStockMap) data = GetBatchAvailableStockQuantities(materielCalc, stockQuery);
-
- // 鍙敤搴撳瓨鏁伴噺鏄犲皠
- Dictionary<int, decimal> availableStockMap = data.AvailableStockMap;
-
- // 鐗╂枡鎬诲彲鐢ㄥ簱瀛樻暟閲�
- decimal totalAvailableStock = availableStockMap.Values.Sum();
-
- // 宸查攣瀹氬簱瀛樻暟閲忔槧灏�
- Dictionary<int, List<Dt_OutStockLockInfo>> lockStockMap = data.LockStockMap;
-
- // 楠岃瘉鎬诲彲鐢ㄥ簱瀛樻槸鍚︽弧瓒冲嚭搴撻渶姹�
- //if (totalAvailableStock < materielCalc.UnallocatedQuantity)
- //{
- // throw new Exception($"鐗╂枡 {materielCalc.MaterielCode} 鍙敤搴撳瓨 {totalAvailableStock} 涓嶈冻鍑哄簱鏁伴噺 {materielCalc.UnallocatedQuantity}");
- //}
- // 闇�鍒嗛厤鏁伴噺
- decimal remainingQuantity = Math.Min(totalAvailableStock, materielCalc.UnallocatedQuantity);
-
- // 闇�鍒嗛厤鏁伴噺
- //decimal remainingQuantity = materielCalc.UnallocatedQuantity;
-
- // 宸插垎閰嶇殑鎵樼洏鍒楄〃
- List<string> allocatedPallets = new List<string>();
-
- // 鑾峰彇绗竴涓嚭搴撴槑缁�
- Dt_OutboundOrderDetail firstDetail = materielCalc.Details.First();
-
- // 棰勫姞杞藉簱瀛樻槑缁嗗拰閿佸畾璁板綍
- List<int> stockIds = stockQuery.Select(x => x.Id).ToList();
- Dictionary<int, List<Dt_StockInfoDetail>> stockDetailMap = stockQuery.ToDictionary(x => x.Id, x => x.Details);
-
- // 璁板綍姣忎釜鎵樼洏鐨勫疄闄呭垎閰嶉噺
- Dictionary<string, decimal> palletAllocations = new Dictionary<string, decimal>();
-
+ List<Dt_Task> generatedTasks = new List<Dt_Task>(); // 鍒濆绌轰换鍔″垪琛�
List<Dt_OutStockLockInfo> lockInfoList = new List<Dt_OutStockLockInfo>();
- foreach (var stock in stockQuery)
+ decimal remainingQuantity = materielCalc.UnallocatedQuantity;
+
+ // 1. 浼樺厛澶勭悊鎸囧畾搴撳瓨鏄庣粏
+ if (request.StockDetailIds?.Any() == true)
{
- if (remainingQuantity <= 0) break;
+ var specifiedResult = AllocateSpecifiedStockDetails(outboundOrder, materielCalc, request, factoryArea, remainingQuantity);
+ pickedDetails.AddRange(specifiedResult.PickedDetails);
+ lockInfoList.AddRange(specifiedResult.LockInfoList);
+ remainingQuantity -= specifiedResult.ActualAllocatedQuantity;
- // 褰撳墠搴撳瓨鍙敤鏁伴噺
- decimal availableQuantity = availableStockMap.GetValueOrDefault(stock.Id, 0);
- if (availableQuantity <= 0) continue;
-
- // 璁$畻璇ユ墭鐩樺彲鍒嗛厤鏁伴噺
- decimal allocateQuantity = Math.Min(remainingQuantity, availableQuantity);
- (decimal ActualAllocatedQuantity, List<Dt_OutStockLockInfo> LockInfoList) actualAllocated = AllocateStockQuantity(stock, allocateQuantity, availableQuantity, outboundOrder, firstDetail, request, lockStockMap.GetValueOrDefault(stock.Id, new List<Dt_OutStockLockInfo>()), stockDetailMap);
-
- // 鏈鍒嗛厤鐨勬暟閲�
- decimal actualAllocatedQuantity = actualAllocated.ActualAllocatedQuantity;
-
- if (actualAllocatedQuantity > 0)
+ // ===== 鏍稿績淇锛氭寚瀹氬簱瀛樺垎閰嶅悗锛岀珛鍗崇敓鎴愪换鍔★紙鏃犺鍓╀綑閲忓灏戯級=====
+ if (specifiedResult.PickedDetails.Any()) // 鏈夋寚瀹氬簱瀛樺垎閰嶇粨鏋滃氨鐢熸垚浠诲姟
{
- allocatedPallets.Add(stock.PalletCode);
- palletAllocations[stock.PalletCode] = actualAllocatedQuantity; // 璁板綍瀹為檯鍒嗛厤閲�
- remainingQuantity -= actualAllocatedQuantity;
- lockInfoList.AddRange(actualAllocated.LockInfoList);
+ var specifiedTasks = GenerateTasksForSpecifiedStock(specifiedResult.PickedDetails, request.OutboundTargetLocation);
+ generatedTasks.AddRange(specifiedTasks); // 娣诲姞鎸囧畾搴撳瓨浠诲姟鍒版�讳换鍔″垪琛�
+ }
+
+ // 鍓╀綑閲�<=0鏃讹紝鐩存帴杩斿洖锛堝凡鐢熸垚鎸囧畾搴撳瓨浠诲姟锛�
+ if (remainingQuantity <= 0)
+ {
+ return (pickedDetails, generatedTasks, lockInfoList);
}
}
- foreach (var palletCode in allocatedPallets)
+ // 2. 澶勭悊鍓╀綑鏁伴噺鐨勮嚜鍔ㄥ垎閰嶏紙鍘熸湁閫昏緫涓嶅彉锛岃嚜鍔ㄥ垎閰嶇殑浠诲姟浼氳拷鍔犲埌generatedTasks锛�
+ List<Dt_StockInfo> stockQuery = BuildStockQueryWithInfo(materielCalc, factoryArea);
+ var allocatedPalletCodes = pickedDetails.Select(x => x.PalletCode).Distinct().ToList();
+ stockQuery = stockQuery.Where(x => !allocatedPalletCodes.Contains(x.PalletCode)).ToList();
+
+ var stockData = GetBatchAvailableStockQuantities(materielCalc, stockQuery);
+ decimal totalAutoAvailable = stockData.AvailableStockMap.Values.Sum();
+ decimal autoAllocateQuantity = Math.Min(remainingQuantity, totalAutoAvailable);
+ remainingQuantity -= autoAllocateQuantity;
+
+ if (autoAllocateQuantity > 0 && stockQuery.Any())
{
- Dt_StockInfo stock = stockQuery.First(x => x.PalletCode == palletCode);
+ Dt_OutboundOrderDetail firstDetail = materielCalc.Details.First();
+ Dictionary<int, List<Dt_StockInfoDetail>> stockDetailMap = stockQuery.ToDictionary(x => x.Id, x => x.Details);
+ Dictionary<string, decimal> palletAllocations = new Dictionary<string, decimal>();
- // 鑾峰彇瀹為檯鍒嗛厤鐨勬暟閲�
- decimal actualAllocatedQuantity = palletAllocations.GetValueOrDefault(palletCode, 0);
-
- // 璁$畻鍒嗛厤鍚庡墿浣欑殑搴撳瓨鏁伴噺
- decimal originalAvailableQuantity = availableStockMap.GetValueOrDefault(stock.Id, 0);
- decimal remainingStockQuantity = Math.Max(0, originalAvailableQuantity - actualAllocatedQuantity);
-
- pickedDetails.Add(new PickedStockDetailDTO
+ foreach (var stock in stockQuery)
{
- PalletCode = palletCode,
- MaterielCode = materielCalc.MaterielCode,
- OutboundQuantity = actualAllocatedQuantity, // 鏈瀹為檯鍒嗛厤鐨勫嚭搴撻噺
- RemainingQuantity = remainingStockQuantity, // 鍒嗛厤鍚庡墿浣欑殑鍙敤搴撳瓨
- LocationCode = stock.LocationCode,
- OutStockLockInfos = lockInfoList
- });
+ if (autoAllocateQuantity <= 0) break;
+ decimal availableQuantity = stockData.AvailableStockMap.GetValueOrDefault(stock.Id, 0);
+ if (availableQuantity <= 0) continue;
- Dt_OutStockLockInfo? outStockLockInfo = lockInfoList.FirstOrDefault(x => x.PalletCode == palletCode);
- int taskNum = outStockLockInfo?.TaskNum ?? Db.Ado.GetScalar($"SELECT NEXT VALUE FOR SeqTaskNum").ObjToInt();
+ // 鑷姩鍒嗛厤鏃舵煡璇㈡墭鐩樻�诲簱瀛橈紙鍘熸湁浼樺寲閫昏緫涓嶅彉锛�
+ decimal palletMaterielTotalStock = _stockDetailRepository.QueryData(
+ x => x.StockId == stock.Id && x.MaterielCode == materielCalc.MaterielCode
+ ).Sum(x => x.StockQuantity);
- Dt_Task task = GenerationOutTask(stock, TaskTypeEnum.Outbound, taskNum, request.OutboundTargetLocation);
- if (generatedTasks.FirstOrDefault(x => x.PalletCode == stock.PalletCode) == null) generatedTasks.Add(task);
+ decimal allocateQuantity = Math.Min(autoAllocateQuantity, availableQuantity);
+ var actualAllocated = AllocateStockQuantity(
+ stock, allocateQuantity, availableQuantity, outboundOrder, firstDetail,
+ request, stockData.LockStockMap.GetValueOrDefault(stock.Id, new List<Dt_OutStockLockInfo>()),
+ stockDetailMap, palletMaterielTotalStock);
+
+ if (actualAllocated.ActualAllocatedQuantity > 0)
+ {
+ palletAllocations[stock.PalletCode] = actualAllocated.ActualAllocatedQuantity;
+ autoAllocateQuantity -= actualAllocated.ActualAllocatedQuantity;
+ lockInfoList.AddRange(actualAllocated.LockInfoList);
+ }
+ }
+
+ // 鐢熸垚鑷姩鍒嗛厤鐨勪换鍔★紙杩藉姞鍒癵eneratedTasks锛屼笉浼氶噸澶嶏級
+ foreach (var palletCode in palletAllocations.Keys)
+ {
+ Dt_StockInfo stock = stockQuery.First(x => x.PalletCode == palletCode);
+ decimal actualQty = palletAllocations[palletCode];
+ decimal originalAvailable = stockData.AvailableStockMap.GetValueOrDefault(stock.Id, 0);
+
+ pickedDetails.Add(new PickedStockDetailDTO
+ {
+ PalletCode = palletCode,
+ MaterielCode = materielCalc.MaterielCode,
+ OutboundQuantity = actualQty,
+ RemainingQuantity = Math.Max(0, originalAvailable - actualQty),
+ LocationCode = stock.LocationCode,
+ OutStockLockInfos = lockInfoList.Where(x => x.PalletCode == palletCode).ToList()
+ });
+
+ int taskNum = lockInfoList.FirstOrDefault(x => x.PalletCode == palletCode)?.TaskNum ??
+ Db.Ado.GetScalar($"SELECT NEXT VALUE FOR SeqTaskNum").ObjToInt();
+ Dt_Task task = GenerationOutTask(stock, TaskTypeEnum.Outbound, taskNum, request.OutboundTargetLocation);
+ // 杩囨护閲嶅浠诲姟锛堟寚瀹氬簱瀛樼殑鎵樼洏宸茬敓鎴愶紝涓嶄細閲嶅娣诲姞锛�
+ if (generatedTasks.FirstOrDefault(x => x.PalletCode == palletCode) == null)
+ generatedTasks.Add(task);
+ }
}
+ // 杩斿洖銆屾寚瀹氬簱瀛樹换鍔�+鑷姩鍒嗛厤浠诲姟銆嶇殑鍚堝苟鍒楄〃
return (pickedDetails, generatedTasks, lockInfoList);
}
/// <summary>
- /// 鐢熸垚鍑哄簱浠诲姟
+ /// 鍒嗛厤鎸囧畾搴撳瓨鏄庣粏锛堟牳蹇冧紭鍖栵細鏌ヨ鎵樼洏鐗╂枡鎬诲簱瀛樺苟浼犻�掞級
/// </summary>
- /// <param name="stockInfo"></param>
- /// <param name="taskType"></param>
- /// <param name="outStation"></param>
- /// <returns></returns>
+ private (decimal ActualAllocatedQuantity, List<PickedStockDetailDTO> PickedDetails, List<Dt_OutStockLockInfo> LockInfoList) AllocateSpecifiedStockDetails(
+ Dt_OutboundOrder outboundOrder,
+ MaterielOutboundCalculationDTO materielCalc,
+ PickingOutboundRequestDTO request,
+ string factoryArea,
+ decimal needAllocateQuantity)
+ {
+ List<PickedStockDetailDTO> pickedDetails = new List<PickedStockDetailDTO>();
+ List<Dt_OutStockLockInfo> lockInfoList = new List<Dt_OutStockLockInfo>();
+ decimal actualAllocated = 0;
+
+ List<Dt_StockInfoDetail> specifiedStockDetails = _stockDetailRepository.QueryData(
+ x => request.StockDetailIds.Contains(x.Id)
+ && x.MaterielCode == materielCalc.MaterielCode
+ && x.StockQuantity > 0
+ && (x.Status == (int)StockStatusEmun.鍏ュ簱瀹屾垚 || x.Status == (int)StockStatusEmun.鎵嬪姩鍐荤粨 || x.Status == (int)StockStatusEmun.鎵嬪姩瑙i攣 || x.Status == (int)StockStatusEmun.杩囨湡));
+
+ if (!specifiedStockDetails.Any())
+ {
+ throw new Exception($"鎸囧畾搴撳瓨鏄庣粏ID [{string.Join(",", request.StockDetailIds)}] 涓嶅瓨鍦ㄦ垨涓嶅彲鐢�");
+ }
+
+ List<int> stockIds = specifiedStockDetails.Select(x => x.StockId).Distinct().ToList();
+ List<Dt_StockInfo> specifiedStocks = _stockInfoRepository.QueryData(x => stockIds.Contains(x.Id));
+ Dictionary<int, Dt_StockInfo> stockMap = specifiedStocks.ToDictionary(x => x.Id);
+
+ foreach (var stockDetail in specifiedStockDetails)
+ {
+ if (needAllocateQuantity <= 0) break;
+ if (!stockMap.ContainsKey(stockDetail.StockId)) continue;
+
+ Dt_StockInfo stock = stockMap[stockDetail.StockId];
+ decimal availableQty = stockDetail.StockQuantity;
+ decimal allocateQty = Math.Min(needAllocateQuantity, availableQty);
+ if (allocateQty <= 0) continue;
+
+ // ===== 鏍稿績浼樺寲1锛氭煡璇㈣鎵樼洏涓嬪綋鍓嶇墿鏂欑殑鎬诲簱瀛� =====
+ decimal palletMaterielTotalStock = _stockDetailRepository.QueryData(
+ x => x.StockId == stock.Id && x.MaterielCode == materielCalc.MaterielCode
+ ).Sum(x => x.StockQuantity); // 璇ユ墭鐩樿鐗╂枡鐨勬�诲簱瀛橈紙鑰岄潪鏈鍒嗛厤閲忥級
+
+ var lockInfos = materielCalc.OutStockLockInfos
+ .Where(x => x.StockId == stock.Id && x.MaterielCode == materielCalc.MaterielCode)
+ .ToList();
+
+ // ===== 浼犻�掓�诲簱瀛樺埌AllocateStockQuantity =====
+ var allocateResult = AllocateStockQuantity(
+ stock, allocateQty, availableQty, outboundOrder, materielCalc.Details.First(),
+ request, lockInfos,
+ new Dictionary<int, List<Dt_StockInfoDetail>> { { stock.Id, new List<Dt_StockInfoDetail> { stockDetail } } },
+ palletMaterielTotalStock // 鏂板锛氫紶鍏ユ墭鐩樼墿鏂欐�诲簱瀛�
+ );
+
+ if (allocateResult.ActualAllocatedQuantity > 0)
+ {
+ pickedDetails.Add(new PickedStockDetailDTO
+ {
+ PalletCode = stock.PalletCode,
+ MaterielCode = materielCalc.MaterielCode,
+ OutboundQuantity = allocateResult.ActualAllocatedQuantity,
+ RemainingQuantity = Math.Max(0, availableQty - allocateResult.ActualAllocatedQuantity),
+ LocationCode = stock.LocationCode,
+ OutStockLockInfos = allocateResult.LockInfoList
+ });
+
+ actualAllocated += allocateResult.ActualAllocatedQuantity;
+ needAllocateQuantity -= allocateResult.ActualAllocatedQuantity;
+ lockInfoList.AddRange(allocateResult.LockInfoList);
+ }
+ }
+
+ return (actualAllocated, pickedDetails, lockInfoList);
+ }
+
+ /// <summary>
+ /// 涓烘寚瀹氬簱瀛樼敓鎴愪换鍔★紙鍘熸湁閫昏緫涓嶅彉锛�
+ /// </summary>
+ private List<Dt_Task> GenerateTasksForSpecifiedStock(List<PickedStockDetailDTO> pickedDetails, string outboundTargetLocation)
+ {
+ List<Dt_Task> tasks = new List<Dt_Task>();
+ var palletCodes = pickedDetails.Select(x => x.PalletCode).Distinct().ToList();
+
+ foreach (var palletCode in palletCodes)
+ {
+ Dt_StockInfo stock = _stockInfoRepository.QueryFirst(x => x.PalletCode == palletCode);
+ if (stock == null) continue;
+
+ int taskNum = pickedDetails.First(x => x.PalletCode == palletCode)
+ .OutStockLockInfos.FirstOrDefault()?.TaskNum ??
+ Db.Ado.GetScalar($"SELECT NEXT VALUE FOR SeqTaskNum").ObjToInt();
+
+ Dt_Task task = GenerationOutTask(stock, TaskTypeEnum.Outbound, taskNum, outboundTargetLocation);
+ if (tasks.FirstOrDefault(x => x.PalletCode == palletCode) == null)
+ tasks.Add(task);
+ }
+
+ return tasks;
+ }
+
+ /// <summary>
+ /// 鏋勫缓搴撳瓨鏌ヨ鏉′欢锛堝師鏈夐�昏緫涓嶅彉锛�
+ /// </summary>
+ private List<Dt_StockInfo> BuildStockQueryWithInfo(MaterielOutboundCalculationDTO materielCalc, string factoryArea)
+ {
+ ISugarQueryable<Dt_StockInfoDetail> stockDetails = _stockDetailRepository.Db.Queryable<Dt_StockInfoDetail>()
+ .Where(x => x.MaterielCode == materielCalc.MaterielCode && x.StockQuantity > 0
+ && (x.Status == (int)StockStatusEmun.鍏ュ簱瀹屾垚 || x.Status == (int)StockStatusEmun.鎵嬪姩瑙i攣));
+
+ if (!string.IsNullOrEmpty(materielCalc.SupplyCode))
+ stockDetails = stockDetails.Where(x => x.SupplyCode == materielCalc.SupplyCode);
+ if (!string.IsNullOrEmpty(materielCalc.WarehouseCode))
+ stockDetails = stockDetails.Where(x => x.WarehouseCode == materielCalc.WarehouseCode);
+ if (!string.IsNullOrEmpty(factoryArea))
+ stockDetails = stockDetails.Where(x => x.FactoryArea == factoryArea);
+ if (!string.IsNullOrEmpty(materielCalc.BatchNo))
+ stockDetails = stockDetails.Where(x => x.BatchNo == materielCalc.BatchNo);
+
+ List<Dt_StockInfoDetail> stockDetailList = stockDetails.ToList();
+ List<string> locationCodes = _locationInfoRepository.QueryData(x =>
+ (x.LocationStatus == LocationStatusEnum.InStock.ObjToInt() || x.LocationStatus == LocationStatusEnum.Lock.ObjToInt())
+ && x.EnableStatus == EnableStatusEnum.Normal.ObjToInt()).Select(x => x.LocationCode).ToList();
+
+ List<int> stockIds = stockDetailList.GroupBy(x => x.StockId).Select(x => x.Key).ToList();
+ List<Dt_StockInfo> stockInfos = _stockInfoRepository.QueryData(x =>
+ stockIds.Contains(x.Id) && (x.StockStatus == StockStatusEmun.鍏ュ簱瀹屾垚.ObjToInt())
+ && !string.IsNullOrEmpty(x.LocationCode) && locationCodes.Contains(x.LocationCode));
+
+ foreach (var stockInfo in stockInfos)
+ {
+ stockInfo.Details = stockDetailList.Where(x => x.StockId == stockInfo.Id).ToList();
+ }
+
+ return stockInfos;
+ }
+
+ /// <summary>
+ /// 鎵归噺鑾峰彇鎵樼洏鍙敤搴撳瓨淇℃伅锛堝師鏈夐�昏緫涓嶅彉锛�
+ /// </summary>
+ private (Dictionary<int, decimal> AvailableStockMap, Dictionary<int, List<Dt_OutStockLockInfo>> LockStockMap) GetBatchAvailableStockQuantities(
+ MaterielOutboundCalculationDTO materielCalc, List<Dt_StockInfo> stockInfos)
+ {
+ List<int> stockIds = stockInfos.Select(x => x.Id).ToList();
+ Dictionary<int, decimal> availableStockMap = new Dictionary<int, decimal>();
+ Dictionary<int, List<Dt_OutStockLockInfo>> lockStockMap = new Dictionary<int, List<Dt_OutStockLockInfo>>();
+
+ List<Dt_OutStockLockInfo> allocatedData = materielCalc.OutStockLockInfos
+ .Where(x => stockIds.Contains(x.StockId) && x.MaterielCode == materielCalc.MaterielCode).ToList();
+
+ foreach (var stockInfo in stockInfos)
+ {
+ decimal totalQuantity = stockInfo.Details.Sum(x => x.StockQuantity);
+ List<Dt_OutStockLockInfo> outStockLockInfos = allocatedData
+ .Where(x => x.StockId == stockInfo.Id && x.MaterielCode == materielCalc.MaterielCode).ToList();
+ decimal allocatedQuantity = outStockLockInfos.Sum(x => x.AllocatedQuantity);
+
+ availableStockMap[stockInfo.Id] = Math.Max(0, totalQuantity - allocatedQuantity);
+ lockStockMap[stockInfo.Id] = outStockLockInfos;
+ }
+
+ return (availableStockMap, lockStockMap);
+ }
+
+ /// <summary>
+ /// 鍒嗛厤搴撳瓨锛堟牳蹇冧紭鍖栵細OriginalQuantity璧嬪�间负鎵樼洏鐗╂枡鎬诲簱瀛橈級
+ /// </summary>
+ private (decimal ActualAllocatedQuantity, List<Dt_OutStockLockInfo> LockInfoList) AllocateStockQuantity(
+ Dt_StockInfo stockInfo, decimal allocateQuantity, decimal availableQuantity,
+ Dt_OutboundOrder outboundOrder, Dt_OutboundOrderDetail detail,
+ PickingOutboundRequestDTO request, List<Dt_OutStockLockInfo> lockInfos,
+ Dictionary<int, List<Dt_StockInfoDetail>> stockDetailMap = null,
+ decimal palletMaterielTotalStock = 0 // 鏂板锛氭墭鐩樼墿鏂欐�诲簱瀛樺弬鏁�
+ )
+ {
+ decimal actualAllocatedQuantity = Math.Min(allocateQuantity, availableQuantity);
+ List<Dt_OutStockLockInfo> lockInfoList = new List<Dt_OutStockLockInfo>();
+
+ if (actualAllocatedQuantity > 0)
+ {
+ // 妫�鏌ョ洰鏍囦綅缃竴鑷存��
+ if (lockInfos.Any() && !string.IsNullOrEmpty(lockInfos.First().OutboundTargetLocation)
+ && !string.Equals(lockInfos.First().OutboundTargetLocation, request.OutboundTargetLocation, StringComparison.OrdinalIgnoreCase))
+ {
+ return (0, lockInfoList);
+ }
+
+ Dt_OutStockLockInfo? lockInfo = lockInfos.FirstOrDefault(x =>
+ x.StockId == stockInfo.Id && x.Status == OutLockStockStatusEnum.宸插垎閰�.ObjToInt()
+ && x.PalletCode == stockInfo.PalletCode && x.OrderNo == outboundOrder.OrderNo);
+
+ if (lockInfo != null)
+ {
+ List<string> currentIds = lockInfo.OrderDetailIds?.Split(',').ToList() ?? new List<string>();
+ if (!currentIds.Contains(detail.Id.ToString()))
+ {
+ currentIds.Add(detail.Id.ToString());
+ lockInfo.OrderDetailIds = string.Join(",", currentIds);
+ }
+
+ decimal totalAllocatedQuantity = CalcTotalAllocatedQuantity(lockInfos, stockInfo.Id, detail.MaterielCode);
+ lockInfo.AssignQuantity += actualAllocatedQuantity;
+ lockInfo.AllocatedQuantity = totalAllocatedQuantity;
+ if (palletMaterielTotalStock > 0)
+ lockInfo.OriginalQuantity = palletMaterielTotalStock;
+ lockInfoList.Add(lockInfo);
+ }
+ else
+ {
+ decimal originalQuantity = palletMaterielTotalStock;
+
+ List<string> allDetailIds = outboundOrder.Details.Where(x =>
+ x.OrderId == outboundOrder.Id && x.MaterielCode == detail.MaterielCode
+ && x.BatchNo == detail.BatchNo && x.SupplyCode == detail.SupplyCode
+ && x.WarehouseCode == detail.WarehouseCode)
+ .Select(x => x.Id.ToString()).ToList();
+
+ decimal totalAllocatedQuantity = CalcTotalAllocatedQuantity(lockInfos, stockInfo.Id, detail.MaterielCode);
+
+ lockInfo = new Dt_OutStockLockInfo
+ {
+ OrderNo = request.OrderNo,
+ OrderDetailIds = string.Join(",", allDetailIds),
+ OrderType = outboundOrder.OrderType,
+ BatchNo = detail.BatchNo,
+ MaterielCode = detail.MaterielCode,
+ MaterielName = detail.MaterielName,
+ StockId = stockInfo.Id,
+ OrderQuantity = allDetailIds.Count > 1
+ ? outboundOrder.Details.Where(x =>
+ x.OrderId == outboundOrder.Id && x.MaterielCode == detail.MaterielCode
+ && x.BatchNo == detail.BatchNo && x.SupplyCode == detail.SupplyCode
+ && x.WarehouseCode == detail.WarehouseCode).Sum(x => x.OrderQuantity)
+ : detail.OrderQuantity,
+ OriginalQuantity = originalQuantity, // 鐜板湪璧嬪�间负鎵樼洏鐗╂枡鎬诲簱瀛�
+ AssignQuantity = actualAllocatedQuantity,
+ AllocatedQuantity = totalAllocatedQuantity,
+ LocationCode = stockInfo.LocationCode,
+ PalletCode = stockInfo.PalletCode,
+ Unit = detail.Unit,
+ OutboundTargetLocation = request.OutboundTargetLocation,
+ Status = OutLockStockStatusEnum.宸插垎閰�.ObjToInt(),
+ SupplyCode = detail.SupplyCode,
+ WarehouseCode = detail.WarehouseCode,
+ FactoryArea = outboundOrder.FactoryArea,
+ TaskNum = Db.Ado.GetScalar($"SELECT NEXT VALUE FOR SeqTaskNum").ObjToInt(),
+ OrderDetailId = 0
+ };
+ lockInfoList.Add(lockInfo);
+ }
+ }
+
+ return (actualAllocatedQuantity, lockInfoList);
+ }
+
+ /// <summary>
+ /// 璁$畻璇ユ墭鐩樼疮璁″凡鍒嗛厤鏁伴噺锛堝師鏈夐�昏緫涓嶅彉锛�
+ /// </summary>
+ private decimal CalcTotalAllocatedQuantity(List<Dt_OutStockLockInfo> lockInfos, int stockId, string materielCode)
+ {
+ List<Dt_OutStockLockInfo> lockRecords = _outboundLockInfoRepository.QueryData(x =>
+ x.StockId == stockId && x.MaterielCode == materielCode);
+
+ return lockRecords?.Sum(x => x.AssignQuantity) ?? 0;
+ }
+
+ /// <summary>
+ /// 鐢熸垚鍑哄簱浠诲姟锛堝師鏈夐�昏緫涓嶅彉锛�
+ /// </summary>
public Dt_Task GenerationOutTask(Dt_StockInfo stockInfo, TaskTypeEnum taskType, int taskNum, string outStation)
{
-
- Dt_Task task = new()
+ return new Dt_Task
{
CurrentAddress = stockInfo.LocationCode,
Grade = 0,
@@ -538,241 +798,18 @@
PalletType = stockInfo.PalletType,
WarehouseId = stockInfo.WarehouseId,
};
-
- return task;
}
-
- /// <summary>
- /// 鏋勫缓搴撳瓨鏌ヨ鏉′欢锛堝寘鍚簱瀛樹俊鎭拰搴撳瓨鏄庣粏锛�
- /// </summary>
- /// <param name="materielCalc"></param>
- /// <param name="factoryArea"></param>
- /// <returns></returns>
- private List<Dt_StockInfo> BuildStockQueryWithInfo(MaterielOutboundCalculationDTO materielCalc, string factoryArea)
- {
- // 鍩虹鏌ヨ鏉′欢锛氱墿鏂欑紪鍙枫�佹壒娆″彿锛堝鏋滄彁渚涳級銆佸簱瀛樻暟閲�>0
- ISugarQueryable<Dt_StockInfoDetail> stockDetails = _stockDetailRepository.Db.Queryable<Dt_StockInfoDetail>().Where(x => x.MaterielCode == materielCalc.MaterielCode && x.StockQuantity > 0 && (x.Status == (int)StockStatusEmun.鍏ュ簱瀹屾垚 || x.Status == (int)StockStatusEmun.鎵嬪姩瑙i攣));
-
- // 鏍规嵁鏉′欢娣诲姞渚涘簲鍟嗙紪鍙峰尮閰嶏紙涓嶄负绌烘椂鎵嶉渶瑕佸尮閰嶏級
- if (!string.IsNullOrEmpty(materielCalc.SupplyCode))
- {
- stockDetails = stockDetails.Where(x => x.SupplyCode == materielCalc.SupplyCode);
- }
-
- // 鏍规嵁鏉′欢娣诲姞浠撳簱缂栧彿鍖归厤锛堜笉涓虹┖鏃舵墠闇�瑕佸尮閰嶏級
- if (!string.IsNullOrEmpty(materielCalc.WarehouseCode))
- {
- stockDetails = stockDetails.Where(x => x.WarehouseCode == materielCalc.WarehouseCode);
- }
-
- // 鏍规嵁鏉′欢娣诲姞鍘傚尯鍖归厤锛堜笉涓虹┖鏃舵墠闇�瑕佸尮閰嶏級
- if (!string.IsNullOrEmpty(factoryArea))
- {
- stockDetails = stockDetails.Where(x => x.FactoryArea == factoryArea);
- }
-
- // 鏍规嵁鎵规鍙疯繘琛岃繃婊わ紙濡傛灉鎻愪緵锛�
- if (!string.IsNullOrEmpty(materielCalc.BatchNo))
- {
- stockDetails = stockDetails.Where(x => x.BatchNo == materielCalc.BatchNo);
- }
-
- List<Dt_StockInfoDetail> stockDetailList = stockDetails.ToList();
-
- // 鑾峰彇鍙敤璐т綅缂栧彿
- List<string> locationCodes = _locationInfoRepository.QueryData(x => (x.LocationStatus == LocationStatusEnum.InStock.ObjToInt() /*|| x.LocationStatus == LocationStatusEnum.Lock.ObjToInt()*/) && x.EnableStatus == EnableStatusEnum.Normal.ObjToInt()).Select(x => x.LocationCode).ToList();
-
- // 鑾峰彇鎵�鏈夌浉鍏崇殑搴撳瓨淇℃伅
- List<int> stockIds = stockDetailList.GroupBy(x => x.StockId).Select(x => x.Key).ToList();
- List<Dt_StockInfo> stockInfos = _stockInfoRepository.QueryData(x => stockIds.Contains(x.Id) && (x.StockStatus == StockStatusEmun.鍏ュ簱瀹屾垚.ObjToInt() /*|| x.StockStatus == StockStatusEmun.鍑哄簱閿佸畾.ObjToInt()*/) && !string.IsNullOrEmpty(x.LocationCode) && locationCodes.Contains(x.LocationCode));
-
- // 鍦ㄥ唴瀛樹腑鍏宠仈鏁版嵁
- foreach (var stockInfo in stockInfos)
- {
- stockInfo.Details = new List<Dt_StockInfoDetail>();
- stockInfo.Details = stockDetailList.Where(x => x.StockId == stockInfo.Id).ToList();
- }
-
- return stockInfos;
- }
-
- /// <summary>
- /// 鎵归噺鑾峰彇鎵樼洏鍙敤搴撳瓨淇℃伅
- /// </summary>
- /// <param name="stockInfos">搴撳瓨淇℃伅鍒楄〃</param>
- /// <param name="materielCode">鐗╂枡缂栧彿</param>
- /// <returns>杩斿洖鍊间负(搴撳瓨涓婚敭锛屽彲鐢ㄦ暟閲�)瀛楀吀</returns>
- private (Dictionary<int, decimal> AvailableStockMap, Dictionary<int, List<Dt_OutStockLockInfo>> LockStockMap) GetBatchAvailableStockQuantities(MaterielOutboundCalculationDTO materielCalc, List<Dt_StockInfo> stockInfos)
- {
- List<int> stockIds = stockInfos.Select(x => x.Id).ToList();
-
- Dictionary<int, decimal> availableStockMap = new Dictionary<int, decimal>(); // 鍙敤搴撳瓨鏁伴噺
- Dictionary<int, List<Dt_OutStockLockInfo>> lockStockMap = new Dictionary<int, List<Dt_OutStockLockInfo>>(); // 宸查攣瀹氬簱瀛樻暟閲�
-
- // 鎵归噺鏌ヨ宸插垎閰嶆暟閲�
- List<Dt_OutStockLockInfo> allocatedData = materielCalc.OutStockLockInfos.Where(x => stockIds.Contains(x.StockId) && x.MaterielCode == materielCalc.MaterielCode).ToList();
-
- foreach (var stockInfo in stockInfos)
- {
- // 璁$畻鎬诲簱瀛樻暟閲�
- decimal totalQuantity = stockInfo.Details.Sum(x => x.StockQuantity);
-
- List<Dt_OutStockLockInfo> outStockLockInfos = allocatedData.Where(x => x.StockId == stockInfo.Id && x.MaterielCode == materielCalc.MaterielCode).ToList();
-
- // 璁$畻宸插垎閰嶆暟閲�
- decimal allocatedQuantity = outStockLockInfos.Sum(x => x.AllocatedQuantity);
- availableStockMap[stockInfo.Id] = Math.Max(0, totalQuantity - allocatedQuantity);
-
- lockStockMap[stockInfo.Id] = outStockLockInfos;
- }
-
- return (availableStockMap, lockStockMap);
- }
-
- /// <summary>
- /// 鍒嗛厤搴撳瓨
- /// </summary>
- /// <param name="stockInfo">搴撳瓨淇℃伅</param>
- /// <param name="allocateQuantity">瑕佸垎閰嶇殑鏁伴噺</param>
- /// <param name="availableQuantity">鍙垎閰嶇殑鏁伴噺</param>
- /// <param name="outboundOrder">鍑哄簱鍗�</param>
- /// <param name="detail">鍑哄簱鍗曟槑缁�</param>
- /// <param name="request"></param>
- /// <param name="lockInfos"></param>
- /// <param name="stockDetailMap"></param>
- /// <returns></returns>
- private (decimal ActualAllocatedQuantity, List<Dt_OutStockLockInfo> LockInfoList) AllocateStockQuantity(Dt_StockInfo stockInfo, decimal allocateQuantity, decimal availableQuantity, Dt_OutboundOrder outboundOrder, Dt_OutboundOrderDetail detail, PickingOutboundRequestDTO request, List<Dt_OutStockLockInfo> lockInfos, Dictionary<int, List<Dt_StockInfoDetail>> stockDetailMap = null)
- {
- decimal actualAllocatedQuantity = Math.Min(allocateQuantity, availableQuantity); // 瀹為檯鍒嗛厤鏁伴噺
- List<Dt_OutStockLockInfo> lockInfoList = new List<Dt_OutStockLockInfo>();
- if (actualAllocatedQuantity > 0)
- {
- //妫�鏌ョ洰鏍囦綅缃竴鑷存�э細濡傛灉鎵樼洏宸叉湁閿佸畾璁板綍涓旂洰鏍囦綅缃笉鍚岋紝鍒欎笉鍏佽鍒嗛厤
- if (lockInfos.Any() && !string.IsNullOrEmpty(lockInfos.First().OutboundTargetLocation))
- {
- if (!string.Equals(lockInfos.First().OutboundTargetLocation, request.OutboundTargetLocation, StringComparison.OrdinalIgnoreCase))
- {
- // 鎵樼洏鐨勭洰鏍囦綅缃笌鏂拌姹傜殑鐩爣浣嶇疆涓嶅悓锛屼笉鍏佽浣跨敤璇ユ墭鐩�
- return (0, lockInfoList);
- }
- }
-
- Dt_OutStockLockInfo? lockInfo = lockInfos.FirstOrDefault(x => x.StockId == stockInfo.Id && x.Status == OutLockStockStatusEnum.宸插垎閰�.ObjToInt() && x.PalletCode == stockInfo.PalletCode && x.OrderNo == outboundOrder.OrderNo);
-
- if (lockInfo != null)
- {
- // 杩藉姞褰撳墠鏄庣粏ID鍒癘rderDetailIds瀛楁锛堥伩鍏嶉噸澶嶏級
- List<string> currentIds = lockInfo.OrderDetailIds?.Split(',').ToList() ?? new List<string>();
- if (!currentIds.Contains(detail.Id.ToString()))
- {
- currentIds.Add(detail.Id.ToString());
- lockInfo.OrderDetailIds = string.Join(",", currentIds);
- }
-
- // 璁$畻璇ユ墭鐩樿鐗╂枡鐨勬�荤疮璁″凡鍑哄簱鏁伴噺锛堣法鎵�鏈夊崟鎹級
- decimal totalAllocatedQuantity = CalcTotalAllocatedQuantity(lockInfos, stockInfo.Id, detail.MaterielCode);
-
- // 鏇存柊鍒嗛厤鍑哄簱閲�
- decimal beforeAssignQuantity = totalAllocatedQuantity; // 鏈鍒嗛厤鍓嶇殑鎬荤疮璁¢噺
- lockInfo.AssignQuantity += actualAllocatedQuantity; // 鏈鍒嗛厤鏁伴噺
- lockInfo.AllocatedQuantity = beforeAssignQuantity; // 璁板綍鏈鍒嗛厤鍓嶇殑鎬荤疮璁¢噺
-
- lockInfoList.Add(lockInfo);
- }
- else
- {
- // 鍒涘缓鏂扮殑閿佸畾璁板綍锛堜娇鐢ㄩ鍔犺浇鐨勫簱瀛樻槑缁嗭級
- decimal originalQuantity = 0;
- if (stockDetailMap?.ContainsKey(stockInfo.Id) == true)
- {
- originalQuantity = stockDetailMap[stockInfo.Id].Sum(x => x.StockQuantity);
- }
-
- // 鑾峰彇璇ョ墿鏂欏湪璇ヨ鍗曚腑鐨勬墍鏈夋槑缁咺D
- List<string> allDetailIds = (outboundOrder.Details.Where(x =>
- x.OrderId == outboundOrder.Id &&
- x.MaterielCode == detail.MaterielCode &&
- x.BatchNo == detail.BatchNo &&
- x.SupplyCode == detail.SupplyCode &&
- x.WarehouseCode == detail.WarehouseCode))
- .Select(x => x.Id.ToString())
- .ToList();
-
- // 璁$畻璇ユ墭鐩樿鐗╂枡鐨勬�荤疮璁″凡鍑哄簱鏁伴噺锛堣法鎵�鏈夊崟鎹級
- decimal totalAllocatedQuantity = CalcTotalAllocatedQuantity(lockInfos, stockInfo.Id, detail.MaterielCode);
-
- lockInfo = new Dt_OutStockLockInfo
- {
- OrderNo = request.OrderNo,
- OrderDetailIds = string.Join(",", allDetailIds), // 璁板綍璇ョ墿鏂欑殑鎵�鏈夋槑缁咺D
- OrderType = outboundOrder.OrderType,
- BatchNo = detail.BatchNo,
- MaterielCode = detail.MaterielCode,
- MaterielName = detail.MaterielName,
- StockId = stockInfo.Id,
- OrderQuantity = allDetailIds.SelectMany(id => allDetailIds).Count() > 1
- ? (outboundOrder.Details.Where(x =>
- x.OrderId == outboundOrder.Id &&
- x.MaterielCode == detail.MaterielCode &&
- x.BatchNo == detail.BatchNo &&
- x.SupplyCode == detail.SupplyCode &&
- x.WarehouseCode == detail.WarehouseCode))
- .Sum(x => x.OrderQuantity)
- : detail.OrderQuantity, // 濡傛灉鍙湁涓�涓槑缁嗭紝浣跨敤鏄庣粏鏁伴噺
- OriginalQuantity = originalQuantity,
- AssignQuantity = actualAllocatedQuantity, // 鏈鍒嗛厤鏁伴噺
- AllocatedQuantity = totalAllocatedQuantity, // 鏈鍒嗛厤鍓嶇殑鎬荤疮璁″凡鍑哄簱鏁伴噺锛堣法鎵�鏈夊崟鎹級
- LocationCode = stockInfo.LocationCode,
- PalletCode = stockInfo.PalletCode,
- Unit = detail.Unit,
- OutboundTargetLocation = request.OutboundTargetLocation,
- Status = OutLockStockStatusEnum.宸插垎閰�.ObjToInt(),
- SupplyCode = detail.SupplyCode,
- WarehouseCode = detail.WarehouseCode,
- FactoryArea = outboundOrder.FactoryArea,
- TaskNum = Db.Ado.GetScalar($"SELECT NEXT VALUE FOR SeqTaskNum").ObjToInt(),
- OrderDetailId = 0 // 鏈叧鑱斿叿浣撴槑缁咺D
- };
- lockInfoList.Add(lockInfo);
- }
- }
- return (actualAllocatedQuantity, lockInfoList);
- }
-
- /// <summary>
- /// 璁$畻璇ユ墭鐩樼疮璁″凡鍒嗛厤鏁伴噺
- /// </summary>
- /// <param name="lockInfos"></param>
- /// <param name="stockId"></param>
- /// <param name="materielCode"></param>
- /// <returns></returns>
- private decimal CalcTotalAllocatedQuantity(List<Dt_OutStockLockInfo> lockInfos, int stockId, string materielCode)
- {
- // 鏌ヨ璇ユ墭鐩樿鐗╂枡鍦ㄦ墍鏈夐攣瀹氳褰曚腑鐨勬渶澶у凡鍒嗛厤鏁伴噺
- List<Dt_OutStockLockInfo> lockRecords = _outboundLockInfoRepository.QueryData(x =>
- x.StockId == stockId &&
- x.MaterielCode == materielCode);
-
- if (lockRecords == null || !lockRecords.Any())
- {
- return 0;
- }
-
- // 杩斿洖绱宸插垎閰嶆暟閲�
- return lockRecords.Sum(x => x.AssignQuantity);
- }
-
- /// <summary>
- /// 鏇存柊鍑哄簱鍗曠姸鎬�
- /// </summary>
public bool UpdateOutboundOrderStatus(string orderNo, int status)
{
try
{
Dt_OutboundOrder outboundOrder = _outboundRepository.QueryFirst(x => x.OrderNo == orderNo);
if (outboundOrder == null) return false;
-
outboundOrder.OrderStatus = status;
+ if(outboundOrder.CreateType == OrderCreateTypeEnum.CreateInSystem.ObjToInt())
+ {
+ outboundOrder.ReturnToMESStatus = 5;
+ }
_outboundRepository.UpdateData(outboundOrder);
return true;
}
@@ -782,22 +819,12 @@
}
}
- /// <summary>
- ///
- /// </summary>
- /// <param name="palletCodes"></param>
- /// <param name="status"></param>
- /// <returns></returns>
public bool UpdateStockStatus(List<string> palletCodes, int status)
{
try
{
List<Dt_StockInfo> stockInfos = _stockInfoRepository.QueryData(x => palletCodes.Contains(x.PalletCode));
- stockInfos.ForEach(stockInfo =>
- {
- stockInfo.StockStatus = status;
- });
-
+ stockInfos.ForEach(stockInfo => stockInfo.StockStatus = status);
_stockInfoRepository.UpdateData(stockInfos);
return true;
}
@@ -807,22 +834,12 @@
}
}
- /// <summary>
- ///
- /// </summary>
- /// <param name="locationCodes"></param>
- /// <param name="status"></param>
- /// <returns></returns>
public bool UpdateLocationStatus(List<string> locationCodes, int status)
{
try
{
List<Dt_LocationInfo> locationInfos = _locationInfoRepository.QueryData(x => locationCodes.Contains(x.LocationCode));
- locationInfos.ForEach(x =>
- {
- x.LocationStatus = status;
- });
-
+ locationInfos.ForEach(x => x.LocationStatus = status);
_locationInfoRepository.UpdateData(locationInfos);
return true;
}
@@ -832,21 +849,14 @@
}
}
- /// <summary>
- ///
- /// </summary>
- /// <param name="outStockLockInfos"></param>
- /// <returns></returns>
public bool UpdateOutStockLockInfo(List<Dt_OutStockLockInfo> outStockLockInfos)
{
try
{
List<Dt_OutStockLockInfo> updateData = outStockLockInfos.Where(x => x.Id > 0).ToList();
_outboundLockInfoRepository.UpdateData(updateData);
-
List<Dt_OutStockLockInfo> addData = outStockLockInfos.Where(x => x.Id <= 0).ToList();
_outboundLockInfoRepository.AddData(addData);
-
return true;
}
catch
@@ -1015,7 +1025,7 @@
// 鏁寸鍑哄簱鏃犻渶鎷嗗寘
PerformFullOutboundOperation(stockInfo, request, lockInfo.TaskNum.GetValueOrDefault());
- if (outboundOrder.OrderType != 0)
+ if (outboundOrder.OrderType == InOrderTypeEnum.InternalAllocat.ObjToInt())
{
Dt_AllocateOrder allocateOrder = _allocateOrderRepository.QueryFirst(x => x.OrderNo == outboundOrder.OrderNo);
if (allocateOrder != null)
@@ -1041,6 +1051,29 @@
}
_allocateMaterialInfoRepository.AddData(allocateMaterialInfos);
}
+ }
+ else if(outboundOrder.OrderType == InOrderTypeEnum.ReCheck.ObjToInt())
+ {
+ List<Dt_AllocateMaterialInfo> allocateMaterialInfos = new List<Dt_AllocateMaterialInfo>();
+ foreach (var item in stockInfo.Details)
+ {
+ Dt_AllocateMaterialInfo allocateMaterialInfo = new Dt_AllocateMaterialInfo()
+ {
+ Barcode = item.Barcode??"",
+ BatchNo = item.BatchNo,
+ FactoryArea = item.FactoryArea,
+ MaterialCode = item.MaterielCode,
+ MaterialName = item.MaterielName,
+ OrderId = outboundOrder.Id,
+ OrderNo = outboundOrder.OrderNo,
+ Quantity = item.StockQuantity,
+ SupplyCode = item.SupplyCode??"",
+ Unit = item.Unit,
+ WarehouseCode = item.WarehouseCode??""
+ };
+ allocateMaterialInfos.Add(allocateMaterialInfo);
+ }
+ _allocateMaterialInfoRepository.AddData(allocateMaterialInfos);
}
decimal allocatedQuantity = actualOutboundQuantity;
@@ -1118,8 +1151,15 @@
{
barcodeQuantity = item.LockQuantity - item.OverOutQuantity;
allocatedQuantity -= (item.LockQuantity - item.OverOutQuantity);
+ if(item.ReturnToMESStatus == 0)
+ {
+ item.CurrentDeliveryQty = item.LockQuantity;
+ }
+ else
+ {
+ item.CurrentDeliveryQty += item.LockQuantity - item.OverOutQuantity;
+ }
item.OverOutQuantity = item.LockQuantity;
- item.CurrentDeliveryQty = item.LockQuantity;
}
updateDetails.Add(item);
@@ -1135,6 +1175,11 @@
ContractResolver = new CamelCasePropertyNamesContractResolver()
};
item.ReturnJsonData = JsonConvert.SerializeObject(barcodesList, settings);
+ //閲嶆嫞鍑哄簱涓嶉渶瑕佸洖浼�
+ if (outboundOrder.OrderType == InOrderTypeEnum.ReCheck.ObjToInt())
+ {
+ item.ReturnJsonData = "";
+ }
}
lockInfo.SortedQuantity = lockInfo.SortedQuantity + actualOutboundQuantity;
@@ -1162,12 +1207,27 @@
response.Message = "鍑哄簱瀹屾垚";
response.UpdatedDetails = updateDetails;
+ if (CheckOutboundOrderDetailCompletedByMatCode(request.OrderNo, lockInfo.MaterielCode, outboundOrderDetails))
+ {
+ Func<Dt_OutStockLockInfo, bool> supWhere = x => string.IsNullOrEmpty(outboundOrderDetails.First().SupplyCode) ? true : x.SupplyCode == outboundOrderDetails.First().SupplyCode;
+
+ Func<Dt_OutStockLockInfo, bool> wareWhere = x => string.IsNullOrEmpty(outboundOrderDetails.First().WarehouseCode) ? true : x.WarehouseCode == outboundOrderDetails.First().WarehouseCode;
+
+ List<Dt_OutStockLockInfo> stockLockInfos = _outboundLockInfoRepository.QueryData(x =>
+ x.OrderNo == request.OrderNo &&
+ x.MaterielCode == stockInfoDetail.MaterielCode).Where(supWhere).Where(wareWhere).ToList();
+ if (stockLockInfos != null && stockLockInfos.Any())
+ {
+ _outboundLockInfoRepository.DeleteAndMoveIntoHty(stockLockInfos, WIDESEA_Core.Enums.OperateTypeEnum.鑷姩鍒犻櫎);
+ }
+ }
+
// 妫�鏌ュ嚭搴撳崟鏄惁瀹屾垚
if (CheckOutboundOrderCompleted(request.OrderNo))
{
UpdateOutboundOrderStatus(request.OrderNo, OutOrderStatusEnum.鍑哄簱瀹屾垚.ObjToInt());
- if (outboundOrder.OrderType != OutOrderTypeEnum.InternalAllocat.ObjToInt())
+ if (outboundOrder.OrderType != OutOrderTypeEnum.InternalAllocat.ObjToInt()&& outboundOrder.OrderType!= InOrderTypeEnum.ReCheck.ObjToInt())
{
_feedbackMesService.OutboundFeedback(outboundOrder.OrderNo);
}
@@ -1396,7 +1456,7 @@
MaterialCodeReturnDTO returnDTO = returnDTOs.First(x => x.Barcode == newBarcode);
- if (outboundOrder.OrderType != 0)
+ if (outboundOrder.OrderType == InOrderTypeEnum.ReCheck.ObjToInt()||outboundOrder.OrderType == InOrderTypeEnum.InternalAllocat.ObjToInt())
{
allocateMaterialInfo = new Dt_AllocateMaterialInfo()
{
@@ -1418,7 +1478,7 @@
{
PerformFullOutboundOperation(stockDetail, stockInfo, actualOutboundQuantity, request, beforeQuantity, lockInfo.TaskNum.GetValueOrDefault());
- if (outboundOrder.OrderType != 0)
+ if (outboundOrder.OrderType == InOrderTypeEnum.ReCheck.ObjToInt() || outboundOrder.OrderType == InOrderTypeEnum.InternalAllocat.ObjToInt())
{
allocateMaterialInfo = new Dt_AllocateMaterialInfo()
{
@@ -1437,8 +1497,8 @@
}
- // 鍒ゆ柇鏄惁鏄皟鎷ㄥ崟
- if (outboundOrder.OrderType != 0)
+ // 鍒ゆ柇鏄惁鏄櫤浠撹皟鏅轰粨鍗�
+ if ( outboundOrder.OrderType == InOrderTypeEnum.InternalAllocat.ObjToInt())
{
Dt_AllocateOrder allocateOrder = _allocateOrderRepository.QueryFirst(x => x.OrderNo == outboundOrder.OrderNo);
if (allocateOrder != null)
@@ -1478,8 +1538,15 @@
{
barcodeQuantity = item.LockQuantity - item.OverOutQuantity;
allocatedQuantity -= (item.LockQuantity - item.OverOutQuantity);
+ if (item.ReturnToMESStatus == 0)
+ {
+ item.CurrentDeliveryQty = item.LockQuantity;
+ }
+ else
+ {
+ item.CurrentDeliveryQty += item.LockQuantity - item.OverOutQuantity;
+ }
item.OverOutQuantity = item.LockQuantity;
- item.CurrentDeliveryQty = item.LockQuantity;
}
updateDetails.Add(item);
@@ -1555,8 +1622,7 @@
_feedbackMesService.BarcodeFeedback(newBarcode);
}
- // 鍒犻櫎閿佸畾璁板綍锛堝鏋滃嚭搴撴槑缁嗗叏閮ㄥ畬鎴愶級 涓嶤alculateActualOutboundQuantity鏂规硶閲岄潰娉ㄩ噴浠g爜2閫�1浣跨敤
- if (CheckOutboundOrderDetailCompletedByMatCode(request.OrderNo, lockInfo.MaterielCode, outboundOrderDetails.First()))
+ if (CheckOutboundOrderDetailCompletedByMatCode(request.OrderNo, lockInfo.MaterielCode, outboundOrderDetails))
{
Func<Dt_OutStockLockInfo, bool> supWhere = x => string.IsNullOrEmpty(outboundOrderDetails.First().SupplyCode) ? true : x.SupplyCode == outboundOrderDetails.First().SupplyCode;
@@ -1570,18 +1636,18 @@
_outboundLockInfoRepository.DeleteAndMoveIntoHty(stockLockInfos, WIDESEA_Core.Enums.OperateTypeEnum.鑷姩鍒犻櫎);
}
}
+
// 妫�鏌ュ嚭搴撳崟鏄惁瀹屾垚
if (CheckOutboundOrderCompleted(request.OrderNo))
{
UpdateOutboundOrderStatus(request.OrderNo, OutOrderStatusEnum.鍑哄簱瀹屾垚.ObjToInt());
- if (outboundOrder.OrderType != OutOrderTypeEnum.InternalAllocat.ObjToInt())
+ if (outboundOrder.OrderType != OutOrderTypeEnum.InternalAllocat.ObjToInt() && outboundOrder.CreateType!=OrderCreateTypeEnum.CreateInSystem.ObjToInt())
{
_feedbackMesService.OutboundFeedback(outboundOrder.OrderNo);
}
}
-
}
catch (Exception ex)
{
@@ -1910,14 +1976,30 @@
/// <summary>
/// 妫�鏌ュ嚭搴撳崟鏄庣粏鏄惁瀹屾垚
/// </summary>
- public bool CheckOutboundOrderDetailCompletedByMatCode(string orderNo, string materialCode, Dt_OutboundOrderDetail outboundOrderDetail)
+ public bool CheckOutboundOrderDetailCompletedByMatCode(string orderNo, string materialCode, List<Dt_OutboundOrderDetail> outboundOrderDetails)
{
+ if (string.IsNullOrEmpty(orderNo) || string.IsNullOrEmpty(materialCode) || outboundOrderDetails == null || !outboundOrderDetails.Any())
+ return false;
+
+ // 鏌ヨ涓昏鍗曪紝涓嶅瓨鍦ㄧ洿鎺ヨ繑鍥瀎alse
Dt_OutboundOrder outboundOrder = _outboundRepository.QueryFirst(x => x.OrderNo == orderNo);
if (outboundOrder == null) return false;
- List<Dt_OutboundOrderDetail> details = _detailRepository.QueryData(x => x.OrderId == outboundOrder.Id && x.MaterielCode == materialCode && (string.IsNullOrEmpty(outboundOrderDetail.SupplyCode) || x.SupplyCode == outboundOrderDetail.SupplyCode) && (string.IsNullOrEmpty(outboundOrderDetail.WarehouseCode) || x.WarehouseCode == outboundOrderDetail.WarehouseCode));
+ var firstDetail = outboundOrderDetails.FirstOrDefault();
+ string supplyCode = firstDetail.SupplyCode;
+ string warehouseCode = firstDetail.WarehouseCode;
+ List<int> ids = outboundOrderDetails.Select(x => x.Id).ToList();
- // 妫�鏌ユ墍鏈夋槑缁嗙殑宸插嚭鏁伴噺鏄惁閮界瓑浜庡崟鎹暟閲�
+ List<Dt_OutboundOrderDetail> details = _detailRepository.QueryData(x =>
+ x.OrderId == outboundOrder.Id
+ && x.MaterielCode == materialCode
+ && ids.Contains(x.Id)
+ && (string.IsNullOrEmpty(supplyCode) || x.SupplyCode == supplyCode)
+ && (string.IsNullOrEmpty(warehouseCode) || x.WarehouseCode == warehouseCode)
+ );
+
+ if (!details.Any()) return false;
+
return details.All(x => x.OverOutQuantity >= x.OrderQuantity - x.MoveQty);
}
@@ -1930,6 +2012,12 @@
try
{
var stock = await _stockInfoRepository.Db.Queryable<Dt_StockInfo>().Includes(x => x.Details).Where(x => x.PalletCode == palletCode).FirstAsync();
+
+ Dt_Task task = _taskRepository.QueryFirst(x => x.PalletCode == palletCode);
+ if (task != null)
+ {
+ return WebResponseContent.Instance.Error("浠诲姟淇℃伅鍒楄〃瀛樺湪璇ユ墭鐩樼殑浠诲姟淇℃伅锛屼笉鍙彇璧扮┖绠憋紝璇锋鏌ヤ换鍔℃槸鍚﹀畬鎴�");
+ }
if (stock == null)
{
@@ -1975,21 +2063,20 @@
if (stock.Details.Count <= 0)
{
stock.PalletType = (int)PalletTypeEnum.Empty;
- stock.StockStatus = (int)StockStatusEmun.缁勭洏鏆傚瓨;
+ stock.StockStatus = (int)StockStatusEmun.鍏ュ簱纭;
stock.LocationCode = "";
}
else if (stock.Details.Count > 0)
{
Dt_OutStockLockInfo lockInfo = _outboundLockInfoRepository.QueryFirst(x =>
- x.OrderNo == OrderNo &&
x.StockId == stock.Id &&
x.PalletCode == palletCode);
if (lockInfo != null && lockInfo.SortedQuantity != lockInfo.AssignQuantity)
{
- return content.Error($"鎵樼洏{palletCode}搴撳瓨鏈嫞閫夊畬涓嶅厑璁稿洖搴�");
+ return content.Error($"鎵樼洏{palletCode}搴撳瓨锛屽湪鍗曟嵁{lockInfo.OrderNo}閲岄潰杩樻湭鎷i�夊畬鎴愶紝涓嶅厑璁稿洖搴�");
}
- stock.StockStatus = (int)StockStatusEmun.缁勭洏鏆傚瓨;
+ stock.StockStatus = (int)StockStatusEmun.鍏ュ簱纭;
stock.LocationCode = "";
}
@@ -2004,6 +2091,11 @@
// 鍒嗛厤鏂拌揣浣�
var newLocation = _locationInfoService.AssignLocation(stock.LocationType);
+
+ if(newLocation == null)
+ {
+ return WebResponseContent.Instance.Error("娌℃湁绌洪棽搴撲綅鍙洖搴�");
+ }
var newTask = new Dt_Task()
{
@@ -2037,6 +2129,67 @@
}
}
+ public WebResponseContent RecheckPicking(RecheckPickingDTO pickingDTO)
+ {
+ try
+ {
+ Dt_ReCheckOrder reCheckOrder = _outboundRepository.Db.Queryable<Dt_ReCheckOrder>().Where(x => x.OrderNo == pickingDTO.orderNo && x.Result == 0).First();
+ if(reCheckOrder == null)
+ {
+ return WebResponseContent.Instance.Error($"鏈壘鍒拌寰呴噸鎷g殑鍗曟嵁{pickingDTO.orderNo}");
+ }
+ Dt_StockInfoDetail stockInfoDetail = _stockDetailRepository.QueryFirst(x=>x.Barcode == pickingDTO.barCode && x.Status == StockStatusEmun.鎵嬪姩鍐荤粨.ObjToInt() );
+ if(stockInfoDetail == null)
+ {
+ return WebResponseContent.Instance.Error($"鏈湪搴撳瓨涓壘鍒拌鍐荤粨/闅旂鏉$爜 {pickingDTO.barCode}");
+ }
+ if (stockInfoDetail.MaterielCode != reCheckOrder.MaterielCode || stockInfoDetail.BatchNo != reCheckOrder.BatchNo)
+ {
+ return WebResponseContent.Instance.Error("璇ユ潯鐮佺殑鐗╂枡缂栫爜鍜屾壒娆″拰璇ラ噸妫�鍗曚笉绗�");
+ }
+ stockInfoDetail.OrderNo = pickingDTO.orderNo;
+ stockInfoDetail.Status = StockStatusEmun.閲嶆涓�.ObjToInt();
+ var currentRemark = _outboundRepository.Db.Queryable<Dt_OutboundOrder>()
+ .Where(x => x.OrderNo == pickingDTO.orderNo)
+ .Select(x => x.Remark)
+ .First();
+
+ string newRemark;
+ if (string.IsNullOrWhiteSpace(currentRemark))
+ {
+ newRemark = pickingDTO.barCode;
+ }
+ else
+ {
+ var existingCodes = currentRemark.Split(',', StringSplitOptions.RemoveEmptyEntries)
+ .Select(s => s.Trim())
+ .ToList();
+
+ if (!existingCodes.Contains(pickingDTO.barCode))
+ {
+ existingCodes.Add(pickingDTO.barCode);
+ newRemark = string.Join(",", existingCodes);
+ }
+ else
+ {
+ newRemark = currentRemark;
+ }
+ }
+ _outboundRepository.Db.Updateable<Dt_OutboundOrder>()
+ .SetColumns(x => x.Remark == newRemark)
+ .SetColumns(x=>x.OrderStatus == (int)OutOrderStatusEnum.鍑哄簱瀹屾垚)
+ .Where(x => x.OrderNo == pickingDTO.orderNo)
+ .ExecuteCommand();
+ _stockDetailRepository.UpdateData(stockInfoDetail);
+
+ return WebResponseContent.Instance.OK();
+ }
+ catch(Exception ex)
+ {
+ return WebResponseContent.Instance.Error(ex.Message);
+ }
+ }
+
#endregion
}
}
--
Gitblit v1.9.3