Browse Source

Introduce `IOrderAppService.CheckCreateAsync` method

pull/190/head
gdlcf88 4 years ago
parent
commit
525f1c415d
  1. 8
      modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application.Contracts/EasyAbp/EShop/Orders/Orders/Dtos/CheckCreateOrderInput.cs
  2. 11
      modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application.Contracts/EasyAbp/EShop/Orders/Orders/Dtos/CheckCreateOrderResultDto.cs
  3. 2
      modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application.Contracts/EasyAbp/EShop/Orders/Orders/IOrderAppService.cs
  4. 43
      modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application/EasyAbp/EShop/Orders/Orders/OrderAppService.cs
  5. 7
      modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.HttpApi/EasyAbp/EShop/Orders/Orders/OrderController.cs
  6. 83
      modules/EasyAbp.EShop.Orders/test/EasyAbp.EShop.Orders.Application.Tests/Orders/OrderAppServiceTests.cs

8
modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application.Contracts/EasyAbp/EShop/Orders/Orders/Dtos/CheckCreateOrderInput.cs

@ -0,0 +1,8 @@
using System;
namespace EasyAbp.EShop.Orders.Orders.Dtos;
[Serializable]
public class CheckCreateOrderInput : CreateOrderDto
{
}

11
modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application.Contracts/EasyAbp/EShop/Orders/Orders/Dtos/CheckCreateOrderResultDto.cs

@ -0,0 +1,11 @@
using System;
namespace EasyAbp.EShop.Orders.Orders.Dtos;
[Serializable]
public class CheckCreateOrderResultDto
{
public bool CanCreate { get; set; }
public string Reason { get; set; }
}

2
modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application.Contracts/EasyAbp/EShop/Orders/Orders/IOrderAppService.cs

@ -19,5 +19,7 @@ namespace EasyAbp.EShop.Orders.Orders
Task<OrderDto> CancelAsync(Guid id, CancelOrderInput input);
Task<OrderDto> UpdateStaffRemarkAsync(Guid id, UpdateStaffRemarkInput input);
Task<CheckCreateOrderResultDto> CheckCreateAsync(CheckCreateOrderInput input);
}
}

43
modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application/EasyAbp/EShop/Orders/Orders/OrderAppService.cs

@ -12,6 +12,7 @@ using EasyAbp.EShop.Stores.Stores;
using Microsoft.AspNetCore.Authorization;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Uow;
using Volo.Abp.Users;
namespace EasyAbp.EShop.Orders.Orders
@ -91,7 +92,7 @@ namespace EasyAbp.EShop.Orders.Orders
var productDict = await GetProductDictionaryAsync(input.OrderLines.Select(dto => dto.ProductId).ToList());
ThrowIfExistFlashSalesProduct(productDict);
await AuthorizationService.CheckAsync(
new OrderCreationResource
{
@ -108,11 +109,12 @@ namespace EasyAbp.EShop.Orders.Orders
.Where(x => x.HasValue)
.Select(x => x.Value)
.ToList();
var productDetailDict = await GetProductDetailDictionaryAsync(productDetailIds);
// Todo: Can we use IProductDataScopedCache/IProductDetailDataScopedCache instead of productDict/productDetailDict?
var order = await _newOrderGenerator.GenerateAsync(CurrentUser.GetId(), input, productDict, productDetailDict);
var order = await _newOrderGenerator.GenerateAsync(CurrentUser.GetId(), input, productDict,
productDetailDict);
await DiscountOrderAsync(order, productDict);
@ -203,11 +205,11 @@ namespace EasyAbp.EShop.Orders.Orders
return await MapToGetOutputDtoAsync(order);
}
public virtual async Task<OrderDto> CancelAsync(Guid id, CancelOrderInput input)
{
var order = await GetEntityByIdAsync(id);
await AuthorizationService.CheckAsync(
order,
new OrderOperationAuthorizationRequirement(OrderOperation.Cancellation)
@ -225,10 +227,39 @@ namespace EasyAbp.EShop.Orders.Orders
await CheckMultiStorePolicyAsync(order.StoreId, OrdersPermissions.Orders.Manage);
order.SetStaffRemark(input.StaffRemark);
await Repository.UpdateAsync(order, true);
return await MapToGetOutputDtoAsync(order);
}
public virtual async Task<CheckCreateOrderResultDto> CheckCreateAsync(CheckCreateOrderInput input)
{
var requiresNewUow = !UnitOfWorkManager.Current?.Options.IsTransactional ?? false;
using var uow = UnitOfWorkManager.Begin(new AbpUnitOfWorkOptions(true), requiresNewUow);
try
{
await CreateAsync(input);
await uow.RollbackAsync();
}
catch
{
await uow.RollbackAsync();
return new CheckCreateOrderResultDto
{
CanCreate = false,
Reason = "Unknown" // Todo: get failure reason
};
}
return new CheckCreateOrderResultDto
{
CanCreate = true,
Reason = null,
};
}
}
}

7
modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.HttpApi/EasyAbp/EShop/Orders/Orders/OrderController.cs

@ -81,5 +81,12 @@ namespace EasyAbp.EShop.Orders.Orders
{
return _service.UpdateStaffRemarkAsync(id, input);
}
[HttpPost]
[Route("check-create")]
public virtual Task<CheckCreateOrderResultDto> CheckCreateAsync(CheckCreateOrderInput input)
{
return _service.CheckCreateAsync(input);
}
}
}

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

@ -13,6 +13,7 @@ using Microsoft.Extensions.DependencyInjection;
using NSubstitute;
using Shouldly;
using Volo.Abp;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Settings;
using Volo.Abp.Timing;
using Xunit;
@ -113,6 +114,88 @@ namespace EasyAbp.EShop.Orders.Orders
services.AddTransient(_ => productDetailAppService);
}
[Fact]
public async Task Check_Create_Order_Should_Succeed()
{
var orderRepository = ServiceProvider.GetRequiredService<IOrderRepository>();
var orderCount = 0;
await WithUnitOfWorkAsync(async () =>
{
orderCount = await orderRepository.CountAsync();
});
// Arrange
var checkCreateOrderInput = new CheckCreateOrderInput
{
CustomerRemark = "customer remark",
StoreId = OrderTestData.Store1Id,
OrderLines = new List<CreateOrderLineDto>
{
new CreateOrderLineDto
{
ProductId = OrderTestData.Product1Id,
ProductSkuId = OrderTestData.ProductSku1Id,
Quantity = 10
}
}
};
CheckCreateOrderResultDto resultDto = null;
// Act
await WithUnitOfWorkAsync(async () =>
{
resultDto = await _orderAppService.CheckCreateAsync(checkCreateOrderInput);
});
// Assert
resultDto.CanCreate.ShouldBeTrue();
await WithUnitOfWorkAsync(async () =>
{
orderCount.ShouldBeEquivalentTo(await orderRepository.CountAsync());
});
}
[Fact]
public async Task Check_Create_Order_Should_Fail()
{
var orderRepository = ServiceProvider.GetRequiredService<IOrderRepository>();
var orderCount = 0;
await WithUnitOfWorkAsync(async () =>
{
orderCount = await orderRepository.CountAsync();
});
// Arrange
var checkCreateOrderInput = new CheckCreateOrderInput
{
CustomerRemark = "customer remark",
StoreId = OrderTestData.Store1Id,
OrderLines = new List<CreateOrderLineDto>
{
new CreateOrderLineDto
{
ProductId = OrderTestData.Product1Id,
ProductSkuId = OrderTestData.ProductSku1Id,
Quantity = 101 // limited range: 1-100
}
}
};
CheckCreateOrderResultDto resultDto = null;
// Act
await WithUnitOfWorkAsync(async () =>
{
resultDto = await _orderAppService.CheckCreateAsync(checkCreateOrderInput);
});
// Assert
resultDto.CanCreate.ShouldBeFalse();
await WithUnitOfWorkAsync(async () =>
{
orderCount.ShouldBeEquivalentTo(await orderRepository.CountAsync());
});
}
[Fact]
public async Task Order_Should_Be_Created()
{

Loading…
Cancel
Save