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 } }