using Admin.NET.Application;
|
using Admin.NET.Core.TaskModule.Enum;
|
using iWareCC.Common.Helper;
|
using iWareCommon;
|
using iWareCommon.Common.Globle;
|
using iWareCommon.Utils;
|
using iWareModel.Entity.WCS;
|
using iWareSql.DataAccess;
|
using iWareSql.MyDbContext;
|
using Newtonsoft.Json;
|
using System;
|
using System.Collections.Generic;
|
using System.ComponentModel;
|
using System.Data.Entity;
|
using System.Linq;
|
using System.Threading;
|
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
|
using static System.Windows.Forms.VisualStyles.VisualStyleElement.StartPanel;
|
|
namespace iWareCC
|
{
|
/// <summary>
|
/// WCS任务完成线程(平库)
|
/// </summary>
|
public static class TaskFinishHandler
|
{
|
public static void Handler()
|
{
|
while (true)
|
{
|
|
Thread.Sleep(2000);//休眠2秒
|
try
|
{
|
if (SystemValue.isAllowRuning_PingKuTaskFinish && SystemValue.isStartedModel)
|
{
|
using (MyDbContext dbContext = new MyDbContext())
|
{
|
//只查询平库
|
|
var models = dbContext.wms_task
|
.Where(x => x.TaskStatus == (int)TaskStatusEnum.已下发)
|
.Where(x => (x.IsDelete == false)
|
// && (x.AreaType == (int)AreaTypeEnum.平库)
|
).ToList();
|
|
if (models != null && models.Count > 0)
|
{
|
FinishTask(dbContext,models);
|
}
|
SystemWarningMsg._lbl_Alert_PingKuTaskFinish = "";
|
}
|
}
|
}
|
catch (Exception ex)
|
{
|
SystemWarningMsg._lbl_Alert_PingKuTaskFinish = "WCS任务完成线程(平库) 出现异常:" + ex.Message;
|
Log4NetHelper.WriteErrorLog(LogType.PingKuTaskFinish, "WCS任务完成线程(平库) 出现异常:" + ex.Message, ex);
|
}
|
}
|
}
|
|
/// <summary>
|
/// 模拟完成任务调度
|
/// </summary>
|
/// <param name="mycontext"></param>
|
/// <returns></returns>
|
public static void FinishTask(MyDbContext dbContext, List<wms_task> taskList)
|
{
|
string errMsg = string.Empty;
|
try
|
{
|
|
|
|
|
//处理调度任务
|
foreach (var singleTask in taskList)
|
{
|
|
OrderMovementFinishTask(dbContext, singleTask, ref errMsg);
|
|
if (!string.IsNullOrEmpty(errMsg))
|
{
|
SystemWarningMsg._lbl_Alert_OutPlanTaskHandler += "任务号" + singleTask.TaskNo + "模拟完成任务失败," + errMsg;
|
}
|
|
}
|
|
|
|
}
|
catch (Exception ex)
|
{
|
SystemWarningMsg._lbl_Alert_OutPlanTaskHandler = "错误信息:" + ex;
|
}
|
}
|
|
|
/// <summary>
|
/// 模拟完成 上、下架
|
/// </summary>
|
/// <param name="mycontext"></param>
|
/// <param name="singleTask"></param>
|
/// <param name="errMsg"></param>
|
/// <returns></returns>
|
private static int OrderMovementFinishTask(MyDbContext mycontext, wms_task singleTask, ref string errMsg)
|
{
|
|
try
|
{
|
|
//获取移动单
|
var moveOrder = BaseInfoHelper.GetOrderMovement(mycontext, singleTask, ref errMsg);
|
var moveOrderDetails = BaseInfoHelper.GetMoveOrderDetails(mycontext, singleTask, moveOrder, ref errMsg);
|
|
//获取业务类型
|
var wmsBusinessType = BusinessTypeHelper.GetBusinessTypeInfoFromDB(moveOrder.BusinessType, mycontext);
|
|
|
|
//查询库位
|
//目标库位校验
|
var toPlace =BaseInfoHelper.GetPlace(mycontext, singleTask.ToPlaceCode, "目标库位", ref errMsg);
|
//目标库区
|
|
var toArea = BaseInfoHelper.GetArea(mycontext, singleTask.ToAreaCode, "目标库区", ref errMsg);
|
|
////源库位校验
|
var sourcePlace = BaseInfoHelper.GetPlace(mycontext, singleTask.SourcePlaceCode, "源库位", ref errMsg);
|
|
|
//解锁起始、目标库位
|
sourcePlace.PlaceStatus = (int)PlaceStatusEnum.正常;
|
toPlace.PlaceStatus = (int)PlaceStatusEnum.正常;
|
|
//查询容器
|
var container = BaseInfoHelper.GetContainer(mycontext, singleTask.ContainerCode, ref errMsg);
|
|
//更新库位容器绑定关系
|
UpdaeContainerPlace(mycontext, singleTask, container, toPlace, ref errMsg);
|
|
|
//更新库存
|
//上架更新库存状态=》已上架
|
//下架更新冻结状态=》未冻结
|
//创建事务记录
|
//非下架、上架仅创建事务记录(因为变更了库位)
|
UpdateStockQuan(mycontext, wmsBusinessType, singleTask, moveOrder, container, toPlace, toArea, ref errMsg);
|
|
#region 处理移动单
|
//处理移动单(上架单、下架单)
|
|
//上架单或下架单业务类型设置了 自动完成 就 自动完成单据
|
bool isFinish = false;
|
if (wmsBusinessType.UpDownShelvesType == (int)UpDownShelvesTypeEnum.上架 || wmsBusinessType.BusinessTypeValue==(int)BusinessTypeEnum.盘点下架||
|
wmsBusinessType.DownShelvesIsAutoFinish == true)
|
{
|
isFinish = true;
|
}
|
|
if (isFinish)
|
{
|
if (moveOrderDetails.Any(a => string.IsNullOrWhiteSpace(a.ContainerCode)))
|
{
|
errMsg = $"{moveOrder.OrderTypeName}类型移动单{moveOrder.OrderNo}存在容器为空的移动单明细";
|
return 3;
|
}
|
//上架调度任务自动完成上架单
|
var updateMoveOrderDetails = moveOrderDetails.Where(w => w.ContainerCode.Equals(container.ContainerCode)).ToList();
|
|
if (updateMoveOrderDetails?.Count <= 0)
|
{
|
errMsg = $"{moveOrder.OrderTypeName}类型移动单{moveOrder.OrderNo}不存在容器为{container.ContainerCode}的移动单明细";
|
return 3;
|
}
|
foreach (var item in updateMoveOrderDetails)
|
{
|
item.OrderStatus = (int)OrderStatusEnum.已完成;
|
item.OrderStatusName = OrderStatusEnum.已完成.ToString();
|
item.UpdateTime = DateTime.Now;
|
item.UpdateUserId = 0;
|
item.UpdateUserName =FormCC.WcsSysUserName;
|
}
|
|
//更新移动单时间信息
|
UpdatOrderMovementStatus(moveOrderDetails, moveOrder, ref errMsg);
|
}
|
|
//盘点下架以外的下架不处理下架单,PDA分拣或自动完成分拣后完成下架单
|
|
#endregion
|
|
singleTask.TaskStatus = (int)TaskStatusEnum.已完成;//更新任务状态为 已完成
|
singleTask.TaskStatusName = TaskStatusEnum.已完成.ToString();
|
singleTask.UpdateTime = DateTime.Now;
|
singleTask.TaskMsg = "任务完成";
|
singleTask.FinishedTime = DateTime.Now;
|
|
mycontext.SaveChanges();
|
return 3;
|
}
|
catch (Exception ex)
|
{
|
SystemWarningMsg._lbl_Alert_OutPlanTaskHandler = "错误信息:" + ex;
|
return 2;
|
}
|
|
}
|
|
// <summary>
|
/// 公共更新 移动单的 状态
|
/// </summary>
|
/// <param name="wmsOrderAsnDetails"></param>
|
/// <param name="wmsOrderAsn"></param>
|
public static void UpdatOrderMovementStatus(List<wms_order_movement_details> wmsOrderMovementDetails, wms_order_movement wmsOrderMovement, ref string errMsg)
|
{
|
|
var wmsOrderMovementDetailsAll = wmsOrderMovementDetails.Where(x => x.MovementId == wmsOrderMovement.Id && x.IsDelete == false).ToList();
|
if (wmsOrderMovementDetailsAll?.Count <= 0)
|
{
|
errMsg = $"{wmsOrderMovement.OrderTypeName}类型移动单{wmsOrderMovement.OrderNo}更新状态,未获取到明细!";
|
}
|
else
|
{
|
int sttaus = (int)OrderStatusEnum.已完成;
|
//汇总已完成的明细
|
var totalOffShelvesCount = wmsOrderMovementDetailsAll.Count(o => o.OrderStatus == sttaus);
|
//单据有所明细数量
|
var totalTount = wmsOrderMovementDetailsAll.Count();
|
|
|
if (totalOffShelvesCount == totalTount) //单据完结
|
{
|
|
wmsOrderMovement.OrderStatus = (int)OrderStatusEnum.已完成;
|
wmsOrderMovement.OrderStatusName = OrderStatusEnum.已完成.ToString();
|
|
//更新时间信息
|
wmsOrderMovement.UpdateTime = DateTime.Now;
|
wmsOrderMovement.UpdateUserId = 0;
|
wmsOrderMovement.UpdateUserName =FormCC.WcsSysUserName;
|
}
|
|
|
|
}
|
}
|
|
|
|
/// <summary>
|
/// 更新库存
|
/// </summary>
|
/// <param name="mycontext"></param>
|
/// <param name="wmsBusinessType"></param>
|
/// <param name="singleTask"></param>
|
/// <param name="moveOrder"></param>
|
/// <param name="updateStockList"></param>
|
/// <param name="updateStockViewList"></param>
|
/// <param name="toPlace"></param>
|
/// <param name="toArea"></param>
|
/// <param name="errMsg"></param>
|
/// <exception cref="Exception"></exception>
|
private static void UpdateStockQuan(MyDbContext mycontext, wms_base_business_type wmsBusinessType, wms_task singleTask, wms_order_movement moveOrder, wms_base_container container, wms_base_place toPlace, wms_base_area toArea, ref string errMsg)
|
{
|
|
//不是 上架,不是下架 不处理库存,仅操作库位转移
|
|
string remark = singleTask.BusinessTypeName + "-完成调度任务";
|
|
var updateStockList = GetWmsStockQuanList(mycontext, container, ref errMsg);
|
var updateStockViewList = GetWmsStockQuanViewList(mycontext, updateStockList, ref errMsg);
|
|
|
|
|
foreach (var currentStock in updateStockList)
|
{
|
//再次之前库存的库位已经发生了变更
|
|
//上架
|
if (wmsBusinessType.UpDownShelvesType== (int)UpDownShelvesTypeEnum.上架)
|
{
|
// 待上架的库存,上架操作完成后变成 已上架
|
if (currentStock.StockStatus == (int)StockStatusEnum.待上架)
|
{
|
currentStock.StockStatus = (int)StockStatusEnum.已上架;
|
currentStock.StockStatusName = StockStatusEnum.已上架.ToString();
|
|
}
|
|
}
|
//下架
|
else if (wmsBusinessType.UpDownShelvesType == (int)UpDownShelvesTypeEnum.下架)
|
{
|
|
//盘点上架或 盘点下架 不解冻库存 调差解冻
|
//下架任务完成不解冻库存,分拣完成后操作解冻
|
//没有分拣环节的 业务类型需要配置 自动完成单据,这里就解冻
|
if (wmsBusinessType.DownShelvesIsAutoFinish == true && moveOrder.BusinessType != (int)BusinessTypeEnum.盘点下架)
|
{
|
LockInfo freezeInfo = new LockInfo()
|
{
|
LockReason = "调度任务完成",
|
LockTime = DateTime.Now,
|
LockUser =FormCC.WcsSysUserName,
|
LockStatus = LockStatusEnum.未锁定,//
|
};
|
StockQuanHelper.UpdateStockLockStatus(currentStock, freezeInfo);
|
}
|
|
}
|
|
|
//在此之前库存的库位已经发生了变更
|
//更新时间信息
|
currentStock.UpdateTime = DateTime.Now;
|
currentStock.UpdateUserId = 0;
|
currentStock.UpdateUserName =FormCC.WcsSysUserName;
|
|
#region 添加调度任务
|
|
var currentStockQuanView = updateStockViewList.FirstOrDefault(f => f.SNCode.Equals(currentStock.SNCode));
|
if (currentStockQuanView == null)
|
{
|
errMsg = $"跟踪码{currentStock.SNCode}没有获取到库存信息";
|
throw new Exception(errMsg);
|
}
|
wms_record_trans addWmsRecordTrans = CreateRecordTransInfo(moveOrder, currentStockQuanView, singleTask, currentStock, toPlace, toArea, remark);
|
mycontext.wms_record_trans.Add(addWmsRecordTrans);
|
#endregion
|
|
}
|
|
|
}
|
|
|
|
/// <summary>
|
///
|
/// </summary>
|
/// <param name="order"></param>
|
/// <param name="currentStockQuanView"></param>
|
/// <param name="task"></param>
|
/// <param name="StockModel"></param>
|
/// <param name="recordTransRemarks"></param>
|
/// <returns></returns>
|
private static wms_record_trans CreateRecordTransInfo(wms_order_movement order, v_wms_stock_quan currentStockQuanView, wms_task task , wms_stock_quan StockModel, wms_base_place toPlace, wms_base_area toArea, string recordTransRemarks)
|
{
|
|
try
|
{
|
|
|
TransferOtherDetail transferOtherDetail = new TransferOtherDetail()
|
{
|
RelationNo = order.OrderNo,//上架单号
|
RelationNoLineNumber = string.Empty,//上架 关联单行号 无法精准获取
|
Remarks = recordTransRemarks,
|
|
};
|
|
|
|
//源信息
|
//新增的库存源信息都
|
TransferDetail sourceDetail = new TransferDetail()
|
{
|
SNCode = currentStockQuanView.SNCode,//源跟踪码
|
Quantity = currentStockQuanView.Quantity,//源库存数
|
StockStatus = currentStockQuanView.StockStatus,//源库存状态
|
StockStatusName = currentStockQuanView.StockStatusName,//源库存状态名称
|
StockQcStatus = currentStockQuanView.QCStatus,//源质量状态
|
StockQcStatusName = currentStockQuanView.QCStatusName,//源质量状态名称
|
ContainerCode = currentStockQuanView.ContainerCode,//源容器编号
|
ContainerName = currentStockQuanView.ContainerCode,//源容器名称
|
AreaCode = currentStockQuanView.AreaCode,//源库区编号
|
AreaName = currentStockQuanView.AreaName,//源库区名称
|
PlaceCode = currentStockQuanView.PlaceCode,//源库位编号
|
PlaceName = currentStockQuanView.PlaceName//源库位名称
|
|
};
|
//目标信息 确认质检产生的心得库存 库区、库位 容器跟源库存一样
|
TransferDetail targetDetail = new TransferDetail()
|
{
|
SNCode = StockModel.SNCode,//目标跟踪码
|
Quantity = StockModel.Quantity,//目标库存数
|
StockStatus = StockModel.StockStatus,//目标库存状态
|
StockStatusName = StockModel.StockStatusName,//目标库存状态名称
|
StockQcStatus = StockModel.QCStatus,//目标质量状态
|
StockQcStatusName = StockModel.QCStatusName,//目标质量状态名称
|
ContainerCode = StockModel.ContainerCode,//目标容器编号
|
ContainerName = StockModel.ContainerCode,//目标容器名称
|
AreaCode = toArea.AreaCode,//目标库区编号
|
AreaName = toArea.AreaName,//目标库区名称
|
PlaceCode = toPlace.PlaceCode,//目标库位编号
|
PlaceName = toPlace.PlaceName//目标库位名称
|
};
|
|
wms_record_trans addWmsRecordTrans = LogRecordHelper.CreateWmsRecordTrans(task, currentStockQuanView, sourceDetail, targetDetail, transferOtherDetail);
|
|
|
return addWmsRecordTrans;
|
}
|
catch (Exception ex)
|
{
|
|
throw ex;
|
|
|
}
|
}
|
|
|
/// <summary>
|
/// 更新容器库位关系
|
/// </summary>
|
/// <param name="mycontext"></param>
|
/// <param name="singleTask"></param>
|
/// <param name="container"></param>
|
/// <param name="toPlace"></param>
|
/// <param name="errMsg"></param>
|
private static void UpdaeContainerPlace(MyDbContext mycontext, wms_task singleTask, wms_base_container container, wms_base_place toPlace, ref string errMsg)
|
{
|
var containerPlaceList = mycontext.wms_container_place.Where(f => f.ContainerCode == singleTask.ContainerCode).ToList();
|
if (containerPlaceList?.Count <= 0)
|
{
|
//新增库位关系绑定到目标容器
|
wms_container_place addContainerPlace = new wms_container_place()
|
{
|
Id = Yitter.IdGenerator.YitIdHelper.NextId(),
|
PlaceCode = toPlace.PlaceCode,
|
PlaceName = toPlace.PlaceName,
|
PlaceId = toPlace.Id,
|
ContainerName = container.ContainerName,
|
ContainerId = container.Id,
|
ContainerCode = singleTask.ContainerCode
|
};
|
addContainerPlace.PlaceCode = singleTask.ToPlaceCode;
|
addContainerPlace.PlaceName = toPlace.PlaceName;
|
addContainerPlace.PlaceId = toPlace.Id;
|
|
|
addContainerPlace.CreateTime = DateTime.Now;
|
addContainerPlace.CreateUserId = 0;
|
addContainerPlace.CreateUserName =FormCC.WcsSysUserName;
|
//addContainerPlace.UpdateTime = DateTime.Now;
|
//addContainerPlace.UpdateUserId = 0;
|
//addContainerPlace.UpdateUserName =FormCC.WcsSysUserName;
|
|
mycontext.wms_container_place.Add(addContainerPlace);
|
}
|
else
|
{
|
if (containerPlaceList.Count > 1)
|
{
|
errMsg = $"库位号{singleTask.ToPlaceCode},容器{singleTask.ContainerCode}有{containerPlaceList.Count}条绑定关系";
|
throw new Exception(errMsg);
|
}
|
else
|
{
|
containerPlaceList.First().PlaceId = toPlace.Id;
|
containerPlaceList.First().PlaceCode = toPlace.PlaceCode;
|
containerPlaceList.First().PlaceName = toPlace.PlaceName;
|
|
containerPlaceList.First().UpdateTime = DateTime.Now;
|
containerPlaceList.First().UpdateUserId = 0;
|
containerPlaceList.First().UpdateUserName =FormCC.WcsSysUserName;
|
}
|
}
|
|
|
}
|
|
/// <summary>
|
/// 获取库存详情信息-查询wms_stock_quan(表)
|
/// </summary>
|
/// <param name="mycontext"></param>
|
/// <param name="container"></param>
|
/// <param name="errMsg"></param>
|
/// <returns></returns>
|
private static List<wms_stock_quan> GetWmsStockQuanList(MyDbContext mycontext,wms_base_container container, ref string errMsg)
|
{
|
|
var updateStockList = mycontext.wms_stock_quan.Where(f => container.ContainerCode.Equals(f.ContainerCode)).ToList();
|
if (updateStockList?.Count <= 0)
|
{
|
errMsg = $"容器{container.ContainerCode}库存不存在";
|
throw new Exception(errMsg);
|
|
}
|
|
return updateStockList;
|
}
|
|
/// <summary>
|
/// 获取库存详情信息-查询v_wms_stock_quan(视图)
|
/// </summary>
|
/// <param name="mycontext"></param>
|
/// <param name="updateStockList"></param>
|
/// <param name="errMsg"></param>
|
/// <returns></returns>
|
private static List<v_wms_stock_quan> GetWmsStockQuanViewList(MyDbContext mycontext, List<wms_stock_quan> updateStockList, ref string errMsg)
|
{
|
|
var snCodeList = updateStockList.Select(s => s.SNCode).ToList();
|
|
var updateStockViewList = mycontext.v_wms_stock_quan.Where(f => snCodeList.Contains(f.SNCode)).ToList();
|
if (updateStockViewList?.Count <= 0)
|
{
|
errMsg = $"根据库存跟踪码没有获取到库存详情";
|
throw new Exception(errMsg);
|
|
}
|
|
return updateStockViewList;
|
}
|
|
|
|
}
|
}
|