Commit 9f524666 authored by gdlcf88's avatar gdlcf88

Completed product management (except SKU management)

parent b8f69bae
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
namespace EasyAbp.EShop.Products.Products.Dtos
{
public class CreateUpdateProductAttributeDto
{
[Required]
[DisplayName("ProductAttributeDisplayName")]
public string DisplayName { get; set; }
[DisplayName("ProductAttributeDescription")]
public string Description { get; set; }
[DisplayName("ProductAttributeDisplayOrder")]
public int DisplayOrder { get; set; }
public ICollection<CreateUpdateProductAttributeOptionDto> ProductAttributeOptions { get; set; }
}
}
\ No newline at end of file
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
namespace EasyAbp.EShop.Products.Products.Dtos
{
public class CreateUpdateProductAttributeOptionDto
{
[Required]
[DisplayName("ProductAttributeOptionDisplayName")]
public string DisplayName { get; set; }
[DisplayName("ProductAttributeOptionDescription")]
public string Description { get; set; }
[DisplayName("ProductAttributeOptionDisplayOrder")]
public int DisplayOrder { get; set; }
}
}
\ No newline at end of file
...@@ -2,10 +2,11 @@ using System; ...@@ -2,10 +2,11 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.Linq;
namespace EasyAbp.EShop.Products.Products.Dtos namespace EasyAbp.EShop.Products.Products.Dtos
{ {
public class CreateUpdateProductDto public class CreateUpdateProductDto : IValidatableObject
{ {
[DisplayName("ProductStoreId")] [DisplayName("ProductStoreId")]
public Guid? StoreId { get; set; } public Guid? StoreId { get; set; }
...@@ -15,7 +16,7 @@ namespace EasyAbp.EShop.Products.Products.Dtos ...@@ -15,7 +16,7 @@ namespace EasyAbp.EShop.Products.Products.Dtos
public Guid ProductTypeId { get; set; } public Guid ProductTypeId { get; set; }
[DisplayName("ProductCategory")] [DisplayName("ProductCategory")]
public IEnumerable<Guid> CategoryIds { get; set; } public ICollection<Guid> CategoryIds { get; set; }
[Required] [Required]
[DisplayName("ProductDisplayName")] [DisplayName("ProductDisplayName")]
...@@ -23,13 +24,40 @@ namespace EasyAbp.EShop.Products.Products.Dtos ...@@ -23,13 +24,40 @@ namespace EasyAbp.EShop.Products.Products.Dtos
public CreateUpdateProductDetailDto ProductDetail { get; set; } public CreateUpdateProductDetailDto ProductDetail { get; set; }
public ICollection<CreateUpdateProductAttributeDto> ProductAttributes { get; set; }
[DisplayName("ProductInventoryStrategy")] [DisplayName("ProductInventoryStrategy")]
public InventoryStrategy InventoryStrategy { get; set; } public InventoryStrategy InventoryStrategy { get; set; }
[DisplayName("ProductDisplayOrder")]
public int DisplayOrder { get; set; }
[DisplayName("ProductMediaResources")] [DisplayName("ProductMediaResources")]
public string MediaResources { get; set; } public string MediaResources { get; set; }
[DisplayName("ProductIsPublished")] [DisplayName("ProductIsPublished")]
public bool IsPublished { get; set; } public bool IsPublished { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (ProductAttributes.Select(a => a.DisplayName.Trim()).Distinct().Count() != ProductAttributes.Count)
{
yield return new ValidationResult(
"DisplayNames of ProductAttributes should be unique!",
new[] { "ProductAttributes" }
);
}
var optionNameList = ProductAttributes.SelectMany(a => a.ProductAttributeOptions)
.Select(o => o.DisplayName.Trim()).ToList();
if (optionNameList.Distinct().Count() != optionNameList.Count)
{
yield return new ValidationResult(
"DisplayNames of ProductAttributeOptions should be unique!",
new[] { "ProductAttributeOptions" }
);
}
}
} }
} }
\ No newline at end of file
...@@ -12,6 +12,8 @@ namespace EasyAbp.EShop.Products.Products.Dtos ...@@ -12,6 +12,8 @@ namespace EasyAbp.EShop.Products.Products.Dtos
public string Description { get; set; } public string Description { get; set; }
public IEnumerable<ProductAttributeOptionDto> ProductAttributeOptions { get; set; } public int DisplayOrder { get; set; }
public ICollection<ProductAttributeOptionDto> ProductAttributeOptions { get; set; }
} }
} }
\ No newline at end of file
...@@ -10,5 +10,7 @@ namespace EasyAbp.EShop.Products.Products.Dtos ...@@ -10,5 +10,7 @@ namespace EasyAbp.EShop.Products.Products.Dtos
public string DisplayName { get; set; } public string DisplayName { get; set; }
public string Description { get; set; } public string Description { get; set; }
public int DisplayOrder { get; set; }
} }
} }
\ No newline at end of file
...@@ -10,7 +10,7 @@ namespace EasyAbp.EShop.Products.Products.Dtos ...@@ -10,7 +10,7 @@ namespace EasyAbp.EShop.Products.Products.Dtos
public Guid ProductTypeId { get; set; } public Guid ProductTypeId { get; set; }
public IEnumerable<Guid> CategoryIds { get; set; } public ICollection<Guid> CategoryIds { get; set; }
public string DisplayName { get; set; } public string DisplayName { get; set; }
...@@ -18,12 +18,14 @@ namespace EasyAbp.EShop.Products.Products.Dtos ...@@ -18,12 +18,14 @@ namespace EasyAbp.EShop.Products.Products.Dtos
public string MediaResources { get; set; } public string MediaResources { get; set; }
public int DisplayOrder { get; set; }
public bool IsPublished { get; set; } public bool IsPublished { get; set; }
public ProductDetailDto ProductDetail { get; set; } public ProductDetailDto ProductDetail { get; set; }
public IEnumerable<ProductAttributeDto> ProductAttributes { get; set; } public ICollection<ProductAttributeDto> ProductAttributes { get; set; }
public IEnumerable<ProductSkuDto> ProductSkus { get; set; } public ICollection<ProductSkuDto> ProductSkus { get; set; }
} }
} }
\ No newline at end of file
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using EasyAbp.EShop.Products.Authorization; using EasyAbp.EShop.Products.Authorization;
...@@ -54,13 +55,101 @@ namespace EasyAbp.EShop.Products.Products ...@@ -54,13 +55,101 @@ namespace EasyAbp.EShop.Products.Products
{ {
await CheckCreatePolicyAsync(); await CheckCreatePolicyAsync();
var entity = MapToEntity(input); var product = MapToEntity(input);
TryToSetTenantId(entity); TryToSetTenantId(product);
await Repository.InsertAsync(entity, autoSave: true); await UpdateProductAttributesAsync(product, input);
return MapToGetOutputDto(entity); await Repository.InsertAsync(product, autoSave: true);
await UpdateProductCategoriesAsync(product.Id, product.StoreId, input.CategoryIds);
return MapToGetOutputDto(product);
}
public override async Task<ProductDto> UpdateAsync(Guid id, CreateUpdateProductDto input)
{
await CheckUpdatePolicyAsync();
var product = await GetEntityByIdAsync(id);
MapToEntity(input, product);
await UpdateProductAttributesAsync(product, input);
await Repository.UpdateAsync(product, autoSave: true);
await UpdateProductCategoriesAsync(product.Id, product.StoreId, input.CategoryIds);
return MapToGetOutputDto(product);
}
private async Task UpdateProductAttributesAsync(Product product, CreateUpdateProductDto input)
{
foreach (var attributeDto in input.ProductAttributes)
{
var attribute = product.ProductAttributes.FirstOrDefault(a => a.DisplayName == attributeDto.DisplayName);
if (attribute == null)
{
attribute = new ProductAttribute(GuidGenerator.Create(),
attributeDto.DisplayName, attributeDto.Description);
product.ProductAttributes.Add(attribute);
}
foreach (var optionDto in attributeDto.ProductAttributeOptions)
{
var option = attribute.ProductAttributeOptions.FirstOrDefault(o => o.DisplayName == optionDto.DisplayName);
if (option == null)
{
option = new ProductAttributeOption(GuidGenerator.Create(),
optionDto.DisplayName, optionDto.Description);
attribute.ProductAttributeOptions.Add(option);
}
}
var exceptOptionNames = attribute.ProductAttributeOptions.Select(o => o.DisplayName)
.Except(attributeDto.ProductAttributeOptions.Select(o => o.DisplayName));
attribute.ProductAttributeOptions.RemoveAll(o => exceptOptionNames.Contains(o.DisplayName));
}
var exceptAttributeNames = product.ProductAttributes.Select(a => a.DisplayName)
.Except(input.ProductAttributes.Select(a => a.DisplayName));
product.ProductAttributes.RemoveAll(a => exceptAttributeNames.Contains(a.DisplayName));
}
public override async Task DeleteAsync(Guid id)
{
await _productCategoryRepository.DeleteAsync(x => x.ProductId.Equals(id));
await base.DeleteAsync(id);
}
public override async Task<ProductDto> GetAsync(Guid id)
{
var dto = await base.GetAsync(id);
dto.CategoryIds = (await _productCategoryRepository.GetListByProductId(dto.Id, dto.StoreId))
.Select(x => x.CategoryId).ToList();
return dto;
}
protected virtual async Task UpdateProductCategoriesAsync(Guid productId, Guid? storeId, IEnumerable<Guid> categoryIds)
{
await _productCategoryRepository.DeleteAsync(x => x.ProductId.Equals(productId));
foreach (var categoryId in categoryIds)
{
await _productCategoryRepository.InsertAsync(new ProductCategory(GuidGenerator.Create(),
CurrentTenant.Id, storeId, categoryId, productId));
}
} }
} }
} }
\ No newline at end of file
...@@ -26,10 +26,11 @@ namespace EasyAbp.EShop.Products ...@@ -26,10 +26,11 @@ namespace EasyAbp.EShop.Products
CreateMap<ProductSku, ProductSkuDto>(); CreateMap<ProductSku, ProductSkuDto>();
CreateMap<CreateUpdateProductDto, Product>(MemberList.Source) CreateMap<CreateUpdateProductDto, Product>(MemberList.Source)
.ForSourceMember(dto => dto.CategoryIds, opt => opt.DoNotValidate()) .ForSourceMember(dto => dto.CategoryIds, opt => opt.DoNotValidate())
.Ignore(p => p.ProductDetail)
.Ignore(p => p.ProductAttributes) .Ignore(p => p.ProductAttributes)
.Ignore(p => p.ProductSkus); .Ignore(p => p.ProductSkus);
CreateMap<CreateUpdateProductDetailDto, ProductDetail>(MemberList.Source); CreateMap<CreateUpdateProductDetailDto, ProductDetail>(MemberList.Source);
CreateMap<CreateUpdateProductAttributeDto, ProductAttribute>(MemberList.Source);
CreateMap<CreateUpdateProductAttributeOptionDto, ProductAttributeOption>(MemberList.Source);
CreateMap<Category, CategoryDto>(); CreateMap<Category, CategoryDto>();
CreateMap<CreateUpdateCategoryDto, Category>(MemberList.Source); CreateMap<CreateUpdateCategoryDto, Category>(MemberList.Source);
CreateMap<ProductType, ProductTypeDto>(); CreateMap<ProductType, ProductTypeDto>();
......
...@@ -3,14 +3,23 @@ ...@@ -3,14 +3,23 @@
"texts": { "texts": {
"Menu:Product": "MenuProduct", "Menu:Product": "MenuProduct",
"Product": "Product", "Product": "Product",
"ProductTenantId": "ProductTenantId", "ProductStore": "ProductStore",
"ProductStoreId": "ProductStoreId",
"ProductProductTypeId": "ProductProductTypeId",
"ProductDisplayName": "ProductDisplayName", "ProductDisplayName": "ProductDisplayName",
"ProductDetailDescription": "ProductDetailDescription", "ProductDetailDescription": "ProductDetailDescription",
"ProductDetailDisplayOrder": "ProductDetailDisplayOrder",
"ProductAttributeNames": "ProductAttributeNames",
"ProductAttributeNamesPlaceholder": "ProductAttributeNamesPlaceholder",
"ProductAttributeOptionNames": "ProductAttributeOptionNames",
"ProductAttributeOptionNamesPlaceholder": "ProductAttributeOptionNamesPlaceholder",
"ProductInventoryStrategy": "ProductInventoryStrategy", "ProductInventoryStrategy": "ProductInventoryStrategy",
"ProductIsPublished": "ProductIsPublished", "ProductIsPublished": "ProductIsPublished",
"ProductMediaResources": "ProductMediaResources", "ProductMediaResources": "ProductMediaResources",
"ProductAttributeDisplayName": "ProductAttributeDisplayName",
"ProductAttributeDescription": "ProductAttributeDescription",
"ProductAttributeDisplayOrder": "ProductAttributeDisplayOrder",
"ProductAttributeOptionDisplayName": "ProductAttributeOptionDisplayName",
"ProductAttributeOptionDescription": "ProductAttributeOptionDescription",
"ProductAttributeOptionDisplayOrder": "ProductAttributeOptionDisplayOrder",
"CreateProduct": "CreateProduct", "CreateProduct": "CreateProduct",
"EditProduct": "EditProduct", "EditProduct": "EditProduct",
"ProductDeletionConfirmationMessage": "Are you sure to delete the product {0}?", "ProductDeletionConfirmationMessage": "Are you sure to delete the product {0}?",
......
...@@ -4,14 +4,23 @@ ...@@ -4,14 +4,23 @@
"ManageYourProfile": "Manage your profile", "ManageYourProfile": "Manage your profile",
"Menu:Product": "MenuProduct", "Menu:Product": "MenuProduct",
"Product": "Product", "Product": "Product",
"ProductTenantId": "ProductTenantId", "ProductStore": "ProductStore",
"ProductStoreId": "ProductStoreId",
"ProductProductTypeId": "ProductProductTypeId",
"ProductDisplayName": "ProductDisplayName", "ProductDisplayName": "ProductDisplayName",
"ProductDetailDescription": "ProductDetailDescription", "ProductDetailDescription": "ProductDetailDescription",
"ProductDetailDisplayOrder": "ProductDetailDisplayOrder",
"ProductAttributeNames": "ProductAttributeNames",
"ProductAttributeNamesPlaceholder": "ProductAttributeNamesPlaceholder",
"ProductAttributeOptionNames": "ProductAttributeOptionNames",
"ProductAttributeOptionNamesPlaceholder": "ProductAttributeOptionNamesPlaceholder",
"ProductInventoryStrategy": "ProductInventoryStrategy", "ProductInventoryStrategy": "ProductInventoryStrategy",
"ProductIsPublished": "ProductIsPublished", "ProductIsPublished": "ProductIsPublished",
"ProductMediaResources": "ProductMediaResources", "ProductMediaResources": "ProductMediaResources",
"ProductAttributeDisplayName": "ProductAttributeDisplayName",
"ProductAttributeDescription": "ProductAttributeDescription",
"ProductAttributeDisplayOrder": "ProductAttributeDisplayOrder",
"ProductAttributeOptionDisplayName": "ProductAttributeOptionDisplayName",
"ProductAttributeOptionDescription": "ProductAttributeOptionDescription",
"ProductAttributeOptionDisplayOrder": "ProductAttributeOptionDisplayOrder",
"CreateProduct": "CreateProduct", "CreateProduct": "CreateProduct",
"EditProduct": "EditProduct", "EditProduct": "EditProduct",
"ProductDeletionConfirmationMessage": "Are you sure to delete the product {0}?", "ProductDeletionConfirmationMessage": "Are you sure to delete the product {0}?",
......
...@@ -3,14 +3,23 @@ ...@@ -3,14 +3,23 @@
"texts": { "texts": {
"Menu:Product": "MenuProduct", "Menu:Product": "MenuProduct",
"Product": "Product", "Product": "Product",
"ProductTenantId": "ProductTenantId", "ProductStore": "ProductStore",
"ProductStoreId": "ProductStoreId",
"ProductProductTypeId": "ProductProductTypeId",
"ProductDisplayName": "ProductDisplayName", "ProductDisplayName": "ProductDisplayName",
"ProductDetailDescription": "ProductDetailDescription", "ProductDetailDescription": "ProductDetailDescription",
"ProductDetailDisplayOrder": "ProductDetailDisplayOrder",
"ProductAttributeNames": "ProductAttributeNames",
"ProductAttributeNamesPlaceholder": "ProductAttributeNamesPlaceholder",
"ProductAttributeOptionNames": "ProductAttributeOptionNames",
"ProductAttributeOptionNamesPlaceholder": "ProductAttributeOptionNamesPlaceholder",
"ProductInventoryStrategy": "ProductInventoryStrategy", "ProductInventoryStrategy": "ProductInventoryStrategy",
"ProductIsPublished": "ProductIsPublished", "ProductIsPublished": "ProductIsPublished",
"ProductMediaResources": "ProductMediaResources", "ProductMediaResources": "ProductMediaResources",
"ProductAttributeDisplayName": "ProductAttributeDisplayName",
"ProductAttributeDescription": "ProductAttributeDescription",
"ProductAttributeDisplayOrder": "ProductAttributeDisplayOrder",
"ProductAttributeOptionDisplayName": "ProductAttributeOptionDisplayName",
"ProductAttributeOptionDescription": "ProductAttributeOptionDescription",
"ProductAttributeOptionDisplayOrder": "ProductAttributeOptionDisplayOrder",
"CreateProduct": "CreateProduct", "CreateProduct": "CreateProduct",
"EditProduct": "EditProduct", "EditProduct": "EditProduct",
"ProductDeletionConfirmationMessage": "Are you sure to delete the product {0}?", "ProductDeletionConfirmationMessage": "Are you sure to delete the product {0}?",
......
...@@ -3,14 +3,23 @@ ...@@ -3,14 +3,23 @@
"texts": { "texts": {
"Menu:Product": "MenuProduct", "Menu:Product": "MenuProduct",
"Product": "Product", "Product": "Product",
"ProductTenantId": "ProductTenantId", "ProductStore": "ProductStore",
"ProductStoreId": "ProductStoreId",
"ProductProductTypeId": "ProductProductTypeId",
"ProductDisplayName": "ProductDisplayName", "ProductDisplayName": "ProductDisplayName",
"ProductDetailDescription": "ProductDetailDescription", "ProductDetailDescription": "ProductDetailDescription",
"ProductDetailDisplayOrder": "ProductDetailDisplayOrder",
"ProductAttributeNames": "ProductAttributeNames",
"ProductAttributeNamesPlaceholder": "ProductAttributeNamesPlaceholder",
"ProductAttributeOptionNames": "ProductAttributeOptionNames",
"ProductAttributeOptionNamesPlaceholder": "ProductAttributeOptionNamesPlaceholder",
"ProductInventoryStrategy": "ProductInventoryStrategy", "ProductInventoryStrategy": "ProductInventoryStrategy",
"ProductIsPublished": "ProductIsPublished", "ProductIsPublished": "ProductIsPublished",
"ProductMediaResources": "ProductMediaResources", "ProductMediaResources": "ProductMediaResources",
"ProductAttributeDisplayName": "ProductAttributeDisplayName",
"ProductAttributeDescription": "ProductAttributeDescription",
"ProductAttributeDisplayOrder": "ProductAttributeDisplayOrder",
"ProductAttributeOptionDisplayName": "ProductAttributeOptionDisplayName",
"ProductAttributeOptionDescription": "ProductAttributeOptionDescription",
"ProductAttributeOptionDisplayOrder": "ProductAttributeOptionDisplayOrder",
"CreateProduct": "CreateProduct", "CreateProduct": "CreateProduct",
"EditProduct": "EditProduct", "EditProduct": "EditProduct",
"ProductDeletionConfirmationMessage": "Are you sure to delete the product {0}?", "ProductDeletionConfirmationMessage": "Are you sure to delete the product {0}?",
......
...@@ -4,14 +4,23 @@ ...@@ -4,14 +4,23 @@
"ManageYourProfile": "Upravljajte svojim profilom", "ManageYourProfile": "Upravljajte svojim profilom",
"Menu:Product": "MenuProduct", "Menu:Product": "MenuProduct",
"Product": "Product", "Product": "Product",
"ProductTenantId": "ProductTenantId", "ProductStore": "ProductStore",
"ProductStoreId": "ProductStoreId",
"ProductProductTypeId": "ProductProductTypeId",
"ProductDisplayName": "ProductDisplayName", "ProductDisplayName": "ProductDisplayName",
"ProductDetailDescription": "ProductDetailDescription", "ProductDetailDescription": "ProductDetailDescription",
"ProductDetailDisplayOrder": "ProductDetailDisplayOrder",
"ProductAttributeNames": "ProductAttributeNames",
"ProductAttributeNamesPlaceholder": "ProductAttributeNamesPlaceholder",
"ProductAttributeOptionNames": "ProductAttributeOptionNames",
"ProductAttributeOptionNamesPlaceholder": "ProductAttributeOptionNamesPlaceholder",
"ProductInventoryStrategy": "ProductInventoryStrategy", "ProductInventoryStrategy": "ProductInventoryStrategy",
"ProductIsPublished": "ProductIsPublished", "ProductIsPublished": "ProductIsPublished",
"ProductMediaResources": "ProductMediaResources", "ProductMediaResources": "ProductMediaResources",
"ProductAttributeDisplayName": "ProductAttributeDisplayName",
"ProductAttributeDescription": "ProductAttributeDescription",
"ProductAttributeDisplayOrder": "ProductAttributeDisplayOrder",
"ProductAttributeOptionDisplayName": "ProductAttributeOptionDisplayName",
"ProductAttributeOptionDescription": "ProductAttributeOptionDescription",
"ProductAttributeOptionDisplayOrder": "ProductAttributeOptionDisplayOrder",
"CreateProduct": "CreateProduct", "CreateProduct": "CreateProduct",
"EditProduct": "EditProduct", "EditProduct": "EditProduct",
"ProductDeletionConfirmationMessage": "Are you sure to delete the product {0}?", "ProductDeletionConfirmationMessage": "Are you sure to delete the product {0}?",
......
...@@ -4,14 +4,23 @@ ...@@ -4,14 +4,23 @@
"ManageYourProfile": "Profil y�netimi", "ManageYourProfile": "Profil y�netimi",
"Menu:Product": "MenuProduct", "Menu:Product": "MenuProduct",
"Product": "Product", "Product": "Product",
"ProductTenantId": "ProductTenantId", "ProductStore": "ProductStore",
"ProductStoreId": "ProductStoreId",
"ProductProductTypeId": "ProductProductTypeId",
"ProductDisplayName": "ProductDisplayName", "ProductDisplayName": "ProductDisplayName",
"ProductDetailDescription": "ProductDetailDescription", "ProductDetailDescription": "ProductDetailDescription",
"ProductDetailDisplayOrder": "ProductDetailDisplayOrder",
"ProductAttributeNames": "ProductAttributeNames",
"ProductAttributeNamesPlaceholder": "ProductAttributeNamesPlaceholder",
"ProductAttributeOptionNames": "ProductAttributeOptionNames",
"ProductAttributeOptionNamesPlaceholder": "ProductAttributeOptionNamesPlaceholder",
"ProductInventoryStrategy": "ProductInventoryStrategy", "ProductInventoryStrategy": "ProductInventoryStrategy",
"ProductIsPublished": "ProductIsPublished", "ProductIsPublished": "ProductIsPublished",
"ProductMediaResources": "ProductMediaResources", "ProductMediaResources": "ProductMediaResources",
"ProductAttributeDisplayName": "ProductAttributeDisplayName",
"ProductAttributeDescription": "ProductAttributeDescription",
"ProductAttributeDisplayOrder": "ProductAttributeDisplayOrder",
"ProductAttributeOptionDisplayName": "ProductAttributeOptionDisplayName",
"ProductAttributeOptionDescription": "ProductAttributeOptionDescription",
"ProductAttributeOptionDisplayOrder": "ProductAttributeOptionDisplayOrder",
"CreateProduct": "CreateProduct", "CreateProduct": "CreateProduct",
"EditProduct": "EditProduct", "EditProduct": "EditProduct",
"ProductDeletionConfirmationMessage": "Are you sure to delete the product {0}?", "ProductDeletionConfirmationMessage": "Are you sure to delete the product {0}?",
......
...@@ -3,14 +3,23 @@ ...@@ -3,14 +3,23 @@
"texts": { "texts": {
"Menu:Product": "MenuProduct", "Menu:Product": "MenuProduct",
"Product": "Product", "Product": "Product",
"ProductTenantId": "ProductTenantId", "ProductStore": "ProductStore",
"ProductStoreId": "ProductStoreId",
"ProductProductTypeId": "ProductProductTypeId",
"ProductDisplayName": "ProductDisplayName", "ProductDisplayName": "ProductDisplayName",
"ProductDetailDescription": "ProductDetailDescription", "ProductDetailDescription": "ProductDetailDescription",
"ProductDetailDisplayOrder": "ProductDetailDisplayOrder",
"ProductAttributeNames": "ProductAttributeNames",
"ProductAttributeNamesPlaceholder": "ProductAttributeNamesPlaceholder",
"ProductAttributeOptionNames": "ProductAttributeOptionNames",
"ProductAttributeOptionNamesPlaceholder": "ProductAttributeOptionNamesPlaceholder",
"ProductInventoryStrategy": "ProductInventoryStrategy", "ProductInventoryStrategy": "ProductInventoryStrategy",
"ProductIsPublished": "ProductIsPublished", "ProductIsPublished": "ProductIsPublished",
"ProductMediaResources": "ProductMediaResources", "ProductMediaResources": "ProductMediaResources",
"ProductAttributeDisplayName": "ProductAttributeDisplayName",
"ProductAttributeDescription": "ProductAttributeDescription",
"ProductAttributeDisplayOrder": "ProductAttributeDisplayOrder",
"ProductAttributeOptionDisplayName": "ProductAttributeOptionDisplayName",
"ProductAttributeOptionDescription": "ProductAttributeOptionDescription",
"ProductAttributeOptionDisplayOrder": "ProductAttributeOptionDisplayOrder",
"CreateProduct": "CreateProduct", "CreateProduct": "CreateProduct",
"EditProduct": "EditProduct", "EditProduct": "EditProduct",
"ProductDeletionConfirmationMessage": "Are you sure to delete the product {0}?", "ProductDeletionConfirmationMessage": "Are you sure to delete the product {0}?",
......
...@@ -4,14 +4,23 @@ ...@@ -4,14 +4,23 @@
"ManageYourProfile": "管理个人资料", "ManageYourProfile": "管理个人资料",
"Menu:Product": "MenuProduct", "Menu:Product": "MenuProduct",
"Product": "Product", "Product": "Product",
"ProductTenantId": "ProductTenantId", "ProductStore": "ProductStore",
"ProductStoreId": "ProductStoreId",
"ProductProductTypeId": "ProductProductTypeId",
"ProductDisplayName": "ProductDisplayName", "ProductDisplayName": "ProductDisplayName",
"ProductDetailDescription": "ProductDetailDescription", "ProductDetailDescription": "ProductDetailDescription",
"ProductDetailDisplayOrder": "ProductDetailDisplayOrder",
"ProductAttributeNames": "ProductAttributeNames",
"ProductAttributeNamesPlaceholder": "ProductAttributeNamesPlaceholder",
"ProductAttributeOptionNames": "ProductAttributeOptionNames",
"ProductAttributeOptionNamesPlaceholder": "ProductAttributeOptionNamesPlaceholder",
"ProductInventoryStrategy": "ProductInventoryStrategy", "ProductInventoryStrategy": "ProductInventoryStrategy",
"ProductIsPublished": "ProductIsPublished", "ProductIsPublished": "ProductIsPublished",
"ProductMediaResources": "ProductMediaResources", "ProductMediaResources": "ProductMediaResources",
"ProductAttributeDisplayName": "ProductAttributeDisplayName",
"ProductAttributeDescription": "ProductAttributeDescription",
"ProductAttributeDisplayOrder": "ProductAttributeDisplayOrder",
"ProductAttributeOptionDisplayName": "ProductAttributeOptionDisplayName",
"ProductAttributeOptionDescription": "ProductAttributeOptionDescription",
"ProductAttributeOptionDisplayOrder": "ProductAttributeOptionDisplayOrder",
"CreateProduct": "CreateProduct", "CreateProduct": "CreateProduct",
"EditProduct": "EditProduct", "EditProduct": "EditProduct",
"ProductDeletionConfirmationMessage": "Are you sure to delete the product {0}?", "ProductDeletionConfirmationMessage": "Are you sure to delete the product {0}?",
......
...@@ -4,14 +4,23 @@ ...@@ -4,14 +4,23 @@
"ManageYourProfile": "管理個人資料", "ManageYourProfile": "管理個人資料",
"Menu:Product": "MenuProduct", "Menu:Product": "MenuProduct",
"Product": "Product", "Product": "Product",
"ProductTenantId": "ProductTenantId", "ProductStore": "ProductStore",
"ProductStoreId": "ProductStoreId",
"ProductProductTypeId": "ProductProductTypeId",
"ProductDisplayName": "ProductDisplayName", "ProductDisplayName": "ProductDisplayName",
"ProductDetailDescription": "ProductDetailDescription", "ProductDetailDescription": "ProductDetailDescription",
"ProductDetailDisplayOrder": "ProductDetailDisplayOrder",
"ProductAttributeNames": "ProductAttributeNames",
"ProductAttributeNamesPlaceholder": "ProductAttributeNamesPlaceholder",
"ProductAttributeOptionNames": "ProductAttributeOptionNames",
"ProductAttributeOptionNamesPlaceholder": "ProductAttributeOptionNamesPlaceholder",
"ProductInventoryStrategy": "ProductInventoryStrategy", "ProductInventoryStrategy": "ProductInventoryStrategy",
"ProductIsPublished": "ProductIsPublished", "ProductIsPublished": "ProductIsPublished",
"ProductMediaResources": "ProductMediaResources", "ProductMediaResources": "ProductMediaResources",
"ProductAttributeDisplayName": "ProductAttributeDisplayName",
"ProductAttributeDescription": "ProductAttributeDescription",
"ProductAttributeDisplayOrder": "ProductAttributeDisplayOrder",
"ProductAttributeOptionDisplayName": "ProductAttributeOptionDisplayName",
"ProductAttributeOptionDescription": "ProductAttributeOptionDescription",
"ProductAttributeOptionDisplayOrder": "ProductAttributeOptionDisplayOrder",
"CreateProduct": "CreateProduct", "CreateProduct": "CreateProduct",
"EditProduct": "EditProduct", "EditProduct": "EditProduct",
"ProductDeletionConfirmationMessage": "Are you sure to delete the product {0}?", "ProductDeletionConfirmationMessage": "Are you sure to delete the product {0}?",
......
...@@ -8,8 +8,8 @@ namespace EasyAbp.EShop.Products.ProductCategories ...@@ -8,8 +8,8 @@ namespace EasyAbp.EShop.Products.ProductCategories
{ {
public interface IProductCategoryRepository : IRepository<ProductCategory, Guid> public interface IProductCategoryRepository : IRepository<ProductCategory, Guid>
{ {
Task<IEnumerable<ProductCategory>> GetListByCategoryId(Guid categoryId, Guid? storeId, CancellationToken cancellationToken = default); Task<List<ProductCategory>> GetListByCategoryId(Guid categoryId, Guid? storeId, CancellationToken cancellationToken = default);
Task<IEnumerable<ProductCategory>> GetListByProductId(Guid productId, Guid? storeId, CancellationToken cancellationToken = default); Task<List<ProductCategory>> GetListByProductId(Guid productId, Guid? storeId, CancellationToken cancellationToken = default);
} }
} }
\ No newline at end of file
...@@ -27,7 +27,7 @@ namespace EasyAbp.EShop.Products.ProductCategories ...@@ -27,7 +27,7 @@ namespace EasyAbp.EShop.Products.ProductCategories
Guid? storeId, Guid? storeId,
Guid categoryId, Guid categoryId,
Guid productId, Guid productId,
int displayOrder int displayOrder = 0
) :base(id) ) :base(id)
{ {
TenantId = tenantId; TenantId = tenantId;
......
...@@ -23,16 +23,20 @@ namespace EasyAbp.EShop.Products.Products ...@@ -23,16 +23,20 @@ namespace EasyAbp.EShop.Products.Products
[CanBeNull] [CanBeNull]
public virtual string MediaResources { get; protected set; } public virtual string MediaResources { get; protected set; }
public virtual int DisplayOrder { get; protected set; }
public virtual bool IsPublished { get; protected set; } public virtual bool IsPublished { get; protected set; }
public virtual ProductDetail ProductDetail { get; protected set; } public virtual ProductDetail ProductDetail { get; protected set; }
public virtual IEnumerable<ProductAttribute> ProductAttributes { get; protected set; } public virtual ICollection<ProductAttribute> ProductAttributes { get; protected set; }
public virtual IEnumerable<ProductSku> ProductSkus { get; protected set; } public virtual ICollection<ProductSku> ProductSkus { get; protected set; }
protected Product() protected Product()
{ {
ProductAttributes = new List<ProductAttribute>();
ProductSkus = new List<ProductSku>();
} }
public Product( public Product(
...@@ -43,7 +47,8 @@ namespace EasyAbp.EShop.Products.Products ...@@ -43,7 +47,8 @@ namespace EasyAbp.EShop.Products.Products
string displayName, string displayName,
InventoryStrategy inventoryStrategy, InventoryStrategy inventoryStrategy,
bool isPublished, bool isPublished,
string mediaResources string mediaResources,
int displayOrder
) :base(id) ) :base(id)
{ {
TenantId = tenantId; TenantId = tenantId;
...@@ -53,6 +58,9 @@ namespace EasyAbp.EShop.Products.Products ...@@ -53,6 +58,9 @@ namespace EasyAbp.EShop.Products.Products
InventoryStrategy = inventoryStrategy; InventoryStrategy = inventoryStrategy;
IsPublished = isPublished; IsPublished = isPublished;
MediaResources = mediaResources; MediaResources = mediaResources;
DisplayOrder = displayOrder;
ProductAttributes = new List<ProductAttribute>();
ProductSkus = new List<ProductSku>();
} }
} }
} }
...@@ -13,6 +13,26 @@ namespace EasyAbp.EShop.Products.Products ...@@ -13,6 +13,26 @@ namespace EasyAbp.EShop.Products.Products
[CanBeNull] [CanBeNull]
public virtual string Description { get; protected set; } public virtual string Description { get; protected set; }
public virtual IEnumerable<ProductAttributeOption> ProductAttributeOptions { get; protected set; } public virtual int DisplayOrder { get; protected set; }
public virtual ICollection<ProductAttributeOption> ProductAttributeOptions { get; protected set; }
protected ProductAttribute()
{
ProductAttributeOptions = new List<ProductAttributeOption>();
}
public ProductAttribute(
Guid id,
[NotNull] string displayName,
[CanBeNull] string description,
int displayOrder = 0) : base(id)
{
DisplayName = displayName;
Description = description;
DisplayOrder = displayOrder;
ProductAttributeOptions = new List<ProductAttributeOption>();
}
} }
} }
\ No newline at end of file
...@@ -11,5 +11,20 @@ namespace EasyAbp.EShop.Products.Products ...@@ -11,5 +11,20 @@ namespace EasyAbp.EShop.Products.Products
[CanBeNull] [CanBeNull]
public virtual string Description { get; protected set; } public virtual string Description { get; protected set; }
public virtual int DisplayOrder { get; protected set; }
protected ProductAttributeOption() {}
public ProductAttributeOption(
Guid id,
[NotNull] string displayName,
[CanBeNull] string description,
int displayOrder = 0) : base(id)
{
DisplayName = displayName;
Description = description;
DisplayOrder = displayOrder;
}
} }
} }
\ No newline at end of file
using System; using System;
using JetBrains.Annotations;
using Volo.Abp.Domain.Entities.Auditing; using Volo.Abp.Domain.Entities.Auditing;
namespace EasyAbp.EShop.Products.Products namespace EasyAbp.EShop.Products.Products
{ {
public class ProductSku : FullAuditedEntity<Guid> public class ProductSku : FullAuditedEntity<Guid>
{ {
[NotNull]
public virtual string SerializedAttributeOptionIds { get; protected set; } public virtual string SerializedAttributeOptionIds { get; protected set; }
public virtual decimal OriginalPrice { get; protected set; } public virtual decimal OriginalPrice { get; protected set; }
...@@ -16,5 +18,24 @@ namespace EasyAbp.EShop.Products.Products ...@@ -16,5 +18,24 @@ namespace EasyAbp.EShop.Products.Products
public virtual int Sold { get; protected set; } public virtual int Sold { get; protected set; }
public virtual int OrderMinQuantity { get; protected set; } public virtual int OrderMinQuantity { get; protected set; }
protected ProductSku() {}
public ProductSku(
Guid id,
[NotNull] string serializedAttributeOptionIds,
decimal originalPrice,
decimal price,
int inventory,
int sold,
int orderMinQuantity) : base(id)
{
SerializedAttributeOptionIds = serializedAttributeOptionIds;
OriginalPrice = originalPrice;
Price = price;
Inventory = inventory;
Sold = sold;
OrderMinQuantity = orderMinQuantity;
}
} }
} }
\ No newline at end of file
...@@ -78,6 +78,8 @@ namespace EasyAbp.EShop.Products.EntityFrameworkCore ...@@ -78,6 +78,8 @@ namespace EasyAbp.EShop.Products.EntityFrameworkCore
b.ToTable(options.TablePrefix + "ProductSkus", options.Schema); b.ToTable(options.TablePrefix + "ProductSkus", options.Schema);
b.ConfigureByConvention(); b.ConfigureByConvention();
/* Configure more properties here */ /* Configure more properties here */
b.Property(x => x.Price).HasColumnType("decimal(18,6)");
b.Property(x => x.OriginalPrice).HasColumnType("decimal(18,6)");
}); });
builder.Entity<Category>(b => builder.Entity<Category>(b =>
......
...@@ -16,14 +16,14 @@ namespace EasyAbp.EShop.Products.ProductCategories ...@@ -16,14 +16,14 @@ namespace EasyAbp.EShop.Products.ProductCategories
{ {
} }
public async Task<IEnumerable<ProductCategory>> GetListByCategoryId(Guid categoryId, Guid? storeId, public virtual async Task<List<ProductCategory>> GetListByCategoryId(Guid categoryId, Guid? storeId,
CancellationToken cancellationToken = default) CancellationToken cancellationToken = default)
{ {
return await GetQueryable().Where(pc => pc.CategoryId == categoryId && pc.StoreId == storeId) return await GetQueryable().Where(pc => pc.CategoryId == categoryId && pc.StoreId == storeId)
.ToListAsync(cancellationToken); .ToListAsync(cancellationToken);
} }
public async Task<IEnumerable<ProductCategory>> GetListByProductId(Guid productId, Guid? storeId, public virtual async Task<List<ProductCategory>> GetListByProductId(Guid productId, Guid? storeId,
CancellationToken cancellationToken = default) CancellationToken cancellationToken = default)
{ {
return await GetQueryable().Where(pc => pc.ProductId == productId && pc.StoreId == storeId) return await GetQueryable().Where(pc => pc.ProductId == productId && pc.StoreId == storeId)
......
using System; using System;
using System.Linq;
using EasyAbp.EShop.Products.EntityFrameworkCore; using EasyAbp.EShop.Products.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore; using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore;
...@@ -10,5 +12,13 @@ namespace EasyAbp.EShop.Products.Products ...@@ -10,5 +12,13 @@ namespace EasyAbp.EShop.Products.Products
public ProductRepository(IDbContextProvider<ProductsDbContext> dbContextProvider) : base(dbContextProvider) public ProductRepository(IDbContextProvider<ProductsDbContext> dbContextProvider) : base(dbContextProvider)
{ {
} }
public override IQueryable<Product> WithDetails()
{
return base.WithDetails()
.Include(x => x.ProductDetail)
.Include(x => x.ProductAttributes).ThenInclude(x => x.ProductAttributeOptions)
.Include(x => x.ProductSkus);
}
} }
} }
\ No newline at end of file
...@@ -9,7 +9,6 @@ ...@@ -9,7 +9,6 @@
<abp-modal> <abp-modal>
<abp-modal-header title="@L["CreateProduct"].Value"></abp-modal-header> <abp-modal-header title="@L["CreateProduct"].Value"></abp-modal-header>
<abp-modal-body> <abp-modal-body>
<abp-select asp-for="Product.CategoryIds" asp-items="@Model.Categories" class="data-select" data-live-search="true" multiple />
<abp-form-content /> <abp-form-content />
</abp-modal-body> </abp-modal-body>
<abp-modal-footer buttons="@(AbpModalButtons.Cancel|AbpModalButtons.Save)"></abp-modal-footer> <abp-modal-footer buttons="@(AbpModalButtons.Cancel|AbpModalButtons.Save)"></abp-modal-footer>
......
...@@ -6,6 +6,8 @@ using EasyAbp.EShop.Products.Categories; ...@@ -6,6 +6,8 @@ using EasyAbp.EShop.Products.Categories;
using EasyAbp.EShop.Products.Categories.Dtos; using EasyAbp.EShop.Products.Categories.Dtos;
using EasyAbp.EShop.Products.Products; using EasyAbp.EShop.Products.Products;
using EasyAbp.EShop.Products.Products.Dtos; using EasyAbp.EShop.Products.Products.Dtos;
using EasyAbp.EShop.Products.ProductTypes;
using EasyAbp.EShop.Products.Web.Pages.EShop.Products.Products.Product.ViewModels;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.AspNetCore.Mvc.Rendering;
using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Dtos;
...@@ -15,29 +17,39 @@ namespace EasyAbp.EShop.Products.Web.Pages.EShop.Products.Products.Product ...@@ -15,29 +17,39 @@ namespace EasyAbp.EShop.Products.Web.Pages.EShop.Products.Products.Product
public class CreateModalModel : ProductsPageModel public class CreateModalModel : ProductsPageModel
{ {
[BindProperty] [BindProperty]
public CreateUpdateProductDto Product { get; set; } public CreateUpdateProductViewModel Product { get; set; }
public IEnumerable<SelectListItem> Categories { get; set; } public ICollection<SelectListItem> ProductTypes { get; set; }
public ICollection<SelectListItem> Categories { get; set; }
private readonly IProductTypeAppService _productTypeAppService;
private readonly ICategoryAppService _categoryAppService; private readonly ICategoryAppService _categoryAppService;
private readonly IProductAppService _service; private readonly IProductAppService _service;
public CreateModalModel( public CreateModalModel(
IProductTypeAppService productTypeAppService,
ICategoryAppService categoryAppService, ICategoryAppService categoryAppService,
IProductAppService service) IProductAppService service)
{ {
_productTypeAppService = productTypeAppService;
_categoryAppService = categoryAppService; _categoryAppService = categoryAppService;
_service = service; _service = service;
} }
public async Task OnGetAsync(Guid? storeId) public async Task OnGetAsync(Guid? storeId)
{ {
ProductTypes =
(await _productTypeAppService.GetListAsync(new PagedAndSortedResultRequestDto
{MaxResultCount = LimitedResultRequestDto.MaxMaxResultCount})).Items
.Select(dto => new SelectListItem(dto.DisplayName, dto.Id.ToString())).ToList();
Categories = Categories =
(await _categoryAppService.GetListAsync(new PagedAndSortedResultRequestDto (await _categoryAppService.GetListAsync(new PagedAndSortedResultRequestDto
{MaxResultCount = LimitedResultRequestDto.MaxMaxResultCount}))?.Items {MaxResultCount = LimitedResultRequestDto.MaxMaxResultCount}))?.Items
.Select(dto => new SelectListItem(dto.DisplayName, dto.Id.ToString())); .Select(dto => new SelectListItem(dto.DisplayName, dto.Id.ToString())).ToList();
Product = new CreateUpdateProductDto Product = new CreateUpdateProductViewModel
{ {
StoreId = storeId StoreId = storeId
}; };
...@@ -45,7 +57,7 @@ namespace EasyAbp.EShop.Products.Web.Pages.EShop.Products.Products.Product ...@@ -45,7 +57,7 @@ namespace EasyAbp.EShop.Products.Web.Pages.EShop.Products.Products.Product
public async Task<IActionResult> OnPostAsync() public async Task<IActionResult> OnPostAsync()
{ {
await _service.CreateAsync(Product); await _service.CreateAsync(ObjectMapper.Map<CreateUpdateProductViewModel, CreateUpdateProductDto>(Product));
return NoContent(); return NoContent();
} }
} }
......
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using EasyAbp.EShop.Products.Categories;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using EasyAbp.EShop.Products.Products; using EasyAbp.EShop.Products.Products;
using EasyAbp.EShop.Products.Products.Dtos; using EasyAbp.EShop.Products.Products.Dtos;
using EasyAbp.EShop.Products.ProductTypes;
using EasyAbp.EShop.Products.Web.Pages.EShop.Products.Products.Product.ViewModels;
using Microsoft.AspNetCore.Mvc.Rendering;
using Volo.Abp.Application.Dtos;
namespace EasyAbp.EShop.Products.Web.Pages.EShop.Products.Products.Product namespace EasyAbp.EShop.Products.Web.Pages.EShop.Products.Products.Product
{ {
...@@ -13,24 +20,46 @@ namespace EasyAbp.EShop.Products.Web.Pages.EShop.Products.Products.Product ...@@ -13,24 +20,46 @@ namespace EasyAbp.EShop.Products.Web.Pages.EShop.Products.Products.Product
public Guid Id { get; set; } public Guid Id { get; set; }
[BindProperty] [BindProperty]
public CreateUpdateProductDto Product { get; set; } public CreateUpdateProductViewModel Product { get; set; }
public ICollection<SelectListItem> ProductTypes { get; set; }
public ICollection<SelectListItem> Categories { get; set; }
private readonly IProductTypeAppService _productTypeAppService;
private readonly ICategoryAppService _categoryAppService;
private readonly IProductAppService _service; private readonly IProductAppService _service;
public EditModalModel(IProductAppService service) public EditModalModel(
IProductTypeAppService productTypeAppService,
ICategoryAppService categoryAppService,
IProductAppService service)
{ {
_productTypeAppService = productTypeAppService;
_categoryAppService = categoryAppService;
_service = service; _service = service;
} }
public async Task OnGetAsync() public async Task OnGetAsync()
{ {
var dto = await _service.GetAsync(Id); ProductTypes =
Product = ObjectMapper.Map<ProductDto, CreateUpdateProductDto>(dto); (await _productTypeAppService.GetListAsync(new PagedAndSortedResultRequestDto
{MaxResultCount = LimitedResultRequestDto.MaxMaxResultCount})).Items
.Select(dto => new SelectListItem(dto.DisplayName, dto.Id.ToString())).ToList();
Categories =
(await _categoryAppService.GetListAsync(new PagedAndSortedResultRequestDto
{MaxResultCount = LimitedResultRequestDto.MaxMaxResultCount}))?.Items
.Select(dto => new SelectListItem(dto.DisplayName, dto.Id.ToString())).ToList();
var productDto = await _service.GetAsync(Id);
Product = ObjectMapper.Map<ProductDto, CreateUpdateProductViewModel>(productDto);
} }
public async Task<IActionResult> OnPostAsync() public async Task<IActionResult> OnPostAsync()
{ {
await _service.UpdateAsync(Id, Product); await _service.UpdateAsync(Id,
ObjectMapper.Map<CreateUpdateProductViewModel, CreateUpdateProductDto>(Product));
return NoContent(); return NoContent();
} }
} }
......
using System.ComponentModel.DataAnnotations;
namespace EasyAbp.EShop.Products.Web.Pages.EShop.Products.Products.Product.ViewModels
{
public class CreateUpdateProductAttributeOptionViewModel
{
[Required]
[Display(Name = "ProductAttributeOptionDisplayName")]
public string DisplayName { get; set; }
[Display(Name = "ProductAttributeOptionDescription")]
public string Description { get; set; }
[Display(Name = "ProductAttributeOptionDisplayOrder")]
public int DisplayOrder { get; set; } = 0;
}
}
\ No newline at end of file
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace EasyAbp.EShop.Products.Web.Pages.EShop.Products.Products.Product.ViewModels
{
public class CreateUpdateProductAttributeViewModel
{
[Required]
[Display(Name = "ProductAttributeDisplayName")]
public string DisplayName { get; set; }
[Display(Name = "ProductAttributeDescription")]
public string Description { get; set; }
[Display(Name = "ProductAttributeDisplayOrder")]
public int DisplayOrder { get; set; } = 0;
public List<CreateUpdateProductAttributeOptionViewModel> ProductAttributeOptions { get; set; }
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using EasyAbp.EShop.Products.Products;
using EasyAbp.EShop.Products.Products.Dtos;
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form;
namespace EasyAbp.EShop.Products.Web.Pages.EShop.Products.Products.Product.ViewModels
{
public class CreateUpdateProductDetailViewModel
{
[TextArea(Rows = 4)]
[Display(Name = "ProductDetailDescription")]
public string Description { get; set; }
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using EasyAbp.EShop.Products.Products;
using EasyAbp.EShop.Products.Products.Dtos;
using Microsoft.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form;
namespace EasyAbp.EShop.Products.Web.Pages.EShop.Products.Products.Product.ViewModels
{
public class CreateUpdateProductViewModel
{
[HiddenInput]
[Display(Name = "ProductStore")]
public Guid? StoreId { get; set; }
[Required]
[SelectItems("ProductTypes")]
[Display(Name = "ProductType")]
public Guid ProductTypeId { get; set; }
[SelectItems("Categories")]
[Display(Name = "ProductCategory")]
public List<Guid> CategoryIds { get; set; }
[Required]
[Display(Name = "ProductDisplayName")]
public string DisplayName { get; set; }
public CreateUpdateProductDetailViewModel ProductDetail { get; set; }
[Required]
[Placeholder("ProductAttributeNamesPlaceholder")]
[Display(Name = "ProductAttributeNames")]
public string ProductAttributeNames { get; set; }
[Required]
[TextArea(Rows = 4)]
[Placeholder("ProductAttributeOptionNamesPlaceholder")]
[Display(Name = "ProductAttributeOptionNames")]
public string ProductAttributeOptionNames { get; set; }
[Display(Name = "ProductInventoryStrategy")]
public InventoryStrategy InventoryStrategy { get; set; }
[Display(Name = "ProductDisplayOrder")]
public int DisplayOrder { get; set; } = 0;
[Display(Name = "ProductMediaResources")]
public string MediaResources { get; set; }
[Display(Name = "ProductIsPublished")]
public bool IsPublished { get; set; }
}
}
\ No newline at end of file
using EasyAbp.EShop.Products.Products.Dtos; using System;
using System.Collections.Generic;
using System.Linq;
using EasyAbp.EShop.Products.Products.Dtos;
using EasyAbp.EShop.Products.Categories.Dtos; using EasyAbp.EShop.Products.Categories.Dtos;
using EasyAbp.EShop.Products.ProductTypes.Dtos; using EasyAbp.EShop.Products.ProductTypes.Dtos;
using AutoMapper; using AutoMapper;
using EasyAbp.EShop.Products.Web.Pages.EShop.Products.Products.Product.ViewModels;
using Volo.Abp.AutoMapper; using Volo.Abp.AutoMapper;
namespace EasyAbp.EShop.Products.Web namespace EasyAbp.EShop.Products.Web
...@@ -13,8 +17,34 @@ namespace EasyAbp.EShop.Products.Web ...@@ -13,8 +17,34 @@ namespace EasyAbp.EShop.Products.Web
/* You can configure your AutoMapper mapping configuration here. /* You can configure your AutoMapper mapping configuration here.
* Alternatively, you can split your mapping configurations * Alternatively, you can split your mapping configurations
* into multiple profile classes for a better organization. */ * into multiple profile classes for a better organization. */
CreateMap<ProductDto, CreateUpdateProductDto>(); CreateMap<ProductDto, CreateUpdateProductViewModel>()
CreateMap<ProductDetailDto, CreateUpdateProductDetailDto>(); // .Ignore(x => x.ProductAttributes);
.ForMember(dest => dest.ProductAttributeNames,
opt => opt.MapFrom(source =>
source.ProductAttributes.Select(x => x.DisplayName).JoinAsString(",")))
.ForMember(dest => dest.ProductAttributeOptionNames,
opt => opt.MapFrom(x =>
x.ProductAttributes
.Select(a => a.ProductAttributeOptions.Select(o => o.DisplayName).JoinAsString(","))
.JoinAsString(Environment.NewLine)));
CreateMap<CreateUpdateProductViewModel, CreateUpdateProductDto>()
.ForMember(dest => dest.ProductAttributes,
opt => opt.MapFrom(x =>
x.ProductAttributeNames.Split(",", StringSplitOptions.RemoveEmptyEntries).Select((s, i) =>
new CreateUpdateProductAttributeDto
{
DisplayName = s,
ProductAttributeOptions = new List<CreateUpdateProductAttributeOptionDto>(
x.ProductAttributeOptionNames.SplitToLines(StringSplitOptions.RemoveEmptyEntries)[i]
.Split(",", StringSplitOptions.RemoveEmptyEntries).Select(o =>
new CreateUpdateProductAttributeOptionDto {DisplayName = o}))
})));
CreateMap<ProductDetailDto, CreateUpdateProductDetailViewModel>();
CreateMap<CreateUpdateProductDetailViewModel, CreateUpdateProductDetailDto>();
CreateMap<ProductAttributeDto, CreateUpdateProductAttributeViewModel>();
CreateMap<CreateUpdateProductAttributeViewModel, CreateUpdateProductAttributeDto>();
CreateMap<ProductAttributeOptionDto, CreateUpdateProductAttributeOptionViewModel>();
CreateMap<CreateUpdateProductAttributeOptionViewModel, CreateUpdateProductAttributeOptionDto>();
CreateMap<CategoryDto, CreateUpdateCategoryDto>(); CreateMap<CategoryDto, CreateUpdateCategoryDto>();
CreateMap<ProductTypeDto, CreateUpdateProductTypeDto>(); CreateMap<ProductTypeDto, CreateUpdateProductTypeDto>();
} }
......
using Microsoft.EntityFrameworkCore.Migrations;
namespace EasyMall.Migrations
{
public partial class AddedDisplayOrder : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<int>(
name: "DisplayOrder",
table: "ProductsProducts",
nullable: false,
defaultValue: 0);
migrationBuilder.AddColumn<int>(
name: "DisplayOrder",
table: "ProductsProductAttributes",
nullable: false,
defaultValue: 0);
migrationBuilder.AddColumn<int>(
name: "DisplayOrder",
table: "ProductsProductAttributeOptions",
nullable: false,
defaultValue: 0);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "DisplayOrder",
table: "ProductsProducts");
migrationBuilder.DropColumn(
name: "DisplayOrder",
table: "ProductsProductAttributes");
migrationBuilder.DropColumn(
name: "DisplayOrder",
table: "ProductsProductAttributeOptions");
}
}
}
using Microsoft.EntityFrameworkCore.Migrations;
namespace EasyMall.Migrations
{
public partial class SetPricePrecision : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<decimal>(
name: "Price",
table: "ProductsProductSkus",
type: "decimal(18,6)",
nullable: false,
oldClrType: typeof(decimal),
oldType: "decimal(18,2)");
migrationBuilder.AlterColumn<decimal>(
name: "OriginalPrice",
table: "ProductsProductSkus",
type: "decimal(18,6)",
nullable: false,
oldClrType: typeof(decimal),
oldType: "decimal(18,2)");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<decimal>(
name: "Price",
table: "ProductsProductSkus",
type: "decimal(18,2)",
nullable: false,
oldClrType: typeof(decimal),
oldType: "decimal(18,6)");
migrationBuilder.AlterColumn<decimal>(
name: "OriginalPrice",
table: "ProductsProductSkus",
type: "decimal(18,2)",
nullable: false,
oldClrType: typeof(decimal),
oldType: "decimal(18,6)");
}
}
}
...@@ -229,6 +229,9 @@ namespace EasyMall.Migrations ...@@ -229,6 +229,9 @@ namespace EasyMall.Migrations
b.Property<string>("DisplayName") b.Property<string>("DisplayName")
.HasColumnType("nvarchar(max)"); .HasColumnType("nvarchar(max)");
b.Property<int>("DisplayOrder")
.HasColumnType("int");
b.Property<string>("ExtraProperties") b.Property<string>("ExtraProperties")
.HasColumnName("ExtraProperties") .HasColumnName("ExtraProperties")
.HasColumnType("nvarchar(max)"); .HasColumnType("nvarchar(max)");
...@@ -299,6 +302,9 @@ namespace EasyMall.Migrations ...@@ -299,6 +302,9 @@ namespace EasyMall.Migrations
b.Property<string>("DisplayName") b.Property<string>("DisplayName")
.HasColumnType("nvarchar(max)"); .HasColumnType("nvarchar(max)");
b.Property<int>("DisplayOrder")
.HasColumnType("int");
b.Property<bool>("IsDeleted") b.Property<bool>("IsDeleted")
.ValueGeneratedOnAdd() .ValueGeneratedOnAdd()
.HasColumnName("IsDeleted") .HasColumnName("IsDeleted")
...@@ -351,6 +357,9 @@ namespace EasyMall.Migrations ...@@ -351,6 +357,9 @@ namespace EasyMall.Migrations
b.Property<string>("DisplayName") b.Property<string>("DisplayName")
.HasColumnType("nvarchar(max)"); .HasColumnType("nvarchar(max)");
b.Property<int>("DisplayOrder")
.HasColumnType("int");
b.Property<bool>("IsDeleted") b.Property<bool>("IsDeleted")
.ValueGeneratedOnAdd() .ValueGeneratedOnAdd()
.HasColumnName("IsDeleted") .HasColumnName("IsDeleted")
...@@ -431,10 +440,10 @@ namespace EasyMall.Migrations ...@@ -431,10 +440,10 @@ namespace EasyMall.Migrations
.HasColumnType("int"); .HasColumnType("int");
b.Property<decimal>("OriginalPrice") b.Property<decimal>("OriginalPrice")
.HasColumnType("decimal(18,2)"); .HasColumnType("decimal(18,6)");
b.Property<decimal>("Price") b.Property<decimal>("Price")
.HasColumnType("decimal(18,2)"); .HasColumnType("decimal(18,6)");
b.Property<Guid?>("ProductId") b.Property<Guid?>("ProductId")
.HasColumnType("uniqueidentifier"); .HasColumnType("uniqueidentifier");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment