diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application/EasyAbp/EShop/Products/Products/ProductAppService.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application/EasyAbp/EShop/Products/Products/ProductAppService.cs index 9c76ef8b..c5f8b75e 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application/EasyAbp/EShop/Products/Products/ProductAppService.cs +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application/EasyAbp/EShop/Products/Products/ProductAppService.cs @@ -53,7 +53,7 @@ namespace EasyAbp.EShop.Products.Products protected override async Task> CreateFilteredQueryAsync(GetProductListInput input) { var query = input.CategoryId.HasValue - ? _repository.WithDetails(input.CategoryId.Value) + ? await _repository.WithDetailsAsync(input.CategoryId.Value) : (await _repository.WithDetailsAsync()); return query @@ -329,7 +329,7 @@ namespace EasyAbp.EShop.Products.Products { var productSkuDto = productDto.ProductSkus.First(x => x.Id == productSku.Id); - var priceDataModel = await _productManager.GetProductPriceAsync(product, productSku); + var priceDataModel = await _productManager.GetRealPriceAsync(product, productSku); productSkuDto.Price = priceDataModel.Price; productSkuDto.DiscountedPrice = priceDataModel.DiscountedPrice; diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application/EasyAbp/EShop/Products/Products/ProductViewAppService.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application/EasyAbp/EShop/Products/Products/ProductViewAppService.cs index f62addca..c05be265 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application/EasyAbp/EShop/Products/Products/ProductViewAppService.cs +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application/EasyAbp/EShop/Products/Products/ProductViewAppService.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using EasyAbp.EShop.Products.Products.CacheItems; @@ -20,17 +21,20 @@ namespace EasyAbp.EShop.Products.Products private readonly IProductViewCacheKeyProvider _productViewCacheKeyProvider; private readonly IDistributedCache _cache; + private readonly IProductManager _productManager; private readonly IProductRepository _productRepository; private readonly IProductViewRepository _repository; public ProductViewAppService( IProductViewCacheKeyProvider productViewCacheKeyProvider, IDistributedCache cache, + IProductManager productManager, IProductRepository productRepository, IProductViewRepository repository) : base(repository) { _productViewCacheKeyProvider = productViewCacheKeyProvider; _cache = cache; + _productManager = productManager; _productRepository = productRepository; _repository = repository; } @@ -38,8 +42,8 @@ namespace EasyAbp.EShop.Products.Products protected override async Task> CreateFilteredQueryAsync(GetProductListInput input) { var query = input.CategoryId.HasValue - ? _repository.WithDetails(input.CategoryId.Value) - : (await _repository.WithDetailsAsync()); + ? await _repository.WithDetailsAsync(input.CategoryId.Value) + : await _repository.WithDetailsAsync(); return query .Where(x => x.StoreId == input.StoreId) @@ -96,7 +100,7 @@ namespace EasyAbp.EShop.Products.Products protected virtual async Task BuildStoreProductViewsAsync(Guid storeId) { - var products = await _productRepository.GetListAsync(x => x.StoreId == storeId); + var products = await _productRepository.GetListAsync(x => x.StoreId == storeId, true); using var uow = UnitOfWorkManager.Begin(true, true); @@ -104,9 +108,14 @@ namespace EasyAbp.EShop.Products.Products foreach (var product in products) { - await _repository.InsertAsync(ObjectMapper.Map(product)); + var productView = ObjectMapper.Map(product); + + await FillPriceInfoWithRealPriceAsync(product, productView); + + await _repository.InsertAsync(productView); } + await uow.SaveChangesAsync(); await uow.CompleteAsync(); await _cache.SetAsync(await GetCacheKeyAsync(storeId), new ProductViewCacheItem(), @@ -116,5 +125,32 @@ namespace EasyAbp.EShop.Products.Products await SettingProvider.GetOrNullAsync(ProductsSettings.ProductView.CacheDurationSeconds))) }); } + + protected virtual async Task FillPriceInfoWithRealPriceAsync(Product product, ProductView productView) + { + if (product.ProductSkus.IsNullOrEmpty()) + { + return; + } + + decimal? min = null, max = null; + + foreach (var productSku in product.ProductSkus) + { + var priceDataModel = await _productManager.GetRealPriceAsync(product, productSku); + + if (min is null || priceDataModel.Price < min.Value) + { + min = productSku.Price; + } + + if (max is null || priceDataModel.Price > max.Value) + { + max = productSku.Price; + } + } + + productView.SetPrices(min, max); + } } } diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/DefaultProductPriceProvider.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/DefaultProductPriceProvider.cs index d0c7cf49..ace15079 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/DefaultProductPriceProvider.cs +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/DefaultProductPriceProvider.cs @@ -1,12 +1,11 @@ -using System; -using System.Threading.Tasks; +using System.Threading.Tasks; using Volo.Abp.DependencyInjection; namespace EasyAbp.EShop.Products.Products { public class DefaultProductPriceProvider : IProductPriceProvider, ITransientDependency { - public virtual Task GetPriceAsync(Product product, ProductSku productSku) + public virtual Task GetPriceAsync(IProduct product, IProductSku productSku) { return Task.FromResult(productSku.Price); } diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/IProductManager.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/IProductManager.cs index 919339a5..6ae5c05f 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/IProductManager.cs +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/IProductManager.cs @@ -29,6 +29,6 @@ namespace EasyAbp.EShop.Products.Products Task TryReduceInventoryAsync(Product product, ProductSku productSku, int quantity, bool increaseSold); - Task GetProductPriceAsync(Product product, ProductSku productSku); + Task GetRealPriceAsync(Product product, ProductSku productSku); } } \ No newline at end of file diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/IProductPriceProvider.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/IProductPriceProvider.cs index e82dc4fc..1926441e 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/IProductPriceProvider.cs +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/IProductPriceProvider.cs @@ -1,10 +1,9 @@ -using System; -using System.Threading.Tasks; +using System.Threading.Tasks; namespace EasyAbp.EShop.Products.Products { public interface IProductPriceProvider { - Task GetPriceAsync(Product product, ProductSku productSku); + Task GetPriceAsync(IProduct product, IProductSku productSku); } } \ No newline at end of file diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/IProductRepository.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/IProductRepository.cs index 004211ce..e7937141 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/IProductRepository.cs +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/IProductRepository.cs @@ -8,9 +8,9 @@ namespace EasyAbp.EShop.Products.Products { public interface IProductRepository : IRepository { - IQueryable GetQueryable(Guid categoryId); + Task> GetQueryableAsync(Guid categoryId); - IQueryable WithDetails(Guid categoryId); + Task> WithDetailsAsync(Guid categoryId); Task CheckUniqueNameAsync(Product entity, CancellationToken cancellationToken = new CancellationToken()); } diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/IProductViewRepository.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/IProductViewRepository.cs index e33be01f..72dd8a89 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/IProductViewRepository.cs +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/IProductViewRepository.cs @@ -1,13 +1,14 @@ using System; using System.Linq; +using System.Threading.Tasks; using Volo.Abp.Domain.Repositories; namespace EasyAbp.EShop.Products.Products { public interface IProductViewRepository : IRepository { - IQueryable GetQueryable(Guid categoryId); + Task> GetQueryableAsync(Guid categoryId); - IQueryable WithDetails(Guid categoryId); + Task> WithDetailsAsync(Guid categoryId); } } \ No newline at end of file diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductManager.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductManager.cs index b91af8b5..f93597bd 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductManager.cs +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductManager.cs @@ -210,13 +210,13 @@ namespace EasyAbp.EShop.Products.Products return await _productInventoryProvider.TryReduceInventoryAsync(product, productSku, quantity, increaseSold); } - [UnitOfWork] - public virtual async Task GetProductPriceAsync(Product product, ProductSku productSku) + public virtual async Task GetRealPriceAsync(Product product, ProductSku productSku) { var price = await _productPriceProvider.GetPriceAsync(product, productSku); var discountedPrice = price; + // Todo: provider execution ordering. foreach (var provider in LazyServiceProvider.LazyGetService>()) { discountedPrice = await provider.GetDiscountedPriceAsync(product, productSku, discountedPrice); diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductView.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductView.cs index f5facbe0..a918d92a 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductView.cs +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductView.cs @@ -89,5 +89,11 @@ namespace EasyAbp.EShop.Products.Products { Sold = sold; } + + public void SetPrices(decimal? minimumPrice, decimal? maximumPrice) + { + MinimumPrice = minimumPrice; + MaximumPrice = maximumPrice; + } } } diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.EntityFrameworkCore/EasyAbp/EShop/Products/Products/ProductRepository.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.EntityFrameworkCore/EasyAbp/EShop/Products/Products/ProductRepository.cs index 2fd38876..5ce836e7 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.EntityFrameworkCore/EasyAbp/EShop/Products/Products/ProductRepository.cs +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.EntityFrameworkCore/EasyAbp/EShop/Products/Products/ProductRepository.cs @@ -51,20 +51,20 @@ namespace EasyAbp.EShop.Products.Products .Include(x => x.ProductSkus); } - public IQueryable GetQueryable(Guid categoryId) + public virtual async Task> GetQueryableAsync(Guid categoryId) { - return JoinProductCategories(DbSet, categoryId); + return await JoinProductCategoriesAsync(await GetDbSetAsync(), categoryId); } - public IQueryable WithDetails(Guid categoryId) + public virtual async Task> WithDetailsAsync(Guid categoryId) { - return JoinProductCategories(WithDetails(), categoryId); + return await JoinProductCategoriesAsync(await WithDetailsAsync(), categoryId); } - protected virtual IQueryable JoinProductCategories(IQueryable queryable, Guid categoryId) + protected virtual async Task> JoinProductCategoriesAsync(IQueryable queryable, Guid categoryId) { return queryable.Join( - DbContext.ProductCategories.Where(productCategory => productCategory.CategoryId == categoryId), + (await GetDbContextAsync()).ProductCategories.Where(productCategory => productCategory.CategoryId == categoryId), product => product.Id, productCategory => productCategory.ProductId, (product, productCategory) => product diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.EntityFrameworkCore/EasyAbp/EShop/Products/Products/ProductViewRepository.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.EntityFrameworkCore/EasyAbp/EShop/Products/Products/ProductViewRepository.cs index c17c7913..8f99664a 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.EntityFrameworkCore/EasyAbp/EShop/Products/Products/ProductViewRepository.cs +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.EntityFrameworkCore/EasyAbp/EShop/Products/Products/ProductViewRepository.cs @@ -18,20 +18,20 @@ namespace EasyAbp.EShop.Products.Products return (await base.GetQueryableAsync()).IncludeDetails(); } - public IQueryable GetQueryable(Guid categoryId) + public virtual async Task> GetQueryableAsync(Guid categoryId) { - return JoinProductCategories(DbSet, categoryId); + return await JoinProductCategoriesAsync(DbSet, categoryId); } - public IQueryable WithDetails(Guid categoryId) + public virtual async Task> WithDetailsAsync(Guid categoryId) { - return JoinProductCategories(WithDetails(), categoryId); + return await JoinProductCategoriesAsync(await WithDetailsAsync(), categoryId); } - protected virtual IQueryable JoinProductCategories(IQueryable queryable, Guid categoryId) + protected virtual async Task> JoinProductCategoriesAsync(IQueryable queryable, Guid categoryId) { return queryable.Join( - DbContext.ProductCategories.Where(productCategory => productCategory.CategoryId == categoryId), + (await GetDbContextAsync()).ProductCategories.Where(productCategory => productCategory.CategoryId == categoryId), product => product.Id, productCategory => productCategory.ProductId, (product, productCategory) => product diff --git a/modules/EasyAbp.EShop.Products/test/EasyAbp.EShop.Products.Application.Tests/Products/ProductAppServiceTests.cs b/modules/EasyAbp.EShop.Products/test/EasyAbp.EShop.Products.Application.Tests/Products/ProductAppServiceTests.cs index 875466de..a8969afe 100644 --- a/modules/EasyAbp.EShop.Products/test/EasyAbp.EShop.Products.Application.Tests/Products/ProductAppServiceTests.cs +++ b/modules/EasyAbp.EShop.Products/test/EasyAbp.EShop.Products.Application.Tests/Products/ProductAppServiceTests.cs @@ -23,7 +23,7 @@ namespace EasyAbp.EShop.Products.Products } [Fact] - public async Task Should_Create_A_Product() + public async Task Should_Create_Product() { // Arrange _eShopProductsOptions.Groups.Configure("Default Group Name", x => @@ -35,7 +35,7 @@ namespace EasyAbp.EShop.Products.Products var requestDto = new CreateUpdateProductDto { ProductGroupName = "Default Group Name", - ProductDetailId = ProductsTestData.ProductDetails1Id, + ProductDetailId = ProductsTestData.ProductDetails2Id, StoreId = ProductsTestData.Store1Id, UniqueName = "Unique Pencil", DisplayName = "Pencil", @@ -78,9 +78,9 @@ namespace EasyAbp.EShop.Products.Products } [Fact] - public async Task Should_Create_A_Sku() + public async Task Should_Create_Skus() { - await Should_Create_A_Product(); + await Should_Create_Product(); Guid productId = default; Guid productAttributeOptionId = default; UsingDbContext(db => @@ -110,6 +110,7 @@ namespace EasyAbp.EShop.Products.Products response.ShouldNotBeNull(); response.MinimumPrice.ShouldBe(1m); + response.MaximumPrice.ShouldBe(1m); response.ProductSkus.Count.ShouldBe(1); var responseSku = response.ProductSkus.First(); @@ -119,7 +120,29 @@ namespace EasyAbp.EShop.Products.Products responseSku.AttributeOptionIds.First().ShouldBe(productAttributeOptionId); responseSku.OrderMinQuantity.ShouldBe(1); responseSku.OrderMaxQuantity.ShouldBe(10); + } + + [Fact] + public async Task Should_Get_Product_Min_Max_Prices() + { + var getListResult = await _productAppService.GetListAsync(new GetProductListInput + { + StoreId = ProductsTestData.Store1Id + }); + getListResult.Items.ShouldNotBeEmpty(); + + var productDto = getListResult.Items.FirstOrDefault(x => x.Id == ProductsTestData.Product1Id); + + productDto.ShouldNotBeNull(); + productDto.MinimumPrice.ShouldBe(1m); + productDto.MaximumPrice.ShouldBe(3m); + + var getResult = await _productAppService.GetAsync(ProductsTestData.Product1Id); + + getResult.ShouldNotBeNull(); + getResult.MinimumPrice.ShouldBe(1m); + getResult.MaximumPrice.ShouldBe(3m); } } } \ No newline at end of file diff --git a/modules/EasyAbp.EShop.Products/test/EasyAbp.EShop.Products.Application.Tests/Products/ProductViewAppServiceTests.cs b/modules/EasyAbp.EShop.Products/test/EasyAbp.EShop.Products.Application.Tests/Products/ProductViewAppServiceTests.cs new file mode 100644 index 00000000..d631bf1e --- /dev/null +++ b/modules/EasyAbp.EShop.Products/test/EasyAbp.EShop.Products.Application.Tests/Products/ProductViewAppServiceTests.cs @@ -0,0 +1,46 @@ +using System; +using System.Linq; +using System.Threading.Tasks; +using EasyAbp.EShop.Products.Products.Dtos; +using Shouldly; +using Xunit; + +namespace EasyAbp.EShop.Products.Products +{ + public class ProductViewAppServiceTests : ProductsApplicationTestBase + { + private readonly IProductManager _productManager; + private readonly IProductViewAppService _productViewAppService; + + public ProductViewAppServiceTests() + { + _productManager = GetRequiredService(); + _productViewAppService = GetRequiredService(); + } + + [Fact] + public async Task Should_Get_Product_Min_Max_Prices() + { + var getListResult = await _productViewAppService.GetListAsync(new GetProductListInput + { + StoreId = ProductsTestData.Store1Id + }); + + getListResult.Items.ShouldNotBeEmpty(); + + var productDto = getListResult.Items.FirstOrDefault(x => x.Id == ProductsTestData.Product1Id); + + productDto.ShouldNotBeNull(); + productDto.MinimumPrice.ShouldBe(1m); + productDto.MaximumPrice.ShouldBe(3m); + + var getResult = await _productViewAppService.GetAsync(ProductsTestData.Product1Id); + + getResult.ShouldNotBeNull(); + getResult.MinimumPrice.ShouldBe(1m); + getResult.MaximumPrice.ShouldBe(3m); + } + + + } +} \ No newline at end of file diff --git a/modules/EasyAbp.EShop.Products/test/EasyAbp.EShop.Products.TestBase/ProductsTestData.cs b/modules/EasyAbp.EShop.Products/test/EasyAbp.EShop.Products.TestBase/ProductsTestData.cs index 6dfaba4b..313aaf8a 100644 --- a/modules/EasyAbp.EShop.Products/test/EasyAbp.EShop.Products.TestBase/ProductsTestData.cs +++ b/modules/EasyAbp.EShop.Products/test/EasyAbp.EShop.Products.TestBase/ProductsTestData.cs @@ -7,5 +7,23 @@ namespace EasyAbp.EShop.Products public static Guid Store1Id { get; } = Guid.NewGuid(); public static Guid ProductDetails1Id { get; } = Guid.NewGuid(); + + public static Guid ProductDetails2Id { get; } = Guid.NewGuid(); + + public static Guid Product1Id { get; } = Guid.NewGuid(); + + public static Guid Product1Attribute1Id { get; } = Guid.NewGuid(); + + public static Guid Product1Attribute1Option1Id { get; } = Guid.NewGuid(); + + public static Guid Product1Attribute1Option2Id { get; } = Guid.NewGuid(); + + public static Guid Product1Attribute1Option3Id { get; } = Guid.NewGuid(); + + public static Guid Product1Sku1Id { get; } = Guid.NewGuid(); + + public static Guid Product1Sku2Id { get; } = Guid.NewGuid(); + + public static Guid Product1Sku3Id { get; } = Guid.NewGuid(); } } \ No newline at end of file diff --git a/modules/EasyAbp.EShop.Products/test/EasyAbp.EShop.Products.TestBase/ProductsTestDataBuilder.cs b/modules/EasyAbp.EShop.Products/test/EasyAbp.EShop.Products.TestBase/ProductsTestDataBuilder.cs index 5c62ef88..0fa488c1 100644 --- a/modules/EasyAbp.EShop.Products/test/EasyAbp.EShop.Products.TestBase/ProductsTestDataBuilder.cs +++ b/modules/EasyAbp.EShop.Products/test/EasyAbp.EShop.Products.TestBase/ProductsTestDataBuilder.cs @@ -1,17 +1,30 @@ +using System; using System.Threading.Tasks; using EasyAbp.EShop.Products.ProductDetails; +using EasyAbp.EShop.Products.Products; using Volo.Abp.DependencyInjection; using Volo.Abp.Threading; +using Volo.Abp.Uow; namespace EasyAbp.EShop.Products { public class ProductsTestDataBuilder : ITransientDependency { + private readonly IProductManager _productManager; + private readonly IUnitOfWorkManager _unitOfWorkManager; private readonly IProductDetailRepository _productDetailRepository; + private readonly IAttributeOptionIdsSerializer _attributeOptionIdsSerializer; - public ProductsTestDataBuilder(IProductDetailRepository productDetailRepository) + public ProductsTestDataBuilder( + IProductManager productManager, + IUnitOfWorkManager unitOfWorkManager, + IProductDetailRepository productDetailRepository, + IAttributeOptionIdsSerializer attributeOptionIdsSerializer) { + _productManager = productManager; + _unitOfWorkManager = unitOfWorkManager; _productDetailRepository = productDetailRepository; + _attributeOptionIdsSerializer = attributeOptionIdsSerializer; } public void Build() @@ -21,8 +34,49 @@ namespace EasyAbp.EShop.Products public async Task BuildAsync() { - await _productDetailRepository.InsertAsync(new ProductDetail(ProductsTestData.ProductDetails1Id, null, - ProductsTestData.Store1Id, "Product details for store 1")); + using var uow = _unitOfWorkManager.Begin(); + + var productDetail1 = await _productDetailRepository.InsertAsync( + new ProductDetail(ProductsTestData.ProductDetails1Id, null, ProductsTestData.Store1Id, + "Product details for store 1"), true); + + var productDetail2 = await _productDetailRepository.InsertAsync( + new ProductDetail(ProductsTestData.ProductDetails2Id, null, ProductsTestData.Store1Id, + "Product details for store 1"), true); + + var product = new Product(ProductsTestData.Product1Id, null, ProductsTestData.Store1Id, "Default", + productDetail1.Id, "Cake", "Cake", InventoryStrategy.NoNeed, true, false, false, null, null, 0); + + var attribute = new ProductAttribute(ProductsTestData.Product1Attribute1Id, "Size", null); + + attribute.ProductAttributeOptions.AddRange(new[] + { + new ProductAttributeOption(ProductsTestData.Product1Attribute1Option1Id, "S", null), + new ProductAttributeOption(ProductsTestData.Product1Attribute1Option2Id, "M", null), + new ProductAttributeOption(ProductsTestData.Product1Attribute1Option3Id, "L", null) + }); + + product.ProductAttributes.Add(attribute); + + await _productManager.CreateAsync(product); + + var productSku1 = new ProductSku(ProductsTestData.Product1Sku1Id, + await _attributeOptionIdsSerializer.SerializeAsync(new[] + { ProductsTestData.Product1Attribute1Option1Id }), null, "CNY", null, 1m, 1, 10, null, null, null); + + var productSku2 = new ProductSku(ProductsTestData.Product1Sku2Id, + await _attributeOptionIdsSerializer.SerializeAsync(new[] + { ProductsTestData.Product1Attribute1Option2Id }), null, "CNY", null, 2m, 1, 10, null, null, null); + + var productSku3 = new ProductSku(ProductsTestData.Product1Sku3Id, + await _attributeOptionIdsSerializer.SerializeAsync(new[] + { ProductsTestData.Product1Attribute1Option3Id }), null, "CNY", null, 3m, 1, 10, null, null, null); + + await _productManager.CreateSkuAsync(product, productSku1); + await _productManager.CreateSkuAsync(product, productSku2); + await _productManager.CreateSkuAsync(product, productSku3); + + await uow.CompleteAsync(); } } } \ No newline at end of file