using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using iWareSql;
using System.Data.Entity.Migrations;
using iWareSql.Orm;
using iWareCommon;
using iWareCommon.Utils;
using iWareSql.Entity.ViewMode;
using iWareSql.DBModel;
using XiGang.Core.Model;
using XiGang.Core.Model.PostParamModels.Task;
using iWareModel;
using iWareCommon.Common.Globle;
using iWareModel.EnumType.XiGangPublicCommon;
using iWareModel.Entity;
namespace iWareSql.DataAccess
{
public class MainTaskHandler
{
///
/// 给任务主表赋值物料信息
///
///
///
public static void SetMaterialForMainTask(ref Task_Main mainTask, Base_Material newMaterial)
{
//物料信息
mainTask.MaterialModel_CodeItemId = newMaterial.MaterialModel_CodeItemId;
mainTask.MaterialModel = newMaterial.MaterialModel;
mainTask.Supplier = newMaterial.Supplier;
mainTask.MaterialType = newMaterial.MaterialType;
mainTask.MaterialTypeName = newMaterial.MaterialTypeName;
mainTask.Series_CodeItemId = newMaterial.Series_CodeItemId;
mainTask.SeriesName = newMaterial.SeriesName;
mainTask.CargoType_CodeItemId = newMaterial.CargoType_CodeItemId;
mainTask.CargoTypeName = newMaterial.CargoTypeName;
mainTask.Qty = newMaterial.Qty;
}
///
/// 获取目标站点和中间站点,空托盘转运专用
///
///
///
///
///
///
///
///
public static FunRetEntity GetMidToPlaceForAddTransferTask(Base_Station sourcePlace, AddTransferTaskEnum flag, DbModel edm, ref string errMsg, ref Base_Station toPlace, ref Base_Station midPlace, ref Task_Main mainTask)
{
if (flag == AddTransferTaskEnum.位置1011转移到1014位置)
{//空托转移到1014位置
toPlace = StationHandler.GetRgvPlace(edm, ((int)EDevice.拆盘机入口1014).ToString());
}
else if (flag == AddTransferTaskEnum.位置1011转移到立体库中)
{//空托转移到立体库中
//目标点 寻找空库位
toPlace = StationHandler.FindBestEmptyPlaceForOrdinaryMaterial(edm, mainTask.OrderNo, MaterialTypeEnum.托盘);
if (toPlace == null)
{
return FunRetEntity.Fail("没有找到目标空闲库位");
}
//中间点
midPlace = StationHandler.GetRgvPlaceBySrmPlaceForInStore(edm, toPlace);
if (midPlace == null)
{
return FunRetEntity.Fail("没有找到RGV入库位置");
}
}
else if (flag == AddTransferTaskEnum.位置1009到位置1011)
{// 3:1009到1011
var getToPlaceResult = StationHandler.GetTargtStationForAddTransferTask(edm, EDevice.空托缓存1011, ref errMsg, ref toPlace);
if (getToPlaceResult.result == false) return getToPlaceResult;
}
else if (flag == AddTransferTaskEnum.立体库到1014位置)
{//4:4:立体库到1014位置
var getToPlaceResult = StationHandler.GetTargtStationForAddTransferTask(edm, EDevice.拆盘机入口1014, ref errMsg, ref toPlace);
if (getToPlaceResult.result == false) return getToPlaceResult;
//中间点
midPlace = StationHandler.GetRgvPlaceBySrmPlaceForOutStore(edm, sourcePlace);
if (midPlace == null)
{
return FunRetEntity.Fail("没有找到RGV出库位置");
}
}
else if (flag == AddTransferTaskEnum.位置1014到1020)
{// 5:1014到1020
var getToPlaceResult = StationHandler.GetTargtStationForAddTransferTask(edm, EDevice.拆盘机1020, ref errMsg, ref toPlace);
if (getToPlaceResult.result == false) return getToPlaceResult;
}
//统一设置目标站点
//判断站点是否有任务被占用
if (StationHandler.IsAllowUsePlace(edm, toPlace, ref errMsg) == false)
{
return FunRetEntity.Fail(errMsg);
}
//判断目标库位是否有库存
var toPlaceStore = StoreHandler.GetV_AllStoreByPlaceId(edm, toPlace.Id);
if (toPlaceStore != null) return FunRetEntity.Fail("目标库位" + toPlace.SrmStationCode + toPlace.RgvStationCode + "有库存!");
mainTask.ToPlace = toPlace.Id;
if (flag == AddTransferTaskEnum.位置1011转移到立体库中)
{
mainTask.RealToPlace = toPlace.SrmStationCode;
//记录区域 [EditBy shaocx,2022-05-02]
var device = BusinessHelper.GetSrmDeviceByPlaceNo(toPlace.SrmStationCode);
mainTask.Area = ((int)device).ToString();
}
else
{
mainTask.RealToPlace = toPlace.RgvStationCode;
}
return FunRetEntity.Success("成功");
}
/*
///
/// 新增入库任务
///
///
///
///
///
public static FunRetEntity AddInStoreTask(SysUser user, AddMainTaskPostParam param)
{
FunRetEntity fr = new FunRetEntity();
var errMsg = "";
var remark = "新增入库任务";
try
{
//数据验证
if (string.IsNullOrEmpty(param.CargoNo))
{
return FunRetEntity.Fail("件号不能为空");
}
if (string.IsNullOrEmpty(param.SalverCode))
{
return FunRetEntity.Fail("托盘号不能为空");
}
#region 事务
#endregion
using (DbModel edm = new DbModel())
{
using (var trans = edm.Database.BeginTransaction())
{
try
{
Task_Main mainTask = new Task_Main();
mainTask.IsVirtual = false;//非虚拟入库
mainTask.TaskNo = TaskNoHelper.GenerateTaskNo("IN");
mainTask.TaskName = "入库";
mainTask.InOutFlag = (int)MainInOutFlagEnum.入库;
mainTask.InOutFlagName = MainInOutFlagEnum.入库.ToString();
//起点
var sourcePlace = StationHandler.GetRgvPlace(edm, "RGV01");
if (sourcePlace == null)
{
return FunRetEntity.Fail("没有找到起点");
}
//判断起点是否有任务被占用
if (StationHandler.IsAllowUsePlace(edm, sourcePlace, ref errMsg) == false)
{
return FunRetEntity.Fail(errMsg);
}
mainTask.SourcePlace = sourcePlace.Id;
mainTask.RealSourcePlace = sourcePlace.RgvStationCode;
//目标点 寻找空库位
var toPlace = StationHandler.FindBestEmptyPlaceForOrdinaryMaterial(edm, "", MaterialTypeEnum.一般物料);
if (toPlace != null)
{
mainTask.ToPlace = toPlace.Id;
mainTask.RealToPlace = toPlace.SrmStationCode;
//记录区域 [EditBy shaocx,2022-05-02]
var device = BusinessHelper.GetSrmDeviceByPlaceNo(toPlace.SrmStationCode);
mainTask.Area = ((int)device).ToString();
}
else
{
return FunRetEntity.Fail("没有找到目标空闲库位");
}
//中间点
var midPlace = StationHandler.GetRgvPlaceBySrmPlaceForInStore(edm, toPlace);
if (midPlace == null)
{
return FunRetEntity.Fail("没有找到RGV入库位置");
}
var _taskType = MainTaskTypeEnum.自动入库;
mainTask.TaskType = Convert.ToInt32(_taskType);
mainTask.TaskTypeName = _taskType.ToString();
var _taskState = MainTaskStatusEnum.已组盘;
mainTask.TaskState = Convert.ToInt32(_taskState);
mainTask.TaskStateName = _taskState.ToString();
//绑定托盘和站点的关系
//新建物料
Base_Material newMaterial = MaterialHandler.CreateCargoMaterial(edm, "入库时,新建物料", param.CargoNo, param.CargoNo);
//判断托盘是否存在,如果存在,就不需要重建,如果不存在,就新建托盘
Base_Salver salver = SalverHandler.GetSalveByCodeForInTask(edm, param.SalverCode, out errMsg);
if (!string.IsNullOrEmpty(errMsg))
{
return FunRetEntity.Fail(errMsg);
}
//绑定托盘和物料的关系
Salver_Material_Handler.CreateCvIRelation(edm, user.Name, salver, newMaterial, remark);
//绑定托盘和站点的关系
Salver_Station_Handler.CreateCvPRelation(edm, user.Name, salver, sourcePlace, Salver_V_Station_StateEnum.入库绑定, remark);
mainTask.CreateTime = mainTask.ModifyTime = mainTask.StartTime = DateTime.Now;
mainTask.CreateBy = mainTask.ModifyBy = user.Name;
mainTask.CreateId = mainTask.ModifyId = user.ID;
mainTask.OperationRemark = "添加";
mainTask.SalverId = salver.Id;
mainTask.SalverCode = salver.SalverCode;
mainTask.MaterialId = newMaterial.Id;
//物料信息
MainTaskHandler.SetMaterialForMainTask(ref mainTask, newMaterial);
//序列号和订货号赋值 [Editby shaocx,2022-04-05]
mainTask.SerialNumber = newMaterial.SerialNumber;
mainTask.OrderNo = newMaterial.OrderNo;
string taskSequenceGuid = "";
mainTask.TaskSequence = MainTaskHandler.GenerateTaskSequence(edm, ref taskSequenceGuid);//生成任务序列号
mainTask.TaskSequenceGuid = taskSequenceGuid;
edm.Task_Main.Add(mainTask);
edm.SaveChanges();//保存一次,此时mainTask的自增ID就有值了
var plcTaskNo = BusinessHelper.CreatePlcTaskIdForSrmTask();
var createTime = DateTime.Now;
//创建RGV任务
FunRetEntity fre = PartTaskHandler.CreatePartTask(createTime, plcTaskNo, edm, EDeviceType.RGV, user.Name, 1, DeviceTaskTypeEnum.组盘入库, mainTask, salver, sourcePlace, midPlace, remark);
if (fre.result == false)
{
throw new Exception(fr.resMsg);
}
//创建堆垛机任务
fre = PartTaskHandler.CreatePartTask(createTime, plcTaskNo, edm, EDeviceType.堆垛机, user.Name, 2, DeviceTaskTypeEnum.组盘入库, mainTask, salver, midPlace, toPlace, remark);
if (fre.result == false)
{
throw new Exception(fr.resMsg);
}
edm.SaveChanges();//第二次保存
trans.Commit();//事务提交
}
catch
{
trans.Rollback();
throw;
}
}
return FunRetEntity.Success("成功");
}
}
catch (System.Exception ex)
{
throw ex;
}
}
//*/
///
/// 新增出库任务
///
///
///
///
///
public static FunRetEntity AddOutStoreTask(Plan_OutTaskDetail outDetailTask, V_Store v_store, DbModel edm, MainTaskTypeEnum _taskType, SysUser user, Base_Station sourcePlace, int myTaskSequence, string myTaskSequenceGuid)
{
FunRetEntity fr = new FunRetEntity();
var errMsg = "";
var remark = "新增出库任务";
try
{
Task_Main mainTask = null;
try
{
mainTask = new Task_Main();
mainTask.IsVirtual = false;//非虚拟入库
mainTask.TaskNo = TaskNoHelper.GenerateTaskNo("OUT");
mainTask.TaskName = "出库";
if (outDetailTask != null)
{
mainTask.Plan_OutTask_Id = outDetailTask.M_PlanId;
mainTask.Plan_OutTask_PlanNo = outDetailTask.M_PlanNo;
mainTask.Plan_OutTaskDetail_Id = outDetailTask.Id;
}
mainTask.InOutFlag = (int)MainInOutFlagEnum.出库;
mainTask.InOutFlagName = MainInOutFlagEnum.出库.ToString();
//起点
var salver = SalverHandler.GetSalverByPlace(edm, sourcePlace);
//中间点
var midPlace = StationHandler.GetRgvPlaceBySrmPlaceForOutStore(edm, sourcePlace);
if (midPlace == null)
{
return FunRetEntity.Fail("没有找到RGV出库位置");
}
//目标点
var toPlace = StationHandler.GetRgvPlace(edm, ((int)EDevice.出库口1012).ToString());//出库口
if (toPlace == null)
{
return FunRetEntity.Fail("没有找到RGV的出库口");
}
//注释以下内容,不再校验 1012出库口的锁定状态,防止因为锁定无法并发下发堆垛机任务的情况 【EditBy shaocx,2022-04-29】
/*
//判断目标点是否有任务被占用
if (StationHandler.IsAllowUsePlace(edm, toPlace, ref errMsg) == false)
{
return FunRetEntity.Fail(errMsg);
}
//*/
mainTask.SourcePlace = sourcePlace.Id;
mainTask.RealSourcePlace = sourcePlace.SrmStationCode;
//记录区域 [EditBy shaocx,2022-05-02]
var device = BusinessHelper.GetSrmDeviceByPlaceNo(sourcePlace.SrmStationCode);
mainTask.Area = ((int)device).ToString();
mainTask.ToPlace = toPlace.Id;
mainTask.RealToPlace = toPlace.RgvStationCode;
mainTask.TaskType = Convert.ToInt32(_taskType);
mainTask.TaskTypeName = _taskType.ToString();
var _taskState = MainTaskStatusEnum.待出库;
mainTask.TaskState = Convert.ToInt32(_taskState);
mainTask.TaskStateName = _taskState.ToString();
mainTask.CreateTime = mainTask.ModifyTime = mainTask.StartTime = DateTime.Now;
mainTask.CreateBy = mainTask.ModifyBy = user.Name;
mainTask.CreateId = mainTask.ModifyId = user.ID;
mainTask.OperationRemark = "添加";
mainTask.SalverId = v_store.SalverId;
mainTask.SalverCode = v_store.SalverCode;
mainTask.MaterialId = v_store.MaterialId;
//物料信息
var newMaterial = edm.Base_Material.Where(x => x.Id == v_store.MaterialId).First();
MainTaskHandler.SetMaterialForMainTask(ref mainTask, newMaterial);
//序列号和订货号赋值 [Editby shaocx,2022-04-05]
mainTask.SerialNumber = v_store.SerialNumber;
mainTask.OrderNo = v_store.OrderNo;
if (myTaskSequence > 0)
{
mainTask.TaskSequence = myTaskSequence;
mainTask.TaskSequenceGuid = myTaskSequenceGuid;
}
else
{
string taskSequenceGuid = "";
mainTask.TaskSequence = MainTaskHandler.GenerateTaskSequence(edm, ref taskSequenceGuid);//生成任务序列号
mainTask.TaskSequenceGuid = taskSequenceGuid;
}
edm.Task_Main.Add(mainTask);
edm.SaveChanges();//保存一次,此时mainTask的自增ID就有值了
fr.resData = mainTask;
//var plcTaskNo = BusinessHelper.CreatePlcTaskIdForSrmTask();
////创建堆垛机任务
//PartTaskHandler.CreatePartTask(plcTaskNo, edm, EDeviceType.堆垛机, user.Name, 1, DeviceTaskTypeEnum.出库, mainTask, salver, sourcePlace, midPlace, remark);
////创建RGV任务
//PartTaskHandler.CreatePartTask(plcTaskNo, edm, EDeviceType.RGV, user.Name, 2, DeviceTaskTypeEnum.出库, mainTask, salver, midPlace, toPlace, remark);
edm.SaveChanges();//第二次保存
}
catch
{
throw;
}
return FunRetEntity.Success("成功", mainTask);
}
catch (System.Exception ex)
{
throw ex;
}
}
///
/// 新增虚拟出库任务【Editby shaocx,2022-07-28】
///
///
///
///
///
public static FunRetEntity AddOutStoreTaskForVirtual(Plan_OutTaskDetail outDetailTask, Wms_VirtualStore v_store, DbModel edm, MainTaskTypeEnum _taskType, SysUser user)
{
FunRetEntity fr = new FunRetEntity();
var errMsg = "";
var remark = "新增虚拟出库任务";
try
{
Task_Main mainTask = null;
try
{
mainTask = new Task_Main();
mainTask.IsNeedOnLine = true;//注意:必须是通知MES上线
mainTask.IsVirtual = true;//虚拟出库
mainTask.TaskNo = TaskNoHelper.GenerateTaskNo("OUT");
mainTask.TaskName = "出库";
if (outDetailTask != null)
{
mainTask.Plan_OutTask_Id = outDetailTask.M_PlanId;
mainTask.Plan_OutTask_PlanNo = outDetailTask.M_PlanNo;
mainTask.Plan_OutTaskDetail_Id = outDetailTask.Id;
}
mainTask.InOutFlag = (int)MainInOutFlagEnum.出库;
mainTask.InOutFlagName = MainInOutFlagEnum.出库.ToString();
mainTask.TaskType = Convert.ToInt32(_taskType);
mainTask.TaskTypeName = _taskType.ToString();
var _taskState = MainTaskStatusEnum.已完成;//注意:状态必须是已完成
mainTask.TaskState = Convert.ToInt32(_taskState);
mainTask.TaskStateName = _taskState.ToString();
mainTask.CreateTime = mainTask.ModifyTime = mainTask.StartTime = mainTask.FinishTime = DateTime.Now;
mainTask.CreateBy = mainTask.ModifyBy = user.Name;
mainTask.CreateId = mainTask.ModifyId = user.ID;
mainTask.OperationRemark = "添加";
//mainTask.SalverId = v_store.SalverId;
//mainTask.SalverCode = v_store.SalverCode;
mainTask.MaterialId = v_store.MaterialId;
//物料信息
var newMaterial = edm.Base_Material.Where(x => x.Id == v_store.MaterialId).First();
MainTaskHandler.SetMaterialForMainTask(ref mainTask, newMaterial);
//删除物料信息
edm.Base_Material.Remove(newMaterial);
//序列号和订货号赋值 [Editby shaocx,2022-04-05]
mainTask.SerialNumber = v_store.SerialNumber;
mainTask.OrderNo = v_store.OrderNo;
mainTask.TaskSequence = 0;//生成任务序列号
edm.Task_Main.Add(mainTask);
edm.SaveChanges();//保存一次,此时mainTask的自增ID就有值了
fr.resData = mainTask;
//保存出入库记录
//添加至虚拟库出入记录
Wms_VirtualStoreRecord newVirtualStoreRecord = new Wms_VirtualStoreRecord();
newVirtualStoreRecord.InOutFlag = (int)MainInOutFlagEnum.出库;
newVirtualStoreRecord.InOutFlagName = "出库";
newVirtualStoreRecord.MaterialId = newMaterial.Id;
newVirtualStoreRecord.OperationRemark = "出库任务完成";
newVirtualStoreRecord.CreateId = 0;
newVirtualStoreRecord.CreateBy = SysGloble.WCSSystem;
newVirtualStoreRecord.CreateTime = DateTime.Now;
newVirtualStoreRecord.ModifyBy = SysGloble.WCSSystem;
newVirtualStoreRecord.ModifyId = 0;
newVirtualStoreRecord.ModifyTime = DateTime.Now;
newVirtualStoreRecord.IsDeleted = false;
newVirtualStoreRecord.SerialNumber = newMaterial.SerialNumber;
newVirtualStoreRecord.MaterialModel = newMaterial.MaterialModel;
newVirtualStoreRecord.MaterialModel_CodeItemId = newMaterial.MaterialModel_CodeItemId;
newVirtualStoreRecord.CargoType_CodeItemId = newMaterial.CargoType_CodeItemId;
newVirtualStoreRecord.CargoTypeName = newMaterial.CargoTypeName;
newVirtualStoreRecord.SeriesName = newMaterial.SeriesName;
newVirtualStoreRecord.Series_CodeItemId = newMaterial.Series_CodeItemId;
newVirtualStoreRecord.Supplier = newMaterial.Supplier;
newVirtualStoreRecord.OrderNo = newMaterial.OrderNo;
edm.Wms_VirtualStoreRecord.Add(newVirtualStoreRecord);
//删除虚拟库存 【Editby shaocx,2022-12-29】
var virtualStore = edm.Wms_VirtualStore.Where(x => x.SerialNumber == newMaterial.SerialNumber).FirstOrDefault();
if (virtualStore != null)
{
edm.Wms_VirtualStore.Remove(virtualStore);
}
edm.SaveChanges();//第二次保存
}
catch
{
throw;
}
return FunRetEntity.Success("成功", mainTask);
}
catch (System.Exception ex)
{
throw ex;
}
}
private static readonly object lockObject = new object();
///
/// 获取成最新的任务序列号
///
///
///
public static TaskSequenceEntity GetTaskSequenceEntity(DbModel edm)
{
TaskSequenceEntity entity = new TaskSequenceEntity();
string taskSequenceGuid = "";
entity.TaskSequence = MainTaskHandler.GenerateTaskSequence(edm, ref taskSequenceGuid);
entity.TaskSequenceGuid = taskSequenceGuid;
return entity;
}
///
/// 生成最新的任务序列号
///
///
///
public static int GenerateTaskSequence(DbModel edm, ref string taskSequenceGuid)
{
lock (lockObject)
{
taskSequenceGuid = "";
var query1 = (int)MainTaskStatusEnum.已完成;
var query2 = (int)MainTaskStatusEnum.已取消;
// 排除虚拟的出入库
var taskList = edm.Task_Main.Where(x => x.TaskState != query1 && x.TaskState != query2 && (x.IsVirtual == null || x.IsVirtual == false)).ToList();
if (taskList == null || taskList.Count == 0)
{
taskSequenceGuid = Guid.NewGuid().ToString();//从1开始,就要重新生成GUID [EditBy shaocx,2022-08-24]
return 1;
}
else
{
//取最近的那个的GUID值
var first = taskList.OrderByDescending(x => x.Id).First();
taskSequenceGuid = first.TaskSequenceGuid;
var task = taskList.Max(x => x.TaskSequence);
return task + 1;
}
}
}
///
/// 根据主任务ID找到主任务
///
///
///
///
public static Task_Main GetMainTaskById(DbModel context, int mainTaskId)
{
var task = context.Task_Main.Where(x => x.Id == mainTaskId).FirstOrDefault();
if (task == null)
throw new Exception("根据主任务ID" + mainTaskId + "没有找到主任务");
return task;
}
///
/// 更新主任务的状态
///
///
///
///
///
public static void UpdateTaskStatus(DbModel context, int mainTaskId, MainTaskStatusEnum changeTaskStatus, string remark)
{
Task_Main task = GetMainTaskById(context, mainTaskId);
task.TaskState = (int)changeTaskStatus;
task.TaskStateName = changeTaskStatus.ToString();
task.ModifyBy = SysGloble.WCSSystem;
task.ModifyTime = DateTime.Now;
task.OperationRemark = remark;
if (changeTaskStatus == MainTaskStatusEnum.已完成)
{
task.FinishTime = DateTime.Now;//记录完成时间
}
}
}
}