using HH.WCS.Mobox3.NFLZ.core;
|
using HH.WCS.Mobox3.NFLZ.dispatch;
|
using HH.WCS.Mobox3.NFLZ.util;
|
using HH.WCS.Mobox3.NFLZ.wms;
|
using Newtonsoft.Json;
|
using SqlSugar;
|
using System;
|
using System.Collections.Generic;
|
using System.Linq;
|
using System.Security.Cryptography;
|
using static HH.WCS.Mobox3.NFLZ.api.OtherModel;
|
|
namespace HH.WCS.Mobox3.NFLZ.process
|
{
|
internal class TaskProcess
|
{
|
#region 任务相关
|
//--------------------------------------------------任务相关--------------------------------------------------
|
/// <summary>
|
/// 取货卸货完成,缓存位状态更新
|
/// </summary>
|
/// <param name="mst"></param>
|
/// <param name="load"></param>
|
internal static void CacheBitUpdate(WCSTask mst, bool load)
|
{
|
var trayCarryCount = mst.N_CNTR_COUNT > 0 ? mst.N_CNTR_COUNT : 1;
|
if (load)
|
{
|
Console.WriteLine($"任务{mst.S_CODE} 货位{mst.S_START_LOC}取货完成,起点解绑容器{mst.S_CNTR_CODE}");
|
LogHelper.Info($"任务{mst.S_CODE} 货位{mst.S_START_LOC}取货完成,起点解绑容器{mst.S_CNTR_CODE}");
|
LocationHelper.UnBindingLoc(mst.S_START_LOC, mst.S_CNTR_CODE.Split(',').ToList());
|
}
|
else
|
{
|
Console.WriteLine($"任务{mst.S_CODE} 货位{mst.S_END_LOC}卸货完成,终点绑定容器{mst.S_CNTR_CODE}");
|
LogHelper.Info($"任务{mst.S_CODE} 货位{mst.S_END_LOC}卸货完成,终点绑定容器{mst.S_CNTR_CODE}");
|
LocationHelper.BindingLoc(mst.S_END_LOC, mst.S_CNTR_CODE.Split(',').ToList());
|
}
|
|
}
|
|
/// <summary>
|
/// 任务取消,缓存位状态更新
|
/// </summary>
|
/// <param name="mst"></param>
|
internal static void CacheBitCancelUpdate(WCSTask mst)
|
{
|
//任务取消,取货完成前的,起点的loadingCount和终点unLoadingCount都清除,取货完成的只处理终点
|
if (WCSHelper.CheckActionRecordExist(mst.S_CODE, 4))
|
{
|
//根据客户现场要求,如果取货完成任务失败人工拉到终点,我们就当卸货完成处理;如果是人工拉走到其它区域,我们就解锁终点,删除托盘。
|
//终点绑定
|
CacheBitUpdate(mst, false);
|
LocationHelper.UnLockLoc(mst.S_END_LOC);
|
}
|
else
|
{
|
//起点终点解锁
|
LocationHelper.UnLockLoc(mst.S_START_LOC);
|
LocationHelper.UnLockLoc(mst.S_END_LOC);
|
|
}
|
|
}
|
|
/// <summary>
|
/// 安全请求
|
/// </summary>
|
/// <param name="no"></param>
|
/// <param name="state"></param>
|
/// <param name="forkliftNo"></param>
|
/// <param name="extData"></param>
|
internal static void OperateReq(string no, int state, string forkliftNo, string extData)
|
{
|
if (state == 1101)
|
{
|
//请求取货,
|
}
|
if (state == 1102)
|
{
|
//请求卸货,
|
//根据终点判断,是cb02的入口,判断内存中状态(要状态时间),允许卸货,通知agv改参数
|
var dic = new Dictionary<string, string>();
|
//< Req >< Order No = 'TN2302020002' ParamNo = '18' Param1 = '12' /></ Req >
|
dic.Add("No", no);
|
dic.Add("ParamNo", "8");
|
dic.Add("Param1", "1");
|
NDC.ChangeOrder(dic);
|
//改完参数车子就会自己卸货
|
}
|
if (state == 1103)
|
{
|
//大铁框叉走以后通知,我们要通知输送线
|
}
|
}
|
|
internal static void UpdateAgvNo(WCSTask mst, string forkliftNo)
|
{
|
var db = new SqlHelper<object>().GetInstance();
|
mst.S_EQ_NO = forkliftNo;
|
db.Updateable(mst).UpdateColumns(it => new { it.S_EQ_NO }).ExecuteCommand();
|
}
|
|
internal static void ThirdReportStatus(WCSTask mst, int state, string forkliftNo)
|
{
|
|
}
|
|
|
|
|
/// <summary>
|
/// 任务拦截
|
/// </summary>
|
/// <param name="task"></param>
|
/// <returns></returns>
|
internal static bool Intercept(WCSTask mst)
|
{
|
var result = false;
|
//出库任务是批量生成的,初始终点我们先给一个虚拟点,不推送。有单独的现场去判断出库缓存区光电,空了再给出库任务分配终点
|
if (mst.S_END_LOC.Trim() == "出库虚拟点")
|
{
|
result = true;
|
}
|
return result;
|
}
|
|
/// <summary>
|
/// 任务状态更新处理
|
/// </summary>
|
/// <param name="mst"></param>
|
/// <param name="state"></param>
|
internal static void OperateStatus(WCSTask mst, int state)
|
{
|
if (state == 4)
|
{
|
claimGoodsTime(mst, state);
|
CacheBitUpdate(mst, true);
|
EmptyTask(mst);
|
}
|
if (state == 6)//卸货完成
|
{
|
claimGoodsTime(mst, state);
|
CacheBitUpdate(mst, false);
|
}
|
if (state == 7)
|
{
|
CacheBitCancelUpdate(mst);
|
}
|
}
|
|
/// <summary>
|
/// 瓶坯瓶盖机满托下线后生成空托上线任务
|
/// </summary>
|
/// <param name="mst"></param>
|
/// <exception cref="NotImplementedException"></exception>
|
public static void EmptyTask(WCSTask mst)
|
{
|
////瓶盖注塑机空托上线,若急产急用库区没有多余的空托,则在非急产急用空托区拿空托
|
//var db = new SqlHelper<object>().GetInstance();
|
//Location startLoca = null;
|
//bool result = false;
|
//
|
//if (mst.S_TYPE.Contains("满托下线"))
|
//{
|
// LogHelper.Info($"空托任务生成处理,任务类型:{mst.S_TYPE}");
|
// startLoca = getMStartLoc1(db, startLoca, "瓶坯");
|
// #region
|
//
|
// if (startLoca != null)
|
// {
|
// LogHelper.Info("startLoca" + JsonConvert.SerializeObject(startLoca));
|
// var startArea = startLoca.S_AREA_CODE;
|
// string taskType = "";
|
// if (mst.S_TYPE == "注塑即产满托下线(瓶坯)") taskType = "注塑即产空托上线(瓶坯)";
|
// if (mst.S_TYPE == "注塑库存满托下线(瓶坯)") taskType = "注塑库存空托上线(瓶坯)";
|
// int startLayer = startLoca.N_CURRENT_NUM;
|
// var cntrInfo = db.Queryable<LocCntrRel>().Where(a => a.S_LOC_CODE == startLoca.S_LOC_CODE).First();
|
// if (cntrInfo != null)
|
// {
|
// string cntr = cntrInfo.S_CNTR_CODE;
|
// result = IntensiveArea.LinJiangCreateTransport(startArea, startLoca.S_LOC_CODE, mst.S_START_LOC, taskType, cntr, 1, 1, mst.S_SRC_SYS, startLoca.N_ROW, 1, 1);
|
// if (result) LogHelper.Info($"{taskType}:{mst.S_SRC_SYS} 当前位置{mst.S_START_LOC} 任务创建成功", "注塑机空托上线");
|
// }
|
// else LogHelper.Info($"未绑定托盘,货位号:{startLoca.S_LOC_CODE}");
|
// }
|
//}
|
//
|
//if (mst.S_TYPE.Contains("空托下线"))
|
//{
|
// LogHelper.Info($"满托任务生成处理,任务类型:{mst.S_TYPE}");
|
// string startArea = "";
|
// bool flage = false;
|
// string jbw = "";
|
// string mk = "";
|
// string machine = "";
|
// LinjiangBCPWorkOrder bcpW = null;
|
// if (mst.S_TYPE.Contains("瓶坯"))
|
// {
|
// jbw = "瓶坯接驳位";
|
// mk = "瓶坯满托出库接驳位";
|
// machine = "瓶坯翻斗机";
|
// bcpW = db.Queryable<LinjiangBCPWorkOrder>().Where(a => a.S_PLineNo.Contains("农夫临江-瓶坯翻斗机")).First();
|
// }
|
// else
|
// {
|
// jbw = "瓶盖接驳位";
|
// mk = "瓶盖满托";
|
// bcpW = db.Queryable<LinjiangBCPWorkOrder>().Where(a => a.S_PLineNo.Contains("农夫临江-瓶盖翻斗机")).First();
|
// }
|
//
|
// if (bcpW.S_UsingNow == "Y")
|
// {
|
// LogHelper.Info("即产即用工单");
|
// //即产即用在起点为线边
|
// var bcpInfo = Settings.GetLinJiangBCPAreaList().Where(a => a.AreaName == jbw && a.Enable == "1").FirstOrDefault();
|
// if (bcpInfo != null)
|
// {
|
// startArea = bcpInfo.AreaNo;
|
// }
|
// }
|
// else
|
// {
|
// LogHelper.Info("非即产即用工单");
|
// //非即产即用起点为库区
|
// var bcpInfo = Settings.GetLinJiangBCPAreaList().Where(a => a.AreaName == mk && a.Enable == "1").FirstOrDefault();
|
// if (bcpInfo != null)
|
// {
|
// startArea = bcpInfo.AreaNo;
|
// }
|
// }
|
//
|
// if (bcpW.S_UsingNow == "Y")
|
// {
|
// bool action = false;
|
// if (jbw == "瓶坯接驳位")
|
// {
|
// flage = true;
|
// action = DeviceProcess.queryBCPFDJRow(db, ref startLoca);
|
// }
|
// LogHelper.Info($"即产即用库区查找");
|
// if (startLoca == null)
|
// {
|
// startLoca = DeviceProcess.getFDSXArea(db, bcpW, startArea, machine);
|
// //startLoca = db.Queryable<Location>().Where(a => a.S_AREA_CODE == startArea && a.N_CURRENT_NUM != 0 && a.S_LOCK_STATE == "无").First();
|
// //startLoca = TempleteOverExtendService.GetLocation(startArea, workInfo.S_ItemCode, "", false);
|
// if (startLoca == null)
|
// {
|
// flage = false;
|
// if (jbw == "瓶坯接驳位")
|
// {
|
// LogHelper.Info($"即产即用库区未找到满托,去满托库区查找");
|
//
|
// //即产即用库区无满托,去非即产即用库区查询
|
// LogHelper.Info($"mk:{mk}");
|
// startArea = Settings.GetLinJiangBCPAreaList().Where(a => a.AreaName == mk && a.Enable == "1").FirstOrDefault().AreaNo;
|
// LogHelper.Info($"startArea:{startArea}");
|
// //startLoca = TempleteOverExtendService.GetLocation(startArea, workInfo.S_ItemCode, "", false, true, true);
|
// startLoca = DeviceProcess.getFDSXArea(db, bcpW, startArea);
|
// }
|
// }
|
// else
|
// {
|
// if (action)
|
// {
|
// CPXXTable table = new CPXXTable
|
// {
|
// S_AREA_CODE = startArea,
|
// S_ROW = startLoca.N_ROW,
|
// S_TASK_TYPE = "瓶坯注塑机"
|
// };
|
// db.Insertable(table).ExecuteCommand();
|
// }
|
// }
|
// }
|
// }
|
// else
|
// {
|
// startLoca = DeviceProcess.getFDSXArea(db, bcpW, startArea);
|
// }
|
//
|
// if (startLoca != null)
|
// {
|
// LogHelper.Info("startLoca" + JsonConvert.SerializeObject(startLoca));
|
// string taskType = "";
|
// if (mst.S_TYPE == "翻斗机即产空托下线(瓶坯)") taskType = "翻斗机即产满托上线(瓶坯)";
|
// if (mst.S_TYPE == "翻斗机库存空托下线(瓶坯)") taskType = "翻斗机库存满托上线(瓶坯)";
|
// if (mst.S_TYPE == "翻斗机即产空托下线(瓶盖)") taskType = "翻斗机即产满托上线(瓶盖)";
|
// if (mst.S_TYPE == "翻斗机库存空托下线(瓶盖)") taskType = "翻斗机库存满托上线(瓶盖)";
|
// int startLayer = startLoca.N_CURRENT_NUM;
|
// var cntrInfo = db.Queryable<LocCntrRel>().Where(a => a.S_LOC_CODE == startLoca.S_LOC_CODE).First();
|
// if (cntrInfo != null)
|
// {
|
// string cntr = cntrInfo.S_CNTR_CODE;
|
// if (flage)
|
// {
|
// result = TaskHelper.LinJiangCreateTask("", startLoca.S_LOC_CODE, mst.S_START_LOC, taskType, 1, cntr, mst.S_SRC_SYS);
|
// if (result)
|
// {
|
// LocationHelper.LockLoc(startLoca.S_LOC_CODE, "出库锁");
|
// LocationHelper.LockLoc(mst.S_START_LOC, "入库锁");
|
// var rowInfo = db.Queryable<RowLock>().Where(a => a.S_AREA_CODE == startArea && a.N_ROW == startLoca.N_ROW).First();
|
// if (rowInfo != null)
|
// {
|
// rowInfo.S_LOCK_STATE = "即产出库锁";
|
// db.Updateable(rowInfo).UpdateColumns(a => new { a.S_LOCK_STATE }).ExecuteCommand();
|
// }
|
// }
|
// }
|
// else
|
// {
|
// int pri = 1;
|
// if (taskType.Contains("瓶盖")) pri = 10;
|
// result = IntensiveArea.LinJiangCreateTransport(startArea, startLoca.S_LOC_CODE, mst.S_START_LOC, taskType, cntr, 1, 1, mst.S_SRC_SYS, startLoca.N_ROW, 1, pri);
|
// }
|
// if (result) LogHelper.Info($"{taskType}:{mst.S_SRC_SYS} 当前位置{mst.S_START_LOC} 任务创建成功", "翻斗机满托上线");
|
// }
|
// else LogHelper.Info($"未绑定托盘,货位号:{startLoca.S_LOC_CODE}");
|
// }
|
//}
|
}
|
|
private static void claimGoodsTime(WCSTask mst, int state)
|
{
|
//将取货完成时间存入中间表
|
var db = new SqlHelper<object>().GetInstance();
|
if (state == 6 && (mst.S_TYPE == "栈板上线" || mst.S_TYPE.Contains("空托上线") || mst.S_TYPE.Contains("满托上线")))
|
{
|
LogHelper.Info($"任务{mst.S_TYPE}卸货时间存入中间表,当前时间:{DateTime.Now}");
|
var cgInfo = db.Queryable<CGTTable>().Where(a => a.Bit == mst.S_END_LOC).First();
|
if (cgInfo != null)
|
{
|
cgInfo.time = DateTime.Now;
|
if (db.Updateable(cgInfo).UpdateColumns(a => new { a.time }).ExecuteCommand() > 0) LogHelper.Info($"数据更改成功,终点:{mst.S_END_LOC}");
|
}
|
else
|
{
|
CGTTable cg = new CGTTable
|
{
|
Bit = mst.S_END_LOC,
|
time = DateTime.Now,
|
};
|
if (db.Insertable(cg).ExecuteCommand() > 0) LogHelper.Info($"数据插入成功,终点:{mst.S_END_LOC}");
|
}
|
}
|
if (state == 4 && (mst.S_TYPE.Contains("空托下线") || mst.S_TYPE.Contains("满托下线")))
|
{
|
LogHelper.Info($"任务{mst.S_TYPE}取货时间存入中间表,当前时间:{DateTime.Now},点位:{mst.S_START_LOC}");
|
var cgInfo = db.Queryable<CGTTable>().Where(a => a.Bit == mst.S_START_LOC).First();
|
if (cgInfo != null)
|
{
|
cgInfo.time = DateTime.Now;
|
if (db.Updateable(cgInfo).UpdateColumns(a => new { a.time }).ExecuteCommand() > 0) LogHelper.Info($"数据更改成功,起点:{mst.S_START_LOC}");
|
}
|
else
|
{
|
CGTTable cg = new CGTTable
|
{
|
Bit = mst.S_START_LOC,
|
time = DateTime.Now,
|
};
|
if (db.Insertable(cg).ExecuteCommand() > 0) LogHelper.Info($"数据插入成功,起点:{mst.S_START_LOC}");
|
}
|
|
}
|
}
|
|
private static object locLocker = new object();
|
|
/// <summary>
|
/// 堆叠库区出入库任务申请
|
/// </summary>
|
/// <param name="ls"></param>
|
/// <param name="cntrs"></param>
|
/// <param name="area"></param>
|
/// <param name="itemCode"></param>
|
/// <param name="itemBatch"></param>
|
/// <param name="taskType"></param>
|
/// <param name="insStock"></param>
|
/// <returns></returns>
|
internal static bool ApplyTN_Task(Location ls, ref List<string> cntrs, string area, string itemCode, string itemBatch, string taskType, bool insStock = true)
|
{
|
var result = false;
|
lock (locLocker)
|
{
|
try
|
{
|
if (insStock)
|
{
|
Console.WriteLine($"MoboxHelperCreateTask: {area}-{itemCode}-{itemBatch}-{taskType}");
|
var endTN_Location = GetLocation4In(area, itemCode, itemBatch, 3);
|
if (endTN_Location != null)
|
{
|
var endLayer = endTN_Location.N_CURRENT_NUM == 0 ? 1 : 2;
|
var taskNo = DateTime.Now.Ticks.ToString();
|
result = TaskProcess.CreateTransport(ls.S_CODE, endTN_Location.S_CODE, taskType, cntrs, 1, endLayer, 3, 70);
|
}
|
else
|
{
|
Console.WriteLine($"MoboxHelperCreateTask: 未找到终点货位");
|
}
|
}
|
else
|
{
|
var startTN_Location = GetLocation4Out(area, itemCode, itemBatch, 3);
|
if (startTN_Location != null)
|
{
|
var startLayer = startTN_Location.N_CURRENT_NUM <= 3 ? 1 : 2;
|
var taskNo = DateTime.Now.Ticks.ToString();
|
var carryCount = startTN_Location.N_CURRENT_NUM > 3 ? startTN_Location.N_CURRENT_NUM - 3 : startTN_Location.N_CURRENT_NUM;
|
//出库要从起点获取托盘
|
var cntrList = LocationHelper.GetLocCntr(startTN_Location.S_CODE);
|
if (cntrList.Count == startTN_Location.N_CURRENT_NUM)
|
{
|
cntrs = cntrList.OrderByDescending(a => a.T_CREATE).Take(carryCount).Select(a => a.S_CNTR_CODE.Trim()).ToList();
|
result = TaskProcess.CreateTransport(startTN_Location.S_CODE, ls.S_CODE, taskType, cntrs, startLayer, 1, carryCount, 65);
|
}
|
else
|
{
|
Console.WriteLine($"起点托盘数量和货位容器表不符合,请检查【货位表】和【货位容器表】");
|
}
|
|
}
|
}
|
}
|
catch (Exception ex)
|
{
|
|
Console.WriteLine("MoboxHelperCreateTask:" + ex.Message);
|
LogHelper.Error("MoboxHelperCreateTask:" + ex.Message, ex);
|
}
|
}
|
return result;
|
|
|
}
|
|
private static Location GetLocation4Out(string area, string itemCode, string itemBatch, int v)
|
{
|
throw new NotImplementedException();
|
}
|
|
private static Location GetLocation4In(string area, string itemCode, string itemBatch, int v)
|
{
|
throw new NotImplementedException();
|
}
|
|
/// <summary>
|
/// 普通货架区的出入库申请
|
/// </summary>
|
/// <param name="ls"></param>
|
/// <param name="cntrs"></param>
|
/// <param name="area"></param>
|
/// <param name="taskType"></param>
|
/// <param name="itemCode"></param>
|
/// <param name="insStock"></param>
|
/// <returns></returns>
|
internal static bool ApplyNormalTN_Task(Location ls, ref List<string> cntrs, string area, string taskType, string itemCode, bool insStock = true)
|
{
|
var result = false;
|
lock (locLocker)
|
{
|
try
|
{
|
if (insStock)
|
{
|
Console.WriteLine($"MoboxHelperCreateTask: {area}-{taskType}");
|
var endTN_Location = new Location();
|
if (endTN_Location != null)
|
{
|
var taskNo = DateTime.Now.Ticks.ToString();
|
result = TaskProcess.CreateTransport(ls.S_CODE, endTN_Location.S_CODE, taskType, cntrs, 70);
|
}
|
else
|
{
|
Console.WriteLine($"MoboxHelperCreateTask: 未找到终点货位");
|
}
|
}
|
else
|
{
|
var startTN_Location = new Location();
|
if (startTN_Location != null)
|
{
|
//出库要从起点获取托盘
|
var cntrList = LocationHelper.GetLocCntr(startTN_Location.S_CODE);
|
if (cntrList.Count == startTN_Location.N_CURRENT_NUM)
|
{
|
result = TaskProcess.CreateTransport(startTN_Location.S_CODE, ls.S_CODE, taskType, new List<string> { cntrList[0].S_CNTR_CODE }, 65);
|
}
|
else
|
{
|
Console.WriteLine($"起点托盘数量和货位容器表不符合,请检查【货位表】和【货位容器表】");
|
}
|
|
}
|
}
|
}
|
catch (Exception ex)
|
{
|
|
Console.WriteLine("MoboxHelperCreateTask:" + ex.Message);
|
LogHelper.Error("MoboxHelperCreateTask:" + ex.Message, ex);
|
}
|
}
|
return result;
|
|
|
}
|
/// <summary>
|
/// 推送任务
|
/// </summary>
|
/// <param name="mst"></param>
|
internal static bool SendTask(WCSTask mst)
|
{
|
var result = false;
|
var start = "0"; var end = "0";
|
var taskType = mst.S_TYPE.Trim();
|
if (mst.N_B_STATE == 0)
|
{
|
//if (mst.S_SCHEDULE_TYPE == "NDC") {
|
// start = LocationHelper.GetAgvSite(mst.S_START_LOC);
|
// end = LocationHelper.GetAgvSite(mst.S_END_LOC);
|
//
|
//
|
// Console.WriteLine($"SendTask {mst.S_CODE}");
|
// Console.WriteLine("start=" + start);
|
// Console.WriteLine("end= " + end);
|
// var dic = new Dictionary<string, string>();
|
// dic.Add("Pri", mst.N_PRIORITY.ToString());
|
// dic.Add("From", start.ToString());
|
// dic.Add("To", end.ToString());
|
// dic.Add("No", mst.S_CODE.Trim());// dic.Add("Ext1", "1"); dic.Add("Ext2", "CALLADDAGV"); dic.Add("N_CNTR_COUNT", "");
|
// var res = NDC.AddNewOrder(1, dic);
|
// if (res != null && (res.Res.ErrCode == 0 || res.Res.ErrCode == 50009)) {
|
// //推送成功,修改任务优先级
|
mst.N_B_STATE = 1;
|
WCSHelper.UpdateStatus(mst, "已推送");
|
result = true;
|
// }
|
// }
|
// else if (mst.S_SCHEDULE_TYPE == "WCS") {
|
// //调第三方接口
|
// var model = new HanAo.TaskInfoModel
|
// {
|
// requestPk = mst.S_CODE,
|
// frmPos = mst.S_START_LOC,
|
// toPos = mst.S_END_LOC,
|
// trkType = mst.S_OP_NAME == "入库" ? "1" : "2",
|
// contNo = mst.S_CNTR_CODE
|
// };
|
// //if (HanAo.CreateOrder(model)) {
|
// mst.N_B_STATE = 1;
|
// WCSHelper.UpdateStatus(mst);
|
// //}
|
// }
|
|
}
|
return result;
|
}
|
|
/// <summary>
|
/// 创建搬运任务
|
/// </summary>
|
/// <param name="start"></param>
|
/// <param name="end"></param>
|
/// <param name="taskType"></param>
|
/// <param name="cntrs"></param>
|
/// <param name="startLayer"></param>
|
/// <param name="endLayer"></param>
|
/// <param name="trayCarryCount"></param>
|
/// <param name="priority"></param>
|
/// <returns></returns>
|
public static bool CreateTransport(string start, string end, string taskType, List<string> cntrs, int startLayer, int endLayer, int trayCarryCount = 1, int priority = 1)
|
{
|
var result = false;
|
//批次号存托盘号,1~3个托盘
|
var trayCodes = string.Join(",", cntrs);
|
var taskNo = DateTime.Now.Ticks.ToString();
|
|
|
var res = WCSHelper.CreateTask(taskNo, start.Trim(), end.Trim(), taskType, priority, trayCodes, trayCarryCount, startLayer, endLayer);
|
if (res)
|
{
|
result = true;
|
//任务创建成功,起点货位出库锁定,终点货位入库锁定
|
LocationHelper.LockLoc(start, 1);
|
LocationHelper.LockLoc(end, 2);
|
}
|
return result;
|
}
|
|
|
public static bool CreateTransport(string start, string end, string taskType, List<string> cntrs, int priority = 1)
|
{
|
var result = false;
|
//批次号存托盘号,1~3个托盘
|
var trayCodes = string.Join(",", cntrs);
|
var taskNo = DateTime.Now.Ticks.ToString();
|
|
|
var res = WCSHelper.CreateTask(taskNo, start.Trim(), end.Trim(), taskType, priority, trayCodes, 1, 1, 1);
|
if (res)
|
{
|
result = true;
|
LocationHelper.LockLoc(start, 2);
|
LocationHelper.LockLoc(end, 1);
|
|
}
|
return result;
|
}
|
#endregion
|
|
/// <summary>
|
/// 半成品出入库
|
/// </summary>
|
/// <param name="db"></param>
|
/// <param name="action">true:入库 false:出库</param>
|
/// <param name="startCode"></param>
|
/// <returns></returns>
|
public static Location BCPInOrOut(SqlSugarClient db, bool action, string startCode = "", string areaName = "", LinZhiBCPWorkOrder workInfo = null)
|
{
|
Location result = null;
|
if (action)
|
{
|
var cntrInfo = db.Queryable<LocCntrRel>().Where(a => a.S_LOC_CODE == startCode).First();
|
var itemInfo = db.Queryable<CntrItemRel>().Where(a => a.S_CNTR_CODE == cntrInfo.S_CNTR_CODE).First();
|
if (itemInfo != null)
|
{
|
//瓶盖库区,两层密集型库区 空满在同一个库区,需要区分不同排
|
var areaInfo = Settings.areaInfos.Where(a => a.areaName == areaName && a.enable == 1).First();
|
if (areaInfo != null)
|
{
|
//库区货位约定:列号越小越靠里
|
LogHelper.Info($"入库算法01:area:{areaInfo.areaCode},itemCode:{itemInfo.S_ITEM_CODE},itemBatch:{itemInfo.S_BATCH_NO}", "WMSAlgoRithm");
|
try
|
{
|
if (result == null)
|
{
|
var locInfo = db.Queryable<Location>().Where(a => a.S_AREA_CODE == areaInfo.areaCode && a.N_CURRENT_NUM > 0).OrderBy(a => a.N_ROW).OrderByDescending(a => a.N_COL)
|
.PartitionBy(a => a.N_ROW).Take(1)
|
.ToList();
|
if (locInfo.Count > 0)
|
{
|
foreach (var a in locInfo)
|
{
|
string itemCode = "";
|
var endCntrInfo = db.Queryable<LocCntrRel>().Where(b => b.S_LOC_CODE == a.S_CODE).First();
|
if (endCntrInfo != null)
|
{
|
var endItemInfo = db.Queryable<CntrItemRel>().Where(b => b.S_CNTR_CODE == endCntrInfo.S_CNTR_CODE).First();
|
if (endItemInfo != null)
|
{
|
itemCode = endItemInfo.S_ITEM_CODE;
|
}
|
else
|
{
|
LogHelper.Info($"终点货位未绑定物料信息");
|
continue;
|
}
|
}
|
else
|
{
|
LogHelper.Info($"终点货位未绑定托盘信息");
|
continue;
|
}
|
|
//去掉当前货位有锁,或者为空托的货位
|
if (a.S_LOCK_STATE == "无")
|
{
|
//判断是否和当前货位的物料编码相同
|
if (itemCode == itemInfo.S_ITEM_CODE)
|
{
|
//查询当前排是否可入(判断是是否有入库锁和出库锁)
|
var lockInfo = db.Queryable<Location>().Where(b => b.S_AREA_CODE == a.S_AREA_CODE && b.N_ROW == a.N_ROW && (b.S_LOCK_STATE == "入库锁" || b.S_LOCK_STATE == "出库锁")).First();
|
if (lockInfo == null)
|
{
|
//当前排无任务
|
if (a.N_CURRENT_NUM < a.N_CAPACITY) result = a;
|
else
|
{
|
//查询后面当前货位后一个
|
result = db.Queryable<Location>().Where(b => b.S_AREA_CODE == a.S_AREA_CODE && b.N_ROW > a.N_ROW && b.S_LOCK_STATE == "无").OrderBy(b => b.N_COL).First();
|
}
|
if (result != null)
|
{
|
break;
|
}
|
}
|
}
|
}
|
}
|
}
|
if (result == null)
|
{
|
//todo 还需要判断锁
|
#region 查找所有数量是空的排
|
LogHelper.Info($"入库算法06:无可用货位,获取空排货位。", "WMSAlgoRithm");
|
//2.0 简化查询只查每一排第一列
|
var list = db.Queryable<Location>().Where(a => a.S_AREA_CODE == areaInfo.areaCode).OrderBy(a => a.N_ROW).OrderBy(a => a.N_COL).PartitionBy(a => a.N_ROW).ToList().Where(a => a.N_CURRENT_NUM == 0).ToList();
|
//2.1 选一个空排
|
if (list.Count > 0)
|
{
|
LogHelper.Info($"入库算法06:无可用货位,获取空排货位数量为:{list.Count}。", "WMSAlgoRithm");
|
for (int i = 0; i < list.Count; i++)
|
{
|
LogHelper.Info($"入库算法07:获取空排货位:货位编码:{list[i].S_CODE.Trim()},当前数量:{list[i].N_CURRENT_NUM},排号:{list[i].N_ROW},库区编码:{list[i].S_AREA_CODE.Trim()}", "WMSAlgoRithm");
|
if (list[i].S_LOCK_STATE.Trim().Contains("无"))
|
{
|
//二次校验当前排所有货位都是空的,防止系统数据错乱
|
int row = list[i].N_ROW;
|
string areaCode = list[i].S_AREA_CODE.Trim();
|
var lockInfo = db.Queryable<Location>().Where(b => b.S_AREA_CODE == areaCode && b.N_ROW == row && (b.S_LOCK_STATE == "入库锁" || b.S_LOCK_STATE == "出库锁")).First();
|
if (lockInfo == null)
|
{
|
var locInfo1 = db.Queryable<Location>().Where(a => a.S_AREA_CODE == areaCode && a.N_ROW == row).Select(a => new { sum = SqlFunc.AggregateSum(a.N_CURRENT_NUM) }).First();
|
if (locInfo1 != null)
|
{
|
LogHelper.Info($"{locInfo1.sum},row:{row}");
|
if (locInfo1.sum == 0)
|
{
|
//空排
|
result = list[i];
|
break;
|
}
|
}
|
else LogHelper.Info("未找到该排");
|
}
|
else
|
{
|
LogHelper.Info("该排有锁");
|
}
|
}
|
}
|
}
|
else LogHelper.Info($"未获取到空排,库区编码:{areaInfo.areaCode}");
|
#endregion
|
}
|
}
|
}
|
catch (Exception ex)
|
{
|
Console.WriteLine("GetLocationIn:" + ex.Message + ex.StackTrace);
|
LogHelper.Error("GetLocationIn:" + ex.Message, ex);
|
}
|
}
|
else
|
{
|
LogHelper.Info($"入库任务 瓶盖库区未配置");
|
}
|
}
|
else
|
{
|
LogHelper.Info($"入库任务 起点货位未绑定物料信息");
|
}
|
}
|
else
|
{
|
string itemCode = "";
|
if (string.IsNullOrEmpty(startCode))
|
{
|
var cntrInfo = db.Queryable<LocCntrRel>().Where(a => a.S_LOC_CODE == startCode).First();
|
var itemInfo = db.Queryable<CntrItemRel>().Where(a => a.S_CNTR_CODE == cntrInfo.S_CNTR_CODE).First();
|
if(itemInfo != null)
|
{
|
itemCode = itemInfo.S_ITEM_CODE;
|
}
|
}
|
if (workInfo != null)
|
{
|
itemCode = workInfo.S_ItemCode;
|
}
|
var areaInfo = Settings.areaInfos.Where(a => a.areaName == areaName && a.enable == 1).FirstOrDefault();
|
if(areaInfo != null)
|
{
|
var locList = db.Queryable<Location>().Where(a => a.S_AREA_CODE == areaInfo.areaCode && a.N_CURRENT_NUM > 0).OrderBy(a => a.N_ROW).OrderByDescending(a => a.N_COL).Take(1).PartitionBy(a => a.N_ROW).Includes(a => a.LocCntrRel).ToList();
|
if(locList.Count > 0)
|
{
|
foreach(var a in locList)
|
{
|
if(a.S_LOCK_STATE == "无")
|
{
|
var cntrInfo = db.Queryable<LocCntrRel>().Where(b => b.S_LOC_CODE == a.S_CODE).First();
|
if(cntrInfo != null)
|
{
|
var itemInfo = db.Queryable<CntrItemRel>().Where(b => b.S_CNTR_CODE == cntrInfo.S_CNTR_CODE).First();
|
if(itemInfo != null && itemInfo.S_ITEM_CODE == itemCode)
|
{
|
//判断当前排有无锁
|
var lockInfo = db.Queryable<Location>().Where(b => b.S_AREA_CODE == areaInfo.areaCode && b.N_ROW == a.N_ROW && (b.S_LOCK_STATE == "入库锁" || b.S_LOCK_STATE == "出库锁")).First();
|
if(lockInfo == null)
|
{
|
result = a;
|
break;
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
else
|
{
|
LogHelper.Info($"{areaName}未配置");
|
}
|
}
|
return result;
|
}
|
|
internal static Location getMStartLoc(SqlSugarClient db)
|
{
|
Location result = null;
|
var areaInfo = Settings.areaInfos.Where(a => a.areaName == "瓶坯注塑机空托" && a.enable == 1).FirstOrDefault();
|
if(areaInfo != null)
|
{
|
var locInfo = db.Queryable<Location>().Where(a => a.S_AREA_CODE == areaInfo.areaCode && a.N_CURRENT_NUM > 0 && a.S_LOCK_STATE == "无").Includes(a => a.LocCntrRel).First();
|
if(locInfo != null)
|
{
|
result = locInfo;
|
}
|
}
|
else
|
{
|
LogHelper.Info("瓶坯注塑机空托未配置");
|
}
|
return result;
|
}
|
|
/// <summary>
|
/// 瓶坯注塑满托下线
|
/// </summary>
|
/// <param name="db"></param>
|
/// <param name="taskName"></param>
|
/// <returns></returns>
|
/// <exception cref="NotImplementedException"></exception>
|
internal static Location BCPFullOut(SqlSugarClient db, string taskName, string S_START_LOC)
|
{
|
Location result = null;
|
|
if (taskName.Contains("即产"))
|
{
|
//即产即用工单,下线到即产即用库区
|
//即产即用库区有两个线边库,如果即产即用A库区满,则放到即产即用B库区,若即产即用库区都满,则放到瓶坯库区
|
var areaInfo = Settings.areaInfos.Where(a => a.areaName == "瓶坯即产即用A" && a.enable == 1).FirstOrDefault();
|
if(areaInfo != null)
|
{
|
var locInfo = db.Queryable<Location>().Where(a => a.S_AREA_CODE == areaInfo.areaCode && a.N_CURRENT_NUM < a.N_CAPACITY && a.S_LOCK_STATE == "无").OrderBy(a => a.N_COL).First();
|
if(locInfo != null)
|
{
|
result = locInfo;
|
}
|
|
}
|
if (result == null)
|
{
|
result = TaskProcess.BCPInOrOut(db, true, S_START_LOC, "瓶坯即产即用B");
|
}
|
if(result == null)
|
{
|
result = TaskProcess.BCPInOrOut(db, true, S_START_LOC,"瓶坯库区");
|
}
|
|
}
|
else
|
{
|
//非即产即用工单,下线到非即产即用库区
|
//非即产即用库区只有一个线边库,如果线边库满,则放到瓶坯库区
|
var areaInfo = Settings.areaInfos.Where(a => a.areaName == "瓶坯非即产即用" && a.enable == 1).FirstOrDefault();
|
if (areaInfo != null)
|
{
|
var locInfo = db.Queryable<Location>().Where(a => a.S_AREA_CODE == areaInfo.areaCode && a.N_CURRENT_NUM < a.N_CAPACITY && a.S_LOCK_STATE == "无").OrderBy(a => a.N_COL).First();
|
if (locInfo != null)
|
{
|
result = locInfo;
|
}
|
|
}
|
if (result == null)
|
{
|
result = TaskProcess.BCPInOrOut(db, true, S_START_LOC, "瓶坯库区");
|
}
|
}
|
return result;
|
}
|
|
/// <summary>
|
/// 翻斗机空托下线
|
/// </summary>
|
/// <param name="db"></param>
|
/// <param name="taskName"></param>
|
/// <returns></returns>
|
/// <exception cref="NotImplementedException"></exception>
|
internal static Location BCPEmptyOut(SqlSugarClient db, string taskName)
|
{
|
Location result = null;
|
//翻斗机库存空托下线(瓶盖)
|
string endAreaName = taskName.Contains("瓶盖") ? "瓶盖空托" : "瓶坯空托";
|
var areaInfo = Settings.areaInfos.Where(a => a.areaName == endAreaName && a.enable == 1).FirstOrDefault();
|
if(areaInfo != null)
|
{
|
var locInfo = db.Queryable<Location>().Where(a => a.S_AREA_CODE == areaInfo.areaCode && a.N_CURRENT_NUM > 0 && a.S_LOCK_STATE == "无").OrderBy(a => a.N_COL).First();
|
if(locInfo != null)
|
{
|
result = locInfo;
|
}
|
}
|
else
|
{
|
LogHelper.Info($"{endAreaName}未配置");
|
}
|
return result;
|
}
|
}
|
}
|