using AutoMapper;
using Kean.Domain.Task.Commands;
using Kean.Domain.Task.Enums;
using Kean.Domain.Task.Events;
using Kean.Domain.Task.Repositories;
using Kean.Domain.Task.SharedServices.Proxies;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Linq;
using System.Threading;
namespace Kean.Domain.Task.CommandHandlers
{
///
/// 任务完成命令处理程序
///
public sealed class CompleteCommandHandler : CommandHandler
{
private readonly ICommandBus _commandBus; // 命令总线
private readonly IMapper _mapper; // 模型映射
private readonly ITaskRepository _taskRepository; // 任务仓库
private readonly IWarehouseRepository _warehouseRepository; // 库房仓库
private readonly StockProxy _stockProxy; // 仓储域
private readonly WcsProxy _wcsProxy;
private readonly Kean.Infrastructure.Soap.LED.LedService _ledService;
private readonly INotification _notifications; // 总线通知
private readonly ILogger _logger; // 日志
///
/// 依赖注入
///
public CompleteCommandHandler(
ICommandBus commandBus,
IMapper mapper,
ITaskRepository taskRepository,
IWarehouseRepository warehouseRepository,
WcsProxy wcsProxy,
Kean.Infrastructure.Soap.LED.LedService ledService,
ILogger logger,
INotification notifications,
StockProxy stockProxy)
{
_commandBus = commandBus;
_mapper = mapper;
_taskRepository = taskRepository;
_warehouseRepository = warehouseRepository;
_wcsProxy = wcsProxy;
_stockProxy = stockProxy;
_ledService = ledService;
_notifications = notifications;
_logger = logger;
}
///
/// 处理程序
///
public override async System.Threading.Tasks.Task Handle(CompleteCommand command, CancellationToken cancellationToken)
{
if (command.ValidationResult.IsValid)
{
var task = await _taskRepository.GetTask(command.Id);
if (task != null)
{
if (task.ManageStatus == TaskState.ScanError.ToString() && command.ManualFlg != 1)
{
}
else
{
if (task.Type != TaskType.ApplyOut && task.Type != TaskType.PalletOut && task.Type != TaskType.Bypass)
{
int? cellId = await _stockProxy.GetCell(task.Barcode);
int originalCellId = cellId.HasValue ? cellId.Value : task.Original;
await _warehouseRepository.ReleaseCell(task.TransitPlace == 0 ? originalCellId : task.TransitPlace, task.Destination);
}
//await _taskRepository.DeleteTask(command.Id);
string isAgv = string.Empty;
bool bDeleteWcs = (task.Tag != "@Avert");
// 前端人工操作
if (command.ManualFlg == 1)
{
if (!string.IsNullOrEmpty(task.Tag) && (task.Tag != "@Avert"))
{
try
{
JObject jObj = JObject.Parse(task.Tag);
JToken manualFlg = jObj.SelectToken("ManualFlg");
if (manualFlg == null)
{
jObj.Add("ManualFlg", command.ManualFlg);
}
JToken transaction = jObj.SelectToken("Transaction");
if (transaction == null)
{
jObj.Add("Transaction", task.Type.ToString());
}
JToken @operator = jObj.SelectToken("Operator");
if (@operator == null)
{
jObj.Add("Operator", command.Operator);
}
else
{
jObj["Operator"] = command.Operator;
}
if (command.IsCancelAgv == "1")
{
jObj["isAgv"] = "0";
}
if (command.IsCancelHiwms == "1")
{
jObj.Add("IsCancelHiwms", command.IsCancelHiwms);
jObj.Remove("orderInfo");
jObj.Remove("backupOrderInfo");
}
isAgv = jObj["isAgv"].ToString();
task.Tag = JsonConvert.SerializeObject(jObj);
}
catch
{
task.Tag = JsonConvert.SerializeObject(new
{
ManualFlg = command.ManualFlg,
Transaction = task.Type.ToString(),
Operator = command.Operator
});
}
}
else
{
task.Tag = JsonConvert.SerializeObject(new
{
ManualFlg = command.ManualFlg,
Transaction = task.Type.ToString(),
Operator = command.Operator
});
}
if (task.Type != TaskType.ApplyOut && task.Type != TaskType.PalletOut && bDeleteWcs)
{
await _wcsProxy.DeleteWcs(task.Id, $"人工完成");
}
}
if (task.Type == TaskType.ApplyOut || task.Type == TaskType.PalletOut || task.Type == TaskType.Bypass)
{
await _stockProxy.SendOutToHiWMS(task.Type.ToString(), task.Barcode, task.RequestNo, "2");
if (!_notifications.Any())
{
if (task.Destination == 29101 || task.Destination == 22017)
{
await _stockProxy.SendAGV(task.Barcode, task.Tag, task.Destination);
}
}
if (!_notifications.Any())
{
// 前端人工操作
if (command.ManualFlg == 1)
{
await _wcsProxy.DeleteWcs(task.Id, $"人工完成");
}
int? cellId = await _stockProxy.GetCell(task.Barcode);
int originalCellId = cellId.HasValue ? cellId.Value : task.Original;
await _warehouseRepository.ReleaseCell(task.TransitPlace == 0 ? originalCellId : task.TransitPlace, task.Destination);
await _warehouseRepository.UpdateCell(task.TransitPlace == 0 ? originalCellId : task.TransitPlace, "Empty");
//await _stockProxy.Relocate(
// "Transfer",
// task.Barcode,
// null,
// task.Original,
// task.Destination,
// task.Operator,
// task.Tag,
// (task.Timestamp, DateTime.Now));
await _taskRepository.DeleteTask(command.Id);
await _stockProxy.AutoOut(task.Type.ToString(), task.Barcode, task.Original, task.Destination, task.Operator, task.Tag, task.Timestamp);
}
//LED提示
string ledSlTarget = string.Empty;
string ledSlSourceL2 = string.Empty;
if (!string.IsNullOrEmpty(task.Tag))
{
JObject jObj = JObject.Parse(task.Tag);
JToken jIsAgv = jObj.SelectToken("isAgv");
JToken jSlTarget = jObj.SelectToken("slTarget");
if (jIsAgv != null && jSlTarget != null)
{
if (jObj["isAgv"].ToString() == "1" && !string.IsNullOrEmpty(jObj["slTarget"].ToString()))
{
ledSlTarget = "-" + jObj["slTarget"].ToString();
ledSlSourceL2 = " 目的地:" + jObj["slTarget"].ToString();
}
}
}
string line1 = $"{task.Barcode}出库{ledSlTarget}";
string line2 = $"请搬运";
if (!string.IsNullOrEmpty(task.Tag))
{
JObject jObj = JObject.Parse(task.Tag);
//JToken isAgvToken = jObj["isAgv"];
JToken jIsAgv = jObj.SelectToken("isAgv");
////使用AGV
//if (jIsAgv != null && jIsAgv.ToString().Equals("1"))
//{
// line2 = $"等待AGV搬运{ledSlSourceL2}";
//}
}
if (_notifications.Any())
{
line1 = $"{task.Barcode}出库错误";
line2 = $"{_notifications.FirstOrDefault().ErrorMessage}";
}
await _ledService.Invoke(task.Destination.ToString(), line1, line2);
}
else
{
//await _taskRepository.DeleteTask(command.Id);
var @event = _mapper.Map(task);
@event.Id = command.Id;
@event.Timestamp = DateTime.Now;
@event.Tag = task.RequestNo;
await _commandBus.Trigger(@event, cancellationToken);
if (!bDeleteWcs)
{
await _wcsProxy.DeleteWcs(task.Id, $"人工完成");
}
try
{
task = await _taskRepository.GetTask(command.Id);
if (task != null && task.ManageStatus != "WaiteWmsResult"
&& task.ManageStatus != "UploadError"
&& task.ManageStatus != "WmsResultFail"
&& task.ManageStatus != "ScanError"
&& task.ManageStatus != "AgvFail")
{
await _taskRepository.DeleteTask(command.Id);
}
}
catch
{
}
}
}
}
try
{
foreach (var item in await _taskRepository.GetRepairFollowed())
{
_logger.LogInformation($"找到需要补发后续任务({item.Id})");
await _taskRepository.DeleteTask(item.Id);
int? cellId = await _stockProxy.GetCell(item.Barcode);
int originalCellId = cellId.HasValue ? cellId.Value : item.Original;
await _warehouseRepository.ReleaseCell(item.TransitPlace == 0 ? originalCellId : item.TransitPlace, item.Destination);
item.Previous = null;
item.Warehouse = (await _warehouseRepository.GetCellById(item.Original)) == null ? 0 : (await _warehouseRepository.GetCellById(item.Original)).Warehouse;
item.Tag = item.Tag.Contains("isAgv") ? item.Tag : "";
var newcommand = _mapper.Map(item, typeof(Models.Task), Type.GetType($"Kean.Domain.Task.Commands.{item.Type}Command")) as ICommand;
await _commandBus.Execute(newcommand, cancellationToken);
if (!_notifications.Any())
{
_logger.LogInformation($"需要补发后续任务({item.Id})生成新的后续任务({Convert.ToInt32(newcommand.GetType().GetProperty("Id").GetValue(newcommand))})");
await _taskRepository.UpdatePrevious(item.Id, Convert.ToInt32(newcommand.GetType().GetProperty("Id").GetValue(newcommand)));
}
}
}
catch (Exception e)
{
_logger.LogInformation($"需要补发后续任务处理异常,原因:{e.StackTrace}");
}
}
else
{
await _commandBus.Notify(command.ValidationResult,
cancellationToken: cancellationToken);
}
}
}
}