Browse Source

Close #33: Implement IProductDiscountManager

pull/57/head
gdlcf88 6 years ago
parent
commit
f6d8fad7d0
  1. 4
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application.Contracts/EasyAbp/EShop/Products/Products/Dtos/ProductDto.cs
  2. 16
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application.Contracts/EasyAbp/EShop/Products/Products/Dtos/ProductSkuDto.cs
  3. 51
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application/EasyAbp/EShop/Products/Products/ProductAppService.cs
  4. 8
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application/EasyAbp/EShop/Products/ProductsApplicationAutoMapperProfile.cs
  5. 11
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/IProductDiscountManager.cs
  6. 10
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/IProductDiscountProvider.cs
  7. 7
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/IProductPriceProvider.cs
  8. 22
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductDiscountManager.cs

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

@ -28,6 +28,10 @@ namespace EasyAbp.EShop.Products.Products.Dtos
public bool IsStatic { get; set; }
public bool IsHidden { get; set; }
public decimal? MinimumPrice { get; set; }
public decimal? MaximumPrice { get; set; }
public ICollection<ProductAttributeDto> ProductAttributes { get; set; }

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

@ -13,10 +13,26 @@ namespace EasyAbp.EShop.Products.Products.Dtos
public decimal? OriginalPrice { get; set; }
/// <summary>
/// Price property in the ProductSku entity.
/// </summary>
public decimal Price { get; set; }
/// <summary>
/// Price from IProductDiscountManager
/// </summary>
public decimal DiscountedPrice { get; set; }
/// <summary>
/// Inventory property in the ProductSku entity.
/// </summary>
public int Inventory { get; set; }
/// <summary>
/// Inventory provider's inventory quantity (same as Inventory property if there is no provider).
/// </summary>
public int RealInventory { get; set; }
public int Sold { get; set; }
public int OrderMinQuantity { get; set; }

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

@ -25,6 +25,7 @@ namespace EasyAbp.EShop.Products.Products
protected override string GetListPolicyName { get; set; } = null;
private readonly IProductManager _productManager;
private readonly IProductDiscountManager _productDiscountManager;
private readonly IProductInventoryProvider _productInventoryProvider;
private readonly IAttributeOptionIdsSerializer _attributeOptionIdsSerializer;
private readonly IProductStoreRepository _productStoreRepository;
@ -33,6 +34,7 @@ namespace EasyAbp.EShop.Products.Products
public ProductAppService(
IProductManager productManager,
IProductDiscountManager productDiscountManager,
IProductInventoryProvider productInventoryProvider,
IAttributeOptionIdsSerializer attributeOptionIdsSerializer,
IProductStoreRepository productStoreRepository,
@ -40,6 +42,7 @@ namespace EasyAbp.EShop.Products.Products
IProductRepository repository) : base(repository)
{
_productManager = productManager;
_productDiscountManager = productDiscountManager;
_productInventoryProvider = productInventoryProvider;
_attributeOptionIdsSerializer = attributeOptionIdsSerializer;
_productStoreRepository = productStoreRepository;
@ -198,6 +201,7 @@ namespace EasyAbp.EShop.Products.Products
}
await LoadRealInventoriesAsync(product, dto, storeId);
await LoadPricesAsync(product, dto, storeId);
dto.CategoryIds = (await _productCategoryRepository.GetListByProductIdAsync(dto.Id))
.Select(x => x.CategoryId).ToList();
@ -226,18 +230,6 @@ namespace EasyAbp.EShop.Products.Products
return dto;
}
protected virtual async Task<ProductDto> LoadRealInventoriesAsync(Product product, ProductDto productDto, Guid storeId)
{
var inventoryDict = await _productInventoryProvider.GetInventoryDictionaryAsync(product, storeId);
foreach (var productSkuDto in productDto.ProductSkus)
{
productSkuDto.Inventory = inventoryDict[productSkuDto.Id];
}
return productDto;
}
public override async Task<PagedResultDto<ProductDto>> GetListAsync(GetProductListDto input)
{
await CheckGetListPolicyAsync();
@ -250,6 +242,7 @@ namespace EasyAbp.EShop.Products.Products
throw new NotAllowedToGetProductListWithShowHiddenException();
}
// Todo: Products cache.
var query = CreateFilteredQuery(input);
if (!isCurrentUserStoreAdmin)
@ -268,11 +261,43 @@ namespace EasyAbp.EShop.Products.Products
foreach (var product in products)
{
items.Add(await LoadRealInventoriesAsync(product, MapToGetListOutputDto(product), input.StoreId));
// Todo: How to get list with details if the queryable is customized?
var productDto = MapToGetListOutputDto(await _repository.GetAsync(product.Id));
await LoadRealInventoriesAsync(product, productDto, input.StoreId);
await LoadPricesAsync(product, productDto, input.StoreId);
items.Add(productDto);
}
return new PagedResultDto<ProductDto>(totalCount, items);
}
protected virtual async Task<ProductDto> LoadRealInventoriesAsync(Product product, ProductDto productDto, Guid storeId)
{
var inventoryDict = await _productInventoryProvider.GetInventoryDictionaryAsync(product, storeId);
foreach (var productSkuDto in productDto.ProductSkus)
{
productSkuDto.RealInventory = inventoryDict[productSkuDto.Id];
}
return productDto;
}
protected virtual async Task<ProductDto> LoadPricesAsync(Product product, ProductDto productDto, Guid storeId)
{
foreach (var productSkuDto in productDto.ProductSkus)
{
productSkuDto.DiscountedPrice = await _productDiscountManager.GetDiscountedPriceAsync(product,
product.ProductSkus.Single(sku => sku.Id == productSkuDto.Id), storeId);
}
productDto.MinimumPrice = productDto.ProductSkus.Select(sku => sku.Price).Min();
productDto.MaximumPrice = productDto.ProductSkus.Select(sku => sku.Price).Max();
return productDto;
}
public async Task DeleteAsync(Guid id, Guid storeId)
{

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

@ -25,11 +25,15 @@ namespace EasyAbp.EShop.Products
* Alternatively, you can split your mapping configurations
* into multiple profile classes for a better organization. */
CreateMap<Product, ProductDto>()
.Ignore(dto => dto.CategoryIds);
.Ignore(dto => dto.CategoryIds)
.Ignore(dto => dto.MinimumPrice)
.Ignore(dto => dto.MaximumPrice);
CreateMap<ProductDetail, ProductDetailDto>();
CreateMap<ProductAttribute, ProductAttributeDto>();
CreateMap<ProductAttributeOption, ProductAttributeOptionDto>();
CreateMap<ProductSku, ProductSkuDto>();
CreateMap<ProductSku, ProductSkuDto>()
.Ignore(dto => dto.DiscountedPrice)
.Ignore(dto => dto.RealInventory);
CreateMap<CreateUpdateProductDto, Product>(MemberList.Source)
.ForSourceMember(dto => dto.StoreId, opt => opt.DoNotValidate())
.ForSourceMember(dto => dto.CategoryIds, opt => opt.DoNotValidate())

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

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

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

@ -0,0 +1,10 @@
using System;
using System.Threading.Tasks;
namespace EasyAbp.EShop.Products.Products
{
public interface IProductDiscountProvider
{
Task<decimal> GetDiscountedPriceAsync(Product product, ProductSku productSku, Guid storeId, decimal currentPrice);
}
}

7
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/IProductPriceProvider.cs

@ -1,7 +0,0 @@
namespace EasyAbp.EShop.Products.Products
{
public interface IProductPriceProvider
{
}
}

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

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