add order status change
add order status event add order status event handler
This commit is contained in:
parent
c863b143d7
commit
78a45cdad3
@ -39,8 +39,12 @@
|
|||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.0" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.AzureKeyVault" Version="3.1.18" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.AzureKeyVault" Version="3.1.18" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.AzureAppServices" Version="6.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Logging.AzureAppServices" Version="6.0.0" />
|
||||||
|
<PackageReference Include="Microsoft.TypeScript.MSBuild" Version="4.7.4">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.11.1" />
|
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.11.1" />
|
||||||
<PackageReference Include="Microsoft.Web.LibraryManager.Build" Version="2.1.113" />
|
<PackageReference Include="Microsoft.Web.LibraryManager.Build" Version="2.1.175" />
|
||||||
<PackageReference Include="Polly" Version="7.2.2" />
|
<PackageReference Include="Polly" Version="7.2.2" />
|
||||||
<PackageReference Include="Serilog.AspNetCore" Version="4.1.1-dev-00229" />
|
<PackageReference Include="Serilog.AspNetCore" Version="4.1.1-dev-00229" />
|
||||||
<PackageReference Include="Serilog.Enrichers.Environment" Version="2.2.1-dev-00787" />
|
<PackageReference Include="Serilog.Enrichers.Environment" Version="2.2.1-dev-00787" />
|
||||||
|
@ -10,4 +10,5 @@ public class IdentifiedCommand<T, R> : IRequest<R>
|
|||||||
Command = command;
|
Command = command;
|
||||||
Id = id;
|
Id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,13 @@
|
|||||||
|
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands;
|
||||||
|
|
||||||
|
public class SetCompletedOrderStatusCommand : IRequest<bool>
|
||||||
|
{
|
||||||
|
|
||||||
|
[DataMember]
|
||||||
|
public int OrderNumber { get; private set; }
|
||||||
|
|
||||||
|
public SetCompletedOrderStatusCommand(int orderNumber)
|
||||||
|
{
|
||||||
|
OrderNumber = orderNumber;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands;
|
||||||
|
|
||||||
|
// Regular CommandHandler
|
||||||
|
public class SetCompletedOrderStatusCommandHandler : IRequestHandler<SetCompletedOrderStatusCommand, bool>
|
||||||
|
{
|
||||||
|
private readonly IOrderRepository _orderRepository;
|
||||||
|
|
||||||
|
public SetCompletedOrderStatusCommandHandler(IOrderRepository orderRepository)
|
||||||
|
{
|
||||||
|
_orderRepository = orderRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handler which processes the command when
|
||||||
|
/// Completed the order
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="command"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<bool> Handle(SetCompletedOrderStatusCommand command, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
// Simulate a work time for validating the completed
|
||||||
|
await Task.Delay(10000, 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 SetCompletedIdentifiedOrderStatusCommandHandler : IdentifiedCommandHandler<SetCompletedOrderStatusCommand, bool>
|
||||||
|
{
|
||||||
|
public SetCompletedIdentifiedOrderStatusCommandHandler(
|
||||||
|
IMediator mediator,
|
||||||
|
IRequestManager requestManager,
|
||||||
|
ILogger<IdentifiedCommandHandler<SetCompletedOrderStatusCommand, bool>> logger)
|
||||||
|
: base(mediator, requestManager, logger)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool CreateResultForDuplicateRequest()
|
||||||
|
{
|
||||||
|
return true; // Ignore duplicate requests for processing order.
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.DomainEventHandlers.OrderCompleted;
|
||||||
|
|
||||||
|
public class OrderStatusChangedToCompletedDomainEventHandler
|
||||||
|
: INotificationHandler<OrderStatusChangedToCompletedDomainEvent>
|
||||||
|
{
|
||||||
|
private readonly IOrderRepository _orderRepository;
|
||||||
|
private readonly ILoggerFactory _logger;
|
||||||
|
private readonly IBuyerRepository _buyerRepository;
|
||||||
|
private readonly IOrderingIntegrationEventService _orderingIntegrationEventService;
|
||||||
|
|
||||||
|
|
||||||
|
public OrderStatusChangedToCompletedDomainEventHandler(
|
||||||
|
IOrderRepository orderRepository, ILoggerFactory 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 ?? throw new ArgumentNullException(nameof(orderingIntegrationEventService));
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Handle(OrderStatusChangedToCompletedDomainEvent orderStatusChangedToCompletedDomainEvent, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
_logger.CreateLogger<OrderStatusChangedToCompletedDomainEventHandler>()
|
||||||
|
.LogTrace("Order with Id: {OrderId} has been successfully updated to status {Status} ({Id})",
|
||||||
|
orderStatusChangedToCompletedDomainEvent.OrderId, nameof(OrderStatus.Complete), OrderStatus.Complete.Id);
|
||||||
|
|
||||||
|
var order = await _orderRepository.GetAsync(orderStatusChangedToCompletedDomainEvent.OrderId);
|
||||||
|
var buyer = await _buyerRepository.FindByIdAsync(order.GetBuyerId.Value.ToString());
|
||||||
|
|
||||||
|
var orderStockList = orderStatusChangedToCompletedDomainEvent.OrderItems
|
||||||
|
.Select(orderItem => new OrderStockItem(orderItem.ProductId, orderItem.GetUnits()));
|
||||||
|
|
||||||
|
var orderStatusChangedToCompletedIntegrationEvent = new OrderStatusChangedToCompletedIntegrationEvent(
|
||||||
|
orderStatusChangedToCompletedDomainEvent.OrderId,
|
||||||
|
order.OrderStatus.Name,
|
||||||
|
buyer.Name,
|
||||||
|
orderStockList);
|
||||||
|
|
||||||
|
await _orderingIntegrationEventService.AddAndSaveEventAsync(orderStatusChangedToCompletedIntegrationEvent);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.IntegrationEvents.EventHandling;
|
||||||
|
|
||||||
|
public class OrderCompletedFailedIntegrationEventHandler :
|
||||||
|
IIntegrationEventHandler<OrderCompletedFailedIntegrationEvent>
|
||||||
|
{
|
||||||
|
private readonly IMediator _mediator;
|
||||||
|
private readonly ILogger<OrderCompletedFailedIntegrationEventHandler> _logger;
|
||||||
|
|
||||||
|
public OrderCompletedFailedIntegrationEventHandler(
|
||||||
|
IMediator mediator,
|
||||||
|
ILogger<OrderCompletedFailedIntegrationEventHandler> logger)
|
||||||
|
{
|
||||||
|
_mediator = mediator ?? throw new ArgumentNullException(nameof(mediator));
|
||||||
|
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Handle(OrderCompletedFailedIntegrationEvent @event)
|
||||||
|
{
|
||||||
|
using (LogContext.PushProperty("IntegrationEventContext", $"{@event.Id}-{Program.AppName}"))
|
||||||
|
{
|
||||||
|
_logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppName} - ({@IntegrationEvent})", @event.Id, Program.AppName, @event);
|
||||||
|
|
||||||
|
var command = new CancelOrderCommand(@event.OrderId);
|
||||||
|
|
||||||
|
_logger.LogInformation(
|
||||||
|
"----- Sending command: {CommandName} - {IdProperty}: {CommandId} ({@Command})",
|
||||||
|
command.GetGenericTypeName(),
|
||||||
|
nameof(command.OrderNumber),
|
||||||
|
command.OrderNumber,
|
||||||
|
command);
|
||||||
|
|
||||||
|
await _mediator.Send(command);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.IntegrationEvents.EventHandling;
|
||||||
|
|
||||||
|
public class OrderCompletedSucceededIntegrationEventHandler :
|
||||||
|
IIntegrationEventHandler<OrderCompletedSucceededIntegrationEvent>
|
||||||
|
{
|
||||||
|
private readonly IMediator _mediator;
|
||||||
|
private readonly ILogger<OrderCompletedSucceededIntegrationEventHandler> _logger;
|
||||||
|
|
||||||
|
public OrderCompletedSucceededIntegrationEventHandler(
|
||||||
|
IMediator mediator,
|
||||||
|
ILogger<OrderCompletedSucceededIntegrationEventHandler> logger)
|
||||||
|
{
|
||||||
|
_mediator = mediator ?? throw new ArgumentNullException(nameof(mediator));
|
||||||
|
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Handle(OrderCompletedSucceededIntegrationEvent @event)
|
||||||
|
{
|
||||||
|
using (LogContext.PushProperty("IntegrationEventContext", $"{@event.Id}-{Program.AppName}"))
|
||||||
|
{
|
||||||
|
_logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppName} - ({@IntegrationEvent})", @event.Id, Program.AppName, @event);
|
||||||
|
|
||||||
|
var command = new SetCompletedOrderStatusCommand(@event.OrderId);
|
||||||
|
|
||||||
|
_logger.LogInformation(
|
||||||
|
"----- Sending command: {CommandName} - {IdProperty}: {CommandId} ({@Command})",
|
||||||
|
command.GetGenericTypeName(),
|
||||||
|
nameof(command.OrderNumber),
|
||||||
|
command.OrderNumber,
|
||||||
|
command);
|
||||||
|
|
||||||
|
await _mediator.Send(command);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.IntegrationEvents.Events;
|
||||||
|
|
||||||
|
public record OrderCompletedFailedIntegrationEvent : IntegrationEvent
|
||||||
|
{
|
||||||
|
public int OrderId { get; }
|
||||||
|
|
||||||
|
public OrderCompletedFailedIntegrationEvent(int orderId) => OrderId = orderId;
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.IntegrationEvents.Events;
|
||||||
|
|
||||||
|
public record OrderCompletedSucceededIntegrationEvent : IntegrationEvent
|
||||||
|
{
|
||||||
|
public int OrderId { get; }
|
||||||
|
|
||||||
|
public OrderCompletedSucceededIntegrationEvent(int orderId) => OrderId = orderId;
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
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 IEnumerable<OrderStockItem> OrderStockItems { get; }
|
||||||
|
|
||||||
|
public OrderStatusChangedToCompletedIntegrationEvent(int orderId,
|
||||||
|
string orderStatus,
|
||||||
|
string buyerName,
|
||||||
|
IEnumerable<OrderStockItem> orderStockItems)
|
||||||
|
{
|
||||||
|
OrderId = orderId;
|
||||||
|
OrderStockItems = orderStockItems;
|
||||||
|
OrderStatus = orderStatus;
|
||||||
|
BuyerName = buyerName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -140,4 +140,29 @@ public class OrdersController : ControllerBase
|
|||||||
|
|
||||||
return await _mediator.Send(createOrderDraftCommand);
|
return await _mediator.Send(createOrderDraftCommand);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Route("completed")]
|
||||||
|
[HttpPut]
|
||||||
|
[ProducesResponseType((int)HttpStatusCode.OK)]
|
||||||
|
[ProducesResponseType((int)HttpStatusCode.BadRequest)]
|
||||||
|
public async Task<IActionResult> CompletedOrderAsync([FromBody] SetCompletedOrderStatusCommand setCompletedOrderStatusCommand, [FromHeader(Name = "x-requestid")] string requestId)
|
||||||
|
{
|
||||||
|
bool commandResult = false;
|
||||||
|
_logger.LogInformation(
|
||||||
|
"----- Sending command: {CommandName} - {IdProperty}: {CommandId} ({@Command})",
|
||||||
|
setCompletedOrderStatusCommand.GetGenericTypeName(),
|
||||||
|
nameof(setCompletedOrderStatusCommand.OrderNumber),
|
||||||
|
setCompletedOrderStatusCommand.OrderNumber,
|
||||||
|
setCompletedOrderStatusCommand);
|
||||||
|
commandResult = await _mediator.Send(setCompletedOrderStatusCommand);
|
||||||
|
if (!commandResult)
|
||||||
|
{
|
||||||
|
return BadRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return Ok();
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -105,7 +105,9 @@ public class Startup
|
|||||||
eventBus.Subscribe<OrderStockConfirmedIntegrationEvent, IIntegrationEventHandler<OrderStockConfirmedIntegrationEvent>>();
|
eventBus.Subscribe<OrderStockConfirmedIntegrationEvent, IIntegrationEventHandler<OrderStockConfirmedIntegrationEvent>>();
|
||||||
eventBus.Subscribe<OrderStockRejectedIntegrationEvent, IIntegrationEventHandler<OrderStockRejectedIntegrationEvent>>();
|
eventBus.Subscribe<OrderStockRejectedIntegrationEvent, IIntegrationEventHandler<OrderStockRejectedIntegrationEvent>>();
|
||||||
eventBus.Subscribe<OrderPaymentFailedIntegrationEvent, IIntegrationEventHandler<OrderPaymentFailedIntegrationEvent>>();
|
eventBus.Subscribe<OrderPaymentFailedIntegrationEvent, IIntegrationEventHandler<OrderPaymentFailedIntegrationEvent>>();
|
||||||
|
eventBus.Subscribe<OrderCompletedFailedIntegrationEvent, IIntegrationEventHandler<OrderCompletedFailedIntegrationEvent>>();
|
||||||
eventBus.Subscribe<OrderPaymentSucceededIntegrationEvent, IIntegrationEventHandler<OrderPaymentSucceededIntegrationEvent>>();
|
eventBus.Subscribe<OrderPaymentSucceededIntegrationEvent, IIntegrationEventHandler<OrderPaymentSucceededIntegrationEvent>>();
|
||||||
|
eventBus.Subscribe<OrderCompletedSucceededIntegrationEvent, IIntegrationEventHandler<OrderCompletedSucceededIntegrationEvent>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void ConfigureAuth(IApplicationBuilder app)
|
protected virtual void ConfigureAuth(IApplicationBuilder app)
|
||||||
|
@ -132,6 +132,16 @@ public class Order
|
|||||||
_description = "The payment was performed at a simulated \"American Bank checking bank account ending on XX35071\"";
|
_description = "The payment was performed at a simulated \"American Bank checking bank account ending on XX35071\"";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public void SetCompletedStatus()
|
||||||
|
{
|
||||||
|
if (_orderStatusId == OrderStatus.Paid.Id)
|
||||||
|
{
|
||||||
|
AddDomainEvent(new OrderStatusChangedToCompletedDomainEvent(Id, OrderItems));
|
||||||
|
|
||||||
|
_orderStatusId = OrderStatus.Complete.Id;
|
||||||
|
_description = "completed \"Yurt içi cargo ending on XX35071\"";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void SetShippedStatus()
|
public void SetShippedStatus()
|
||||||
{
|
{
|
||||||
|
@ -11,6 +11,7 @@ public class OrderStatus
|
|||||||
public static OrderStatus Paid = new OrderStatus(4, nameof(Paid).ToLowerInvariant());
|
public static OrderStatus Paid = new OrderStatus(4, nameof(Paid).ToLowerInvariant());
|
||||||
public static OrderStatus Shipped = new OrderStatus(5, nameof(Shipped).ToLowerInvariant());
|
public static OrderStatus Shipped = new OrderStatus(5, nameof(Shipped).ToLowerInvariant());
|
||||||
public static OrderStatus Cancelled = new OrderStatus(6, nameof(Cancelled).ToLowerInvariant());
|
public static OrderStatus Cancelled = new OrderStatus(6, nameof(Cancelled).ToLowerInvariant());
|
||||||
|
public static OrderStatus Complete = new OrderStatus(7, nameof(Complete).ToLowerInvariant());
|
||||||
|
|
||||||
public OrderStatus(int id, string name)
|
public OrderStatus(int id, string name)
|
||||||
: base(id, name)
|
: base(id, name)
|
||||||
@ -18,7 +19,7 @@ public class OrderStatus
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static IEnumerable<OrderStatus> List() =>
|
public static IEnumerable<OrderStatus> List() =>
|
||||||
new[] { Submitted, AwaitingValidation, StockConfirmed, Paid, Shipped, Cancelled };
|
new[] { Submitted, AwaitingValidation, StockConfirmed, Paid, Shipped, Cancelled, Complete };
|
||||||
|
|
||||||
public static OrderStatus FromName(string name)
|
public static OrderStatus FromName(string name)
|
||||||
{
|
{
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.Events;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event used when the order is completed
|
||||||
|
/// </summary>
|
||||||
|
public class OrderStatusChangedToCompletedDomainEvent
|
||||||
|
: INotification
|
||||||
|
{
|
||||||
|
public int OrderId { get; }
|
||||||
|
public IEnumerable<OrderItem> OrderItems { get; }
|
||||||
|
|
||||||
|
public OrderStatusChangedToCompletedDomainEvent(int orderId,
|
||||||
|
IEnumerable<OrderItem> orderItems)
|
||||||
|
{
|
||||||
|
OrderId = orderId;
|
||||||
|
OrderItems = orderItems;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
namespace Microsoft.eShopOnContainers.Services.Ordering.SignalrHub.IntegrationEvents.EventHandling;
|
||||||
|
|
||||||
|
public class OrderStatusChangedToCompletedIntegrationEventHandler : IIntegrationEventHandler<OrderStatusChangedToCompletedIntegrationEvent>
|
||||||
|
{
|
||||||
|
private readonly IHubContext<NotificationsHub> _hubContext;
|
||||||
|
private readonly ILogger<OrderStatusChangedToCompletedIntegrationEventHandler> _logger;
|
||||||
|
|
||||||
|
public OrderStatusChangedToCompletedIntegrationEventHandler(
|
||||||
|
IHubContext<NotificationsHub> hubContext,
|
||||||
|
ILogger<OrderStatusChangedToCompletedIntegrationEventHandler> logger)
|
||||||
|
{
|
||||||
|
_hubContext = hubContext ?? throw new ArgumentNullException(nameof(hubContext));
|
||||||
|
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public async Task Handle(OrderStatusChangedToCompletedIntegrationEvent @event)
|
||||||
|
{
|
||||||
|
using (LogContext.PushProperty("IntegrationEventContext", $"{@event.Id}-{Program.AppName}"))
|
||||||
|
{
|
||||||
|
_logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppName} - ({@IntegrationEvent})", @event.Id, Program.AppName, @event);
|
||||||
|
|
||||||
|
await _hubContext.Clients
|
||||||
|
.Group(@event.BuyerName)
|
||||||
|
.SendAsync("UpdatedOrderState", new { OrderId = @event.OrderId, Status = @event.OrderStatus });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
namespace Microsoft.eShopOnContainers.Services.Ordering.SignalrHub.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;
|
||||||
|
}
|
||||||
|
}
|
@ -138,6 +138,7 @@ public class Startup
|
|||||||
|
|
||||||
eventBus.Subscribe<OrderStatusChangedToAwaitingValidationIntegrationEvent, OrderStatusChangedToAwaitingValidationIntegrationEventHandler>();
|
eventBus.Subscribe<OrderStatusChangedToAwaitingValidationIntegrationEvent, OrderStatusChangedToAwaitingValidationIntegrationEventHandler>();
|
||||||
eventBus.Subscribe<OrderStatusChangedToPaidIntegrationEvent, OrderStatusChangedToPaidIntegrationEventHandler>();
|
eventBus.Subscribe<OrderStatusChangedToPaidIntegrationEvent, OrderStatusChangedToPaidIntegrationEventHandler>();
|
||||||
|
eventBus.Subscribe<OrderStatusChangedToCompletedIntegrationEvent, OrderStatusChangedToCompletedIntegrationEventHandler>();
|
||||||
eventBus.Subscribe<OrderStatusChangedToStockConfirmedIntegrationEvent, OrderStatusChangedToStockConfirmedIntegrationEventHandler>();
|
eventBus.Subscribe<OrderStatusChangedToStockConfirmedIntegrationEvent, OrderStatusChangedToStockConfirmedIntegrationEventHandler>();
|
||||||
eventBus.Subscribe<OrderStatusChangedToShippedIntegrationEvent, OrderStatusChangedToShippedIntegrationEventHandler>();
|
eventBus.Subscribe<OrderStatusChangedToShippedIntegrationEvent, OrderStatusChangedToShippedIntegrationEventHandler>();
|
||||||
eventBus.Subscribe<OrderStatusChangedToCancelledIntegrationEvent, OrderStatusChangedToCancelledIntegrationEventHandler>();
|
eventBus.Subscribe<OrderStatusChangedToCancelledIntegrationEvent, OrderStatusChangedToCancelledIntegrationEventHandler>();
|
||||||
|
@ -131,4 +131,20 @@ public class OrdersWebApiTest
|
|||||||
//Assert
|
//Assert
|
||||||
Assert.Equal((actionResult.Result as OkObjectResult).StatusCode, (int)System.Net.HttpStatusCode.OK);
|
Assert.Equal((actionResult.Result as OkObjectResult).StatusCode, (int)System.Net.HttpStatusCode.OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Completed_order_status_requestId_change()
|
||||||
|
{
|
||||||
|
//Arrange
|
||||||
|
_mediatorMock.Setup(x => x.Send(It.IsAny<SetCompletedOrderStatusCommand>(), default(CancellationToken)))
|
||||||
|
.Returns(Task.FromResult(true));
|
||||||
|
|
||||||
|
//Act
|
||||||
|
var orderController = new OrdersController(_mediatorMock.Object, _orderQueriesMock.Object, _identityServiceMock.Object, _loggerMock.Object);
|
||||||
|
var actionResult = await orderController.CompletedOrderAsync(new SetCompletedOrderStatusCommand(22),Guid.NewGuid().ToString()) as OkResult;
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
Assert.Equal(actionResult.StatusCode, (int)System.Net.HttpStatusCode.OK);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,6 +65,13 @@ public class OrderController : Controller
|
|||||||
var order = await _orderSvc.GetOrder(user, orderId);
|
var order = await _orderSvc.GetOrder(user, orderId);
|
||||||
return View(order);
|
return View(order);
|
||||||
}
|
}
|
||||||
|
[HttpPost]
|
||||||
|
public async Task Completed(string orderId)
|
||||||
|
{
|
||||||
|
|
||||||
|
await _orderSvc.CompleteOrder(orderId);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<IActionResult> Index(Order item)
|
public async Task<IActionResult> Index(Order item)
|
||||||
{
|
{
|
||||||
|
@ -45,6 +45,14 @@ public static class API
|
|||||||
{
|
{
|
||||||
return $"{baseUri}/ship";
|
return $"{baseUri}/ship";
|
||||||
}
|
}
|
||||||
|
public static string CompleteOrder(string baseUri)
|
||||||
|
{
|
||||||
|
return $"{baseUri}/completed";
|
||||||
|
|
||||||
|
///o/api/v1/orders/complated
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Catalog
|
public static class Catalog
|
||||||
|
@ -10,4 +10,6 @@ public interface IOrderingService
|
|||||||
Order MapUserInfoIntoOrder(ApplicationUser user, Order order);
|
Order MapUserInfoIntoOrder(ApplicationUser user, Order order);
|
||||||
BasketDTO MapOrderToBasket(Order order);
|
BasketDTO MapOrderToBasket(Order order);
|
||||||
void OverrideUserInfoIntoOrder(Order original, Order destination);
|
void OverrideUserInfoIntoOrder(Order original, Order destination);
|
||||||
|
Task CompleteOrder(string orderId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -137,4 +137,24 @@ public class OrderingService : IOrderingService
|
|||||||
RequestId = order.RequestId
|
RequestId = order.RequestId
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async public Task CompleteOrder(string orderId)
|
||||||
|
{
|
||||||
|
var order = new OrderDTO()
|
||||||
|
{
|
||||||
|
OrderNumber = orderId
|
||||||
|
};
|
||||||
|
|
||||||
|
var uri = API.Order.CompleteOrder(_remoteServiceBaseUrl);
|
||||||
|
var orderContent = new StringContent(JsonSerializer.Serialize(order), System.Text.Encoding.UTF8, "application/json");
|
||||||
|
|
||||||
|
var response = await _httpClient.PutAsync(uri, orderContent);
|
||||||
|
|
||||||
|
if (response.StatusCode == System.Net.HttpStatusCode.InternalServerError)
|
||||||
|
{
|
||||||
|
throw new Exception("Error completeng order, try later.");
|
||||||
|
}
|
||||||
|
|
||||||
|
response.EnsureSuccessStatusCode();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,34 +14,55 @@
|
|||||||
<partial name="_Header" model="headerList" />
|
<partial name="_Header" model="headerList" />
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<article class="esh-orders-titles row">
|
|
||||||
<section class="esh-orders-title col-2">Order number</section>
|
|
||||||
<section class="esh-orders-title col-4">Date</section>
|
|
||||||
<section class="esh-orders-title col-2">Total</section>
|
<table class="table">
|
||||||
<section class="esh-orders-title col-2">Status</section>
|
<thead>
|
||||||
<section class="esh-orders-title col-2"></section>
|
<tr>
|
||||||
</article>
|
<th scope="col">#</th>
|
||||||
|
<th scope="col">Order number</th>
|
||||||
|
<th scope="col">Date</th>
|
||||||
|
<th scope="col">Total</th>
|
||||||
|
<th scope="col">Status</th>
|
||||||
|
<th scope="col"></th>
|
||||||
|
<th scope="col"></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
@if (Model != null && Model.Any())
|
@if (Model != null && Model.Any())
|
||||||
{
|
{
|
||||||
foreach (var item in Model)
|
foreach (var item in Model)
|
||||||
{
|
{
|
||||||
<article class="esh-orders-items row">
|
|
||||||
<section class="esh-orders-item col-2">@Html.DisplayFor(modelItem => item.OrderNumber)</section>
|
<tr>
|
||||||
<section class="esh-orders-item col-4">@Html.DisplayFor(modelItem => item.Date)</section>
|
<th scope="row">1</th>
|
||||||
<section class="esh-orders-item col-2">$ @Html.DisplayFor(modelItem => item.Total)</section>
|
<td>@Html.DisplayFor(modelItem => item.OrderNumber)</td>
|
||||||
<section class="esh-orders-item col-2">@Html.DisplayFor(modelItem => item.Status)</section>
|
<td>$ @Html.DisplayFor(modelItem => item.Total)</td>
|
||||||
<section class="esh-orders-item col-1">
|
<td>@Html.DisplayFor(modelItem => item.Status)</td>
|
||||||
<a class="esh-orders-link" asp-controller="Order" asp-action="Detail" asp-route-orderId="@item.OrderNumber">Detail</a>
|
<td> <a class="esh-orders-link" asp-controller="Order" asp-action="Detail" asp-route-orderId="@item.OrderNumber">Detail</a></td>
|
||||||
</section>
|
<td>
|
||||||
<section class="esh-orders-item col-1">
|
|
||||||
@if (item.Status.ToLower() == "submitted")
|
@if (item.Status.ToLower() == "submitted")
|
||||||
{
|
{
|
||||||
<a class="esh-orders-link" asp-controller="Order" asp-action="cancel" asp-route-orderId="@item.OrderNumber">Cancel</a>
|
<a class="esh-orders-link" asp-controller="Order" asp-action="cancel" asp-route-orderId="@item.OrderNumber">Cancel</a>
|
||||||
}
|
}
|
||||||
</section>
|
</td>
|
||||||
</article>
|
<td>
|
||||||
|
@if (item.Status.ToLower() == "paid")
|
||||||
|
{
|
||||||
|
<button id="completed" class="btn btn-primary" data-order-id="@item.OrderNumber"> Completed Event</button>
|
||||||
|
@*<a class="esh-orders-link" asp-controller="Order" asp-action="completed" asp-route-orderId="@item.OrderNumber">Completed</a>*@
|
||||||
}
|
}
|
||||||
|
</td>
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -94,11 +94,12 @@
|
|||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
if ('@User.Identity.IsAuthenticated' === 'True') {
|
if ('@User.Identity.IsAuthenticated' === 'True') {
|
||||||
var timerId;
|
var timerId;
|
||||||
|
console.log("registerNotificationHandlers geldim.");
|
||||||
stablishConnection((conn) => registerNotificationHandlers(conn));
|
stablishConnection((conn) => registerNotificationHandlers(conn));
|
||||||
}
|
}
|
||||||
|
|
||||||
function stablishConnection(cb) {
|
function stablishConnection(cb) {
|
||||||
|
console.log("stablishConnection geldim.");
|
||||||
let connection = new signalR.HubConnectionBuilder()
|
let connection = new signalR.HubConnectionBuilder()
|
||||||
.withUrl('@settings.Value.SignalrHubUrl/hub/notificationhub', {
|
.withUrl('@settings.Value.SignalrHubUrl/hub/notificationhub', {
|
||||||
accessTokenFactory: () => {
|
accessTokenFactory: () => {
|
||||||
@ -115,7 +116,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function registerNotificationHandlers(connection) {
|
function registerNotificationHandlers(connection) {
|
||||||
|
console.log("UpdatedOrderState geldim.");
|
||||||
|
|
||||||
connection.on("UpdatedOrderState", (message) => {
|
connection.on("UpdatedOrderState", (message) => {
|
||||||
|
console.log(message);
|
||||||
|
|
||||||
toastr.success('Updated to status: ' + message.status, 'Order Id: ' + message.orderId);
|
toastr.success('Updated to status: ' + message.status, 'Order Id: ' + message.orderId);
|
||||||
if (window.location.pathname.split("/").pop() === 'Order') {
|
if (window.location.pathname.split("/").pop() === 'Order') {
|
||||||
refreshOrderList();
|
refreshOrderList();
|
||||||
@ -133,6 +138,21 @@
|
|||||||
window.location.reload();
|
window.location.reload();
|
||||||
}, 1000);
|
}, 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$("#completed").click(function() {
|
||||||
|
var orderId = $(this).data("order-id");
|
||||||
|
var url = "@Url.Action("Completed","Order")";
|
||||||
|
console.log(url);
|
||||||
|
$.post(url,
|
||||||
|
{
|
||||||
|
orderId
|
||||||
|
}
|
||||||
|
|
||||||
|
//function(data, status) {
|
||||||
|
// console.log("Data: " + data + "\nStatus: " + status);
|
||||||
|
//});
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -34,7 +34,11 @@
|
|||||||
<PackageReference Include="Microsoft.AspNetCore.HealthChecks" Version="1.0.0" />
|
<PackageReference Include="Microsoft.AspNetCore.HealthChecks" Version="1.0.0" />
|
||||||
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="16.8.0" />
|
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="16.8.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.AzureAppServices" Version="6.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Logging.AzureAppServices" Version="6.0.0" />
|
||||||
<PackageReference Include="Microsoft.Web.LibraryManager.Build" Version="2.1.113" />
|
<PackageReference Include="Microsoft.TypeScript.MSBuild" Version="4.7.4">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="Microsoft.Web.LibraryManager.Build" Version="2.1.175" />
|
||||||
<PackageReference Include="Serilog.AspNetCore" Version="3.4.0" />
|
<PackageReference Include="Serilog.AspNetCore" Version="3.4.0" />
|
||||||
<PackageReference Include="Serilog.Enrichers.Environment" Version="2.1.3" />
|
<PackageReference Include="Serilog.Enrichers.Environment" Version="2.1.3" />
|
||||||
<PackageReference Include="Serilog.Settings.Configuration" Version="3.1.1-dev-00216" />
|
<PackageReference Include="Serilog.Settings.Configuration" Version="3.1.1-dev-00216" />
|
||||||
|
@ -18,7 +18,11 @@
|
|||||||
<PackageReference Include="Microsoft.ApplicationInsights.Kubernetes" Version="2.0.2-beta2" />
|
<PackageReference Include="Microsoft.ApplicationInsights.Kubernetes" Version="2.0.2-beta2" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.HealthChecks" Version="2.2.0" />
|
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.HealthChecks" Version="2.2.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.AzureAppServices" Version="6.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Logging.AzureAppServices" Version="6.0.0" />
|
||||||
<PackageReference Include="Microsoft.Web.LibraryManager.Build" Version="2.1.113" />
|
<PackageReference Include="Microsoft.TypeScript.MSBuild" Version="4.7.4">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="Microsoft.Web.LibraryManager.Build" Version="2.1.175" />
|
||||||
<PackageReference Include="Serilog.AspNetCore" Version="3.4.0" />
|
<PackageReference Include="Serilog.AspNetCore" Version="3.4.0" />
|
||||||
<PackageReference Include="Serilog.Enrichers.Environment" Version="2.1.3" />
|
<PackageReference Include="Serilog.Enrichers.Environment" Version="2.1.3" />
|
||||||
<PackageReference Include="Serilog.Settings.Configuration" Version="3.1.1-dev-00216" />
|
<PackageReference Include="Serilog.Settings.Configuration" Version="3.1.1-dev-00216" />
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio Version 16
|
# Visual Studio Version 17
|
||||||
VisualStudioVersion = 16.0.29020.237
|
VisualStudioVersion = 17.2.32630.192
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{E53339B2-1760-4266-BCC7-CA923CBCF16C}") = "docker-compose", "docker-compose.dcproj", "{FEA0C318-FFED-4D39-8781-265718CA43DD}"
|
Project("{E53339B2-1760-4266-BCC7-CA923CBCF16C}") = "docker-compose", "docker-compose.dcproj", "{FEA0C318-FFED-4D39-8781-265718CA43DD}"
|
||||||
EndProject
|
EndProject
|
||||||
@ -450,8 +450,8 @@ Global
|
|||||||
{F16E3C6A-1C94-4EAB-BE91-099618060B68}.AppStore|x64.Build.0 = Release|Any CPU
|
{F16E3C6A-1C94-4EAB-BE91-099618060B68}.AppStore|x64.Build.0 = Release|Any CPU
|
||||||
{F16E3C6A-1C94-4EAB-BE91-099618060B68}.AppStore|x86.ActiveCfg = Release|Any CPU
|
{F16E3C6A-1C94-4EAB-BE91-099618060B68}.AppStore|x86.ActiveCfg = Release|Any CPU
|
||||||
{F16E3C6A-1C94-4EAB-BE91-099618060B68}.AppStore|x86.Build.0 = Release|Any CPU
|
{F16E3C6A-1C94-4EAB-BE91-099618060B68}.AppStore|x86.Build.0 = Release|Any CPU
|
||||||
{F16E3C6A-1C94-4EAB-BE91-099618060B68}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{F16E3C6A-1C94-4EAB-BE91-099618060B68}.Debug|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{F16E3C6A-1C94-4EAB-BE91-099618060B68}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{F16E3C6A-1C94-4EAB-BE91-099618060B68}.Debug|Any CPU.Build.0 = Release|Any CPU
|
||||||
{F16E3C6A-1C94-4EAB-BE91-099618060B68}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
{F16E3C6A-1C94-4EAB-BE91-099618060B68}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||||
{F16E3C6A-1C94-4EAB-BE91-099618060B68}.Debug|ARM.Build.0 = Debug|Any CPU
|
{F16E3C6A-1C94-4EAB-BE91-099618060B68}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||||
{F16E3C6A-1C94-4EAB-BE91-099618060B68}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
{F16E3C6A-1C94-4EAB-BE91-099618060B68}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||||
|
Loading…
x
Reference in New Issue
Block a user