Browse Source

Merge branch 'dev' of https://github.com/EasyAbp/EShop into dev

pull/87/head
gdlcf88 6 years ago
parent
commit
135c548d36
  1. 2
      common.props
  2. 7
      modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application/EasyAbp/EShop/Orders/Orders/NewOrderGenerator.cs
  3. 2
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application.Contracts/EasyAbp/EShop/Products/ProductInventories/Dtos/ProductInventoryDto.cs
  4. 3
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application.Contracts/EasyAbp/EShop/Products/Products/Dtos/CreateUpdateProductDto.cs
  5. 6
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application.Contracts/EasyAbp/EShop/Products/Products/Dtos/CreateUpdateProductSkuDto.cs
  6. 4
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application.Contracts/EasyAbp/EShop/Products/Products/Dtos/ProductDto.cs
  7. 7
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application.Contracts/EasyAbp/EShop/Products/Products/Dtos/ProductSkuDto.cs
  8. 4
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application/EasyAbp/EShop/Products/ProductInventories/ProductInventoryAppService.cs
  9. 31
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application/EasyAbp/EShop/Products/Products/ProductAppService.cs
  10. 1
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application/EasyAbp/EShop/Products/ProductsApplicationAutoMapperProfile.cs
  11. 5
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/cs.json
  12. 5
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/en.json
  13. 5
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/pl.json
  14. 5
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/pt-BR.json
  15. 5
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/sl.json
  16. 5
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/tr.json
  17. 5
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/vi.json
  18. 5
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/zh-Hans.json
  19. 5
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/zh-Hant.json
  20. 2
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/ProductInventories/ProductInventoryChangedEto.cs
  21. 5
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/ProductInventories/IProductInventoryRepository.cs
  22. 24
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/ProductInventories/ProductInventory.cs
  23. 2
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ConsumeInventoryModel.cs
  24. 37
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/DefaultProductInventoryProvider.cs
  25. 11
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/IProductDiscountManager.cs
  26. 10
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/IProductInventoryProvider.cs
  27. 8
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/IProductManager.cs
  28. 9
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/InventoryDataModel.cs
  29. 6
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/OrderCreatedEventHandler.cs
  30. 6
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/OrderPaidEventHandler.cs
  31. 5
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/Product.cs
  32. 22
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductDiscountManager.cs
  33. 54
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductManager.cs
  34. 5
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductSku.cs
  35. 22
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.EntityFrameworkCore/EasyAbp/EShop/Products/ProductInventories/ProductInventoryRepository.cs
  36. 2
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/Pages/EShop/Products/Products/Product/Index.cshtml
  37. 6
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/Pages/EShop/Products/Products/Product/ViewModels/CreateEditProductViewModel.cs
  38. 2
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/Pages/EShop/Products/Products/Product/index.js
  39. 1
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/Pages/EShop/Products/Products/ProductSku/Index.cshtml
  40. 5
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/Pages/EShop/Products/Products/ProductSku/ViewModels/EditProductSkuViewModel.cs
  41. 1
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/Pages/EShop/Products/Products/ProductSku/index.js
  42. 1
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/ProductsWebAutoMapperProfile.cs
  43. 3837
      samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore.DbMigrations/Migrations/20200706060054_AddedSpecifiedInventoryProviderName.Designer.cs
  44. 31
      samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore.DbMigrations/Migrations/20200706060054_AddedSpecifiedInventoryProviderName.cs
  45. 3837
      samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore.DbMigrations/Migrations/20200706070250_ChangedSoldToLong.Designer.cs
  46. 27
      samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore.DbMigrations/Migrations/20200706070250_ChangedSoldToLong.cs
  47. 10
      samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore.DbMigrations/Migrations/EShopSampleMigrationsDbContextModelSnapshot.cs

2
common.props

@ -1,7 +1,7 @@
<Project> <Project>
<PropertyGroup> <PropertyGroup>
<LangVersion>latest</LangVersion> <LangVersion>latest</LangVersion>
<Version>0.3.8</Version> <Version>0.4.0</Version>
<NoWarn>$(NoWarn);CS1591</NoWarn> <NoWarn>$(NoWarn);CS1591</NoWarn>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild> <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Authors>EasyAbp Team</Authors> <Authors>EasyAbp Team</Authors>

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

@ -4,6 +4,7 @@ using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using EasyAbp.EShop.Orders.Orders.Dtos; using EasyAbp.EShop.Orders.Orders.Dtos;
using EasyAbp.EShop.Products.ProductInventories;
using EasyAbp.EShop.Products.Products; using EasyAbp.EShop.Products.Products;
using EasyAbp.EShop.Products.Products.Dtos; using EasyAbp.EShop.Products.Products.Dtos;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
@ -75,6 +76,12 @@ namespace EasyAbp.EShop.Orders.Orders
{ {
throw new OrderLineInvalidQuantityException(product.Id, productSku.Id, input.Quantity); throw new OrderLineInvalidQuantityException(product.Id, productSku.Id, input.Quantity);
} }
if (productSku.Inventory < input.Quantity)
{
throw new InventoryInsufficientException(input.ProductId, input.ProductSkuId, input.Quantity,
productSku.Inventory);
}
return new OrderLine( return new OrderLine(
id: _guidGenerator.Create(), id: _guidGenerator.Create(),

2
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application.Contracts/EasyAbp/EShop/Products/ProductInventories/Dtos/ProductInventoryDto.cs

@ -12,6 +12,6 @@ namespace EasyAbp.EShop.Products.ProductInventories.Dtos
public int Inventory { get; set; } public int Inventory { get; set; }
public int Sold { get; set; } public long Sold { get; set; }
} }
} }

3
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application.Contracts/EasyAbp/EShop/Products/Products/Dtos/CreateUpdateProductDto.cs

@ -41,6 +41,9 @@ namespace EasyAbp.EShop.Products.Products.Dtos
[DisplayName("ProductMediaResources")] [DisplayName("ProductMediaResources")]
public string MediaResources { get; set; } public string MediaResources { get; set; }
[DisplayName("ProductSpecifiedInventoryProviderName")]
public string SpecifiedInventoryProviderName { get; set; }
[DisplayName("ProductIsPublished")] [DisplayName("ProductIsPublished")]
public bool IsPublished { get; set; } public bool IsPublished { get; set; }

6
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application.Contracts/EasyAbp/EShop/Products/Products/Dtos/CreateUpdateProductSkuDto.cs

@ -27,6 +27,12 @@ namespace EasyAbp.EShop.Products.Products.Dtos
[DefaultValue(99)] [DefaultValue(99)]
[DisplayName("ProductSkuOrderMaxQuantity")] [DisplayName("ProductSkuOrderMaxQuantity")]
public int OrderMaxQuantity { get; set; } public int OrderMaxQuantity { get; set; }
[DisplayName("ProductSkuMediaResources")]
public string MediaResources { get; set; }
[DisplayName("ProductSkuSpecifiedInventoryProviderName")]
public string SpecifiedInventoryProviderName { get; set; }
[DisplayName("ProductSkuProductDetailId")] [DisplayName("ProductSkuProductDetailId")]
public Guid? ProductDetailId { get; set; } public Guid? ProductDetailId { get; set; }

4
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application.Contracts/EasyAbp/EShop/Products/Products/Dtos/ProductDto.cs

@ -20,6 +20,8 @@ namespace EasyAbp.EShop.Products.Products.Dtos
public string MediaResources { get; set; } public string MediaResources { get; set; }
public string SpecifiedInventoryProviderName { get; set; }
public int DisplayOrder { get; set; } public int DisplayOrder { get; set; }
public bool IsPublished { get; set; } public bool IsPublished { get; set; }
@ -28,6 +30,8 @@ namespace EasyAbp.EShop.Products.Products.Dtos
public bool IsHidden { get; set; } public bool IsHidden { get; set; }
public long Sold { get; set; }
public decimal? MinimumPrice { get; set; } public decimal? MinimumPrice { get; set; }
public decimal? MaximumPrice { get; set; } public decimal? MaximumPrice { get; set; }

7
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application.Contracts/EasyAbp/EShop/Products/Products/Dtos/ProductSkuDto.cs

@ -19,14 +19,11 @@ namespace EasyAbp.EShop.Products.Products.Dtos
/// </summary> /// </summary>
public decimal Price { get; set; } public decimal Price { get; set; }
/// <summary>
/// Price from IProductDiscountManager
/// </summary>
public decimal DiscountedPrice { get; set; } public decimal DiscountedPrice { get; set; }
public int Inventory { get; set; } public int Inventory { get; set; }
public int Sold { get; set; } public long Sold { get; set; }
public int OrderMinQuantity { get; set; } public int OrderMinQuantity { get; set; }
@ -34,6 +31,8 @@ namespace EasyAbp.EShop.Products.Products.Dtos
public string MediaResources { get; set; } public string MediaResources { get; set; }
public string SpecifiedInventoryProviderName { get; set; }
public Guid? ProductDetailId { get; set; } public Guid? ProductDetailId { get; set; }
} }
} }

4
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application/EasyAbp/EShop/Products/ProductInventories/ProductInventoryAppService.cs

@ -81,7 +81,7 @@ namespace EasyAbp.EShop.Products.ProductInventories
{ {
if (changedInventory >= 0) if (changedInventory >= 0)
{ {
if (!await _productInventoryProvider.TryIncreaseInventoryAsync(productInventory, changedInventory)) if (!await _productInventoryProvider.TryIncreaseInventoryAsync(productInventory, changedInventory, false))
{ {
throw new InventoryChangeFailedException(productInventory.ProductId, productInventory.ProductSkuId, throw new InventoryChangeFailedException(productInventory.ProductId, productInventory.ProductSkuId,
productInventory.Inventory, changedInventory); productInventory.Inventory, changedInventory);
@ -89,7 +89,7 @@ namespace EasyAbp.EShop.Products.ProductInventories
} }
else else
{ {
if (!await _productInventoryProvider.TryReduceInventoryAsync(productInventory, -changedInventory)) if (!await _productInventoryProvider.TryReduceInventoryAsync(productInventory, -changedInventory, false))
{ {
throw new InventoryChangeFailedException(productInventory.ProductId, productInventory.ProductSkuId, throw new InventoryChangeFailedException(productInventory.ProductId, productInventory.ProductSkuId,
productInventory.Inventory, changedInventory); productInventory.Inventory, changedInventory);

31
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application/EasyAbp/EShop/Products/Products/ProductAppService.cs

@ -23,7 +23,6 @@ namespace EasyAbp.EShop.Products.Products
protected override string GetListPolicyName { get; set; } = null; protected override string GetListPolicyName { get; set; } = null;
private readonly IProductManager _productManager; private readonly IProductManager _productManager;
private readonly IProductDiscountManager _productDiscountManager;
private readonly IProductInventoryProvider _productInventoryProvider; private readonly IProductInventoryProvider _productInventoryProvider;
private readonly IAttributeOptionIdsSerializer _attributeOptionIdsSerializer; private readonly IAttributeOptionIdsSerializer _attributeOptionIdsSerializer;
private readonly IProductStoreRepository _productStoreRepository; private readonly IProductStoreRepository _productStoreRepository;
@ -31,14 +30,12 @@ namespace EasyAbp.EShop.Products.Products
public ProductAppService( public ProductAppService(
IProductManager productManager, IProductManager productManager,
IProductDiscountManager productDiscountManager,
IProductInventoryProvider productInventoryProvider, IProductInventoryProvider productInventoryProvider,
IAttributeOptionIdsSerializer attributeOptionIdsSerializer, IAttributeOptionIdsSerializer attributeOptionIdsSerializer,
IProductStoreRepository productStoreRepository, IProductStoreRepository productStoreRepository,
IProductRepository repository) : base(repository) IProductRepository repository) : base(repository)
{ {
_productManager = productManager; _productManager = productManager;
_productDiscountManager = productDiscountManager;
_productInventoryProvider = productInventoryProvider; _productInventoryProvider = productInventoryProvider;
_attributeOptionIdsSerializer = attributeOptionIdsSerializer; _attributeOptionIdsSerializer = attributeOptionIdsSerializer;
_productStoreRepository = productStoreRepository; _productStoreRepository = productStoreRepository;
@ -202,8 +199,8 @@ namespace EasyAbp.EShop.Products.Products
var dto = MapToGetOutputDto(product); var dto = MapToGetOutputDto(product);
await LoadRealInventoriesAsync(product, dto, storeId); await LoadDtoInventoryDataAsync(product, dto, storeId);
await LoadPricesAsync(product, dto, storeId); await LoadDtoPriceAsync(product, dto, storeId);
return dto; return dto;
} }
@ -221,7 +218,7 @@ namespace EasyAbp.EShop.Products.Products
var dto = MapToGetOutputDto(product); var dto = MapToGetOutputDto(product);
await LoadRealInventoriesAsync(product, dto, storeId); await LoadDtoInventoryDataAsync(product, dto, storeId);
return dto; return dto;
} }
@ -259,8 +256,8 @@ namespace EasyAbp.EShop.Products.Products
{ {
var productDto = MapToGetListOutputDto(product); var productDto = MapToGetListOutputDto(product);
await LoadRealInventoriesAsync(product, productDto, input.StoreId); await LoadDtoInventoryDataAsync(product, productDto, input.StoreId);
await LoadPricesAsync(product, productDto, input.StoreId); await LoadDtoPriceAsync(product, productDto, input.StoreId);
items.Add(productDto); items.Add(productDto);
} }
@ -268,23 +265,29 @@ namespace EasyAbp.EShop.Products.Products
return new PagedResultDto<ProductDto>(totalCount, items); return new PagedResultDto<ProductDto>(totalCount, items);
} }
protected virtual async Task<ProductDto> LoadRealInventoriesAsync(Product product, ProductDto productDto, Guid storeId) protected virtual async Task<ProductDto> LoadDtoInventoryDataAsync(Product product, ProductDto productDto, Guid storeId)
{ {
var inventoryDict = await _productInventoryProvider.GetInventoryDictionaryAsync(product, storeId); var inventoryDataDict = await _productInventoryProvider.GetInventoryDataDictionaryAsync(product, storeId);
productDto.Sold = 0;
foreach (var productSkuDto in productDto.ProductSkus) foreach (var productSkuDto in productDto.ProductSkus)
{ {
productSkuDto.Inventory = inventoryDict[productSkuDto.Id]; var inventoryData = inventoryDataDict[productSkuDto.Id];
productSkuDto.Inventory = inventoryData.Inventory;
productSkuDto.Sold = inventoryData.Sold;
productDto.Sold += productSkuDto.Sold;
} }
return productDto; return productDto;
} }
protected virtual async Task<ProductDto> LoadPricesAsync(Product product, ProductDto productDto, Guid storeId) protected virtual async Task<ProductDto> LoadDtoPriceAsync(Product product, ProductDto productDto, Guid storeId)
{ {
foreach (var productSkuDto in productDto.ProductSkus) foreach (var productSkuDto in productDto.ProductSkus)
{ {
productSkuDto.DiscountedPrice = await _productDiscountManager.GetDiscountedPriceAsync(product, productSkuDto.DiscountedPrice = await _productManager.GetDiscountedPriceAsync(product,
product.ProductSkus.Single(sku => sku.Id == productSkuDto.Id), storeId); product.ProductSkus.Single(sku => sku.Id == productSkuDto.Id), storeId);
} }
@ -372,7 +375,5 @@ namespace EasyAbp.EShop.Products.Products
return ObjectMapper.Map<Product, ProductDto>(product); return ObjectMapper.Map<Product, ProductDto>(product);
} }
} }
} }

1
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application/EasyAbp/EShop/Products/ProductsApplicationAutoMapperProfile.cs

@ -29,6 +29,7 @@ namespace EasyAbp.EShop.Products
* Alternatively, you can split your mapping configurations * Alternatively, you can split your mapping configurations
* into multiple profile classes for a better organization. */ * into multiple profile classes for a better organization. */
CreateMap<Product, ProductDto>() CreateMap<Product, ProductDto>()
.Ignore(dto => dto.Sold)
.Ignore(dto => dto.MinimumPrice) .Ignore(dto => dto.MinimumPrice)
.Ignore(dto => dto.MaximumPrice); .Ignore(dto => dto.MaximumPrice);
CreateMap<ProductDetail, ProductDetailDto>(); CreateMap<ProductDetail, ProductDetailDto>();

5
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/cs.json

@ -1,6 +1,7 @@
{ {
"culture": "cs", "culture": "cs",
"texts": { "texts": {
"KeepEmptyIfDoNotKnow": "KeepEmptyIfDoNotKnow",
"Menu:Product": "MenuProduct", "Menu:Product": "MenuProduct",
"Product": "Product", "Product": "Product",
"ProductStore": "ProductStore", "ProductStore": "ProductStore",
@ -26,9 +27,11 @@
"ProductSkuOriginalPrice": "ProductSkuOriginalPrice", "ProductSkuOriginalPrice": "ProductSkuOriginalPrice",
"ProductSkuPrice": "ProductSkuPrice", "ProductSkuPrice": "ProductSkuPrice",
"ProductSkuInventory": "ProductSkuInventory", "ProductSkuInventory": "ProductSkuInventory",
"ProductSkuSold": "ProductSkuSold",
"ProductSkuOrderMinQuantity": "ProductSkuOrderMinQuantity", "ProductSkuOrderMinQuantity": "ProductSkuOrderMinQuantity",
"ProductSkuOrderMaxQuantity": "ProductSkuOrderMaxQuantity", "ProductSkuOrderMaxQuantity": "ProductSkuOrderMaxQuantity",
"ProductSkuMediaResources": "ProductSkuMediaResources", "ProductSkuMediaResources": "ProductSkuMediaResources",
"ProductSkuSpecifiedInventoryProviderName": "ProductSkuSpecifiedInventoryProviderName",
"ProductSkuProductDetailId": "ProductSkuProductDetailId", "ProductSkuProductDetailId": "ProductSkuProductDetailId",
"ProductSkuContentDescription": "ProductSkuContentDescription", "ProductSkuContentDescription": "ProductSkuContentDescription",
"CreateProductSku": "CreateProductSku", "CreateProductSku": "CreateProductSku",
@ -37,6 +40,7 @@
"ProductInventoryStrategy": "ProductInventoryStrategy", "ProductInventoryStrategy": "ProductInventoryStrategy",
"ProductIsPublished": "ProductIsPublished", "ProductIsPublished": "ProductIsPublished",
"ProductMediaResources": "ProductMediaResources", "ProductMediaResources": "ProductMediaResources",
"ProductSpecifiedInventoryProviderName": "ProductSpecifiedInventoryProviderName",
"ProductAttributeDisplayName": "ProductAttributeDisplayName", "ProductAttributeDisplayName": "ProductAttributeDisplayName",
"ProductAttributeDescription": "ProductAttributeDescription", "ProductAttributeDescription": "ProductAttributeDescription",
"ProductAttributeDisplayOrder": "ProductAttributeDisplayOrder", "ProductAttributeDisplayOrder": "ProductAttributeDisplayOrder",
@ -84,7 +88,6 @@
"IncreaseInventory": "Increase", "IncreaseInventory": "Increase",
"DecreaseInventory": "Decrease", "DecreaseInventory": "Decrease",
"ProductInventoryInventory": "ProductInventoryInventory", "ProductInventoryInventory": "ProductInventoryInventory",
"ProductInventoryChangeType": "ProductInventoryChangeType",
"ChangeProductInventory": "ChangeProductInventory" "ChangeProductInventory": "ChangeProductInventory"
} }
} }

5
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/en.json

@ -2,6 +2,7 @@
"culture": "en", "culture": "en",
"texts": { "texts": {
"ManageYourProfile": "Manage your profile", "ManageYourProfile": "Manage your profile",
"KeepEmptyIfDoNotKnow": "KeepEmptyIfDoNotKnow",
"Menu:Product": "MenuProduct", "Menu:Product": "MenuProduct",
"Product": "Product", "Product": "Product",
"ProductStore": "ProductStore", "ProductStore": "ProductStore",
@ -27,9 +28,11 @@
"ProductSkuOriginalPrice": "ProductSkuOriginalPrice", "ProductSkuOriginalPrice": "ProductSkuOriginalPrice",
"ProductSkuPrice": "ProductSkuPrice", "ProductSkuPrice": "ProductSkuPrice",
"ProductSkuInventory": "ProductSkuInventory", "ProductSkuInventory": "ProductSkuInventory",
"ProductSkuSold": "ProductSkuSold",
"ProductSkuOrderMinQuantity": "ProductSkuOrderMinQuantity", "ProductSkuOrderMinQuantity": "ProductSkuOrderMinQuantity",
"ProductSkuOrderMaxQuantity": "ProductSkuOrderMaxQuantity", "ProductSkuOrderMaxQuantity": "ProductSkuOrderMaxQuantity",
"ProductSkuMediaResources": "ProductSkuMediaResources", "ProductSkuMediaResources": "ProductSkuMediaResources",
"ProductSkuSpecifiedInventoryProviderName": "ProductSkuSpecifiedInventoryProviderName",
"ProductSkuProductDetailId": "ProductSkuProductDetailId", "ProductSkuProductDetailId": "ProductSkuProductDetailId",
"ProductSkuContentDescription": "ProductSkuContentDescription", "ProductSkuContentDescription": "ProductSkuContentDescription",
"CreateProductSku": "CreateProductSku", "CreateProductSku": "CreateProductSku",
@ -38,6 +41,7 @@
"ProductInventoryStrategy": "ProductInventoryStrategy", "ProductInventoryStrategy": "ProductInventoryStrategy",
"ProductIsPublished": "ProductIsPublished", "ProductIsPublished": "ProductIsPublished",
"ProductMediaResources": "ProductMediaResources", "ProductMediaResources": "ProductMediaResources",
"ProductSpecifiedInventoryProviderName": "ProductSpecifiedInventoryProviderName",
"ProductAttributeDisplayName": "ProductAttributeDisplayName", "ProductAttributeDisplayName": "ProductAttributeDisplayName",
"ProductAttributeDescription": "ProductAttributeDescription", "ProductAttributeDescription": "ProductAttributeDescription",
"ProductAttributeDisplayOrder": "ProductAttributeDisplayOrder", "ProductAttributeDisplayOrder": "ProductAttributeDisplayOrder",
@ -85,7 +89,6 @@
"IncreaseInventory": "Increase", "IncreaseInventory": "Increase",
"DecreaseInventory": "Decrease", "DecreaseInventory": "Decrease",
"ProductInventoryInventory": "ProductInventoryInventory", "ProductInventoryInventory": "ProductInventoryInventory",
"ProductInventoryChangeType": "ProductInventoryChangeType",
"ChangeProductInventory": "ChangeProductInventory" "ChangeProductInventory": "ChangeProductInventory"
} }
} }

5
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/pl.json

@ -1,6 +1,7 @@
{ {
"culture": "pl", "culture": "pl",
"texts": { "texts": {
"KeepEmptyIfDoNotKnow": "KeepEmptyIfDoNotKnow",
"Menu:Product": "MenuProduct", "Menu:Product": "MenuProduct",
"Product": "Product", "Product": "Product",
"ProductStore": "ProductStore", "ProductStore": "ProductStore",
@ -26,9 +27,11 @@
"ProductSkuOriginalPrice": "ProductSkuOriginalPrice", "ProductSkuOriginalPrice": "ProductSkuOriginalPrice",
"ProductSkuPrice": "ProductSkuPrice", "ProductSkuPrice": "ProductSkuPrice",
"ProductSkuInventory": "ProductSkuInventory", "ProductSkuInventory": "ProductSkuInventory",
"ProductSkuSold": "ProductSkuSold",
"ProductSkuOrderMinQuantity": "ProductSkuOrderMinQuantity", "ProductSkuOrderMinQuantity": "ProductSkuOrderMinQuantity",
"ProductSkuOrderMaxQuantity": "ProductSkuOrderMaxQuantity", "ProductSkuOrderMaxQuantity": "ProductSkuOrderMaxQuantity",
"ProductSkuMediaResources": "ProductSkuMediaResources", "ProductSkuMediaResources": "ProductSkuMediaResources",
"ProductSkuSpecifiedInventoryProviderName": "ProductSkuSpecifiedInventoryProviderName",
"ProductSkuProductDetailId": "ProductSkuProductDetailId", "ProductSkuProductDetailId": "ProductSkuProductDetailId",
"ProductSkuContentDescription": "ProductSkuContentDescription", "ProductSkuContentDescription": "ProductSkuContentDescription",
"CreateProductSku": "CreateProductSku", "CreateProductSku": "CreateProductSku",
@ -37,6 +40,7 @@
"ProductInventoryStrategy": "ProductInventoryStrategy", "ProductInventoryStrategy": "ProductInventoryStrategy",
"ProductIsPublished": "ProductIsPublished", "ProductIsPublished": "ProductIsPublished",
"ProductMediaResources": "ProductMediaResources", "ProductMediaResources": "ProductMediaResources",
"ProductSpecifiedInventoryProviderName": "ProductSpecifiedInventoryProviderName",
"ProductAttributeDisplayName": "ProductAttributeDisplayName", "ProductAttributeDisplayName": "ProductAttributeDisplayName",
"ProductAttributeDescription": "ProductAttributeDescription", "ProductAttributeDescription": "ProductAttributeDescription",
"ProductAttributeDisplayOrder": "ProductAttributeDisplayOrder", "ProductAttributeDisplayOrder": "ProductAttributeDisplayOrder",
@ -84,7 +88,6 @@
"IncreaseInventory": "Increase", "IncreaseInventory": "Increase",
"DecreaseInventory": "Decrease", "DecreaseInventory": "Decrease",
"ProductInventoryInventory": "ProductInventoryInventory", "ProductInventoryInventory": "ProductInventoryInventory",
"ProductInventoryChangeType": "ProductInventoryChangeType",
"ChangeProductInventory": "ChangeProductInventory" "ChangeProductInventory": "ChangeProductInventory"
} }
} }

5
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/pt-BR.json

@ -1,6 +1,7 @@
{ {
"culture": "pt-BR", "culture": "pt-BR",
"texts": { "texts": {
"KeepEmptyIfDoNotKnow": "KeepEmptyIfDoNotKnow",
"Menu:Product": "MenuProduct", "Menu:Product": "MenuProduct",
"Product": "Product", "Product": "Product",
"ProductStore": "ProductStore", "ProductStore": "ProductStore",
@ -26,9 +27,11 @@
"ProductSkuOriginalPrice": "ProductSkuOriginalPrice", "ProductSkuOriginalPrice": "ProductSkuOriginalPrice",
"ProductSkuPrice": "ProductSkuPrice", "ProductSkuPrice": "ProductSkuPrice",
"ProductSkuInventory": "ProductSkuInventory", "ProductSkuInventory": "ProductSkuInventory",
"ProductSkuSold": "ProductSkuSold",
"ProductSkuOrderMinQuantity": "ProductSkuOrderMinQuantity", "ProductSkuOrderMinQuantity": "ProductSkuOrderMinQuantity",
"ProductSkuOrderMaxQuantity": "ProductSkuOrderMaxQuantity", "ProductSkuOrderMaxQuantity": "ProductSkuOrderMaxQuantity",
"ProductSkuMediaResources": "ProductSkuMediaResources", "ProductSkuMediaResources": "ProductSkuMediaResources",
"ProductSkuSpecifiedInventoryProviderName": "ProductSkuSpecifiedInventoryProviderName",
"ProductSkuProductDetailId": "ProductSkuProductDetailId", "ProductSkuProductDetailId": "ProductSkuProductDetailId",
"ProductSkuContentDescription": "ProductSkuContentDescription", "ProductSkuContentDescription": "ProductSkuContentDescription",
"CreateProductSku": "CreateProductSku", "CreateProductSku": "CreateProductSku",
@ -37,6 +40,7 @@
"ProductInventoryStrategy": "ProductInventoryStrategy", "ProductInventoryStrategy": "ProductInventoryStrategy",
"ProductIsPublished": "ProductIsPublished", "ProductIsPublished": "ProductIsPublished",
"ProductMediaResources": "ProductMediaResources", "ProductMediaResources": "ProductMediaResources",
"ProductSpecifiedInventoryProviderName": "ProductSpecifiedInventoryProviderName",
"ProductAttributeDisplayName": "ProductAttributeDisplayName", "ProductAttributeDisplayName": "ProductAttributeDisplayName",
"ProductAttributeDescription": "ProductAttributeDescription", "ProductAttributeDescription": "ProductAttributeDescription",
"ProductAttributeDisplayOrder": "ProductAttributeDisplayOrder", "ProductAttributeDisplayOrder": "ProductAttributeDisplayOrder",
@ -84,7 +88,6 @@
"IncreaseInventory": "Increase", "IncreaseInventory": "Increase",
"DecreaseInventory": "Decrease", "DecreaseInventory": "Decrease",
"ProductInventoryInventory": "ProductInventoryInventory", "ProductInventoryInventory": "ProductInventoryInventory",
"ProductInventoryChangeType": "ProductInventoryChangeType",
"ChangeProductInventory": "ChangeProductInventory" "ChangeProductInventory": "ChangeProductInventory"
} }
} }

5
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/sl.json

@ -2,6 +2,7 @@
"culture": "sl", "culture": "sl",
"texts": { "texts": {
"ManageYourProfile": "Upravljajte svojim profilom", "ManageYourProfile": "Upravljajte svojim profilom",
"KeepEmptyIfDoNotKnow": "KeepEmptyIfDoNotKnow",
"Menu:Product": "MenuProduct", "Menu:Product": "MenuProduct",
"Product": "Product", "Product": "Product",
"ProductStore": "ProductStore", "ProductStore": "ProductStore",
@ -27,9 +28,11 @@
"ProductSkuOriginalPrice": "ProductSkuOriginalPrice", "ProductSkuOriginalPrice": "ProductSkuOriginalPrice",
"ProductSkuPrice": "ProductSkuPrice", "ProductSkuPrice": "ProductSkuPrice",
"ProductSkuInventory": "ProductSkuInventory", "ProductSkuInventory": "ProductSkuInventory",
"ProductSkuSold": "ProductSkuSold",
"ProductSkuOrderMinQuantity": "ProductSkuOrderMinQuantity", "ProductSkuOrderMinQuantity": "ProductSkuOrderMinQuantity",
"ProductSkuOrderMaxQuantity": "ProductSkuOrderMaxQuantity", "ProductSkuOrderMaxQuantity": "ProductSkuOrderMaxQuantity",
"ProductSkuMediaResources": "ProductSkuMediaResources", "ProductSkuMediaResources": "ProductSkuMediaResources",
"ProductSkuSpecifiedInventoryProviderName": "ProductSkuSpecifiedInventoryProviderName",
"ProductSkuProductDetailId": "ProductSkuProductDetailId", "ProductSkuProductDetailId": "ProductSkuProductDetailId",
"ProductSkuContentDescription": "ProductSkuContentDescription", "ProductSkuContentDescription": "ProductSkuContentDescription",
"CreateProductSku": "CreateProductSku", "CreateProductSku": "CreateProductSku",
@ -38,6 +41,7 @@
"ProductInventoryStrategy": "ProductInventoryStrategy", "ProductInventoryStrategy": "ProductInventoryStrategy",
"ProductIsPublished": "ProductIsPublished", "ProductIsPublished": "ProductIsPublished",
"ProductMediaResources": "ProductMediaResources", "ProductMediaResources": "ProductMediaResources",
"ProductSpecifiedInventoryProviderName": "ProductSpecifiedInventoryProviderName",
"ProductAttributeDisplayName": "ProductAttributeDisplayName", "ProductAttributeDisplayName": "ProductAttributeDisplayName",
"ProductAttributeDescription": "ProductAttributeDescription", "ProductAttributeDescription": "ProductAttributeDescription",
"ProductAttributeDisplayOrder": "ProductAttributeDisplayOrder", "ProductAttributeDisplayOrder": "ProductAttributeDisplayOrder",
@ -85,7 +89,6 @@
"IncreaseInventory": "Increase", "IncreaseInventory": "Increase",
"DecreaseInventory": "Decrease", "DecreaseInventory": "Decrease",
"ProductInventoryInventory": "ProductInventoryInventory", "ProductInventoryInventory": "ProductInventoryInventory",
"ProductInventoryChangeType": "ProductInventoryChangeType",
"ChangeProductInventory": "ChangeProductInventory" "ChangeProductInventory": "ChangeProductInventory"
} }
} }

5
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/tr.json

@ -2,6 +2,7 @@
"culture": "tr", "culture": "tr",
"texts": { "texts": {
"ManageYourProfile": "Profil y�netimi", "ManageYourProfile": "Profil y�netimi",
"KeepEmptyIfDoNotKnow": "KeepEmptyIfDoNotKnow",
"Menu:Product": "MenuProduct", "Menu:Product": "MenuProduct",
"Product": "Product", "Product": "Product",
"ProductStore": "ProductStore", "ProductStore": "ProductStore",
@ -27,9 +28,11 @@
"ProductSkuOriginalPrice": "ProductSkuOriginalPrice", "ProductSkuOriginalPrice": "ProductSkuOriginalPrice",
"ProductSkuPrice": "ProductSkuPrice", "ProductSkuPrice": "ProductSkuPrice",
"ProductSkuInventory": "ProductSkuInventory", "ProductSkuInventory": "ProductSkuInventory",
"ProductSkuSold": "ProductSkuSold",
"ProductSkuOrderMinQuantity": "ProductSkuOrderMinQuantity", "ProductSkuOrderMinQuantity": "ProductSkuOrderMinQuantity",
"ProductSkuOrderMaxQuantity": "ProductSkuOrderMaxQuantity", "ProductSkuOrderMaxQuantity": "ProductSkuOrderMaxQuantity",
"ProductSkuMediaResources": "ProductSkuMediaResources", "ProductSkuMediaResources": "ProductSkuMediaResources",
"ProductSkuSpecifiedInventoryProviderName": "ProductSkuSpecifiedInventoryProviderName",
"ProductSkuProductDetailId": "ProductSkuProductDetailId", "ProductSkuProductDetailId": "ProductSkuProductDetailId",
"ProductSkuContentDescription": "ProductSkuContentDescription", "ProductSkuContentDescription": "ProductSkuContentDescription",
"CreateProductSku": "CreateProductSku", "CreateProductSku": "CreateProductSku",
@ -38,6 +41,7 @@
"ProductInventoryStrategy": "ProductInventoryStrategy", "ProductInventoryStrategy": "ProductInventoryStrategy",
"ProductIsPublished": "ProductIsPublished", "ProductIsPublished": "ProductIsPublished",
"ProductMediaResources": "ProductMediaResources", "ProductMediaResources": "ProductMediaResources",
"ProductSpecifiedInventoryProviderName": "ProductSpecifiedInventoryProviderName",
"ProductAttributeDisplayName": "ProductAttributeDisplayName", "ProductAttributeDisplayName": "ProductAttributeDisplayName",
"ProductAttributeDescription": "ProductAttributeDescription", "ProductAttributeDescription": "ProductAttributeDescription",
"ProductAttributeDisplayOrder": "ProductAttributeDisplayOrder", "ProductAttributeDisplayOrder": "ProductAttributeDisplayOrder",
@ -85,7 +89,6 @@
"IncreaseInventory": "Increase", "IncreaseInventory": "Increase",
"DecreaseInventory": "Decrease", "DecreaseInventory": "Decrease",
"ProductInventoryInventory": "ProductInventoryInventory", "ProductInventoryInventory": "ProductInventoryInventory",
"ProductInventoryChangeType": "ProductInventoryChangeType",
"ChangeProductInventory": "ChangeProductInventory" "ChangeProductInventory": "ChangeProductInventory"
} }
} }

5
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/vi.json

@ -1,6 +1,7 @@
{ {
"culture": "vi", "culture": "vi",
"texts": { "texts": {
"KeepEmptyIfDoNotKnow": "KeepEmptyIfDoNotKnow",
"Menu:Product": "MenuProduct", "Menu:Product": "MenuProduct",
"Product": "Product", "Product": "Product",
"ProductStore": "ProductStore", "ProductStore": "ProductStore",
@ -26,9 +27,11 @@
"ProductSkuOriginalPrice": "ProductSkuOriginalPrice", "ProductSkuOriginalPrice": "ProductSkuOriginalPrice",
"ProductSkuPrice": "ProductSkuPrice", "ProductSkuPrice": "ProductSkuPrice",
"ProductSkuInventory": "ProductSkuInventory", "ProductSkuInventory": "ProductSkuInventory",
"ProductSkuSold": "ProductSkuSold",
"ProductSkuOrderMinQuantity": "ProductSkuOrderMinQuantity", "ProductSkuOrderMinQuantity": "ProductSkuOrderMinQuantity",
"ProductSkuOrderMaxQuantity": "ProductSkuOrderMaxQuantity", "ProductSkuOrderMaxQuantity": "ProductSkuOrderMaxQuantity",
"ProductSkuMediaResources": "ProductSkuMediaResources", "ProductSkuMediaResources": "ProductSkuMediaResources",
"ProductSkuSpecifiedInventoryProviderName": "ProductSkuSpecifiedInventoryProviderName",
"ProductSkuProductDetailId": "ProductSkuProductDetailId", "ProductSkuProductDetailId": "ProductSkuProductDetailId",
"ProductSkuContentDescription": "ProductSkuContentDescription", "ProductSkuContentDescription": "ProductSkuContentDescription",
"CreateProductSku": "CreateProductSku", "CreateProductSku": "CreateProductSku",
@ -37,6 +40,7 @@
"ProductInventoryStrategy": "ProductInventoryStrategy", "ProductInventoryStrategy": "ProductInventoryStrategy",
"ProductIsPublished": "ProductIsPublished", "ProductIsPublished": "ProductIsPublished",
"ProductMediaResources": "ProductMediaResources", "ProductMediaResources": "ProductMediaResources",
"ProductSpecifiedInventoryProviderName": "ProductSpecifiedInventoryProviderName",
"ProductAttributeDisplayName": "ProductAttributeDisplayName", "ProductAttributeDisplayName": "ProductAttributeDisplayName",
"ProductAttributeDescription": "ProductAttributeDescription", "ProductAttributeDescription": "ProductAttributeDescription",
"ProductAttributeDisplayOrder": "ProductAttributeDisplayOrder", "ProductAttributeDisplayOrder": "ProductAttributeDisplayOrder",
@ -84,7 +88,6 @@
"IncreaseInventory": "Increase", "IncreaseInventory": "Increase",
"DecreaseInventory": "Decrease", "DecreaseInventory": "Decrease",
"ProductInventoryInventory": "ProductInventoryInventory", "ProductInventoryInventory": "ProductInventoryInventory",
"ProductInventoryChangeType": "ProductInventoryChangeType",
"ChangeProductInventory": "ChangeProductInventory" "ChangeProductInventory": "ChangeProductInventory"
} }
} }

5
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/zh-Hans.json

@ -2,6 +2,7 @@
"culture": "zh-Hans", "culture": "zh-Hans",
"texts": { "texts": {
"ManageYourProfile": "管理个人资料", "ManageYourProfile": "管理个人资料",
"KeepEmptyIfDoNotKnow": "KeepEmptyIfDoNotKnow",
"Menu:Product": "MenuProduct", "Menu:Product": "MenuProduct",
"Product": "Product", "Product": "Product",
"ProductStore": "ProductStore", "ProductStore": "ProductStore",
@ -27,9 +28,11 @@
"ProductSkuOriginalPrice": "ProductSkuOriginalPrice", "ProductSkuOriginalPrice": "ProductSkuOriginalPrice",
"ProductSkuPrice": "ProductSkuPrice", "ProductSkuPrice": "ProductSkuPrice",
"ProductSkuInventory": "ProductSkuInventory", "ProductSkuInventory": "ProductSkuInventory",
"ProductSkuSold": "ProductSkuSold",
"ProductSkuOrderMinQuantity": "ProductSkuOrderMinQuantity", "ProductSkuOrderMinQuantity": "ProductSkuOrderMinQuantity",
"ProductSkuOrderMaxQuantity": "ProductSkuOrderMaxQuantity", "ProductSkuOrderMaxQuantity": "ProductSkuOrderMaxQuantity",
"ProductSkuMediaResources": "ProductSkuMediaResources", "ProductSkuMediaResources": "ProductSkuMediaResources",
"ProductSkuSpecifiedInventoryProviderName": "ProductSkuSpecifiedInventoryProviderName",
"ProductSkuProductDetailId": "ProductSkuProductDetailId", "ProductSkuProductDetailId": "ProductSkuProductDetailId",
"ProductSkuContentDescription": "ProductSkuContentDescription", "ProductSkuContentDescription": "ProductSkuContentDescription",
"CreateProductSku": "CreateProductSku", "CreateProductSku": "CreateProductSku",
@ -38,6 +41,7 @@
"ProductInventoryStrategy": "ProductInventoryStrategy", "ProductInventoryStrategy": "ProductInventoryStrategy",
"ProductIsPublished": "ProductIsPublished", "ProductIsPublished": "ProductIsPublished",
"ProductMediaResources": "ProductMediaResources", "ProductMediaResources": "ProductMediaResources",
"ProductSpecifiedInventoryProviderName": "ProductSpecifiedInventoryProviderName",
"ProductAttributeDisplayName": "ProductAttributeDisplayName", "ProductAttributeDisplayName": "ProductAttributeDisplayName",
"ProductAttributeDescription": "ProductAttributeDescription", "ProductAttributeDescription": "ProductAttributeDescription",
"ProductAttributeDisplayOrder": "ProductAttributeDisplayOrder", "ProductAttributeDisplayOrder": "ProductAttributeDisplayOrder",
@ -85,7 +89,6 @@
"IncreaseInventory": "Increase", "IncreaseInventory": "Increase",
"DecreaseInventory": "Decrease", "DecreaseInventory": "Decrease",
"ProductInventoryInventory": "ProductInventoryInventory", "ProductInventoryInventory": "ProductInventoryInventory",
"ProductInventoryChangeType": "ProductInventoryChangeType",
"ChangeProductInventory": "ChangeProductInventory" "ChangeProductInventory": "ChangeProductInventory"
} }
} }

5
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/zh-Hant.json

@ -2,6 +2,7 @@
"culture": "zh-Hant", "culture": "zh-Hant",
"texts": { "texts": {
"ManageYourProfile": "管理個人資料", "ManageYourProfile": "管理個人資料",
"KeepEmptyIfDoNotKnow": "KeepEmptyIfDoNotKnow",
"Menu:Product": "MenuProduct", "Menu:Product": "MenuProduct",
"Product": "Product", "Product": "Product",
"ProductStore": "ProductStore", "ProductStore": "ProductStore",
@ -27,9 +28,11 @@
"ProductSkuOriginalPrice": "ProductSkuOriginalPrice", "ProductSkuOriginalPrice": "ProductSkuOriginalPrice",
"ProductSkuPrice": "ProductSkuPrice", "ProductSkuPrice": "ProductSkuPrice",
"ProductSkuInventory": "ProductSkuInventory", "ProductSkuInventory": "ProductSkuInventory",
"ProductSkuSold": "ProductSkuSold",
"ProductSkuOrderMinQuantity": "ProductSkuOrderMinQuantity", "ProductSkuOrderMinQuantity": "ProductSkuOrderMinQuantity",
"ProductSkuOrderMaxQuantity": "ProductSkuOrderMaxQuantity", "ProductSkuOrderMaxQuantity": "ProductSkuOrderMaxQuantity",
"ProductSkuMediaResources": "ProductSkuMediaResources", "ProductSkuMediaResources": "ProductSkuMediaResources",
"ProductSkuSpecifiedInventoryProviderName": "ProductSkuSpecifiedInventoryProviderName",
"ProductSkuProductDetailId": "ProductSkuProductDetailId", "ProductSkuProductDetailId": "ProductSkuProductDetailId",
"ProductSkuContentDescription": "ProductSkuContentDescription", "ProductSkuContentDescription": "ProductSkuContentDescription",
"CreateProductSku": "CreateProductSku", "CreateProductSku": "CreateProductSku",
@ -38,6 +41,7 @@
"ProductInventoryStrategy": "ProductInventoryStrategy", "ProductInventoryStrategy": "ProductInventoryStrategy",
"ProductIsPublished": "ProductIsPublished", "ProductIsPublished": "ProductIsPublished",
"ProductMediaResources": "ProductMediaResources", "ProductMediaResources": "ProductMediaResources",
"ProductSpecifiedInventoryProviderName": "ProductSpecifiedInventoryProviderName",
"ProductAttributeDisplayName": "ProductAttributeDisplayName", "ProductAttributeDisplayName": "ProductAttributeDisplayName",
"ProductAttributeDescription": "ProductAttributeDescription", "ProductAttributeDescription": "ProductAttributeDescription",
"ProductAttributeDisplayOrder": "ProductAttributeDisplayOrder", "ProductAttributeDisplayOrder": "ProductAttributeDisplayOrder",
@ -85,7 +89,6 @@
"IncreaseInventory": "Increase", "IncreaseInventory": "Increase",
"DecreaseInventory": "Decrease", "DecreaseInventory": "Decrease",
"ProductInventoryInventory": "ProductInventoryInventory", "ProductInventoryInventory": "ProductInventoryInventory",
"ProductInventoryChangeType": "ProductInventoryChangeType",
"ChangeProductInventory": "ChangeProductInventory" "ChangeProductInventory": "ChangeProductInventory"
} }
} }

2
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/ProductInventories/ProductInventoryChangedEto.cs

@ -12,5 +12,7 @@ namespace EasyAbp.EShop.Products.ProductInventories
public int OriginalInventory { get; set; } public int OriginalInventory { get; set; }
public int NewInventory { get; set; } public int NewInventory { get; set; }
public long Sold { get; set; }
} }
} }

5
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/ProductInventories/IProductInventoryRepository.cs

@ -2,14 +2,15 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using EasyAbp.EShop.Products.Products;
using Volo.Abp.Domain.Repositories; using Volo.Abp.Domain.Repositories;
namespace EasyAbp.EShop.Products.ProductInventories namespace EasyAbp.EShop.Products.ProductInventories
{ {
public interface IProductInventoryRepository : IRepository<ProductInventory, Guid> public interface IProductInventoryRepository : IRepository<ProductInventory, Guid>
{ {
Task<int> GetInventoryAsync(Guid productSkuId, CancellationToken cancellationToken = default); Task<InventoryDataModel> GetInventoryDataAsync(Guid productSkuId, CancellationToken cancellationToken = default);
Task<Dictionary<Guid, int>> GetInventoryDictionaryAsync(List<Guid> productSkuIds, CancellationToken cancellationToken = default); Task<Dictionary<Guid, InventoryDataModel>> GetInventoryDataDictionaryAsync(List<Guid> productSkuIds, CancellationToken cancellationToken = default);
} }
} }

24
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/ProductInventories/ProductInventory.cs

@ -11,8 +11,7 @@ namespace EasyAbp.EShop.Products.ProductInventories
public virtual int Inventory { get; protected set; } public virtual int Inventory { get; protected set; }
// Todo: should be implemented public virtual long Sold { get; protected set; }
public virtual int Sold { get; protected set; }
protected ProductInventory() protected ProductInventory()
{ {
@ -23,7 +22,7 @@ namespace EasyAbp.EShop.Products.ProductInventories
Guid productId, Guid productId,
Guid productSkuId, Guid productSkuId,
int inventory, int inventory,
int sold) : base(id) long sold) : base(id)
{ {
ProductId = productId; ProductId = productId;
ProductSkuId = productSkuId; ProductSkuId = productSkuId;
@ -31,19 +30,29 @@ namespace EasyAbp.EShop.Products.ProductInventories
Sold = sold; Sold = sold;
} }
internal bool TryIncreaseInventory(int quantity) internal bool TryIncreaseInventory(int quantity, bool decreaseSold)
{ {
if (quantity < 0) if (quantity < 0)
{ {
return false; return false;
} }
if (decreaseSold && Sold - quantity < 0)
{
return false;
}
Inventory = checked(Inventory + quantity); Inventory = checked(Inventory + quantity);
if (decreaseSold)
{
Sold -= quantity;
}
return true; return true;
} }
internal bool TryReduceInventory(int quantity) internal bool TryReduceInventory(int quantity, bool increaseSold)
{ {
if (quantity > Inventory || quantity < 0) if (quantity > Inventory || quantity < 0)
{ {
@ -51,6 +60,11 @@ namespace EasyAbp.EShop.Products.ProductInventories
} }
Inventory -= quantity; Inventory -= quantity;
if (increaseSold)
{
Sold = checked(Sold + quantity);
}
return true; return true;
} }

2
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ReduceInventoryModel.cs → modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ConsumeInventoryModel.cs

@ -2,7 +2,7 @@
namespace EasyAbp.EShop.Products.Products namespace EasyAbp.EShop.Products.Products
{ {
public class ReduceInventoryModel public class ConsumeInventoryModel
{ {
public Product Product { get; set; } public Product Product { get; set; }

37
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/DefaultProductInventoryProvider.cs

@ -11,6 +11,8 @@ namespace EasyAbp.EShop.Products.Products
{ {
public class DefaultProductInventoryProvider : IProductInventoryProvider, ITransientDependency public class DefaultProductInventoryProvider : IProductInventoryProvider, ITransientDependency
{ {
public string ProviderName { get; } = "Default";
// Todo: should use IProductInventoryStore. // Todo: should use IProductInventoryStore.
private readonly IUnitOfWorkManager _unitOfWorkManager; private readonly IUnitOfWorkManager _unitOfWorkManager;
private readonly IDistributedEventBus _distributedEventBus; private readonly IDistributedEventBus _distributedEventBus;
@ -26,39 +28,39 @@ namespace EasyAbp.EShop.Products.Products
_productInventoryRepository = productInventoryRepository; _productInventoryRepository = productInventoryRepository;
} }
public virtual async Task<int> GetInventoryAsync(Product product, ProductSku productSku, Guid storeId) public virtual async Task<InventoryDataModel> GetInventoryDataAsync(Product product, ProductSku productSku, Guid storeId)
{ {
return await _productInventoryRepository.GetInventoryAsync(productSku.Id); return await _productInventoryRepository.GetInventoryDataAsync(productSku.Id);
} }
public virtual async Task<Dictionary<Guid, int>> GetInventoryDictionaryAsync(Product product, Guid storeId) public virtual async Task<Dictionary<Guid, InventoryDataModel>> GetInventoryDataDictionaryAsync(Product product, Guid storeId)
{ {
var dict = await _productInventoryRepository.GetInventoryDictionaryAsync(product.ProductSkus var dict = await _productInventoryRepository.GetInventoryDataDictionaryAsync(product.ProductSkus
.Select(sku => sku.Id).ToList()); .Select(sku => sku.Id).ToList());
foreach (var sku in product.ProductSkus) foreach (var sku in product.ProductSkus)
{ {
dict.GetOrAdd(sku.Id, () => 0); dict.GetOrAdd(sku.Id, () => new InventoryDataModel());
} }
return dict; return dict;
} }
public virtual async Task<bool> TryIncreaseInventoryAsync(Product product, ProductSku productSku, Guid storeId, int quantity) public virtual async Task<bool> TryIncreaseInventoryAsync(Product product, ProductSku productSku, Guid storeId, int quantity, bool decreaseSold)
{ {
var productInventory = await _productInventoryRepository.GetAsync(x => x.ProductSkuId == productSku.Id); var productInventory = await _productInventoryRepository.GetAsync(x => x.ProductSkuId == productSku.Id);
return await TryIncreaseInventoryAsync(productInventory, quantity); return await TryIncreaseInventoryAsync(productInventory, quantity, decreaseSold);
} }
public virtual async Task<bool> TryReduceInventoryAsync(Product product, ProductSku productSku, Guid storeId, int quantity) public virtual async Task<bool> TryReduceInventoryAsync(Product product, ProductSku productSku, Guid storeId, int quantity, bool increaseSold)
{ {
var productInventory = await _productInventoryRepository.GetAsync(x => x.ProductSkuId == productSku.Id); var productInventory = await _productInventoryRepository.GetAsync(x => x.ProductSkuId == productSku.Id);
return await TryReduceInventoryAsync(productInventory, quantity); return await TryReduceInventoryAsync(productInventory, quantity, increaseSold);
} }
public virtual async Task<bool> TryIncreaseInventoryAsync(ProductInventory productInventory, int quantity) public virtual async Task<bool> TryIncreaseInventoryAsync(ProductInventory productInventory, int quantity, bool decreaseSold)
{ {
if (quantity < 0) if (quantity < 0)
{ {
@ -67,7 +69,7 @@ namespace EasyAbp.EShop.Products.Products
var originalInventory = productInventory.Inventory; var originalInventory = productInventory.Inventory;
if (!productInventory.TryIncreaseInventory(quantity)) if (!productInventory.TryIncreaseInventory(quantity, decreaseSold))
{ {
return false; return false;
} }
@ -75,12 +77,12 @@ namespace EasyAbp.EShop.Products.Products
await _productInventoryRepository.UpdateAsync(productInventory, true); await _productInventoryRepository.UpdateAsync(productInventory, true);
PublishInventoryChangedEventOnUowCompleted(productInventory.ProductId, productInventory.ProductSkuId, PublishInventoryChangedEventOnUowCompleted(productInventory.ProductId, productInventory.ProductSkuId,
originalInventory, productInventory.Inventory); originalInventory, productInventory.Inventory, productInventory.Sold);
return true; return true;
} }
public virtual async Task<bool> TryReduceInventoryAsync(ProductInventory productInventory, int quantity) public virtual async Task<bool> TryReduceInventoryAsync(ProductInventory productInventory, int quantity, bool increaseSold)
{ {
if (quantity < 0) if (quantity < 0)
{ {
@ -89,7 +91,7 @@ namespace EasyAbp.EShop.Products.Products
var originalInventory = productInventory.Inventory; var originalInventory = productInventory.Inventory;
if (!productInventory.TryReduceInventory(quantity)) if (!productInventory.TryReduceInventory(quantity, increaseSold))
{ {
return false; return false;
} }
@ -97,13 +99,13 @@ namespace EasyAbp.EShop.Products.Products
await _productInventoryRepository.UpdateAsync(productInventory, true); await _productInventoryRepository.UpdateAsync(productInventory, true);
PublishInventoryChangedEventOnUowCompleted(productInventory.ProductId, productInventory.ProductSkuId, PublishInventoryChangedEventOnUowCompleted(productInventory.ProductId, productInventory.ProductSkuId,
originalInventory, productInventory.Inventory); originalInventory, productInventory.Inventory, productInventory.Sold);
return true; return true;
} }
protected virtual void PublishInventoryChangedEventOnUowCompleted(Guid productId, Guid productSkuId, protected virtual void PublishInventoryChangedEventOnUowCompleted(Guid productId, Guid productSkuId,
int originalInventory, int newInventory) int originalInventory, int newInventory, long sold)
{ {
_unitOfWorkManager.Current.OnCompleted(async () => await _distributedEventBus.PublishAsync( _unitOfWorkManager.Current.OnCompleted(async () => await _distributedEventBus.PublishAsync(
new ProductInventoryChangedEto new ProductInventoryChangedEto
@ -111,7 +113,8 @@ namespace EasyAbp.EShop.Products.Products
ProductId = productId, ProductId = productId,
ProductSkuId = productSkuId, ProductSkuId = productSkuId,
OriginalInventory = originalInventory, OriginalInventory = originalInventory,
NewInventory = newInventory NewInventory = newInventory,
Sold = sold
} }
)); ));
} }

11
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/IProductDiscountManager.cs

@ -1,11 +0,0 @@
using System;
using System.Threading.Tasks;
using Volo.Abp.Domain.Services;
namespace EasyAbp.EShop.Products.Products
{
public interface IProductDiscountManager : IDomainService
{
Task<decimal> GetDiscountedPriceAsync(Product product, ProductSku productSku, Guid storeId);
}
}

10
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/IProductInventoryProvider.cs

@ -6,12 +6,14 @@ namespace EasyAbp.EShop.Products.Products
{ {
public interface IProductInventoryProvider public interface IProductInventoryProvider
{ {
Task<int> GetInventoryAsync(Product product, ProductSku productSku, Guid storeId); string ProviderName { get; }
Task<Dictionary<Guid, int>> GetInventoryDictionaryAsync(Product product, Guid storeId); Task<InventoryDataModel> GetInventoryDataAsync(Product product, ProductSku productSku, Guid storeId);
Task<Dictionary<Guid, InventoryDataModel>> GetInventoryDataDictionaryAsync(Product product, Guid storeId);
Task<bool> TryIncreaseInventoryAsync(Product product, ProductSku productSku, Guid storeId, int quantity); Task<bool> TryIncreaseInventoryAsync(Product product, ProductSku productSku, Guid storeId, int quantity, bool decreaseSold);
Task<bool> TryReduceInventoryAsync(Product product, ProductSku productSku, Guid storeId, int quantity); Task<bool> TryReduceInventoryAsync(Product product, ProductSku productSku, Guid storeId, int quantity, bool increaseSold);
} }
} }

8
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/IProductManager.cs

@ -23,10 +23,12 @@ namespace EasyAbp.EShop.Products.Products
Task<bool> IsInventorySufficientAsync(Product product, ProductSku productSku, Guid storeId, int quantity); Task<bool> IsInventorySufficientAsync(Product product, ProductSku productSku, Guid storeId, int quantity);
Task<int> GetInventoryAsync(Product product, ProductSku productSku, Guid storeId); Task<InventoryDataModel> GetInventoryDataAsync(Product product, ProductSku productSku, Guid storeId);
Task<bool> TryIncreaseInventoryAsync(Product product, ProductSku productSku, Guid storeId, int quantity); Task<bool> TryIncreaseInventoryAsync(Product product, ProductSku productSku, Guid storeId, int quantity, bool reduceSold);
Task<bool> TryReduceInventoryAsync(Product product, ProductSku productSku, Guid storeId, int quantity); Task<bool> TryReduceInventoryAsync(Product product, ProductSku productSku, Guid storeId, int quantity, bool increaseSold);
Task<decimal> GetDiscountedPriceAsync(Product product, ProductSku productSku, Guid storeId);
} }
} }

9
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/InventoryDataModel.cs

@ -0,0 +1,9 @@
namespace EasyAbp.EShop.Products.Products
{
public class InventoryDataModel
{
public int Inventory { get; set; }
public long Sold { get; set; }
}
}

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

@ -38,7 +38,7 @@ namespace EasyAbp.EShop.Products.Products
using var uow = _unitOfWorkManager.Begin(isTransactional: true); using var uow = _unitOfWorkManager.Begin(isTransactional: true);
var models = new List<ReduceInventoryModel>(); var models = new List<ConsumeInventoryModel>();
foreach (var orderLine in eventData.Entity.OrderLines) foreach (var orderLine in eventData.Entity.OrderLines)
{ {
@ -67,7 +67,7 @@ namespace EasyAbp.EShop.Products.Products
return; return;
} }
models.Add(new ReduceInventoryModel models.Add(new ConsumeInventoryModel
{ {
Product = product, Product = product,
ProductSku = productSku, ProductSku = productSku,
@ -79,7 +79,7 @@ namespace EasyAbp.EShop.Products.Products
foreach (var model in models) foreach (var model in models)
{ {
if (await _productManager.TryReduceInventoryAsync(model.Product, model.ProductSku, model.StoreId, if (await _productManager.TryReduceInventoryAsync(model.Product, model.ProductSku, model.StoreId,
model.Quantity)) model.Quantity, true))
{ {
continue; continue;
} }

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

@ -37,7 +37,7 @@ namespace EasyAbp.EShop.Products.Products
using var uow = _unitOfWorkManager.Begin(isTransactional: true); using var uow = _unitOfWorkManager.Begin(isTransactional: true);
var models = new List<ReduceInventoryModel>(); var models = new List<ConsumeInventoryModel>();
foreach (var orderLine in eventData.Order.OrderLines) foreach (var orderLine in eventData.Order.OrderLines)
{ {
@ -66,7 +66,7 @@ namespace EasyAbp.EShop.Products.Products
return; return;
} }
models.Add(new ReduceInventoryModel models.Add(new ConsumeInventoryModel
{ {
Product = product, Product = product,
ProductSku = productSku, ProductSku = productSku,
@ -78,7 +78,7 @@ namespace EasyAbp.EShop.Products.Products
foreach (var model in models) foreach (var model in models)
{ {
if (await _productManager.TryReduceInventoryAsync(model.Product, model.ProductSku, model.StoreId, if (await _productManager.TryReduceInventoryAsync(model.Product, model.ProductSku, model.StoreId,
model.Quantity)) model.Quantity, true))
{ {
continue; continue;
} }

5
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/Product.cs

@ -23,6 +23,9 @@ namespace EasyAbp.EShop.Products.Products
[CanBeNull] [CanBeNull]
public virtual string MediaResources { get; protected set; } public virtual string MediaResources { get; protected set; }
[CanBeNull]
public virtual string SpecifiedInventoryProviderName { get; protected set; }
public virtual int DisplayOrder { get; protected set; } public virtual int DisplayOrder { get; protected set; }
public virtual bool IsPublished { get; protected set; } public virtual bool IsPublished { get; protected set; }
@ -50,6 +53,7 @@ namespace EasyAbp.EShop.Products.Products
bool isStatic, bool isStatic,
bool isHidden, bool isHidden,
[CanBeNull] string mediaResources, [CanBeNull] string mediaResources,
[CanBeNull] string specifiedInventoryProviderName,
int displayOrder int displayOrder
) : base(id) ) : base(id)
{ {
@ -62,6 +66,7 @@ namespace EasyAbp.EShop.Products.Products
IsStatic = isStatic; IsStatic = isStatic;
IsHidden = isHidden; IsHidden = isHidden;
MediaResources = mediaResources; MediaResources = mediaResources;
SpecifiedInventoryProviderName = specifiedInventoryProviderName;
DisplayOrder = displayOrder; DisplayOrder = displayOrder;
ProductAttributes = new List<ProductAttribute>(); ProductAttributes = new List<ProductAttribute>();

22
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductDiscountManager.cs

@ -1,22 +0,0 @@
using System;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Domain.Services;
namespace EasyAbp.EShop.Products.Products
{
public class ProductDiscountManager : DomainService, IProductDiscountManager
{
public async Task<decimal> GetDiscountedPriceAsync(Product product, ProductSku productSku, Guid storeId)
{
var currentPrice = productSku.Price;
foreach (var provider in ServiceProvider.GetServices<IProductDiscountProvider>())
{
currentPrice = await provider.GetDiscountedPriceAsync(product, productSku, storeId, currentPrice);
}
return currentPrice;
}
}
}

54
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductManager.cs

@ -3,32 +3,30 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using EasyAbp.EShop.Products.ProductCategories; using EasyAbp.EShop.Products.ProductCategories;
using EasyAbp.EShop.Products.ProductDetails;
using EasyAbp.EShop.Products.ProductStores; using EasyAbp.EShop.Products.ProductStores;
using Volo.Abp.Domain.Entities; using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Domain.Services; using Volo.Abp.Domain.Services;
namespace EasyAbp.EShop.Products.Products namespace EasyAbp.EShop.Products.Products
{ {
public class ProductManager : DomainService, IProductManager public class ProductManager : DomainService, IProductManager
{ {
protected Dictionary<string, IProductInventoryProvider> InventoryProviders;
private readonly IProductRepository _productRepository; private readonly IProductRepository _productRepository;
private readonly IProductStoreRepository _productStoreRepository; private readonly IProductStoreRepository _productStoreRepository;
private readonly IProductCategoryRepository _productCategoryRepository; private readonly IProductCategoryRepository _productCategoryRepository;
private readonly IProductInventoryProvider _productInventoryProvider;
private readonly IAttributeOptionIdsSerializer _attributeOptionIdsSerializer; private readonly IAttributeOptionIdsSerializer _attributeOptionIdsSerializer;
public ProductManager( public ProductManager(
IProductRepository productRepository, IProductRepository productRepository,
IProductStoreRepository productStoreRepository, IProductStoreRepository productStoreRepository,
IProductCategoryRepository productCategoryRepository, IProductCategoryRepository productCategoryRepository,
IProductInventoryProvider productInventoryProvider,
IAttributeOptionIdsSerializer attributeOptionIdsSerializer) IAttributeOptionIdsSerializer attributeOptionIdsSerializer)
{ {
_productRepository = productRepository; _productRepository = productRepository;
_productStoreRepository = productStoreRepository; _productStoreRepository = productStoreRepository;
_productCategoryRepository = productCategoryRepository; _productCategoryRepository = productCategoryRepository;
_productInventoryProvider = productInventoryProvider;
_attributeOptionIdsSerializer = attributeOptionIdsSerializer; _attributeOptionIdsSerializer = attributeOptionIdsSerializer;
} }
@ -186,24 +184,54 @@ namespace EasyAbp.EShop.Products.Products
public virtual async Task<bool> IsInventorySufficientAsync(Product product, ProductSku productSku, Guid storeId, int quantity) public virtual async Task<bool> IsInventorySufficientAsync(Product product, ProductSku productSku, Guid storeId, int quantity)
{ {
var inventory = await _productInventoryProvider.GetInventoryAsync(product, productSku, storeId); var inventoryData = await GetInventoryProviderOrDefault(product, productSku)
.GetInventoryDataAsync(product, productSku, storeId);
return product.InventoryStrategy == InventoryStrategy.NoNeed || inventory - quantity >= 0; return product.InventoryStrategy == InventoryStrategy.NoNeed || inventoryData.Inventory - quantity >= 0;
}
public virtual async Task<InventoryDataModel> GetInventoryDataAsync(Product product, ProductSku productSku, Guid storeId)
{
return await GetInventoryProviderOrDefault(product, productSku)
.GetInventoryDataAsync(product, productSku, storeId);
} }
public virtual async Task<int> GetInventoryAsync(Product product, ProductSku productSku, Guid storeId) public virtual async Task<bool> TryIncreaseInventoryAsync(Product product, ProductSku productSku, Guid storeId, int quantity, bool reduceSold)
{ {
return await _productInventoryProvider.GetInventoryAsync(product, productSku, storeId); return await GetInventoryProviderOrDefault(product, productSku)
.TryIncreaseInventoryAsync(product, productSku, storeId, quantity, reduceSold);
} }
public virtual async Task<bool> TryIncreaseInventoryAsync(Product product, ProductSku productSku, Guid storeId, int quantity) public virtual async Task<bool> TryReduceInventoryAsync(Product product, ProductSku productSku, Guid storeId, int quantity, bool increaseSold)
{ {
return await _productInventoryProvider.TryIncreaseInventoryAsync(product, productSku, storeId, quantity); return await GetInventoryProviderOrDefault(product, productSku)
.TryReduceInventoryAsync(product, productSku, storeId, quantity, increaseSold);
} }
public virtual async Task<bool> TryReduceInventoryAsync(Product product, ProductSku productSku, Guid storeId, int quantity) protected virtual IProductInventoryProvider GetInventoryProviderOrDefault(Product product, ProductSku productSku)
{ {
return await _productInventoryProvider.TryReduceInventoryAsync(product, productSku, storeId, quantity); var providerName = !productSku.SpecifiedInventoryProviderName.IsNullOrWhiteSpace()
? productSku.SpecifiedInventoryProviderName
: !product.SpecifiedInventoryProviderName.IsNullOrWhiteSpace()
? product.SpecifiedInventoryProviderName
: "Default";
InventoryProviders ??= ServiceProvider.GetServices<IProductInventoryProvider>()
.ToDictionary(p => p.ProviderName, p => p);
return InventoryProviders.GetOrDefault(providerName) ?? InventoryProviders["Default"];
}
public virtual async Task<decimal> GetDiscountedPriceAsync(Product product, ProductSku productSku, Guid storeId)
{
var currentPrice = productSku.Price;
foreach (var provider in ServiceProvider.GetServices<IProductDiscountProvider>())
{
currentPrice = await provider.GetDiscountedPriceAsync(product, productSku, storeId, currentPrice);
}
return currentPrice;
} }
} }
} }

5
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductSku.cs

@ -26,6 +26,9 @@ namespace EasyAbp.EShop.Products.Products
[CanBeNull] [CanBeNull]
public virtual string MediaResources { get; protected set; } public virtual string MediaResources { get; protected set; }
[CanBeNull]
public virtual string SpecifiedInventoryProviderName { get; protected set; }
public Guid? ProductDetailId { get; set; } public Guid? ProductDetailId { get; set; }
protected ProductSku() {} protected ProductSku() {}
@ -40,6 +43,7 @@ namespace EasyAbp.EShop.Products.Products
int orderMinQuantity, int orderMinQuantity,
int orderMaxQuantity, int orderMaxQuantity,
[CanBeNull] string mediaResources, [CanBeNull] string mediaResources,
[CanBeNull] string specifiedInventoryProviderName,
Guid? productDetailId) : base(id) Guid? productDetailId) : base(id)
{ {
SerializedAttributeOptionIds = serializedAttributeOptionIds; SerializedAttributeOptionIds = serializedAttributeOptionIds;
@ -50,6 +54,7 @@ namespace EasyAbp.EShop.Products.Products
OrderMinQuantity = orderMinQuantity; OrderMinQuantity = orderMinQuantity;
OrderMaxQuantity = orderMaxQuantity; OrderMaxQuantity = orderMaxQuantity;
MediaResources = mediaResources; MediaResources = mediaResources;
SpecifiedInventoryProviderName = specifiedInventoryProviderName;
ProductDetailId = productDetailId; ProductDetailId = productDetailId;
} }

22
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.EntityFrameworkCore/EasyAbp/EShop/Products/ProductInventories/ProductInventoryRepository.cs

@ -4,6 +4,7 @@ using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using EasyAbp.EShop.Products.EntityFrameworkCore; using EasyAbp.EShop.Products.EntityFrameworkCore;
using EasyAbp.EShop.Products.Products;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore; using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore;
@ -16,16 +17,27 @@ namespace EasyAbp.EShop.Products.ProductInventories
{ {
} }
public async Task<int> GetInventoryAsync(Guid productSkuId, CancellationToken cancellationToken = default) public async Task<InventoryDataModel> GetInventoryDataAsync(Guid productSkuId, CancellationToken cancellationToken = default)
{ {
return await GetQueryable().Where(x => x.ProductSkuId == productSkuId).Select(x => x.Inventory) return await GetQueryable()
.Where(x => x.ProductSkuId == productSkuId)
.Select(x => new InventoryDataModel
{
Inventory = x.Inventory,
Sold = x.Sold
})
.FirstOrDefaultAsync(cancellationToken); .FirstOrDefaultAsync(cancellationToken);
} }
public async Task<Dictionary<Guid, int>> GetInventoryDictionaryAsync(List<Guid> productSkuIds, CancellationToken cancellationToken = default) public async Task<Dictionary<Guid, InventoryDataModel>> GetInventoryDataDictionaryAsync(List<Guid> productSkuIds, CancellationToken cancellationToken = default)
{ {
return await GetQueryable().Where(x => productSkuIds.Contains(x.ProductSkuId)) return await GetQueryable()
.ToDictionaryAsync(x => x.ProductSkuId, x => x.Inventory, cancellationToken); .Where(x => productSkuIds.Contains(x.ProductSkuId))
.ToDictionaryAsync(x => x.ProductSkuId, x => new InventoryDataModel
{
Inventory = x.Inventory,
Sold = x.Sold
}, cancellationToken);
} }
} }
} }

2
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/Pages/EShop/Products/Products/Product/Index.cshtml

@ -49,7 +49,7 @@
<th>@L["ProductCode"]</th> <th>@L["ProductCode"]</th>
<th>@L["ProductDisplayName"]</th> <th>@L["ProductDisplayName"]</th>
<th>@L["ProductInventoryStrategy"]</th> <th>@L["ProductInventoryStrategy"]</th>
<th>@L["ProductMediaResources"]</th> <th>@L["ProductSold"]</th>
<th>@L["ProductIsPublished"]</th> <th>@L["ProductIsPublished"]</th>
</tr> </tr>
</thead> </thead>

6
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/Pages/EShop/Products/Products/Product/ViewModels/CreateEditProductViewModel.cs

@ -48,11 +48,15 @@ namespace EasyAbp.EShop.Products.Web.Pages.EShop.Products.Products.Product.ViewM
public InventoryStrategy InventoryStrategy { get; set; } public InventoryStrategy InventoryStrategy { get; set; }
[Display(Name = "ProductDisplayOrder")] [Display(Name = "ProductDisplayOrder")]
public int DisplayOrder { get; set; } = 0; public int DisplayOrder { get; set; }
[Display(Name = "ProductMediaResources")] [Display(Name = "ProductMediaResources")]
public string MediaResources { get; set; } public string MediaResources { get; set; }
[Placeholder("KeepEmptyIfDoNotKnow")]
[Display(Name = "ProductSpecifiedInventoryProviderName")]
public string SpecifiedInventoryProviderName { get; set; }
[Display(Name = "ProductIsPublished")] [Display(Name = "ProductIsPublished")]
public bool IsPublished { get; set; } public bool IsPublished { get; set; }
} }

2
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/Pages/EShop/Products/Products/Product/index.js

@ -54,7 +54,7 @@ $(function () {
{ data: "code" }, { data: "code" },
{ data: "displayName" }, { data: "displayName" },
{ data: "inventoryStrategy" }, { data: "inventoryStrategy" },
{ data: "mediaResources" }, { data: "sold" },
{ data: "isPublished" }, { data: "isPublished" },
] ]
})); }));

1
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/Pages/EShop/Products/Products/ProductSku/Index.cshtml

@ -55,6 +55,7 @@
<th>@L["ProductSkuContentDescription"]</th> <th>@L["ProductSkuContentDescription"]</th>
<th>@L["ProductSkuPrice"]</th> <th>@L["ProductSkuPrice"]</th>
<th>@L["ProductSkuInventory"]</th> <th>@L["ProductSkuInventory"]</th>
<th>@L["ProductSkuSold"]</th>
</tr> </tr>
</thead> </thead>
</abp-table> </abp-table>

5
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/Pages/EShop/Products/Products/ProductSku/ViewModels/EditProductSkuViewModel.cs

@ -2,6 +2,7 @@
using System.ComponentModel; using System.ComponentModel;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form;
namespace EasyAbp.EShop.Products.Web.Pages.EShop.Products.Products.ProductSku.ViewModels namespace EasyAbp.EShop.Products.Web.Pages.EShop.Products.Products.ProductSku.ViewModels
{ {
@ -34,6 +35,10 @@ namespace EasyAbp.EShop.Products.Web.Pages.EShop.Products.Products.ProductSku.Vi
[Display(Name = "ProductSkuMediaResources")] [Display(Name = "ProductSkuMediaResources")]
public string MediaResources { get; set; } public string MediaResources { get; set; }
[Placeholder("KeepEmptyIfDoNotKnow")]
[Display(Name = "ProductSkuSpecifiedInventoryProviderName")]
public string SpecifiedInventoryProviderName { get; set; }
[HiddenInput] [HiddenInput]
[Display(Name = "ProductSkuProductDetailId")] [Display(Name = "ProductSkuProductDetailId")]
public Guid? ProductDetailId { get; set; } public Guid? ProductDetailId { get; set; }

1
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/Pages/EShop/Products/Products/ProductSku/index.js

@ -63,6 +63,7 @@ $(function () {
{ data: "contentDescription" }, { data: "contentDescription" },
{ data: "price" }, { data: "price" },
{ data: "inventory" }, { data: "inventory" },
{ data: "sold" },
] ]
})); }));

1
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/ProductsWebAutoMapperProfile.cs

@ -24,6 +24,7 @@ namespace EasyAbp.EShop.Products.Web
.Ignore(model => model.CategoryIds) .Ignore(model => model.CategoryIds)
.Ignore(model => model.ProductDetail) .Ignore(model => model.ProductDetail)
.Ignore(model => model.StoreId) .Ignore(model => model.StoreId)
.ForSourceMember(dto => dto.Sold, opt => opt.DoNotValidate())
.ForSourceMember(dto => dto.ProductDetailId, opt => opt.DoNotValidate()) .ForSourceMember(dto => dto.ProductDetailId, opt => opt.DoNotValidate())
// .Ignore(x => x.ProductAttributes); // .Ignore(x => x.ProductAttributes);
.ForMember(dest => dest.ProductAttributeNames, .ForMember(dest => dest.ProductAttributeNames,

3837
samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore.DbMigrations/Migrations/20200706060054_AddedSpecifiedInventoryProviderName.Designer.cs

File diff suppressed because it is too large

31
samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore.DbMigrations/Migrations/20200706060054_AddedSpecifiedInventoryProviderName.cs

@ -0,0 +1,31 @@
using Microsoft.EntityFrameworkCore.Migrations;
namespace EShopSample.Migrations
{
public partial class AddedSpecifiedInventoryProviderName : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "SpecifiedInventoryProviderName",
table: "EShopProductsProductSkus",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "SpecifiedInventoryProviderName",
table: "EShopProductsProducts",
nullable: true);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "SpecifiedInventoryProviderName",
table: "EShopProductsProductSkus");
migrationBuilder.DropColumn(
name: "SpecifiedInventoryProviderName",
table: "EShopProductsProducts");
}
}
}

3837
samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore.DbMigrations/Migrations/20200706070250_ChangedSoldToLong.Designer.cs

File diff suppressed because it is too large

27
samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore.DbMigrations/Migrations/20200706070250_ChangedSoldToLong.cs

@ -0,0 +1,27 @@
using Microsoft.EntityFrameworkCore.Migrations;
namespace EShopSample.Migrations
{
public partial class ChangedSoldToLong : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<long>(
name: "Sold",
table: "EShopProductsProductInventories",
nullable: false,
oldClrType: typeof(int),
oldType: "int");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<int>(
name: "Sold",
table: "EShopProductsProductInventories",
type: "int",
nullable: false,
oldClrType: typeof(long));
}
}
}

10
samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore.DbMigrations/Migrations/EShopSampleMigrationsDbContextModelSnapshot.cs

@ -916,8 +916,8 @@ namespace EShopSample.Migrations
b.Property<Guid>("ProductSkuId") b.Property<Guid>("ProductSkuId")
.HasColumnType("uniqueidentifier"); .HasColumnType("uniqueidentifier");
b.Property<int>("Sold") b.Property<long>("Sold")
.HasColumnType("int"); .HasColumnType("bigint");
b.HasKey("Id"); b.HasKey("Id");
@ -1129,6 +1129,9 @@ namespace EShopSample.Migrations
b.Property<Guid>("ProductTypeId") b.Property<Guid>("ProductTypeId")
.HasColumnType("uniqueidentifier"); .HasColumnType("uniqueidentifier");
b.Property<string>("SpecifiedInventoryProviderName")
.HasColumnType("nvarchar(max)");
b.HasKey("Id"); b.HasKey("Id");
b.ToTable("EShopProductsProducts"); b.ToTable("EShopProductsProducts");
@ -1310,6 +1313,9 @@ namespace EShopSample.Migrations
b.Property<string>("SerializedAttributeOptionIds") b.Property<string>("SerializedAttributeOptionIds")
.HasColumnType("nvarchar(max)"); .HasColumnType("nvarchar(max)");
b.Property<string>("SpecifiedInventoryProviderName")
.HasColumnType("nvarchar(max)");
b.HasKey("Id"); b.HasKey("Id");
b.HasIndex("ProductId"); b.HasIndex("ProductId");

Loading…
Cancel
Save