154 lines
6.7 KiB
C#
154 lines
6.7 KiB
C#
using JSMachine.WMS.App.Dto;
|
|
using JSMachine.WMS.App.Dto.Enum;
|
|
using JSMachine.WMS.App.ServiceImpl;
|
|
using JSMachine.WMS.Infrastructure.Helper;
|
|
using NPOI.OpenXmlFormats.Dml;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace JSMachine.WMS.Business.StockIn.ServiceImpl.ResponsibilityChain
|
|
{
|
|
/// <summary>
|
|
/// 放置在已有相同批次的列上
|
|
/// </summary>
|
|
public class StockInByExist : StockInHandler
|
|
{
|
|
public override async Task<StorageRackDto> CalculateWarehouse(
|
|
TransportEnum startArea,
|
|
FloorEnum floor,
|
|
string materialBatch,
|
|
List<StorageRackDto> storageRacks
|
|
)
|
|
{
|
|
//1.查找有没有同批次待执行的任务
|
|
//2.有待执行的任务,直接进入中转区域
|
|
//3.没有待执行的任务,则采用现有逻辑获取一个同批次库位
|
|
|
|
//非中转区的任务,需要先判断是否有同批次未完成的任务,如有则需要等待,确保同批次的货物放满同一列
|
|
|
|
await _SemaphoreSlim.WaitAsync();
|
|
StorageRackDto destStorageRack = null;
|
|
|
|
try
|
|
{
|
|
storageRacks = await base.GetStorageRackExceptStockout(floor);
|
|
|
|
if (storageRacks.IsNullOrEmpty())
|
|
{
|
|
LogHelper.Info("没有可用库位");
|
|
return null;
|
|
}
|
|
|
|
List<AGVTaskDto> uncompletedTasks = await _agvTaskService.GetListByExpression(p =>
|
|
p.CreationTime > DateTime.Now.Date &&
|
|
p.MateriaBatch == materialBatch &&
|
|
(p.TaskType == TaskTypeEnum.PdaIn || p.TaskType == TaskTypeEnum.TailIn || p.TaskType == TaskTypeEnum.TransferStockIn) &&
|
|
(p.TaskStatus != TaskStatusEnum.Completed)
|
|
);
|
|
|
|
List<long> sameBatchColIds = storageRacks
|
|
.Where(p =>
|
|
p.MateriaBatch == materialBatch ||
|
|
(!uncompletedTasks.IsNullOrEmpty() && uncompletedTasks.Select(x => x.EndPositionCode).Contains(p.StorageRackNo))
|
|
)
|
|
.Select(p => p.ReservoirAreaColumnId)
|
|
.Distinct()
|
|
.ToList();
|
|
|
|
if (sameBatchColIds.IsNullOrEmpty())
|
|
{
|
|
destStorageRack = await HandleByNext(startArea, floor, materialBatch, storageRacks);
|
|
}
|
|
else
|
|
{
|
|
List<StorageRackDto> sameBatchInclude = storageRacks
|
|
.Where(p => sameBatchColIds.Contains(p.ReservoirAreaColumnId))
|
|
.ToList();
|
|
|
|
var sameBatchIncludeCol = sameBatchInclude.GroupBy(p => p.ReservoirAreaColumnId);
|
|
|
|
// 筛选还有空位的列(包含锁定的列)
|
|
// 有未锁定的列优先取该列
|
|
// 没有未锁定的列,则任取一列做中转(如果物料所处位置已经是中转区,则不执行)
|
|
|
|
var useableStorageCol = sameBatchIncludeCol
|
|
.FirstOrDefault(p =>
|
|
p.All(x => !x.IsLock) &&
|
|
p.Any(x => !x.IsDisabled && string.IsNullOrEmpty(x.BarCode)));
|
|
|
|
if (useableStorageCol != null && useableStorageCol.Any())
|
|
{
|
|
destStorageRack = useableStorageCol
|
|
.Where(p => !p.IsDisabled && string.IsNullOrEmpty(p.BarCode))
|
|
.OrderByDescending(p => p.NumSort)
|
|
.First();
|
|
}
|
|
else
|
|
{
|
|
var emptyCols = sameBatchIncludeCol.Where(p => p.Any(x => !x.IsLock && !x.IsDisabled && string.IsNullOrEmpty(x.BarCode)));
|
|
if (emptyCols.Any())
|
|
{
|
|
//如果仅有一个空列,则可以开一个新列,保证最多只开2列
|
|
if (emptyCols.Count() <= 1)
|
|
{
|
|
destStorageRack = await HandleByNext(startArea, floor, materialBatch, storageRacks);
|
|
}
|
|
else
|
|
{
|
|
//一楼不允许混放或进入中转区。同批次已开启两列后,等待现有任务完成并解锁列。
|
|
if (floor == FloorEnum.FirstFloor)
|
|
{
|
|
LogHelper.Warn("一楼同批次已开启两列且目标列被锁定,入库任务等待列解锁");
|
|
return null;
|
|
}
|
|
|
|
//物料已在中转区,则不可以继续在中转区生成任务
|
|
if (startArea == TransportEnum.TransitArea)
|
|
{
|
|
LogHelper.Warn("目标库位所在列被锁定,中转入库任调度需要等待列解锁");
|
|
return null;
|
|
}
|
|
else
|
|
{
|
|
destStorageRack = await _storageRackService.GetUsableTransferStorageRack();
|
|
|
|
if (destStorageRack == null)
|
|
{
|
|
LogHelper.Warn($"中转区已满,尝试放货到空白列或者和其他货物混放");
|
|
destStorageRack = await HandleByNext(startArea, floor, materialBatch, storageRacks);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
destStorageRack = await HandleByNext(startArea, floor, materialBatch, storageRacks);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (destStorageRack != null)
|
|
{
|
|
// 先完成数据库锁定,确保数据一致性
|
|
await _storageRackService.Lock(destStorageRack);
|
|
}
|
|
|
|
return destStorageRack;
|
|
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
LogHelper.Error($"入库责任链处理异常:{ex.Message} \n {ex.StackTrace}");
|
|
return null;
|
|
}
|
|
finally
|
|
{
|
|
_SemaphoreSlim.Release();
|
|
}
|
|
}
|
|
}
|
|
}
|