diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/cs.json b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/cs.json index 5472daf3..8dd0d2ff 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/cs.json +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/cs.json @@ -87,6 +87,7 @@ "EasyAbp.EShop.Products:NonexistentProductGroup": "The specified product group ({productGroupName}) is nonexistent.", "EasyAbp.EShop.Products:ProductSkuCodeDuplicated": "Sku code {code} is duplicate for the product {productId}", "EasyAbp.EShop.Products:ProductSkuDuplicated": "Sku {serializedAttributeOptionIds} is duplicate for the product {productId}", + "EasyAbp.EShop.Products:ProductSkuIncorrectAttributeOptions": "Sku {serializedAttributeOptionIds} is incorrect for the product {productId}", "EasyAbp.EShop.Products:NotAllowedToGetCategoryListWithShowHidden": "You have no permission to get category list with hidden categories.", "EasyAbp.EShop.Products:ProductAttributeOptionsDeletionFailed": "Should ensure there are no SKUs using the attribute option which you want to delete.", "EasyAbp.EShop.Products:ProductAttributesModificationFailed": "Should ensure SKUs are empty if you want to modify attributes of a product.", diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/en.json b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/en.json index 195e1add..7d39ef3b 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/en.json +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/en.json @@ -88,6 +88,7 @@ "EasyAbp.EShop.Products:NonexistentProductGroup": "The specified product group ({productGroupName}) is nonexistent.", "EasyAbp.EShop.Products:ProductSkuCodeDuplicated": "Sku code {code} is duplicate for the product {productId}", "EasyAbp.EShop.Products:ProductSkuDuplicated": "Sku {serializedAttributeOptionIds} is duplicate for the product {productId}", + "EasyAbp.EShop.Products:ProductSkuIncorrectAttributeOptions": "Sku {serializedAttributeOptionIds} is incorrect for the product {productId}", "EasyAbp.EShop.Products:NotAllowedToGetCategoryListWithShowHidden": "You have no permission to get category list with hidden categories.", "EasyAbp.EShop.Products:ProductAttributeOptionsDeletionFailed": "Should ensure there are no SKUs using the attribute option which you want to delete.", "EasyAbp.EShop.Products:ProductAttributesModificationFailed": "Should ensure SKUs are empty if you want to modify attributes of a product.", diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/pl.json b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/pl.json index 8f38f8a1..67b62e2b 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/pl.json +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/pl.json @@ -87,6 +87,7 @@ "EasyAbp.EShop.Products:NonexistentProductGroup": "The specified product group ({productGroupName}) is nonexistent.", "EasyAbp.EShop.Products:ProductSkuCodeDuplicated": "Sku code {code} is duplicate for the product {productId}", "EasyAbp.EShop.Products:ProductSkuDuplicated": "Sku {serializedAttributeOptionIds} is duplicate for the product {productId}", + "EasyAbp.EShop.Products:ProductSkuIncorrectAttributeOptions": "Sku {serializedAttributeOptionIds} is incorrect for the product {productId}", "EasyAbp.EShop.Products:NotAllowedToGetCategoryListWithShowHidden": "You have no permission to get category list with hidden categories.", "EasyAbp.EShop.Products:ProductAttributeOptionsDeletionFailed": "Should ensure there are no SKUs using the attribute option which you want to delete.", "EasyAbp.EShop.Products:ProductAttributesModificationFailed": "Should ensure SKUs are empty if you want to modify attributes of a product.", diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/pt-BR.json b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/pt-BR.json index 4bbf27e2..ba6b48db 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/pt-BR.json +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/pt-BR.json @@ -87,6 +87,7 @@ "EasyAbp.EShop.Products:NonexistentProductGroup": "The specified product group ({productGroupName}) is nonexistent.", "EasyAbp.EShop.Products:ProductSkuCodeDuplicated": "Sku code {code} is duplicate for the product {productId}", "EasyAbp.EShop.Products:ProductSkuDuplicated": "Sku {serializedAttributeOptionIds} is duplicate for the product {productId}", + "EasyAbp.EShop.Products:ProductSkuIncorrectAttributeOptions": "Sku {serializedAttributeOptionIds} is incorrect for the product {productId}", "EasyAbp.EShop.Products:NotAllowedToGetCategoryListWithShowHidden": "You have no permission to get category list with hidden categories.", "EasyAbp.EShop.Products:ProductAttributeOptionsDeletionFailed": "Should ensure there are no SKUs using the attribute option which you want to delete.", "EasyAbp.EShop.Products:ProductAttributesModificationFailed": "Should ensure SKUs are empty if you want to modify attributes of a product.", diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/sl.json b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/sl.json index 92f16776..1fee2035 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/sl.json +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/sl.json @@ -88,6 +88,7 @@ "EasyAbp.EShop.Products:NonexistentProductGroup": "The specified product group ({productGroupName}) is nonexistent.", "EasyAbp.EShop.Products:ProductSkuCodeDuplicated": "Sku code {code} is duplicate for the product {productId}", "EasyAbp.EShop.Products:ProductSkuDuplicated": "Sku {serializedAttributeOptionIds} is duplicate for the product {productId}", + "EasyAbp.EShop.Products:ProductSkuIncorrectAttributeOptions": "Sku {serializedAttributeOptionIds} is incorrect for the product {productId}", "EasyAbp.EShop.Products:NotAllowedToGetCategoryListWithShowHidden": "You have no permission to get category list with hidden categories.", "EasyAbp.EShop.Products:ProductAttributeOptionsDeletionFailed": "Should ensure there are no SKUs using the attribute option which you want to delete.", "EasyAbp.EShop.Products:ProductAttributesModificationFailed": "Should ensure SKUs are empty if you want to modify attributes of a product.", diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/tr.json b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/tr.json index d8e25e1c..cb9c4994 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/tr.json +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/tr.json @@ -88,6 +88,7 @@ "EasyAbp.EShop.Products:NonexistentProductGroup": "The specified product group ({productGroupName}) is nonexistent.", "EasyAbp.EShop.Products:ProductSkuCodeDuplicated": "Sku code {code} is duplicate for the product {productId}", "EasyAbp.EShop.Products:ProductSkuDuplicated": "Sku {serializedAttributeOptionIds} is duplicate for the product {productId}", + "EasyAbp.EShop.Products:ProductSkuIncorrectAttributeOptions": "Sku {serializedAttributeOptionIds} is incorrect for the product {productId}", "EasyAbp.EShop.Products:NotAllowedToGetCategoryListWithShowHidden": "You have no permission to get category list with hidden categories.", "EasyAbp.EShop.Products:ProductAttributeOptionsDeletionFailed": "Should ensure there are no SKUs using the attribute option which you want to delete.", "EasyAbp.EShop.Products:ProductAttributesModificationFailed": "Should ensure SKUs are empty if you want to modify attributes of a product.", diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/vi.json b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/vi.json index 68e43d47..aa785b24 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/vi.json +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/vi.json @@ -87,6 +87,7 @@ "EasyAbp.EShop.Products:NonexistentProductGroup": "The specified product group ({productGroupName}) is nonexistent.", "EasyAbp.EShop.Products:ProductSkuCodeDuplicated": "Sku code {code} is duplicate for the product {productId}", "EasyAbp.EShop.Products:ProductSkuDuplicated": "Sku {serializedAttributeOptionIds} is duplicate for the product {productId}", + "EasyAbp.EShop.Products:ProductSkuIncorrectAttributeOptions": "Sku {serializedAttributeOptionIds} is incorrect for the product {productId}", "EasyAbp.EShop.Products:NotAllowedToGetCategoryListWithShowHidden": "You have no permission to get category list with hidden categories.", "EasyAbp.EShop.Products:ProductAttributeOptionsDeletionFailed": "Should ensure there are no SKUs using the attribute option which you want to delete.", "EasyAbp.EShop.Products:ProductAttributesModificationFailed": "Should ensure SKUs are empty if you want to modify attributes of a product.", diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/zh-Hans.json b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/zh-Hans.json index 6bad87c7..e261b4ed 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/zh-Hans.json +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/zh-Hans.json @@ -85,6 +85,7 @@ "EasyAbp.EShop.Products:NonexistentProductGroup": "指定的产品组({productGroupName})不存在", "EasyAbp.EShop.Products:ProductSkuCodeDuplicated": "商品{productId}的Sku代码{code}重复", "EasyAbp.EShop.Products:ProductSkuDuplicated": "商品{productId}的Sku{serializedAttributeOptionIds}重复", + "EasyAbp.EShop.Products:ProductSkuIncorrectAttributeOptions": "商品{productId}的Sku{serializedAttributeOptionIds}不正确", "EasyAbp.EShop.Products:NotAllowedToGetCategoryListWithShowHidden": "您没有权限获取带有隐藏类别的类别列表", "EasyAbp.EShop.Products:ProductAttributeOptionsDeletionFailed": "请确保没有使用您想要删除的属性选项的sku", "EasyAbp.EShop.Products:ProductAttributesModificationFailed": "请先确保Sku为空再修改商品的属性", diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/zh-Hant.json b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/zh-Hant.json index 33ab9343..eabbaa0b 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/zh-Hant.json +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/zh-Hant.json @@ -85,6 +85,7 @@ "EasyAbp.EShop.Products:NonexistentProductGroup": "指定的產品組({productGroupName})不存在", "EasyAbp.EShop.Products:ProductSkuCodeDuplicated": "商品{productId}的Sku代碼{code}重復", "EasyAbp.EShop.Products:ProductSkuDuplicated": "商品{productId}的Sku{serializedAttributeOptionIds}重復", + "EasyAbp.EShop.Products:ProductSkuIncorrectAttributeOptions": "商品{productId}的Sku{serializedAttributeOptionIds}不正確", "EasyAbp.EShop.Products:NotAllowedToGetCategoryListWithShowHidden": "您沒有權限獲取帶有隱藏類別的類別列表", "EasyAbp.EShop.Products:ProductAttributeOptionsDeletionFailed": "請確保沒有使用您想要刪除的屬性選項的sku", "EasyAbp.EShop.Products:ProductAttributesModificationFailed": "請先確保Sku為空再修改商品的屬性", diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/ProductsErrorCodes.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/ProductsErrorCodes.cs index 5ce4947f..6b198991 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/ProductsErrorCodes.cs +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/ProductsErrorCodes.cs @@ -8,6 +8,7 @@ public const string NonexistentProductGroup = "EasyAbp.EShop.Products:NonexistentProductGroup"; public const string ProductSkuCodeDuplicated = "EasyAbp.EShop.Products:ProductSkuCodeDuplicated"; public const string ProductSkuDuplicated = "EasyAbp.EShop.Products:ProductSkuDuplicated"; + public const string ProductSkuIncorrectAttributeOptions = "EasyAbp.EShop.Products:ProductSkuIncorrectAttributeOptions"; public const string NotAllowedToGetCategoryListWithShowHidden = "EasyAbp.EShop.Products:NotAllowedToGetCategoryListWithShowHidden"; public const string ProductAttributeOptionsDeletionFailed = "EasyAbp.EShop.Products:ProductAttributeOptionsDeletionFailed"; public const string ProductAttributesModificationFailed = "EasyAbp.EShop.Products:ProductAttributesModificationFailed"; 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 08889dae..abfce434 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 @@ -19,6 +19,7 @@ namespace EasyAbp.EShop.Products.Products private readonly IProductDetailRepository _productDetailRepository; private readonly IProductCategoryRepository _productCategoryRepository; private readonly IProductInventoryProvider _productInventoryProvider; + private readonly IAttributeOptionIdsSerializer _attributeOptionIdsSerializer; private readonly IProductGroupConfigurationProvider _productGroupConfigurationProvider; public ProductManager( @@ -27,6 +28,7 @@ namespace EasyAbp.EShop.Products.Products IProductDetailRepository productDetailRepository, IProductCategoryRepository productCategoryRepository, IProductInventoryProvider productInventoryProvider, + IAttributeOptionIdsSerializer attributeOptionIdsSerializer, IProductGroupConfigurationProvider productGroupConfigurationProvider) { _productRepository = productRepository; @@ -34,6 +36,7 @@ namespace EasyAbp.EShop.Products.Products _productDetailRepository = productDetailRepository; _productCategoryRepository = productCategoryRepository; _productInventoryProvider = productInventoryProvider; + _attributeOptionIdsSerializer = attributeOptionIdsSerializer; _productGroupConfigurationProvider = productGroupConfigurationProvider; } @@ -131,15 +134,25 @@ namespace EasyAbp.EShop.Products.Products return Task.CompletedTask; } - protected virtual Task CheckSkuAttributeOptionsAsync(Product product, ProductSku productSku) + protected virtual async Task CheckSkuAttributeOptionsAsync(Product product, ProductSku productSku) { + var attributeOptionIds = + (await _attributeOptionIdsSerializer.DeserializeAsync(productSku.SerializedAttributeOptionIds)) + .ToList(); + + if (!product.ProductAttributes.TrueForAll(attribute => + attribute.ProductAttributeOptions.Select(option => option.Id).Intersect(attributeOptionIds) + .Count() == 1)) + { + throw new ProductSkuIncorrectAttributeOptionsException(product.Id, + productSku.SerializedAttributeOptionIds); + } + if (product.ProductSkus.Where(sku => sku.Id != productSku.Id).FirstOrDefault(sku => - sku.SerializedAttributeOptionIds.Equals(productSku.SerializedAttributeOptionIds)) != null) + sku.SerializedAttributeOptionIds.Equals(productSku.SerializedAttributeOptionIds)) != null) { throw new ProductSkuDuplicatedException(product.Id, productSku.SerializedAttributeOptionIds); } - - return Task.CompletedTask; } [UnitOfWork] diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductSkuIncorrectAttributeOptionsException.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductSkuIncorrectAttributeOptionsException.cs new file mode 100644 index 00000000..7e5e8981 --- /dev/null +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductSkuIncorrectAttributeOptionsException.cs @@ -0,0 +1,14 @@ +using System; +using Volo.Abp; + +namespace EasyAbp.EShop.Products.Products +{ + public class ProductSkuIncorrectAttributeOptionsException : BusinessException + { + public ProductSkuIncorrectAttributeOptionsException(Guid productId, string serializedAttributeOptionIds) : base(ProductsErrorCodes.ProductSkuIncorrectAttributeOptions) + { + WithData(nameof(productId), productId); + WithData(nameof(serializedAttributeOptionIds), serializedAttributeOptionIds); + } + } +} \ No newline at end of file diff --git a/modules/EasyAbp.EShop.Products/test/EasyAbp.EShop.Products.Domain.Tests/Products/ProductDomainTests.cs b/modules/EasyAbp.EShop.Products/test/EasyAbp.EShop.Products.Domain.Tests/Products/ProductDomainTests.cs index 60355b76..6bc7dca4 100644 --- a/modules/EasyAbp.EShop.Products/test/EasyAbp.EShop.Products.Domain.Tests/Products/ProductDomainTests.cs +++ b/modules/EasyAbp.EShop.Products/test/EasyAbp.EShop.Products.Domain.Tests/Products/ProductDomainTests.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; @@ -11,11 +12,13 @@ namespace EasyAbp.EShop.Products.Products { private IProductRepository ProductRepository { get; } private IProductManager ProductManager { get; } + private IAttributeOptionIdsSerializer AttributeOptionIdsSerializer { get; } public ProductDomainTests() { ProductRepository = ServiceProvider.GetRequiredService(); ProductManager = ServiceProvider.GetRequiredService(); + AttributeOptionIdsSerializer = ServiceProvider.GetRequiredService(); } [Fact] @@ -121,5 +124,64 @@ namespace EasyAbp.EShop.Products.Products sku1.ProductDetailId.ShouldBeNull(); }); } + + [Fact] + public async Task Should_Create_Sku() + { + var product1 = await ProductRepository.GetAsync(ProductsTestData.Product1Id); + + var attributeOptionIds = new[] + { + ProductsTestData.Product1Attribute1Option4Id, + ProductsTestData.Product1Attribute2Option2Id + }; + + await Should.NotThrowAsync(async () => + { + await ProductManager.CreateSkuAsync(product1, await CreateTestSkuAsync(attributeOptionIds)); + }); + + var serializedAttributeOptionIds = await AttributeOptionIdsSerializer.SerializeAsync(attributeOptionIds); + + product1.ProductSkus.Count(x => x.SerializedAttributeOptionIds == serializedAttributeOptionIds).ShouldBe(1); + } + + [Fact] + public async Task Should_Throw_If_Create_Sku_With_Incorrect_AttributeOptionIds() + { + var product1 = await ProductRepository.GetAsync(ProductsTestData.Product1Id); + + await Should.ThrowAsync(async () => + { + await ProductManager.CreateSkuAsync(product1, await CreateTestSkuAsync(new[] + { + ProductsTestData.Product1Attribute1Option1Id // need 2 options but input 1 + })); + }); + + await Should.ThrowAsync(async () => + { + await ProductManager.CreateSkuAsync(product1, await CreateTestSkuAsync(new[] + { + ProductsTestData.Product1Attribute1Option1Id, + Guid.NewGuid() // a nonexistent option + })); + }); + + await Should.ThrowAsync(async () => + { + await ProductManager.CreateSkuAsync(product1, await CreateTestSkuAsync(new[] + { + ProductsTestData.Product1Attribute1Option1Id, + ProductsTestData.Product1Attribute1Option2Id // 2 options from attribute1 + })); + }); + } + + private async Task CreateTestSkuAsync(IEnumerable attributeOptionIds) + { + return new ProductSku(Guid.NewGuid(), await AttributeOptionIdsSerializer.SerializeAsync(attributeOptionIds), + "test-sku", "CNY", null, 0m, 1, 10, null, null, null); + } } }