From ba5e397ce874f0854eda6710db7c03067fdb043a Mon Sep 17 00:00:00 2001 From: gdlcf88 Date: Wed, 29 Apr 2020 17:26:29 +0800 Subject: [PATCH] Product sku management, close #5 --- .../Dtos/CreateUpdateProductSkuDto.cs | 34 +++++++ .../Products/Products/Dtos/ProductSkuDto.cs | 2 + .../Products/Products/IProductAppService.cs | 6 ++ .../Products/Products/ProductAppService.cs | 72 +++++++++++++++ .../Products/ProductSkuDuplicatedException.cs | 13 +++ .../ProductsApplicationAutoMapperProfile.cs | 2 + .../Products/Localization/Products/cs.json | 14 +++ .../Products/Localization/Products/en.json | 14 +++ .../Products/Localization/Products/pl.json | 14 +++ .../Products/Localization/Products/pt-BR.json | 14 +++ .../Products/Localization/Products/sl.json | 14 +++ .../Products/Localization/Products/tr.json | 14 +++ .../Products/Localization/Products/vi.json | 14 +++ .../Localization/Products/zh-Hans.json | 14 +++ .../Localization/Products/zh-Hant.json | 14 +++ .../ISerializedAttributeOptionIdsFormatter.cs | 13 +++ .../SerializedAttributeOptionIdsFormatter.cs | 22 +++++ .../EasyAbp.EShop.Products.Web.csproj | 13 ++- .../EShop/Products/Products/Product/index.js | 6 ++ .../Products/ProductSku/CreateModal.cshtml | 22 +++++ .../Products/ProductSku/CreateModal.cshtml.cs | 70 ++++++++++++++ .../Products/ProductSku/EditModal.cshtml | 17 ++++ .../Products/ProductSku/EditModal.cshtml.cs | 55 +++++++++++ .../Products/Products/ProductSku/Index.cshtml | 52 +++++++++++ .../Products/ProductSku/Index.cshtml.cs | 31 +++++++ .../CreateEditProductSkuViewModel.cs | 32 +++++++ .../Products/Products/ProductSku/index.css | 0 .../Products/Products/ProductSku/index.js | 92 +++++++++++++++++++ .../ProductsWebAutoMapperProfile.cs | 6 ++ 29 files changed, 685 insertions(+), 1 deletion(-) create mode 100644 modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application.Contracts/EasyAbp/EShop/Products/Products/Dtos/CreateUpdateProductSkuDto.cs create mode 100644 modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application/EasyAbp/EShop/Products/Products/ProductSkuDuplicatedException.cs create mode 100644 modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ISerializedAttributeOptionIdsFormatter.cs create mode 100644 modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/SerializedAttributeOptionIdsFormatter.cs create mode 100644 modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/Pages/EShop/Products/Products/ProductSku/CreateModal.cshtml create mode 100644 modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/Pages/EShop/Products/Products/ProductSku/CreateModal.cshtml.cs create mode 100644 modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/Pages/EShop/Products/Products/ProductSku/EditModal.cshtml create mode 100644 modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/Pages/EShop/Products/Products/ProductSku/EditModal.cshtml.cs create mode 100644 modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/Pages/EShop/Products/Products/ProductSku/Index.cshtml create mode 100644 modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/Pages/EShop/Products/Products/ProductSku/Index.cshtml.cs create mode 100644 modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/Pages/EShop/Products/Products/ProductSku/ViewModels/CreateEditProductSkuViewModel.cs create mode 100644 modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/Pages/EShop/Products/Products/ProductSku/index.css create mode 100644 modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/Pages/EShop/Products/Products/ProductSku/index.js diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application.Contracts/EasyAbp/EShop/Products/Products/Dtos/CreateUpdateProductSkuDto.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application.Contracts/EasyAbp/EShop/Products/Products/Dtos/CreateUpdateProductSkuDto.cs new file mode 100644 index 00000000..4b0f1a60 --- /dev/null +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application.Contracts/EasyAbp/EShop/Products/Products/Dtos/CreateUpdateProductSkuDto.cs @@ -0,0 +1,34 @@ +using System; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; + +namespace EasyAbp.EShop.Products.Products.Dtos +{ + public class UpdateProductSkuDto + { + [DisplayName("ProductSkuCurrency")] + public string Currency { get; set; } + + [DisplayName("ProductSkuOriginalPrice")] + public decimal OriginalPrice { get; set; } + + [DisplayName("ProductSkuPrice")] + public decimal Price { get; set; } + + [DisplayName("ProductSkuInventory")] + public int Inventory { get; set; } + + [DisplayName("ProductSkuOrderMinQuantity")] + public int OrderMinQuantity { get; set; } + + [DisplayName("ProductSkuProductDetailId")] + public Guid? ProductDetailId { get; set; } + } + + public class CreateProductSkuDto : UpdateProductSkuDto + { + [Required] + [DisplayName("ProductSkuSerializedAttributeOptionIds")] + public string SerializedAttributeOptionIds { get; set; } + } +} \ No newline at end of file diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application.Contracts/EasyAbp/EShop/Products/Products/Dtos/ProductSkuDto.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application.Contracts/EasyAbp/EShop/Products/Products/Dtos/ProductSkuDto.cs index 6af28a23..bae050ba 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application.Contracts/EasyAbp/EShop/Products/Products/Dtos/ProductSkuDto.cs +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application.Contracts/EasyAbp/EShop/Products/Products/Dtos/ProductSkuDto.cs @@ -7,6 +7,8 @@ namespace EasyAbp.EShop.Products.Products.Dtos { public string SerializedAttributeOptionIds { get; set; } + public string Currency { get; set; } + public decimal OriginalPrice { get; set; } public decimal Price { get; set; } diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application.Contracts/EasyAbp/EShop/Products/Products/IProductAppService.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application.Contracts/EasyAbp/EShop/Products/Products/IProductAppService.cs index 0eddf92a..4684d477 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application.Contracts/EasyAbp/EShop/Products/Products/IProductAppService.cs +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application.Contracts/EasyAbp/EShop/Products/Products/IProductAppService.cs @@ -15,5 +15,11 @@ namespace EasyAbp.EShop.Products.Products CreateUpdateProductDto> { Task DeleteAsync(Guid id, Guid storeId); + + Task CreateSkuAsync(Guid productId, Guid storeId, CreateProductSkuDto input); + + Task UpdateSkuAsync(Guid productId, Guid productSkuId, Guid storeId, UpdateProductSkuDto input); + + Task DeleteSkuAsync(Guid productId, Guid productSkuId, Guid storeId); } } \ No newline at end of file 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 b0d16005..1bf6b198 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 @@ -22,15 +22,18 @@ namespace EasyAbp.EShop.Products.Products protected override string GetPolicyName { get; set; } = ProductsPermissions.Products.Default; protected override string GetListPolicyName { get; set; } = ProductsPermissions.Products.Default; + private readonly ISerializedAttributeOptionIdsFormatter _serializedAttributeOptionIdsFormatter; private readonly IProductStoreRepository _productStoreRepository; private readonly IProductCategoryRepository _productCategoryRepository; private readonly IProductRepository _repository; public ProductAppService( + ISerializedAttributeOptionIdsFormatter serializedAttributeOptionIdsFormatter, IProductStoreRepository productStoreRepository, IProductCategoryRepository productCategoryRepository, IProductRepository repository) : base(repository) { + _serializedAttributeOptionIdsFormatter = serializedAttributeOptionIdsFormatter; _productStoreRepository = productStoreRepository; _productCategoryRepository = productCategoryRepository; _repository = repository; @@ -178,6 +181,75 @@ namespace EasyAbp.EShop.Products.Products await base.DeleteAsync(id); } + public async Task CreateSkuAsync(Guid productId, Guid storeId, CreateProductSkuDto input) + { + await CheckUpdatePolicyAsync(); + + await CheckStoreIsProductOwnerAsync(productId, storeId); + + var product = await GetEntityByIdAsync(productId); + + input.SerializedAttributeOptionIds = + await _serializedAttributeOptionIdsFormatter.ParseAsync(input.SerializedAttributeOptionIds); + + await CheckSkuAttributeOptionsAsync(product, input.SerializedAttributeOptionIds); + + var sku = ObjectMapper.Map(input); + + EntityHelper.TrySetId(sku, GuidGenerator.Create); + + product.ProductSkus.Add(sku); + + await _repository.UpdateAsync(product, true); + + return ObjectMapper.Map(product); + } + + protected virtual Task CheckSkuAttributeOptionsAsync(Product product, string inputSerializedAttributeOptionIds) + { + if (product.ProductSkus.FirstOrDefault(sku => + sku.SerializedAttributeOptionIds.Equals(inputSerializedAttributeOptionIds)) != null) + { + throw new ProductSkuDuplicatedException(product.Id, inputSerializedAttributeOptionIds); + } + + return Task.CompletedTask; + } + + public async Task UpdateSkuAsync(Guid productId, Guid productSkuId, Guid storeId, UpdateProductSkuDto input) + { + await CheckUpdatePolicyAsync(); + + await CheckStoreIsProductOwnerAsync(productId, storeId); + + var product = await GetEntityByIdAsync(productId); + + var sku = product.ProductSkus.Single(x => x.Id == productSkuId); + + ObjectMapper.Map(input, sku); + + await _repository.UpdateAsync(product, true); + + return ObjectMapper.Map(product); + } + + public async Task DeleteSkuAsync(Guid productId, Guid productSkuId, Guid storeId) + { + await CheckUpdatePolicyAsync(); + + await CheckStoreIsProductOwnerAsync(productId, storeId); + + var product = await GetEntityByIdAsync(productId); + + var sku = product.ProductSkus.Single(x => x.Id == productSkuId); + + product.ProductSkus.Remove(sku); + + await _repository.UpdateAsync(product, true); + + return ObjectMapper.Map(product); + } + protected virtual async Task UpdateProductCategoriesAsync(Guid productId, IEnumerable categoryIds) { await _productCategoryRepository.DeleteAsync(x => x.ProductId.Equals(productId)); diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application/EasyAbp/EShop/Products/Products/ProductSkuDuplicatedException.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application/EasyAbp/EShop/Products/Products/ProductSkuDuplicatedException.cs new file mode 100644 index 00000000..d13b68ad --- /dev/null +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application/EasyAbp/EShop/Products/Products/ProductSkuDuplicatedException.cs @@ -0,0 +1,13 @@ +using System; +using Volo.Abp; + +namespace EasyAbp.EShop.Products.Products +{ + public class ProductSkuDuplicatedException : BusinessException + { + public ProductSkuDuplicatedException(Guid productId, string serializedAttributeOptionIds) : base( + message: $"Sku {serializedAttributeOptionIds} is duplicate for the product {productId}") + { + } + } +} \ No newline at end of file diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application/EasyAbp/EShop/Products/ProductsApplicationAutoMapperProfile.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application/EasyAbp/EShop/Products/ProductsApplicationAutoMapperProfile.cs index bed0a851..bc6455a9 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application/EasyAbp/EShop/Products/ProductsApplicationAutoMapperProfile.cs +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application/EasyAbp/EShop/Products/ProductsApplicationAutoMapperProfile.cs @@ -35,6 +35,8 @@ namespace EasyAbp.EShop.Products .ForSourceMember(dto => dto.StoreId, opt => opt.DoNotValidate()); CreateMap(MemberList.Source); CreateMap(MemberList.Source); + CreateMap(MemberList.Source); + CreateMap(MemberList.Source); CreateMap(); CreateMap(MemberList.Source); CreateMap(); 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 79916d28..c0e9d84a 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 @@ -12,10 +12,24 @@ "ProductDetailProductSkuId": "ProductDetailProductSkuId", "ProductDetailDescription": "ProductDetailDescription", "ProductDetailDisplayOrder": "ProductDetailDisplayOrder", + "ProductAttribute": "ProductAttribute", "ProductAttributeNames": "ProductAttributeNames", "ProductAttributeNamesPlaceholder": "ProductAttributeNamesPlaceholder", + "ProductAttributeOption": "ProductAttributeOption", "ProductAttributeOptionNames": "ProductAttributeOptionNames", "ProductAttributeOptionNamesPlaceholder": "ProductAttributeOptionNamesPlaceholder", + "ProductSku": "ProductSku", + "ProductSkuSerializedAttributeOptionIds": "ProductSkuSerializedAttributeOptionIds", + "ProductSkuCurrency": "ProductSkuCurrency", + "ProductSkuOriginalPrice": "ProductSkuOriginalPrice", + "ProductSkuPrice": "ProductSkuPrice", + "ProductSkuInventory": "ProductSkuInventory", + "ProductSkuOrderMinQuantity": "ProductSkuOrderMinQuantity", + "ProductSkuProductDetailId": "ProductSkuProductDetailId", + "ProductSkuContentDescription": "ProductSkuContentDescription", + "CreateProductSku": "CreateProductSku", + "EditProductSku": "EditProductSku", + "ProductSkuDeletionConfirmationMessage": "Are you sure to delete the product sku {0}?", "ProductInventoryStrategy": "ProductInventoryStrategy", "ProductIsPublished": "ProductIsPublished", "ProductMediaResources": "ProductMediaResources", 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 dd6924d6..1f89dc90 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 @@ -13,10 +13,24 @@ "ProductDetailProductSkuId": "ProductDetailProductSkuId", "ProductDetailDescription": "ProductDetailDescription", "ProductDetailDisplayOrder": "ProductDetailDisplayOrder", + "ProductAttribute": "ProductAttribute", "ProductAttributeNames": "ProductAttributeNames", "ProductAttributeNamesPlaceholder": "ProductAttributeNamesPlaceholder", + "ProductAttributeOption": "ProductAttributeOption", "ProductAttributeOptionNames": "ProductAttributeOptionNames", "ProductAttributeOptionNamesPlaceholder": "ProductAttributeOptionNamesPlaceholder", + "ProductSku": "ProductSku", + "ProductSkuSerializedAttributeOptionIds": "ProductSkuSerializedAttributeOptionIds", + "ProductSkuCurrency": "ProductSkuCurrency", + "ProductSkuOriginalPrice": "ProductSkuOriginalPrice", + "ProductSkuPrice": "ProductSkuPrice", + "ProductSkuInventory": "ProductSkuInventory", + "ProductSkuOrderMinQuantity": "ProductSkuOrderMinQuantity", + "ProductSkuProductDetailId": "ProductSkuProductDetailId", + "ProductSkuContentDescription": "ProductSkuContentDescription", + "CreateProductSku": "CreateProductSku", + "EditProductSku": "EditProductSku", + "ProductSkuDeletionConfirmationMessage": "Are you sure to delete the product sku {0}?", "ProductInventoryStrategy": "ProductInventoryStrategy", "ProductIsPublished": "ProductIsPublished", "ProductMediaResources": "ProductMediaResources", 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 d23e564d..7ea196ff 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 @@ -12,10 +12,24 @@ "ProductDetailProductSkuId": "ProductDetailProductSkuId", "ProductDetailDescription": "ProductDetailDescription", "ProductDetailDisplayOrder": "ProductDetailDisplayOrder", + "ProductAttribute": "ProductAttribute", "ProductAttributeNames": "ProductAttributeNames", "ProductAttributeNamesPlaceholder": "ProductAttributeNamesPlaceholder", + "ProductAttributeOption": "ProductAttributeOption", "ProductAttributeOptionNames": "ProductAttributeOptionNames", "ProductAttributeOptionNamesPlaceholder": "ProductAttributeOptionNamesPlaceholder", + "ProductSku": "ProductSku", + "ProductSkuSerializedAttributeOptionIds": "ProductSkuSerializedAttributeOptionIds", + "ProductSkuCurrency": "ProductSkuCurrency", + "ProductSkuOriginalPrice": "ProductSkuOriginalPrice", + "ProductSkuPrice": "ProductSkuPrice", + "ProductSkuInventory": "ProductSkuInventory", + "ProductSkuOrderMinQuantity": "ProductSkuOrderMinQuantity", + "ProductSkuProductDetailId": "ProductSkuProductDetailId", + "ProductSkuContentDescription": "ProductSkuContentDescription", + "CreateProductSku": "CreateProductSku", + "EditProductSku": "EditProductSku", + "ProductSkuDeletionConfirmationMessage": "Are you sure to delete the product sku {0}?", "ProductInventoryStrategy": "ProductInventoryStrategy", "ProductIsPublished": "ProductIsPublished", "ProductMediaResources": "ProductMediaResources", 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 94621020..ed35d315 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 @@ -12,10 +12,24 @@ "ProductDetailProductSkuId": "ProductDetailProductSkuId", "ProductDetailDescription": "ProductDetailDescription", "ProductDetailDisplayOrder": "ProductDetailDisplayOrder", + "ProductAttribute": "ProductAttribute", "ProductAttributeNames": "ProductAttributeNames", "ProductAttributeNamesPlaceholder": "ProductAttributeNamesPlaceholder", + "ProductAttributeOption": "ProductAttributeOption", "ProductAttributeOptionNames": "ProductAttributeOptionNames", "ProductAttributeOptionNamesPlaceholder": "ProductAttributeOptionNamesPlaceholder", + "ProductSku": "ProductSku", + "ProductSkuSerializedAttributeOptionIds": "ProductSkuSerializedAttributeOptionIds", + "ProductSkuCurrency": "ProductSkuCurrency", + "ProductSkuOriginalPrice": "ProductSkuOriginalPrice", + "ProductSkuPrice": "ProductSkuPrice", + "ProductSkuInventory": "ProductSkuInventory", + "ProductSkuOrderMinQuantity": "ProductSkuOrderMinQuantity", + "ProductSkuProductDetailId": "ProductSkuProductDetailId", + "ProductSkuContentDescription": "ProductSkuContentDescription", + "CreateProductSku": "CreateProductSku", + "EditProductSku": "EditProductSku", + "ProductSkuDeletionConfirmationMessage": "Are you sure to delete the product sku {0}?", "ProductInventoryStrategy": "ProductInventoryStrategy", "ProductIsPublished": "ProductIsPublished", "ProductMediaResources": "ProductMediaResources", 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 68fba77c..7aca7f22 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 @@ -13,10 +13,24 @@ "ProductDetailProductSkuId": "ProductDetailProductSkuId", "ProductDetailDescription": "ProductDetailDescription", "ProductDetailDisplayOrder": "ProductDetailDisplayOrder", + "ProductAttribute": "ProductAttribute", "ProductAttributeNames": "ProductAttributeNames", "ProductAttributeNamesPlaceholder": "ProductAttributeNamesPlaceholder", + "ProductAttributeOption": "ProductAttributeOption", "ProductAttributeOptionNames": "ProductAttributeOptionNames", "ProductAttributeOptionNamesPlaceholder": "ProductAttributeOptionNamesPlaceholder", + "ProductSku": "ProductSku", + "ProductSkuSerializedAttributeOptionIds": "ProductSkuSerializedAttributeOptionIds", + "ProductSkuCurrency": "ProductSkuCurrency", + "ProductSkuOriginalPrice": "ProductSkuOriginalPrice", + "ProductSkuPrice": "ProductSkuPrice", + "ProductSkuInventory": "ProductSkuInventory", + "ProductSkuOrderMinQuantity": "ProductSkuOrderMinQuantity", + "ProductSkuProductDetailId": "ProductSkuProductDetailId", + "ProductSkuContentDescription": "ProductSkuContentDescription", + "CreateProductSku": "CreateProductSku", + "EditProductSku": "EditProductSku", + "ProductSkuDeletionConfirmationMessage": "Are you sure to delete the product sku {0}?", "ProductInventoryStrategy": "ProductInventoryStrategy", "ProductIsPublished": "ProductIsPublished", "ProductMediaResources": "ProductMediaResources", 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 8ffd90f7..19a45144 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 @@ -13,10 +13,24 @@ "ProductDetailProductSkuId": "ProductDetailProductSkuId", "ProductDetailDescription": "ProductDetailDescription", "ProductDetailDisplayOrder": "ProductDetailDisplayOrder", + "ProductAttribute": "ProductAttribute", "ProductAttributeNames": "ProductAttributeNames", "ProductAttributeNamesPlaceholder": "ProductAttributeNamesPlaceholder", + "ProductAttributeOption": "ProductAttributeOption", "ProductAttributeOptionNames": "ProductAttributeOptionNames", "ProductAttributeOptionNamesPlaceholder": "ProductAttributeOptionNamesPlaceholder", + "ProductSku": "ProductSku", + "ProductSkuSerializedAttributeOptionIds": "ProductSkuSerializedAttributeOptionIds", + "ProductSkuCurrency": "ProductSkuCurrency", + "ProductSkuOriginalPrice": "ProductSkuOriginalPrice", + "ProductSkuPrice": "ProductSkuPrice", + "ProductSkuInventory": "ProductSkuInventory", + "ProductSkuOrderMinQuantity": "ProductSkuOrderMinQuantity", + "ProductSkuProductDetailId": "ProductSkuProductDetailId", + "ProductSkuContentDescription": "ProductSkuContentDescription", + "CreateProductSku": "CreateProductSku", + "EditProductSku": "EditProductSku", + "ProductSkuDeletionConfirmationMessage": "Are you sure to delete the product sku {0}?", "ProductInventoryStrategy": "ProductInventoryStrategy", "ProductIsPublished": "ProductIsPublished", "ProductMediaResources": "ProductMediaResources", 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 72b1bf67..966d6462 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 @@ -12,10 +12,24 @@ "ProductDetailProductSkuId": "ProductDetailProductSkuId", "ProductDetailDescription": "ProductDetailDescription", "ProductDetailDisplayOrder": "ProductDetailDisplayOrder", + "ProductAttribute": "ProductAttribute", "ProductAttributeNames": "ProductAttributeNames", "ProductAttributeNamesPlaceholder": "ProductAttributeNamesPlaceholder", + "ProductAttributeOption": "ProductAttributeOption", "ProductAttributeOptionNames": "ProductAttributeOptionNames", "ProductAttributeOptionNamesPlaceholder": "ProductAttributeOptionNamesPlaceholder", + "ProductSku": "ProductSku", + "ProductSkuSerializedAttributeOptionIds": "ProductSkuSerializedAttributeOptionIds", + "ProductSkuCurrency": "ProductSkuCurrency", + "ProductSkuOriginalPrice": "ProductSkuOriginalPrice", + "ProductSkuPrice": "ProductSkuPrice", + "ProductSkuInventory": "ProductSkuInventory", + "ProductSkuOrderMinQuantity": "ProductSkuOrderMinQuantity", + "ProductSkuProductDetailId": "ProductSkuProductDetailId", + "ProductSkuContentDescription": "ProductSkuContentDescription", + "CreateProductSku": "CreateProductSku", + "EditProductSku": "EditProductSku", + "ProductSkuDeletionConfirmationMessage": "Are you sure to delete the product sku {0}?", "ProductInventoryStrategy": "ProductInventoryStrategy", "ProductIsPublished": "ProductIsPublished", "ProductMediaResources": "ProductMediaResources", 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 384123b1..886b4c08 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 @@ -13,10 +13,24 @@ "ProductDetailProductSkuId": "ProductDetailProductSkuId", "ProductDetailDescription": "ProductDetailDescription", "ProductDetailDisplayOrder": "ProductDetailDisplayOrder", + "ProductAttribute": "ProductAttribute", "ProductAttributeNames": "ProductAttributeNames", "ProductAttributeNamesPlaceholder": "ProductAttributeNamesPlaceholder", + "ProductAttributeOption": "ProductAttributeOption", "ProductAttributeOptionNames": "ProductAttributeOptionNames", "ProductAttributeOptionNamesPlaceholder": "ProductAttributeOptionNamesPlaceholder", + "ProductSku": "ProductSku", + "ProductSkuSerializedAttributeOptionIds": "ProductSkuSerializedAttributeOptionIds", + "ProductSkuCurrency": "ProductSkuCurrency", + "ProductSkuOriginalPrice": "ProductSkuOriginalPrice", + "ProductSkuPrice": "ProductSkuPrice", + "ProductSkuInventory": "ProductSkuInventory", + "ProductSkuOrderMinQuantity": "ProductSkuOrderMinQuantity", + "ProductSkuProductDetailId": "ProductSkuProductDetailId", + "ProductSkuContentDescription": "ProductSkuContentDescription", + "CreateProductSku": "CreateProductSku", + "EditProductSku": "EditProductSku", + "ProductSkuDeletionConfirmationMessage": "Are you sure to delete the product sku {0}?", "ProductInventoryStrategy": "ProductInventoryStrategy", "ProductIsPublished": "ProductIsPublished", "ProductMediaResources": "ProductMediaResources", 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 fef533cd..565dea55 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 @@ -13,10 +13,24 @@ "ProductDetailProductSkuId": "ProductDetailProductSkuId", "ProductDetailDescription": "ProductDetailDescription", "ProductDetailDisplayOrder": "ProductDetailDisplayOrder", + "ProductAttribute": "ProductAttribute", "ProductAttributeNames": "ProductAttributeNames", "ProductAttributeNamesPlaceholder": "ProductAttributeNamesPlaceholder", + "ProductAttributeOption": "ProductAttributeOption", "ProductAttributeOptionNames": "ProductAttributeOptionNames", "ProductAttributeOptionNamesPlaceholder": "ProductAttributeOptionNamesPlaceholder", + "ProductSku": "ProductSku", + "ProductSkuSerializedAttributeOptionIds": "ProductSkuSerializedAttributeOptionIds", + "ProductSkuCurrency": "ProductSkuCurrency", + "ProductSkuOriginalPrice": "ProductSkuOriginalPrice", + "ProductSkuPrice": "ProductSkuPrice", + "ProductSkuInventory": "ProductSkuInventory", + "ProductSkuOrderMinQuantity": "ProductSkuOrderMinQuantity", + "ProductSkuProductDetailId": "ProductSkuProductDetailId", + "ProductSkuContentDescription": "ProductSkuContentDescription", + "CreateProductSku": "CreateProductSku", + "EditProductSku": "EditProductSku", + "ProductSkuDeletionConfirmationMessage": "Are you sure to delete the product sku {0}?", "ProductInventoryStrategy": "ProductInventoryStrategy", "ProductIsPublished": "ProductIsPublished", "ProductMediaResources": "ProductMediaResources", diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ISerializedAttributeOptionIdsFormatter.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ISerializedAttributeOptionIdsFormatter.cs new file mode 100644 index 00000000..766e12f7 --- /dev/null +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ISerializedAttributeOptionIdsFormatter.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace EasyAbp.EShop.Products.Products +{ + public interface ISerializedAttributeOptionIdsFormatter + { + Task ParseAsync(string serializedAttributeOptionIds); + + Task ParseAsync(IEnumerable attributeOptionIds); + } +} \ No newline at end of file diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/SerializedAttributeOptionIdsFormatter.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/SerializedAttributeOptionIdsFormatter.cs new file mode 100644 index 00000000..db90b53f --- /dev/null +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/SerializedAttributeOptionIdsFormatter.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Newtonsoft.Json; +using Volo.Abp.DependencyInjection; + +namespace EasyAbp.EShop.Products.Products +{ + public class SerializedAttributeOptionIdsFormatter : ISerializedAttributeOptionIdsFormatter, ITransientDependency + { + public async Task ParseAsync(string serializedAttributeOptionIds) + { + return await ParseAsync(JsonConvert.DeserializeObject>(serializedAttributeOptionIds)); + } + + public Task ParseAsync(IEnumerable attributeOptionIds) + { + return Task.FromResult(JsonConvert.SerializeObject(attributeOptionIds.OrderBy(x => x))); + } + } +} \ No newline at end of file diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/EasyAbp.EShop.Products.Web.csproj b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/EasyAbp.EShop.Products.Web.csproj index 67ad7928..1a3e3c0d 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/EasyAbp.EShop.Products.Web.csproj +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/EasyAbp.EShop.Products.Web.csproj @@ -37,7 +37,6 @@ - @@ -53,4 +52,16 @@ <_ContentIncludedByDefault Remove="Pages\Categories\Category\Index.cshtml" /> + + + CreateModal.cshtml + + + EditModal.cshtml + + + Index.cshtml + + + diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/Pages/EShop/Products/Products/Product/index.js b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/Pages/EShop/Products/Products/Product/index.js index a6b868da..51d69057 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/Pages/EShop/Products/Products/Product/index.js +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/Pages/EShop/Products/Products/Product/index.js @@ -22,6 +22,12 @@ $(function () { rowAction: { items: [ + { + text: l('ProductSku'), + action: function (data) { + document.location.href = document.location.origin + '/EShop/Products/Products/ProductSku?ProductId=' + data.record.id + '&StoreId=' + storeId; + } + }, { text: l('Edit'), action: function (data) { diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/Pages/EShop/Products/Products/ProductSku/CreateModal.cshtml b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/Pages/EShop/Products/Products/ProductSku/CreateModal.cshtml new file mode 100644 index 00000000..f6bbc60f --- /dev/null +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/Pages/EShop/Products/Products/ProductSku/CreateModal.cshtml @@ -0,0 +1,22 @@ +@page +@inherits EasyAbp.EShop.Products.Web.Pages.ProductsPage +@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal +@model EasyAbp.EShop.Products.Web.Pages.EShop.Products.Products.ProductSku.CreateModalModel +@{ + Layout = null; +} + + + + + + @foreach (var attr in Model.Attributes) + { + + } + + + + + + \ No newline at end of file diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/Pages/EShop/Products/Products/ProductSku/CreateModal.cshtml.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/Pages/EShop/Products/Products/ProductSku/CreateModal.cshtml.cs new file mode 100644 index 00000000..418bcee7 --- /dev/null +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/Pages/EShop/Products/Products/ProductSku/CreateModal.cshtml.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using EasyAbp.EShop.Products.Categories; +using EasyAbp.EShop.Products.ProductDetails; +using EasyAbp.EShop.Products.ProductDetails.Dtos; +using EasyAbp.EShop.Products.Products; +using EasyAbp.EShop.Products.Products.Dtos; +using EasyAbp.EShop.Products.ProductTypes; +using EasyAbp.EShop.Products.Web.Pages.EShop.Products.Products.Product.ViewModels; +using EasyAbp.EShop.Products.Web.Pages.EShop.Products.Products.ProductSku.ViewModels; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Rendering; +using Newtonsoft.Json; +using Volo.Abp.Application.Dtos; + +namespace EasyAbp.EShop.Products.Web.Pages.EShop.Products.Products.ProductSku +{ + public class CreateModalModel : ProductsPageModel + { + [HiddenInput] + [BindProperty(SupportsGet = true)] + public Guid StoreId { get; set; } + + [HiddenInput] + [BindProperty(SupportsGet = true)] + public Guid ProductId { get; set; } + + [BindProperty] + public CreateEditProductSkuViewModel ProductSku { get; set; } + + [BindProperty] + public Dictionary SelectedAttributeOptionIdDict { get; set; } + + public Dictionary> Attributes { get; set; } + + private readonly IProductAppService _productAppService; + + public CreateModalModel(IProductAppService productAppService) + { + _productAppService = productAppService; + } + + public virtual async Task OnGetAsync() + { + var product = await _productAppService.GetAsync(ProductId); + + Attributes = new Dictionary>(); + + foreach (var attribute in product.ProductAttributes.ToList()) + { + Attributes.Add(attribute.DisplayName, + attribute.ProductAttributeOptions + .Select(dto => new SelectListItem(dto.DisplayName, dto.Id.ToString())).ToList()); + } + } + + public virtual async Task OnPostAsync() + { + var createDto = ObjectMapper.Map(ProductSku); + + createDto.SerializedAttributeOptionIds = JsonConvert.SerializeObject(SelectedAttributeOptionIdDict.Values); + + await _productAppService.CreateSkuAsync(ProductId, StoreId, createDto); + + return NoContent(); + } + } +} \ No newline at end of file diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/Pages/EShop/Products/Products/ProductSku/EditModal.cshtml b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/Pages/EShop/Products/Products/ProductSku/EditModal.cshtml new file mode 100644 index 00000000..288f3020 --- /dev/null +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/Pages/EShop/Products/Products/ProductSku/EditModal.cshtml @@ -0,0 +1,17 @@ +@page +@inherits EasyAbp.EShop.Products.Web.Pages.ProductsPage +@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal +@model EasyAbp.EShop.Products.Web.Pages.EShop.Products.Products.ProductSku.EditModalModel +@{ + Layout = null; +} + + + + + + + + + + \ No newline at end of file diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/Pages/EShop/Products/Products/ProductSku/EditModal.cshtml.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/Pages/EShop/Products/Products/ProductSku/EditModal.cshtml.cs new file mode 100644 index 00000000..1b79c7e7 --- /dev/null +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/Pages/EShop/Products/Products/ProductSku/EditModal.cshtml.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using EasyAbp.EShop.Products.Products; +using EasyAbp.EShop.Products.Products.Dtos; +using EasyAbp.EShop.Products.Web.Pages.EShop.Products.Products.ProductSku.ViewModels; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Rendering; + +namespace EasyAbp.EShop.Products.Web.Pages.EShop.Products.Products.ProductSku +{ + public class EditModalModel : ProductsPageModel + { + [HiddenInput] + [BindProperty(SupportsGet = true)] + public Guid Id { get; set; } + + [BindProperty(SupportsGet = true)] + public Guid StoreId { get; set; } + + [BindProperty(SupportsGet = true)] + public Guid ProductId { get; set; } + + [BindProperty(SupportsGet = true)] + public Guid ProductSkuId { get; set; } + + [BindProperty] + public CreateEditProductSkuViewModel ProductSku { get; set; } + + private readonly IProductAppService _productAppService; + + public EditModalModel(IProductAppService productAppService) + { + _productAppService = productAppService; + } + + public virtual async Task OnGetAsync() + { + var product = await _productAppService.GetAsync(ProductId); + + ProductSku = + ObjectMapper.Map( + product.ProductSkus.Single(x => x.Id == ProductSkuId)); + } + + public virtual async Task OnPostAsync() + { + await _productAppService.UpdateSkuAsync(ProductId, ProductSkuId, StoreId, + ObjectMapper.Map(ProductSku)); + + return NoContent(); + } + } +} \ No newline at end of file diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/Pages/EShop/Products/Products/ProductSku/Index.cshtml b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/Pages/EShop/Products/Products/ProductSku/Index.cshtml new file mode 100644 index 00000000..f8d4b1c5 --- /dev/null +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/Pages/EShop/Products/Products/ProductSku/Index.cshtml @@ -0,0 +1,52 @@ +@page +@using EasyAbp.EShop.Products.Web.Pages.EShop.Products.Products.ProductSku +@using Volo.Abp.AspNetCore.Mvc.UI.Layout +@inherits EasyAbp.EShop.Products.Web.Pages.ProductsPage +@model IndexModel +@inject IPageLayout PageLayout +@{ + PageLayout.Content.Title = L["ProductSku"].Value; + PageLayout.Content.BreadCrumb.Add(L["Menu:Product"].Value); + PageLayout.Content.MenuItemName = "Product"; +} + +@section scripts +{ + +} +@section styles +{ + +} + + + + + + + @L["ProductSku"] - @Model.ProductDisplayName + + + + + + + + + + + @L["Actions"] + @L["ProductSkuContentDescription"] + @L["ProductSkuPrice"] + @L["ProductSkuInventory"] + + + + + \ No newline at end of file diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/Pages/EShop/Products/Products/ProductSku/Index.cshtml.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/Pages/EShop/Products/Products/ProductSku/Index.cshtml.cs new file mode 100644 index 00000000..da070df5 --- /dev/null +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/Pages/EShop/Products/Products/ProductSku/Index.cshtml.cs @@ -0,0 +1,31 @@ +using System; +using System.Threading.Tasks; +using EasyAbp.EShop.Products.Products; +using EasyAbp.EShop.Stores.Stores; +using Microsoft.AspNetCore.Mvc; + +namespace EasyAbp.EShop.Products.Web.Pages.EShop.Products.Products.ProductSku +{ + public class IndexModel : ProductsPageModel + { + private readonly IProductAppService _productAppService; + + [BindProperty(SupportsGet = true)] + public Guid StoreId { get; set; } + + [BindProperty(SupportsGet = true)] + public Guid ProductId { get; set; } + + public string ProductDisplayName { get; set; } + + public IndexModel(IProductAppService productAppService) + { + _productAppService = productAppService; + } + + public virtual async Task OnGetAsync() + { + ProductDisplayName = (await _productAppService.GetAsync(ProductId)).DisplayName; + } + } +} diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/Pages/EShop/Products/Products/ProductSku/ViewModels/CreateEditProductSkuViewModel.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/Pages/EShop/Products/Products/ProductSku/ViewModels/CreateEditProductSkuViewModel.cs new file mode 100644 index 00000000..da2d3e21 --- /dev/null +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/Pages/EShop/Products/Products/ProductSku/ViewModels/CreateEditProductSkuViewModel.cs @@ -0,0 +1,32 @@ +using System; +using System.ComponentModel.DataAnnotations; +using Microsoft.AspNetCore.Mvc; + +namespace EasyAbp.EShop.Products.Web.Pages.EShop.Products.Products.ProductSku.ViewModels +{ + public class CreateEditProductSkuViewModel + { + [Required] + [Display(Name = "ProductSkuCurrency")] + public string Currency { get; set; } + + [Required] + [Display(Name = "ProductSkuPrice")] + public decimal Price { get; set; } + + [Display(Name = "ProductSkuOriginalPrice")] + public decimal OriginalPrice { get; set; } + + [Required] + [Display(Name = "ProductSkuInventory")] + public int Inventory { get; set; } + + [Required] + [Display(Name = "ProductSkuOrderMinQuantity")] + public int OrderMinQuantity { get; set; } + + [HiddenInput] + [Display(Name = "ProductSkuProductDetailId")] + public Guid? ProductDetailId { get; set; } + } +} \ No newline at end of file diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/Pages/EShop/Products/Products/ProductSku/index.css b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/Pages/EShop/Products/Products/ProductSku/index.css new file mode 100644 index 00000000..e69de29b diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/Pages/EShop/Products/Products/ProductSku/index.js b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/Pages/EShop/Products/Products/ProductSku/index.js new file mode 100644 index 00000000..0da3a7f9 --- /dev/null +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/Pages/EShop/Products/Products/ProductSku/index.js @@ -0,0 +1,92 @@ +$(function () { + + var l = abp.localization.getResource('Products'); + + var service = easyAbp.eShop.products.products.product; + var createModal = new abp.ModalManager(abp.appPath + 'EShop/Products/Products/ProductSku/CreateModal'); + var editModal = new abp.ModalManager(abp.appPath + 'EShop/Products/Products/ProductSku/EditModal'); + + var dataTable = $('#ProductSkuTable').DataTable(abp.libs.datatables.normalizeConfiguration({ + processing: true, + autoWidth: false, + scrollCollapse: true, + order: [[1, "asc"]], + ajax: function (requestData, callback, settings) { + if (callback) { + service.get(productId).then(function (result) { + callback({ + recordsTotal: result.productSkus.length, + recordsFiltered: result.productSkus.length, + data: fillProductSkusContentDescription(result).productSkus + }); + }); + } + }, + columnDefs: [ + { + rowAction: { + items: + [ + { + text: l('Edit'), + action: function (data) { + editModal.open({ productId: productId, productSkuId: data.record.id, storeId: storeId }); + } + }, + { + text: l('Delete'), + confirmMessage: function (data) { + return l('ProductDeletionConfirmationMessage', data.record.id); + }, + action: function (data) { + service.deleteSku(productId, data.record.id, storeId) + .then(function () { + abp.notify.info(l('SuccessfullyDeleted')); + dataTable.ajax.reload(); + }); + } + } + ] + } + }, + { data: "contentDescription" }, + { data: "price" }, + { data: "inventory" }, + ] + })); + + createModal.onResult(function () { + dataTable.ajax.reload(); + }); + + editModal.onResult(function () { + dataTable.ajax.reload(); + }); + + $('#NewProductSkuButton').click(function (e) { + e.preventDefault(); + createModal.open({ storeId: storeId, productId: productId }); + }); + + function fillProductSkusContentDescription(product) { + let attributeOptionNames = []; + for (let i in product.productAttributes) { + let attribute = product.productAttributes[i]; + for (let j in attribute.productAttributeOptions) { + let option = attribute.productAttributeOptions[j]; + attributeOptionNames[option.id] = option.displayName; + } + } + for (let i in product.productSkus) { + let sku = product.productSkus[i]; + let options = []; + let attributeOptionIds = JSON.parse(sku.serializedAttributeOptionIds); + for (let j in attributeOptionIds) { + let optionId = attributeOptionIds[j]; + options.push(attributeOptionNames[optionId]); + } + sku.contentDescription = options.join(','); + } + return product; + } +}); \ No newline at end of file diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/ProductsWebAutoMapperProfile.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/ProductsWebAutoMapperProfile.cs index 1af554db..389f8af0 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/ProductsWebAutoMapperProfile.cs +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/ProductsWebAutoMapperProfile.cs @@ -7,6 +7,7 @@ using EasyAbp.EShop.Products.ProductTypes.Dtos; using AutoMapper; using EasyAbp.EShop.Products.ProductDetails.Dtos; using EasyAbp.EShop.Products.Web.Pages.EShop.Products.Products.Product.ViewModels; +using EasyAbp.EShop.Products.Web.Pages.EShop.Products.Products.ProductSku.ViewModels; using Volo.Abp.AutoMapper; namespace EasyAbp.EShop.Products.Web @@ -50,6 +51,11 @@ namespace EasyAbp.EShop.Products.Web CreateMap(); CreateMap(); CreateMap(); + CreateMap() + .Ignore(dto => dto.SerializedAttributeOptionIds); + CreateMap(); + CreateMap() + .ForSourceMember(dto => dto.SerializedAttributeOptionIds, opt => opt.DoNotValidate()); CreateMap(); CreateMap(); CreateMap();