Browse Source

CompleteOrderAsyn action is added.

pull/2134/head
hsn 1 year ago
parent
commit
abf4fc5fe7
6 changed files with 122 additions and 1 deletions
  1. +16
    -0
      src/Services/Ordering/Ordering.API/Application/Commands/CompleteOrderCommand.cs
  2. +48
    -0
      src/Services/Ordering/Ordering.API/Application/Commands/CompleteOrderCommandHandler.cs
  3. +30
    -0
      src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs
  4. +14
    -0
      src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Order.cs
  5. +2
    -1
      src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/OrderStatus.cs
  6. +12
    -0
      src/Services/Ordering/Ordering.Domain/Events/OrderCompletedDomainEvent.cs

+ 16
- 0
src/Services/Ordering/Ordering.API/Application/Commands/CompleteOrderCommand.cs View File

@ -0,0 +1,16 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands;
public class CompleteOrderCommand : IRequest<bool>
{
[DataMember]
public int OrderNumber { get; set; }
public CompleteOrderCommand()
{
}
public CompleteOrderCommand(int orderNumber)
{
OrderNumber = orderNumber;
}
}

+ 48
- 0
src/Services/Ordering/Ordering.API/Application/Commands/CompleteOrderCommandHandler.cs View File

@ -0,0 +1,48 @@
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
/// customer executes complete order from app
/// </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.
}
}

+ 30
- 0
src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs View File

@ -55,6 +55,36 @@ public class OrdersController : ControllerBase
return Ok(); return Ok();
} }
[Route("complete")]
[HttpPut]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<IActionResult> CompleteOrderAsync([FromBody] CompleteOrderCommand command, [FromHeader(Name = "x-requestid")] string requestId)
{
bool commandResult = false;
if (Guid.TryParse(requestId, out Guid guid) && guid != Guid.Empty)
{
var requestCompleteOrder = new IdentifiedCommand<CompleteOrderCommand, bool>(command, guid);
_logger.LogInformation(
"Sending command: {CommandName} - {IdProperty}: {CommandId} ({@Command})",
requestCompleteOrder.GetGenericTypeName(),
nameof(requestCompleteOrder.Command.OrderNumber),
requestCompleteOrder.Command.OrderNumber,
requestCompleteOrder);
commandResult = await _mediator.Send(requestCompleteOrder);
}
if (!commandResult)
{
return BadRequest();
}
return Ok();
}
[Route("ship")] [Route("ship")]
[HttpPut] [HttpPut]
[ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status200OK)]


+ 14
- 0
src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Order.cs View File

@ -156,6 +156,20 @@ public class Order
AddDomainEvent(new OrderCancelledDomainEvent(this)); AddDomainEvent(new OrderCancelledDomainEvent(this));
} }
public void SetCompletedStatus()
{
// make sure it is shipped and paid before completing
if (_orderStatusId == OrderStatus.Paid.Id ||
_orderStatusId == OrderStatus.Shipped.Id)
{
StatusChangeException(OrderStatus.Completed);
}
_orderStatusId = OrderStatus.Completed.Id;
_description = $"The order is completed.";
AddDomainEvent(new OrderCompletedDomainEvent(this)); // a postponed way to raise domain events
}
public void SetCancelledStatusWhenStockIsRejected(IEnumerable<int> orderStockRejectedItems) public void SetCancelledStatusWhenStockIsRejected(IEnumerable<int> orderStockRejectedItems)
{ {
if (_orderStatusId == OrderStatus.AwaitingValidation.Id) if (_orderStatusId == OrderStatus.AwaitingValidation.Id)


+ 2
- 1
src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/OrderStatus.cs View File

@ -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 Completed = new OrderStatus(7, nameof(Completed).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, Completed };
public static OrderStatus FromName(string name) public static OrderStatus FromName(string name)
{ {


+ 12
- 0
src/Services/Ordering/Ordering.Domain/Events/OrderCompletedDomainEvent.cs View File

@ -0,0 +1,12 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.Events;
public class OrderCompletedDomainEvent : INotification
{
public Order Order { get; }
public OrderCompletedDomainEvent(Order order)
{
Order = order;
}
}

Loading…
Cancel
Save