|
|
@ -1,16 +1,14 @@ |
|
|
|
using System; |
|
|
|
using System.Collections.Generic; |
|
|
|
using System.Linq; |
|
|
|
using System.Linq.Expressions; |
|
|
|
using System.Text.Json; |
|
|
|
using System.Threading; |
|
|
|
using System.Threading.Tasks; |
|
|
|
using DocumentFormat.OpenXml.Office2016.Drawing.ChartDrawing; |
|
|
|
using Microsoft.AspNetCore.Authorization; |
|
|
|
using Microsoft.AspNetCore.Mvc; |
|
|
|
using Microsoft.Extensions.Logging; |
|
|
|
using Volo.Abp; |
|
|
|
using Volo.Abp.Application.Dtos; |
|
|
|
using Volo.Abp.Domain.Entities.Events.Distributed; |
|
|
|
using Volo.Abp.Domain.Repositories; |
|
|
|
using Win_in.Sfs.Basedata.Application.Contracts; |
|
|
|
using Win_in.Sfs.Shared.Application.Contracts; |
|
|
@ -21,12 +19,11 @@ using Win_in.Sfs.Wms.Inventory.Domain; |
|
|
|
using Win_in.Sfs.Wms.Inventory.Domain.Acl.ItemBasic; |
|
|
|
using Win_in.Sfs.Wms.Inventory.Domain.Acl.Location; |
|
|
|
using Win_in.Sfs.Wms.Inventory.Domain.Shared; |
|
|
|
using JsonSerializer = System.Text.Json.JsonSerializer; |
|
|
|
|
|
|
|
namespace Win_in.Sfs.Wms.Inventory.Application; |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 库存余额
|
|
|
|
/// 库存余额
|
|
|
|
/// </summary>
|
|
|
|
[Authorize] |
|
|
|
[Route($"{InventoryConsts.RootPath}inventory-balance")] |
|
|
@ -58,13 +55,55 @@ public class BalanceAppService |
|
|
|
_locationAclService = locationAclService; |
|
|
|
_itemBasicAclService = itemBasicAclService; |
|
|
|
_itemBasicAppService = itemBasicAppService; |
|
|
|
_stdCostPriceSheetAppService= stdCostPriceSheetAppService; |
|
|
|
_stdCostPriceSheetAppService = stdCostPriceSheetAppService; |
|
|
|
} |
|
|
|
|
|
|
|
#region Update
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 修改批次
|
|
|
|
/// 库存余额更新物品基础信息
|
|
|
|
/// </summary>
|
|
|
|
[HttpPost("update/item-basic-info")] |
|
|
|
public async Task UpdateItemBasicInfoAsync(BalanceUpdateItemBasicInfoDto balanceUpdateItemBasicInfoDto) |
|
|
|
{ |
|
|
|
//停用,可能用其他处理方案
|
|
|
|
return; |
|
|
|
// 物品编码
|
|
|
|
var itemCodes = balanceUpdateItemBasicInfoDto.BalanceUpdateItemBasicInfos?.Select(c => c.ItemCode); |
|
|
|
itemCodes = itemCodes?.Where(t => string.IsNullOrWhiteSpace(t) == false); |
|
|
|
if (itemCodes == null || itemCodes.Any() == false) |
|
|
|
{ |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
// 获取库存余额
|
|
|
|
var entitys = await _repository.GetListAsync(p => |
|
|
|
itemCodes.Contains(p.ItemCode)).ConfigureAwait(false); |
|
|
|
if (entitys.Count <= 0) |
|
|
|
{ |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
// 库存余额更新物品基础信息
|
|
|
|
var entitysGroup = entitys.GroupBy(t => t.ItemCode); |
|
|
|
|
|
|
|
foreach (var entity in entitysGroup) |
|
|
|
{ |
|
|
|
var balanceUpdateItemBasicInfo = |
|
|
|
balanceUpdateItemBasicInfoDto.BalanceUpdateItemBasicInfos.FirstOrDefault(t => t.ItemCode == entity.Key); |
|
|
|
foreach (var item in entity) |
|
|
|
{ |
|
|
|
item.ItemName = balanceUpdateItemBasicInfo.ItemName ?? item.ItemName; |
|
|
|
item.ItemDesc1 = balanceUpdateItemBasicInfo.ItemDesc1 ?? item.ItemDesc1; |
|
|
|
item.ItemDesc2 = balanceUpdateItemBasicInfo.ItemDesc2 ?? item.ItemDesc2; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
await _repository.UpdateManyAsync(entitys).ConfigureAwait(false); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 修改批次
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="id"></param>
|
|
|
|
/// <param name="lot"></param>
|
|
|
@ -74,19 +113,22 @@ public class BalanceAppService |
|
|
|
/// <param name="expireDate"></param>
|
|
|
|
/// <returns></returns>
|
|
|
|
[HttpPost("update/batch")] |
|
|
|
public virtual async Task UpdateBatchAsync(Guid id, string lot, string supplierBatch, DateTime arriveDate, DateTime produceDate, DateTime expireDate) |
|
|
|
public virtual async Task UpdateBatchAsync(Guid id, string lot, string supplierBatch, DateTime arriveDate, |
|
|
|
DateTime produceDate, DateTime expireDate) |
|
|
|
{ |
|
|
|
var entity = await _repository.FindAsync(id).ConfigureAwait(false); |
|
|
|
Check.NotNull(entity, EntityClassName); |
|
|
|
var worker = CurrentUser.GetUserName(); |
|
|
|
var jobNumber = ""; |
|
|
|
var docNumber = ""; |
|
|
|
await _transferLogManager.ChangeBatchAsync(entity, lot, supplierBatch, arriveDate, produceDate, expireDate, worker, jobNumber, docNumber).ConfigureAwait(false); |
|
|
|
await _transferLogManager |
|
|
|
.ChangeBatchAsync(entity, lot, supplierBatch, arriveDate, produceDate, expireDate, worker, jobNumber, |
|
|
|
docNumber).ConfigureAwait(false); |
|
|
|
await _repository.UpdateAsync(entity).ConfigureAwait(false); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 修改序号
|
|
|
|
/// 修改序号
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="id"></param>
|
|
|
|
/// <param name="serialNumber"></param>
|
|
|
@ -101,7 +143,7 @@ public class BalanceAppService |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 修改库位
|
|
|
|
/// 修改库位
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="id"></param>
|
|
|
|
/// <param name="warehouseCode"></param>
|
|
|
@ -109,7 +151,8 @@ public class BalanceAppService |
|
|
|
/// <param name="containerCode"></param>
|
|
|
|
/// <returns></returns>
|
|
|
|
[HttpPost("update/location")] |
|
|
|
public virtual async Task UpdateLocationAsync(Guid id, string warehouseCode, string locationCode, string containerCode) |
|
|
|
public virtual async Task UpdateLocationAsync(Guid id, string warehouseCode, string locationCode, |
|
|
|
string containerCode) |
|
|
|
{ |
|
|
|
var entity = await _repository.FindAsync(id).ConfigureAwait(false); |
|
|
|
Check.NotNull(entity, EntityClassName); |
|
|
@ -122,7 +165,7 @@ public class BalanceAppService |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 修改状态
|
|
|
|
/// 修改状态
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="id"></param>
|
|
|
|
/// <param name="status"></param>
|
|
|
@ -140,7 +183,7 @@ public class BalanceAppService |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 修改过期日期
|
|
|
|
/// 修改过期日期
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="id"></param>
|
|
|
|
/// <param name="expireDate"></param>
|
|
|
@ -155,7 +198,7 @@ public class BalanceAppService |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 修改托盘标签
|
|
|
|
/// 修改托盘标签
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="id"></param>
|
|
|
|
/// <param name="containerCode"></param>
|
|
|
@ -170,7 +213,7 @@ public class BalanceAppService |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 可用
|
|
|
|
/// 可用
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="id"></param>
|
|
|
|
/// <returns></returns>
|
|
|
@ -184,7 +227,7 @@ public class BalanceAppService |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 不可用
|
|
|
|
/// 不可用
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="id"></param>
|
|
|
|
/// <returns></returns>
|
|
|
@ -198,7 +241,7 @@ public class BalanceAppService |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 设置为不可用 根据 库位 零件 箱码 批次 状态
|
|
|
|
/// 设置为不可用 根据 库位 零件 箱码 批次 状态
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="packingCode"></param>
|
|
|
|
/// <param name="itemCode"></param>
|
|
|
@ -227,7 +270,7 @@ public class BalanceAppService |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 设置为可用 根据 库位 零件 箱码 批次 状态
|
|
|
|
/// 设置为可用 根据 库位 零件 箱码 批次 状态
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="packingCode"></param>
|
|
|
|
/// <param name="itemCode"></param>
|
|
|
@ -258,27 +301,30 @@ public class BalanceAppService |
|
|
|
#endregion Update
|
|
|
|
|
|
|
|
#region Get
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 获取库存余额带标准价格得
|
|
|
|
/// 获取库存余额带标准价格得
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="sfsRequestInput"></param>
|
|
|
|
/// <param name="includeDetails"></param>
|
|
|
|
/// <param name="cancellationToken"></param>
|
|
|
|
/// <returns></returns>
|
|
|
|
[HttpPost("get-list")] |
|
|
|
public virtual async Task<PagedResultDto<BalanceDTO>> GetBalancePagedListByFilterAsync(SfsInventoryRequestInputBase sfsRequestInput, bool includeDetails = false, |
|
|
|
CancellationToken cancellationToken = default) |
|
|
|
public virtual async Task<PagedResultDto<BalanceDTO>> GetBalancePagedListByFilterAsync( |
|
|
|
SfsInventoryRequestInputBase sfsRequestInput, bool includeDetails = false, |
|
|
|
CancellationToken cancellationToken = default) |
|
|
|
{ |
|
|
|
var result =await base.GetPagedListByFilterAsync(sfsRequestInput, includeDetails, cancellationToken); |
|
|
|
var result = await base.GetPagedListByFilterAsync(sfsRequestInput, includeDetails, cancellationToken); |
|
|
|
foreach (var item in result.Items) |
|
|
|
{ |
|
|
|
var std = await _stdCostPriceSheetAppService.GetByItemCode(item.ItemCode).ConfigureAwait(false); |
|
|
|
item.StdCostPrice = std == null ? 0 : std.StdCostPrice; |
|
|
|
} |
|
|
|
|
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
///
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="input"></param>
|
|
|
|
/// <returns></returns>
|
|
|
@ -304,11 +350,11 @@ public class BalanceAppService |
|
|
|
dto.ItemDesc2 = item.Desc2; |
|
|
|
dto.Uom = item.BasicUom; |
|
|
|
} |
|
|
|
|
|
|
|
return dtos; |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
///
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="packingCode"></param>
|
|
|
|
/// <param name="itemCode"></param>
|
|
|
@ -317,20 +363,23 @@ public class BalanceAppService |
|
|
|
/// <exception cref="NotImplementedException"></exception>
|
|
|
|
[HttpGet("item-status")] |
|
|
|
[AllowAnonymous] |
|
|
|
public virtual async Task<BalanceDTO> GetByItemLocationAndPackingAsync(string packingCode, string itemCode, string locationCode) |
|
|
|
public virtual async Task<BalanceDTO> GetByItemLocationAndPackingAsync(string packingCode, string itemCode, |
|
|
|
string locationCode) |
|
|
|
{ |
|
|
|
var entity = await _repository.FirstOrDefaultAsync(c => |
|
|
|
c.PackingCode == packingCode && c.ItemCode == itemCode && c.LocationCode == locationCode).ConfigureAwait(false); |
|
|
|
c.PackingCode == packingCode && c.ItemCode == itemCode && c.LocationCode == locationCode) |
|
|
|
.ConfigureAwait(false); |
|
|
|
if (entity == null) |
|
|
|
{ |
|
|
|
throw new UserFriendlyException($"未找到箱码为 {packingCode},物料代码为 {itemCode},库位代码为 {locationCode} 的库存"); |
|
|
|
} |
|
|
|
|
|
|
|
var dto = ObjectMapper.Map<Balance, BalanceDTO>(entity); |
|
|
|
return dto; |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 获取对应的库存
|
|
|
|
/// 获取对应的库存
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="packingCode"></param>
|
|
|
|
/// <param name="itemCode"></param>
|
|
|
@ -339,14 +388,17 @@ public class BalanceAppService |
|
|
|
/// <returns></returns>
|
|
|
|
/// <exception cref="NotImplementedException"></exception>
|
|
|
|
[HttpGet("item-loc-packing-status")] |
|
|
|
public virtual async Task<BalanceDTO> GetByItemLocationPackingAndStatusAsync(string packingCode, string itemCode, string locationCode, EnumInventoryStatus status) |
|
|
|
public virtual async Task<BalanceDTO> GetByItemLocationPackingAndStatusAsync(string packingCode, string itemCode, |
|
|
|
string locationCode, EnumInventoryStatus status) |
|
|
|
{ |
|
|
|
var entity = await _repository.FirstOrDefaultAsync(c => |
|
|
|
c.PackingCode == packingCode && c.ItemCode == itemCode && c.LocationCode == locationCode && c.Status == status).ConfigureAwait(false); |
|
|
|
c.PackingCode == packingCode && c.ItemCode == itemCode && c.LocationCode == locationCode && |
|
|
|
c.Status == status).ConfigureAwait(false); |
|
|
|
if (entity == null) |
|
|
|
{ |
|
|
|
throw new UserFriendlyException($"未找到箱码为 {packingCode},物料代码为 {itemCode},库位代码为 {locationCode} 的库存"); |
|
|
|
} |
|
|
|
|
|
|
|
var dto = ObjectMapper.Map<Balance, BalanceDTO>(entity); |
|
|
|
return dto; |
|
|
|
} |
|
|
@ -407,14 +459,16 @@ public class BalanceAppService |
|
|
|
&& p.Status == status).ConfigureAwait(false); |
|
|
|
if (entity == null) |
|
|
|
{ |
|
|
|
throw new UserFriendlyException($"未找到箱码为 {packingCode},物料代码为 {itemCode},库位代码为 {locationCode},状态为为 {status} 的库存"); |
|
|
|
throw new UserFriendlyException( |
|
|
|
$"未找到箱码为 {packingCode},物料代码为 {itemCode},库位代码为 {locationCode},状态为为 {status} 的库存"); |
|
|
|
} |
|
|
|
|
|
|
|
var dto = ObjectMapper.Map<Balance, BalanceDTO>(entity); |
|
|
|
return dto; |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 查找可用物品的库存(此物品库存状态为合格)
|
|
|
|
/// 查找可用物品的库存(此物品库存状态为合格)
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="itemCode"></param>
|
|
|
|
/// <returns></returns>
|
|
|
@ -436,35 +490,39 @@ public class BalanceAppService |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 获取【库存】根据 库位代码 和 物品代码
|
|
|
|
/// 获取【库存】根据 库位代码 和 物品代码
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="locationCode"></param>
|
|
|
|
/// <param name="itemCode"></param>
|
|
|
|
/// <returns></returns>
|
|
|
|
[HttpGet("list/by-location-and-item")] |
|
|
|
public virtual async Task<List<BalanceDTO>> GetListByLocationCodeAndItemCodeAsync(string locationCode, string itemCode) |
|
|
|
public virtual async Task<List<BalanceDTO>> GetListByLocationCodeAndItemCodeAsync(string locationCode, |
|
|
|
string itemCode) |
|
|
|
{ |
|
|
|
var entitys = await _repository.GetListAsync(p => p.LocationCode == locationCode && p.ItemCode == itemCode).ConfigureAwait(false); |
|
|
|
var entitys = await _repository.GetListAsync(p => p.LocationCode == locationCode && p.ItemCode == itemCode) |
|
|
|
.ConfigureAwait(false); |
|
|
|
var dtos = ObjectMapper.Map<List<Balance>, List<BalanceDTO>>(entitys); |
|
|
|
return dtos; |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 获取【库存】根据 库位代码 和 物品代码
|
|
|
|
/// 获取【库存】根据 库位代码 和 物品代码
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="erplocationCode"></param>
|
|
|
|
/// <param name="itemCode"></param>
|
|
|
|
/// <returns></returns>
|
|
|
|
[HttpGet("list/by-erplocation-and-item")] |
|
|
|
public virtual async Task<List<BalanceDTO>> GetListByErpLocationCodeAndItemCodeAsync(string erplocationCode, string itemCode) |
|
|
|
public virtual async Task<List<BalanceDTO>> GetListByErpLocationCodeAndItemCodeAsync(string erplocationCode, |
|
|
|
string itemCode) |
|
|
|
{ |
|
|
|
var entitys = await _repository.GetListAsync(p => p.LocationErpCode == erplocationCode && p.ItemCode == itemCode).ConfigureAwait(false); |
|
|
|
var entitys = await _repository |
|
|
|
.GetListAsync(p => p.LocationErpCode == erplocationCode && p.ItemCode == itemCode).ConfigureAwait(false); |
|
|
|
var dtos = ObjectMapper.Map<List<Balance>, List<BalanceDTO>>(entitys); |
|
|
|
return dtos; |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 根据发料任务需求,算出推荐的库存 (在获取时 已经添加预占用)
|
|
|
|
/// 根据发料任务需求,算出推荐的库存 (在获取时 已经去除了预占用)
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="input"></param>
|
|
|
|
/// <returns></returns>
|
|
|
@ -480,7 +538,9 @@ public class BalanceAppService |
|
|
|
var statuses = input.Statuses; |
|
|
|
Logger.LogDebug(traceId + "|Input:" + input); |
|
|
|
|
|
|
|
var balances = await _balanceManager.GetRecommendBalancesAsync(traceId, itemCode, qty, locationTypes, locationAreas, statuses).ConfigureAwait(false); |
|
|
|
var balances = await _balanceManager |
|
|
|
.GetRecommendBalancesAsync(traceId, itemCode, qty, locationTypes, locationAreas, statuses) |
|
|
|
.ConfigureAwait(false); |
|
|
|
|
|
|
|
var dtos = ObjectMapper.Map<List<Balance>, List<BalanceDTO>>(balances); |
|
|
|
|
|
|
@ -488,7 +548,7 @@ public class BalanceAppService |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 根据发料任务需求的库位,算出推荐的库存 (在获取时 已经添加预占用)
|
|
|
|
/// 根据发料任务需求的库位,算出推荐的库存 (在获取时 已经去除了预占用)
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="input"></param>
|
|
|
|
/// <returns></returns>
|
|
|
@ -506,21 +566,26 @@ public class BalanceAppService |
|
|
|
var locationDto = await _locationAclService.GetByCodeAsync(location).ConfigureAwait(false); |
|
|
|
if (locationDto != null) |
|
|
|
{ |
|
|
|
if(input.LocationAreas==null) |
|
|
|
if (input.LocationAreas == null) |
|
|
|
{ |
|
|
|
input.LocationAreas = new List<string>(); |
|
|
|
} |
|
|
|
|
|
|
|
input.LocationAreas.Add(locationDto.AreaCode); |
|
|
|
if (input.LocationTypes == null) |
|
|
|
{ |
|
|
|
input.LocationTypes = new List<EnumLocationType>(); |
|
|
|
} |
|
|
|
|
|
|
|
input.LocationTypes.Add(locationDto.Type); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
Logger.LogDebug(traceId + "|Input:" + input); |
|
|
|
|
|
|
|
var balances = await _balanceManager.GetRecommendBalancesByLocationAsync(traceId, itemCode, qty, locations, statuses, input.IsPackingCode).ConfigureAwait(false); |
|
|
|
var balances = await _balanceManager |
|
|
|
.GetRecommendBalancesByLocationAsync(traceId, itemCode, qty, locations, statuses, input.IsPackingCode) |
|
|
|
.ConfigureAwait(false); |
|
|
|
|
|
|
|
var dtos = ObjectMapper.Map<List<Balance>, List<BalanceDTO>>(balances); |
|
|
|
|
|
|
@ -528,7 +593,24 @@ public class BalanceAppService |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// pda发料执行查询使用
|
|
|
|
/// 获取可用库存列表
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="input"></param>
|
|
|
|
/// <returns></returns>
|
|
|
|
/// <exception cref="NotImplementedException"></exception>
|
|
|
|
[HttpGet("usable-list")] |
|
|
|
public virtual async Task<List<BalanceDTO>> GetUsableListAsync(RecommendBalanceRequestInput input) |
|
|
|
{ |
|
|
|
var inventoryBalances = await _balanceManager |
|
|
|
.GetUsableListAsync(input.ItemCode, input.Locations, input.Statuses, true).ConfigureAwait(false); |
|
|
|
|
|
|
|
var dtos = ObjectMapper.Map<List<Balance>, List<BalanceDTO>>(inventoryBalances); |
|
|
|
|
|
|
|
return dtos; |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// pda发料执行查询使用
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="input"></param>
|
|
|
|
/// <returns></returns>
|
|
|
@ -539,7 +621,8 @@ public class BalanceAppService |
|
|
|
//可以领料
|
|
|
|
if (input.IsEnablePick != null) |
|
|
|
{ |
|
|
|
var locations = await _locationAclService.GetListByEnablePickAsync((bool)input.IsEnablePick).ConfigureAwait(false); |
|
|
|
var locations = await _locationAclService.GetListByEnablePickAsync((bool)input.IsEnablePick) |
|
|
|
.ConfigureAwait(false); |
|
|
|
var codes = JsonSerializer.Serialize(locations.Select(c => c.Code)); |
|
|
|
input.Condition.Filters.Add(new Filter("LocationCode", codes, "In")); |
|
|
|
} |
|
|
@ -552,48 +635,51 @@ public class BalanceAppService |
|
|
|
input.Condition.Filters.Add(new Filter("LocationCode", codes, "In")); |
|
|
|
} |
|
|
|
|
|
|
|
var dtos = await GetPagedListByFilterAsync(input, false).ConfigureAwait(false); |
|
|
|
var dtos = await GetPagedListByFilterAsync(input).ConfigureAwait(false); |
|
|
|
return dtos; |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 查询库存余额 根据 状态集合 库位类别集合 物品代码 箱码 托码 批次 库位
|
|
|
|
/// 查询库存余额 根据 状态集合 库位类别集合 物品代码 箱码 托码 批次 库位
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="balanceManyParameterRequestInput"></param>
|
|
|
|
/// <returns></returns>
|
|
|
|
[HttpPost("get-by-item-location-packing-container-lot-locationtype-status")] |
|
|
|
public virtual async Task<List<BalanceDTO>> GetListByManyParameter(BalanceManyParameterRequestInput balanceManyParameterRequestInput) |
|
|
|
public virtual async Task<List<BalanceDTO>> GetListByManyParameter( |
|
|
|
BalanceManyParameterRequestInput balanceManyParameterRequestInput) |
|
|
|
{ |
|
|
|
var input = new SfsInventoryRequestInputBase() |
|
|
|
var input = new SfsInventoryRequestInputBase |
|
|
|
{ |
|
|
|
MaxResultCount = 1000, |
|
|
|
SkipCount = 0, |
|
|
|
Sorting = string.Empty, |
|
|
|
Condition = new Condition() |
|
|
|
{ |
|
|
|
Filters = new List<Filter>() |
|
|
|
} |
|
|
|
Condition = new Condition { Filters = new List<Filter>() } |
|
|
|
}; |
|
|
|
if (!string.IsNullOrWhiteSpace(balanceManyParameterRequestInput.ItemCode)) |
|
|
|
{ |
|
|
|
input.Condition.Filters.Add(new Filter("ItemCode", balanceManyParameterRequestInput.ItemCode)); |
|
|
|
} |
|
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(balanceManyParameterRequestInput.LocationCode)) |
|
|
|
{ |
|
|
|
input.Condition.Filters.Add(new Filter("LocationCode", balanceManyParameterRequestInput.LocationCode)); |
|
|
|
} |
|
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(balanceManyParameterRequestInput.PackingCode)) |
|
|
|
{ |
|
|
|
input.Condition.Filters.Add(new Filter("PackingCode", balanceManyParameterRequestInput.PackingCode)); |
|
|
|
} |
|
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(balanceManyParameterRequestInput.ContainerCode)) |
|
|
|
{ |
|
|
|
input.Condition.Filters.Add(new Filter("ContainerCode", balanceManyParameterRequestInput.ContainerCode)); |
|
|
|
} |
|
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(balanceManyParameterRequestInput.Lot)) |
|
|
|
{ |
|
|
|
input.Condition.Filters.Add(new Filter("Lot", balanceManyParameterRequestInput.Lot)); |
|
|
|
} |
|
|
|
|
|
|
|
//筛选库存状态
|
|
|
|
if (balanceManyParameterRequestInput.InventoryStatuses.Count > 0) |
|
|
|
{ |
|
|
@ -601,6 +687,7 @@ public class BalanceAppService |
|
|
|
balanceManyParameterRequestInput.InventoryStatuses); |
|
|
|
input.Condition.Filters.Add(new Filter("Status", Statuses, "In")); |
|
|
|
} |
|
|
|
|
|
|
|
//筛选库位类型
|
|
|
|
if (balanceManyParameterRequestInput.LocationTypes.Count > 0) |
|
|
|
{ |
|
|
@ -617,91 +704,115 @@ public class BalanceAppService |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 查询库存余额 根据 物品 库位 库位类型 库存状态 批次
|
|
|
|
/// 查询库存余额 根据 物品 库位 库位类型 库存状态 批次
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="listInput"></param>
|
|
|
|
/// <returns></returns>
|
|
|
|
[HttpPost("by-balances-request-many-parameter")] |
|
|
|
public async Task<PagedResultDto<BalanceDTO>> GetListByLocationTypeAndInventoryStatusAsync(BalanceListByIssueInputByInventoryStatusAndLocationType listInput) |
|
|
|
public async Task<PagedResultDto<BalanceDTO>> GetListByLocationTypeAndInventoryStatusAsync( |
|
|
|
BalanceListByIssueInputByInventoryStatusAndLocationType listInput) |
|
|
|
{ |
|
|
|
var input = new SfsInventoryRequestInputBase() |
|
|
|
var input = new SfsInventoryRequestInputBase |
|
|
|
{ |
|
|
|
MaxResultCount = listInput.pageSize, |
|
|
|
SkipCount = (listInput.pageIndex - 1) * listInput.pageSize, |
|
|
|
Sorting = listInput.sortBy, |
|
|
|
Condition = new Condition() |
|
|
|
{ |
|
|
|
Filters = new List<Filter>() |
|
|
|
} |
|
|
|
Condition = new Condition { Filters = new List<Filter>() } |
|
|
|
}; |
|
|
|
if (!string.IsNullOrWhiteSpace(listInput.itemCode)) |
|
|
|
{ |
|
|
|
input.Condition.Filters.Add(new Filter("ItemCode", listInput.itemCode)); |
|
|
|
} |
|
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(listInput.locationCode)) |
|
|
|
{ |
|
|
|
input.Condition.Filters.Add(new Filter("LocationCode", listInput.locationCode)); |
|
|
|
} |
|
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(listInput.lot)) |
|
|
|
{ |
|
|
|
input.Condition.Filters.Add(new Filter("Lot", listInput.lot)); |
|
|
|
} |
|
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(listInput.packingCode)) |
|
|
|
{ |
|
|
|
input.Condition.Filters.Add(new Filter("PackingCode", listInput.packingCode)); |
|
|
|
} |
|
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(listInput.containerCode)) |
|
|
|
{ |
|
|
|
input.Condition.Filters.Add(new Filter("ContainerCode", listInput.containerCode)); |
|
|
|
} |
|
|
|
|
|
|
|
if (listInput.locationTypes != null && listInput.locationTypes.Any()) |
|
|
|
{ |
|
|
|
var locationCodes = (await _locationAclService.GetListByTypesAsync(listInput.locationTypes).ConfigureAwait(false)).Select(t => t.Code).ToList(); |
|
|
|
var locationCodes = |
|
|
|
(await _locationAclService.GetListByTypesAsync(listInput.locationTypes).ConfigureAwait(false)) |
|
|
|
.Select(t => t.Code).ToList(); |
|
|
|
if (locationCodes.Any()) |
|
|
|
{ |
|
|
|
input.Condition.Filters.Add(new Filter("LocationCode", JsonSerializer.Serialize(locationCodes), "In")); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (listInput.inventoryStatuses != null && listInput.inventoryStatuses.Any()) |
|
|
|
{ |
|
|
|
input.Condition.Filters.Add(new Filter("Status", JsonSerializer.Serialize(listInput.inventoryStatuses), "In")); |
|
|
|
input.Condition.Filters.Add(new Filter("Status", JsonSerializer.Serialize(listInput.inventoryStatuses), |
|
|
|
"In")); |
|
|
|
} |
|
|
|
var balanceDTOs = await GetPagedListByFilterAsync(input, false).ConfigureAwait(false); |
|
|
|
|
|
|
|
var balanceDTOs = await GetPagedListByFilterAsync(input).ConfigureAwait(false); |
|
|
|
return balanceDTOs; |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 获取 隔离库位 不合格 库存
|
|
|
|
/// 获取 隔离库位 不合格 库存
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="sfsRequestDTO"></param>
|
|
|
|
/// <param name="includeDetails"></param>
|
|
|
|
/// <param name="cancellationToken"></param>
|
|
|
|
/// <returns></returns>
|
|
|
|
[HttpPost("by-hold-location-code-and-no-ok")] |
|
|
|
public async Task<PagedResultDto<BalanceDTO>> GetByHoldLocationCodeAndNoOkAsync(SfsInventoryRequestInputBase sfsRequestDTO, bool includeDetails = false, |
|
|
|
public async Task<PagedResultDto<BalanceDTO>> GetByHoldLocationCodeAndNoOkAsync( |
|
|
|
SfsInventoryRequestInputBase sfsRequestDTO, bool includeDetails = false, |
|
|
|
CancellationToken cancellationToken = default) |
|
|
|
{ |
|
|
|
var locationInfo = await _locationAclService.GetFirstByTypeAsync(EnumLocationType.HOLD).ConfigureAwait(false); |
|
|
|
|
|
|
|
sfsRequestDTO.Condition.Filters.Add(new Sfs.Shared.Domain.Filter() { Action = "==", Column = "LocationCode", Logic = EnumFilterLogic.And.ToString(), Value = locationInfo.Code }); |
|
|
|
sfsRequestDTO.Condition.Filters.Add(new Sfs.Shared.Domain.Filter() { Action = "==", Column = "Status", Logic = EnumFilterLogic.And.ToString(), Value = ((int)EnumInventoryStatus.NOK).ToString(), }); |
|
|
|
sfsRequestDTO.Condition.Filters.Add(new Filter |
|
|
|
{ |
|
|
|
Action = "==", |
|
|
|
Column = "LocationCode", |
|
|
|
Logic = EnumFilterLogic.And.ToString(), |
|
|
|
Value = locationInfo.Code |
|
|
|
}); |
|
|
|
sfsRequestDTO.Condition.Filters.Add(new Filter |
|
|
|
{ |
|
|
|
Action = "==", |
|
|
|
Column = "Status", |
|
|
|
Logic = EnumFilterLogic.And.ToString(), |
|
|
|
Value = ((int)EnumInventoryStatus.NOK).ToString() |
|
|
|
}); |
|
|
|
|
|
|
|
Expression<Func<Balance, bool>> expression = sfsRequestDTO.Condition.Filters?.Count > 0 |
|
|
|
var expression = sfsRequestDTO.Condition.Filters?.Count > 0 |
|
|
|
? sfsRequestDTO.Condition.Filters.ToLambda<Balance>() |
|
|
|
: p => true; |
|
|
|
|
|
|
|
return await GetPagedListAsync(expression, sfsRequestDTO.SkipCount, sfsRequestDTO.MaxResultCount, sfsRequestDTO.Sorting, includeDetails, cancellationToken).ConfigureAwait(false); |
|
|
|
return await GetPagedListAsync(expression, sfsRequestDTO.SkipCount, sfsRequestDTO.MaxResultCount, |
|
|
|
sfsRequestDTO.Sorting, includeDetails, cancellationToken).ConfigureAwait(false); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 获取 【实际库存余额】(不包含预计入,抛出预计出)
|
|
|
|
/// 获取 【实际库存余额】(不包含预计入,抛出预计出)
|
|
|
|
/// </summary>
|
|
|
|
/// <returns></returns>
|
|
|
|
[HttpPost("get-real-qty-by-packing-and-item-and-location-and-status")] |
|
|
|
public async Task<BalanceDTO> GetRealQtyByPackingCodeAndItemCodeAndLocationCodeAndStatusAsync(string packingCode, string itemCode, string locationCode, EnumInventoryStatus status) |
|
|
|
public async Task<BalanceDTO> GetRealQtyByPackingCodeAndItemCodeAndLocationCodeAndStatusAsync(string packingCode, |
|
|
|
string itemCode, string locationCode, EnumInventoryStatus status) |
|
|
|
{ |
|
|
|
var entity = await _repository.FirstOrDefaultAsync(c => |
|
|
|
c.PackingCode == packingCode && c.ItemCode == itemCode && c.LocationCode == locationCode && c.Status == status).ConfigureAwait(false); |
|
|
|
c.PackingCode == packingCode && c.ItemCode == itemCode && c.LocationCode == locationCode && |
|
|
|
c.Status == status).ConfigureAwait(false); |
|
|
|
if (entity == null) |
|
|
|
{ |
|
|
|
throw new UserFriendlyException($"未找到箱码为 {packingCode},物料代码为 {itemCode},库位代码为 {locationCode} 的库存"); |
|
|
@ -714,7 +825,8 @@ public class BalanceAppService |
|
|
|
} |
|
|
|
|
|
|
|
[HttpGet("list-by-location-status")] |
|
|
|
public async Task<List<BalanceDTO>> GetListByLocationCodeAndStatusAsync(string locationCode, EnumInventoryStatus status) |
|
|
|
public async Task<List<BalanceDTO>> GetListByLocationCodeAndStatusAsync(string locationCode, |
|
|
|
EnumInventoryStatus status) |
|
|
|
{ |
|
|
|
var entities = await _repository.GetListAsync( |
|
|
|
c => c.LocationCode == locationCode && c.Status == status |
|
|
@ -728,17 +840,18 @@ public class BalanceAppService |
|
|
|
#endregion Get
|
|
|
|
|
|
|
|
#region export
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 导出数据
|
|
|
|
/// 导出数据
|
|
|
|
/// </summary>
|
|
|
|
[HttpPost("export")] |
|
|
|
public override async Task<IActionResult> ExportAsync(SfsInventoryRequestInputBase input) |
|
|
|
{ |
|
|
|
var expression = input.Condition.Filters?.Count > 0 |
|
|
|
? input.Condition.Filters.ToLambda<Balance>() |
|
|
|
: p => true; |
|
|
|
? input.Condition.Filters.ToLambda<Balance>() |
|
|
|
: p => true; |
|
|
|
var entities = await _repository.GetPagedListAsync(expression, input.SkipCount, input.MaxResultCount, |
|
|
|
input.Sorting, true).ConfigureAwait(false); |
|
|
|
input.Sorting, true).ConfigureAwait(false); |
|
|
|
var list = ObjectMapper.Map<List<Balance>, List<BalanceDTO>>(entities); |
|
|
|
|
|
|
|
//var hasDetails = typeof(TEntity) is SfsMasterAggregateRootBase<TDetail> detailEntity;
|
|
|
@ -760,47 +873,6 @@ public class BalanceAppService |
|
|
|
|
|
|
|
return ExportImportService.Export(list, detailsProptyName: hasDetails ? nameof(EmptyDetail) : null); |
|
|
|
} |
|
|
|
#endregion
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 库存余额更新物品基础信息
|
|
|
|
/// </summary>
|
|
|
|
[HttpPost("update/item-basic-info")] |
|
|
|
public async Task UpdateItemBasicInfoAsync(BalanceUpdateItemBasicInfoDto balanceUpdateItemBasicInfoDto) |
|
|
|
{ |
|
|
|
//停用,可能用其他处理方案
|
|
|
|
return; |
|
|
|
// 物品编码
|
|
|
|
var itemCodes = balanceUpdateItemBasicInfoDto.BalanceUpdateItemBasicInfos?.Select(c => c.ItemCode); |
|
|
|
itemCodes = itemCodes?.Where(t => string.IsNullOrWhiteSpace(t) == false); |
|
|
|
if (itemCodes == null || itemCodes.Any() == false) |
|
|
|
{ |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
// 获取库存余额
|
|
|
|
var entitys = await _repository.GetListAsync(p => |
|
|
|
itemCodes.Contains(p.ItemCode)).ConfigureAwait(false); |
|
|
|
if (entitys.Count <= 0) |
|
|
|
{ |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
// 库存余额更新物品基础信息
|
|
|
|
var entitysGroup = entitys.GroupBy(t => t.ItemCode); |
|
|
|
|
|
|
|
foreach (var entity in entitysGroup) |
|
|
|
{ |
|
|
|
var balanceUpdateItemBasicInfo = balanceUpdateItemBasicInfoDto.BalanceUpdateItemBasicInfos.FirstOrDefault(t => t.ItemCode == entity.Key); |
|
|
|
foreach (var item in entity) |
|
|
|
{ |
|
|
|
item.ItemName = balanceUpdateItemBasicInfo.ItemName ?? item.ItemName; |
|
|
|
item.ItemDesc1 = balanceUpdateItemBasicInfo.ItemDesc1 ?? item.ItemDesc1; |
|
|
|
item.ItemDesc2 = balanceUpdateItemBasicInfo.ItemDesc2 ?? item.ItemDesc2; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
await _repository.UpdateManyAsync(entitys).ConfigureAwait(false); |
|
|
|
} |
|
|
|
|
|
|
|
#endregion
|
|
|
|
} |
|
|
|