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)); 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; 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; 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 EasyAbp.EShop.Products.Products;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Entities.Events.Distributed; using Volo.Abp.Domain.Entities.Events.Distributed;
@ -9,6 +10,9 @@ namespace EasyAbp.EShop.Orders.Orders
{ {
public class OrderCreatedEventHandler : IDistributedEventHandler<EntityCreatedEto<OrderEto>>, ITransientDependency 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 ICurrentTenant _currentTenant;
private readonly IDistributedEventBus _distributedEventBus; private readonly IDistributedEventBus _distributedEventBus;
@ -19,9 +23,21 @@ namespace EasyAbp.EShop.Orders.Orders
_currentTenant = currentTenant; _currentTenant = currentTenant;
_distributedEventBus = distributedEventBus; _distributedEventBus = distributedEventBus;
} }
public virtual async Task HandleEventAsync(EntityCreatedEto<OrderEto> eventData) 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); using var changeTenant = _currentTenant.Change(eventData.Entity.TenantId);
await _distributedEventBus.PublishAsync(new ProductInventoryReductionAfterOrderPlacedResultEto 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)] [UnitOfWork(true)]
public virtual async Task HandleEventAsync(EntityCreatedEto<OrderEto> eventData) 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); using var changeTenant = _currentTenant.Change(eventData.Entity.TenantId);
var models = new List<ConsumeInventoryModel>(); var models = new List<ConsumeInventoryModel>();
foreach (var orderLine in eventData.Entity.OrderLines) foreach (var orderLine in eventData.Entity.OrderLines)
{ {
// Todo: Should use ProductHistory. var inventoryStrategy = orderLine.ProductInventoryStrategy;
var product = await _productRepository.FindAsync(orderLine.ProductId); 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); var productSku = product?.ProductSkus.FirstOrDefault(sku => sku.Id == orderLine.ProductSkuId);
if (productSku == null) if (productSku == null)
{ {
await PublishInventoryReductionResultEventAsync(eventData, false); await PublishInventoryReductionResultEventAsync(eventData, false);
return; return;
} }
if (product.InventoryStrategy != InventoryStrategy.ReduceAfterPlacing) inventoryStrategy ??= product.InventoryStrategy;
if (inventoryStrategy != InventoryStrategy.ReduceAfterPlacing)
{ {
continue; 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) foreach (var orderLine in eventData.Order.OrderLines)
{ {
// Todo: Should use ProductHistory. var inventoryStrategy = orderLine.ProductInventoryStrategy;
var product = await _productRepository.FindAsync(orderLine.ProductId); 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); var productSku = product?.ProductSkus.FirstOrDefault(sku => sku.Id == orderLine.ProductSkuId);
if (productSku == null) if (productSku == null)
{ {
await PublishInventoryReductionResultEventAsync(eventData, false); await PublishInventoryReductionResultEventAsync(eventData, false);
@ -56,7 +59,8 @@ namespace EasyAbp.EShop.Products.Products
return; return;
} }
if (product.InventoryStrategy != InventoryStrategy.ReduceAfterPayment) inventoryStrategy ??= product.InventoryStrategy;
if (inventoryStrategy != InventoryStrategy.ReduceAfterPayment)
{ {
continue; continue;
} }

Loading…
Cancel
Save