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
{
///
/// 寻找 空库位的处理类
///
public class FindEmptyLocationServiceHandle
{
private static readonly object lockFindBestEmpty = new object();
protected readonly IRepository _v_EmptyLocationRep;
protected readonly IRepository _wareLocationRep;
protected readonly IRepository _wareTaskRep;
protected readonly IRepository _wareContainerVsMaterial;
protected readonly IRepository _wareContainer;
protected readonly IRepository _wareContainerType;
protected readonly IRepository _v_ware_inventory_by_container;
protected List findEmptyLocationList = null;
protected string _containerCode = "";
protected string _siteCode = "";
///
/// 构造函数
///
///
///
///
///
///
///
///
///
///
public FindEmptyLocationServiceHandle(IRepository v_EmptyLocationRep,
IRepository wareLocationRep,
IRepository wareTaskRep,
IRepository wareContainerVsMaterial,
IRepository wareContainer,
IRepository wareContainerType,
IRepository 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;
}
///
/// 主方法入口
///
///* 原则:
///* 1、方法必须使用lock锁定,防止并发抢同一个库位
///* 2、该库位如果所在的堆垛机被设定为 禁用,则不允许寻找该库位
///* 3、入库-库存分摊原则(注意:此项按照客户约定规则,视情况而定)
///
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 虚方法
///
/// 查询最基础的空库位集合,即获取数据库数据源的入口
///
protected virtual void QueryBaseEmptyLocationList()
{
findEmptyLocationList = _v_EmptyLocationRep.Where(x => 1 == 1).ToList();
}
///
/// 可用的堆垛机巷道 -- 筛选条件
///
protected virtual void EnableLaneFilter()
{
}
///
/// 排除未终结的任务占用库位 -- 筛选条件
///
protected virtual void TaskOccupyFilter()
{
}
///
/// 自定义查询条件 -- 筛选条件
///
protected virtual void DiyFilter()
{
}
///
/// 数据排序
///
protected virtual void DataOrder()
{
if (findEmptyLocationList != null && findEmptyLocationList.Count > 0)
{
findEmptyLocationList = findEmptyLocationList
//先按照层,升序排列
.OrderBy(x => x.LayerNo + x.ColumnNo).ToList();
}
}
#endregion
}
}