Browse Source

成品和半成品按无箱码判断库存

dev_DY_CC
周红军 1 year ago
parent
commit
5de4b01a6c
  1. 106
      be/Modules/Inventory/src/Win_in.Sfs.Wms.Inventory.Domain/Balances/BalanceManager.cs
  2. 4
      be/Modules/Inventory/src/Win_in.Sfs.Wms.Inventory.Domain/Balances/IBalanceManager.cs
  3. 2
      be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Requests/ThirdLocationRequests/ThirdLocationRequestAppService.cs

106
be/Modules/Inventory/src/Win_in.Sfs.Wms.Inventory.Domain/Balances/BalanceManager.cs

@ -1026,6 +1026,112 @@ public class BalanceManager : DomainService, IBalanceManager
return usableBalances;
}
/// <summary>
/// 获取无箱码可用库存列表
/// </summary>
/// <param name="itemCode"></param>
/// <param name="validLocations"></param>
/// <param name="validStatuses"></param>
/// <param name="isRemovePackingCode"></param>
/// <returns></returns>
public virtual async Task<List<Balance>> GetNoPackCodeUsableListAsync(string itemCode,
List<string> validLocations,
List<EnumInventoryStatus> validStatuses, bool isRemovePackingCode)
{
var recommendBalances = new List<Balance>();//返回可使用的推荐库存余额
var item = await _itemBasicAclService.GetByCodeAsync(itemCode).ConfigureAwait(false);
if (item == null) //物品是否存在
{
// throw new UserFriendlyException($"未找到代码为 {itemCode} 的物料记录");
return recommendBalances;
}
//构造查询条件
Expression<Func<Balance, bool>> 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;

4
be/Modules/Inventory/src/Win_in.Sfs.Wms.Inventory.Domain/Balances/IBalanceManager.cs

@ -51,5 +51,9 @@ public interface IBalanceManager : IDomainService
Task<List<Balance>> GetUsableListAsync(string itemCode,
List<string> validLocations,
List<EnumInventoryStatus> validStatuses, bool isRemovePackingCode);
Task<List<Balance>> GetNoPackCodeUsableListAsync(string itemCode,
List<string> validLocations,
List<EnumInventoryStatus> validStatuses, bool isRemovePackingCode);
Task<List<Balance>> GetRecommendBalancesByLocationExpectOldBalancesAsync(Guid traceId, string itemCode, decimal requestQty, List<string> validLocations, List<EnumInventoryStatus> validStatuses, bool ispackingcode, List<Balance> oldBalances);
}

2
be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Requests/ThirdLocationRequests/ThirdLocationRequestAppService.cs

@ -167,7 +167,7 @@ public class ThirdLocationRequestAppService : SfsStoreRequestAppServiceBase<Thir
}
else
{
inventoryBalances = await _balanceManager.GetUsableListAsync(detailInput.ItemCode, locationCodes, inventoryStatusList, false).ConfigureAwait(false);
inventoryBalances = await _balanceManager.GetNoPackCodeUsableListAsync(detailInput.ItemCode, locationCodes, inventoryStatusList, true).ConfigureAwait(false);
}
decimal balanceSum = 0;

Loading…
Cancel
Save