using Admin.NET.Application;
using Admin.NET.Core.TaskModule.Enum;
using iWareCommon;
using iWareCommon.Utils;
using iWareModel.Entity.MES;
using iWareModel.Entity.WCS;
using iWareSql.DataAccess;
using iWareSql.MyDbContext;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
namespace iWareCC.Common.Helper
{
///
/// 下发任务帮助类 【EditBy shaocx,2022-02-05】
///
public class IssueTaskHelper
{
///
/// 所有巷道的出库任务
///
///
///
///
public static bool Out(MyDbContext mycontext, string WcsIp, int Lane, List wms_tasks, ref string errMsg)
{
// List wcsTaskInputs = new List();
// WCSTaskInput wcsTask = new WCSTaskInput();
// //State 任务状态 0 - 未下发WCS ,1 - 已下发WCS
// //TaskState 任务状态 0-未执行,1-已暂停,2-执行中,3-已完成
// // TaskCategory 任务类别 1入库任务 2出库任务,3移库任务
// //出库任务查找
// //var wms_tasks = mycontext.wms_task.Where(x => x.TaskState != 3 && (x.IsDeleted ==null || x.IsDeleted == false) && x.State == 0 && x.AreaType == (int)AreaTypeEnum.立体库 && x.TaskCategory == 2 && x.Lane==Lane).OrderByDescending(x => x.TaskPriority).ToList();//查询未WCS下发未完成的任务
// if (wms_tasks == null || wms_tasks.Count <= 0)
// {
// SystemWarningMsg._lbl_Alert_OutPlanTaskHandler = "当前未存在出入库任务";
// return false;
// }
// wms_task singleTask = null;
// var needFirstTask = wms_tasks.Where(x => x.MoveType == (int)MoveTypeEnum.移库&&x.BusinessType==(int)BusinessTypeEnum.销售下架).OrderByDescending(x => x.TaskPriority).FirstOrDefault();
// //这个是需要首发的
// var isInsideLocation = FindEmptyLocationHelper.IsInsideLocation(needFirstTask.SourcePlace);
// if (isInsideLocation == false)
// {//外侧库位
// singleTask = needFirstTask;
// }
// else
// {//如果是内侧库位, 1排和4排,需要校验下 这个1排和4排是否有未完结的任务,如果有,就不要出
// var outsideLocation = FindEmptyLocationHelper.GetWidesideLocation(needFirstTask.FromLocationCode);
// var noFinishedTask = TaskHandler.IsExistNoFinishedTask(mycontext, outsideLocation);
// if (noFinishedTask == null)
// {//外侧没有任何任务占用,就下发该库位
// singleTask = needFirstTask;
// }
// else
// {//有任务占用该外侧库位
// //如果是 出库任务,则优先干
// if (noFinishedTask.TaskCategory == 2 && noFinishedTask.TaskState == 0)
// {
// singleTask = noFinishedTask;
// }
// else
// {
// //那么只能不处理这个任务了。不下发
// errMsg = $"准备要下发出库任务{needFirstTask.TaskNo},但是他是内侧库位,并且外侧库位{outsideLocation}有未结束的任务占用,所以无法下发这个任务{needFirstTask.TaskNo}";
// singleTask = null;
// }
// }
// }
// //原先的寻找下发逻辑 【2023-11-1】
// /*
// singleTask = wms_tasks.Where(x => x.TaskCategory == 2 && (x.Row == 2 || x.Row == 3)).OrderByDescending(x => x.TaskPriority).FirstOrDefault();//出库任务先找2-3排
// if (singleTask == null)
// {
// singleTask = wms_tasks.Where(x => x.TaskCategory == 2 && (x.Row == 1 || x.Row == 4)).OrderByDescending(x => x.TaskPriority).FirstOrDefault();
// }
// //*/
// if (singleTask != null)
// {
// return SingleOut(mycontext, WcsIp, singleTask, ref errMsg);
// }
return true;
}
///
/// 所有巷道的单个出库任务处理
///
///
///
///
// private static bool SingleOut(MyDbContext mycontext, string WcsIp, wms_task singleTask, ref string errMsg)
//{
//List wcsTaskInputs = new List();
//WCSTaskInput wcsTask = new WCSTaskInput();
////State 任务状态 0 - 未下发WCS ,1 - 已下发WCS
////TaskState 任务状态 0-未执行,1-已暂停,2-执行中,3-已完成
//// TaskCategory 任务类别 1入库任务 2出库任务,3移库任务
//#region 存在未下发的任务,生成WCS任务
//int Priority = int.Parse(singleTask.TaskPriority.ToString());
//bool isLane3 = false;
//int palletType = MyExtendHelper.GetPalletType(mycontext, singleTask.ContainerCode, ref isLane3);
//// var containers = GetWareContainerType(mycontext, singleTask.ContainerCode);//查询容器类型
//wcsTask.WmsTaskNo = singleTask.TaskNo;
//wcsTask.TaskName = singleTask.TaskName;
//wcsTask.TaskType = int.Parse(singleTask.TaskCategory.ToString());
//wcsTask.Container = singleTask.ContainerCode;
//wcsTask.High = 1;
//wcsTask.PalletType = palletType;
//wcsTask.SourcePlace = singleTask.FromLocationCode;
//wcsTask.ToPlace = "";
//wcsTask.Creator = "cc";
//wcsTask.Timestamp = DateTime.UtcNow.ToString();
//wcsTask.Priority = Priority;
//#endregion
//var arr = singleTask.FromLocationCode.Split('-');
//string needMoveWareLocationCode = string.Empty;//需要移库的库位,即外侧的库位
//if (arr[2] == "1")
//{
// needMoveWareLocationCode = arr[0] + "-" + arr[1] + "-2-" + arr[3];
//}
//else if (arr[2] == "4")
//{
// needMoveWareLocationCode = arr[0] + "-" + arr[1] + "-3-" + arr[3];
//}
////判断箱子在里侧还是外侧(修改任务为下发状态,直接下发WCS任务)还是里侧(判断外侧是否有箱子,并判断外侧箱子是否有任务)
//wms_task moveTask = null;
//wms_task move_out_Task = null;//移库出库任务
//if (!string.IsNullOrEmpty(needMoveWareLocationCode))
//{
// //如果此时外面的库位有任务被占用,就暂时不处理 【Editby shaocx,2023-03-03】
// var noFinishedTask = TaskHandler.IsExistNoFinishedTask(mycontext, needMoveWareLocationCode);
// if (noFinishedTask != null)
// {
// errMsg = $"出库任务{singleTask.FromLocationCode}的外侧库位{needMoveWareLocationCode}当前有未结束的任务,暂时不清楚是否需要移库!";
// TaskHandler.UpdateTaskMsg(singleTask.Id, errMsg);//判断如果有错误日志,就更新任务表的消息 【Editby shaocx,2023-04-08】
// return false;
// }
// //下面的代码注释,因为库位上有库存,目前设计是 库位就锁定,暂时不判断锁定状态 【Editby shaocx,2023-03-04】
// //var needMoveWareLocation = mycontext.ware_location.Where(x => x.Code == needMoveWareLocationCode).FirstOrDefault();
// //if (needMoveWareLocation.IsLocked == 1)
// //{
// // errMsg = $"出库任务{singleTask.FromLocationCode}的外侧库位{needMoveWareLocationCode}被锁定,锁定原因:{needMoveWareLocation.LockRemark}!";
// // return false;
// //}
// var lvc = mycontext.ware_location_vs_container.Where(x => !string.IsNullOrEmpty(needMoveWareLocationCode) && x.WareLocationCode == needMoveWareLocationCode && (x.IsDeleted == null || x.IsDeleted == false)).FirstOrDefault();// 出库任务是1-4列判断2-3是否有容器
// if (lvc != null)//外侧存在箱子
// {//需要移库
// var moveResult = CreateMoveTask(mycontext, needMoveWareLocationCode, singleTask, lvc, Priority, ref wcsTaskInputs, ref errMsg, ref moveTask, ref move_out_Task);
// if (moveResult == false)
// {
// TaskHandler.UpdateTaskMsg(singleTask.Id, errMsg);//判断如果有错误日志,就更新任务表的消息 【Editby shaocx,2023-04-08】
// return false;
// }
// }
//}
//wcsTaskInputs.Add(wcsTask);
//bool wcsResult = CreateBatchTask(wcsTaskInputs, WcsIp, ref errMsg);
//if (wcsResult)
//{
// //成功后,修改任务状态
// singleTask.State = 1;//修改任务为下发状态
// singleTask.IssueTime = DateTime.Now;//增加下发时间 【Editby shaocx,2023-03-03】
// singleTask.TaskMsg = "下发成功";
// singleTask.UpdatedTime = DateTime.Now;
// if (moveTask != null)
// {//移库
// mycontext.wms_task.Add(moveTask);
// //锁定 移库的起点和目标点
// MyExtendHelper.LockLocation(true, mycontext, moveTask.ToLocationCode, "移库操作,锁定目标库位,下发出库任务");
// MyExtendHelper.LockLocation(true, mycontext, moveTask.FromLocationCode, "移库操作,锁定开始库位,下发出库任务");
// }
// if (move_out_Task != null)
// {//移库出库任务
// mycontext.wms_task.Add(move_out_Task);
// //锁定 移库出库的起点
// MyExtendHelper.LockLocation(true, mycontext, move_out_Task.FromLocationCode, "移库出库操作,锁定开始库位,下发出库任务");
// }
//}
//else
//{
// singleTask.TaskMsg = "下发失败:" + errMsg;
// singleTask.UpdateTime = DateTime.Now;
//}
//if (mycontext.SaveChanges() > 0)
//{
// return true;
//}
//else
//{
// return false;
//}
// }
#region 移库有关
///
/// 获取库中的高度值
///
///
///
///
///
//private static int GetDetectionHeight(ware_location_vs_container move_ware_location_vs_container, int PalletType)
//{
// if (move_ware_location_vs_container.DetectionHeight == null)
// {
// //自行计算高度
// string[] arr = move_ware_location_vs_container.WareLocationCode.Split('-');
// int layer = Convert.ToInt32(arr[3]);//层高
// //3-1-3-8 巷道-列-排-层
// /*
// * 塑料托盘, 只有两个高度,1层的高度值是2, 2 3 4 的高度值是1
// * 钢制托盘,必须是高度3 的
// */
// if (PalletType == 2)
// {//刚托盘库位
// return 3;
// }
// else if (PalletType == 1)
// {//塑料托盘库位
// if (layer == 1)
// {
// return 2;
// }
// else
// {
// return 1;
// }
// }
// else
// {
// throw new Exception("无效的PalletType值:" + PalletType);
// }
// }
// else
// {
// return Convert.ToInt32(move_ware_location_vs_container.DetectionHeight);
// }
//}
///
/// 生成移库任务
///
///
///
///
///
///
///
///
///
///
//private static bool CreateMoveTask(MyDbContext mycontext, string needMoveWareLocationCode,
// wms_task model, ware_location_vs_container lvc, int Priority
// , ref List wcsTaskInputs, ref string errMsg, ref wms_task moveTask, ref wms_task move_out_Task)
//{
// var preTitle = ",任务起点: " + model.FromLocationCode;
// var wareTask = mycontext.wms_task.Where(x => (x.IsDeleted == null || x.IsDeleted == false) && (x.FromLocationCode == needMoveWareLocationCode || x.ToLocationCode == needMoveWareLocationCode))
// .Where(TaskHandler.CommonFilterExpressionForNoFinishAndNoCancel())
// .FirstOrDefault();//查询外侧箱子是否有出库任务
// if (wareTask != null)
// {
// errMsg = "外侧有任务,请优先执行外侧任务,外侧库位编号:" + lvc.WareLocationCode + preTitle;
// return false;
// }
// #region 根据箱子类型查询可用库位
// bool isLane3 = false;//是否是第3巷道
// int PalletType = 0;
// PalletType = MyExtendHelper.GetPalletType(mycontext, lvc.WareContainerCode, ref isLane3);
// #endregion
// int _DetectionHeight = 1;
// #region 移库时优先移一四列,一四列无位置时移入二三列
// CriterionContainerOutput output = null;
// if (isLane3)
// {//3巷道
// //获取这个库位的ware_location_vs_container对象
// var move_ware_location_vs_container_list = mycontext.ware_location_vs_container.Where(x => x.WareLocationCode == needMoveWareLocationCode
// && (x.IsDeleted == null || x.IsDeleted == false)
// ).ToList();
// if (move_ware_location_vs_container_list == null || move_ware_location_vs_container_list.Count == 0)
// {
// errMsg = $"3巷道查找库位有0条 库位和托盘绑定关系,请联系管理员!" + preTitle;
// return false;
// }
// if (move_ware_location_vs_container_list.Count > 1)
// {
// errMsg = $"3巷道查找库位有{move_ware_location_vs_container_list.Count}条 库位和托盘绑定关系,请联系管理员!" + preTitle;
// return false;
// }
// var move_ware_location_vs_container = move_ware_location_vs_container_list.FirstOrDefault();
// _DetectionHeight = GetDetectionHeight(move_ware_location_vs_container, PalletType);
// output = WMSRequestHelper.FindEmptyLocationForLane3(_DetectionHeight
// , move_ware_location_vs_container.WareContainerCode, 1);
// }
// else
// {//1巷道和2巷道
// _DetectionHeight = 1;
// int lane = Convert.ToInt32(lvc.WareLocationCode.Substring(0, 1));//起点所属的巷道
// FindEmptyLocationHelper.FindEmptyLocatonListForLane12(true, false, mycontext, FormCC.WcsIp, lvc.WareContainerCode, ref PalletType, ref output, lane);//说明新建任务的时候,没有获取到目标库位,需要重新找 新库位
// //output = FindCriterionContainerOutput(lane, mycontext, criterionRetionOutputs1, needMoveWareLocationCode);
// }
// if (output == null)
// {
// /*
// errMsg = "移库没有找到空库位移库" + preTitle;
// return false;
// //*/
// //如果移库实在没有找到库位,那么就直接创建出库任务得了 【Editby shaocx,2023-12-28】
// var TaskNo = Yitter.IdGenerator.YitIdHelper.NextId().ToString();
// var wcsTask_move_out = new WCSTaskInput();
// wcsTask_move_out.WmsTaskNo = TaskNo;
// wcsTask_move_out.TaskName = SystemValue.YIKU_CK_NAME;
// wcsTask_move_out.TaskType = 2;//出库任务
// wcsTask_move_out.Priority = Priority + 1;
// wcsTask_move_out.Container = lvc.WareContainerCode;
// wcsTask_move_out.High = _DetectionHeight;
// wcsTask_move_out.PalletType = PalletType;
// wcsTask_move_out.SourcePlace = lvc.WareLocationCode;
// wcsTask_move_out.ToPlace = "";
// wcsTask_move_out.Creator = "cc";
// wcsTask_move_out.Timestamp = DateTime.UtcNow.ToString();
// wcsTaskInputs.Add(wcsTask_move_out);
// move_out_Task = new wms_task
// {
// Id = Yitter.IdGenerator.YitIdHelper.NextId(),
// OrderNo = "",
// TaskNo = wcsTask_move_out.WmsTaskNo,
// TaskName = wcsTask_move_out.TaskName,
// TaskCategory = wcsTask_move_out.TaskType,
// TaskDescribe = "无工单",
// TaskPriority = wcsTask_move_out.Priority,
// AreaType = (int)AreaTypeEnum.立体库,
// //TaskState = 2,
// TaskState = Convert.ToInt32(WareTaskStateEnum.执行中),
// TaskType = (int)WareTaskTypeEnum.移库出库,
// FromLocationCode = wcsTask_move_out.SourcePlace,
// ToLocationCode = wcsTask_move_out.ToPlace,
// ContainerCode = wcsTask_move_out.Container,
// CreatedTime = DateTime.Now,
// CreatedUserId = 142307070910551,
// CreatedUserName = "cc",
// State = 1,
// IssueTime = DateTime.Now,//增加下发时间 【Editby shaocx,2023-03-03】
// IsDeleted = false,
// DetectionHeight = _DetectionHeight
// };
// }
// else
// {//找到了移库的目标库位
// var TaskNo = Yitter.IdGenerator.YitIdHelper.NextId().ToString();
// var wcsTask1 = new WCSTaskInput();
// wcsTask1.WmsTaskNo = TaskNo;
// wcsTask1.TaskName = SystemValue.YIKUNAME;
// wcsTask1.TaskType = 3;
// wcsTask1.Priority = Priority + 1;
// wcsTask1.Container = lvc.WareContainerCode;
// wcsTask1.High = _DetectionHeight;
// wcsTask1.PalletType = PalletType;
// wcsTask1.SourcePlace = lvc.WareLocationCode;
// wcsTask1.ToPlace = output.Code;
// wcsTask1.Creator = "cc";
// wcsTask1.Timestamp = DateTime.UtcNow.ToString();
// wcsTaskInputs.Add(wcsTask1);
// moveTask = new wms_task
// {
// Id = Yitter.IdGenerator.YitIdHelper.NextId(),
// OrderNo = "",
// TaskNo = wcsTask1.WmsTaskNo,
// TaskName = wcsTask1.TaskName,
// TaskCategory = wcsTask1.TaskType,
// TaskDescribe = "无工单",
// TaskPriority = wcsTask1.Priority,
// AreaType = (int)AreaTypeEnum.立体库,
// //TaskState = 2,
// TaskState = Convert.ToInt32(WareTaskStateEnum.执行中),
// //TaskType = 1,
// TaskType = (int)WareTaskTypeEnum.出库,
// FromLocationCode = wcsTask1.SourcePlace,
// ToLocationCode = wcsTask1.ToPlace,
// ContainerCode = wcsTask1.Container,
// CreatedTime = DateTime.Now,
// CreatedUserId = 142307070910551,
// CreatedUserName = "cc",
// State = 1,
// IssueTime = DateTime.Now,//增加下发时间 【Editby shaocx,2023-03-03】
// IsDeleted = false,
// DetectionHeight = _DetectionHeight
// };
// #region 验证移库任务,不能再不同巷道中移库 【Editby shaocx,2022-12-28】
// var fromLane = wcsTask1.SourcePlace.Substring(0, 1);
// var toLane = wcsTask1.ToPlace.Substring(0, 1);
// if (fromLane != toLane)
// {
// errMsg = "将要生成的移库任务,起点巷道是" + fromLane + ",目标巷道是" + toLane + ",移库任务不能在不同巷道中移库,处理的任务号是:" + model.TaskNo + preTitle;
// return false;
// }
// #endregion
// }
// #endregion
// return true;
//}
#endregion
///
/// 模拟下发
///
///
///
public static int Put(MyDbContext mycontext, string WcsIp, int Lane, wms_task singleTask, ref string errMsg)
{
try
{
if (singleTask == null)
{
errMsg = "当前未存在 入库任务";
return 1;
}
//获取移动单
var moveOrder = BaseInfoHelper.GetOrderMovement(mycontext, singleTask, ref errMsg);
var moveOrderDetails = BaseInfoHelper.GetMoveOrderDetails(mycontext, singleTask, moveOrder, ref errMsg);
//目标库区
//var toArea = BaseInfoHelper.GetArea(mycontext, singleTask.ToAreaCode, "目标库区", ref errMsg);
//目标库位校验
var toPlace = BaseInfoHelper.GetPlace(mycontext, singleTask.ToPlaceCode, "目标库位", ref errMsg);
//if (toArea.AreaCode != toPlace.AreaCode)
//{
// errMsg = $"目标库位{toPlace.PlaceCode}所属库区{toPlace.AreaCode}与目标库区{toArea.AreaCode}不匹配";
// return 1;
//}
if (toPlace.PlaceStatus != (int)PlaceStatusEnum.正常)
{
errMsg = $"任务下发,目标库位{singleTask.ToPlaceCode}库位属性不是{PlaceStatusEnum.正常.ToString()}";
return 1;
}
//源库位校验
var sourcePlace = BaseInfoHelper.GetPlace(mycontext, singleTask.SourcePlaceCode, "源库位", ref errMsg);
if (sourcePlace.PlaceStatus != (int)PlaceStatusEnum.正常)
{
errMsg = $"任务下发,源库位{singleTask.SourcePlaceCode}库位属性不是{PlaceStatusEnum.正常.ToString()}";
return 1;
}
#region 锁定起始、目标库位
//锁定起始、目标库位
sourcePlace.PlaceStatus = (int)PlaceStatusEnum.锁定;
sourcePlace.UpdateTime = DateTime.Now;
sourcePlace.UpdateUserId = 0;
sourcePlace.UpdateUserName = FormCC.WcsSysUserName;
toPlace.PlaceStatus = (int)PlaceStatusEnum.锁定;
toPlace.UpdateTime = DateTime.Now;
toPlace.UpdateUserId = 0;
toPlace.UpdateUserName = FormCC.WcsSysUserName;
#endregion
#region 移动单状态变更处理中
if(moveOrder.OrderStatus == (int)OrderStatusEnum.新建)
{
moveOrder.OrderStatus = (int)OrderStatusEnum.处理中;
moveOrder.OrderStatusName = OrderStatusEnum.处理中.ToString();
}
foreach (var item in moveOrderDetails)
{
if (item.OrderStatus == (int)OrderStatusEnum.新建)
{
item.OrderStatus = (int)OrderStatusEnum.处理中;
item.OrderStatusName = OrderStatusEnum.处理中.ToString();
item.UpdateTime = DateTime.Now;
item.UpdateUserId = 0;
item.UpdateUserName = FormCC.WcsSysUserName;
}
}
#endregion
//更新调度任务状态
singleTask.TaskStatus = (int)TaskStatusEnum.已下发;//更新任务状态为 已下发
singleTask.IssueTime = DateTime.Now;//增加下发时间
singleTask.UpdateTime = DateTime.Now;
singleTask.TaskMsg = "下发成功";
mycontext.SaveChanges();
return 3;
}
catch (Exception ex)
{
SystemWarningMsg._lbl_Alert_OutPlanTaskHandler = "错误信息:" + ex;
return 2;
}
}
///
/// 批量下发WCS任务
///
///
///
///
public static bool CreateBatchTask(List taskOutputs, string WcsIp, ref string errMsg)
{
errMsg = "";
//将任务下发给WCS
var json = JsonConvert.SerializeObject(taskOutputs);
if (FormCC.IsSimulationPLC)
{//如果是模拟
//记录日志
Log4NetHelper.WriteInfoLog(LogType.OutPlanTask, "批量下发WCS任务[成功][注意:这是模拟测试!!!!],taskOutputs:" + json);
return true;
}
//var utl = string.Format(WcsIp + @"CreateBatchTask");
//var result = HttpHelper.Post(utl, json);
var utl = string.Format(@"CreateBatchTask");
var result = new HTTPService(WcsIp).postContentForString(utl, json, "");
if (result == null)
{
//记录日志
Log4NetHelper.WriteInfoLog(LogType.OutPlanTask, "批量下发WCS任务[失败],taskOutputs:" + json);
SystemWarningMsg._lbl_Alert_OutPlanTaskHandler = "批量下发WCS任务失败,WCS返回NULL,托盘号:" + taskOutputs[0].Container
+ ",起点:" + taskOutputs[0].SourcePlace + ",目标点:" + taskOutputs[0].ToPlace;
errMsg = "WCS返回结果NULL";
return false;
}
var data = JsonConvert.DeserializeObject(result);
if (data == null || !data.Success)
{
//记录日志
Log4NetHelper.WriteInfoLog(LogType.OutPlanTask, "批量下发WCS任务[失败],taskOutputs:" + json);
SystemWarningMsg._lbl_Alert_OutPlanTaskHandler = "批量下发WCS任务失败,WCS返回失败,托盘号:" + taskOutputs[0].Container
+ ",起点:" + taskOutputs[0].SourcePlace + ",目标点:" + taskOutputs[0].ToPlace + ",WCS结果:" + (string.IsNullOrEmpty(data.Message) ? "" : data.Message);
errMsg = "WCS返回失败,返回消息:" + data.Message;
return false;
}
//记录日志
Log4NetHelper.WriteInfoLog(LogType.OutPlanTask, "批量下发WCS任务[成功],taskOutputs:" + json);
return true;
}
}
}