using Admin.NET.Application.Entity;
using Microsoft.CodeAnalysis;
namespace Admin.NET.Application
{
///
/// 寻找 空库位的处理类
///
public class FindEmptyPlaceServiceHandle
{
///
/// 是否正在执行方法
///
private static bool isRuning_Fun = false;
private static SemaphoreSlim semaphoreSlim = new SemaphoreSlim(1, 1);
protected readonly SqlSugarRepository _v_empty_placeRep;
protected readonly SqlSugarRepository _wmsPlaceRep;
private readonly SqlSugarRepository _wareTaskRep;
protected List findEmptyPlaceList = null;
///
/// 构造函数
///
///
///
///
public FindEmptyPlaceServiceHandle(
SqlSugarRepository v_empty_placeRep,
SqlSugarRepository wmsPlaceRep,
SqlSugarRepository wareTaskRep
)
{
_v_empty_placeRep = v_empty_placeRep;
_wmsPlaceRep = wmsPlaceRep;
_wareTaskRep = wareTaskRep;
}
///
/// 主方法入口1:查询单个库位
///
///* 原则:
///* 1、方法必须使用lock锁定,防止并发抢同一个库位
///* 2、该库位如果所在的堆垛机被设定为 禁用,则不允许寻找该库位
///* 3、入库-库存分摊原则(注意:此项按照客户约定规则,视情况而定)
///
public async Task MainFindSingleEmptyLocation(FindEmptyPlaceInput input)
{
var findList = await MainFindMultiEmptyLocation(input);
if (findList != null && findList.Count > 0)
{
return findList.First();
}
return null;
}
///
/// 主方法入口2:查询多个库位
///
///* 原则:
///* 1、方法必须使用lock锁定,防止并发抢同一个库位
///* 2、该库位如果所在的堆垛机被设定为 禁用,则不允许寻找该库位
///* 3、入库-库存分摊原则(注意:此项按照客户约定规则,视情况而定)
///
public async Task> MainFindMultiEmptyLocation(FindEmptyPlaceInput input)
{
try
{
if (isRuning_Fun)
{
throw Oops.Oh("程序正忙,请稍后再试");
}
await semaphoreSlim.WaitAsync();
isRuning_Fun = true;
await QueryBaseEmptyLocationList(input); //查询所有的空闲库位
await EnableLaneFilter();//可用的堆垛机巷道 --筛选条件
await TaskOccupyFilter();//任务占用的库位 -- 筛选条件
DiyFilter();//自定义查询条件 -- 筛选条件
DataOrder();//数据排序
//返回结果
if (findEmptyPlaceList != null && findEmptyPlaceList.Count > 0)
{
var queryIds = findEmptyPlaceList.Select(x => x.Id).ToList();
return _wmsPlaceRep.GetList(x => queryIds.Contains(x.Id));
}
return new List();
}
catch (Exception)
{
throw;
}
finally
{
semaphoreSlim.Release();
isRuning_Fun = false;
}
}
#region 虚方法
///
/// 查询最基础的空库位集合,即获取数据库数据源的入口
///
protected virtual async Task QueryBaseEmptyLocationList(FindEmptyPlaceInput input)
{
findEmptyPlaceList = await _v_empty_placeRep.GetListAsync(x => 1 == 1);
if (input != null)
{
if (input.AreaList?.Count > 0)
{
findEmptyPlaceList = findEmptyPlaceList.Where(x => input.AreaList.Contains(x.AreaCode)).ToList();
}
if (!string.IsNullOrEmpty(input.PalceNo))
{
findEmptyPlaceList = findEmptyPlaceList.Where(x => x.PlaceCode == input.PalceNo).ToList();
}
}
}
///
/// 可用的堆垛机巷道 -- 筛选条件
///
protected virtual async Task EnableLaneFilter()
{
if (findEmptyPlaceList != null && findEmptyPlaceList.Count > 0)
{
//该库位如果所在的堆垛机被设定为 禁用,则不允许寻找该库位
List enable_laneList = await GetEnableLaneList();
if (enable_laneList != null && enable_laneList.Count > 0)
{
findEmptyPlaceList = await _v_empty_placeRep.AsQueryable().Where(x => enable_laneList.Contains(x.LaneNo)).ToListAsync();
}
}
}
///
/// 排除未终结的任务占用库位 -- 筛选条件
///
protected virtual async Task TaskOccupyFilter()
{
if (findEmptyPlaceList != null && findEmptyPlaceList.Count > 0)
{
List removeIdList = new List();
var noFinishTask = await _wareTaskRep.AsQueryable().Where(x => x.TaskStatus != TaskStatusEnum.已完成 && x.TaskStatus != TaskStatusEnum.已取消).ToListAsync();
var noFinishTask_Form = noFinishTask.Select(x => x.SourcePlaceCode).ToList();
var noFinishTask_To = noFinishTask.Select(x => x.ToPlaceCode).ToList();
//排除未结束任务占用的
findEmptyPlaceList = findEmptyPlaceList.Where(x => !noFinishTask_Form.Contains(x.PlaceCode) && !noFinishTask_To.Contains(x.PlaceCode)).ToList();
}
}
///
/// 自定义查询条件 -- 筛选条件
///
protected virtual void DiyFilter()
{
}
///
/// 数据排序
///
protected virtual void DataOrder()
{
if (findEmptyPlaceList != null && findEmptyPlaceList.Count > 0)
{
findEmptyPlaceList = findEmptyPlaceList
//先按照层,升序排列
.OrderBy(x => x.LayerNo)
//再按照列,升序排列
.ThenBy(x => x.ColumnNo).ToList();
}
}
#endregion
#region 公共方法
///
/// 获取可用的堆垛机所在的巷道集合
///
///
protected async Task> GetEnableLaneList()
{
//根据自己的项目自行判断
////该库位如果所在的堆垛机被设定为 禁用,则不允许寻找该库位
//var eqType = _wareEquipmentTypeRep.FirstOrDefault(x => x.Code == EquipmentTypeEnum.Srm.ToString());
//if (eqType == null)
//{
// throw Oops.Bah("没有找到类型是堆垛机的数据");
//}
//var noramlEquipmentList = _wareEquipmentRep.Where(x => x.Status == 0 && x.EquipmentTypeId == eqType.Id).ToList();//查询所有可用的堆垛机列表
//if (noramlEquipmentList != null && noramlEquipmentList.Count > 0)
//{
// return noramlEquipmentList.Where(x => x.Lane != null).Select(x => x.Lane).ToList();
//}
return null;
}
#endregion
}
}