Browse Source

Close #71: Implement Baskets plugin module

pull/87/head
gdlcf88 6 years ago
parent
commit
620db9bd1a
  1. 27
      modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application/EasyAbp/EShop/Orders/Orders/NewOrderGenerator.cs
  2. 11
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application.Contracts/EasyAbp/EShop/Products/Products/Dtos/ProductDto.cs
  3. 2
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application.Contracts/EasyAbp/EShop/Products/Products/Dtos/ProductSkuDto.cs
  4. 10
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application.Contracts/EasyAbp/EShop/Products/Products/IProductSkuDescriptionProvider.cs
  5. 33
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application.Contracts/EasyAbp/EShop/Products/Products/ProductSkuDescriptionProvider.cs
  6. 1
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/cs.json
  7. 1
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/en.json
  8. 1
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/pl.json
  9. 1
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/pt-BR.json
  10. 1
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/sl.json
  11. 1
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/tr.json
  12. 1
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/vi.json
  13. 1
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/zh-Hans.json
  14. 1
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/zh-Hant.json
  15. 13
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/ProductInventories/InventoryInsufficientException.cs
  16. 20
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/ProductInventories/ProductInventoryChangedEto.cs
  17. 29
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Products/IProduct.cs
  18. 13
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Products/IProductAttribute.cs
  19. 11
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Products/IProductAttributeOption.cs
  20. 29
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Products/IProductSku.cs
  21. 18
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Products/ProductAttributeEto.cs
  22. 15
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Products/ProductAttributeOptionEto.cs
  23. 36
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Products/ProductEto.cs
  24. 31
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Products/ProductSkuEto.cs
  25. 1
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp.EShop.Products.Domain.csproj
  26. 22
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/EShopProductsDomainModule.cs
  27. 6
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/Product.cs
  28. 4
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductAttribute.cs
  29. 2
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductAttributeOption.cs
  30. 7
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductSku.cs
  31. 19
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/ProductsDomainAutoMapperProfile.cs
  32. 3
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/Pages/EShop/Products/Products/ProductSku/ViewModels/CreateEditProductSkuViewModel.cs
  33. 1
      plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Application.Contracts/EasyAbp.EShop.Plugins.Baskets.Application.Contracts.csproj
  34. 39
      plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Application.Contracts/EasyAbp/EShop/Plugins/Baskets/BasketItems/Dtos/BasketItemDto.cs
  35. 45
      plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Application.Contracts/EasyAbp/EShop/Plugins/Baskets/BasketItems/Dtos/CreateBasketItemDto.cs
  36. 17
      plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Application.Contracts/EasyAbp/EShop/Plugins/Baskets/BasketItems/Dtos/GetBasketItemListDto.cs
  37. 23
      plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Application.Contracts/EasyAbp/EShop/Plugins/Baskets/BasketItems/Dtos/UpdateBasketItemDto.cs
  38. 20
      plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Application.Contracts/EasyAbp/EShop/Plugins/Baskets/BasketItems/IBasketItemAppService.cs
  39. 4
      plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Application.Contracts/EasyAbp/EShop/Plugins/Baskets/EShopPluginsBasketsApplicationContractsModule.cs
  40. 8
      plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Application.Contracts/EasyAbp/EShop/Plugins/Baskets/Permissions/BasketsPermissionDefinitionProvider.cs
  41. 12
      plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Application.Contracts/EasyAbp/EShop/Plugins/Baskets/Permissions/BasketsPermissions.cs
  42. 280
      plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Application/EasyAbp/EShop/Plugins/Baskets/BasketItems/BasketItemAppService.cs
  43. 13
      plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Application/EasyAbp/EShop/Plugins/Baskets/BasketItems/ProductSkuNotFoundException.cs
  44. 7
      plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Application/EasyAbp/EShop/Plugins/Baskets/BasketsApplicationAutoMapperProfile.cs
  45. 7
      plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp/EShop/Plugins/Baskets/BasketsConsts.cs
  46. 29
      plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp/EShop/Plugins/Baskets/Localization/cs.json
  47. 29
      plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp/EShop/Plugins/Baskets/Localization/en.json
  48. 26
      plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp/EShop/Plugins/Baskets/Localization/pl-PL.json
  49. 26
      plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp/EShop/Plugins/Baskets/Localization/pt-BR.json
  50. 27
      plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp/EShop/Plugins/Baskets/Localization/sl.json
  51. 29
      plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp/EShop/Plugins/Baskets/Localization/tr.json
  52. 28
      plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp/EShop/Plugins/Baskets/Localization/vi.json
  53. 27
      plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp/EShop/Plugins/Baskets/Localization/zh-Hans.json
  54. 27
      plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp/EShop/Plugins/Baskets/Localization/zh-Hant.json
  55. 1
      plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain/EasyAbp.EShop.Plugins.Baskets.Domain.csproj
  56. 52
      plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain/EasyAbp/EShop/Plugins/Baskets/BasketItems/BasketItem.cs
  57. 10
      plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain/EasyAbp/EShop/Plugins/Baskets/BasketItems/IBasketItemRepository.cs
  58. 21
      plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain/EasyAbp/EShop/Plugins/Baskets/BasketItems/IProductData.cs
  59. 14
      plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain/EasyAbp/EShop/Plugins/Baskets/BasketItems/IProductUpdateRecorder.cs
  60. 21
      plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain/EasyAbp/EShop/Plugins/Baskets/BasketItems/ProductDataModel.cs
  61. 59
      plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain/EasyAbp/EShop/Plugins/Baskets/BasketItems/ProductUpdateRecorder.cs
  62. 8
      plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain/EasyAbp/EShop/Plugins/Baskets/EShopPluginsBasketsDomainModule.cs
  63. 13
      plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain/EasyAbp/EShop/Plugins/Baskets/ProductUpdates/IProductUpdateRepository.cs
  64. 22
      plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain/EasyAbp/EShop/Plugins/Baskets/ProductUpdates/ProductUpdate.cs
  65. 14
      plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore/EasyAbp/EShop/Plugins/Baskets/BasketItems/BasketItemRepository.cs
  66. 8
      plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore/EasyAbp/EShop/Plugins/Baskets/EntityFrameworkCore/BasketsDbContext.cs
  67. 32
      plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore/EasyAbp/EShop/Plugins/Baskets/EntityFrameworkCore/BasketsDbContextModelCreatingExtensions.cs
  68. 8
      plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore/EasyAbp/EShop/Plugins/Baskets/EntityFrameworkCore/EShopPluginsBasketsEntityFrameworkCoreModule.cs
  69. 9
      plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore/EasyAbp/EShop/Plugins/Baskets/EntityFrameworkCore/IBasketsDbContext.cs
  70. 25
      plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore/EasyAbp/EShop/Plugins/Baskets/ProductUpdates/ProductUpdateRepository.cs
  71. 9
      plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Web/BasketsWebAutoMapperProfile.cs
  72. 28
      plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Web/Menus/BasketsMenuContributor.cs
  73. 6
      plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Web/Menus/BasketsMenus.cs
  74. 18
      plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Web/Pages/EShop/Plugins/Baskets/BasketItems/BasketItem/CreateModal.cshtml
  75. 28
      plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Web/Pages/EShop/Plugins/Baskets/BasketItems/BasketItem/CreateModal.cshtml.cs
  76. 19
      plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Web/Pages/EShop/Plugins/Baskets/BasketItems/BasketItem/EditModal.cshtml
  77. 39
      plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Web/Pages/EShop/Plugins/Baskets/BasketItems/BasketItem/EditModal.cshtml.cs
  78. 72
      plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Web/Pages/EShop/Plugins/Baskets/BasketItems/BasketItem/Index.cshtml
  79. 20
      plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Web/Pages/EShop/Plugins/Baskets/BasketItems/BasketItem/Index.cshtml.cs
  80. 30
      plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Web/Pages/EShop/Plugins/Baskets/BasketItems/BasketItem/ViewModels/CreateBasketItemViewModel.cs
  81. 12
      plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Web/Pages/EShop/Plugins/Baskets/BasketItems/BasketItem/ViewModels/EditBasketItemViewModel.cs
  82. 0
      plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Web/Pages/EShop/Plugins/Baskets/BasketItems/BasketItem/index.css
  83. 79
      plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Web/Pages/EShop/Plugins/Baskets/BasketItems/BasketItem/index.js
  84. 26
      plugins/Baskets/test/EasyAbp.EShop.Plugins.Baskets.Application.Tests/BasketItems/BasketItemAppServiceTests.cs
  85. 23
      plugins/Baskets/test/EasyAbp.EShop.Plugins.Baskets.Domain.Tests/BasketItems/BasketItemDomainTests.cs
  86. 31
      plugins/Baskets/test/EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore.Tests/EntityFrameworkCore/BasketItems/BasketItemRepositoryTests.cs
  87. 3699
      samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore.DbMigrations/Migrations/20200704104743_AddedMediaResourcesToProductSku.Designer.cs
  88. 59
      samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore.DbMigrations/Migrations/20200704104743_AddedMediaResourcesToProductSku.cs
  89. 3699
      samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore.DbMigrations/Migrations/20200704130321_AddedDecimalConfigurationsToBasketItem.Designer.cs
  90. 61
      samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore.DbMigrations/Migrations/20200704130321_AddedDecimalConfigurationsToBasketItem.cs
  91. 3702
      samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore.DbMigrations/Migrations/20200704130714_AddedStoreIdToBasketItem.Designer.cs
  92. 24
      samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore.DbMigrations/Migrations/20200704130714_AddedStoreIdToBasketItem.cs
  93. 3762
      samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore.DbMigrations/Migrations/20200704181535_CreatedProductUpdateEntity.Designer.cs
  94. 44
      samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore.DbMigrations/Migrations/20200704181535_CreatedProductUpdateEntity.cs
  95. 3770
      samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore.DbMigrations/Migrations/20200704182511_ChangeBasketItemToAuditedEntity.Designer.cs
  96. 32
      samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore.DbMigrations/Migrations/20200704182511_ChangeBasketItemToAuditedEntity.cs
  97. 3776
      samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore.DbMigrations/Migrations/20200704195327_AddInventoryAndIsInvalidToBasketItem.Designer.cs
  98. 33
      samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore.DbMigrations/Migrations/20200704195327_AddInventoryAndIsInvalidToBasketItem.cs
  99. 3772
      samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore.DbMigrations/Migrations/20200704200233_RemoveTenantIdFromProductUpdate.Designer.cs
  100. 24
      samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore.DbMigrations/Migrations/20200704200233_RemoveTenantIdFromProductUpdate.cs

27
modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application/EasyAbp/EShop/Orders/Orders/NewOrderGenerator.cs

@ -4,6 +4,7 @@ using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;
using EasyAbp.EShop.Orders.Orders.Dtos;
using EasyAbp.EShop.Products.Products;
using EasyAbp.EShop.Products.Products.Dtos;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Guids;
@ -18,21 +19,21 @@ namespace EasyAbp.EShop.Orders.Orders
private readonly IGuidGenerator _guidGenerator;
private readonly ICurrentTenant _currentTenant;
private readonly ICurrentUser _currentUser;
private readonly IJsonSerializer _jsonSerializer;
private readonly IOrderNumberGenerator _orderNumberGenerator;
private readonly IProductSkuDescriptionProvider _productSkuDescriptionProvider;
public NewOrderGenerator(
IGuidGenerator guidGenerator,
ICurrentTenant currentTenant,
ICurrentUser currentUser,
IJsonSerializer jsonSerializer,
IOrderNumberGenerator orderNumberGenerator)
IOrderNumberGenerator orderNumberGenerator,
IProductSkuDescriptionProvider productSkuDescriptionProvider)
{
_guidGenerator = guidGenerator;
_currentTenant = currentTenant;
_currentUser = currentUser;
_jsonSerializer = jsonSerializer;
_orderNumberGenerator = orderNumberGenerator;
_productSkuDescriptionProvider = productSkuDescriptionProvider;
}
public virtual async Task<Order> GenerateAsync(CreateOrderDto input, Dictionary<Guid, ProductDto> productDict)
@ -68,7 +69,7 @@ namespace EasyAbp.EShop.Orders.Orders
protected virtual async Task<OrderLine> GenerateNewOrderLineAsync(CreateOrderLineDto input, Dictionary<Guid, ProductDto> productDict)
{
var product = productDict[input.ProductId];
var productSku = product.ProductSkus.Single(x => x.Id == input.ProductSkuId);
var productSku = product.GetSkuById(input.ProductSkuId);
if (!input.Quantity.IsBetween(productSku.OrderMinQuantity, productSku.OrderMaxQuantity))
{
@ -82,7 +83,7 @@ namespace EasyAbp.EShop.Orders.Orders
productModificationTime: product.LastModificationTime ?? product.CreationTime,
productDetailModificationTime: productSku.LastModificationTime ?? productSku.CreationTime,
productName: product.DisplayName,
skuDescription: await GenerateSkuDescriptionAsync(product, productSku),
skuDescription: await _productSkuDescriptionProvider.GenerateAsync(product, productSku),
mediaResources: product.MediaResources,
currency: productSku.Currency,
unitPrice: productSku.Price,
@ -92,20 +93,6 @@ namespace EasyAbp.EShop.Orders.Orders
);
}
protected virtual Task<string> GenerateSkuDescriptionAsync(ProductDto product, ProductSkuDto productSku)
{
var names = new Collection<string[]>();
foreach (var attributeOptionId in productSku.AttributeOptionIds)
{
names.Add(product.ProductAttributes.SelectMany(
attribute => attribute.ProductAttributeOptions.Where(option => option.Id == attributeOptionId),
(attribute, option) => new [] {attribute.DisplayName, option.DisplayName}).Single());
}
return Task.FromResult(_jsonSerializer.Serialize(names));
}
protected virtual Task<string> GetStoreCurrencyAsync(Guid storeId)
{
// Todo: Get real store currency configuration.

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

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Volo.Abp.Application.Dtos;
namespace EasyAbp.EShop.Products.Products.Dtos
@ -34,5 +35,15 @@ namespace EasyAbp.EShop.Products.Products.Dtos
public ICollection<ProductAttributeDto> ProductAttributes { get; set; }
public ICollection<ProductSkuDto> ProductSkus { get; set; }
public ProductSkuDto GetSkuById(Guid skuId)
{
return ProductSkus.Single(x => x.Id == skuId);
}
public ProductSkuDto FindSkuById(Guid skuId)
{
return ProductSkus.FirstOrDefault(x => x.Id == skuId);
}
}
}

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

@ -40,6 +40,8 @@ namespace EasyAbp.EShop.Products.Products.Dtos
public int OrderMaxQuantity { get; set; }
public string MediaResources { get; set; }
public Guid? ProductDetailId { get; set; }
}
}

10
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application.Contracts/EasyAbp/EShop/Products/Products/IProductSkuDescriptionProvider.cs

@ -0,0 +1,10 @@
using System.Threading.Tasks;
using EasyAbp.EShop.Products.Products.Dtos;
namespace EasyAbp.EShop.Products.Products
{
public interface IProductSkuDescriptionProvider
{
Task<string> GenerateAsync(ProductDto productDto, ProductSkuDto productSkuDto);
}
}

33
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application.Contracts/EasyAbp/EShop/Products/Products/ProductSkuDescriptionProvider.cs

@ -0,0 +1,33 @@
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;
using EasyAbp.EShop.Products.Products.Dtos;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Json;
namespace EasyAbp.EShop.Products.Products
{
public class ProductSkuDescriptionProvider : IProductSkuDescriptionProvider, ITransientDependency
{
private readonly IJsonSerializer _jsonSerializer;
public ProductSkuDescriptionProvider(IJsonSerializer jsonSerializer)
{
_jsonSerializer = jsonSerializer;
}
public virtual Task<string> GenerateAsync(ProductDto productDto, ProductSkuDto productSkuDto)
{
var names = new Collection<string[]>();
foreach (var attributeOptionId in productSkuDto.AttributeOptionIds)
{
names.Add(productDto.ProductAttributes.SelectMany(
attribute => attribute.ProductAttributeOptions.Where(option => option.Id == attributeOptionId),
(attribute, option) => new [] {attribute.DisplayName, option.DisplayName}).Single());
}
return Task.FromResult(_jsonSerializer.Serialize(names));
}
}
}

1
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/cs.json

@ -28,6 +28,7 @@
"ProductSkuInventory": "ProductSkuInventory",
"ProductSkuOrderMinQuantity": "ProductSkuOrderMinQuantity",
"ProductSkuOrderMaxQuantity": "ProductSkuOrderMaxQuantity",
"ProductSkuMediaResources": "ProductSkuMediaResources",
"ProductSkuProductDetailId": "ProductSkuProductDetailId",
"ProductSkuContentDescription": "ProductSkuContentDescription",
"CreateProductSku": "CreateProductSku",

1
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/en.json

@ -29,6 +29,7 @@
"ProductSkuInventory": "ProductSkuInventory",
"ProductSkuOrderMinQuantity": "ProductSkuOrderMinQuantity",
"ProductSkuOrderMaxQuantity": "ProductSkuOrderMaxQuantity",
"ProductSkuMediaResources": "ProductSkuMediaResources",
"ProductSkuProductDetailId": "ProductSkuProductDetailId",
"ProductSkuContentDescription": "ProductSkuContentDescription",
"CreateProductSku": "CreateProductSku",

1
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/pl.json

@ -28,6 +28,7 @@
"ProductSkuInventory": "ProductSkuInventory",
"ProductSkuOrderMinQuantity": "ProductSkuOrderMinQuantity",
"ProductSkuOrderMaxQuantity": "ProductSkuOrderMaxQuantity",
"ProductSkuMediaResources": "ProductSkuMediaResources",
"ProductSkuProductDetailId": "ProductSkuProductDetailId",
"ProductSkuContentDescription": "ProductSkuContentDescription",
"CreateProductSku": "CreateProductSku",

1
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/pt-BR.json

@ -28,6 +28,7 @@
"ProductSkuInventory": "ProductSkuInventory",
"ProductSkuOrderMinQuantity": "ProductSkuOrderMinQuantity",
"ProductSkuOrderMaxQuantity": "ProductSkuOrderMaxQuantity",
"ProductSkuMediaResources": "ProductSkuMediaResources",
"ProductSkuProductDetailId": "ProductSkuProductDetailId",
"ProductSkuContentDescription": "ProductSkuContentDescription",
"CreateProductSku": "CreateProductSku",

1
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/sl.json

@ -29,6 +29,7 @@
"ProductSkuInventory": "ProductSkuInventory",
"ProductSkuOrderMinQuantity": "ProductSkuOrderMinQuantity",
"ProductSkuOrderMaxQuantity": "ProductSkuOrderMaxQuantity",
"ProductSkuMediaResources": "ProductSkuMediaResources",
"ProductSkuProductDetailId": "ProductSkuProductDetailId",
"ProductSkuContentDescription": "ProductSkuContentDescription",
"CreateProductSku": "CreateProductSku",

1
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/tr.json

@ -29,6 +29,7 @@
"ProductSkuInventory": "ProductSkuInventory",
"ProductSkuOrderMinQuantity": "ProductSkuOrderMinQuantity",
"ProductSkuOrderMaxQuantity": "ProductSkuOrderMaxQuantity",
"ProductSkuMediaResources": "ProductSkuMediaResources",
"ProductSkuProductDetailId": "ProductSkuProductDetailId",
"ProductSkuContentDescription": "ProductSkuContentDescription",
"CreateProductSku": "CreateProductSku",

1
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/vi.json

@ -28,6 +28,7 @@
"ProductSkuInventory": "ProductSkuInventory",
"ProductSkuOrderMinQuantity": "ProductSkuOrderMinQuantity",
"ProductSkuOrderMaxQuantity": "ProductSkuOrderMaxQuantity",
"ProductSkuMediaResources": "ProductSkuMediaResources",
"ProductSkuProductDetailId": "ProductSkuProductDetailId",
"ProductSkuContentDescription": "ProductSkuContentDescription",
"CreateProductSku": "CreateProductSku",

1
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/zh-Hans.json

@ -29,6 +29,7 @@
"ProductSkuInventory": "ProductSkuInventory",
"ProductSkuOrderMinQuantity": "ProductSkuOrderMinQuantity",
"ProductSkuOrderMaxQuantity": "ProductSkuOrderMaxQuantity",
"ProductSkuMediaResources": "ProductSkuMediaResources",
"ProductSkuProductDetailId": "ProductSkuProductDetailId",
"ProductSkuContentDescription": "ProductSkuContentDescription",
"CreateProductSku": "CreateProductSku",

1
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/zh-Hant.json

@ -29,6 +29,7 @@
"ProductSkuInventory": "ProductSkuInventory",
"ProductSkuOrderMinQuantity": "ProductSkuOrderMinQuantity",
"ProductSkuOrderMaxQuantity": "ProductSkuOrderMaxQuantity",
"ProductSkuMediaResources": "ProductSkuMediaResources",
"ProductSkuProductDetailId": "ProductSkuProductDetailId",
"ProductSkuContentDescription": "ProductSkuContentDescription",
"CreateProductSku": "CreateProductSku",

13
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/ProductInventories/InventoryInsufficientException.cs

@ -0,0 +1,13 @@
using System;
using Volo.Abp;
namespace EasyAbp.EShop.Products.ProductInventories
{
public class InventoryInsufficientException : BusinessException
{
public InventoryInsufficientException(Guid productId, Guid productSkuId, int quantity, int inventory) : base(
message: $"The inventory of the product {productId} (SKU: {productSkuId}) is insufficient, {quantity} are needed, but only {inventory}.")
{
}
}
}

20
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/ProductInventories/ProductInventoryChangedEto.cs

@ -0,0 +1,20 @@
using System;
using Volo.Abp.MultiTenancy;
namespace EasyAbp.EShop.Products.ProductInventories
{
public class ProductInventoryChangedEto : IMultiTenant
{
public Guid Id { get; set; }
public Guid? TenantId { get; set; }
public Guid ProductId { get; set; }
public Guid ProductSkuId { get; set; }
public int OriginalInventory { get; set; }
public int NewInventory { get; set; }
}
}

29
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Products/IProduct.cs

@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using Volo.Abp.Data;
namespace EasyAbp.EShop.Products.Products
{
public interface IProduct : IHasExtraProperties
{
Guid ProductTypeId { get; }
Guid ProductDetailId { get; }
string Code { get; }
string DisplayName { get; }
InventoryStrategy InventoryStrategy { get; }
string MediaResources { get; }
int DisplayOrder { get; }
bool IsPublished { get; }
bool IsStatic { get; }
bool IsHidden { get; }
}
}

13
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Products/IProductAttribute.cs

@ -0,0 +1,13 @@
using System.Collections.Generic;
namespace EasyAbp.EShop.Products.Products
{
public interface IProductAttribute
{
string DisplayName { get; }
string Description { get; }
int DisplayOrder { get; }
}
}

11
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Products/IProductAttributeOption.cs

@ -0,0 +1,11 @@
namespace EasyAbp.EShop.Products.Products
{
public interface IProductAttributeOption
{
string DisplayName { get; }
string Description { get; }
int DisplayOrder { get; }
}
}

29
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Products/IProductSku.cs

@ -0,0 +1,29 @@
using System;
namespace EasyAbp.EShop.Products.Products
{
public interface IProductSku
{
string SerializedAttributeOptionIds { get; }
string Code { get; }
string Currency { get; }
decimal? OriginalPrice { get; }
decimal Price { get; }
int Inventory { get; }
int Sold { get; }
int OrderMinQuantity { get; }
int OrderMaxQuantity { get; }
string MediaResources { get; }
public Guid? ProductDetailId { get; }
}
}

18
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Products/ProductAttributeEto.cs

@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
namespace EasyAbp.EShop.Products.Products
{
public class ProductAttributeEto : IProductAttribute
{
public Guid Id { get; set; }
public string DisplayName { get; set; }
public string Description { get; set; }
public int DisplayOrder { get; set; }
public ICollection<ProductAttributeOptionEto> ProductAttributeOptions { get; set; }
}
}

15
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Products/ProductAttributeOptionEto.cs

@ -0,0 +1,15 @@
using System;
namespace EasyAbp.EShop.Products.Products
{
public class ProductAttributeOptionEto : IProductAttributeOption
{
public Guid Id { get; set; }
public string DisplayName { get; set; }
public string Description { get; set; }
public int DisplayOrder { get; set; }
}
}

36
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Products/ProductEto.cs

@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
namespace EasyAbp.EShop.Products.Products
{
public class ProductEto : IProduct
{
public Guid Id { get; set; }
public Guid ProductTypeId { get; set; }
public Guid ProductDetailId { get; set; }
public string Code { get; set; }
public string DisplayName { get; set; }
public InventoryStrategy InventoryStrategy { get; set; }
public string MediaResources { get; set; }
public int DisplayOrder { get; set; }
public bool IsPublished { get; set; }
public bool IsStatic { get; set; }
public bool IsHidden { get; set; }
public Dictionary<string, object> ExtraProperties { get; set; }
public ICollection<ProductAttributeEto> ProductAttributes { get; set; }
public ICollection<ProductSkuEto> ProductSkus { get; set; }
}
}

31
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Products/ProductSkuEto.cs

@ -0,0 +1,31 @@
using System;
namespace EasyAbp.EShop.Products.Products
{
public class ProductSkuEto : IProductSku
{
public Guid Id { get; set; }
public string SerializedAttributeOptionIds { get; set; }
public string Code { get; set; }
public string Currency { get; set; }
public decimal? OriginalPrice { get; set; }
public decimal Price { get; set; }
public int Inventory { get; set; }
public int Sold { get; set; }
public int OrderMinQuantity { get; set; }
public int OrderMaxQuantity { get; set; }
public string MediaResources { get; set; }
public Guid? ProductDetailId { get; set; }
}
}

1
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp.EShop.Products.Domain.csproj

@ -9,6 +9,7 @@
<ItemGroup>
<PackageReference Include="EasyAbp.Abp.Trees.Domain" Version="0.290.4" />
<PackageReference Include="Volo.Abp.AutoMapper" Version="3.0.1" />
<PackageReference Include="Volo.Abp.Ddd.Domain" Version="3.0.1" />
<ProjectReference Include="..\..\..\EasyAbp.EShop.Orders\src\EasyAbp.EShop.Orders.Domain.Shared\EasyAbp.EShop.Orders.Domain.Shared.csproj" />
<ProjectReference Include="..\..\..\EasyAbp.EShop.Stores\src\EasyAbp.EShop.Stores.Domain.Shared\EasyAbp.EShop.Stores.Domain.Shared.csproj" />

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

@ -1,5 +1,9 @@
using EasyAbp.Abp.Trees;
using EasyAbp.EShop.Products.Products;
using EasyAbp.EShop.Stores;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.AutoMapper;
using Volo.Abp.Domain.Entities.Events.Distributed;
using Volo.Abp.Modularity;
namespace EasyAbp.EShop.Products
@ -11,6 +15,24 @@ namespace EasyAbp.EShop.Products
)]
public class EShopProductsDomainModule : AbpModule
{
public override void PreConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpDistributedEntityEventOptions>(options =>
{
options.EtoMappings.Add<Product, ProductEto>();
options.AutoEventSelectors.Add<Product>();
});
}
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddAutoMapperObjectMapper<EShopProductsDomainModule>();
Configure<AbpAutoMapperOptions>(options =>
{
options.AddProfile<ProductsDomainAutoMapperProfile>(validate: true);
});
}
}
}

6
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/Product.cs

@ -6,7 +6,7 @@ using Volo.Abp.Domain.Entities.Auditing;
namespace EasyAbp.EShop.Products.Products
{
public class Product : FullAuditedAggregateRoot<Guid>
public class Product : FullAuditedAggregateRoot<Guid>, IProduct
{
public virtual Guid ProductTypeId { get; protected set; }
@ -31,9 +31,9 @@ namespace EasyAbp.EShop.Products.Products
public virtual bool IsHidden { get; protected set; }
public virtual ICollection<ProductAttribute> ProductAttributes { get; protected set; }
public virtual List<ProductAttribute> ProductAttributes { get; protected set; }
public virtual ICollection<ProductSku> ProductSkus { get; protected set; }
public virtual List<ProductSku> ProductSkus { get; protected set; }
protected Product()
{

4
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductAttribute.cs

@ -5,7 +5,7 @@ using Volo.Abp.Domain.Entities.Auditing;
namespace EasyAbp.EShop.Products.Products
{
public class ProductAttribute : FullAuditedEntity<Guid>
public class ProductAttribute : FullAuditedEntity<Guid>, IProductAttribute
{
[NotNull]
public virtual string DisplayName { get; protected set; }
@ -15,7 +15,7 @@ namespace EasyAbp.EShop.Products.Products
public virtual int DisplayOrder { get; protected set; }
public virtual ICollection<ProductAttributeOption> ProductAttributeOptions { get; protected set; }
public virtual List<ProductAttributeOption> ProductAttributeOptions { get; protected set; }
protected ProductAttribute()
{

2
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductAttributeOption.cs

@ -4,7 +4,7 @@ using Volo.Abp.Domain.Entities.Auditing;
namespace EasyAbp.EShop.Products.Products
{
public class ProductAttributeOption : FullAuditedEntity<Guid>
public class ProductAttributeOption : FullAuditedEntity<Guid>, IProductAttributeOption
{
[NotNull]
public virtual string DisplayName { get; protected set; }

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

@ -4,7 +4,7 @@ using Volo.Abp.Domain.Entities.Auditing;
namespace EasyAbp.EShop.Products.Products
{
public class ProductSku : FullAuditedEntity<Guid>
public class ProductSku : FullAuditedEntity<Guid>, IProductSku
{
[NotNull]
public virtual string SerializedAttributeOptionIds { get; protected set; }
@ -28,6 +28,9 @@ namespace EasyAbp.EShop.Products.Products
public virtual int OrderMaxQuantity { get; protected set; }
[CanBeNull]
public virtual string MediaResources { get; protected set; }
public Guid? ProductDetailId { get; set; }
protected ProductSku() {}
@ -43,6 +46,7 @@ namespace EasyAbp.EShop.Products.Products
int sold,
int orderMinQuantity,
int orderMaxQuantity,
[CanBeNull] string mediaResources,
Guid? productDetailId) : base(id)
{
SerializedAttributeOptionIds = serializedAttributeOptionIds;
@ -54,6 +58,7 @@ namespace EasyAbp.EShop.Products.Products
Sold = sold;
OrderMinQuantity = orderMinQuantity;
OrderMaxQuantity = orderMaxQuantity;
MediaResources = mediaResources;
ProductDetailId = productDetailId;
}

19
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/ProductsDomainAutoMapperProfile.cs

@ -0,0 +1,19 @@
using AutoMapper;
using EasyAbp.EShop.Products.Products;
namespace EasyAbp.EShop.Products
{
public class ProductsDomainAutoMapperProfile : Profile
{
public ProductsDomainAutoMapperProfile()
{
/* You can configure your AutoMapper mapping configuration here.
* Alternatively, you can split your mapping configurations
* into multiple profile classes for a better organization. */
CreateMap<Product, ProductEto>();
CreateMap<ProductAttribute, ProductAttributeEto>();
CreateMap<ProductAttributeOption, ProductAttributeOptionEto>();
CreateMap<ProductSku, ProductSkuEto>();
}
}
}

3
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Web/Pages/EShop/Products/Products/ProductSku/ViewModels/CreateEditProductSkuViewModel.cs

@ -35,6 +35,9 @@ namespace EasyAbp.EShop.Products.Web.Pages.EShop.Products.Products.ProductSku.Vi
[Display(Name = "ProductSkuOrderMaxQuantity")]
public int OrderMaxQuantity { get; set; }
[Display(Name = "ProductSkuMediaResources")]
public string MediaResources { get; set; }
[HiddenInput]
[Display(Name = "ProductSkuProductDetailId")]
public Guid? ProductDetailId { get; set; }

1
plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Application.Contracts/EasyAbp.EShop.Plugins.Baskets.Application.Contracts.csproj

@ -10,6 +10,7 @@
<ItemGroup>
<PackageReference Include="Volo.Abp.Ddd.Application.Contracts" Version="3.0.1" />
<PackageReference Include="Volo.Abp.Authorization" Version="3.0.1" />
<ProjectReference Include="..\..\..\..\modules\EasyAbp.EShop.Products\src\EasyAbp.EShop.Products.Application.Contracts\EasyAbp.EShop.Products.Application.Contracts.csproj" />
<ProjectReference Include="..\EasyAbp.EShop.Plugins.Baskets.Domain.Shared\EasyAbp.EShop.Plugins.Baskets.Domain.Shared.csproj" />
</ItemGroup>

39
plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Application.Contracts/EasyAbp/EShop/Plugins/Baskets/BasketItems/Dtos/BasketItemDto.cs

@ -0,0 +1,39 @@
using System;
using Volo.Abp.Application.Dtos;
namespace EasyAbp.EShop.Plugins.Baskets.BasketItems.Dtos
{
[Serializable]
public class BasketItemDto : AuditedEntityDto<Guid>
{
public string BasketName { get; set; }
public Guid UserId { get; set; }
public Guid StoreId { get; set; }
public Guid ProductId { get; set; }
public Guid ProductSkuId { get; set; }
public int Quantity { get; set; }
public string MediaResources { get; set; }
public string ProductName { get; set; }
public string SkuDescription { get; set; }
public string Currency { get; set; }
public decimal UnitPrice { get; set; }
public decimal TotalPrice { get; set; }
public decimal TotalDiscount { get; set; }
public int Inventory { get; set; }
public bool IsInvalid { get; set; }
}
}

45
plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Application.Contracts/EasyAbp/EShop/Plugins/Baskets/BasketItems/Dtos/CreateBasketItemDto.cs

@ -0,0 +1,45 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
namespace EasyAbp.EShop.Plugins.Baskets.BasketItems.Dtos
{
[Serializable]
public class CreateBasketItemDto : IValidatableObject
{
public string BasketName { get; set; } = BasketsConsts.DefaultBasketName;
/// <summary>
/// Specify the basket item owner user ID. Use current user ID if this property is null.
/// </summary>
public Guid? UserId { get; set; }
public Guid StoreId { get; set; }
public Guid ProductId { get; set; }
public Guid ProductSkuId { get; set; }
public int Quantity { get; set; }
public new IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (Quantity <= 0)
{
yield return new ValidationResult(
"Quantity should be greater than 0.",
new[] { "Quantity" }
);
}
if (BasketName.IsNullOrWhiteSpace())
{
yield return new ValidationResult(
"BasketName should not be empty.",
new[] { "BasketName" }
);
}
}
}
}

17
plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Application.Contracts/EasyAbp/EShop/Plugins/Baskets/BasketItems/Dtos/GetBasketItemListDto.cs

@ -0,0 +1,17 @@
using System;
using System.ComponentModel.DataAnnotations;
using Volo.Abp.Application.Dtos;
namespace EasyAbp.EShop.Plugins.Baskets.BasketItems.Dtos
{
public class GetBasketItemListDto : PagedAndSortedResultRequestDto
{
[Required]
public string BasketName { get; set; }
/// <summary>
/// Specify the basket item owner user ID. Use current user ID if this property is null.
/// </summary>
public Guid? UserId { get; set; }
}
}

23
plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Application.Contracts/EasyAbp/EShop/Plugins/Baskets/BasketItems/Dtos/UpdateBasketItemDto.cs

@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace EasyAbp.EShop.Plugins.Baskets.BasketItems.Dtos
{
[Serializable]
public class UpdateBasketItemDto : IValidatableObject
{
public int Quantity { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (Quantity <= 0)
{
yield return new ValidationResult(
"Quantity should be greater than 0.",
new[] { "Quantity" }
);
}
}
}
}

20
plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Application.Contracts/EasyAbp/EShop/Plugins/Baskets/BasketItems/IBasketItemAppService.cs

@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using EasyAbp.EShop.Plugins.Baskets.BasketItems.Dtos;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
namespace EasyAbp.EShop.Plugins.Baskets.BasketItems
{
public interface IBasketItemAppService :
ICrudAppService<
BasketItemDto,
Guid,
GetBasketItemListDto,
CreateBasketItemDto,
UpdateBasketItemDto>
{
Task DeleteInBulkAsync(IEnumerable<Guid> ids);
}
}

4
plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Application.Contracts/EasyAbp/EShop/Plugins/Baskets/EShopPluginsBasketsApplicationContractsModule.cs

@ -1,4 +1,5 @@
using Volo.Abp.Application;
using EasyAbp.EShop.Products;
using Volo.Abp.Application;
using Volo.Abp.Modularity;
using Volo.Abp.Authorization;
@ -6,6 +7,7 @@ namespace EasyAbp.EShop.Plugins.Baskets
{
[DependsOn(
typeof(EShopPluginsBasketsDomainSharedModule),
typeof(EShopProductsApplicationContractsModule),
typeof(AbpDddApplicationContractsModule),
typeof(AbpAuthorizationModule)
)]

8
plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Application.Contracts/EasyAbp/EShop/Plugins/Baskets/Permissions/BasketsPermissionDefinitionProvider.cs

@ -9,6 +9,12 @@ namespace EasyAbp.EShop.Plugins.Baskets.Permissions
public override void Define(IPermissionDefinitionContext context)
{
var myGroup = context.AddGroup(BasketsPermissions.GroupName, L("Permission:Baskets"));
var basketItemPermission = myGroup.AddPermission(BasketsPermissions.BasketItem.Default, L("Permission:BasketItem"));
basketItemPermission.AddChild(BasketsPermissions.BasketItem.Manage, L("Permission:Manage"));
basketItemPermission.AddChild(BasketsPermissions.BasketItem.Create, L("Permission:Create"));
basketItemPermission.AddChild(BasketsPermissions.BasketItem.Update, L("Permission:Update"));
basketItemPermission.AddChild(BasketsPermissions.BasketItem.Delete, L("Permission:Delete"));
}
private static LocalizableString L(string name)
@ -16,4 +22,4 @@ namespace EasyAbp.EShop.Plugins.Baskets.Permissions
return LocalizableString.Create<BasketsResource>(name);
}
}
}
}

12
plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Application.Contracts/EasyAbp/EShop/Plugins/Baskets/Permissions/BasketsPermissions.cs

@ -10,5 +10,15 @@ namespace EasyAbp.EShop.Plugins.Baskets.Permissions
{
return ReflectionHelper.GetPublicConstantsRecursively(typeof(BasketsPermissions));
}
public class BasketItem
{
public const string Default = GroupName + ".BasketItem";
public const string Manage = Default + ".Manage";
public const string Update = Default + ".Update";
public const string Create = Default + ".Create";
public const string Delete = Default + ".Delete";
}
}
}
}

280
plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Application/EasyAbp/EShop/Plugins/Baskets/BasketItems/BasketItemAppService.cs

@ -0,0 +1,280 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using EasyAbp.EShop.Plugins.Baskets.Permissions;
using EasyAbp.EShop.Plugins.Baskets.BasketItems.Dtos;
using EasyAbp.EShop.Plugins.Baskets.ProductUpdates;
using EasyAbp.EShop.Products.ProductInventories;
using EasyAbp.EShop.Products.Products;
using EasyAbp.EShop.Products.Products.Dtos;
using Microsoft.AspNetCore.Authorization;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Authorization;
using Volo.Abp.Domain.Entities;
using Volo.Abp.Users;
namespace EasyAbp.EShop.Plugins.Baskets.BasketItems
{
public class BasketItemAppService : CrudAppService<BasketItem, BasketItemDto, Guid, GetBasketItemListDto, CreateBasketItemDto, UpdateBasketItemDto>,
IBasketItemAppService
{
protected override string GetPolicyName { get; set; } = BasketsPermissions.BasketItem.Default;
protected override string GetListPolicyName { get; set; } = BasketsPermissions.BasketItem.Default;
protected override string CreatePolicyName { get; set; } = BasketsPermissions.BasketItem.Create;
protected override string UpdatePolicyName { get; set; } = BasketsPermissions.BasketItem.Update;
protected override string DeletePolicyName { get; set; } = BasketsPermissions.BasketItem.Delete;
private readonly IBasketItemRepository _repository;
private readonly IProductUpdateRepository _productUpdateRepository;
private readonly IProductAppService _productAppService;
private readonly IProductSkuDescriptionProvider _productSkuDescriptionProvider;
public BasketItemAppService(
IBasketItemRepository repository,
IProductUpdateRepository productUpdateRepository,
IProductAppService productAppService,
IProductSkuDescriptionProvider productSkuDescriptionProvider) : base(repository)
{
_repository = repository;
_productUpdateRepository = productUpdateRepository;
_productAppService = productAppService;
_productSkuDescriptionProvider = productSkuDescriptionProvider;
}
public override async Task<BasketItemDto> GetAsync(Guid id)
{
await CheckGetPolicyAsync();
var item = await GetEntityByIdAsync(id);
if (item.UserId != CurrentUser.GetId() && !await IsCurrentUserManagerAsync())
{
throw new AbpAuthorizationException();
}
var productUpdate = await _productUpdateRepository.FindAsync(x => x.ProductSkuId == item.ProductSkuId);
if (productUpdate != null)
{
var itemUpdateTime = item.LastModificationTime ?? item.CreationTime;
var productUpdateTime = productUpdate.LastModificationTime ?? productUpdate.CreationTime;
if (itemUpdateTime < productUpdateTime)
{
var productDto = await _productAppService.GetAsync(item.ProductId, item.StoreId);
await UpdateProductDataAsync(item.Quantity, item, productDto);
await _repository.UpdateAsync(item, true);
}
}
return MapToGetOutputDto(item);
}
public override async Task<PagedResultDto<BasketItemDto>> GetListAsync(GetBasketItemListDto input)
{
await CheckGetListPolicyAsync();
if (input.UserId != CurrentUser.GetId() && !await IsCurrentUserManagerAsync())
{
throw new AbpAuthorizationException();
}
var query = CreateFilteredQuery(input);
var totalCount = await AsyncExecuter.CountAsync(query);
query = ApplySorting(query, input);
query = ApplyPaging(query, input);
var items = await AsyncExecuter.ToListAsync(query);
var productSkuIds = items.Select(item => item.ProductSkuId).ToList();
var skuIdUpdateTimeDict =
(await _productUpdateRepository.GetListByProductSkuIdsAsync(productSkuIds)).ToDictionary(
x => x.ProductSkuId, x => x.LastModificationTime ?? x.CreationTime);
var productDtoDict = new Dictionary<Guid, ProductDto>();
foreach (var item in items)
{
if (!skuIdUpdateTimeDict.ContainsKey(item.ProductSkuId))
{
continue;
}
var itemUpdateTime = item.LastModificationTime ?? item.CreationTime;
var productUpdateTime = skuIdUpdateTimeDict[item.ProductSkuId];
if (itemUpdateTime >= productUpdateTime)
{
continue;
}
if (!productDtoDict.ContainsKey(item.ProductId))
{
// Todo: deleted product cause errors
productDtoDict[item.ProductId] =
await _productAppService.GetAsync(item.ProductId, item.StoreId);
}
await UpdateProductDataAsync(item.Quantity, item, productDtoDict[item.ProductId]);
await _repository.UpdateAsync(item);
}
return new PagedResultDto<BasketItemDto>(
totalCount,
items.Select(MapToGetListOutputDto).ToList()
);
}
protected virtual async Task UpdateProductDataAsync(int quantity, BasketItem item, ProductDto productDto)
{
item.SetIsInvalid(false);
var productSkuDto = productDto.FindSkuById(item.ProductSkuId);
if (productSkuDto == null)
{
item.SetIsInvalid(true);
return;
}
if (productDto.InventoryStrategy != InventoryStrategy.NoNeed && quantity > productSkuDto.RealInventory)
{
item.SetIsInvalid(true);
}
item.UpdateProductData(quantity, new ProductDataModel
{
MediaResources = productSkuDto.MediaResources ?? productDto.MediaResources,
ProductName = productDto.DisplayName,
SkuDescription = await _productSkuDescriptionProvider.GenerateAsync(productDto, productSkuDto),
Currency = productSkuDto.Currency,
UnitPrice = productSkuDto.DiscountedPrice,
TotalPrice = productSkuDto.DiscountedPrice * item.Quantity,
TotalDiscount = (productSkuDto.Price - productSkuDto.DiscountedPrice) * item.Quantity,
Inventory = productSkuDto.RealInventory
});
if (!productDto.IsPublished)
{
item.SetIsInvalid(true);
}
}
protected override IQueryable<BasketItem> CreateFilteredQuery(GetBasketItemListDto input)
{
var userId = input.UserId ?? CurrentUser.GetId();
return ReadOnlyRepository.Where(item => item.UserId == userId && item.BasketName == input.BasketName);
}
public override async Task<BasketItemDto> CreateAsync(CreateBasketItemDto input)
{
await CheckCreatePolicyAsync();
var userId = input.UserId ?? CurrentUser.GetId();
if (userId != CurrentUser.GetId() && !await IsCurrentUserManagerAsync())
{
throw new AbpAuthorizationException();
}
var productDto = await _productAppService.GetAsync(input.ProductId, input.StoreId);
var item = await _repository.FindAsync(x =>
x.UserId == userId && x.BasketName == input.BasketName && x.StoreId == input.StoreId &&
x.ProductSkuId == input.ProductSkuId);
if (item != null)
{
await UpdateProductDataAsync(input.Quantity + item.Quantity, item, productDto);
await Repository.UpdateAsync(item, autoSave: true);
return MapToGetOutputDto(item);
}
var productSkuDto = productDto.FindSkuById(input.ProductSkuId);
if (productSkuDto == null)
{
throw new ProductSkuNotFoundException(input.ProductId, input.ProductSkuId);
}
item = new BasketItem(GuidGenerator.Create(), CurrentTenant.Id, input.BasketName, CurrentUser.GetId(),
input.StoreId, input.ProductId, input.ProductSkuId);
await UpdateProductDataAsync(input.Quantity, item, productDto);
await Repository.InsertAsync(item, autoSave: true);
return MapToGetOutputDto(item);
}
public override async Task<BasketItemDto> UpdateAsync(Guid id, UpdateBasketItemDto input)
{
await CheckUpdatePolicyAsync();
var item = await GetEntityByIdAsync(id);
if (item.UserId != CurrentUser.GetId() && !await IsCurrentUserManagerAsync())
{
throw new AbpAuthorizationException();
}
var productDto = await _productAppService.GetAsync(item.ProductId, item.StoreId);
await UpdateProductDataAsync(input.Quantity, item, productDto);
await Repository.UpdateAsync(item, autoSave: true);
return MapToGetOutputDto(item);
}
public override async Task DeleteAsync(Guid id)
{
await CheckDeletePolicyAsync();
var item = await _repository.GetAsync(id);
if (item.UserId != CurrentUser.GetId() && !await IsCurrentUserManagerAsync())
{
throw new AbpAuthorizationException();
}
await _repository.DeleteAsync(item, true);
}
public virtual async Task DeleteInBulkAsync(IEnumerable<Guid> ids)
{
await CheckDeletePolicyAsync();
var isCurrentUserManager = await IsCurrentUserManagerAsync();
foreach (var id in ids)
{
var item = await GetEntityByIdAsync(id);
if (item.UserId != CurrentUser.GetId() && !isCurrentUserManager)
{
throw new AbpAuthorizationException();
}
await _repository.DeleteAsync(item);
}
}
protected virtual async Task<bool> IsCurrentUserManagerAsync()
{
return await AuthorizationService.IsGrantedAsync(BasketsPermissions.BasketItem.Manage);
}
}
}

13
plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Application/EasyAbp/EShop/Plugins/Baskets/BasketItems/ProductSkuNotFoundException.cs

@ -0,0 +1,13 @@
using System;
using Volo.Abp;
namespace EasyAbp.EShop.Plugins.Baskets.BasketItems
{
public class ProductSkuNotFoundException : BusinessException
{
public ProductSkuNotFoundException(Guid productId, Guid productSkuId) : base(
message: $"Product {productId} (SKU: {productSkuId}) not found.")
{
}
}
}

7
plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Application/EasyAbp/EShop/Plugins/Baskets/BasketsApplicationAutoMapperProfile.cs

@ -1,4 +1,6 @@
using AutoMapper;
using EasyAbp.EShop.Plugins.Baskets.BasketItems;
using EasyAbp.EShop.Plugins.Baskets.BasketItems.Dtos;
using AutoMapper;
namespace EasyAbp.EShop.Plugins.Baskets
{
@ -9,6 +11,7 @@ namespace EasyAbp.EShop.Plugins.Baskets
/* You can configure your AutoMapper mapping configuration here.
* Alternatively, you can split your mapping configurations
* into multiple profile classes for a better organization. */
CreateMap<BasketItem, BasketItemDto>();
}
}
}
}

7
plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp/EShop/Plugins/Baskets/BasketsConsts.cs

@ -0,0 +1,7 @@
namespace EasyAbp.EShop.Plugins.Baskets
{
public static class BasketsConsts
{
public const string DefaultBasketName = "Default";
}
}

29
plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp/EShop/Plugins/Baskets/Localization/cs.json

@ -1,6 +1,31 @@
{
"culture": "cs",
"texts": {
"ManageYourProfile": "Spravovat profil"
"ManageYourProfile": "Spravovat profil",
"Permission:BasketItem": "BasketItem",
"Permission:Create": "Create",
"Permission:Update": "Update",
"Permission:Delete": "Delete",
"Menu:BasketItem": "MenuBasketItem",
"BasketItem": "BasketItem",
"BasketItemBasketName": "BasketItemBasketName",
"BasketItemUserId": "BasketItemUserId",
"BasketItemStoreId": "BasketItemStoreId",
"BasketItemProductId": "BasketItemProductId",
"BasketItemProductSkuId": "BasketItemProductSkuId",
"BasketItemQuantity": "BasketItemQuantity",
"BasketItemMediaResources": "BasketItemMediaResources",
"BasketItemProductName": "BasketItemProductName",
"BasketItemSkuDescription": "BasketItemSkuDescription",
"BasketItemCurrency": "BasketItemCurrency",
"BasketItemUnitPrice": "BasketItemUnitPrice",
"BasketItemTotalPrice": "BasketItemTotalPrice",
"BasketItemTotalDiscount": "BasketItemTotalDiscount",
"BasketItemInventory": "BasketItemInventory",
"BasketItemIsInvalid": "BasketItemIsInvalid",
"CreateBasketItem": "CreateBasketItem",
"EditBasketItem": "EditBasketItem",
"BasketItemDeletionConfirmationMessage": "Are you sure to delete the basketItem {0}?",
"SuccessfullyDeleted": "Successfully deleted"
}
}
}

29
plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp/EShop/Plugins/Baskets/Localization/en.json

@ -1,7 +1,32 @@
{
"culture": "en",
"texts": {
"ManageYourProfile": "Manage your profile",
"SamplePageMessage": "A sample page for the Baskets module"
"ManageYourProfile": "Manage your profile",
"SamplePageMessage": "A sample page for the Baskets module",
"Permission:BasketItem": "BasketItem",
"Permission:Create": "Create",
"Permission:Update": "Update",
"Permission:Delete": "Delete",
"Menu:BasketItem": "MenuBasketItem",
"BasketItem": "BasketItem",
"BasketItemBasketName": "BasketItemBasketName",
"BasketItemUserId": "BasketItemUserId",
"BasketItemStoreId": "BasketItemStoreId",
"BasketItemProductId": "BasketItemProductId",
"BasketItemProductSkuId": "BasketItemProductSkuId",
"BasketItemQuantity": "BasketItemQuantity",
"BasketItemMediaResources": "BasketItemMediaResources",
"BasketItemProductName": "BasketItemProductName",
"BasketItemSkuDescription": "BasketItemSkuDescription",
"BasketItemCurrency": "BasketItemCurrency",
"BasketItemUnitPrice": "BasketItemUnitPrice",
"BasketItemTotalPrice": "BasketItemTotalPrice",
"BasketItemTotalDiscount": "BasketItemTotalDiscount",
"BasketItemInventory": "BasketItemInventory",
"BasketItemIsInvalid": "BasketItemIsInvalid",
"CreateBasketItem": "CreateBasketItem",
"EditBasketItem": "EditBasketItem",
"BasketItemDeletionConfirmationMessage": "Are you sure to delete the basketItem {0}?",
"SuccessfullyDeleted": "Successfully deleted"
}
}

26
plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp/EShop/Plugins/Baskets/Localization/pl-PL.json

@ -1,6 +1,30 @@
{
"culture": "pl-PL",
"texts": {
"Permission:BasketItem": "BasketItem",
"Permission:Create": "Create",
"Permission:Update": "Update",
"Permission:Delete": "Delete",
"Menu:BasketItem": "MenuBasketItem",
"BasketItem": "BasketItem",
"BasketItemBasketName": "BasketItemBasketName",
"BasketItemUserId": "BasketItemUserId",
"BasketItemStoreId": "BasketItemStoreId",
"BasketItemProductId": "BasketItemProductId",
"BasketItemProductSkuId": "BasketItemProductSkuId",
"BasketItemQuantity": "BasketItemQuantity",
"BasketItemMediaResources": "BasketItemMediaResources",
"BasketItemProductName": "BasketItemProductName",
"BasketItemSkuDescription": "BasketItemSkuDescription",
"BasketItemCurrency": "BasketItemCurrency",
"BasketItemUnitPrice": "BasketItemUnitPrice",
"BasketItemTotalPrice": "BasketItemTotalPrice",
"BasketItemTotalDiscount": "BasketItemTotalDiscount",
"BasketItemInventory": "BasketItemInventory",
"BasketItemIsInvalid": "BasketItemIsInvalid",
"CreateBasketItem": "CreateBasketItem",
"EditBasketItem": "EditBasketItem",
"BasketItemDeletionConfirmationMessage": "Are you sure to delete the basketItem {0}?",
"SuccessfullyDeleted": "Successfully deleted"
}
}

26
plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp/EShop/Plugins/Baskets/Localization/pt-BR.json

@ -1,6 +1,30 @@
{
"culture": "pt-BR",
"texts": {
"Permission:BasketItem": "BasketItem",
"Permission:Create": "Create",
"Permission:Update": "Update",
"Permission:Delete": "Delete",
"Menu:BasketItem": "MenuBasketItem",
"BasketItem": "BasketItem",
"BasketItemBasketName": "BasketItemBasketName",
"BasketItemUserId": "BasketItemUserId",
"BasketItemStoreId": "BasketItemStoreId",
"BasketItemProductId": "BasketItemProductId",
"BasketItemProductSkuId": "BasketItemProductSkuId",
"BasketItemQuantity": "BasketItemQuantity",
"BasketItemMediaResources": "BasketItemMediaResources",
"BasketItemProductName": "BasketItemProductName",
"BasketItemSkuDescription": "BasketItemSkuDescription",
"BasketItemCurrency": "BasketItemCurrency",
"BasketItemUnitPrice": "BasketItemUnitPrice",
"BasketItemTotalPrice": "BasketItemTotalPrice",
"BasketItemTotalDiscount": "BasketItemTotalDiscount",
"BasketItemInventory": "BasketItemInventory",
"BasketItemIsInvalid": "BasketItemIsInvalid",
"CreateBasketItem": "CreateBasketItem",
"EditBasketItem": "EditBasketItem",
"BasketItemDeletionConfirmationMessage": "Are you sure to delete the basketItem {0}?",
"SuccessfullyDeleted": "Successfully deleted"
}
}

27
plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp/EShop/Plugins/Baskets/Localization/sl.json

@ -1,6 +1,31 @@
{
"culture": "sl",
"texts": {
"ManageYourProfile": "Upravljajte svojim profilom"
"ManageYourProfile": "Upravljajte svojim profilom",
"Permission:BasketItem": "BasketItem",
"Permission:Create": "Create",
"Permission:Update": "Update",
"Permission:Delete": "Delete",
"Menu:BasketItem": "MenuBasketItem",
"BasketItem": "BasketItem",
"BasketItemBasketName": "BasketItemBasketName",
"BasketItemUserId": "BasketItemUserId",
"BasketItemStoreId": "BasketItemStoreId",
"BasketItemProductId": "BasketItemProductId",
"BasketItemProductSkuId": "BasketItemProductSkuId",
"BasketItemQuantity": "BasketItemQuantity",
"BasketItemMediaResources": "BasketItemMediaResources",
"BasketItemProductName": "BasketItemProductName",
"BasketItemSkuDescription": "BasketItemSkuDescription",
"BasketItemCurrency": "BasketItemCurrency",
"BasketItemUnitPrice": "BasketItemUnitPrice",
"BasketItemTotalPrice": "BasketItemTotalPrice",
"BasketItemTotalDiscount": "BasketItemTotalDiscount",
"BasketItemInventory": "BasketItemInventory",
"BasketItemIsInvalid": "BasketItemIsInvalid",
"CreateBasketItem": "CreateBasketItem",
"EditBasketItem": "EditBasketItem",
"BasketItemDeletionConfirmationMessage": "Are you sure to delete the basketItem {0}?",
"SuccessfullyDeleted": "Successfully deleted"
}
}

29
plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp/EShop/Plugins/Baskets/Localization/tr.json

@ -1,7 +1,32 @@
{
"culture": "tr",
"texts": {
"ManageYourProfile": "Profil yönetimi",
"SamplePageMessage": "Baskets modulünden örnek bir sayfa"
"ManageYourProfile": "Profil yönetimi",
"SamplePageMessage": "Baskets modulünden örnek bir sayfa",
"Permission:BasketItem": "BasketItem",
"Permission:Create": "Create",
"Permission:Update": "Update",
"Permission:Delete": "Delete",
"Menu:BasketItem": "MenuBasketItem",
"BasketItem": "BasketItem",
"BasketItemBasketName": "BasketItemBasketName",
"BasketItemUserId": "BasketItemUserId",
"BasketItemStoreId": "BasketItemStoreId",
"BasketItemProductId": "BasketItemProductId",
"BasketItemProductSkuId": "BasketItemProductSkuId",
"BasketItemQuantity": "BasketItemQuantity",
"BasketItemMediaResources": "BasketItemMediaResources",
"BasketItemProductName": "BasketItemProductName",
"BasketItemSkuDescription": "BasketItemSkuDescription",
"BasketItemCurrency": "BasketItemCurrency",
"BasketItemUnitPrice": "BasketItemUnitPrice",
"BasketItemTotalPrice": "BasketItemTotalPrice",
"BasketItemTotalDiscount": "BasketItemTotalDiscount",
"BasketItemInventory": "BasketItemInventory",
"BasketItemIsInvalid": "BasketItemIsInvalid",
"CreateBasketItem": "CreateBasketItem",
"EditBasketItem": "EditBasketItem",
"BasketItemDeletionConfirmationMessage": "Are you sure to delete the basketItem {0}?",
"SuccessfullyDeleted": "Successfully deleted"
}
}

28
plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp/EShop/Plugins/Baskets/Localization/vi.json

@ -1,6 +1,30 @@
{
"culture": "vi",
"texts": {
"Permission:BasketItem": "BasketItem",
"Permission:Create": "Create",
"Permission:Update": "Update",
"Permission:Delete": "Delete",
"Menu:BasketItem": "MenuBasketItem",
"BasketItem": "BasketItem",
"BasketItemBasketName": "BasketItemBasketName",
"BasketItemUserId": "BasketItemUserId",
"BasketItemStoreId": "BasketItemStoreId",
"BasketItemProductId": "BasketItemProductId",
"BasketItemProductSkuId": "BasketItemProductSkuId",
"BasketItemQuantity": "BasketItemQuantity",
"BasketItemMediaResources": "BasketItemMediaResources",
"BasketItemProductName": "BasketItemProductName",
"BasketItemSkuDescription": "BasketItemSkuDescription",
"BasketItemCurrency": "BasketItemCurrency",
"BasketItemUnitPrice": "BasketItemUnitPrice",
"BasketItemTotalPrice": "BasketItemTotalPrice",
"BasketItemTotalDiscount": "BasketItemTotalDiscount",
"BasketItemInventory": "BasketItemInventory",
"BasketItemIsInvalid": "BasketItemIsInvalid",
"CreateBasketItem": "CreateBasketItem",
"EditBasketItem": "EditBasketItem",
"BasketItemDeletionConfirmationMessage": "Are you sure to delete the basketItem {0}?",
"SuccessfullyDeleted": "Successfully deleted"
}
}
}

27
plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp/EShop/Plugins/Baskets/Localization/zh-Hans.json

@ -1,6 +1,31 @@
{
"culture": "zh-Hans",
"texts": {
"ManageYourProfile": "管理个人资料"
"ManageYourProfile": "管理个人资料",
"Permission:BasketItem": "BasketItem",
"Permission:Create": "Create",
"Permission:Update": "Update",
"Permission:Delete": "Delete",
"Menu:BasketItem": "MenuBasketItem",
"BasketItem": "BasketItem",
"BasketItemBasketName": "BasketItemBasketName",
"BasketItemUserId": "BasketItemUserId",
"BasketItemStoreId": "BasketItemStoreId",
"BasketItemProductId": "BasketItemProductId",
"BasketItemProductSkuId": "BasketItemProductSkuId",
"BasketItemQuantity": "BasketItemQuantity",
"BasketItemMediaResources": "BasketItemMediaResources",
"BasketItemProductName": "BasketItemProductName",
"BasketItemSkuDescription": "BasketItemSkuDescription",
"BasketItemCurrency": "BasketItemCurrency",
"BasketItemUnitPrice": "BasketItemUnitPrice",
"BasketItemTotalPrice": "BasketItemTotalPrice",
"BasketItemTotalDiscount": "BasketItemTotalDiscount",
"BasketItemInventory": "BasketItemInventory",
"BasketItemIsInvalid": "BasketItemIsInvalid",
"CreateBasketItem": "CreateBasketItem",
"EditBasketItem": "EditBasketItem",
"BasketItemDeletionConfirmationMessage": "Are you sure to delete the basketItem {0}?",
"SuccessfullyDeleted": "Successfully deleted"
}
}

27
plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp/EShop/Plugins/Baskets/Localization/zh-Hant.json

@ -1,6 +1,31 @@
{
"culture": "zh-Hant",
"texts": {
"ManageYourProfile": "管理個人資料"
"ManageYourProfile": "管理個人資料",
"Permission:BasketItem": "BasketItem",
"Permission:Create": "Create",
"Permission:Update": "Update",
"Permission:Delete": "Delete",
"Menu:BasketItem": "MenuBasketItem",
"BasketItem": "BasketItem",
"BasketItemBasketName": "BasketItemBasketName",
"BasketItemUserId": "BasketItemUserId",
"BasketItemStoreId": "BasketItemStoreId",
"BasketItemProductId": "BasketItemProductId",
"BasketItemProductSkuId": "BasketItemProductSkuId",
"BasketItemQuantity": "BasketItemQuantity",
"BasketItemMediaResources": "BasketItemMediaResources",
"BasketItemProductName": "BasketItemProductName",
"BasketItemSkuDescription": "BasketItemSkuDescription",
"BasketItemCurrency": "BasketItemCurrency",
"BasketItemUnitPrice": "BasketItemUnitPrice",
"BasketItemTotalPrice": "BasketItemTotalPrice",
"BasketItemTotalDiscount": "BasketItemTotalDiscount",
"BasketItemInventory": "BasketItemInventory",
"BasketItemIsInvalid": "BasketItemIsInvalid",
"CreateBasketItem": "CreateBasketItem",
"EditBasketItem": "EditBasketItem",
"BasketItemDeletionConfirmationMessage": "Are you sure to delete the basketItem {0}?",
"SuccessfullyDeleted": "Successfully deleted"
}
}

1
plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain/EasyAbp.EShop.Plugins.Baskets.Domain.csproj

@ -9,6 +9,7 @@
<ItemGroup>
<PackageReference Include="Volo.Abp.Ddd.Domain" Version="3.0.1" />
<ProjectReference Include="..\..\..\..\modules\EasyAbp.EShop.Products\src\EasyAbp.EShop.Products.Domain.Shared\EasyAbp.EShop.Products.Domain.Shared.csproj" />
<ProjectReference Include="..\EasyAbp.EShop.Plugins.Baskets.Domain.Shared\EasyAbp.EShop.Plugins.Baskets.Domain.Shared.csproj" />
</ItemGroup>

52
plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain/EasyAbp/EShop/Plugins/Baskets/BasketItems/BasketItem.cs

@ -1,11 +1,11 @@
using System;
using System;
using JetBrains.Annotations;
using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.MultiTenancy;
namespace EasyAbp.EShop.Plugins.Baskets.BasketItems
{
public class BasketItem : CreationAuditedAggregateRoot<Guid>, IMultiTenant
public class BasketItem : AuditedAggregateRoot<Guid>, IMultiTenant, IProductData
{
public virtual Guid? TenantId { get; protected set; }
@ -14,6 +14,8 @@ namespace EasyAbp.EShop.Plugins.Baskets.BasketItems
public virtual Guid UserId { get; protected set; }
public virtual Guid StoreId { get; protected set; }
public virtual Guid ProductId { get; protected set; }
public virtual Guid ProductSkuId { get; protected set; }
@ -37,5 +39,49 @@ namespace EasyAbp.EShop.Plugins.Baskets.BasketItems
public virtual decimal TotalPrice { get; protected set; }
public virtual decimal TotalDiscount { get; protected set; }
public virtual int Inventory { get; protected set; }
public virtual bool IsInvalid { get; protected set; }
protected BasketItem()
{
}
public BasketItem(
Guid id,
Guid? tenantId,
[NotNull] string basketName,
Guid userId,
Guid storeId,
Guid productId,
Guid productSkuId) : base(id)
{
TenantId = tenantId;
BasketName = basketName;
UserId = userId;
StoreId = storeId;
ProductId = productId;
ProductSkuId = productSkuId;
}
public void UpdateProductData(int quantity, IProductData productData)
{
Quantity = quantity;
MediaResources = productData.MediaResources;
ProductName = productData.ProductName;
SkuDescription = productData.SkuDescription;
Currency = productData.Currency;
UnitPrice = productData.UnitPrice;
TotalPrice = productData.TotalPrice;
TotalDiscount = productData.TotalDiscount;
Inventory = productData.Inventory;
}
public void SetIsInvalid(bool isForSale)
{
IsInvalid = isForSale;
}
}
}
}

10
plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain/EasyAbp/EShop/Plugins/Baskets/BasketItems/IBasketItemRepository.cs

@ -0,0 +1,10 @@
using System;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories;
namespace EasyAbp.EShop.Plugins.Baskets.BasketItems
{
public interface IBasketItemRepository : IRepository<BasketItem, Guid>
{
}
}

21
plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain/EasyAbp/EShop/Plugins/Baskets/BasketItems/IProductData.cs

@ -0,0 +1,21 @@
namespace EasyAbp.EShop.Plugins.Baskets.BasketItems
{
public interface IProductData
{
string MediaResources { get; }
string ProductName { get; }
string SkuDescription { get; }
string Currency { get; }
decimal UnitPrice { get; }
decimal TotalPrice { get; }
decimal TotalDiscount { get; }
int Inventory { get; }
}
}

14
plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain/EasyAbp/EShop/Plugins/Baskets/BasketItems/IProductUpdateRecorder.cs

@ -0,0 +1,14 @@
using EasyAbp.EShop.Products.ProductInventories;
using EasyAbp.EShop.Products.Products;
using Volo.Abp.Domain.Entities.Events.Distributed;
using Volo.Abp.EventBus.Distributed;
namespace EasyAbp.EShop.Plugins.Baskets.BasketItems
{
public interface IProductUpdateRecorder :
IDistributedEventHandler<EntityUpdatedEto<ProductEto>>,
IDistributedEventHandler<ProductInventoryChangedEto>
{
}
}

21
plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain/EasyAbp/EShop/Plugins/Baskets/BasketItems/ProductDataModel.cs

@ -0,0 +1,21 @@
namespace EasyAbp.EShop.Plugins.Baskets.BasketItems
{
public class ProductDataModel : IProductData
{
public string MediaResources { get; set; }
public string ProductName { get; set; }
public string SkuDescription { get; set; }
public string Currency { get; set; }
public decimal UnitPrice { get; set; }
public decimal TotalPrice { get; set; }
public decimal TotalDiscount { get; set; }
public int Inventory { get; set; }
}
}

59
plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain/EasyAbp/EShop/Plugins/Baskets/BasketItems/ProductUpdateRecorder.cs

@ -0,0 +1,59 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using EasyAbp.EShop.Plugins.Baskets.ProductUpdates;
using EasyAbp.EShop.Products.ProductInventories;
using EasyAbp.EShop.Products.Products;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Entities.Events.Distributed;
using Volo.Abp.Guids;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Uow;
namespace EasyAbp.EShop.Plugins.Baskets.BasketItems
{
public class ProductUpdateRecorder : IProductUpdateRecorder, ITransientDependency
{
private readonly IGuidGenerator _guidGenerator;
private readonly IProductUpdateRepository _productUpdateRepository;
public ProductUpdateRecorder(
IGuidGenerator guidGenerator,
IProductUpdateRepository productUpdateRepository)
{
_guidGenerator = guidGenerator;
_productUpdateRepository = productUpdateRepository;
}
[UnitOfWork(true)]
public virtual async Task HandleEventAsync(EntityUpdatedEto<ProductEto> eventData)
{
foreach (var skuId in eventData.Entity.ProductSkus.Select(sku => sku.Id))
{
await UpdateAsync(skuId);
}
}
[UnitOfWork(true)]
public virtual async Task HandleEventAsync(ProductInventoryChangedEto eventData)
{
await UpdateAsync(eventData.ProductSkuId);
}
protected virtual async Task UpdateAsync(Guid skuId)
{
var entity = await _productUpdateRepository.FindAsync(x => x.ProductSkuId == skuId);
if (entity == null)
{
entity = new ProductUpdate(_guidGenerator.Create(), skuId);
await _productUpdateRepository.InsertAsync(entity);
}
else
{
await _productUpdateRepository.UpdateAsync(entity);
}
}
}
}

8
plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain/EasyAbp/EShop/Plugins/Baskets/EShopPluginsBasketsDomainModule.cs

@ -1,10 +1,12 @@
using Volo.Abp.Modularity;
using EasyAbp.EShop.Products;
using Volo.Abp.Modularity;
namespace EasyAbp.EShop.Plugins.Baskets
{
[DependsOn(
typeof(EShopPluginsBasketsDomainSharedModule)
)]
typeof(EShopPluginsBasketsDomainSharedModule),
typeof(EShopProductsDomainSharedModule)
)]
public class EShopPluginsBasketsDomainModule : AbpModule
{

13
plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain/EasyAbp/EShop/Plugins/Baskets/ProductUpdates/IProductUpdateRepository.cs

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories;
namespace EasyAbp.EShop.Plugins.Baskets.ProductUpdates
{
public interface IProductUpdateRepository : IRepository<ProductUpdate, Guid>
{
Task<List<ProductUpdate>> GetListByProductSkuIdsAsync(IEnumerable<Guid> productSkuIds, CancellationToken cancellationToken = default);
}
}

22
plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain/EasyAbp/EShop/Plugins/Baskets/ProductUpdates/ProductUpdate.cs

@ -0,0 +1,22 @@
using System;
using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.MultiTenancy;
namespace EasyAbp.EShop.Plugins.Baskets.ProductUpdates
{
public class ProductUpdate : FullAuditedAggregateRoot<Guid>
{
public virtual Guid ProductSkuId { get; protected set; }
protected ProductUpdate()
{
}
public ProductUpdate(
Guid id,
Guid productSkuId) : base(id)
{
ProductSkuId = productSkuId;
}
}
}

14
plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore/EasyAbp/EShop/Plugins/Baskets/BasketItems/BasketItemRepository.cs

@ -0,0 +1,14 @@
using System;
using EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;
namespace EasyAbp.EShop.Plugins.Baskets.BasketItems
{
public class BasketItemRepository : EfCoreRepository<BasketsDbContext, BasketItem, Guid>, IBasketItemRepository
{
public BasketItemRepository(IDbContextProvider<BasketsDbContext> dbContextProvider) : base(dbContextProvider)
{
}
}
}

8
plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore/EasyAbp/EShop/Plugins/Baskets/EntityFrameworkCore/BasketsDbContext.cs

@ -1,6 +1,8 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore;
using EasyAbp.EShop.Plugins.Baskets.BasketItems;
using EasyAbp.EShop.Plugins.Baskets.ProductUpdates;
namespace EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore
{
@ -10,6 +12,8 @@ namespace EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore
/* Add DbSet for each Aggregate Root here. Example:
* public DbSet<Question> Questions { get; set; }
*/
public DbSet<BasketItem> BasketItems { get; set; }
public DbSet<ProductUpdate> ProductUpdates { get; set; }
public BasketsDbContext(DbContextOptions<BasketsDbContext> options)
: base(options)
@ -24,4 +28,4 @@ namespace EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore
builder.ConfigurePluginsBaskets();
}
}
}
}

32
plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore/EasyAbp/EShop/Plugins/Baskets/EntityFrameworkCore/BasketsDbContextModelCreatingExtensions.cs

@ -1,6 +1,9 @@
using System;
using EasyAbp.EShop.Plugins.Baskets.BasketItems;
using System;
using EasyAbp.EShop.Plugins.Baskets.ProductUpdates;
using Microsoft.EntityFrameworkCore;
using Volo.Abp;
using Volo.Abp.EntityFrameworkCore.Modeling;
namespace EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore
{
@ -38,6 +41,31 @@ namespace EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore
b.HasIndex(q => q.CreationTime);
});
*/
builder.Entity<BasketItem>(b =>
{
b.ToTable(options.TablePrefix + "BasketItems", options.Schema);
b.ConfigureByConvention();
/* Configure more properties here */
b.HasIndex(x => x.UserId);
b.Property(x => x.UnitPrice).HasColumnType("decimal(20,8)");
b.Property(x => x.TotalPrice).HasColumnType("decimal(20,8)");
b.Property(x => x.TotalDiscount).HasColumnType("decimal(20,8)");
});
builder.Entity<ProductUpdate>(b =>
{
b.ToTable(options.TablePrefix + "ProductUpdates", options.Schema);
b.ConfigureByConvention();
/* Configure more properties here */
b.HasIndex(x => x.ProductSkuId);
});
}
}
}
}

8
plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore/EasyAbp/EShop/Plugins/Baskets/EntityFrameworkCore/EShopPluginsBasketsEntityFrameworkCoreModule.cs

@ -1,4 +1,6 @@
using Microsoft.Extensions.DependencyInjection;
using EasyAbp.EShop.Plugins.Baskets.BasketItems;
using EasyAbp.EShop.Plugins.Baskets.ProductUpdates;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.Modularity;
@ -17,7 +19,9 @@ namespace EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore
/* Add custom repositories here. Example:
* options.AddRepository<Question, EfCoreQuestionRepository>();
*/
options.AddRepository<BasketItem, BasketItemRepository>();
options.AddRepository<ProductUpdate, ProductUpdateRepository>();
});
}
}
}
}

9
plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore/EasyAbp/EShop/Plugins/Baskets/EntityFrameworkCore/IBasketsDbContext.cs

@ -1,5 +1,8 @@
using Volo.Abp.Data;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore;
using EasyAbp.EShop.Plugins.Baskets.BasketItems;
using EasyAbp.EShop.Plugins.Baskets.ProductUpdates;
namespace EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore
{
@ -9,5 +12,7 @@ namespace EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore
/* Add DbSet for each Aggregate Root here. Example:
* DbSet<Question> Questions { get; }
*/
DbSet<BasketItem> BasketItems { get; set; }
DbSet<ProductUpdate> ProductUpdates { get; set; }
}
}
}

25
plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore/EasyAbp/EShop/Plugins/Baskets/ProductUpdates/ProductUpdateRepository.cs

@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;
namespace EasyAbp.EShop.Plugins.Baskets.ProductUpdates
{
public class ProductUpdateRepository : EfCoreRepository<BasketsDbContext, ProductUpdate, Guid>, IProductUpdateRepository
{
public ProductUpdateRepository(IDbContextProvider<BasketsDbContext> dbContextProvider) : base(dbContextProvider)
{
}
public async Task<List<ProductUpdate>> GetListByProductSkuIdsAsync(IEnumerable<Guid> productSkuIds, CancellationToken cancellationToken = default)
{
return await GetQueryable().Where(x => productSkuIds.Contains(x.ProductSkuId))
.ToListAsync(cancellationToken: cancellationToken);
}
}
}

9
plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Web/BasketsWebAutoMapperProfile.cs

@ -1,4 +1,6 @@
using AutoMapper;
using EasyAbp.EShop.Plugins.Baskets.BasketItems.Dtos;
using AutoMapper;
using EasyAbp.EShop.Plugins.Baskets.Web.Pages.EShop.Plugins.Baskets.BasketItems.BasketItem.ViewModels;
namespace EasyAbp.EShop.Plugins.Baskets.Web
{
@ -9,6 +11,9 @@ namespace EasyAbp.EShop.Plugins.Baskets.Web
/* You can configure your AutoMapper mapping configuration here.
* Alternatively, you can split your mapping configurations
* into multiple profile classes for a better organization. */
CreateMap<BasketItemDto, EditBasketItemViewModel>();
CreateMap<CreateBasketItemViewModel, CreateBasketItemDto>();
CreateMap<EditBasketItemViewModel, UpdateBasketItemDto>();
}
}
}
}

28
plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Web/Menus/BasketsMenuContributor.cs

@ -1,4 +1,7 @@
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Threading.Tasks;
using EasyAbp.EShop.Plugins.Baskets.Localization;
using EasyAbp.EShop.Plugins.Baskets.Permissions;
using Volo.Abp.UI.Navigation;
namespace EasyAbp.EShop.Plugins.Baskets.Web.Menus
@ -13,11 +16,26 @@ namespace EasyAbp.EShop.Plugins.Baskets.Web.Menus
}
}
private Task ConfigureMainMenu(MenuConfigurationContext context)
private async Task ConfigureMainMenu(MenuConfigurationContext context)
{
//Add main menu items.
var l = context.GetLocalizer<BasketsResource>(); //Add main menu items.
return Task.CompletedTask;
var basketManagementMenuItem = new ApplicationMenuItem(BasketsMenus.Prefix, l["Menu:BasketManagement"]);
if (await context.IsGrantedAsync(BasketsPermissions.BasketItem.Default))
{
basketManagementMenuItem.AddItem(
new ApplicationMenuItem(BasketsMenus.BasketItem, l["Menu:BasketItem"], $"/EShop/Plugins/Baskets/BasketItems/BasketItem?basketName={BasketsConsts.DefaultBasketName}&userId=")
);
}
if (!basketManagementMenuItem.Items.IsNullOrEmpty())
{
var eShopMenuItem = context.Menu.Items.GetOrAdd(i => i.Name == BasketsMenus.ModuleGroupPrefix,
() => new ApplicationMenuItem(BasketsMenus.BasketItem, l["Menu:EasyAbpEShop"]));
eShopMenuItem.Items.Add(basketManagementMenuItem);
}
}
}
}
}

6
plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Web/Menus/BasketsMenus.cs

@ -2,7 +2,11 @@
{
public class BasketsMenus
{
private const string Prefix = "EasyAbp.EShop.Plugins.Baskets";
public const string ModuleGroupPrefix = "EasyAbp.EShop";
public const string Prefix = ModuleGroupPrefix + ".Plugins.Baskets";
public const string BasketItem = Prefix + ".BasketItem";
//Add your menu items here...
//public const string Home = Prefix + ".MyNewMenuItem";

18
plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Web/Pages/EShop/Plugins/Baskets/BasketItems/BasketItem/CreateModal.cshtml

@ -0,0 +1,18 @@
@page
@using EasyAbp.EShop.Plugins.Baskets.Localization
@using Microsoft.AspNetCore.Mvc.Localization
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal
@inject IHtmlLocalizer<BasketsResource> L
@model EasyAbp.EShop.Plugins.Baskets.Web.Pages.EShop.Plugins.Baskets.BasketItems.BasketItem.CreateModalModel
@{
Layout = null;
}
<abp-dynamic-form abp-model="ViewModel" data-ajaxForm="true" asp-page="CreateModal">
<abp-modal>
<abp-modal-header title="@L["CreateBasketItem"].Value"></abp-modal-header>
<abp-modal-body>
<abp-form-content />
</abp-modal-body>
<abp-modal-footer buttons="@(AbpModalButtons.Cancel|AbpModalButtons.Save)"></abp-modal-footer>
</abp-modal>
</abp-dynamic-form>

28
plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Web/Pages/EShop/Plugins/Baskets/BasketItems/BasketItem/CreateModal.cshtml.cs

@ -0,0 +1,28 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using EasyAbp.EShop.Plugins.Baskets.BasketItems;
using EasyAbp.EShop.Plugins.Baskets.BasketItems.Dtos;
using EasyAbp.EShop.Plugins.Baskets.Web.Pages.EShop.Plugins.Baskets.BasketItems.BasketItem.ViewModels;
namespace EasyAbp.EShop.Plugins.Baskets.Web.Pages.EShop.Plugins.Baskets.BasketItems.BasketItem
{
public class CreateModalModel : BasketsPageModel
{
[BindProperty]
public CreateBasketItemViewModel ViewModel { get; set; } = new CreateBasketItemViewModel();
private readonly IBasketItemAppService _service;
public CreateModalModel(IBasketItemAppService service)
{
_service = service;
}
public virtual async Task<IActionResult> OnPostAsync()
{
var dto = ObjectMapper.Map<CreateBasketItemViewModel, CreateBasketItemDto>(ViewModel);
await _service.CreateAsync(dto);
return NoContent();
}
}
}

19
plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Web/Pages/EShop/Plugins/Baskets/BasketItems/BasketItem/EditModal.cshtml

@ -0,0 +1,19 @@
@page
@using EasyAbp.EShop.Plugins.Baskets.Localization
@using Microsoft.AspNetCore.Mvc.Localization
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal
@inject IHtmlLocalizer<BasketsResource> L
@model EasyAbp.EShop.Plugins.Baskets.Web.Pages.EShop.Plugins.Baskets.BasketItems.BasketItem.EditModalModel
@{
Layout = null;
}
<abp-dynamic-form abp-model="ViewModel" data-ajaxForm="true" asp-page="EditModal">
<abp-modal>
<abp-modal-header title="@L["EditBasketItem"].Value"></abp-modal-header>
<abp-modal-body>
<abp-input asp-for="Id" />
<abp-form-content />
</abp-modal-body>
<abp-modal-footer buttons="@(AbpModalButtons.Cancel|AbpModalButtons.Save)"></abp-modal-footer>
</abp-modal>
</abp-dynamic-form>

39
plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Web/Pages/EShop/Plugins/Baskets/BasketItems/BasketItem/EditModal.cshtml.cs

@ -0,0 +1,39 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using EasyAbp.EShop.Plugins.Baskets.BasketItems;
using EasyAbp.EShop.Plugins.Baskets.BasketItems.Dtos;
using EasyAbp.EShop.Plugins.Baskets.Web.Pages.EShop.Plugins.Baskets.BasketItems.BasketItem.ViewModels;
namespace EasyAbp.EShop.Plugins.Baskets.Web.Pages.EShop.Plugins.Baskets.BasketItems.BasketItem
{
public class EditModalModel : BasketsPageModel
{
[HiddenInput]
[BindProperty(SupportsGet = true)]
public Guid Id { get; set; }
[BindProperty]
public EditBasketItemViewModel ViewModel { get; set; }
private readonly IBasketItemAppService _service;
public EditModalModel(IBasketItemAppService service)
{
_service = service;
}
public virtual async Task OnGetAsync()
{
var dto = await _service.GetAsync(Id);
ViewModel = ObjectMapper.Map<BasketItemDto, EditBasketItemViewModel>(dto);
}
public virtual async Task<IActionResult> OnPostAsync()
{
var dto = ObjectMapper.Map<EditBasketItemViewModel, UpdateBasketItemDto>(ViewModel);
await _service.UpdateAsync(Id, dto);
return NoContent();
}
}
}

72
plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Web/Pages/EShop/Plugins/Baskets/BasketItems/BasketItem/Index.cshtml

@ -0,0 +1,72 @@
@page
@using EasyAbp.EShop.Plugins.Baskets.Permissions
@using EasyAbp.EShop.Plugins.Baskets.Web.Pages.EShop.Plugins.Baskets.BasketItems.BasketItem
@using EasyAbp.EShop.Plugins.Baskets.Localization
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Mvc.Localization
@using Volo.Abp.AspNetCore.Mvc.UI.Layout
@model IndexModel
@inject IPageLayout PageLayout
@inject IHtmlLocalizer<BasketsResource> L
@inject IAuthorizationService Authorization
@{
PageLayout.Content.Title = L["BasketItem"].Value;
PageLayout.Content.BreadCrumb.Add(L["Menu:BasketItem"].Value);
PageLayout.Content.MenuItemName = "EasyAbpEShopBasketsBasketItem";
}
@section scripts
{
<abp-script src="/Pages/EShop/Plugins/Baskets/BasketItems/BasketItem/index.js" />
}
@section styles
{
<abp-style src="/Pages/EShop/Plugins/Baskets/BasketItems/BasketItem/index.css"/>
}
<script>
let basketName = '@Model.BasketName';
let userId = '@Model.UserId';
</script>
<abp-card>
<abp-card-header>
<abp-row>
<abp-column size-md="_6">
<abp-card-title>@L["BasketItem"]</abp-card-title>
</abp-column>
<abp-column size-md="_6" class="text-right">
@if (await Authorization.IsGrantedAsync(BasketsPermissions.BasketItem.Create))
{
<abp-button id="NewBasketItemButton"
text="@L["CreateBasketItem"].Value"
icon="plus"
button-type="Primary" />
}
</abp-column>
</abp-row>
</abp-card-header>
<abp-card-body>
<abp-table striped-rows="true" id="BasketItemTable" class="nowrap">
<thead>
<tr>
<th>@L["Actions"]</th>
<th>@L["BasketItemBasketName"]</th>
<th>@L["BasketItemUserId"]</th>
<th>@L["BasketItemStoreId"]</th>
<th>@L["BasketItemProductId"]</th>
<th>@L["BasketItemProductSkuId"]</th>
<th>@L["BasketItemQuantity"]</th>
<th>@L["BasketItemMediaResources"]</th>
<th>@L["BasketItemProductName"]</th>
<th>@L["BasketItemSkuDescription"]</th>
<th>@L["BasketItemCurrency"]</th>
<th>@L["BasketItemUnitPrice"]</th>
<th>@L["BasketItemTotalPrice"]</th>
<th>@L["BasketItemTotalDiscount"]</th>
<th>@L["BasketItemInventory"]</th>
<th>@L["BasketItemIsInvalid"]</th>
</tr>
</thead>
</abp-table>
</abp-card-body>
</abp-card>

20
plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Web/Pages/EShop/Plugins/Baskets/BasketItems/BasketItem/Index.cshtml.cs

@ -0,0 +1,20 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
namespace EasyAbp.EShop.Plugins.Baskets.Web.Pages.EShop.Plugins.Baskets.BasketItems.BasketItem
{
public class IndexModel : BasketsPageModel
{
[BindProperty(SupportsGet = true)]
public string BasketName { get; set; }
[BindProperty(SupportsGet = true)]
public Guid? UserId { get; set; }
public virtual async Task OnGetAsync()
{
await Task.CompletedTask;
}
}
}

30
plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Web/Pages/EShop/Plugins/Baskets/BasketItems/BasketItem/ViewModels/CreateBasketItemViewModel.cs

@ -0,0 +1,30 @@
using System;
using System.ComponentModel.DataAnnotations;
namespace EasyAbp.EShop.Plugins.Baskets.Web.Pages.EShop.Plugins.Baskets.BasketItems.BasketItem.ViewModels
{
public class CreateBasketItemViewModel
{
[Display(Name = "BasketItemBasketName")]
public string BasketName { get; set; } = BasketsConsts.DefaultBasketName;
/// <summary>
/// Specify the basket item owner user ID. Use current user ID if this property is null.
/// </summary>
[Display(Name = "BasketItemUserId")]
public Guid? UserId { get; set; }
[Display(Name = "BasketItemStoreId")]
public Guid StoreId { get; set; }
[Display(Name = "BasketItemProductId")]
public Guid ProductId { get; set; }
[Display(Name = "BasketItemProductSkuId")]
public Guid ProductSkuId { get; set; }
[Display(Name = "BasketItemQuantity")]
public int Quantity { get; set; }
}
}

12
plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Web/Pages/EShop/Plugins/Baskets/BasketItems/BasketItem/ViewModels/EditBasketItemViewModel.cs

@ -0,0 +1,12 @@
using System;
using System.ComponentModel.DataAnnotations;
namespace EasyAbp.EShop.Plugins.Baskets.Web.Pages.EShop.Plugins.Baskets.BasketItems.BasketItem.ViewModels
{
public class EditBasketItemViewModel
{
[Display(Name = "BasketItemQuantity")]
public int Quantity { get; set; }
}
}

0
plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Web/Pages/EShop/Plugins/Baskets/BasketItems/BasketItem/index.css

79
plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Web/Pages/EShop/Plugins/Baskets/BasketItems/BasketItem/index.js

@ -0,0 +1,79 @@
$(function () {
var l = abp.localization.getResource('EShopPluginsBaskets');
var service = easyAbp.eShop.plugins.baskets.basketItems.basketItem;
var createModal = new abp.ModalManager(abp.appPath + 'EShop/Plugins/Baskets/BasketItems/BasketItem/CreateModal');
var editModal = new abp.ModalManager(abp.appPath + 'EShop/Plugins/Baskets/BasketItems/BasketItem/EditModal');
var dataTable = $('#BasketItemTable').DataTable(abp.libs.datatables.normalizeConfiguration({
processing: true,
serverSide: true,
paging: true,
searching: false,
autoWidth: false,
scrollCollapse: true,
order: [[1, "asc"]],
ajax: abp.libs.datatables.createAjax(service.getList, function () {
return { basketName: basketName, userId: userId }
}),
columnDefs: [
{
rowAction: {
items:
[
{
text: l('Edit'),
visible: abp.auth.isGranted('EasyAbp.EShop.Plugins.Baskets.BasketItem.Update'),
action: function (data) {
editModal.open({ id: data.record.id });
}
},
{
text: l('Delete'),
visible: abp.auth.isGranted('EasyAbp.EShop.Plugins.Baskets.BasketItem.Delete'),
confirmMessage: function (data) {
return l('BasketItemDeletionConfirmationMessage', data.record.id);
},
action: function (data) {
service.delete(data.record.id)
.then(function () {
abp.notify.info(l('SuccessfullyDeleted'));
dataTable.ajax.reload();
});
}
}
]
}
},
{ data: "basketName" },
{ data: "userId" },
{ data: "storeId" },
{ data: "productId" },
{ data: "productSkuId" },
{ data: "quantity" },
{ data: "mediaResources" },
{ data: "productName" },
{ data: "skuDescription" },
{ data: "currency" },
{ data: "unitPrice" },
{ data: "totalPrice" },
{ data: "totalDiscount" },
{ data: "inventory" },
{ data: "isInvalid" },
]
}));
createModal.onResult(function () {
dataTable.ajax.reload();
});
editModal.onResult(function () {
dataTable.ajax.reload();
});
$('#NewBasketItemButton').click(function (e) {
e.preventDefault();
createModal.open();
});
});

26
plugins/Baskets/test/EasyAbp.EShop.Plugins.Baskets.Application.Tests/BasketItems/BasketItemAppServiceTests.cs

@ -0,0 +1,26 @@
using Shouldly;
using System.Threading.Tasks;
using Xunit;
namespace EasyAbp.EShop.Plugins.Baskets.BasketItems
{
public class BasketItemAppServiceTests : BasketsApplicationTestBase
{
private readonly IBasketItemAppService _basketItemAppService;
public BasketItemAppServiceTests()
{
_basketItemAppService = GetRequiredService<IBasketItemAppService>();
}
[Fact]
public async Task Test1()
{
// Arrange
// Act
// Assert
}
}
}

23
plugins/Baskets/test/EasyAbp.EShop.Plugins.Baskets.Domain.Tests/BasketItems/BasketItemDomainTests.cs

@ -0,0 +1,23 @@
using System.Threading.Tasks;
using Shouldly;
using Xunit;
namespace EasyAbp.EShop.Plugins.Baskets.BasketItems
{
public class BasketItemDomainTests : BasketsDomainTestBase
{
public BasketItemDomainTests()
{
}
[Fact]
public async Task Test1()
{
// Arrange
// Assert
// Assert
}
}
}

31
plugins/Baskets/test/EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore.Tests/EntityFrameworkCore/BasketItems/BasketItemRepositoryTests.cs

@ -0,0 +1,31 @@
using System;
using System.Threading.Tasks;
using EasyAbp.EShop.Plugins.Baskets.BasketItems;
using Volo.Abp.Domain.Repositories;
using Xunit;
namespace EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore.BasketItems
{
public class BasketItemRepositoryTests : BasketsEntityFrameworkCoreTestBase
{
private readonly IBasketItemRepository _basketItemRepository;
public BasketItemRepositoryTests()
{
_basketItemRepository = GetRequiredService<IBasketItemRepository>();
}
[Fact]
public async Task Test1()
{
await WithUnitOfWorkAsync(async () =>
{
// Arrange
// Act
//Assert
});
}
}
}

3699
samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore.DbMigrations/Migrations/20200704104743_AddedMediaResourcesToProductSku.Designer.cs

File diff suppressed because it is too large

59
samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore.DbMigrations/Migrations/20200704104743_AddedMediaResourcesToProductSku.cs

@ -0,0 +1,59 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
namespace EShopSample.Migrations
{
public partial class AddedMediaResourcesToProductSku : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "MediaResources",
table: "EShopProductsProductSkus",
nullable: true);
migrationBuilder.CreateTable(
name: "EShopPluginsBasketsBasketItems",
columns: table => new
{
Id = table.Column<Guid>(nullable: false),
ExtraProperties = table.Column<string>(nullable: true),
ConcurrencyStamp = table.Column<string>(maxLength: 40, nullable: true),
CreationTime = table.Column<DateTime>(nullable: false),
CreatorId = table.Column<Guid>(nullable: true),
TenantId = table.Column<Guid>(nullable: true),
BasketName = table.Column<string>(nullable: true),
UserId = table.Column<Guid>(nullable: false),
ProductId = table.Column<Guid>(nullable: false),
ProductSkuId = table.Column<Guid>(nullable: false),
Quantity = table.Column<int>(nullable: false),
MediaResources = table.Column<string>(nullable: true),
ProductName = table.Column<string>(nullable: true),
SkuDescription = table.Column<string>(nullable: true),
Currency = table.Column<string>(nullable: true),
UnitPrice = table.Column<decimal>(nullable: false),
TotalPrice = table.Column<decimal>(nullable: false),
TotalDiscount = table.Column<decimal>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_EShopPluginsBasketsBasketItems", x => x.Id);
});
migrationBuilder.CreateIndex(
name: "IX_EShopPluginsBasketsBasketItems_UserId",
table: "EShopPluginsBasketsBasketItems",
column: "UserId");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "EShopPluginsBasketsBasketItems");
migrationBuilder.DropColumn(
name: "MediaResources",
table: "EShopProductsProductSkus");
}
}
}

3699
samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore.DbMigrations/Migrations/20200704130321_AddedDecimalConfigurationsToBasketItem.Designer.cs

File diff suppressed because it is too large

61
samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore.DbMigrations/Migrations/20200704130321_AddedDecimalConfigurationsToBasketItem.cs

@ -0,0 +1,61 @@
using Microsoft.EntityFrameworkCore.Migrations;
namespace EShopSample.Migrations
{
public partial class AddedDecimalConfigurationsToBasketItem : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<decimal>(
name: "UnitPrice",
table: "EShopPluginsBasketsBasketItems",
type: "decimal(20,8)",
nullable: false,
oldClrType: typeof(decimal),
oldType: "decimal(18,2)");
migrationBuilder.AlterColumn<decimal>(
name: "TotalPrice",
table: "EShopPluginsBasketsBasketItems",
type: "decimal(20,8)",
nullable: false,
oldClrType: typeof(decimal),
oldType: "decimal(18,2)");
migrationBuilder.AlterColumn<decimal>(
name: "TotalDiscount",
table: "EShopPluginsBasketsBasketItems",
type: "decimal(20,8)",
nullable: false,
oldClrType: typeof(decimal),
oldType: "decimal(18,2)");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<decimal>(
name: "UnitPrice",
table: "EShopPluginsBasketsBasketItems",
type: "decimal(18,2)",
nullable: false,
oldClrType: typeof(decimal),
oldType: "decimal(20,8)");
migrationBuilder.AlterColumn<decimal>(
name: "TotalPrice",
table: "EShopPluginsBasketsBasketItems",
type: "decimal(18,2)",
nullable: false,
oldClrType: typeof(decimal),
oldType: "decimal(20,8)");
migrationBuilder.AlterColumn<decimal>(
name: "TotalDiscount",
table: "EShopPluginsBasketsBasketItems",
type: "decimal(18,2)",
nullable: false,
oldClrType: typeof(decimal),
oldType: "decimal(20,8)");
}
}
}

3702
samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore.DbMigrations/Migrations/20200704130714_AddedStoreIdToBasketItem.Designer.cs

File diff suppressed because it is too large

24
samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore.DbMigrations/Migrations/20200704130714_AddedStoreIdToBasketItem.cs

@ -0,0 +1,24 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
namespace EShopSample.Migrations
{
public partial class AddedStoreIdToBasketItem : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<Guid>(
name: "StoreId",
table: "EShopPluginsBasketsBasketItems",
nullable: false,
defaultValue: new Guid("00000000-0000-0000-0000-000000000000"));
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "StoreId",
table: "EShopPluginsBasketsBasketItems");
}
}
}

3762
samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore.DbMigrations/Migrations/20200704181535_CreatedProductUpdateEntity.Designer.cs

File diff suppressed because it is too large

44
samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore.DbMigrations/Migrations/20200704181535_CreatedProductUpdateEntity.cs

@ -0,0 +1,44 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
namespace EShopSample.Migrations
{
public partial class CreatedProductUpdateEntity : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "EShopPluginsBasketsProductUpdates",
columns: table => new
{
Id = table.Column<Guid>(nullable: false),
ExtraProperties = table.Column<string>(nullable: true),
ConcurrencyStamp = table.Column<string>(maxLength: 40, nullable: true),
CreationTime = table.Column<DateTime>(nullable: false),
CreatorId = table.Column<Guid>(nullable: true),
LastModificationTime = table.Column<DateTime>(nullable: true),
LastModifierId = table.Column<Guid>(nullable: true),
IsDeleted = table.Column<bool>(nullable: false, defaultValue: false),
DeleterId = table.Column<Guid>(nullable: true),
DeletionTime = table.Column<DateTime>(nullable: true),
TenantId = table.Column<Guid>(nullable: true),
ProductSkuId = table.Column<Guid>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_EShopPluginsBasketsProductUpdates", x => x.Id);
});
migrationBuilder.CreateIndex(
name: "IX_EShopPluginsBasketsProductUpdates_ProductSkuId",
table: "EShopPluginsBasketsProductUpdates",
column: "ProductSkuId");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "EShopPluginsBasketsProductUpdates");
}
}
}

3770
samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore.DbMigrations/Migrations/20200704182511_ChangeBasketItemToAuditedEntity.Designer.cs

File diff suppressed because it is too large

32
samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore.DbMigrations/Migrations/20200704182511_ChangeBasketItemToAuditedEntity.cs

@ -0,0 +1,32 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
namespace EShopSample.Migrations
{
public partial class ChangeBasketItemToAuditedEntity : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<DateTime>(
name: "LastModificationTime",
table: "EShopPluginsBasketsBasketItems",
nullable: true);
migrationBuilder.AddColumn<Guid>(
name: "LastModifierId",
table: "EShopPluginsBasketsBasketItems",
nullable: true);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "LastModificationTime",
table: "EShopPluginsBasketsBasketItems");
migrationBuilder.DropColumn(
name: "LastModifierId",
table: "EShopPluginsBasketsBasketItems");
}
}
}

3776
samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore.DbMigrations/Migrations/20200704195327_AddInventoryAndIsInvalidToBasketItem.Designer.cs

File diff suppressed because it is too large

33
samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore.DbMigrations/Migrations/20200704195327_AddInventoryAndIsInvalidToBasketItem.cs

@ -0,0 +1,33 @@
using Microsoft.EntityFrameworkCore.Migrations;
namespace EShopSample.Migrations
{
public partial class AddInventoryAndIsInvalidToBasketItem : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<int>(
name: "Inventory",
table: "EShopPluginsBasketsBasketItems",
nullable: false,
defaultValue: 0);
migrationBuilder.AddColumn<bool>(
name: "IsInvalid",
table: "EShopPluginsBasketsBasketItems",
nullable: false,
defaultValue: false);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "Inventory",
table: "EShopPluginsBasketsBasketItems");
migrationBuilder.DropColumn(
name: "IsInvalid",
table: "EShopPluginsBasketsBasketItems");
}
}
}

3772
samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore.DbMigrations/Migrations/20200704200233_RemoveTenantIdFromProductUpdate.Designer.cs

File diff suppressed because it is too large

24
samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore.DbMigrations/Migrations/20200704200233_RemoveTenantIdFromProductUpdate.cs

@ -0,0 +1,24 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
namespace EShopSample.Migrations
{
public partial class RemoveTenantIdFromProductUpdate : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "TenantId",
table: "EShopPluginsBasketsProductUpdates");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<Guid>(
name: "TenantId",
table: "EShopPluginsBasketsProductUpdates",
type: "uniqueidentifier",
nullable: true);
}
}
}

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save