From 5de4b01a6cd7c346b241f75274c2f76ea7a354cb Mon Sep 17 00:00:00 2001
From: zhouhongjun <565221961@qq.com>
Date: Fri, 14 Jun 2024 11:59:20 +0800
Subject: [PATCH] =?UTF-8?q?=E6=88=90=E5=93=81=E5=92=8C=E5=8D=8A=E6=88=90?=
=?UTF-8?q?=E5=93=81=E6=8C=89=E6=97=A0=E7=AE=B1=E7=A0=81=E5=88=A4=E6=96=AD?=
=?UTF-8?q?=E5=BA=93=E5=AD=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../Balances/BalanceManager.cs | 106 ++++++++++++++++++
.../Balances/IBalanceManager.cs | 4 +
.../ThirdLocationRequestAppService.cs | 2 +-
3 files changed, 111 insertions(+), 1 deletion(-)
diff --git a/be/Modules/Inventory/src/Win_in.Sfs.Wms.Inventory.Domain/Balances/BalanceManager.cs b/be/Modules/Inventory/src/Win_in.Sfs.Wms.Inventory.Domain/Balances/BalanceManager.cs
index 69f37b12d..48afaa429 100644
--- a/be/Modules/Inventory/src/Win_in.Sfs.Wms.Inventory.Domain/Balances/BalanceManager.cs
+++ b/be/Modules/Inventory/src/Win_in.Sfs.Wms.Inventory.Domain/Balances/BalanceManager.cs
@@ -1026,6 +1026,112 @@ public class BalanceManager : DomainService, IBalanceManager
return usableBalances;
}
+ ///
+ /// 获取无箱码可用库存列表
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public virtual async Task> GetNoPackCodeUsableListAsync(string itemCode,
+ List validLocations,
+ List validStatuses, bool isRemovePackingCode)
+ {
+ var recommendBalances = new List();//返回可使用的推荐库存余额
+
+ var item = await _itemBasicAclService.GetByCodeAsync(itemCode).ConfigureAwait(false);
+ if (item == null) //物品是否存在
+ {
+ // throw new UserFriendlyException($"未找到代码为 {itemCode} 的物料记录");
+ return recommendBalances;
+ }
+
+ //构造查询条件
+ Expression> expression = p => p.ItemCode == itemCode;
+ expression = expression.And(p => validStatuses.Contains(p.Status));
+ expression = expression.And(p => p.IsActive);
+
+ //如果物品的有效期不是无限的, 要过滤掉过期库存
+ if (item.ValidityUnit != EnumValidityUnit.Infinite)
+ {
+ expression = expression.And(p => p.ExpireDate > DateTime.Now);
+ }
+ //排除有箱码库存
+ if (isRemovePackingCode)
+ {
+ expression = expression.And(p => string.IsNullOrEmpty(p.PackingCode));
+ }
+
+
+ var allBalances = await
+ (await _balanceRepository.GetDbSetAsync().ConfigureAwait(false))
+ .Where(expression)
+ .AsNoTracking()
+ .ToListAsync().ConfigureAwait(false);
+
+ var balanceLocationCodes = allBalances.Select(p => p.LocationCode).Distinct().ToList();
+ var locations = await _locationAclService.GetByCodesAsync(balanceLocationCodes).ConfigureAwait(false);
+ //筛选有效库位类型
+ if (validLocations.Any())
+ {
+ locations = locations.Where(p => validLocations.Contains(p.Code)).ToList();
+ }
+ var locationCodes = locations.Where(p => p.EnablePick).Select(p => p.Code).ToList();
+
+ if (!locationCodes.Any())
+ {
+ return recommendBalances;
+ }
+ //获取物品存储关系
+ var itemStoreRelationDict = await GetItemStoreRelationDictAsync(itemCode, locationCodes).ConfigureAwait(false);
+ //过滤掉无用的库位代码
+ locationCodes = itemStoreRelationDict.Keys.ToList();
+ locations = locations.Where(p => locationCodes.Contains(p.Code)).ToList();
+
+ var usableBalances = allBalances.Where(p => locationCodes.Contains(p.LocationCode)).ToList();
+
+ if (!usableBalances.Any())
+ {
+ return recommendBalances;
+ }
+
+ //读取该itemCode项目为空的预占用库存
+ var expectOuts = await
+ (await _expectOutRepository.GetDbSetAsync().ConfigureAwait(false))
+ .AsNoTracking()
+ .Where(p => p.ItemCode == itemCode
+ && locationCodes.Contains(p.LocationCode) && string.IsNullOrEmpty(p.PackingCode)
+ && validStatuses.Contains(p.Status))
+ .ToListAsync().ConfigureAwait(false);
+
+ var containerCodes = usableBalances
+ .Where(p => !string.IsNullOrEmpty(p.ContainerCode))
+ .Select(p => p.ContainerCode)
+ .ToList();
+
+ var expectOutContainerCodes = await
+ (await _expectOutRepository.GetDbSetAsync().ConfigureAwait(false))
+ .Where(p => containerCodes.Contains(p.ContainerCode))
+ .GroupBy(p => p.ContainerCode)
+ .Select(d => d.Key)
+ .ToListAsync().ConfigureAwait(false);
+
+ usableBalances
+ //扣减已占用库存
+ .DecreaseExpectOutQty(expectOuts, locations)
+ //去除不可拆箱 拆托的且有预占用的库存余额
+ .IgnoreExpectOutOfSameContainer(expectOutContainerCodes, itemStoreRelationDict, locations)
+ //过滤掉不允许拣料的库位
+ .FilterLocationEnablePickAsync(locations)
+ //排序库存余额 最终可用的余额集合
+ .SortByFifo();
+ usableBalances = usableBalances.Where(p => p.Qty != 0).ToList();
+
+ return usableBalances;
+ }
+
+
private decimal GetRecommendQty(Guid traceId, decimal requestQty, decimal remainingQty, Balance usableBalance, LocationDTO location, ItemStoreRelationDTO itemStoreRelation)
{
var balanceQty = usableBalance.Qty;
diff --git a/be/Modules/Inventory/src/Win_in.Sfs.Wms.Inventory.Domain/Balances/IBalanceManager.cs b/be/Modules/Inventory/src/Win_in.Sfs.Wms.Inventory.Domain/Balances/IBalanceManager.cs
index 1d2e4880d..a5f0ad18c 100644
--- a/be/Modules/Inventory/src/Win_in.Sfs.Wms.Inventory.Domain/Balances/IBalanceManager.cs
+++ b/be/Modules/Inventory/src/Win_in.Sfs.Wms.Inventory.Domain/Balances/IBalanceManager.cs
@@ -51,5 +51,9 @@ public interface IBalanceManager : IDomainService
Task> GetUsableListAsync(string itemCode,
List validLocations,
List validStatuses, bool isRemovePackingCode);
+
+ Task> GetNoPackCodeUsableListAsync(string itemCode,
+ List validLocations,
+ List validStatuses, bool isRemovePackingCode);
Task> GetRecommendBalancesByLocationExpectOldBalancesAsync(Guid traceId, string itemCode, decimal requestQty, List validLocations, List validStatuses, bool ispackingcode, List oldBalances);
}
diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Requests/ThirdLocationRequests/ThirdLocationRequestAppService.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Requests/ThirdLocationRequests/ThirdLocationRequestAppService.cs
index e480576c1..a199ce6ed 100644
--- a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Requests/ThirdLocationRequests/ThirdLocationRequestAppService.cs
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Requests/ThirdLocationRequests/ThirdLocationRequestAppService.cs
@@ -167,7 +167,7 @@ public class ThirdLocationRequestAppService : SfsStoreRequestAppServiceBase