Browse Source

Set `Order.ReducedInventoryAfterPlacingTime` in advance

Resolve #214
pull/217/head
gdlcf88 4 years ago
parent
commit
6713e47355
  1. 7
      modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application/EasyAbp/EShop/Orders/Orders/NewOrderGenerator.cs
  2. 80
      modules/EasyAbp.EShop.Orders/test/EasyAbp.EShop.Orders.Application.Tests/Orders/OrderAppServiceTests.cs
  3. 20
      modules/EasyAbp.EShop.Orders/test/EasyAbp.EShop.Orders.Application.Tests/Orders/OrderCreatedEventHandler.cs
  4. 21
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/OrderCreatedEventHandler.cs
  5. 12
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/OrderPaidEventHandler.cs

7
modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application/EasyAbp/EShop/Orders/Orders/NewOrderGenerator.cs

@ -93,6 +93,13 @@ namespace EasyAbp.EShop.Orders.Orders
order.SetOrderNumber(await _orderNumberGenerator.CreateAsync(order));
// set ReducedInventoryAfterPlacingTime directly if an order contains no OrderLine with `InventoryStrategy.ReduceAfterPlacing`.
// see https://github.com/EasyAbp/EShop/issues/214
if (order.OrderLines.All(x => x.ProductInventoryStrategy != InventoryStrategy.ReduceAfterPlacing))
{
order.SetReducedInventoryAfterPlacingTime(_clock.Now);
}
return order;
}

80
modules/EasyAbp.EShop.Orders/test/EasyAbp.EShop.Orders.Application.Tests/Orders/OrderAppServiceTests.cs

@ -591,5 +591,85 @@ namespace EasyAbp.EShop.Orders.Orders
throw;
}
}
[Fact]
public async Task Should_Set_ReducedInventoryAfterPlacingTime_If_No_ReduceAfterPlacing_OrderLine()
{
var createOrderDto = new CreateOrderDto
{
CustomerRemark = "customer remark",
StoreId = OrderTestData.Store1Id,
OrderLines = new List<CreateOrderLineDto>
{
new CreateOrderLineDto
{
ProductId = OrderTestData.Product1Id,
ProductSkuId = OrderTestData.ProductSku1Id,
Quantity = 10
},
new CreateOrderLineDto
{
ProductId = OrderTestData.Product1Id,
ProductSkuId = OrderTestData.ProductSku2Id,
Quantity = 1
}
}
};
OrderDto createResponse = null;
await WithUnitOfWorkAsync(async () =>
{
createResponse = await _orderAppService.CreateAsync(createOrderDto);
});
var order = await _orderAppService.GetAsync(createResponse.Id);
// The fake inventory reducer (OrderCreatedEventHandler) should skip handling.
OrderCreatedEventHandler.LastOrderId.ShouldBe(order.Id);
OrderCreatedEventHandler.SkippedHandling.ShouldBeTrue();
order.ReducedInventoryAfterPlacingTime.ShouldNotBeNull();
}
[Fact]
public async Task Should_Not_Set_ReducedInventoryAfterPlacingTime_If_Contains_ReduceAfterPlacing_OrderLine()
{
Product1.InventoryStrategy = InventoryStrategy.ReduceAfterPlacing;
var createOrderDto = new CreateOrderDto
{
CustomerRemark = "customer remark",
StoreId = OrderTestData.Store1Id,
OrderLines = new List<CreateOrderLineDto>
{
new CreateOrderLineDto
{
ProductId = OrderTestData.Product1Id,
ProductSkuId = OrderTestData.ProductSku1Id,
Quantity = 10
},
new CreateOrderLineDto
{
ProductId = OrderTestData.Product1Id,
ProductSkuId = OrderTestData.ProductSku2Id,
Quantity = 1
}
}
};
OrderDto createResponse = null;
await WithUnitOfWorkAsync(async () =>
{
createResponse = await _orderAppService.CreateAsync(createOrderDto);
});
var order = await _orderAppService.GetAsync(createResponse.Id);
// The fake inventory reducer (OrderCreatedEventHandler) should handle it.
OrderCreatedEventHandler.LastOrderId.ShouldBe(order.Id);
OrderCreatedEventHandler.SkippedHandling.ShouldBeFalse();
order.ReducedInventoryAfterPlacingTime.ShouldNotBeNull();
}
}
}

20
modules/EasyAbp.EShop.Orders/test/EasyAbp.EShop.Orders.Application.Tests/Orders/OrderCreatedEventHandler.cs

@ -1,4 +1,5 @@
using System.Threading.Tasks;
using System;
using System.Threading.Tasks;
using EasyAbp.EShop.Products.Products;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Entities.Events.Distributed;
@ -9,6 +10,9 @@ namespace EasyAbp.EShop.Orders.Orders
{
public class OrderCreatedEventHandler : IDistributedEventHandler<EntityCreatedEto<OrderEto>>, ITransientDependency
{
public static Guid LastOrderId { get; set; }
public static bool SkippedHandling { get; set; }
private readonly ICurrentTenant _currentTenant;
private readonly IDistributedEventBus _distributedEventBus;
@ -19,9 +23,21 @@ namespace EasyAbp.EShop.Orders.Orders
_currentTenant = currentTenant;
_distributedEventBus = distributedEventBus;
}
public virtual async Task HandleEventAsync(EntityCreatedEto<OrderEto> eventData)
{
LastOrderId = eventData.Entity.Id;
// skip if an order contains no OrderLine with `InventoryStrategy.ReduceAfterPlacing`.
// see https://github.com/EasyAbp/EShop/issues/214
if (eventData.Entity.ReducedInventoryAfterPlacingTime is not null)
{
SkippedHandling = true;
return;
}
SkippedHandling = false;
using var changeTenant = _currentTenant.Change(eventData.Entity.TenantId);
await _distributedEventBus.PublishAsync(new ProductInventoryReductionAfterOrderPlacedResultEto

21
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/OrderCreatedEventHandler.cs

@ -39,25 +39,36 @@ namespace EasyAbp.EShop.Products.Products
[UnitOfWork(true)]
public virtual async Task HandleEventAsync(EntityCreatedEto<OrderEto> eventData)
{
// skip if an order contains no OrderLine with `InventoryStrategy.ReduceAfterPlacing`.
// see https://github.com/EasyAbp/EShop/issues/214
if (eventData.Entity.ReducedInventoryAfterPlacingTime is not null)
{
return;
}
using var changeTenant = _currentTenant.Change(eventData.Entity.TenantId);
var models = new List<ConsumeInventoryModel>();
foreach (var orderLine in eventData.Entity.OrderLines)
{
// Todo: Should use ProductHistory.
var product = await _productRepository.FindAsync(orderLine.ProductId);
var inventoryStrategy = orderLine.ProductInventoryStrategy;
if (inventoryStrategy is not null && inventoryStrategy != InventoryStrategy.ReduceAfterPlacing)
{
continue;
}
var product = await _productRepository.FindAsync(orderLine.ProductId);
var productSku = product?.ProductSkus.FirstOrDefault(sku => sku.Id == orderLine.ProductSkuId);
if (productSku == null)
{
await PublishInventoryReductionResultEventAsync(eventData, false);
return;
}
if (product.InventoryStrategy != InventoryStrategy.ReduceAfterPlacing)
inventoryStrategy ??= product.InventoryStrategy;
if (inventoryStrategy != InventoryStrategy.ReduceAfterPlacing)
{
continue;
}

12
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/OrderPaidEventHandler.cs

@ -44,11 +44,14 @@ namespace EasyAbp.EShop.Products.Products
foreach (var orderLine in eventData.Order.OrderLines)
{
// Todo: Should use ProductHistory.
var product = await _productRepository.FindAsync(orderLine.ProductId);
var inventoryStrategy = orderLine.ProductInventoryStrategy;
if (inventoryStrategy is not null && inventoryStrategy != InventoryStrategy.ReduceAfterPayment)
{
continue;
}
var product = await _productRepository.FindAsync(orderLine.ProductId);
var productSku = product?.ProductSkus.FirstOrDefault(sku => sku.Id == orderLine.ProductSkuId);
if (productSku == null)
{
await PublishInventoryReductionResultEventAsync(eventData, false);
@ -56,7 +59,8 @@ namespace EasyAbp.EShop.Products.Products
return;
}
if (product.InventoryStrategy != InventoryStrategy.ReduceAfterPayment)
inventoryStrategy ??= product.InventoryStrategy;
if (inventoryStrategy != InventoryStrategy.ReduceAfterPayment)
{
continue;
}

Loading…
Cancel
Save