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
|
{
|
/// <summary>
|
/// 成品流程
|
/// </summary>
|
internal class ProcessHelperCP
|
{
|
private static Dictionary<string, int> itemHeights = new Dictionary<string, int>();
|
|
static ProcessHelperCP()
|
{
|
new SqlHelper<object>().CreateTable(new List<Type> {
|
typeof(MoveOrderNotice),
|
typeof(InOutRecord),
|
typeof(PgZsjReportMesInfo),
|
typeof(PgFdjReportMesFeedInfo),
|
typeof(PgReportFluxInfo),
|
});
|
|
var db = new SqlHelper<object>().GetInstance();
|
var list = db.Queryable<ItemInfo>().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);
|
}
|
});
|
}
|
}
|
|
/// <summary>
|
/// 根据物料信息获取托盘高度
|
/// </summary>
|
/// <param name="itemCode"></param>
|
/// <returns></returns>
|
internal static int GetTrayHeightByItem(string itemCode)
|
{
|
var result = 0;
|
if (itemHeights.Keys.Contains(itemCode))
|
{
|
result = itemHeights[itemCode];
|
}
|
else
|
{
|
var db = new SqlHelper<object>().GetInstance();
|
var itemInfo = db.Queryable<ItemInfo>().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;
|
}
|
|
|
/// <summary>
|
/// 获取物料二层高度
|
/// </summary>
|
/// <param name="itemName">物料名称</param>
|
/// <param name="itemLayer">物料层高</param>
|
/// <param name="irayType">托盘类型</param>
|
/// <returns></returns>
|
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<object>().GetInstance();
|
var itemInfo = db.Queryable<ItemInfo>().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;
|
}
|
|
/// <summary>
|
/// 获取物料层高
|
/// </summary>
|
/// <param name="trayCode"></param>
|
/// <returns></returns>
|
internal static int GetTrayHeightByTray(string trayCode)
|
{
|
var result = 0;
|
|
var db = new SqlHelper<object>().GetInstance();
|
|
|
var cntr = db.Queryable<Container>().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;
|
}
|
/// <summary>
|
/// 获取富勒物料层高
|
/// </summary>
|
/// <param name="trayCode"></param>
|
/// <returns></returns>
|
internal static int GetTrayHeightByTrayFL(string trayCode)
|
{
|
var result = 0;
|
int itemLayer = 0;
|
var db = new SqlHelper<object>().GetInstance();
|
|
var cntrfl = db.Queryable<ThirdPartTrayInfo>().Where(a => a.trayCode.Contains(trayCode)).First();
|
if (cntrfl != null)
|
{
|
itemLayer = int.Parse(cntrfl.itemLayer);
|
var cntr = db.Queryable<Container>().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;
|
}
|
|
/// <summary>
|
/// 成品下线
|
/// </summary>
|
/// <param name="workOrder"></param>
|
/// <param name="loc"></param>
|
/// <param name="height"></param>
|
internal static void InStock(WorkOrder1 workOrder, string loc)
|
{
|
try
|
{
|
//判断最大任务数,如果执行中的任务大于等于最大任务数,不生成任务
|
if (!TaskHelper.GetTaskByMaxtask(workOrder, loc))
|
{
|
LogHelper.Info($"执行中任务数量大于等于最大任务限制,不生成任务", "成品");
|
return;
|
}
|
//根据工单查询对应物料信息
|
var db = new SqlHelper<object>().GetInstance();
|
ItemInfo item = null;
|
if (workOrder.withCode == "是")
|
{
|
//使用富勒数据
|
// List<ThirdPartTrayInfo> trayInfos = GetThirdPartTrayInfo(workOrder.S_WorkNo);
|
List<ThirdPartTrayInfo> 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<ItemInfo>().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<ItemInfo>().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<string> { };
|
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<ThirdPartTrayInfo> trayInfos = GetThirdPartTrayInfo(workOrder.S_WorkNo);
|
List<ThirdPartTrayInfo> 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<string> { 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;
|
}
|
|
}
|
/// <summary>
|
/// 顶升机下线
|
/// </summary>
|
/// <param name="workOrder"></param>
|
/// <param name="loc"></param>
|
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<string> { tray }, 1, 1, 1, 80);
|
}
|
}
|
catch (Exception ex)
|
{
|
|
LogHelper.Info($"DsjStock-Error:{ex.ToString()}", "顶升机");
|
}
|
|
}
|
|
/// <summary>
|
/// 获取富勒托盘数据
|
/// </summary>
|
/// <param name="workNo"></param>
|
/// <returns></returns>
|
private static List<ThirdPartTrayInfo> GetThirdPartTrayInfo(string workNo)
|
{
|
var db = new SqlHelper<object>().GetInstance();
|
return db.Queryable<ThirdPartTrayInfo>().Where(a => a.workNo == workNo).ToList();
|
}
|
|
|
/// <summary>
|
/// 获取富勒托盘数据
|
/// </summary>
|
/// <param name="workNo"></param>
|
/// <returns></returns>
|
private static List<ThirdPartTrayInfo> GetThirdPartTrayInfoByDeviceName(string deviceName)
|
{
|
var db = new SqlHelper<object>().GetInstance();
|
return db.Queryable<ThirdPartTrayInfo>().Where(a => a.deviceName == deviceName).ToList();
|
}
|
/// <summary>
|
/// 同品相 同设备 同批次 的可以入同一排
|
/// </summary>
|
/// <param name="area0"></param>
|
/// <param name="itemCode"></param>
|
/// <param name="trayType"></param>
|
/// <returns></returns>
|
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<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();
|
// Console.WriteLine($"查到所有有托盘的排 {list.Count}");
|
// LogHelper.Info($"查到所有有托盘的排 {list.Count}", "HosttoagvTask");
|
////查询移库工单相同库区的数据
|
//var listykstart = db.Queryable<WorkOrder2>().Where(a => a.start_area== area0).ToList();
|
//var listykend = db.Queryable<WorkOrder2>().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<Location>().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<Location>().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<Location>().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<Location>().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<Location>().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<Location>().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;
|
}
|
|
/// <summary>
|
/// 成品入库移库完成记录信息需要上报给富勒
|
/// </summary>
|
/// <param name="mst"></param>
|
/// <param name="move"></param>
|
internal static void AddTaskStatus(WMSTask mst, bool move = false)
|
{
|
try
|
{
|
//无码的不需要写入中间表
|
if (mst.S_CNTRS.Length != 25)
|
{
|
var db = new SqlHelper<object>().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<Container>().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<InOutRecord>(model).ExecuteCommand();
|
}
|
|
}
|
catch (Exception ex)
|
{
|
|
LogHelper.Info($"写入 InOutRecord 失败{ex.Message}");
|
}
|
}
|
|
/// <summary>
|
/// 查找空排
|
/// </summary>
|
/// <param name="area0"></param>
|
/// <param name="itemCode"></param>
|
/// <param name="itemBatch"></param>
|
/// <param name="trayType"></param>
|
/// <returns></returns>
|
public static Location GetLocation4InEmptyRow(string area0, string trayType)
|
{
|
Location result = null;
|
|
try
|
{
|
var db = new SqlHelper<object>().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<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();
|
// 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<Location>().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<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();
|
//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<Location>().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;
|
}
|
|
/// <summary>
|
/// 同品相 不同设备的可以入同一排
|
/// </summary>
|
/// <param name="area0"></param>
|
/// <param name="itemCode"></param>
|
/// <param name="itemBatch"></param>
|
/// <param name="trayType"></param>
|
/// <returns></returns>
|
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<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 查到所有有托盘的排
|
Console.WriteLine("查到所有有托盘的排 ");
|
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)
|
{
|
//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<Location>().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<Location>().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<Location>().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<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();
|
|
LogHelper.Info($"{list[i]}货位满,批次号相同找后一个空货位", "成品");
|
}
|
else
|
{
|
LogHelper.Info($"{list[i]}货位满,批次号不同,隔一个空位", "成品");
|
result = db.Queryable<Location>().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<Location>().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;
|
}
|
/// <summary>
|
/// 根据物料信息获取入库优先级
|
/// </summary>
|
/// <param name="ItemCode"></param>
|
/// <returns></returns>
|
/// <exception cref="NotImplementedException"></exception>
|
private static List<string> GetZones(string ItemName)
|
{
|
var list = new List<string>();
|
var db = new SqlHelper<object>().GetInstance();
|
var itemZonePris = db.Queryable<ItemZonePriInfo>().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;
|
}
|
|
/// <summary>
|
/// 根据托盘类型获取库区后缀
|
/// </summary>
|
/// <param name="trayType"></param>
|
/// <returns></returns>
|
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;
|
}
|
|
|
/// <summary>
|
/// 根据库区和排号找托盘类型
|
/// </summary>
|
/// <param name="kq"></param>
|
/// <param name="row"></param>
|
/// <returns></returns>
|
public static string GetTypebyrow(string kq, int row)
|
{
|
var res = "";
|
string trayType = "";
|
var db = new SqlHelper<object>().GetInstance();
|
//string[] reslist = new string[] { "D", "J", "X", "JC2", "DC", "XC", "JC" };
|
foreach (var item in areaTypes)
|
{
|
var list = db.Queryable<Location>().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;
|
|
|
}
|
/// <summary>
|
/// 库区后缀
|
/// </summary>
|
private static List<string> areaTypes = new List<string> { "J", "D", "X", "JC2", "DC", "XC", "JC4", "C" };
|
public static List<string> GetOtherAreas(string baseArea, string size)
|
{
|
var res = new List<string>();
|
var at = GetType(size);
|
for (int i = 0; i < areaTypes.Count; i++)
|
{
|
if (areaTypes[i] != at)
|
{
|
res.Add(baseArea + "_" + areaTypes[i]);
|
}
|
}
|
return res;
|
}
|
|
/// <summary>
|
/// 获取被占用的排号
|
/// </summary>
|
/// <param name="area0"></param>
|
/// <param name="areaType"></param>
|
/// <param name="flag"></param>
|
/// <returns></returns>
|
private static List<int> GetUsedRow(string area0, string areaType, ref bool flag)
|
{
|
//如果当前库区是C,有任意库区任意排不是C整区不能入
|
//如果当前库区不是C,但是有任意排有C整区不能入
|
bool intercept = false;
|
var db = new SqlHelper<object>().GetInstance();
|
var res = new List<int>();
|
areaTypes.Where(b => b != areaType).ToList().ForEach(b =>
|
{
|
//判断库区排有没有被占用
|
var area = area0 + "_" + b;
|
//有托盘的其他库区的排要排除
|
var list = db.Queryable<Location>().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<Location>().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<WorkOrder2>().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<WorkOrder2>().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<object>().GetInstance();
|
var other = db.Queryable<Location>().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<object>().GetInstance();
|
var otherTaskCount = db.Queryable<WMSTask>().Count(a => a.S_TYPE == "空托转运入库" && a.S_B_STATE != "完成" && a.S_B_STATE != "取消");
|
if (otherTaskCount == 0 && startZone != null)
|
{
|
var listSize = new List<string> { "大板", "小板", "集化板" };
|
listSize.ForEach(s =>
|
{
|
|
var list1 = db.Queryable<CPEmptyIn>().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<CPEmptyIn> 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<string> { 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<CPEmptyIn> GetCPEmptyArea(string cntrType)
|
{
|
var db = new SqlHelper<object>().GetInstance();
|
var list = db.Queryable<CPEmptyIn>().OrderByDescending(a => a.priority).Where(a => a.cntrType == cntrType).ToList();
|
return list;
|
}
|
private static List<CPEmptyIn> GetCPEmptyArea(string cntrType, int startRow)
|
{
|
var db = new SqlHelper<object>().GetInstance();
|
var list = db.Queryable<CPEmptyIn>().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<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();
|
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<Location>().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<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 && result.C_ENABLE != "禁用")
|
{
|
break;
|
}
|
|
}
|
|
|
#endregion
|
}
|
}
|
}
|
|
if (result != null && (!string.IsNullOrEmpty(result.C_ENABLE) && result.C_ENABLE == "禁用"))
|
{
|
//禁用了选择后面一个货位
|
//Console.WriteLine("禁用了选择后面一个货位");
|
result = db.Queryable<Location>().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<object>().GetInstance();
|
var list = db.Queryable<Location>().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<Location>().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<Location>().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<Location>().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<object>().GetInstance();
|
|
res = db.Queryable<Location>().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<object>().GetInstance();
|
res = db.Queryable<Location>().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<Location>().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;
|
}
|
|
|
|
/// <summary>
|
/// 移库
|
/// </summary>
|
internal static void FinishedMoveAuto()
|
{
|
try
|
{
|
var db = new SqlHelper<object>().GetInstance();
|
//检查
|
var listUnlock = db.Queryable<WorkOrder2>().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<WorkOrder2>().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<Location>().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<Location>().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<string> { 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<string> { 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<string> { 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<string> { 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<string> { 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<object>().GetInstance();
|
var start = db.Queryable<Location>().Where(a => a.S_AREA_CODE == start_area && a.N_ROW == start_row).First();
|
var end = db.Queryable<Location>().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<MoveOrderNotice>().Where(a => a.OrderNo == moveOrder).First();
|
if (!complete)
|
{
|
if (old == null)
|
{
|
old = new MoveOrderNotice { OrderNo = moveOrder };
|
old.StartArea = startArea;
|
old.EndArea = endArea;
|
db.Insertable<MoveOrderNotice>(old).ExecuteCommand();
|
}
|
}
|
else
|
{
|
if (old != null)
|
{
|
old.State = 1;
|
old.IsNotice = 0;
|
db.Updateable<MoveOrderNotice>(old).UpdateColumns(it => new { it.State, it.IsNotice }).ExecuteCommand();
|
}
|
}
|
}
|
|
}
|
|
internal static Location GetLocation4EmptyCntrOut(string size)
|
{
|
Location start = null;
|
var db = new SqlHelper<object>().GetInstance();
|
var list = db.Queryable<CPEmptyOut>().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<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 查到所有有托盘的排
|
Console.WriteLine("查到所有有托盘的排 ");
|
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)
|
{
|
//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<Location>().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<Location>().GetInstance().Queryable<Location>().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;
|
}
|
|
|
|
|
/// <summary>
|
/// 移库 上报锁定或解锁库位(排)
|
/// </summary>
|
/// <param name="Row"></param>
|
public static void YiKuUnLockRow(string row, string worno, bool state, string startarea, string endarea, int startrow, int endrow)
|
{
|
// var db = new SqlHelper<object>().GetInstance();
|
//检查
|
//var Startloc = db.Queryable<Location>().Where(a => a.S_AREA_CODE == startarea && a.N_ROW == startrow).ToList();
|
//var Endloc = db.Queryable<Location>().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
|
|
}
|
}
|
|
}
|
|
/// <summary>
|
/// 根据移库单号判断移库任务是否全部完成
|
/// </summary>
|
/// <param name="worno"></param>
|
/// <returns></returns>
|
public static bool IsTask(string worno)
|
{
|
bool res = true;
|
var db = new SqlHelper<object>().GetInstance();
|
|
//判断是否有未完成的任务
|
var task = TaskHelper.GetTaskBySrcNo(worno);
|
List<WMSTask> 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;
|
}
|
}
|
}
|