using HH.WCS.Mobox3.FJJF.models;
using HH.WCS.Mobox3.FJJT.device;
using HH.WCS.Mobox3.FJJT.dispatch;
using HH.WCS.Mobox3.FJJT.models;
using HH.WCS.Mobox3.FJJT.process;
using HH.WCS.Mobox3.FJJT.util;
using HH.WCS.Mobox3.FJJT.wms;
using Newtonsoft.Json;
using NLog;
using NLog.Fluent;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Threading;
using static HH.WCS.Mobox3.FJJT.api.ApiModel;
using static HH.WCS.Mobox3.FJJT.api.OtherModel;
using static HH.WCS.Mobox3.FJJT.api.WmsController;
using static HH.WCS.Mobox3.FJJT.util.ExcetionHelper;
using static HH.WCS.Mobox3.FJJT.util.Settings;
using static System.Net.Mime.MediaTypeNames;
namespace HH.WCS.Mobox3.FJJT.api {
///
/// api接口辅助类
///
public class ApiHelper {
static ApiHelper() {
}
///
/// 空工装出库
///
///
///
public static ResponseResult emptyPalletOutStock(OutStockModel model) {
ResponseResult result = new ResponseResult();
Location endLoc = LocationHelper.GetLoc(model.endLocCode);
if (endLoc == null)
{
WMSHelper.addAlarmRecord("流程异常", "低", $"WMS系统未查询到终点货位:{model.endLocCode}");
throw new BusinessException($"WMS系统未查询到终点货位:{model.endLocCode},请检查终点货位编码是否正确");
}
else
{
if (endLoc.C_ENABLE == "Y")
{
if (endLoc.N_LOCK_STATE != 0)
{
var existTask = WCSHelper.GetTaskByStartOrEnd(model.endLocCode);
if (existTask != null)
{
WMSHelper.addAlarmRecord("流程异常", "低", $"终点货位:{model.endLocCode} 已有任务");
throw new BusinessException($"终点货位:{model.endLocCode} 已有任务");
}
else
{
LocationHelper.UnLockLoc(model.endLocCode); // 没有任务就,自动解锁终点货位
}
}
}
else
{
WMSHelper.addAlarmRecord("流程异常", "低", $"终点货位:{model.endLocCode} 已禁用,请联系管理人员解除禁用");
throw new BusinessException($"终点货位:{model.endLocCode} 已禁用,请联系管理人员解除禁用");
}
}
var transfeRelevance = WMSHelper.GetTransfeRelevance(model.endLocCode); // 接驳货位关联属性
if (transfeRelevance == null)
{
WMSHelper.addAlarmRecord("流程异常", "低", $"终点货位:{model.endLocCode},缺少配置属性,请联系管理人员进行配置属性");
throw new BusinessException($"终点货位:{model.endLocCode},缺少配置属性,请联系管理人员进行配置属性");
}
Location startLoc = WMSHelper.getOutStockStartLoc(transfeRelevance.S_RELE_AREA, null);
if (startLoc == null)
{
WMSHelper.addAlarmRecord("流程异常", "低", $"未查询到空工装,立库可能缺少空工装");
throw new BusinessException($"未查询到空工装,立库可能缺少空工装");
}
var locCntrRels = LocationHelper.GetLocCntr(startLoc.S_CODE);
if (locCntrRels.Count > 0)
{
string cntrCode = locCntrRels[0].S_CNTR_CODE;
var wmsTask = new WMSTask()
{
S_CNTR_CODE = cntrCode,
S_CODE = WMSHelper.GenerateTaskNo(),
S_START_LOC = startLoc.S_CODE,
S_START_AREA = startLoc.S_AREA_CODE,
S_END_LOC = endLoc.S_CODE,
S_END_AREA = endLoc.S_AREA_CODE,
S_TYPE = "空工装出库任务",
S_OP_DEF_NAME = "空工装出库缓存位",
N_PRIORITY = 10,
T_START_TIME = DateTime.Now,
};
if (WMSHelper.CreateWmsTask(wmsTask))
{
// 创建一段入库任务
WCSTask wcsTask = new WCSTask()
{
S_OP_NAME = wmsTask.S_OP_DEF_NAME,
S_OP_CODE = wmsTask.S_CODE,
S_CODE = WCSHelper.GenerateTaskNo(),
S_CNTR_CODE = wmsTask.S_CNTR_CODE,
S_TYPE = wmsTask.S_TYPE,
S_START_LOC = startLoc.S_CODE,
S_START_AREA = startLoc.S_AREA_CODE,
S_END_LOC = endLoc.S_CODE,
S_END_AREA = endLoc.S_AREA_CODE,
S_SCHEDULE_TYPE = "WCS",
N_PRIORITY = wmsTask.N_PRIORITY,
T_START_TIME = DateTime.Now,
};
if (WCSHelper.CreateTask(wcsTask))
{
// 起点、终点加锁
LocationHelper.LockLoc(wcsTask.S_START_LOC, 2);
LocationHelper.LockLoc(wcsTask.S_END_LOC, 1);
// 更新作业任务状态
wmsTask.N_B_STATE = 1;
WMSHelper.UpdateTaskState(wmsTask);
}
}
}
else
{
WMSHelper.addAlarmRecord("流程异常", "中", $"查询的空工装有误,错误原因:未查询到货位容器的绑定关系");
throw new BusinessException($"查询空工装错误,未查询到货位容器的绑定关系,请联系开发人员排查");
}
return result;
}
///
/// WCS读码请求流程
/// 1.判断RFID 是否读取成功(托盘号是否为空)
/// 2.查询关于RFID的预创建任务
/// 3.如果读取成功,则激活预创建任务
/// 4.如果读取不成功,查看异常区是否有空货位,有则创建搬运异常区任务,无则,记录异常激活预创建任务
///
///
///
public static ResponseResult readCodeProcess(ReadCodeRequest request) {
ResponseResult responseResult = new ResponseResult();
Location loc = LocationHelper.GetLoc(request.loc);
if (loc == null)
{
WMSHelper.addAlarmRecord("流程异常", "中", $"读码位:{request.loc},没有在WMS系统中录入");
throw new BusinessException($"读码位:{request.loc},没有在WMS系统中录入");
}
var locCntrRels = LocationHelper.GetLocCntr(request.loc);
if (locCntrRels.Count > 0)
{
string taskCntrCode = locCntrRels[0].S_CNTR_CODE;
// 2.查询关于RFID的预创建任务
var cst = WCSHelper.GetPreCreatedTaskByCntr(taskCntrCode);
if (cst != null)
{
bool errFlag = true;
// 1.判断RFID 是否读取成功(托盘号是否为空)
if (request.cntrNo != null)
{
if (request.cntrNo == taskCntrCode)
{
Container container = ContainerHelper.GetCntr(request.cntrNo);
if (container.N_E_STATE == 0)
{
errFlag = false;
WCSHelper.ActivatePreCreateTask(cst.S_OP_CODE);
}
}
else
{
ContainerHelper.UpdateCntrState(taskCntrCode, 1,"WCS反馈RFID与任务RFID不一致");
}
}
else
{
ContainerHelper.UpdateCntrState(taskCntrCode, 1,"WCS反馈RFID为null");
}
// 方案1 4.激活预创建任务
if (errFlag)
{
WCSHelper.ActivatePreCreateTask(cst.S_OP_CODE,1);
}
// 方案2 4.如果读取不成功,查看异常区是否有空货位
/* var agvEndLoc = WMSHelper.GetTransfeRelevanceLoc(loc.S_AREA_CODE, "4");
if (agvEndLoc != null)
{
// 4.1 有,则创建搬运异常区任务
WCSTask wcsTask = new WCSTask()
{
S_OP_NAME = cst.S_OP_NAME,
S_OP_CODE = cst.S_OP_CODE,
S_CODE = WCSHelper.GenerateTaskNo(),
S_CNTR_CODE = cst.S_CNTR_CODE,
S_TYPE = "异常工装移库异常区",
S_START_LOC = loc.S_CODE,
S_START_AREA = loc.S_AREA_CODE,
S_END_LOC = agvEndLoc.S_CODE,
S_END_AREA = agvEndLoc.S_AREA_CODE,
S_SCHEDULE_TYPE = "AGV",
N_PRIORITY = 99,
T_START_TIME = DateTime.Now,
};
if (WCSHelper.CreateTask(wcsTask))
{
// 起点、接驳点、终点加锁
LocationHelper.LockLoc(wcsTask.S_START_LOC, 1);
LocationHelper.LockLoc(wcsTask.S_END_LOC, 1);
WCSHelper.CancelPreCreateTask(cst.S_OP_CODE);
}
}
else
{
// 4.2 无,则记录异常激活预创建任务
WCSHelper.ActivatePreCreateTask(cst.S_OP_CODE);
}*/
}
else
{
WMSHelper.addAlarmRecord("流程异常", "低", $"读码位:{request.loc}触发读码请求,读码位上容器:{taskCntrCode}没有预创建任务");
}
}
else
{
WMSHelper.addAlarmRecord("流程异常", "中", $"读码位:{request.loc},没有查询到容器");
throw new BusinessException($"读码位:{request.loc},没有查询到容器");
}
return responseResult;
}
///
/// 满料下线流程
/// 1.判断RFID是否读取成功,读取不成功,记录异常(读取失败后,临时生成一个托盘码)
/// 2.根据RFID查询中间表,不存在,记录异常
/// 3.判断满料接驳位对应的空工装缓存位状态(查询线体光电)
///
/// 直连
/// 4.需要补,则生成空工装出库任务(胎面、胎侧直连提高优先级)
/// 5.下发满料搬运任务(帘布直连提高优先级)
///
/// 非直连
/// 4.需要补空工装,则空工装出库任务(完成后,生成满料搬运任务,并提高优先级99)
/// 5.不需要补空工装,则生成满料搬运任务
///
/// 6.读任务中间表
///
///
///
public static ResponseResult offLineProcess(OffLineRequest model) {
ResponseResult responseResult = new ResponseResult();
var existWmsTask = WMSHelper.GetWmsTaskByStart(model.loc);
if (existWmsTask == null)
{
// 判断满料接驳位对应的空工装缓存位状态(查询线体光电)
var logicConfig = WMSHelper.getLogicConfigByJtCode(model.jtNo);
if (logicConfig != null)
{
if (logicConfig.S_TASK_TYPE == "1" || logicConfig.S_TASK_TYPE == "2")
{
// 满料下线(直连)
LjMesTask mesTask = null;
if (model.cntrNo != null && model.cntrNo != "")
{
var container = ContainerHelper.GetCntr(model.cntrNo);
if (container == null)
{
ContainerHelper.AddCntr(model.cntrNo);
ContainerHelper.UpdateCntrState(model.cntrNo, 1, $"满料下线(直连),WCS反馈的RFID:{model.cntrNo}在WMS系统中不存在");
WMSHelper.addAlarmRecord("流程异常", "中", $"满料下线(直连),WCS反馈的RFID:{model.cntrNo}在WMS系统中不存在");
}
else
{
ContainerHelper.UpdateCntrState(model.cntrNo, 0, "");
mesTask = WMSHelper.getLjMesTaskByCntr(model.cntrNo);
if (mesTask == null)
{
ContainerHelper.UpdateCntrState(model.cntrNo, 1, $"未查询到MES任务");
WMSHelper.addAlarmRecord("流程异常", "低", $"满料下线(直连),容器:{model.cntrNo}未查询到MES任务");
}
}
}
else
{
model.cntrNo = ContainerHelper.GenerateCntrNo();
ContainerHelper.AddCntr(model.cntrNo);
ContainerHelper.UpdateCntrState(model.cntrNo, 1, $"WCS反馈的RFID:{model.cntrNo} 为空");
WMSHelper.addAlarmRecord("流程异常", "中", $"WCS反馈的RFID:{model.cntrNo} 为空");
}
triggerItemOffLineFlow(model.loc, model.cntrNo, logicConfig, mesTask);
}
else
{
// 满料下线(非直连)
var mesTask = WMSHelper.getLjMesTaskByLoc(model.loc);
triggerItemOffLineFlow4(model.loc, logicConfig,mesTask);
}
}
else
{
WMSHelper.addAlarmRecord("流程异常", "高", $"机台号{model.jtNo},没有可用的逻辑线路,请联系管理人员");
throw new BusinessException($"机台号{model.jtNo},没有可用的逻辑线路,请联系管理人员");
}
}
else
{
WMSHelper.addAlarmRecord("流程异常", "低", $"下线货位:{model.loc}已有任务,请勿重复下发任务");
throw new BusinessException($"下线货位:{model.loc}已有任务,请勿重复下发任务");
}
return responseResult;
}
///
/// 满料下线(非直连)
/// 1.创建满料下线作业
/// 2.判断是否需要补空工装,需要则创建空工装补缓存位任务
/// 3.判断容器是否是异常工装,是,如异常区有空货位则创建异常工装入线边异常区任务;否,则创建满料工装入库任务(如需要补空工装,则将任务状态改为预创建,等待补空工装任务完成后触发)
/// 4.作业创建完成后,读取中间表,更新中间表状态
///
///
///
///
public static bool triggerItemOffLineFlow4(string offLineLoc, LogicConfig logicConfig ,LjMesTask mesTask)
{
bool result = true;
try
{
if (mesTask != null)
{
// 2.判断是否需要补空工装,需要,则创建空工装出库任务
// TODO 查询缓存位线体光电++++++
bool photoStatus = false;
var hcLoc = LocationHelper.GetLoc(logicConfig.S_LKBKHCLOC);
if (hcLoc != null)
{
var transfeRelevance = WMSHelper.GetTransfeRelevance(hcLoc.S_CODE); // 缓存位关联属性
if (transfeRelevance != null)
{
photoStatus = true;
// 方案1,如果非直连的缓存位有光电信号,则查询设备状态判断是否需要补空工装
/*var deviceStatusDatas = WCSDispatch.getDeviceStatus(new List() { transfeRelevance.S_DEVICE_NO });
if (deviceStatusDatas != null && deviceStatusDatas.Count > 0)
{
var deviceStatus = deviceStatusDatas[0];
if (deviceStatus.workStatus == 1 && deviceStatus.manualStatus == 0)
{
photoStatus = deviceStatus.photoStatus == 1;
}
else
{
WMSHelper.addAlarmRecord("流程异常", "高", $"设备号:{transfeRelevance.S_DEVICE_NO},设备当前处于不可用状态,请联系管理人员调整设备状态");
throw new BusinessException($"设备号:{transfeRelevance.S_DEVICE_NO},设备当前处于不可用状态,请联系管理人员调整设备状态");
}
}
else
{
WMSHelper.addAlarmRecord("流程异常", "高", $"设备号:{transfeRelevance.S_DEVICE_NO},查询设备状态失败,请联系工作人员查看设备是否正常");
throw new BusinessException($"设备号:{transfeRelevance.S_DEVICE_NO},查询设备状态失败,请联系工作人员查看设备是否正常");
}*/
// 方案2,如果非直连的缓存位没有光电信号,则根据货位状态进行判断,需要注意:人工取空工装需要解锁
}
else
{
WMSHelper.addAlarmRecord("流程异常", "高", $"缓存位:{logicConfig.S_LKBKHCLOC},没有配置属性信息,请联系管理人员配置");
throw new BusinessException($"缓存位:{logicConfig.S_LKBKHCLOC},没有配置属性信息,请联系管理人员配置");
}
}
else
{
WMSHelper.addAlarmRecord("流程异常", "高", $"缓存位:{logicConfig.S_LKBKHCLOC},没有WMS系统中录入");
throw new BusinessException($"缓存位:{logicConfig.S_LKBKHCLOC},没有WMS系统中录入");
}
// 空工装出库判断条件
Location kgzStartLoc = null;
Location kgzEndLoc = null;
string kgzCntrCode = null;
if (photoStatus)
{
kgzStartLoc = LocationHelper.GetLoc(logicConfig.S_LKKTJBLOC);
kgzEndLoc = LocationHelper.GetLoc(logicConfig.S_LKBKHCLOC);
if (kgzStartLoc == null)
{
WMSHelper.addAlarmRecord("流程异常", "高", $"库区:{logicConfig.S_AREA_CODE},没有可用的空工装");
throw new BusinessException($"库区:{logicConfig.S_AREA_CODE},没有可用的空工装");
}
if (kgzEndLoc == null)
{
WMSHelper.addAlarmRecord("流程异常", "中", $"空工装缓存位:{logicConfig.S_LKBKHCLOC},没有在WMS系统中录入");
throw new BusinessException($"空工装缓存位:{logicConfig.S_LKBKHCLOC},没有在WMS系统中录入");
}
var locCntrRels = LocationHelper.GetLocCntr(kgzStartLoc.S_CODE);
if (locCntrRels.Count > 0)
{
kgzCntrCode = locCntrRels[0].S_CNTR_CODE;
}
else
{
WMSHelper.addAlarmRecord("流程异常", "中", $"空工装补充接驳位:{logicConfig.S_LKKTJBLOC},没有空工装");
throw new BusinessException($"空工装补充接驳位:{logicConfig.S_LKKTJBLOC},没有空工装");
}
}
string cntrCode = mesTask.PALLET_ID;
Location startLoc = LocationHelper.GetLoc(offLineLoc);
if (startLoc != null)
{
// 1.创建满料下线作业
var wmsTask = new WMSTask()
{
S_CNTR_CODE = cntrCode,
S_CODE = WMSHelper.GenerateTaskNo(),
S_START_LOC = startLoc.S_CODE,
S_START_AREA = startLoc.S_AREA_CODE,
S_END_LOC = "虚拟货位",
S_END_AREA = "虚拟库区",
S_TYPE = "满料/异常工装入库任务(非直连)",
S_OP_DEF_NAME = "满料/异常工装入库任务(非直连)",
S_OP_DEF_CODE = mesTask.ID.ToString(),
T_START_TIME = DateTime.Now,
};
if (WMSHelper.CreateWmsTask(wmsTask))
{
int priority = 10;
// 2.判断是否需要补空工装,需要则创建空工装补缓存位任务
if (photoStatus)
{
WCSTask kgzWcsTask = new WCSTask()
{
S_OP_NAME = wmsTask.S_OP_DEF_NAME,
S_OP_CODE = wmsTask.S_CODE,
S_CODE = WCSHelper.GenerateTaskNo(),
S_CNTR_CODE = kgzCntrCode,
S_TYPE = "空工装出库任务",
S_START_LOC = kgzStartLoc.S_CODE,
S_START_AREA = kgzStartLoc.S_AREA_CODE,
S_END_LOC = kgzEndLoc.S_CODE,
S_END_AREA = kgzEndLoc.S_AREA_CODE,
S_SCHEDULE_TYPE = "AGV",
N_PRIORITY = priority,
T_START_TIME = DateTime.Now,
};
if (WCSHelper.CreateTask(kgzWcsTask))
{
// 起点、终点加锁
LocationHelper.LockLoc(kgzWcsTask.S_START_LOC, 2);
LocationHelper.LockLoc(kgzWcsTask.S_END_LOC, 1);
}
}
// 3.判断容器是否是异常工装,是,则创建异常工装入线边异常区任务;
// 否,则创建满料工装入库任务(如需要补空工装,则将任务状态改为预创建,等待补空工装任务完成后触发)
WCSTask wcsTask = new WCSTask()
{
S_OP_NAME = wmsTask.S_OP_DEF_NAME,
S_OP_CODE = wmsTask.S_CODE,
S_CODE = WCSHelper.GenerateTaskNo(),
S_CNTR_CODE = wmsTask.S_CNTR_CODE,
S_START_LOC = startLoc.S_CODE,
S_START_AREA = startLoc.S_AREA_CODE,
S_END_LOC = wmsTask.S_END_LOC,
S_END_AREA = wmsTask.S_END_AREA,
S_SCHEDULE_TYPE = "AGV",
N_PRIORITY = 99,
T_START_TIME = DateTime.Now,
};
Container container = ContainerHelper.GetCntr(cntrCode);
if (container.N_E_STATE == 0)
{
wcsTask.S_TYPE = "满料工装入库任务(非直连)";
}
else
{
Location ycgzLoc = null;
if (ycgzLoc != null)
{
wcsTask.S_TYPE = "异常工装入库线边异常区";
wcsTask.S_END_LOC = ycgzLoc.S_CODE;
wcsTask.S_END_AREA = ycgzLoc.S_AREA_CODE;
}
else
{
wcsTask.S_TYPE = "异常工装入库";
}
}
if (photoStatus)
{
wcsTask.N_B_STATE = -1;
wcsTask.S_B_STATE = "预创建";
}
if (WCSHelper.CreateTask(wcsTask))
{
// 起点、终点加锁
LocationHelper.LockLoc(wcsTask.S_START_LOC, 2);
LocationHelper.LockLoc(wcsTask.S_END_LOC, 1);
}
// 更新作业任务状态
wmsTask.N_B_STATE = 1;
WMSHelper.UpdateTaskState(wmsTask);
// 4.作业创建完成后,读取中间表,更新中间表状态
WMSHelper.readLjMesOffItemTask(wmsTask.S_CODE, mesTask.ID);
}
}
else
{
WMSHelper.addAlarmRecord("流程异常", "中", $"下线位:{offLineLoc},没有在WMS系统中录入");
throw new BusinessException($"下线位:{offLineLoc},没有在WMS系统中录入");
}
}
else
{
WMSHelper.addAlarmRecord("流程异常", "中", $"非直连下线货位:{offLineLoc}触发下线请求,未查询到MES任务");
throw new BusinessException($"非直连下线货位:{offLineLoc}触发下线请求,未查询到MES任务");
}
}
catch (BusinessException be)
{
throw be;
}
catch (Exception ex)
{
WMSHelper.addAlarmRecord("系统错误", "高", ex.Message);
LogHelper.Error("WMS内部错误:触发满料下线(非直连)作业错误 ; ERROR_MGS:" + ex.Message, ex, "WMS");
result = false;
}
return result;
}
///
/// 满料下线(直连)
/// 1.创建满料下线作业
/// 2.判断是否需要补空工装,需要,则创建空工装出库任务
/// 3.创建满料入库任务
/// 4.判断直连模式,如是胎侧直连模式,则提高空工装出库任务优先级;如是帘布直连模式则,提高满料入库优先级
/// 5.作业创建完成后,读取中间表,更新中间表状态
///
/// 下线货位
/// 下线容器编码
/// 逻辑配置
///
public static bool triggerItemOffLineFlow(string offLineLoc, string cntrCode, LogicConfig logicConfig ,LjMesTask mesTask) {
bool result = true;
try
{
// 2.判断是否需要补空工装,需要,则创建空工装出库任务
bool photoStatus = false;
var hcLoc = LocationHelper.GetLoc(logicConfig.S_LKBKHCLOC);
if (hcLoc != null)
{
var transfeRelevance = WMSHelper.GetTransfeRelevance(hcLoc.S_CODE); // 缓存位关联属性
if (transfeRelevance != null)
{
// 测试代码
photoStatus = true;
// 业务代码,勿删
/*var deviceStatusDatas = WCSDispatch.getDeviceStatus(new List() { transfeRelevance.S_DEVICE_NO });
if (deviceStatusDatas != null && deviceStatusDatas.Count > 0)
{
var deviceStatus = deviceStatusDatas[0];
if (deviceStatus.workStatus == 1 && deviceStatus.manualStatus == 0)
{
photoStatus = deviceStatus.photoStatus == 1;
}
else
{
WMSHelper.addAlarmRecord("流程异常", "高", $"设备号:{transfeRelevance.S_DEVICE_NO},设备当前处于不可用状态,请联系管理人员调整设备状态");
throw new BusinessException($"设备号:{transfeRelevance.S_DEVICE_NO},设备当前处于不可用状态,请联系管理人员调整设备状态");
}
}
else
{
WMSHelper.addAlarmRecord("流程异常", "高", $"设备号:{transfeRelevance.S_DEVICE_NO},查询设备状态失败,请联系工作人员查看设备是否正常");
throw new BusinessException($"设备号:{transfeRelevance.S_DEVICE_NO},查询设备状态失败,请联系工作人员查看设备是否正常");
}*/
}
else
{
WMSHelper.addAlarmRecord("流程异常", "高", $"缓存位:{logicConfig.S_LKBKHCLOC},没有配置属性信息,请联系管理人员配置");
throw new BusinessException($"缓存位:{logicConfig.S_LKBKHCLOC},没有配置属性信息,请联系管理人员配置");
}
}
else
{
WMSHelper.addAlarmRecord("流程异常", "高", $"缓存位:{logicConfig.S_LKBKHCLOC},没有在WMS系统中录入");
throw new BusinessException($"缓存位:{logicConfig.S_LKBKHCLOC},没有在WMS系统中录入");
}
Location startLoc = LocationHelper.GetLoc(offLineLoc);
if (startLoc == null)
{
WMSHelper.addAlarmRecord("流程异常", "中", $"下线位:{offLineLoc},没有在WMS系统中录入");
throw new BusinessException($"下线位:{offLineLoc},没有在WMS系统中录入");
}
Location endLoc = WMSHelper.getInStockEndLoc(logicConfig.S_AREA_CODE, 1);
if (endLoc == null)
{
WMSHelper.addAlarmRecord("流程异常", "高", $"库内没有空余货位");
throw new BusinessException($"库内没有空余货位");
}
Container container = ContainerHelper.GetCntr(cntrCode);
if (container != null)
{
// 1.创建满料下线作业
var wmsTask = new WMSTask()
{
S_CNTR_CODE = cntrCode,
S_CODE = WMSHelper.GenerateTaskNo(),
S_START_LOC = startLoc.S_CODE,
S_START_AREA = startLoc.S_AREA_CODE,
S_END_LOC = endLoc.S_CODE,
S_END_AREA = endLoc.S_AREA_CODE,
S_TYPE = "满料/异常工装入库任务(直连)",
S_OP_DEF_NAME = "满料/异常工装入库任务(直连)",
S_OP_DEF_CODE = mesTask != null ? mesTask.ID.ToString() : null,
T_START_TIME = DateTime.Now,
};
if (WMSHelper.CreateWmsTask(wmsTask))
{
int priority = 10;
// 是否创建空工装出口任务
if (photoStatus)
{
Location kgzStartLoc = WMSHelper.getOutStockStartLoc(logicConfig.S_AREA_CODE, null);
Location kgzEndLoc = LocationHelper.GetLoc(logicConfig.S_LKBKHCLOC);
if (kgzStartLoc == null)
{
WMSHelper.DeleteWmsTask(wmsTask.S_CODE);
WMSHelper.addAlarmRecord("流程异常", "高", $"库区:{logicConfig.S_AREA_CODE},没有可用的空工装");
throw new BusinessException($"库区:{logicConfig.S_AREA_CODE},没有可用的空工装");
}
if (kgzEndLoc == null)
{
WMSHelper.DeleteWmsTask(wmsTask.S_CODE);
WMSHelper.addAlarmRecord("流程异常", "中", $"空工装缓存位:{logicConfig.S_LKBKHCLOC},没有在WMS系统中录入");
throw new BusinessException($"空工装缓存位:{logicConfig.S_LKBKHCLOC},没有在WMS系统中录入");
}
var locCntrRels = LocationHelper.GetLocCntr(kgzStartLoc.S_CODE);
if (locCntrRels.Count > 0)
{
string kgzCntrCode = locCntrRels[0].S_CNTR_CODE;
// 如是胎侧直连模式,则提高空工装出库任务优先级
if (logicConfig.S_TASK_TYPE == "1")
{
priority = 99;
}
WCSTask kgzWcsTask = new WCSTask()
{
S_OP_NAME = wmsTask.S_OP_DEF_NAME,
S_OP_CODE = wmsTask.S_CODE,
S_CODE = WCSHelper.GenerateTaskNo(),
S_CNTR_CODE = kgzCntrCode,
S_TYPE = "空工装出库任务",
S_START_LOC = kgzStartLoc.S_CODE,
S_START_AREA = kgzStartLoc.S_AREA_CODE,
S_END_LOC = kgzEndLoc.S_CODE,
S_END_AREA = kgzEndLoc.S_AREA_CODE,
S_SCHEDULE_TYPE = "WCS",
N_PRIORITY = priority,
T_START_TIME = DateTime.Now,
};
if (WCSHelper.CreateTask(kgzWcsTask))
{
// 起点、终点加锁
LocationHelper.LockLoc(kgzWcsTask.S_START_LOC, 2);
LocationHelper.LockLoc(kgzWcsTask.S_END_LOC, 1);
}
}
else
{
WMSHelper.DeleteWmsTask(wmsTask.S_CODE);
WMSHelper.addAlarmRecord("流程异常", "高", $"查询空工装货位错误,货位:{kgzStartLoc.S_CODE}没有空工装");
throw new BusinessException($"查询空工装货位错误,货位:{kgzStartLoc.S_CODE}没有空工装");
}
}
// 如是帘布直连模式则,提高满料入库优先级
if (logicConfig.S_TASK_TYPE == "2")
{
priority = 99;
}
else
{
priority = 10;
}
WCSTask wcsTask = new WCSTask()
{
S_OP_NAME = wmsTask.S_OP_DEF_NAME,
S_OP_CODE = wmsTask.S_CODE,
S_CODE = WCSHelper.GenerateTaskNo(),
S_CNTR_CODE = wmsTask.S_CNTR_CODE,
S_TYPE = wmsTask.S_TYPE,
S_START_LOC = startLoc.S_CODE,
S_START_AREA = startLoc.S_AREA_CODE,
S_END_LOC = endLoc.S_CODE,
S_END_AREA = endLoc.S_AREA_CODE,
S_SCHEDULE_TYPE = "WCS",
N_PRIORITY = priority,
T_START_TIME = DateTime.Now,
};
if (WCSHelper.CreateTask(wcsTask))
{
// 起点、终点加锁
LocationHelper.LockLoc(wcsTask.S_START_LOC, 2);
LocationHelper.LockLoc(wcsTask.S_END_LOC, 1);
}
// 更新作业任务状态
wmsTask.N_B_STATE = 1;
WMSHelper.UpdateTaskState(wmsTask);
// 5.作业创建完成后,读取中间表,更新中间表状态
if (mesTask != null)
{
WMSHelper.readLjMesOffItemTask(wmsTask.S_CODE, mesTask.ID);
}
}
}
else
{
WMSHelper.addAlarmRecord("流程异常", "高", $"未查询到容器为:{cntrCode}的容器");
throw new BusinessException($"未查询到容器为:{cntrCode}的容器");
}
}
catch (BusinessException be)
{
throw be;
}
catch (Exception ex)
{
// 报警:WMS内部错误:触发满料工装下线作业错误
WMSHelper.addAlarmRecord("系统错误", "高", ex.Message);
LogHelper.Info($"WMS内部错误:触发满料工装下线作业错误 ; 错误原因:{ex.Message}", "WMS");
result = false;
}
return result;
}
///
/// 叫料请求
/// 1.查询中间表,判断是否是环带物料
/// 2.查询库区物料信息,并过滤故障的堆垛机立库
/// 3.无库存写入中间表异常和异常原因
/// 4.计算出库货位,生成出库任务
///
///
///
public static ResponseResult callMaterialProcess(CallMaterialRequest model)
{
ResponseResult responseResult = new ResponseResult();
var mesTask = WMSHelper.getLjMesTaskByLoc(model.loc);
if (mesTask != null)
{
Location endLoc = LocationHelper.GetLoc(model.loc);
Location startLoc = null;
Location middleLoc = null;
string scheduleType = "";
if (mesTask.PALLET_TYPE == "环带")
{
scheduleType = "HDK";
// 查询环带库该物料库存情况,并比较与中转库的库存进行比较,先入先出
}
else
{
scheduleType = "WCS";
// 查询库区物料信息,根据先入先出原则计算,物料起点
startLoc = WMSHelper.getOutStockStartLoc(null, mesTask.MATERIAL_CODE);
}
if (startLoc == null)
{
// 无库存写入中间表异常和异常原因
mesTask.RETURN_CODE = "6";
mesTask.RECEIVE_MSG = "没有库存或设备故障无法出库";
WMSHelper.updateLjMesTask(mesTask);
WMSHelper.addAlarmRecord("流程异常", "低", $"MES叫料任务{mesTask.ID},没有库存或设备故障无法出库");
responseResult.code = 1;
responseResult.msg = "没有库存或设备故障无法出库";
return responseResult;
}
middleLoc = WMSHelper.GetMinTaskTransfeLoc(startLoc.S_AREA_CODE, 2 , 2);
if (middleLoc == null) {
WMSHelper.addAlarmRecord("流程异常", "高", $"MES叫料任务{mesTask.ID},立库接驳位可能处于锁定或禁用状态,请查看");
responseResult.code = 1;
responseResult.msg = "立库接驳位可能处于锁定或禁用状态";
return responseResult;
}
String cntrCode = "";
var locCntrs = LocationHelper.GetLocCntr(startLoc.S_CODE);
if (locCntrs != null && locCntrs.Count > 0)
{
cntrCode = locCntrs[0].S_CNTR_CODE;
}
var wmsTask = new WMSTask()
{
S_CNTR_CODE = "",
S_CODE = WMSHelper.GenerateTaskNo(),
S_START_LOC = startLoc.S_CODE,
S_START_AREA = startLoc.S_AREA_CODE,
S_END_LOC = endLoc.S_CODE,
S_END_AREA = endLoc.S_AREA_CODE,
S_TYPE = "满料出库任务",
N_PRIORITY = 10,
T_START_TIME = DateTime.Now,
};
if (WMSHelper.CreateWmsTask(wmsTask))
{
// 创建一段入库任务
WCSTask wcsTask = new WCSTask()
{
S_OP_NAME = wmsTask.S_OP_DEF_NAME,
S_OP_CODE = wmsTask.S_CODE,
S_CODE = WCSHelper.GenerateTaskNo(),
S_CNTR_CODE = wmsTask.S_CNTR_CODE,
S_TYPE = wmsTask.S_TYPE,
S_START_LOC = startLoc.S_CODE,
S_START_AREA = startLoc.S_AREA_CODE,
S_END_LOC = middleLoc.S_CODE,
S_END_AREA = middleLoc.S_AREA_CODE,
S_SCHEDULE_TYPE = scheduleType,
N_PRIORITY = wmsTask.N_PRIORITY,
T_START_TIME = DateTime.Now,
};
if (WCSHelper.CreateTask(wcsTask))
{
// 起点、终点加锁
LocationHelper.LockLoc(wcsTask.S_START_LOC, 2);
LocationHelper.LockLoc(wcsTask.S_END_LOC, 1);
LocationHelper.LockLoc(wmsTask.S_END_LOC, 1);
// 更新作业任务状态
wmsTask.N_B_STATE = 1;
WMSHelper.UpdateTaskState(wmsTask);
WMSHelper.updateMesTaskStatus("", "2");
// 任务创建成功读取MES任务
WMSHelper.readLjMesCallItemTask("", mesTask.ID);
}
}
}
else
{
WMSHelper.addAlarmRecord("流程异常", "高", $"MES叫料任务{mesTask.ID},MES中间表没有该线边货位的叫料任务,请查看");
responseResult.code = 1;
responseResult.msg = "MES中间表没有该线边货位的叫料任务";
}
return responseResult;
}
///
/// WCS任务状态回报
/// 任务状态 1:开始/执行中;完成;3:准备取货;4:取货完成;5:准备卸货;6:卸货完成;7:异常取消;8:强制完成
/// 1.根据任务状态回报更新货位状态、任务状态
/// 2.更新任务中间表状态
/// 4.更新出库任务中间表状态
///
///
///
public static ResponseResult taskStatusFeedback(TaskStatusFeedbackModel model)
{
ResponseResult responseResult = new ResponseResult();
WCSTask cst = WCSHelper.GetTask(model.taskNo);
if (cst != null)
{
WMSTask mst = WMSHelper.GetWmsTask(cst.S_OP_CODE);
if (mst != null)
{
switch (model.status)
{
case 1:
WCSHelper.Begin(cst);
WMSHelper.updateMesTaskStatus(mst.S_CODE, "2");
if (cst.S_TYPE.Contains("出库"))
{
WMSHelper.addLotOutTask(mst.S_START_LOC);
}
break;
case 2:
WCSHelper.End(cst);
break;
case 3:
WCSHelper.UpdateStatus(cst, "准备取货");
break;
case 4:
WCSHelper.UpdateStatus(cst, "取货完成");
TaskProcess.OperateStatus(cst, 4);
break;
case 5:
WCSHelper.UpdateStatus(cst, "准备卸货");
break;
case 6:
WCSHelper.UpdateStatus(cst, "卸货完成");
TaskProcess.OperateStatus(cst, 6);
break;
case 7:
WCSHelper.UpdateStatus(cst, "异常取消");
TaskProcess.OperateStatus(cst, 7);
mst.N_B_STATE = 3;
WMSHelper.UpdateTaskState(mst);
WMSHelper.updateMesTaskStatus(mst.S_CODE, "5", "WCS异常取消任务");
WMSHelper.addAlarmRecord("流程异常", "高", $"WCS异常取消任务,任务号:{cst.S_CODE}");
break;
case 8:
WCSHelper.UpdateStatus(cst, "强制完成");
break;
}
// 添加WCS动作记录
WCSHelper.AddActionRecord(model.taskNo, model.status, model.deviceNo, model.loc);
if (model.status == 2 || model.status == 8)
{
if (cst.S_TYPE.Contains("入库"))
{
var cntrItemRels = ContainerHelper.GetCntrItemRel(cst.S_CNTR_CODE);
if (cntrItemRels != null && cntrItemRels.Count > 0)
{
foreach (var cntrItem in cntrItemRels)
{
cntrItem.T_INBOUND_TIME = DateTime.Now;
ContainerHelper.updateCntrItemRel(cntrItem);
}
}
}
if (cst.S_TYPE.Contains("【异常】"))
{
WCSHelper.ActivatePreCreateTask(mst.S_CODE, 1);
}
else
{
WCSHelper.ActivatePreCreateTask(mst.S_CODE);
}
if (WMSHelper.isFinishTask(mst.S_CODE))
{
// 更新作业任务状态
mst.N_B_STATE = 2;
mst.T_END_TIME = DateTime.Now;
WMSHelper.UpdateTaskState(mst);
// 更新任务中间表状态
WMSHelper.updateMesTaskStatus(mst.S_CODE, "3");
if (cst.S_TYPE.Contains("出库"))
{
// 更新出库任务中间表状态
WMSHelper.updateLotOutTask(cst.S_CNTR_CODE, "2");
}
}
}
}
}
return responseResult;
}
///
/// WCS申请终点
///
///
///
public static ResponseResult applyDest(ApplyDestinationModel model) {
ResponseResult result = new ResponseResult();
ApplyDest applyDest = new ApplyDest();
WCSTask cst = WCSHelper.GetTask(model.taskNo);
if (cst != null && cst.N_B_STATE < 3)
{
WMSTask mst = WMSHelper.GetWmsTask(cst.S_OP_CODE);
if (mst != null && mst.N_B_STATE < 2) {
int emptyFlag = 0; // 容器空满标识
Container cntr = ContainerHelper.GetCntr(cst.S_CNTR_CODE);
if (cntr != null && cntr.N_DETAIL_COUNT > 0) {
emptyFlag = 1;
}
// 1:堆垛机放货异常申请新终点
if (model.applyType == 1) {
// 报警:流程异常
WMSHelper.addAlarmRecord("流程异常", "低", $"堆垛机放货异常,异常货位:{cst.S_END_LOC}");
// 1.将异常货位上锁,并报警
LocationHelper.LockLoc(cst.S_END_LOC, 3);
// 2.查询新的入库终点
Location endLoc = WMSHelper.getInStockEndLoc(cst.S_END_AREA, emptyFlag);
cst.S_END_LOC = endLoc.S_CODE;
WCSHelper.UpdateEndLoc(cst);
LocationHelper.LockLoc(endLoc.S_CODE, 1);
applyDest.destLoc = endLoc.S_CODE;
}
else if (model.applyType == 2)
{
if (cst.S_END_LOC == "虚拟库位")
{
var transfeRelevance = WMSHelper.GetTransfeRelevance(model.loc); // 接驳位关联属性
if (transfeRelevance != null)
{
// 1.查询新的入库终点
Location endLoc = WMSHelper.getInStockEndLoc(transfeRelevance.S_RELE_AREA, emptyFlag);
cst.S_END_LOC = endLoc.S_CODE;
WCSHelper.UpdateEndLoc(cst);
LocationHelper.LockLoc(endLoc.S_CODE, 1);
applyDest.destLoc = endLoc.S_CODE;
}
}
}
}
}
result.data = applyDest;
return result;
}
///
/// AGV申请终点
/// 顺序 RFID验证 -> RFID与任务号验证 -> 物料合格状态验证 -> 虚拟终点
/// 申请类型: 1.虚拟终点 2.RFID与任务不匹配 3.物料状态不合格
/// 入库策略:先计算库区的容积率,再计算库区对应的入库站台的任务数,都取最小的
///
/// 1.确定任务是否在执行中
/// 2.判断申请类型
/// 1).虚拟终点,计算入库站台,同时预先生成入库站台-立库终点的搬运任务
/// 2).RFID验证失败,记录异常,并计算异常区的空货位
/// 3).RFID与任务不匹配,记录异常并报警,并计算异常区的空货位
/// 4).物料状态不合格,记录异常,计算入库站台,同时预先生成入库站台-立库终点的搬运任务 ;最后重新生成新的出库任务
///
/// 3. 2)\3) 异常区没有空货位,计算入库站台,同时预先生成入库站台-立库终点的搬运任务
///
/// 4.余料/空工装回库任务
/// 1).根据RFID查询中间表,判断物料类型,如为空工装,正常入库(计算入库站台,生成预创建搬运任务)
/// 2).如是余料,查询是否有余料有关的叫料任务,且未执行,则取消叫料任务,修改终点为该叫料终点
/// 3).如没有相关叫料任务,则正常入库
///
/// 5.空工装出库和成型机叫料任务,当申请类型为2,3,4是,需要重新生成任务
///
///
///
///
/// 1.正常 2.异常
///
public static string AGVApplyDest(string taskNo ,string loc ,string trayCode,string applyType)
{
LogHelper.Info($"AGV申请终点,任务号:{taskNo},当前位置:{loc},申请类型:{applyType}", "HosttoagvTask");
string applyDest = null;
try
{
WCSTask cst = WCSHelper.GetTask(taskNo);
if (cst != null && cst.N_B_STATE < 3)
{
WMSTask mst = WMSHelper.GetWmsTask(cst.S_OP_CODE);
if (mst != null && mst.N_B_STATE < 2)
{
// 防止重复申请
if ((applyType != "1" && !cst.S_TYPE.Contains("【异常】")) || (applyType == "1" && cst.S_END_LOC.Contains("虚拟货位")))
{
// 斜裁立库
if (mst.S_OP_DEF_NAME.Contains("斜裁"))
{
applyDest = applyAgvDestXC(applyType, mst, cst);
}
else
{
applyDest = applyAgvDest(applyType, loc, mst, cst);
}
}
}
}
}
catch (Exception ex)
{
WMSHelper.addAlarmRecord("系统错误","高", $"AGV申请终点,WMS内部错误,错误原因:{ex.Message}", "AGV");
}
return null;
}
///
/// 斜裁立库任务,AGV申请终点
/// 1).根据RFID查询中间表,判断物料类型,如为空工装,正常入库(计算入库站台,生成预创建搬运任务)
/// 2).如是余料,查询是否有余料有关的叫料任务,且未执行,则取消叫料任务,修改终点为该叫料终点
///
///
///
///
///
public static string applyAgvDestXC(string applyType, WMSTask mst, WCSTask cst)
{
string destLoc = null;
Location agvEndLoc = null;
Location wmsEndLoc = null;
if (applyType == "1")
{
if (mst.S_TYPE == "余料/空工装入库")
{
var mesTask = WMSHelper.GetLjMesTaskById(int.Parse(mst.S_OP_DEF_CODE));
if (mesTask.QTY != 0)
{
var awaitTask = WMSHelper.GetAwaitWmsTaskByMaterialCode(mesTask.MATERIAL_CODE);
if (awaitTask != null)
{
// 取消任务
ApiHelper.cancelTask(awaitTask.S_CODE);
// 修改终点
agvEndLoc = LocationHelper.GetLoc(awaitTask.S_END_LOC);
wmsEndLoc = agvEndLoc;
mst.S_TYPE = "叫料出库任务";
}
}
}
}
if (agvEndLoc == null)
{
string msg = "";
if (applyType == "2" || applyType == "3" || applyType == "4")
{
cst.S_TYPE = cst.S_TYPE + "【异常】";
msg = "工装异常";
}
// TODO 反馈斜裁立库异常,请求斜裁入库终点
agvEndLoc = null;
}
if (agvEndLoc != null)
{
destLoc = agvEndLoc.S_CODE;
cst.S_END_LOC = agvEndLoc.S_CODE;
cst.S_END_AREA = agvEndLoc.S_AREA_CODE;
WCSHelper.UpdateEndLoc(cst);
}
if (wmsEndLoc != null)
{
mst.S_END_LOC = wmsEndLoc.S_CODE;
mst.S_END_AREA = wmsEndLoc.S_AREA_CODE;
WMSHelper.UpdateTaskEnd(mst);
}
return destLoc;
}
///
/// AGV申请终点
///
/// 1.正常 2.RFID与任务RFID不匹配 3.物料状态不合格
///
///
///
///
public static string applyAgvDest(string applyType,string loc, WMSTask mst, WCSTask cst)
{
LogHelper.Info($"开始申请AGV终点", "AGV");
string destLoc = null;
Location agvEndLoc = null;
Location wmsEndLoc = null;
Location currentLoc = LocationHelper.GetLoc(loc);
// RFID 检测正常
if (applyType == "1")
{
// 场景:1.余料/空工装入库任务
// 1).根据RFID查询中间表,判断物料类型,如为空工装,正常入库(计算入库站台,生成预创建搬运任务)
// 2).如是余料,查询是否有余料有关的叫料任务,且未执行,则取消叫料任务,修改终点为该叫料终点
if (cst.S_TYPE.Contains("余料/空工装入库"))
{
LogHelper.Info($"余料/空工装入库任务,判断是否回库或发往叫料点", "AGV");
var mesTask = WMSHelper.GetLjMesTaskById(int.Parse(mst.S_OP_DEF_CODE));
if (mesTask.QTY != 0)
{
var awaitTask = WMSHelper.GetAwaitWmsTaskByMaterialCode(mesTask.MATERIAL_CODE);
if (awaitTask != null)
{
LogHelper.Info($"余料/空工装入库任务,存在等待的叫料任务,发往叫料点", "AGV");
// 取消任务
ApiHelper.cancelTask(awaitTask.S_CODE);
// 修改终点
agvEndLoc = LocationHelper.GetLoc(awaitTask.S_END_LOC);
cst.S_TYPE = "叫料出库任务";
mst.S_TYPE = mst.S_TYPE + "【叫料】";
}
}
}
// 场景:1.满料/空工装入库 2.余料/空工装入库
if (agvEndLoc == null && cst.S_TYPE.Contains("入库"))
{
LogHelper.Info($"如没有满足条件的agv终点货位,则发往立库", "AGV");
Container container = ContainerHelper.GetCntr(cst.S_CNTR_CODE);
if (container != null)
{
wmsEndLoc = WMSHelper.getInStockEndLoc(null, container.N_DETAIL_COUNT == 0 ? 0 : 1, container.N_TYPE);
if (wmsEndLoc != null)
{
agvEndLoc = WMSHelper.GetMinTaskTransfeLoc(wmsEndLoc.S_AREA_CODE, 1, 2); // 1.立库接驳位 1.入库 2.非直连
if (agvEndLoc != null)
{
LogHelper.Info($"创建立库站台到立库的预创建任务,agv终点货位:{agvEndLoc.S_CODE},立库终点货位:{wmsEndLoc.S_CODE}", "AGV");
// 预先生成入库站台-立库终点的搬运任务
WCSTask wcsTask = new WCSTask()
{
S_OP_NAME = mst.S_OP_DEF_NAME,
S_OP_CODE = mst.S_CODE,
S_CODE = WCSHelper.GenerateTaskNo(),
S_CNTR_CODE = cst.S_CNTR_CODE,
S_TYPE = mst.S_TYPE,
S_START_LOC = agvEndLoc.S_CODE,
S_START_AREA = agvEndLoc.S_AREA_CODE,
S_END_LOC = wmsEndLoc.S_CODE,
S_END_AREA = wmsEndLoc.S_AREA_CODE,
S_SCHEDULE_TYPE = "WCS",
N_PRIORITY = 10,
N_B_STATE = -1,
T_START_TIME = DateTime.Now,
};
if (WCSHelper.CreateTask(wcsTask))
{
// 起点、终点加锁
LocationHelper.LockLoc(wcsTask.S_START_LOC, 1);
LocationHelper.LockLoc(wcsTask.S_END_LOC, 1);
}
}
else
{
WMSHelper.addAlarmRecord("流程异常", "高", $"AGV申请终点失败,未查询到立库接驳位");
return null;
}
}
else
{
WMSHelper.addAlarmRecord("流程异常", "高", $"AGV申请终点失败,未查询到空余立库货位");
return null;
}
}
else
{
WMSHelper.addAlarmRecord("流程异常", "高", $"AGV申请终点失败,未查询到容器编码:{cst.S_CNTR_CODE}的容器");
return null;
}
}
}
// 场景:1.满料/空工装出库异常 2.满料/空工装入库异常(空工装出库异常 、满料入库异常)
if (applyType == "2" )
{
WCSHelper.CancelPreCreateTask(mst.S_CODE);
mst.S_TYPE = mst.S_TYPE + "【异常】";
// 1.异常工装优先发往异常区
LogHelper.Info($"异常工装优先发往异常区", "AGV");
agvEndLoc = WMSHelper.getAbnormalAreaLoc(currentLoc.S_AREA_CODE);
if (agvEndLoc != null)
{
wmsEndLoc = agvEndLoc;
}
else
{
LogHelper.Info($"异常区没有空货位,发往立库", "AGV");
}
// 2.异常区没有空货位,则发往立库
if (agvEndLoc == null)
{
LogHelper.Info($"如没有满足条件的agv终点货位,则发往立库", "AGV");
Container container = ContainerHelper.GetCntr(cst.S_CNTR_CODE);
if (container != null)
{
wmsEndLoc = WMSHelper.getInStockEndLoc(null, container.N_DETAIL_COUNT == 0 ? 0 : 1, container.N_TYPE);
if (wmsEndLoc != null)
{
agvEndLoc = WMSHelper.GetMinTaskTransfeLoc(wmsEndLoc.S_AREA_CODE, 1, 2); // 1.立库接驳位 1.入库 2.非直连
if (agvEndLoc != null)
{
LogHelper.Info($"创建立库站台到立库的预创建任务,agv终点货位:{agvEndLoc.S_CODE},立库终点货位:{wmsEndLoc.S_CODE}", "AGV");
// 预先生成入库站台-立库终点的搬运任务
WCSTask wcsTask = new WCSTask()
{
S_OP_NAME = mst.S_OP_DEF_NAME,
S_OP_CODE = mst.S_CODE,
S_CODE = WCSHelper.GenerateTaskNo(),
S_CNTR_CODE = cst.S_CNTR_CODE,
S_TYPE = cst.S_TYPE + "【异常】",
S_START_LOC = agvEndLoc.S_CODE,
S_START_AREA = agvEndLoc.S_AREA_CODE,
S_END_LOC = wmsEndLoc.S_CODE,
S_END_AREA = wmsEndLoc.S_AREA_CODE,
S_SCHEDULE_TYPE = "WCS",
N_PRIORITY = 10,
N_B_STATE = -1,
T_START_TIME = DateTime.Now,
};
if (WCSHelper.CreateTask(wcsTask))
{
// 起点、终点加锁
LocationHelper.LockLoc(wcsTask.S_START_LOC, 1);
LocationHelper.LockLoc(wcsTask.S_END_LOC, 1);
cst.S_TYPE = cst.S_TYPE + "【异常】";
}
}
else
{
WMSHelper.addAlarmRecord("流程异常", "高", $"AGV申请终点失败,未查询到立库接驳位");
return null;
}
}
else
{
WMSHelper.addAlarmRecord("流程异常", "高", $"AGV申请终点失败,未查询到空余立库货位");
return null;
}
}
else
{
WMSHelper.addAlarmRecord("流程异常", "高", $"AGV申请终点失败,未查询到容器编码:{cst.S_CNTR_CODE}的容器");
return null;
}
}
}
// 重新发起新任务
if (applyType != "1")
{
var mesTask = WMSHelper.GetLjMesTaskByAgvorderId(mst.S_CODE);
if (mesTask != null)
{
if (mst.S_TYPE.Contains("叫料出库任务"))
{
LogHelper.Info($"叫料出库任务异常,再次发起叫料出库任务", "AGV");
callMaterial(mesTask.MATERIAL_CODE, mesTask.POSITION_ID, mesTask.ID);
/*againCallMaterial(mst, mesTask.MATERIAL_CODE, mesTask.POSITION_ID, mesTask.ID);*/
}
// 满料下线(非直连)
if (mst.S_TYPE.Contains("满料/异常工装入库任务") && cst.S_TYPE.Contains("空工装出库任务"))
{
LogHelper.Info($"满料/异常工装入库任务异常,再次发起满料/异常工装入库任务", "AGV");
var logicConfig = WMSHelper.getLogicConfigByJtCode(mesTask.EQP);
if (logicConfig != null)
{
triggerItemOffLineFlow4(mesTask.POSITION_ID, logicConfig, mesTask);
}
else
{
WMSHelper.addAlarmRecord("流程异常", "高", $"MES任务{mesTask.ID},机台号:{mesTask.EQP},未查询到逻辑线路", "AGV");
}
}
}
}
if (agvEndLoc != null && wmsEndLoc != null)
{
destLoc = agvEndLoc.S_CODE;
cst.S_END_LOC = agvEndLoc.S_CODE;
cst.S_END_AREA = agvEndLoc.S_AREA_CODE;
WCSHelper.UpdateEndLoc(cst);
mst.S_END_LOC = wmsEndLoc.S_CODE;
mst.S_END_AREA = wmsEndLoc.S_AREA_CODE;
WMSHelper.UpdateTaskEnd(mst);
}
return destLoc;
}
///
/// 成新机叫料
///
///
///
///
public static void callMaterial(string materialCode, string endLocCode, int mesTaskId)
{
var oldWmsTask = WMSHelper.GetWmsTaskByEnd(endLocCode);
if (oldWmsTask == null) {
string cntrCode = "";
Location endLoc = LocationHelper.GetLoc(endLocCode);
if (endLoc != null)
{
Location middleLoc = null;
Location startLoc = WMSHelper.getOutStockStartLoc(null, materialCode);
if (startLoc == null)
{
var mesTask = WMSHelper.GetLjMesTaskById(mesTaskId);
if (mesTask != null)
{
mesTask.RECEIVE_MSG = "没有库存";
WMSHelper.updateLjMesTask(mesTask);
}
WMSHelper.addAlarmRecord("流程异常", "高", $"叫料失败,物料:{materialCode}没有库存");
return;
}
else
{
var locCntrRels = LocationHelper.GetLocCntr(startLoc.S_CODE);
if (locCntrRels.Count > 0)
{
cntrCode = locCntrRels[0].S_CNTR_CODE;
}
else
{
WMSHelper.addAlarmRecord("流程异常", "高", $"查询物料异常,货位:{startLoc.S_CODE}缺少容器信息");
return;
}
}
middleLoc = WMSHelper.GetTransfeRelevanceLoc(startLoc.S_AREA_CODE, 1 , 2);
if (middleLoc != null)
{
// 1.创建成新机叫料作业
var wmsTask = new WMSTask()
{
S_CNTR_CODE = cntrCode,
S_CODE = WMSHelper.GenerateTaskNo(),
S_START_LOC = startLoc.S_CODE,
S_START_AREA = startLoc.S_AREA_CODE,
S_END_LOC = endLoc.S_CODE,
S_END_AREA = endLoc.S_AREA_CODE,
S_TYPE = "叫料出库任务",
S_OP_DEF_CODE = mesTaskId.ToString(),
S_OP_DEF_NAME = "成型机叫料出库任务",
T_START_TIME = DateTime.Now,
};
if (WMSHelper.CreateWmsTask(wmsTask))
{
WCSTask wcsTask = new WCSTask()
{
S_OP_NAME = wmsTask.S_OP_DEF_NAME,
S_OP_CODE = wmsTask.S_CODE,
S_CODE = WCSHelper.GenerateTaskNo(),
S_CNTR_CODE = wmsTask.S_CNTR_CODE,
S_TYPE = wmsTask.S_TYPE + "-WCS",
S_START_LOC = startLoc.S_CODE,
S_START_AREA = startLoc.S_AREA_CODE,
S_END_LOC = middleLoc.S_CODE,
S_END_AREA = middleLoc.S_AREA_CODE,
S_SCHEDULE_TYPE = "WCS",
N_PRIORITY = 10,
T_START_TIME = DateTime.Now,
};
if (WCSHelper.CreateTask(wcsTask))
{
// 起点、终点加锁
LocationHelper.LockLoc(wcsTask.S_START_LOC, 2);
LocationHelper.LockLoc(wcsTask.S_END_LOC, 1);
// 更新作业任务状态
wmsTask.N_B_STATE = 1;
WMSHelper.UpdateTaskState(wmsTask);
}
// 预创建二段任务
WCSTask twoWcsTask = new WCSTask()
{
S_OP_NAME = wmsTask.S_OP_DEF_NAME,
S_OP_CODE = wmsTask.S_CODE,
S_CODE = WCSHelper.GenerateTaskNo(),
S_CNTR_CODE = wmsTask.S_CNTR_CODE,
S_TYPE = wmsTask.S_TYPE,
S_START_LOC = middleLoc.S_CODE,
S_START_AREA = middleLoc.S_AREA_CODE,
S_END_LOC = endLoc.S_CODE,
S_END_AREA = endLoc.S_AREA_CODE,
S_SCHEDULE_TYPE = "AGV",
N_PRIORITY = 10,
T_START_TIME = DateTime.Now,
N_B_STATE = -1
};
WCSHelper.CreateTask(twoWcsTask);
WMSHelper.readLjMesCallItemTask(wmsTask.S_CODE, mesTaskId);
}
}
else
{
WMSHelper.addAlarmRecord("流程异常", "高", $"库区{startLoc.S_AREA_CODE}未查询到可用的接驳位");
}
}
}
}
///
/// 成新机叫料(环带库)
/// 1.查询环带库物料库存
/// 2.查询中转库库存,根据入库时间 进行先入先出
/// 3.如果为环带库物料,则将mes任务写入环带库任务中间表
///
///
///
///
public static void callMaterialHDK(string materialCode, string endLocCode, int mesTaskId)
{
// 1.查询环带库物料库存
// 2.查询中转库库存,根据入库时间 进行先入先出
// 3.将MES任务写入环带库任务中间表
WMSHelper.addLjXcTask(mesTaskId);
}
///
/// 余料/空托回库
///
/// 1.查询成型机叫料终点对应的 余料/空托返回位
/// 2.查询mes任务中间表是否存在返料任务
/// 3.创建余料回库作业,创建agv搬运任务,虚拟终点
///
/// 成型机叫料终点
public static void returnMaterialOrEmptyTray(string locCode)
{
if (locCode != null)
{
// 2.查询mes任务中间表
var mesTask = WMSHelper.getLjMesTaskByLoc(locCode);
if (mesTask != null)
{
createReturnTask(locCode, mesTask);
}
}
}
///
/// 创建余料/空工装返回任务
///
///
///
public static void createReturnTask(string locCode ,LjMesTask mesTask) {
Location startLoc = LocationHelper.GetLoc(locCode);
Location endLoc = new Location() { S_CODE = "虚拟货位", S_AREA_CODE = "虚拟库区" };
string suffix = "";
if (mesTask.PALLET_TYPE == "5" || mesTask.PALLET_TYPE == "6") {
suffix = "(斜裁)";
}
var wmsTask = new WMSTask()
{
S_CNTR_CODE = mesTask.PALLET_ID,
S_CODE = WMSHelper.GenerateTaskNo(),
S_START_LOC = startLoc.S_CODE,
S_START_AREA = startLoc.S_AREA_CODE,
S_END_LOC = endLoc.S_CODE,
S_END_AREA = endLoc.S_AREA_CODE,
S_TYPE = "余料/空工装入库任务" + suffix,
S_OP_DEF_CODE = mesTask.ID.ToString(),
S_OP_DEF_NAME = "余料/空工装入库" + suffix,
T_START_TIME = DateTime.Now
};
if (WMSHelper.CreateWmsTask(wmsTask))
{
// 创建一段入库任务
WCSTask wcsTask = new WCSTask()
{
S_OP_NAME = wmsTask.S_OP_DEF_NAME,
S_OP_CODE = wmsTask.S_CODE,
S_CODE = WCSHelper.GenerateTaskNo(),
S_CNTR_CODE = wmsTask.S_CNTR_CODE,
S_TYPE = wmsTask.S_TYPE,
S_START_LOC = startLoc.S_CODE,
S_START_AREA = startLoc.S_AREA_CODE,
S_END_LOC = endLoc.S_CODE,
S_END_AREA = endLoc.S_AREA_CODE,
S_SCHEDULE_TYPE = "AGV",
N_PRIORITY = 99,
T_START_TIME = DateTime.Now,
};
if (WCSHelper.CreateTask(wcsTask))
{
// 起点、接驳点、终点加锁
LocationHelper.LockLoc(wcsTask.S_START_LOC, 2);
LocationHelper.LockLoc(wcsTask.S_END_LOC, 1);
// 更新作业任务状态
wmsTask.N_B_STATE = 1;
WMSHelper.UpdateTaskState(wmsTask);
WMSHelper.readLjMesOffItemTask(wmsTask.S_CODE, mesTask.ID);
}
}
}
///
/// 不合格品回库
/// 1.创建回库任务
/// 2.重新发起新的叫料任务
///
///
///
///
public static bool rejectReturnStock(WMSTask mst, WCSTask cst)
{
bool result = true;
Location startLoc = LocationHelper.GetLoc(cst.S_END_LOC);
Location agvEndLoc = null;
Location wmsEndLoc = null;
// 斜裁立库
if (mst.S_OP_DEF_NAME.Contains("斜裁"))
{
// TODO 反馈斜裁立库异常,请求斜裁入库终点
agvEndLoc = null;
wmsEndLoc = agvEndLoc;
if (agvEndLoc != null)
{
// 预先生成入库站台-立库终点的搬运任务
WCSTask wcsTask = new WCSTask()
{
S_OP_NAME = mst.S_OP_DEF_NAME,
S_OP_CODE = mst.S_CODE,
S_CODE = WCSHelper.GenerateTaskNo(),
S_CNTR_CODE = cst.S_CNTR_CODE,
S_TYPE = "不合格品回库",
S_START_LOC = startLoc.S_CODE,
S_START_AREA = startLoc.S_AREA_CODE,
S_END_LOC = agvEndLoc.S_CODE,
S_END_AREA = agvEndLoc.S_AREA_CODE,
S_SCHEDULE_TYPE = "AGV",
N_PRIORITY = 10,
T_START_TIME = DateTime.Now,
};
if (WCSHelper.CreateTask(wcsTask))
{
// 起点、接驳点、终点加锁
LocationHelper.LockLoc(wcsTask.S_START_LOC, 1);
LocationHelper.LockLoc(wcsTask.S_END_LOC, 1);
}
}
}
else
{
Container container = ContainerHelper.GetCntr(cst.S_CNTR_CODE);
wmsEndLoc = WMSHelper.getInStockEndLoc(null, container.N_DETAIL_COUNT == 0 ? 0 : 1, container.N_TYPE);
if (wmsEndLoc != null)
{
agvEndLoc = WMSHelper.GetMinTaskTransfeLoc(wmsEndLoc.S_AREA_CODE, 1, 2); // 1.立库接驳位 1.入库 2.非直连
if (agvEndLoc != null)
{
// 预先生成入库站台-立库终点的搬运任务
WCSTask oneWcsTask = new WCSTask()
{
S_OP_NAME = mst.S_OP_DEF_NAME,
S_OP_CODE = mst.S_CODE,
S_CODE = WCSHelper.GenerateTaskNo(),
S_CNTR_CODE = cst.S_CNTR_CODE,
S_TYPE = "不合格品回库",
S_START_LOC = startLoc.S_CODE,
S_START_AREA = startLoc.S_AREA_CODE,
S_END_LOC = agvEndLoc.S_CODE,
S_END_AREA = agvEndLoc.S_AREA_CODE,
S_SCHEDULE_TYPE = "AGV",
N_PRIORITY = 10,
T_START_TIME = DateTime.Now,
};
if (WCSHelper.CreateTask(oneWcsTask))
{
// 起点、接驳点、终点加锁
LocationHelper.LockLoc(oneWcsTask.S_START_LOC, 1);
LocationHelper.LockLoc(oneWcsTask.S_END_LOC, 1);
}
// 预先生成入库站台-立库终点的搬运任务
WCSTask twoWcsTask = new WCSTask()
{
S_OP_NAME = mst.S_OP_DEF_NAME,
S_OP_CODE = mst.S_CODE,
S_CODE = WCSHelper.GenerateTaskNo(),
S_CNTR_CODE = cst.S_CNTR_CODE,
S_TYPE = "不合格品回库",
S_START_LOC = agvEndLoc.S_CODE,
S_START_AREA = agvEndLoc.S_AREA_CODE,
S_END_LOC = wmsEndLoc.S_CODE,
S_END_AREA = wmsEndLoc.S_AREA_CODE,
S_SCHEDULE_TYPE = "WCS",
N_PRIORITY = 10,
N_B_STATE = -1,
T_START_TIME = DateTime.Now,
};
if (WCSHelper.CreateTask(twoWcsTask))
{
// 起点、接驳点、终点加锁
LocationHelper.LockLoc(twoWcsTask.S_START_LOC, 1);
LocationHelper.LockLoc(twoWcsTask.S_END_LOC, 1);
}
}
}
if (cst.S_TYPE == "叫料出库任务")
{
var mesTask = WMSHelper.GetLjMesTaskByAgvorderId(mst.S_CODE);
callMaterial( mesTask.MATERIAL_CODE, mesTask.POSITION_ID, mesTask.ID);
}
}
return result;
}
///
/// 查询容器物料信息(中间表)
///
///
///
public static ResponseResult findTrayItemInfo(FindTrayItemInfoModel model) {
ResponseResult responseResult = new ResponseResult();
var cntrItemRels = ContainerHelper.GetCntrItemRel(model.cntrNo);
if (cntrItemRels != null && cntrItemRels.Count > 0) {
TrayItemInfo trayItemInfo = new TrayItemInfo()
{
S_SERIAL_NO = cntrItemRels[0].S_SERIAL_NO,
S_ITEM_CODE = cntrItemRels[0].S_ITEM_CODE,
S_ITEM_NAME = cntrItemRels[0].S_ITEM_NAME,
S_ITEM_SPEC = cntrItemRels[0].S_ITEM_SPEC,
S_ITEM_STATE = cntrItemRels[0].S_ITEM_STATE,
N_ITEM_STATE = cntrItemRels[0].N_ITEM_STATE,
S_BATCH_NO = cntrItemRels[0].S_BATCH_NO,
F_QTY = cntrItemRels[0].F_QTY,
S_UOM = cntrItemRels[0].S_UOM,
S_CNTR_CODE = cntrItemRels[0].S_CNTR_CODE,
D_PRD_DATE = cntrItemRels[0].D_PRD_DATE,
D_EXP_DATE = cntrItemRels[0].D_EXP_DATE,
D_EXP_DATE1 = cntrItemRels[0].D_EXP_DATE1,
};
responseResult.data = trayItemInfo;
}
return responseResult;
}
///
/// 设备报警反馈
///
///
///
public static ResponseResult notifyAlarm(DeviceAlertorFeedbackModel model) {
ResponseResult responseResult = new ResponseResult();
WMSHelper.addAlarmRecord("设备故障", "高", $"设备号{model.deviceNo},错误信息:"+model.errMsg);
return responseResult;
}
///
/// 人工手动入库
/// 2.根据容器号查询入库任务
/// 3.如果没有入库任务,记录异常
/// 4.进行入库
///
///
///
public static ResponseResult manualStorage(ManualStorageModel model)
{
ResponseResult responseResult = new ResponseResult();
// 查询中间表
var ljMesTask = WMSHelper.getLjMesTaskByCntr( model.cntrNo);
if (ljMesTask == null)
{
responseResult.code = 1;
responseResult.msg = "未查询到MES下发的入库任务";
return responseResult;
}
string taskType = "";
if (ljMesTask.QTY == 0)
{
taskType = "空工装人工入库";
}
else {
taskType = "满料工装人工入库";
}
var startLoc = LocationHelper.GetLoc(model.from);
var transfeRele = WMSHelper.GetTransfeRelevance(model.from); // 接驳位属性
if (transfeRele != null)
{
var endLoc = WMSHelper.getInStockEndLoc(transfeRele.S_RELE_AREA, ljMesTask.QTY);
if (startLoc == null)
{
responseResult.code = 1;
responseResult.msg = "接驳位不存在,请检查起点货位编码是否有误";
return responseResult;
}
if (endLoc == null)
{
responseResult.code = 1;
responseResult.msg = "立库空余库位不足";
return responseResult;
}
var wmsTask = new WMSTask()
{
S_CNTR_CODE = model.cntrNo,
S_CODE = WMSHelper.GenerateTaskNo(),
S_START_LOC = startLoc.S_CODE,
S_START_AREA = startLoc.S_AREA_CODE,
S_END_LOC = endLoc.S_CODE,
S_END_AREA = endLoc.S_AREA_CODE,
S_TYPE = taskType,
S_OP_DEF_CODE = ljMesTask.ID.ToString(),
S_OP_DEF_NAME = "人工入库任务",
N_PRIORITY = 1,
T_START_TIME = DateTime.Now
};
if (WMSHelper.CreateWmsTask(wmsTask))
{
// 创建一段入库任务
WCSTask wcsTask = new WCSTask()
{
S_OP_NAME = wmsTask.S_OP_DEF_NAME,
S_OP_CODE = wmsTask.S_CODE,
S_CODE = WCSHelper.GenerateTaskNo(),
S_CNTR_CODE = wmsTask.S_CNTR_CODE,
S_TYPE = wmsTask.S_TYPE + "-WCS",
S_START_LOC = startLoc.S_CODE,
S_START_AREA = startLoc.S_AREA_CODE,
S_END_LOC = endLoc.S_CODE,
S_END_AREA = endLoc.S_AREA_CODE,
S_SCHEDULE_TYPE = "WCS",
N_PRIORITY = wmsTask.N_PRIORITY,
T_START_TIME = DateTime.Now,
};
if (WCSHelper.CreateTask(wcsTask))
{
// 起点、接驳点、终点加锁
LocationHelper.LockLoc(wcsTask.S_START_LOC, 2);
LocationHelper.LockLoc(wcsTask.S_END_LOC, 1);
// 更新作业任务状态
wmsTask.N_B_STATE = 1;
WMSHelper.UpdateTaskState(wmsTask);
WMSHelper.readLjMesOffItemTask(wmsTask.S_CODE ,ljMesTask.ID);
}
}
}
else
{
WMSHelper.addAlarmRecord("流程异常", "中", $"接驳位:{model.from},缺少属性配置项,请联系管理进行配置");
responseResult.code = 1;
responseResult.msg = $"接驳位缺少属性配置项,请联系管理进行配置";
}
return responseResult;
}
///
/// 人工出库
///
///
///
public static ResponseResult manualDelivery(ManualDeliveryModel model) {
ResponseResult responseResult = new ResponseResult();
// 查询中间表
var ljMesTask = WMSHelper.getLjMesTaskByLoc(model.to);
if (ljMesTask == null)
{
responseResult.code = 1;
responseResult.msg = "未查询到MES任务表数据";
return responseResult;
}
string taskType = "";
if (ljMesTask.QTY == 0)
{
taskType = "空工装人工出库";
}
else
{
taskType = "满料工装人工出库";
}
var endLoc = LocationHelper.GetLoc(model.to);
var transfeRele = WMSHelper.GetTransfeRelevance(model.to); // 接驳位属性
if (transfeRele != null)
{
var startLoc = WMSHelper.getOutStockStartLoc(transfeRele.S_RELE_AREA, model.materialCode,model.trayStatus, model.cntrNo);
if (endLoc == null)
{
responseResult.code = 1;
responseResult.msg = "接驳位不存在,请检查起点货位编码是否有误";
return responseResult;
}
if (startLoc == null)
{
responseResult.code = 1;
responseResult.msg = "立库库存不足";
return responseResult;
}
var wmsTask = new WMSTask()
{
S_CNTR_CODE = model.cntrNo,
S_CODE = WMSHelper.GenerateTaskNo(),
S_START_LOC = startLoc.S_CODE,
S_START_AREA = startLoc.S_AREA_CODE,
S_END_LOC = endLoc.S_CODE,
S_END_AREA = endLoc.S_AREA_CODE,
S_TYPE = taskType,
S_OP_DEF_NAME = "人工出库任务",
N_PRIORITY = 1,
T_START_TIME = DateTime.Now
};
if (WMSHelper.CreateWmsTask(wmsTask))
{
// 创建一段入库任务
WCSTask wcsTask = new WCSTask()
{
S_OP_NAME = wmsTask.S_OP_DEF_NAME,
S_OP_CODE = wmsTask.S_CODE,
S_CODE = WCSHelper.GenerateTaskNo(),
S_CNTR_CODE = wmsTask.S_CNTR_CODE,
S_TYPE = wmsTask.S_TYPE + "-WCS",
S_START_LOC = startLoc.S_CODE,
S_START_AREA = startLoc.S_AREA_CODE,
S_END_LOC = endLoc.S_CODE,
S_END_AREA = endLoc.S_AREA_CODE,
S_SCHEDULE_TYPE = "WCS",
N_PRIORITY = wmsTask.N_PRIORITY,
T_START_TIME = DateTime.Now,
};
if (WCSHelper.CreateTask(wcsTask))
{
// 起点、接驳点、终点加锁
LocationHelper.LockLoc(wcsTask.S_START_LOC, 2);
LocationHelper.LockLoc(wcsTask.S_END_LOC, 1);
// 更新作业任务状态
wmsTask.N_B_STATE = 1;
WMSHelper.UpdateTaskState(wmsTask);
WMSHelper.readLjMesOffItemTask(wmsTask.S_CODE, ljMesTask.ID);
}
}
}
else {
WMSHelper.addAlarmRecord("流程异常", "中", $"接驳位:{model.to},缺少属性配置项,请联系管理进行配置");
responseResult.code = 1;
responseResult.msg = $"接驳位缺少属性配置项,请联系管理进行配置";
}
return responseResult;
}
///
/// 取消任务
///
///
public static ResponseResult cancelTask(string taskNo) {
ResponseResult responseResult = new ResponseResult();
WMSTask wmsTask = WMSHelper.GetWmsTask(taskNo);
if (wmsTask != null && wmsTask.N_B_STATE == 0)
{
var wcsTaskList = WCSHelper.GetTaskListBySrcNo(wmsTask.S_CODE);
foreach (var wcsTask in wcsTaskList)
{
if (wcsTask != null && wcsTask.N_B_STATE < 3)
{
WCSHelper.Fail(wcsTask);
LocationHelper.UnLockLoc(wcsTask.S_START_LOC);
LocationHelper.UnLockLoc(wcsTask.S_END_LOC);
}
}
wmsTask.N_B_STATE = 3;
wmsTask.S_B_STATE = "取消";
wmsTask.T_END_TIME = DateTime.Now;
WMSHelper.UpdateTaskState(wmsTask);
}
return responseResult;
}
///
/// 切换站台属性
///
///
///
public static ResponseResult switchStationAttribute(SwitchStationAttributeModel model)
{
ResponseResult responseResult = new ResponseResult();
var task = WCSHelper.GetTaskByStartOrEnd(model.locCode);
if (task == null)
{
var transfeRelevance = WMSHelper.GetTransfeRelevance(model.locCode); // 接驳位属性
LogHelper.Info($"原站台属性:{JsonConvert.SerializeObject(transfeRelevance)}", "WMS");
if (transfeRelevance != null && transfeRelevance.N_PROPERTY == 2)
{
if (model.signalType == "1")
{
WMSHelper.updateTransfeLocProperty(model.locCode, 0);
}
if (model.signalType == "2")
{
WMSHelper.updateTransfeLocProperty(model.locCode, 1);
}
}
}
else
{
responseResult.code = 1;
responseResult.msg = "接驳位存在未完成的任务,无法切换站台属性";
}
return responseResult;
}
///
/// 货位状态反馈
///
///
///
public static bool locStateFeedBack(LocStateFeedBackModel model)
{
bool result = false;
if (model.type == "1")
{
var task = WCSHelper.GetTask(model.req_no);
if (task != null)
{
TaskAction taskAction = null;
if (model.type == "1")
{
taskAction = WCSHelper.getActionRecord(task.S_CODE, 1101);
}
if (model.type == "2")
{
taskAction = WCSHelper.getActionRecord(task.S_CODE, 1102);
}
if (taskAction != null)
{
taskAction.N_S_STATUS = 1;
result = WCSHelper.updateActionRecord(taskAction);
}
}
}
return result;
}
//----------------------------------------------------------------------------------------------------------------------------
public class LocModel
{
public string locCode { get; set; }
}
public class ApplyDest {
public string destLoc { get; set; } // 终点货位编码
}
public class TrayItemInfo
{
public string S_SERIAL_NO { get; set; } // 原材料批次号
public string S_ITEM_CODE { get; set; } // 物料编码
public string S_ITEM_NAME { get; set; } // 物料编码
public string S_ITEM_SPEC { get; set; } // 规格
public string S_ITEM_STATE { get; set; } = "0"; // 检验状态 0:未检验 1:合格,2:不合格
///
/// 1:合格 2:不合格
///
public int N_ITEM_STATE { get; set; } // 物料状态
public string S_BATCH_NO { get; set; } // 批次条码
public float F_QTY { get; set; } // 数量
public string S_UOM { get; set; } = ""; // 单位
public string S_CNTR_CODE { get; set; } // 容器
public string D_PRD_DATE { get; set; } // 生产日期
public string D_EXP_DATE { get; set; } // 最小停放日期
public string D_EXP_DATE1 { get; set; } // 最大停放日期
}
///
/// 人工出库模型
///
public class ManualDeliveryModel {
public string to { get; set; } // 接驳货位编码
public string cntrNo { get; set; } // 容器号
public int trayStatus { get; set; } // 托盘状态 0.正常 1.异常
public string materialCode { get; set; } // 物料编号 物料编码为空,表示空工装
}
///
/// 人工入库模型
///
public class ManualStorageModel {
public string from { get; set; } // 起点
public string cntrNo { get; set; } // 容器号
}
///
/// 设备报警反馈模型
///
public class DeviceAlertorFeedbackModel {
public string reqId { get; set; }
public string reqTime { get; set; }
public string deviceNo { get; set; } // 设备号
public string errCode { get; set; } // 错误码
public string errMsg { get; set; } // 错误信息
}
///
/// 获取托盘物料信息模型
///
public class FindTrayItemInfoModel {
public string reqId { get; set; }
public string reqTime { get; set; }
public string cntrNo { get; set; } // 托盘号
}
///
/// 申请终点模型
///
public class ApplyDestinationModel {
public string reqId { get; set; }
public string reqTime { get; set; }
public string taskNo { get; set; } // 任务号
public string loc { get; set; } // 当前货位
public int applyType { get; set; } // 申请类型 1:堆垛机放货异常申请新终点;2:输送线到达接驳位申请终点;3:
}
public class AGVApplyDestModel{
public string taskNo { get; set; } // 任务号
public string loc { get; set; } // 当前货位
public string trayCode { get; set; } // 托盘码(RFID)
public string applyType { get; set; } // 1.虚拟终点 2.RFID验证失败 3.RFID与任务不匹配 4.物料状态不合格
}
///
/// 任务状态反馈模型
///
public class TaskStatusFeedbackModel {
public string reqId { get; set; }
public string reqTime { get; set; }
public string taskNo { get; set; } // 任务号
public string subTaskNo { get; set; } // 子任务号
public int status { get; set; } // 任务状态 1:开始/执行中;2:完成;3:准备取货;4:取货完成;5:准备卸货;6:卸货完成;7:异常取消;8:强制完成
public string deviceNo { get; set; } // 设备号
public string errCode { get; set; } // 异常代码 0.无异常 1.设备故障码、2.rfid校验失败、3.取货无货、4.放货有货
public string loc { get; set; } // 当前货位
}
///
/// 设备信号反馈模型
///
public class DeviceSignalFeedbackModel
{
public string reqId { get; set; }
public string reqTime { get; set; }
public string loc { get; set; } // 货位 上料点、下料点、读码位、称重位(必填)
public string cntrNo { get; set; } // 托盘号
public int signalType { get; set; } //请求类型 1:下线请求 2:叫料请求 3:读码请求(必填)
public string deviceNo { get; set; } //设备号
public object extData { get; set; }
}
///
/// 叫料请求
///
public class CallMaterialRequest
{
public string loc { get; set; } // 货位 上料点、下料点、读码位、称重位(必填)
}
///
/// 下线请求
///
public class OffLineRequest
{
public string loc { get; set; } // 货位 上料点、下料点、读码位、称重位(必填)
public string cntrNo { get; set; } // 托盘号
public string jtNo { get; set; } // 机台号
}
///
/// 读码请求
///
public class ReadCodeRequest
{
public string loc { get; set; } // 货位 上料点、下料点、读码位、称重位(必填)
public string cntrNo { get; set; } // 托盘号
}
public class AddTaskModel {
public string From { get; set; }
public string To { get; set; }
public string No { get; set; }
}
public class TN_LocationModel {
public string TN_Location { get; set; }
}
public class CodeInfo {
///
/// 生产订单内码
///
public string FInterID { get; set; }
///
/// 生产订单编号
///
public string FSourceNo { get; set; }
///
/// 批号
///
public string FGMPBatchNo { get; set; }
public string FState { get; set; }
///
/// 物料编码(内码就是编码)
///
public string Fitemid_XK { get; set; }
///
/// 分录id
///
public string Fentryid { get; set; }
}
public class NoteInfo : CodeInfo {
public string WmsBillNo { get; set; }
}
}
}