using AutoMapper;
using Kean.Domain.Stock.Commands;
using Kean.Domain.Stock.Events;
using Kean.Domain.Stock.Repositories;
using Kean.Domain.Stock.SharedServices.Proxies;
using Kean.Infrastructure.Configuration;
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace Kean.Domain.Stock.CommandHandlers
{
///
/// 出库命令处理程序
///
public sealed class AutoOutCommandHandler : CommandHandler
{
private readonly ICommandBus _commandBus; // 命令总线
private readonly INotification _notifications; // 总线通知
private readonly IMapper _mapper; // 模型映射
private readonly IStockRepository _stockRepository; // 存储仓库
///
/// 依赖注入
///
public AutoOutCommandHandler(
ICommandBus commandBus,
INotification notifications,
IMapper mapper,
IStockRepository stockRepository,
IWarehouseRepository warehouseRepository,
BarcodeValidator barcodeValidator,
TaskProxy taskProxy)
{
_commandBus = commandBus;
_notifications = notifications;
_mapper = mapper;
_stockRepository = stockRepository;
}
///
/// 处理程序
///
public override async Task Handle(AutoOutCommand command, CancellationToken cancellationToken)
{
var original = await _stockRepository.GetCell(command.Barcode);
// 托盘不存在
if (!original.HasValue)
{
await _commandBus.Notify(nameof(command.Barcode), "托盘不存在", command.Barcode,
cancellationToken: cancellationToken);
return;
}
// 时间戳
command.Timestamp ??= DateTime.Now;
// 切点事件
var event0 = _mapper.Map(command);
event0.Cell = original.Value;
// 成功事件
var event1 = _mapper.Map(command);
event1.EndTime = command.Timestamp.Value;
event1.Lines = await _stockRepository.GetLines(event1.Barcode);
await _commandBus.Trigger(event0, cancellationToken);
if (!_notifications.Any())
{
// 允许删除库存
var stock = _mapper.Map(command);
stock.Cell = original.Value;
stock.Timestamp = command.Timestamp.Value;
if (await _stockRepository.DeleteStock(stock).ContinueWith(task =>
{
if (task.Exception?.InnerException is RepositoryException ex)
{
task.Exception.Handle(_ => true);
_commandBus.Notify(ex.Member.Key, ex.Message, ex.Member.Value,
cancellationToken: cancellationToken).Wait();
return true;
}
return false;
}))
{
return;
}
// 成功事件
await _commandBus.Trigger(event1, cancellationToken);
}
}
}
}