using HH.WCS.Mobox3.WeiLi.util;
|
using HH.WCS.Mobox3.WeiLi.wms;
|
using System;
|
using System.Collections.Generic;
|
using System.Linq;
|
using System.Reflection;
|
using System.Text;
|
using System.Threading.Tasks;
|
|
namespace HH.WCS.Mobox3.WeiLi.core
|
{
|
internal class WMSCore
|
{
|
/// <summary>
|
/// 遍历定版的发货单,生产分拣单主表和子表(也可以手动调接口触发)
|
/// </summary>
|
internal static void CheckShippingOrder()
|
{
|
//1.0、获取已经定版的发货单,生产分拣单子表和主表,设置【发货单】的业务状态 N_B_STATE = 1(待分拣)
|
//2.0、如果发货单C_AUTO_SORTING=Y,则自动将分拣单状态设置为开始配货
|
|
}
|
/// <summary>
|
/// 开始配货创建分拣单明细(改成调接口触发)
|
/// </summary>
|
internal static void CheckSortingOrder()
|
{
|
//new SortingOrder().N_B_STATE
|
//1.0、获取 N_B_STATE = 1 (开始配货)状态的分拣单
|
//2.0、遍历分拣单子表,创建分拣单明细,更新分拣单子表的明细汇总F_ACC_S_QTY
|
//3.0、全部分拣单子表的明细创建完毕,子表明细汇总和子表数量一致,更新分拣单状态,N_B_STATE = 2配货完成
|
//4.0、如果分拣单是自动作业,就直接更新到 N_B_STATE = 3开始作业
|
//WMSHelper.GetWaitingSortingOrderList();
|
|
}
|
|
/// <summary>
|
/// 遍历分拣单明细创建出库作业
|
/// </summary>
|
internal static void CheckSortingTask()
|
{
|
LogHelper.Info($"开始查询配盘单明细 获取托盘");
|
var db = new SqlHelper<object>().GetInstance();
|
//new SortingOrder().N_B_STATE
|
//遍历N_B_STATE = 3的分拣单创建作业
|
//或 遍历分拣单明细创建分拣作业,因为一个分拣单里面的明细都是批量生成的
|
var list = WMSHelper.GetWaitingSortingOperationList();
|
LogHelper.Info($"获取配盘数量 {list.Count}");
|
if (list.Count > 0)
|
{
|
list.ForEach(a =>
|
{
|
var cntrInfo = db.Queryable<LocCntrRel>().Where(it => it.S_CNTR_CODE == a.S_CNTR_CODE).First();
|
if (cntrInfo != null)
|
{
|
a.S_LOC_CODE = cntrInfo.S_LOC_CODE;
|
var startloc = db.Queryable<Location>().Where(it => it.S_CODE == a.S_LOC_CODE).First();
|
if (startloc != null && startloc.S_LOCK_STATE == "其它锁")
|
{
|
LogHelper.Info($"托盘{a.S_CNTR_CODE} 绑定位置{a.S_LOC_CODE} 锁状态{startloc.S_LOCK_STATE}");
|
if (Settings.LKCodes.Where(it => it.LiKuCode == startloc.S_AREA_CODE).FirstOrDefault() != null)
|
{
|
string taskType = "";
|
Location endbit = null;
|
if (a.S_SORT_TYPE == "整托")
|
{
|
LogHelper.Info($"托盘{a.S_CNTR_CODE} 分拣类型为整托 直接出到外部库区 无需分拣");
|
endbit = db.Queryable<Location>().Where(it => it.S_CODE == "Z03").First();
|
taskType = "分拣出";
|
}
|
else if (a.S_SORT_TYPE != "整托备料")
|
{
|
LogHelper.Info($"托盘{a.S_CNTR_CODE} 分拣类型为{a.S_SORT_TYPE} 出到分拣位进行分拣");
|
taskType = a.S_BS_TYPE;
|
var endList = Settings.ConnetAreas.Where(it => it.LineArea == a.S_EXIT_AREA_CODE && it.Station == a.S_OUT_TO).ToList();
|
if (endList.Count > 0)
|
{
|
foreach (var endlist in endList)
|
{
|
for (int i = 0; i < endlist.FullList.Length; i++)
|
{
|
var endloc = endlist.FullList[i];
|
var end = db.Queryable<Location>().Where(it => it.S_CODE == endloc && it.N_LOCK_STATE == 0 && it.N_CURRENT_NUM == 0).First();
|
if (end != null)
|
{
|
endbit = end;
|
break;
|
}
|
else LogHelper.Info($"配盘 货位{endloc} 不可用");
|
}
|
if (endbit != null) break;
|
}
|
}
|
else LogHelper.Info($"配盘 未找到出库口库区编码{a.S_EXIT_AREA_CODE} 对应的配置文件");
|
}
|
|
if (endbit != null)
|
{
|
var optask = new WMSTask
|
{
|
S_CODE = WMSHelper.GenerateTaskNo(),
|
S_START_LOC = a.S_LOC_CODE,
|
S_START_AREA = startloc.S_AREA_CODE,
|
S_START_WH = startloc.S_WH_CODE,
|
S_END_LOC = endbit.S_CODE,
|
S_END_AREA = endbit.S_AREA_CODE,
|
S_END_WH = endbit.S_WH_CODE,
|
S_STATION_LOC = a.S_OUT_TO,
|
S_TYPE = "出库",
|
N_TYPE = 2,
|
N_B_STATE = 0,
|
S_CNTR_CODE = a.S_CNTR_CODE,
|
S_OP_DEF_NAME = taskType,
|
S_BS_NO = a.S_ZT_NO
|
};
|
var note = Settings.Tasktypes.Where(it => it.StartArea == optask.S_START_AREA && it.EndArea == optask.S_END_AREA).FirstOrDefault();
|
if (note != null)
|
{
|
optask.S_NOTE = note.TaskType;
|
}
|
var res = db.Insertable(optask).ExecuteCommand() > 0;
|
if (res)
|
{
|
LogHelper.Info($"修改配盘单状态及出库锁");
|
startloc.N_LOCK_STATE = 2;
|
startloc.S_LOCK_STATE = "出库锁";
|
db.Updateable(startloc).UpdateColumns(it => new { it.S_LOCK_STATE, it.N_LOCK_STATE }).ExecuteCommand();
|
LocationHelper.LockLoc(endbit.S_CODE, 1);
|
a.N_B_STATE = 2;
|
a.S_B_STATE = "作业启动";
|
db.Updateable(a).UpdateColumns(it => new { it.S_B_STATE, it.N_B_STATE }).ExecuteCommand();
|
LogHelper.Info($"修改成功");
|
}
|
}
|
else LogHelper.Info($"配盘 未找到可用分拣货位");
|
}
|
else
|
{
|
LogHelper.Info($"托盘{a.S_CNTR_CODE} 不在立库中 无法出库");
|
}
|
}
|
else LogHelper.Info($"配盘 托盘号{a.S_CNTR_CODE} 货位{a.S_LOC_CODE} 锁定状态异常");
|
}
|
});
|
}
|
|
|
}
|
|
|
/// <summary>
|
/// 遍历分拣单明细创建出库作业
|
/// </summary>
|
internal static void CheckPlanInventoryTask()
|
{
|
LogHelper.Info($"开始查询盘点单明细 获取托盘");
|
var db = new SqlHelper<object>().GetInstance();
|
//new SortingOrder().N_B_STATE
|
//遍历N_B_STATE = 3的分拣单创建作业
|
//或 遍历分拣单明细创建分拣作业,因为一个分拣单里面的明细都是批量生成的
|
var list = WMSHelper.GetWaitingPlanInventoryList();
|
LogHelper.Info($"获取盘点数量 {list.Count}");
|
if (list.Count > 0)
|
{
|
list.ForEach(a =>
|
{
|
var cntrInfo = db.Queryable<LocCntrRel>().Where(it => it.S_CNTR_CODE == a.S_CNTR_CODE).First();
|
if (cntrInfo != null)
|
{
|
a.S_LOC_CODE = cntrInfo.S_LOC_CODE;
|
var startloc = db.Queryable<Location>().Where(it => it.S_CODE == a.S_LOC_CODE).First();
|
if (startloc != null)
|
{
|
LogHelper.Info($"托盘{a.S_CNTR_CODE} 绑定位置{a.S_LOC_CODE} 锁状态{startloc.S_LOCK_STATE}");
|
if (a.N_B_STATE == 0 && startloc.S_LOCK_STATE == "其它锁")
|
{
|
if (Settings.LKCodes.Where(it => it.LiKuCode == startloc.S_AREA_CODE).FirstOrDefault() != null)
|
{
|
string taskType = "";
|
Location endbit = null;
|
|
LogHelper.Info($"托盘{a.S_CNTR_CODE} 分拣区域{a.S_STATION_NO} 出库方向{a.S_OUT_TO} 出到分拣位进行分拣");
|
taskType = "盘点出";
|
var endList = Settings.ConnetAreas.Where(it => it.LineArea == a.S_STATION_NO.Trim() && it.Station == a.S_OUT_TO.Trim()).ToList();
|
if (endList.Count > 0)
|
{
|
foreach (var endlist in endList)
|
{
|
for (int i = 0; i < endlist.FullList.Length; i++)
|
{
|
var endloc = endlist.FullList[i];
|
var end = db.Queryable<Location>().Where(it => it.S_CODE == endloc && it.N_LOCK_STATE == 0 && it.N_CURRENT_NUM == 0).First();
|
if (end != null)
|
{
|
endbit = end;
|
break;
|
}
|
else LogHelper.Info($"盘点 货位{endloc} 不可用");
|
}
|
if (endbit != null) break;
|
}
|
}
|
else LogHelper.Info($"盘点 未找到出库口库区编码{a.S_STATION_NO} 对应的配置文件");
|
|
|
if (endbit != null)
|
{
|
var optask = new WMSTask
|
{
|
S_CODE = WMSHelper.GenerateTaskNo(),
|
S_START_LOC = a.S_LOC_CODE,
|
S_START_AREA = startloc.S_AREA_CODE,
|
S_START_WH = startloc.S_WH_CODE,
|
S_END_LOC = endbit.S_CODE,
|
S_END_AREA = endbit.S_AREA_CODE,
|
S_END_WH = endbit.S_WH_CODE,
|
S_STATION_LOC = a.S_OUT_TO,
|
S_TYPE = "出库",
|
N_TYPE = 2,
|
N_B_STATE = 0,
|
S_CNTR_CODE = a.S_CNTR_CODE,
|
S_OP_DEF_NAME = taskType,
|
S_BS_NO = a.S_COUNT_NO
|
};
|
var note = Settings.Tasktypes.Where(it => it.StartArea == optask.S_START_AREA && it.EndArea == optask.S_END_AREA).FirstOrDefault();
|
if (note != null)
|
{
|
optask.S_NOTE = note.TaskType;
|
}
|
var res = db.Insertable(optask).ExecuteCommand() > 0;
|
if (res)
|
{
|
LogHelper.Info($"修改盘点单状态及出库锁");
|
startloc.N_LOCK_STATE = 2;
|
startloc.S_LOCK_STATE = "出库锁";
|
db.Updateable(startloc).UpdateColumns(it => new { it.S_LOCK_STATE, it.N_LOCK_STATE }).ExecuteCommand();
|
LocationHelper.LockLoc(endbit.S_CODE, 1);
|
a.N_B_STATE = 1;
|
db.Updateable(a).UpdateColumns(it => new { it.N_B_STATE }).ExecuteCommand();
|
LogHelper.Info($"修改成功");
|
}
|
}
|
else LogHelper.Info($"盘点 未找到可用分拣货位");
|
}
|
else
|
{
|
LogHelper.Info($"托盘{a.S_CNTR_CODE} 不在立库中 无法出库");
|
}
|
}
|
else if (a.N_B_STATE == 3 && startloc.N_LOCK_STATE == 0)
|
{
|
var optask = new WMSTask
|
{
|
S_CODE = WMSHelper.GenerateTaskNo(),
|
S_START_LOC = a.S_LOC_CODE,
|
S_START_AREA = startloc.S_AREA_CODE,
|
S_START_WH = startloc.S_WH_CODE,
|
S_END_LOC = "",
|
S_END_AREA = a.S_AREA_CODE,
|
S_END_WH = a.S_WH_CODE,
|
S_STATION_LOC = a.S_OUT_TO,
|
S_TYPE = "入库",
|
N_TYPE = 1,
|
N_B_STATE = 0,
|
S_CNTR_CODE = a.S_CNTR_CODE,
|
S_OP_DEF_NAME = "盘点回",
|
S_BS_NO = a.S_COUNT_NO
|
};
|
var note = Settings.Tasktypes.Where(it => it.StartArea == optask.S_START_AREA && it.EndArea == optask.S_END_AREA).FirstOrDefault();
|
if (note != null)
|
{
|
optask.S_NOTE = note.TaskType;
|
}
|
var res = db.Insertable(optask).ExecuteCommand() > 0;
|
if (res)
|
{
|
LogHelper.Info($"修改盘点单状态及出库锁");
|
startloc.N_LOCK_STATE = 2;
|
startloc.S_LOCK_STATE = "出库锁";
|
db.Updateable(startloc).UpdateColumns(it => new { it.S_LOCK_STATE, it.N_LOCK_STATE }).ExecuteCommand();
|
a.N_B_STATE = 4;
|
db.Updateable(a).UpdateColumns(it => new { it.N_B_STATE }).ExecuteCommand();
|
LogHelper.Info($"修改成功");
|
}
|
}
|
|
}
|
else LogHelper.Info($"盘点 托盘号{a.S_CNTR_CODE} 货位{a.S_LOC_CODE} 锁定状态异常");
|
}
|
});
|
}
|
|
|
}
|
|
|
/// <summary>
|
/// 作业启动,创建子任务
|
/// </summary>
|
internal static void Start()
|
{
|
LogHelper.Info($"作业启动 创建子任务");
|
var db = new SqlHelper<object>().GetInstance();
|
List<WMSTask> list = WMSHelper.GetWaitingOperationList();
|
LogHelper.Info($"获取任务数据 数量{list.Count}");
|
if (list.Count > 0)
|
{
|
//如果是出库的作业锁定托盘的时候已经明确起点了,如果发货单或分拣单指定了终点,
|
//如果没有作业、任务的顺序限制就可以启动,创建子任务了
|
foreach (var a in list)
|
{
|
try
|
{
|
if (a.N_TYPE == 1)
|
{
|
//入库有终点就可以执行
|
var cntrinfo = db.Queryable<LocCntrRel>().Where(it => it.S_CNTR_CODE == a.S_CNTR_CODE).First();
|
if (cntrinfo != null)
|
{
|
LocationHelper.LockLoc(cntrinfo.S_LOC_CODE, 2);
|
//查询托盘所在位置
|
//计算终点
|
Location end = WMSHelper.GetEnd(a);
|
if (end != null)
|
{
|
LogHelper.Info($"作业{a.S_CODE} 获取终点成功 任务终点{end.S_CODE}");
|
WMSHelper.UpdateTaskEnd(a);
|
LocationHelper.LockLoc(a.S_END_LOC, 1);
|
LocationHelper.LockLoc(end.S_CODE, 1);
|
|
a.S_START_LOC = cntrinfo.S_LOC_CODE;
|
if (!string.IsNullOrEmpty(a.S_END_LOC))
|
{
|
var type = "NDC";
|
var startinfo = db.Queryable<Location>().Where(it => it.S_CODE == a.S_START_LOC).First();
|
var endinfo = db.Queryable<Location>().Where(it => it.S_CODE == end.S_CODE).First();
|
if (startinfo != null && endinfo != null)
|
{
|
//起点或终点在立库中 类型为杭奥
|
var bol = Settings.LKCodes.Where(it => it.LiKuCode == startinfo.S_AREA_CODE).FirstOrDefault() != null || Settings.LKCodes.Where(it => it.LiKuCode == endinfo.S_AREA_CODE).FirstOrDefault() != null;
|
if (bol) type = "WCS";
|
}
|
//创建wcs任务
|
var wcsTask = new WCSTask
|
{
|
S_OP_CODE = a.S_CODE,
|
S_OP_NAME = "入库",
|
S_CODE = WCSHelper.GenerateTaskNo(),
|
S_TYPE = a.S_OP_DEF_NAME,
|
S_START_LOC = a.S_START_LOC,
|
S_START_AREA = startinfo.S_AREA_CODE,
|
S_START_WH = startinfo.S_WH_CODE,
|
S_END_LOC = end.S_CODE,
|
S_END_AREA = endinfo.S_AREA_CODE,
|
S_END_WH = endinfo.S_WH_CODE,
|
S_SCHEDULE_TYPE = type,
|
N_CNTR_COUNT = 1,
|
S_CNTR_CODE = a.S_CNTR_CODE,
|
};
|
if (WCSHelper.CreateTask(wcsTask))
|
{
|
LogHelper.Info($"作业{a.S_CODE} 创建任务成功 修改作业状态");
|
//更新作业状态为执行
|
a.N_B_STATE = 1;
|
a.S_B_STATE = "执行";
|
WMSHelper.UpdateTaskState(a);
|
}
|
else
|
{
|
LogHelper.Info($"作业{a.S_CODE} 创建任务失败");
|
}
|
}
|
else
|
{
|
LogHelper.Info($"作业{a.S_CODE} 获取终点失败");
|
}
|
}
|
}
|
}
|
else if (a.N_TYPE == 2)
|
{
|
//通过托盘获取到对应的分拣单 通过分拣单查找发货单上的终点库区 如果是备货出库的话 从配置文件中找一个空闲的点位
|
//计算终点
|
var cntrinfo = db.Queryable<LocCntrRel>().Where(it => it.S_CNTR_CODE == a.S_CNTR_CODE).First();
|
if (cntrinfo != null)
|
{
|
LocationHelper.LockLoc(cntrinfo.S_LOC_CODE, 2);
|
Location end = WMSHelper.GetEnd(a);
|
if (end != null)
|
{
|
LogHelper.Info($"查询到可用货位{end.S_CODE} 准备上锁");
|
WMSHelper.UpdateTaskEnd(a);
|
LocationHelper.LockLoc(a.S_END_LOC, 1);
|
LocationHelper.LockLoc(end.S_CODE, 1);
|
|
|
a.S_START_LOC = cntrinfo.S_LOC_CODE;
|
if (!string.IsNullOrEmpty(a.S_END_LOC))
|
{
|
var type = "NDC";
|
var startinfo = db.Queryable<Location>().Where(it => it.S_CODE == a.S_START_LOC).First();
|
var endinfo = db.Queryable<Location>().Where(it => it.S_CODE == end.S_CODE).First();
|
if (startinfo != null && endinfo != null)
|
{
|
//起点或终点在立库中 类型为杭奥
|
var bol = (Settings.LKCodes.Where(it => it.LiKuCode == startinfo.S_AREA_CODE).FirstOrDefault() != null ||
|
Settings.LKCodes.Where(it => it.LiKuCode == endinfo.S_AREA_CODE).FirstOrDefault() != null) ||
|
(Settings.ConnetAreas.Where(it => it.AreaCode == startinfo.S_AREA_CODE).FirstOrDefault() != null &&
|
Settings.ConnetAreas.Where(it => it.OutLocList.Contains(startinfo.S_CODE)).FirstOrDefault() == null);
|
if (bol)
|
{
|
type = "WCS";
|
}
|
}
|
//创建wcs任务
|
var wcsTask = new WCSTask
|
{
|
S_OP_CODE = a.S_CODE,
|
S_OP_NAME = "出库",
|
S_CODE = WCSHelper.GenerateTaskNo(),
|
S_TYPE = a.S_OP_DEF_NAME,
|
S_START_LOC = a.S_START_LOC,
|
S_START_AREA = startinfo.S_AREA_CODE,
|
S_START_WH = startinfo.S_WH_CODE,
|
S_END_LOC = end.S_CODE,
|
S_END_AREA = endinfo.S_AREA_CODE,
|
S_END_WH = endinfo.S_WH_CODE,
|
S_SCHEDULE_TYPE = type,
|
N_CNTR_COUNT = 1,
|
S_CNTR_CODE = a.S_CNTR_CODE,
|
};
|
|
if (type == "NDC" && (a.S_OP_DEF_NAME == "出库" || a.S_OP_DEF_NAME == "分拣出" || a.S_OP_DEF_NAME == "空框出库"))
|
{
|
string workNo = "";
|
if (a.S_OP_DEF_NAME == "分拣出")
|
{
|
workNo = a.S_BS_NO;
|
}
|
else
|
{
|
workNo = a.S_CODE;
|
}
|
//调接口
|
var endbit = WMSHelper.OutState(wcsTask, workNo);
|
if (!string.IsNullOrEmpty(endbit))
|
{
|
//替换终点 原终点解锁
|
var NewEndinfo = db.Queryable<Location>().Where(it => it.S_CODE == endbit).First();
|
if (NewEndinfo != null)
|
{
|
//替换终点
|
wcsTask.S_END_LOC = endbit;
|
wcsTask.S_END_AREA = NewEndinfo.S_AREA_CODE;
|
wcsTask.S_END_WH = NewEndinfo.S_WH_CODE;
|
//解锁原终点
|
LocationHelper.UnLockLoc(a.S_END_LOC);
|
//作业终点替换
|
a.S_END_LOC = endbit;
|
WMSHelper.UpdateTaskEnd(a);
|
LocationHelper.LockLoc(a.S_END_LOC, 1);
|
}
|
else
|
{
|
LogHelper.Info($"中台返回终点{endbit} 不存在货位信息");
|
LocationHelper.UnLockLoc(end.S_CODE);
|
break;
|
}
|
}
|
else
|
{
|
LogHelper.Info($"中台并未返回终点");
|
LocationHelper.UnLockLoc(end.S_CODE);
|
break;
|
}
|
}
|
|
if (WCSHelper.CreateTask(wcsTask))
|
{
|
LogHelper.Info($"作业{a.S_CODE} 创建任务成功 修改作业状态");
|
//更新作业状态为执行
|
a.N_B_STATE = 1;
|
a.S_B_STATE = "执行";
|
WMSHelper.UpdateTaskState(a);
|
}
|
|
}
|
}
|
}
|
}
|
else if (a.N_TYPE == 3)
|
{
|
//agv转运任务
|
if (!string.IsNullOrEmpty(a.S_END_LOC))
|
{
|
var startinfo = db.Queryable<Location>().Where(it => it.S_CODE == a.S_START_LOC).First();
|
var endinfo = db.Queryable<Location>().Where(it => it.S_CODE == a.S_END_LOC).First();
|
var type = "NDC";
|
if (startinfo != null && endinfo != null)
|
{
|
//起点或终点在立库中 类型为杭奥
|
var bol = Settings.LKCodes.Where(it => it.LiKuCode == startinfo.S_AREA_CODE).FirstOrDefault() != null || Settings.LKCodes.Where(it => it.LiKuCode == endinfo.S_AREA_CODE).FirstOrDefault() != null;
|
if (bol) type = "WCS";
|
}
|
//创建wcs任务
|
var wcsTask = new WCSTask
|
{
|
S_OP_CODE = a.S_CODE,
|
S_OP_NAME = "转运",
|
S_CODE = WCSHelper.GenerateTaskNo(),
|
S_TYPE = a.S_OP_DEF_NAME,
|
S_START_LOC = a.S_START_LOC,
|
S_START_AREA = startinfo.S_AREA_CODE,
|
S_START_WH = startinfo.S_WH_CODE,
|
S_END_LOC = a.S_END_LOC,
|
S_END_AREA = endinfo.S_AREA_CODE,
|
S_END_WH = endinfo.S_WH_CODE,
|
S_SCHEDULE_TYPE = type,
|
N_CNTR_COUNT = 1,
|
S_CNTR_CODE = a.S_CNTR_CODE,
|
};
|
if (WCSHelper.CreateTask(wcsTask))
|
{
|
//更新作业状态为执行
|
a.N_B_STATE = 1;
|
a.S_B_STATE = "执行";
|
WMSHelper.UpdateTaskState(a);
|
}
|
|
}
|
}
|
}
|
catch (Exception ex)
|
{
|
LogHelper.Error($"作业启动异常 异常信息={ex.Message}", ex);
|
}
|
}
|
}
|
}
|
}
|
}
|