/*
*所有关于Dt_TaskWCSinfo类的业务代码应在此处编写
*可使用repository.调用常用方法,获取EF/Dapper等信息
*如果需要事务请使用repository.DbContextBeginTransaction
*也可使用DBServerProvider.手动获取数据库相关信息
*用户信息、权限、角色等使用UserContext.Current操作
*Dt_TaskWCSinfoService对增、删、改查、导入、导出、审核业务代码扩展参照ServiceFunFilter
*/
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using WIDESEA_Common;
using WIDESEA_Common.CutomerModel;
using WIDESEA_Common.TaskEnum;
using WIDESEA_Common.Tools;
using WIDESEA_Core.BaseProvider;
using WIDESEA_Core.Extensions;
using WIDESEA_Core.Extensions.AutofacManager;
using WIDESEA_Core.Utilities;
using WIDESEA_Entity.DomainModels;
using WIDESEA_Services.IRepositories;
using WIDESEA_Services.Repositories;
namespace WIDESEA_Services.Services
{
public partial class Dt_TaskWCSinfoService
{
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly IDt_TaskWCSinfoRepository _repository;//访问数据库
[ActivatorUtilitiesConstructor]
public Dt_TaskWCSinfoService(
IDt_TaskWCSinfoRepository dbRepository,
IHttpContextAccessor httpContextAccessor
)
: base(dbRepository)
{
_httpContextAccessor = httpContextAccessor;
_repository = dbRepository;
//多租户会用到这init代码,其他情况可以不用
//base.Init(dbRepository);
}
///
/// 根据WMS下发的任务,添加WCS任务
///
///
///
public WebResponseContent AddTaskByWms(List taskInfos)
{
WebResponseContent content = new WebResponseContent();
try
{
List wcsTaskList = new List();
List rgvTaskList = new List();
foreach (var taskInfo in taskInfos)
{
if (repository.Exists(x => x.wcstask_barcode == taskInfo.task_barcode))
return content.Error(taskInfo.task_barcode + "已存在未完成的任务,请先检查。");
if (taskInfo.task_type.Contains("Inbound"))
if (repository.Exists(x => x.wcstask_startPoint == "20101" && x.wcstask_state == TaskState.TaskState_Assigned.ToString()))
return content.Error("当前存在待执行的入库任务,请等待.");
//空托盘入库
if (taskInfo.task_type == TaskType.TaskType_Empty_Pallet_Inbound.ToString())
{
Dt_TaskWCSinfo wcsInfo = CommonFunction.AddWCSEmptyInboundTask(taskInfo, Dt_TaskWCSinfoRepository.Instance);
wcsTaskList.Add(wcsInfo);
}
//空托盘出库
else if (taskInfo.task_type == TaskType.TaskType_Empty_Pallet_Outbound.ToString())
{
Dt_TaskWCSinfo wcsInfo = CommonFunction.AddWCSEmptyOutboundTask(taskInfo);
wcsTaskList.Add(wcsInfo);
if (taskInfo.task_endstation.Equal("20101"))
{
Dt_TaskRGVinfo rgvInfo = CommonFunction.AddOutboundTask(taskInfo, wcsInfo);
rgvTaskList.Add(rgvInfo);
}
}
//实托入库
else if (taskInfo.task_type == TaskType.TaskType_Box_Pallet_Inbound.ToString() || taskInfo.task_type == TaskType.TaskType_ErrorCheckBackIn.ToString()
|| taskInfo.task_type == TaskType.TaskType_CheckBackIn.ToString())
{
Dt_TaskWCSinfo wcsInfo = CommonFunction.AddWCSBoxInboundTask(taskInfo);
wcsTaskList.Add(wcsInfo);
}
//实托出库
else if (taskInfo.task_type == TaskType.TaskType_Box_Pallet_Outbound.ToString()|| taskInfo.task_type == TaskType.TaskType_CheckOutbound.ToString())
{
Dt_TaskWCSinfo wcsInfo = CommonFunction.AddWCSBoxOutboundTask(taskInfo);
wcsTaskList.Add(wcsInfo);
//入库区才直接添加AGV任务
if (taskInfo.task_endstation.Equal("20101"))
{
Dt_TaskRGVinfo rgvInfo = CommonFunction.AddOutboundTask(taskInfo, wcsInfo);
rgvTaskList.Add(rgvInfo);
}
}
//轴承测量出库
else if (taskInfo.task_type == TaskType.TaskType_Box_Pallet_Measure_Out.ToString())
{
Dt_TaskWCSinfo wcsInfo = CommonFunction.AddWCSMeasureOutboundTask(taskInfo);
wcsTaskList.Add(wcsInfo);
Dt_TaskRGVinfo rgvInfo = CommonFunction.AddOutboundTask(taskInfo, wcsInfo);
rgvTaskList.Add(rgvInfo);
}
//轴承测量完成后回库-----【该类任务不是WMS下发的,而是WCS在测量完成后,自动转变为该类任务的】
else if (taskInfo.task_type == TaskType.TaskType_Box_Pallet_Measure_Back.ToString())
{
}
else if (taskInfo.task_type == TaskType.TaskType_MoveOutbound.ToString())
{
Dt_TaskWCSinfo wcsInfo = CommonFunction.AddWCSMoveOutboundTask(taskInfo);
wcsTaskList.Add(wcsInfo);
string[] fromLocationArray = wcsInfo.wcstask_startLocation.Split('-');
string[] toLocationArray = wcsInfo.wcstask_endLocation.Split('-');
if (fromLocationArray[0] == toLocationArray[0])
{
Dt_TaskRGVinfo moveOutbound = CommonFunction.AddRGVMoveOutboundTask(taskInfo, wcsInfo, RGVTaskType.RgvTaskType_Move);
rgvTaskList.Add(moveOutbound);
}
else
{
Dt_TaskRGVinfo moveInbound = CommonFunction.AddRGVMoveOutboundTask(taskInfo, wcsInfo, RGVTaskType.RgvTaskType_Outbound);
rgvTaskList.Add(moveInbound);
}
}
else
throw new Exception("无效任务类型:" + taskInfo.task_type);
}
if (null != wcsTaskList && wcsTaskList.Count > 0)
{
content = repository.DbContextBeginTransaction(() =>
{
repository.AddRange(wcsTaskList, true);
if (null != rgvTaskList && rgvTaskList.Count > 0)
repository.AddRange(rgvTaskList, true);
return content.OK();
});
}
}
catch (Exception ex)
{
content.Error(ex.Message);
}
return content;
}
///
/// 取消一条未开始执行的任务
///
///
///
public WebResponseContent CancelATask(SaveModel saveModel)
{
WebResponseContent content = new WebResponseContent();
try
{
string barcode = saveModel.MainData["barcode"].ToString();
if (barcode == null)
throw new Exception("取消任务的托盘号不能为空");
Dt_TaskWCSinfo taskinfo = Dt_TaskWCSinfoRepository.Instance.FindFirst(x => x.wcstask_barcode == barcode);
if (taskinfo == null)
return content.OK($"没有找到托盘号:【{barcode}】对应的任务");
if (taskinfo.wcstask_state != TaskState.TaskState_Assigned.ToString())
throw new Exception($"托盘号:【{barcode}】对应的任务已经开始执行,无法取消");
content = Dt_TaskWCSinfoRepository.Instance.DbContextBeginTransaction(() =>
{
Dt_TaskWCSinfoRepository.Instance.Delete(taskinfo, true);
Dt_TaskRGVinfo rgvInfo = Dt_TaskRGVinfoRepository.Instance.FindFirst(x => x.rgvtask_barCode == barcode && x.rgvtask_taskStatus == RGVTaskState.RgvTaskState_Wait_Send.ToString());
if (rgvInfo != null)
Dt_TaskRGVinfoRepository.Instance.Delete(rgvInfo, true);
return content.OK();
});
}
catch (Exception ex)
{
content.Error(ex.Message);
}
return content;
}
///
/// WMS下发的更改任务状态,给测量设备测量完毕后,更新WCS任务状态
///
///
///
public WebResponseContent UpdateWcsTaskState(SaveModel saveModel)
{
WebResponseContent content = new WebResponseContent();
try
{
string barcode = saveModel.MainData["barcode"].ToString();
string state = saveModel.MainData["state"].ToString();
string taskType = saveModel.MainData["tasktype"].ToString();
Dt_TaskWCSinfo wcsInfo = Dt_TaskWCSinfoRepository.Instance.FindFirst(x => x.wcstask_barcode == barcode);
if (wcsInfo != null)
{
//更新任务数据,准备回库,起点终点倒换
string endLoc = wcsInfo.wcstask_endPoint;
wcsInfo.wcstask_state = TaskState.TaskState_Measure_Back_Line_Executing.ToString();
wcsInfo.wcstask_endPoint = wcsInfo.wcstask_startPoint;
wcsInfo.wcstask_endLocation = wcsInfo.wcstask_startLocation;
wcsInfo.wcstask_startLocation = endLoc;
wcsInfo.wcstask_startPoint = "10301";
wcsInfo.wcstask_state = state;
wcsInfo.wcstask_type = taskType;
Dt_TaskWCSinfoRepository.Instance.Update(wcsInfo, true);
}
else
{
content.Error($"没有找到托盘码:【{barcode}】对应的任务!!");
return content;
}
content.OK();
}
catch (Exception ex)
{
content.Error(ex.Message);
}
return content;
}
///
/// 手动更改任务状态
///
///
///
public static WebResponseContent ChangeWcsTaskStatus(SaveModel saveModel)
{
WebResponseContent content = new WebResponseContent();
try
{
int taskNumer = int.Parse(saveModel.MainData["taskNumber"].ToString());
string state = saveModel.MainData["state"].ToString();
Dt_TaskWCSinfo wcsInfo = Dt_TaskWCSinfoRepository.Instance.FindFirst(x => x.wcstask_taskNumber == taskNumer);
if (wcsInfo == null)
{
content.Error($"::Error::没有找到任务号:【{taskNumer}】对应的任务!");
return content;
}
content = Dt_TaskWCSinfoRepository.Instance.DbContextBeginTransaction(() =>
{
try
{
content = WMSApi.PostTaskStateToWMS(wcsInfo.wcstask_barcode, state);
if (content.Status)
{
wcsInfo.wcstask_state = state;
if (state == TaskState.TaskState_Measure_Back_Line_Executing.ToString())
{
//将任务类型改为回库中
wcsInfo.wcstask_type = TaskType.TaskType_Box_Pallet_Measure_Back.ToString();
//将任务起始站台和目的站台对调,准备回库
wcsInfo.wcstask_endPoint = wcsInfo.wcstask_startPoint;
wcsInfo.wcstask_startPoint = "10301";
wcsInfo.wcstask_endLocation = wcsInfo.wcstask_startLocation;
wcsInfo.wcstask_startLocation = wcsInfo.wcstask_endPoint;
wcsInfo.wcstask_state = TaskState.TaskState_Measure_Back_Line_Executing.ToString();
wcsInfo.wcstask_dispatcherTime = DateTime.Now;
}
Dt_TaskWCSinfoRepository.Instance.Update(wcsInfo, true);
WriteLog.Info("手动更改测量状态").Write($"{DateTime.Now}:测量回库异常,反转货位 任务号{taskNumer},托盘号{wcsInfo.wcstask_barcode},反转后起始站台【10301】" +
$"终点货位【{wcsInfo.wcstask_endLocation}】", "手动更改测量状态");
}
else
{
content.Error($"::Error::上报WMS更新任务号:【{taskNumer}】对应的任务出错!原因:{content.Message}");
return content;
}
content.OK();
}
catch (Exception ex)
{
content.Error(ex.Message);
}
return content;
});
if (content.Status)
{
Dt_TaskRGVinfoRepository taskRGVinfoRepository = new Dt_TaskRGVinfoRepository(Dt_TaskRGVinfoRepository.Instance.DbContext);
//根据任务类型和更改的任务状态,进行接着的逻辑
if (wcsInfo.wcstask_type == TaskType.TaskType_Box_Pallet_Inbound.ToString() ||
wcsInfo.wcstask_type == TaskType.TaskType_Empty_Pallet_Inbound.ToString())
{
//比如手动操作系统将托盘运送至入库口,则需要生成对应的穿梭车任务
if (state == TaskState.TaskState_ConveyorLineFinish.ToString())
{
Dt_TaskRGVinfo rgvInfo = new Dt_TaskRGVinfo();
rgvInfo.rgvtask_taskId = GetTaskNumber.GetRgvTaskNumber().ToString();
rgvInfo.rgvtask_taskType = RGVTaskType.RgvTaskType_Inbound.ToString();
rgvInfo.rgvtask_taskStatus = RGVTaskState.RgvTaskState_Wait_Send.ToString();
rgvInfo.rgvtask_priorityCode = wcsInfo.wcstask_grade.ToString();
rgvInfo.rgvtask_startNode = wcsInfo.wcstask_startLocation;
rgvInfo.rgvtask_endNode = wcsInfo.wcstask_endLocation;
rgvInfo.rgvtask_wcsTaskNumber = wcsInfo.wcstask_taskNumber;
rgvInfo.rgvtask_barCode = wcsInfo.wcstask_barcode;
rgvInfo.rgvtask_msgTime = DateTime.Now;
rgvInfo.rgvtask_areaCode = "InboundArea";
taskRGVinfoRepository.Add(rgvInfo, true);
}
}
else
{
}
}
}
catch (Exception ex)
{
content.Error(ex.Message);
}
return content;
}
///
/// WMS下发更改任务信息,当入库任务与出库测量任务冲突时,WMS调用此接口来更换目的货位
///
///
///
public WebResponseContent UpdateWcsTaskInformation(SaveModel saveModel)
{
WebResponseContent content = new WebResponseContent();
try
{
string barcode = saveModel.MainData["barcode"].ToString();
string newLocationId = saveModel.MainData["newLocationId"].ToString();
string newStation = saveModel.MainData["newStation"].ToString();
Dt_TaskWCSinfo wcsInfo = Dt_TaskWCSinfoRepository.Instance.FindFirst(x => x.wcstask_barcode == barcode);
if (wcsInfo == null)
{
Console.WriteLine($"::Error::=> WMS下发新货位是,在WCS任务中没有找到对应托盘【{barcode}】的号的任务");
return content.Error($"::Error::=> WMS下发新货位是,在WCS任务中没有找到对应托盘【{barcode}】的号的任务");
}
wcsInfo.wcstask_startLocation = newStation;
wcsInfo.wcstask_endPoint = newStation;
wcsInfo.wcstask_endLocation = newLocationId;
Dt_TaskWCSinfoRepository.Instance.Update(wcsInfo, true);
content.OK();
}
catch (Exception ex)
{
content.Error(ex.Message);
}
return content;
}
///
/// 取消测量,直接回库
///
///
///
public WebResponseContent CancelAMeasureTask(SaveModel saveModel)
{
WebResponseContent content = new WebResponseContent();
try
{
string barcode = saveModel.MainData["barcode"].ToString();
Dt_TaskWCSinfo wcsInfo = Dt_TaskWCSinfoRepository.Instance.FindFirst(x => x.wcstask_barcode == barcode);
if (wcsInfo == null)
{
Console.WriteLine($"::Error::=> 没有找到【{barcode}】对应的测量任务");
return content.Error($"::Error::=> 没有找到【{barcode}】对应的测量任务");
}
//将任务类型改为回库中
wcsInfo.wcstask_type = TaskType.TaskType_Box_Pallet_Measure_Back.ToString();
//将任务起始站台和目的站台对调,准备回库
wcsInfo.wcstask_endPoint = wcsInfo.wcstask_startPoint;
wcsInfo.wcstask_startPoint = "10301";
wcsInfo.wcstask_endLocation = wcsInfo.wcstask_startLocation;
wcsInfo.wcstask_startLocation = wcsInfo.wcstask_endPoint;
wcsInfo.wcstask_state = TaskState.TaskState_Measure_Back_Line_Wait_Executing.ToString();
wcsInfo.wcstask_dispatcherTime = DateTime.Now;
Dt_TaskWCSinfoRepository.Instance.Update(wcsInfo, true);
content.OK();
}
catch (Exception ex)
{
content.Error(ex.Message);
}
return content;
}
///
/// 手动完成一个WCS任务(目前仅支持手动完成空托盘出库功能,因为空托盘到了缓存位经常有人手动去动)
///
///
///
public static WebResponseContent CompleteWcsTaskByMannual(SaveModel saveModel)
{
WebResponseContent content = new WebResponseContent();
try
{
int taskNumer = int.Parse(saveModel.MainData["taskNumber"].ToString());
Dt_TaskWCSinfo taskWCSinfo = Dt_TaskWCSinfoRepository.Instance.FindFirst(x => x.wcstask_taskNumber == taskNumer);
if (taskWCSinfo == null)
throw new Exception($"没有找到任务号:【{taskNumer}】对应的WCS任务");
//在此完成该空托出库任务
content = Dt_TaskWCSinfoRepository.Instance.DbContextBeginTransaction(() =>
{
WebResponseContent transContent = new WebResponseContent();
try
{
//上报WMS任务完成
transContent = WMSApi.TellWmsTaskFinished(taskWCSinfo.wcstask_barcode,taskWCSinfo.wcstask_backUp_2);
if (transContent.Status)
{
//移动任务到历史表
taskWCSinfo.wcstask_state = TaskState.TaskState_Finished.ToString();
CommonFunction.AddWcsTaskToHistory(taskWCSinfo, Dt_TaskWCSinfoRepository.Instance, Dt_TaskWCSinfo_HtyRepository.Instance);
}
else
{
throw new Exception($"上报WMS任务完成出错,原因:【{transContent.Message}】");
}
transContent.OK();
}
catch (Exception ex)
{
transContent.Error(ex.Message);
}
return transContent;
});
if (!content.Status)
throw new Exception($"::Error::=> 手动完成任务出错,原因:{content.Message}");
}
catch (Exception ex)
{
content.Error(ex.Message);
}
return content;
}
}
}