|
|
@ -1,21 +1,20 @@ |
|
|
|
using System.Collections.Generic; |
|
|
|
using System.Linq; |
|
|
|
using System.Text; |
|
|
|
using System.Text.Json; |
|
|
|
using System.Threading.Tasks; |
|
|
|
using AutoMapper; |
|
|
|
using Castle.Components.DictionaryAdapter; |
|
|
|
using Volo.Abp; |
|
|
|
using Volo.Abp.AutoMapper; |
|
|
|
using Volo.Abp.EventBus; |
|
|
|
using Win_in.Sfs.Basedata.Application.Contracts; |
|
|
|
using Win_in.Sfs.Shared.Domain.Shared; |
|
|
|
using Win_in.Sfs.Shared.Domain.Shared.Enums.Store; |
|
|
|
using Win_in.Sfs.Shared.Event; |
|
|
|
using Win_in.Sfs.Wms.Inventory.Application.Contracts; |
|
|
|
using Win_in.Sfs.Wms.Inventory.Domain; |
|
|
|
using Win_in.Sfs.Wms.Store.Application.Contracts; |
|
|
|
using Win_in.Sfs.Wms.Store.Domain; |
|
|
|
using Win_in.Sfs.Wms.Store.Domain.Shared; |
|
|
|
using Win_in.Sfs.Wms.Store.Jobs.IssueJobs; |
|
|
|
using Win_in.Sfs.Wms.Store.Requests.MaterialRequests; |
|
|
|
|
|
|
|
namespace Win_in.Sfs.Wms.Store.Event.BusinessRequest; |
|
|
|
|
|
|
@ -32,17 +31,22 @@ public class CoatingIssueRequestEventHandler |
|
|
|
private readonly IProductionLineItemAppService _productionLineItemAppService; |
|
|
|
private readonly ILocationAppService _locationAppService; |
|
|
|
private readonly IBalanceAppService _balanceAppService; |
|
|
|
private IMapper _mapper; |
|
|
|
//private readonly ICoatingIssueRequestManager _coatingIssueRequestManager;
|
|
|
|
|
|
|
|
public CoatingIssueRequestEventHandler( |
|
|
|
ICoatingIssueJobAppService coatingIssueJobAppService, IProductionLineAppService productionLineAppService, |
|
|
|
ILocationAppService locationAppService, |
|
|
|
IBalanceAppService balanceAppService, IProductionLineItemAppService productionLineItemAppService) |
|
|
|
IBalanceAppService balanceAppService, IProductionLineItemAppService productionLineItemAppService |
|
|
|
//, ICoatingIssueRequestManager coatingIssueRequestManager
|
|
|
|
) |
|
|
|
{ |
|
|
|
_coatingIssueJobAppService = coatingIssueJobAppService; |
|
|
|
_productionLineAppService = productionLineAppService; |
|
|
|
_locationAppService = locationAppService; |
|
|
|
_balanceAppService = balanceAppService; |
|
|
|
_productionLineItemAppService = productionLineItemAppService; |
|
|
|
//_coatingIssueRequestManager = coatingIssueRequestManager;
|
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
@ -51,7 +55,9 @@ public class CoatingIssueRequestEventHandler |
|
|
|
/// <param name="eventData">Event data</param>
|
|
|
|
public virtual async Task HandleEventAsync(SfsCreatedEntityEventData<CoatingIssueRequest> eventData) |
|
|
|
{ |
|
|
|
await Task.CompletedTask.ConfigureAwait(false); |
|
|
|
var entity = eventData.Entity; |
|
|
|
|
|
|
|
await CreateAllCoatingIssueJobAsync(entity).ConfigureAwait(false); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
@ -60,6 +66,8 @@ public class CoatingIssueRequestEventHandler |
|
|
|
/// <param name="eventData">Event data</param>
|
|
|
|
public virtual async Task HandleEventAsync(SfsCreatedEntityEventData<List<CoatingIssueRequest>> eventData) |
|
|
|
{ |
|
|
|
var entity = eventData.Entity; |
|
|
|
|
|
|
|
await Task.CompletedTask.ConfigureAwait(false); |
|
|
|
} |
|
|
|
|
|
|
@ -72,22 +80,7 @@ public class CoatingIssueRequestEventHandler |
|
|
|
{ |
|
|
|
var entity = eventData.Entity; |
|
|
|
|
|
|
|
List<CoatingIssueJobEditInput> coatingIssueJobs = new EditableList<CoatingIssueJobEditInput>(); |
|
|
|
|
|
|
|
//switch (entity.Type)
|
|
|
|
//{
|
|
|
|
// case nameof(EnumIssueType.BoxQty):
|
|
|
|
// coatingIssueJobs = await CreateCoatingIssueJobWithBoxQtyTypeAsync(entity).ConfigureAwait(false);
|
|
|
|
// break;
|
|
|
|
// case nameof(EnumIssueType.Qty):
|
|
|
|
// coatingIssueJobs = await CreateCoatingIssueJobWithQtyTypeAsync(entity).ConfigureAwait(false);
|
|
|
|
// break;
|
|
|
|
//}
|
|
|
|
|
|
|
|
if (coatingIssueJobs.Any()) |
|
|
|
{ |
|
|
|
await _coatingIssueJobAppService.CreateManyAsync(coatingIssueJobs).ConfigureAwait(false); |
|
|
|
} |
|
|
|
await CreateAllCoatingIssueJobAsync(entity).ConfigureAwait(false); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
@ -118,194 +111,135 @@ public class CoatingIssueRequestEventHandler |
|
|
|
#region 按数量叫料
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 创建注塑任务
|
|
|
|
/// 创建注塑任务-按数量
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="coatingMaterialRequest"></param>
|
|
|
|
/// <param name="coatingIssueRequest"></param>
|
|
|
|
/// <param name="coatingIssueRequestDetails"></param>
|
|
|
|
/// <param name="recommendbalanceDtos"></param>
|
|
|
|
/// <param name="useBalanceList"></param>
|
|
|
|
/// <returns></returns>
|
|
|
|
/// <exception cref="UserFriendlyException"></exception>
|
|
|
|
private async Task<List<CoatingIssueJobEditInput>> CreateCoatingIssueJobWithQtyTypeAsync |
|
|
|
(CoatingIssueRequest coatingMaterialRequest) |
|
|
|
(CoatingIssueRequest coatingIssueRequest, List<CoatingIssueRequestDetail> coatingIssueRequestDetails, |
|
|
|
List<BalanceDTO> recommendbalanceDtos, |
|
|
|
List<BalanceDTO> useBalanceList) |
|
|
|
{ |
|
|
|
var jobs = new List<CoatingIssueJobEditInput>(); |
|
|
|
//用来临时存放所有未生成任务的发料集合 如果生成完了再这里去掉
|
|
|
|
var tempDetailDtos = |
|
|
|
ObjectMapper.Map<List<CoatingIssueRequestDetail>, List<CoatingIssueRequestDetailDTO>>( |
|
|
|
coatingIssueRequestDetails); |
|
|
|
|
|
|
|
var toLocationCodes = coatingMaterialRequest.Details.Select(p => p.ToLocationCode).Distinct().ToList(); //所有发送库位的集合
|
|
|
|
var toLocations = await _locationAppService.GetByCodesAsync(toLocationCodes).ConfigureAwait(false); //所有库位的集合
|
|
|
|
var coatingIssueJobDetailInputs = new List<CoatingIssueJobDetailInput>(); |
|
|
|
|
|
|
|
var coatingMaterialRequestDetails = coatingMaterialRequest.Details.Where(p => p.ToBeIssuedQty > 0); //所有还没发送物品的集合
|
|
|
|
foreach (var coatingMaterialRequestDetail in coatingMaterialRequestDetails) //如果有还有剩余未叫料的数量 则创建新的任务
|
|
|
|
if (recommendbalanceDtos != null && recommendbalanceDtos.Count > 0) |
|
|
|
{ |
|
|
|
var toLocation = |
|
|
|
toLocations.FirstOrDefault(p => p.Code == coatingMaterialRequestDetail.ToLocationCode); //判断目标库位是否存在
|
|
|
|
Check.NotNull(toLocation, "库位代码", $"库位 {coatingMaterialRequestDetail.ToLocationCode} 不存在"); |
|
|
|
|
|
|
|
//创建详情
|
|
|
|
var jobDetails = |
|
|
|
await CreateCoatingIssueJobDetailInputsWithQtyTypeAsync(coatingMaterialRequest, coatingMaterialRequestDetail, |
|
|
|
toLocation.LocationGroupCode).ConfigureAwait(false); |
|
|
|
if (!jobDetails.Any()) |
|
|
|
var queue = new Queue<BalanceDTO>(recommendbalanceDtos); |
|
|
|
while (queue.TryDequeue(out var balanceDto)) |
|
|
|
{ |
|
|
|
continue; |
|
|
|
} |
|
|
|
var next = false; |
|
|
|
|
|
|
|
var fromLocationCode = jobDetails[0].RecommendFromLocationCode; |
|
|
|
var fromLocation = await _locationAppService.GetByCodeAsync(fromLocationCode).ConfigureAwait(false); |
|
|
|
var job = jobs.FirstOrDefault(p => p.WorkGroupCode == fromLocation?.WorkGroupCode); |
|
|
|
if (job == null || job.Details.Any(p => p.RecommendToLocationCode != coatingMaterialRequestDetail.ToLocationCode)) |
|
|
|
{ |
|
|
|
job = await BuildCoatingIssueJobCreateInputWithQtyTypeAsync(coatingMaterialRequest, fromLocation) |
|
|
|
.ConfigureAwait(false); |
|
|
|
jobs.Add(job); |
|
|
|
} |
|
|
|
var temp = tempDetailDtos.ToList(); |
|
|
|
|
|
|
|
job.Details.AddRange(jobDetails); |
|
|
|
if (coatingMaterialRequestDetail.ToBeIssuedQty < 0) |
|
|
|
{ |
|
|
|
coatingMaterialRequestDetail.Status = EnumStatus.Close; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
jobs = jobs.Where(p => p.Details.Any()).ToList(); |
|
|
|
foreach (var tempDetailDto in tempDetailDtos) |
|
|
|
{ |
|
|
|
//未发送的数量
|
|
|
|
tempDetailDto.Qty = tempDetailDto.Qty - tempDetailDto.IssuedQty; |
|
|
|
|
|
|
|
if (tempDetailDto.Qty > balanceDto.Qty) //需求量大于 这条推荐库存的余额
|
|
|
|
{ |
|
|
|
tempDetailDto.Qty -= balanceDto.Qty; |
|
|
|
} |
|
|
|
else if (tempDetailDto.Qty <= balanceDto.Qty) |
|
|
|
{ |
|
|
|
temp.Remove(tempDetailDto); |
|
|
|
balanceDto.Qty = tempDetailDto.Qty; |
|
|
|
} |
|
|
|
|
|
|
|
coatingIssueJobDetailInputs.Add( |
|
|
|
await BuildCoatingIssueJobDetailWithQtyTypeAsync(tempDetailDto, balanceDto) |
|
|
|
.ConfigureAwait(false)); |
|
|
|
useBalanceList.Add(balanceDto); |
|
|
|
|
|
|
|
if (balanceDto.Qty <= 0) |
|
|
|
{ |
|
|
|
next = true; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
var openRequestDetails = |
|
|
|
coatingMaterialRequest.Details.Where(p => p.Status != EnumStatus.Close).ToList(); |
|
|
|
tempDetailDtos = temp; |
|
|
|
|
|
|
|
if (!openRequestDetails.Any()) |
|
|
|
{ |
|
|
|
return jobs; |
|
|
|
if (next) |
|
|
|
{ |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var enableMultipleCreateCoatingIssueJob = await SettingManager |
|
|
|
.IsTrueAsync(StoreSettings.MaterialRequest.EnableMultipleCreateIssueJob).ConfigureAwait(false); |
|
|
|
if (enableMultipleCreateCoatingIssueJob) |
|
|
|
if (coatingIssueJobDetailInputs.Any()) |
|
|
|
{ |
|
|
|
//coatingMaterialRequest.Partial();
|
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
var sb = new StringBuilder(); |
|
|
|
foreach (var openRequestDetail in openRequestDetails) |
|
|
|
{ |
|
|
|
sb.AppendLine( |
|
|
|
$"{openRequestDetail.ItemCode}请求数量 {openRequestDetail.Qty},可用库存数量 {openRequestDetail.IssuedQty}"); |
|
|
|
} |
|
|
|
|
|
|
|
throw new UserFriendlyException($"{sb} 可用库存数量不足, 无法生成发料任务"); |
|
|
|
var coatingIssueJobEditInput = new CoatingIssueJobEditInput(); |
|
|
|
coatingIssueJobEditInput = await BuildCoatingIssueJobCreateInputWithQtyTypeAsync(coatingIssueRequest, |
|
|
|
coatingIssueRequestDetails.First()).ConfigureAwait(false); |
|
|
|
coatingIssueJobEditInput.Details = coatingIssueJobDetailInputs; |
|
|
|
jobs.Add(coatingIssueJobEditInput); |
|
|
|
} |
|
|
|
|
|
|
|
return jobs; |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 构造注塑任务
|
|
|
|
/// 构造注塑任务-按数量
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="coatingMaterialRequest"></param>
|
|
|
|
/// <param name="fromLocation"></param>
|
|
|
|
/// <param name="coatingIssueRequest"></param>
|
|
|
|
/// <param name="requestDetailInput"></param>
|
|
|
|
/// <returns></returns>
|
|
|
|
private async Task<CoatingIssueJobEditInput> BuildCoatingIssueJobCreateInputWithQtyTypeAsync( |
|
|
|
CoatingIssueRequest coatingMaterialRequest, |
|
|
|
LocationDTO fromLocation) |
|
|
|
CoatingIssueRequest coatingIssueRequest, CoatingIssueRequestDetail requestDetailInput) |
|
|
|
{ |
|
|
|
CoatingIssueJobEditInput job; |
|
|
|
job = ObjectMapper.Map<CoatingIssueRequest, CoatingIssueJobEditInput>(coatingMaterialRequest); |
|
|
|
var job = ObjectMapper.Map<CoatingIssueRequest, CoatingIssueJobEditInput>(coatingIssueRequest); |
|
|
|
job.JobType = EnumJobType.IssueJob; |
|
|
|
job.JobStatus = EnumJobStatus.Open; |
|
|
|
job.WorkGroupCode = fromLocation.WorkGroupCode; |
|
|
|
job.WarehouseCode = fromLocation.WarehouseCode; |
|
|
|
job.Worker = coatingMaterialRequest.Worker; |
|
|
|
if (string.IsNullOrEmpty(job.Worker)) |
|
|
|
{ |
|
|
|
job.Worker = "admin"; |
|
|
|
} |
|
|
|
|
|
|
|
job.MaterialRequestNumber = coatingMaterialRequest.Number; |
|
|
|
job.WorkGroupCode = requestDetailInput.ToLocationGroup; |
|
|
|
job.WarehouseCode = requestDetailInput.ToWarehouseCode; |
|
|
|
job.Worker = coatingIssueRequest.Worker; |
|
|
|
job.KittingRequestNumber = coatingIssueRequest.Number; |
|
|
|
job.EnumIssueSendType = EnumIssueSendType.QtyType; |
|
|
|
|
|
|
|
await Task.CompletedTask.ConfigureAwait(false); |
|
|
|
|
|
|
|
return job; |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 创建注塑任务明细
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="coatingMaterialRequest"></param>
|
|
|
|
/// <param name="coatingMaterialRequestDetail"></param>
|
|
|
|
/// <param name="toLocationGroupCode"></param>
|
|
|
|
/// <returns></returns>
|
|
|
|
/// <exception cref="UserFriendlyException"></exception>
|
|
|
|
private async Task<List<CoatingIssueJobDetailInput>> CreateCoatingIssueJobDetailInputsWithQtyTypeAsync( |
|
|
|
CoatingIssueRequest coatingMaterialRequest, |
|
|
|
CoatingIssueRequestDetail coatingMaterialRequestDetail, string toLocationGroupCode) |
|
|
|
{ |
|
|
|
var jobDetails = new List<CoatingIssueJobDetailInput>(); |
|
|
|
|
|
|
|
//获取推荐库存
|
|
|
|
var productionLineDto = await _productionLineAppService |
|
|
|
.GetByLocationCodeAsync(coatingMaterialRequestDetail.ToLocationCode).ConfigureAwait(false); |
|
|
|
var productionLineItemDtos = await _productionLineItemAppService |
|
|
|
.GetByProductLineCodeAsync(productionLineDto.Code).ConfigureAwait(false); |
|
|
|
if (productionLineItemDtos == null) |
|
|
|
{ |
|
|
|
throw new UserFriendlyException($"物品代码【{coatingMaterialRequestDetail.ItemCode}】没有对应的【生产线物品关系】"); |
|
|
|
} |
|
|
|
|
|
|
|
var productionLineItemDto = |
|
|
|
productionLineItemDtos.FirstOrDefault(p => p.ItemCode == coatingMaterialRequestDetail.ItemCode); |
|
|
|
var input = new RecommendBalanceRequestInput |
|
|
|
{ |
|
|
|
ItemCode = coatingMaterialRequestDetail.ItemCode, |
|
|
|
Qty = coatingMaterialRequestDetail.ToBeIssuedQty, |
|
|
|
//LocationTypes = transactionType.OutLocationTypes, productionLineItemDto.RawLocationCodeListJson
|
|
|
|
Statuses = new EditableList<EnumInventoryStatus> { EnumInventoryStatus.OK }, |
|
|
|
Locations = JsonSerializer.Deserialize<List<string>>(productionLineItemDto.RawLocationCodeListJson) |
|
|
|
}; |
|
|
|
|
|
|
|
var recommendList = await _balanceAppService.GetRecommendBalancesByLocationsAsync(input).ConfigureAwait(false); |
|
|
|
//没有推荐库存时 跳过此明细 不生成任务
|
|
|
|
if (recommendList.Count != 0) |
|
|
|
{ |
|
|
|
foreach (var recommend in recommendList) |
|
|
|
{ |
|
|
|
//拿走需求量
|
|
|
|
var detail = |
|
|
|
await BuildCoatingIssueJobDetailWithQtyTypeAsync(coatingMaterialRequestDetail, recommend, |
|
|
|
toLocationGroupCode) |
|
|
|
.ConfigureAwait(false); |
|
|
|
if (coatingMaterialRequest.UseOnTheWayLocation) |
|
|
|
{ |
|
|
|
//获取在途库
|
|
|
|
var locationDto = await _locationAppService.GetFirstByTypeAsync(EnumLocationType.TRANSPORT) |
|
|
|
.ConfigureAwait(false); |
|
|
|
|
|
|
|
detail.OnTheWayLocationCode = locationDto.Code; |
|
|
|
} |
|
|
|
|
|
|
|
jobDetails.Add(detail); |
|
|
|
coatingMaterialRequestDetail.IssuedQty += recommend.Qty; |
|
|
|
|
|
|
|
//await _coatingMaterialRequestManager.UpdateDetailsAsync(coatingMaterialRequest).ConfigureAwait(false);
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return jobDetails; |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 构造注塑任务明细
|
|
|
|
/// 构造注塑任务明细-按数量
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="coatingMaterialRequestDetail"></param>
|
|
|
|
/// <param name="coatingIssueRequestDetail"></param>
|
|
|
|
/// <param name="balance"></param>
|
|
|
|
/// <param name="toLocationGroupCode"></param>
|
|
|
|
/// <returns></returns>
|
|
|
|
private async Task<CoatingIssueJobDetailInput> BuildCoatingIssueJobDetailWithQtyTypeAsync( |
|
|
|
CoatingIssueRequestDetail coatingMaterialRequestDetail, BalanceDTO balance, string toLocationGroupCode) |
|
|
|
CoatingIssueRequestDetailDTO coatingIssueRequestDetail, BalanceDTO balance) |
|
|
|
{ |
|
|
|
//ProductionLineDTO prodLine = await _productionLineAppService.GetByLocationGroupCodeAsync(toLocationGroupCode).ConfigureAwait(false);
|
|
|
|
|
|
|
|
var detail = ObjectMapper.Map<BalanceDTO, CoatingIssueJobDetailInput>(balance); |
|
|
|
detail.RequestLocationCode = coatingMaterialRequestDetail.ToLocationCode; |
|
|
|
detail.PositionCode = coatingMaterialRequestDetail.PositionCode; |
|
|
|
detail.RecommendType = coatingMaterialRequestDetail.RecommendType; |
|
|
|
var detail = new CoatingIssueJobDetailInput(); |
|
|
|
detail.RequestLocationCode = coatingIssueRequestDetail.ToLocationCode; |
|
|
|
detail.PositionCode = coatingIssueRequestDetail.PositionCode; |
|
|
|
detail.RecommendType = coatingIssueRequestDetail.RecommendType; |
|
|
|
detail.Uom = balance.Uom; |
|
|
|
detail.ItemCode = balance.ItemCode; |
|
|
|
detail.ItemDesc2 = balance.ItemDesc2; |
|
|
|
detail.ItemDesc1 = balance.ItemDesc1; |
|
|
|
detail.ItemName = balance.ItemName; |
|
|
|
detail.ProdLine = coatingIssueRequestDetail.ProdLine; |
|
|
|
detail.RequestQty = balance.Qty; |
|
|
|
detail.StdPackQty = coatingIssueRequestDetail.StdPackQty; |
|
|
|
detail.Status = balance.Status; |
|
|
|
|
|
|
|
detail.RequestLocationErpCode = coatingIssueRequestDetail.ToLocationErpCode; |
|
|
|
detail.RequestLocationArea = coatingIssueRequestDetail.ToLocationArea; |
|
|
|
detail.RequestWarehouseCode = coatingIssueRequestDetail.ToWarehouseCode; |
|
|
|
detail.RequestLocationGroup = coatingIssueRequestDetail.ToLocationGroup; |
|
|
|
detail.RequestLocationCode = coatingIssueRequestDetail.ToLocationCode; |
|
|
|
|
|
|
|
detail.RecommendFromPackingCode = balance.PackingCode; |
|
|
|
detail.RecommendFromContainerCode = balance.ContainerCode; |
|
|
@ -315,21 +249,69 @@ public class CoatingIssueRequestEventHandler |
|
|
|
detail.RecommendFromLot = balance.Lot; |
|
|
|
detail.RecommendFromProduceDate = balance.ProduceDate; |
|
|
|
detail.RecommendFromArriveDate = balance.ArriveDate; |
|
|
|
detail.RecommendFromQty = balance.Qty; |
|
|
|
detail.RecommendFromContainerCode = balance.ContainerCode; |
|
|
|
detail.RecommendFromPackingCode = balance.PackingCode; |
|
|
|
|
|
|
|
detail.RecommendToPackingCode = balance.PackingCode; |
|
|
|
detail.RecommendToContainerCode = balance.ContainerCode; |
|
|
|
detail.RecommendToSupplierBatch = balance.SupplierBatch; |
|
|
|
detail.RecommendToProduceDate = balance.ProduceDate; |
|
|
|
detail.RecommendToExpireDate = balance.ExpireDate; |
|
|
|
detail.RecommendToLot = balance.Lot; |
|
|
|
detail.RecommendToProduceDate = balance.ProduceDate; |
|
|
|
detail.RecommendToArriveDate = balance.ArriveDate; |
|
|
|
detail.RecommendToQty = balance.Qty; |
|
|
|
detail.RecommendToContainerCode = balance.ContainerCode; |
|
|
|
detail.RecommendToPackingCode = balance.PackingCode; |
|
|
|
|
|
|
|
detail.RecommendFromLocationArea = balance.LocationArea; |
|
|
|
detail.RecommendFromLocationCode = balance.LocationCode; |
|
|
|
detail.RecommendFromLocationErpCode = balance.LocationErpCode; |
|
|
|
detail.RecommendFromLocationGroup = balance.LocationGroup; |
|
|
|
detail.RecommendFromWarehouseCode = balance.WarehouseCode; |
|
|
|
detail.RecommendFromQty = balance.Qty; |
|
|
|
detail.Uom = balance.Uom; |
|
|
|
|
|
|
|
detail.RecommendToLocationCode = coatingMaterialRequestDetail.ToLocationCode; |
|
|
|
detail.RecommendToLocationErpCode = coatingMaterialRequestDetail.ToLocationErpCode; |
|
|
|
detail.RecommendToLocationArea = coatingMaterialRequestDetail.ToLocationArea; |
|
|
|
detail.RecommendToWarehouseCode = coatingMaterialRequestDetail.ToWarehouseCode; |
|
|
|
detail.RecommendToLocationCode = coatingIssueRequestDetail.ToLocationCode; |
|
|
|
detail.RecommendToLocationErpCode = coatingIssueRequestDetail.ToLocationErpCode; |
|
|
|
detail.RecommendToLocationArea = coatingIssueRequestDetail.ToLocationArea; |
|
|
|
detail.RecommendToWarehouseCode = coatingIssueRequestDetail.ToWarehouseCode; |
|
|
|
detail.RecommendToLocationGroup = coatingIssueRequestDetail.ToLocationGroup; |
|
|
|
|
|
|
|
detail.TransferLibFromPackingCode = balance.PackingCode; |
|
|
|
detail.TransferLibFromContainerCode = balance.ContainerCode; |
|
|
|
detail.TransferLibFromSupplierBatch = balance.SupplierBatch; |
|
|
|
detail.TransferLibFromProduceDate = balance.ProduceDate; |
|
|
|
detail.TransferLibFromExpireDate = balance.ExpireDate; |
|
|
|
detail.TransferLibFromLot = balance.Lot; |
|
|
|
detail.TransferLibFromProduceDate = balance.ProduceDate; |
|
|
|
detail.TransferLibFromArriveDate = balance.ArriveDate; |
|
|
|
detail.TransferLibFromQty = balance.Qty; |
|
|
|
detail.TransferLibFromContainerCode = balance.ContainerCode; |
|
|
|
detail.TransferLibFromPackingCode = balance.PackingCode; |
|
|
|
|
|
|
|
detail.TransferLibToPackingCode = balance.PackingCode; |
|
|
|
detail.TransferLibToContainerCode = balance.ContainerCode; |
|
|
|
detail.TransferLibToSupplierBatch = balance.SupplierBatch; |
|
|
|
detail.TransferLibToProduceDate = balance.ProduceDate; |
|
|
|
detail.TransferLibToExpireDate = balance.ExpireDate; |
|
|
|
detail.TransferLibToLot = balance.Lot; |
|
|
|
detail.TransferLibToProduceDate = balance.ProduceDate; |
|
|
|
detail.TransferLibToArriveDate = balance.ArriveDate; |
|
|
|
detail.TransferLibToQty = balance.Qty; |
|
|
|
detail.TransferLibToPackingCode = balance.PackingCode; |
|
|
|
|
|
|
|
detail.TransferLibFromLocationArea = balance.LocationArea; |
|
|
|
detail.TransferLibFromLocationCode = balance.LocationCode; |
|
|
|
detail.TransferLibFromLocationErpCode = balance.LocationErpCode; |
|
|
|
detail.TransferLibFromLocationGroup = balance.LocationGroup; |
|
|
|
detail.TransferLibFromWarehouseCode = balance.WarehouseCode; |
|
|
|
|
|
|
|
detail.TransferLibToLocationCode = coatingIssueRequestDetail.ToLocationCode; |
|
|
|
detail.TransferLibToLocationErpCode = coatingIssueRequestDetail.ToLocationErpCode; |
|
|
|
detail.TransferLibToLocationArea = coatingIssueRequestDetail.ToLocationArea; |
|
|
|
detail.TransferLibToWarehouseCode = coatingIssueRequestDetail.ToWarehouseCode; |
|
|
|
detail.TransferLibToLocationGroup = coatingIssueRequestDetail.ToLocationGroup; |
|
|
|
|
|
|
|
//detail.ProdLine = prodLine == null ? toLocationGroupCode : prodLine.Code;
|
|
|
|
detail.ProdLine = toLocationGroupCode; |
|
|
|
await Task.CompletedTask.ConfigureAwait(false); |
|
|
|
return detail; |
|
|
|
} |
|
|
@ -339,72 +321,71 @@ public class CoatingIssueRequestEventHandler |
|
|
|
#region 按箱叫料
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 创建注塑任务
|
|
|
|
/// 创建注塑任务 按箱叫料-按箱
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="coatingMaterialRequest"></param>
|
|
|
|
/// <param name="coatingIssueRequest"></param>
|
|
|
|
/// <param name="coatingIssueRequestDetailList"></param>
|
|
|
|
/// <param name="recommendbalanceDtos"></param>
|
|
|
|
/// <param name="useBalanceList"></param>
|
|
|
|
/// <returns></returns>
|
|
|
|
/// <exception cref="UserFriendlyException"></exception>
|
|
|
|
private async Task<List<CoatingIssueJobEditInput>> CreateCoatingIssueJobWithBoxQtyTypeAsync |
|
|
|
(CoatingIssueRequest coatingMaterialRequest) |
|
|
|
( |
|
|
|
CoatingIssueRequest coatingIssueRequest, |
|
|
|
List<CoatingIssueRequestDetail> coatingIssueRequestDetailList, |
|
|
|
List<SortBalance> recommendbalanceDtos, |
|
|
|
List<BalanceDTO> useBalanceList) |
|
|
|
{ |
|
|
|
var inputJobs = new List<CoatingIssueJobEditInput>(); |
|
|
|
var inputExpectOutEditInput = new ExpectOutEditInput(); |
|
|
|
//已用的库存的箱码集合
|
|
|
|
var useBalanceList = new List<string>(); |
|
|
|
|
|
|
|
var groupByItemCodeAndLocationCode = |
|
|
|
coatingMaterialRequest.Details.GroupBy(p => new { p.ItemCode, p.ToLocationCode }); |
|
|
|
//已用的库存的集合
|
|
|
|
useBalanceList = useBalanceList; |
|
|
|
|
|
|
|
foreach (var locationCodeItemCodeGroup in groupByItemCodeAndLocationCode) |
|
|
|
foreach (var detail in coatingIssueRequestDetailList) |
|
|
|
{ |
|
|
|
var inputDetails = coatingMaterialRequest.Details.Where(p => |
|
|
|
p.ItemCode == locationCodeItemCodeGroup.Key.ItemCode && |
|
|
|
p.ToLocationCode == locationCodeItemCodeGroup.Key.ToLocationCode); |
|
|
|
var inputDetailTemplate = inputDetails.First(); |
|
|
|
//当前零件的集合
|
|
|
|
var inputDetails = coatingIssueRequestDetailList; |
|
|
|
//获取请求下 这个零件和这个库位一个需要多少箱
|
|
|
|
var sumBoxQty = inputDetails.Sum(p => p.BoxQty); |
|
|
|
var sumBoxQty = inputDetails.Sum(p => p.BoxQty - p.IssuedQty); |
|
|
|
//获取生产线
|
|
|
|
var productionLineDto = await _productionLineAppService |
|
|
|
.GetByLocationCodeAsync(inputDetails.First().ToLocationCode).ConfigureAwait(false); |
|
|
|
if (productionLineDto == null) |
|
|
|
{ |
|
|
|
throw new UserFriendlyException($"库位【{inputDetailTemplate.ToLocationCode}】没有对应的【生产线】"); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var productLineCodeAndItemCode = await _productionLineItemAppService |
|
|
|
.GetByProductLineCodeAndItemCodeAsync(productionLineDto.Code, inputDetailTemplate.ItemCode) |
|
|
|
.GetByProductLineCodeAndItemCodeAsync(productionLineDto.Code, detail.ItemCode) |
|
|
|
.ConfigureAwait(false); |
|
|
|
if (productLineCodeAndItemCode == null) |
|
|
|
{ |
|
|
|
throw new UserFriendlyException( |
|
|
|
$"物品代码【{inputDetailTemplate.ItemCode}】在生产线【{productionLineDto.Code}】中没有对应的【生产线物品关系】"); |
|
|
|
$"物品代码【{detail.ItemCode}】在生产线【{productionLineDto.Code}】中没有对应的【生产线物品关系】"); |
|
|
|
} |
|
|
|
|
|
|
|
//获取可用库存
|
|
|
|
var input = new RecommendBalanceRequestInput |
|
|
|
{ |
|
|
|
ItemCode = locationCodeItemCodeGroup.Key.ItemCode, |
|
|
|
Qty = decimal.MaxValue, |
|
|
|
Statuses = new EditableList<EnumInventoryStatus> { EnumInventoryStatus.OK }, |
|
|
|
Locations = JsonSerializer.Deserialize<List<string>>(productLineCodeAndItemCode |
|
|
|
.RawLocationCodeListJson) |
|
|
|
}; |
|
|
|
var usableList = await _balanceAppService.GetUsableListAsync(input).ConfigureAwait(false); |
|
|
|
usableList = usableList.Where(p => !useBalanceList.Contains(p.PackingCode)).ToList(); |
|
|
|
//可用库存
|
|
|
|
var usableList = recommendbalanceDtos; |
|
|
|
usableList = usableList.Where(p => !useBalanceList.Select(p => p.PackingCode).Contains(p.PackingCode)) |
|
|
|
.ToList(); |
|
|
|
if (usableList.Any()) |
|
|
|
{ |
|
|
|
for (var i = 0; i < sumBoxQty; i++) |
|
|
|
{ |
|
|
|
var firstUsable = usableList.First(); |
|
|
|
useBalanceList.Add(firstUsable.PackingCode); |
|
|
|
usableList.Remove(firstUsable); |
|
|
|
|
|
|
|
var coatingIssueJobEditInput = |
|
|
|
await BuildCoatingIssueJobCreateInputWithBoxQtyTypeAsync(coatingMaterialRequest, inputDetailTemplate, |
|
|
|
firstUsable) |
|
|
|
.ConfigureAwait(false); |
|
|
|
|
|
|
|
inputJobs.Add(coatingIssueJobEditInput); |
|
|
|
if (usableList.Any()) |
|
|
|
{ |
|
|
|
var firstUsable = usableList.First(); |
|
|
|
useBalanceList.Add((BalanceDTO)firstUsable); |
|
|
|
usableList.Remove(firstUsable); |
|
|
|
|
|
|
|
var coatingIssueJobEditInput = |
|
|
|
await BuildCoatingIssueJobCreateInputWithBoxQtyTypeAsync(coatingIssueRequest, |
|
|
|
detail, firstUsable) |
|
|
|
.ConfigureAwait(false); |
|
|
|
|
|
|
|
inputJobs.Add(coatingIssueJobEditInput); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -413,25 +394,26 @@ public class CoatingIssueRequestEventHandler |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 构造注塑任务
|
|
|
|
/// 构造注塑任务-按箱
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="coatingMaterialRequest"></param>
|
|
|
|
/// <param name="coatingMaterialRequestDetail"></param>
|
|
|
|
/// <param name="coatingIssueRequest"></param>
|
|
|
|
/// <param name="coatingIssueRequestDetail"></param>
|
|
|
|
/// <param name="balanceDtos"></param>
|
|
|
|
/// <returns></returns>
|
|
|
|
private async Task<CoatingIssueJobEditInput> BuildCoatingIssueJobCreateInputWithBoxQtyTypeAsync( |
|
|
|
CoatingIssueRequest coatingMaterialRequest, |
|
|
|
CoatingIssueRequestDetail coatingMaterialRequestDetail, BalanceDTO balanceDtos) |
|
|
|
CoatingIssueRequest coatingIssueRequest, |
|
|
|
CoatingIssueRequestDetail coatingIssueRequestDetail, BalanceDTO balanceDtos) |
|
|
|
{ |
|
|
|
var job = ObjectMapper.Map<CoatingIssueRequest, CoatingIssueJobEditInput>(coatingMaterialRequest); |
|
|
|
var job = ObjectMapper.Map<CoatingIssueRequest, CoatingIssueJobEditInput>(coatingIssueRequest); |
|
|
|
job.JobType = EnumJobType.IssueJob; |
|
|
|
job.JobStatus = EnumJobStatus.Open; |
|
|
|
job.WorkGroupCode = coatingMaterialRequestDetail.ToLocationGroup; |
|
|
|
job.WarehouseCode = coatingMaterialRequestDetail.ToWarehouseCode; |
|
|
|
job.Worker = coatingMaterialRequest.Worker; |
|
|
|
job.MaterialRequestNumber = coatingMaterialRequest.Number; |
|
|
|
job.WorkGroupCode = coatingIssueRequestDetail.ToLocationGroup; |
|
|
|
job.WarehouseCode = coatingIssueRequestDetail.ToWarehouseCode; |
|
|
|
job.Worker = coatingIssueRequest.Worker; |
|
|
|
job.KittingRequestNumber = coatingIssueRequest.Number; |
|
|
|
job.EnumIssueSendType = EnumIssueSendType.BoxQtyType; |
|
|
|
|
|
|
|
job.Details.Add(await BuildCoatingIssueJobDetailWithBoxQtyTypeAsync(coatingMaterialRequestDetail, balanceDtos) |
|
|
|
job.Details.Add(await BuildCoatingIssueJobDetailWithBoxQtyTypeAsync(coatingIssueRequestDetail, balanceDtos) |
|
|
|
.ConfigureAwait(false)); |
|
|
|
|
|
|
|
await Task.CompletedTask.ConfigureAwait(false); |
|
|
@ -440,30 +422,31 @@ public class CoatingIssueRequestEventHandler |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 构造注塑任务明细
|
|
|
|
/// 构造注塑任务明细-按箱
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="coatingMaterialRequestDetail"></param>
|
|
|
|
/// <param name="coatingIssueRequestDetail"></param>
|
|
|
|
/// <param name="balance"></param>
|
|
|
|
/// <param name="toLocationGroupCode"></param>
|
|
|
|
/// <returns></returns>
|
|
|
|
private async Task<CoatingIssueJobDetailInput> BuildCoatingIssueJobDetailWithBoxQtyTypeAsync( |
|
|
|
CoatingIssueRequestDetail coatingMaterialRequestDetail, BalanceDTO balance) |
|
|
|
CoatingIssueRequestDetail coatingIssueRequestDetail, BalanceDTO balance) |
|
|
|
{ |
|
|
|
var detail = new CoatingIssueJobDetailInput(); |
|
|
|
detail.RequestLocationCode = coatingMaterialRequestDetail.ToLocationCode; |
|
|
|
detail.RequestLocationGroup = coatingMaterialRequestDetail.ToLocationGroup; |
|
|
|
detail.RequestLocationArea = coatingMaterialRequestDetail.ToLocationArea; |
|
|
|
detail.RequestLocationErpCode = coatingMaterialRequestDetail.ToLocationErpCode; |
|
|
|
detail.RequestWarehouseCode = coatingMaterialRequestDetail.ToWarehouseCode; |
|
|
|
|
|
|
|
detail.PositionCode = coatingMaterialRequestDetail.PositionCode; |
|
|
|
detail.RecommendType = coatingMaterialRequestDetail.RecommendType; |
|
|
|
detail.ProdLine = coatingMaterialRequestDetail.ToLocationCode; |
|
|
|
|
|
|
|
detail.ItemCode = coatingMaterialRequestDetail.ItemCode; |
|
|
|
detail.ItemName = coatingMaterialRequestDetail.ItemName; |
|
|
|
detail.ItemDesc1 = coatingMaterialRequestDetail.ItemDesc1; |
|
|
|
detail.ItemDesc2 = coatingMaterialRequestDetail.ItemDesc2; |
|
|
|
detail.RequestLocationCode = coatingIssueRequestDetail.ToLocationCode; |
|
|
|
detail.RequestLocationGroup = coatingIssueRequestDetail.ToLocationGroup; |
|
|
|
detail.RequestLocationArea = coatingIssueRequestDetail.ToLocationArea; |
|
|
|
detail.RequestLocationErpCode = coatingIssueRequestDetail.ToLocationErpCode; |
|
|
|
detail.RequestWarehouseCode = coatingIssueRequestDetail.ToWarehouseCode; |
|
|
|
detail.RequestQty = 1; |
|
|
|
|
|
|
|
detail.PositionCode = coatingIssueRequestDetail.PositionCode; |
|
|
|
detail.RecommendType = coatingIssueRequestDetail.RecommendType; |
|
|
|
detail.ProdLine = coatingIssueRequestDetail.ToLocationCode; |
|
|
|
|
|
|
|
detail.ItemCode = coatingIssueRequestDetail.ItemCode; |
|
|
|
detail.ItemName = coatingIssueRequestDetail.ItemName; |
|
|
|
detail.ItemDesc1 = coatingIssueRequestDetail.ItemDesc1; |
|
|
|
detail.ItemDesc2 = coatingIssueRequestDetail.ItemDesc2; |
|
|
|
|
|
|
|
detail.Status = EnumInventoryStatus.OK; |
|
|
|
detail.Uom = balance.Uom; |
|
|
@ -498,11 +481,11 @@ public class CoatingIssueRequestEventHandler |
|
|
|
detail.RecommendToProduceDate = balance.ProduceDate; |
|
|
|
detail.RecommendToArriveDate = balance.ArriveDate; |
|
|
|
|
|
|
|
detail.RecommendToLocationCode = coatingMaterialRequestDetail.ToLocationCode; |
|
|
|
detail.RecommendToLocationErpCode = coatingMaterialRequestDetail.ToLocationErpCode; |
|
|
|
detail.RecommendToLocationArea = coatingMaterialRequestDetail.ToLocationArea; |
|
|
|
detail.RecommendToWarehouseCode = coatingMaterialRequestDetail.ToWarehouseCode; |
|
|
|
detail.RecommendToLocationGroup = coatingMaterialRequestDetail.ToLocationGroup; |
|
|
|
detail.RecommendToLocationCode = coatingIssueRequestDetail.ToLocationCode; |
|
|
|
detail.RecommendToLocationErpCode = coatingIssueRequestDetail.ToLocationErpCode; |
|
|
|
detail.RecommendToLocationArea = coatingIssueRequestDetail.ToLocationArea; |
|
|
|
detail.RecommendToWarehouseCode = coatingIssueRequestDetail.ToWarehouseCode; |
|
|
|
detail.RecommendToLocationGroup = coatingIssueRequestDetail.ToLocationGroup; |
|
|
|
|
|
|
|
await Task.CompletedTask.ConfigureAwait(false); |
|
|
|
return detail; |
|
|
@ -511,4 +494,210 @@ public class CoatingIssueRequestEventHandler |
|
|
|
#endregion
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
//创建任务
|
|
|
|
private async Task<List<CoatingIssueJobDTO>> CreateAllCoatingIssueJobAsync( |
|
|
|
CoatingIssueRequest coatingIssueRequest) |
|
|
|
{ |
|
|
|
var coatingIssueJobEditInputs = new List<CoatingIssueJobEditInput>(); |
|
|
|
|
|
|
|
//已用的库存的集合
|
|
|
|
var useBalanceList = new List<BalanceDTO>(); |
|
|
|
|
|
|
|
foreach (var groupbyItemCodeAndProdLine in coatingIssueRequest.Details.GroupBy(p => |
|
|
|
new { p.ItemCode })) |
|
|
|
{ |
|
|
|
foreach (var coatingIssueRequestDetail in groupbyItemCodeAndProdLine) |
|
|
|
{ |
|
|
|
var productionLineItemDto = await _productionLineItemAppService.GetByProductLineCodeAndItemCodeAsync( |
|
|
|
coatingIssueRequestDetail.ProdLine, |
|
|
|
groupbyItemCodeAndProdLine.Key.ItemCode).ConfigureAwait(false); |
|
|
|
|
|
|
|
if (productionLineItemDto == null) |
|
|
|
{ |
|
|
|
throw new UserFriendlyException( |
|
|
|
$"未在生产线【{coatingIssueRequestDetail.ProdLine}】物品【{groupbyItemCodeAndProdLine.Key.ItemCode}】的关系,请查看【生产线物品关系】"); |
|
|
|
} |
|
|
|
|
|
|
|
//原料
|
|
|
|
if (!string.IsNullOrEmpty(productionLineItemDto.RawLocationCodeListJson)) //因为一个零件 要不是原料 要不是半成品
|
|
|
|
{ |
|
|
|
var usableLocationCode = |
|
|
|
JsonSerializer.Deserialize<List<string>>(productionLineItemDto.RawLocationCodeListJson); |
|
|
|
if (usableLocationCode.Any()) |
|
|
|
{ |
|
|
|
//获取可用库存
|
|
|
|
var input = new RecommendBalanceRequestInput |
|
|
|
{ |
|
|
|
ItemCode = coatingIssueRequestDetail.ItemCode, |
|
|
|
Qty = decimal.MaxValue, |
|
|
|
Statuses = new EditableList<EnumInventoryStatus> { EnumInventoryStatus.OK }, |
|
|
|
Locations = |
|
|
|
JsonSerializer.Deserialize<List<string>>(productionLineItemDto.RawLocationCodeListJson), |
|
|
|
IsPackingCode = true |
|
|
|
}; |
|
|
|
var usableList = await _balanceAppService.GetUsableListAsync(input).ConfigureAwait(false); |
|
|
|
var sortByFifoAsync = await SortByFifoAsync(usableList).ConfigureAwait(false); |
|
|
|
|
|
|
|
//因为是按箱叫料 先把值赋值给箱数量上
|
|
|
|
coatingIssueRequestDetail.BoxQty = coatingIssueRequestDetail.Qty; |
|
|
|
|
|
|
|
if (usableList.Any()) |
|
|
|
{ |
|
|
|
//因为是原料所以按箱叫料
|
|
|
|
coatingIssueJobEditInputs.AddRange( |
|
|
|
await CreateCoatingIssueJobWithBoxQtyTypeAsync(coatingIssueRequest, |
|
|
|
new EditableList<CoatingIssueRequestDetail> { coatingIssueRequestDetail }, |
|
|
|
sortByFifoAsync, |
|
|
|
useBalanceList).ConfigureAwait(false)); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
//半成品
|
|
|
|
if (!string.IsNullOrEmpty(productionLineItemDto.ProductLocationCodeListJson)) //因为一个零件 要不是原料 要不是半成品
|
|
|
|
{ |
|
|
|
var usableLocationCode = |
|
|
|
JsonSerializer.Deserialize<List<string>>(productionLineItemDto.ProductLocationCodeListJson); |
|
|
|
if (usableLocationCode.Any()) |
|
|
|
{ |
|
|
|
//获取可用库存
|
|
|
|
var input = new RecommendBalanceRequestInput |
|
|
|
{ |
|
|
|
ItemCode = groupbyItemCodeAndProdLine.Key.ItemCode, |
|
|
|
Qty = coatingIssueRequestDetail.Qty, |
|
|
|
Statuses = new EditableList<EnumInventoryStatus> { EnumInventoryStatus.OK }, |
|
|
|
Locations = |
|
|
|
JsonSerializer.Deserialize<List<string>>(productionLineItemDto |
|
|
|
.ProductLocationCodeListJson), |
|
|
|
IsPackingCode = false |
|
|
|
}; |
|
|
|
var usableList = await _balanceAppService.GetUsableListAsync(input).ConfigureAwait(false); |
|
|
|
var temp = usableList.ToList(); |
|
|
|
|
|
|
|
foreach (var balanceDto in usableList) //计算已经用过的库存
|
|
|
|
{ |
|
|
|
var useBalanceDto = useBalanceList.Where(p => |
|
|
|
p.ItemCode == balanceDto.ItemCode && p.LocationCode == balanceDto.LocationCode && |
|
|
|
p.Lot == balanceDto.Lot && p.Status == balanceDto.Status && |
|
|
|
p.PackingCode == balanceDto.PackingCode); |
|
|
|
if (useBalanceDto.Any()) //如果不为NULL,就是用过了的库存 需要减去使用量
|
|
|
|
{ |
|
|
|
balanceDto.Qty -= useBalanceDto.Sum(p => p.Qty); |
|
|
|
if (balanceDto.Qty <= 0) |
|
|
|
{ |
|
|
|
temp.Remove(balanceDto); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
usableList = temp; |
|
|
|
|
|
|
|
coatingIssueJobEditInputs.AddRange( |
|
|
|
await CreateCoatingIssueJobWithQtyTypeAsync(coatingIssueRequest, |
|
|
|
new List<CoatingIssueRequestDetail> { coatingIssueRequestDetail }, temp, |
|
|
|
useBalanceList).ConfigureAwait(false)); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (coatingIssueJobEditInputs.Count > 0) //有库存 可以创建任务
|
|
|
|
{ |
|
|
|
//新增任务
|
|
|
|
var addCoatingIssueJobDtos = await _coatingIssueJobAppService.CreateManyAsync(coatingIssueJobEditInputs) |
|
|
|
.ConfigureAwait(false); |
|
|
|
|
|
|
|
await UpdateCoatingIssueRequestDetailQtyAsync(coatingIssueRequest, addCoatingIssueJobDtos) |
|
|
|
.ConfigureAwait(false); |
|
|
|
|
|
|
|
return addCoatingIssueJobDtos; |
|
|
|
} |
|
|
|
|
|
|
|
return new List<CoatingIssueJobDTO>(); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 修改请求的 已发 已收数量
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="coatingIssueRequest"></param>
|
|
|
|
/// <param name="addCoatingIssueJobDtos"></param>
|
|
|
|
/// <returns></returns>
|
|
|
|
private async Task UpdateCoatingIssueRequestDetailQtyAsync(CoatingIssueRequest coatingIssueRequest, |
|
|
|
List<CoatingIssueJobDTO> addCoatingIssueJobDtos) |
|
|
|
{ |
|
|
|
//原有任务
|
|
|
|
var existCoatingIssueJobDtos = await _coatingIssueJobAppService |
|
|
|
.GetByRequestNumberAsync(coatingIssueRequest.Number) |
|
|
|
.ConfigureAwait(false); |
|
|
|
|
|
|
|
//新增的任务和已有的任务总和
|
|
|
|
var allCoatingIssueJobDtos = new List<CoatingIssueJobDTO>(); |
|
|
|
allCoatingIssueJobDtos.AddRange(addCoatingIssueJobDtos); |
|
|
|
allCoatingIssueJobDtos.AddRange(existCoatingIssueJobDtos); |
|
|
|
|
|
|
|
var groupByItemCodeLocationCode = coatingIssueRequest.Details.GroupBy(p => |
|
|
|
new { p.ItemCode, p.ToLocationCode }); |
|
|
|
foreach (var group in groupByItemCodeLocationCode) |
|
|
|
{ |
|
|
|
foreach (var requestDetail in group) |
|
|
|
{ |
|
|
|
//所有已发数量
|
|
|
|
decimal allIssuedQty = 0; |
|
|
|
|
|
|
|
//所有已发数量
|
|
|
|
decimal allReceivedQty = 0; |
|
|
|
|
|
|
|
foreach (var allCoatingIssueJobDto in allCoatingIssueJobDtos) |
|
|
|
{ |
|
|
|
var jobDetailDtos = allCoatingIssueJobDto.Details.Where(p => |
|
|
|
p.ItemCode == group.Key.ItemCode && p.RequestLocationCode == group.Key.ToLocationCode); |
|
|
|
//所有已发数量
|
|
|
|
allIssuedQty += jobDetailDtos.Sum(p => p.RequestQty); |
|
|
|
//所有已发数量
|
|
|
|
allReceivedQty += jobDetailDtos.Sum(p => p.HandledToQty); |
|
|
|
} |
|
|
|
|
|
|
|
requestDetail.IssuedQty += allIssuedQty; |
|
|
|
requestDetail.ReceivedQty += allReceivedQty; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
//await _coatingIssueRequestManager.UpdateAsync(coatingIssueRequest).ConfigureAwait(false);
|
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 排序规则 1.批次正序 2.底层 3.到货日期正序 4.数量倒序(整箱优先) 5.库位正序 6.箱码正序
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="balances"></param>
|
|
|
|
/// <returns></returns>
|
|
|
|
public async Task<List<SortBalance>> SortByFifoAsync(List<BalanceDTO> balances) |
|
|
|
{ |
|
|
|
var sortBalances = new List<SortBalance>(); |
|
|
|
var config = new MapperConfiguration(cfg => |
|
|
|
{ |
|
|
|
cfg.CreateMap<BalanceDTO, SortBalance>() |
|
|
|
.Ignore(x => x.LocationRow); |
|
|
|
}); |
|
|
|
_mapper = new Mapper(config); |
|
|
|
|
|
|
|
var resultBalances = _mapper.Map<List<BalanceDTO>, List<SortBalance>>(balances); |
|
|
|
foreach (var resultBalance in resultBalances) |
|
|
|
{ |
|
|
|
var locationDto = await _locationAppService.GetByCodeAsync(resultBalance.LocationCode).ConfigureAwait(false); |
|
|
|
resultBalance.LocationRow = locationDto.RowCode; |
|
|
|
} |
|
|
|
|
|
|
|
resultBalances |
|
|
|
.OrderBy(p => p.Lot) |
|
|
|
.ThenBy(p => p.LocationRow) |
|
|
|
.ThenBy(p => p.PutInTime) |
|
|
|
.ThenBy(p => p.Qty)//2023-9-14 苑静雯 从小数开始发料
|
|
|
|
.ThenBy(p => p.LocationCode) |
|
|
|
.ThenBy(p => p.PackingCode) |
|
|
|
.ToList(); |
|
|
|
|
|
|
|
return resultBalances; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|