using Furion.DatabaseAccessor;
|
using Furion.FriendlyException;
|
using iWare.Wms.Core;
|
using Microsoft.CodeAnalysis;
|
using System;
|
using System.Collections.Generic;
|
using System.Linq;
|
using System.Text;
|
using System.Threading.Tasks;
|
|
namespace Admin.NET.Application.Common
|
{
|
/// <summary>
|
/// 寻找 空库位的处理类
|
/// </summary>
|
public class FindEmptyLocationServiceHandle
|
{
|
private static readonly object lockFindBestEmpty = new object();
|
protected readonly IRepository<v_empty_location, MasterDbContextLocator> _v_EmptyLocationRep;
|
protected readonly IRepository<WmsPlace, MasterDbContextLocator> _wareLocationRep;
|
protected readonly IRepository<WareTask, MasterDbContextLocator> _wareTaskRep;
|
protected readonly IRepository<WareContainerVsMaterial, MasterDbContextLocator> _wareContainerVsMaterial;
|
protected readonly IRepository<WmsContainer, MasterDbContextLocator> _wareContainer;
|
protected readonly IRepository<WmsContainerType, MasterDbContextLocator> _wareContainerType;
|
protected readonly IRepository<v_ware_inventory_by_container, MasterDbContextLocator> _v_ware_inventory_by_container;
|
protected List<v_empty_location> findEmptyLocationList = null;
|
|
protected string _containerCode = "";
|
protected string _siteCode = "";
|
|
/// <summary>
|
/// 构造函数
|
/// </summary>
|
/// <param name="v_EmptyLocationRep"></param>
|
/// <param name="wareLocationRep"></param>
|
/// <param name="wareTaskRep"></param>
|
/// <param name="wareContainerVsMaterial"></param>
|
/// <param name="wareContainer"></param>
|
/// <param name="wareContainerType"></param>
|
/// <param name="v_ware_inventory_by_container"></param>
|
/// <param name="containerCode"></param>
|
/// <param name="siteCode"></param>
|
public FindEmptyLocationServiceHandle(IRepository<v_empty_location, MasterDbContextLocator> v_EmptyLocationRep,
|
IRepository<WmsPlace, MasterDbContextLocator> wareLocationRep,
|
IRepository<WareTask, MasterDbContextLocator> wareTaskRep,
|
IRepository<WareContainerVsMaterial, MasterDbContextLocator> wareContainerVsMaterial,
|
IRepository<WmsContainer, MasterDbContextLocator> wareContainer,
|
IRepository<WmsContainerType, MasterDbContextLocator> wareContainerType,
|
IRepository<v_ware_inventory_by_container, MasterDbContextLocator> v_ware_inventory_by_container,
|
string containerCode,string siteCode
|
)
|
{
|
_v_EmptyLocationRep = v_EmptyLocationRep;
|
_wareLocationRep = wareLocationRep;
|
_wareTaskRep = wareTaskRep;
|
_wareContainerVsMaterial = wareContainerVsMaterial;
|
_wareContainer = wareContainer;
|
_wareContainerType = wareContainerType;
|
_v_ware_inventory_by_container = v_ware_inventory_by_container;
|
_containerCode = containerCode;
|
_siteCode = siteCode;
|
}
|
|
|
/// <summary>
|
/// 主方法入口
|
///
|
///* 原则:
|
///* 1、方法必须使用lock锁定,防止并发抢同一个库位
|
///* 2、该库位如果所在的堆垛机被设定为 禁用,则不允许寻找该库位
|
///* 3、入库-库存分摊原则(注意:此项按照客户约定规则,视情况而定)
|
/// </summary>
|
public WmsPlace MainFindEmptyLocation()
|
{
|
lock (lockFindBestEmpty)
|
{
|
QueryBaseEmptyLocationList(); //查询所有的空闲库位
|
|
//EnableLaneFilter();//可用的堆垛机巷道 --筛选条件
|
|
//TaskOccupyFilter();//任务占用的库位 -- 筛选条件
|
|
DiyFilter();//自定义查询条件 -- 筛选条件
|
|
DataOrder();//数据排序
|
|
//返回结果
|
if (findEmptyLocationList != null && findEmptyLocationList.Count > 0)
|
{
|
long id = findEmptyLocationList.First().Id;
|
//long id = 0;
|
//foreach (var item in findEmptyLocationList)
|
//{
|
// if (item.Row == 1 || item.Row == 4)
|
// {
|
// var vs = item.Code.Split('-');
|
// if (vs.Length != 4)
|
// {
|
// continue;
|
// }
|
// if (vs[1] == "01")
|
// {
|
// vs[1] = "02";
|
// }
|
// else if (vs[1] == "04")
|
// {
|
// vs[1] = "03";
|
// }
|
// string str = $"{vs[0]}-{vs[1]}-{vs[2]}-{vs[3]}";
|
// //查看近伸位有没有货
|
// var isExist = _inventoryByContainer.DetachedEntities.Any(u => u.WareLocationCode == str);
|
// if (!isExist)
|
// {
|
// id = item.Id;
|
// break;
|
// }
|
// }
|
// else if (item.Row == 2 || item.Row == 3)
|
// {
|
// var vs = item.Code.Split('-');
|
// if (vs.Length != 4)
|
// {
|
// continue;
|
// }
|
// if (vs[1] == "02")
|
// {
|
// vs[1] = "01";
|
// }
|
// else if (vs[1] == "03")
|
// {
|
// vs[1] = "04";
|
// }
|
// string str = $"{vs[0]}-{vs[1]}-{vs[2]}-{vs[3]}";
|
// //查看远伸位有没有任务
|
// var task = _wareTaskRep.DetachedEntities.Any(u => u.FromLocationCode == str || u.ToLocationCode == str || u.MoveFromLocation == str || u.MoveToLocation == str);
|
// if (!task)
|
// {
|
// id = item.Id;
|
// break;
|
// }
|
// }
|
//}
|
return _wareLocationRep.FindOrDefault(id);
|
}
|
return null;
|
}
|
}
|
|
#region 虚方法
|
|
/// <summary>
|
/// 查询最基础的空库位集合,即获取数据库数据源的入口
|
/// </summary>
|
protected virtual void QueryBaseEmptyLocationList()
|
{
|
findEmptyLocationList = _v_EmptyLocationRep.Where(x => 1 == 1).ToList();
|
}
|
|
/// <summary>
|
/// 可用的堆垛机巷道 -- 筛选条件
|
/// </summary>
|
protected virtual void EnableLaneFilter()
|
{
|
|
}
|
|
/// <summary>
|
/// 排除未终结的任务占用库位 -- 筛选条件
|
/// </summary>
|
protected virtual void TaskOccupyFilter()
|
{
|
|
}
|
|
/// <summary>
|
/// 自定义查询条件 -- 筛选条件
|
/// </summary>
|
protected virtual void DiyFilter()
|
{
|
|
}
|
|
/// <summary>
|
/// 数据排序
|
/// </summary>
|
protected virtual void DataOrder()
|
{
|
if (findEmptyLocationList != null && findEmptyLocationList.Count > 0)
|
{
|
findEmptyLocationList = findEmptyLocationList
|
//先按照层,升序排列
|
.OrderBy(x => x.LayerNo + x.ColumnNo).ToList();
|
}
|
}
|
|
#endregion
|
|
}
|
}
|