using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using HH.WCS.JingyuNongfu.wms;
using HH.WCS.JingyuNongfu.util;
using SqlSugar.Extensions;
using Newtonsoft.Json;
using System.Reflection;
namespace HH.WCS.JingyuNongfu.process
{
///
/// 成品流程
///
internal class ProcessHelperCP
{
private static Dictionary itemHeights = new Dictionary();
static ProcessHelperCP()
{
new SqlHelper().CreateTable(new List {
typeof(MoveOrderNotice),
typeof(InOutRecord),
typeof(PgZsjReportMesInfo),
typeof(PgFdjReportMesFeedInfo),
typeof(PgReportFluxInfo),
});
var db = new SqlHelper().GetInstance();
var list = db.Queryable().ToList();
if (list.Count > 0)
{
list.ForEach(a =>
{
if (!itemHeights.Keys.Contains(a.S_ITEM_NAME))
{
itemHeights.Add(a.S_ITEM_NAME, a.S_ITEM_LAYER);
}
});
}
}
///
/// 根据物料信息获取托盘高度
///
///
///
internal static int GetTrayHeightByItem(string itemCode)
{
var result = 0;
if (itemHeights.Keys.Contains(itemCode))
{
result = itemHeights[itemCode];
}
else
{
var db = new SqlHelper().GetInstance();
var itemInfo = db.Queryable().Where(a => a.S_ITEM_CODE == itemCode).First();
if (itemInfo != null)
{
result = itemInfo.S_ITEM_LAYER;
itemHeights.Add(itemCode, itemInfo.S_ITEM_LAYER);
}
}
return result;
}
///
/// 获取物料二层高度
///
/// 物料名称
/// 物料层高
/// 托盘类型
///
internal static int GetTrayHeight(string itemCode, string itemLayer, string irayType)
{
var result = 0;
//if (itemHeights.Keys.Contains(itemCode + "_" + itemLayer + "_" + itemLayer))
//{
// result = itemHeights[itemCode + "_" + itemLayer + "_" + itemLayer];
//}
//else
//{
var db = new SqlHelper().GetInstance();
var itemInfo = db.Queryable().Where(a => a.S_ITEM_CODE == itemCode && a.S_ITEM_MODEL == itemLayer && a.S_TRAY_TYPE == irayType).First();
if (itemInfo != null)
{
result = itemInfo.S_ITEM_LAYER;
//itemHeights.Add(itemCode + "_" + itemLayer + "_" + itemLayer, itemInfo.S_ITEM_LAYER);
}
// }
return result;
}
///
/// 获取物料层高
///
///
///
internal static int GetTrayHeightByTray(string trayCode)
{
var result = 0;
var db = new SqlHelper().GetInstance();
var cntr = db.Queryable().Where(a => a.S_CNTR_CODE.Contains(trayCode)).Includes(a => a.CntrItemRel).First();
if (cntr != null && cntr.CntrItemRel != null)
{
//根据物料名称、物料层数、托盘类型找物料层高
result = GetTrayHeight(cntr.CntrItemRel.S_ITEM_CODE, cntr.CntrItemRel.S_ITEM_MODEL, cntr.S_TYPE);
}
else
{
LogHelper.Info("未获取cntr信息", "HosttoagvTask");
}
return result;
}
///
/// 获取富勒物料层高
///
///
///
internal static int GetTrayHeightByTrayFL(string trayCode)
{
var result = 0;
int itemLayer = 0;
var db = new SqlHelper().GetInstance();
var cntrfl = db.Queryable().Where(a => a.trayCode.Contains(trayCode)).First();
if (cntrfl != null)
{
itemLayer = int.Parse(cntrfl.itemLayer);
var cntr = db.Queryable().Where(a => a.S_CNTR_CODE.Contains(trayCode)).Includes(a => a.CntrItemRel).First();
if (cntr != null && cntr.CntrItemRel != null)
{
//根据物料名称、物料层数、托盘类型找物料层高
result = GetTrayHeight(cntr.CntrItemRel.S_ITEM_CODE, itemLayer.ToString(), cntr.S_TYPE);
}
}
else
{
LogHelper.Info("未找到富勒cntr信息", "HosttoagvTask");
}
return result;
}
///
/// 成品下线
///
///
///
///
internal static void InStock(WorkOrder1 workOrder, string loc)
{
try
{
//判断最大任务数,如果执行中的任务大于等于最大任务数,不生成任务
if (!TaskHelper.GetTaskByMaxtask(workOrder, loc))
{
LogHelper.Info($"执行中任务数量大于等于最大任务限制,不生成任务", "成品");
return;
}
//根据工单查询对应物料信息
var db = new SqlHelper().GetInstance();
ItemInfo item = null;
if (workOrder.withCode == "是")
{
//使用富勒数据
// List trayInfos = GetThirdPartTrayInfo(workOrder.S_WorkNo);
List trayInfos = GetThirdPartTrayInfoByDeviceName(workOrder.S_PLineNo);
if (trayInfos.Count == 2)
{
workOrder.S_ItemLayer = trayInfos[0].itemLayer;
}
else
{
LogHelper.Info("未获取到富勒托盘号", "成品");
return;
}
}
if (workOrder.withCode == "是")
{
item = db.Queryable().Where(a => a.S_ITEM_CODE == workOrder.S_ItemCode && a.S_TRAY_TYPE == workOrder.S_TrayType && a.S_ITEM_MODEL == workOrder.S_ItemLayer.ToString()).First();
}
else
{
item = db.Queryable().Where(a => a.S_ITEM_NAME == workOrder.SQL_ItemName && a.S_TRAY_TYPE == workOrder.S_TrayType && a.S_ITEM_MODEL == workOrder.S_ItemLayer.ToString()).First();
}
var itemCode = "";
var itemName = "";
var itemTrayType = "";
var itemModel = "";
if (item != null)
{
itemCode = item.S_ITEM_CODE;
itemName = item.S_ITEM_NAME;
itemTrayType = item.S_TRAY_TYPE;
itemModel = item.S_ITEM_MODEL;
}
else
{
LogHelper.Info("未获取物料信息", "成品");
}
var listZones = new List { };
if (!string.IsNullOrEmpty(workOrder.SQL_Area))
{
listZones.Add(workOrder.SQL_Area);
if (!string.IsNullOrEmpty(workOrder.SQL_Area1)) { listZones.Add(workOrder.SQL_Area1); }
if (!string.IsNullOrEmpty(workOrder.SQL_Area2)) { listZones.Add(workOrder.SQL_Area2); }
}
else
{
listZones.AddRange(GetZones(workOrder.SQL_ItemName));
}
//按物料名称查找库区
//var code1 = LocationHelper.GenerateCntrNo() + "_" + height;
//var code2 = LocationHelper.GenerateCntrNo() + "_" + height;
//var tray = $"{code1}-{code2}";
string tray = "";
string batchNo = "";
var count = "1";
if (workOrder.withCode == "是")
{
//使用富勒数据
// List trayInfos = GetThirdPartTrayInfo(workOrder.S_WorkNo);
List trayInfos = GetThirdPartTrayInfoByDeviceName(workOrder.S_PLineNo);
if (trayInfos.Count == 2)
{
tray = $"{trayInfos[0].trayCode},{trayInfos[1].trayCode}";
count = $"{trayInfos[0].trayNum},{trayInfos[1].trayNum}";
batchNo = trayInfos[0].batchNo + ',' + trayInfos[1].batchNo;
itemCode = $"{workOrder.S_ItemCode}";
}
else
{
Console.WriteLine("未获取到富勒托盘号");
return;
}
}
else
{
batchNo = DateTime.Now.ToString("yyyyMMdd") + workOrder.S_PLineNo;
}
Location end = null;
Console.WriteLine($"查找同品相 同设备 {itemCode} {batchNo}");
if (item == null)
{
Console.WriteLine("查询物料信息出错");
return;
}
int maxLayer = item.N_MaxLayer;
Console.WriteLine($"层数:{maxLayer}");
for (int i = 0; i < listZones.Count; i++)
{
LogHelper.Info("库区" + listZones[i], "成品");
//LogHelper.Info($"任务:{workOrder.S_PLineNo},产线{workOrder.S_WorkNo}", "成品");
//end = LocationHelper.GetLocation4InFinish(listZones[i], workOrder.SQL_ItemCode, workOrder.size);
end = GetLocation4InSameSrc(listZones[i], itemCode, batchNo, workOrder.S_TrayType, maxLayer);
if (end != null)
{
// LogHelper.Info($"方法(GetLocation4InSameSrc)选择货位{end.S_LOC_CODE}", "成品");
break;
}
}
if (end == null)
{
Console.WriteLine("查找空排");
for (int i = 0; i < listZones.Count; i++)
{
Console.WriteLine("库区" + listZones[i]);
end = GetLocation4InEmptyRow(listZones[i], workOrder.S_TrayType);
if (end != null)
{
// LogHelper.Info($"方法(GetLocation4InEmptyRow)选择货位{end.S_LOC_CODE}", "成品");
break;
}
}
}
//if (end == null)
//{
// Console.WriteLine($"查找同品相 不同设备 {itemCode} {batchNo}");
// for (int i = 0; i < listZones.Count; i++)
// {
// Console.WriteLine("库区" + listZones[i]);
// end = GetLocation4InAnySrc(listZones[i], itemCode, batchNo, workOrder.S_TrayType, maxLayer);
// if (end != null)
// {
// LogHelper.Info($"方法(GetLocation4InAnySrc)选择货位{end.S_LOC_CODE}", "成品");
// break;
// }
// }
//}
if (end != null)
{
LogHelper.Info($"任务:{workOrder.S_PLineNo},终点库区{end.S_LOC_CODE},物料编码{itemCode},批次号{batchNo},下线托盘类型{workOrder.S_TrayType},层数{maxLayer}", "HosttoagvTask");
//生成托盘号
string[] traylist = null;
if (workOrder.withCode != "是")
{
tray = $"{ContainerHelper.GenerateCntrNo()},{ContainerHelper.GenerateCntrNo()}";
traylist = tray.Split(',');
}
else
{
traylist = tray.Split(',');
}
int cg = 0;
//计算层高
if (end.N_CURRENT_NUM == 0)
{
cg = 1;
}
else if (end.N_CURRENT_NUM == 2)
{
cg = 2;
}
else if (end.N_CURRENT_NUM == 4)
{
cg = 3;
}
//判断任务终点有无相同任务
if (TaskHelper.GetTaskByEndandlayer(end.S_LOC_CODE, cg))
{
if (ContainerHelper.CreateCntrItem(traylist, itemCode, itemName, workOrder.S_TrayType, batchNo, count, itemModel, itemTrayType, workOrder.S_WorkNo))
{
//创建入库搬运任务
if (!TaskProcess.CreateTransport(loc, end.S_LOC_CODE, "成品下线", new List { tray }, 1, cg, 1, 80, workOrder.S_WorkNo, workOrder.withCode))
{
//任务创建失败删除创建的托盘
if (ContainerHelper.DeleteCntrItem(tray.Split(',')))
{
LogHelper.Info($"任务创建失败删除托盘{tray}", "成品");
}
else
{
LogHelper.Info($"任务创建失败删除托盘{tray}失败", "成品");
}
}
}
}
else
{
LogHelper.Info($"任务终点{end.S_LOC_CODE},层高:{cg}有执行中的任务,不生成任务", "成品");
}
}
}
catch (Exception ex)
{
throw ex;
}
}
///
/// 顶升机下线
///
///
///
internal static void DsjStock(string startLoc, string endLoc)
{
string bussType = "";
string cntrtype = "";
if (startLoc == "LYP-1-1")
{
bussType = "顶升机留样品下线";
cntrtype = "留样品";
}
else if (startLoc == "FL-1-1")
{
bussType = "顶升机废料下线";
cntrtype = "废料";
}
else if (startLoc == "ZX-1-1")
{
bussType = "顶升机空托下线";
cntrtype = "纸箱空托";
}
string tray = ContainerHelper.GenerateCntrNo();
try
{
if (ContainerHelper.CreateCntrItem(tray, cntrtype))
{
TaskProcess.CreateTransport(startLoc, endLoc, bussType, new List { tray }, 1, 1, 1, 80);
}
}
catch (Exception ex)
{
LogHelper.Info($"DsjStock-Error:{ex.ToString()}", "顶升机");
}
}
///
/// 获取富勒托盘数据
///
///
///
private static List GetThirdPartTrayInfo(string workNo)
{
var db = new SqlHelper().GetInstance();
return db.Queryable().Where(a => a.workNo == workNo).ToList();
}
///
/// 获取富勒托盘数据
///
///
///
private static List GetThirdPartTrayInfoByDeviceName(string deviceName)
{
var db = new SqlHelper().GetInstance();
return db.Queryable().Where(a => a.deviceName == deviceName).ToList();
}
///
/// 同品相 同设备 同批次 的可以入同一排
///
///
///
///
///
public static Location GetLocation4InSameSrc(string area0, string itemCode, string itemBatch, string trayType, int maxLayer = 2)
{
Location result = null;
//string itemBatch = DateTime.Now.ToString("yyMMdd");
try
{
itemBatch = itemBatch.Split(',')[0];
var area = area0 + "_" + GetType(trayType);
LogHelper.Info("成品满托入库 GetLocation4InSameSrc:" + area, "成品");
bool flag = false;
var usedRows = GetUsedRow(area0, GetType(trayType), ref flag);
if (flag)
{
LogHelper.Info($"当前库区{area}不可用,被其它尺寸托盘占用,直接返回");
return null;
}
//1.0 获取每一排最大的列
//1.1 判断当前数量是不是满的,如果是满的并且是最大列,需要排除
var listMaxCol = new SqlHelper().GetInstance().Queryable().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().GetInstance();
var list = db.Queryable().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();
// Console.WriteLine($"查到所有有托盘的排 {list.Count}");
// LogHelper.Info($"查到所有有托盘的排 {list.Count}", "HosttoagvTask");
////查询移库工单相同库区的数据
//var listykstart = db.Queryable().Where(a => a.start_area== area0).ToList();
//var listykend = db.Queryable().Where(a => a.end_area== area0).ToList();
if (list.Count > 0)
{
//1.2 查找其它尺寸有托盘或者锁定的排
for (int i = list.Count - 1; i >= 0; i--)
{
LogHelper.Info("成品满托入库 GetLocation4InSameSrc:剩余排数" + list.Count, "成品");
var remove = false;
//排除已经锁定的货位 和 放满了且是最大列的货位
// LogHelper.Info("成品满托入库 GetLocation4InSameSrc:11111", "成品");
if (list[i].S_LOCK_STATE.Trim() != "无" || (list[i].N_CURRENT_NUM == 4 && listMaxCol.Count(a => a.S_LOC_CODE == list[i].S_LOC_CODE) > 0))
{
// Console.WriteLine($"排除已经锁定的货位 和 放满了且是最大列的货位 排{list[i].N_ROW}");
LogHelper.Info($"排除已经锁定的货位 和 放满了且是最大列的货位 排{list[i].N_ROW}", "成品");
remove = list.Remove(list[i]);
}
else
{
// LogHelper.Info("成品满托入库 GetLocation4InSameSrc:2222", "成品");
//排有锁也排除
var other = db.Queryable().Where(a => a.S_AREA_CODE == area && a.N_ROW == list[i].N_ROW && a.S_LOCK_STATE.Trim() != "无").First();
if (other != null)
{
//Console.WriteLine($"排除有锁的排{list[i].N_ROW}");
LogHelper.Info($"排除有锁的排{list[i].N_ROW}", "成品");
remove = list.Remove(list[i]);
}
//LogHelper.Info("成品满托入库 GetLocation4InSameSrc:3333", "成品");
}
if (!remove)
{
//判断是否被其它库区占用了
// LogHelper.Info($"判断是否被其它库区占用了 {list[i].N_ROW}", "成品");
if (usedRows.Contains(list[i].N_ROW))
{
LogHelper.Info($"被其他库区占用{list[i].N_ROW}", "成品");
remove = list.Remove(list[i]);
}
}
}
//LogHelper.Info($"有托盘排数为{list.Count}","成品");
LogHelper.Info("成品满托入库 GetLocation4InSameSrc:开始计算排数" + list.Count, "成品");
if (list.Count > 0)
{
//1.3 遍历判断物料类型是否相同
//Console.WriteLine("遍历判断物料类型是否相同");
// LogHelper.Info($"遍历判断物料类型是否相同", "成品");
for (int i = 0; i < list.Count(); i++)
{
//Console.WriteLine($"货位{list[i].S_LOC_CODE} 物料{list[i].LocCntrRel.CntrItemRel.S_ITEM_CODE} 批次{list[i].LocCntrRel.CntrItemRel.S_BATCH_NO}");
//todo 还需要判断锁
#region 满托盘判断 物料信息相同,并且批次里面的设备相同
//var ssss = itemBatch.Substring(6).Trim();
if (list[i].LocCntrRel != null && list[i].LocCntrRel.CntrItemRel != null && list[i].LocCntrRel.CntrItemRel.S_ITEM_CODE.Trim() == itemCode && list[i].LocCntrRel.CntrItemRel.S_BATCH_NO.Contains(itemBatch.Substring(6).Trim()) && list[i].LocCntrRel.CntrItemRel.S_BATCH_NO.Length == itemBatch.Length)
{
// LogHelper.Info($"有托盘的货位{list[i].S_LOC_CODE} 当前数量={list[i].N_CURRENT_NUM} 容量={list[i].N_CAPACITY},入库数量={maxLayer}", "成品");
if (list[i].N_CAPACITY - list[i].N_CURRENT_NUM >= maxLayer)
{
//堆叠,判断批次里面的日期是不是相同的
//LogHelper.Info("堆叠,判断批次里面的日期是不是相同的", "成品");
// if (list[i].LocCntrRel.CntrItemRel.S_BATCH_NO.Trim() == itemBatch)
// {
result = list[i];
// Console.WriteLine("判断是不是单托");
//if (list[i].LocCntrRel.S_CNTR_CODE.Contains(','))
//{
// result = list[i];
//}
//else
//{
// //一层是单托,入库放后面一个位置
// Console.WriteLine("一层是单托,入库放后面一个位置");
// result = db.Queryable().OrderBy(a => a.N_COL).Where(a => a.S_AREA_CODE == area && a.N_ROW == list[i].N_ROW && a.N_COL > list[i].N_COL).First();
//}
// }
// else
// {
//排除批次不一样
//Console.WriteLine("批次不一样空一个位置");
// LogHelper.Info($" 货位{list[i].S_LOC_CODE},货位批次号{list[i].LocCntrRel.CntrItemRel.S_BATCH_NO.Trim()}和任务批次号{itemBatch}不同,批次不一样空一个位置", "成品");
// result = db.Queryable().OrderBy(a => a.N_COL).Where(a => a.S_AREA_CODE == area && a.N_ROW == list[i].N_ROW && a.N_COL > (list[i].N_COL + 1)).First();
//return null;
// }
}
else
{
//LogHelper.Info($"货位当前数量{list[i].N_CURRENT_NUM },存放数量{maxLayer}", "成品");
//选择后面空位,判断批次里面日期是不是相同的
// Console.WriteLine($"判断批次是不是相同的");
// if (list[i].LocCntrRel.CntrItemRel.S_BATCH_NO.Trim() == itemBatch)
// {
// LogHelper.Info($"S_AREA_CODE={area},N_ROW={list[i].N_ROW},N_COL>{list[i].N_COL}", "成品");
result = db.Queryable().Where(a => a.S_AREA_CODE.Trim() == area.Trim() && a.N_ROW == list[i].N_ROW && a.N_COL > list[i].N_COL).OrderBy(a => a.N_COL).First();
//if (result != null)
//{
// LogHelper.Info($"{result.S_LOC_CODE}", "成品");
//}
//LogHelper.Info($"{list[i]}货位满,批次号相同找后一个空货位", "成品");
//}
// else
// {
//LogHelper.Info($"{list[i]}货位满,批次号不同,隔一个空位", "成品");
// result = db.Queryable().OrderBy(a => a.N_COL).Where(a => a.S_AREA_CODE == area && a.N_ROW == list[i].N_ROW && a.N_COL > (list[i].N_COL + 1)).First();
//return null;
// }
}
if (result != null && (!string.IsNullOrEmpty(result.C_ENABLE) && result.C_ENABLE == "禁用"))
{
//禁用了选择后面一个货位
result = db.Queryable().OrderBy(a => a.N_COL).Where(a => (string.IsNullOrEmpty(a.C_ENABLE) || a.C_ENABLE.Trim() != "禁用") && a.S_AREA_CODE == area && a.N_ROW == result.N_ROW && a.N_COL > result.N_COL).First();
//LogHelper.Info($"禁用选择后一个货位{result}", "成品");
}
if (result != null)
{
break;
}
//根据容器编码获取容器信息
var ctrlCode = list[i].LocCntrRel.CntrItemRel.S_CNTR_CODE.Trim();
var ctrl = ContainerHelper.GetCntr(ctrlCode);
//托盘类型不一样隔一排位置
if (ctrl.S_TYPE != trayType)
{
Console.WriteLine("托盘类型不一样隔一排");
break;
}
}
else
{
LogHelper.Info($"货位{list[i].S_LOC_CODE}不允许堆叠,托盘:{list[i].LocCntrRel.S_CNTR_CODE},容器货品{list[i].LocCntrRel.CntrItemRel},托盘物料编码{list[i].LocCntrRel.CntrItemRel.S_ITEM_CODE.Trim()},订单物料编码:{itemCode} ,批次号{list[i].LocCntrRel.CntrItemRel.S_BATCH_NO}是否含有{itemBatch.Substring(6).Trim()},物料编码长度{list[i].LocCntrRel.CntrItemRel.S_BATCH_NO.Length}是否相等{itemBatch.Length},有与上一个货位不同的地方", "成品");
}
#endregion
}
}
else
{
LogHelper.Info($"有托盘的排数为0", "成品");
}
}
}
catch (Exception ex)
{
//Console.WriteLine("GetLocation4InFinish:" + ex.Message + ex.StackTrace);
LogHelper.Info("GetLocation4InSameSrc:" + ex.Message, "成品");
}
return result;
}
///
/// 成品入库移库完成记录信息需要上报给富勒
///
///
///
internal static void AddTaskStatus(WMSTask mst, bool move = false)
{
try
{
//无码的不需要写入中间表
if (mst.S_CNTRS.Length != 25)
{
var db = new SqlHelper().GetInstance();
var model = new InOutRecord { TrayInfo = mst.S_CNTRS };
model.EndArea = mst.S_END_LOC.Substring(0, 1) + mst.S_END_LOC.Split('-')[1];
if (move)
{
model.IsMove = 1;
model.StartArea = mst.S_START_LOC.Substring(0, 1) + mst.S_START_LOC.Split('-')[1];
}
else
{
var cir = db.Queryable().Where(a => a.S_CNTR_CODE == mst.S_CNTRS).Includes(a => a.CntrItemRel).First();
if (cir != null && cir.CntrItemRel != null)
{
model.WorkOrder = cir.CntrItemRel.workOrder;
}
else
{
LogHelper.Info($"写入 InOutRecord 失败 托盘{mst.S_CNTRS}物料信息不存在");
}
}
var res = db.Insertable(model).ExecuteCommand();
}
}
catch (Exception ex)
{
LogHelper.Info($"写入 InOutRecord 失败{ex.Message}");
}
}
///
/// 查找空排
///
///
///
///
///
///
public static Location GetLocation4InEmptyRow(string area0, string trayType)
{
Location result = null;
try
{
var db = new SqlHelper().GetInstance();
var area = area0 + "_" + GetType(trayType);
Console.WriteLine("成品满托入库 GetLocation4InEmptyRow:" + area);
//var usedRows = GetUsedRow(area0, GetType(trayType));
bool flag = false;
var usedRows = GetUsedRow(area0, GetType(trayType), ref flag);
LogHelper.Info("usedRows信息" + JsonConvert.SerializeObject(usedRows), "成品");
if (flag) { return null; }
//todo 还需要判断锁
#region 查找所有数量是空的排
//Console.WriteLine("查找所有数量是空的排");
//2.0 简化查询只查每一排第一列
var list = db.Queryable().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();
// LogHelper.Info($"库区编码:{area}", "成品");
if (list.Count > 0)
{
// LogHelper.Info($"list.Count:{list.Count},", "成品");
//2.1 选一个空排
for (int i = 0; i < list.Count; i++)
{
if (!usedRows.Contains(list[i].N_ROW))
{
//LogHelper.Info($"area0:{area0} llist[i].N_ROW:{list[i].N_ROW},GetType(trayType):{GetType(trayType)}", "成品");
//判断其它库区排是否有锁定
if (!CheckLockedRow(area0, GetType(trayType), list[i].N_ROW))
{
//LogHelper.Info($"area:{area},N_ROW :{list[i].N_ROW}", "成品");
var other = db.Queryable().Where(a => a.S_AREA_CODE == area && a.N_ROW == list[i].N_ROW && a.S_LOCK_STATE.Trim() != "无").First();
//LogHelper.Info($"other:{other},list[i].S_LOCK_STATE.Trim() :{list[i].S_LOCK_STATE.Trim() }", "成品");
if (list[i].S_LOCK_STATE.Trim() == "无" && other == null)
{
//二次校验当前排所有货位都是空的,防止系统数据错乱
// LogHelper.Info($"i:{i} llist[i].N_ROW:{list[i].N_ROW},area:{area}", "成品");
var rowSumInfo = db.Queryable().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();
//LogHelper.Info($"rowSumInfo.sum:{rowSumInfo.sum}", "成品");
if (rowSumInfo.sum == 0)
{
result = list[i];
break;
}
}
}
}
}
}
else
{
LogHelper.Info($"根据库区:{area},找不到空排", "成品");
}
#endregion
if (result != null && (!string.IsNullOrEmpty(result.C_ENABLE) && result.C_ENABLE == "禁用"))
{
//禁用了选择后面一个货位
//Console.WriteLine("禁用了选择后面一个货位");
result = db.Queryable().OrderBy(a => a.N_COL).Where(a => a.S_AREA_CODE == area && a.N_ROW == result.N_ROW && (string.IsNullOrEmpty(a.C_ENABLE) || a.C_ENABLE != "禁用") && a.N_COL > result.N_COL).First();
LogHelper.Info("货位信息" + JsonConvert.SerializeObject(result), "HosttoagvTask");
}
}
catch (Exception ex)
{
//Console.WriteLine("GetLocation4InFinish:" + ex.Message + ex.StackTrace);
LogHelper.Error("GetLocation4InEmptyRow:" + ex.Message, ex);
}
return result;
}
///
/// 同品相 不同设备的可以入同一排
///
///
///
///
///
///
public static Location GetLocation4InAnySrc(string area0, string itemCode, string itemBatch, string trayType, int maxLayer = 2)
{
Location result = null;
try
{
var area = area0 + "_" + GetType(trayType);
Console.WriteLine("成品满托入库 GetLocation4InAnySrc:" + area);
//var usedRows = GetUsedRow(area0, GetType(trayType));
bool flag = false;
var usedRows = GetUsedRow(area0, GetType(trayType), ref flag);
if (flag) { return null; }
//1.0 获取每一排最大的列
//1.1 判断当前数量是不是满的,如果是满的并且是最大列,需要排除
var listMaxCol = new SqlHelper().GetInstance().Queryable().Where(a => a.S_AREA_CODE == area).OrderByDescending(a => a.N_COL).Take(1).PartitionBy(a => a.N_ROW).ToList();
//1.1 查到所有有托盘的排
Console.WriteLine("查到所有有托盘的排 ");
var db = new SqlHelper().GetInstance();
var list = db.Queryable().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)
{
//1.2 查找其它尺寸有托盘或者锁定的排
for (int i = list.Count - 1; i >= 0; i--)
{
var remove = false;
//排除已经锁定的货位 和 放满了且是最大列的货位
if (list[i].S_LOCK_STATE.Trim() != "无" || (list[i].N_CURRENT_NUM == 4 && listMaxCol.Count(a => a.S_LOC_CODE == list[i].S_LOC_CODE) > 0))
{
LogHelper.Info($"排除已经锁定的货位 和 放满了且是最大列的货位 排{list[i].N_ROW}", "成品");
remove = list.Remove(list[i]);
}
else
{
//排有锁也排除
var other = db.Queryable().Where(a => a.S_AREA_CODE == area && a.N_ROW == list[i].N_ROW && a.S_LOCK_STATE.Trim() != "无").First();
if (other != null)
{
LogHelper.Info($"排除有锁的排{list[i].N_ROW}", "成品");
remove = list.Remove(list[i]);
}
}
if (!remove)
{
//判断是否被其它库区占用了
if (usedRows.Contains(list[i].N_ROW))
{
remove = list.Remove(list[i]);
LogHelper.Info($"被其他库区占用{list[i].N_ROW}", "成品");
}
}
}
Console.WriteLine($"有托盘排数为{list.Count}");
if (list.Count > 0)
{
//1.3 遍历判断物料类型是否相同
Console.WriteLine("遍历判断物料类型是否相同");
for (int i = 0; i < list.Count; i++)
{
//todo 还需要判断锁
#region 空托盘或者满托盘判断 ,如果是空托盘 托盘物料信息为空
if (list[i].LocCntrRel != null && list[i].LocCntrRel.CntrItemRel != null)
{
LogHelper.Info($"货位{list[i].S_LOC_CODE} 物料{list[i].LocCntrRel.CntrItemRel.S_ITEM_CODE} 批次{list[i].LocCntrRel.CntrItemRel.S_BATCH_NO}", "成品");
if (list[i].LocCntrRel.CntrItemRel.S_ITEM_CODE.Trim() == itemCode && list[i].LocCntrRel.CntrItemRel.S_BATCH_NO.Length == itemBatch.Length)
{
LogHelper.Info($"不同设备生产排;有托盘的货位{list[i].S_LOC_CODE} 当前数量={list[i].N_CURRENT_NUM} 容量={list[i].N_CAPACITY},入库数量={maxLayer}", "成品");
if (list[i].N_CAPACITY - list[i].N_CURRENT_NUM >= maxLayer)
{
//堆叠,判断批次是不是相同的,不是相同的放到后面
// Console.WriteLine("堆叠,判断批次里面日期是不是相同的,不是相同的放到后面");
//if (list[i].LocCntrRel.CntrItemRel.S_BATCH_NO.Substring(0, itemBatch.Length - 2) == itemBatch.Substring(0, itemBatch.Length - 2)) {
//判断是不是单托
result = list[i];
//Console.WriteLine("判断是不是单托");
//if (list[i].LocCntrRel.S_CNTR_CODE.Contains(','))
//{
// result = list[i];
//}
//else
//{
// //一层是单托,入库放后面一个位置
// Console.WriteLine("一层是单托,入库放后面一个位置");
// result = db.Queryable().OrderBy(a => a.N_COL).Where(a => a.S_AREA_CODE == area && a.N_ROW == list[i].N_ROW && a.N_COL > list[i].N_COL).First();
//}
//}
//else {
// //批次不一样空一个位置
// Console.WriteLine("批次不一样空一个位置");
// result = db.Queryable().OrderBy(a => a.N_COL).Where(a => a.S_AREA_CODE == area && a.N_ROW == list[i].N_ROW && a.N_COL > (list[i].N_COL + 1)).First();
//}
}
else
{
LogHelper.Info($"货位{list[i].S_LOC_CODE}满,选择后面货位", "成品");
//选择后面空位,判断批次是不是相同的,不是相同的放到后面
// LogHelper.Info("选择后面空位,判断批次是不是相同的,不是相同的放到后面", "成品");
if (list[i].LocCntrRel.CntrItemRel.S_BATCH_NO.Substring(0, itemBatch.Length - 2) == itemBatch.Substring(0, itemBatch.Length - 2))
{
result = db.Queryable().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();
LogHelper.Info($"{list[i]}货位满,批次号相同找后一个空货位", "成品");
}
else
{
LogHelper.Info($"{list[i]}货位满,批次号不同,隔一个空位", "成品");
result = db.Queryable().OrderBy(a => a.N_COL).Where(a => a.S_AREA_CODE == area && a.N_ROW == list[i].N_ROW && a.N_COL > (list[i].N_COL + 1)).First();
}
}
if (result != null && result.C_ENABLE != "禁用")
{
break;
}
//根据容器编码获取容器信息
var ctrlCode = list[i].LocCntrRel.CntrItemRel.S_CNTR_CODE.Trim();
var ctrl = ContainerHelper.GetCntr(ctrlCode);
//托盘类型不一样隔一排
if (ctrl.S_TYPE != trayType)
{
Console.WriteLine("托盘类型不一样隔一排");
break;
}
}
}
#endregion
}
}
}
if (result != null && (!string.IsNullOrEmpty(result.C_ENABLE) && result.C_ENABLE == "禁用"))
{
//禁用了选择后面一个货位
//Console.WriteLine("禁用了选择后面一个货位");
LogHelper.Info($"禁用货位{result.S_LOC_CODE},库区编码{area},排{result.N_ROW},列{result.N_COL}", "成品");
result = db.Queryable().OrderBy(a => a.N_COL).Where(a => (string.IsNullOrEmpty(a.C_ENABLE) || a.C_ENABLE.Trim() != "禁用") && a.S_AREA_CODE == area && a.N_ROW == result.N_ROW && a.N_COL > result.N_COL).First();
// LogHelper.Info($"禁用选择后一个货位{result}", "成品");
}
}
catch (Exception ex)
{
//Console.WriteLine("GetLocation4InFinish:" + ex.Message + ex.StackTrace);
LogHelper.Error("GetLocation4InFinish:" + ex.Message, ex);
}
return result;
}
///
/// 根据物料信息获取入库优先级
///
///
///
///
private static List GetZones(string ItemName)
{
var list = new List();
var db = new SqlHelper().GetInstance();
var itemZonePris = db.Queryable().Where(a => a.S_ITEM_NAME == ItemName).ToList();
if (itemZonePris.Count > 0)
{
list = itemZonePris.OrderBy(a => a.S_PRIORITY).Select(a => a.S_AREA_CODE).ToList();
}
return list;
}
///
/// 根据托盘类型获取库区后缀
///
///
///
public static string GetType(string trayType)
{
var res = "";
switch (trayType)
{
case "集化板": res = "J"; break;
case "大板": res = "D"; break;
case "小板": res = "X"; break;
case "超托板": res = "C"; break;
case "集化板前后超托": res = "JC2"; break;
case "大板前后超托": res = "DC"; break;
case "小板前后超托": res = "XC"; break;
case "集化板四面超托": res = "JC4"; break;
}
return res;
}
///
/// 根据库区和排号找托盘类型
///
///
///
///
public static string GetTypebyrow(string kq, int row)
{
var res = "";
string trayType = "";
var db = new SqlHelper().GetInstance();
//string[] reslist = new string[] { "D", "J", "X", "JC2", "DC", "XC", "JC" };
foreach (var item in areaTypes)
{
var list = db.Queryable().Where(a => a.S_AREA_CODE == kq + "_" + item && a.N_ROW == row && a.N_CURRENT_NUM > 0).ToList();
if (list.Count > 0)
{
trayType = item;
break;
}
}
switch (trayType)
{
case "J": res = "集化板"; break;
case "D": res = "大板"; break;
case "X": res = "小板"; break;
case "C": res = "超托板"; break;
case "JC2": res = "集化板前后超托"; break;
case "DC": res = "大板前后超托"; break;
case "XC": res = "小板前后超托"; break;
case "JC4": res = "集化板四面超托"; break;
}
return res;
}
///
/// 库区后缀
///
private static List areaTypes = new List { "J", "D", "X", "JC2", "DC", "XC", "JC4", "C" };
public static List GetOtherAreas(string baseArea, string size)
{
var res = new List();
var at = GetType(size);
for (int i = 0; i < areaTypes.Count; i++)
{
if (areaTypes[i] != at)
{
res.Add(baseArea + "_" + areaTypes[i]);
}
}
return res;
}
///
/// 获取被占用的排号
///
///
///
///
///
private static List GetUsedRow(string area0, string areaType, ref bool flag)
{
//如果当前库区是C,有任意库区任意排不是C整区不能入
//如果当前库区不是C,但是有任意排有C整区不能入
bool intercept = false;
var db = new SqlHelper().GetInstance();
var res = new List();
areaTypes.Where(b => b != areaType).ToList().ForEach(b =>
{
//判断库区排有没有被占用
var area = area0 + "_" + b;
//有托盘的其他库区的排要排除
var list = db.Queryable().Where(a => a.N_CURRENT_NUM > 0 && a.S_AREA_CODE == area).OrderByDescending(a => a.N_COL).Take(1).PartitionBy(a => a.N_ROW).ToList();
if (list.Count > 0)
{
res.AddRange(list.Select(c => c.N_ROW).ToList());
//if (areaType == "C")
//{
// Console.WriteLine($"当前库区是{areaType},JDX库区有托盘,不可用");
// intercept = true;
//}
//else
//{
// if (b == "C")
// {
// Console.WriteLine($"当前库区是{areaType},C库区有托盘,不可用");
// intercept = true;
// }
//}
}
//有锁的其他库区的排要排除
var listsuo = db.Queryable().Where(a => a.S_LOCK_STATE != "无" && a.S_AREA_CODE == area).OrderByDescending(a => a.N_COL).Take(1).PartitionBy(a => a.N_ROW).ToList();
if (listsuo.Count > 0)
{
res.AddRange(listsuo.Select(c => c.N_ROW).ToList());
}
});
flag = intercept;
//有移库任务的排也需要排除
var list1 = db.Queryable().Where(a => (a.SQL_State == "执行中" || a.SQL_State == "暂停") && a.start_area == area0).ToList();
if (list1.Count > 0)
{
list1.ForEach(a =>
{
LogHelper.Info($"移库任务{a.SQL_WorkNo}:起点排{a.start_row}有移库任务", "成品");
res.Add(a.start_row);
// res.Add(a.end_row);
});
}
var list2 = db.Queryable().Where(a => (a.SQL_State == "执行中" || a.SQL_State == "暂停") && a.end_area == area0).ToList();
if (list2.Count > 0)
{
list2.ForEach(a =>
{
LogHelper.Info($"移库任务{a.SQL_WorkNo}:终点排{a.end_row}有移库任务", "成品");
// res.Add(a.start_row);
res.Add(a.end_row);
});
}
return res;
}
private static bool CheckLockedRow(string area0, string areaType, int row)
{
var res = false;
areaTypes.Where(b => b != areaType).ToList().ForEach(b =>
{
//判断库区排有没有被占用
var area = area0 + "_" + b;
var db = new SqlHelper().GetInstance();
var other = db.Queryable().Where(a => a.S_AREA_CODE == area && a.N_ROW == row && a.S_LOCK_STATE.Trim() != "无").First();
if (other != null)
{
res = true;
}
});
return res;
}
internal static void CpAuto()
{
FinishedMoveAuto();
//EmptyAuto();
}
internal static void EmptyAuto()
{
//空框区zoneType=3 自动转运入库
var startZone = Settings.cpZones.Where(a => a.zoneType == 3).FirstOrDefault();
var db = new SqlHelper().GetInstance();
var otherTaskCount = db.Queryable().Count(a => a.S_TYPE == "空托转运入库" && a.S_B_STATE != "完成" && a.S_B_STATE != "取消");
if (otherTaskCount == 0 && startZone != null)
{
var listSize = new List { "大板", "小板", "集化板" };
listSize.ForEach(s =>
{
var list1 = db.Queryable().OrderByDescending(a => a.priority).Where(a => a.cntrType == s).ToList();
if (list1.Count > 0)
{
list1.ForEach(a =>
{
var start = LocationHelper.GetLocation4OutEmptyNotStack(startZone.zone[0], a.startRow, s);
if (start != null)
{
Console.WriteLine("准备创建 自动转运入库");
//创建入库搬运任务
var cntrList = LocationHelper.GetLocCntr(start.S_LOC_CODE);
if (cntrList.Count > 0)
{
Console.WriteLine($"托盘类型 {cntrList[0].Container.S_TYPE}");
Location end = null;
//查找空托入库库区
List list = list1.Where(b => b.startRow == a.startRow).ToList();
if (list.Count > 0)
{
Console.WriteLine("查找空托盘排");
for (int i = 0; i < list.Count; i++)
{
end = GetLocation4EmptyCntrIn(list[i].endArea, list[i].endRow, cntrList[0].Container.S_TYPE);
if (end != null)
{
break;
}
}
//if (end == null) {
// Console.WriteLine("查找空排");
// for (int i = 0; i < list.Count; i++) {
// Console.WriteLine("库区" + list[i]);
// end = GetLocation4InEmptyRow(list[i].endArea, cntrList[0].Container.S_TYPE);
// if (end != null) {
// break;
// }
// }
//}
}
if (end != null)
{
TaskProcess.CreateTransport(start.S_LOC_CODE, end.S_LOC_CODE, "空托转运入库", new List { cntrList[0].S_CNTR_CODE.Trim() }, 1, end.N_CURRENT_NUM + 1, 1, 80);
}
}
else
{
Console.WriteLine($"{start.S_LOC_CODE}未找到托盘");
}
}
else
{
Console.WriteLine("空托转运入库 起点没找到托盘");
}
});
}
});
}
}
private static List GetCPEmptyArea(string cntrType)
{
var db = new SqlHelper().GetInstance();
var list = db.Queryable().OrderByDescending(a => a.priority).Where(a => a.cntrType == cntrType).ToList();
return list;
}
private static List GetCPEmptyArea(string cntrType, int startRow)
{
var db = new SqlHelper().GetInstance();
var list = db.Queryable().OrderByDescending(a => a.priority).Where(a => a.cntrType == cntrType && a.startRow == startRow).ToList();
return list;
}
public static Location GetLocation4EmptyCntrIn(string area0, string trayType)
{
Location result = null;
//string itemBatch = DateTime.Now.ToString("yyMMdd");
try
{
var area = area0 + "_" + GetType(trayType);
Console.WriteLine("成品空托入库 GetLocation4EmptyCntrIn:" + area);
bool flag = false;
var usedRows = GetUsedRow(area0, GetType(trayType), ref flag);
if (flag)
{
Console.WriteLine("当前库区不可用,被其它尺寸托盘占用,直接返回");
return null;
}
//1.0 获取每一排最大的列
//1.1 判断当前数量是不是满的,如果是满的并且是最大列,需要排除
var listMaxCol = new SqlHelper().GetInstance().Queryable().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().GetInstance();
var list = db.Queryable().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();
Console.WriteLine($"查到所有有托盘的排 {list.Count}");
if (list.Count > 0)
{
//1.2 查找其它尺寸有托盘或者锁定的排
for (int i = list.Count - 1; i >= 0; i--)
{
var remove = false;
//排除已经锁定的货位 和 放满了且是最大列的货位
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))
{
Console.WriteLine($"排除已经锁定的货位 和 放满了且是最大列的货位 排{list[i].N_ROW}");
remove = list.Remove(list[i]);
}
else
{
//排有锁也排除
var other = db.Queryable().Where(a => a.S_AREA_CODE == area && a.N_ROW == list[i].N_ROW && a.S_LOCK_STATE.Trim() != "无").First();
if (other != null)
{
Console.WriteLine($"排除有锁的排{list[i].N_ROW}");
remove = list.Remove(list[i]);
}
}
if (!remove)
{
//判断是否被其它库区占用了
Console.WriteLine("判断是否被其它库区占用了");
if (usedRows.Contains(list[i].N_ROW))
{
remove = list.Remove(list[i]);
}
}
}
Console.WriteLine($"有托盘排数为{list.Count}");
if (list.Count > 0)
{
//1.3 遍历判断物料类型是否相同
Console.WriteLine("遍历判断是不是空托盘");
for (int i = 0; i < list.Count; i++)
{
//todo 还需要判断锁
#region 满托盘判断 物料信息相同,并且批次里面的设备相同
if (list[i].LocCntrRel != null && list[i].LocCntrRel.CntrItemRel == null)
{
Console.WriteLine($"有托盘的货位{list[i].S_LOC_CODE} 当前数量={list[i].N_CURRENT_NUM} 容量={list[i].N_CAPACITY}");
if (list[i].N_CURRENT_NUM < list[i].N_CAPACITY)
{
result = list[i];
}
else
{
//选择后面空位
result = db.Queryable().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 && result.C_ENABLE != "禁用")
{
break;
}
}
#endregion
}
}
}
if (result != null && (!string.IsNullOrEmpty(result.C_ENABLE) && result.C_ENABLE == "禁用"))
{
//禁用了选择后面一个货位
//Console.WriteLine("禁用了选择后面一个货位");
result = db.Queryable().OrderBy(a => a.N_COL).Where(a => a.S_AREA_CODE == area && a.N_ROW == result.N_ROW && (string.IsNullOrEmpty(a.C_ENABLE) || a.C_ENABLE != "禁用") && a.N_COL > result.N_COL).First();
}
}
catch (Exception ex)
{
//Console.WriteLine("GetLocation4InFinish:" + ex.Message + ex.StackTrace);
LogHelper.Error("GetLocation4EmptyCntrIn:" + ex.Message, ex);
}
return result;
}
public static Location GetLocation4EmptyCntrIn(string area0, int row, string trayType)
{
Location result = null;
//string itemBatch = DateTime.Now.ToString("yyMMdd");
try
{
var area = area0 + "_" + GetType(trayType);
Console.WriteLine($"成品空托入库 GetLocation4EmptyCntrIn:{area} - {row}");
bool flag = false;
var usedRows = GetUsedRow(area0, GetType(trayType), ref flag);
if (flag)
{
Console.WriteLine("当前库区不可用,被其它尺寸托盘占用,直接返回");
return null;
}
if (!usedRows.Contains(row))
{
//
var db = new SqlHelper().GetInstance();
var list = db.Queryable().Where(a => a.N_CURRENT_NUM > 0 && a.N_ROW == row && a.S_AREA_CODE == area).Includes(a => a.LocCntrRel, a => a.CntrItemRel).OrderByDescending(a => a.N_COL).ToList();
if (list.Count(a => a.S_LOCK_STATE != "无") == 0)
{
//没有锁
if (list.Count > 0)
{
var last = list.OrderByDescending(a => a.N_COL).FirstOrDefault();
if (last.LocCntrRel != null && last.LocCntrRel.CntrItemRel == null)
{
//是空托盘
if (last.N_CURRENT_NUM == 1)
{
result = last;
}
else
{
result = db.Queryable().Where(a => a.N_ROW == row && a.S_AREA_CODE == area && a.N_COL > last.N_COL).OrderBy(a => a.N_COL).First();
}
}
}
else
{
//当前排没有托盘是空排,判断有没有被其它库区锁定
if (!CheckLockedRow(area0, GetType(trayType), row))
{
//没有锁住入最小位置
result = db.Queryable().Where(a => a.N_ROW == row && a.S_AREA_CODE == area).OrderBy(a => a.N_COL).First();
}
}
if (result != null && (!string.IsNullOrEmpty(result.C_ENABLE) && result.C_ENABLE == "禁用"))
{
//禁用了选择后面一个货位
//Console.WriteLine("禁用了选择后面一个货位");
result = db.Queryable().OrderBy(a => a.N_COL).Where(a => a.S_AREA_CODE == area && a.N_ROW == result.N_ROW && (string.IsNullOrEmpty(a.C_ENABLE) || a.C_ENABLE != "禁用") && a.N_COL > result.N_COL).First();
}
}
}
}
catch (Exception ex)
{
//Console.WriteLine("GetLocation4InFinish:" + ex.Message + ex.StackTrace);
LogHelper.Error("GetLocation4EmptyCntrIn:" + ex.Message, ex);
}
return result;
}
private static bool CheckStartRow(string baseArea, int row, string size)
{
//判断起点库区排有托盘
bool res = false;
var area = baseArea + "_" + GetType(size);
var db = new SqlHelper().GetInstance();
res = db.Queryable().Count(l => l.S_AREA_CODE == area && l.N_ROW == row && l.N_CURRENT_NUM > 0) > 0;
return res;
}
private static bool CheckEndRow(string baseArea, int row, string size)
{
//判断终点库区排有相同托盘,或者没有其他托盘
bool res = false;
var area = baseArea + "_" + GetType(size);
var db = new SqlHelper().GetInstance();
res = db.Queryable().Count(l => l.S_AREA_CODE == area && l.N_ROW == row && l.N_CURRENT_NUM > 0) > 0;
if (!res)
{
//终点排没有托盘,判断是否有其他尺寸的托盘
LogHelper.Info($"移库任务:终点排没有托盘,判断是否有其他尺寸的托盘");
var list = GetOtherAreas(baseArea, size);
var res1 = true;
for (int i = 0; i < list.Count; i++)
{
res1 = db.Queryable().Count(l => l.S_AREA_CODE == list[i] && l.N_ROW == row && l.N_CURRENT_NUM > 0) == 0;
if (!res1)
{
LogHelper.Info($"移库任务:库区{list[i]},排{row},存在托盘");
break;
}
}
res = res1;
}
return res;
}
///
/// 移库
///
internal static void FinishedMoveAuto()
{
try
{
var db = new SqlHelper().GetInstance();
//检查
var listUnlock = db.Queryable().Where(a => a.SQL_State == "已完成" && a.IsUnlock != "1").ToList();
if (listUnlock.Count > 0)
{
listUnlock.ForEach(a =>
{
//根据起点排,起点库区查询托盘类型
string tptype = GetTypebyrow(a.start_area, a.start_row);
var startArea = a.start_area + "_" + GetType(tptype);
var endArea = a.end_area + "_" + GetType(tptype);
AddMoveOrderNotice(a.SQL_WorkNo, startArea, a.start_row, endArea, a.end_row);
if (a.IsUnlock != "1")
{
//手动移库货位解锁上报
YiKuUnLockRow(a.start_area + "-" + a.start_row.ToString() + "," + a.end_area + "-" + a.end_row.ToString(), a.SQL_WorkNo, false, startArea, endArea, a.start_row, a.end_row);
}
a.IsUnlock = "1";
a.T_MODIFY = DateTime.Now;
db.Updateable(a).UpdateColumns(it => new { it.IsUnlock, it.T_MODIFY }).ExecuteCommand();
});
}
var list = db.Queryable().Where(a => a.SQL_State == "执行中").ToList();
if (list.Count > 0)
{
//判断是否有其它任务相同起点排或者相同终点排,如果有优先级更高,当前工单不做
//Console.WriteLine("成品移库,判断是否有其它任务相同起点排或者相同终点排,如果有优先级更高,当前工单不做");
list.ForEach(a =>
{
//根据起点排,起点库区查询托盘类型
string tptype = GetTypebyrow(a.start_area, a.start_row);
//var other = list.OrderByDescending(b => b.priority).Where(b => b.S_ID != a.S_ID && ((b.start_area == a.start_area && b.start_row == a.start_row) || (b.end_area == a.end_area && b.end_row == a.end_row))).FirstOrDefault();
//if (other == null || (a.priority > other.priority || (a.priority == other.priority && a.T_CREATE < other.T_CREATE))) {
//准备移库
var startArea = a.start_area + "_" + GetType(tptype);
var endArea = a.end_area + "_" + GetType(tptype);
AddMoveOrderNotice(a.SQL_WorkNo, startArea, a.start_row, endArea, a.end_row, false);
//判断是否有执行中的任务
if (IsTask(a.SQL_WorkNo))
{
//判断起点排是否有正确托盘、终点排有托盘,如果没托盘是否有其他尺寸托
if (!CheckStartRow(a.start_area, a.start_row, tptype))
{
a.note = $"起点库区、排没有找到{tptype}托盘";
a.SQL_State = "已完成";
a.IsUnlock = "1";
a.T_MODIFY = DateTime.Now;
db.Updateable(a).UpdateColumns(it => new { it.SQL_State, it.note, it.IsUnlock, it.T_MODIFY }).ExecuteCommand();
AddMoveOrderNotice(a.SQL_WorkNo, startArea, a.start_row, endArea, a.end_row);
//货位解锁上报
LogHelper.Info($"移库任务:{a.SQL_WorkNo}=> 起点库区、排没有找到{tptype}托盘,任务改成完成");
YiKuUnLockRow(a.start_area + "-" + a.start_row.ToString() + "," + a.end_area + "-" + a.end_row.ToString(), a.SQL_WorkNo, false, startArea, endArea, a.start_row, a.end_row);
return;
}
}
if (!CheckEndRow(a.end_area, a.end_row, tptype))
{
a.note = $"终点库区、排有其他尺寸托盘";
a.SQL_State = "已完成";
a.IsUnlock = "1";
a.T_MODIFY = DateTime.Now;
db.Updateable(a).UpdateColumns(it => new { it.SQL_State, it.note, it.IsUnlock, it.T_MODIFY }).ExecuteCommand();
AddMoveOrderNotice(a.SQL_WorkNo, startArea, a.start_row, endArea, a.end_row);
//货位解锁上报
LogHelper.Info($"移库任务:{a.SQL_WorkNo}=> 终点库区、排有其他尺寸托盘,任务改成完成");
YiKuUnLockRow(a.start_area + "-" + a.start_row.ToString() + "," + a.end_area + "-" + a.end_row.ToString(), a.SQL_WorkNo, false, startArea, endArea, a.start_row, a.end_row);
return;
}
//起点排的货位全部查询
Console.WriteLine("准备移库");
if (a.current >= a.number)
{
a.note = $"已经完成入库数量";
a.SQL_State = "已完成";
a.IsUnlock = "1";
a.T_MODIFY = DateTime.Now;
db.Updateable(a).UpdateColumns(it => new { it.SQL_State, it.note, it.IsUnlock, it.T_MODIFY }).ExecuteCommand();
AddMoveOrderNotice(a.SQL_WorkNo, startArea, a.start_row, endArea, a.end_row);
//货位解锁上报
LogHelper.Info($"移库任务:{a.SQL_WorkNo}=> 已经完成入库数量,任务改成完成");
YiKuUnLockRow(a.start_area + "-" + a.start_row.ToString() + "," + a.end_area + "-" + a.end_row.ToString(), a.SQL_WorkNo, false, startArea, endArea, a.start_row, a.end_row);
return;
}
var listStarts = new SqlHelper().GetList(b => b.S_AREA_CODE.Trim() == startArea && b.N_ROW == a.start_row);
if (listStarts.Count > 0 && listStarts.Count(b => b.S_LOCK_STATE.Trim() != "无") == 0)
{
//列从大到小找一个满托
//Console.WriteLine("列从大到小找一个满托");
var start = listStarts.OrderByDescending(l => l.N_COL).Where(l => l.N_CURRENT_NUM > 0).FirstOrDefault();
if (start != null)
{
var cntrList = LocationHelper.GetLocCntr(start.S_LOC_CODE);
var cntr = cntrList.OrderByDescending(c => c.T_CREATE).Take(2).ToList();
var cirStart = ContainerHelper.GetCntrItemRel(cntr[0].S_CNTR_CODE);
// string tp = cntr.ToString();
string tp = string.Join(",", cntr.Select(t => t.S_CNTR_CODE).ToArray());
//查找终点
//Console.WriteLine("查找终点");
var listEnds = new SqlHelper().GetList(b => b.S_AREA_CODE.Trim() == endArea && b.N_ROW == a.end_row);// && b.C_ENABLE != "禁用"
if (listEnds.Count > 0 && listStarts.Count(b => b.S_LOCK_STATE.Trim() != "无") == 0 && listEnds.Count(b => b.S_LOCK_STATE.Trim() != "无") == 0)
{
//从大到小找个满的,然后选择后面一个空位
//Console.WriteLine("从大到小找个满的");
var full = listEnds.OrderByDescending(l => l.N_COL).Where(l => l.N_CURRENT_NUM > 0).FirstOrDefault();
if (full == null)
{
var end = listEnds.Where(loc => loc.C_ENABLE != "禁用").OrderBy(loc => loc.N_COL).FirstOrDefault();
int cg = 0;
//计算层高
if (end.N_CURRENT_NUM == 0)
{
cg = 1;
}
else if (end.N_CURRENT_NUM == 2)
{
cg = 2;
}
else if (end.N_CURRENT_NUM == 4)
{
cg = 3;
}
//创建任务
//Console.WriteLine("没有满托,选一个最小的空位");
TaskProcess.CreateTransport(start.S_LOC_CODE, end.S_LOC_CODE, "成品移库", new List { tp.Trim() }, cntrList.Count / 2, cg, 1, 1, a.SQL_WorkNo);
a.current++;
a.T_MODIFY = DateTime.Now;
db.Updateable(a).UpdateColumns(it => new { it.current, it.T_MODIFY }).ExecuteCommand();
//货位锁定上报
YiKuUnLockRow(a.start_area + "-" + a.start_row.ToString() + "," + a.end_area + "-" + a.end_row.ToString(), a.SQL_WorkNo, true, startArea, endArea, a.start_row, a.end_row);
}
else
{
var cntrFull = LocationHelper.GetLocCntr(full.S_LOC_CODE);
var cirEnd = ContainerHelper.GetCntrItemRel(cntrFull[0].S_CNTR_CODE);
if (cirStart[0].S_ITEM_CODE.Trim() != cirEnd[0].S_ITEM_CODE.Trim())
{
//物料信息不一样,直接结束工单
//Console.WriteLine("物料信息不一样,直接结束工单");
a.note = "物料信息不一样,工单结束";
a.SQL_State = "已完成";
a.IsUnlock = "1";
a.T_MODIFY = DateTime.Now;
db.Updateable(a).UpdateColumns(it => new { it.SQL_State, it.note, it.IsUnlock, it.T_MODIFY }).ExecuteCommand();
AddMoveOrderNotice(a.SQL_WorkNo, startArea, a.start_row, endArea, a.end_row);
LogHelper.Info($"移库任务:{a.SQL_WorkNo}=> 物料信息不一样,工单结束,任务改成完成");
//货位解锁上报
YiKuUnLockRow(a.start_area + "-" + a.start_row.ToString() + "," + a.end_area + "-" + a.end_row.ToString(), a.SQL_WorkNo, false, startArea, endArea, a.start_row, a.end_row);
}
else
{
//判断批次是不是一样
//if (cirStart[0].S_BATCH_NO.Substring(0, 6) == cirEnd[0].S_BATCH_NO.Substring(0, 6)) {
//Console.WriteLine("批次一样");
//判断满托位有几个托盘,如果是4个托盘,直接找后一位
if (cntrFull.Count == 4)
{
//Console.WriteLine("货位满了,选择后一个货位");
var after = listEnds.OrderBy(loc => loc.N_COL).Where(loc => loc.N_COL > full.N_COL && loc.C_ENABLE != "禁用").FirstOrDefault();
//创建任务
if (after != null)
{
int cg = 0;
//计算层高
if (after.N_CURRENT_NUM == 0)
{
cg = 1;
}
else if (after.N_CURRENT_NUM == 2)
{
cg = 2;
}
else if (after.N_CURRENT_NUM == 4)
{
cg = 3;
}
TaskProcess.CreateTransport(start.S_LOC_CODE, after.S_LOC_CODE, "成品移库", new List { tp.Trim() }, cntrList.Count / 2, cg, 1, 1, a.SQL_WorkNo);
a.current++;
a.T_MODIFY = DateTime.Now;
db.Updateable(a).UpdateColumns(it => new { it.current, it.T_MODIFY }).ExecuteCommand();
//货位锁定上报
YiKuUnLockRow(a.start_area + "-" + a.start_row.ToString() + "," + a.end_area + "-" + a.end_row.ToString(), a.SQL_WorkNo, true, startArea, endArea, a.start_row, a.end_row);
}
}
else
{
//如果是1个托盘,要判断是单托还是双托
//Console.WriteLine("如果是1个托盘,要判断是单托还是双托");
//if (cntrFull[0].S_CNTR_CODE.Contains(','))
// {
//创建任务
//Console.WriteLine("双托,可以卸货");
int cg = 0;
//计算层高
if (full.N_CURRENT_NUM == 0)
{
cg = 1;
}
else if (full.N_CURRENT_NUM == 2)
{
cg = 2;
}
else if (full.N_CURRENT_NUM == 4)
{
cg = 3;
}
TaskProcess.CreateTransport(start.S_LOC_CODE, full.S_LOC_CODE, "成品移库", new List { tp.Trim() }, cntrList.Count / 2, cg, 1, 1, a.SQL_WorkNo);
a.current++;
a.T_MODIFY = DateTime.Now;
db.Updateable(a).UpdateColumns(it => new { it.current, it.T_MODIFY }).ExecuteCommand();
//货位锁定上报
YiKuUnLockRow(a.start_area + "-" + a.start_row.ToString() + "," + a.end_area + "-" + a.end_row.ToString(), a.SQL_WorkNo, true, startArea, endArea, a.start_row, a.end_row);
// }
//else
//{
// //单托不可以卸货
// //Console.WriteLine("单托不可以卸货,选择后一个货位");
// var after = listEnds.OrderBy(loc => loc.N_COL).Where(loc => loc.N_COL > full.N_COL && loc.C_ENABLE != "禁用").FirstOrDefault();
// //创建任务
// if (after != null)
// {
// TaskProcess.CreateTransport(start.S_LOC_CODE, after.S_LOC_CODE, "成品移库", new List { cntr.S_CNTR_CODE.Trim() }, cntrList.Count, 1);
// a.current++;
// a.T_MODIFY = DateTime.Now;
// db.Updateable(a).UpdateColumns(it => new { it.current, it.T_MODIFY }).ExecuteCommand();
// }
// else
// {
// //终点排满了,自动结束
// //Console.WriteLine("终点满了或不可入,工单结束");
// a.note = "终点满了或不可入,工单结束";
// a.SQL_State = "已完成";
// a.IsUnlock = "1";
// a.T_MODIFY = DateTime.Now;
// db.Updateable(a).UpdateColumns(it => new { it.SQL_State, it.note, it.IsUnlock, it.T_MODIFY }).ExecuteCommand();
// AddMoveOrderNotice(a.SQL_WorkNo, startArea, a.start_row, endArea, a.end_row);
// }
//}
}
//}
//else {
// //批次不一样,空一格
// //Console.WriteLine("批次不一样,空一格");
// var after = listEnds.OrderBy(loc => loc.N_COL).Where(loc => loc.N_COL > (full.N_COL + 1) && loc.C_ENABLE != "禁用").FirstOrDefault();
// if (after != null) {
// TaskProcess.CreateTransport(start.S_LOC_CODE, after.S_LOC_CODE, "成品移库", new List { cntr.S_CNTR_CODE.Trim() }, cntrList.Count, 1);
// }
// else {
// //终点排满了,自动结束
// //Console.WriteLine("终点满了或不可入,工单结束");
// a.note = "终点满了或不可入,工单结束";
// a.SQL_State = "已完成";
// a.IsUnlock = "1";
// db.Updateable(a).UpdateColumns(it => new { it.SQL_State, it.note, it.IsUnlock }).ExecuteCommand();
// AddMoveOrderNotice(a.SQL_WorkNo, startArea, a.start_row, endArea, a.end_row);
// }
//}
}
}
}
}
else
{
if (IsTask(a.SQL_WorkNo))
{
//起点排没有托盘了,更新工单状态为完成
a.note = "起点没托盘,工单结束";
a.SQL_State = "已完成";
a.IsUnlock = "1";
a.T_MODIFY = DateTime.Now;
db.Updateable(a).UpdateColumns(it => new { it.SQL_State, it.note, it.IsUnlock, it.T_MODIFY }).ExecuteCommand();
AddMoveOrderNotice(a.SQL_WorkNo, startArea, a.start_row, endArea, a.end_row);
//货位解锁上报
LogHelper.Info($"移库任务:{a.SQL_WorkNo}=> 起点没托盘,工单结束,任务改成完成");
YiKuUnLockRow(a.start_area + "-" + a.start_row.ToString() + "," + a.end_area + "-" + a.end_row.ToString(), a.SQL_WorkNo, false, startArea, endArea, a.start_row, a.end_row);
}
}
}
});
}
}
catch (Exception ex)
{
//Console.WriteLine("FinishedMoveAuto:" + ex.Message);
LogHelper.Error("FinishedMoveAuto:" + ex.Message, ex);
}
}
private static void AddMoveOrderNotice(string moveOrder, string start_area, int start_row, string end_area, int end_row, bool complete = true)
{
var db = new SqlHelper().GetInstance();
var start = db.Queryable().Where(a => a.S_AREA_CODE == start_area && a.N_ROW == start_row).First();
var end = db.Queryable().Where(a => a.S_AREA_CODE == end_area && a.N_ROW == end_row).First();
if (start != null && end != null)
{
var startArea = start.S_LOC_CODE.Substring(0, 1) + start.N_ROW;
var endArea = end.S_LOC_CODE.Substring(0, 1) + end.N_ROW;
var old = db.Queryable().Where(a => a.OrderNo == moveOrder).First();
if (!complete)
{
if (old == null)
{
old = new MoveOrderNotice { OrderNo = moveOrder };
old.StartArea = startArea;
old.EndArea = endArea;
db.Insertable(old).ExecuteCommand();
}
}
else
{
if (old != null)
{
old.State = 1;
old.IsNotice = 0;
db.Updateable(old).UpdateColumns(it => new { it.State, it.IsNotice }).ExecuteCommand();
}
}
}
}
internal static Location GetLocation4EmptyCntrOut(string size)
{
Location start = null;
var db = new SqlHelper().GetInstance();
var list = db.Queryable().ToList();
if (list.Count > 0)
{
for (int i = 0; i < list.Count; i++)
{
start = GetLocation4EmptyOut(list[i].area, list[i].row, size);
if (start != null)
{
break;
}
}
}
return start;
}
public static Location GetLocation4EmptyOut(string area0, string trayType)
{
Location result = null;
try
{
var area = area0 + "_" + GetType(trayType);
Console.WriteLine("成品空托出库 GetLocation4EmptyOut:" + area);
//var usedRows = GetUsedRow(area0, GetType(trayType));
bool flag = false;
var usedRows = GetUsedRow(area0, GetType(trayType), ref flag);
if (flag) { return null; }
//1.0 获取每一排最大的列
//1.1 判断当前数量是不是满的,如果是满的并且是最大列,需要排除
var listMaxCol = new SqlHelper().GetInstance().Queryable().Where(a => a.S_AREA_CODE == area).OrderByDescending(a => a.N_COL).Take(1).PartitionBy(a => a.N_ROW).ToList();
//1.1 查到所有有托盘的排
Console.WriteLine("查到所有有托盘的排 ");
var db = new SqlHelper().GetInstance();
var list = db.Queryable().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)
{
//1.2 查找其它尺寸有托盘或者锁定的排
for (int i = list.Count - 1; i >= 0; i--)
{
var remove = false;
//排除已经锁定的货位
if (list[i].S_LOCK_STATE.Trim() != "无")
{
remove = list.Remove(list[i]);
}
else
{
//排有锁也排除
var other = db.Queryable().Where(a => a.S_AREA_CODE == area && a.N_ROW == list[i].N_ROW && a.S_LOCK_STATE.Trim() != "无").First();
if (other != null)
{
//Console.WriteLine($"排除有锁的排{list[i].N_ROW}");
remove = list.Remove(list[i]);
}
}
if (!remove)
{
//判断是否被其它库区占用了
if (usedRows.Contains(list[i].N_ROW))
{
remove = list.Remove(list[i]);
}
}
}
Console.WriteLine($"有托盘排数为{list.Count}");
if (list.Count > 0)
{
//1.3 遍历判断物料类型是否相同
Console.WriteLine("遍历判断是否为空托盘");
for (int i = 0; i < list.Count; i++)
{
if (list[i].LocCntrRel != null && list[i].LocCntrRel.CntrItemRel == null)
{
result = list[i];
if (result != null)
{
break;
}
}
}
}
}
}
catch (Exception ex)
{
LogHelper.Error("GetLocation4EmptyOut:" + ex.Message, ex);
}
return result;
}
public static Location GetLocation4EmptyOut(string area0, int row, string trayType)
{
Location result = null;
try
{
var area = area0 + "_" + GetType(trayType);
Console.WriteLine($"成品空托出库 GetLocation4EmptyOut: {area} - {row}");
var list = new SqlHelper().GetInstance().Queryable().Where(a => a.S_AREA_CODE == area && a.N_ROW == row && a.N_CURRENT_NUM > 0).Includes(a => a.LocCntrRel, a => a.CntrItemRel).ToList();
if (list.Count > 0 && list.Count(a => a.S_LOCK_STATE != "无") == 0)
{
//当前排没有锁
//判断托盘类型是否一致
var start = list.OrderByDescending(a => a.N_COL).FirstOrDefault();
if (start.LocCntrRel != null && start.LocCntrRel.CntrItemRel == null)
{
result = start;
}
}
}
catch (Exception ex)
{
LogHelper.Error("GetLocation4EmptyOut:" + ex.Message, ex);
}
return result;
}
///
/// 移库 上报锁定或解锁库位(排)
///
///
public static void YiKuUnLockRow(string row, string worno, bool state, string startarea, string endarea, int startrow, int endrow)
{
// var db = new SqlHelper().GetInstance();
//检查
//var Startloc = db.Queryable().Where(a => a.S_AREA_CODE == startarea && a.N_ROW == startrow).ToList();
//var Endloc = db.Queryable().Where(a => a.S_AREA_CODE == endarea && a.N_ROW == endrow).ToList();
// 第一次生成任务上报锁定货位
// 接触货位判断是不是生成过货位
// 排锁上报格式:库区加排号 如:(C04-1)
if (state)
{
//判断是否第一条任务,第一条任务上报锁定排
var task = TaskHelper.GetTaskBySrcNo(worno);
if (task.Count == 1)
{
//移库锁定货位上报
TaskProcess.AreaRowLockState(row, state);
#region 排锁 弃用
//移库起点终点排添加移库锁
//Startloc.ForEach(a =>
//{
// LocationHelper.LockLoc(a.S_LOC_CODE, "移库锁");
//});
//Endloc.ForEach(a =>
//{
// LocationHelper.LockLoc(a.S_LOC_CODE, "移库锁");
//});
#endregion
}
}
else
{
//判断是否创建任务,创建任务上传解锁排
var task = TaskHelper.GetTaskBySrcNo(worno);
if (task.Count >= 1)
{
//移库解锁定货位上报
TaskProcess.AreaRowLockState(row, state);
#region 排锁 弃用
//移库起点终点排解锁
//Startloc.ForEach(a =>
//{
// LocationHelper.LockLoc(a.S_LOC_CODE, "无");
//});
//Endloc.ForEach(a =>
//{
// LocationHelper.LockLoc(a.S_LOC_CODE, "无");
//});
#endregion
}
}
}
///
/// 根据移库单号判断移库任务是否全部完成
///
///
///
public static bool IsTask(string worno)
{
bool res = true;
var db = new SqlHelper().GetInstance();
//判断是否有未完成的任务
var task = TaskHelper.GetTaskBySrcNo(worno);
List taskbystate = task.FindAll(a => a.S_B_STATE != "完成").ToList();
taskbystate = taskbystate.FindAll(a => a.S_B_STATE != "强制完成").ToList();
if (taskbystate.Count > 0)
{
res = false;
}
return res;
}
}
}