using HH.WCS.NongFuChaYuan.OtherService;
|
using HH.WCS.NongFuChaYuan.TaskController;
|
using Newtonsoft.Json;
|
using NLog.Fluent;
|
using SqlSugar;
|
using System;
|
using System.Collections.Generic;
|
using System.Linq;
|
using System.Security.Cryptography;
|
using static System.Runtime.CompilerServices.RuntimeHelpers;
|
|
namespace HH.WCS.NongFuChaYuan.WmsService
|
{
|
/// <summary>
|
/// 密集型库区
|
/// </summary>
|
internal class IntensiveArea
|
{
|
static IntensiveArea()
|
{
|
//InitRowLockTable(new List<string> { "PGKQ", "PGKTK" });
|
}
|
|
/// <summary>
|
/// 根据库区和物料获取入库的货位(堆叠先考虑标准的,容量都是一样的,例如均州都是3+3;不考虑峨眉山非标2+2和2+1同时存在)
|
/// </summary>
|
/// <param name="area"></param>
|
/// <param name="itemCode">如果itemCode是空表示空容器</param>
|
/// <param name="standardCarryQty">标准搬运数量</param>
|
/// <returns></returns>
|
public static Location GetLocation4In(string area, string itemCode, string itemBatch, int standardCarryQty = 1)
|
{
|
Location result = null;
|
|
try
|
{
|
//1.0 获取每一排最大的列
|
//1.1 判断当前数量是不是满的,如果是满的并且是最大列,需要排除
|
var listMaxCol = new SqlHelper<Location>().GetInstance().Queryable<Location>().Where(a => a.S_AREA_CODE == area).OrderByDescending(a => a.N_COL).Take(1).PartitionBy(a => a.N_ROW).ToList();
|
|
//1.1 查到所有有容器的排
|
var db = new SqlHelper<object>().GetInstance();
|
var list = db.Queryable<Location>().Where(a => a.N_CURRENT_NUM > 0 && a.S_AREA_CODE == area).Includes(a => a.LocCntrRel, a => a.CntrItemRel).OrderByDescending(a => a.N_COL).Take(1).PartitionBy(a => a.N_ROW).ToList();
|
if (list.Count > 0)
|
{
|
for (int i = list.Count - 1; i >= 0; i--)
|
{
|
//排除已经锁定的货位 和 放满了且是最大列的货位
|
//其它项目还需要查询排锁
|
if (list[i].S_LOCK_STATE.Trim() != "无" || (list[i].N_CURRENT_NUM == list[i].N_CAPACITY && listMaxCol.Count(a => a.S_LOC_CODE == list[i].S_LOC_CODE) > 0))
|
{
|
list.Remove(list[i]);
|
}
|
}
|
if (list.Count > 0)
|
{
|
//1.21 加载货位的容器信息 (mapper之前只能是查询原始数据,如果有其他查询 mapper失效)
|
#region MyRegion
|
/*
|
//Console.WriteLine("加载货位的容器信息");
|
db.ThenMapper(list, loc => {
|
loc.LocCntrRel = db.Queryable<LocCntrRel>().SetContext(x => x.S_LOC_CODE, () => loc.S_LOC_CODE, loc).FirstOrDefault();
|
});
|
|
//1.22 加载容器的物料信息
|
//Console.WriteLine("加载容器的物料信息");
|
db.ThenMapper(list.Select(loc => loc.LocCntrRel), lcr => {
|
lcr.CntrItemRel = db.Queryable<CntrItemRel>().SetContext(x => x.S_CNTR_CODE, () => lcr.S_CNTR_CODE, lcr).FirstOrDefault();
|
});
|
*/
|
#endregion
|
//1.3 遍历判断物料类型是否相同
|
for (int i = 0; i < list.Count; i++)
|
{
|
|
//todo 还需要判断锁
|
#region 空容器或者满容器判断 ,如果是空容器 容器物料信息为空
|
if (list[i].LocCntrRel != null)
|
{
|
//LogHelper.Info("itemCode=" + itemCode);
|
if ((itemCode != null && list[i].LocCntrRel.CntrItemRel != null && list[i].LocCntrRel.CntrItemRel.S_ITEM_CODE.Trim() == itemCode && list[i].LocCntrRel.CntrItemRel.S_BATCH_NO.Trim() == itemBatch.Trim()) || (itemCode == null && list[i].LocCntrRel.CntrItemRel == null))
|
{
|
if (list[i].N_CURRENT_NUM < list[i].N_CAPACITY)
|
{
|
//1.31 如果搬运数量=1
|
//1.32 搬运多个容器,例如3+3模式 ,必须当前数量=0或3;如果是3+3+,必须当前数量=0或3或6
|
if (list[i].N_CURRENT_NUM % standardCarryQty == 0)
|
{
|
result = list[i];
|
}
|
else
|
{
|
//1.33 不满足则选择后一列,后一列肯定是空货位
|
result = db.Queryable<Location>().Where(a => a.S_AREA_CODE == area && a.N_ROW == list[i].N_ROW && a.N_COL > list[i].N_COL).OrderBy(a => a.N_COL).First();
|
}
|
}
|
else
|
{
|
//当前货位满了,比他col大一位的货位,后一列肯定是空货位
|
result = db.Queryable<Location>().Where(a => a.S_AREA_CODE == area && a.N_ROW == list[i].N_ROW && a.N_COL > list[i].N_COL).OrderBy(a => a.N_COL).First();
|
}
|
|
if (result != null)
|
{
|
break;
|
}
|
}
|
}
|
else
|
{
|
LogHelper.Info("货位容器物料信息为空");
|
}
|
|
|
#endregion
|
|
}
|
}
|
}
|
if (result == null)
|
{
|
//todo 还需要判断锁
|
#region 查找所有数量是空的排
|
//2.0 简化查询只查每一排第一列
|
list = db.Queryable<Location>().Where(a => a.S_AREA_CODE == area).OrderBy(a => a.N_COL).Take(1).PartitionBy(a => a.N_ROW).ToList().Where(a => a.N_CURRENT_NUM == 0).ToList();
|
//2.1 选一个空排
|
for (int i = 0; i < list.Count; i++)
|
{
|
if (list[i].S_LOCK_STATE.Trim() == "无")
|
{
|
//二次校验当前排所有货位都是空的,防止系统数据错乱
|
var rowSumInfo = db.Queryable<Location>().Where(a => a.S_AREA_CODE == area && a.N_ROW == list[i].N_ROW).Select(a => new { sum = SqlFunc.AggregateSum(a.N_CURRENT_NUM) }).First();
|
if (rowSumInfo.sum == 0)
|
{
|
result = list[i];
|
break;
|
}
|
}
|
}
|
#endregion
|
}
|
}
|
catch (Exception ex)
|
{
|
//Console.WriteLine("GetLocation4In:" + ex.Message + ex.StackTrace);
|
LogHelper.Error("GetLocation4In:" + ex.Message, ex);
|
}
|
return result;
|
}
|
|
internal static bool GetYiKuLocation(List<string> rowlist, WorkOrder WorkOrder, string BatchNo)
|
{
|
bool result = false;
|
string startbit = "";
|
string endbit = "";
|
string itemcode = "";
|
string batchNo = "";
|
int startley = 1;
|
int endley = 1;
|
var dic = new Dictionary<string, int>();
|
var strList = new List<string>();
|
//var intList = new List<int>();
|
var db = new SqlHelper<object>().GetInstance();
|
for (int i = 0; i < rowlist.Count(); i++)
|
{
|
string rowNo = rowlist[i];
|
var rowSum = db.Queryable<Location>().Where(a => a.N_ROW == rowNo && a.S_LOCK_STATE.Trim() != "报废").Select(a => new { sum = SqlFunc.AggregateSum(a.N_CURRENT_NUM) }).First();
|
dic.Add(rowNo, rowSum.sum);
|
strList.Add(rowNo);
|
}
|
LogHelper.Info($"将所有的排数量放进列表进行排序 各个排数量为{JsonConvert.SerializeObject(dic)}", "自动移库");
|
for (int i = 0; i < strList.Count() - 1; i++)
|
{
|
for (int j = i + 1; j < strList.Count(); j++)
|
{
|
int ts1 = 0;
|
int ts2 = 0;
|
dic.TryGetValue(strList[i], out ts1);
|
dic.TryGetValue(strList[j], out ts2);
|
|
if (ts1 > ts2)
|
{
|
string temp = strList[i];
|
strList[i] = strList[j];
|
strList[j] = temp;
|
}
|
}
|
}
|
//LogHelper.Info($"排序后的数量为 {JsonConvert.SerializeObject(intList)}");
|
//for (int i = 0; i < intList.Count(); i++)
|
//{
|
// string ts = "";
|
// dic.TryGetValue(intList[i], out ts);
|
// strList.Add(ts);
|
//}
|
LogHelper.Info($"通过数量将排提取出来 排号排序为{JsonConvert.SerializeObject(strList)}");
|
for (int i = 0; i < strList.Count(); i++)
|
{
|
string startrowNo = strList[i];
|
var start = db.Queryable<Location>().Where(a => a.N_CURRENT_NUM > 0 && a.N_ROW == startrowNo).Includes(a => a.LocCntrRel, a => a.CntrItemRel).OrderByDescending(a => a.N_COL).Take(1).First();
|
LogHelper.Info($"判断起点 起点货位编码={start.S_LOC_CODE} 物料编码={start.LocCntrRel.CntrItemRel.S_ITEM_CODE} 批次号={start.LocCntrRel.CntrItemRel.S_BATCH_NO}", "自动移库");
|
for (int j = strList.Count() - 1; j > i; j--)
|
{
|
string endrow = strList[j];
|
var end = db.Queryable<Location>().Where(a => a.N_CURRENT_NUM > 0 && a.N_ROW == endrow).Includes(a => a.LocCntrRel, a => a.CntrItemRel).OrderByDescending(a => a.N_COL).Take(1).First();
|
LogHelper.Info($"判断终点 终点货位编码={end.S_LOC_CODE} 物料编码={end.LocCntrRel.CntrItemRel.S_ITEM_CODE} 批次号={end.LocCntrRel.CntrItemRel.S_BATCH_NO}", "自动移库");
|
|
if (start.LocCntrRel.CntrItemRel.S_ITEM_CODE == end.LocCntrRel.CntrItemRel.S_ITEM_CODE && start.LocCntrRel.CntrItemRel.S_BATCH_NO.Trim() == BatchNo && end.LocCntrRel.CntrItemRel.S_BATCH_NO.Trim() == BatchNo)
|
{
|
itemcode = start.LocCntrRel.CntrItemRel.S_ITEM_CODE;
|
batchNo = start.LocCntrRel.CntrItemRel.S_BATCH_NO;
|
//物料编码一样的时候确认起点终点
|
if (end.N_CURRENT_NUM == end.N_CAPACITY)
|
{
|
//如果终点层放满二层 选下一列
|
end = db.Queryable<Location>().Where(a => a.N_ROW == end.N_ROW && a.N_COL == end.N_COL + 1).First();
|
}
|
|
}
|
else LogHelper.Info($"物料编码不同 或批次号异常", "自动移库");
|
}
|
if (!string.IsNullOrEmpty(startbit) && !string.IsNullOrEmpty(endbit))
|
{
|
break;
|
}
|
}
|
if (result)
|
{
|
//创建任务
|
var cntrList = LocationHelper.GetLocCntrRel(startbit);
|
if (cntrList.Count > 0)
|
{
|
var trayInfo = new List<LocCntrRel>();
|
string cntrs = "";
|
trayInfo = cntrList.OrderByDescending(a => a.T_CREATE).Take(2).ToList();//双托出库
|
trayInfo.ForEach(a => { cntrs = cntrs + "," + a.S_CNTR_CODE.Trim(); });
|
var item = db.Queryable<CntrItemRel>().Where(a => a.S_CNTR_CODE == cntrs.Split(',')[0]).First();
|
if (item != null)
|
{
|
LogHelper.Info($"获取物料配置 物料={item.S_ITEM_CODE} 层数={item.S_ITEM_MODEL}", "自动移库");
|
var iteminfo = WCSHelper.GetItemrel(item.S_ITEM_CODE, item.S_ITEM_MODEL);
|
DaMingShanCreateTransport(startbit, endbit, WorkOrder.S_ORDER_TYPE, cntrs, startley, endley, WorkOrder.S_PLineNo, 1, 1, int.Parse(iteminfo.S_ITEM_LAYER), WorkOrder.S_WorkNo, batchNo, itemcode);
|
}
|
|
}
|
else
|
{
|
LogHelper.Info($"获取托盘异常 自动移库获取不到起点托盘 货位编码={startbit}", "自动移库");
|
}
|
}
|
return result;
|
}
|
|
/// <summary>
|
/// 大明山自动移库 剔除所有满排和空排
|
/// </summary>
|
/// <param name="rowlist"></param>
|
internal static void ExcludeFullEmyRow(ref List<string> rowlist, string S_PLineNo)
|
{
|
var db = new SqlHelper<object>().GetInstance();
|
for (int i = 0; i < rowlist.Count; i++)
|
{
|
string rowNo = rowlist[i];
|
var rowSum = db.Queryable<Location>().Where(a => a.N_ROW == rowNo && a.S_LOCK_STATE.Trim() != "报废").Select(a => new { sum = SqlFunc.AggregateSum(a.N_CURRENT_NUM) }).First();
|
var MaxrowSum = db.Queryable<Location>().Where(a => a.N_ROW == rowNo && a.S_LOCK_STATE.Trim() != "报废").Select(a => new { sum = SqlFunc.AggregateSum(a.N_CAPACITY) }).First();
|
if (rowSum.sum == 0 || rowSum.sum == MaxrowSum.sum)
|
{
|
//解锁
|
UnlockYiKu(rowNo);
|
rowlist.Remove(rowNo);
|
db.Deleteable<DaMingShanAnalysisMoveLib>().Where(a => a.DeviceName == S_PLineNo && a.RowNo == rowNo).ExecuteCommand();
|
}
|
}
|
}
|
|
internal static void ExcludeTaskRow(ref List<string> rowlist)
|
{
|
var db = new SqlHelper<object>().GetInstance();
|
|
}
|
|
internal static void UnlockYiKu(string rowNo)
|
{
|
var db = new SqlHelper<object>().GetInstance();
|
var lockinfo = db.Queryable<Location>().Where(a => a.N_ROW.Trim() == rowNo && a.S_LOCK_STATE.Trim() == "移库锁").ToList();
|
if (lockinfo.Count > 0)
|
{
|
foreach (var item in lockinfo)
|
{
|
item.S_LOCK_STATE = "无";
|
db.Updateable(item).UpdateColumns(ab => new { ab.S_LOCK_STATE }).ExecuteCommand();
|
}
|
TaskProcess.AreaRowLockState(rowNo, false);
|
}
|
}
|
|
|
internal static void LockYiKu(ref List<string> rowlist)
|
{
|
var db = new SqlHelper<object>().GetInstance();
|
for (int i = 0; i < rowlist.Count(); i++)
|
{
|
string rowNo = rowlist[i];
|
var lockinfo = db.Queryable<Location>().Where(a => a.N_ROW.Trim() == rowNo && a.S_LOCK_STATE.Trim() != "移库锁" && a.S_LOCK_STATE.Trim() != "报废" && a.S_LOCK_STATE.Trim() != "无").First();
|
if (lockinfo == null)
|
{
|
//如果没有移库锁需锁定整排货位
|
var YikuLockinfo = db.Queryable<Location>().Where(a => a.N_ROW.Trim() == rowNo && a.S_LOCK_STATE.Trim() == "移库锁").ToList();
|
if (YikuLockinfo.Count == 0)
|
{
|
//锁定该排
|
var rowinfo = db.Queryable<Location>().Where(a => a.N_ROW.Trim() == rowNo).ToList();
|
foreach (var item in rowinfo)
|
{
|
if (item.S_LOCK_STATE.Trim() != "报废")
|
{
|
item.S_LOCK_STATE = "移库锁";
|
db.Updateable(item).UpdateColumns(ab => new { ab.S_LOCK_STATE }).ExecuteCommand();
|
}
|
}
|
TaskProcess.AreaRowLockState(rowNo);
|
}
|
}
|
else
|
{
|
rowlist.Remove(rowNo);
|
}
|
}
|
|
}
|
|
|
/// <summary>
|
/// 判断任务表是否存在当前库区以及当前库位未完成的任务 均取货完成-true 反之-false
|
/// </summary>
|
/// <param name="AreaNo"></param>
|
/// <param name="RowNo"></param>
|
/// <param name="UnStart">true:作为 起点判断 false:作为终点判断</param>
|
/// <returns></returns>
|
public static bool TaskTakeAreaOver2(List<string> rowlist)
|
{
|
bool result = true;
|
var db = new SqlHelper<object>().GetInstance();
|
|
var taskInfo = db.Queryable<WMSTask>().Where(a => a.S_TYPE.Trim() == "自动移库" && a.S_B_STATE.Trim() != "完成" && a.S_B_STATE.Trim() != "失败" && a.S_B_STATE.Trim() != "取消").OrderByDescending(a => a.T_CREATE).ToList();//WmsTaskAction
|
if (taskInfo.Count() > 0)
|
{
|
for (int i = 0; i < rowlist.Count; i++)
|
{
|
string RowNo = rowlist[i];
|
taskInfo.ForEach(it =>
|
{
|
//起点属于 查询库位 内;即 判断 此任务是否有取货完成
|
var locInfo = db.Queryable<Location>().Where(a => a.N_ROW == RowNo && (a.S_LOC_CODE == it.S_START_LOC.Trim() || a.S_LOC_CODE == it.S_END_LOC.Trim())).First();
|
if (locInfo != null)
|
{
|
result = false;
|
}
|
});
|
}
|
}
|
return result;
|
|
}
|
|
/// <summary>
|
/// 根据库区和物料获取出库的货位(堆叠先考虑标准的,容量都是一样的,例如均州都是3+3;不考虑峨眉山非标2+2和2+1同时存在)
|
/// </summary>
|
/// <param name="area"></param>
|
/// <param name="itemCode">如果itemCode是空表示空容器</param>
|
/// <param name="standardCarryQty">标准搬运数量</param>
|
/// <returns></returns>
|
/// <returns></returns>
|
public static Location GetLocation4Out(string area, string itemCode, string itemBatch, int standardCarryQty = 1)
|
{
|
//Console.WriteLine($"area={area}");
|
Location result = null;
|
var db = new SqlHelper<Location>().GetInstance();
|
|
//1.0 查到所有有容器的排 var list = db.Queryable<Location>().Where(a => a.N_CURRENT_NUM>0).Includes(a => a.LocCntrRel, a => a.CntrItemRel).ToList();
|
var list = db.Queryable<Location>().Where(a => a.N_CURRENT_NUM > 0 && a.S_AREA_CODE == area).Includes(a => a.LocCntrRel, a => a.CntrItemRel).OrderByDescending(a => a.N_COL).Take(1).PartitionBy(a => a.N_ROW).ToList();
|
//1.1 判断当前数量是不是满的,如果是满的并且是最大列,需要排除
|
if (list.Count > 0)
|
{
|
//LogHelper.Info("GetLocation4Out:" + JsonConvert.SerializeObject(list));
|
#region MyRegion
|
/*
|
//1.21 加载货位的容器信息
|
db.ThenMapper(list, loc => {
|
loc.LocCntrRel = db.Queryable<LocCntrRel>().SetContext(x => x.S_LOC_CODE, () => loc.S_LOC_CODE, loc).FirstOrDefault();
|
});
|
//1.22 加载容器的物料信息
|
db.ThenMapper(list.Select(loc => loc.LocCntrRel), lcr => {
|
lcr.CntrItemRel = db.Queryable<CntrItemRel>().SetContext(x => x.S_CNTR_CODE, () => lcr.S_CNTR_CODE, lcr).FirstOrDefault();
|
});
|
*/
|
#endregion
|
//1.3 遍历判断物料类型是否相同
|
for (int i = 0; i < list.Count; i++)
|
{
|
|
//todo 还需要判断锁
|
|
#region 空容器或者满容器判断 ,如果是空容器 容器物料信息为空
|
if (list[i].S_LOCK_STATE.Trim() == "无" && list[i].LocCntrRel != null)
|
{
|
if ((itemCode != null && list[i].LocCntrRel.CntrItemRel != null && list[i].LocCntrRel.CntrItemRel.S_ITEM_CODE.Trim() == itemCode && (itemBatch == null || list[i].LocCntrRel.CntrItemRel.S_BATCH_NO.Trim() == itemBatch.Trim())) || (itemCode == null && list[i].LocCntrRel.CntrItemRel == null))
|
{
|
//搬运选择货位
|
//如果当前出库位后面有空位,不能是入库中
|
var after = new SqlHelper<Location>().Get(a => a.S_AREA_CODE == area && a.N_ROW == list[i].N_ROW && a.N_COL == list[i].N_COL + 1);
|
if (after == null || after.S_LOCK_STATE.Trim() == "无")
|
{
|
result = list[i];
|
}
|
if (result != null)
|
{
|
break;
|
}
|
}
|
}
|
|
|
#endregion
|
|
}
|
}
|
|
return result;
|
}
|
|
|
|
|
|
/// <summary>
|
/// 初始化密集排锁表格
|
/// </summary>
|
public static void InitRowLockTable(List<string> areas)
|
{
|
var db = new SqlHelper<object>().GetInstance();
|
var listRowLocks = db.Queryable<RowLock>().ToList();
|
areas.ForEach(a =>
|
{
|
var list = db.Queryable<Location>().Where(l => l.S_AREA_CODE == a).Distinct().Select(it => it.N_ROW).ToList();
|
list.ForEach(r =>
|
{
|
if (listRowLocks.Count(d => d.S_AREA_CODE.Trim() == a && d.N_ROW == r) == 0)
|
{
|
var res = db.Insertable<RowLock>(new RowLock { N_ROW = r, S_AREA_CODE = a, S_LOCK_STATE = "无", S_LOCK_SRC = "", S_WORK_MODE = "正常" }).ExecuteCommand();
|
}
|
});
|
});
|
}
|
|
internal static void Test()
|
{
|
//UnLockLoc("PGKQ-02-02");
|
//LockLoc("PGKQ-02-02", "入库锁");
|
//Binding("PGKQ-02-03", "AAA", "", 3);
|
//UnBinding("PGKQ-02-03", 2);
|
|
//var full = GetLocation4In("PGKQ", "AAA");
|
//var empty = GetLocation4In("PGKQ", null);
|
//var fullOut = GetLocation4Out("PGKQ", "AAA");
|
//var emptyOut = GetLocation4Out("PGKQ", null);
|
//var Locations = new SqlHelper<Location>().GetList();
|
//var LocCntrRels = new SqlHelper<LocCntrRel>().GetList();
|
//var CntrItemRels = new SqlHelper<CntrItemRel>().GetList();
|
|
//var list = new SqlHelper<Location>().GetInstance().Queryable<Location>().LeftJoin<LocCntrRel>((l, lc) => l.S_LOC_CODE == lc.S_LOC_CODE).ToList();
|
//var results = context.Client.Queryable<Employee>().Mapper(t=>t.Person, p=>p.PersonId).ToList();
|
var db = new SqlHelper<object>().GetInstance();
|
|
//var list = db.Queryable<Location>().Mapper(l => l.LocCntrRel, lcr => lcr.S_LOC_CODE).Where(a=>a.S_LOC_CODE== "PGKQ-01-01").ToList();
|
|
//多级查询会嵌套,需要指定导航属性和主键,循环嵌套查询不建议
|
//[Navigate(NavigateType.OneToOne, nameof(S_LOC_CODE))]、 [Navigate(NavigateType.OneToOne, nameof(S_CNTR_CODE))]、[SugarColumn(IsPrimaryKey = true)]
|
var list = db.Queryable<Location>().Where(a => a.N_CURRENT_NUM > 0).Includes(a => a.LocCntrRel, a => a.CntrItemRel).ToList();
|
|
#region MyRegion
|
/*
|
// SetContext不会生成循环操作,高性能 和直接Where性能是不一样的
|
var list = db.Queryable<Location>().Where(a => a.N_CURRENT_NUM > 0).ToList();
|
//第一层
|
db.ThenMapper(list, loc => {
|
loc.LocCntrRel = db.Queryable<LocCntrRel>().SetContext(x => x.S_LOC_CODE, () => loc.S_LOC_CODE, loc).FirstOrDefault();
|
});
|
//第二层
|
db.ThenMapper(list.Select(loc => loc.LocCntrRel), lcr => {
|
lcr.CntrItemRel = db.Queryable<CntrItemRel>().SetContext(x => x.S_CNTR_CODE, () => lcr.S_CNTR_CODE, lcr).FirstOrDefault();
|
});
|
*/
|
#endregion
|
}
|
|
|
|
|
#region 淳安出入库算法
|
|
|
|
/// <summary>
|
/// 移库出入库处理
|
/// </summary>
|
/// <param name="startArea"></param>
|
/// <param name="endArea"></param>
|
/// <param name="startRow"></param>
|
/// <param name="endRow"></param>
|
/// <param name="taskType"></param>
|
/// <param name="itemCode"></param>
|
/// <param name="batchNo"></param>
|
/// <param name="itemLayer"></param>
|
/// <returns></returns>
|
internal static bool DaMingShanYiKuTask(string startArea, string endArea, string startRow, string endRow, string taskType, string itemCode = "", string batchNo = "", string itemLayer = "", string workNo = "")
|
{
|
var db = new SqlHelper<object>().GetInstance();
|
bool result = false;
|
var endLocation = new Location();
|
try
|
{
|
var startLocation = GetYiKuLocationOut(startArea, startRow, itemCode, batchNo, itemLayer);
|
if (startLocation != null && !string.IsNullOrEmpty(startLocation.S_LOC_CODE))
|
endLocation = GetYiKuLocationIn(endArea, endRow, itemCode, batchNo, 1, itemLayer, startLocation.S_LOC_CODE.Trim());
|
//else //Console.WriteLine($"{workNo}:移库处理异常:未获取到出库起点信息!");
|
if (startLocation != null && endLocation != null && startLocation.S_LOCK_STATE.Trim() == "移库锁" && endLocation.S_LOCK_STATE.Trim() == "移库锁")
|
{
|
LogHelper.Info($"人工移库 算法结束获取点位成功");
|
var startLayer = startLocation.N_CURRENT_NUM;
|
var endLayer = endLocation.N_CURRENT_NUM + 1;
|
var taskNo = DateTime.Now.Ticks.ToString();
|
//出库要从起点获取托盘
|
var cntrList = LocationHelper.GetLocCntrRel(startLocation.S_LOC_CODE.Trim());
|
LogHelper.Info($"人工移库 获取托盘数量={cntrList.Count()}");
|
//淳安两个托盘为 一个 货位当前容量
|
if (cntrList.Count > 0)
|
{
|
var trayInfo = new List<LocCntrRel>();
|
string cntrs = "";
|
if (cntrList.Count % 2 == 0) trayInfo = cntrList.OrderByDescending(a => a.T_CREATE).Take(2).ToList();//双托出库
|
else trayInfo = cntrList.OrderByDescending(a => a.T_CREATE).Take(1).ToList();//单托出库
|
trayInfo.ForEach(a => { cntrs = cntrs + "," + a.S_CNTR_CODE.Trim(); });
|
var cntr = trayInfo[0].S_CNTR_CODE;
|
|
var iteminfo = db.Queryable<CntrItemRel>().Where(a => a.S_CNTR_CODE == cntr).First();
|
if (iteminfo != null)
|
{
|
|
var cntrtype = db.Queryable<ItemArea>().Where(a => a.S_AREA_CODE == startArea).First();
|
|
var info = db.Queryable<ItemRel>().Where(a => a.S_ITEM_CODE == iteminfo.S_ITEM_CODE && a.S_ITEM_MODEL == iteminfo.S_ITEM_MODEL).First();
|
|
result = DaMingShanCreateTransport(startLocation.S_LOC_CODE, endLocation.S_LOC_CODE, taskType, cntrs, startLayer, endLayer, cntrList[0].S_SRC, 1, 1, int.Parse(info.S_ITEM_LAYER), workNo, batchNo, itemCode, cntrtype.S_TRAY_TYPE);
|
}
|
}
|
else
|
{
|
//Console.WriteLine($"起点托盘数量和货位容器表不符合,请检查【货位表】和【货位容器表】");
|
LogHelper.Info($"起点托盘数量和货位容器表不符合,请检查【货位表】和【货位容器表】", "WMSAlgoRithm");
|
}
|
}
|
else
|
{
|
string lockStart = "";
|
string lockEnd = "";
|
string lockTaskNo = "";
|
if (startLocation != null && startLocation.S_LOCK_STATE.Trim() != "无") lockStart = startLocation.N_ROW.Trim();
|
if (endLocation != null && endLocation.S_LOCK_STATE.Trim() != "无") lockEnd = endLocation.N_ROW.Trim();
|
//var db = new SqlHelper<object>().GetInstance();
|
if (!string.IsNullOrEmpty(lockStart))
|
{
|
var taskInfo = db.Queryable<WMSTask>().Where(a => (a.S_START_LOC == lockStart || a.S_END_LOC == lockStart) && a.S_B_STATE != "完成" && a.S_B_STATE != "取消" && a.S_B_STATE != "失败").OrderByDescending(a => a.T_CREATE).First();
|
if (taskInfo != null) lockTaskNo = lockTaskNo + taskInfo.S_TASK_NO.Trim() + ",";
|
}
|
if (!string.IsNullOrEmpty(lockEnd))
|
{
|
var taskInfo = db.Queryable<WMSTask>().Where(a => (a.S_START_LOC == lockEnd || a.S_END_LOC == lockEnd) && a.S_B_STATE != "完成" && a.S_B_STATE != "取消" && a.S_B_STATE != "失败").OrderByDescending(a => a.T_CREATE).First();
|
if (taskInfo != null) lockTaskNo = lockTaskNo + taskInfo.S_TASK_NO.Trim() + ",";
|
}
|
//Console.WriteLine($"{workNo}:移库处理--起点或终点库位被锁定!锁定任务号:{lockTaskNo}");
|
LogHelper.Info($"{workNo}:移库处理--起点或终点库位被锁定!锁定任务号:{lockTaskNo}", "WMSAlgoRithm");
|
}
|
}
|
catch (Exception ex)
|
{
|
LogHelper.Info($"人工移库算法异常 异常信息={ex.Message}");
|
}
|
return result;
|
}
|
|
/// <summary>
|
/// 备货移库出入库处理
|
/// </summary>
|
/// <param name="startArea"></param>
|
/// <param name="endArea"></param>
|
/// <param name="startRow"></param>
|
/// <param name="endRow"></param>
|
/// <param name="taskType"></param>
|
/// <param name="itemCode"></param>
|
/// <param name="batchNo"></param>
|
/// <param name="itemLayer"></param>
|
/// <returns></returns>
|
internal static bool DaMingShanYiKuTask1(string startArea, string endArea, string startRow, string endRow, string taskType, string workNo = "")
|
{
|
string itemcode = "";
|
bool result = false;
|
var db = new SqlHelper<object>().GetInstance();
|
var endLocation = new Location();
|
try
|
{
|
var startLocation = GetYiKuLocationOut(startArea, startRow);
|
if (startLocation != null && !string.IsNullOrEmpty(startLocation.S_LOC_CODE))
|
{
|
|
itemcode = LocationHelper.GetCntrItemRel(startLocation.S_LOC_CODE);
|
endLocation = GetYiKuLocationIn1(endArea, endRow, itemcode);
|
}
|
//else //Console.WriteLine($"{workNo}:移库处理异常:未获取到出库起点信息!");
|
if (startLocation != null && endLocation != null && startLocation.S_LOCK_STATE.Trim() == "移库锁" && endLocation.S_LOCK_STATE.Trim() == "移库锁")
|
{
|
|
LogHelper.Info($"备货移库 算法结束获取点位成功");
|
var startLayer = startLocation.N_CURRENT_NUM;
|
var endLayer = endLocation.N_CURRENT_NUM + 1;
|
var taskNo = DateTime.Now.Ticks.ToString();
|
//出库要从起点获取托盘
|
var cntrList = LocationHelper.GetLocCntrRel(startLocation.S_LOC_CODE.Trim());
|
LogHelper.Info($"备货移库 获取托盘数量={cntrList.Count()}");
|
//淳安两个托盘为 一个 货位当前容量
|
if (cntrList.Count > 0)
|
{
|
var trayInfo = new List<LocCntrRel>();
|
string cntrs = "";
|
if (cntrList.Count % 2 == 0) trayInfo = cntrList.OrderByDescending(a => a.T_CREATE).Take(2).ToList();//双托出库
|
else trayInfo = cntrList.OrderByDescending(a => a.T_CREATE).Take(1).ToList();//单托出库
|
|
trayInfo.ForEach(a => { cntrs = cntrs + "," + a.S_CNTR_CODE.Trim(); });
|
|
var iteminfo = db.Queryable<CntrItemRel>().Where(a => a.S_CNTR_CODE == cntrs.Split(',')[0]).First();
|
if (iteminfo != null)
|
{
|
var info = db.Queryable<ItemRel>().Where(a => a.S_ITEM_CODE == iteminfo.S_ITEM_CODE && a.S_ITEM_MODEL == iteminfo.S_ITEM_MODEL).First();
|
result = DaMingShanCreateTransport(startLocation.S_LOC_CODE, endLocation.S_LOC_CODE, taskType, cntrs, startLayer, endLayer, "", 1, 1, int.Parse(info.S_ITEM_LAYER), workNo, "", itemcode);
|
|
}
|
}
|
else
|
{
|
//Console.WriteLine($"起点托盘数量和货位容器表不符合,请检查【货位表】和【货位容器表】");
|
LogHelper.Info($"起点托盘数量和货位容器表不符合,请检查【货位表】和【货位容器表】", "WMSAlgoRithm");
|
}
|
|
}
|
else
|
{
|
string lockStart = "";
|
string lockEnd = "";
|
string lockTaskNo = "";
|
if (startLocation != null && startLocation.S_LOCK_STATE.Trim() != "无") lockStart = startLocation.N_ROW.Trim();
|
if (endLocation != null && endLocation.S_LOCK_STATE.Trim() != "无") lockEnd = endLocation.N_ROW.Trim();
|
//var db = new SqlHelper<object>().GetInstance();
|
if (!string.IsNullOrEmpty(lockStart))
|
{
|
var taskInfo = db.Queryable<WMSTask>().Where(a => (a.S_START_LOC == lockStart || a.S_END_LOC == lockStart) && a.S_B_STATE != "完成" && a.S_B_STATE != "取消" && a.S_B_STATE != "失败").OrderByDescending(a => a.T_CREATE).First();
|
if (taskInfo != null) lockTaskNo = lockTaskNo + taskInfo.S_TASK_NO.Trim() + ",";
|
}
|
if (!string.IsNullOrEmpty(lockEnd))
|
{
|
var taskInfo = db.Queryable<WMSTask>().Where(a => (a.S_START_LOC == lockEnd || a.S_END_LOC == lockEnd) && a.S_B_STATE != "完成" && a.S_B_STATE != "取消" && a.S_B_STATE != "失败").OrderByDescending(a => a.T_CREATE).First();
|
if (taskInfo != null) lockTaskNo = lockTaskNo + taskInfo.S_TASK_NO.Trim() + ",";
|
}
|
//Console.WriteLine($"{workNo}:移库处理--起点或终点库位被锁定!锁定任务号:{lockTaskNo}");
|
LogHelper.Info($"{workNo}:移库处理--起点或终点库位被锁定!锁定任务号:{lockTaskNo}", "WMSAlgoRithm");
|
}
|
}
|
catch (Exception ex)
|
{
|
LogHelper.Info($"备货移库算法异常 异常信息={ex.Message}");
|
}
|
return result;
|
}
|
|
|
/// <summary>
|
/// 判断任务表是否存在当前库区以及当前库位未完成的任务 均取货完成-true 反之-false
|
/// </summary>
|
/// <param name="AreaNo"></param>
|
/// <param name="RowNo"></param>
|
/// <param name="UnStart">true:作为 起点判断 false:作为终点判断</param>
|
/// <returns></returns>
|
public static bool TaskTakeAreaOver(string AreaNo, string RowNo, bool UnStart = true, bool CmWork = true)
|
{
|
bool result = true;
|
var db = new SqlHelper<object>().GetInstance();
|
if (UnStart)
|
{
|
var taskInfo = db.Queryable<WMSTask>().Where(a => a.S_START_LAREA == AreaNo && a.S_B_STATE.Trim() != "完成" && a.S_B_STATE.Trim() != "失败" && a.S_B_STATE.Trim() != "取消").OrderByDescending(a => a.T_CREATE).ToList();//WmsTaskAction
|
if (taskInfo.Count() > 0)
|
{
|
taskInfo.ForEach(it =>
|
{
|
//起点属于 查询库位 内;即 判断 此任务是否有取货完成
|
var locInfo = db.Queryable<Location>().Where(a => a.N_ROW == RowNo && a.S_LOC_CODE == it.S_START_LOC.Trim()).First();
|
if (locInfo != null)
|
{
|
if (CmWork)
|
{
|
//非缠膜移库工单 执行中任务未取货完成 不允许使用当前库位
|
var taskAction = db.Queryable<WmsTaskAction>().Where(a => a.S_ACTION_CODE == "4" && a.S_TASK_NO == it.S_TASK_NO).First();
|
if (taskAction == null) result = false;
|
}
|
}
|
});
|
}
|
}
|
else
|
{
|
var taskInfo = db.Queryable<WMSTask>().Where(a => a.S_END_LAREA == AreaNo && a.S_B_STATE.Trim() != "完成" && a.S_B_STATE.Trim() != "失败" && a.S_B_STATE.Trim() != "取消").OrderByDescending(a => a.T_CREATE).ToList();//WmsTaskAction
|
taskInfo.ForEach(it =>
|
{
|
//终点查询 只有 此库位 有一条 任务未完成,即 返回false,不可使用
|
var locInfo = db.Queryable<Location>().Where(a => a.N_ROW == RowNo && a.S_LOC_CODE == it.S_END_LOC.Trim()).First();
|
if (locInfo != null)
|
{
|
//Console.WriteLine($"移库任务判断终点库位是否可用:当前任务未完成,任务号:{it.S_TASK_NO.Trim()}");
|
result = false;
|
}
|
});
|
}
|
|
return result;
|
}
|
|
|
/// <summary>
|
/// 创建搬运任务
|
/// </summary>
|
/// <param name="start"></param>
|
/// <param name="end"></param>
|
/// <param name="taskType"></param>
|
/// <param name="cntrs"></param>
|
/// <param name="startLayer"></param>
|
/// <param name="endLayer"></param>
|
/// <param name="trayCarryCount"></param>
|
/// <param name="priority"></param>
|
/// <returns></returns>
|
public static bool ChunAnCreateTransport(string start, string end, string taskType, string cntrs, int startLayer, int endLayer, string deviceName, int trayCarryCount = 1, int priority = 1, int itemLayer = 5, string workNo = "")
|
{
|
var result = false;
|
var taskNo = DateTime.Now.Ticks.ToString();
|
var res = TaskHelper.CreateTask(taskNo, start.Trim(), end.Trim(), taskType, priority, cntrs, trayCarryCount, startLayer, endLayer, itemLayer, workNo);
|
if (res)
|
{
|
result = true;
|
//任务创建成功,起点货位出库锁定,终点货位入库锁定
|
LocationHelper.LockLoc(start, "出库锁");
|
LocationHelper.LockLoc(end, "入库锁");
|
|
//排锁定
|
var db = new SqlHelper<object>().GetInstance();
|
var Sinfo = db.Queryable<Location>().Where(a => a.S_LOC_CODE == start).First();
|
var Einfo = db.Queryable<Location>().Where(a => a.S_LOC_CODE == end).First();
|
if (Sinfo != null && Einfo != null)
|
{
|
string startRow = string.IsNullOrEmpty(Sinfo.N_ROW) ? "" : Sinfo.N_ROW.Trim();
|
string sArea = string.IsNullOrEmpty(Sinfo.S_AREA_CODE) ? "" : Sinfo.S_AREA_CODE;
|
string endRow = string.IsNullOrEmpty(Einfo.N_ROW) ? "" : Einfo.N_ROW.Trim();
|
string eArea = string.IsNullOrEmpty(Einfo.S_AREA_CODE) ? "" : Einfo.S_AREA_CODE;
|
LockRow(startRow, endRow, sArea, eArea, taskType);
|
//if (taskType == "成品下线")
|
//{
|
// //成品下线 任务类型,需要在终点库位标记下线产线,用于 产线工单结束,进行自动移库
|
// SignRow(deviceName, endRow, eArea);
|
// //成品下线任务生产成功 删除设备下线时间数据
|
// db.Deleteable<ChunAnDeviceState>().Where(a => a.DeviceName.Trim() == deviceName).ExecuteCommand();
|
//}
|
}
|
}
|
return result;
|
}
|
|
/// <summary>
|
/// 根据库区和物料获取入库的货位(堆叠先考虑标准的,容量都是一样的,例如均州都是3+3;不考虑峨眉山非标2+2和2+1同时存在)
|
/// </summary>
|
/// <param name="area"></param>
|
/// <param name="itemCode">如果itemCode是空表示空容器</param>
|
/// <param name="standardCarryQty">标准搬运数量</param>
|
/// <returns></returns>
|
public static Location GetLocationIn(string area, string itemCode, string itemBatch, string deviceName, string itemLayer)
|
{
|
LogHelper.Info($"入库算法开始", "输送线");
|
Location result = null;
|
var db = new SqlHelper<object>().GetInstance();
|
try
|
{
|
//var info = Settings.GetDaMingShanItemNameList().Where(a => a.ItemName == itemCode).FirstOrDefault();
|
var info = db.Queryable<ItemRel>().Where(a => a.S_ITEM_CODE == itemCode && a.S_ITEM_MODEL == itemLayer).First();
|
if (info != null)
|
{
|
LogHelper.Info("获取到物料编码配置文件", "输送线");
|
//1.0 获取每一排最大的列
|
//1.1 判断当前数量是不是满的,如果是满的并且是最大列,需要排除
|
var listMaxCol = new SqlHelper<Location>().GetInstance().Queryable<Location>().Where(a => a.S_AREA_CODE == area).OrderByDescending(a => a.N_COL).Take(1).PartitionBy(a => a.N_ROW).ToList();
|
//1.1 查到所有有容器的排
|
var list = db.Queryable<Location>().Where(a => a.N_CURRENT_NUM > 0 && a.S_AREA_CODE == area).Includes(a => a.LocCntrRel, a => a.CntrItemRel).OrderByDescending(a => a.N_COL).OrderBy(a => a.N_OROW).Take(1).PartitionBy(a => a.N_ROW).ToList();
|
if (list.Count > 0)
|
{
|
var time = DateTime.Now;
|
for (int i = list.Count - 1; i >= 0; i--)
|
{
|
//排除已经锁定的货位 和 放满了且是最大列的货位 N_CAPACITY-货位最大容量
|
//排除已锁定的排
|
var rowInfo = db.Queryable<Location>().Where(a => a.N_ROW == list[i].N_ROW && a.S_LOCK_STATE.Trim() != "无" && a.S_LOCK_STATE.Trim() != "报废").ToList();
|
if (list[i].S_LOCK_STATE.Trim() != "无" || rowInfo.Count() > 0 || (list[i].N_CURRENT_NUM == list[i].N_CAPACITY && listMaxCol.Count(a => a.S_LOC_CODE.Trim() == list[i].S_LOC_CODE.Trim()) > 0))
|
{
|
list.Remove(list[i]);
|
}
|
}
|
var sum = DateTime.Now - time;
|
LogHelper.Info($"库区={area}剔除排 使用时间={sum.TotalMilliseconds}");
|
var time1 = DateTime.Now;
|
if (list.Count > 0)
|
{
|
LogHelper.Info($"有货物的排数量={list.Count}");
|
//1.3 遍历判断物料类型是否相同
|
for (int i = 0; i < list.Count; i++)
|
{
|
//todo 还需要判断锁
|
#region 空容器或者满容器判断 ,如果是空容器 容器物料信息为空
|
if (list[i].LocCntrRel != null)
|
{
|
LogHelper.Info($"货位容器数据={JsonConvert.SerializeObject(list[i].LocCntrRel)}");
|
LogHelper.Info($"容器货品数据={JsonConvert.SerializeObject(list[i].LocCntrRel.CntrItemRel)}");
|
//var oldinfo = db.Queryable<ItemRel>().Where(a => a.S_ITEM_CODE == list[i].LocCntrRel.CntrItemRel.S_ITEM_CODE && a.S_ITEM_MODEL == list[i].LocCntrRel.CntrItemRel.S_ITEM_MODEL).First();
|
|
LogHelper.Info($"判断物料是否满足条件 Location={list[i].S_LOC_CODE} itemCode=" + itemCode, "输送线");
|
//此处需要判断当前满托货位批次号与即将下线的批次号是否相同,不同需要再往后查一个货位
|
//货位-货位托盘-托盘物料(批次号)
|
if ((itemCode != null && list[i].LocCntrRel.CntrItemRel != null))
|
{
|
LogHelper.Info($"olditemcode={list[i].LocCntrRel.CntrItemRel.S_ITEM_CODE.Trim()}", "输送线");
|
//相同物料 相同批次
|
//oldinfo = Settings.GetDaMingShanItemNameList().Where(a => a.ItemName == list[i].LocCntrRel.CntrItemRel.S_ITEM_CODE.Trim()).FirstOrDefault();
|
//if (oldinfo != null)
|
//{
|
//LogHelper.Info($"站点{list[i].S_LOC_CODE} 物料配置 物料编码={oldinfo.S_ITEM_CODE} 层数={oldinfo.S_ITEM_MODEL}", "输送线");
|
//if (oldinfo.Package != info.Package)
|
//{
|
// return result;
|
//}
|
if (itemCode.Trim() == list[i].LocCntrRel.CntrItemRel.S_ITEM_CODE.Trim()
|
&& list[i].LocCntrRel.S_SRC.Trim() == deviceName
|
&& list[i].LocCntrRel.CntrItemRel.S_ITEM_MODEL.Trim() == itemLayer.Trim()
|
&& list[i].LocCntrRel.CntrItemRel.S_BATCH_NO.Trim() == itemBatch.Trim()
|
)
|
{
|
//if (list[i].LocCntrRel.CntrItemRel.S_BATCH_NO.Trim() == itemBatch.Trim())
|
//{
|
if (list[i].N_CURRENT_NUM < list[i].N_CAPACITY)
|
{
|
string locCode = list[i].S_LOC_CODE.Trim();
|
var trayInfo = db.Queryable<LocCntrRel>().Where(a => a.S_LOC_CODE == locCode).ToList();
|
if (trayInfo.Count() % 2 == 0)
|
{
|
result = list[i];
|
}
|
else
|
{
|
//1.33 不满足则选择后一列,后一列肯定是空货位
|
var locinfo = db.Queryable<Location>().Where(a => a.S_AREA_CODE == area && a.N_ROW == list[i].N_ROW && a.N_COL > list[i].N_COL).OrderBy(a => a.N_COL).First();
|
if (locinfo != null)
|
{
|
result = locinfo;
|
}
|
}
|
}
|
else
|
{
|
//当前货位满了,比他col大一位的货位,后一列肯定是空货位
|
var locinfo = db.Queryable<Location>().Where(a => a.S_AREA_CODE == area && a.N_ROW == list[i].N_ROW && a.N_COL > list[i].N_COL).OrderBy(a => a.N_COL).First();
|
if (locinfo != null)
|
{
|
result = locinfo;
|
}
|
}
|
//}
|
//else
|
//{
|
// var locinfo = db.Queryable<Location>().Where(a => a.S_AREA_CODE == area && a.N_ROW == list[i].N_ROW && a.N_COL > (list[i].N_COL + 1)).OrderBy(a => a.N_COL).First();
|
// if (locinfo != null)
|
// {
|
// result = locinfo;
|
// }
|
//}
|
if (result != null) break;
|
}
|
}
|
}
|
else LogHelper.Info("货位容器物料信息为空", "输送线");
|
#endregion
|
}
|
}
|
var sum1 = DateTime.Now - time1;
|
LogHelper.Info($"库区={area}满排算法 使用时间={sum1.TotalMilliseconds}");
|
}
|
if (result == null)
|
{
|
list = new List<Location>();
|
var time2 = DateTime.Now;
|
//todo 还需要判断锁
|
#region 查找所有数量是空的排
|
//2.0 简化查询只查每一排第一列
|
LogHelper.Info("判断空排是否满足条件", "输送线");
|
//list = db.Queryable<Location>().Where(a => a.S_AREA_CODE == area).OrderBy(a => a.N_COL).PartitionBy(a => a.N_ROW).ToList().Where(a => a.N_CURRENT_NUM == 0).ToList();
|
//list = db.Queryable<Location>().Where(a => a.S_AREA_CODE == area).ToList().Where(a => a.N_CURRENT_NUM == 0).ToList();
|
|
//找出库区所有排 筛选所有数量为空的排放入集合
|
var emylist = new List<string>();
|
list = db.Queryable<Location>().Where(a => a.S_AREA_CODE == area).OrderBy(a => a.N_OROW).Take(1).PartitionBy(a => a.N_OROW).ToList();
|
for (int i = 0; i < list.Count(); i++)
|
{
|
var emyinfo = db.Queryable<Location>().Where(a => a.N_ROW == list[i].N_ROW).Select(a => new { sum = SqlFunc.AggregateSum(a.N_CURRENT_NUM) }).First();
|
if (emyinfo.sum == 0)
|
{
|
emylist.Add(list[i].N_ROW);
|
}
|
}
|
|
LogHelper.Info($"空排筛选 经过排序的空排顺序={JsonConvert.SerializeObject(emylist)}");
|
|
//2.1 选一个空排
|
//Console.WriteLine($"空排数量为{emylist.Count}");
|
LogHelper.Info($"空排数量为{emylist.Count} ", "输送线");
|
for (int i = 0; i < emylist.Count; i++)
|
{
|
LogHelper.Info($"遍历查找排,库区={area} 排号={emylist[i]}", "输送线");
|
var state = db.Queryable<Location>().Where(a => a.N_ROW == emylist[i] && a.S_LOCK_STATE != "无" && a.S_LOCK_STATE != "报废").First();
|
if (state == null)
|
{
|
var locinfo = db.Queryable<Location>().Where(a => a.S_AREA_CODE == area && a.N_ROW == emylist[i] && a.N_CURRENT_NUM == 0 && a.S_LOCK_STATE == "无").OrderBy(a => a.N_COL).First();
|
if (locinfo != null)
|
{
|
LogHelper.Info($"货位编码={locinfo.S_LOC_CODE},货位状态={locinfo.S_LOCK_STATE},货位数量={locinfo.N_CURRENT_NUM}", "输送线");
|
|
//Console.WriteLine("开启二次校验");
|
//二次校验当前排所有货位都是空的,防止系统数据错乱
|
string row = locinfo.N_ROW.Trim();
|
var rowSumInfo = db.Queryable<Location>().Where(a => a.N_ROW == row).Select(a => new { sum = SqlFunc.AggregateSum(a.N_CURRENT_NUM) }).First();
|
if (rowSumInfo.sum == 0)
|
{
|
result = locinfo;
|
break;
|
}
|
else
|
{
|
LogHelper.Info($"排{row} 不为空排 当前数量={rowSumInfo.sum}");
|
}
|
}
|
}
|
#endregion
|
}
|
var sum2 = DateTime.Now - time2;
|
LogHelper.Info($"库区={area}空排算法 使用时间={sum2.TotalMilliseconds}");
|
}
|
else if (result.S_LOCK_STATE.Trim() != "无")
|
{
|
result = null;
|
}
|
}
|
}
|
catch (Exception ex)
|
{
|
|
//Console.WriteLine("GetLocationIn:" + ex.Message + ex.StackTrace);
|
LogHelper.Error("GetLocationIn:" + ex.Message, ex);
|
}
|
return result;
|
}
|
|
|
|
|
|
/// <summary>
|
/// 根据库区和物料获取出库的货位(堆叠先考虑标准的,容量都是一样的,例如均州都是3+3;不考虑峨眉山非标2+2和2+1同时存在)
|
/// </summary>
|
/// <param name="area"></param>
|
/// <param name="itemCode">如果itemCode是空表示空容器</param>
|
/// <param name="standardCarryQty">标准搬运数量</param>
|
/// <returns></returns>
|
/// <returns></returns>
|
public static Location GetLocationOut(string area, string itemCode, string itemBatch, string itemLayer)
|
{
|
//Console.WriteLine($"area={area}");
|
Location result = null;
|
var db = new SqlHelper<Location>().GetInstance();
|
itemCode = itemCode + itemLayer;
|
//1.0 查到所有有容器的排 var list = db.Queryable<Location>().Where(a => a.N_CURRENT_NUM>0).Includes(a => a.LocCntrRel, a => a.CntrItemRel).ToList();
|
var list = db.Queryable<Location>().Where(a => a.N_CURRENT_NUM > 0 && a.S_AREA_CODE == area).Includes(a => a.LocCntrRel, a => a.CntrItemRel).OrderByDescending(a => a.N_COL).Take(1).PartitionBy(a => a.N_ROW).ToList();
|
//1.1 判断当前数量是不是满的,如果是满的并且是最大列,需要排除
|
if (list.Count > 0)
|
{
|
//1.3 遍历判断物料类型是否相同
|
for (int i = 0; i < list.Count; i++)
|
{
|
|
//todo 还需要判断锁
|
|
#region 空容器或者满容器判断 ,如果是空容器 容器物料信息为空
|
if (list[i].S_LOCK_STATE.Trim() == "无" && list[i].LocCntrRel != null)
|
{
|
if ((itemCode != null && list[i].LocCntrRel.CntrItemRel != null && list[i].LocCntrRel.CntrItemRel.S_ITEM_CODE.Trim() == itemCode && (itemBatch == null || list[i].LocCntrRel.CntrItemRel.S_BATCH_NO.Trim() == itemBatch.Trim())) || (itemCode == null && list[i].LocCntrRel.CntrItemRel == null))
|
{
|
//搬运选择货位
|
//如果当前出库位后面有空位,不能是入库中
|
string row = list[i].N_ROW.Trim();
|
int col = list[i].N_COL + 1;
|
var after = new SqlHelper<Location>().Get(a => a.S_AREA_CODE == area && a.N_ROW == row && a.N_COL == col);
|
if (after == null || after.S_LOCK_STATE.Trim() == "无")
|
{
|
result = list[i];
|
}
|
if (result != null)
|
{
|
break;
|
}
|
}
|
}
|
#endregion
|
}
|
}
|
|
return result;
|
}
|
|
|
/// <summary>
|
/// 移库获取入库货位
|
/// </summary>
|
/// <param name="area"></param>
|
/// <param name="itemCode">如果itemCode是空表示空容器</param>
|
/// <param name="standardCarryQty">标准搬运数量</param>
|
/// <returns></returns>
|
public static Location GetYiKuLocationIn(string area, string row, string itemCode = "", string itemBatch = "", int standardCarryQty = 0, string itemLayer = "", string startLoc = "")
|
{
|
//库区货位约定:列号越小越靠里
|
Location result = null;
|
Location res = null;
|
//itemCode = itemCode + itemLayer;
|
try
|
{
|
//Console.WriteLine($"移库任务入库计算:当前库区:{area},当前库位:{row}!");
|
LogHelper.Info($"移库任务入库计算:当前库区:{area},当前库位:{row}!", "WMSAlgoRithm");
|
|
var db = new SqlHelper<object>().GetInstance();
|
|
//入库 降序 从外往里查,获取 最靠外 的有托盘的货位;判断当前货位 托盘数量是否 满托;
|
//满托获取后面一个货位;反之,使用此货位
|
var list = db.Queryable<Location>().Where(a => a.N_CURRENT_NUM > 0 && a.S_AREA_CODE == area && a.N_ROW == row).Includes(a => a.LocCntrRel, a => a.CntrItemRel).OrderByDescending(a => a.N_COL).Take(1).First();
|
if (list != null)
|
{
|
//获取当前货位所有托盘数
|
var trayInfo = db.Queryable<LocCntrRel>().Where(a => a.S_LOC_CODE == list.S_LOC_CODE.Trim()).ToList();
|
//判断前一个货位与当前批次是否一样,不一样需要空一个货位
|
bool batch = BatchBool(list.S_LOC_CODE.Trim(), startLoc, db);
|
|
if (trayInfo.Count() == list.N_CAPACITY * 2 || trayInfo.Count() % 2 != 0 || batch)
|
{
|
//1.当前货位满了 查询后面一个货位 必然是空货位
|
//2.当前货位为 1+2 或 1 的货位,不可再入库,查询后面的货位
|
//3.不同批次号的物料需要隔一个货位
|
int Col = list.N_COL + 1;
|
if (batch) Col = Col + 1;
|
res = db.Queryable<Location>().Where(a => a.S_AREA_CODE == area && a.N_ROW == row && a.N_COL == Col).Take(1).First();
|
result = res;
|
}
|
else
|
{
|
result = list;
|
}
|
}
|
else
|
{
|
LogHelper.Info($"终点库区={area} 排={row}");
|
var empty = db.Queryable<Location>().Where(a => a.S_AREA_CODE == area && a.N_ROW == row).OrderBy(a => a.N_COL).Where(a => a.N_CURRENT_NUM == 0 && a.S_LOCK_STATE.Trim() == "移库锁").First();
|
//2.1 选一个空排
|
if (empty != null) result = empty;
|
else
|
{
|
//Console.WriteLine($"移库任务入库计算异常:当前库位以及库区无可用货位!当前库区:{area},当前库位:{row}!");
|
LogHelper.Info($"移库任务入库计算异常:当前库位以及库区无可用货位!当前库区:{area},当前库位:{row}!", "WMSAlgoRithm");
|
}
|
}
|
}
|
catch (Exception ex)
|
{
|
//Console.WriteLine("GetLocationIn:" + ex.Message + ex.StackTrace);
|
LogHelper.Error("GetLocationIn:" + ex.Message, ex);
|
}
|
if (result != null) LogHelper.Info($"人工移库入库算法 终点货位={result.S_LOC_CODE}");
|
return result;
|
}
|
|
|
/// <summary>
|
/// 移库获取入库货位
|
/// </summary>
|
/// <param name="area"></param>
|
/// <param name="itemCode">如果itemCode是空表示空容器</param>
|
/// <param name="standardCarryQty">标准搬运数量</param>
|
/// <returns></returns>
|
public static Location GetYiKuLocationIn1(string area, string row, string itemCode = "")
|
{
|
//库区货位约定:列号越小越靠里
|
Location result = null;
|
Location res = null;
|
//itemCode = itemCode + itemLayer;
|
try
|
{
|
//Console.WriteLine($"移库任务入库计算:当前库区:{area},当前库位:{row}!");
|
LogHelper.Info($"移库任务入库计算:当前库区:{area},当前库位:{row}!", "WMSAlgoRithm");
|
|
var db = new SqlHelper<object>().GetInstance();
|
|
//入库 降序 从外往里查,获取 最靠外 的有托盘的货位;判断当前货位 托盘数量是否 满托;
|
//满托获取后面一个货位;反之,使用此货位
|
var list = db.Queryable<Location>().Where(a => a.N_CURRENT_NUM == 0 && a.S_AREA_CODE == area && a.N_ROW == row).OrderBy(a => a.N_COL).First();
|
if (list != null)
|
{
|
result = list;
|
}
|
else
|
{
|
var empty = db.Queryable<Location>().Where(a => a.S_AREA_CODE == area && a.N_ROW == row).OrderBy(a => a.N_COL).Where(a => a.N_CURRENT_NUM == 0 && a.S_LOCK_STATE.Trim() == "移库锁").First();
|
//2.1 选一个空排
|
if (empty != null) result = empty;
|
else
|
{
|
//Console.WriteLine($"移库任务入库计算异常:当前库位以及库区无可用货位!当前库区:{area},当前库位:{row}!");
|
LogHelper.Info($"移库任务入库计算异常:当前库位以及库区无可用货位!当前库区:{area},当前库位:{row}!", "WMSAlgoRithm");
|
}
|
}
|
}
|
catch (Exception ex)
|
{
|
//Console.WriteLine("GetLocationIn:" + ex.Message + ex.StackTrace);
|
LogHelper.Error("GetLocationIn:" + ex.Message, ex);
|
}
|
if (result != null) LogHelper.Info($"人工移库入库算法 终点货位={result.S_LOC_CODE}");
|
return result;
|
}
|
private static bool BatchBool(string endLoc, string startLoc, SqlSugarClient db)
|
{
|
//Console.WriteLine($"移库入库批次号判断:入库终点货位:{endLoc},出库起点货位:{startLoc}");
|
bool batch = false;
|
var endCntr = db.Queryable<LocCntrRel>().Where(a => a.S_LOC_CODE == endLoc).First();
|
var startCntr = db.Queryable<LocCntrRel>().Where(a => a.S_LOC_CODE == startLoc).First();
|
if (endCntr != null && startCntr != null)
|
{
|
var endItem = db.Queryable<CntrItemRel>().Where(a => a.S_CNTR_CODE == endCntr.S_CNTR_CODE.Trim()).First();
|
var startItem = db.Queryable<CntrItemRel>().Where(a => a.S_CNTR_CODE == startCntr.S_CNTR_CODE.Trim()).First();
|
if (endItem != null && startItem != null && !string.IsNullOrEmpty(endItem.S_BATCH_NO))
|
{
|
if (endItem.S_BATCH_NO.Trim() != startItem.S_BATCH_NO.Trim())
|
batch = true;
|
}
|
//else //Console.WriteLine($"移库入库批次号判断:起点或终点 托盘物料表 为空!");
|
}
|
//else //Console.WriteLine($"移库入库批次号判断:起点或终点 托盘货位表 为空!");
|
|
return batch;
|
}
|
|
/// <summary>
|
/// 出库获取出库货位
|
/// </summary>
|
/// <param name="area"></param>
|
/// <param name="itemCode">如果itemCode是空表示空容器</param>
|
/// <param name="standardCarryQty">标准搬运数量</param>
|
/// <returns></returns>
|
/// <returns></returns>
|
public static Location GetYiKuLocationOut(string area, string row, string itemCode = "", string itemBatch = "", string itemLayer = "")
|
{
|
//Console.WriteLine($"移库任务出库计算:当前库区:{area},当前库位:{row}!");
|
LogHelper.Info($"移库任务出库计算:当前库区:{area},当前库位:{row}!", "WMSAlgoRithm");
|
Location result = null;
|
var db = new SqlHelper<Location>().GetInstance();
|
//itemCode = itemCode + itemLayer;
|
|
var list = db.Queryable<Location>().Where(a => a.N_CURRENT_NUM > 0 && a.S_AREA_CODE == area && a.N_ROW == row).OrderByDescending(a => a.N_COL).Take(1).First();
|
if (list != null)
|
{
|
result = list;
|
LogHelper.Info($"移库出库算法 起点货位={result.S_LOC_CODE}");
|
}
|
else
|
{
|
//Console.WriteLine($"移库任务出库计算异常:当前库位以及库区无可用货位!当前库区:{area},当前库位:{row}!");
|
LogHelper.Info($"移库任务出库计算异常:当前库位以及库区无可用货位!当前库区:{area},当前库位:{row}!", "WMSAlgoRithm");
|
}
|
return result;
|
}
|
|
/// <summary>
|
/// 出库获取空托出库货位
|
/// </summary>
|
/// <param name="area"></param>
|
/// <param name="itemCode">如果itemCode是空表示空容器</param>
|
/// <param name="standardCarryQty">标准搬运数量</param>
|
/// <returns></returns>
|
/// <returns></returns>
|
public static Location GetEmptyLocationOut(string area, string row, string trayType)
|
{
|
//Console.WriteLine($"空托任务出库计算:当前库区:{area},当前库位:{row}!");
|
LogHelper.Info($"空托任务出库计算:当前库区:{area},当前库位:{row}!", "WMSAlgoRithm");
|
Location result = null;
|
var db = new SqlHelper<Location>().GetInstance();
|
//itemCode = itemCode + itemLayer;
|
|
var list = db.Queryable<Location>().Where(a => a.N_CURRENT_NUM > 0 && a.S_AREA_CODE == area && a.N_ROW == row).OrderByDescending(a => a.N_COL).Take(1).First();
|
if (list != null)
|
{
|
string note = string.IsNullOrEmpty(list.S_NOTE) ? "" : list.S_NOTE.Trim();
|
if (string.IsNullOrEmpty(note) || note == trayType) result = list;
|
else LogHelper.Info($"空托任务出库计算异常:当前库位与所需托盘类型不一致。当前库区:{area},当前库位:{row}!所需托盘:{trayType},当前托盘:{note}", "WMSAlgoRithm");
|
}
|
else
|
{
|
//Console.WriteLine($"空托任务出库计算异常:当前库位以及库区无可用货位!当前库区:{area},当前库位:{row}!");
|
LogHelper.Info($"空托任务出库计算异常:当前库位以及库区无可用货位!当前库区:{area},当前库位:{row}!", "WMSAlgoRithm");
|
}
|
return result;
|
}
|
|
|
/// <summary>
|
/// 绑定货位容器表
|
/// </summary>
|
/// <param name="cntr"></param>
|
/// <returns></returns>
|
internal static bool BindLocCntr(string loc, string cntr, string itemCode, string batchNo, string deviceName = "", string itemlayer = "", string ItemTrayType = "")
|
{
|
bool result = true;
|
List<string> list = new List<string>(cntr.Split(','));
|
var db = new SqlHelper<object>().GetInstance();
|
list.ForEach(it =>
|
{
|
if (!string.IsNullOrEmpty(it))
|
{
|
string cntrCode = it.Trim();
|
LogHelper.Info($"查找货位{loc} 是否存在容器{cntrCode}的托盘");
|
var Cntr = db.Queryable<LocCntrRel>().Where(a => a.S_LOC_CODE == loc && a.S_CNTR_CODE == cntrCode).First();
|
if (Cntr == null)
|
{
|
LogHelper.Info("容器不存在准备插入");
|
var cir = new LocCntrRel { S_LOC_CODE = loc, S_CNTR_CODE = cntrCode, S_SRC = deviceName };
|
db.Insertable<LocCntrRel>(cir).ExecuteCommand();
|
LogHelper.Info($"容器插入成功");
|
IntensiveArea.BindCntrItem(cntrCode, itemCode, batchNo, itemlayer);
|
}
|
else
|
{
|
LogHelper.Info("容器已存在");
|
}
|
}
|
});
|
//1.0 查货位容器表
|
return result;
|
}
|
|
|
/// <summary>
|
/// 绑定容器物料表
|
/// </summary>
|
/// <param name="itemCode"></param>
|
/// <param name="batchNo"></param>
|
/// <param name="qty"></param>
|
/// <returns></returns>
|
internal static bool BindCntrItem(string trayCode, string itemCode, string batchNo, string itemlayer = "")
|
{
|
LogHelper.Info($"容器货品绑定 容器{trayCode}");
|
var res = false;
|
var db = new SqlHelper<object>().GetInstance();
|
try
|
{
|
db.BeginTran();
|
//db.Updateable(cntr).UpdateColumns(it => new { it.S_DEST }).ExecuteCommand();
|
//1.将原有容器物料信息删除
|
//db.Deleteable<CntrItemRel>().Where(it => it.S_CNTR_CODE == cntr.S_CNTR_CODE.Trim()).ExecuteCommand();
|
//2.插入新的容器物料信息(容器号不变)
|
LogHelper.Info($"查找容器货品绑定表中是否有相同容器号的物料");
|
var info = db.Queryable<CntrItemRel>().Where(a => a.S_CNTR_CODE == trayCode.Trim()).First();
|
if (info == null)
|
{
|
LogHelper.Info($"插入容器货品数据");
|
var cir = new CntrItemRel { S_CNTR_CODE = trayCode, S_BATCH_NO = batchNo, S_ITEM_CODE = itemCode, S_ITEM_MODEL = itemlayer };
|
db.Insertable(cir).ExecuteCommand();
|
LogHelper.Info($"插入成功");
|
}
|
else
|
{
|
LogHelper.Info($"托盘号重复");
|
}
|
|
|
db.Ado.CommitTran();
|
res = true;
|
}
|
catch (Exception ex)
|
{
|
db.Ado.RollbackTran();
|
}
|
return res;
|
}
|
|
/// <summary>
|
/// 任务创建时锁定排
|
/// </summary>
|
/// <param name="startRow"></param>
|
/// <param name="endRow"></param>
|
public static void LockRow(string startRow, string endRow, string SArea, string EArea, string taskType)
|
{
|
string startRowXB = startRow + "";
|
string endRowXB = endRow + "";
|
string SAreaXB = SArea + "";
|
string EAreaXB = EArea + "";
|
var db = new SqlHelper<object>().GetInstance();
|
string LockRow = "";
|
var Srow = db.Queryable<RowLock>().Where(a => a.N_ROW == startRow && a.S_AREA_CODE == SArea).First();
|
if (Srow != null && !Srow.S_LOCK_STATE.Trim().Contains("锁"))
|
{
|
Srow.S_LOCK_STATE = "出库锁";
|
db.Updateable(Srow).UpdateColumns(it => new { it.S_LOCK_STATE }).ExecuteCommand();
|
LockRow = LockRow + Srow.N_ROW.Trim().Replace("-XB", "") + ",";
|
}
|
var Erow = db.Queryable<RowLock>().Where(a => a.N_ROW == endRow && a.S_AREA_CODE == EArea).First();
|
if (Erow != null && !Erow.S_LOCK_STATE.Trim().Contains("锁"))
|
{
|
Erow.S_LOCK_STATE = "入库锁";
|
db.Updateable(Erow).UpdateColumns(it => new { it.S_LOCK_STATE }).ExecuteCommand();
|
LockRow = LockRow + Erow.N_ROW.Trim().Replace("-XB", "") + ",";
|
}
|
if (!string.IsNullOrEmpty(LockRow) && taskType.Contains("移库")) TaskProcess.AreaRowLockState(LockRow);//移库任务 回报富勒库位锁定
|
}
|
|
/// <summary>
|
/// 解锁排
|
/// </summary>
|
/// <param name="startRow"></param>
|
/// <param name="endRow"></param>
|
public static void UnLockRow(string bit, string taskType)
|
{
|
if (!taskType.Contains("移库"))
|
{
|
string rowNo = ""; string areaCode = "";
|
var db = new SqlHelper<object>().GetInstance();
|
|
var Sinfo = new SqlHelper<Location>().GetInstance().Queryable<Location>().Where(a => a.S_LOC_CODE == bit).First();
|
if (Sinfo != null)
|
{
|
rowNo = string.IsNullOrEmpty(Sinfo.N_ROW.Trim()) ? "" : Sinfo.N_ROW.ToString();
|
areaCode = string.IsNullOrEmpty(Sinfo.S_AREA_CODE.Trim()) ? "" : Sinfo.S_AREA_CODE.Trim();
|
var listRowLocks = db.Queryable<RowLock>().ToList();
|
var Srow = db.Queryable<RowLock>().Where(a => a.N_ROW == rowNo && a.S_AREA_CODE == areaCode).First();
|
if (Srow != null && Srow.S_LOCK_STATE.Trim().Contains("锁"))
|
{
|
Srow.S_LOCK_STATE = "无";
|
db.Updateable(Srow).UpdateColumns(it => new { it.S_LOCK_STATE }).ExecuteCommand();
|
//TaskProcess.AreaRowLockState(Srow.N_ROW.Trim(), false);//回报WMS库位锁定信息--暂不使用
|
}
|
}
|
else LogHelper.Info($"当前货位不存在于货位表,货位编码:{bit}", "WMSAlgoRithm");
|
}
|
}
|
|
/// <summary>
|
/// 更新工单移库数量
|
/// </summary>
|
/// <param name="mst"></param>
|
internal static void UpdateWorkNum(WMSTask mst)
|
{
|
var db = new SqlHelper<object>().GetInstance();
|
var workInfo = db.Queryable<WorkOrder>().Where(a => a.S_WorkNo == mst.S_SRC_NO.Trim()).First();
|
LogHelper.Info($"查询工单号为{mst.S_SRC_NO} 的移库工单");
|
if (workInfo != null)
|
{
|
LogHelper.Info($"找到移库工单 移库数量为{workInfo.S_YiKuNum}");
|
if (workInfo.S_YiKuNum != 9999 && workInfo.S_YiKuNum > 0)
|
{
|
workInfo.S_YiKuNum = workInfo.S_YiKuNum - 1;
|
LogHelper.Info($"修改移库数量为{workInfo.S_YiKuNum}");
|
db.Updateable(workInfo).UpdateColumns(a => new { a.S_YiKuNum }).ExecuteCommand();
|
}
|
}
|
else
|
{
|
//Console.WriteLine($"更新工单移库数量异常:未查询到此工单的信息,工单号:{mst.S_SRC_NO.Trim()}");
|
}
|
}
|
|
#endregion
|
|
#region 大明山出入库算法
|
|
/// <summary>
|
/// 注塑机入库 翻斗机入库
|
/// </summary>
|
/// <param name="plc"></param>
|
/// <param name="location">起点</param>
|
/// <param name="trayCode">托盘号</param>
|
/// <param name="batchNo">批次号</param>
|
/// <param name="v">true:注塑机入库 false:翻斗机入库</param>
|
/// <returns></returns>
|
public static bool DaMingShanPLCIn(Settings.deviceInfo plc, string location, string trayCode, string batchNo, PGWorkOrder workorder, bool v)
|
{
|
LogHelper.Info($"查询瓶坯满筐入库站点", "注塑机");
|
string endlocation = "";
|
var db = new SqlHelper<object>().GetInstance();
|
bool result = false;
|
//var info = Settings.GetDaMingShanPriProLineList().Where(a => a.deviceName == plc.deviceName && a.Enable == "1" && a.ItemTrayType == "满").FirstOrDefault();
|
var info = Settings.GetDaMingShanPriProLineList().Where(a => a.deviceName == workorder.S_LinkLineNo && a.Enable == "1" && a.ItemTrayType == "满").FirstOrDefault();
|
if (v)
|
{
|
//即产即用 优先送翻斗机缓存位
|
if (info != null)
|
{
|
string ItemName = workorder.S_ItemCode;
|
//查询对应终点的库位状态
|
if (info.ProductLocation.Count() > 0)
|
{
|
LogHelper.Info($"遍历查询缓存点的状态 result={result}", "注塑机");
|
foreach (var a in info.ProductLocation)
|
{
|
var endlocationinfo = db.Queryable<Location>().Where(b => b.S_LOC_CODE == a && b.N_CURRENT_NUM == 0 && b.S_LOCK_STATE.Trim() == "无").First();
|
if (endlocationinfo != null)
|
{
|
endlocation = endlocationinfo.S_LOC_CODE.Trim();
|
result = DaMingShanCreateTransport(location, endlocation, "注塑即产满筐下线(瓶坯)", trayCode, 1, 1, plc.deviceName, 1);
|
break;
|
}
|
}
|
}
|
LogHelper.Info($"遍历缓存点状态结束 result={result}");
|
//对应终点找不到空闲货位 从对应库区寻找空闲货位
|
if (!result)
|
{
|
LogHelper.Info($"遍历查询缓存区的状态 缓存区配置={JsonConvert.SerializeObject(info.ProductArea)}", "注塑机");
|
if (info.IsDense == 0)
|
{
|
for (int i = 0; i < info.ProductArea.Count(); i++)
|
{
|
string endarea = info.ProductArea[i];
|
LogHelper.Info($"查询满筐缓存位 是否有空货位 库区编码={endarea}");
|
var endLocation = db.Queryable<Location>().Where(a => a.S_AREA_CODE == endarea && a.N_CURRENT_NUM == 0 && a.S_LOCK_STATE.Trim() == "无").First();
|
if (endLocation != null)
|
{
|
var endLayer = endLocation.N_CURRENT_NUM + 1;
|
result = DaMingShanCreateTransport(location, endLocation.S_LOC_CODE, "注塑即产满筐下线(瓶坯)", trayCode, 1, endLayer, plc.deviceName, 1);
|
break;
|
}
|
}
|
}
|
else
|
{
|
for (int i = 0; i < info.ProductArea.Count(); i++)
|
{
|
string endarea = info.ProductArea[i];
|
var endbitlist = db.Queryable<Location>()
|
.Where(a => a.S_AREA_CODE == endarea && a.N_CURRENT_NUM == 0 && a.S_LOCK_STATE == "无")
|
.PartitionBy(a => a.N_OROW)
|
.Take(1)
|
.OrderBy(a => a.N_COL)
|
.ToList();
|
foreach (var item in endbitlist)
|
{
|
var lockinfo = db.Queryable<Location>().Where(a => a.S_AREA_CODE == item.S_AREA_CODE && a.N_ROW == item.N_ROW && a.S_LOCK_STATE != "无").First();
|
if (lockinfo == null)
|
{
|
var endLayer = item.N_CURRENT_NUM + 1;
|
result = DaMingShanCreateTransport(location, item.S_LOC_CODE, "注塑即产满筐下线(瓶坯)", trayCode, 1, endLayer, plc.deviceName, 1);
|
break;
|
}
|
}
|
if (result) break;
|
}
|
}
|
|
}
|
LogHelper.Info($"遍历缓存区状态结束 result={result}");
|
|
if (!result)
|
{
|
if (info.IsDense == 0)
|
{
|
var bitinfo = Settings.GetinStockCacheBitList().Where(a => a.deviceType == 3 && a.Enable == "1" && a.ItemTrayType == "满").FirstOrDefault();
|
if (bitinfo != null)
|
{
|
var locinfo = db.Queryable<Location>().Where(q => q.S_AREA_CODE == bitinfo.location && q.N_CURRENT_NUM == 0 && q.S_LOCK_STATE.Trim() == "无").First();
|
if (locinfo != null)
|
{
|
var endLayer = locinfo.N_CURRENT_NUM + 1;
|
result = DaMingShanCreateTransport(location, locinfo.S_LOC_CODE, "注塑即产满筐下线(瓶坯)", trayCode, 1, endLayer, plc.deviceName, 1);
|
}
|
}
|
}
|
|
}
|
LogHelper.Info($"遍历入库缓存位结束 result={result}");
|
|
if (result)
|
{
|
IntensiveArea.BindCntrItem(trayCode, ItemName, batchNo);
|
}
|
}
|
}
|
else
|
{
|
//非即产即用 直接入库缓存位 3+2
|
var bitinfo = Settings.GetinStockCacheBitList().Where(a => a.deviceType == 3 && a.Enable == "1" && a.ItemTrayType == "满").FirstOrDefault();
|
if (info != null && bitinfo != null)
|
{
|
string ItemName = info.ItemName;
|
var locinfo = db.Queryable<Location>().Where(a => a.S_AREA_CODE == bitinfo.location && a.N_CURRENT_NUM == 0 && a.S_LOCK_STATE == "无").OrderBy(a => a.N_COL).First();
|
if (locinfo != null)
|
{
|
var endLayer = locinfo.N_CURRENT_NUM + 1;
|
result = DaMingShanCreateTransport(location, locinfo.S_LOC_CODE, "注塑即产满筐下线(瓶坯)", trayCode, 1, endLayer, plc.deviceName, 1);
|
}
|
if (result)
|
{
|
IntensiveArea.BindCntrItem(trayCode, ItemName, batchNo);
|
}
|
}
|
}
|
return result;
|
}
|
|
/// <summary>
|
/// 瓶盖机入库
|
/// </summary>
|
/// <param name="plc"></param>
|
/// <param name="location">起点</param>
|
/// <param name="trayCode">托盘号</param>
|
/// <param name="batchNo">批次号</param>
|
/// <param name="v">true:即产即用 false:非即产即用</param>
|
/// <returns></returns>
|
public static bool DaMingShanPLCIn2(Settings.deviceInfo plc, string location, string trayCode, string batchNo, string itemcode, bool v)
|
{
|
LogHelper.Info($"查询瓶盖满筐入库站点", "瓶盖机");
|
string endlocation = "";
|
var db = new SqlHelper<object>().GetInstance();
|
bool result = false;
|
var info = Settings.GetDaMingShanPriProLineList().Where(a => a.deviceName == plc.deviceName && a.Enable == "1" && a.ItemTrayType == "满").FirstOrDefault();
|
if (v)
|
{
|
//即产即用 优先送翻斗机缓存位
|
if (info != null)
|
{
|
string ItemName = itemcode;
|
//查询对应终点的库位状态
|
if (info.ProductLocation.Count() > 0)
|
{
|
LogHelper.Info($"遍历查询缓存点的状态", "瓶盖机");
|
foreach (var a in info.ProductLocation)
|
{
|
var endlocationinfo = db.Queryable<Location>().Where(b => b.S_LOC_CODE == a).First();
|
if (endlocationinfo.N_CURRENT_NUM == 0 && endlocationinfo.S_LOCK_STATE.Trim() == "无")
|
{
|
endlocation = endlocationinfo.S_LOC_CODE.Trim();
|
result = DaMingShanCreateTransport(location, endlocation, "注塑即产满筐下线(瓶盖)", trayCode, 1, 1, plc.deviceName, 1);
|
break;
|
}
|
}
|
}
|
//对应终点找不到空闲货位 从对应库区寻找空闲货位
|
if (!result)
|
{
|
LogHelper.Info($"遍历查询缓存区的状态", "瓶盖机");
|
string endarea = info.ProductArea[0];
|
LogHelper.Info($"查询满筐缓存位 是否有空货位 库区编码={endarea}");
|
var endLocation = db.Queryable<Location>().Where(a => a.S_AREA_CODE == endarea && a.N_CURRENT_NUM == 0).First();
|
if (endLocation.S_LOCK_STATE.Trim() == "无")
|
{
|
var endLayer = endLocation.N_CURRENT_NUM + 1;
|
result = DaMingShanCreateTransport(location, endLocation.S_LOC_CODE, "注塑即产满筐下线(瓶盖)", trayCode, 1, endLayer, plc.deviceName, 1);
|
}
|
}
|
if (!result)
|
{
|
var bitinfo = Settings.GetinStockCacheBitList().Where(a => a.deviceType == 1 && a.Enable == "1" && a.ItemTrayType == "满").FirstOrDefault();
|
if (bitinfo != null)
|
{
|
var locinfo = db.Queryable<Location>().Where(q => q.S_LOC_CODE == bitinfo.location).First();
|
if (locinfo != null)
|
{
|
if (locinfo.S_LOCK_STATE == "无")
|
{
|
var endLayer = locinfo.N_CURRENT_NUM + 1;
|
result = DaMingShanCreateTransport(location, locinfo.S_LOC_CODE, "注塑即产满筐下线(瓶盖)", trayCode, 1, endLayer, plc.deviceName, 1);
|
}
|
}
|
}
|
}
|
if (result)
|
{
|
IntensiveArea.BindCntrItem(trayCode, ItemName, batchNo);
|
}
|
}
|
}
|
else
|
{
|
//非即产即用 直接入库缓存位 3+2
|
var bitinfo = Settings.GetinStockCacheBitList().Where(a => a.deviceType == 1 && a.Enable == "1" && a.ItemTrayType == "满").FirstOrDefault();
|
if (info != null && bitinfo != null)
|
{
|
string ItemName = info.ItemName;
|
var locinfo = db.Queryable<Location>().Where(q => q.S_LOC_CODE == bitinfo.location).First();
|
if (locinfo != null)
|
{
|
if (locinfo.S_LOCK_STATE == "无" && locinfo.N_CURRENT_NUM < locinfo.N_CAPACITY)
|
{
|
var endLayer = locinfo.N_CURRENT_NUM + 1;
|
result = DaMingShanCreateTransport(location, locinfo.S_LOC_CODE, "注塑即产满筐下线(瓶盖)", trayCode, 1, endLayer, plc.deviceName, 1);
|
}
|
}
|
if (result)
|
{
|
IntensiveArea.BindCntrItem(trayCode, ItemName, batchNo);
|
}
|
}
|
}
|
return result;
|
}
|
|
|
|
/// <summary>
|
/// 瓶盖翻斗机入库
|
/// </summary>
|
/// <param name="plc"></param>
|
/// <param name="location">起点</param>
|
/// <param name="trayCode">托盘号</param>
|
/// <param name="batchNo">批次号</param>
|
/// <param name="v">true:即产即用 false:非即产即用</param>
|
/// <returns></returns>
|
public static bool DaMingShanPLCIn3(Settings.deviceInfo plc, string location, string trayCode, string batchNo, bool v)
|
{
|
LogHelper.Info($"查询瓶盖翻斗机空筐入库站点", "翻斗机");
|
string endlocation = "";
|
var db = new SqlHelper<object>().GetInstance();
|
bool result = false;
|
var info = Settings.GetDaMingShanPriProLineList().Where(a => a.deviceName == plc.deviceName && a.Enable == "1" && a.ItemTrayType == "空").FirstOrDefault();
|
if (v)
|
{
|
//即产即用 优先送翻斗机缓存位
|
if (info != null)
|
{
|
//查询对应终点的库位状态
|
if (info.ProductLocation.Count() > 0)
|
{
|
LogHelper.Info($"遍历查询缓存点的状态", "翻斗机");
|
foreach (var a in info.ProductLocation)
|
{
|
var endlocationinfo = db.Queryable<Location>().Where(b => b.S_LOC_CODE == a).First();
|
if (endlocationinfo != null)
|
{
|
if (endlocationinfo.N_CURRENT_NUM == 0 && endlocationinfo.S_LOCK_STATE.Trim() == "无")
|
{
|
endlocation = endlocationinfo.S_LOC_CODE.Trim();
|
result = DaMingShanCreateTransport(location, endlocation, "翻斗机即产空筐下线(瓶盖)", trayCode, 1, 1, plc.deviceName, 1);
|
break;
|
}
|
}
|
}
|
}
|
//对应终点找不到空闲货位 从对应库区寻找空闲货位
|
if (!result)
|
{
|
LogHelper.Info($"遍历查询缓存区的状态", "翻斗机");
|
string endarea = info.ProductArea[0];
|
LogHelper.Info($"查询空筐筐缓存位 是否有空货位 库区编码={endarea}");
|
|
var endlocationlist = db.Queryable<Location>()
|
.Where(a => a.S_AREA_CODE == endarea && a.N_CURRENT_NUM < a.N_CAPACITY)
|
.PartitionBy(a => a.N_ROW)
|
.Take(1)
|
.OrderBy(a => a.N_COL)
|
.OrderBy(a => a.N_OROW)
|
.ToList();
|
|
foreach (var item in endlocationlist)
|
{
|
var lockinfo = db.Queryable<Location>().Where(a => a.S_AREA_CODE == item.S_AREA_CODE && a.N_ROW == item.N_ROW && a.S_LOCK_STATE != "无").First();
|
if (lockinfo == null)
|
{
|
var endLayer = item.N_CURRENT_NUM + 1;
|
result = DaMingShanCreateTransport(location, item.S_LOC_CODE, "翻斗机即产空筐下线(瓶盖)", trayCode, 1, endLayer, plc.deviceName, 1);
|
break;
|
}
|
}
|
|
//var endLocation = db.Queryable<Location>().Where(a => a.S_AREA_CODE == endarea && a.N_CURRENT_NUM == 0).First();
|
//if (endLocation.S_LOCK_STATE.Trim() == "无")
|
//{
|
//
|
//}
|
}
|
if (!result)
|
{
|
var bitinfo = Settings.GetinStockCacheBitList().Where(a => a.deviceType == 2 && a.Enable == "1" && a.ItemTrayType == "空").FirstOrDefault();
|
if (bitinfo != null)
|
{
|
var endarea = bitinfo.ProductArea[0];
|
var endbitlist = db.Queryable<Location>().Where(a => a.S_AREA_CODE == endarea && a.N_CURRENT_NUM == 0)
|
.PartitionBy(a => a.N_ROW)
|
.OrderBy(a => a.N_COL)
|
.Take(1)
|
.ToList();
|
foreach (var item in endbitlist)
|
{
|
var lockinfo = db.Queryable<Location>().Where(a => a.S_AREA_CODE == item.S_AREA_CODE && a.N_ROW == a.N_ROW && a.S_LOCK_STATE != "无").First();
|
if (lockinfo == null)
|
{
|
var endLayer = item.N_CURRENT_NUM + 1;
|
result = DaMingShanCreateTransport(location, item.S_LOC_CODE, "翻斗机即产空筐下线(瓶盖)", trayCode, 1, endLayer, plc.deviceName, 1);
|
break;
|
}
|
}
|
}
|
}
|
if (result)
|
{
|
IntensiveArea.UnBindLocCntr(trayCode);
|
}
|
}
|
}
|
else
|
{
|
//非即产即用 直接入库缓存位 3+2
|
var bitinfo = Settings.GetinStockCacheBitList().Where(a => a.deviceType == 2 && a.Enable == "1" && a.ItemTrayType == "空").FirstOrDefault();
|
if (info != null && bitinfo != null)
|
{
|
//var bitinfo = Settings.GetinStockCacheBitList().Where(a => a.deviceType == 2 && a.Enable == "1" && a.ItemTrayType == "空").FirstOrDefault();
|
if (bitinfo != null)
|
{
|
var endarea = bitinfo.ProductArea[0];
|
var endbitlist = db.Queryable<Location>().Where(a => a.S_AREA_CODE == endarea && a.N_CURRENT_NUM <a.N_CAPACITY)
|
.PartitionBy(a => a.N_ROW)
|
.OrderBy(a => a.N_COL)
|
.Take(1)
|
.ToList();
|
foreach (var item in endbitlist)
|
{
|
var lockinfo = db.Queryable<Location>().Where(a => a.S_AREA_CODE == item.S_AREA_CODE && a.N_ROW == a.N_ROW && a.S_LOCK_STATE != "无").First();
|
if (lockinfo == null)
|
{
|
var endLayer = item.N_CURRENT_NUM + 1;
|
result = DaMingShanCreateTransport(location, item.S_LOC_CODE, "翻斗机即产空筐下线(瓶盖)", trayCode, 1, endLayer, plc.deviceName, 1);
|
break;
|
}
|
}
|
}
|
if (result)
|
{
|
IntensiveArea.UnBindLocCntr(trayCode);
|
}
|
}
|
}
|
return result;
|
}
|
|
/// <summary>
|
/// 瓶坯翻斗机入库
|
/// </summary>
|
/// <param name="plc"></param>
|
/// <param name="location">起点</param>
|
/// <param name="trayCode">托盘号</param>
|
/// <param name="batchNo">批次号</param>
|
/// <param name="v">true:即产即用 false:非即产即用</param>
|
/// <returns></returns>
|
public static bool DaMingShanPLCIn4(Settings.deviceInfo plc, string location, string trayCode, PGWorkOrder workorder, bool v)
|
{
|
LogHelper.Info($"查询瓶坯翻斗机空筐入库站点", "翻斗机");
|
string endlocation = "";
|
var db = new SqlHelper<object>().GetInstance();
|
bool result = false;
|
//var info = Settings.GetDaMingShanPriProLineList().Where(a => a.deviceName == plc.deviceName && a.Enable == "1" && a.ItemTrayType == "空").FirstOrDefault();
|
var info = Settings.GetDaMingShanPriProLineList().Where(a => a.deviceName == workorder.S_LinkLineNo && a.Enable == "1" && a.ItemTrayType == "空").FirstOrDefault();
|
|
if (v)
|
{
|
//即产即用 优先送翻斗机缓存位
|
if (info != null)
|
{
|
//查询对应终点的库位状态
|
if (info.ProductLocation.Count() > 0)
|
{
|
LogHelper.Info($"遍历查询缓存点的状态", "翻斗机");
|
foreach (var a in info.ProductLocation)
|
{
|
var endlocationinfo = db.Queryable<Location>().Where(b => b.S_LOC_CODE == a).First();
|
if (endlocationinfo != null)
|
{
|
if (endlocationinfo.N_CURRENT_NUM == 0 && endlocationinfo.S_LOCK_STATE.Trim() == "无")
|
{
|
endlocation = endlocationinfo.S_LOC_CODE.Trim();
|
result = DaMingShanCreateTransport(location, endlocation, "翻斗机即产空筐下线(瓶坯)", trayCode, 1, 1, plc.deviceName, 1);
|
break;
|
}
|
}
|
}
|
}
|
//对应终点找不到空闲货位 从对应库区寻找空闲货位
|
if (!result)
|
{
|
LogHelper.Info($"遍历查询缓存区的状态", "翻斗机");
|
string endarea = info.ProductArea[0];
|
LogHelper.Info($"查询空筐筐缓存位 是否有空货位 库区编码={endarea}");
|
|
var endlocationlist = db.Queryable<Location>()
|
.Where(a => a.S_AREA_CODE == endarea && a.N_CURRENT_NUM == 0)
|
.PartitionBy(a => a.N_ROW)
|
.Take(1)
|
.OrderBy(a => a.N_COL)
|
.OrderBy(a => a.N_OROW)
|
.ToList();
|
|
foreach (var item in endlocationlist)
|
{
|
var lockinfo = db.Queryable<Location>().Where(a => a.S_AREA_CODE == item.S_AREA_CODE && a.N_ROW == item.N_ROW && a.S_LOCK_STATE != "无").First();
|
if (lockinfo == null)
|
{
|
var endLayer = item.N_CURRENT_NUM + 1;
|
result = DaMingShanCreateTransport(location, item.S_LOC_CODE, "翻斗机即产空筐下线(瓶坯)", trayCode, 1, endLayer, plc.deviceName, 1);
|
break;
|
}
|
}
|
|
//LogHelper.Info($"遍历查询缓存区的状态", "翻斗机");
|
//for (int i = 0; i < info.ProductArea.Count(); i++)
|
//{
|
// string endarea = info.ProductArea[i];
|
// LogHelper.Info($"查询空筐筐缓存位 是否有空货位 库区编码={endarea}");
|
// var endLocation = db.Queryable<Location>().Where(a => a.S_AREA_CODE == endarea && a.N_CURRENT_NUM == 0 && a.S_LOCK_STATE.Trim() == "无").First();
|
// if (endlocation != null)
|
// {
|
// var endLayer = endLocation.N_CURRENT_NUM + 1;
|
// result = DaMingShanCreateTransport(location, endLocation.S_LOC_CODE, "翻斗机即产空筐下线(瓶坯)", trayCode, 1, endLayer, plc.deviceName, 1);
|
// break;
|
// }
|
//}
|
}
|
if (!result)
|
{
|
var bitinfo = Settings.GetinStockCacheBitList().Where(a => a.deviceType == 4 && a.Enable == "1" && a.ItemTrayType == "空").FirstOrDefault();
|
if (bitinfo != null)
|
{
|
var locinfo = db.Queryable<Location>().Where(q => q.S_AREA_CODE == bitinfo.location && q.N_CURRENT_NUM == 0 && q.S_LOCK_STATE.Trim() == "无").First();
|
if (locinfo != null)
|
{
|
var endLayer = locinfo.N_CURRENT_NUM + 1;
|
result = DaMingShanCreateTransport(location, locinfo.S_LOC_CODE, "翻斗机即产空筐下线(瓶坯)", trayCode, 1, endLayer, plc.deviceName, 1);
|
}
|
}
|
}
|
if (result)
|
{
|
IntensiveArea.UnBindLocCntr(trayCode);
|
}
|
}
|
}
|
else
|
{
|
//非即产即用 直接入库缓存位 3+2
|
var bitinfo = Settings.GetinStockCacheBitList().Where(a => a.deviceType == 4 && a.Enable == "1" && a.ItemTrayType == "空").FirstOrDefault();
|
if (info != null && bitinfo != null)
|
{
|
string ItemName = info.ItemName;
|
var locinfo = db.Queryable<Location>().Where(a => a.S_AREA_CODE == bitinfo.location && a.N_CURRENT_NUM == 0 && a.S_LOCK_STATE == "无").OrderBy(a => a.N_COL).First();
|
if (locinfo != null)
|
{
|
var endLayer = locinfo.N_CURRENT_NUM + 1;
|
result = DaMingShanCreateTransport(location, locinfo.S_LOC_CODE, "翻斗机即产空筐下线(瓶坯)", trayCode, 1, endLayer, plc.deviceName, 1);
|
}
|
if (result)
|
{
|
IntensiveArea.UnBindLocCntr(trayCode);
|
}
|
}
|
}
|
return result;
|
}
|
|
|
/// <summary>
|
/// 解绑物料信息
|
/// </summary>
|
/// <param name="location"></param>
|
/// <param name="trayCode"></param>
|
/// <param name="itemName"></param>
|
/// <param name="batchNo"></param>
|
/// <exception cref="NotImplementedException"></exception>
|
private static bool UnBindLocCntr(string trayCode)
|
{
|
bool result = true;
|
List<string> list = new List<string>(trayCode.Split(','));
|
var db = new SqlHelper<object>().GetInstance();
|
for (int i = 0; i < list.Count; i++)
|
{
|
if (db.Queryable<CntrItemRel>().Count(a => a.S_CNTR_CODE.Trim() == list[i]) > 0)
|
{
|
db.Deleteable<CntrItemRel>().Where(a => a.S_CNTR_CODE == list[i]).ExecuteCommand();
|
}
|
}
|
//1.0 查货位容器表
|
return result;
|
}
|
|
|
/// <summary>
|
/// 创建搬运任务
|
/// </summary>
|
/// <param name="start"></param>
|
/// <param name="end"></param>
|
/// <param name="taskType"></param>
|
/// <param name="cntrs"></param>
|
/// <param name="startLayer"></param>
|
/// <param name="endLayer"></param>
|
/// <param name="trayCarryCount"></param>
|
/// <param name="priority"></param>
|
/// <returns></returns>
|
public static bool DaMingShanCreateTransport(string start, string end, string taskType, string cntrs, int startLayer, int endLayer, string deviceName, int trayCarryCount = 1, int priority = 1, int itemLayer = 0, string workNo = "", string batch = "", string itemcode = "", string traytype = "")
|
{
|
var db = new SqlHelper<object>().GetInstance();
|
var result = false;
|
var taskNo = DateTime.Now.Ticks.ToString();
|
var res = TaskHelper.DaMingShanCreateTask(taskNo, start.Trim(), end.Trim(), taskType, priority, cntrs, deviceName, trayCarryCount, startLayer, endLayer, itemLayer, workNo, batch, itemcode, traytype);
|
if (res)
|
{
|
result = true;
|
//任务创建成功,起点货位出库锁定,终点货位入库锁定
|
LocationHelper.LockLoc(start, "出库锁");
|
LocationHelper.LockLoc(end, "入库锁");
|
if (taskType == "成品下线" && Settings.FULEenable == "1")
|
{
|
//IntensiveArea.SLlock(end);
|
//成品下线任务生成成功,删除当前下线托盘中间表数据
|
List<string> cntr = cntrs.Split(',').ToList();
|
|
db.Deleteable<DaMingShanDeviceState>().Where(a => a.DeviceName.Trim() == deviceName).ExecuteCommand();
|
db.Deleteable<DaMingShanTrayInfo>().Where(it => cntr.Contains(it.trayCode)).ExecuteCommand();// && it.workNo == workNo.Trim()
|
}
|
|
}
|
else
|
{
|
if (taskType == "成品下线" && Settings.FULEenable == "1")
|
{
|
db.Deleteable<DaMingShanDeviceState>().Where(a => a.DeviceName.Trim() == deviceName).ExecuteCommand();
|
}
|
}
|
return result;
|
}
|
|
private static void SLlock(string end)
|
{
|
if (Settings.FULEenable == "1")
|
{
|
var db = new SqlHelper<object>().GetInstance();
|
var info = db.Queryable<Location>().Where(a => a.S_LOC_CODE == end).First();
|
if (info != null)
|
{
|
TaskProcess.AreaRowLockState(info.N_ROW);
|
}
|
}
|
}
|
|
public static void ULlock(string end)
|
{
|
if (Settings.FULEenable == "1")
|
{
|
var db = new SqlHelper<object>().GetInstance();
|
var info = db.Queryable<Location>().Where(a => a.S_LOC_CODE == end).First();
|
if (info != null)
|
{
|
TaskProcess.AreaRowLockState(info.N_ROW, false);
|
}
|
}
|
|
}
|
|
|
|
/// <summary>
|
/// 缓存位入库
|
/// </summary>
|
/// <param name="area"></param>
|
/// <param name="itemCode">如果itemCode是空表示空容器</param>
|
/// <param name="standardCarryQty">标准搬运数量</param>
|
/// <returns></returns>
|
public static Location DaMingShanGetCacheLocationIn(string area)
|
{
|
//库区货位约定:列号越小越靠里
|
Location result = null;
|
try
|
{
|
//1.1 查到所有有容器的排
|
var db = new SqlHelper<object>().GetInstance();
|
var list = db.Queryable<Location>().Where(a => a.S_AREA_CODE == area).ToList();
|
LogHelper.Info($"查询库区{area} 的货位数量为{list.Count()}");
|
if (list.Count > 0)
|
{
|
foreach (var a in list)
|
{
|
if (a.N_CURRENT_NUM == 0 && a.S_LOCK_STATE.Trim() == "无")
|
{
|
result = a;
|
break;
|
}
|
}
|
}
|
}
|
catch (Exception ex)
|
{
|
|
//Console.WriteLine("GetLocationIn:" + ex.Message + ex.StackTrace);
|
LogHelper.Error("GetLocationIn:" + ex.Message, ex);
|
}
|
return result;
|
}
|
|
/// <summary>
|
/// 输送线叫空托
|
/// </summary>
|
/// <param name="areaCode"></param>
|
/// <returns></returns>
|
internal static Location GetEmptyOut(string areaCode, string traytype)
|
{
|
LogHelper.Info($"输送线:空托库区出库算法开始", "输送线");
|
Location result = null;
|
var list = new SqlHelper<Location>().GetInstance().Queryable<Location>().Where(a => a.S_AREA_CODE == areaCode && a.N_CURRENT_NUM > 0).Includes(a => a.LocCntrRel).OrderByDescending(a => a.N_COL).Take(1).PartitionBy(a => a.N_ROW).ToList();
|
LogHelper.Info($"输送线:该库区可用库位数量为{list.Count}", "输送线");
|
for (int i = 0; i < list.Count; i++)
|
{
|
if (list[i].LocCntrRel != null)
|
{
|
LogHelper.Info($"判断货位{list[i].S_LOC_CODE} 板型{list[i].LocCntrRel.S_TRAY_TYPE} 与工单板型{traytype} 是否一致");
|
if (list[i].LocCntrRel.S_TRAY_TYPE == traytype)
|
{
|
LogHelper.Info($"输送线:库位{list[i].S_LOC_CODE} 判断是否有锁:{list[i].S_LOCK_STATE.Trim()}", "输送线");
|
if (list[i].S_LOCK_STATE.Trim() == "无")
|
{
|
result = list[i];
|
break;
|
}
|
}
|
|
}
|
|
}
|
return result;
|
}
|
|
/// <summary>
|
/// 缓存位出库
|
/// </summary>
|
/// <param name="area"></param>
|
/// <param name="itemCode">如果itemCode是空表示空容器</param>
|
/// <param name="standardCarryQty">标准搬运数量</param>
|
/// <returns></returns>
|
public static Location DaMingShanGetCacheLocationOut(string area)
|
{
|
//库区货位约定:列号越小越靠里
|
Location result = null;
|
try
|
{
|
//1.1 查到所有有容器的排
|
LogHelper.Info($"查询{area}库区所有的货位");
|
var db = new SqlHelper<object>().GetInstance();
|
var trayList = new List<LocCntrRel>();
|
var list = db.Queryable<Location>().Where(a => a.S_AREA_CODE.Trim() == area && a.N_CURRENT_NUM > 0 && a.S_LOCK_STATE.Trim() == "无").ToList();
|
LogHelper.Info($"货位数量为{list.Count()}");
|
if (list.Count > 0)
|
{
|
foreach (var a in list)
|
{
|
//if (a.N_CURRENT_NUM > 0 && a.S_LOCK_STATE.Trim() == "无")
|
//{
|
//result = a;
|
var trayNo = LocationHelper.GetLocCntrRel(a.S_LOC_CODE);
|
if (trayNo != null)
|
{
|
foreach (var item in trayNo)
|
{
|
trayList.Add(item);
|
}
|
}
|
//break;
|
//}
|
}
|
if (trayList.Count > 0)
|
{
|
var cntr = trayList.OrderBy(a => a.T_CREATE).First();
|
result = db.Queryable<Location>().Where(a => a.S_LOC_CODE == cntr.S_LOC_CODE).Includes(a => a.LocCntrRel).First();
|
}
|
}
|
LogHelper.Info($"算法结束 结果{result != null}");
|
}
|
catch (Exception ex)
|
{
|
|
//Console.WriteLine("GetLocationIn:" + ex.Message + ex.StackTrace);
|
LogHelper.Error("GetLocationIn:" + ex.Message, ex);
|
}
|
return result;
|
}
|
|
/// <summary>
|
/// 缓存位出库
|
/// </summary>
|
/// <param name="area"></param>
|
/// <param name="itemCode">如果itemCode是空表示空容器</param>
|
/// <param name="standardCarryQty">标准搬运数量</param>
|
/// <returns></returns>
|
public static Location DaMingShanGetCacheLocationOut2(string area, string itemcode)
|
{
|
//库区货位约定:列号越小越靠里
|
Location result = null;
|
try
|
{
|
//1.1 查到所有有容器的排
|
LogHelper.Info($"查询{area}库区所有的货位");
|
var db = new SqlHelper<object>().GetInstance();
|
var list = db.Queryable<Location>().Where(a => a.S_AREA_CODE.Trim() == area).Includes(a => a.LocCntrRel, a => a.CntrItemRel).ToList();
|
LogHelper.Info($"货位数量为{list.Count()}");
|
if (list.Count > 0)
|
{
|
foreach (var a in list)
|
{
|
if (a.N_CURRENT_NUM > 0 && a.S_LOCK_STATE.Trim() == "无" && a.LocCntrRel.CntrItemRel.S_ITEM_CODE == itemcode)
|
{
|
result = a;
|
break;
|
}
|
}
|
}
|
LogHelper.Info($"算法结束 结果{result != null}");
|
}
|
catch (Exception ex)
|
{
|
|
//Console.WriteLine("GetLocationIn:" + ex.Message + ex.StackTrace);
|
LogHelper.Error("GetLocationIn:" + ex.Message, ex);
|
}
|
return result;
|
}
|
|
/// <summary>
|
/// 注塑机出库、翻斗机出库
|
/// </summary>
|
/// <param name="plc"></param>
|
/// <param name="location"></param>
|
/// <param name="v">true:注塑机 false:翻斗机</param>
|
/// <returns></returns>
|
internal static bool DaMingShanPLCOut(Settings.deviceInfo plc, string location, bool v, PGWorkOrder workOrder)
|
{
|
string startlocation = "";
|
var tasktype = "";
|
var db = new SqlHelper<object>().GetInstance();
|
bool result = false;
|
if (v)
|
{
|
//注塑机出库
|
var info = Settings.GetDaMingShanPriProLineList().Where(a => a.deviceName == workOrder.S_LinkLineNo && a.Enable == "1" && a.ItemTrayType == "空").FirstOrDefault();
|
if (info != null)
|
{
|
//瓶盖机即产即用
|
if (info != null)
|
{
|
string ItemName = info.ItemName;
|
if (workOrder.S_UsingNow == "Y")
|
{
|
tasktype = "注塑即产空筐上线(瓶胚)";
|
}
|
else
|
{
|
tasktype = "注塑库存空筐上线(瓶胚)";
|
}
|
//查询对应终点的库位状态
|
if (info.ProductLocation.Count() > 0)
|
{
|
foreach (var a in info.ProductLocation)
|
{
|
var startlocationinfo = db.Queryable<Location>().Where(b => b.S_LOC_CODE == a).First();
|
if (startlocationinfo != null)
|
{
|
if (startlocationinfo.N_CURRENT_NUM > 0 && startlocationinfo.S_LOCK_STATE.Trim() == "无")
|
{
|
startlocation = startlocationinfo.S_LOC_CODE.Trim();
|
result = DaMingShanCreateTransport(startlocation, location, tasktype, startlocationinfo.LocCntrRel.S_CNTR_CODE, 1, 1, plc.deviceName, 1);
|
break;
|
}
|
}
|
}
|
}
|
//对应终点找不到空闲货位 从对应库区寻找货位
|
if (!result)
|
{
|
if (info.IsDense == 0)
|
{
|
foreach (var item in info.ProductArea)
|
{
|
var startLocation = DaMingShanGetCacheLocationOut(item);
|
if (startLocation != null)
|
{
|
var cntrList = LocationHelper.GetLocCntrRel(startLocation.S_LOC_CODE.Trim());
|
//淳安两个托盘为 一个 货位当前容量
|
var trayInfo = new LocCntrRel();
|
if (cntrList.Count >= 1)
|
{
|
//string cntrs = "";
|
trayInfo = cntrList.OrderByDescending(a => a.T_CREATE).Take(1).First();//单托出库
|
}
|
result = DaMingShanCreateTransport(startLocation.S_LOC_CODE, location, tasktype, trayInfo.S_CNTR_CODE, 1, 1, plc.deviceName, 1);
|
break;
|
}
|
}
|
}
|
else
|
{
|
for (int i = 0; i < info.ProductArea.Count(); i++)
|
{
|
string startarea = info.ProductArea[i];
|
var startbitlist = db.Queryable<Location>()
|
.Where(a => a.S_AREA_CODE == startarea && a.N_CURRENT_NUM > 0 && a.S_LOCK_STATE == "无")
|
.PartitionBy(a => a.N_OROW)
|
.Take(1)
|
.OrderByDescending(a => a.N_COL)
|
.ToList();
|
foreach (var item in startbitlist)
|
{
|
var lockinfo = db.Queryable<Location>().Where(a => a.S_AREA_CODE == item.S_AREA_CODE && a.N_ROW == item.N_ROW && a.S_LOCK_STATE != "无").First();
|
if (lockinfo == null)
|
{
|
var cntrList = LocationHelper.GetLocCntrRel(item.S_LOC_CODE.Trim());
|
//淳安两个托盘为 一个 货位当前容量
|
var trayInfo = new LocCntrRel();
|
if (cntrList.Count >= 1)
|
{
|
//string cntrs = "";
|
trayInfo = cntrList.OrderByDescending(a => a.T_CREATE).Take(1).First();//单托出库
|
}
|
result = DaMingShanCreateTransport(item.S_LOC_CODE, location, tasktype, trayInfo.S_CNTR_CODE, 1, 1, plc.deviceName, 1);
|
break;
|
}
|
}
|
if (result) break;
|
}
|
}
|
|
}
|
}
|
}
|
}
|
//else
|
//{
|
// //翻斗机入库
|
// LogHelper.Info($"翻斗机补满筐");
|
// var info = Settings.GetDaMingShanPriProLineList().Where(a => a.deviceName == plc.deviceName && a.Enable == "1" && a.ItemTrayType == "满").FirstOrDefault();
|
// if (info != null)
|
// {
|
// LogHelper.Info($"查询到满筐缓存区信息 location={JsonConvert.SerializeObject(info.ProductLocation)} area={JsonConvert.SerializeObject(info.ProductArea)}");
|
// string ItemName = info.ItemName;
|
// //查询对应终点的库位状态
|
// if (info.ProductLocation.Count() > 0)
|
// {
|
// foreach (var a in info.ProductLocation)
|
// {
|
// var startlocationinfo = db.Queryable<Location>().Where(b => b.S_LOC_CODE == a).First();
|
// if (startlocationinfo != null)
|
// {
|
// if (startlocationinfo.N_CURRENT_NUM > 0 && startlocationinfo.S_LOCK_STATE.Trim() == "无")
|
// {
|
// startlocation = startlocationinfo.S_LOC_CODE.Trim();
|
// result = DaMingShanCreateTransport(startlocation, location, "翻斗机补满筐", startlocationinfo.LocCntrRel.S_CNTR_CODE, 1, 1, plc.deviceName, 1, 1, 1);
|
// break;
|
// }
|
// }
|
// }
|
// }
|
// //对应终点找不到空闲货位 从对应库区寻找货位
|
// if (!result)
|
// {
|
// LogHelper.Info($"查询满筐缓存区");
|
// foreach (var item in info.ProductArea)
|
// {
|
// var startLocation = DaMingShanGetCacheLocationOut(item);
|
// if (startLocation != null)
|
// {
|
// var startlocationinfo = db.Queryable<Location>().Where(b => b.S_LOC_CODE == startLocation.S_LOC_CODE).Includes(a => a.LocCntrRel, a => a.CntrItemRel).First();
|
// result = DaMingShanCreateTransport(startLocation.S_LOC_CODE, location, "翻斗机补满筐", startlocationinfo.LocCntrRel.S_CNTR_CODE, 1, 1, plc.deviceName, 1, 1, 1);
|
// break;
|
// }
|
// }
|
// }
|
// }
|
//}
|
return result;
|
}
|
|
|
/// <summary>
|
/// 瓶坯翻斗机 瓶盖翻斗机
|
/// </summary>
|
/// <param name="plc"></param>
|
/// <param name="location"></param>
|
/// <param name="v">true:注塑机 false:翻斗机</param>
|
/// <returns></returns>
|
internal static bool DaMingShanPLCOut3(Settings.deviceInfo plc, string location, bool v, PGWorkOrder workorder)
|
{
|
string startlocation = "";
|
var tasktype = "";
|
var db = new SqlHelper<object>().GetInstance();
|
bool result = false;
|
if (v)
|
{
|
//注塑翻斗机叫料
|
var info = Settings.GetDaMingShanPriProLineList().Where(a => a.deviceName == workorder.S_LinkLineNo && a.Enable == "1" && a.ItemTrayType == "满").FirstOrDefault();
|
if (info != null)
|
{
|
LogHelper.Info($"查询到满筐缓存区信息 location={JsonConvert.SerializeObject(info.ProductLocation)} area={JsonConvert.SerializeObject(info.ProductArea)}");
|
string ItemName = info.ItemName;
|
if (workorder.S_UsingNow == "Y")
|
{
|
tasktype = "翻斗机即产满筐上线(瓶胚)";
|
}
|
else
|
{
|
tasktype = "翻斗机库存满筐上线(瓶胚)";
|
}
|
//查询对应终点的库位状态
|
if (info.ProductLocation.Count() > 0)
|
{
|
foreach (var a in info.ProductLocation)
|
{
|
var startlocationinfo = db.Queryable<Location>().Where(b => b.S_LOC_CODE == a).First();
|
if (startlocationinfo != null)
|
{
|
if (startlocationinfo.N_CURRENT_NUM > 0 && startlocationinfo.S_LOCK_STATE.Trim() == "无")
|
{
|
startlocation = startlocationinfo.S_LOC_CODE.Trim();
|
result = DaMingShanCreateTransport(startlocation, location, tasktype, startlocationinfo.LocCntrRel.S_CNTR_CODE, startlocationinfo.N_CURRENT_NUM, 1, plc.deviceName, 1, 1, 1);
|
break;
|
}
|
}
|
}
|
}
|
//对应终点找不到空闲货位 从对应库区寻找货位
|
if (!result)
|
{
|
LogHelper.Info($"查询满筐缓存区");
|
foreach (var item in info.ProductArea)
|
{
|
Location startLocation = null;
|
if (plc.deviceName != "Y9坯" && plc.deviceName != "Y7盖")
|
{
|
startLocation = DaMingShanGetCacheLocationOut(item);
|
}
|
else
|
{
|
//起点密集型
|
startLocation = DaMingShanGetCacheLocationOut1(item);
|
}
|
if (startLocation != null)
|
{
|
var startlocationinfo = db.Queryable<Location>().Where(b => b.S_LOC_CODE == startLocation.S_LOC_CODE).Includes(a => a.LocCntrRel, a => a.CntrItemRel).First();
|
result = DaMingShanCreateTransport(startLocation.S_LOC_CODE, location, tasktype, startlocationinfo.LocCntrRel.S_CNTR_CODE, startlocationinfo.N_CURRENT_NUM, 1, plc.deviceName, 1, 1, 1);
|
break;
|
}
|
}
|
}
|
}
|
}
|
else
|
{
|
//瓶盖翻斗机叫料
|
LogHelper.Info($"翻斗机补满筐");
|
var info = Settings.GetDaMingShanPriProLineList().Where(a => a.deviceName == plc.deviceName && a.Enable == "1" && a.ItemTrayType == "满").FirstOrDefault();
|
if (info != null)
|
{
|
LogHelper.Info($"查询到满筐缓存区信息 location={JsonConvert.SerializeObject(info.ProductLocation)} area={JsonConvert.SerializeObject(info.ProductArea)}");
|
string ItemName = info.ItemName;
|
if (workorder.S_UsingNow == "Y")
|
{
|
tasktype = "翻斗机即产满筐上线(瓶盖)";
|
}
|
else
|
{
|
tasktype = "翻斗机库存满筐上线(瓶盖)";
|
}
|
//查询对应终点的库位状态
|
if (info.ProductLocation.Count() > 0)
|
{
|
foreach (var a in info.ProductLocation)
|
{
|
var startlocationinfo = db.Queryable<Location>().Where(b => b.S_LOC_CODE == a).First();
|
if (startlocationinfo != null)
|
{
|
if (startlocationinfo.N_CURRENT_NUM > 0 && startlocationinfo.S_LOCK_STATE.Trim() == "无")
|
{
|
startlocation = startlocationinfo.S_LOC_CODE.Trim();
|
result = DaMingShanCreateTransport(startlocation, location, tasktype, startlocationinfo.LocCntrRel.S_CNTR_CODE, startlocationinfo.N_CURRENT_NUM, 1, plc.deviceName, 1, 1, 1);
|
break;
|
}
|
}
|
}
|
}
|
//对应终点找不到空闲货位 从对应库区寻找货位
|
if (!result)
|
{
|
LogHelper.Info($"查询满筐缓存区");
|
foreach (var item in info.ProductArea)
|
{
|
Location startLocation = null;
|
if (plc.deviceName != "Y9坯" && plc.deviceName != "Y7盖")
|
{
|
startLocation = DaMingShanGetCacheLocationOut(item);
|
}
|
else
|
{
|
//起点密集型
|
startLocation = DaMingShanGetCacheLocationOut1(item);
|
}
|
if (startLocation != null)
|
{
|
var startlocationinfo = db.Queryable<Location>().Where(b => b.S_LOC_CODE == startLocation.S_LOC_CODE).Includes(a => a.LocCntrRel, a => a.CntrItemRel).First();
|
result = DaMingShanCreateTransport(startLocation.S_LOC_CODE, location, tasktype, startlocationinfo.LocCntrRel.S_CNTR_CODE, startLocation.N_CURRENT_NUM, 1, plc.deviceName, 1, 1, 1);
|
break;
|
}
|
}
|
}
|
}
|
}
|
return result;
|
}
|
|
private static Location DaMingShanGetCacheLocationOut1(string areaNo)
|
{
|
Location result = null;
|
var db = new SqlHelper<object>().GetInstance();
|
var startbitlist = db.Queryable<Location>()
|
.Where(a => a.S_AREA_CODE == areaNo && a.N_CURRENT_NUM > 0)
|
.Select(it => new { sum = SqlFunc.AggregateSum(it.N_CURRENT_NUM), it.N_ROW })
|
.GroupBy(it => it.N_ROW)
|
.MergeTable()
|
.OrderByDescending(it => it.sum)
|
.ToList();
|
foreach (var item in startbitlist)
|
{
|
var lockinfo = db.Queryable<Location>().Where(a => a.S_AREA_CODE == areaNo && a.N_ROW == item.N_ROW && a.S_LOCK_STATE != "无").First();
|
if (lockinfo == null)
|
{
|
result = db.Queryable<Location>().Where(a => a.S_AREA_CODE == areaNo && a.N_ROW == item.N_ROW && a.N_CURRENT_NUM > 0)
|
.OrderByDescending(a => a.N_COL)
|
.Includes(a => a.LocCntrRel)
|
.First();
|
break;
|
}
|
}
|
|
return result;
|
}
|
|
|
/// <summary>
|
/// 瓶盖机补空筐
|
/// </summary>
|
/// <param name="plc"></param>
|
/// <param name="location"></param>
|
/// <param name="v">true:即产即用 false:非即产即用</param>
|
/// <returns></returns>
|
internal static bool DaMingShanPLCOut2(Settings.deviceInfo plc, string location, bool v, PGWorkOrder workOrder)
|
{
|
string startlocation = "";
|
var tasktype = "";
|
var db = new SqlHelper<object>().GetInstance();
|
bool result = false;
|
var info = Settings.GetDaMingShanPriProLineList().Where(a => a.deviceName == plc.deviceName && a.Enable == "1" && a.ItemTrayType == "空").FirstOrDefault();
|
if (v)
|
{
|
//瓶盖机即产即用
|
if (info != null)
|
{
|
string ItemName = info.ItemName;
|
if (workOrder.S_UsingNow == "Y")
|
{
|
tasktype = "注塑即产空筐上线(瓶盖)";
|
}
|
else
|
{
|
tasktype = "注塑库存空筐上线(瓶盖)";
|
}
|
//查询对应终点的库位状态
|
if (info.ProductLocation.Count() > 0)
|
{
|
foreach (var a in info.ProductLocation)
|
{
|
var startlocationinfo = db.Queryable<Location>().Where(b => b.S_LOC_CODE == a).First();
|
if (startlocationinfo != null)
|
{
|
if (startlocationinfo.N_CURRENT_NUM > 0 && startlocationinfo.S_LOCK_STATE.Trim() == "无")
|
{
|
startlocation = startlocationinfo.S_LOC_CODE.Trim();
|
result = DaMingShanCreateTransport(startlocation, location, tasktype, startlocationinfo.LocCntrRel.S_CNTR_CODE, 1, 1, plc.deviceName, 1);
|
break;
|
}
|
}
|
}
|
}
|
//对应终点找不到空闲货位 从对应库区寻找货位
|
if (!result)
|
{
|
foreach (var item in info.ProductArea)
|
{
|
var startLocation = DaMingShanGetCacheLocationOut(item);
|
if (startLocation != null)
|
{
|
var cntrList = LocationHelper.GetLocCntrRel(startLocation.S_LOC_CODE.Trim());
|
//淳安两个托盘为 一个 货位当前容量
|
var trayInfo = new LocCntrRel();
|
if (cntrList.Count >= 1)
|
{
|
//string cntrs = "";
|
trayInfo = cntrList.OrderByDescending(a => a.T_CREATE).Take(1).First();//单托出库
|
}
|
result = DaMingShanCreateTransport(startLocation.S_LOC_CODE, location, tasktype, trayInfo.S_CNTR_CODE, 1, 1, plc.deviceName, 1);
|
break;
|
}
|
}
|
}
|
}
|
}
|
//else
|
//{
|
// //瓶盖机非即产即用
|
//
|
// //非即产即用 直接入库缓存位 3+2
|
// var bitinfo = Settings.GetinStockCacheBitList().Where(a => a.deviceType == 1 && a.Enable == "1" && a.ItemTrayType == "满").FirstOrDefault();
|
// if (info != null && bitinfo != null)
|
// {
|
// string ItemName = info.ItemName;
|
// var locinfo = db.Queryable<Location>().Where(q => q.S_LOC_CODE == bitinfo.location).First();
|
// if (locinfo != null)
|
// {
|
// if (locinfo.S_LOCK_STATE == "无")
|
// {
|
// var cntrList = LocationHelper.GetLocCntrRel(locinfo.S_LOC_CODE.Trim());
|
// //淳安两个托盘为 一个 货位当前容量
|
// var trayInfo = new LocCntrRel();
|
// if (cntrList.Count >= 1)
|
// {
|
// string cntrs = "";
|
// trayInfo = cntrList.OrderByDescending(a => a.T_CREATE).Take(1).First();//单托出库
|
// }
|
// var startley = cntrList.Count();
|
// result = DaMingShanCreateTransport(location, locinfo.S_LOC_CODE, "注塑即产满筐下线(瓶坯)", trayInfo.S_CNTR_CODE, startley, 1, plc.deviceName, 1);
|
// }
|
// }
|
// }
|
//}
|
return result;
|
}
|
|
/// <summary>
|
/// 标准出入库处理
|
/// </summary>
|
/// <param name="bit">起点点位 或 终点点位</param>
|
/// <param name="taskType">任务类型</param>
|
/// <param name="trayCode">托盘编码</param>
|
/// <param name="areaCode">库区编码</param>
|
/// <param name="itemCode">物料编码</param>
|
/// <param name="batchNo">批次号</param>
|
/// <param name="itemLayer">物料层数</param>
|
/// <param name="itemTrayType">物料托盘类型</param>
|
/// <param name="actionType">动作类型 True-入库 False-出库</param>
|
/// <returns></returns>
|
internal static bool DaMingShanPlcTask(string bit, string taskType, string trayCode, string areaCode, string itemCode, string batchNo, string itemLayer, string itemTrayType, string deviceName, bool actionType, string workNo = "")
|
{
|
var result = false;
|
LogHelper.Info($"成品入库算法匹配终点,产线号={deviceName},库区={areaCode},物料编码={itemCode},批次号={batchNo}", "输送线");
|
//1.任务创建:锁定起点,终点,终点排号-排锁定表(任务完成解锁),
|
// 任务数据携带-托盘码(便于回报)--两个托盘码存入任务表 WMSTask 的 托盘字段 S_CNTRS
|
// 物料层数(NDC下发必要参数) --起点层数 N_START_LAYER :默认为1
|
// --终点层数 N_END_LAYER :获取 货位表-终点货位信息 N_CAPACITY + 1
|
//2.插入 当前排号、产线号 至 自动移库中间表,等待工单完成即进行 自动移库
|
var db = new SqlHelper<object>().GetInstance();
|
var info = db.Queryable<ItemRel>().Where(a => a.S_ITEM_CODE == itemCode && a.S_ITEM_MODEL == itemLayer).First();
|
if (info != null)
|
{
|
if (actionType)
|
{
|
var endLocation = GetLocationIn(areaCode, itemCode, batchNo, deviceName, itemLayer);
|
if (endLocation != null)
|
{
|
var endLayer = endLocation.N_CURRENT_NUM + 1;
|
//DaMingShanAnalysisMoveLib model = new DaMingShanAnalysisMoveLib { RowNo = endLocation.N_ROW, Batch = batchNo, DeviceName = deviceName };
|
//WCSHelper.DaMingShanInsertAnalysisMoveLib(model);
|
result = DaMingShanCreateTransport(bit, endLocation.S_LOC_CODE, taskType, trayCode, 1, endLayer, deviceName, 1, 1, int.Parse(info.S_ITEM_LAYER), workNo, batchNo, itemCode, itemTrayType);
|
}
|
//else //Console.WriteLine($"MoboxHelperCreateTask: 未找到终点货位");
|
}
|
else
|
{
|
var startLocation = GetLocationOut(areaCode, itemCode, batchNo, itemLayer);
|
if (startLocation != null)
|
{
|
var startLayer = startLocation.N_CURRENT_NUM;
|
var taskNo = DateTime.Now.Ticks.ToString();
|
//淳安只需要一个一拿
|
//var carryCount = startLocation.N_CURRENT_NUM > 3 ? startLocation.N_CURRENT_NUM - 3 : startLocation.N_CURRENT_NUM;
|
//出库要从起点获取托盘
|
var cntrList = LocationHelper.GetLocCntr(startLocation.S_LOC_CODE);
|
//淳安两个托盘为 一个 货位当前容量
|
if (cntrList.Count == startLocation.N_CURRENT_NUM * 2)
|
{
|
string cntrs = "";
|
var trayInfo = cntrList.OrderByDescending(a => a.T_CREATE).Skip(2).ToList();
|
trayInfo.ForEach(a =>
|
{
|
cntrs = cntrs + "," + a.S_CNTR_CODE.Trim();
|
});
|
result = DaMingShanCreateTransport(startLocation.S_LOC_CODE, bit, taskType, cntrs, startLayer, 1, deviceName, 1, 1);
|
}
|
else
|
{
|
//Console.WriteLine($"起点托盘数量和货位容器表不符合,请检查【货位表】和【货位容器表】");
|
}
|
}
|
}
|
}
|
LogHelper.Info($"创建任务是否成功 {result}");
|
return result;
|
}
|
#endregion
|
}
|
}
|