Browse Source

Introduce CurrencyCode setting in the Orders module

Resolve #22
pull/178/head
gdlcf88 4 years ago
parent
commit
29cf960a5e
  1. 33
      modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application/EasyAbp/EShop/Orders/Orders/NewOrderGenerator.cs
  2. 4
      modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain.Shared/EasyAbp/EShop/Orders/Localization/Orders/en.json
  3. 4
      modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain.Shared/EasyAbp/EShop/Orders/Localization/Orders/zh-Hans.json
  4. 4
      modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain.Shared/EasyAbp/EShop/Orders/Localization/Orders/zh-Hant.json
  5. 21
      modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain/EasyAbp/EShop/Orders/Settings/OrdersSettingDefinitionProvider.cs
  6. 2
      modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain/EasyAbp/EShop/Orders/Settings/OrdersSettings.cs
  7. 61
      modules/EasyAbp.EShop.Orders/test/EasyAbp.EShop.Orders.Application.Tests/Orders/OrderAppServiceTests.cs

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

@ -3,14 +3,17 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using EasyAbp.EShop.Orders.Orders.Dtos;
using EasyAbp.EShop.Orders.Settings;
using EasyAbp.EShop.Products.ProductDetails.Dtos;
using EasyAbp.EShop.Products.Products;
using EasyAbp.EShop.Products.Products.Dtos;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Guids;
using Volo.Abp.MultiTenancy;
using Volo.Abp.ObjectExtending;
using Volo.Abp.Settings;
using Volo.Abp.Timing;
namespace EasyAbp.EShop.Orders.Orders
@ -20,6 +23,7 @@ namespace EasyAbp.EShop.Orders.Orders
private readonly IClock _clock;
private readonly IGuidGenerator _guidGenerator;
private readonly ICurrentTenant _currentTenant;
private readonly ISettingProvider _settingProvider;
private readonly IServiceProvider _serviceProvider;
private readonly IOrderNumberGenerator _orderNumberGenerator;
private readonly IProductSkuDescriptionProvider _productSkuDescriptionProvider;
@ -29,6 +33,7 @@ namespace EasyAbp.EShop.Orders.Orders
IClock clock,
IGuidGenerator guidGenerator,
ICurrentTenant currentTenant,
ISettingProvider settingProvider,
IServiceProvider serviceProvider,
IOrderNumberGenerator orderNumberGenerator,
IProductSkuDescriptionProvider productSkuDescriptionProvider,
@ -37,6 +42,7 @@ namespace EasyAbp.EShop.Orders.Orders
_clock = clock;
_guidGenerator = guidGenerator;
_currentTenant = currentTenant;
_settingProvider = settingProvider;
_serviceProvider = serviceProvider;
_orderNumberGenerator = orderNumberGenerator;
_productSkuDescriptionProvider = productSkuDescriptionProvider;
@ -53,16 +59,17 @@ namespace EasyAbp.EShop.Orders.Orders
orderLines.Add(await GenerateOrderLineAsync(input, inputOrderLine, productDict, productDetailDict));
}
var storeCurrency = await GetStoreCurrencyAsync(input.StoreId);
var effectiveCurrency = await GetEffectiveCurrencyAsync();
if (orderLines.Any(x => x.Currency != storeCurrency))
if (orderLines.Any(x => x.Currency != effectiveCurrency))
{
throw new UnexpectedCurrencyException(storeCurrency);
throw new UnexpectedCurrencyException(effectiveCurrency);
}
var productTotalPrice = orderLines.Select(x => x.TotalPrice).Sum();
var paymentExpireIn = orderLines.Select(x => productDict[x.ProductId].GetSkuPaymentExpireIn(x.ProductSkuId)).Min();
var paymentExpireIn = orderLines.Select(x => productDict[x.ProductId].GetSkuPaymentExpireIn(x.ProductSkuId))
.Min();
var totalPrice = productTotalPrice;
var totalDiscount = orderLines.Select(x => x.TotalDiscount).Sum();
@ -72,7 +79,7 @@ namespace EasyAbp.EShop.Orders.Orders
tenantId: _currentTenant.Id,
storeId: input.StoreId,
customerUserId: customerUserId,
currency: storeCurrency,
currency: effectiveCurrency,
productTotalPrice: productTotalPrice,
totalDiscount: totalDiscount,
totalPrice: totalPrice,
@ -124,7 +131,7 @@ namespace EasyAbp.EShop.Orders.Orders
}
var unitPrice = await GetUnitPriceAsync(input, inputOrderLine, product, productSku);
var totalPrice = unitPrice * inputOrderLine.Quantity;
var orderLine = new OrderLine(
@ -148,7 +155,7 @@ namespace EasyAbp.EShop.Orders.Orders
actualTotalPrice: totalPrice,
quantity: inputOrderLine.Quantity
);
inputOrderLine.MapExtraPropertiesTo(orderLine, MappingPropertyDefinitionChecks.Destination);
return orderLine;
@ -171,10 +178,14 @@ namespace EasyAbp.EShop.Orders.Orders
return productSku.Price;
}
protected virtual Task<string> GetStoreCurrencyAsync(Guid storeId)
protected virtual async Task<string> GetEffectiveCurrencyAsync()
{
// Todo: Get real store currency configuration.
return Task.FromResult("USD");
var currencyCode = Check.NotNullOrWhiteSpace(
await _settingProvider.GetOrNullAsync(OrdersSettings.CurrencyCode),
nameof(OrdersSettings.CurrencyCode)
);
return currencyCode;
}
}
}

4
modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain.Shared/EasyAbp/EShop/Orders/Localization/Orders/en.json

@ -53,6 +53,8 @@
"EasyAbp.EShop.Orders:InvalidRefundAmount": "The refund amount ({amount}) is invalid.",
"EasyAbp.EShop.Orders:InvalidRefundQuantity": "The refund quantity ({quantity}) is invalid.",
"EasyAbp.EShop.Orders:OrderIsInWrongStage": "The order {orderId} is in the wrong stage.",
"EasyAbp.EShop.Orders:ExistFlashSalesProduct": "Exist unexpected flash-sales product"
"EasyAbp.EShop.Orders:ExistFlashSalesProduct": "Exist unexpected flash-sales product",
"DisplayName:EasyAbp.EShop.Orders.CurrencyCode": "Currency code",
"Description:EasyAbp.EShop.Orders.CurrencyCode": "ISO 4217 code (see https://en.wikipedia.org/wiki/ISO_4217)"
}
}

4
modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain.Shared/EasyAbp/EShop/Orders/Localization/Orders/zh-Hans.json

@ -53,6 +53,8 @@
"EasyAbp.EShop.Orders:InvalidRefundAmount": "退款金额({amount})无效",
"EasyAbp.EShop.Orders:InvalidRefundQuantity": "退款数量({quantity})无效",
"EasyAbp.EShop.Orders:OrderIsInWrongStage": "订单{orderId}处于错误的阶段",
"EasyAbp.EShop.Orders:ExistFlashSalesProduct": "清单中不允许存在闪购产品"
"EasyAbp.EShop.Orders:ExistFlashSalesProduct": "清单中不允许存在闪购产品",
"DisplayName:EasyAbp.EShop.Orders.CurrencyCode": "货币代码",
"Description:EasyAbp.EShop.Orders.CurrencyCode": "ISO 4217 货币代码 (详见 https://en.wikipedia.org/wiki/ISO_4217)"
}
}

4
modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain.Shared/EasyAbp/EShop/Orders/Localization/Orders/zh-Hant.json

@ -53,6 +53,8 @@
"EasyAbp.EShop.Orders:InvalidRefundAmount": "退款金額({amount})無效",
"EasyAbp.EShop.Orders:InvalidRefundQuantity": "退款數量({quantity})無效",
"EasyAbp.EShop.Orders:OrderIsInWrongStage": "訂單{orderId}處於錯誤的階段",
"EasyAbp.EShop.Orders:ExistFlashSalesProduct": "清單中不允許存在閃購產品"
"EasyAbp.EShop.Orders:ExistFlashSalesProduct": "清單中不允許存在閃購產品",
"DisplayName:EasyAbp.EShop.Orders.CurrencyCode": "貨幣代碼",
"Description:EasyAbp.EShop.Orders.CurrencyCode": "ISO 4217 貨幣代碼 (詳見 https://en.wikipedia.org/wiki/ISO_4217)"
}
}

21
modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain/EasyAbp/EShop/Orders/Settings/OrdersSettingDefinitionProvider.cs

@ -1,14 +1,33 @@
using Volo.Abp.Settings;
using EasyAbp.EShop.Orders.Localization;
using Volo.Abp.Localization;
using Volo.Abp.Settings;
namespace EasyAbp.EShop.Orders.Settings
{
public class OrdersSettingDefinitionProvider : SettingDefinitionProvider
{
public static string DefaultCurrency { get; set; } = "USD";
public override void Define(ISettingDefinitionContext context)
{
/* Define module settings here.
* Use names from OrdersSettings class.
*/
context.Add(
new SettingDefinition(
OrdersSettings.CurrencyCode,
DefaultCurrency,
L($"DisplayName:{OrdersSettings.CurrencyCode}"),
L($"Description:{OrdersSettings.CurrencyCode}"),
isVisibleToClients: true
)
);
}
private static LocalizableString L(string name)
{
return LocalizableString.Create<OrdersResource>(name);
}
}
}

2
modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain/EasyAbp/EShop/Orders/Settings/OrdersSettings.cs

@ -7,5 +7,7 @@
/* Add constants for setting names. Example:
* public const string MySettingName = GroupName + ".MySettingName";
*/
public const string CurrencyCode = GroupName + ".CurrencyCode";
}
}

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

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using EasyAbp.EShop.Orders.Orders.Dtos;
using EasyAbp.EShop.Orders.Settings;
using EasyAbp.EShop.Products.ProductDetails;
using EasyAbp.EShop.Products.ProductDetails.Dtos;
using EasyAbp.EShop.Products.Products;
@ -12,6 +13,7 @@ using Microsoft.Extensions.DependencyInjection;
using NSubstitute;
using Shouldly;
using Volo.Abp;
using Volo.Abp.Settings;
using Volo.Abp.Timing;
using Xunit;
@ -532,17 +534,62 @@ namespace EasyAbp.EShop.Orders.Orders
}
};
Product1.InventoryStrategy = InventoryStrategy.FlashSales;
try
{
Product1.InventoryStrategy = InventoryStrategy.FlashSales;
await WithUnitOfWorkAsync(async () =>
await WithUnitOfWorkAsync(async () =>
{
var exception =
await Should.ThrowAsync<BusinessException>(() => _orderAppService.CreateAsync(createOrderDto));
exception.Code.ShouldBe(OrdersErrorCodes.ExistFlashSalesProduct);
});
Product1.InventoryStrategy = InventoryStrategy.NoNeed;
}
catch
{
var exception =
await Should.ThrowAsync<BusinessException>(() => _orderAppService.CreateAsync(createOrderDto));
Product1.InventoryStrategy = InventoryStrategy.NoNeed;
throw;
}
}
exception.Code.ShouldBe(OrdersErrorCodes.ExistFlashSalesProduct);
});
[Fact]
public async Task Should_Throw_If_Product_Sku_Uses_Unexpected_Currency()
{
var createOrderDto = new CreateOrderDto
{
StoreId = OrderTestData.Store1Id,
OrderLines = new List<CreateOrderLineDto>
{
new()
{
ProductId = OrderTestData.Product1Id,
ProductSkuId = OrderTestData.ProductSku1Id,
Quantity = 1
}
}
};
try
{
OrdersSettingDefinitionProvider.DefaultCurrency = "CNY"; // The effective value is "USD"
await WithUnitOfWorkAsync(async () =>
{
var exception =
await Should.ThrowAsync<BusinessException>(() => _orderAppService.CreateAsync(createOrderDto));
Product1.InventoryStrategy = InventoryStrategy.NoNeed;
exception.Code.ShouldBe(OrdersErrorCodes.UnexpectedCurrency);
});
OrdersSettingDefinitionProvider.DefaultCurrency = "USD";
}
catch
{
OrdersSettingDefinitionProvider.DefaultCurrency = "USD";
throw;
}
}
}
}
Loading…
Cancel
Save