@ -0,0 +1,12 @@ | |||||
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands; | |||||
public class CompleteOrderCommand : IRequest<bool> | |||||
{ | |||||
[DataMember] | |||||
public int OrderNumber { get; private set; } | |||||
public CompleteOrderCommand(int orderNumber) | |||||
{ | |||||
OrderNumber = orderNumber; | |||||
} | |||||
} |
@ -0,0 +1,47 @@ | |||||
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands; | |||||
// Regular CommandHandler | |||||
public class CompleteOrderCommandHandler : IRequestHandler<CompleteOrderCommand, bool> | |||||
{ | |||||
private readonly IOrderRepository _orderRepository; | |||||
public CompleteOrderCommandHandler(IOrderRepository orderRepository) | |||||
{ | |||||
_orderRepository = orderRepository; | |||||
} | |||||
/// <summary> | |||||
/// Handler which processes the command when | |||||
/// shipment company requests to complete order from API | |||||
/// </summary> | |||||
/// <param name="command"></param> | |||||
/// <returns></returns> | |||||
public async Task<bool> Handle(CompleteOrderCommand command, CancellationToken cancellationToken) | |||||
{ | |||||
var orderToUpdate = await _orderRepository.GetAsync(command.OrderNumber); | |||||
if (orderToUpdate == null) | |||||
{ | |||||
return false; | |||||
} | |||||
orderToUpdate.SetCompletedStatus(); | |||||
return await _orderRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken); | |||||
} | |||||
} | |||||
// Use for Idempotency in Command process | |||||
public class CompleteOrderIdentifiedCommandHandler : IdentifiedCommandHandler<CompleteOrderCommand, bool> | |||||
{ | |||||
public CompleteOrderIdentifiedCommandHandler(IMediator mediator, IRequestManager requestManager, ILogger<IdentifiedCommandHandler<CompleteOrderCommand, bool>> logger) | |||||
: base(mediator, requestManager, logger) | |||||
{ | |||||
} | |||||
protected override bool CreateResultForDuplicateRequest() | |||||
{ | |||||
return true; // Ignore duplicate requests for processing order. | |||||
} | |||||
} |
@ -0,0 +1,29 @@ | |||||
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.DomainEventHandlers; | |||||
public partial class OrderCompletedDomainEventHandler : INotificationHandler<OrderCompletedDomainEvent> | |||||
{ | |||||
private readonly IOrderRepository _orderRepository; | |||||
private readonly IBuyerRepository _buyerRepository; | |||||
private readonly IOrderingIntegrationEventService _orderingIntegrationEventService; | |||||
private readonly ILogger _logger; | |||||
public OrderCompletedDomainEventHandler(IOrderRepository orderRepository, ILogger<OrderCompletedDomainEventHandler> logger, IBuyerRepository buyerRepository, IOrderingIntegrationEventService orderingIntegrationEventService) | |||||
{ | |||||
_orderRepository = orderRepository ?? throw new ArgumentNullException(nameof(orderRepository)); | |||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger)); | |||||
_buyerRepository = buyerRepository ?? throw new ArgumentNullException(nameof(buyerRepository)); | |||||
_orderingIntegrationEventService = orderingIntegrationEventService; | |||||
} | |||||
public async Task Handle(OrderCompletedDomainEvent domainEvent, CancellationToken cancellationToken) | |||||
{ | |||||
OrderingApiTrace.LogOrderStatusUpdated(_logger, domainEvent.Order.Id, nameof(OrderStatus.Completed), OrderStatus.Completed.Id); | |||||
var order = await _orderRepository.GetAsync(domainEvent.Order.Id); | |||||
var buyer = await _buyerRepository.FindByIdAsync(order.GetBuyerId.Value.ToString()); | |||||
var integrationEvent = new OrderStatusChangedToCompletedIntegrationEvent(order.Id, order.OrderStatus.Name, buyer.Name); | |||||
await _orderingIntegrationEventService.AddAndSaveEventAsync(integrationEvent); | |||||
} | |||||
} |
@ -0,0 +1,15 @@ | |||||
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.IntegrationEvents.Events; | |||||
public record OrderStatusChangedToCompletedIntegrationEvent : IntegrationEvent | |||||
{ | |||||
public int OrderId { get; } | |||||
public string OrderStatus { get; } | |||||
public string BuyerName { get; } | |||||
public OrderStatusChangedToCompletedIntegrationEvent(int orderId, string orderStatus, string buyerName) | |||||
{ | |||||
OrderId = orderId; | |||||
OrderStatus = orderStatus; | |||||
BuyerName = buyerName; | |||||
} | |||||
} |
@ -0,0 +1,11 @@ | |||||
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Validations; | |||||
public class CompleteOrderCommandValidator : AbstractValidator<CompleteOrderCommand> | |||||
{ | |||||
public CompleteOrderCommandValidator(ILogger<CompleteOrderCommandValidator> logger) | |||||
{ | |||||
RuleFor(order => order.OrderNumber).NotEmpty().WithMessage("No orderId found"); | |||||
logger.LogTrace("INSTANCE CREATED - {ClassName}", GetType().Name); | |||||
} | |||||
} |
@ -0,0 +1,11 @@ | |||||
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.Events; | |||||
public class OrderCompletedDomainEvent : INotification | |||||
{ | |||||
public Order Order { get; } | |||||
public OrderCompletedDomainEvent(Order order) | |||||
{ | |||||
Order = order; | |||||
} | |||||
} |